-
Notifications
You must be signed in to change notification settings - Fork 1
/
map.lua
86 lines (78 loc) · 2.43 KB
/
map.lua
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
-- As the map is going to be large (I'm thinking 1000x200 meters),
-- only sparsely populated, and changing quite often (waves),
-- a tiled map doesn't make that much sense.
-- Instead the map will manage only entities.
-- For a future optimization the map might be split up into smaller maps
-- Entities are arranged in layers, each of which the map view has to draw
-- Entities are expected to have a position with x, y and z (layer)
-- and update and draw functions
Map = class("Map")
function Map:initialize(width, height, generator, level)
self.width = width
self.height = height
self.layers = {} -- here the entities are stuffed into
self.layer_indexes = {}
self.level = level
self.generator = generator
self.generator.map = self
self.generator.level = level
self.generator:randomize()
end
function Map:addEntity(entity)
entity.map = self
if not self.layers[entity.position.z] then
self.layers[entity.position.z] = {}
table.insert(self.layer_indexes, entity.position.z)
table.sort(self.layer_indexes, function(a,b) return a < b end)
end
table.insert(self.layers[entity.position.z], entity)
end
function Map:fitIntoMap(position)
-- The map is wrapped on the x-axis, meaning if something leaves on one side it
-- reappears on the opposing side
if position.x < 0 then
position.x = self.width
elseif position.x > self.width then
position.x = 0
end
-- for the up/down make it hard borders
if position.y < 0 then
position.y = 0
elseif position.y > self.height then
position.y = self.height
end
return position
end
function Map:belowPosition(position)
-- only search layers under the position.z
local result = {}
for i=1, position.z do
if self.layers[position.z - i + 1] then
for e, entity in ipairs(self.layers[position.z - i + 1]) do
if entity.includesPoint and entity:includesPoint(position) then
table.insert(result, entity)
end
end
end
end
return result
end
function Map:entitiesOfType(position, _type)
local result = {}
for i, entity in ipairs(self:belowPosition(position)) do
if entity._type == _type then
table.insert(result, entity)
end
end
return result
end
function Map:waves(position)
return self:entitiesOfType(position, 'Wave')
end
function Map:surface(position)
for i, entity in ipairs(self:belowPosition(position)) do
if entity._type ~= 'Wave' then
return entity._type or type(entity)
end
end
end