R-Type  2
Doom but in better
Loading...
Searching...
No Matches
Orchestrator.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2024
3** rtype (Workspace)
4** File description:
5** Orchestrator.cpp
6*/
7
15
17 : EntityNode(entityId)
18{
19};
20
21void GUI::ECS::Online::Orchestrator::initialiseClass(std::unordered_map<std::type_index, std::vector<std::any>> &ecsEntities)
22{
23 PRETTY_DEBUG << "Resetting the values stored in the class" << std::endl;
24 _ecsEntities = ecsEntities;
25 _event.reset();
26 _window.reset();
27 _spriteBullet.reset();
28 _spritePlayer.reset();
29 _spriteEnemy.reset();
30 _playerBrain.clear();
31 _enemyBrain.clear();
32 _enemyBullets.clear();
33 _playerBullets.clear();
34 PRETTY_DEBUG << "The values stored in the class have been reset" << std::endl;
35
36 PRETTY_DEBUG << "Fetching the window manager" << std::endl;
37 std::any win = _ecsEntities[typeid(GUI::ECS::Systems::Window)][0];
38 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> window_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>>(win, false);
39 if (!window_ptr.has_value()) {
40 PRETTY_ERROR << "The window manager has not been found" << std::endl;
41 throw CustomExceptions::NoWindow("<No window to draw on>");
42 }
43 _window = window_ptr.value();
44 PRETTY_DEBUG << "The window manager has been fetched" << std::endl;
45
46 PRETTY_DEBUG << "Fetching the event manager" << std::endl;
47 std::any evt = _ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0];
48 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(evt, false);
49 if (!event_ptr.has_value()) {
50 PRETTY_ERROR << "The event has been found" << std::endl;
51 throw CustomExceptions::NoEventManager("<No events to listen on>");
52 }
53 _event = event_ptr.value();
54 PRETTY_DEBUG << "The event manager has been fetched" << std::endl;
55
56 PRETTY_DEBUG << "Fetching the sprites contained in the ecs array (if present)" << std::endl;
57 const std::vector<std::any> sprites = _ecsEntities[typeid(GUI::ECS::Components::SpriteComponent)];
58
59 for (std::any node : sprites) {
60 const std::optional<std::shared_ptr<GUI::ECS::Components::SpriteComponent>> sprite = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::SpriteComponent>>(node, false);
61 if (!sprite.has_value()) {
62 PRETTY_WARNING << "Sprite uncasting failed" << std::endl;
63 }
64 std::string name = sprite.value()->getName();
65 std::string applicationContext = sprite.value()->getApplication();
66
67 PRETTY_DEBUG << "Current sprite info { name: '" << name << "', application context: '" << applicationContext << "' }" << std::endl;
68
69 if (
70 applicationContext == "sprite42" || name == "r-typesheet42" ||
71 applicationContext == "sprite42" || name == "r-typesheet42"
72 ) {
73 PRETTY_DEBUG << "Sprite player has been found" << std::endl;
74 _spritePlayer = sprite.value();
75 PRETTY_DEBUG << "Sprite player content:\n" << *_spritePlayer << std::endl;
76 } else if (
77 applicationContext == "sprite30c" || name == "sprite30c" ||
78 applicationContext == "typesheet30c" || name == "typesheet30c"
79 ) {
80 PRETTY_DEBUG << "Sprite bullet found" << std::endl;
81 _spriteBullet = sprite.value();
82 _spriteBullet->forceTick();
83 PRETTY_DEBUG << "Sprite bullet content:\n" << *_spriteBullet << std::endl;
84 } else if (
85 applicationContext == "sprite3c" || name == "sprite3c" ||
86 applicationContext == "r-typesheet3c" || name == "r-typesheet3c"
87 ) {
88 PRETTY_DEBUG << "Sprite bullet enemy found" << std::endl;
89 _spriteBulletEnemy = sprite.value();
90 _spriteBulletEnemy->forceTick();
91 PRETTY_DEBUG << "Sprite bullet enemy content:\n" << *_spriteBulletEnemy << std::endl;
92 } else if (
93 applicationContext == "r-typesheet13" || name == "r-typesheet13" ||
94 applicationContext == "sprite13" || name == "sprite13"
95 ) {
96 PRETTY_DEBUG << "Sprite enemy found" << std::endl;
97 _spriteEnemy = sprite.value();
98 PRETTY_DEBUG << "Sprite enemy content:\n" << *_spriteEnemy << std::endl;
99 }
100 }
101 PRETTY_DEBUG << "The sprite player has been fetched" << std::endl;
102
103 PRETTY_DEBUG << "Checking if the elements are loaded or not" << std::endl;
104 if (_spriteBullet == nullptr || _spritePlayer == nullptr || _spriteEnemy == nullptr || _spriteBulletEnemy == nullptr) {
105 PRETTY_ERROR << "The sprite player, bullet, enemy or bullet enemy has not been found" << std::endl;
106 throw CustomExceptions::NoSprite("<One of the sprites that the program attempted to load was missing>");
107 }
108 PRETTY_DEBUG << "The elements are loaded" << std::endl;
109 _setTheScene();
110 _setTextComponents();
111 PRETTY_DEBUG << "Fetching a background for the game" << std::endl;
112 const std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
113 PRETTY_DEBUG << "Declaring the ressource required for the settings menu to have a background" << std::endl;
114 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundItem;
115 PRETTY_DEBUG << "Declared the ressource required for the settings menu to have a background" << std::endl;
116
117 for (std::any backgroundCast : backgrounds) {
118 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
119 if (!backgroundCapsule.has_value()) {
120 continue;
121 }
122 if (
123 backgroundCapsule.value()->getApplication() == "space" || backgroundCapsule.value()->getName() == "space" ||
124 backgroundCapsule.value()->getApplication() == "Space" || backgroundCapsule.value()->getName() == "Space"
125 ) {
126 backgroundItem.emplace(backgroundCapsule.value());
127 }
128 }
129 PRETTY_DEBUG << "Background fetched if present" << std::endl;
130};
131
132void GUI::ECS::Online::Orchestrator::setNetworkClass(const std::shared_ptr<GUI::Network::ThreadCapsule> &network)
133{
134 if (network == nullptr) {
135 throw CustomExceptions::NoNetworkClass("<Network class not found>");
136 }
137 _network.emplace(network);
138}
139
141{
142 PRETTY_DEBUG << "The start function has been called" << std::endl;
143 _playing = true;
144 _gameOver = false;
145 _gameWon = false;
146};
147
149{
150 PRETTY_DEBUG << "The stop function has been called" << std::endl;
151 _playing = false;
152 _gameOver = false;
153 _gameWon = false;
154};
155
157{
158 PRETTY_DEBUG << "The reset function has been called" << std::endl;
159 _gameOver = false;
160 _gameWon = false;
161 _kill();
162 _setTheScene();
163 stop();
164};
165
166void GUI::ECS::Online::Orchestrator::tick(const std::vector<GUI::Network::MessageNode> &packets)
167{
168 // Check if the class is set to calculate it's move
169 if (!_playing) {
170 PRETTY_DEBUG << "Skipping tick because we are not playing" << std::endl;
171 return;
172 }
173
174 PRETTY_DEBUG << "Orchestrator dump (before tick):\n" << getInfo(0) << std::endl;
175
176 // update entities based on packets received
177 PRETTY_DEBUG << "Going to process received packets" << std::endl;
178 for (const GUI::Network::MessageNode &packet : packets) {
179 PRETTY_DEBUG << "Packet received: " << Recoded::myToString(packet) << std::endl;
180 switch (packet.type) {
182 _setPosition(packet.id, packet.info.coords);
183 break;
185 /* animation */
186 break;
188 if (packet.info.assetId == static_cast<int>(GUI::ECS::GameComponents::EntityType::ENEMY)) {
189 _spawnEnemy(packet.id, packet.info.coords);
190 } else if (packet.info.assetId == static_cast<int>(GUI::ECS::GameComponents::EntityType::PLAYER)) {
191 _spawn(packet.id, packet.info.coords);
192 } else if (packet.info.assetId == static_cast<int>(GUI::ECS::GameComponents::EntityType::LASER_ENEMY)) {
193 _spawnEnemyBullet(packet.id, packet.info.coords);
194 } else {
195 _spawnFriendBullet(packet.id, packet.info.coords);
196 }
197 break;
199 _killEntity(packet.id);
200 break;
202 /* animation */
203 break;
204 default:
205 break;
206 }
207 }
208 PRETTY_DEBUG << "Processed received packets" << std::endl;
209
210 // Update player movements
211 PRETTY_DEBUG << "Going to process the events" << std::endl;
212 if (_event->getKeys().size() > 0) {
213 PRETTY_DEBUG << "Checking if the player id: " << Recoded::myToString(_playerId) << " is present" << std::endl;
214 if (_playerId < _playerBrain.size()) {
215 std::pair<float, float> position = _playerBrain[_playerId]->getCollision().getPosition();
216
217 // Handle movement
218 if (_event->isKeyPressed(GUI::ECS::Systems::Key::Up) && position.second > 0) {
219 position.second += _stepUp;
220 } else if (_event->isKeyPressed(GUI::ECS::Systems::Key::Down) && position.second < _window->getDimensions().second - _screenPosYOffset) {
221 position.second += _stepDown;
222 } else if (_event->isKeyPressed(GUI::ECS::Systems::Key::Left) && position.first > 0) {
223 position.first += _stepLeft;
224 } else if (_event->isKeyPressed(GUI::ECS::Systems::Key::Right) && position.first < _window->getDimensions().first - _screenPosXOffset) {
225 position.first += _stepRight;
226 }
227
228 // Handle shooting
229 PRETTY_DEBUG << "Checking if the player has shot" << std::endl;
230 if (_event->isKeyPressed(GUI::ECS::Systems::Key::Space)) {
231 PRETTY_DEBUG << "The player has shot" << std::endl;
232 if (_playerId < _playerBrain.size()) {
233 PRETTY_DEBUG << "Player shot" << std::endl;
234 _sendMessage({ GUI::Network::MessageType::P_SHOOT, _playerBrain[_playerId]->getEntityNodeId(), {0, 0, "", {0, 0}} });
235 _shootSound();
236 } else {
237 PRETTY_WARNING << "There is no player to update" << std::endl;
238 throw CustomExceptions::NoSprite("<No player>");
239 }
240 }
241 PRETTY_DEBUG << "Checked if the player had shot" << std::endl;
242
243 // Update player position
244 PRETTY_DEBUG << "Updating the player's position" << std::endl;
245 if (_playerId < _playerBrain.size()) {
246 _playerBrain[_playerId]->setPosition(position);
247 _sendMessage({ GUI::Network::MessageType::P_MOVE, _playerBrain[_playerId]->getEntityNodeId(), {0, 0, "", {position.first, position.second}} });
248 } else {
249 PRETTY_WARNING << "There is no player to update" << std::endl;
250 throw CustomExceptions::NoSprite("<No player>");
251 }
252 PRETTY_DEBUG << "The player position has been updated" << std::endl;
253 } else {
254 PRETTY_WARNING << "There is no player to update" << std::endl;
255 throw CustomExceptions::NoSprite("<No player>");
256 }
257 }
258 PRETTY_DEBUG << "Updating the enemy count component (if present)" << std::endl;
259 if (_remainingEnemies.has_value()) {
260 PRETTY_DEBUG << "Remaining enemy counter updated" << std::endl;
261 _remainingEnemies.value()->setText("Remaining ennemies: " + Recoded::myToString(_activeEnemies));
262 }
263 PRETTY_DEBUG << "Orchestrator dump (after tick): \n" << getInfo(0) << std::endl;
264
265 PRETTY_DEBUG << "Ticking all entities.";
266 tick_all();
267};
268
270{
271 for (std::size_t i = 0; i < _playerBrain.size(); i++) {
272 _playerBrain[i]->tick();
273 }
274 for (std::size_t i = 0; i < _enemyBrain.size(); i++) {
275 _enemyBrain[i]->tick();
276 }
277 for (std::size_t i = 0; i < _enemyBullets.size(); i++) {
278 _enemyBullets[i].tick();
279 }
280 for (std::size_t i = 0; i < _playerBullets.size(); i++) {
281 _playerBullets[i].tick();
282 }
283}
284
286{
287 PRETTY_DEBUG << "In the render function" << std::endl;
288 PRETTY_DEBUG << "Displaying the background image (if present)" << std::endl;
289 if (_backgroundItem.has_value()) {
290 PRETTY_DEBUG << "The background is present, displaying" << std::endl;
291 _window->draw(*(_backgroundItem.value()));
292 } else {
293 PRETTY_WARNING << "There is no background to display" << std::endl;
294 }
295 PRETTY_DEBUG << "Displayed the background image (if present)" << std::endl;
296 PRETTY_DEBUG << "Going to render the players" << std::endl;
297 unsigned int index = 0;
298 for (std::shared_ptr<GUI::ECS::Online::PlayerBrain> item : _playerBrain) {
299 std::string name = item->getSprite().getName();
300 std::pair<float, float> pos = item->getCollision().getPosition();
301 std::pair<float, float> dim = item->getCollision().getDimension();
302 bool visible = item->isVisible();
303 PRETTY_DEBUG << "_playerBrain[" << name << index << "]<" << pos << ">%" << dim << "%:" << Recoded::myToString(visible) << std::endl;
304 _window->draw(item->render());
305 index++;
306 }
307 PRETTY_DEBUG << "Players rendered" << std::endl;
308 PRETTY_DEBUG << "Going to render the ennemies" << std::endl;
309 index = 0;
310 for (std::shared_ptr<GUI::ECS::Online::EnemyBrain> item : _enemyBrain) {
311 std::string name = item->getSprite().getName();
312 std::pair<float, float> pos = item->getCollision().getPosition();
313 std::pair<float, float> dim = item->getCollision().getDimension();
314 bool visible = item->isVisible();
315 PRETTY_DEBUG << "_enemyBrain[" << name << index << "]<" << pos << ">%" << dim << "%:" << Recoded::myToString(visible) << std::endl;
316 _window->draw(item->render());
317 index++;
318 }
319 PRETTY_DEBUG << "Ennemies rendered" << std::endl;
320 PRETTY_DEBUG << "Going to render the player bullets" << std::endl;
321 index = 0;
322 for (GUI::ECS::Online::Bullet item : _playerBullets) {
323 std::string name = item.getSprite().getName();
324 std::pair<float, float> pos = item.getCollision().getPosition();
325 std::pair<float, float> dim = item.getCollision().getDimension();
326 bool enemy = item.isEnemy();
327 bool visible = item.isVisible();
328 PRETTY_DEBUG << "_playerBullets[" << name << index << "]<" << pos << ">%" << dim << "%(" << Recoded::myToString(enemy) << "):" << Recoded::myToString(visible) << std::endl;
329 _window->draw(item.render());
330 index++;
331 }
332 PRETTY_DEBUG << "Player bullets rendred" << std::endl;
333 PRETTY_DEBUG << "Going to render the enemy bullets" << std::endl;
334 index = 0;
335 for (GUI::ECS::Online::Bullet item : _enemyBullets) {
336 std::string name = item.getSprite().getName();
337 std::pair<float, float> pos = item.getCollision().getPosition();
338 std::pair<float, float> dim = item.getCollision().getDimension();
339 bool enemy = item.isEnemy();
340 bool visible = item.isVisible();
341 PRETTY_DEBUG << "_enemyBullets[" << name << index << "]<" << pos << ">%" << dim << "%(" << Recoded::myToString(enemy) << "):" << Recoded::myToString(visible) << std::endl;
342 _window->draw(item.render());
343 index++;
344 }
345 PRETTY_DEBUG << "Enemy bullets rendred" << std::endl;
346 PRETTY_DEBUG << "Rendering the overlay text (if present)" << std::endl;
347 if (_remainingEnemies.has_value()) {
348 PRETTY_DEBUG << "Remaining ennemies has a value, displaying" << std::endl;
349 _window->draw(*(_remainingEnemies.value()));
350 }
351 PRETTY_DEBUG << "Displayed the overlay text (if present)" << std::endl;
352 PRETTY_DEBUG << "Out of render()" << std::endl;
353};
354
356{
357 return _gameOver;
358}
359
361{
362 return _gameWon;
363}
364
365
366const std::string GUI::ECS::Online::Orchestrator::getInfo(const unsigned int indent) const
367{
368
369 std::string indentation = "";
370 for (unsigned int i = 0; i < indent; ++i) {
371 indentation += "\t";
372 }
373 std::string result = indentation + "Player brain:\n";
374 result += indentation + "- Entity Id: " + Recoded::myToString(getEntityNodeId()) + "\n";
375 result += indentation + "- Playing: '" + Recoded::myToString(_playing) + "'\n";
376 result += indentation + "- Game Won: '" + Recoded::myToString(_gameWon) + "'\n";
377 result += indentation + "- Game Over: '" + Recoded::myToString(_gameOver) + "'\n";
378 result += indentation + "- Step Up: '" + Recoded::myToString(_stepUp) + "'\n";
379 result += indentation + "- Step Down: '" + Recoded::myToString(_stepDown) + "'\n";
380 result += indentation + "- Step Left: '" + Recoded::myToString(_stepLeft) + "'\n";
381 result += indentation + "- Step Right: '" + Recoded::myToString(_stepRight) + "'\n";
382 result += indentation + "- Screen Position X Offset: '" + Recoded::myToString(_screenPosXOffset) + "'\n";
383 result += indentation + "- Screen Position Y Offset: '" + Recoded::myToString(_screenPosYOffset) + "'\n";
384 result += indentation + "- Active Enemies: '" + Recoded::myToString(_activeEnemies) + "'\n";
385 result += indentation + "- Player Id: '" + Recoded::myToString(_playerId) + "'\n";
386 result += indentation + "- Remaining enemies (has value): '" + Recoded::myToString(_remainingEnemies.has_value()) + "'\n";
387 if (_remainingEnemies.has_value()) {
388 result += indentation + "- Remaining enemies: {\n" + _remainingEnemies.value()->getInfo(indent + 1) + indentation + "}\n";
389 }
390 result += indentation + "- background item (has value): '" + Recoded::myToString(_backgroundItem.has_value()) + "'\n";
391 if (_backgroundItem.has_value()) {
392 result += indentation + "- background item: {\n" + _backgroundItem.value()->getInfo(indent + 1) + indentation + "}\n";
393 }
394 result += indentation + "- Sprite Bullet: {\n" + _spriteBullet->getInfo(indent + 1) + indentation + "}\n";
395 result += indentation + "- Sprite Bullet Enemy: {\n" + _spriteBulletEnemy->getInfo(indent + 1) + indentation + "}\n";
396 result += indentation + "- Sprite Player: {\n" + _spritePlayer->getInfo(indent + 1) + indentation + "}\n";
397 result += indentation + "- Sprite Enemy: {\n" + _spriteEnemy->getInfo(indent + 1) + indentation + "}\n";
398 result += indentation + "- Enemy Bullets: {\n";
399 for (unsigned int index = 0; index < _enemyBullets.size(); index++) {
400 result += indentation + "\t" + Recoded::myToString(index) + ": {\n";
401 result += _enemyBullets[index].getInfo(indent + 2);
402 result += indentation + "\t}\n";
403 }
404 result += indentation + "}\n";
405 result += indentation + "- Window: {\n" + _window->getInfo(indent + 1) + indentation + "}\n";
406 result += indentation + "- Event: {\n" + _event->getInfo(indent + 1) + indentation + "}\n";
407 result += indentation + "- Player Bullets: {\n";
408 for (unsigned int index = 0; index < _playerBullets.size(); index++) {
409 result += indentation + "\t" + Recoded::myToString(index) + ": {\n";
410 result += _playerBullets[index].getInfo(indent + 2);
411 result += indentation + "\t}\n";
412 }
413 result += indentation + "}\n";
414 result += indentation + "- Player Brains: {\n";
415 for (unsigned int index = 0; index < _playerBrain.size(); index++) {
416 result += indentation + "\t" + Recoded::myToString(index) + ": {\n";
417 result += _playerBrain[index]->getInfo(indent + 2);
418 result += indentation + "\t}\n";
419 }
420 result += indentation + "}\n";
421 result += indentation + "- Enemy Brains: {\n";
422 for (unsigned int index = 0; index < _enemyBrain.size(); index++) {
423 result += indentation + "\t" + Recoded::myToString(index) + ": {\n";
424 result += _enemyBrain[index]->getInfo(indent + 2);
425 result += indentation + "\t}\n";
426 }
427 result += indentation + "}\n";
428 result += indentation + "- Entity Id: " + Recoded::myToString(getEntityNodeId()) + "\n";
429 return result;
430}
431
432
433void GUI::ECS::Online::Orchestrator::_spawn(const std::uint32_t id, const std::pair<float, float> &pos)
434{
435 PRETTY_DEBUG << "In _spawn function in charge of creating the user" << std::endl;
436 if (_spritePlayer == nullptr) {
437 PRETTY_ERROR << "The _spritePlayer is set to nullptr" << std::endl;
438 throw CustomExceptions::NoSprite("<Sprite player not found>");
439 }
440 if (_spriteBullet == nullptr) {
441 PRETTY_ERROR << "The _spriteBullet is set to nullptr" << std::endl;
442 throw CustomExceptions::NoSprite("<Sprite bullet not found>");
443 }
444 PRETTY_DEBUG << "The _playerBrain shared pointer is going to be created" << std::endl;
445 std::shared_ptr<GUI::ECS::Online::PlayerBrain> playerEntity = std::make_shared<GUI::ECS::Online::PlayerBrain>(id);
446 PRETTY_DEBUG << "The playerEntity shared pointer has been created" << std::endl;
447 playerEntity->setSprite(_spritePlayer, _spriteBullet);
448 PRETTY_DEBUG << "The playerEntity has been set with the sprites of bullet and player" << std::endl;
449 playerEntity->setDimension({ 2,2 });
450 playerEntity->setPosition(pos);
451 playerEntity->setBulletSize({ 0.5,0.5 });
452 _playerBrain.push_back(playerEntity);
453 PRETTY_DEBUG << "Friend spawned" << std::endl;
454};
455
456void GUI::ECS::Online::Orchestrator::_spawnFriendBullet(const std::uint32_t id, const std::pair<float, float> &pos)
457{
458 PRETTY_DEBUG << "In _spawnFriendBullet function in charge of creating the user" << std::endl;
459 if (_spriteBullet == nullptr) {
460 PRETTY_ERROR << "The _spriteBullet is set to nullptr" << std::endl;
461 throw CustomExceptions::NoSprite("<Sprite bullet not found>");
462 }
463 PRETTY_DEBUG << "The _spawnFriendBullet shared pointer is going to be created" << std::endl;
464 const bool fromEnemy = false;
465 GUI::ECS::Online::Bullet bullet(id);
466 bullet.setSprite(*_spriteBullet);
467 bullet.setEnemy(fromEnemy);
468 bullet.setPosition(pos);
469 bullet.setDamage(5);
470 bullet.setDirection({ 1,0 });
471 bullet.setSpeed(1);
472 _playerBullets.push_back(bullet);
473 PRETTY_DEBUG << "Friend bullet created" << std::endl;
474};
475
476void GUI::ECS::Online::Orchestrator::_spawnEnemyBullet(const std::uint32_t id, const std::pair<float, float> &pos)
477{
478 PRETTY_DEBUG << "In _spawnEnemyBullet function in charge of creating the user" << std::endl;
479 if (_spriteBullet == nullptr) {
480 PRETTY_ERROR << "The _spriteBullet is set to nullptr" << std::endl;
481 throw CustomExceptions::NoSprite("<Sprite bullet not found>");
482 }
483 PRETTY_DEBUG << "The _spawnEnemyBullet shared pointer is going to be created" << std::endl;
484 const bool fromEnemy = true;
485 GUI::ECS::Online::Bullet bullet(id);
486 bullet.setSprite(*_spriteBullet);
487 bullet.setEnemy(fromEnemy);
488 bullet.setPosition(pos);
489 bullet.setDamage(5);
490 bullet.setDirection({ 1,0 });
491 bullet.setSpeed(1);
492 _enemyBullets.push_back(bullet);
493 PRETTY_DEBUG << "Enemy bullet created" << std::endl;
494};
495
496
497void GUI::ECS::Online::Orchestrator::_setPosition(const std::uint32_t id, const std::pair<float, float> &pos)
498{
499 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
500 std::size_t entityIndex = -1;
501 for (std::size_t i = 0; i < _playerBrain.size(); i++) {
502 if (_playerBrain[i]->getEntityNodeId() == id) {
503 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
504 entityIndex = i;
505 break;
506 }
507 }
508 if (entityIndex != -1) {
509 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
510 _playerBrain[entityIndex]->setPosition(pos);
511 return;
512 }
513 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
514 entityIndex = -1;
515 for (std::size_t i = 0; i < _enemyBrain.size(); i++) {
516 if (_enemyBrain[i]->getEntityNodeId() == id) {
517 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
518 entityIndex = i;
519 break;
520 }
521 }
522 if (entityIndex != -1) {
523 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
524 _enemyBrain[entityIndex]->setPosition(pos);
525 return;
526 }
527 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
528 entityIndex = -1;
529 for (std::size_t i = 0; i < _playerBullets.size(); i++) {
530 if (_playerBullets[i].getEntityNodeId() == id) {
531 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
532 entityIndex = i;
533 break;
534 }
535 }
536 if (entityIndex != -1) {
537 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
538 _playerBullets[entityIndex].setPosition(pos);
539 return;
540 }
541 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
542 entityIndex = -1;
543 for (std::size_t i = 0; i < _enemyBullets.size(); i++) {
544 if (_enemyBullets[i].getEntityNodeId() == id) {
545 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
546 entityIndex = i;
547 break;
548 }
549 }
550 if (entityIndex != -1) {
551 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
552 _enemyBullets[entityIndex].setPosition(pos);
553 return;
554 }
555 PRECISE_DEBUG << Recoded::myToString(id) << " was not found, thus not moved" << std::endl;
556}
557
558void GUI::ECS::Online::Orchestrator::_killEntity(const std::uint32_t id)
559{
560 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
561 std::size_t entityIndex = -1;
562 for (std::size_t i = 0; i < _playerBrain.size(); i++) {
563 if (_playerBrain[i]->getEntityNodeId() == id) {
564 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
565 entityIndex = i;
566 break;
567 }
568 }
569 if (entityIndex != -1) {
570 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
571 _playerBrain.erase(_playerBrain.begin() + entityIndex);
572 return;
573 }
574 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
575 entityIndex = -1;
576 for (std::size_t i = 0; i < _enemyBrain.size(); i++) {
577 if (_enemyBrain[i]->getEntityNodeId() == id) {
578 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
579 entityIndex = i;
580 break;
581 }
582 }
583 if (entityIndex != -1) {
584 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
585 _enemyBrain.erase(_enemyBrain.begin() + entityIndex);
586 _activeEnemies -= 1;
587 return;
588 }
589 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
590 entityIndex = -1;
591 for (std::size_t i = 0; i < _playerBullets.size(); i++) {
592 if (_playerBullets[i].getEntityNodeId() == id) {
593 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
594 entityIndex = i;
595 break;
596 }
597 }
598 if (entityIndex != -1) {
599 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
600 _playerBullets.erase(_playerBullets.begin() + entityIndex);
601 return;
602 }
603 PRETTY_DEBUG << "Checking if " << Recoded::myToString(id) << " is present in the vector" << std::endl;
604 entityIndex = -1;
605 for (std::size_t i = 0; i < _enemyBullets.size(); i++) {
606 if (_enemyBullets[i].getEntityNodeId() == id) {
607 PRETTY_DEBUG << Recoded::myToString(id) << " is present in the vector, marking for removal" << std::endl;
608 entityIndex = i;
609 break;
610 }
611 }
612 if (entityIndex != -1) {
613 PRETTY_DEBUG << "Removing " << Recoded::myToString(entityIndex) << std::endl;
614 _enemyBullets.erase(_enemyBullets.begin() + entityIndex);
615 return;
616 }
617 PRECISE_DEBUG << Recoded::myToString(id) << " was not present, thus not removed." << std::endl;
618}
619
620void GUI::ECS::Online::Orchestrator::_sendMessage(const GUI::Network::MessageNode &node)
621{
622 if (!_network.has_value()) {
623 PRETTY_CRITICAL << "There is no network manager to use to send packets" << std::endl;
624 throw CustomExceptions::NoNetworkClass("<No network manager for the online brain>");
625 }
626 PRETTY_DEBUG << "Sending message" << std::endl;
627 _network.value()->sendMessage(node);
628}
629
630void GUI::ECS::Online::Orchestrator::_kill()
631{
632 PRETTY_DEBUG << "The _kill function has been called" << std::endl;
633 for (unsigned int index = 0; index < _playerBrain.size(); index++) {
634 PRETTY_DEBUG << "Resetting players: " << index << std::endl;
635 _playerBrain[index].reset();
636 }
637 _playerBrain.clear();
638 for (unsigned int index = 0; index < _enemyBrain.size(); index++) {
639 PRETTY_DEBUG << "Resetting enemy: " << index << std::endl;
640 _enemyBrain[index].reset();
641 }
642 PRETTY_DEBUG << "Clearing enemy vector" << std::endl;
643 _enemyBrain.clear();
644 _activeEnemies = 0;
645 PRETTY_DEBUG << "Enemies cleared, size: " << _enemyBrain.size() << std::endl;
646 PRETTY_DEBUG << "Clearing remaining bullets" << std::endl;
647 unsigned int bIndex = 0;
648 while (_playerBullets.size() > 0) {
649 PRETTY_DEBUG << "Removing bullet: " << bIndex << ", bullet enemy: " << Recoded::myToString(_playerBullets[_playerBullets.size() - 1].isEnemy()) << std::endl;
650 _playerBullets.pop_back();
651 bIndex++;
652 }
653 PRETTY_DEBUG << "Removed the player bullets" << std::endl;
654 bIndex = 0;
655 while (_enemyBullets.size() > 0) {
656 PRETTY_DEBUG << "Removing bullet: " << bIndex << ", bullet enemy: " << Recoded::myToString(_enemyBullets[_enemyBullets.size() - 1].isEnemy()) << std::endl;
657 _enemyBullets.pop_back();
658 bIndex++;
659 }
660 PRETTY_DEBUG << "Removed the enemy bullets" << std::endl;
661 PRETTY_DEBUG << "A the end of the kill function" << std::endl;
662};
663
664void GUI::ECS::Online::Orchestrator::_spawnEnemy(const std::uint32_t id, std::pair<float, float> pos)
665{
666 PRETTY_DEBUG << "In spawn enemy" << std::endl;
667 if (_spriteEnemy == nullptr) {
668 PRETTY_ERROR << "The _spriteEnemy is set to nullptr" << std::endl;
669 throw CustomExceptions::NoSprite("<Sprite enemy not found>");
670 }
671 if (_spriteBulletEnemy == nullptr) {
672 PRETTY_ERROR << "The _spriteBulletEnemy is set to nullptr" << std::endl;
673 throw CustomExceptions::NoSprite("<Sprite bullet enemy not found>");
674 }
675 PRETTY_DEBUG << "The _enemyBrain shared pointer is going to be created" << std::endl;
676 std::shared_ptr<GUI::ECS::Online::EnemyBrain> enemy = std::make_shared<GUI::ECS::Online::EnemyBrain>(id);
677 PRETTY_DEBUG << "The _enemyBrain shared pointer has been created" << std::endl;
678 enemy->setSprite(_spriteEnemy, _spriteBulletEnemy);
679 PRETTY_DEBUG << "The sprite enemy and sprite bullet enemy has been set" << std::endl;
680 enemy->setPosition(pos);
681 PRETTY_DEBUG << "The enemy has been set with the position: " << pos << std::endl;
682 enemy->setVisible(true);
683 enemy->setDimension({ 4,4 });
684 enemy->setBulletSize({ 0.5, 0.5 });
685 PRETTY_DEBUG << "The enemy is visible" << std::endl;
686 _enemyBrain.push_back(enemy);
687 _activeEnemies += 1;
688 PRETTY_DEBUG << "The enemy has been added to the _enemyBrain" << std::endl;
689}
690
691const int GUI::ECS::Online::Orchestrator::_randInt(int min, int max)
692{
693 static std::random_device rd;
694 static std::mt19937 gen(rd());
695 std::uniform_int_distribution<> dist(min, max);
696 return dist(gen);
697}
698
699void GUI::ECS::Online::Orchestrator::_setTheScene()
700{
701 PRETTY_DEBUG << "Resetting the victory and loss variables" << std::endl;
702 _gameOver = false;
703 _gameWon = false;
704 PRETTY_DEBUG << "Reset the victory and loss variables" << std::endl;
705 PRETTY_DEBUG << "Resetting the position of the items on screen" << std::endl;
706 std::pair<float, float> pos = { 1,1 };
707 _spriteBullet->setPosition(pos);
708 _spriteBulletEnemy->setPosition(pos);
709 _spriteEnemy->setPosition(pos);
710 _spritePlayer->setPosition(pos);
711 PRETTY_DEBUG << "Reset the position of the items on screen" << std::endl;
712 _activeEnemies = 0;
713 PRETTY_DEBUG << "The enemies have been spawned" << std::endl;
714}
715
716void GUI::ECS::Online::Orchestrator::_setTextComponents()
717{
718
719 PRETTY_DEBUG << "Setting the health value of the player" << std::endl;
720 const std::vector<std::any> fonts = _ecsEntities[typeid(GUI::ECS::Systems::Font)];
721
722 PRETTY_DEBUG << "Declaring font holder instances" << std::endl;
723 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFont;
724 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont;
725 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont;
726 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFont;
727 PRETTY_DEBUG << "Declared font holder instances" << std::endl;
728 PRETTY_DEBUG << "Fetching the fonts that will be used in the window" << std::endl;
729 unsigned int index = 0;
730 unsigned int titleFontIndex = 0;
731 unsigned int bodyFontIndex = 0;
732 unsigned int defaultFontIndex = 0;
733 unsigned int buttonFontIndex = 0;
734 for (std::any fontCast : fonts) {
735 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> fontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fontCast, false);
736 if (!fontCapsule.has_value()) {
737 continue;
738 }
739 std::string applicationContext = fontCapsule.value()->getApplication();
740 if (applicationContext == "title") {
741 titleFontIndex = index;
742 } else if (applicationContext == "body") {
743 bodyFontIndex = index;
744 } else if (applicationContext == "default") {
745 defaultFontIndex = index;
746 } else if (applicationContext == "button") {
747 buttonFontIndex = index;
748 } else {
749 index++;
750 continue;
751 }
752 index++;
753 }
754 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[titleFontIndex], false);
755 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[bodyFontIndex], false);
756 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[defaultFontIndex], false);
757 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[buttonFontIndex], false);
758 if (!defaultFontCapsule.has_value()) {
759 PRETTY_DEBUG << "No default font found, aborting program" << std::endl;
760 throw CustomExceptions::NoFont("<Default font not found>");
761 }
762 defaultFont.emplace(defaultFontCapsule.value());
763 titleFont.emplace(defaultFontCapsule.value());
764 bodyFont.emplace(defaultFontCapsule.value());
765 buttonFont.emplace(defaultFontCapsule.value());
766 if (titleFontCapsule.has_value()) {
767 PRETTY_SUCCESS << "Title font found, not defaulting to the default font." << std::endl;
768 titleFont.emplace(titleFontCapsule.value());
769 }
770 if (bodyFontCapsule.has_value()) {
771 PRETTY_SUCCESS << "Body font found, not defaulting to the default font." << std::endl;
772 bodyFont.emplace(bodyFontCapsule.value());
773 }
774 if (buttonFontCapsule.has_value()) {
775 PRETTY_SUCCESS << "Button font found, not defaulting to the default font." << std::endl;
776 buttonFont.emplace(buttonFontCapsule.value());
777 }
778 PRETTY_DEBUG << "Fetched the fonts that will be used in the window" << std::endl;
779 PRETTY_DEBUG << "Creating the text to display the user's health" << std::endl;
780 const unsigned int size = 20;
781 const std::pair<float, float> posEnnemies = { 10, 40 };
782 std::shared_ptr<GUI::ECS::Components::TextComponent> textEnnemies = std::make_shared<GUI::ECS::Components::TextComponent>(
783 0,
784 *(bodyFont.value()),
785 "Remaining ennemies: ",
786 size,
790 posEnnemies
791 );
792 _remainingEnemies.emplace(textEnnemies);
793 PRETTY_DEBUG << "Fonts gathered" << std::endl;
794
795}
796
797
806void GUI::ECS::Online::Orchestrator::_shootSound()
807{
808 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
809 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
810 return;
811 }
812 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
813 if (!soundLib.has_value()) {
814 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
815 return;
816 }
817 soundLib.value()->shootSound();
818}
819
828void GUI::ECS::Online::Orchestrator::_damageSound()
829{
830 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
831 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
832 return;
833 }
834 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
835 if (!soundLib.has_value()) {
836 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
837 return;
838 }
839 soundLib.value()->damageSound();
840}
841
850void GUI::ECS::Online::Orchestrator::_deadSound()
851{
852 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
853 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
854 return;
855 }
856 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
857 if (!soundLib.has_value()) {
858 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
859 return;
860 }
861 soundLib.value()->deadSound();
862}
863
872void GUI::ECS::Online::Orchestrator::_buttonSound()
873{
874 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
875 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
876 return;
877 }
878 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
879 if (!soundLib.has_value()) {
880 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
881 return;
882 }
883 soundLib.value()->buttonSound();
884}
885
894void GUI::ECS::Online::Orchestrator::_gameOverSound()
895{
896 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
897 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
898 return;
899 }
900 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
901 if (!soundLib.has_value()) {
902 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
903 return;
904 }
905 soundLib.value()->gameOverSound();
906}
907
916void GUI::ECS::Online::Orchestrator::_winSound()
917{
918 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
919 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
920 return;
921 }
922 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
923 if (!soundLib.has_value()) {
924 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
925 return;
926 }
927 soundLib.value()->winSound();
928}
929
930std::ostream &GUI::ECS::Online::operator<<(std::ostream &os, const GUI::ECS::Online::Orchestrator &item)
931{
932 os << item.getInfo();
933 return os;
934}
#define PRETTY_ERROR
Error log with details and colour.
#define PRECISE_DEBUG
Debug log with precise details.
#define PRETTY_DEBUG
Debug log with details and colour.
#define PRETTY_CRITICAL
Critical log with details and colour.
#define PRETTY_WARNING
Warning log with details and colour.
#define PRETTY_SUCCESS
Success log with details and colour.
Declaration of the Orchestrator class and its related functionality.
std::random_device rd
Definition Random.cpp:4
This is the class in charge of informing the user that they tried to access a non-existant Event Mana...
Definition No.hpp:87
This is the class in charge of informing the user that they tried to access a non-existant font insta...
Definition No.hpp:358
This is the class in charge of informing the user that the program could not find any network class i...
Definition No.hpp:964
This is the class in charge of informing the user that they tried to access a non-existant animation ...
Definition No.hpp:298
This is the class in charge of informing the user that they tried to access a non-existant window.
Definition No.hpp:57
Represents an image component in the GUI ECS system.
Represents a drawable and interactive sprite in the ECS system.
Represents a bullet entity in the game.
Definition Bullet.hpp:31
The Orchestrator class manages the overall game state, including entity creation, updates,...
const bool isGameWon() const
Checks if the game has been won.
void tick(const std::vector< GUI::Network::MessageNode > &packets)
Updates the game state for the current frame.
void start()
Starts the game logic and sets the game to a playing state.
void reset()
Resets the game state, clearing all entities and resetting conditions.
const bool isGameOver() const
Checks if the game is over.
void render()
Renders the game entities to the window.
void stop()
Stops the game logic and resets the playing state.
Orchestrator(const std::uint32_t entityId=0)
Default constructor.
void initialiseClass(std::unordered_map< std::type_index, std::vector< std::any > > &ecsEntities)
Initializes the ECS entities managed by the orchestrator.
void tick_all()
Ticks all entities.
const std::string getInfo(const unsigned int indent=0) const
This is a function meant for debugging purposes It will dump the current state of the variables upon ...
void setNetworkClass(const std::shared_ptr< GUI::Network::ThreadCapsule > &network)
static const Colour Red
Definition Colour.hpp:322
Manages input events such as mouse movements, key presses, and window interactions.
Manages font entities in the GUI ECS.
Definition Font.hpp:45
Manages an SFML-based graphical window and handles rendering of ECS components.
Definition Window.hpp:67
The SoundLib class manages sound effects and interactions with ECS entities.
Definition SoundLib.hpp:35
std::ostream & operator<<(std::ostream &os, const Bullet &item)
Outputs the sprite's info to a stream.
Definition Bullet.cpp:260
const std::string myToString(const Rect< RectType > &rectangle)
Converts a Rect<T> object to its string representation.
Definition Rect.hpp:223
std::optional< T > unCast(const std::any &classNode, const bool raiseOnError=true, const std::string customErrorMessage="")
Casts the content of a std::any back to its original type.
Definition UnCast.hpp:65