summary refs log tree commit diff stats
path: root/src/systems
diff options
context:
space:
mode:
Diffstat (limited to 'src/systems')
-rw-r--r--src/systems/automating.cpp71
-rw-r--r--src/systems/automating.h19
-rw-r--r--src/systems/realizing.cpp174
3 files changed, 264 insertions, 0 deletions
diff --git a/src/systems/automating.cpp b/src/systems/automating.cpp new file mode 100644 index 0000000..0d85957 --- /dev/null +++ b/src/systems/automating.cpp
@@ -0,0 +1,71 @@
1#include "automating.h"
2#include "game.h"
3#include "components/automatable.h"
4#include "components/ponderable.h"
5#include "systems/pondering.h"
6
7void AutomatingSystem::tick(double dt)
8{
9 auto entities = game_.getEntityManager().getEntitiesWithComponents<
10 AutomatableComponent,
11 PonderableComponent>();
12
13 for (id_type entity : entities)
14 {
15 auto& automatable = game_.getEntityManager().
16 getComponent<AutomatableComponent>(entity);
17
18 if (!automatable.active)
19 {
20 continue;
21 }
22
23 if (automatable.behaviorRunning &&
24 (automatable.remaining <= 0.0))
25 {
26 automatable.currentAction++;
27 automatable.actionRunning = false;
28
29 if (automatable.currentAction ==
30 automatable.behaviors[automatable.currentBehavior].size())
31 {
32 automatable.behaviorRunning = false;
33 }
34 }
35
36 if (!automatable.behaviorRunning)
37 {
38 automatable.currentBehavior = automatable.behaviorDist(game_.getRng());
39 automatable.currentAction = 0;
40 automatable.behaviorRunning = true;
41 }
42
43 AutomatableComponent::Action& curAction =
44 automatable.behaviors
45 [automatable.currentBehavior]
46 [automatable.currentAction];
47
48 if (!automatable.actionRunning)
49 {
50 automatable.remaining = curAction.dur;
51 automatable.actionRunning = true;
52 }
53
54 auto& ponderable = game_.getEntityManager().
55 getComponent<PonderableComponent>(entity);
56
57 ponderable.velX = curAction.speedX;
58 ponderable.velY = curAction.speedY;
59
60 automatable.remaining -= dt;
61 }
62}
63
64void AutomatingSystem::initPrototype(id_type prototype)
65{
66 auto& automatable = game_.getEntityManager().
67 getComponent<AutomatableComponent>(prototype);
68
69 automatable.behaviorRunning = false;
70 automatable.actionRunning = false;
71}
diff --git a/src/systems/automating.h b/src/systems/automating.h new file mode 100644 index 0000000..c78b7cf --- /dev/null +++ b/src/systems/automating.h
@@ -0,0 +1,19 @@
1#ifndef AUTOMATING_H_E6E5D76E
2#define AUTOMATING_H_E6E5D76E
3
4#include "system.h"
5
6class AutomatingSystem : public System {
7public:
8
9 AutomatingSystem(Game& game) : System(game)
10 {
11 }
12
13 void tick(double dt);
14
15 void initPrototype(id_type prototype);
16
17};
18
19#endif /* end of include guard: AUTOMATING_H_E6E5D76E */
diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp index 3656acb..8e670ac 100644 --- a/src/systems/realizing.cpp +++ b/src/systems/realizing.cpp
@@ -12,9 +12,11 @@
12#include "components/playable.h" 12#include "components/playable.h"
13#include "components/ponderable.h" 13#include "components/ponderable.h"
14#include "components/transformable.h" 14#include "components/transformable.h"
15#include "components/automatable.h"
15#include "systems/mapping.h" 16#include "systems/mapping.h"
16#include "systems/animating.h" 17#include "systems/animating.h"
17#include "systems/pondering.h" 18#include "systems/pondering.h"
19#include "systems/automating.h"
18 20
19inline xmlChar* getProp(xmlNodePtr node, const char* attr) 21inline xmlChar* getProp(xmlNodePtr node, const char* attr)
20{ 22{
@@ -27,6 +29,92 @@ inline xmlChar* getProp(xmlNodePtr node, const char* attr)
27 return key; 29 return key;
28} 30}
29 31
32void parseAI(
33 xmlNodePtr node,
34 std::vector<AutomatableComponent::Action>& behavior,
35 const std::map<std::string, int>& items)
36{
37 xmlChar* key = nullptr;
38
39 if (!xmlStrcmp(
40 node->name,
41 reinterpret_cast<const xmlChar*>("switch")))
42 {
43 key = getProp(node, "item");
44 std::string switchItem = reinterpret_cast<char*>(key);
45 xmlFree(key);
46
47 for (xmlNodePtr switchNode = node->xmlChildrenNode;
48 switchNode != nullptr;
49 switchNode = switchNode->next)
50 {
51 if (!xmlStrcmp(
52 switchNode->name,
53 reinterpret_cast<const xmlChar*>("case")))
54 {
55 key = getProp(switchNode, "value");
56 int caseValue = atoi(reinterpret_cast<char*>(key));
57 xmlFree(key);
58
59 if (items.at(switchItem) == caseValue)
60 {
61 for (xmlNodePtr caseNode = switchNode->xmlChildrenNode;
62 caseNode != nullptr;
63 caseNode = caseNode->next)
64 {
65 parseAI(
66 caseNode,
67 behavior,
68 items);
69 }
70 }
71 }
72 }
73 } else if (!xmlStrcmp(
74 node->name,
75 reinterpret_cast<const xmlChar*>("move")))
76 {
77 key = getProp(node, "direction");
78 std::string direction = reinterpret_cast<char*>(key);
79 xmlFree(key);
80
81 key = getProp(node, "length-var");
82 std::string lengthVar = reinterpret_cast<char*>(key);
83 xmlFree(key);
84
85 key = getProp(node, "speed-var");
86 std::string speedVar = reinterpret_cast<char*>(key);
87 xmlFree(key);
88
89 double length = items.at(lengthVar);
90 double speed = items.at(speedVar);
91
92 AutomatableComponent::Action action;
93
94 if (direction == "left")
95 {
96 action.speedX = -speed;
97 action.speedY = 0;
98 } else if (direction == "right")
99 {
100 action.speedX = speed;
101 action.speedY = 0;
102 } else if (direction == "up")
103 {
104 action.speedX = 0;
105 action.speedY = -speed;
106 } else if (direction == "down")
107 {
108 action.speedX = 0;
109 action.speedY = speed;
110 }
111
112 action.dur = length / speed;
113
114 behavior.push_back(std::move(action));
115 }
116}
117
30// TODO: neither the XML doc nor any of the emplaced entities are properly 118// TODO: neither the XML doc nor any of the emplaced entities are properly
31// destroyed if this method throws an exception. 119// destroyed if this method throws an exception.
32EntityManager::id_type RealizingSystem::initSingleton( 120EntityManager::id_type RealizingSystem::initSingleton(
@@ -211,6 +299,70 @@ EntityManager::id_type RealizingSystem::initSingleton(
211 game_.getSystemManager().getSystem<PonderingSystem>(). 299 game_.getSystemManager().getSystem<PonderingSystem>().
212 initializeBody(mapObject, PonderableComponent::Type::vacuumed); 300 initializeBody(mapObject, PonderableComponent::Type::vacuumed);
213 301
302 // Look for any object configuration.
303 std::map<std::string, int> items;
304
305 for (xmlNodePtr objectNode = mapNode->xmlChildrenNode;
306 objectNode != nullptr;
307 objectNode = objectNode->next)
308 {
309 if (!xmlStrcmp(
310 objectNode->name,
311 reinterpret_cast<const xmlChar*>("item")))
312 {
313 key = getProp(objectNode, "id");
314 std::string itemName = reinterpret_cast<char*>(key);
315 xmlFree(key);
316
317 key = xmlNodeGetContent(objectNode);
318 int itemVal = atoi(reinterpret_cast<char*>(key));
319 xmlFree(key);
320
321 items[itemName] = itemVal;
322 }
323 }
324
325 // Add any AI behaviors.
326 std::vector<double> behaviorWeights;
327
328 for (xmlNodePtr protoSubNode = prototypeNode->xmlChildrenNode;
329 protoSubNode != nullptr;
330 protoSubNode = protoSubNode->next)
331 {
332 if (!xmlStrcmp(
333 protoSubNode->name,
334 reinterpret_cast<const xmlChar*>("ai")))
335 {
336 if (!game_.getEntityManager().
337 hasComponent<AutomatableComponent>(mapObject))
338 {
339 game_.getEntityManager().
340 emplaceComponent<AutomatableComponent>(mapObject);
341 }
342
343 auto& automatable = game_.getEntityManager().
344 getComponent<AutomatableComponent>(mapObject);
345
346 key = getProp(protoSubNode, "chance");
347 behaviorWeights.push_back(atof(reinterpret_cast<char*>(key)));
348 xmlFree(key);
349
350 std::vector<AutomatableComponent::Action> behavior;
351
352 for (xmlNodePtr aiNode = protoSubNode->xmlChildrenNode;
353 aiNode != nullptr;
354 aiNode = aiNode->next)
355 {
356 parseAI(
357 aiNode,
358 behavior,
359 items);
360 }
361
362 automatable.behaviors.push_back(std::move(behavior));
363 }
364 }
365
214 mappable.objects.push_back(mapObject); 366 mappable.objects.push_back(mapObject);
215 } else if (!xmlStrcmp( 367 } else if (!xmlStrcmp(
216 mapNode->name, 368 mapNode->name,
@@ -304,6 +456,7 @@ void RealizingSystem::loadMap(id_type mapEntity)
304 456
305 auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); 457 auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>();
306 auto& pondering = game_.getSystemManager().getSystem<PonderingSystem>(); 458 auto& pondering = game_.getSystemManager().getSystem<PonderingSystem>();
459 auto& automating = game_.getSystemManager().getSystem<AutomatingSystem>();
307 460
308 std::set<id_type> players = 461 std::set<id_type> players =
309 game_.getEntityManager().getEntitiesWithComponents< 462 game_.getEntityManager().getEntitiesWithComponents<
@@ -366,6 +519,11 @@ void RealizingSystem::loadMap(id_type mapEntity)
366 pondering.initPrototype(prototype); 519 pondering.initPrototype(prototype);
367 } 520 }
368 521
522 if (game_.getEntityManager().hasComponent<AutomatableComponent>(prototype))
523 {
524 automating.initPrototype(prototype);
525 }
526
369 enterActiveMap(prototype); 527 enterActiveMap(prototype);
370 } 528 }
371 529
@@ -399,6 +557,14 @@ void RealizingSystem::enterActiveMap(id_type entity)
399 557
400 ponderable.active = true; 558 ponderable.active = true;
401 } 559 }
560
561 if (game_.getEntityManager().hasComponent<AutomatableComponent>(entity))
562 {
563 auto& automatable = game_.getEntityManager().
564 getComponent<AutomatableComponent>(entity);
565
566 automatable.active = true;
567 }
402} 568}
403 569
404void RealizingSystem::leaveActiveMap(id_type entity) 570void RealizingSystem::leaveActiveMap(id_type entity)
@@ -418,4 +584,12 @@ void RealizingSystem::leaveActiveMap(id_type entity)
418 584
419 ponderable.active = false; 585 ponderable.active = false;
420 } 586 }
587
588 if (game_.getEntityManager().hasComponent<AutomatableComponent>(entity))
589 {
590 auto& automatable = game_.getEntityManager().
591 getComponent<AutomatableComponent>(entity);
592
593 automatable.active = false;
594 }
421} 595}