forked from TomK32/Poppy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap.lua
146 lines (126 loc) · 3.63 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
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
-- 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)
if position.x < 0 then
position.x = 0
elseif position.x + 1 >= self.width then
position.x = self.width - 1
end
-- for the up/down make it hard borders
if position.y < 0 then
position.y = 0
elseif position.y + 1 > self.height then
position.y = self.height - 1
end
return position
end
function Map:belowPosition(position)
-- only search layers under the position.z
local result = {}
local layer = position.z
if #self.layer_indexes == 0 then return {} end
if not layer then layer = self.layer_indexes[#self.layer_indexes] end
for i=1, layer do
if self.layers[layer - i + 1] then
for e, entity in ipairs(self.layers[layer - 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(_type)
local result = {}
local top_layer = self.layer_indexes[#self.layer_indexes]
for i=0, top_layer do
if self.layers[top_layer - i] then
for e, entity in ipairs(self.layers[top_layer - i]) do
if entity._type == _type then
table.insert(result, entity)
end
end
end
end
return result
end
-- compability for AStar
function Map:getNode(position)
if self.level.map_passable and self.level.map_passable[position.y+1] then
if self.level.map_passable[position.y+1][position.x+1] == 0 then
return nil
end
end
local entities = self:belowPosition(position)
if #entities > 0 then
for i, entity in ipairs(entities) do
if entity.passable == false then
return nil
end
end
end
return Node(position, 1, position.x * self.width + position.y)
end
function Map:locationsAreEqual(a,b)
return a.x == b.x and a.y == b.y
end
function Map:getAdjacentNodes(curnode, dest)
local result = {}
local cl = curnode.location
local dl = dest
local n = false
n = self:_handleNode(cl.x + 1, cl.y, curnode, dl.x, dl.y)
if n then
table.insert(result, n)
end
n = self:_handleNode(cl.x - 1, cl.y, curnode, dl.x, dl.y)
if n then
table.insert(result, n)
end
n = self:_handleNode(cl.x, cl.y + 1, curnode, dl.x, dl.y)
if n then
table.insert(result, n)
end
n = self:_handleNode(cl.x, cl.y - 1, curnode, dl.x, dl.y)
if n then
table.insert(result, n)
end
return result
end
function Map:_handleNode(x, y, fromnode, destx, desty)
-- Fetch a Node for the given location and set its parameters
local n = self:getNode({x = x, y = y})
if n ~= nil then
local dx = math.max(x, destx) - math.min(x, destx)
local dy = math.max(y, desty) - math.min(y, desty)
local emCost = dx + dy
n.mCost = n.mCost + fromnode.mCost
n.score = n.mCost + emCost
n.parent = fromnode
return n
end
return nil
end