• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Lua CreatureScript executes multiple times

Snavy

Bakasta
Senator
Joined
Apr 1, 2012
Messages
1,250
Solutions
71
Reaction score
632
GitHub
idontreallywolf
Iam trying to build zombie event system on my own, learning while doing.. however...
I have managed to write the script where players who get attacked by zombies get kicked out of the arena.
BUT ... the problem is that it seems as if the script was running multiple times. Im not sure what the cause is.

CONSOLE OUTPUT:
Code:
Pleb kicked out! 
Pleb  kicked out! 
Flip Flop kicked out! 
Player Plebinator won zombie event! 
Flip Flop kicked out! 
Player Plebinator won zombie event!

SCRIPT
LUA:
Z_ARENA_TOP_LEFT = {x = 1006, y = 791, z = 7}
Z_ARENA_BOTTOM_RIGHT = {x = 1033, y = 814, z = 7}

function onCombat(cid, target)
    local counter = 0
    local players = {}
    local temple = {x=1006, y=998, z=7}

    -- Teleport Player to temple when attacked by zombie
    if(isMonster(cid) and getCreatureName(cid):lower() == "zombie") then
        if(isPlayer(target)) then
            doTeleportThing(target, temple)
            doSendMagicEffect(temple, 43)
            print(getPlayerName(target) .. " kicked out!")
        end
    end

    -- Scan arena for players left
    for posy = Z_ARENA_TOP_LEFT.y, Z_ARENA_BOTTOM_RIGHT.y do
        for posx = Z_ARENA_TOP_LEFT.x, Z_ARENA_BOTTOM_RIGHT.x do
            if isPlayer(getTopCreature({x=posx, y=posy, z=7}).uid) then
                counter = counter+1
                table.insert(players, getTopCreature({x=posx, y=posy, z=7}).uid)
            end
        end
    end

    if counter == 1 then
        doTeleportThing(players[1], temple)
        print("Player "..getPlayerName(players[1]).." won zombie event!")
    end

    counter = 0
    players = {}
    return true
end
 
Solution
It's probably calling when they attack the player, and also when they lose focus of the player.

Maybe make the zombies do like 1000 water damage or something, so the damage triggers, and put it through onStatsChange, and simply return the damage as false to the player.

Also for checking the area for zombie event, checking every single tile for players/monsters
Do a check for players online, and check the player position to see if it's inside the arena, count the amount of players inside the arena and , not including the person who was hit by the attack, if only 1 person is inside arena positions, then they are the winner.

pseudo code
Code:
function onStatsChange(cid, target, blah, blah2, blah3)
    local last_known_cid = 0
    local...
Iam trying to build zombie event system on my own, learning while doing.. however...
I have managed to write the script where players who get attacked by zombies get kicked out of the arena.
BUT ... the problem is that it seems as if the script was running multiple times. Im not sure what the cause is.

CONSOLE OUTPUT:
Code:
Pleb kicked out!
Pleb  kicked out!
Flip Flop kicked out!
Player Plebinator won zombie event!
Flip Flop kicked out!
Player Plebinator won zombie event!

SCRIPT
LUA:
Z_ARENA_TOP_LEFT = {x = 1006, y = 791, z = 7}
Z_ARENA_BOTTOM_RIGHT = {x = 1033, y = 814, z = 7}

function onCombat(cid, target)
    local counter = 0
    local players = {}
    local temple = {x=1006, y=998, z=7}

    -- Teleport Player to temple when attacked by zombie
    if(isMonster(cid) and getCreatureName(cid):lower() == "zombie") then
        if(isPlayer(target)) then
            doTeleportThing(target, temple)
            doSendMagicEffect(temple, 43)
            print(getPlayerName(target) .. " kicked out!")
        end
    end

    -- Scan arena for players left
    for posy = Z_ARENA_TOP_LEFT.y, Z_ARENA_BOTTOM_RIGHT.y do
        for posx = Z_ARENA_TOP_LEFT.x, Z_ARENA_BOTTOM_RIGHT.x do
            if isPlayer(getTopCreature({x=posx, y=posy, z=7}).uid) then
                counter = counter+1
                table.insert(players, getTopCreature({x=posx, y=posy, z=7}).uid)
            end
        end
    end

    if counter == 1 then
        doTeleportThing(players[1], temple)
        print("Player "..getPlayerName(players[1]).." won zombie event!")
    end

    counter = 0
    players = {}
    return true
end
It's probably calling when they attack the player, and also when they lose focus of the player.

Maybe make the zombies do like 1000 water damage or something, so the damage triggers, and put it through onStatsChange, and simply return the damage as false to the player.

Also for checking the area for zombie event, checking every single tile for players/monsters
Do a check for players online, and check the player position to see if it's inside the arena, count the amount of players inside the arena and , not including the person who was hit by the attack, if only 1 person is inside arena positions, then they are the winner.

pseudo code
Code:
function onStatsChange(cid, target, blah, blah2, blah3)
    local last_known_cid = 0
    local counter = 0
    for pid, #playersOnline do
        local cid_pos = getPlayerPosition(pid)
        if cid_pos.x > Z_ARENA_TOP_LEFT.x and cid_pos.x < Z_ARENA_BOTTOM_RIGHT.x then
            if cid_pos.y > Z_ARENA_TOP_LEFT.y and cid_pos.y < Z_ARENA_BOTTOM_RIGHT.y then
                if cid_pos.z > Z_ARENA_TOP_LEFT.z and cid_pos.z < Z_ARENA_BOTTOM_RIGHT.z then
                    if pid ~= cid then
                        if counter == 0 then
                            last_known_cid = pid
                            counter = 1
                        else
                            counter = 2
                            break
                        end
                    end
                end
            end
        end
    end
    doTeleportThing(cid, temple)
    if counter == 1 then
        -- winner found
        -- give reward
        -- send reward text
        doTeleportThing(last_known_cid, temple)
    end
    return false -- so no damage
end

Something like that I suppose.

edit - -
check to make sure cid/target is correct and make sure the player is actually being damaged by the monster not other players et cetera, not being healed. blah blah
 
Last edited by a moderator:
It's probably calling when they attack the player, and also when they lose focus of the player.

Maybe make the zombies do like 1000 water damage or something, so the damage triggers, and put it through onStatsChange, and simply return the damage as false to the player.

Also for checking the area for zombie event, checking every single tile for players/monsters
Do a check for players online, and check the player position to see if it's inside the arena, count the amount of players inside the arena and , not including the person who was hit by the attack, if only 1 person is inside arena positions, then they are the winner.

pseudo code
Code:
function onStatsChange(cid, target, blah, blah2, blah3)
    local last_known_cid = 0
    local counter = 0
    for pid, #playersOnline do
        local cid_pos = getPlayerPosition(pid)
        if cid_pos.x > Z_ARENA_TOP_LEFT.x and cid_pos.x < Z_ARENA_BOTTOM_RIGHT.x then
            if cid_pos.y > Z_ARENA_TOP_LEFT.y and cid_pos.y < Z_ARENA_BOTTOM_RIGHT.y then
                if cid_pos.z > Z_ARENA_TOP_LEFT.z and cid_pos.z < Z_ARENA_BOTTOM_RIGHT.z then
                    if pid ~= cid then
                        if counter == 0 then
                            last_known_cid = pid
                            counter = 1
                        else
                            counter = 2
                            break
                        end
                    end
                end
            end
        end
    end
    doTeleportThing(cid, temple)
    if counter == 1 then
        -- winner found
        -- give reward
        -- send reward text
        doTeleportThing(last_known_cid, temple)
    end
    return false -- so no damage
end

Something like that I suppose.

edit - -
check to make sure cid/target is correct and make sure the player is actually being damaged by the monster not other players et cetera, not being healed. blah blah

@Xikini , thank you alot for your time. I will probably consider changing the loops.
But when i changed to return false instead of return true ( in original script ), it didnt repeat the code. :D
 
Solution
Back
Top