summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-01-27 13:43:49 +0000
committerubq323 <ubq323@ubq323.website>2023-01-27 13:46:41 +0000
commitd0916d568a00f5171b96fbc3bfc19ff263affc27 (patch)
treeef007be582d2b872ff2ac407def9d0ad64e3bc86 /common
parent0eab09311f6634aefe0e79ecafd975ab68b2812c (diff)
coords, hexagons, drawing, chunks
Diffstat (limited to 'common')
-rw-r--r--common/chunk.lua30
-rw-r--r--common/coords.lua90
2 files changed, 120 insertions, 0 deletions
diff --git a/common/chunk.lua b/common/chunk.lua
new file mode 100644
index 0000000..38cdaf0
--- /dev/null
+++ b/common/chunk.lua
@@ -0,0 +1,30 @@
+local CHUNK_SIZE = 128
+
+-- for now tiles shall be booleans
+
+local function index(offq,offr)
+ -- indexes start at 0
+ -- and go up to (CHUNK_SIZE^2)-1
+ assert(0<=offq and 0<=offr and offq<CHUNK_SIZE and offr<CHUNK_SIZE, "chunk hex offset out of bounds")
+ return CHUNK_SIZE*offq + offr
+end
+
+local Chunk = {}
+Chunk.__index = Chunk
+function Chunk.make()
+ -- todo actual worldgen
+ local tiles = {}
+ for i=0,CHUNK_SIZE-1 do
+ for j=0,CHUNK_SIZE-1 do
+ tiles[index(i,j)] = (math.random()<0.5)
+ end
+ end
+
+ return setmetatable({tiles=tiles},Chunk)
+end
+
+return {
+ Chunk=Chunk,
+ SIZE=CHUNK_SIZE,
+ index=index
+}
diff --git a/common/coords.lua b/common/coords.lua
new file mode 100644
index 0000000..1bb9154
--- /dev/null
+++ b/common/coords.lua
@@ -0,0 +1,90 @@
+-- Hex: q,r,s. invariant that q+r+s=0
+-- add, subtract
+-- constructor takes 3 positions and rounds to closest hex centre.
+
+-- round to nearest int, rounding .5 away from 0.
+local function round(x)
+ if x<0 then
+ return math.ceil(x-0.5)
+ else
+ return math.floor(x+0.5)
+ end
+end
+
+local Pos, Hex
+
+local SR3 = math.sqrt(3)
+
+Hex={}
+Hex.__index = Hex
+function Hex.make(q,r,s)
+ s=s or -q-r
+ assert(q+r+s==0,"hex coord doesn't meet invariant")
+ return setmetatable({q=q,r=r,s=s},Hex)
+end
+function Hex.round(self)
+ -- return a new Hex rounded to integer coordinates
+ local fq,fr,fs = self.q,self.r,self.s
+ -- round all to nearest integer
+ -- find which was changed the most, reset that one to be coherent with the other two.
+ local abs = math.abs
+
+ local rq,rr,rs = round(fq),round(fr),round(fs)
+ local dq,dr,ds = abs(fq-rq), abs(fr-rr), abs(fs-rs)
+
+ if dq>dr and dq>ds then
+ rq = -rr-rs
+ elseif dr>ds then
+ rr = -rq-rs
+ else
+ rs = -rq-rr
+ end
+
+ return Hex.make(rq,rr,rs)
+end
+
+function Hex.to_pos(self)
+ local x = self.q*SR3 + self.r*(SR3/2)
+ local y = self.r*(3/2)
+ return Pos.make(x,y)
+end
+
+function Hex.__add(self,other) return Hex.make(self.q+other.q, self.r+other.r, self.s+other.s) end
+function Hex.__sub(self,other) return Hex.make(self.q-other.q, self.r-other.r, self.s-other.s) end
+function Hex.__tostring(self) return string.format("H(%.2f,%.2f)",self.q,self.r) end
+
+
+Pos = {}
+Pos.__index=Pos
+function Pos.make(x,y)
+ return setmetatable({x=x,y=y},Pos)
+end
+function Pos.__add(self,other) return Pos.make(self.x+other.x,self.y+other.y) end
+function Pos.__sub(self,other) return Pos.make(self.x-other.x,self.y-other.y) end
+function Pos.__mul(a,b)
+ if type(a) == "number" then
+ return Pos.make(a*b.x,a*b.y)
+ elseif type(b) == "number" then
+ return Pos.make(a.x*b,a.y*b)
+ else
+ error("can only multiply Pos by scalar")
+ end
+end
+function Pos.__div(a,b)
+ assert(type(b) == "number","can only divide Pos by scalar, and can't divide scalar by Pos")
+ return a*(1/b)
+end
+function Pos.lensq(self) return self.x^2 + self.y^2 end
+function Pos.len(self) return math.sqrt(self:lensq()) end
+function Pos.to_hex(self)
+ local q = self.x*(SR3/3) - self.y*(1/3)
+ local r = (2/3)*self.y
+ return Hex.make(q,r,-q-r)
+end
+function Pos.__tostring(self) return string.format("(%.2f,%.2f)",self.x,self.y) end
+
+
+
+return {Hex=Hex,Pos=Pos}
+
+