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

[LUA] & possibly [C++] requests - Sizaro

Sizaro

Advanced OT User
Joined
Aug 20, 2007
Messages
5,151
Solutions
5
Reaction score
210
Location
Sweden
GitHub
coldensjo
So I've been playing around with a new server of mine for a while now and I need a few things, thought I'd request them.

(If you have a better idea that works the same way please let me know)

[DONE] #1: onLogin add outfit (once) based on gender and vocation.
Thanks Ninja
Heres the code:

data\creaturescripts\Actions.xml
Code:
    <event type="login" name="FirstOutfit" script="firstoutfit.lua"/>

data\creaturescripts\scripts\firstoutfit.lua
Code:
local config = {
[1] = {female = 575, male = 574},
[2] = {female = 269, male = 268},
[3] = {female = 142, male = 134},
[4] = {female = 138, male = 130},
[5] = {female = 148, male = 144},
[6] = {female = 137, male = 129}
}

function onLogin(cid)
local player = Player(cid)
local targetVocation = config[player:getVocation():getBase():getId()]
if not targetVocation then
return true
end

if player:hasOutfit(player:getSex() == 0 and targetVocation.female or targetVocation.male) then
return true
end

player:addOutfit(targetVocation.female)
player:addOutfit(targetVocation.male)
return true
end

\data\global or compat.lua
bottom add:

Code:
add this to your global/compat.lua, credits goes to dalkon
function Vocation.getBase(self)
local demotion = self:getDemotion()
while demotion do
local tmp = demotion:getDemotion()
if not tmp then
return demotion
end
demotion = tmp
end
return self
end



[DONE] #2: Dual-Wielding daggers (Swords)

Thanks hakeee

IHgvn3a.png


[DONE] #3: Teleport to house exit function StepIn.
Thanks Ninja
Heres the code:

data\movements\movements.xml
Code:
<movevent event="StepIn" actionid="x" script="houseTeleport.lua" />

data\movements\scripts\houseTeleport.lua
Code:
function onStepIn(cid, item, position, fromPosition)
local player = Player(cid)
if not player then
return true
end

local house = player:getHouse()
if not house then
player:teleportTo(fromPosition, true)
fromPosition:sendMagicEffect(CONST_ME_TELEPORT)
return true
end

player:teleportTo(house:getExitPosition())
player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
return true
end

[DONE] #3: Summons following you
XML:
<talkaction words="utevo res" separator=" " script="summonmonster.lua" />
Lua:
local summonables = {
    'Rat',
    'Bat',
    'Cat'
}
local sum = {}
for _, mon in pairs(summonables) do -- LOWERCASE ALL MONSTER NAMES FOR COMPARISON WITH PARAMETER
    table.insert(sum,mon:lower())
end
function onSay(player, words, param)
    local name = param:match('%a+')
    if not name then
        player:sendCancelMessage('Invalid parameters.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if #player:getSummons() > 1 then
        player:sendCancelMessage('You cannot summon any more creatures.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if not isInArray(sum,name:lower()) then
        player:sendCancelMessage('You cannot summon this monster.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    local monster = Game.createMonster(name, player:getPosition())
    if not monster then
        player:sendCancelMessage('There is not enough room.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    monster:setMaster(player)
    monster:registerEvent('summonfollow')
    return false
end
and then in creaturescripts.xml
XML:
<event type="think" name="summonfollow" script="summonfollow.lua" />
and in summonfollow.lua
Lua:
function onThink(cid, interval)
    local cpos = cid:getPosition()
    local ppos = cid:getMaster():getPosition()
    if cpos.z ~= ppos.z or math.abs(cpos.x - ppos.x) > 8 or math.abs(cpos.y - ppos.y) > 6 then
        cid:teleportTo(ppos)
    end
    return true
end
don't forget to remove utevo res from spells.xml
 
Last edited:
Solution
It's probably best done in source code but I reckon you could handle all that in LUA
Ok so, if you handle utevo res as a talk action like this
XML:
<talkaction words="utevo res" separator=" " script="summonmonster.lua" />
Lua:
local summonables = {
    'Rat',
    'Bat',
    'Cat'
}
local sum = {}
for _, mon in pairs(summonables) do -- LOWERCASE ALL MONSTER NAMES FOR COMPARISON WITH PARAMETER
    table.insert(sum,mon:lower())
end
function onSay(player, words, param)
    local name = param:match('%a+')
    if not name then
        player:sendCancelMessage('Invalid parameters.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if #player:getSummons() > 1 then
        player:sendCancelMessage('You...
So I want to make summons teleport to you when you walk too far away and kills from them should give normal (100%) exp, but I'm guessing this is done in source code?
Code:
<instant group="support" spellid="9" name="Summon Creature" words="utevo_res" lvl="25" params="1" exhaustion="2000" groupcooldown="2000" needlearn="0" function="summonMonster">
        <vocation name="Sorcerer" />
        <vocation name="Druid" />
    </instant>

Using latest TFS 10.98
 
Last edited:
It's probably best done in source code but I reckon you could handle all that in LUA
Ok so, if you handle utevo res as a talk action like this
XML:
<talkaction words="utevo res" separator=" " script="summonmonster.lua" />
Lua:
local summonables = {
    'Rat',
    'Bat',
    'Cat'
}
local sum = {}
for _, mon in pairs(summonables) do -- LOWERCASE ALL MONSTER NAMES FOR COMPARISON WITH PARAMETER
    table.insert(sum,mon:lower())
end
function onSay(player, words, param)
    local name = param:match('%a+')
    if not name then
        player:sendCancelMessage('Invalid parameters.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if #player:getSummons() > 1 then
        player:sendCancelMessage('You cannot summon any more creatures.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if not isInArray(sum,name:lower()) then
        player:sendCancelMessage('You cannot summon this monster.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    local monster = Game.createMonster(name, player:getPosition())
    if not monster then
        player:sendCancelMessage('There is not enough room.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    monster:setMaster(player)
    monster:registerEvent('summonfollow')
    return false
end
and then in creaturescripts.xml
XML:
<event type="think" name="summonfollow" script="summonfollow.lua" />
and in summonfollow.lua
Lua:
function onThink(cid, interval)
    local cpos = cid:getPosition()
    local ppos = cid:getMaster():getPosition()
    if cpos.z ~= ppos.z or math.abs(cpos.x - ppos.x) > 8 or math.abs(cpos.y - ppos.y) > 6 then
        cid:teleportTo(ppos)
    end
    return true
end
then your monster will follow you up and down stairs 'nd shit
don't forget to remove utevo res from spells.xml
as regards to experience gain, onKill() doesn't give us the experience amount
There is onGainExperience() in events but I believe it only runs for players
 
Last edited:
Solution
Really nice. And how do I do the following things;
  • Mana cost for summoning.
  • Level requirement for summoning
  • Summon despawn in protection zone
When I attempted to summon Apocalypse, it didn't like me and started to attack me even though I summoned him ...
CRA0OVi.png

OXiBCZR.png


:(

legubHB.png


Also, how do I make it possible to walk through players / summons like in RL Tibia? Isn't this system in OT yet?
 
Last edited:
lol well I don't know why apocalypse didn't like you maybe its because has flag summonable = 0 in creature xml?
here is updated script for manacost and level req
Lua:
--------- CONFIG ------
local summonables = {
    ['Rat'] = {mana = 60, level = 10}, -- rat costs 60 mana and you must be level 10 to summon
    ['Bat'] = {mana = 80}, -- bat no minimum level
    ['Cat'] = {level = 8} -- free cats
}
------------------------
local names, manas, levels = {}, {}, {}
for i, mon in pairs(summonables) do -- LOWERCASE ALL MONSTER NAMES FOR COMPARISON WITH PARAMETER
    table.insert(names,1,i:lower())
    table.insert(manas,1,mon.mana or 0)
    table.insert(levels,1,mon.level or 0)
end
function onSay(player, words, param)
    local name = param:match('%a+')
    local index = 0
    if not name then
        player:sendCancelMessage('Invalid parameters.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    for i, n in ipairs(names) do
        if name:lower() == n:lower() then
            index = i
        end
    end
    if index == 0 then
        player:sendCancelMessage('You cannot summon this monster.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if #player:getSummons() > 1 then
        player:sendCancelMessage('You cannot summon any more creatures.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if levels[index] > player:getLevel() then
        player:sendCancelMessage('You do not have enough level.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if manas[index] > player:getMana() then
        player:sendCancelMessage('You do not have enough mana.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    local monster = Game.createMonster(name, player:getPosition())
    if not monster then
        player:sendCancelMessage('There is not enough room.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    player:addMana(-manas[index])
    player:addManaSpent(manas[index] * configManager.getNumber(configKeys.RATE_MAGIC))
    monster:setMaster(player)
    monster:registerEvent('summonfollow')
    return false
end
and for despawn in pz put this
Lua:
function onThink(cid, interval)
    local cpos = cid:getPosition()
    local ppos = cid:getMaster():getPosition()
    if cpos.z ~= ppos.z or math.abs(cpos.x - ppos.x) > 8 or math.abs(cpos.y - ppos.y) > 6 then
        cid:teleportTo(ppos)
    end
    if Tile(ppos):hasFlag(TILESTATE_PROTECTIONZONE) then
        cpos:sendMagicEffect(CONST_ME_POFF)
        cid:remove()
    end
    return true
end
as for the console errors, the onThink event is running because of this line
Lua:
monster:registerEvent('summonfollow')
you get errors because of this line:
Lua:
local ppos = cid:getMaster():getPosition()
the apocalypse did not have a master, which means either you removed this line
Lua:
monster:setMaster(player)
or it did not work properly
I am 99.999999999999999999999999% sure that walking through players will require source and 99.999999999999999999999999999999999999999999999999999999% sure that it is easier than doing it in lua, if it possible
 
Last edited:
Well I guess the talkaction can summon unsummonable monsters but it can't set them as master :p

Full list if anyone want it:
Lua:
    ['Skunk'] = {level = 25, mana = 200},
    ['Rat'] = {level = 25, mana = 200},
    ['Badger'] = {level = 25, mana = 200},
    ['Snake'] = {level = 25, mana = 205},
    ['Spider'] = {level = 25, mana = 210},
    ['Chicken'] = {level = 25, mana = 220},
    ['Rabbit'] = {level = 25, mana = 220},
    ['Silver Rabbit'] = {level = 25, mana = 220},
    ['Cat'] = {level = 25, mana = 220},
    ['Dog'] = {level = 25, mana = 220},
    ['Poodle'] = {level = 25, mana = 220},
    ['Squirrel'] = {level = 25, mana = 220},
    ['Enraged Squirrel'] = {level = 25, mana = 220},
    ['Thieving Squirrel'] = {level = 25, mana = 220},
    ['Black Sheep'] = {level = 25, mana = 250},
    ['Flamingo'] = {level = 25, mana = 250},
    ['Green Frog'] = {level = 25, mana = 250},
    ['Parrot'] = {level = 25, mana = 250},
    ['Seagull'] = {level = 25, mana = 250},
    ['Bat'] = {level = 25, mana = 250},
    ['Cave Rat'] = {level = 25, mana = 250},
    ['Bug'] = {level = 25, mana = 250},
    ['Sandcrawler'] = {level = 25, mana = 250},
    ['Pig'] = {level = 25, mana = 255},
    ['Wolf'] = {level = 25, mana = 255},
    ['Deer'] = {level = 25, mana = 260},
    ['Winter Wolf'] = {level = 25, mana = 260},
    ['Poison Spider'] = {level = 25, mana = 270},
    ['Hyaena'] = {level = 25, mana = 275},
    ['Cobra'] = {level = 25, mana = 275},
    ['Wasp'] = {level = 25, mana = 280},
    ['Penguin'] = {level = 25, mana = 290},
    ['Island Troll'] = {level = 25, mana = 290},
    ['Troll'] = {level = 25, mana = 290},
    ['Goblin'] = {level = 25, mana = 300},
    ['Goblin Leader'] = {level = 25, mana = 300},
    ['Frost Troll'] = {level = 25, mana = 300},
    ['Bear'] = {level = 25, mana = 300},
    ['Panda'] = {level = 25, mana = 300},
    ['Orc'] = {level = 25, mana = 300},
    ['Skeleton'] = {level = 25, mana = 300},
    ['Crazed Beggar'] = {level = 25, mana = 300},
    ['Crab'] = {level = 25, mana = 305},
    ['Orc Spearman'] = {level = 25, mana = 310},
    ['Scorpion'] = {level = 25, mana = 310},
    ['Polar Bear'] = {level = 25, mana = 315},
    ['Swamp Troll'] = {level = 25, mana = 320},
    ['Lion'] = {level = 25, mana = 320},
    ['Dwarf'] = {level = 25, mana = 320},
    ['Minotaur'] = {level = 25, mana = 330},
    ['Centipede'] = {level = 25, mana = 335},
    ['Troll Champion'] = {level = 25, mana = 350},
    ['Crocodile'] = {level = 25, mana = 350},
    ['Skeleton Warrior'] = {level = 25, mana = 350},
    ['Larva'] = {level = 25, mana = 355},
    ['Orc Warrior'] = {level = 25, mana = 360},
    ['Dwarf Soldier'] = {level = 25, mana = 360},
    ['Smuggler'] = {level = 25, mana = 390},
    ['Amazon'] = {level = 25, mana = 390},
    ['Minotaur Archer'] = {level = 25, mana = 390},
    ['Scarab'] = {level = 25, mana = 395},
    ['Toad'] = {level = 25, mana = 400},
    ['Husky'] = {level = 25, mana = 420},
    ['Tiger'] = {level = 25, mana = 420},
    ['Rabbit'] = {level = 25, mana = 420},
    ['Dwarf Miner'] = {level = 25, mana = 420},
    ['Wild Warrior'] = {level = 25, mana = 420},
    ['Nomad'] = {level = 25, mana = 420},
    ['Undead Mine Worker'] = {level = 25, mana = 435},
    ['Bandit'] = {level = 25, mana = 450},
    ['Ghoul'] = {level = 25, mana = 450},
    ['Valkyrie'] = {level = 25, mana = 450},
    ['Tarantula'] = {level = 25, mana = 485},
    ['Cyclops'] = {level = 25, mana = 490},
    ['Frost Giantess'] = {level = 25, mana = 490},
    ['Terror Bird'] = {level = 25, mana = 490},
    ['Elephant'] = {level = 25, mana = 500},
    ['Blood Crab'] = {level = 25, mana = 505},
    ['Fire DEvil'] = {level = 25, mana = 530},
    ['Minotaur Guard'] = {level = 26, mana = 550},
    ['Stone Golem'] = {level = 27, mana = 590},
    ['Orc Berserker'] = {level = 27, mana = 590},
    ['Monk'] = {level = 27, mana = 600},
    ['Demon Skeleton'] = {level = 28, mana = 620},
    ['Orc Leader'] = {level = 29, mana = 640},
    ['Dwarf Guard'] = {level = 29, mana = 650},
    ['Fire ELemental'] = {level = 30, mana = 690},
    ['Gozzler'] = {level = 34, mana = 800}
}

So I just tried it again with summonable monsters and

Afw13wm.png

pVf2EwB.png


It worked fine with rats and cats :S

Rr2Q65r.png
 
Last edited by a moderator:
So I just tried it again with summonable monsters and

Afw13wm.png

pVf2EwB.png


It worked fine with rats and cats :S

Rr2Q65r.png
It worked fine with rats and cats :S
spat my drink out..
for now, put
Lua:
function onThink(cid, interval)
    local cpos = cid:getPosition()
    if not cid:getMaster() then
     print('ERROR:'..cid:getName()..' removed at '..cpos.x..' '..cpos.y..' '..cpos.z..' for having no master')
      cid:remove()
      return true
    end
    local ppos = cid:getMaster():getPosition()
    if cpos.z ~= ppos.z or math.abs(cpos.x - ppos.x) > 8 or math.abs(cpos.y - ppos.y) > 6 then
        cid:teleportTo(ppos)
    end
    if Tile(ppos):hasFlag(TILESTATE_PROTECTIONZONE) then
        cpos:sendMagicEffect(CONST_ME_POFF)
        cid:remove()
    end
    return true
end
Right now I am just about to leave the house, I will look at it later
 
lol well I don't know why apocalypse didn't like you maybe its because has flag summonable = 0 in creature xml?
here is updated script for manacost and level req
Lua:
--------- CONFIG ------
local summonables = {
    ['Rat'] = {mana = 60, level = 10}, -- rat costs 60 mana and you must be level 10 to summon
    ['Bat'] = {mana = 80}, -- bat no minimum level
    ['Cat'] = {level = 8} -- free cats
}
------------------------
local names, manas, levels = {}, {}, {}
for i, mon in pairs(summonables) do -- LOWERCASE ALL MONSTER NAMES FOR COMPARISON WITH PARAMETER
    table.insert(names,1,i:lower())
    table.insert(manas,1,mon.mana or 0)
    table.insert(levels,1,mon.level or 0)
end
function onSay(player, words, param)
    local name = param:match('%a+')
    local index = 0
    if not name then
        player:sendCancelMessage('Invalid parameters.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    for i, n in ipairs(names) do
        if name:lower() == n:lower() then
            index = i
        end
    end
    if index == 0 then
        player:sendCancelMessage('You cannot summon this monster.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if #player:getSummons() > 1 then
        player:sendCancelMessage('You cannot summon any more creatures.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if levels[index] > player:getLevel() then
        player:sendCancelMessage('You do not have enough level.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    if manas[index] > player:getMana() then
        player:sendCancelMessage('You do not have enough mana.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    local monster = Game.createMonster(name, player:getPosition())
    if not monster then
        player:sendCancelMessage('There is not enough room.')
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end
    player:addMana(-manas[index])
    player:addManaSpent(manas[index] * configManager.getNumber(configKeys.RATE_MAGIC))
    monster:setMaster(player)
    monster:registerEvent('summonfollow')
    return false
end
and for despawn in pz put this
Lua:
function onThink(cid, interval)
    local cpos = cid:getPosition()
    local ppos = cid:getMaster():getPosition()
    if cpos.z ~= ppos.z or math.abs(cpos.x - ppos.x) > 8 or math.abs(cpos.y - ppos.y) > 6 then
        cid:teleportTo(ppos)
    end
    if Tile(ppos):hasFlag(TILESTATE_PROTECTIONZONE) then
        cpos:sendMagicEffect(CONST_ME_POFF)
        cid:remove()
    end
    return true
end
as for the console errors, the onThink event is running because of this line
Lua:
monster:registerEvent('summonfollow')
you get errors because of this line:
Lua:
local ppos = cid:getMaster():getPosition()
the apocalypse did not have a master, which means either you removed this line
Lua:
monster:setMaster(player)
or it did not work properly
I am 99.999999999999999999999999% sure that walking through players will require source and 99.999999999999999999999999999999999999999999999999999999% sure that it is easier than doing it in lua, if it possible

Why you doing twice str:lower()? :p
Code:
if name:lower() == n:lower() then

You did it already in top of your script.
 
Monster must be convinceable, if you want to set a master.
This ^

Literally just tried this before you posted and yes this is why.

Also; I cannot summon creatures with 2 word names. Demon Skeleton, Fire Devil and Fire Elemental for example.
 
Why you doing twice str:lower()? :p
Code:
if name:lower() == n:lower() then

You did it already in top of your script.
idk just to be sure :p
Monster must be convinceable, if you want to set a master.
good information
This ^

Literally just tried this before you posted and yes this is why.

Also; I cannot summon creatures with 2 word names. Demon Skeleton, Fire Devil and Fire Elemental for example.
I am sorry, change line:
Lua:
local name = param:match('%a+')
for
Lua:
local name = param:match('%P+')
 
I'm trying to compile a fork of tfs and I'm getting this error. I'm a newbie at visual basic / C++ so I only have general knowledge about what I'm doing. I'm guessing there something wrong with boost?
I have latest version of visual basic + boost 1.6.3
Code:
1>connection.obj : error LNK2001: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::system_category(void)" (?system_category@system@boost@@YAAEBVerror_category@12@XZ)
1>otpch.obj : error LNK2001: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::generic_category(void)" (?generic_category@system@boost@@YAAEBVerror_category@12@XZ)
 
Last edited:
I'm trying to compile a fork of tfs and I'm getting this error. I'm a newbie at visual basic / C++ so I only have general knowledge about what I'm doing. I'm guessing there something wrong with boost?
I have latest version of visual basic + boost 1.6.3
Code:
1>connection.obj : error LNK2001: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::system_category(void)" (?system_category@system@boost@@YAAEBVerror_category@12@XZ)
1>otpch.obj : error LNK2001: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::generic_category(void)" (?generic_category@system@boost@@YAAEBVerror_category@12@XZ)
Probably you didnt link the boost libs to tfs or didnt link them correctly.
 
Anyone willing to add me on Skype and answer my scripting questions?

Also, is it possible to write a talkaction that clears the console?

Like so
/clearconsole
ghVO7bh.png
 
Last edited by a moderator:
Where is the default "walkradius" defined? Couldn't find it anywhere in the NPCSystem files. My NPCS sometimes walk far from the initial spawn point. I recall them only being able to walk inside the spawn radius created by RME before?
 
This simple script is not working for me and I have no clue why.

Map >>
5hkiypc.png


Ingame >>
jvxHpTK.png


It's litterally a direct copy of any real map server out there.

XML:
<action actionid="2023" script="quests/pits of inferno/goshnar.lua" />

Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if target.actionid ~= 2023 then
        print "1"
        return false
    end

    if not Tile(toPosition):getItemById(2016, 2) then
        print "2"
        return true
    end
    print "3"
    toPosition.z = toPosition.z + 1
    player:teleportTo(toPosition)
    toPosition:sendMagicEffect(CONST_ME_TELEPORT)
    return true
end

9KZSFzE.png
 
other/fluids.lua

Code:
local function graveStoneTeleport(cid, fromPosition, toPosition)
    local player = Player(cid)
    if not player then
        return true
    end

    player:teleportTo(toPosition)
    player:say('Muahahahaha..', TALKTYPE_MONSTER_SAY, false, player)
    fromPosition:sendMagicEffect(CONST_ME_DRAWBLOOD)
    toPosition:sendMagicEffect(CONST_ME_MORTAREA)
end
 
t0cFS6j.jpg


@Aled
o3KxKkw.png


XML:
  <event type="login" name="rarelootlogin" script="loot.lua" />
    <event type="kill" name="rarelootkill" script="loot.lua" />
    <event type="death" name="rarelootdeath" script="loot.lua" />

Lua:
local effect = CONST_ME_TUTORIALARROW -- magic effect
local chance = 2 -- magic effect for item that drops less than 5% of the time

function onLogin(player)
    player:registerEvent('rarelootkill')
    return true
end

function onKill(player, target)
    if target:isMonster() then target:registerEvent('rarelootdeath') end
    return true
end

function getContainerItemIds(container)
    t = {}
    if not container then return t end
    for i = container:getSize()-1, 1, -1 do
        table.insert(t,container:getItem(i):getId())
    end
    return t
end

function hasItemById(container,itemid)
    if not itemid or not container then return false end
    if isInArray(getContainerItemIds(container),itemid) then return true end
    return false
end

function onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
    if not creature then return true end
    local loot = creature:getType():getLoot()
    if not loot then return true end
    local totalchance = 0
    for i, k in pairs(loot) do
        totalchance = totalchance + k.chance
    end
    addEvent(function()
        for i, k in pairs(loot) do
            if not corpse or not killer then
                return
            end
            if hasItemById(corpse,k.itemId) and k.chance/totalchance < chance/100  then
                corpse:getPosition():sendMagicEffect(effect)
                killer:sendTextMessage(MESSAGE_STATUS_DEFAULT, "You looted a "..ItemType(k.itemId):getName().."!")
            end
        end
    end,1)
    return true
end
 
Last edited by a moderator:
It happens when you kill a summon (has no loot), I didn't think about this when I wrote it
I fixed mine by only registering the event to a creature with no master
Lua:
function onKill(player, target)
    if target:isMonster() then
        if not target:getMaster() then
            target:registerEvent('rarelootdeath')
        end
    end
    return true
end
you could also fix it like this
Lua:
function getContainerItemIds(container)
    t = {}
    if not container then return t end
    if not container:getSize() then return t end
    for i = container:getSize()-1, 1, -1 do
        table.insert(t,container:getItem(i):getId())
    end
    return t
end
I believe
not sure how isInArray behaves with an empty table..
 
Back
Top