Bom, queria expor minha função, já que sempre vi vários comentários construtivos (e outros nem tanto) nas funções postadas aqui.
Primeiramente, editei a função isWalkable(pos) do Nord pra tirar o loop, com medo de fazer uma função monstruosa demais.
Essa é a função isWalkable original
function isWalkable(pos, creature, proj, pz)-- by Nord
if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then return false end
if getTopCreature(pos).uid > 0 and creature then return false end
cr = getThingFromPos({x = pos.x, y = pos.y, z = pos.z, stackpos = STACKPOS_TOP_CREATURE})
if isPlayer(cr.uid) or isMonster(cr.uid) then return false end
if getTileInfo(pos).protection and pz then return false, true 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
Essa é a minha versão editada:
function isWalkable(pos)-- by Nord / editado por Omega
if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0
then return false
elseif getTopCreature(pos).uid > 0 then
return false
elseif isCreature(getTopCreature(pos).uid) then
return false
elseif getTileInfo(pos).protection then
return false
elseif hasProperty(getThingFromPos(pos).uid, 3) or hasProperty(getThingFromPos(pos).uid, 7) then
return false
end
return true
end
E agora a minha função: eu queria uma função que distribuiria aleatoriamente alguns monstros em uma área, porque acho que seria muito útil em eventos.
function doSpawnMonsters(monsters, pos, radius, limit)
if not pos.x or not pos.y or not pos.z or not type(monsters) == 'table' then -- checa se os parâmetros estão corretos
return false
end
local radius = tonumber(radius)
if radius > 5 then -- impede um raio grande demais (para evitar loops muito grandes)
radius = 5
elseif radius < 2 then
radius = 2
end
if not limit or limit < 1 then -- impede um limite negativo ou 0
limit = 1
elseif limit > radius ^ 2 then -- impede um limite maior do que a área pode suportar
limit = radius * 2
end
local k = 0
local tries = 0
repeat
for x = pos.x - radius, pos.x + radius do
for y = pos.y - radius, pos.y + radius do
if isWalkable({x=x, y=y, z=pos.z}) then
local monster = monsters[math.random(1, #monsters)]
local chance = math.random(1, 100)
if k == limit then
break
elseif chance <= 10 and doCreateMonster(monster, {x=x, y=y, z=pos.z}) then
k = k + 1
end
end
end
end
tries = tries + 1 -- para evitar um loop gigantesco
until k >= limit or tries >= 200
return k >= limit and true or false
end







