• 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+ TFS 1.5 - Exercise Training

Forkz

Intermediate OT User
Joined
Jun 29, 2020
Messages
528
Solutions
16
Reaction score
129
Hi otlanders,

My physical training script is only checking to attack on the next attack, I would like it to stop attacking when the player moves, is there a function for this?

For example, if the player moves he will immediately stop attacking.

LUA:
local skills = {
    [5132] = {id = SKILL_SWORD, voc = {4}}, -- KNIGHT
    [5130] = {id = SKILL_AXE, voc = {4}}, -- KNIGHT
    [5131] = {id = SKILL_CLUB, voc = {4}}, -- KNIGHT
    [5129] = {id = SKILL_DISTANCE, voc = {3}, range = CONST_ANI_ARROW}, -- PALADIN
    [5133] = {id = SKILL_MAGLEVEL, voc = {1, 2, 3, 4}, range = CONST_ANI_SMALLICE}, -- DRUID
    [5134] = {id = SKILL_MAGLEVEL, voc = {1, 2, 3, 4}, range = CONST_ANI_FIRE}, -- SORCERER
    [5135] = {id = SKILL_SHIELD, voc = {1, 2, 3, 4}}, -- SHIELD
}

local dummies = {5136, 5137, 5138, 5139, 5140, 5141, 5142, 5143}
local house_dummies = {5138, 5139, 5140, 5141, 5142, 5143}

local function start_train(pid, start_pos, itemid, fpos, t_id)
    local player = Player(pid)
    if not player then return end

    local baseSkillRate = configManager.getNumber(configKeys.RATE_SKILL)
    local baseMagicRate = configManager.getNumber(configKeys.RATE_MAGIC)

    local skillRate = baseSkillRate
    local magicRate = baseMagicRate

    if isInArray(dummies, t_id) then
        if isInArray(house_dummies, t_id) then
            skillRate = skillRate * 1.3
            magicRate = magicRate * 1.3
        else
            skillRate = skillRate * 1.1
            magicRate = magicRate * 1.1
        end
    end

    local skillType = skills[itemid].id
    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 and exercise:isItem() and exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then
                local charges = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES)
                if charges >= 1 then

                    -- Checar se dummy ainda está no lugar ANTES de aplicar o treino
                    local target = Tile(fpos):getItemById(t_id)
                    if not target then
                        player:sendCancelMessage("Someone has moved the dummy, the training has stopped.")
                        stopEvent(player:getStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent))
                        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, -1)
                        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 0)
                        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, -1)
                        return true
                    end

                    -- Consumir carga
                    exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES, charges - 1)

                    -- Aplicar treino
                    if skillType == SKILL_MAGLEVEL then
                        player:addManaSpent(math.ceil(250 * magicRate))
                    elseif skillType == SKILL_SHIELD then
                        player:addSkillTries(skillType, 1 * skillRate)
                    else
                        player:addSkillTries(skillType, 1 * skillRate)
                    end

                    fpos:sendMagicEffect(CONST_ME_HITAREA)
                    if skills[itemid].range then
                        pos_n:sendDistanceEffect(fpos, skills[itemid].range)
                    end

                    -- Última carga
                    if charges == 1 then
                        player:sendCancelMessage("Your training weapon vanished.")
                        stopEvent(player:getStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent))
                        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, -1)
                        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 0)
                        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, -1)
                        exercise:remove(1)
                        return true
                    end

                    -- Repetir treino
                    local attackSpeed = player:getVocation():getAttackSpeed()
                    local training = addEvent(start_train, attackSpeed, pid, start_pos, itemid, fpos, t_id)
                    player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 1)
                    player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, training)
                    player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, 1)
                end
            end
        end
    else
        player:sendCancelMessage("Your training has stopped.")
        stopEvent(player:getStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent))
        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, -1)
        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 0)
        player:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, -1)
    end
    return true
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if target:isItem() and isInArray(dummies, target:getId()) then
        local itemid = item:getId()
        if not skills[itemid] then return true end

        local start_pos = player:getPosition()
        if not isInArray(skills[itemid].voc, player:getVocation():getBase():getId()) then
            player:sendCancelMessage("You don't train with this weapon.")
            return true
        end

        if skills[itemid].range == nil and start_pos:getDistance(target:getPosition()) > 1 then
            player:sendCancelMessage("Get closer to the dummy.")
            return true
        end

        if player:getStorageValue(PlayerStorageKeys.exerciseDummy.isTraining) == 1 then
            player:sendCancelMessage("You are already training.")
            return true
        end

        player:sendCancelMessage("You have started training on an exercise dummy.")
        start_train(player:getId(), start_pos, itemid, target:getPosition(), target:getId())
    end
    return true
end
 
Solution
To solve this problem, I had to create the onStepTile event
HTML:
https://github.com/search?q=repo%3Amoviebr%2FTFS-1.5-Downgrades%20onStepTile&type=code

player.lua

LUA:
function Player:onStepTile(fromPosition, toPosition)
    -- Exercise Training
    if self:getStorageValue(PlayerStorageKeys.exerciseDummy.isTraining) == 1 then
        stopEvent(self:getStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent))
        self:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, -1)
        self:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 0)
        self:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, -1)
        self:sendCancelMessage("Your training has stopped.")
    end

    local...
Ye, just compare position and stop event if they are not matching
This comparison already exists, but it only checks when the player attacks the dummy again, but I would like the event to be canceled as soon as the player moves, understand?
Post automatically merged:

This function exists but I don't know how to use it and where to use it.

LUA:
function Player:onMoveCreature(creature, fromPosition, toPosition)
    if hasEventCallback(EVENT_CALLBACK_ONMOVECREATURE) then
        return EventCallback(EVENT_CALLBACK_ONMOVECREATURE, self, creature, fromPosition, toPosition)
    end
    return true
end


LUA:
function onMoveCreature(creature, fromPosition, toPosition)
    if not creature:isPlayer() then
        return true
    end

    if creature:getStorageValue(PlayerStorageKeys.exerciseDummy.isTraining) == 1 then
        creature:sendCancelMessage("You moved and stopped training.")
        stopEvent(creature:getStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent))
        creature:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, -1)
        creature:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 0)
        creature:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, -1)
    end
    return true
end
 
Last edited:
To solve this problem, I had to create the onStepTile event
HTML:
https://github.com/search?q=repo%3Amoviebr%2FTFS-1.5-Downgrades%20onStepTile&type=code

player.lua

LUA:
function Player:onStepTile(fromPosition, toPosition)
    -- Exercise Training
    if self:getStorageValue(PlayerStorageKeys.exerciseDummy.isTraining) == 1 then
        stopEvent(self:getStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent))
        self:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingEvent, -1)
        self:setStorageValue(PlayerStorageKeys.exerciseDummy.isTraining, 0)
        self:setStorageValue(PlayerStorageKeys.exerciseDummy.isTrainingStorage, -1)
        self:sendCancelMessage("Your training has stopped.")
    end

    local onStepTile = EventCallback.onStepTile
    if onStepTile then
        return onStepTile(self, fromPosition, toPosition)
    end
    return true
end
 
Solution

Similar threads

Back
Top