RType
Lobby.cpp
Go to the documentation of this file.
1 /*
2 ** EPITECH PROJECT, 2023
3 ** R-type
4 ** File description:
5 ** R-type
6 */
7 
8 #include "Lobby.hpp"
9 #include "Collision.hpp"
10 #include "Graphic.hpp"
11 #include "Move.hpp"
12 #include "Spawner.hpp"
13 #include <random>
14 
15 /**
16  * @brief Construct a new LobbyScene:: LobbyScene object
17  * @param serverSocket
18  */
19 LobbyScene::LobbyScene(std::shared_ptr<ServerSocket> serverSocket) :
21 {
23  gettimeofday(&_chrono, nullptr);
24  gettimeofday(&_start, nullptr);
25  _bulletTriggerLimiter = {0, 0};
26  _nbBullets = 0;
27  _nbBossBullets = 0;
28  _lifeBoss = 10;
29 }
30 
31 /**
32  * @brief initScene, init the scene
33  */
35 {
38 }
39 
40 /**
41  * @brief initEntities, init the entities
42  */
44 {
45  std::shared_ptr<IEntity> floor_bg = std::make_shared<IEntity>();
46  std::shared_ptr<Drawable> sprite_floor_bg = std::make_shared<Drawable>();
47  std::shared_ptr<Animatable> animation_floor_bg = std::make_shared<Animatable>();
48  sprite_floor_bg->setRect({0, 0, 800, 30});
49  sprite_floor_bg->setSize({1600 * 4, 30 * 4});
50  sprite_floor_bg->setScale(4);
51  sprite_floor_bg->setPosition({0, 480});
52  sprite_floor_bg->setAttribute("sprite floor bg");
53  sprite_floor_bg->_textureId = FLOOR_BACKGROUND;
54  gettimeofday(&animation_floor_bg->_chrono, nullptr);
55  animation_floor_bg->setTarget(sprite_floor_bg);
56  animation_floor_bg->setTime({0, 10000});
57  animation_floor_bg->_frameIndex = 0;
58  animation_floor_bg->_numberFrameToAnim = 800 * 4;
59  animation_floor_bg->_numberFrame = 1600 * 4;
60  animation_floor_bg->_startFrameIndex = 0;
61  animation_floor_bg->_frameForOnePicture = 800 * 4;
62  floor_bg->setAttribute("sprite floor bg");
63  floor_bg->addComponent(sprite_floor_bg);
64  floor_bg->addComponent(animation_floor_bg);
65 
66  std::shared_ptr<IEntity> roof_bg = std::make_shared<IEntity>();
67  std::shared_ptr<Drawable> sprite_roof_bg = std::make_shared<Drawable>();
68  std::shared_ptr<Animatable> animation_roof_bg = std::make_shared<Animatable>();
69  sprite_roof_bg->setRect({0, 0, 800, 30});
70  sprite_roof_bg->setSize({1600 * 4, 30 * 4});
71  sprite_roof_bg->setScale(4);
72  sprite_roof_bg->setPosition({0, 0});
73  sprite_roof_bg->setAttribute("sprite roof bg");
74  sprite_roof_bg->_textureId = ROOF_BACKGROUND;
75  gettimeofday(&animation_roof_bg->_chrono, nullptr);
76  animation_roof_bg->setTarget(sprite_roof_bg);
77  animation_roof_bg->setTime({0, 10000});
78  animation_roof_bg->_frameIndex = 0;
79  animation_roof_bg->_numberFrameToAnim = 800 * 4;
80  animation_roof_bg->_numberFrame = 1600 * 4;
81  animation_roof_bg->_startFrameIndex = 0;
82  animation_roof_bg->_frameForOnePicture = 800 * 4;
83  roof_bg->setAttribute("sprite roof bg");
84  roof_bg->addComponent(sprite_roof_bg);
85  roof_bg->addComponent(animation_roof_bg);
86 
87  std::shared_ptr<IEntity> bg1 = std::make_shared<IEntity>();
88  std::shared_ptr<Drawable> sprite_bg1 = std::make_shared<Drawable>();
89  std::shared_ptr<Animatable> animation_bg1 = std::make_shared<Animatable>();
90  sprite_bg1->setRect({0, 0, 800, 600});
91  sprite_bg1->setSize({1600, 600});
92  sprite_bg1->setScale(1);
93  sprite_bg1->setPosition({0, 0});
94  sprite_bg1->setAttribute("sprite bg1");
95  sprite_bg1->_textureId = BACKGROUND1;
96  gettimeofday(&animation_bg1->_chrono, nullptr);
97  animation_bg1->setTarget(sprite_bg1);
98  animation_bg1->setTime({0, 10000});
99  animation_bg1->_frameIndex = 0;
100  animation_bg1->_numberFrameToAnim = 800;
101  animation_bg1->_numberFrame = 1600;
102  animation_bg1->_startFrameIndex = 0;
103  animation_bg1->_frameForOnePicture = 800;
104  bg1->setAttribute("sprite bg1");
105  bg1->addComponent(sprite_bg1);
106  bg1->addComponent(animation_bg1);
107 
108  std::shared_ptr<IEntity> bg2 = std::make_shared<IEntity>();
109  std::shared_ptr<Drawable> sprite_bg2 = std::make_shared<Drawable>();
110  std::shared_ptr<Animatable> animation_bg2 = std::make_shared<Animatable>();
111  sprite_bg2->setRect({0, 0, 800, 600});
112  sprite_bg2->setSize({1600, 600});
113  sprite_bg2->setScale(1);
114  sprite_bg2->setPosition({0, 0});
115  sprite_bg2->setAttribute("sprite bg2");
116  sprite_bg2->_textureId = BACKGROUND2;
117  gettimeofday(&animation_bg2->_chrono, nullptr);
118  animation_bg2->setTarget(sprite_bg2);
119  animation_bg2->setTime({0, 30000});
120  animation_bg2->_frameIndex = 0;
121  animation_bg2->_numberFrameToAnim = 800;
122  animation_bg2->_numberFrame = 1600;
123  animation_bg2->_startFrameIndex = 0;
124  animation_bg2->_frameForOnePicture = 800;
125  bg2->setAttribute("sprite bg2");
126  bg2->addComponent(sprite_bg2);
127  bg2->addComponent(animation_bg2);
128 
129  std::shared_ptr<IEntity> bg3 = std::make_shared<IEntity>();
130  std::shared_ptr<Drawable> sprite_bg3 = std::make_shared<Drawable>();
131  std::shared_ptr<Animatable> animation_bg3 = std::make_shared<Animatable>();
132  sprite_bg3->setRect({0, 0, 800, 600});
133  sprite_bg3->setSize({1600, 600});
134  sprite_bg3->setScale(1);
135  sprite_bg3->setPosition({0, 0});
136  sprite_bg3->setAttribute("sprite bg3");
137  sprite_bg3->_textureId = BACKGROUND3;
138  gettimeofday(&animation_bg3->_chrono, nullptr);
139  animation_bg3->setTarget(sprite_bg3);
140  animation_bg3->setTime({0, 5000});
141  animation_bg3->_frameIndex = 0;
142  animation_bg3->_numberFrameToAnim = 800;
143  animation_bg3->_numberFrame = 1600;
144  animation_bg3->_startFrameIndex = 0;
145  animation_bg3->_frameForOnePicture = 800;
146  bg3->setAttribute("sprite bg3");
147  bg3->addComponent(sprite_bg3);
148  bg3->addComponent(animation_bg3);
149 
150  std::shared_ptr<IEntity> bg4 = std::make_shared<IEntity>();
151  std::shared_ptr<Drawable> sprite_bg4 = std::make_shared<Drawable>();
152  std::shared_ptr<Animatable> animation_bg4 = std::make_shared<Animatable>();
153  sprite_bg4->setRect({0, 0, 800, 600});
154  sprite_bg4->setSize({1600, 600});
155  sprite_bg4->setScale(1);
156  sprite_bg4->setPosition({0, 0});
157  sprite_bg4->setAttribute("sprite bg4");
158  sprite_bg4->_textureId = BACKGROUND4;
159  gettimeofday(&animation_bg4->_chrono, nullptr);
160  animation_bg4->setTarget(sprite_bg4);
161  animation_bg4->setTime({0, 50000});
162  animation_bg4->_frameIndex = 0;
163  animation_bg4->_numberFrameToAnim = 800;
164  animation_bg4->_numberFrame = 1600;
165  animation_bg4->_startFrameIndex = 0;
166  animation_bg4->_frameForOnePicture = 800;
167  bg4->setAttribute("sprite bg4");
168  bg4->addComponent(sprite_bg4);
169  bg4->addComponent(animation_bg4);
170 
171  addEntity(bg1);
172  addEntity(bg2);
173  addEntity(bg3);
174  addEntity(bg4);
175  // addEntity(floor_bg);
176  // addEntity(roof_bg);
177  // addEntity(enemy1);
178  // addEntity(enemy2);
179 }
180 
181 /**
182  * @brief initServices, init the services
183  */
184 
186  std::shared_ptr<IEntity> boss = std::make_shared<IEntity>();
187  std::shared_ptr<Drawable> sprite_boss = std::make_shared<Drawable>();
188  std::shared_ptr<Animatable> animation_boss = std::make_shared<Animatable>();
189  std::shared_ptr<Timer> timer_boss = std::make_shared<Timer>();
190  gettimeofday(&timer_boss->_startTime, nullptr);
191  timer_boss->_targetTime.tv_sec = 0;
192  timer_boss->_targetTime.tv_usec = 25000;
193  timer_boss->setTarget(sprite_boss);
194  timer_boss->setActive(true);
195  timer_boss->setDirection(-1);
196  sprite_boss->setRect({0, 0, 161, 214});
197  sprite_boss->setSize({973 * 2, 214 * 2});
198  sprite_boss->setScale(2);
199  sprite_boss->setPosition({1000, 100});
200  sprite_boss->setAttribute("sprite boss");
201  sprite_boss->_textureId = BOSS;
202  gettimeofday(&animation_boss->_chrono, nullptr);
203  animation_boss->setTarget(sprite_boss);
204  animation_boss->setTime({0, 200000});
205  animation_boss->_frameIndex = 0;
206  animation_boss->_numberFrameToAnim = 6;
207  animation_boss->_numberFrame = 6;
208  animation_boss->_startFrameIndex = 0;
209  animation_boss->_frameForOnePicture = 1;
210  boss->setAttribute("sprite boss");
211  boss->addComponent(sprite_boss);
212  boss->addComponent(animation_boss);
213  boss->addComponent(timer_boss);
214 
215  addEntity(boss);
216 }
217 
218 int generateRandomNumber(int lowerBound, int upperBound) {
219  // Utilisez std::random_device pour initialiser le générateur de nombres aléatoires
220  std::random_device rd;
221 
222  // Utilisez std::mt19937 comme générateur de nombres aléatoires
223  std::mt19937 gen(rd());
224 
225  // Utilisez std::uniform_int_distribution pour spécifier la plage de valeurs
226  std::uniform_int_distribution<int> distribution(lowerBound, upperBound);
227 
228  // Générez le nombre aléatoire
229  int randomNumber = distribution(gen);
230 
231  return randomNumber;
232 }
233 
234 /**
235  * @brief shootBoss, boss attacks
236  */
237 void LobbyScene::shootBoss(int nb) {
238  for (int i = 0; i < nb; i++) {
239  std::tuple<float, float> position = std::make_tuple(500, generateRandomNumber(0, 601 - 36 * 2));
240  std::shared_ptr <IEntity> boss_bullet = std::make_shared<IEntity>();
241  std::shared_ptr <Drawable> sprite_boss_bullet = std::make_shared<Drawable>();
242  std::shared_ptr <Animatable> animation_boss_bullet = std::make_shared<Animatable>();
243  std::shared_ptr <Timer> timer_boss_bullet = std::make_shared<Timer>();
244  gettimeofday(&timer_boss_bullet->_startTime, nullptr);
245  timer_boss_bullet->_targetTime.tv_sec = 0;
246  timer_boss_bullet->_targetTime.tv_usec = 10000;
247  timer_boss_bullet->setTarget(sprite_boss_bullet);
248  timer_boss_bullet->setActive(true);
249  timer_boss_bullet->setDirection(-1);
250  sprite_boss_bullet->setRect({0, 0, 23, 23});
251  sprite_boss_bullet->setSize({94 * 3, 23 * 3});
252  sprite_boss_bullet->setScale(3);
253  sprite_boss_bullet->setPosition(position);
254  sprite_boss_bullet->setAttribute(
255  "boss attack" + std::to_string(_nbBossBullets));
256  _nbBossBullets++;
257  sprite_boss_bullet->_textureId = BOSS_BULLET;
258  gettimeofday(&animation_boss_bullet->_chrono, nullptr);
259  animation_boss_bullet->setTarget(sprite_boss_bullet);
260  animation_boss_bullet->setTime({0, 200000});
261  animation_boss_bullet->_frameIndex = 0;
262  animation_boss_bullet->_numberFrameToAnim = 4;
263  animation_boss_bullet->_numberFrame = 4;
264  animation_boss_bullet->_startFrameIndex = 0;
265  animation_boss_bullet->_frameForOnePicture = 1;
266  boss_bullet->setAttribute("boss attack");
267  boss_bullet->addComponent(sprite_boss_bullet);
268  boss_bullet->addComponent(animation_boss_bullet);
269  boss_bullet->addComponent(timer_boss_bullet);
270 
271  addEntity(boss_bullet);
272  }
273 }
274 
275 /**
276  * @brief initServices, init the services
277  */
279 {
280  std::shared_ptr<Graphic> graphic = std::make_shared<Graphic>(_serverSocket);
281  std::shared_ptr<TimeManagement> timeManagement = std::make_shared<TimeManagement>(_serverSocket);
282  std::shared_ptr<Animation> animation = std::make_shared<Animation>(_serverSocket);
283  std::shared_ptr<Collision> collision = std::make_shared<Collision>(_serverSocket);
284  std::shared_ptr<Move> move = std::make_shared<Move>(_serverSocket);
285 
286  addService(graphic);
287  addService(collision);
288  addService(move);
289  addService(animation);
290  addService(timeManagement);
291 }
292 
294 {
295  int spaceBetweenEnemy = 0;
296  int nbEntityToSpawn = generateRandomNumber(std::get<0>(_numberEntityWave), std::get<1>(_numberEntityWave));
297  for (int i = 0; i < nbEntityToSpawn; ++i) {
298  int randomVertcalPosition = generateRandomNumber(0, 601 - 36 * 2);// 601 car le modulo exclut la borne supérieure et 36 * 2 car la taille de l'ennemi est de 36 * 2
299 
300  std::shared_ptr <IEntity> enemy = std::make_shared<IEntity>();
301  std::shared_ptr <Drawable> sprite_enemy = std::make_shared<Drawable>();
302  std::shared_ptr <Animatable> animation_enemy = std::make_shared<Animatable>();
303  std::shared_ptr <Timer> timer_enemy = std::make_shared<Timer>();
304  gettimeofday(&timer_enemy->_startTime, nullptr);
305  timer_enemy->_targetTime.tv_sec = 0;
306  timer_enemy->_targetTime.tv_usec = 40000;
307  timer_enemy->setTarget(sprite_enemy);
308  timer_enemy->setActive(true);
309  timer_enemy->setDirection(-1);
310  sprite_enemy->setRect({0, 0, 33, 36});
311  sprite_enemy->setSize({263 * 2, 36 * 2});
312  sprite_enemy->setScale(2);
313  sprite_enemy->setPosition({1000 + spaceBetweenEnemy, randomVertcalPosition});
314  sprite_enemy->setAttribute(
315  "sprite enemy" + std::to_string(i));
316  sprite_enemy->_textureId = ENEMY;
317  gettimeofday(&animation_enemy->_chrono, nullptr);
318  animation_enemy->setTarget(sprite_enemy);
319  animation_enemy->setTime({0, 200000});
320  animation_enemy->_frameIndex = 0;
321  animation_enemy->_numberFrameToAnim = 8;
322  animation_enemy->_numberFrame = 8;
323  animation_enemy->_startFrameIndex = 0;
324  animation_enemy->_frameForOnePicture = 1;
325  enemy->setAttribute("sprite enemy");
326  enemy->addComponent(sprite_enemy);
327  enemy->addComponent(animation_enemy);
328  enemy->addComponent(timer_enemy);
329 
330  addEntity(enemy);
331  spaceBetweenEnemy += 20 + 33 * 2;
332 
333  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
334  sendpacket->code = NEW_COMPONENT;
335  sendpacket->data_size = sizeof(NewComponent);
336  sendpacket->data = malloc(sendpacket->data_size);
337  NewComponent newComponent{};
338  newComponent.type = ComponentTypeSocket::SPRITESOCKET;
339  newComponent.id = ENEMY;
340  std::memcpy(&newComponent.attribute, enemy->getAttribute().c_str(), 16);
341  memcpy(sendpacket->data, &newComponent, sendpacket->data_size);
342  _serverSocket->broadcast(sendpacket.get());
343  free(sendpacket->data);
344 
346  }
347  _spawnerActive = false;
348 }
349 
351 {
352  for (auto &entity : getEntities()) {
353  if (entity->getAttribute() == "sprite enemy") {
354  for (const auto &component : entity->getComponents()) {
355  auto drawable = std::dynamic_pointer_cast<Drawable>(component);
356  if (drawable != nullptr && std::get<0>(drawable->getPosition()) > - 33 * 2) {
357  return false; // Au moins un ennemi n'a pas quitté l'écran
358  }
359  }
360  }
361  }
362  return true; // Tous les ennemis ont quitté l'écran
363 }
364 
366 {
367  for (auto &entity : getEntities()) {
368  if (entity->getAttribute() == "boss attack") {
369  for (const auto &component : entity->getComponents()) {
370  auto drawable = std::dynamic_pointer_cast<Drawable>(component);
371  if (drawable != nullptr && std::get<0>(drawable->getPosition()) > - 33 * 2) {
372  return false; // Au moins un ennemi n'a pas quitté l'écran
373  }
374  }
375  }
376  }
377  return true; // Tous les ennemis ont quitté l'écran
378 }
379 
381 {
382  for (auto &entity : getEntities()) {
383  for (auto &component : entity->getComponents()) {
384  if (std::string(component->getAttribute()).find("enemy") != std::string::npos) {
385  auto draw = std::dynamic_pointer_cast<Drawable>(component);
386 
387  _entities.erase(std::remove(_entities.begin(), _entities.end(), entity), _entities.end());
388  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
389  sendpacket->code = DELETE_COMPONENT;
390  sendpacket->data_size = std::string(component->getAttribute()).size();
391  sendpacket->data = malloc(sendpacket->data_size);
392  std::memcpy(sendpacket->data, component->getAttribute(), sendpacket->data_size);
393  _serverSocket->broadcast(sendpacket.get());
394  free(sendpacket->data);
395  }
396  }
397  }
398 }
399 
401 {
402  for (auto &entity : getEntities()) {
403  if (entity->getAttribute() == "boss attack") {
404  for (const auto &component : entity->getComponents()) {
405  auto drawable = std::dynamic_pointer_cast<Drawable>(component);
406  if (drawable != nullptr) {
407  drawable->_toDelete = true;
408  }
409  }
410  }
411  }
412 }
413 
414 /**
415  * @brief update, update the scene
416  * @param event
417  * @param packet
418  */
419 void LobbyScene::update(std::shared_ptr<Event> event, std::shared_ptr<Packet> packet)
420 {
421  timeval now{};
422  timeval diff{};
423  gettimeofday(&now, nullptr);
424  timersub(&now, &_chrono, &diff);
425 
426  if (event->key != sf::Keyboard::Key::Unknown)
427  _lastEvent = event;
428 
429  if (diff.tv_usec >= 20000) {
430  for (auto &_entitie : _entities) {
431  for (auto &component : _entitie->getComponents()) {
432  for (auto &service : _services) {
433  service->update(_lastEvent, component);
434  }
435  }
436  }
437  _lastEvent = nullptr;
438  _chrono = now;
439  }
440 
441  if (!_bossActive) {
442  if (now.tv_sec - _start.tv_sec >= 5) {
443  if (_spawnerActive) {
445  } else if (allEnemiesLeftScreen()) {
447  _spawnerActive = true;
448  }
449  }
450  if (now.tv_sec - _start.tv_sec >= 45) {
451  _bossActive = true;
452  _timing = now.tv_sec;
453  spawnBoss();
454  }
455  }
456 
457  if (_bossActive) {
458  if (now.tv_sec - _start.tv_sec >= 45 && now.tv_sec - _timing >= 5 && _nbBossBullets < 11) {
460  _timing = now.tv_sec;
461  }
464  }
465 
467 
468  auto entitytodelete = _entities.begin();
469  while (entitytodelete != _entities.end()) {
470  for (auto &component : (*entitytodelete)->getComponents()) {
471  auto drawable = std::dynamic_pointer_cast<Drawable>(component);
472  if (drawable && drawable->_toDelete) {
473  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
474 
475  sendpacket->code = DELETE_COMPONENT;
476  sendpacket->data_size = std::string(drawable->getAttribute()).size();
477  sendpacket->data = malloc(sendpacket->data_size);
478  std::memcpy(sendpacket->data, drawable->getAttribute(), sendpacket->data_size);
479  _serverSocket->broadcast(sendpacket.get());
480 
481  free(sendpacket->data);
482 
483  entitytodelete = _entities.erase(entitytodelete);
484 
485  break;
486  }
487  }
488  if (entitytodelete != _entities.end())
489  entitytodelete++;
490  }
491 
492  if (packet != nullptr) {
493  int id = event->id;
494  if (packet->code == MESSAGE) {
495  if (std::string(static_cast<char *>(packet->data)) == "enter game") {
496  std::cout << "enter game player id " << id << std::endl;
497  std::shared_ptr<IEntity> entity = std::make_shared<IEntity>();
498  std::shared_ptr<Drawable> drawable = std::make_shared<Drawable>();
499 
500  drawable->setAttribute("player " + std::to_string(id));
501  drawable->setPosition({100 * id, 100 * id});
502  drawable->setHasChanged(true);
503  drawable->_textureId = PLAYER;
504  for (const auto &e : getEntities()) {
505  for (const auto &component : e->getComponents()) {
506  std::string attribute = component->getAttribute();
507  auto drawablePlayer = std::dynamic_pointer_cast<Drawable>(component);
508  bool isPlayer = attribute.substr(0, 6) == "player";
509  if (isPlayer && drawablePlayer) {
510  drawable->addDrawableCollision(drawablePlayer);
511  drawablePlayer->addDrawableCollision(drawable);
512  }
513  }
514  }
515  drawable->setRect({101, 0, 33, 17});
516  drawable->setScale(2);
517  drawable->setSize({532 * drawable->getScale(), 372 * drawable->getScale()});
518  entity->addComponent(drawable);
519  entity->setAttribute("player " + std::to_string(id));
520  addEntity(entity);
521  std::cout << "Entity added" << std::endl;
522 
523  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
524  sendpacket->code = NEW_COMPONENT;
525  sendpacket->data_size = sizeof(NewComponent);
526  sendpacket->data = malloc(sendpacket->data_size);
527  NewComponent newComponent{};
528  newComponent.type = ComponentTypeSocket ::SPRITESOCKET;
529  newComponent.id = PLAYER;
530  std::memcpy(&newComponent.attribute, entity->getAttribute().c_str(), 8);
531  std::memcpy(&newComponent.attribute2, entity->getAttribute().c_str() + 8, 8);
532  memcpy(sendpacket->data, &newComponent, sendpacket->data_size);
533  _serverSocket->broadcast(sendpacket.get());
534  free(sendpacket->data);
535 
536  std::shared_ptr<Packet> sendpacket2 = std::make_shared<Packet>();
537  sendpacket2->code = MESSAGE;
538  sendpacket2->data_size = ("event: Player " + std::to_string(id) + " joined the game").size();
539  sendpacket2->data = malloc(sendpacket2->data_size);
540  std::memcpy(sendpacket2->data, ("event: Player " + std::to_string(id) + " joined the game").c_str(), sendpacket2->data_size);
541  _serverSocket->broadcast(sendpacket2.get());
542  free(sendpacket2->data);
543 
544  sendGameState(id);
546  }
547  if (std::string(static_cast<char *>(packet->data)) == "exit game") {
548  std::cout << "exit game player id " << id << std::endl;
549  // delete Entity("player " + std::to_string(id));
550  for (auto &entity : _entities) {
551  if (entity->getAttribute() == "player " + std::to_string(id)) {
552  _entities.erase(std::remove(_entities.begin(), _entities.end(), entity), _entities.end());
553  break;
554  }
555  }
556  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
557  sendpacket->code = DELETE_COMPONENT;
558  sendpacket->data_size = ("player " + std::to_string(id)).size();
559  sendpacket->data = malloc(sendpacket->data_size);
560  std::memcpy(sendpacket->data, ("player " + std::to_string(id)).c_str(), sendpacket->data_size);
561  _serverSocket->broadcast(sendpacket.get());
562  free(sendpacket->data);
563 
564  std::shared_ptr<Packet> sendpacket2 = std::make_shared<Packet>();
565  sendpacket2->code = MESSAGE;
566  sendpacket2->data_size = ("event: Player " + std::to_string(id) + " left the game").size();
567  sendpacket2->data = malloc(sendpacket2->data_size);
568  std::memcpy(sendpacket2->data, ("event: Player " + std::to_string(id) + " left the game").c_str(), sendpacket2->data_size);
569  _serverSocket->broadcast(sendpacket2.get());
570  std::cout << "broadcasted" << std::endl;
571  free(sendpacket2->data);
572 
574  }
575  }
576  }
577 
578  int clientIdDisconnected = _serverSocket->checkClientsDeconnection();
579 
580  if (clientIdDisconnected != -1) {
581  std::cout << "Client " << clientIdDisconnected << " disconnected" << std::endl;
582  for (auto &entity : _entities) {
583  if (entity->getAttribute() == "player " + std::to_string(clientIdDisconnected)) {
584  _entities.erase(std::remove(_entities.begin(), _entities.end(), entity), _entities.end());
585  break;
586  }
587  }
588  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
589  sendpacket->code = DELETE_COMPONENT;
590  sendpacket->data_size = ("player " + std::to_string(clientIdDisconnected)).size();
591  sendpacket->data = malloc(sendpacket->data_size);
592  std::memcpy(sendpacket->data, ("player " + std::to_string(_serverSocket->checkClientsDeconnection())).c_str(),
593  sendpacket->data_size);
594  _serverSocket->broadcast(sendpacket.get());
595  free(sendpacket->data);
596 
597  std::shared_ptr<Packet> sendpacket2 = std::make_shared<Packet>();
598  sendpacket2->code = MESSAGE;
599  sendpacket2->data_size = ("event: Player " + std::to_string(clientIdDisconnected) + " left the game").size();
600  sendpacket2->data = malloc(sendpacket2->data_size);
601  std::memcpy(sendpacket2->data, ("event: Player " + std::to_string(clientIdDisconnected) + " left the game").c_str(), sendpacket2->data_size);
602  _serverSocket->broadcast(sendpacket2.get());
603  free(sendpacket2->data);
604 
606  }
607 
608  if (event->key == sf::Keyboard::Key::Space) {
609  timeval nowbullet{};
610  timeval diffbullet{};
611  gettimeofday(&nowbullet, nullptr);
612  timersub(&nowbullet, &_bulletTriggerLimiter, &diffbullet);
613 
614  if (_bulletTriggerLimiter.tv_sec != 0 && _bulletTriggerLimiter.tv_usec != 0)
615  if (diffbullet.tv_sec <= 0 && diffbullet.tv_usec < 500000)
616  return;
617 
618  _bulletTriggerLimiter = {0, 0};
619 
620  gettimeofday(&_bulletTriggerLimiter, nullptr);
621 
622  std::shared_ptr<IEntity> bullet = std::make_shared<IEntity>();
623  std::shared_ptr<Drawable> bullet_sprite = std::make_shared<Drawable>();
624  std::shared_ptr<Timer> timer = std::make_shared<Timer>();
625 
626  std::shared_ptr<IEntity> player = nullptr;
627 
628  for (const auto &entity : getEntities())
629  for (const auto &component : entity->getComponents()) {
630  if (component->getAttribute() == "player " + std::to_string(event->id)) {
631  player = entity;
632  break;
633  }
634  }
635 
636  if (player != nullptr) {
637 
638  auto draw = std::dynamic_pointer_cast<Drawable>(player->getComponents()[0]);
639 
640  if (draw != nullptr) {
641  auto [x, y] = draw->getPosition();
642 
643  bullet_sprite->setPosition({x, y});
644  bullet_sprite->setAttribute("bullet" + std::to_string(_nbBullets));
645  _nbBullets++;
646  bullet_sprite->_textureId = BULLET;
647  bullet_sprite->setRect({233, 120, 32, 12});
648  bullet_sprite->setScale(3);
649  bullet_sprite->setSize({532 * bullet_sprite->getScale(), 372 * bullet_sprite->getScale()});
650  bullet->addComponent(bullet_sprite);
651  bullet->setAttribute("bullet" + std::to_string(_nbBullets));
652  timer->_targetTime.tv_sec = 0;
653  timer->_targetTime.tv_usec = 25000;
654  timer->setTarget(bullet_sprite);
655  timer->setActive(true);
656  bullet->addComponent(timer);
657 
658  for (const auto &e : getEntities()) {
659  for (const auto &component : e->getComponents()) {
660  std::string attribute = component->getAttribute();
661  auto enemy = std::dynamic_pointer_cast<Drawable>(component);
662  if (enemy && enemy->_textureId == ENEMY)
663  bullet_sprite->addDrawableCollision(enemy);
664  if (enemy && enemy->_textureId == BOSS)
665  bullet_sprite->addDrawableCollision(enemy);
666  }
667  }
668 
669  addEntity(bullet);
670 
671  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
672  sendpacket->code = NEW_COMPONENT;
673  sendpacket->data_size = sizeof(NewComponent);
674  sendpacket->data = malloc(sendpacket->data_size);
675  NewComponent newComponent{};
676  newComponent.type = ComponentTypeSocket::SPRITESOCKET;
677  newComponent.id = BULLET;
678  std::memcpy(&newComponent.attribute, bullet->getAttribute().c_str(), 16);
679  memcpy(sendpacket->data, &newComponent, sendpacket->data_size);
680  _serverSocket->broadcast(sendpacket.get());
681  free(sendpacket->data);
682 
684  }
685  }
686  }
687 }
688 
689 /**
690  * @brief checkBulletDeletion, check the bullet deletion
691  */
693 {
694  for (auto &entity : getEntities()) {
695  for (auto &component : entity->getComponents()) {
696  // std::cout << "component: " << component->getAttribute() << std::endl;
697  if (std::string(component->getAttribute()).find("bullet") != std::string::npos) {
698  // std::cout << "bullet x position: " <<
699  // std::get<0>(std::dynamic_pointer_cast<Drawable>(component)->getPosition()) << " y position: " <<
700  // std::get<1>(std::dynamic_pointer_cast<Drawable>(component)->getPosition()) << std::endl;
701  auto draw = std::dynamic_pointer_cast<Drawable>(component);
702  auto [x, y] = draw->getPosition();
703  if (x > 900) {
704  _entities.erase(std::remove(_entities.begin(), _entities.end(), entity), _entities.end());
705  _nbBullets--;
706  std::shared_ptr<Packet> sendpacket = std::make_shared<Packet>();
707  sendpacket->code = DELETE_COMPONENT;
708  sendpacket->data_size = std::string(component->getAttribute()).size();
709  sendpacket->data = malloc(sendpacket->data_size);
710  std::memcpy(sendpacket->data, component->getAttribute(), sendpacket->data_size);
711  _serverSocket->broadcast(sendpacket.get());
712  free(sendpacket->data);
713  }
714  }
715  }
716  }
717 }