• 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+ passing arguments to onTargetCreature(cid, var)

mackerel

Well-Known Member
Joined
Apr 26, 2017
Messages
398
Solutions
18
Reaction score
72
just curious how would you make it work- passing one argument to onTargetCreature

onTargetCreature will execute for every target it hits

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_EFFECT, 12)

combat:setArea(createCombatArea(AREA_SQUAREWAVE5))

function onTargetCreature(cid, var, message)
   print(message)
   return true
end

function onCastSpell(cid, var)
    local message = "hello world"
   
    return combat:execute(cid, var, message)
end

console output is just nil
 
Try
Lua:
local message = 'hello'
function onTargetCreature(cid, var)
   print(message)
   return true
end
setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCombat")
 
Try
Lua:
local message = 'hello'
function onTargetCreature(cid, var)
   print(message)
   return true
end
setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCombat")

yes, that will work. I wanted to pass an argument which is constantly changing so I cannot have it like that because its unique for the player, and why would I do that? Its because I've come across complicated issue but eventually fixed it :p

When we define an area for a spell it will iterate through it one by one, because that's how the computers meant to work right? Reading lines from top to bottom. Well there might be an issue with that when you consider scenario with teleporting targets. Let's say we have this grid here:

{1, 1, 1}
{1, 3, 1}

Top left is our target that just got hit by our spell and will be teleported to player' left position and then what will happen is, the combat:execute will still be executing so it will iterate another 1 and another 1 until it gets to the enemy it just teleported, so then it will execute that function again for the same target and will also deal damage (again), which is wrong.

To overcome this issue I had to create like a table (local - 1st line, just where you have your local message) and this is for; to save each target that got hit and then simple if statement to check if the target is still in the table. Well it works but not great since it can be accessed and modified by every player which is wrong.

Eventually I removed the table because it was not working properly and adjusted the code in other ways. I have not fixed the issue above but adapted my code differently. If someone wants to fix that issue with teleporting you can simply create a table and then just add player:getId() and its targets there in order to avoid players from accessing and modifying the same targets. Even though it might not be noticeable because of how fast the computer performs its task, its still something I would consider fixing :D
 
Like
Lua:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA)

local area = createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)
setCombatArea(combat, area)

function onGetFormulaValues(cid, level, maglevel)
    min = -((level / 5) + (maglevel * 0.8) + 5)
    max = -((level / 5) + (maglevel * 2) + 12)
    return min, max
end

function onTargetCombat(creature, target)
target:teleportTo(creature:getClosestFreePosition(creature:getPosition(), false))
end

setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCombat")

setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")


function onCastSpell(cid, var)
    return doCombat(cid, combat, var)
end
?
 
Like
Lua:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA)

local area = createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)
setCombatArea(combat, area)

function onGetFormulaValues(cid, level, maglevel)
    min = -((level / 5) + (maglevel * 0.8) + 5)
    max = -((level / 5) + (maglevel * 2) + 12)
    return min, max
end

function onTargetCombat(creature, target)
target:teleportTo(creature:getClosestFreePosition(creature:getPosition(), false))
end

setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCombat")

setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")


function onCastSpell(cid, var)
    return doCombat(cid, combat, var)
end
?

yes something similar to this. not necessarily teleport inside the player haha but yeah thats the idea behind it :p

if you want to re-create the bug then you have to teleport enemy near the player or just use AREA_CROSS5X5 as your area

then you will see double dmg
 
Like
Lua:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA)

local area = createCombatArea(AREA_WAVE4, AREADIAGONAL_WAVE4)
setCombatArea(combat, area)

function onGetFormulaValues(cid, level, maglevel)
    min = -((level / 5) + (maglevel * 0.8) + 5)
    max = -((level / 5) + (maglevel * 2) + 12)
    return min, max
end

function onTargetCombat(creature, target)
target:teleportTo(creature:getClosestFreePosition(creature:getPosition(), false))
end

setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCombat")

setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")


function onCastSpell(cid, var)
    return doCombat(cid, combat, var)
end
?
ahahahhahahahahahahahahahahah very good XD
 
yes something similar to this. not necessarily teleport inside the player haha but yeah thats the idea behind it :p

if you want to re-create the bug then you have to teleport enemy near the player or just use AREA_CROSS5X5 as your area

then you will see double dmg
Its teleporting inside a player, because youte probably using a God character.
Area shouldnt make a difference here.
 
Its teleporting inside a player, because youte probably using a God character.
Area shouldnt make a difference here.

Yes, area won't make a difference, its just easier to notice than using WAVE4

but here is the bug

Player using spell deals dmg to training monk and then it gets teleported, after it gets teleported its gonna take dmg again and most likely the function will execute twice as well. Also that getClosestFreePosition function feels like it has been made specifically for game masters but I guess it can be used for players if someone needs basic functionality. I mean there is no way to make it teleport enemies to coordinates you want them to. For instance they will always be teleported to top-left then I think top and then top-right etc. instead of saying that you want to make each position unique. But that's more advanced stuff I guess and requires more coding and maths - really useful


2dGkyHB.png
 
Back
Top