• 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!

CreatureEvent Party Loot Bonus - v. 1.2

Dantez

Member
Joined
May 16, 2009
Messages
67
Solutions
3
Reaction score
20
Hello! I've made a script which add items to our loot if we kill monster in specific amount of players (they must be in party). Easy and interesting.

How it works in practice?
partybonusloot.png


Ok, what if players are more than 30 sqm far away and don't even damaged monster?
partybonusloot2.png


And when I kill it alone?
partybonusloot3.png


v. 1.2 Roll Option
partylootbonusroll.png

CODE :)
creaturescripts/scripts/login.lua
Under:
Code:
registerCreatureEvent(cid, "AdvanceSave")
Add:
Code:
registerCreatureEvent(cid, "PartyBoss")

creaturescripts/creaturescripts.xml
Code:
<event type="kill" name="PartyBoss" event="script" value="partyBoss.lua"/>

creaturescripts/scripts/partyBoss.lua
Code:
local config = {
    rollItems = 1,
}

local array = {
["Example Boss"] = {
    [2] = {{2160, 15}, {2159, 10}, {2472, 2}},
    [3] = {{2453, 1}},
    [4] = {{2493, 2}}
    },
}

function sendPartyMessage(members, msg)
    for _, pid in pairs(members) do
        doPlayerSendTextMessage(pid, MESSAGE_INFO_DESCR, msg)
    end
return true
end

function dropBonusLoot(items, corpseid, position, members)
local container = doAddContainerItem(getTileItemById(position, corpseid).uid, 1988, 1)
    for _, item in pairs(items) do
        doAddContainerItem(container, item[1], item[2])
    end
    sendPartyMessage(members, createLootMessage(container))
return true
end

function roll(items, members)
    for i=1, #items do
        local numbers, index, num = {}, 0, 0
        for _, person in pairs(members) do
            table.insert(numbers, {person, math.random(1, 100)})
        end
       
        for z, val in ipairs(numbers) do
            if (val[2] > num) then
                num = val[2]
                index = z
            end
        end
        doPlayerAddItem(numbers[index][1], items[1], items[2])
        sendPartyMessage(members, getCreatureName(numbers[index][1]) .. " rolled " .. numbers[index][2] .. " and gained " .. getItemNameById(items[1]) .. ".")
    end
    return true
end

function createLootMessage(container)
local text = "Party loot bonus: "

    for i=0, getContainerSize(container)-1 do
        local item = getContainerItem(container, i)
        if item ~= nil then
            local info = getItemInfo(item.itemid)
            if (item.type > 1 and info.stackable) then
                text = text .. item.type .. " " .. info.plural
            else
                if (info.article) then
                    text = text .. info.article .. " " .. info.name
                else
                    text = text .. info.name
                end
            end
       
            if (getContainerItem(container, i+1).itemid > 0 ) then
                text = text .. ", "
            else
                text = text .. "."
            end
               
        else
            return text
        end
    end
return text
end

function partyMembersCheck(cid, members)
    for _, person in pairs(members) do
        if(getDistanceBetween(getCreaturePosition(cid), getCreaturePosition(person)) > 30) then
            return false
        end
    end
return true
end

function onKill(cid, target, lastHit)
    local corpseid, loot = getMonsterInfo(getCreatureName(target)).lookCorpse, array[getCreatureName(target)]
    if not (loot) or corpseid == nil or not isItemContainer(corpseid) then return true end
   
    if (isInParty(cid)) then
        local members, tab, items = getPartyMembers(getPartyLeader(cid)), 0, {}
        if (partyMembersCheck(cid, members)) then
            if (#members >= table.maxn(loot)) then tab = table.maxn(loot) else tab = #members end
            for i=2, tab do
                if (loot) then
                    for _, it in pairs(loot) do
                        if (it[2] > 1 and not getItemInfo(it[1]).stackable) then
                            for x=1, it[2] do
                                table.insert(items, {it[1], 1})
                            end
                        else
                            table.insert(items, it)
                        end
                    end
                end
            end
               
            if #items > 0 then
                if (config.rollItems > 0) then
                    roll(items, members)
                else
                    addEvent(dropBonusLoot, 0, items, corpseid, getCreaturePosition(target), members)
                end
            end
        else
            doPlayerSendTextMessage(cid, 27, "Some party members are too far away. Bonus inactive.")
        end
    else
        doPlayerSendTextMessage(cid, 27, "Next time take some people in party to get bonus loot.")
    end
return true
end

How can I add new monster? It's easy:
Code:
["CREATURE NAME"] = {
-- [NUMBER OF PARTY MEMBERS] = {{ITEM_ID, ITEM_COUNT}, {ITEM2_ID, ITEM2_COUNT}}
    [2] = {{2160, 5}, {2159, 10}, {2472, 2}},
    [3] = {{2453, 1}, {2160, 50}},
    [4] = {{2493, 2}}
    }

Changelog:
Version 1.1:



    • New array form
    • Detect stackable and not stackable items (loot message)
    • Bonus loot is now in backpack
Version 1.2:



    • New Roll Items option!
    • Fixed bug with empty arrays.
    • Better messages - like normal loot (magic plate armor, magic plate armor).
    • When 3 players are in the same party you earn loot for 2 players too!
    • Some other bugs repaired.
Found bug? Write!
Have an idea what to add/change? Write!
 
Last edited:
Nice Script, here are some pointers:
Write LUA Codes with this:
Code:
[code=lua][./lua]
(without the "dot")instead of using PHP Codes Brackets.

I would separate the table from the main script and add it to another place and have the main script do that file at the beginning of the script.

Also, to make it more "newbie" friendly you can make this form of building tables, sure it requires more writing, but it is more understandable and cleaner for anyone to review.
Lua:
local C = {
-- Monster Names

    ["Rat"] = {}
    -- Number of Party Member - Rewards
    
        ["Rat"][2] = {{ITEM_ID, ITEM_COUNT}, {ITEM_ID_2, ITEM_COUNT_2}}
        ["Rat"][3] = {{ITEM_ID, ITEM_COUNT}, {ITEM_ID_2, ITEM_COUNT_2}}
        
    ["Troll"] = {}
    
        ["Troll"][2] = {{ITEM_ID, ITEM_COUNT}, {ITEM_ID_2, ITEM_COUNT_2}}
        ["Troll"][3] = {{ITEM_ID, ITEM_COUNT}, {ITEM_ID_2, ITEM_COUNT_2}}
        
        
        
}

Let me know if it helps.
 
Last edited:
@Shinmaru
Your post motivated me to do something with that ugly array :D Thanks
You mean include other file with array?

@top
Version 1.1:
  • New array form
  • Detect stackable and not stackable items (loot message)
  • Bonus loot is now in backpack
 
@Shinmaru
Your post motivated me to do something with that ugly array :D Thanks
You mean include other file with array?

@top
Version 1.1:
  • New array form
  • Detect stackable and not stackable items (loot message)
  • Bonus loot is now in backpack

Glad I was of help :p
Btw you have a small typo with the first line "llocal".
 
Version 1.2:
  • New Roll Items option!
  • Fixed bug with empty arrays.
  • Better messages - like normal loot (magic plate armor, magic plate armor).
  • When 3 players are in the same party you earn loot for 2 players too!
  • Some other bugs repaired.
 
im using TFS 1.0 , i used that system... but nothing happens and no erroe logs appear at the server log...


SOME HELP ?
 
I GOT THIS:

TFS 1.0

Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/others/partyboss.lua:onKill
data/creaturescripts/scripts/others/partyboss.lua:88: attempt to call global 'getMonsterInfo' (a nil value)
stack traceback:
  [C]: in function 'getMonsterInfo'
  data/creaturescripts/scripts/others/partyboss.lua:88: in function <data/creaturescripts/scripts/others/partyboss.lua:87>
 
Last edited:
Code:
local config = {
    rollItems = 1,
}

local array = {
["Example Boss"] = {
    [2] = {{2160, 15}, {2159, 10}, {2472, 2}},
    [3] = {{2453, 1}},
    [4] = {{2493, 2}}
    },
}

function sendPartyMessage(members, msg)
    for _, pid in pairs(members) do
        doPlayerSendTextMessage(pid, MESSAGE_INFO_DESCR, msg)
    end
return true
end

function dropBonusLoot(items, corpseid, position, members)
local container = doAddContainerItemEx(getTileItemById(position, corpseid).uid, 1988, 1)
    for _, item in pairs(items) do
        doAddContainerItemEx(container, item[1], item[2])
    end
    sendPartyMessage(members, createLootMessage(container))
return true
end

function roll(items, members)
    for i=1, #items do
        local numbers, index, num = {}, 0, 0
        for _, person in pairs(members) do
            table.insert(numbers, {person, math.random(1, 100)})
        end
      
        for z, val in ipairs(numbers) do
            if (val[2] > num) then
                num = val[2]
                index = z
            end
        end
        doPlayerAddItemEx(numbers[index][1], items[1], items[2])
        sendPartyMessage(members, getCreatureName(numbers[index][1]) .. " rolled " .. numbers[index][2] .. " and gained " .. getItemName(items[1]) .. ".")
    end
    return true
end

function createLootMessage(container)
local text = "Party loot bonus: "

    for i=0, getContainerSize(container)-1 do
        local item = getContainerItem(container, i)
        if item ~= nil then
            local info = Item(item.itemid):getType()
            if (item:getType() > 1 and info:isStackable()) then
                text = text .. info:getType() .. " " .. info:getPluralName()
            else
                if (info:getArticle()) then
                    text = text .. info:getArticle() .. " " .. info:getName()
                else
                    text = text .. info:getName()
                end
            end
      
            if (getContainerItem(container, i+1).itemid > 0 ) then
                text = text .. ", "
            else
                text = text .. "."
            end
              
        else
            return text
        end
    end
return text
end

function partyMembersCheck(cid, members)
    for _, person in pairs(members) do
        if(getCreaturePosition(cid):getDistance(getCreaturePosition(person)) > 30) then
            return false
        end
    end
return true
end

function onKill(cid, target, lastHit)
    local corpseid, loot = Monster(target):getType():getCorpseId(), array[getCreatureName(target)]
    if not (loot) or corpseid == nil or not isItemContainer(corpseid) then return true end
  
    if (isInParty(cid)) then
        local members, tab, items = getPartyMembers(cid), 0, {}
        if (partyMembersCheck(cid, members)) then
            if (#members >= table.maxn(loot)) then tab = table.maxn(loot) else tab = #members end
            for i=2, tab do
                if (loot) then
                    for _, it in pairs(loot) do
                        if (it[2] > 1 and not Item(it[1]):getType():isStackable()) then
                            for x=1, it[2] do
                                table.insert(items, {it[1], 1})
                            end
                        else
                            table.insert(items, it)
                        end
                    end
                end
            end
              
            if #items > 0 then
                if (config.rollItems > 0) then
                    roll(items, members)
                else
                    addEvent(dropBonusLoot, 0, items, corpseid, getCreaturePosition(target), members)
                end
            end
        else
            doPlayerSendTextMessage(cid, 27, "Some party members are too far away. Bonus inactive.")
        end
    else
        doPlayerSendTextMessage(cid, 27, "Next time take some people in party to get bonus loot.")
    end
return true
end

I'm sorry you had to wait that long. My code is designed and tested for 0.3.6pl1 version and it's obvious that TFS 1.0 is a little bit different. However, I edited previous code and this one should work. (I haven't tested it so probably it won't work)
 
Hey no problem man! thx for answere, now i get this error:



Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/others/partyboss.lua:onKill
data/creaturescripts/scripts/others/partyboss.lua:91: attempt to call global 'isInParty' (a nil value)
stack traceback:
        [C]: in function 'isInParty'
        data/creaturescripts/scripts/others/partyboss.lua:91: in function <data/creaturescripts/scripts/others/partyboss.lua:87>
 
Code:
local config = {
    rollItems = 1,
}

local array = {
["Example Boss"] = {
    [2] = {{2160, 15}, {2159, 10}, {2472, 2}},
    [3] = {{2453, 1}},
    [4] = {{2493, 2}}
    },
}

function sendPartyMessage(members, msg)
    for _, pid in pairs(members) do
        doPlayerSendTextMessage(pid, MESSAGE_INFO_DESCR, msg)
    end
return true
end

function dropBonusLoot(items, corpseid, position, members)
local container = doAddContainerItemEx(getTileItemById(position, corpseid).uid, 1988, 1)
    for _, item in pairs(items) do
        doAddContainerItemEx(container, item[1], item[2])
    end
    sendPartyMessage(members, createLootMessage(container))
return true
end

function roll(items, members)
    for i=1, #items do
        local numbers, index, num = {}, 0, 0
        for _, person in pairs(members) do
            table.insert(numbers, {person, math.random(1, 100)})
        end
     
        for z, val in ipairs(numbers) do
            if (val[2] > num) then
                num = val[2]
                index = z
            end
        end
        doPlayerAddItemEx(numbers[index][1], items[1], items[2])
        sendPartyMessage(members, getCreatureName(numbers[index][1]) .. " rolled " .. numbers[index][2] .. " and gained " .. getItemName(items[1]) .. ".")
    end
    return true
end

function createLootMessage(container)
local text = "Party loot bonus: "

    for i=0, getContainerSize(container)-1 do
        local item = getContainerItem(container, i)
        if item ~= nil then
            local info = Item(item.itemid):getType()
            if (item:getType() > 1 and info:isStackable()) then
                text = text .. info:getType() .. " " .. info:getPluralName()
            else
                if (info:getArticle()) then
                    text = text .. info:getArticle() .. " " .. info:getName()
                else
                    text = text .. info:getName()
                end
            end
     
            if (getContainerItem(container, i+1).itemid > 0 ) then
                text = text .. ", "
            else
                text = text .. "."
            end
             
        else
            return text
        end
    end
return text
end

function partyMembersCheck(cid, members)
    for _, person in pairs(members) do
        if(getCreaturePosition(cid):getDistance(getCreaturePosition(person)) > 30) then
            return false
        end
    end
return true
end

function onKill(cid, target, lastHit)
    local corpseid, loot = Monster(target):getType():getCorpseId(), array[getCreatureName(target)]
    if not (loot) or corpseid == nil or not isItemContainer(corpseid) then return true end
 
    if (getPlayerParty(cid)) then
        local members, tab, items = getPartyMembers(cid), 0, {}
        if (partyMembersCheck(cid, members)) then
            if (#members >= table.maxn(loot)) then tab = table.maxn(loot) else tab = #members end
            for i=2, tab do
                if (loot) then
                    for _, it in pairs(loot) do
                        if (it[2] > 1 and not Item(it[1]):getType():isStackable()) then
                            for x=1, it[2] do
                                table.insert(items, {it[1], 1})
                            end
                        else
                            table.insert(items, it)
                        end
                    end
                end
            end
             
            if #items > 0 then
                if (config.rollItems > 0) then
                    roll(items, members)
                else
                    addEvent(dropBonusLoot, 0, items, corpseid, getCreaturePosition(target), members)
                end
            end
        else
            doPlayerSendTextMessage(cid, 27, "Some party members are too far away. Bonus inactive.")
        end
    else
        doPlayerSendTextMessage(cid, 27, "Next time take some people in party to get bonus loot.")
    end
return true
end

It's too long for me to check if every function exists in TFS 1.0 :(
 
Even at a party, nothing happens. And I don't even have an error on the console. TFS 1.2 nostalrius
 
Back
Top