• 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+ Is it possible to execute effect exactly when distaneeffect hits the target

henkas

Well-Known Member
Joined
Jul 8, 2015
Messages
1,050
Solutions
5
Reaction score
62
Hey is it possible to execute the effect exactlly at the moment when missile reaches the target? Seen some servers achieving it, example of code, trying to time the effect 73

LUA:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, 17)
function onGetFormulaValues(player, level, maglevel)
    local min = (level * 5) + (maglevel * 12.5) + 25
    local max = (level * 5) + (maglevel * 14) + 50
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")


function onCastSpell(creature, variant)
    local player = Player(creature)
    if not player then
        return false
    end
    local target = player:getTarget()
    if not target then
        return false
    end
    local position = target:getPosition() + Position(0, 0, 0)
    position:sendMagicEffect(73)
    return combat:execute(creature, variant)
end
 
Solution
LUA:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CAKE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, 1, 1, 1, 1)

local function callback(creature, variant)
    local target = Creature(variant:getNumber())
    if not target then return false end
    local creaturePos = creature:getPosition()
    local targetPos = target:getPosition()
    local distance = creaturePos:getDistance(targetPos)
    local milliseconds = distance * 80
    creaturePos:sendDistanceEffect(targetPos, CONST_ANI_ARROW)
    addEvent(function()
        combat:execute(creature, variant)
    end, milliseconds)
    return true
end

local spell = Spell(SPELL_INSTANT)

function...
You can use addevent for that
How addevent solves it, it makes it hardcoded if distance and speed changes of missile it will be not in sync anymore, someone mentioned that Flatlander have made such system that when missile reaches target it executes the effect
 
How addevent solves it, it makes it hardcoded if distance and speed changes of missile it will be not in sync anymore, someone mentioned that Flatlander have made such system that when missile reaches target it executes the effect
What speed? There is no speed, every missile has duration of 100ms per tile. Just get the distance to target, addEvent with 100 * distance and do the damage there.
 
What speed? There is no speed, every missile has duration of 100ms per tile. Just get the distance to target, addEvent with 100 * distance and do the damage there.
What I mean is, if you stand farther away from the target—say, 10 tiles instead of just one tile—the time it takes to reach the target will change, because what if he executes the spell one or two ir four tiles away from target so, addevent won't work at that point, and there wont be any sync
 
What I mean is, if you stand farther away from the target—say, 10 tiles instead of just one tile—the time it takes to reach the target will change, because what if he executes the spell one or two ir four tiles away from target so, addevent won't work at that point, and there wont be any sync
Bruh, what? The only difference that can cause desync is player ping, that's all. But if you use 80-100ms per tile then players with normal ping will see the effect apply damage on hit.
 
Bruh, what? The only difference that can cause desync is player ping, that's all. But if you use 80-100ms per tile then players with normal ping will see the effect apply damage on hit.
So example something like this?
LUA:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, 17)

function onGetFormulaValues(player, level, maglevel)
    local min = (level * 5) + (maglevel * 12.5) + 25
    local max = (level * 5) + (maglevel * 14) + 50
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    local player = Player(creature)
    if not player then
        return false
    end

    local target = player:getTarget()
    if not target then
        return false
    end

    local casterPosition = player:getPosition()
    local targetPosition = target:getPosition()
    local distance = casterPosition:getDistance(targetPosition)

    local delay = distance * 100

    local effectPosition = targetPosition + Position(1, 1, 0)
    combat:execute(creature, variant)

    addEvent(function()
        effectPosition:sendMagicEffect(985)
    end, delay)

    return true
end
This seems to do the job, but there is slight delay of effect if you stand for example 10 tiles away from target, but its perfect if you're upclose
 
Made another conspet of adjusting addevent depending on distance of tiles, this way its in sync pretty much fine, just that damage is being applied faster than spell effect reaches the target.
LUA:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, 17)

function onGetFormulaValues(player, level, maglevel)
    local min = (level * 5) + (maglevel * 12.5) + 25
    local max = (level * 5) + (maglevel * 14) + 50
    return -min, -max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    local player = Player(creature)
    if not player then
        return false
    end

    local target = player:getTarget()
    if not target then
        return false
    end

    local casterPosition = player:getPosition()
    local targetPosition = target:getPosition()
    local distance = casterPosition:getDistance(targetPosition)

    local delay
    if distance == 1 then
        delay = 100
    elseif distance == 2 then
        delay = 200
    elseif distance == 3 then
        delay = 250
    elseif distance == 4 then
        delay = 250
    elseif distance == 5 then
        delay = 250
    elseif distance == 6 then
        delay = 250
    else
        delay = distance * 50  
    end

    local effectPosition = targetPosition + Position(1, 1, 0)
    combat:execute(creature, variant)

    addEvent(function()
        effectPosition:sendMagicEffect(985)
    end, delay)

    return true
end
 
LUA:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CAKE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, 1, 1, 1, 1)

local function callback(creature, variant)
    local target = Creature(variant:getNumber())
    if not target then return false end
    local creaturePos = creature:getPosition()
    local targetPos = target:getPosition()
    local distance = creaturePos:getDistance(targetPos)
    local milliseconds = distance * 80
    creaturePos:sendDistanceEffect(targetPos, CONST_ANI_ARROW)
    addEvent(function()
        combat:execute(creature, variant)
    end, milliseconds)
    return true
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    return callback(creature, variant)
end

spell:name("testing")
spell:id(0)
spell:words("test")
spell:needTarget(true)
spell:register()

tyuytuyt.gif
 
Solution
LUA:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CAKE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, 1, 1, 1, 1)

local function callback(creature, variant)
    local target = Creature(variant:getNumber())
    if not target then return false end
    local creaturePos = creature:getPosition()
    local targetPos = target:getPosition()
    local distance = creaturePos:getDistance(targetPos)
    local milliseconds = distance * 80
    creaturePos:sendDistanceEffect(targetPos, CONST_ANI_ARROW)
    addEvent(function()
        combat:execute(creature, variant)
    end, milliseconds)
    return true
end

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
    return callback(creature, variant)
end

spell:name("testing")
spell:id(0)
spell:words("test")
spell:needTarget(true)
spell:register()

View attachment 86546
Dont have revscript and you deleted offset of spell and damage formula of min and max, and another issue even if you change for example to a combat:setParameter(COMBAT_PARAM_EFFECT, 986) the spell shown is way different
 
Dont have revscript and you deleted offset of spell and damage formula of min and max, and another issue even if you change for example to a combat:setParameter(COMBAT_PARAM_EFFECT, 986) the spell shown is way different
There you go
LUA:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
combat:setFormula(COMBAT_FORMULA_LEVELMAGIC, 3, 12, 4, 25) -- should be similar to your

local function callback(creature, variant)
    local target = Creature(variant:getNumber())
    if not target then return false end

    local creaturePos = creature:getPosition()
    local targetPos = target:getPosition()
    local distance = creaturePos:getDistance(targetPos)

    local milliseconds = distance * 80
    creaturePos:sendDistanceEffect(targetPos, CONST_ANI_ARROW)

    addEvent(function()
        combat:execute(creature, variant)
        local effectPosition = targetPos + Position(1, 1, 0)
        effectPosition:sendMagicEffect(986)
    end, milliseconds)

    return true
end


function onCastSpell(creature, variant)
    return callback(creature, variant)
end
 

Similar threads

Back
Top