map_lib_cfg = {
prefix = "[Generator]: ",
msgType = MESSAGE_INFO_DESCR
}
MAP_STATUS_NONE = 0
-- unused
MAP_STATUS_OPEN = 1
MAP_STATUS_CLOSED = 2
MAP_STATUS_RENDERING = 3
MAP_STATUS_LOCKED = 4
MAP_STATUS_END = 5
if not Map then
Map = setmetatable({
instances = {}
}, {
__call = function (self, id, fromPosition, toPosition)
local object = self.instances[id]
if not object then
self.instances[id] = setmetatable({
id = id,
exist = true,
layers = {},
delay = 100,
status = MAP_STATUS_NONE
}, {
__index = Map
})
object = self.instances[id]
object:setPosition(fromPosition, toPosition)
end
return object
end
})
end
function Map:getId()
return self.exist and self.id
end
function Map:remove()
if not self.exist then return false end
local from = self.fromPosition
local to = self.toPosition
if from and to then
from:iterateArea(to, function(position)
local tile = Tile(position)
if tile then
local items = tile:getItems()
for index = 1, #items do
items[index]:remove()
end
local creatures = tile:getCreatures()
for index = 1, #creatures do
local creature = creatures[index]
if creature:isPlayer() then
creature:teleportTo(creature:getTown():getTemplePosition())
creature:sendTextMessage(map_lib_cfg.msgType, map_lib_cfg.prefix .. "Area closed.")
else
creature:remove()
end
end
tile:getGround():remove()
end
end
)
end
self.exist = false
end
function Map:reset()
self.exist = true
self.layers = {}
self.delay = 100
self.status = MAP_STATUS_NONE
self.seed = nil
end
function Map:setPosition(fromPosition, toPosition)
self.fromPosition = Position(fromPosition) or Position()
self.toPosition = Position(toPosition) or Position()
end
function Map:setSeed(seed)
if not seed then return false end
local strseed = tostring(seed)
local numseed = tonumber(seed)
if numseed then
self.seed = numseed
return true
elseif strseed then
self.seed = strseed:toSeed()
return true
end
end
function Map:getSeed()
return self.exist and self.seed
end
function string:toSeed()
local seed = ""
for i = 1, #self do seed = seed .. self:byte(i) end
return tonumber(seed)
end
function Map:setStatus(status)
self.status = status
end
function Map:getStatus()
return self.exist and self.status
end
function Map:addLayer(callback, arguments)
if not self.exist then return nil end
local layers = self.layers
layers[#layers + 1] = {callback = callback, arguments = arguments}
end
function Map:removeLayer(layer_index)
table.remove(self.layers, layer_index)
end
function Map:getLayers()
return self.exist and self.layers
end
function newGround(pos, id)
Game.createTile(pos)
return Game.createItem(id, 1, pos)
end
-- chunk size 16x16
function Map:base(grounds)
local from = self.fromPosition
local to = self.toPosition
from:iterateArea(to, function(pos) addEvent(newGround, self.delay, pos, grounds[math.random(1, #grounds)]) self.delay = self.delay + 1 end)
end
function Map:draw()
if not self.exist then return false end
local from = self.fromPosition
local to = self.toPosition
local x_chunksize = math.floor((to.x - from.x) / 16)
local y_chunksize = math.floor((to.y - from.y) / 16)
for a = 0, x_chunksize do
for b = 0, y_chunksize do
-- print(a, b)
-- todo: split generating to chunks
end
end
if not (from and to) then
return false
end
for i = 1, #self.layers do
local layer = self.layers[i]
layer.callback(unpack(layer.arguments))
end
-- from:iterateArea(to, function(pos) self:drawTile(pos) end)
return true
end
-- from: otland.net/threads/226401
function Position:iterateArea(topos, func)
for z = self.z, topos.z do
for y = self.y, topos.y do
for x = self.x, topos.x do
func(Position(x, y, z))
end
end
end
end
--[[
function map_example(id, from, to)
local map = Map(4, {x = 922, y = 1174, z = 8}, {x = 1749, y = 1701, z = 15})
map:setSeed(os.time())
map:addLayer(Map.base, {map, {101, 407}})
map:draw()
map:reset()
end
]]