• 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+ Help with refactoring code

mackerel

Well-Known Member
Joined
Apr 26, 2017
Messages
398
Solutions
18
Reaction score
72
I would be so grateful if someone could help me with this code, it seems really hard for me to figure it out.

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, pos, iteration)
    local player = Player(cid)
    player:teleportTo(pos, false) -- pos[iteration]?
  
    return true
end

function onCastSpell(cid, var)
    local player = Player(cid)
  
    local moveToPos = player:getPosition()
    local playerDirection = player:getDirection()

    if playerDirection == SOUTH then
        moveToPos.y = moveToPos.y + 0
    elseif playerDirection == NORTH then
        moveToPos.y = moveToPos.y - 0
    elseif playerDirection == WEST then
        moveToPos.x = moveToPos.x - 0
    elseif playerDirection == EAST then
        moveToPos.x = moveToPos.x + 0
    end
  
    addEvent(movePlayer, 1000, player:getId(), moveToPos, 1)
    addEvent(movePlayer, 2000, player:getId(), moveToPos, 2)
    addEvent(movePlayer, 3000, player:getId(), moveToPos, 3)
  
    return combat:execute(cid, var)
end

As you can see, onCastSpell is getting the player position and its direction. It will then teleport the player to 1 square forward.

I do not want to use if statements in movePlayer function because I think it will not be properly structured, there is no need to check what direction the player is facing every time, it can be checked once during the onCastSpell and, there is no need to get the position each time.

So, to improve the code I wanted to use iteration numbers (0 - in if statements, and 1, 2, 3 in addEvent)

The movePlayer meant to push the player into the right position, depending on which addEvent is currently running, as you can see the number is increasing so it will look like the player is walking.

But that is point where I am stuck and completely clueless if it's actually possible to do it without another set of if statements in movePlayer function.

Any help appreciated :(
 
Solution
You could take advantage of Position.getNextPosition.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, direction, executions, maxExecutions)
    local player = Player(cid)
    if not player then
        return
    end

    local position = player:getPosition()
    position:getNextPosition(direction)

    player:teleportTo(position)
    position:sendMagicEffect(CONST_ME_TELEPORT)

    executions = executions + 1
    if executions < maxExecutions then
        addEvent(movePlayer, 1000, cid, direction, executions, maxExecutions)
    end
end

function onCastSpell(creature, var)
    addEvent(movePlayer, 1000, creature:getId(), creature:getDirection(), 0, 3)
    return...
first of all, add check if player still exist in movePlayer func.

then

If you want any help, please provide what you want to achive.

Currently you have spell that checks players pos once and for constans computed positions force him to move (teleport) there no matter what will happend in next 3 seconds.

We cant help you as long as you dont tell us what you want to have in the end
 
first of all, add check if player still exist in movePlayer func.

then

If you want any help, please provide what you want to achive.

Currently you have spell that checks players pos once and for constans computed positions force him to move (teleport) there no matter what will happend in next 3 seconds.

We cant help you as long as you dont tell us what you want to have in the end

I want the player to move 3 squares from their original position to the position they are facing

We can have if statements in movePlayer function but that's something I tried to avoid
 
I would be so grateful if someone could help me with this code, it seems really hard for me to figure it out.

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, pos, iteration)
    local player = Player(cid)
    player:teleportTo(pos, false) -- pos[iteration]?
 
    return true
end

function onCastSpell(cid, var)
    local player = Player(cid)
 
    local moveToPos = player:getPosition()
    local playerDirection = player:getDirection()

    if playerDirection == SOUTH then
        moveToPos.y = moveToPos.y + 0
    elseif playerDirection == NORTH then
        moveToPos.y = moveToPos.y - 0
    elseif playerDirection == WEST then
        moveToPos.x = moveToPos.x - 0
    elseif playerDirection == EAST then
        moveToPos.x = moveToPos.x + 0
    end
 
    addEvent(movePlayer, 1000, player:getId(), moveToPos, 1)
    addEvent(movePlayer, 2000, player:getId(), moveToPos, 2)
    addEvent(movePlayer, 3000, player:getId(), moveToPos, 3)
 
    return combat:execute(cid, var)
end

As you can see, onCastSpell is getting the player position and its direction. It will then teleport the player to 1 square forward.

I do not want to use if statements in movePlayer function because I think it will not be properly structured, there is no need to check what direction the player is facing every time, it can be checked once during the onCastSpell and, there is no need to get the position each time.

So, to improve the code I wanted to use iteration numbers (0 - in if statements, and 1, 2, 3 in addEvent)

The movePlayer meant to push the player into the right position, depending on which addEvent is currently running, as you can see the number is increasing so it will look like the player is walking.

But that is point where I am stuck and completely clueless if it's actually possible to do it without another set of if statements in movePlayer function.

Any help appreciated :(
Hello.

try this: you can put an array like:

Code:
currentpos = player:getPosition()
MoveArray = {
[SOUTH] = {currentpos.x, currentpos.y+1, currentpos.z},
[NORTH] = {currentpos.x, currentpos.y-1, currentpos.z},
[WEST] = {currentpos.x+1, currentpos.y, currentpos.z},
[EAST] = {currentpos.x-1, currentpos.y, currentpos.z}
} 
addevent(moveplayer,1000,MoveArray[player:getDirection()])


I think you get the idea
 
Hello.

try this: you can put an array like:

Code:
currentpos = player:getPosition()
MoveArray = {
[SOUTH] = {currentpos.x, currentpos.y+1, currentpos.z},
[NORTH] = {currentpos.x, currentpos.y-1, currentpos.z},
[WEST] = {currentpos.x+1, currentpos.y, currentpos.z},
[EAST] = {currentpos.x-1, currentpos.y, currentpos.z}
}
addevent(moveplayer,1000,MoveArray[player:getDirection()])


I think you get the idea

Hi, it's completely the same as mine. It's only teleporting the player once because it needs to increase the number 1 somehow

This is what I used

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, pos)
    local player = Player(cid)
   
    player:teleportTo(pos, false)
   
    return true
end

function onCastSpell(cid, var)
    local player = Player(cid)
   
    local moveToPos = player:getPosition()
    local playerDirection = player:getDirection()

    MoveArray = {
        [SOUTH] = Position(moveToPos.x, moveToPos.y + 1, moveToPos.z),
        [NORTH] = Position(moveToPos.x, moveToPos.y - 1, moveToPos.z),
        [WEST] = Position(moveToPos.x - 1, moveToPos.y, moveToPos.z),
        [EAST] = Position(moveToPos.x + 1, moveToPos.y, moveToPos.z)
    }

    addEvent(movePlayer, 1000, player:getId(), MoveArray[playerDirection])
    addEvent(movePlayer, 2000, player:getId(), MoveArray[playerDirection])
    addEvent(movePlayer, 3000, player:getId(), MoveArray[playerDirection])
   
    return combat:execute(cid, var)
end
 
ofc becouse it check the position only once on spell cast, you need to place it in event to work properly, also i dont know what you want to achive with avoiding if statements in movePlayer but you need them anyway to check player exist and check the teleporting position is walkable and isn't pz
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)
local function movePlayer(cid)
    local player = Player(cid)
 
    local moveToPos = player:getPosition()
    local playerDirection = player:getDirection()
    MoveArray = {
        [SOUTH] = Position(moveToPos.x, moveToPos.y + 1, moveToPos.z),
        [NORTH] = Position(moveToPos.x, moveToPos.y - 1, moveToPos.z),
        [WEST] = Position(moveToPos.x - 1, moveToPos.y, moveToPos.z),
        [EAST] = Position(moveToPos.x + 1, moveToPos.y, moveToPos.z)
    }
 
    player:teleportTo(MoveArray[playerDirection], false)
 
    return true
end
function onCastSpell(cid, var)
    local player = Player(cid)
 
    addEvent(movePlayer, 0, player:getId())
    addEvent(movePlayer, 1000, player:getId())
    addEvent(movePlayer, 2000, player:getId())
 
    return combat:execute(cid, var)
end
if you want to stick to the same direction as on cast, get playerDirection on cast and insert to movePlayer
 
Well then replace the +1 or -1 to +3 or -3?

Then its going to be fixed value again :D, it needs to go like 1 -> 2 -> 3

ofc becouse it check the position only once on spell cast, you need to place it in event to work properly, also i dont know what you want to achive with avoiding if statements in movePlayer but you need them anyway to check player exist and check the teleporting position is walkable and isn't pz
Code:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)
local function movePlayer(cid)
    local player = Player(cid)
 
    local moveToPos = player:getPosition()
    local playerDirection = player:getDirection()
    MoveArray = {
        [SOUTH] = Position(moveToPos.x, moveToPos.y + 1, moveToPos.z),
        [NORTH] = Position(moveToPos.x, moveToPos.y - 1, moveToPos.z),
        [WEST] = Position(moveToPos.x - 1, moveToPos.y, moveToPos.z),
        [EAST] = Position(moveToPos.x + 1, moveToPos.y, moveToPos.z)
    }
 
    player:teleportTo(MoveArray[playerDirection], false)
 
    return true
end
function onCastSpell(cid, var)
    local player = Player(cid)
 
    addEvent(movePlayer, 0, player:getId())
    addEvent(movePlayer, 1000, player:getId())
    addEvent(movePlayer, 2000, player:getId())
 
    return combat:execute(cid, var)
end
if you want to stick to the same direction as on cast, get playerDirection on cast and insert to movePlayer

haha its something I tried to avoid doing. Just making the code better I guess. Right now, you are assigning values to the table each time it's executed. And yeah you need if statement for the player and check whether its walkable. It's just the table values that I am curious about
 
You could take advantage of Position.getNextPosition.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, direction, executions, maxExecutions)
    local player = Player(cid)
    if not player then
        return
    end

    local position = player:getPosition()
    position:getNextPosition(direction)

    player:teleportTo(position)
    position:sendMagicEffect(CONST_ME_TELEPORT)

    executions = executions + 1
    if executions < maxExecutions then
        addEvent(movePlayer, 1000, cid, direction, executions, maxExecutions)
    end
end

function onCastSpell(creature, var)
    addEvent(movePlayer, 1000, creature:getId(), creature:getDirection(), 0, 3)
    return combat:execute(creature, var)
end
 
Solution
You could take advantage of Position.getNextPosition.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, direction, executions, maxExecutions)
    local player = Player(cid)
    if not player then
        return
    end

    local position = player:getPosition()
    position:getNextPosition(direction)

    player:teleportTo(position)
    position:sendMagicEffect(CONST_ME_TELEPORT)

    executions = executions + 1
    if executions < maxExecutions then
        addEvent(movePlayer, 1000, cid, direction, executions, maxExecutions)
    end
end

function onCastSpell(creature, var)
    addEvent(movePlayer, 1000, creature:getId(), creature:getDirection(), 0, 3)
    return combat:execute(creature, var)
end

Omg so Coool!

Though you are assigning position in movePlayer each time. Here is the one I was looking for

Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local function movePlayer(cid, pos, dir)
    local player = Player(cid)
    if not player then
        return false
    end
   
    pos:getNextPosition(dir)
    player:teleportTo(pos, false)
   
    addEvent(movePlayer, 1000, cid, pos, dir)
   
    return true
end

function onCastSpell(cid, var)
    local player = Player(cid)

    addEvent(movePlayer, 1000, player:getId(), player:getPosition(), player:getDirection())
   
    return combat:execute(cid, var)
end
 
Back
Top