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

Spell TFS 0.4 - cast different spells based on item in hand (or other LUA 'if')

Gesior.pl

Mega Noob&LOL 2012
Senator
Joined
Sep 18, 2007
Messages
2,964
Solutions
99
Reaction score
3,374
Location
Poland
GitHub
gesior
@Sir Sezago
Asked me about spell that attack like 'exori vis' (front of player or distance if creature attacked), but if item 'x' in hand, it should be 'wave' (front of player, no matter if creature attacked).

After.. 53 days I found time to write it.
It wasn't easy, so I decided to release it and show how to handle 'var' in spells to customize target of spell.

spells.xml (casterTargetOrDirection="1" range="3"):
PHP:
    <instant name="Mis Strike" words="exori mis" lvl="12" mana="20" prem="0" range="3" casterTargetOrDirection="1" blockwalls="1" exhaustion="500" needlearn="0" event="script" value="attack/mis strike.lua">
    </instant>

attack/mis strike.lua:
PHP:
local combatStrike = createCombatObject()
setCombatParam(combatStrike, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
setCombatParam(combatStrike, COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA)
setCombatParam(combatStrike, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
setCombatFormula(combatStrike, COMBAT_FORMULA_LEVELMAGIC, -1, -10, -1, -20, 5, 5, 3.4, 5.1)


local  combatWave = createCombatObject()
setCombatParam(combatWave, COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
setCombatParam(combatWave, COMBAT_PARAM_EFFECT, CONST_ME_HOLYDAMAGE)
setCombatParam(combatWave, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_HOLY)
setAttackFormula(combatWave, COMBAT_FORMULA_LEVELMAGIC, 3, 3, 19, 24)
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5))

local items = {12609, 7424}

function onCastSpell(cid, var)
    for i, itemid in pairs(items) do
        if getPlayerSlotItem(cid, CONST_SLOT_RIGHT).itemid == itemid then
            -- if in right hand
            -- replace 'var' (which contains TARGET!) with position in front of player
            local targetPosition = getCreatureLookPosition(cid) -- position if front of player
            local newVar = positionToVariant(targetPosition)
            return doCombat(cid, combatWave, newVar)
        elseif getPlayerSlotItem(cid, CONST_SLOT_LEFT).itemid == itemid  then
            -- if in left hand
            -- do normal 'exori vis' attack, just pass 'var'
            return doCombat(cid, combatStrike, var)
        end
    end

    -- HERE YOU CAN PLACE 'WHAT TO DO WHEN NO ITEM'
    -- I set it to 'nothing'
    return false
end
Item in right hand:
Replace 'var' (which containts target of spell) with position 'in front of player' and cast 'wave'.
Item in left hand:
Just cast spell like exori vis, if player has target it will attack target, if not then it will attack in front of him.
No item:
No attack, but you can change it.

IMPORTANT thing to understand how it works is 'var' in spells. In this variable is information about target of spell. It may contain 3 types of value:
- number = CID of target creature/player (selected on battle window)
- position = position of target creature/player OR position in front of casting player if it's wave spell
- string = name of target player (for spells like 'exura sio "gesior')

To display it's value (in console) or modify, you must use one of functions:
PHP:
number = variantToNumber(var) // returns 0, if not set
string = variantToString(var) // returns empty string, if not set
position = luaVariantToPosition(var) // returns {x=0, y=0, z=0, stackpos=0}, if not set
To change some LUA variable into 'variant' you must use one functions:
PHP:
var = numberToVariant(number)
var = stringToVariant(string)
var = positionToVariant(pos)
var = targetPositionToVariant(pos)
and then you can pass 'var' to 'doCombat' as 3rd parameter.
 
Last edited by a moderator:
@Gesior.pl Thanks Bro So much that what i was need and more you gave me new ideas for more spells :D
 
I made little mistake in code:
PHP:
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))
Should be:
PHP:
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5))
I copied it from some Sezago priv. message. Second parameter to createCombatArea is 'diagonal attack area' and is useless in case when player got no target creature (which can be in diagonal position to player).
In case when player has target and it's some kind of 'wave', it looks really cool:
diagonal_wave.png
 
I made little mistake in code:
PHP:
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5))
Should be:
PHP:
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5))
I copied it from some Sezago priv. message. Second parameter to createCombatArea is 'diagonal attack area' and is useless in case when player got no target creature (which can be in diagonal position to player).
In case when player has target and it's some kind of 'wave', it looks really cool:
diagonal_wave.png
i already fixed the Code but can you explain me if i need make parameter as i need make something like this in wave spell
Code:
    addEvent(doCombat, 0, cid, combat1, var)
    addEvent(doCombat, 250, cid, combat2, var)
 
i already fixed the Code but can you explain me if i need make parameter as i need make something like this in wave spell
Code:
    addEvent(doCombat, 0, cid, combat1, var)
    addEvent(doCombat, 250, cid, combat2, var)
There are 2 options:
1. Cast second wave in same position as it was in moment when player casted spell - just pass same 'var'.
2. Cast second wave 'like' player cast spell again. It will adjust second wave position to player current positon (player can move within 0.25 sec).

Code 1:
PHP:
local combatWave = createCombatObject()
setCombatParam(combatWave, COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
setCombatParam(combatWave, COMBAT_PARAM_EFFECT, CONST_ME_HOLYDAMAGE)
setAttackFormula(combatWave, COMBAT_FORMULA_LEVELMAGIC, 3, 3, 19, 24)
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5))

function onCastSpell(cid, var)
    doCombat(cid, combatWave, var)
    addEvent(doCombat, 2000, cid, combatWave, var)
    -- return true to make it start count spell cooldown
    return true
end
Code 2:
PHP:
local combatWave = createCombatObject()
setCombatParam(combatWave, COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
setCombatParam(combatWave, COMBAT_PARAM_EFFECT, CONST_ME_HOLYDAMAGE)
setAttackFormula(combatWave, COMBAT_FORMULA_LEVELMAGIC, 3, 3, 19, 24)
setCombatArea(combatWave, createCombatArea(AREA_SQUAREWAVE5))

local function decayedWave(cid, combat)
    local currentPositionInFrontOfPlayer = getCreatureLookPosition(cid)
    local var = positionToVariant(currentPositionInFrontOfPlayer)
    doCombat(cid, combat, var)
end

function onCastSpell(cid, var)
    decayedWave(cid, combatWave)
    addEvent(decayedWave, 2000, cid, combatWave)
    -- return true to make it start count spell cooldown
    return true
end
 
Its possible to instead of item, get the distance between the player and target, get this value and add a delay like, if distbetween = 2, add animation delay = 50 miliseconds, if = 3 100 miniseconds?
 
Its possible to instead of item, get the distance between the player and target, get this value and add a delay like, if distbetween = 2, add animation delay = 50 miliseconds, if = 3 100 miniseconds?
Do you mean delay animation (start it with delay) or make animation slower on screen? You cannot change animation speed in Tibia Client.
 
Do you mean delay animation (start it with delay) or make animation slower on screen? You cannot change animation speed in Tibia Client.
I meant if the target is 2 sqm from you, will take 60 miliseconds to the effect shows, if 3 sqm away, will take 120 miliseconds, etc.
 
Back
Top