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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
|