diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-05-10 19:27:59 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2018-05-17 15:39:39 -0400 |
commit | 4bbfeae42a1245b1b84e8847787d7643e6a6f2cf (patch) | |
tree | 8dd65d9ab0cfffd0e79f670c94b035c5eebfa934 /src/systems/realizing.cpp | |
parent | 67b24a8ddd89371cfb944c5b441c852f0edc23b1 (diff) | |
download | therapy-4bbfeae42a1245b1b84e8847787d7643e6a6f2cf.tar.gz therapy-4bbfeae42a1245b1b84e8847787d7643e6a6f2cf.tar.bz2 therapy-4bbfeae42a1245b1b84e8847787d7643e6a6f2cf.zip |
Started integrating Lua as a scripting engine
Currently moving platforms are able to have their movement controlled by a script rather than by XML, which is probably a better implementation and scales better to other things. The scripts, instead of using the components as state, use the stack as state. In this way, they pretend to be multithreaded. For instance, the moving platform calls moveRight and then moveLeft. Both of those functions internally make calls that say to wait until the next tick. When the AutomatingSystem ticks, it continues execution of all scripts (sequentially, of course) until they ask for the next tick again. This is implemented using coroutines.
Diffstat (limited to 'src/systems/realizing.cpp')
-rw-r--r-- | src/systems/realizing.cpp | 153 |
1 files changed, 8 insertions, 145 deletions
diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp index f9285ad..28e2279 100644 --- a/src/systems/realizing.cpp +++ b/src/systems/realizing.cpp | |||
@@ -29,92 +29,6 @@ inline xmlChar* getProp(xmlNodePtr node, const char* attr) | |||
29 | return key; | 29 | return key; |
30 | } | 30 | } |
31 | 31 | ||
32 | void 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.speed.x() = -speed; | ||
97 | action.speed.y() = 0; | ||
98 | } else if (direction == "right") | ||
99 | { | ||
100 | action.speed.x() = speed; | ||
101 | action.speed.y() = 0; | ||
102 | } else if (direction == "up") | ||
103 | { | ||
104 | action.speed.x() = 0; | ||
105 | action.speed.y() = -speed; | ||
106 | } else if (direction == "down") | ||
107 | { | ||
108 | action.speed.x() = 0; | ||
109 | action.speed.y() = speed; | ||
110 | } | ||
111 | |||
112 | action.dur = length / speed; | ||
113 | |||
114 | behavior.push_back(std::move(action)); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | // TODO: neither the XML doc nor any of the emplaced entities are properly | 32 | // TODO: neither the XML doc nor any of the emplaced entities are properly |
119 | // destroyed if this method throws an exception. | 33 | // destroyed if this method throws an exception. |
120 | EntityManager::id_type RealizingSystem::initSingleton( | 34 | EntityManager::id_type RealizingSystem::initSingleton( |
@@ -126,6 +40,9 @@ EntityManager::id_type RealizingSystem::initSingleton( | |||
126 | auto& realizable = game_.getEntityManager(). | 40 | auto& realizable = game_.getEntityManager(). |
127 | emplaceComponent<RealizableComponent>(world); | 41 | emplaceComponent<RealizableComponent>(world); |
128 | 42 | ||
43 | game_.getSystemManager().getSystem<AutomatingSystem>(). | ||
44 | initScriptEngine(realizable.scriptEngine); | ||
45 | |||
129 | realizable.worldFile = worldFile; | 46 | realizable.worldFile = worldFile; |
130 | realizable.prototypeFile = prototypeFile; | 47 | realizable.prototypeFile = prototypeFile; |
131 | 48 | ||
@@ -299,68 +216,14 @@ EntityManager::id_type RealizingSystem::initSingleton( | |||
299 | game_.getSystemManager().getSystem<PonderingSystem>(). | 216 | game_.getSystemManager().getSystem<PonderingSystem>(). |
300 | initializeBody(mapObject, PonderableComponent::Type::vacuumed); | 217 | initializeBody(mapObject, PonderableComponent::Type::vacuumed); |
301 | 218 | ||
302 | // Look for any object configuration. | 219 | if (prototypeId == "movplat") |
303 | std::map<std::string, int> items; | ||
304 | |||
305 | for (xmlNodePtr objectNode = mapNode->xmlChildrenNode; | ||
306 | objectNode != nullptr; | ||
307 | objectNode = objectNode->next) | ||
308 | { | 220 | { |
309 | if (!xmlStrcmp( | 221 | auto& automatable = game_.getEntityManager(). |
310 | objectNode->name, | 222 | emplaceComponent<AutomatableComponent>(mapObject); |
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 | 223 | ||
325 | // Add any AI behaviors. | ||
326 | std::vector<double> behaviorWeights; | ||
327 | 224 | ||
328 | for (xmlNodePtr protoSubNode = prototypeNode->xmlChildrenNode; | 225 | realizable.scriptEngine.script_file( |
329 | protoSubNode != nullptr; | 226 | "res/platform.lua");//, |
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 | } | 227 | } |
365 | 228 | ||
366 | mappable.objects.push_back(mapObject); | 229 | mappable.objects.push_back(mapObject); |