summaryrefslogtreecommitdiff
path: root/utils.lua
diff options
context:
space:
mode:
Diffstat (limited to 'utils.lua')
-rw-r--r--utils.lua125
1 files changed, 125 insertions, 0 deletions
diff --git a/utils.lua b/utils.lua
new file mode 100644
index 0000000..b6a7ef9
--- /dev/null
+++ b/utils.lua
@@ -0,0 +1,125 @@
+-- misc. utilities
+
+-- returns a list of directions to where this cell in a structure is at the structure border.
+-- returns an empty list for inner nodes
+-- horizontal_only restricts search to only the horizontal plane (no y)
+function cellworld.get_border_sides(rel_pos, str_size, horizontal_only)
+ local borders = {}
+
+ if rel_pos.z == str_size.z-1 then
+ borders[#borders+1] = cellworld.NORTH
+ end
+ if rel_pos.x == str_size.x-1 then
+ borders[#borders+1] = cellworld.EAST
+ end
+
+ if rel_pos.z == 0 then
+ borders[#borders+1] = cellworld.SOUTH
+ end
+ if rel_pos.x == 0 then
+ borders[#borders+1] = cellworld.WEST
+ end
+
+ if not horizontal_only then
+ if rel_pos.y == str_size.y-1 then
+ borders[#borders+1] = cellworld.UP
+ end
+ if rel_pos.y == 0 then
+ borders[#borders+1] = cellworld.DOWN
+ end
+ end
+
+ return borders
+
+end
+
+cellworld.opposite_directions = {
+ [cellworld.EAST] = cellworld.WEST,
+ [cellworld.WEST] = cellworld.EAST,
+ [cellworld.NORTH]= cellworld.SOUTH,
+ [cellworld.SOUTH]= cellworld.NORTH,
+ [cellworld.UP] = cellworld.DOWN,
+ [cellworld.DOWN] = cellworld.UP,
+}
+
+cellworld.direction_to_vector = {
+ [cellworld.EAST] = vector.new(1,0,0),
+ [cellworld.WEST] = vector.new(-1,0,0),
+ [cellworld.NORTH]= vector.new(0,0,1),
+ [cellworld.SOUTH]= vector.new(0,0,-1),
+ [cellworld.UP] = vector.new(0,1,0),
+ [cellworld.DOWN] = vector.new(0,-1,0),
+}
+
+-- quickly hash a position. Only suitable for relative positions, limited to a range of 0..255 each coordinate
+function cellworld.small_pos_hash(x,y,z)
+ return y*65536 + x*256 + z
+end
+
+-- returns the relative structure cell definition
+function cellworld.get_structure_cell(struct, relpos)
+ if struct.cells then
+ local pstr = relpos.x.."|"..relpos.y.."|"..relpos.z
+ if struct.cells[pstr] then
+ return struct.cells[pstr]
+ end
+ end
+ return struct.cell
+end
+
+cellworld.pcgrandom = PcgRandom(os.time())
+
+function cellworld.random(min, max)
+ return cellworld.pcgrandom:next(min,max)
+end
+
+-- returns random element from the list
+function cellworld.select_random_element(list)
+ local r = cellworld.random(1, #list)
+ return list[r]
+end
+
+-- returns a for iterator that iterates from 'from' to 'to' integers but in random order
+function iterate_random_order(from, to)
+ local list = {}
+ for i=from,to do
+ list[#list+1] = i
+ end
+ return function()
+ if #list==0 then return nil end
+ local r = cellworld.random(1, #list)
+ return table.remove(list, r)
+ end
+end
+
+function cellworld.v_decompose(vec)
+ return vec.x, vec.y, vec.z
+end
+
+-- convert back and forth
+function cellworld.world_to_cell_pos(wpos)
+ if not cellworld.grid_size then
+ error("Grid size hasn't been configured yet, is a structure set loaded?")
+ end
+ return vector.new(
+ math.floor(wpos.x / cellworld.grid_size),
+ math.floor(wpos.y / cellworld.grid_size),
+ math.floor(wpos.z / cellworld.grid_size)
+ )
+end
+
+-- upper: output the upper corner of the cell
+function cellworld.cell_to_world_pos(cpos, upper)
+ if not cellworld.grid_size then
+ error("Grid size hasn't been configured yet, is a structure set loaded?")
+ end
+ local wi=0
+ if upper then
+ wi = cellworld.grid_size-1
+ end
+ return vector.new(
+ cpos.x * cellworld.grid_size + wi,
+ cpos.y * cellworld.grid_size + wi,
+ cpos.z * cellworld.grid_size + wi
+ )
+end