• 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 Monster dont spawning on random position

Fortera Global

Intermediate OT User
Joined
Nov 20, 2015
Messages
1,180
Solutions
2
Reaction score
117
I'm using this script to spawn monsters after died, onDeath event:

Lua:
local position = {
    from = Position(31371, 32189, 7),
    to = Position(30453, 32269, 7),
}

function onDeath(creature)
    local randomPosition
    addEvent(function()
      randomPosition = Position(math.random(position.from.x, position.to.x), math.random(position.from.y, position.to.y), 7)
      local monstro = Game.createMonster("Demon", randomPosition)
      end, 100 * 1000)
 
    return true
end

but The monsters are spawning in the same sqm that they died, but I want it to spawn in random positions.

PS. The spawn is not by RME, it's in startUP. The monsters are registered events.

I'm using tfs 1.3, whats wrong?
 
Solution
Okay, seems your going to be adding this to multiple monsters I would implement it like this.

Global.lua
Lua:
local areas = { -- Make sure areaMin is a position top_left of areaMax. areaMin x and y should NEVER be higher than areaMax and z should never be lower.
    [1] = {name = "Demon", areaMin = {1000, 1000, 7}, areaMax = {1000, 1000, 7}},
    [2] = {name = "Another Monster Name", areaMin = {1000, 1000, 7}, areaMax = {1000, 1000, 7}}
}
monsterSpawn_array = {}
function addSpawnablePositions()
    for i = 1, #areas do
    local x = 0
    local y = 0
    local z = 0
        while area[i].areaMin[1] < area[i].areaMax[1] do
            while area[i].areaMin[2] < area[i].areaMax[2] do
                while area[i].areaMin[3] <...
I think it doesn't know what table values your trying to find.
Also, why is the 'to.x' a smaller value then 'from.x'?
You might want to reconfirm your position values.


Try my noob scripting method.
Lua:
local config = {
   [1] = {900, 900, 6}, -- north west, upper floor
   [2] = {1100, 1100, 8} -- south east, lower floor
}

function onDeath(creature)
   local random_x, random_y, random_z = 0, 0, 0
   random_x = math.random(config[1][1], config[2][1])
   random_y = math.random(config[1][2], config[2][2])
   random_z = math.random(config[1][3], config[2][3])
  
   addEvent(function()
       local monstro = Game.createMonster("Demon", (random_x, random_y, random_z))
   end, 100 * 1000)
  
   return true
end
 
Last edited by a moderator:
I think it doesn't know what table values your trying to find.
Also, why is the 'to.x' a smaller value then 'from.x'?
You might want to reconfirm your position values.


Try my noob scripting method.
Lua:
local config = {
   [1] = {900, 900, 6}, -- north west, upper floor
   [2] = {1100, 1100, 8} -- south east, lower floor
}

function onDeath(creature)
   local random_x, random_y, random_z = 0, 0, 0
   random_x = math.random(config[1][1], config[2][1])
   random_y = math.random(config[1][2], config[2][2])
   random_z = math.random(config[1][3], config[2][3])
 
   addEvent(function()
       local monstro = Game.createMonster("Demon", (random_x, random_y, random_z))
   end, 100 * 1000)
 
   return true
end

they continue spawning in the same sqm and was an error without Position in this script :(

Lua:
local monstro = Game.createMonster("Demon", (random_x, random_y, random_z))
to
Lua:
local monstro = Game.createMonster("Demon", Position(random_x, random_y, random_z))

PS. The strange thing is that this same script works normal on Startup (with random spawn).
 
Last edited by a moderator:
they continue spawning in the same sqm and was an error without Position in this script :(

Lua:
local monstro = Game.createMonster("Demon", (random_x, random_y, random_z))
to
Lua:
local monstro = Game.createMonster("Demon", Position(random_x, random_y, random_z))

PS. The strange thing is that this same script works normal on Startup (with random spawn).
Strange.

Let's try some troubleshooting.
Let's kill the addEvent for now, and add a print in, so we know where the monster should be spawning.

This way we can maybe narrow the issue down.

(oh, also. You should add in a check for isMonster(creature) in the future, so that player summons, and player deaths to not summon more demons.)
Lua:
local config = {
   [1] = {900, 900, 6}, -- north west, upper floor
   [2] = {1100, 1100, 8} -- south east, lower floor
}

function onDeath(creature)
   local random_x, random_y, random_z = 0, 0, 0
   random_x = math.random(config[1][1], config[2][1])
   random_y = math.random(config[1][2], config[2][2])
   random_z = math.random(config[1][3], config[2][3])
   
   print("x = " .. random_x .. ", y = " .. random_y .. ", z = " .. random_z .. "")
   Game.createMonster("Demon", Position(random_x, random_y, random_z))
   
   --addEvent(function()
   --   local monstro = Game.createMonster("Demon", Position(random_x, random_y, random_z))
   --end, 100 * 1000)
   
   return true
end
 
I think it doesn't know what table values your trying to find.
Also, why is the 'to.x' a smaller value then 'from.x'?
You might want to reconfirm your position values.


Try my noob scripting method.
Lua:
local config = {
   [1] = {900, 900, 6}, -- north west, upper floor
   [2] = {1100, 1100, 8} -- south east, lower floor
}

function onDeath(creature)
   local random_x, random_y, random_z = 0, 0, 0
   random_x = math.random(config[1][1], config[2][1])
   random_y = math.random(config[1][2], config[2][2])
   random_z = math.random(config[1][3], config[2][3])
 
   addEvent(function()
       local monstro = Game.createMonster("Demon", (random_x, random_y, random_z))
   end, 100 * 1000)
 
   return true
end

This is working, but the sometimes dont spawn, but ok.. its good
 
I would imagine it doesn't spawn because it is trying to spawn in a position it cant. Try this.

Lua:
local area = {
   min = {900, 900, 6}, -- north west, upper floor
   max = {1100, 1100, 8} -- south east, lower floor
}

function onDeath(creature)
   local pos = {math.random(area.min[1], area.max[1]), math.random(area.min[2], area.max[2]), math.random(area.min[3], area.max[3]}
   
    if not pos then
        print("Could not find position to spawn.")
    end
   
   local tile = Tile(pos)
   
   local posOpen = false
   
   while posOpen = false do
        if tile == nil or tile:getGround() == nil or tile:hasProperty(TILESTATE_NONE) or tile:hasProperty(TILESTATE_FLOORCHANGE_EAST) or isItem(tile:getThing()) and not isMoveable(tile:getThing()) or tile:getTopCreature() then
        pos = {math.random(area.min[1], area.max[1]), math.random(area.min[2], area.max[2]), math.random(area.min[3], area.max[3]}
        tile = Tile(pos)
    else
        posOpen = true
        break
    end
    if posOpen then
        Game.createMonster("Demon", Position(pos))
    end
   return true
end
 
Last edited:
I would imagine it doesn't spawn because it is trying to spawn in a position it cant. Try this.

Lua:
local area = {
   min = {900, 900, 6}, -- north west, upper floor
   max = {1100, 1100, 8} -- south east, lower floor
}

function onDeath(creature)
   local pos = {math.random(area.min[1], area.max[1]), math.random(area.min[2], area.max[2]), math.random(area.min[3], area.max[3]}
  
    if not pos then
        print("Could not find position to spawn.")
    end
  
   local tile = Tile(pos)
  
   local posOpen = false
  
   while posOpen = false do
        if tile == nil or tile:getGround() == nil or tile:hasProperty(TILESTATE_NONE) or tile:hasProperty(TILESTATE_FLOORCHANGE_EAST) or isItem(tile:getThing()) and not isMoveable(tile:getThing()) or tile:getTopCreature() then
        pos = {math.random(area.min[1], area.max[1]), math.random(area.min[2], area.max[2]), math.random(area.min[3], area.max[3]}
        tile = Tile(pos)
    else
        posOpen = true
        break
    end
    if posOpen then
        Game.createMonster("Demon", Position(pos))
    end
   return true
end

But will not that make lag? Because we will have more than 200 monsters with this script.
 
But will not that make lag? Because we will have more than 200 monsters with this script.
No it won't, Unless your get miraculously unlucky and it finds 100+ locations that a demon can't spawn.
 
Okay, seems your going to be adding this to multiple monsters I would implement it like this.

Global.lua
Lua:
local areas = { -- Make sure areaMin is a position top_left of areaMax. areaMin x and y should NEVER be higher than areaMax and z should never be lower.
    [1] = {name = "Demon", areaMin = {1000, 1000, 7}, areaMax = {1000, 1000, 7}},
    [2] = {name = "Another Monster Name", areaMin = {1000, 1000, 7}, areaMax = {1000, 1000, 7}}
}
monsterSpawn_array = {}
function addSpawnablePositions()
    for i = 1, #areas do
    local x = 0
    local y = 0
    local z = 0
        while area[i].areaMin[1] < area[i].areaMax[1] do
            while area[i].areaMin[2] < area[i].areaMax[2] do
                while area[i].areaMin[3] < area[i].areaMax[3] do
                    if x == area[i].areaMax[1] and y == area[i].areaMax[2] then
                        x = area[i].areaMin[1]
                        y = area[i].areaMin[2]
                        z = z - 1
                    elseif x == 0 and y == 0 and z == 0
                        x = area[i].areaMin[1]
                        y = area[i].areaMin[2]
                        z = area[i].areaMin[3]
                    end
                   
                    local posSpawn = Position({x, y, z})
                    local tile = Tile({x, y, z})
                   
                    if tile == nil or tile:getGround() == nil or tile:hasProperty(TILESTATE_NONE) or tile:hasProperty(TILESTATE_FLOORCHANGE_EAST) or isItem(tile:getThing()) and not isMoveable(tile:getThing()) or tile:getTopCreature() then
                        x = x + 1
                        y = y + 1
                    else
                        if monsterSpawn_array[areas.name] then
                            local length = monsterSpawn_array[areas.name] + 1
                            monsterSpawn_array[areas.name][length] = posSpawn
                        else
                        monsterSpawn_array[areas.name][1] = posSpawn
                        end
                    x = x + 1
                    y = y + 1
                    end
                end
            end
        end
    end               
end
function selectRandSpawn(spawnName)
    if monsterSpawn_array[spawnName] then
        pos = monsterSpawn_array[math.random(1, #monsterSpawn_array[spawnName])]
        return true
    else
    return false
    end
end

GlobalEvents: onStartup.lua -- Add this somewhere in there.
Lua:
addSpawnablePositions()

onDeath: Creaturescript
Lua:
function onDeath(creature)
   local pos = selectRandSpawn("Demon")
 
    if not pos then
        print("Could not find position")
    return true
    end
 
    Game.createMonster("Demon", pos)
   return true
end
 
Last edited:
Solution
Okay, seems your going to be adding this to multiple monsters I would implement it like this.

Global.lua
Lua:
local areas = { -- Make sure areaMin is a position top_left of areaMax. areaMin x and y should NEVER be higher than areaMax and z should never be lower.
    [1] = {name = "Demon", areaMin = {1000, 1000, 7}, areaMax = {1000, 1000, 7}},
    [2] = {name = "Another Monster Name", areaMin = {1000, 1000, 7}, areaMax = {1000, 1000, 7}}
}
monsterSpawn_array = {}
function addSpawnablePositions()
    for i = 1, #areas do
    local x = 0
    local y = 0
    local z = 0
        while area[i].areaMin[1] < area[i].areaMax[1] do
            while area[i].areaMin[2] < area[i].areaMax[2] do
                while area[i].areaMin[3] < area[i].areaMax[3] do
                    if x == area[i].areaMax[1] and y == area[i].areaMax[2] then
                        x = area[i].areaMin[1]
                        y = area[i].areaMin[2]
                        z = z - 1
                    elseif x == 0 and y == 0 and z == 0
                        x = area[i].areaMin[1]
                        y = area[i].areaMin[2]
                        z = area[i].areaMin[3]
                    end
                  
                    local posSpawn = Position({x, y, z})
                    local tile = Tile({x, y, z})
                  
                    if tile == nil or tile:getGround() == nil or tile:hasProperty(TILESTATE_NONE) or tile:hasProperty(TILESTATE_FLOORCHANGE_EAST) or isItem(tile:getThing()) and not isMoveable(tile:getThing()) or tile:getTopCreature() then
                        x = x + 1
                        y = y + 1
                    else
                        if monsterSpawn_array[areas.name] then
                            local length = monsterSpawn_array[areas.name] + 1
                            monsterSpawn_array[areas.name][length] = posSpawn
                        else
                        monsterSpawn_array[areas.name][1] = posSpawn
                        end
                    x = x + 1
                    y = y + 1
                    end
                end
            end
        end
    end              
end
function selectRandSpawn(spawnName)
    if monsterSpawn_array[spawnName] then
        pos = monsterSpawn_array[math.random(1, #monsterSpawn_array[spawnName])]
        return true
    else
    return false
    end
end

GlobalEvents: onStartup.lua -- Add this somewhere in there.
Lua:
addSpawnablePositions()

onDeath: Creaturescript
Lua:
function onDeath(creature)
   local pos = selectRandSpawn("Demon")
 
    if not pos then
        print("Could not find position")
    return true
    end
 
    Game.createMonster("Demon", pos)
   return true
end


Omg, thank you, I was looking for the thread and had not found .. But looking at the script, it looks like it will weigh heavily or I'm wrong?
 
Back
Top