Boa noite!

Esse código faz a creature (NPC, monster ou player) andar até a posição desejada.


Notas:

-Não use para longas distâncias. Crie um sistema de waypoints para isso.
-A creature não para exatamente na posição desejada. (caso alguém se interesse em corrigir, eu anexarei ao tópico)
-Utiliza grande poder de processamento. Use de forma sábia.
-Testado apenas em TFS 1.2

Coloque em luascript.cpp

registerMethod("Creature", "moveTo", LuaScriptInterface::luaCreatureMoveTo);

Código:
int32_t LuaScriptInterface::luaCreatureMoveTo(lua_State* L)
{
        //creature:moveTo(pos)
    Creature* creature = getUserdata<Creature>(L, 1);
    if (!creature) {
        lua_pushnil(L);
        return 1;
    }

    const Position& position = getPosition(L, 2);

    FindPathParams fpp;
    fpp.minTargetDist = getNumber<int32_t>(L, 3, 0);
    fpp.maxTargetDist = getNumber<int32_t>(L, 4, 1);
    fpp.fullPathSearch = getBoolean(L, 5, fpp.fullPathSearch);
    fpp.clearSight = getBoolean(L, 6, fpp.clearSight);
    fpp.maxSearchDist = getNumber<int32_t>(L, 7, 150);

    std::forward_list<Direction> dirList;
    if (creature->getPathTo(position, dirList, fpp)) {
        creature->hasFollowPath = true;
        creature->startAutoWalk(dirList);
        pushBoolean(L, true);
    }
    else { pushBoolean(L, false); }
    return 1;
}
Coloque em luascript.h

static int luaCreatureMoveTo(lua_State* L);


Substitua a função original em creature.cpp
Código:
bool Creature::setFollowCreature(Creature* creature)
{
    if (creature) {
        if (followCreature == creature) {
            return true;
        }

        const Position& creaturePos = creature->getPosition();
        FindPathParams fpp;
        fpp.minTargetDist = 0;
        fpp.maxTargetDist = 1;
        fpp.fullPathSearch = true;
        fpp.clearSight = true;
        fpp.maxSearchDist = 150;
        std::forward_list<Direction> dirList;
        if (creaturePos.z != getPosition().z || !canSee(creaturePos) || !getPathTo(creaturePos, dirList, fpp)) {
            followCreature = nullptr;
            return false;
        }

        if (!listWalkDir.empty()) {
            listWalkDir.clear();
            onWalkAborted();
        }

        hasFollowPath = false;
        forceUpdateFollowPath = false;
        followCreature = creature;
        isUpdatingPath = true;
    } else {
        isUpdatingPath = false;
        followCreature = nullptr;
    }

    onFollowCreature(creature);
    return true;
}
Substitua a função original em monster.cpp

Código:
bool Monster::getNextStep(Direction& dir, uint32_t& flags)
{
   if (getHealth() <= 0) {
     //we dont have anyone watching might aswell stop walking
     eventWalk = 0;
     return false;
   }
 
   bool result = false;
   if (hasFollowPath)
     return Creature::getNextStep(dir, flags);
   else if ((!followCreature || !hasFollowPath) && !isSummon()) {
     if ((followCreature || getTimeSinceLastMove() > 1000) && !hasFollowPath && !isIdle) {
       //choose a random direction
       result = getRandomStep(getPosition(), dir);
     }
   } else if (isSummon() || followCreature) {
     result = Creature::getNextStep(dir, flags);
     if (result) {
       flags |= FLAG_PATHFINDING;
     } else {
       //target dancing
       if (attackedCreature && attackedCreature == followCreature) {
         if (isFleeing()) {
           result = getDanceStep(getPosition(), dir, false, false);
         } else if (mType->staticAttackChance < static_cast<uint32_t>(uniform_random(1, 100))) {
           result = getDanceStep(getPosition(), dir);
         }
       }
     }
   }

   if (result && (canPushItems() || canPushCreatures())) {
     const Position& pos = Spells::getCasterPosition(this, dir);
     Tile* tile = g_game.map.getTile(pos);
     if (tile) {
       if (canPushItems()) {
         Monster::pushItems(tile);
       }

       if (canPushCreatures()) {
         Monster::pushCreatures(tile);
       }
     }
   }

   return result;
}
Aproveitem! Abraço.