Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
VideoGame.cpp
Go to the documentation of this file.
1/*
2Purpose: Implementation of the VideoGame class, which represents a video game with attributes such as title, genre, and platform.
3*/
4
5#include "VideoGame.h"
6#include "DataManager.h"
7#include <sstream>
8#include <string>
9#include "InputsManager.h"
10#include "prefabfactory.h"
11#include "engine_utils.h"
12#include "ECS_Systems.h"
13#include "system/EventQueue.h"
14#include "ECS_Components_AI.h"
15
17using namespace std;
19
21{
22 name = "VideoGame";
23
24 // Initialize viewport manager
26
27 // Ensure default state is running
29
30 // Register all prefab items for the game
32
33 //PrefabFactory::Get().CreateEntity("OlympeIdentity");
34
35 // Initialize AI test scene (NPC "garde" with patrol)
37
38 SYSTEM_LOG << "VideoGame created\n";
39}
40//-------------------------------------------------------------
42{
43 SYSTEM_LOG << "VideoGame destroyed\n";
44}
45//-------------------------------------------------------------
46// Player management: supports up to 8 players
47// Returns assigned player ID -1 on failure
48//-------------------------------------------------------------
50{
51 // Check if an input device is available before creating player
53 {
54 SYSTEM_LOG << "X Cannot create player '" << _playerPrefabName << "': no input device available (all joysticks and keyboard already assigned)\n";
55 return INVALID_ENTITY_ID;
56 }
57
58 // -> Utiliser le système centralisé
60
62 {
63 SYSTEM_LOG << "X Failed to create player from prefab '" << _playerPrefabName << "'\n";
64 return INVALID_ENTITY_ID;
65 }
66
68
69 // Vérifier que les composants requis existent
72 {
73 SYSTEM_LOG << "X Player entity missing required input components!\n";
74 return INVALID_ENTITY_ID;
75 }
76
77 // Add to player list only after all validation passes
78 m_playersEntity.push_back(eID);
79
80 // bind input components with player ID
83
84 binding.playerIndex = ++m_playerIdCounter;
85 binding.controllerID = -1; // keyboard by default
86
87 // assign controller (if available)
89 {
91 binding.controllerID = IM::Get().AutoBindControllerToPlayer(binding.playerIndex);
92 controller.controllerID = binding.controllerID;
93 SYSTEM_LOG << "Player " << binding.playerIndex << " bound to controller " << binding.controllerID << "\n";
94 }
95
96 //Send message to ViewportManager to add a new player viewport
100 -1,
101 -1,
102 eID
103 );
104 msg.param1 = binding.playerIndex;
105
107
108 SetViewportLayout(binding.playerIndex);
109
110 // Bind camera input to the same device as the player
112 if (camSys)
113 {
114 // Get or create camera for this player
117 {
118 // Camera doesn't exist yet, create it
119 cameraEntity = camSys->CreateCameraForPlayer(binding.playerIndex, false);
120 }
121
122 // Bind camera to the same input device as the player
123 if (binding.controllerID == -1)
124 {
125 // Keyboard-bound player: bind camera to keyboard
126 camSys->BindCameraToKeyboard(cameraEntity);
127
128 // Disable keyboard binding on default camera (player -1) if it exists
129 EntityID defaultCamera = camSys->GetCameraEntityForPlayer(-1);
131 {
132 camSys->UnbindCameraKeyboard(defaultCamera);
133 }
134 }
135 else if (binding.controllerID >= 0)
136 {
137 // Joystick-bound player: bind camera to joystick
138 // Safe cast: controllerID validated as >= 0, matches SDL_JoystickID range
139 camSys->BindCameraToJoystick(cameraEntity, binding.playerIndex, (SDL_JoystickID)binding.controllerID);
140 }
141 }
142
143 SYSTEM_LOG << "-> Player " << binding.playerIndex << " created (Entity: " << eID << ")\n";
144 return eID;
145}
146//-------------------------------------------------------------
148{
149 return false;
150}
151//-------------------------------------------------------------
153{
154 // Check if there are available joysticks or if keyboard is not yet assigned
157
159}
160//-------------------------------------------------------------
162{
163 // Validate entity ID
164 if (entity == INVALID_ENTITY_ID)
165 {
166 SYSTEM_LOG << "X VideoGame::RegisterLoadedPlayerEntity: Invalid entity ID\n";
167 return;
168 }
169
170 // Check if an input device is available before registering player
172 {
173 SYSTEM_LOG << "X Cannot register player entity " << entity << ": no input device available (all joysticks and keyboard already assigned)\n";
174 return;
175 }
176
178 {
179 SYSTEM_LOG << "X VideoGame::RegisterLoadedPlayerEntity: Entity missing PlayerBinding_data component\n";
180 return;
181 }
182
183 if (! world.HasComponent<Controller_data>(entity))
184 {
185 SYSTEM_LOG << "X VideoGame::RegisterLoadedPlayerEntity: Entity missing Controller_data component\n";
186 return;
187 }
188
189 // Entity already exists, just need to register and configure it
190
191 // Note: Component validation is performed by World::RegisterPlayerEntity before calling this
192 // These components are guaranteed to exist at this point
193
194 // Add to player list
195 m_playersEntity.push_back(entity);
196
197 // Bind input components with player ID
200
201 binding.playerIndex = ++m_playerIdCounter;
202 binding.controllerID = -1; // keyboard by default
203
204 // Assign controller (if available)
205 // Useless nos because we test the devices availability above if (IM::Get().GetAvailableJoystickCount() > 0)
206 {
207 IM::Get().AddPlayerEntityIndex(binding.playerIndex, entity);
208 binding.controllerID = IM::Get().AutoBindControllerToPlayer(binding.playerIndex);
209 controller.controllerID = binding.controllerID;
210 SYSTEM_LOG << "Player " << binding.playerIndex << " bound to controller " << binding.controllerID << "\n";
211 }
212
213 // Send message to ViewportManager to add a new player viewport
217 -1,
218 -1,
219 entity
220 );
221 msg.param1 = binding.playerIndex;
222
224
225 SetViewportLayout(binding.playerIndex);
226
227 // Bind camera input to the same device as the player
229 if (camSys)
230 {
231 // Get or create camera for this player
234 {
235 // Camera doesn't exist yet, create it
236 cameraEntity = camSys->CreateCameraForPlayer(binding.playerIndex, false);
237 }
238
239 // Bind camera to the same input device as the player
240 if (binding.controllerID == -1)
241 {
242 // Keyboard-bound player: bind camera to keyboard
243 camSys->BindCameraToKeyboard(cameraEntity);
244
245 // Disable keyboard binding on default camera (player -1) if it exists
246 EntityID defaultCamera = camSys->GetCameraEntityForPlayer(-1);
248 {
249 camSys->UnbindCameraKeyboard(defaultCamera);
250 }
251 }
252 else if (binding.controllerID >= 0)
253 {
254 // Joystick-bound player: bind camera to joystick
255 // Safe cast: controllerID validated as >= 0, matches SDL_JoystickID range
256 camSys->BindCameraToJoystick(cameraEntity, binding.playerIndex, (SDL_JoystickID)binding.controllerID);
257 }
258 }
259
260 SYSTEM_LOG << "-> Player " << binding.playerIndex << " registered from level (Entity: " << entity << ")\n";
261}
262//-------------------------------------------------------------
264{
265 short nbPLayer = static_cast<short>(m_playersEntity.size());
266
267 switch (nbPLayer)
268 {
269 case 1:
271 break;
272 case 2:
274 break;
275 case 3:
277 break;
278 case 4:
280 break;
281 case 5:
282 case 6:
284 break;
285 case 7:
286 case 8:
288 break;
289
290 default:
291 break;
292 }
293}
294//-------------------------------------------------------------
296{
297 // DERPECATED PREFAB REGISTRATION
298/* PrefabFactory::Get().RegisterPrefab("PlayerEntity", [](EntityID id) {
299 World& world = World::Get();
300 world.AddComponent<Identity_data>(id, string("Player_" + to_string(id)), "Player", "Player");
301
302 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
303 string prefabName = "PlayerEntity";
304 static VisualSprite_data* st_vspriteData_ptr = nullptr;
305 string str_index = to_string(Random_Int(1, 15));
306 st_vspriteData_ptr = DataManager::Get().GetSprite_data(prefabName + str_index, "Resources/Sprites/entity_" + str_index + ".png");
307 if (!st_vspriteData_ptr)
308 {
309 SYSTEM_LOG << "PrefabFactory: Failed to load sprite data for " + prefabName + " \n";
310 return;
311 }
312 st_vspriteData_ptr->color = Random_Color(50, 255);
313 VisualSprite_data st_vsprite = *st_vspriteData_ptr;
314 world.AddComponent<VisualSprite_data>(id, st_vsprite);// .srcRect, st_vsprite.sprite, st_vsprite.hotSpot);
315 world.AddComponent<BoundingBox_data>(id, SDL_FRect{ 0.f, 0.f, st_vsprite.srcRect.w, st_vsprite.srcRect.h });
316 world.AddComponent<PlayerBinding_data>(id);// , (short)++m_playerIdCounter, (short)-1); // default to keyboard
317 world.AddComponent<Controller_data>(id);// , (short)-1, false, false);
318 world.AddComponent<PlayerController_data>(id);// , Vector(), false, false, false, false, false);
319 world.AddComponent<Health_data>(id, 100, 100);
320 world.AddComponent<PhysicsBody_data>(id);// , Vector(), Vector(), false, 0.f, 0.f,
321 // Add other components as needed
322 });
323
324 //TRIGGER PREFAB
325 PrefabFactory::Get().RegisterPrefab("Trigger", [](EntityID id) {
326 World& world = World::Get();
327 world.AddComponent<Identity_data>(id, string("Trigger_" + to_string(id)), "Trigger", "Trigger");
328 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
329 string prefabName = "Trigger";
330 static VisualSprite_data* st_vspriteData_ptr = DataManager::Get().GetSprite_data(prefabName, "Resources/Icons/trigger-50.png");
331 if (!st_vspriteData_ptr)
332 {
333 SYSTEM_LOG << "PrefabFactory: Failed to load sprite data for " + prefabName + " \n";
334 return;
335 }
336 VisualSprite_data st_vsprite = *st_vspriteData_ptr;
337 world.AddComponent<VisualSprite_data>(id, st_vsprite.srcRect, st_vsprite.sprite, st_vsprite.hotSpot);
338 world.AddComponent<BoundingBox_data>(id, SDL_FRect{ 0.f, 0.f, st_vsprite.srcRect.w, st_vsprite.srcRect.h });
339 });
340
341 // WAYPOINT PREFAB
342 PrefabFactory::Get().RegisterPrefab("Waypoint", [](EntityID id) {
343 World& world = World::Get();
344 world.AddComponent<Identity_data>(id, string("Waypoint_" + to_string(id)), "Waypoint", "Waypoint");
345 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
346 string prefabName = "Waypoint";
347 static VisualEditor_data* st_vspriteData_ptr = DataManager::Get().GetSpriteEditor_data(prefabName, "Resources/Icons/location-32.png");
348 if (!st_vspriteData_ptr)
349 {
350 SYSTEM_LOG << "PrefabFactory: Failed to load sprite data for " + prefabName + " \n";
351 return;
352 }
353 VisualEditor_data st_vsprite = *st_vspriteData_ptr;
354 world.AddComponent<VisualEditor_data>(id, st_vsprite.srcRect, st_vsprite.sprite, st_vsprite.hotSpot);
355 world.AddComponent<BoundingBox_data>(id, SDL_FRect{ 0.f, 0.f, st_vsprite.srcRect.w, st_vsprite.srcRect.h });
356 });
357
358 //NPC PREFAB
359 PrefabFactory::Get().RegisterPrefab("NPCEntity", [](EntityID id) {
360 World& world = World::Get();
361 world.AddComponent<Identity_data>(id, string("Npc_" + to_string(id)), "Npc", "Npc");
362 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
363 string prefabName = "NPCEntity";
364 static VisualSprite_data * st_vspriteData_ptr = DataManager::Get().GetSprite_data(prefabName, "Resources/Sprites/entity_" + to_string(Random_Int(1, 15)) + ".png");
365 if (!st_vspriteData_ptr)
366 {
367 SYSTEM_LOG << "PrefabFactory: Failed to load sprite data for " + prefabName + " \n";
368 return;
369 }
370 st_vspriteData_ptr->color = Random_Color(50, 255);
371 VisualSprite_data st_vsprite = *st_vspriteData_ptr;
372 world.AddComponent<VisualSprite_data>(id, st_vsprite.srcRect, st_vsprite.sprite, st_vsprite.hotSpot);
373 world.AddComponent<BoundingBox_data>(id, SDL_FRect{ 0.f, 0.f, st_vsprite.srcRect.w, st_vsprite.srcRect.h });
374 world.AddComponent<Health_data>(id, 100, 100);
375 // Add other components as needed
376 });
377
378 //GUARD NPC PREFAB (AI-enabled)
379 PrefabFactory::Get().RegisterPrefab("GuardNPC", [](EntityID id) {
380 World& world = World::Get();
381 world.AddComponent<Identity_data>(id, string("GuardNPC_" + to_string(id)), "GuardNPC", "Npc");
382 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
383 string prefabName = "GuardNPC";
384 static VisualSprite_data* st_vspriteData_ptr = DataManager::Get().GetSprite_data(prefabName, "Resources/Sprites/entity_4.png");
385 if (!st_vspriteData_ptr)
386 {
387 SYSTEM_LOG << "PrefabFactory: Failed to load sprite data for " + prefabName + " \n";
388 return;
389 }
390 st_vspriteData_ptr->color = SDL_Color{255, 0, 0, 255}; // Red color for guards
391 VisualSprite_data st_vsprite = *st_vspriteData_ptr;
392 world.AddComponent<VisualSprite_data>(id, st_vsprite.srcRect, st_vsprite.sprite, st_vsprite.hotSpot);
393 world.AddComponent<BoundingBox_data>(id, SDL_FRect{ 0.f, 0.f, st_vsprite.srcRect.w, st_vsprite.srcRect.h });
394 world.AddComponent<Health_data>(id, 100, 100);
395 world.AddComponent<Movement_data>(id);
396 world.AddComponent<PhysicsBody_data>(id, 1.0f, 120.0f);
397
398 // AI components
399 world.AddComponent<AIBlackboard_data>(id);
400 world.AddComponent<AISenses_data>(id);
401 world.AddComponent<AIState_data>(id);
402 world.AddComponent<BehaviorTreeRuntime_data>(id);
403 world.AddComponent<MoveIntent_data>(id);
404 world.AddComponent<AttackIntent_data>(id);
405
406 // Configure AI senses
407 AISenses_data& senses = world.GetComponent<AISenses_data>(id);
408 senses.visionRadius = 200.0f; // 2m detection range (assuming 100 units = 1m)
409 senses.hearingRadius = 600.0f;
410 senses.perceptionHz = 5.0f;
411 senses.thinkHz = 10.0f;
412
413 // Start in patrol mode
414 AIState_data& state = world.GetComponent<AIState_data>(id);
415 state.currentMode = AIMode::Patrol;
416 state.combatEngageDistance = 200.0f; // 2m
417
418 // Activate behavior tree (Patrol tree = ID 2)
419 BehaviorTreeRuntime_data& btRuntime = world.GetComponent<BehaviorTreeRuntime_data>(id);
420 btRuntime.treeAssetId = 2; // Patrol tree
421 btRuntime.isActive = true;
422 });
423
424 //OLYMPE LOGO PREFAB
425 PrefabFactory::Get().RegisterPrefab("OlympeIdentity", [](EntityID id) {
426 World& world = World::Get();
427 world.AddComponent<Identity_data>(id, string("OlympeIdentity_" + to_string(id)), "Logo", "UIElement");
428 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
429 string prefabName = "OlympeIdentity";
430 static VisualSprite_data* st_vspriteData_ptr = DataManager::Get().GetSprite_data(prefabName, "Resources/olympe_logo.png");
431 if (!st_vspriteData_ptr)
432 {
433 SYSTEM_LOG << "PrefabFactory: Failed to load sprite data for " + prefabName + " \n";
434 return;
435 }
436 VisualSprite_data st_vsprite = *st_vspriteData_ptr;
437 world.AddComponent<VisualSprite_data>(id, st_vsprite.srcRect, st_vsprite.sprite, st_vsprite.hotSpot);
438 world.AddComponent<BoundingBox_data>(id, SDL_FRect{ 0.f, 0.f, st_vsprite.srcRect.w, st_vsprite.srcRect.h });
439 // Add other components as needed
440 });
441
442 // ENEMY PREFAB
443 PrefabFactory::Get().RegisterPrefab("Ennemy", [](EntityID id) {
444 World& world = World::Get();
445 world.AddComponent<Identity_data>(id, "Ennemy_" + std::to_string(id), "Ennemy", "Ennemy");
446 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
447
448 static VisualSprite_data* sprite = DataManager::Get().GetSprite_data("Ennemy", "Resources/Sprites/ennemy.png");
449 if (!sprite) {
450 // Fallback to random entity sprite
451 string str_index = to_string(Random_Int(1, 15));
452 sprite = DataManager::Get().GetSprite_data("Enemy", "Resources/Sprites/entity_" + str_index + ".png");
453 }
454 if (sprite) {
455 sprite->color = SDL_Color{255, 100, 100, 255}; // Reddish tint for enemies
456 world.AddComponent<VisualSprite_data>(id, *sprite);
457 SDL_FRect frect = { 0.f, 0.f, sprite->srcRect.w, sprite->srcRect.h };
458 world.AddComponent<BoundingBox_data>(id, frect);
459 }
460
461 world.AddComponent<Movement_data>(id);
462 world.AddComponent<PhysicsBody_data>(id);
463 world.AddComponent<Health_data>(id, 50, 50);
464 world.AddComponent<AIBlackboard_data>(id);
465 world.AddComponent<AISenses_data>(id);
466 world.AddComponent<AIState_data>(id);
467 world.AddComponent<BehaviorTreeRuntime_data>(id, 3, true);
468 });
469
470 // ZOMBIE PREFAB
471 PrefabFactory::Get().RegisterPrefab("Zombie", [](EntityID id) {
472 World& world = World::Get();
473 world.AddComponent<Identity_data>(id, "Zombie_" + std::to_string(id), "Zombie", "Zombie");
474 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
475
476 static VisualSprite_data* sprite = DataManager::Get().GetSprite_data("Zombie", "Resources/Sprites/zombie.png");
477 if (!sprite) {
478 // Fallback to random entity sprite
479 string str_index = to_string(Random_Int(1, 15));
480 sprite = DataManager::Get().GetSprite_data("Zombie", "Resources/Sprites/entity_" + str_index + ".png");
481 }
482 if (sprite) {
483 sprite->color = SDL_Color{100, 255, 100, 255}; // Greenish tint for zombies
484 world.AddComponent<VisualSprite_data>(id, *sprite);
485 SDL_FRect frect = { 0.f, 0.f, sprite->srcRect.w, sprite->srcRect.h };
486 world.AddComponent<BoundingBox_data>(id, frect);
487 }
488
489 world.AddComponent<Movement_data>(id);
490 world.AddComponent<PhysicsBody_data>(id, 0.5f, 80.0f);
491 world.AddComponent<Health_data>(id, 30, 30);
492 world.AddComponent<AIBlackboard_data>(id);
493 world.AddComponent<AISenses_data>(id, 150.0f, 300.0f);
494 world.AddComponent<AIState_data>(id);
495 world.AddComponent<BehaviorTreeRuntime_data>(id, 3, true);
496 });
497
498 // KEY PREFAB
499 PrefabFactory::Get().RegisterPrefab("Key", [](EntityID id) {
500 World& world = World::Get();
501 world.AddComponent<Identity_data>(id, "Key_" + std::to_string(id), "Key", "Key");
502 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
503
504 static VisualSprite_data* sprite = DataManager::Get().GetSprite_data("Key", "Resources/Items/key.png");
505 if (!sprite) {
506 sprite = DataManager::Get().GetSprite_data("Key", "Resources/Icons/trigger-50.png");
507 }
508 if (sprite) {
509 sprite->color = SDL_Color{255, 215, 0, 255}; // Gold color
510 world.AddComponent<VisualSprite_data>(id, *sprite);
511 SDL_FRect frect = { 0.f, 0.f, sprite->srcRect.w, sprite->srcRect.h };
512 world.AddComponent<BoundingBox_data>(id, frect);
513 }
514 });
515
516 // COLLECTIBLE PREFAB
517 PrefabFactory::Get().RegisterPrefab("Collectible", [](EntityID id) {
518 World& world = World::Get();
519 world.AddComponent<Identity_data>(id, "Collectible_" + std::to_string(id), "Collectible", "Collectible");
520 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
521
522 static VisualSprite_data* sprite = DataManager::Get().GetSprite_data("Collectible", "Resources/Items/coin.png");
523 if (!sprite) {
524 sprite = DataManager::Get().GetSprite_data("Collectible", "Resources/Icons/trigger-50.png");
525 }
526 if (sprite) {
527 sprite->color = SDL_Color{255, 255, 0, 255}; // Yellow color
528 world.AddComponent<VisualSprite_data>(id, *sprite);
529 SDL_FRect frect = { 0.f, 0.f, sprite->srcRect.w, sprite->srcRect.h };
530 world.AddComponent<BoundingBox_data>(id, frect);
531 }
532 });
533
534 // TREASURE PREFAB
535 PrefabFactory::Get().RegisterPrefab("Treasure", [](EntityID id) {
536 World& world = World::Get();
537 world.AddComponent<Identity_data>(id, "Treasure_" + std::to_string(id), "Treasure", "Treasure");
538 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
539
540 static VisualSprite_data* sprite = DataManager::Get().GetSprite_data("Treasure", "Resources/Items/chest.png");
541 if (!sprite) {
542 sprite = DataManager::Get().GetSprite_data("Treasure", "Resources/Icons/trigger-50.png");
543 }
544 if (sprite) {
545 sprite->color = SDL_Color{139, 69, 19, 255}; // Brown color
546 world.AddComponent<VisualSprite_data>(id, *sprite);
547 SDL_FRect frect = { 0.f, 0.f, sprite->srcRect.w, sprite->srcRect.h };
548 world.AddComponent<BoundingBox_data>(id, frect);
549 }
550 });
551
552 // PORTAL PREFAB
553 PrefabFactory::Get().RegisterPrefab("Portal", [](EntityID id) {
554 World& world = World::Get();
555 world.AddComponent<Identity_data>(id, "Portal_" + std::to_string(id), "Portal", "Portal");
556 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
557
558 static VisualSprite_data* sprite = DataManager::Get().GetSprite_data("Portal", "Resources/Items/portal.png");
559 if (!sprite) {
560 sprite = DataManager::Get().GetSprite_data("Portal", "Resources/Icons/trigger-50.png");
561 }
562 if (sprite) {
563 sprite->color = SDL_Color{138, 43, 226, 255}; // Purple color
564 world.AddComponent<VisualSprite_data>(id, *sprite);
565 SDL_FRect frect = { 0.f, 0.f, sprite->srcRect.w, sprite->srcRect.h };
566 world.AddComponent<BoundingBox_data>(id, frect);
567 }
568 });
569
570 // AMBIENT SOUND PREFAB
571 PrefabFactory::Get().RegisterPrefab("AmbientSound", [](EntityID id) {
572 World& world = World::Get();
573 world.AddComponent<Identity_data>(id, "AmbientSound_" + std::to_string(id), "AmbientSound", "AmbientSound");
574 world.AddComponent<Position_data>(id, Vector(0, 0, 0));
575 });
576 /**/
577}
578//-------------------------------------------------------------
580{
581 /*SYSTEM_LOG << "VideoGame: Initializing AI Test Scene...\n";
582
583 // Create a guard NPC "garde" at position (400, 300)
584 EntityID garde = PrefabFactory::Get().CreateEntity("GuardNPC");
585
586 if (garde != INVALID_ENTITY_ID)
587 {
588 // Set initial position
589 Position_data& pos = world.GetComponent<Position_data>(garde);
590 pos.position = Vector(400.0f, 300.0f, 0.0f);
591
592 // Configure patrol waypoints (square patrol pattern)
593 AIBlackboard_data& blackboard = world.GetComponent<AIBlackboard_data>(garde);
594 blackboard.patrolPoints[0] = Vector(300.0f, 200.0f, 0.0f);
595 blackboard.patrolPoints[1] = Vector(500.0f, 200.0f, 0.0f);
596 blackboard.patrolPoints[2] = Vector(500.0f, 400.0f, 0.0f);
597 blackboard.patrolPoints[3] = Vector(300.0f, 400.0f, 0.0f);
598 blackboard.patrolPointCount = 4;
599 blackboard.currentPatrolPoint = 0;
600
601 //create waypoints entities for visualization
602 for (int i = 0; i < blackboard.patrolPointCount; ++i)
603 {
604 EntityID waypoint = PrefabFactory::Get().CreateEntity("Waypoint");
605
606 if (waypoint != INVALID_ENTITY_ID)
607 {
608 Position_data& wpPos = world.GetComponent<Position_data>(waypoint);
609 wpPos.position = blackboard.patrolPoints[i];
610 }
611 }
612
613 SYSTEM_LOG << "VideoGame: Created guard NPC 'garde' (Entity " << garde << ") with 4 waypoints\n";
614 SYSTEM_LOG << " - Patrol waypoints: (300,200), (500,200), (500,400), (300,400)\n";
615 SYSTEM_LOG << " - Detection range: 200 units (~2m)\n";
616 SYSTEM_LOG << " - Will attack player if within 2m, otherwise patrol\n";
617 }
618 else
619 {
620 SYSTEM_LOG << "VideoGame: ERROR - Failed to create guard NPC\n";
621 }/**/
622
623 return;
624 std::vector<Vector> entityPositions = {
625 Vector(0.0f, 0.0f, 5.0f),
626 Vector(540.0f, 540.0f, 5.0f),
627 Vector(0.0f, 540.0f, 5.0f),
628 Vector(540.0f, 0.0f, 5.0f),
629 Vector(270.0f, 270.0f, 5.0f)
630 };
631
632 for (int i = 0; i < 5; ++i)
633 {
636 {
639
640 // Set unique color for each beacon
642 switch (i)
643 {
644 case 0:
645 sprite.color = SDL_Color{ 255, 0, 0, 255 }; // Red
646 break;
647 case 1:
648 sprite.color = SDL_Color{ 0, 255, 0, 255 }; // Green
649 break;
650 case 2:
651 sprite.color = SDL_Color{ 0, 0, 255, 255 }; // Blue
652 break;
653 case 3:
654 sprite.color = SDL_Color{ 255, 255, 0, 255 }; // Yellow
655 break;
656 case 4:
657 sprite.color = SDL_Color{ 255, 0, 255, 255 }; // Magenta
658 break;
659 default:
660 break;
661 }
662 //Set persistent flag
664 identity.isPersistent = true;
665 }
666 }
667}
668
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
std::uint64_t EntityID
Definition ECS_Entity.h:21
const EntityID INVALID_ENTITY_ID
Definition ECS_Entity.h:23
@ GameState_Running
EntityID GetCameraEntityForPlayer(short playerID)
void Push(const Message &msg)
Definition EventQueue.h:37
static EventQueue & Get()
Definition EventQueue.h:34
static int screenWidth
Screen width in pixels.
Definition GameEngine.h:123
static int screenHeight
Screen height in pixels.
Definition GameEngine.h:126
static InputsManager & Get()
int GetAvailableJoystickCount() const
short AutoBindControllerToPlayer(short playerID)
bool IsKeyboardAssigned() const
bool AddPlayerEntityIndex(short playerID, EntityID eID)
static PrefabFactory & Get()
Get singleton instance.
EntityID CreateEntity(const std::string &prefabName)
Create an entity using legacy prefab system.
EntityID CreateEntityFromPrefabName(const std::string &prefabName)
Create entity from prefab name.
std::vector< EntityID > m_playersEntity
Definition VideoGame.h:91
static short m_playerIdCounter
Definition VideoGame.h:92
World & world
Definition VideoGame.h:84
ViewportManager & viewport
Definition VideoGame.h:88
EntityID AddPlayerEntity(string _playerPrefabName="Player")
Definition VideoGame.cpp:49
bool IsInputDeviceAvailable() const
void RegisterLoadedPlayerEntity(EntityID entity)
string name
Definition VideoGame.h:95
void InitializeAITestScene()
void SetViewportLayout(short playerID)
virtual void RegisterPrefabItems()
virtual ~VideoGame()
Definition VideoGame.cpp:41
bool RemovePlayerEntity(const EntityID eid)
void Initialize(int w, int h)
bool AddPlayer(short playerID, ViewportLayout viewportLayout)
Core ECS manager and world coordinator.
Definition World.h:210
static World & Get()
Get singleton instance (short form)
Definition World.h:232
bool HasComponent(EntityID entity) const
Definition World.h:451
T * GetSystem()
Definition World.h:244
T & GetComponent(EntityID entity)
Definition World.h:438
void SetState(GameState s)
Definition GameState.cpp:10
Header file for PrefabFactory class, responsible for creating game object prefabs.
Identity component for entity identification.
bool isPersistent
Should the entity persist across levels?
static Message Create(EventType _ev_t, EventDomain _domain, int _d_id=-1, int _c_id=-1, uint64_t _t_uid=0)
Definition message.h:28
Position component for spatial location.
Vector position
2D/3D position vector
@ Olympe_EventType_Camera_Target_Follow
#define SYSTEM_LOG