From 0dc1276df57aa16b4f0eaecf54fb5cd8f00115c6 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Sat, 4 Feb 2023 23:03:19 +0000 Subject: many many optimizations and refactorings; introduction of Map to support multiple chunks, modify worldgen and client drawing to support multiple chunks --- common/map.lua | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'common/map.lua') 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} -- cgit v1.2.3