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

Action [TFS 1.2] Exercise Weapons

Discovery

Developing myself
Joined
Apr 16, 2010
Messages
561
Solutions
11
Reaction score
262
Location
Neverland
Hello guys, this is the first version of the new exercise weapons script!

Feel free to help to make suggestions :)
If you no have this new sprites, use another.. no have difference (like wooden dummy)

jkujujA.gif



Create the file exercise_training.lua

Lua:
local skills = {
    [26397] = {id=SKILL_SWORD,voc=4},
    [26398] = {id=SKILL_AXE,voc=4},
    [26399] = {id=SKILL_CLUB,voc=4},
    [26400] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW},
    [26401] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_ENERGY},
    [26402] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE},
}

------- CONFIG -----//
local dummies = {26403,26404}
local skill_gain = 1 -- per hit
local gain_stamina = 60

local function start_train(pid,start_pos,itemid,fpos)
    local player = Player(pid)
    if player ~= nil then
        local pos_n = player:getPosition()

        if start_pos:getDistance(pos_n) == 0 and getTilePzInfo(pos_n) then
            if player:getItemCount(itemid) >= 1 then
                local exercise = player:getItemById(itemid,true)

                if exercise:isItem() then
                    if exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then
                        local charges_n = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES)

                        if charges_n >= 1 then
                            exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES, (charges_n-1))

                            local required = 0
                            local currently = 0
                            local voc = player:getVocation()

                            if skills[itemid].id == SKILL_MAGLEVEL then
                                required = voc:getRequiredManaSpent(player:getBaseMagicLevel() + 1)/skill_gain
                                currently = player:getManaSpent()
                                player:addManaSpent(required - currently)
                            else
                                required = voc:getRequiredSkillTries(skills[itemid].id, player:getSkillLevel(skills[itemid].id)+1)/skill_gain
                                currently = player:getSkillTries(skills[itemid].id)

                                player:addSkillTries(skills[itemid].id, (required - currently))
                            end

                            fpos:sendMagicEffect(CONST_ME_HITAREA)
                            if skills[itemid].range then
                                pos_n:sendDistanceEffect(fpos, skills[itemid].range)
                            end
                            player:setStamina(player:getStamina() + 60)

                            if charges_n == 1 then
                                exercise:remove(1)
                                return true
                            end
                            local training = addEvent(start_train, voc:getAttackSpeed(), pid,start_pos,itemid,fpos)
                        else
                            exercise:remove(1)
                            stopEvent(training)
                        end
                    end
                end
            end
        else
            stopEvent(training)
        end
    else
        stopEvent(training)
    end
    return true
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local start_pos = player:getPosition()

    if target:isItem() then
        if isInArray(dummies,target:getId()) then
            if not skills[item.itemid].range and (start_pos:getDistance(target:getPosition()) > 1) then
                stopEvent(training)
                return false
            end
            if not player:getVocation():getId() == skills[item.itemid].voc or not player:getVocation():getId() == (skills[item.itemid].voc+4) then
                stopEvent(training)
                return false
            end
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You started training.")
            start_train(player:getId(),start_pos,item.itemid,target:getPosition())
        end
    end

    return true
end

Added this line in actions.xml
XML:
<!-- Training -->
<action fromid="26397" toid="26402" script="exercise_training.lua" allowfaruse="1"/>

In events.xml

- You will change enable="0" to "1".
XML:
<event class="Player" method="onTradeRequest" enabled="1" />

In /events/scripts/player.lua
Added this lines in the top of the file
Lua:
local exercise_ids = {26397,26398,26399,26400,26401,26402}

- Go to the function function Player::onMoveItem added this lines in the top.
Lua:
-- Exercise Weapons
if isInArray(exercise_ids,item.itemid) then
    self:sendCancelMessage('You cannot move this item outside this container.')
    return false
end

- Go to the function function Player::onTradeRequest added this lines in the top.
Lua:
if isInArray(exercise_ids,item.itemid) then
    return false
end

Have fun!
 
Last edited by a moderator:
Haven't tested it yet on the server I'm working on, but looks good.
Thanks for this.
 
Hello guys, this is the first version of the new exercise weapons script!

Feel free to help to make suggestions :)
If you no have this new sprites, use another.. no have difference (like wodden dummy)

jkujujA.gif



Create the file exercise_training.lua

Lua:
local skills = {
    [26397] = {id=SKILL_SWORD,voc=4},
    [26398] = {id=SKILL_AXE,voc=4},
    [26399] = {id=SKILL_CLUB,voc=4},
    [26400] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW},
    [26401] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_ENERGY},
    [26402] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE},
}

------- CONFIG -----//
local dummies = {26403,26404}
local skill_gain = 1 -- per hit
local gain_stamina = 60

local function start_train(pid,start_pos,itemid,fpos)
    local player = Player(pid)
    if player ~= nil then
        local pos_n = player:getPosition()

        if start_pos:getDistance(pos_n) == 0 and getTilePzInfo(pos_n) then
            if player:getItemCount(itemid) >= 1 then
                local exercise = player:getItemById(itemid,true)

                if exercise:isItem() then
                    if exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then
                        local charges_n = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES)

                        if charges_n >= 1 then
                            exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES, (charges_n-1))

                            local required = 0
                            local currently = 0
                            local voc = player:getVocation()

                            if skills[itemid].id == SKILL_MAGLEVEL then
                                required = voc:getRequiredManaSpent(player:getBaseMagicLevel() + 1)/skill_gain
                                currently = player:getManaSpent()
                                player:addManaSpent(required - currently)
                            else
                                required = voc:getRequiredSkillTries(skills[itemid].id, player:getSkillLevel(skills[itemid].id)+1)/skill_gain
                                currently = player:getSkillTries(skills[itemid].id)

                                player:addSkillTries(skills[itemid].id, (required - currently))
                            end

                            fpos:sendMagicEffect(CONST_ME_HITAREA)
                            if skills[itemid].range then
                                pos_n:sendDistanceEffect(fpos, skills[itemid].range)
                            end
                            player:setStamina(player:getStamina() + 60)

                            if charges_n == 1 then
                                exercise:remove(1)
                                return true
                            end
                            local training = addEvent(start_train, voc:getAttackSpeed(), pid,start_pos,itemid,fpos)
                        else
                            exercise:remove(1)
                            stopEvent(training)
                        end
                    end
                end
            end
        else
            stopEvent(training)
        end
    else
        stopEvent(training)
    end
    return true
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local start_pos = player:getPosition()

    if target:isItem() then
        if isInArray(dummies,target:getId()) then
            if not skills[item.itemid].range and (start_pos:getDistance(target:getPosition()) > 1) then
                stopEvent(training)
                return false
            end
            if not player:getVocation():getId() == skills[item.itemid].voc or not player:getVocation():getId() == (skills[item.itemid].voc+4) then
                stopEvent(training)
                return false
            end
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You started training.")
            start_train(player:getId(),start_pos,item.itemid,target:getPosition())
        end
    end

    return true
end

Added this line in actions.xml
Lua:
    <!-- Training -->
    <action fromid="26397" toid="26402" script="exercise_training.lua" allowfaruse="1"/>

In events.xml

- You will change enable="0" to "1".
Lua:
    <event class="Player" method="onTradeRequest" enabled="1" />

In /events/scripts/player.lua
Added this lines in the top of the file
Lua:
local exercise_ids = {26397,26398,26399,26400,26401,26402}

- Go to the function function Player:eek:nMoveItem added this lines in the top.
Lua:
    -- Exercise Weapons
    if isInArray(exercise_ids,item.itemid) then
        self:sendCancelMessage('You cannot move this item outside this container.')
        return false
    end

- Go to the function function Player:eek:nTradeRequest added this lines in the top.
Lua:
if isInArray(exercise_ids,item.itemid) then
        return false
    end

Have fun!
Wow.. this is looking great! Keep up the good work!
 
It's nice.

Think about "early exit" in functions. There are more readable in that way.

Code:
--- [...]
  local player = Player(pid)
  if player == nil then
    stopEvent(training)
    return true
  end

  local pos_n = player:getPosition()
  if start_pos:getDistance(pos_n) ~= 0 or not getTilePzInfo(pos_n) then
    stopEvent(training)
    return true
  end

  if player:getItemCount(itemid) == 0 then
    return true
  end
--- [...]
 
Thank you @hellboy !

I rewrite the code after this version and removed a lot of insecurity parts and wrong code architectures
Now I can't edit this post .. but your suggestion is pretty excellent!
 
Thank you @hellboy !

I rewrite the code after this version and removed a lot of insecurity parts and wrong code architectures
Now I can't edit this post .. but your suggestion is pretty excellent!
report your post with a pastebin link with the new code requesting an update, the mods will update your main post with the new code
 
Hello guys, this is the first version of the new exercise weapons script!

Feel free to help to make suggestions :)
If you no have this new sprites, use another.. no have difference (like wodden dummy)

jkujujA.gif



Create the file exercise_training.lua

Lua:
local skills = {
    [26397] = {id=SKILL_SWORD,voc=4},
    [26398] = {id=SKILL_AXE,voc=4},
    [26399] = {id=SKILL_CLUB,voc=4},
    [26400] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW},
    [26401] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_ENERGY},
    [26402] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE},
}

------- CONFIG -----//
local dummies = {26403,26404}
local skill_gain = 1 -- per hit
local gain_stamina = 60

local function start_train(pid,start_pos,itemid,fpos)
    local player = Player(pid)
    if player ~= nil then
        local pos_n = player:getPosition()

        if start_pos:getDistance(pos_n) == 0 and getTilePzInfo(pos_n) then
            if player:getItemCount(itemid) >= 1 then
                local exercise = player:getItemById(itemid,true)

                if exercise:isItem() then
                    if exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then
                        local charges_n = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES)

                        if charges_n >= 1 then
                            exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES, (charges_n-1))

                            local required = 0
                            local currently = 0
                            local voc = player:getVocation()

                            if skills[itemid].id == SKILL_MAGLEVEL then
                                required = voc:getRequiredManaSpent(player:getBaseMagicLevel() + 1)/skill_gain
                                currently = player:getManaSpent()
                                player:addManaSpent(required - currently)
                            else
                                required = voc:getRequiredSkillTries(skills[itemid].id, player:getSkillLevel(skills[itemid].id)+1)/skill_gain
                                currently = player:getSkillTries(skills[itemid].id)

                                player:addSkillTries(skills[itemid].id, (required - currently))
                            end

                            fpos:sendMagicEffect(CONST_ME_HITAREA)
                            if skills[itemid].range then
                                pos_n:sendDistanceEffect(fpos, skills[itemid].range)
                            end
                            player:setStamina(player:getStamina() + 60)

                            if charges_n == 1 then
                                exercise:remove(1)
                                return true
                            end
                            local training = addEvent(start_train, voc:getAttackSpeed(), pid,start_pos,itemid,fpos)
                        else
                            exercise:remove(1)
                            stopEvent(training)
                        end
                    end
                end
            end
        else
            stopEvent(training)
        end
    else
        stopEvent(training)
    end
    return true
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local start_pos = player:getPosition()

    if target:isItem() then
        if isInArray(dummies,target:getId()) then
            if not skills[item.itemid].range and (start_pos:getDistance(target:getPosition()) > 1) then
                stopEvent(training)
                return false
            end
            if not player:getVocation():getId() == skills[item.itemid].voc or not player:getVocation():getId() == (skills[item.itemid].voc+4) then
                stopEvent(training)
                return false
            end
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You started training.")
            start_train(player:getId(),start_pos,item.itemid,target:getPosition())
        end
    end

    return true
end

Added this line in actions.xml
Lua:
    <!-- Training -->
    <action fromid="26397" toid="26402" script="exercise_training.lua" allowfaruse="1"/>

In events.xml

- You will change enable="0" to "1".
Lua:
    <event class="Player" method="onTradeRequest" enabled="1" />

In /events/scripts/player.lua
Added this lines in the top of the file
Lua:
local exercise_ids = {26397,26398,26399,26400,26401,26402}

- Go to the function function Player:eek:nMoveItem added this lines in the top.
Lua:
    -- Exercise Weapons
    if isInArray(exercise_ids,item.itemid) then
        self:sendCancelMessage('You cannot move this item outside this container.')
        return false
    end

- Go to the function function Player:eek:nTradeRequest added this lines in the top.
Lua:
if isInArray(exercise_ids,item.itemid) then
        return false
    end

Have fun!
Nice! Gonna test it out for sure.
 
Hello guys, this is the first version of the new exercise weapons script!

Feel free to help to make suggestions :)
If you no have this new sprites, use another.. no have difference (like wodden dummy)

jkujujA.gif



Create the file exercise_training.lua

Lua:
local skills = {
    [26397] = {id=SKILL_SWORD,voc=4},
    [26398] = {id=SKILL_AXE,voc=4},
    [26399] = {id=SKILL_CLUB,voc=4},
    [26400] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW},
    [26401] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_ENERGY},
    [26402] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE},
}

------- CONFIG -----//
local dummies = {26403,26404}
local skill_gain = 1 -- per hit
local gain_stamina = 60

local function start_train(pid,start_pos,itemid,fpos)
    local player = Player(pid)
    if player ~= nil then
        local pos_n = player:getPosition()

        if start_pos:getDistance(pos_n) == 0 and getTilePzInfo(pos_n) then
            if player:getItemCount(itemid) >= 1 then
                local exercise = player:getItemById(itemid,true)

                if exercise:isItem() then
                    if exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then
                        local charges_n = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES)

                        if charges_n >= 1 then
                            exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES, (charges_n-1))

                            local required = 0
                            local currently = 0
                            local voc = player:getVocation()

                            if skills[itemid].id == SKILL_MAGLEVEL then
                                required = voc:getRequiredManaSpent(player:getBaseMagicLevel() + 1)/skill_gain
                                currently = player:getManaSpent()
                                player:addManaSpent(required - currently)
                            else
                                required = voc:getRequiredSkillTries(skills[itemid].id, player:getSkillLevel(skills[itemid].id)+1)/skill_gain
                                currently = player:getSkillTries(skills[itemid].id)

                                player:addSkillTries(skills[itemid].id, (required - currently))
                            end

                            fpos:sendMagicEffect(CONST_ME_HITAREA)
                            if skills[itemid].range then
                                pos_n:sendDistanceEffect(fpos, skills[itemid].range)
                            end
                            player:setStamina(player:getStamina() + 60)

                            if charges_n == 1 then
                                exercise:remove(1)
                                return true
                            end
                            local training = addEvent(start_train, voc:getAttackSpeed(), pid,start_pos,itemid,fpos)
                        else
                            exercise:remove(1)
                            stopEvent(training)
                        end
                    end
                end
            end
        else
            stopEvent(training)
        end
    else
        stopEvent(training)
    end
    return true
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local start_pos = player:getPosition()

    if target:isItem() then
        if isInArray(dummies,target:getId()) then
            if not skills[item.itemid].range and (start_pos:getDistance(target:getPosition()) > 1) then
                stopEvent(training)
                return false
            end
            if not player:getVocation():getId() == skills[item.itemid].voc or not player:getVocation():getId() == (skills[item.itemid].voc+4) then
                stopEvent(training)
                return false
            end
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You started training.")
            start_train(player:getId(),start_pos,item.itemid,target:getPosition())
        end
    end

    return true
end

Added this line in actions.xml
Lua:
    <!-- Training -->
    <action fromid="26397" toid="26402" script="exercise_training.lua" allowfaruse="1"/>

In events.xml

- You will change enable="0" to "1".
Lua:
    <event class="Player" method="onTradeRequest" enabled="1" />

In /events/scripts/player.lua
Added this lines in the top of the file
Lua:
local exercise_ids = {26397,26398,26399,26400,26401,26402}

- Go to the function function Player:eek:nMoveItem added this lines in the top.
Lua:
    -- Exercise Weapons
    if isInArray(exercise_ids,item.itemid) then
        self:sendCancelMessage('You cannot move this item outside this container.')
        return false
    end

- Go to the function function Player:eek:nTradeRequest added this lines in the top.
Lua:
if isInArray(exercise_ids,item.itemid) then
        return false
    end

Have fun!
Just tested it out and I was wondering if it's supposed to give 1 level on each attack? That seems a bit OP would it be possible to make it a bit more like rl tibia that every attack is like you wasted aprox 610 mana?
 
Are you inside a PZ? I get this message when I am not in PZ and testing it.
 
How can I make it attack many times?

I installed it but I can only use it once for each item
 
You mean it shoots once?

Because it is it set to keep shooting using attackspeed.
The only problem is if you hotkey it you can mass shoot the full wand in no time at all.
trainingrod.gif
 
Back
Top