1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
-- a Map is a 2d array of chunks
-- it handles loading and unloading of chunks
-- the specifics of which are then implemented separately for client and server
-- it will probably also do things relating to entities and multiblock things
local class = require"common.class"
local chunk = require"common.chunk"
local CHUNK_SIZE = require"common.constants".CHUNK_SIZE
local Map = class()
function Map.make(cls)
return setmetatable({chunks={}},cls)
end
function Map.add_chunk(self,cp,the_chunk)
print("adding chunk",cp)
assert(the_chunk.cp == cp,"attempting to add chunk with the wrong cp")
if not self.chunks[cp.u] then self.chunks[cp.u] = {} end
self.chunks[cp.u][cp.v] = the_chunk
end
function Map.unload_chunk(self,cp)
if not self.chunks[cp.u] then return end
self.chunks[cp.u][cp.v] = nil
-- remove list if empty
if next(self.chunks[cp.u]) == nil then self.chunks[cp.u] = nil end
end
function Map.chunk(self,cp)
-- return chunk at chunk coord cp
-- if that chunk isn't loaded return nil
return self:_chunkuv(cp.u,cp.v)
end
function Map._chunkuv(self,u,v)
-- same as above but with numbers instead of objects
-- to avoid allocations inside loop
return self.chunks[u] and self.chunks[u][v]
end
function Map.at(self,hpos)
-- returns tile at world coord hpos
-- if that tile's containing chunk isn't loaded, return nil
-- not using the methods for doing this, in order to avoid lots of allocations
-- inside the main drawing loop
local cpu,cpv = math.floor(hpos.q/CHUNK_SIZE),math.floor(hpos.r/CHUNK_SIZE)
local hoffq,hoffr = hpos.q-(cpu*CHUNK_SIZE), hpos.r-(cpv*CHUNK_SIZE)
local ch = self:_chunkuv(cpu,cpv)
if ch == nil then return nil end
return ch:_atqr(hoffq,hoffr)
end
function Map.set_at(self,hpos,tile)
local cp,hoffs = hpos:chunk_and_offset()
local ch = self:chunk(cp)
-- setting a tile in an unloaded chunk is silently ignored
-- this might change one day
if ch == nil then return nil end
ch:set_at(hoffs,tile)
end
return {Map=Map}
|