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

TFS 1.X+ tfs 1.2 spell crash server?

roriscrave

Advanced OT User
Joined
Dec 7, 2011
Messages
1,188
Solutions
34
Reaction score
200
Hi, i use this spell in my server, but when the player die, the server crashes.
OBS: if a player who used the spell die, when the script is running, the server crashes.

Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)




function onCastSpell(cid, var)


local function Repeat_Effect(target, times)
if times > 0 then
    if isCreature(cid) then
        if isCreature(target) then
            doSendMagicEffect(getCreaturePosition(target), 199)
            doSendDistanceShoot(getCreaturePosition(cid), getCreaturePosition(target), 15)
            addEvent(Repeat_Effect,100,target,times-1)
        end
    end
end
end

local target = getCreatureTarget(cid)
Repeat_Effect(target,6)
return doCombat(cid, combat, var)
end
 
Last edited:
Solution
Hi, i use this spell in my server, but when the player die, the server crashes.
OBS: if a player who used the spell die, when the script is running, the server crashes.

Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)




function onCastSpell(cid, var)


local function Repeat_Effect(target, times)
if times > 0 then
    if isCreature(cid) then
        if isCreature(target) then
            doSendMagicEffect(getCreaturePosition(target), 199)
            doSendDistanceShoot(getCreaturePosition(cid), getCreaturePosition(target), 15)
            addEvent(Repeat_Effect,100,target,times-1)
        end
    end
end...
Hi, i use this spell in my server, but when the player die, the server crashes.
OBS: if a player who used the spell die, when the script is running, the server crashes.

Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)




function onCastSpell(cid, var)


local function Repeat_Effect(target, times)
if times > 0 then
    if isCreature(cid) then
        if isCreature(target) then
            doSendMagicEffect(getCreaturePosition(target), 199)
            doSendDistanceShoot(getCreaturePosition(cid), getCreaturePosition(target), 15)
            addEvent(Repeat_Effect,100,target,times-1)
        end
    end
end
end

local target = getCreatureTarget(cid)
Repeat_Effect(target,6)
return doCombat(cid, combat, var)
end
Creating a seperate function that does Creature() every time will fix this issue. Also when you call function inside onCastSpell then you should verify that the doCombat actually worked first.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)

local function repeatEffect(cid, target_uid, times)
    if times <= 0 then
        return
    end

    local creature, target = Creature(cid), Creature(target_uid)
    if creature and target then
        if not creature:getTile():hasFlag(TILESTATE_PROTECTIONZONE) and not target:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then
            local target_pos = target:getPosition()
            target_pos:sendMagicEffect(199)
            creature:getPosition():sendDistanceEffect(target_pos, CONST_ANI_POISON)
            addEvent(repeatEffect, 100, cid, target_uid, times - 1)
        end
    end
end


function onCastSpell(creature, variant)
    if combat:execute(creature, variant) then
        repeatEffect(creature.uid, variantToNumber(variant), 6)
        return true
    end
    return false
end
 
Solution
Hi, i use this spell in my server, but when the player die, the server crashes.
OBS: if a player who used the spell die, when the script is running, the server crashes.

Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)




function onCastSpell(cid, var)


local function Repeat_Effect(target, times)
if times > 0 then
    if isCreature(cid) then
        if isCreature(target) then
            doSendMagicEffect(getCreaturePosition(target), 199)
            doSendDistanceShoot(getCreaturePosition(cid), getCreaturePosition(target), 15)
            addEvent(Repeat_Effect,100,target,times-1)
        end
    end
end
end

local target = getCreatureTarget(cid)
Repeat_Effect(target,6)
return doCombat(cid, combat, var)
end
Lua:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)

local function Repeat_Effect(x)
    if x.times > 0 then
        if isCreature(x.cid) and isCreature(x.target) then
            local targPos = getCreaturePosition(x.target)
            doSendMagicEffect(targPos, 199)
            doSendDistanceShoot(getCreaturePosition(x.cid), targPos, 15)
            doCombat(x.cid, x.combat, x.var)
            x.times = x.times - 1
            addEvent(Repeat_Effect, 100, x)
        end
    end
end

function onCastSpell(cid, var)
    Repeat_Effect({cid = cid, combat = combat, var = var, target = getCreatureTarget(cid), times = 6})
    return true
end
 
Last edited:
Creating a seperate function that does Creature() every time will fix this issue. Also when you call function inside onCastSpell then you should verify that the doCombat actually worked first.
it works!
Can u explain for me the last return false? why its not return true?
 
it works!
Can u explain for me the last return false? why its not return true?
Hopefully this explains:
Lua:
function onCastSpell(creature, variant)
    if combat:execute(creature, variant) then    -- IF COMBAT:EXECUTE RETURNS TRUE THEN WE GO INTO THIS BRANCH
        repeatEffect(creature.uid, variantToNumber(variant), 6)    -- SEND EFFECTS
        return true    -- RETURN TRUE HERE SO THE SERVER KNOWS THE SPELL WORKED
    end
    return false    -- IF COMBAT:EXECUTE DIDNT' WORK IT'LL JUMP TO DOWN HERE AND TELL SERVER IT DIDN'T WORK
end

Compared to how most spells are returned you can see how the combat:execute determines what boolean should be returned for the onCastSpell:
Lua:
function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end
 
Creating a seperate function that does Creature() every time will fix this issue. Also when you call function inside onCastSpell then you should verify that the doCombat actually worked first.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)

local function repeatEffect(cid, target_uid, times)
    if times <= 0 then
        return
    end

    local creature, target = Creature(cid), Creature(target_uid)
    if creature and target then
        if not creature:getTile():hasFlag(TILESTATE_PROTECTIONZONE) and not target:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then
            local target_pos = target:getPosition()
            target_pos:sendMagicEffect(199)
            creature:getPosition():sendDistanceEffect(target_pos, CONST_ANI_POISON)
            addEvent(repeatEffect, 100, cid, target_uid, times - 1)
        end
    end
end


function onCastSpell(creature, variant)
    if combat:execute(creature, variant) then
        repeatEffect(creature.uid, variantToNumber(variant), 6)
        return true
    end
    return false
end
@roriscrave
This only executes the combat object once the rest is just a spamming of effects but mine (if it works) would execute the combat object for the amount of times the addEvent is executed. (6)
 
Hopefully this explains:
Lua:
function onCastSpell(creature, variant)
    if combat:execute(creature, variant) then    -- IF COMBAT:EXECUTE RETURNS TRUE THEN WE GO INTO THIS BRANCH
        repeatEffect(creature.uid, variantToNumber(variant), 6)    -- SEND EFFECTS
        return true    -- RETURN TRUE HERE SO THE SERVER KNOWS THE SPELL WORKED
    end
    return false    -- IF COMBAT:EXECUTE DIDNT' WORK IT'LL JUMP TO DOWN HERE AND TELL SERVER IT DIDN'T WORK
end

thx bro!!!!

Compared to how most spells are returned you can see how the combat:execute determines what boolean should be returned for the onCastSpell:
Lua:
function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end
@roriscrave
This only executes the combat object once the rest is just a spamming of effects but mine (if it works) would execute the combat object for the amount of times the addEvent is executed. (6)

yes, i want to spam only effects, with one combat, but thanks you too! I ill use u form to another script!
 
@roriscrave
This only executes the combat object once the rest is just a spamming of effects but mine (if it works) would execute the combat object for the amount of times the addEvent is executed. (6)
You're is missing the TILESTATE_PROTECTIONZONE verification and still returning the onCast true without verifying that it actually worked. Also if you have an opportunity to update to meta methods then you might as well.

You would want to do something like this:
Lua:
function onCastSpell(cid, var)
    if doCombat(cid, combat, var) then
        addEvent(Repeat_Effect, 100, {cid = cid, combat = combat, var = var, target = getCreatureTarget(cid), times = 5})
        return true
    end
    return false
end

Then continue the combat within Repeat_Effect but it's also important to verify within that function as well.
 
You're is missing the TILESTATE_PROTECTIONZONE verification and still returning the onCast true without verifying that it actually worked. Also if you have an opportunity to update to meta methods then you might as well.
So tell me exactly why I need to "verify" the return value? and I don't need to use TILESTATE_PROTECTIONZONE because a combat object will not execute within the bounds of a protection zone by default. It's effects might but the damage will cancel out.
 
So tell me exactly why I need to "verify" the return value? and I don't need to use TILESTATE_PROTECTIONZONE because a combat object will not execute within the bounds of a protection zone by default. It's effects might but the damage will cancel out.
If you return true and your character can't shoot to the target or is in protection zone your character will say the spell words out loud without anything actually happening. The combat object doesn't say the words because the combat:execute function is typically called like this in the onCastSpell "return combat:execute(creature, variant)" so the return of combat:execute is the return of onCastSpell.

Also if you didn't verify the TILESTATE_PROTECTIONZONE within the Repeat_Effect function it will still attempt to send doCombat, fail, and then still send the distance effect and magic effect.

I hope that makes sense.
 
If you return true and your character can't shoot to the target or is in protection zone your character will say the spell words out loud without anything actually happening. The combat object doesn't say the words because the combat:execute function is typically called like this in the onCastSpell "return combat:execute(creature, variant)" so the return of combat:execute is the return of onCastSpell.

Also if you didn't verify the TILESTATE_PROTECTIONZONE within the Repeat_Effect function it will still attempt to send doCombat, fail, and then still send the distance effect and magic effect.

I hope that makes sense.
No it doesn't especially the middle paragraph.
 
No it doesn't especially the middle paragraph.
This part for sure is bugged.
Lua:
local function Repeat_Effect(x)
    if x.times > 0 then
        if isCreature(x.cid) and isCreature(x.target) then
            local targPos = getCreaturePosition(x.target)
            doSendMagicEffect(targPos, 199)
            doSendDistanceShoot(getCreaturePosition(x.cid), targPos, 15)
            doCombat(x.cid, x.combat, x.var)    -- IF THIS FAILS THE TWO ABOVE FUNCTION WILL HAVE STILL BE SENT
            x.times = x.times - 1
            addEvent(Repeat_Effect, 100, x)
        end
    end
end

Regarding the onCastSpell returns, I was wrong. You're right that it still will not send the effect or words but there's a reason they do onCasts like this:
Lua:
function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end
It's good practice and communicating to the sources that the spell did send, I'm not experienced enough in c++ to tell you for sure if it's essential.
 
@Apollos don't just say it's bugged give your input of why you think it's bugged & how you think the code should execute. We are all here to learn right?

The only catch is you have to use the code style & syntax that is used in my script. Standard functions not metatables & metamethods.
 
@Apollos don't just say it's bugged give your input of why you think it's bugged & how you think the code should execute. We are all here to learn right?
I did, there's a comment inside the code explaining the issue and I explained what to do before.
Code:
if doCombat(cid, combat, var) then
    -- put your effects and other stuff here
end
This way the spell won't continue if you or the target goes into protection zone.
 
Creating a seperate function that does Creature() every time will fix this issue. Also when you call function inside onCastSpell then you should verify that the doCombat actually worked first.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, -3.2, 1, -5.2, 1)

local function repeatEffect(cid, target_uid, times)
    if times <= 0 then
        return
    end

    local creature, target = Creature(cid), Creature(target_uid)
    if creature and target then
        if not creature:getTile():hasFlag(TILESTATE_PROTECTIONZONE) and not target:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then
            local target_pos = target:getPosition()
            target_pos:sendMagicEffect(199)
            creature:getPosition():sendDistanceEffect(target_pos, CONST_ANI_POISON)
            addEvent(repeatEffect, 100, cid, target_uid, times - 1)
        end
    end
end


function onCastSpell(creature, variant)
    if combat:execute(creature, variant) then
        repeatEffect(creature.uid, variantToNumber(variant), 6)
        return true
    end
    return false
end

bro.. if i want to put "combat:execute(creature, variant)" into to the function repeatEffect, for hit in all effect, how i do it?
if i put only "combat:execute(creature, variant)" it give me a error.
Code:
attempt to index a nil value
stack traceback:
        [C]: at 0x7ff757017ad0
        [C]: in function 'execute'
        data/spells/scripts/spell1.lua:15: in function 'repeatEffect'
 
Back
Top