• 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 Blue Arrow when drop item rare

Carlitos Flow

Developer (lvl*1)
Joined
Mar 2, 2011
Messages
156
Solutions
4
Reaction score
10
Hello, im trying to add the magic effect #55 when x player drops x item (like an item rare) from a corpse of monster, its not working, anyone can help me please? Thanks (already registed in login)
-(Arrow effect appear on the corpse from the monster)
I was testing with print console and only prints number 0 and 1

Lua:
local effect = 55                             
local arrow = {55, 60}                     --Effect and seconds.

function isRare(itemid)
local items = {5897, 2666, 3976}          --IDs from items
 return isInArray(ids, itemid)
end

function sendEffect(pos, time)
    if time < 0 then
        return true
    end
    doSendMagicEffect(pos, arrow[1])
    addEvent(sendEffect, 1000, pos, time - 1)
end
local function func(cid, position, corpseid, effect)
    print(1)
    if not isCreature(cid) then return true end
    local corpse = getTileItemById(position, corpseid).uid
    if corpse <= 1 then return end
    if not isContainer(corpse) then return true end
    for slot = 0, (getContainerSize(corpse)-1) do
        local item = getContainerItem(corpse, slot)
        if item.uid <= 1 then return end
        if isRare(item.itemid) then
            print(2)
            return doSendMagicEffect(position, effect)
        end
    end
end
function onKill(cid, target, lastHit)

    print(0)
    if not isMonster(target) then return true end
    local corpse = getMonsterInfo(getCreatureName(target)).lookCorpse

    addEvent(func, 5, getCreatureSummons(cid)[1], getThingPos(target), corpse, effect)
    return true
end
 
Solution
Lua:
local rare_items = {5897}
local effect = CONST_ME_TUTORIALARROW
local timer = 5

local function countdown(pos, timer)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 6500, pos, timer - 1)
end

local function scanContainer(uid, pos)
    for i = getContainerSize(uid) - 1, 0, -1 do
        local item = getContainerItem(uid, i)
        if isContainer(item.uid) then
            scanContainer(item.uid, pos)
        else
            if isInArray(rare_items, item.itemid) then
                doSendMagicEffect(pos, effect)
                addEvent(countdown, 6500, pos, timer)
            end
        end
    end
end

local function scanCorpse(pos, corpseId)
    local corpse =...
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

function onDeath(cid, corpse, deathList, lastHitKiller, mostDamageKiller)
   local rare_items = {5897, 2666, 3976}
   local effect = 55
   local timer = 60
   if isMonster(cid) then
       if isContainer(corpse.uid) then
           for i = 1, getContainerSize(corpse.uid) do
               if isInArray(getContainerItem(corpse.uid, i), rare_items) then
                   doSendMagicEffect(getCreaturePosition(cid), effect)
                   addEvent(countdown, 1000, getCreaturePosition(cid), timer, effect)
                   return true
               end
           end
       end
   end
   return true
end
Also you need to create a creaturescipt onKill which registring event to monster onDeath.
 
Last edited:
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

function onDeath(cid, corpse, deathList, lastHitKiller, mostDamageKiller)
   local rare_items = {5897, 2666, 3976}
   local effect = 55
   local timer = 60
   if isMonster(cid) then
       if isContainer(corpse.uid) then
           for i = 1, getContainerSize(corpse.uid) do
               if isInArray(getContainerItem(corpse.uid, i), rare_items) then
                   doSendMagicEffect(getCreaturePosition(cid), effect)
                   addEvent(countdown, 1000, getCreaturePosition(cid), timer, effect)
                   return true
               end
           end
       end
   end
   return true
end
Also you need to create a creaturescipt onKill which registring event to monster onDeath.
I don't understand, why the script is onDeath? and how i create a creaturescipt onKill which registring event to monster onDeath?
Using dofile..?
 
no, you should convert that to an onKill script, since applying onDeath to every creature through script tags in the monster xml would be redundant
use an onKill script and search the corpse body, checking for specific item ids you count as "rare", and then send the magic effect
 
no, you should convert that to an onKill script, since applying onDeath to every creature through script tags in the monster xml would be redundant
use an onKill script and search the corpse body, checking for specific item ids you count as "rare", and then send the magic effect
Hmm maybe... I will try, BUMP...
 
#Edit
Just only script onKill:
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
   addEvent(countdown, 1000, pos, timer - 1, effect)
end
function onKill(cid, target, lastHit)
   local rare_items = {5897, 2666, 3976}
   local effect = 55
   local timer = 60
   local idc, pos, corpse = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target), getTileItemById(pos, idc).uid
   if isMonster(target) then
       if isContainer(corpse) then
           for i = 1, getContainerSize(corpse) do
               if isInArray(getContainerItem(corpse, i).itemid, rare_items) then
                   doSendMagicEffect(pos, effect)
                   addEvent(countdown, 1000, pos, timer, effect)
                   return true
               end
           end
       end
   end
   return true
end
 
Last edited:
#Edit
Just only script onKill:
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
   addEvent(countdown, 1000, pos, timer - 1, effect)
end
function onKill(cid, target, lastHit)
   local rare_items = {5897, 2666, 3976}
   local effect = 55
   local timer = 60
   local idc, pos, corpse = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target), getTileItemById(pos, idc).uid
   if isMonster(target) then
       if isContainer(corpse) then
           for i = 1, getContainerSize(corpse) do
               if isInArray(getContainerItem(corpse, i).itemid, rare_items) then
                   doSendMagicEffect(pos, effect)
                   addEvent(countdown, 1000, pos, timer, effect)
                   return true
               end
           end
       end
   end
   return true
end
Error:
C: in function 'getTileItemById' attempt to index a nil value
 
Error:
C: in function 'getTileItemById' attempt to index a nil value

You can't use idc and pos in the same variable scope as corpse = nil value, it dosn't exist yet.
If you wanna avoid it in the future just write them out on another line, no reason to make everything 1 liners.

There is also no reason to have the rare_items, effect and timer in the function scope since they won't change each time the function is executed.

Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897, 2666, 3976}
local effect = CONST_ME_PLANTATTACK
local timer = 60

function onKill(cid, target, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target)
    local corpse = getTileItemById(pos, idc).uid

    if isMonster(target) then
        if isContainer(corpse) then
            for i = 1, getContainerSize(corpse) do
                if isInArray(getContainerItem(corpse, i).itemid, rare_items) then
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end

    return true
end
 
You can't use idc and pos in the same variable scope as corpse = nil value, it dosn't exist yet.
If you wanna avoid it in the future just write them out on another line, no reason to make everything 1 liners.

There is also no reason to have the rare_items, effect and timer in the function scope since they won't change each time the function is executed.

Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897, 2666, 3976}
local effect = CONST_ME_PLANTATTACK
local timer = 60

function onKill(cid, target, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target)
    local corpse = getTileItemById(pos, idc).uid

    if isMonster(target) then
        if isContainer(corpse) then
            for i = 1, getContainerSize(corpse) do
                if isInArray(getContainerItem(corpse, i).itemid, rare_items) then
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end

    return true
end
Doesn't work, no errors on console :/ Bump!
 
Add a couple of prints before and after if statments to see if the code is executed and where it stops
Lua:
print("1")
Just change 1 to 2 and so on for the next if statments

Only print (1) when i kill 1x1 and sometimes when i kill like 8 monsters with a UE Print 1, 2 and 3. It don't print the number 4.
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897}
local effect = CONST_ME_TUTORIALARROW
local timer = 60

function onKill(cid, target, corpse, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target)
    local corpse = getTileItemById(pos, idc).uid

    if isMonster(target) then
    print("1")
        if isContainer(corpse) then
        print("2")
            for i = 1, getContainerSize(corpse) do
            print("3")
                if isInArray(getContainerItem(corpse, i).itemid, rare_items) then
                print("4")
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end
    return true
end
 
Only print (1) when i kill 1x1 and sometimes when i kill like 8 monsters with a UE Print 1, 2 and 3. It don't print the number 4.
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897}
local effect = CONST_ME_TUTORIALARROW
local timer = 60

function onKill(cid, target, corpse, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target)
    local corpse = getTileItemById(pos, idc).uid

    if isMonster(target) then
    print("1")
        if isContainer(corpse) then
        print("2")
            for i = 1, getContainerSize(corpse) do
            print("3")
                if isInArray(getContainerItem(corpse, i).itemid, rare_items) then
                print("4")
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end
    return true
end

Okay well print out pos, idc and corpse to see if something is nil there, also check if the monsters you kill actually have the loot (5897)
If it's going to 3 then it's the loot that is the problem, if it's not printing 2 then the corpse dosn't exist on that position (maybe not yet, try using an addEvent function to see if the server has registerd the corpse yet.
 
Your isInArray call is wrong. You need to swap arguments, the first one is the array, the second is what you look for: isInArray(haystack, needle)
 
Only print (1) when i kill 1x1
I guess it's because you are calling tile item from target's position, wich means that target still exists and doesn't have a corpse when script is executed.
On your second try, some monsters had to stand on some older corpses, so script passed it trough container check.
 
By swapping arguments of this call. Change this:
Lua:
isInArray(getContainerItem(corpse, i).itemid, rare_items)
into this:
Lua:
isInArray(rare_items, getContainerItem(corpse, i).itemid)
Doesn't works :/ also:

Okay well print out pos, idc and corpse to see if something is nil there, also check if the monsters you kill actually have the loot (5897)
If it's going to 3 then it's the loot that is the problem, if it's not printing 2 then the corpse dosn't exist on that position (maybe not yet, try using an addEvent function to see if the server has registerd the corpse yet.
Guys this is my script now, it print 1,2,3,5,6... it doesn't prints the number 4
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897}
local effect = CONST_ME_TUTORIALARROW
local timer = 60

function onKill(cid, target, corpse, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target) print("5")
    local corpse = getTileItemById(pos, idc).uid print("6")

    if isMonster(target) then
    print("1")
        if isContainer(corpse) then
        print("2")
            for i = 1, getContainerSize(corpse) do
            print("3")
                if isInArray(rare_items, getContainerItem(corpse, i).itemid) then
                print("4")
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end
    return true
end
 
here you go dad
indexing starts at 0, not 1 (the loop was incorrect, skipping index 0)
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897}
local effect = CONST_ME_TUTORIALARROW
local timer = 60

function onKill(cid, target, corpse, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target)
    local corpse = getTileItemById(pos, idc).uid

    if isMonster(target) then
        if isContainer(corpse) then
            for i = getContainerSize(corpse)-1, 0, -1 do
                if isInArray(rare_items, getContainerItem(corpse, i).itemid) then
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end
    return true
end
 
here you go dad
indexing starts at 0, not 1 (the loop was incorrect, skipping index 0)
Lua:
function countdown(pos, timer, effect)
    if timer < 0 then
        return true
    end
    doSendMagicEffect(pos, effect)
    addEvent(countdown, 1000, pos, timer - 1, effect)
end

local rare_items = {5897}
local effect = CONST_ME_TUTORIALARROW
local timer = 60

function onKill(cid, target, corpse, lastHit)
    local idc, pos = getMonsterInfo(getCreatureName(target)).lookCorpse, getCreaturePosition(target)
    local corpse = getTileItemById(pos, idc).uid

    if isMonster(target) then
        if isContainer(corpse) then
            for i = getContainerSize(corpse)-1, 0, -1 do
                if isInArray(rare_items, getContainerItem(corpse, i).itemid) then
                    doSendMagicEffect(pos, effect)
                    addEvent(countdown, 1000, pos, timer, effect)
                    return true
                end
            end
        end
    end
    return true
end
Little bug. Look bro, the item 5897 is the wolf paw, when a wolf drops 1 wolf paw, don't show the effect, only if have other corpse inside of which drops the wolf paw. (you need kill other wolf on the same position of the corpse who drop the item to show the effect)
 
Last edited:
Back
Top