summaryrefslogtreecommitdiff
path: root/common/map.lua
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-02-04 23:03:19 +0000
committerubq323 <ubq323@ubq323.website>2023-02-04 23:03:19 +0000
commit0dc1276df57aa16b4f0eaecf54fb5cd8f00115c6 (patch)
tree0d5672f6f05f56022ed834ad35c1c2b2df52c21c /common/map.lua
parent1ebd7d9b7b62c8e05d527611a1944ed1a876b890 (diff)
many many optimizations and refactorings; introduction of Map to support multiple chunks, modify worldgen and client drawing to support multiple chunks
Diffstat (limited to 'common/map.lua')
-rw-r--r--common/map.lua51
1 files changed, 51 insertions, 0 deletions
diff --git a/common/map.lua b/common/map.lua
index fe4b9e0..5bcd09e 100644
--- a/common/map.lua
+++ b/common/map.lua
@@ -3,4 +3,55 @@
-- 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}