• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Feature Reward Chest & Boss Reward [TFS 1.2]

Mkalo

ボーカロイド
Senator
Joined
Jun 1, 2011
Messages
1,118
Solutions
55
Reaction score
946
Location
Japan
cg0QG0q.png

NOT WORKING PROPERLY! FIX:
https://otland.net/threads/reward-chest-boss-reward-tfs-1-2.238554/page-2#post-2314080
Thanks to @imkingran
Credits:
Based on cbrm's code:
https://otland.net/threads/reward-chest-boss-reward-tfs-1-2.233397/

Instructions:

src/const.h:

Below...
Code:
  ITEM_MARKET = 14405,

...Add:
Code:
  ITEM_REWARD_BAG = 21518,
  ITEM_REWARD_CHEST = 21584,
  REWARD_CHEST_DEPOTID = 99,

src/depotchest.h:

Below...
Code:
explicit DepotChest(uint16_t _type);

...Add:
Code:
uint32_t getDepotId() const {
return depotId;
}

void setDepotId(uint32_t id) {
depotId = id;
}

Below...
Code:
uint32_t maxDepotItems;

...Add:
Code:
uint32_t depotId;

src/depotchest.cpp:

Below...
Code:
maxDepotItems = 1500;

...Add:
Code:
depotId = 0;

Above...
Code:
return Container::queryAdd(index, thing, count, flags, actor);

...Add:
Code:
if (actor != nullptr && getDepotId() == REWARD_CHEST_DEPOTID) {
  return RETURNVALUE_NOTPOSSIBLE;
}

src/depotlocker.h:

Above...
Code:
//cylinder implementations

...Add:
Code:
void setMaxLockerItems(uint32_t maxitems) {
  maxSize = maxitems;
}

src/player.h:

Below...
Code:
DepotLocker* getDepotLocker(uint32_t depotId);

...Add:
Code:
  DepotChest* getRewardBag(uint32_t depotId, bool autoCreate);
  DepotLocker* getRewardChest(uint16_t itemId);

src/player.cpp:

Above...
Code:
void Player::sendCancelMessage(ReturnValue message) const

...Add:
Code:
DepotChest* Player::getRewardBag(uint32_t depotId, bool autoCreate)
{
  auto it = depotChests.find(depotId);
  if (it != depotChests.end()) {
  return it->second;
  }

  if (!autoCreate) {
  return nullptr;
  }
  DepotChest* bagReward = new DepotChest(ITEM_REWARD_BAG);
  bagReward->setDepotId(depotId);
  bagReward->incrementReferenceCounter();
  bagReward->setMaxDepotItems(getMaxDepotItems());
  depotChests[depotId] = bagReward;
  return bagReward;
}
DepotLocker* Player::getRewardChest(uint16_t itemId)
{
  auto it = depotLockerMap.find(REWARD_CHEST_DEPOTID);
  if (it != depotLockerMap.end()) {
  it->second->setID(itemId);
  return it->second;
  }
  DepotLocker* rewardChest = new DepotLocker(ITEM_REWARD_CHEST);
  rewardChest->setID(itemId);
  rewardChest->setDepotId(REWARD_CHEST_DEPOTID);
  rewardChest->setMaxLockerItems(1);
  rewardChest->internalAddThing(getRewardBag(REWARD_CHEST_DEPOTID, true));
  depotLockerMap[REWARD_CHEST_DEPOTID] = rewardChest;
  return rewardChest;
}
On player.cpp, container.cpp, inbox.cpp:

Change:
Code:
if (!item->isPickupable()) {

For:
Code:
if (item->getID() != 21518 && !item->isPickupable()) {

src/actions.cpp:

Change:
Code:
//depot container
if (DepotLocker* depot = container->getDepotLocker()) {
  DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId());
  myDepotLocker->setParent(depot->getParent()->getTile());
  openContainer = myDepotLocker;
  player->setLastDepotId(depot->getDepotId());
} else {
  openContainer = container;
}

For:
Code:
  //reward chest and depot container
  if (item->getActionId() == ITEM_REWARD_CHEST || item->getID() == ITEM_REWARD_CHEST) {
  DepotLocker* myRewardChest = player->getRewardChest(item->getID());
  myRewardChest->setParent(item->getTile());
  openContainer = myRewardChest;
  player->setLastDepotId(REWARD_CHEST_DEPOTID);
  }
  else if (DepotLocker* depot = container->getDepotLocker()) {
  DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId());
  myDepotLocker->setParent(depot->getParent()->getTile());
  openContainer = myDepotLocker;
  player->setLastDepotId(depot->getDepotId());
  }
  else {
  openContainer = container;
  }

src/game.cpp:

Above...
Code:
  if (!item->isPushable() || item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) {

...Add:
Code:
  if (item->getID() == ITEM_REWARD_BAG || item->getActionId() == ITEM_REWARD_CHEST) {
  player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE);
  return;
  }

src/monsters.h:
Below...
Code:
  int32_t subType;
  int32_t actionId;
  std::string text;

...Add:
Code:
  bool uniquedrop;

Below...
Code:
  actionId = -1;

...Add:
Code:
  uniquedrop = false;

Below...
Code:
  bool hiddenHealth;

...Add:
Code:
  bool rewardChest;

src/monsters.cpp:

Below...
Code:
  healthMax = 100;

...Add:
Code:
  rewardChest = false;

Below...
Code:
  } else if (strcasecmp(attrName, "hidehealth") == 0) {
  mType->hiddenHealth = attr.as_bool();
...Add:
Code:
  } else if (strcasecmp(attrName, "rewardchest") == 0) {
  mType->rewardChest = attr.as_bool();

Above...
Code:
  if ((attr = node.attribute("actionId"))) {

...Add:
Code:
  if ((attr = node.attribute("uniquedrop"))) {
  lootBlock.uniquedrop = attr.as_bool();
  }

src/iologindata.cpp:

Below...
Code:
  //load depot items

...Add:
Code:
  player->getRewardChest(ITEM_REWARD_CHEST);

Change:
Code:
  if (pid >= 0 && pid < 100) {
  DepotChest* depotChest = player->getDepotChest(pid, true);
  if (depotChest) {
  depotChest->internalAddThing(item);
  }

For:
Code:
if (pid >= 0 && pid < 100) {
  if (pid == REWARD_CHEST_DEPOTID) {
  DepotChest* depotChest = player->getRewardBag(pid, true);
  if (depotChest) {
  depotChest->internalAddThing(item);
  }
  }
  else {
  DepotChest* depotChest = player->getDepotChest(pid, true);
  if (depotChest) {
  depotChest->internalAddThing(item);
  }
  }

src/luascript.h:

Above...
Code:
// Combat

...Add:
Code:
// Reward
  static int luaItemGetNameDescription(lua_State* L);
  static int luaMonsterTypeUseRewardChest(lua_State* L);
src/luascript.cpp:

Above...
Code:
// Party

   registerClass("Party", "", nullptr);

...Add:
Code:
  // Reward
  registerMethod("MonsterType", "useRewardChest", LuaScriptInterface::luaMonsterTypeUseRewardChest);
  registerMethod("Item", "getNameDescription", LuaScriptInterface::luaItemGetNameDescription);

Above...
Code:
// Combat
int LuaScriptInterface::luaCombatCreate(lua_State* L)

...Add:
Code:
int LuaScriptInterface::luaItemGetNameDescription(lua_State* L)
{
  // item:getNameDescription()
  const Item* item = getUserdata<const Item>(L, 1);

  int32_t subType;
  bool addArticle = true;
  if (item) {
  subType = item->getSubType();
  const ItemType& it = Item::items[item->getID()];
  std::ostringstream s;

  const std::string& name = (item ? item->getName() : it.name);
  if (!name.empty()) {
  if (it.stackable && subType > 1) {
  if (it.showCount) {
  s << subType << ' ';
  }

  s << (item ? item->getPluralName() : it.getPluralName());
  }
  else {
  if (addArticle) {
  const std::string& article = (item ? item->getArticle() : it.article);
  if (!article.empty()) {
  s << article << ' ';
  }
  }

  s << name;
  }
  }
  else {
  s << "an item of type " << it.id;
  }
  pushString(L, s.str());
  } else {
  lua_pushnil(L);
  }
  return 1;
}

int LuaScriptInterface::luaMonsterTypeUseRewardChest(lua_State* L)
{
  // monsterType:useRewardChest()
  MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  if (monsterType) {
  pushBoolean(L, monsterType->rewardChest);
  }
  else {
  lua_pushnil(L);
  }
  return 1;
}

Change:
Code:
int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L)
{
  MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  if (!monsterType) {
  lua_pushnil(L);
  return 1;
  }

  static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) {
  lua_createtable(L, lootList.size(), 0);

  int index = 0;
  for (const auto& lootBlock : lootList) {
  lua_createtable(L, 0, 7);

  setField(L, "itemId", lootBlock.id);
  setField(L, "chance", lootBlock.chance);
  setField(L, "subType", lootBlock.subType);
  setField(L, "maxCount", lootBlock.countmax);
  setField(L, "actionId", lootBlock.actionId);
  setField(L, "text", lootBlock.text);
  parseLoot(lootBlock.childLoot);
  lua_setfield(L, -2, "childLoot");
  lua_rawseti(L, -2, ++index);
  }
  };
  parseLoot(monsterType->lootItems);
  return 1;
}

For:
Code:
int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L)
{
  // monsterType:getLoot()
  MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  if (!monsterType) {
  lua_pushnil(L);
  return 1;
  }
  static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) {
  lua_createtable(L, lootList.size(), 0);

  int index = 0;
  for (const auto& lootBlock : lootList) {
  lua_createtable(L, 0, 8);

  setField(L, "itemId", lootBlock.id);
  setField(L, "chance", lootBlock.chance);
  setField(L, "subType", lootBlock.subType);
  setField(L, "maxCount", lootBlock.countmax);
  setField(L, "actionId", lootBlock.actionId);
  setField(L, "text", lootBlock.text);
  pushBoolean(L, lootBlock.uniquedrop);
  lua_setfield(L, -2, "uniquedrop");
  parseLoot(lootBlock.childLoot);
  lua_setfield(L, -2, "childLoot");
  lua_rawseti(L, -2, ++index);
  }
  };
  parseLoot(monsterType->lootItems);
  return 1;
}
 
Last edited:
Add @ data/items/items/xml

Code:
<item id="21518" article="a" name="reward container">
  <attribute key="weight" value="1800" />
  <attribute key="containersize" value="100" />
  <attribute key="slotType" value="backpack" />
</item>
<item id="21584" article="a" name="reward chest">
  <attribute key="type" value="depot" />
  <attribute key="containerSize" value="1" />
  <attribute key="description" value="This chest contains your rewards earned in battles." />
</item>

Add @ data/creaturescripts/creaturescripts.xml

Code:
<event type="kill" name="RewardLoot" script="rewardloot.lua"/>

Register @data/creaturescripts/scripts/login.lua

Code:
player:registerEvent("RewardLoot")

data/creaturescripts/scripts/rewardloot.lua:

Code:
function sort_descending(t)
    local tmp = {}
    for k, v in pairs(t) do
        table.insert(tmp, {k, v})
    end
    table.sort(tmp, function(a, b) return a[2] > b[2] end)
    return tmp
end

function table.find(t, v)
    for i,x in pairs(t) do
        if x == v then
            return true
        end
    end
end

function Player:addItemRewardBag(itemid, count)
    local rewardbag = self:getDepotChest(99)
    return rewardbag:addItem(itemid, count)
end

function MonsterType:getBossReward(chance, unique)
    local ret = {}
    local function randomItem(lootBlock, chance)
        local randvalue = math.random(0, 100000) / (getConfigInfo("rateLoot") * chance)
        if randvalue < lootBlock.chance then
            if (ItemType(lootBlock.itemId):isStackable()) then
                return (randvalue%lootBlock.maxCount) + 1
            else
                return 1
            end
        end
    end
    local lootBlockList = self:getLoot()
    for _, loot in pairs(lootBlockList) do
        local rd = randomItem(loot, chance)
        if rd then
            if loot.uniquedrop then
                if unique then
                    table.insert(ret, {loot, rd})
                end
            else
                table.insert(ret, {loot, rd})
            end
        end
    end
    return ret
end

BossLoot = {}
BossUids = {}

function BossLoot:new(boss)
    if not table.find(BossUids, boss:getId()) then
        table.insert(BossUids, boss:getId())
        return setmetatable({creature=boss}, {__index = BossLoot})
    end
end

function BossLoot:updateDamage()
    if self.creature then
        local tmp = {}
        local totaldmg = 0
        for killer, damage in pairs(self.creature:getDamageMap()) do
            totaldmg = totaldmg+damage.total
            tmp[killer] = damage.total
        end
        self.players = sort_descending(tmp)
        self.totaldmg = totaldmg
    else
        error("Creature not found.")
    end
end

function BossLoot:setRewards()
    if self.totaldmg and self.creature then
        if getConfigInfo("rateLoot") > 0 then
            local mt = MonsterType(self.creature:getName())
            for i, playertab in ipairs(self.players) do
                local loot
                if i == 1 then
                    loot = mt:getBossReward(playertab[2] / self.totaldmg, true)
                else
                    loot = mt:getBossReward(playertab[2] / self.totaldmg, false)
                end
                table.insert(self.players[i], loot)
            end
        end
    else
        error("Error")
    end
end

function BossLoot:addRewards()
    if self.players and self.players[1] and self.players[1][3] then
        for i, playertab in ipairs(self.players) do
            local player = Player(playertab[1])
            if player then
                local str = "The following items are available in your reward chest: "
                for i, lootTable in ipairs(playertab[3]) do
                    local item = player:addItemRewardBag(lootTable[1].itemId, math.ceil(lootTable[2]))
                    if item then
                        str = str .. item:getNameDescription() .. ", "
                    end
                end
                str = str:sub(1, #str-2)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, str)
            end
        end
    else
        error("Error")
    end
end

function onKill(creature, target)
    if (Monster(target) ~= nil) then
        local mt = MonsterType(target:getName())
        if mt and mt:useRewardChest() then
            local loot = BossLoot:new(target)
            if loot then
                local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition()))
                corpse:decay()
                target:setDropLoot(false)
                loot:updateDamage()
                loot:setRewards()
                loot:addRewards()
                corpse:setAttribute('aid', 21584)
            end
        end
    end
end

HOW TO USE !!

Simply add this flag to the monster:
Code:
        <flag rewardchest="1" />

You can also set a drop to be unique, that way only the person that did the most damage will get this item.

Code:
        <item id="5903" chance="100000" uniquedrop="1" /><!-- ferumbras' hat -->
 
Last edited:
just tested, compiled everything, no errors nothing happens, boss dies and drop normal loot and nothing happens to the chest, using latest master branch from tfs repository (I upgraded it to 10.82, i don't think that matters tho)

EDIT: nvm, forgot to register the event on login.lua, i'll leave my comment here tho, in case someone forgets it too, working perfectly fine, thanks for the release
 
just tested, compiled everything, no errors nothing happens, boss dies and drop normal loot and nothing happens to the chest, using latest master branch from tfs repository (I upgraded it to 10.82, i don't think that matters tho)

EDIT: nvm, forgot to register the event on login.lua, i'll leave my comment here tho, in case someone forgets it too, working perfectly fine, thanks for the release

Did you register the event on login.lua and edited the monster's .xml

nvm
 
Last edited:
if I open my reward chest, the reward from the corpse will come to the chest too ?
 
Yes! You just have to create the chest it should work when you click it.
 
Can't get both at chest and in depot?

Why you won't release the chest too?
Didn't get what you mean by "in depot"

The chest is there here:

Code:
  if (item->getActionId() == ITEM_REWARD_CHEST || item->getID() == ITEM_REWARD_CHEST) {

Whenever a player uses an item (container) that has id equal to ITEM_REWARD_CHEST or the actionId "21584", it will pop up the reward container.

In the case of the chest you just need to create it and it will work just fine.
 
It work for me, its perfect i think in tfs 1.2!

*** I'm trying to use in tfs 1.0 i think that i did all the changes and did it right, but i got problem in script probably in this part because the functions change in tfs... do you know how to convert this part to 1.0?
Code:
function onKill(creature, target)

    if (Monster(target) ~= nil) then

        local mt = MonsterType(target:getName())

        if mt:useRewardChest() then

            local loot = BossLoot:new(target)
            if loot then
                local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition()))
                corpse:decay()
                target:setDropLoot(false)
                loot:updateDamage()
                loot:setRewards()
                loot:addRewards()
                corpse:setAttribute('aid', 21584)
            end
        end
    end
end

i think its specially in:
if (Monster(target) ~= nil) then

local mt = MonsterType(target:getName())

if mt:useRewardChest() then
 
Last edited:
It work for me, its perfect i think in tfs 1.2!

*** I'm trying to use in tfs 1.0 i think that i did all the changes and did it right, but i got problem in script probably in this part because the functions change in tfs... do you know how to convert this part to 1.0?
Code:
function onKill(creature, target)

    if (Monster(target) ~= nil) then

        local mt = MonsterType(target:getName())

        if mt:useRewardChest() then

            local loot = BossLoot:new(target)
            if loot then
                local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition()))
                corpse:decay()
                target:setDropLoot(false)
                loot:updateDamage()
                loot:setRewards()
                loot:addRewards()
                corpse:setAttribute('aid', 21584)
            end
        end
    end
end

i think its specially in:
if (Monster(target) ~= nil) then

local mt = MonsterType(target:getName())

if mt:useRewardChest() then

Could you send the error?
 
Could you send the error?
Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/reward_chest.lua:onKill
data/creaturescripts/scripts/reward_chest.lua:120: attempt to index local 'targe
t' (a number value)
stack traceback:
        [C]: in function '__index'
        data/creaturescripts/scripts/reward_chest.lua:120: in function <data/cre
aturescripts/scripts/reward_chest.lua:116>

It's line local mt = MonsterType(target:getName()) and
function onKill(creature, target)
 
Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/reward_chest.lua:onKill
data/creaturescripts/scripts/reward_chest.lua:120: attempt to index local 'targe
t' (a number value)
stack traceback:
        [C]: in function '__index'
        data/creaturescripts/scripts/reward_chest.lua:120: in function <data/cre
aturescripts/scripts/reward_chest.lua:116>

It's line local mt = MonsterType(target:getName()) and
function onKill(creature, target)
Code:
local mt = MonsterType(Monster(target):getName())

Try this
 
Code:
local mt = MonsterType(Monster(target):getName())

Try this

Very Thanks, i think its right but i got others problems now, i think it's not possible in 1.0 or is it possible?

Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/reward_chest.lua:onKill
data/creaturescripts/scripts/reward_chest.lua:55: attempt to index local 'boss'
(a number value)
stack traceback:
        [C]: in function '__index'
        data/creaturescripts/scripts/reward_chest.lua:55: in function 'new'
        data/creaturescripts/scripts/reward_chest.lua:124: in function <data/cre
aturescripts/scripts/reward_chest.lua:116>

function BossLoot:new(boss)
if not table.find(BossUids, boss:getId()) then <<< this is line 55
table.insert(BossUids, boss:getId())
return setmetatable({creature=boss}, {__index = BossLoot})
end
end

line 124:
local loot = BossLoot:new(target)
 
Code:
function onKill(creature, target)
    local target = Monster(target)
    if (Monster(target) ~= nil) then

        local mt = MonsterType(target:getName())

        if mt:useRewardChest() then

            local loot = BossLoot:new(target)
            if loot then
                local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition()))
                corpse:decay()
                target:setDropLoot(false)
                loot:updateDamage()
                loot:setRewards()
                loot:addRewards()
                corpse:setAttribute('aid', 21584)
            end
        end
    end
end

Use this.
 
Code:
function onKill(creature, target)
    local target = Monster(target)
    if (Monster(target) ~= nil) then

        local mt = MonsterType(target:getName())

        if mt:useRewardChest() then

            local loot = BossLoot:new(target)
            if loot then
                local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition()))
                corpse:decay()
                target:setDropLoot(false)
                loot:updateDamage()
                loot:setRewards()
                loot:addRewards()
                corpse:setAttribute('aid', 21584)
            end
        end
    end
end

Use this.
Omg! With your help i got it!! I think it's working good. very thanks i will post later every changes of your sources to work in tfs 1.0, and the finally reward script is
Code:
function sort_descending(t)
    local tmp = {}
    for k, v in pairs(t) do
        table.insert(tmp, {k, v})
    end
    table.sort(tmp, function(a, b) return a[2] > b[2] end)
    return tmp
end

function table.find(t, v)
    for i,x in pairs(t) do
        if x == v then
            return true
        end
    end
end

function Player:addItemRewardBag(itemid, count)
    local rewardbag = self:getDepotChest(99)
    return rewardbag:addItem(itemid, count)
end

function MonsterType:getBossReward(chance, unique)
    local ret = {}
    local function randomItem(lootBlock, chance)
        local randvalue = math.random(0, 100000) / (getConfigInfo("rateLoot") * chance)
        if randvalue < lootBlock.chance then
            if (ItemType(lootBlock.itemId):isStackable()) then
                return (randvalue%lootBlock.maxCount) + 1
            else
                return 1
            end
        end
    end
    local lootBlockList = self:getLoot()
    for _, loot in pairs(lootBlockList) do
        local rd = randomItem(loot, chance)
        if rd then
            if loot.uniquedrop then
                if unique then
                    table.insert(ret, {loot, rd})
                end
            else
                table.insert(ret, {loot, rd})
            end
        end
    end
    return ret
end

BossLoot = {}
BossUids = {}

function BossLoot:new(boss)
    if not table.find(BossUids, boss:getId()) then
        table.insert(BossUids, boss:getId())
        return setmetatable({creature=boss}, {__index = BossLoot})
    end
end

function BossLoot:updateDamage()
    if self.creature then
        local tmp = {}
        local totaldmg = 0
        for killer, damage in pairs(self.creature:getDamageMap()) do
            totaldmg = totaldmg+damage.total
            tmp[killer] = damage.total
        end
        self.players = sort_descending(tmp)
        self.totaldmg = totaldmg
    else
        error("Creature not found.")
    end
end

function BossLoot:setRewards()
    if self.totaldmg and self.creature then
        if getConfigInfo("rateLoot") > 0 then
            local mt = MonsterType(self.creature:getName())
            for i, playertab in ipairs(self.players) do
                local loot
                if i == 1 then
                    loot = mt:getBossReward(playertab[2] / self.totaldmg, true)
                else
                    loot = mt:getBossReward(playertab[2] / self.totaldmg, false)
                end
                table.insert(self.players[i], loot)
            end
        end
    else
        error("Error")
    end
end

function BossLoot:addRewards()
    if self.players and self.players[1] and self.players[1][3] then
        for i, playertab in ipairs(self.players) do
            local player = Player(playertab[1])
            if player then
                local str = "The following items are available in your reward chest: "
                for i, lootTable in ipairs(playertab[3]) do
                    local item = player:addItemRewardBag(lootTable[1].itemId, math.ceil(lootTable[2]))
                    if item then
                        str = str .. item:getNameDescription() .. ", "
                    end
                end
                str = str:sub(1, #str-2)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, str)
            end
        end
    else
        error("Error")
    end
end

function onKill(creature, target)

target = Monster(target)

    if (target ~= nil) then

        local mt = MonsterType(target:getName())

        if mt:useRewardChest() then

            local loot = BossLoot:new(target)
            if loot then
                local corpse = Item(doCreateItem(MonsterType(target:getName()):getCorpseId(), 1, target:getPosition()))
                corpse:decay()
                target:setDropLoot(false)
                loot:updateDamage()
                loot:setRewards()
                loot:addRewards()
                corpse:setAttribute('aid', 21584)
            end
        end
    end
end
 
This itens will be added in Reward Chest or in Reward Bag (Direct to Player)?

The items are going to be added both in the chest and in the reward bag inside the boss' corpse.
 
Perferct except one thing.
I found a serious bug.
If you attack boss with summon creature - server will crash. (loot can't go to summon creature, it should move loot to summon owner).
 
Back
Top