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.cpp106
-rw-r--r--src/systems/automating.h22
-rw-r--r--src/systems/pondering.cpp13
-rw-r--r--src/systems/realizing.cpp66
-rw-r--r--src/systems/scripting.cpp219
-rw-r--r--src/systems/scripting.h28
6 files changed, 302 insertions, 152 deletions
diff --git a/src/systems/automating.cpp b/src/systems/automating.cpp deleted file mode 100644 index 4a5357d..0000000 --- a/src/systems/automating.cpp +++ /dev/null
@@ -1,106 +0,0 @@
1#include "automating.h"
2#include "game.h"
3#include "components/automatable.h"
4#include "components/ponderable.h"
5#include "components/realizable.h"
6#include "components/transformable.h"
7#include "systems/realizing.h"
8#include "vector.h"
9
10struct script_entity {
11 using id_type = EntityManager::id_type;
12
13 id_type id;
14
15 script_entity(id_type id) : id(id)
16 {
17 }
18};
19
20void AutomatingSystem::tick(double dt)
21{
22 auto entities = game_.getEntityManager().getEntitiesWithComponents<
23 AutomatableComponent>();
24
25 for (id_type entity : entities)
26 {
27 auto& automatable = game_.getEntityManager().
28 getComponent<AutomatableComponent>(entity);
29
30 if (!automatable.active)
31 {
32 continue;
33 }
34
35 auto result = (*automatable.behavior)(dt);
36 if (!result.valid())
37 {
38 sol::error e = result;
39 throw std::runtime_error(e.what());
40 }
41 }
42}
43
44void AutomatingSystem::initPrototype(id_type prototype)
45{
46 auto& automatable = game_.getEntityManager().
47 getComponent<AutomatableComponent>(prototype);
48
49 auto& realizable = game_.getEntityManager().
50 getComponent<RealizableComponent>(
51 game_.getSystemManager().getSystem<RealizingSystem>().getSingleton());
52 automatable.behavior.reset();
53 automatable.runner = std::unique_ptr<sol::thread>(new sol::thread(sol::thread::create(realizable.scriptEngine.lua_state())));
54 automatable.behavior = std::unique_ptr<sol::coroutine>(new sol::coroutine(automatable.runner->state()["run"]));
55
56 auto result = (*automatable.behavior)(script_entity(prototype));
57 if (!result.valid())
58 {
59 sol::error e = result;
60 throw std::runtime_error(e.what());
61 }
62}
63
64void AutomatingSystem::initScriptEngine(sol::state& scriptEngine)
65{
66 scriptEngine.open_libraries(sol::lib::base, sol::lib::coroutine);
67 scriptEngine.new_usertype<vec2d>(
68 "vec2d",
69 sol::constructors<vec2d(), vec2d(double, double)>(),
70 "x", sol::property(
71 [] (vec2d& v) -> double { return v.x(); },
72 [] (vec2d& v, double x) { v.x() = x; }),
73 "y", sol::property(
74 [] (vec2d& v) -> double { return v.y(); },
75 [] (vec2d& v, double y) { v.y() = y; }));
76
77 scriptEngine.new_usertype<vec2i>(
78 "vec2i",
79 sol::constructors<vec2i(), vec2i(int, int)>(),
80 "x", [] (vec2i& v) -> int& { return v.x(); },
81 "y", [] (vec2i& v) -> int& { return v.y(); });
82
83 scriptEngine.new_usertype<script_entity>(
84 "entity",
85 sol::constructors<script_entity(id_type)>(),
86 "id", &script_entity::id,
87 "transformable",
88 [&] (script_entity& entity) -> TransformableComponent& {
89 return game_.getEntityManager().
90 getComponent<TransformableComponent>(entity.id);
91 },
92 "ponderable",
93 [&] (script_entity& entity) -> PonderableComponent& {
94 return game_.getEntityManager().
95 getComponent<PonderableComponent>(entity.id);
96 });
97
98 scriptEngine.new_usertype<TransformableComponent>(
99 "transformable",
100 "pos", &TransformableComponent::pos);
101
102 scriptEngine.new_usertype<PonderableComponent>(
103 "ponderable",
104 "vel", &PonderableComponent::vel,
105 "accel", &PonderableComponent::accel);
106}
diff --git a/src/systems/automating.h b/src/systems/automating.h deleted file mode 100644 index 117b622..0000000 --- a/src/systems/automating.h +++ /dev/null
@@ -1,22 +0,0 @@
1#ifndef AUTOMATING_H_E6E5D76E
2#define AUTOMATING_H_E6E5D76E
3
4#include "system.h"
5#include <sol.hpp>
6
7class AutomatingSystem : public System {
8public:
9
10 AutomatingSystem(Game& game) : System(game)
11 {
12 }
13
14 void tick(double dt);
15
16 void initPrototype(id_type prototype);
17
18 void initScriptEngine(sol::state& scriptEngine);
19
20};
21
22#endif /* end of include guard: AUTOMATING_H_E6E5D76E */
diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index c806cc8..a3eb36d 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp
@@ -11,6 +11,7 @@
11#include "systems/orienting.h" 11#include "systems/orienting.h"
12#include "systems/playing.h" 12#include "systems/playing.h"
13#include "systems/realizing.h" 13#include "systems/realizing.h"
14#include "systems/scripting.h"
14#include "consts.h" 15#include "consts.h"
15 16
16void PonderingSystem::tick(double dt) 17void PonderingSystem::tick(double dt)
@@ -857,6 +858,18 @@ void PonderingSystem::processCollision(
857 break; 858 break;
858 } 859 }
859 860
861 case PonderableComponent::Collision::event:
862 {
863 if (game_.getEntityManager().
864 hasComponent<PlayableComponent>(entity))
865 {
866 game_.getSystemManager().getSystem<ScriptingSystem>().
867 onTouch(collider, entity);
868 }
869
870 break;
871 }
872
860 default: 873 default:
861 { 874 {
862 // Not yet implemented. 875 // Not yet implemented.
diff --git a/src/systems/realizing.cpp b/src/systems/realizing.cpp index 28e2279..2ee5897 100644 --- a/src/systems/realizing.cpp +++ b/src/systems/realizing.cpp
@@ -12,11 +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 "components/prototypable.h"
16#include "systems/mapping.h" 16#include "systems/mapping.h"
17#include "systems/animating.h" 17#include "systems/animating.h"
18#include "systems/pondering.h" 18#include "systems/pondering.h"
19#include "systems/automating.h" 19#include "systems/scripting.h"
20 20
21inline xmlChar* getProp(xmlNodePtr node, const char* attr) 21inline xmlChar* getProp(xmlNodePtr node, const char* attr)
22{ 22{
@@ -40,9 +40,6 @@ EntityManager::id_type RealizingSystem::initSingleton(
40 auto& realizable = game_.getEntityManager(). 40 auto& realizable = game_.getEntityManager().
41 emplaceComponent<RealizableComponent>(world); 41 emplaceComponent<RealizableComponent>(world);
42 42
43 game_.getSystemManager().getSystem<AutomatingSystem>().
44 initScriptEngine(realizable.scriptEngine);
45
46 realizable.worldFile = worldFile; 43 realizable.worldFile = worldFile;
47 realizable.prototypeFile = prototypeFile; 44 realizable.prototypeFile = prototypeFile;
48 45
@@ -216,14 +213,28 @@ EntityManager::id_type RealizingSystem::initSingleton(
216 game_.getSystemManager().getSystem<PonderingSystem>(). 213 game_.getSystemManager().getSystem<PonderingSystem>().
217 initializeBody(mapObject, PonderableComponent::Type::vacuumed); 214 initializeBody(mapObject, PonderableComponent::Type::vacuumed);
218 215
216
217
218
219
220 auto& prototypable = game_.getEntityManager().
221 emplaceComponent<PrototypableComponent>(mapObject);
222
223 prototypable.prototypeId = prototypeId;
224
225 key = getProp(mapNode, "index");
226 prototypable.mapObjectIndex = atoi(reinterpret_cast<char*>(key));
227 xmlFree(key);
228
219 if (prototypeId == "movplat") 229 if (prototypeId == "movplat")
220 { 230 {
221 auto& automatable = game_.getEntityManager(). 231 prototypable.hasBehavior = true;
222 emplaceComponent<AutomatableComponent>(mapObject); 232 } else if (prototypeId == "checkpoint")
223 233 {
234 auto& ponderable = game_.getEntityManager().
235 getComponent<PonderableComponent>(mapObject);
224 236
225 realizable.scriptEngine.script_file( 237 ponderable.colliderType = PonderableComponent::Collision::event;
226 "res/platform.lua");//,
227 } 238 }
228 239
229 mappable.objects.push_back(mapObject); 240 mappable.objects.push_back(mapObject);
@@ -319,7 +330,6 @@ void RealizingSystem::loadMap(id_type mapEntity)
319 330
320 auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>(); 331 auto& animating = game_.getSystemManager().getSystem<AnimatingSystem>();
321 auto& pondering = game_.getSystemManager().getSystem<PonderingSystem>(); 332 auto& pondering = game_.getSystemManager().getSystem<PonderingSystem>();
322 auto& automating = game_.getSystemManager().getSystem<AutomatingSystem>();
323 333
324 std::set<id_type> players = 334 std::set<id_type> players =
325 game_.getEntityManager().getEntitiesWithComponents< 335 game_.getEntityManager().getEntitiesWithComponents<
@@ -380,11 +390,6 @@ void RealizingSystem::loadMap(id_type mapEntity)
380 pondering.initPrototype(prototype); 390 pondering.initPrototype(prototype);
381 } 391 }
382 392
383 if (game_.getEntityManager().hasComponent<AutomatableComponent>(prototype))
384 {
385 automating.initPrototype(prototype);
386 }
387
388 enterActiveMap(prototype); 393 enterActiveMap(prototype);
389 } 394 }
390 395
@@ -419,12 +424,19 @@ void RealizingSystem::enterActiveMap(id_type entity)
419 ponderable.active = true; 424 ponderable.active = true;
420 } 425 }
421 426
422 if (game_.getEntityManager().hasComponent<AutomatableComponent>(entity)) 427 if (game_.getEntityManager().hasComponent<PrototypableComponent>(entity))
423 { 428 {
424 auto& automatable = game_.getEntityManager(). 429 auto& prototypable = game_.getEntityManager().
425 getComponent<AutomatableComponent>(entity); 430 getComponent<PrototypableComponent>(entity);
431
432 if (prototypable.hasBehavior)
433 {
434 auto& scripting = game_.getSystemManager().getSystem<ScriptingSystem>();
426 435
427 automatable.active = true; 436 prototypable.hasBehavior = true;
437 prototypable.runningBehavior = true;
438 prototypable.behaviorScript = scripting.runBehaviorScript(entity);
439 }
428 } 440 }
429} 441}
430 442
@@ -446,11 +458,17 @@ void RealizingSystem::leaveActiveMap(id_type entity)
446 ponderable.active = false; 458 ponderable.active = false;
447 } 459 }
448 460
449 if (game_.getEntityManager().hasComponent<AutomatableComponent>(entity)) 461 if (game_.getEntityManager().hasComponent<PrototypableComponent>(entity))
450 { 462 {
451 auto& automatable = game_.getEntityManager(). 463 auto& prototypable = game_.getEntityManager().
452 getComponent<AutomatableComponent>(entity); 464 getComponent<PrototypableComponent>(entity);
453 465
454 automatable.active = false; 466 if (prototypable.runningBehavior)
467 {
468 auto& scripting = game_.getSystemManager().getSystem<ScriptingSystem>();
469 scripting.killScript(prototypable.behaviorScript);
470
471 prototypable.runningBehavior = false;
472 }
455 } 473 }
456} 474}
diff --git a/src/systems/scripting.cpp b/src/systems/scripting.cpp new file mode 100644 index 0000000..dc1fff5 --- /dev/null +++ b/src/systems/scripting.cpp
@@ -0,0 +1,219 @@
1#include "scripting.h"
2#include "game.h"
3#include "components/runnable.h"
4#include "components/ponderable.h"
5#include "components/realizable.h"
6#include "components/transformable.h"
7#include "components/playable.h"
8#include "components/mappable.h"
9#include "components/prototypable.h"
10#include "systems/realizing.h"
11#include "vector.h"
12
13struct script_entity {
14 using id_type = EntityManager::id_type;
15
16 id_type id;
17
18 script_entity(id_type id) : id(id)
19 {
20 }
21};
22
23ScriptingSystem::ScriptingSystem(Game& game) : System(game)
24{
25 id_type entity = game_.getEntityManager().emplaceEntity();
26
27 engine.open_libraries(sol::lib::base, sol::lib::coroutine);
28
29 engine.new_usertype<vec2d>(
30 "vec2d",
31 sol::constructors<vec2d(), vec2d(double, double)>(),
32 "x", sol::property(
33 [] (vec2d& v) -> double { return v.x(); },
34 [] (vec2d& v, double x) { v.x() = x; }),
35 "y", sol::property(
36 [] (vec2d& v) -> double { return v.y(); },
37 [] (vec2d& v, double y) { v.y() = y; }));
38
39 engine.new_usertype<vec2i>(
40 "vec2i",
41 sol::constructors<vec2i(), vec2i(int, int)>(),
42 "x", [] (vec2i& v) -> int& { return v.x(); },
43 "y", [] (vec2i& v) -> int& { return v.y(); });
44
45 engine.new_usertype<script_entity>(
46 "entity",
47 sol::constructors<script_entity(id_type)>(),
48 "id", &script_entity::id,
49 "transformable",
50 [&] (script_entity& entity) -> TransformableComponent& {
51 return game_.getEntityManager().
52 getComponent<TransformableComponent>(entity.id);
53 },
54 "ponderable",
55 [&] (script_entity& entity) -> PonderableComponent& {
56 return game_.getEntityManager().
57 getComponent<PonderableComponent>(entity.id);
58 },
59 "mappable",
60 [&] (script_entity& entity) -> MappableComponent& {
61 return game_.getEntityManager().
62 getComponent<MappableComponent>(entity.id);
63 },
64 "playable",
65 [&] (script_entity& entity) -> PlayableComponent& {
66 return game_.getEntityManager().
67 getComponent<PlayableComponent>(entity.id);
68 },
69 "realizable",
70 [&] (script_entity& entity) -> RealizableComponent& {
71 return game_.getEntityManager().
72 getComponent<RealizableComponent>(entity.id);
73 },
74 "prototypable",
75 [&] (script_entity& entity) -> PrototypableComponent& {
76 return game_.getEntityManager().
77 getComponent<PrototypableComponent>(entity.id);
78 });
79
80 engine.new_usertype<TransformableComponent>(
81 "transformable",
82 "pos", &TransformableComponent::pos);
83
84 engine.new_usertype<PonderableComponent>(
85 "ponderable",
86 "vel", &PonderableComponent::vel,
87 "accel", &PonderableComponent::accel);
88
89 engine.new_usertype<MappableComponent>(
90 "mappable",
91 "mapId", &MappableComponent::mapId);
92
93 engine.new_usertype<PlayableComponent>(
94 "playable",
95 "checkpointPos", &PlayableComponent::checkpointPos,
96 "checkpointMapId", &PlayableComponent::checkpointMapId,
97 "checkpointMapObject", &PlayableComponent::checkpointMapObject,
98 "checkpointMapObjectIndex", &PlayableComponent::checkpointMapObjectIndex);
99
100 engine.new_usertype<RealizableComponent>(
101 "realizable",
102 "activeMap", &RealizableComponent::activeMap);
103
104 engine.new_usertype<PrototypableComponent>(
105 "prototypable",
106 "mapObjectIndex", &PrototypableComponent::mapObjectIndex,
107 "prototypeId", &PrototypableComponent::prototypeId);
108
109 engine.new_usertype<RealizingSystem>(
110 "realizing",
111 "singleton",
112 [&] (RealizingSystem& realizing) -> script_entity {
113 return realizing.getSingleton();
114 });
115
116 engine.set_function(
117 "realizing",
118 [&] () {
119 return game_.getSystemManager().getSystem<RealizingSystem>();
120 });
121
122 engine.script_file("scripts/common.lua");
123 engine.script_file("scripts/movplat.lua");
124 engine.script_file("scripts/checkpoint.lua");
125}
126
127void ScriptingSystem::tick(double dt)
128{
129 auto entities = game_.getEntityManager().getEntitiesWithComponents<
130 RunnableComponent>();
131
132 for (id_type entity : entities)
133 {
134 auto& runnable = game_.getEntityManager().
135 getComponent<RunnableComponent>(entity);
136
137 if (*runnable.callable)
138 {
139 auto result = (*runnable.callable)(dt);
140 if (!result.valid())
141 {
142 sol::error e = result;
143 throw std::runtime_error(e.what());
144 }
145 }
146
147 if (!*runnable.callable)
148 {
149 game_.getEntityManager().deleteEntity(entity);
150 }
151 }
152}
153
154void ScriptingSystem::killScript(id_type entity)
155{
156 if (game_.getEntityManager().hasComponent<RunnableComponent>(entity))
157 {
158 game_.getEntityManager().deleteEntity(entity);
159 }
160}
161
162template <typename... Args>
163EntityManager::id_type ScriptingSystem::runScript(
164 std::string event,
165 id_type entity,
166 Args&&... args)
167{
168 auto& prototypable = game_.getEntityManager().
169 getComponent<PrototypableComponent>(entity);
170
171 id_type script = game_.getEntityManager().emplaceEntity();
172
173 auto& runnable = game_.getEntityManager().
174 emplaceComponent<RunnableComponent>(script);
175
176 runnable.runner =
177 std::unique_ptr<sol::thread>(
178 new sol::thread(
179 sol::thread::create(
180 engine.lua_state())));
181
182 runnable.callable =
183 std::unique_ptr<sol::coroutine>(
184 new sol::coroutine(
185 runnable.runner->state().
186 traverse_get<sol::function>(
187 prototypable.prototypeId,
188 event)));
189
190 if (!*runnable.callable)
191 {
192 throw std::runtime_error("Error running script");
193 }
194
195 auto result = (*runnable.callable)(
196 script_entity(entity),
197 std::forward<Args>(args)...);
198
199 if (!result.valid())
200 {
201 sol::error e = result;
202 throw std::runtime_error(e.what());
203 }
204
205 return script;
206}
207
208EntityManager::id_type ScriptingSystem::runBehaviorScript(id_type entity)
209{
210 return runScript("Behavior", entity);
211}
212
213void ScriptingSystem::onTouch(id_type entity, id_type player)
214{
215 runScript(
216 "OnTouch",
217 entity,
218 script_entity(player));
219}
diff --git a/src/systems/scripting.h b/src/systems/scripting.h new file mode 100644 index 0000000..d5380f1 --- /dev/null +++ b/src/systems/scripting.h
@@ -0,0 +1,28 @@
1#ifndef AUTOMATING_H_E6E5D76E
2#define AUTOMATING_H_E6E5D76E
3
4#include "system.h"
5#include <sol.hpp>
6
7class ScriptingSystem : public System {
8public:
9
10 ScriptingSystem(Game& game);
11
12 void tick(double dt);
13
14 void killScript(id_type entity);
15
16 id_type runBehaviorScript(id_type entity);
17
18 void onTouch(id_type entity, id_type player);
19
20private:
21
22 template <typename... Args>
23 id_type runScript(std::string event, id_type entity, Args&&... args);
24
25 sol::state engine;
26};
27
28#endif /* end of include guard: AUTOMATING_H_E6E5D76E */