Action [TFS 1.2] Exercise Weapons

Discovery

Developing myself
Joined
Apr 16, 2010
Messages
310
Best answers
4
Likes
50
Location
Central Circle I, South - Edron
#1
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)




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:
Joined
Dec 4, 2017
Messages
69
Best answers
11
Likes
26
#2
Haven't tested it yet on the server I'm working on, but looks good.
Thanks for this.
 

reddit1

Experienced G'
Joined
May 27, 2014
Messages
237
Best answers
0
Likes
32
Location
Bosnia
#3
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)




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!
 

hellboy

Active Member
Joined
Apr 6, 2008
Messages
392
Best answers
3
Likes
52
Location
getPlayerTown (getCreatureByName("Hellboy"))
#5
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
--- [...]
 

Stigma

Well-Known Member
Joined
Feb 14, 2015
Messages
4,363
Best answers
356
Likes
1,938
#8
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
 

oualid6496

Premium User
Premium User
Joined
Aug 24, 2014
Messages
340
Best answers
0
Likes
51
Location
Dordrecht, The Netherlands
#9
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)




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.
 
Joined
Sep 11, 2018
Messages
61
Best answers
1
Likes
6
#10
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)




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?
 
Joined
Dec 4, 2017
Messages
69
Best answers
11
Likes
26
#13
Are you inside a PZ? I get this message when I am not in PZ and testing it.
 

erick12

New Member
Joined
May 21, 2018
Messages
7
Best answers
0
Likes
1
#17
How can I make it attack many times?

I installed it but I can only use it once for each item
 
Joined
Dec 4, 2017
Messages
69
Best answers
11
Likes
26
#18
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
 
Top