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

Russian Roullet tfs 1.5

vexler222

Active Member
Joined
Apr 22, 2012
Messages
714
Solutions
15
Reaction score
46
Hi, i tried make a russian roulette quest, and i edited for it default annihilator quest script.
And problem is if player have manashield, then he died but server died too (crashed)

Lua:
local russian_rullet = Action()
local playerPositions = {
    Position(1313, 1238, 7),
    Position(1312, 1239, 7),
    Position(1314, 1239, 7),
    Position(1313, 1240, 7),

}
local players = {}

function russian_rullet.onUse(player, position, fromposition, toPosition, item)
    local looser = Tile(playerPositions[math.random(1, 4)]):getTopCreature()
    for _, position in ipairs(playerPositions) do
        local topPlayer = Tile(position):getTopCreature()
        if not topPlayer or not topPlayer:isPlayer() then
            player:sendTextMessage(MESSAGE_EVENT_ORANGE, "You need 4 players.")
            return false
        end
        players[#players + 1] = topPlayer
    end
    for i, targetPlayer in ipairs(players) do
        doTargetCombat(0, looser, COMBAT_PHYSICALDAMAGE, -looser:getHealth(), -looser:getHealth())
        addEvent(function()
            targetPlayer:teleportTo(Position(1316, 1239, 7))
        end, 100)
    end
end

russian_rullet:aid(34345)
russian_rullet:register()
 
Solution
There was 2 issues:
1- You were trying to repeatedly kill the loser (by putting doTargetCombat inside the loop)
2- Missing verification for userdata on addEvent
(always recreate userdata inside events)

In short, trying to access userdata which no longer exist (player died/logout) will crash the server.
As you can see on this script also uses userdata without verification but thats because it does not use addEvent and also execution goes almost instantly, so there is no need

Lua:
local playerPositions = {
    Position(1313, 1238, 7),
    Position(1312, 1239, 7),
    Position(1314, 1239, 7),
    Position(1313, 1240, 7),
}

local russian_rullet = Action()
function russian_rullet.onUse(player, position, fromposition, toPosition, item)...
There was 2 issues:
1- You were trying to repeatedly kill the loser (by putting doTargetCombat inside the loop)
2- Missing verification for userdata on addEvent
(always recreate userdata inside events)

In short, trying to access userdata which no longer exist (player died/logout) will crash the server.
As you can see on this script also uses userdata without verification but thats because it does not use addEvent and also execution goes almost instantly, so there is no need

Lua:
local playerPositions = {
    Position(1313, 1238, 7),
    Position(1312, 1239, 7),
    Position(1314, 1239, 7),
    Position(1313, 1240, 7),
}

local russian_rullet = Action()
function russian_rullet.onUse(player, position, fromposition, toPosition, item)

    local players = {}
    for i = 1, #playerPositions do
        local topPlayer = Tile(playerPositions[i]):getTopCreature()
        if topPlayer and topPlayer:isPlayer() then
            players[#players + 1] = topPlayer
        end
    end

    if (#players ~= #playerPositions) then
        return player:sendTextMessage(MESSAGE_EVENT_ORANGE, "You need "..#playerPositions.." players.")
    end

    local looser = math.random(1, #players)
    for i = 1, #players do
        local player = players[i]
        if (i ~= looser) then
            player:teleportTo(Position(1316, 1239, 7))
        else
            doTargetCombat(0, player, COMBAT_PHYSICALDAMAGE, -player:getHealth(), -player:getHealth())
        end
    end
    return true
end

russian_rullet:aid(34345)
russian_rullet:register()
 
Last edited:
Solution
Back
Top