Loading [MathJax]/extensions/MathMenu.js
Cytopia  0.3
A city building simulation game
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ZoneManager.cxx
Go to the documentation of this file.
1 #include "ZoneManager.hxx"
2 #include "LOG.hxx"
3 #include "../services/GameClock.hxx"
4 #include "../services/Randomizer.hxx"
5 #include "GameStates.hxx"
6 #include <SignalMediator.hxx>
7 #include <MapFunctions.hxx>
8 
10 {
11  // Callbacks for setTileID
15 
17  [this]()
18  {
19  update();
21  return false;
22  },
23  1s, 1s);
24 }
25 
27 {
28  // Vacate nodes (Demolish Buildings on zones)
29  if (!m_nodesToVacate.empty())
30  {
31  for (auto nodeToVacate : m_nodesToVacate)
32  {
33  for (auto &zoneArea : m_zoneAreas)
34  {
35  if (zoneArea.isMemberOf(nodeToVacate))
36  {
37  zoneArea.setVacancy(nodeToVacate, true);
38  break;
39  }
40  }
41  }
42  m_nodesToVacate.clear();
43  }
44 
45  // Occupy nodes (building has been spawned on a zone node)
46  if (!m_nodesToOccupy.empty())
47  {
48  for (auto nodeToOccupy : m_nodesToOccupy)
49  {
50  for (auto &zoneArea : m_zoneAreas)
51  {
52  if (zoneArea.isMemberOf(nodeToOccupy))
53  {
54  zoneArea.setVacancy(nodeToOccupy, false);
55  break;
56  }
57  }
58  }
59  m_nodesToOccupy.clear();
60  }
61 
62  // Add new nodes (zone has been placed)
63  if (!m_nodesToAdd.empty())
64  {
65  for (auto nodeToAdd : m_nodesToAdd)
66  {
67  addZoneNodeToArea(nodeToAdd, m_zoneAreas);
68  }
69  m_nodesToAdd.clear();
70  }
71 
72  // Remove nodes (Dezone on zone tiles)
73  if (!m_nodesToRemove.empty())
74  {
75  for (auto m_nodeToRemove : m_nodesToRemove)
76  {
77  removeZoneNode(m_nodeToRemove);
78  }
79  m_nodesToRemove.clear();
80  }
81 }
82 
84 {
85  for (auto &zoneArea : m_zoneAreas)
86  {
87  // check if there are any buildings to spawn, if not, do nothing.
88  if (zoneArea.isVacant() && zoneArea.hasPowerSupply())
89  {
90  int occupied = 0;
91  int free = 0;
92  for (auto node : zoneArea)
93  {
94  if (node.occupied)
95  {
96  occupied++;
97  }
98  else
99  free++;
100  }
101  zoneArea.spawnBuildings();
102  }
103  }
104 }
105 
106 std::vector<int> ZoneManager::getAdjacentZoneAreas(const ZoneNode &zoneNode, std::vector<ZoneArea> &zoneAreas)
107 {
108  std::vector<int> neighborZones;
109  int i = 0;
110 
111  for (auto &zoneArea : zoneAreas)
112  {
113  if (zoneArea.getZone() == zoneNode.zoneType && (zoneArea.getZoneDensity() == zoneNode.zoneDensity) &&
114  zoneArea.isWithinBoundaries(zoneNode.coordinate) && zoneArea.isNeighbor(zoneNode.coordinate))
115  {
116  neighborZones.push_back(i);
117  }
118  ++i;
119  }
120 
121  return neighborZones;
122 }
123 
124 void ZoneManager::addZoneNodeToArea(ZoneNode &zoneNode, std::vector<ZoneArea> &zoneAreas)
125 {
126  auto zoneNeighbour = getAdjacentZoneAreas(zoneNode, zoneAreas);
127 
128  if (zoneNeighbour.empty())
129  {
130  // new zonearea
131  zoneAreas.emplace_back(zoneNode);
132  }
133  else if (zoneNeighbour.size() == 1)
134  {
135  // add to this zone
136  zoneAreas[zoneNeighbour[0]].addNode(zoneNode);
137  }
138  else
139  {
140  // merge zone areas
141  ZoneArea &mergedZone = zoneAreas[zoneNeighbour[0]];
142  mergedZone.addNode(zoneNode);
143 
144  for (int idx = 1; idx < zoneNeighbour.size(); ++idx)
145  {
146  mergeZoneAreas(mergedZone, zoneAreas[zoneNeighbour[idx]]);
147  }
148 
149  for (int idx = zoneNeighbour.size() - 1; idx > 0; --idx)
150  {
151  zoneAreas.erase(zoneAreas.begin() + zoneNeighbour[idx]);
152  }
153  }
154 }
155 
156 std::vector<ZoneArea> ZoneManager::rebuildZoneArea(ZoneArea &zoneArea)
157 {
158  std::vector<ZoneArea> newZoneAreas;
159 
160  for (ZoneNode zoneNode : zoneArea)
161  {
162  addZoneNodeToArea(zoneNode, newZoneAreas);
163  }
164 
165  return newZoneAreas;
166 }
167 
169 {
170  for (auto zoneIt = m_zoneAreas.begin(); zoneIt != m_zoneAreas.end(); zoneIt++)
171  {
172  if (zoneIt->isMemberOf(coordinate))
173  {
174  zoneIt->removeZoneNode(coordinate);
175 
176  if (zoneIt->size() == 0)
177  {
178  m_zoneAreas.erase(zoneIt);
179  }
180  else
181  {
182  auto zoneAreas = rebuildZoneArea(*zoneIt);
183  assert(zoneAreas.size() > 0);
184  // If zoneAreas size is 1, means zoneArea is still compact, nothing to be done
185 
186  if (zoneAreas.size() > 1)
187  {
188  m_zoneAreas.erase(zoneIt);
189  m_zoneAreas.insert(m_zoneAreas.end(), zoneAreas.begin(), zoneAreas.end());
190  }
191  }
192 
193  break;
194  }
195  }
196 }
197 
198 void ZoneManager::updatePower(const std::vector<PowerGrid> &powerGrid)
199 {
200  for (const auto &grid : powerGrid)
201  {
202  for (auto &area : m_zoneAreas)
203  {
204  if (bool isGridConnected =
205  area.end() !=
206  std::find_if(area.begin(), area.end(), [grid](const ZoneNode &node) { return grid.isNeighbor(node.coordinate); });
207  !isGridConnected)
208  continue;
209  if (grid.getPowerLevel() > 0)
210  {
211  area.setPowerSupply(true);
212  }
213  else
214  {
215  area.setPowerSupply(false);
216  }
217  }
218  }
219 }
220 
222 {
223 
225  {
227  {
228  m_nodesToRemove.push_back(mapNode->getCoordinates());
229  break;
230  }
232  {
233  if (!mapNode->getTileData(Layer::BUILDINGS))
234  {
235  m_nodesToVacate.push_back(mapNode->getCoordinates());
236  }
237 
238  break;
239  }
240  default:
241  break;
242  }
243 }
244 
246 {
247  if (mapNode.getTileData(Layer::BUILDINGS) && mapNode.getTileData(Layer::ZONE))
248  {
249  m_nodesToOccupy.push_back(mapNode.getCoordinates());
250  }
251 
252  // zone placed
253  else if (mapNode.getTileData(Layer::ZONE))
254  {
255  ZoneNode nodeToAdd = {mapNode.getCoordinates(), mapNode.getTileData(Layer::ZONE)->zoneTypes[0],
256  mapNode.getTileData(Layer::ZONE)->zoneDensity[0]};
257  m_nodesToAdd.push_back(nodeToAdd);
258  }
259 }
260 
262 {
263  m_zoneAreas.clear();
264  for (const auto &mapNode : MapFunctions::instance().getMapNodes())
265  {
266  if (mapNode.getTileData(Layer::ZONE))
267  {
268  ZoneNode nodeToAdd = {mapNode.getCoordinates(), mapNode.getTileData(Layer::ZONE)->zoneTypes[0],
269  mapNode.getTileData(Layer::ZONE)->zoneDensity[0]};
270  m_nodesToAdd.push_back(nodeToAdd);
271  }
272  }
273 }
demolishMode
bool demolishMode
Definition: mapEdit.cxx:5
ZoneManager::updatePlacedNodes
void updatePlacedNodes(const MapNode &mapNode)
Definition: ZoneManager.cxx:245
DemolishMode::DE_ZONE
@ DE_ZONE
Remove only zones.
ZoneManager::m_zoneAreas
std::vector< ZoneArea > m_zoneAreas
Definition: ZoneManager.hxx:66
ZoneManager::spawnBuildings
void spawnBuildings()
Spawn Buildings on the gathered tileMap.
Definition: ZoneManager.cxx:83
ZoneManager::updatePower
void updatePower(const std::vector< PowerGrid > &powerGrid)
Definition: ZoneManager.cxx:198
ZoneManager::m_nodesToVacate
std::vector< Point > m_nodesToVacate
All zoneAreas.
Definition: ZoneManager.hxx:69
mergeZoneAreas
void mergeZoneAreas(ZoneArea &mainZone, ZoneArea &toBeMerged)
Definition: ZoneArea.cxx:7
ZoneArea
Definition: ZoneArea.hxx:19
ZoneManager::removeZoneNode
void removeZoneNode(Point coordinate)
Removes a zonenode.
Definition: ZoneManager.cxx:168
MapNode::getCoordinates
const Point & getCoordinates() const
get iso coordinates of this node
Definition: MapNode.hxx:59
LOG.hxx
ZoneManager::update
void update()
Process previously cached nodes to update.
Definition: ZoneManager.cxx:26
MapFunctions.hxx
ZoneManager::ZoneManager
ZoneManager()
Definition: ZoneManager.cxx:9
MapNode::getTileData
const TileData * getTileData(Layer layer) const
Definition: MapNode.hxx:84
ZoneNode::zoneType
ZoneType zoneType
Definition: ZoneArea.hxx:11
SignalMediator::registerCbDemolish
void registerCbDemolish(std::function< void(MapNode *)> const &cb)
Definition: SignalMediator.hxx:41
MapNode
Class that holds map nodes.
Definition: MapNode.hxx:30
GameStates.hxx
ZONE
@ ZONE
4- Optional layer, zones(Industrial/Residential/Commercial).
Definition: enums.hxx:15
BUILDINGS
@ BUILDINGS
8- Buildings, Streets and everything that goes on the terrain
Definition: enums.hxx:19
ZoneManager::addZoneNodeToArea
void addZoneNodeToArea(ZoneNode &zoneNode, std::vector< ZoneArea > &zoneAreas)
Adds a zoneNode to a given area.
Definition: ZoneManager.cxx:124
ZoneManager::m_nodesToRemove
std::vector< Point > m_nodesToRemove
All zoneAreas.
Definition: ZoneManager.hxx:70
ZoneNode::zoneDensity
ZoneDensity zoneDensity
Definition: ZoneArea.hxx:12
ZoneManager::updateRemovedNodes
void updateRemovedNodes(const MapNode *mapNode)
Definition: ZoneManager.cxx:221
TileData::zoneTypes
std::vector< ZoneType > zoneTypes
Restrict this building to a zone type.
Definition: tileData.hxx:170
DemolishMode::DEFAULT
@ DEFAULT
Demolish everything, but not.
ZoneManager::m_nodesToAdd
std::vector< ZoneNode > m_nodesToAdd
All zoneAreas.
Definition: ZoneManager.hxx:67
ZoneNode::coordinate
Point coordinate
Definition: ZoneArea.hxx:10
ZoneNode
Definition: ZoneArea.hxx:8
SignalMediator::registerCbUpdatePower
void registerCbUpdatePower(std::function< void(const std::vector< PowerGrid > &)> const &cb)
Definition: SignalMediator.hxx:44
ZoneManager::rebuildZoneArea
std::vector< ZoneArea > rebuildZoneArea(ZoneArea &zoneArea)
rebuild a certain zone area
Definition: ZoneManager.cxx:156
Signal::slot
std::function< R(Args...)> slot(instance &object, R(Class::*method)(Args...))
This function creates a std::function by binding object to the member function pointer method.
Definition: Signal.hxx:167
TileData::zoneDensity
std::vector< ZoneDensity > zoneDensity
Restrict this building to a certain zone density. See enum ZoneDensity.
Definition: tileData.hxx:172
SignalMediator.hxx
Point
Definition: Point.hxx:7
Singleton< SignalMediator >::instance
static SignalMediator & instance(void)
Get an instance of the singleton.
Definition: Singleton.hxx:15
ZoneManager::getAdjacentZoneAreas
std::vector< int > getAdjacentZoneAreas(const ZoneNode &zoneNode, std::vector< ZoneArea > &zoneAreas)
get a list of neighboring zoneareas for a zoneNode
Definition: ZoneManager.cxx:106
SignalMediator::registerCbSetTileID
void registerCbSetTileID(std::function< void(const MapNode &)> const &cb)
Definition: SignalMediator.hxx:40
GameClock::addRealTimeClockTask
GameClock::ClockTaskHndl addRealTimeClockTask(ClockCbk cbk, DelayType delay, PeriodType period=TimePointZero)
Add new real time clock task.
Definition: GameClock.inl.hxx:5
ZoneArea::addNode
void addNode(ZoneNode zoneNode) override
Add a zoneNode to this zoneArea.
Definition: ZoneArea.cxx:106
ZoneManager::reset
void reset()
Definition: ZoneManager.cxx:261
ZoneManager.hxx
ZoneManager::m_nodesToOccupy
std::vector< Point > m_nodesToOccupy
All zoneAreas.
Definition: ZoneManager.hxx:68