• 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 [TFS 1.0] NPC walking to position

El605

New Member
Joined
Jul 7, 2014
Messages
10
Reaction score
0
I want to create a NPC walking to given position. I started from moving 1 sqm, but it doesn't work. Here is a full code:
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

function onCreatureSay(cid, type, msg)  npcHandler:onCreatureSay(cid, type, msg)  end
function onThink()  npcHandler:onThink()  end

function creatureSayCallback(cid, type, msg)
    if (msgcontains(msg, 'go')) then
        selfSay("Yes, Sir!")
        local pos = getCreaturePosition(getNpcCid())
        pos.x = pos.x + 1
        selfMoveTo(pos)
        -- I tried also moveToPosition(pos)
   end
return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
After greeting and saying "go", NPC says "Yes, Sir!" and still stands (no erros in console).

Of course, I'd like to move NPC for longer distance. I searched and found this thread. However there is used
doSteerCreature function, which doesn't exists.

Any tips?
 
Both work correctly, but only for 1 sqm (I mean using doTeleportThing like moving, so I can move only 1 sqm for push effect). Something for longer distance?
 
You can do something like this
Code:
function doMoveCreature(cid, fromPos, toPos, state)
     local toPosState = toPos[state]
     if not toPosState then
         return false
     end
     if fromPos.y == toPosState.y then
         fromPos.x = fromPos.x > toPosState.x and fromPos.x - 1 or (fromPos.x < toPosState.x and fromPos.x + 1 or fromPos.x)
     else
         fromPos.y = fromPos.y > toPosState.y and fromPos.y - 1 or (fromPos.y < toPosState.y and fromPos.y + 1 or fromPos.y)
     end
     Creature(cid):teleportTo(fromPos, true)
     if fromPos.x == toPosState.x and fromPos.y == toPosState.y then
         state = state + 1 
     end
     return addEvent(doMoveCreature, 600, cid, fromPos, toPos, state)
end

Positions where it should walk to
Code:
local walkPos = {
     {x = 100, y = 105, z = 7},
     {x = 100, y = 110, z = 7},
     {x = 108, y = 110, z = 7}
}
Code:
doMoveCreature(getNpcCid(), Npc():getPosition(), walkPos, 1)
 
Last edited:
@julianfern94
Very "helpful" answer.

@Limos
I tested it. Your code works partly. NPC is walking from one to the other position, but if there is no way, it passes through walls, monsters etc. Is it possible to prevent this?
 
@Limos
I tested it. Your code works partly. NPC is walking from one to the other position, but if there is no way, it passes through walls, monsters etc. Is it possible to prevent this?

ohyeah2qg9.gif
 
@Limos
I know, but what if positions are unknown? For example, I create a NPC in runtime in a random position on the map and there is also destination in a random position. What then? Should I create a double loop (one for coordinate X and the other for coordinate Y) checking tiles on specified area, like here (pseudo code):
Code:
for y = ... do
    for x = ... do
        if queryTileAddThing(cid, pos) == 1 and getTopCreature(pos).uid == 0 then
             table.insert(way, pos)
        end
    end
end
It seems to me that this way is slow. What do you think?

@J.Dre
Haha, exactly.
 
Why it doesn't work as for monsters?
Code:
void Npc::doMoveTo(const Position& target)
{
    std::list<Direction> listDir;
    if (g_game.getPathToEx(this, target, listDir, 1, 12, true, false)) {
        startAutoWalk(listDir);
    }
}
 
Have you tried moving the npc more than one sqm with selfMoveTo(pos)? If i remember correctly it dosn't move if it's standing right next to the target.
 
You can do something like this
Code:
function doMoveCreature(cid, fromPos, toPos, state)
     local toPosState = toPos[state]
     if not toPosState then
         return false
     end
     if fromPos.y == toPosState.y then
         fromPos.x = fromPos.x > toPosState.x and fromPos.x - 1 or (fromPos.x < toPosState.x and fromPos.x + 1 or fromPos.x)
     else
         fromPos.y = fromPos.y > toPosState.y and fromPos.y - 1 or (fromPos.y < toPosState.y and fromPos.y + 1 or fromPos.y)
     end
     Creature(cid):teleportTo(fromPos, true)
     if fromPos.x == toPosState.x and fromPos.y == toPosState.y then
         state = state + 1
     end
     return addEvent(doMoveCreature, 600, cid, fromPos, toPos, state)
end

Positions where it should walk to
Code:
local walkPos = {
     {x = 100, y = 105, z = 7},
     {x = 100, y = 110, z = 7},
     {x = 108, y = 110, z = 7}
}
Code:
doMoveCreature(getNpcCid(), Npc():getPosition(), walkPos, 1)




I would like any NPC like that for TFs 1.3
can someone help?
 
I would like any NPC like that for TFs 1.3
can someone help?
in 0.3.7 we had a function called doSteer or doSteerCreature.
If you can find an old-datapack, maybe you can find that function and implement it into the newer TFS versions.

There was some drawbacks of the function, such as limited distance it could travel. (typically 3-4 sqm at a time), it would stop moving if anything got in the way of it's intended walk-path, and it would also stop functioning anytime something interacted with the creature. (monster/npc), such as a player talking to the npc, or the monster attempting to re-target someone.

Lot's of ways around these issues using loops and other commands, but at the very least it was functional.

I don't know if something similar already exists in tfs 1.3 already, but if not, this is something you can at least look into.
 
Back
Top