Eu fiz algo parecido, mas não utiliza tabelas como você pede não...
enfim:
crie uma lib qualquer e coloque isso dentro:
local dirpref = {
[1] = {[NORTH] = {[1] = {NORTH}, [2] = {EAST, WEST}, [3] = {NORTHEAST, NORTHWEST}},
[EAST] = {[1] = {EAST}, [2] = {NORTH, SOUTH}, [3] = {NORTHEAST, SOUTHEAST}},
[sOUTH] = {[1] = {SOUTH}, [2] = {EAST, WEST}, [3] = {SOUTHEAST, SOUTHWEST}},
[WEST] = {[1] = {WEST}, [2] = {SOUTH, NORTH}, [3] = {NORTHWEST, SOUTHWEST}},
[NORTHEAST] = {[1] = {NORTH, EAST}, [2] = {NORTHEAST}, [3] = {SOUTH, WEST}},
[sOUTHEAST] = {[1] = {SOUTH, EAST}, [2] = {SOUTHEAST}, [3] = {NORTH, WEST}},
[sOUTHWEST] = {[1] = {SOUTH, WEST}, [2] = {SOUTHWEST}, [3] = {NORTH, EAST}},
[NORTHWEST] = {[1] = {NORTH, WEST}, [2] = {NORTHWEST}, [3] = {EAST, SOUTH}}},
[2] = {[NORTH] = {[1] = {NORTH}, [2] = {WEST, EAST}, [3] = {NORTHWEST, NORTHEAST}},
[EAST] = {[1] = {EAST}, [2] = {SOUTH, NORTH}, [3] = {SOUTHEAST, NORTHEAST}},
[sOUTH] = {[1] = {SOUTH}, [2] = {WEST, EAST}, [3] = {SOUTHWEST, SOUTHEAST}},
[WEST] = {[1] = {WEST}, [2] = {NORTH, SOUTH}, [3] = {SOUTHWEST, NORTHWEST}},
[NORTHEAST] = {[1] = {EAST, NORTH}, [2] = {NORTHEAST}, [3] = {WEST, SOUTH}},
[sOUTHEAST] = {[1] = {EAST, SOUTH}, [2] = {SOUTHEAST}, [3] = {WEST, NORTH}},
[sOUTHWEST] = {[1] = {WEST, SOUTH}, [2] = {SOUTHWEST}, [3] = {EAST, NORTH}},
[NORTHWEST] = {[1] = {WEST, NORTH}, [2] = {NORTHWEST}, [3] = {SOUTH, EAST}}},
}
function getCreatureLP(cid)
return getPlayerStorageValue(cid, 197)
end
function markLP(cid, dir)
setPlayerStorageValue(cid, 197, dir)
end
function canWalkOnPos(pos, creature, pz, water, sqm, proj)
if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid <= 1 and sqm then return false end
if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 919 then return false end
if isInArray({4820, 4821, 4822, 4823, 4824, 4825}, getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid) and water then return false end
if getTopCreature(pos).uid > 0 and creature then return false end
if getTileInfo(pos).protection and pz then return false end
local n = not proj and 3 or 2
for i = 0, 255 do
pos.stackpos = i
local tile = getTileThingByPos(pos)
if tile.itemid ~= 0 and not isCreature(tile.uid) then
if hasProperty(tile.uid, n) or hasProperty(tile.uid, 7) then
return false
end
end
end
return true
end
function doCreatureWalk(cid, pos, delay)
if not isCreature(cid) then return true end
if getNextPosition(cid, topos) == false then
doPlayerSendCancel(getCreatureMaster(cid), "Destination is not reachable.")
return true
end
addEvent(doCreatureWalk, delay, cid, pos, delay)
end
function getNextPosition(cid, finalpos)
local random = math.random(1, 2)
local direction = getDirectionTo(getThingPos(cid), finalpos)
for ta = 1, 3 do
for tb = 1, #dirpref[random][direction][ta] do
local y = getPosByDir(getThingPos(cid), dirpref[random][direction][ta][tb])
local w = getCreatureLP(cid)
local z = getDirectionTo(y, getThingPos(cid)) -- direção q vai marcar
local j = getDirectionTo(getThingPos(cid), y) -- direção q ele vai
if canWalkOnPos(y, true, false, true, true, true) and w ~= j then
doPushCreature(cid, dirpref[random][direction][ta][tb], 1, 0)
markLP(cid, z)
return true
end
end
end
return false
end
Lembrando que você já deve ter a lib doPushCreature adicionada no seu server
Exemplo de uso:
function onUse(cid, item, frompos, item2, topos) [b]-- um item que tenha use with[/b] if #getCreatureSummons(cid) <= 0 then return false end local sid = getCreatureSummons(cid)[1] markLP(sid, -1) doCreatureWalk(sid, topos, 700) -- esse 700 é o delay entre cada passo da criatura return true end
Não testei, mas tenho certeza que a função não é 100%, ou seja, em caminhos com muitos obstáculos logicamente a criatura não vai fazer um caminho perfeito.
O certo seria você fazer uma função em C++, em map.cpp existe a função getPathTo, essa função retorna uma boolean, mas ela ao mesmo tempo preenche uma lista com todas as direções até chegar no lugar desejado...


info
Grupo: Visconde
Registrado: 12/09/10
Posts: 416
Reputação: +160
Char no Tibia: Draky Lucas
Pedido de nivel difícil.
Função traceRoute(frompos,topos)
o que ela fará?
ela fará uma rota de tal posição ateh tal posição,armazenando-a em uma table [usando insert.table] onde tiles não andaveis [paredes,bordas...] são contados,ou seja, ele tem que dar a volta.
Ela deverá fazer de tudo para não andar diagonal, ou seja, só devera traçar diagonal quando não houver jeito.
Foto explicando:
Valendo REP+