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

Lua Change outfit when cast spell's [Tfs1.1]

Ruan Sebast

New Member
Joined
Nov 9, 2014
Messages
38
Reaction score
0
Location
Brazil
I need help in a lua script, that should be used in spells.
When i or a monster cast a spell the scripts runs, then it check if the player/monster have x looktype.

If yes, then the script change player or monster outfit for x seconds and back.
If no, just cast the spell normal.

The script will run in all spells, its just a check , if the looktype = x , then the script run , if no , it just cast the spell normal.

Im using tfs 1.1
 
Okay, so when onCastSpell is called, you want to check the player's looktype and do a bunch of operations before returning back to the server.

Code:
function onCastSpell(creature, variant)

    -- Everything must happen here

    return doCombat(creature, combat, variant)
end

First, you need to think how you exactly want this to go.
Let's briefly go over your idea:
  • Check if caster has X looktype
    • If yes, change caster looktype to Y for Z seconds and revert back to old
    • If no, return back to server
This sounds very simple and it all has to go where "-- Everything must happen here" is in the previous script.

The caster is defined when onCastSpell is called, under creature (which is a userdata by the way).
So, let's go back to our bullet point and see what we need to do first.

We need to check if the caster (creature) has X looktype, so we'll use creature:getOutfit().lookType in a conditional statement.

Code:
function onCastSpell(creature, variant)

    if creature:getOutfit().lookType == X then
    end

    return doCombat(creature, combat, variant)
end

Now we have a equal conditional statement, meaning if the outfit == (equals) X, then do something.
This something is for the "If yes" part of the bullet points. Here is where it gets tricky.

We want to change the caster's outfit to something else and then revert it back to what it had before.
In order to go back to the previous outfit, we want to tell the server to remember the caster's outfit, so we'll store it to a variable.
Note, I used prevOutfit in the condition statement so that we don't have to call creature:getOutfit() again

Code:
function onCastSpell(creature, variant)
    local prevOutfit = creature:getOutfit()

    if prevOutfit.lookType == X then
    end

    return doCombat(creature, combat, variant)
end

Now we got the outfit saved, we can then change the caster's looktype safely without losing the previous outfit.
In order to do something at a delay of some sort, we use addEvent().

addEvent() takes n+2 parameters, where n = the number of parameters the callback function requires.

addEvent(callback, time, ...)

So, as we mentioned before, we want to change the outfit and then change it back to what it was before Z time later.
We'll use setOutfit() to set the caster's outfit to Y and addEvent() to set the caster's outfit to what it was previously Z time later.

Code:
function onCastSpell(creature, variant)
    local prevOutfit = creature:getOutfit()

    if prevOutfit.lookType == X then
        addEvent(creature:setOutfit, Y, prevOutfit)
        creature:setOutfit(newOutfit)
    end
    return doCombat(creature, combat, variant)
end

But whoops! We have a problem! A lot of people make this mistake, including myself. Think carefully about addEvent().
Don't notice it? What happens if you log out before the addEvent() time is up? We'll get a nil error.
So, we want to check if the caster still exists before setting the outfit back to original. So, we'll add a simple if not creature then return end check.

This also means our callback function for the addEvent() has to change since we're using a bulk of operations now; so we'll use a lambda function.
We cannot pass userdata as a parameter into the addEvent() function, so we'll send the caster's id and create an instance of creature userdata inside.

Code:
function onCastSpell(creature, variant)
    local prevOutfit = creature:getOutfit()

    if prevOutfit.lookType == X then
        addEvent(function(cid, prev)
            local creature = Creature(cid)
            if not creature then
                return
            end
            creature:setOutfit(prev)
        end, Y, creature:getId(), prevOutfit)

        creature:setOutfit(newOutfit)
    end
    return doCombat(creature, combat, variant)
end

Now everything looks good to me. I should also note that creature:setOutfit() only takes 1 parameter (an outfit object).
An outfit object is a table indexed: lookType, lookTypeEx, lookHead, lookBody, lookLegs, lookFeet, lookAddons, lookMount.

So, here is an example I have:

Code:
function onCastSpell(creature, variant)
    local prevOutfit = creature:getOutfit()
    local newOutfit = {
        lookType = 269,
        lookHead = 20,
        lookBody = 30,
        lookLegs = 40,
        lookFeet = 50,
        lookAddons = 1,
        lookMount = 377
    }

    if prevOutfit.lookType == 136 then
        addEvent(function(cid, prev)
            local creature = Creature(cid)
            if not creature then
                return
            end
            creature:setOutfit(prev)
        end, 5000, creature:getId(), prevOutfit)

        creature:setOutfit(newOutfit)
    end

    return doCombat(creature, combat, variant)
end

Here is a gif of me testing it using the exura spell:

PZcUcNm.gif


You can see that since I wore outfit 137, it just uses exura without doing anything else.
Now if I change it to 136, it passes the conditional check and changes my outfit so that it looks like a nightmare outfit riding on a hog before changing back to the original outfit 136.
 
Evan Great job but i already posted how to, and he still did not adapt the script. Also why not use conditions like i did here:
http://otland.net/threads/change-outfit.224551/

Ah yeah, both ways work. I'm still a bit old-fashioned for the most part.
And heck, why not teach someone how to do addEvent? I've considered a tutorial, but never got around it.
 
Im trying edit it to, too check if the target have X outfit, if yes change target outfit too to Y, tried that:

function onCastSpell(cid, variant)
if getCreatureOutfit(target).lookType == 128 then
doSetCreatureOutfit(cid, {lookType = 62}, -1)
end

But got error, why im asking it? Im doing outfits of the player character attacking, and the target outfit receiving damage ._.
 
Im trying edit it to, too check if the target have X outfit, if yes change target outfit too to Y, tried that:

function onCastSpell(cid, variant)
if getCreatureOutfit(target).lookType == 128 then
doSetCreatureOutfit(cid, {lookType = 62}, -1)
end

But got error, why im asking it? Im doing outfits of the player character attacking, and the target outfit receiving damage ._.
Code:
function onCastSpell(cid, variant)
local target = getCreatureTarget(cid)

if getCreatureOutfit(target).lookType == 128 then
   doSetCreatureOutfit(target, {lookType = 62}, -1)
   return true
end

Not tested, but should work.
 
Tfs1.1 havent this function dosetcreatureoutfit :(

This is the only function i have in compat.lua with 'outfit':
doCreatureChangeOutfit(cid, outfit)

Tried with it:

function onCastSpell(cid, variant)
local target = getCreatureTarget(cid)

if getCreatureOutfit(target).lookType == 128 then
doCreatureChangeOutfit(target, {lookType = 62}, -1)
return true
end
end

Not working yet
 
Last edited:
Tfs1.1 havent this function dosetcreatureoutfit :(

This is the only function i have in compat.lua with 'outfit':
doCreatureChangeOutfit(cid, outfit)

Tried with it:



Not working yet
You should have say that you need it for TFS 1.1
Code:
local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(-1)
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })

function onCastSpell(creature, var)
local target = creature:getTarget()

    if target:getOutfit().lookType == 128 then
        target:addCondition(condition)
    end
    return true
end
Try this one, still not tested but should work xD.
 
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE)

function onGetFormulaValues(cid, level, maglevel)
min = -((level / 5) + (maglevel * 1.4) + 8)
max = -((level / 5) + (maglevel * 2.2) + 14)
return min, max
end
setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
local prevOutfit = creature:getOutfit()
local newOutfit = {
lookType = 131
}
if prevOutfit.lookType == 128 then
addEvent(function(cid, prev)
local creature = Creature(cid)
if not creature then
return
end
creature:setOutfit(prev)
end, 900, creature:getId(), prevOutfit)

creature:setOutfit(newOutfit)
end


return doCombat(creature, combat, variant)
end

local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(-1)
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })

function onCastSpell(creature, var)
local target = creature:getTarget()

if target:getOutfit().lookType == 128 then
target:addCondition(condition)
end
return true
end

Now it only change the target outfit, but dont change myself outfit and cast the spell
 
Now it only change the target outfit, but dont change myself outfit and cast the spell
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE)

local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(900) -- 900 miliseconds
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })

function onGetFormulaValues(player, level, maglevel)
        min = -((level / 5) + (maglevel * 1.4) + 8)
        max = -((level / 5) + (maglevel * 2.2) + 14)
    return min, max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, var)
    local prevOutfit = creature:getOutfit()
    local newOutfit = {lookType = 131}

    if prevOutfit.lookType == 128 then
        addEvent(function(cid, prev)
            local creature = Creature(cid)
            if not creature then
                return
            end
            creature:setOutfit(prev)
        end, 900, creature:getId(), prevOutfit)

        creature:setOutfit(newOutfit)
       
        local target = creature:getTarget()
        if not target then
            return
        end   
        target:addCondition(condition)
    end

    return combat:execute(creature, var)
end
Try this, I'm not sure if its what you mean, but try it.
 
Worked :D thankyou
Yes it works, but only when you have target lol. this one below should fix this problem \/.
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE)

local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(900) -- 900 miliseconds
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })

function onGetFormulaValues(player, level, maglevel)
        min = -((level / 5) + (maglevel * 1.4) + 8)
        max = -((level / 5) + (maglevel * 2.2) + 14)
    return min, max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, var)
    local prevOutfit = creature:getOutfit()
    local target = creature:getTarget()
    local newOutfit = {lookType = 131}

    if prevOutfit.lookType == 128 and target ~= nil then
        addEvent(function(cid, prev)
            local creature = Creature(cid)
            if not creature then
                return
            end
            creature:setOutfit(prev)
        end, 900, creature:getId(), prevOutfit)

        creature:setOutfit(newOutfit)
      
        if not target then
            return
        end  
        target:addCondition(condition)
        return combat:execute(creature, var)
    else  
    return combat:execute(creature, var)
    end
end
 
Forgot the part to check if the target have the correct outfit.

The spells is changing outfit of any monster who receive it, it should change only if the monster have X looktype
 
I gave you a tutorial up above with a part that shows how to check a creature's looktype.
I was hoping you at least read the post and learned a little bit of something.
 
Who said i dont read? Im still learning about script in lua man

Look, this is the part where we change looktype of target monster.

Code:
target:addCondition(condition)

You said it changes the looktype of every monster who receives it, right? You want it to make sure only monsters with X looktype can change, right?
What can you do? I briefly went over that in my post above. I said, we need a check to see if a creature (in my 2nd post, it was caster; in this case, it needs to be target, right?) has X looktype.

Let's scroll up and see what I said
(by the way, if you didn't read the post, you can do so here: http://otland.net/threads/change-outfit-when-cast-spells-tfs1-1.224767/#post-2162389)

ET84laO.png


creature can be a Creature userdata/metatable, meaning it is an object that represents a creature and has a load of methods (functions).
You can see all kinds of methods (functions) that are available for use here: https://github.com/otland/forgottenserver/wiki/Metatable:Creature

So, to your case, target.
We can see in @Moj mistrz's script that target is defined as such:
Code:
local target = creature:getTarget()

The :getTarget() function returns the target creature, which is more specifically, a Creature userdata/metatable.
Which again, means it is an object that represents a creature and has a load of methods (functions).
You can see all kinds of methods (functions) that are available for use here: https://github.com/otland/forgottenserver/wiki/Metatable:Creature

Just in-case you can't assume that getTarget() returns a creature (if there is such target), then feel free to check the sources in luascript.cpp:
https://github.com/otland/forgottenserver/blob/master/src/luascript.cpp#L7364

Now, up to this point, we know target can be a Creature userdata, which means we can perform a bunch of methods (as linked twice above).
We want to know if this target has X looktype, right?

In my first post, I provided an example of how to check for the looktype of a creature, see picture above.
Or, I can just copy it right here:

Code:
if creature:getOutfit().lookType == X then
end

But we need to change it because we want to get the looktype of target, not creature.

Code:
if target:getOutfit().lookType == X then
end

Now we have a conditional statement that means: if target has X looktype, do this

What is the 'do this' that we wanted to do? We wanted to change the looktype of that target if they have X looktype, right?
In @Moj mistrz's script above, you can find the part where it changes the looktype here:

Code:
target:addCondition(condition)

By the way, just in-case you don't know what the condition we're adding to the target, you can follow the condition definition at the top of his script.
Code:
local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(900) -- 900 miliseconds
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })
This basically is a condition that changes the outfit to looktype 62 for 900 miliseconds.

Okay, so we found the part that changes the target's looktype, we want it so it only happens when the target has X looktype, right?
We figured out that conditional statement here:
Code:
if target:getOutfit().lookType == X then
end

We also found the part that changes the target's outfit here:
Code:
target:addCondition(condition)

We want the latter part inside the conditional statement that way it can only be reached when target has X looktype.
Code:
if target:getOutfit().lookType == X then
    target:addCondition(condition)
end

BAM! KABAM! Simply-doo!

So, as a result, modifying @Moj mistrz's script with the newly added check, we will get:
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE)

local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(900) -- 900 miliseconds
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })

function onGetFormulaValues(player, level, maglevel)
        min = -((level / 5) + (maglevel * 1.4) + 8)
        max = -((level / 5) + (maglevel * 2.2) + 14)
    return min, max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, var)
    local prevOutfit = creature:getOutfit()
    local target = creature:getTarget()
    local newOutfit = {lookType = 131}

    if prevOutfit.lookType == 128 and target ~= nil then
        addEvent(function(cid, prev)
            local creature = Creature(cid)
            if not creature then
                return
            end
            creature:setOutfit(prev)
        end, 900, creature:getId(), prevOutfit)

        creature:setOutfit(newOutfit)
 
        if not target then
            return
        end
        if target:getOutfit().lookType == 128 then
            target:addCondition(condition)
        end
        return combat:execute(creature, var)
    else
    return combat:execute(creature, var)
    end
end

Hope that clears it all for you; any questions, ask.
 
Look, this is the part where we change looktype of target monster.

Code:
target:addCondition(condition)

You said it changes the looktype of every monster who receives it, right? You want it to make sure only monsters with X looktype can change, right?
What can you do? I briefly went over that in my post above. I said, we need a check to see if a creature (in my 2nd post, it was caster; in this case, it needs to be target, right?) has X looktype.

Let's scroll up and see what I said

ET84laO.png


creature can be a Creature userdata/metatable, meaning it is an object that represents a creature and has a load of methods (functions).
You can see all kinds of methods (functions) that are available for use here: https://github.com/otland/forgottenserver/wiki/Metatable:Creature

So, to your case, target.
We can see in @Moj mistrz's script that target is defined as such:
Code:
local target = creature:getTarget()

The :getTarget() function returns the target creature, which is more specifically, a Creature userdata/metatable.
Which again, means it is an object that represents a creature and has a load of methods (functions).
You can see all kinds of methods (functions) that are available for use here: https://github.com/otland/forgottenserver/wiki/Metatable:Creature

Just in-case you can't assume that getTarget() returns a creature (if there is such target), then feel free to check the sources in luascript.cpp:
https://github.com/otland/forgottenserver/blob/master/src/luascript.cpp#L7364

Now, up to this point, we know target can be a Creature userdata, which means we can perform a bunch of methods (as linked twice above).
We want to know if this target has X looktype, right?

In my first post, I provided an example of how to check for the looktype of a creature, see picture above.
Or, I can just copy it right here:

Code:
if creature:getOutfit().lookType == X then
end

But we need to change it because we want to get the looktype of target, not creature.

Code:
if target:getOutfit().lookType == X then
end

Now we have a conditional statement that means: if target has X looktype, do this

What is the 'do this' that we wanted to do? We wanted to change the looktype of that target if they have X looktype, right?
In @Moj mistrz's script above, you can find the part where it changes the looktype here:

Code:
target:addCondition(condition)

By the way, just in-case you don't know what the condition we're adding to the target, you can follow the condition definition at the top of his script.
Code:
local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(900) -- 900 miliseconds
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })
This basically is a condition that changes the outfit to looktype 62 for 900 miliseconds.

Okay, so we found the part that changes the target's looktype, we want it so it only happens when the target has X looktype, right?
We figured out that conditional statement here:
Code:
if target:getOutfit().lookType == X then
end

We also found the part that changes the target's outfit here:
Code:
target:addCondition(condition)

We want the latter part inside the conditional statement that way it can only be reached when target has X looktype.
Code:
if target:getOutfit().lookType == X then
    target:addCondition(condition)
end

BAM! KABAM! Simply-doo!

So, as a result, modifying @Moj mistrz's script with the newly added check, we will get:
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK)
combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLICE)

local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(900) -- 900 miliseconds
condition:setOutfit({lookType = 62, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, lookAddons = 0, lookMount = 0 })

function onGetFormulaValues(player, level, maglevel)
        min = -((level / 5) + (maglevel * 1.4) + 8)
        max = -((level / 5) + (maglevel * 2.2) + 14)
    return min, max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, var)
    local prevOutfit = creature:getOutfit()
    local target = creature:getTarget()
    local newOutfit = {lookType = 131}

    if prevOutfit.lookType == 128 and target ~= nil then
        addEvent(function(cid, prev)
            local creature = Creature(cid)
            if not creature then
                return
            end
            creature:setOutfit(prev)
        end, 900, creature:getId(), prevOutfit)

        creature:setOutfit(newOutfit)
  
        if not target then
            return
        end
        if target:getOutfit().lookType == 128 then
            target:addCondition(condition)
        end
        return combat:execute(creature, var)
    else
    return combat:execute(creature, var)
    end
end

Hope that clears it all for you; any questions, ask.

2 much time writing for someone who doesn't read is not a good trade
 
Back
Top