summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--src/collision.h1
-rw-r--r--src/components/mappable.h6
-rw-r--r--src/components/playable.h2
-rw-r--r--src/components/ponderable.h44
-rw-r--r--src/game.cpp4
-rw-r--r--src/game.h9
-rw-r--r--src/map.h66
-rw-r--r--src/prototype.cpp55
-rw-r--r--src/prototype.h45
-rw-r--r--src/prototype_manager.cpp71
-rw-r--r--src/prototype_manager.h23
-rw-r--r--src/systems/mapping.cpp14
-rw-r--r--src/systems/playing.cpp33
-rw-r--r--src/systems/playing.h2
-rw-r--r--src/systems/pondering.cpp88
-rw-r--r--src/systems/pondering.h9
-rw-r--r--src/world.cpp67
-rw-r--r--src/xml.cpp13
-rw-r--r--src/xml.h8
20 files changed, 533 insertions, 30 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 34246ad..0309cd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -56,6 +56,9 @@ add_executable(Aromatherapy
56 src/world.cpp 56 src/world.cpp
57 src/util.cpp 57 src/util.cpp
58 src/collision.cpp 58 src/collision.cpp
59 src/prototype.cpp
60 src/prototype_manager.cpp
61 src/xml.cpp
59 src/renderer/renderer.cpp 62 src/renderer/renderer.cpp
60 src/renderer/mesh.cpp 63 src/renderer/mesh.cpp
61 src/renderer/shader.cpp 64 src/renderer/shader.cpp
diff --git a/src/collision.h b/src/collision.h index e5371f8..0f62b98 100644 --- a/src/collision.h +++ b/src/collision.h
@@ -15,6 +15,7 @@ public:
15 platform, 15 platform,
16 adjacency, 16 adjacency,
17 warp, 17 warp,
18 event,
18 danger 19 danger
19 }; 20 };
20 21
diff --git a/src/components/mappable.h b/src/components/mappable.h index 633cdf4..e26326d 100644 --- a/src/components/mappable.h +++ b/src/components/mappable.h
@@ -125,6 +125,11 @@ public:
125 font_ = std::move(v); 125 font_ = std::move(v);
126 } 126 }
127 127
128 inline std::map<size_t, id_type>& getInstances()
129 {
130 return instances_;
131 }
132
128private: 133private:
129 134
130 size_t mapId_ = -1; 135 size_t mapId_ = -1;
@@ -135,6 +140,7 @@ private:
135 asc_boundaries_type downBoundaries_; 140 asc_boundaries_type downBoundaries_;
136 Texture tileset_; 141 Texture tileset_;
137 Texture font_; 142 Texture font_;
143 std::map<size_t, id_type> instances_;
138}; 144};
139 145
140#endif /* end of include guard: MAPPABLE_H_0B0316FB */ 146#endif /* end of include guard: MAPPABLE_H_0B0316FB */
diff --git a/src/components/playable.h b/src/components/playable.h index 86a7ee7..0d91929 100644 --- a/src/components/playable.h +++ b/src/components/playable.h
@@ -18,6 +18,8 @@ public:
18 int checkpointMapId = -1; 18 int checkpointMapId = -1;
19 double checkpointX = 0; 19 double checkpointX = 0;
20 double checkpointY = 0; 20 double checkpointY = 0;
21 bool checkpointObjectActivated = false;
22 size_t checkpointObjectIndex = 0;
21 23
22}; 24};
23 25
diff --git a/src/components/ponderable.h b/src/components/ponderable.h index 78af25f..da509a2 100644 --- a/src/components/ponderable.h +++ b/src/components/ponderable.h
@@ -2,22 +2,44 @@
2#define TANGIBLE_H_746DB3EE 2#define TANGIBLE_H_746DB3EE
3 3
4#include "component.h" 4#include "component.h"
5#include <functional>
6#include <array>
7
8class Game;
5 9
6class PonderableComponent : public Component { 10class PonderableComponent : public Component {
7public: 11public:
8 12
9 enum class Type { 13 enum class BodyType {
10 vacuumed, 14 vacuumed,
11 freefalling 15 freefalling
12 }; 16 };
13 17
14 PonderableComponent(Type type) : type_(type) 18 enum class ColliderType {
19 player,
20 event
21 };
22
23 static const size_t COLLIDER_TYPES = 2;
24
25 PonderableComponent(
26 BodyType bodyType,
27 ColliderType colliderType) :
28 bodyType_(bodyType),
29 colliderType_(colliderType)
30 {
31 }
32
33 using event_callback_type = std::function<void(Game& game)>;
34
35 inline BodyType getBodyType() const
15 { 36 {
37 return bodyType_;
16 } 38 }
17 39
18 inline Type getType() const 40 inline ColliderType getColliderType() const
19 { 41 {
20 return type_; 42 return colliderType_;
21 } 43 }
22 44
23 inline double getVelocityX() const 45 inline double getVelocityX() const
@@ -90,16 +112,28 @@ public:
90 collidable_ = v; 112 collidable_ = v;
91 } 113 }
92 114
115 inline const event_callback_type& getEventCallback(ColliderType v) const
116 {
117 return eventCallbacks_[static_cast<size_t>(v)];
118 }
119
120 inline void setEventCallback(ColliderType v, event_callback_type callback)
121 {
122 eventCallbacks_[static_cast<size_t>(v)] = std::move(callback);
123 }
124
93private: 125private:
94 126
95 double velX_ = 0.0; 127 double velX_ = 0.0;
96 double velY_ = 0.0; 128 double velY_ = 0.0;
97 double accelX_ = 0.0; 129 double accelX_ = 0.0;
98 double accelY_ = 0.0; 130 double accelY_ = 0.0;
99 Type type_ = Type::vacuumed; 131 BodyType bodyType_;
132 ColliderType colliderType_;
100 bool grounded_ = false; 133 bool grounded_ = false;
101 bool frozen_ = false; 134 bool frozen_ = false;
102 bool collidable_ = true; 135 bool collidable_ = true;
136 std::array<event_callback_type, COLLIDER_TYPES> eventCallbacks_;
103}; 137};
104 138
105#endif /* end of include guard: TANGIBLE_H_746DB3EE */ 139#endif /* end of include guard: TANGIBLE_H_746DB3EE */
diff --git a/src/game.cpp b/src/game.cpp index 3da23a3..5259739 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -28,7 +28,9 @@ void key_callback(GLFWwindow* window, int key, int, int action, int)
28 game.systemManager_.input(key, action); 28 game.systemManager_.input(key, action);
29} 29}
30 30
31Game::Game() : world_("res/maps.xml") 31Game::Game() :
32 world_("res/maps.xml"),
33 prototypes_("res/entities.xml")
32{ 34{
33 systemManager_.emplaceSystem<PlayingSystem>(*this); 35 systemManager_.emplaceSystem<PlayingSystem>(*this);
34 systemManager_.emplaceSystem<SchedulingSystem>(*this); 36 systemManager_.emplaceSystem<SchedulingSystem>(*this);
diff --git a/src/game.h b/src/game.h index 43e08da..2dd7f91 100644 --- a/src/game.h +++ b/src/game.h
@@ -5,6 +5,7 @@
5#include "system_manager.h" 5#include "system_manager.h"
6#include "world.h" 6#include "world.h"
7#include "renderer/renderer.h" 7#include "renderer/renderer.h"
8#include "prototype_manager.h"
8 9
9class Game { 10class Game {
10public: 11public:
@@ -28,11 +29,16 @@ public:
28 return systemManager_; 29 return systemManager_;
29 } 30 }
30 31
31 inline const World& getWorld() 32 inline const World& getWorld() const
32 { 33 {
33 return world_; 34 return world_;
34 } 35 }
35 36
37 inline const PrototypeManager& getPrototypeManager() const
38 {
39 return prototypes_;
40 }
41
36 friend void key_callback( 42 friend void key_callback(
37 GLFWwindow* window, 43 GLFWwindow* window,
38 int key, 44 int key,
@@ -46,6 +52,7 @@ private:
46 EntityManager entityManager_; 52 EntityManager entityManager_;
47 SystemManager systemManager_; 53 SystemManager systemManager_;
48 World world_; 54 World world_;
55 PrototypeManager prototypes_;
49 bool shouldQuit_ = false; 56 bool shouldQuit_ = false;
50}; 57};
51 58
diff --git a/src/map.h b/src/map.h index 6fe1e62..0e11b9d 100644 --- a/src/map.h +++ b/src/map.h
@@ -4,7 +4,6 @@
4#include <vector> 4#include <vector>
5#include <string> 5#include <string>
6#include <list> 6#include <list>
7#include <stdexcept>
8#include <map> 7#include <map>
9 8
10class Map { 9class Map {
@@ -44,6 +43,59 @@ public:
44 int mapId_; 43 int mapId_;
45 }; 44 };
46 45
46 class Object {
47 public:
48
49 Object(
50 std::string type,
51 double x,
52 double y,
53 size_t index,
54 std::map<std::string, int> items) :
55 type_(std::move(type)),
56 x_(x),
57 y_(y),
58 index_(index),
59 items_(std::move(items))
60 {
61 }
62
63 inline const std::string& getType() const
64 {
65 return type_;
66 }
67
68 inline double getX() const
69 {
70 return x_;
71 }
72
73 inline double getY() const
74 {
75 return y_;
76 }
77
78 inline size_t getIndex() const
79 {
80 return index_;
81 }
82
83 inline const std::map<std::string, int>& getItems() const
84 {
85 return items_;
86 }
87
88 private:
89
90 std::string type_;
91 double x_;
92 double y_;
93 size_t index_;
94 std::map<std::string, int> items_;
95 };
96
97 using object_storage_type = std::list<Object>;
98
47 Map( 99 Map(
48 int id, 100 int id,
49 std::vector<int> tiles, 101 std::vector<int> tiles,
@@ -51,14 +103,16 @@ public:
51 Adjacent leftAdjacent, 103 Adjacent leftAdjacent,
52 Adjacent rightAdjacent, 104 Adjacent rightAdjacent,
53 Adjacent upAdjacent, 105 Adjacent upAdjacent,
54 Adjacent downAdjacent) : 106 Adjacent downAdjacent,
107 object_storage_type objects) :
55 id_(id), 108 id_(id),
56 tiles_(std::move(tiles)), 109 tiles_(std::move(tiles)),
57 title_(std::move(title)), 110 title_(std::move(title)),
58 leftAdjacent_(std::move(leftAdjacent)), 111 leftAdjacent_(std::move(leftAdjacent)),
59 rightAdjacent_(std::move(rightAdjacent)), 112 rightAdjacent_(std::move(rightAdjacent)),
60 upAdjacent_(std::move(upAdjacent)), 113 upAdjacent_(std::move(upAdjacent)),
61 downAdjacent_(std::move(downAdjacent)) 114 downAdjacent_(std::move(downAdjacent)),
115 objects_(std::move(objects))
62 { 116 {
63 } 117 }
64 118
@@ -97,6 +151,11 @@ public:
97 return downAdjacent_; 151 return downAdjacent_;
98 } 152 }
99 153
154 inline const object_storage_type& getObjects() const
155 {
156 return objects_;
157 }
158
100private: 159private:
101 160
102 int id_; 161 int id_;
@@ -106,6 +165,7 @@ private:
106 Adjacent rightAdjacent_; 165 Adjacent rightAdjacent_;
107 Adjacent upAdjacent_; 166 Adjacent upAdjacent_;
108 Adjacent downAdjacent_; 167 Adjacent downAdjacent_;
168 object_storage_type objects_;
109}; 169};
110 170
111#endif /* end of include guard: MAP_H_74055FC0 */ 171#endif /* end of include guard: MAP_H_74055FC0 */
diff --git a/src/prototype.cpp b/src/prototype.cpp new file mode 100644 index 0000000..a4a0e80 --- /dev/null +++ b/src/prototype.cpp
@@ -0,0 +1,55 @@
1#include "prototype.h"
2#include "game.h"
3#include "animation.h"
4#include "components/animatable.h"
5#include "components/transformable.h"
6#include "components/ponderable.h"
7#include "systems/pondering.h"
8#include "systems/playing.h"
9
10id_type Prototype::instantiate(
11 Game& game,
12 const Map::Object& object) const
13{
14 id_type entity = game.getEntityManager().emplaceEntity();
15
16 AnimationSet entityGraphics(spritePath_.c_str(), w_, h_, 1);
17 entityGraphics.emplaceAnimation("default", 0, 1, 1);
18
19 game.getEntityManager().emplaceComponent<AnimatableComponent>(
20 entity,
21 std::move(entityGraphics),
22 "default");
23
24 game.getEntityManager().emplaceComponent<TransformableComponent>(
25 entity,
26 object.getX(),
27 object.getY(),
28 w_,
29 h_);
30
31 game.getSystemManager().getSystem<PonderingSystem>().initializeBody(
32 entity,
33 PonderableComponent::BodyType::vacuumed,
34 PonderableComponent::ColliderType::event);
35
36 auto& ponderable = game.getEntityManager().
37 getComponent<PonderableComponent>(entity);
38
39 switch (action_)
40 {
41 case Action::save:
42 {
43 ponderable.setEventCallback(PonderableComponent::ColliderType::player,
44 [] (Game& game) {
45 auto& playing = game.getSystemManager().getSystem<PlayingSystem>();
46
47 playing.save();
48 });
49
50 break;
51 }
52 }
53
54 return entity;
55}
diff --git a/src/prototype.h b/src/prototype.h new file mode 100644 index 0000000..03df00f --- /dev/null +++ b/src/prototype.h
@@ -0,0 +1,45 @@
1#ifndef PROTOTYPE_H_BB208E0F
2#define PROTOTYPE_H_BB208E0F
3
4#include <string>
5#include <map>
6#include "map.h"
7#include "entity_manager.h"
8
9class Game;
10
11class Prototype {
12public:
13
14 using id_type = EntityManager::id_type;
15
16 enum class Action {
17 none,
18 save
19 };
20
21 Prototype(
22 int w,
23 int h,
24 std::string spritePath,
25 Action action) :
26 w_(w),
27 h_(h),
28 spritePath_(std::move(spritePath)),
29 action_(action)
30 {
31 }
32
33 id_type instantiate(
34 Game& game,
35 const Map::Object& object) const;
36
37private:
38
39 int w_;
40 int h_;
41 std::string spritePath_;
42 Action action_;
43};
44
45#endif /* end of include guard: PROTOTYPE_H_BB208E0F */
diff --git a/src/prototype_manager.cpp b/src/prototype_manager.cpp new file mode 100644 index 0000000..250aa59 --- /dev/null +++ b/src/prototype_manager.cpp
@@ -0,0 +1,71 @@
1#include "prototype_manager.h"
2#include <utility>
3#include <stdexcept>
4#include "xml.h"
5
6PrototypeManager::PrototypeManager(std::string path)
7{
8 xmlDocPtr doc = xmlParseFile(path.c_str());
9 if (doc == nullptr)
10 {
11 throw std::invalid_argument("Cannot find prototypes file");
12 }
13
14 xmlNodePtr top = xmlDocGetRootElement(doc);
15 if (top == nullptr)
16 {
17 throw std::invalid_argument("Error parsing prototypes file");
18 }
19
20 if (xmlStrcmp(top->name, reinterpret_cast<const xmlChar*>("entities")))
21 {
22 throw std::invalid_argument("Error parsing prototypes file");
23 }
24
25 xmlChar* key = nullptr;
26
27 for (xmlNodePtr node = top->xmlChildrenNode;
28 node != nullptr;
29 node = node->next)
30 {
31 if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("entity")))
32 {
33 key = getProp(node, "id");
34 std::string prototypeName(reinterpret_cast<char*>(key));
35 xmlFree(key);
36
37 key = getProp(node, "sprite");
38 std::string spritePath(reinterpret_cast<char*>(key));
39 xmlFree(key);
40
41 key = getProp(node, "width");
42 int width = atoi(reinterpret_cast<char*>(key));
43 xmlFree(key);
44
45 key = getProp(node, "height");
46 int height = atoi(reinterpret_cast<char*>(key));
47 xmlFree(key);
48
49 key = getProp(node, "action");
50 std::string actionStr(reinterpret_cast<char*>(key));
51 xmlFree(key);
52
53 Prototype::Action pAction = Prototype::Action::none;
54 if (actionStr == "save")
55 {
56 pAction = Prototype::Action::save;
57 }
58
59 prototypes_.emplace(
60 std::piecewise_construct,
61 std::tie(prototypeName),
62 std::tie(
63 width,
64 height,
65 spritePath,
66 pAction));
67 }
68 }
69
70 xmlFreeDoc(doc);
71}
diff --git a/src/prototype_manager.h b/src/prototype_manager.h new file mode 100644 index 0000000..3fadd23 --- /dev/null +++ b/src/prototype_manager.h
@@ -0,0 +1,23 @@
1#ifndef PROTOTYPE_MANAGER_H_83CECCA6
2#define PROTOTYPE_MANAGER_H_83CECCA6
3
4#include <string>
5#include <map>
6#include "prototype.h"
7
8class PrototypeManager {
9public:
10
11 PrototypeManager(std::string path);
12
13 inline const Prototype& getPrototype(std::string name) const
14 {
15 return prototypes_.at(name);
16 }
17
18private:
19
20 std::map<std::string, Prototype> prototypes_;
21};
22
23#endif /* end of include guard: PROTOTYPE_MANAGER_H_83CECCA6 */
diff --git a/src/systems/mapping.cpp b/src/systems/mapping.cpp index a3a17ec..c7c2f9d 100644 --- a/src/systems/mapping.cpp +++ b/src/systems/mapping.cpp
@@ -195,4 +195,18 @@ void MappingSystem::loadMap(size_t mapId)
195 MappableComponent::Boundary::Type::danger); 195 MappableComponent::Boundary::Type::danger);
196 } 196 }
197 } 197 }
198
199 for (const Map::Object& object : map.getObjects())
200 {
201 const Prototype& prototype = game_.getPrototypeManager().
202 getPrototype(object.getType());
203
204 id_type emplacedObject = prototype.instantiate(
205 game_,
206 object.getX(),
207 object.getY(),
208 object.getItems());
209
210 mappable.getInstances()[object.getIndex()] = emplacedObject;
211 }
198} 212}
diff --git a/src/systems/playing.cpp b/src/systems/playing.cpp index 40d9706..5077f8a 100644 --- a/src/systems/playing.cpp +++ b/src/systems/playing.cpp
@@ -5,6 +5,7 @@
5#include "components/playable.h" 5#include "components/playable.h"
6#include "components/controllable.h" 6#include "components/controllable.h"
7#include "components/orientable.h" 7#include "components/orientable.h"
8#include "components/mappable.h"
8#include "systems/mapping.h" 9#include "systems/mapping.h"
9#include "systems/pondering.h" 10#include "systems/pondering.h"
10#include "systems/orienting.h" 11#include "systems/orienting.h"
@@ -84,7 +85,8 @@ void PlayingSystem::initPlayer()
84 85
85 game_.getSystemManager().getSystem<PonderingSystem>().initializeBody( 86 game_.getSystemManager().getSystem<PonderingSystem>().initializeBody(
86 player, 87 player,
87 PonderableComponent::Type::freefalling); 88 PonderableComponent::BodyType::freefalling,
89 PonderableComponent::ColliderType::player);
88 90
89 game_.getEntityManager().emplaceComponent<ControllableComponent>(player); 91 game_.getEntityManager().emplaceComponent<ControllableComponent>(player);
90 game_.getEntityManager().emplaceComponent<OrientableComponent>(player); 92 game_.getEntityManager().emplaceComponent<OrientableComponent>(player);
@@ -173,3 +175,32 @@ void PlayingSystem::die()
173 }); 175 });
174 } 176 }
175} 177}
178
179void PlayingSystem::save()
180{
181 playSound("res/Pickup_Coin23.wav", 0.25);
182
183 auto players = game_.getEntityManager().getEntitiesWithComponents<
184 TransformableComponent,
185 PlayableComponent>();
186
187 auto maps = game_.getEntityManager().getEntitiesWithComponents<
188 MappableComponent>();
189
190 auto& mappable = game_.getEntityManager().
191 getComponent<MappableComponent>(*maps.begin());
192
193 for (id_type player : players)
194 {
195 auto& transformable = game_.getEntityManager().
196 getComponent<TransformableComponent>(player);
197
198 auto& playable = game_.getEntityManager().
199 getComponent<PlayableComponent>(player);
200
201 playable.checkpointMapId = mappable.getMapId();
202 playable.checkpointX = transformable.getX();
203 playable.checkpointY = transformable.getY();
204 playable.checkpointObjectActivated = false;
205 }
206}
diff --git a/src/systems/playing.h b/src/systems/playing.h index ff16808..d7f5072 100644 --- a/src/systems/playing.h +++ b/src/systems/playing.h
@@ -23,6 +23,8 @@ public:
23 23
24 void die(); 24 void die();
25 25
26 void save();
27
26}; 28};
27 29
28#endif /* end of include guard: PLAYING_H_70A54F7D */ 30#endif /* end of include guard: PLAYING_H_70A54F7D */
diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index 02d5cfc..9115988 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp
@@ -39,7 +39,7 @@ void PonderingSystem::tick(double dt)
39 ponderable.setVelocityY( 39 ponderable.setVelocityY(
40 ponderable.getVelocityY() + ponderable.getAccelY() * dt); 40 ponderable.getVelocityY() + ponderable.getAccelY() * dt);
41 41
42 if ((ponderable.getType() == PonderableComponent::Type::freefalling) 42 if ((ponderable.getBodyType() == PonderableComponent::BodyType::freefalling)
43 && (ponderable.getVelocityY() > TERMINAL_VELOCITY)) 43 && (ponderable.getVelocityY() > TERMINAL_VELOCITY))
44 { 44 {
45 ponderable.setVelocityY(TERMINAL_VELOCITY); 45 ponderable.setVelocityY(TERMINAL_VELOCITY);
@@ -58,7 +58,7 @@ void PonderingSystem::tick(double dt)
58 58
59 std::priority_queue<Collision> collisions; 59 std::priority_queue<Collision> collisions;
60 60
61 // Find collisions 61 // Find map collisions
62 for (id_type mapEntity : maps) 62 for (id_type mapEntity : maps)
63 { 63 {
64 auto& mappable = game_.getEntityManager(). 64 auto& mappable = game_.getEntityManager().
@@ -366,6 +366,51 @@ void PonderingSystem::tick(double dt)
366 } 366 }
367 } 367 }
368 368
369 // Find body collisions
370 for (id_type body : entities)
371 {
372 // Can't collide with self
373 if (body == entity)
374 {
375 continue;
376 }
377
378 // Make sure the body is collidable
379 auto& colliderPonderable =
380 game_.getEntityManager().getComponent<PonderableComponent>(body);
381
382 if (!colliderPonderable.isCollidable())
383 {
384 continue;
385 }
386
387 // Test if the body was already colliding
388 auto& colliderTransformable =
389 game_.getEntityManager().getComponent<TransformableComponent>(body);
390
391 if ((oldRight > colliderTransformable.getX())
392 && (oldX < colliderTransformable.getX() + colliderTransformable.getW())
393 && (oldBottom > colliderTransformable.getY())
394 && (oldY < colliderTransformable.getY() + colliderTransformable.getH()))
395 {
396 continue;
397 }
398
399 // Test if there is a new collision
400 if (!((newX + transformable.getW() > colliderTransformable.getX())
401 && (newX < colliderTransformable.getX() + colliderTransformable.getW())
402 && (newY + transformable.getH() > colliderTransformable.getY())
403 && (newY <
404 colliderTransformable.getY() + colliderTransformable.getH())))
405 {
406 continue;
407 }
408
409 // Process the collision
410 processBodyCollision(entity, body);
411 processBodyCollision(body, entity);
412 }
413
369 // Move 414 // Move
370 transformable.setX(newX); 415 transformable.setX(newX);
371 transformable.setY(newY); 416 transformable.setY(newY);
@@ -399,13 +444,46 @@ void PonderingSystem::tick(double dt)
399 444
400void PonderingSystem::initializeBody( 445void PonderingSystem::initializeBody(
401 id_type entity, 446 id_type entity,
402 PonderableComponent::Type type) 447 PonderableComponent::BodyType bodyType,
448 PonderableComponent::ColliderType colliderType)
403{ 449{
404 auto& ponderable = game_.getEntityManager(). 450 auto& ponderable = game_.getEntityManager().
405 emplaceComponent<PonderableComponent>(entity, type); 451 emplaceComponent<PonderableComponent>(entity, bodyType, colliderType);
406 452
407 if (type == PonderableComponent::Type::freefalling) 453 if (bodyType == PonderableComponent::BodyType::freefalling)
408 { 454 {
409 ponderable.setAccelY(NORMAL_GRAVITY); 455 ponderable.setAccelY(NORMAL_GRAVITY);
410 } 456 }
411} 457}
458
459void PonderingSystem::processBodyCollision(id_type body, id_type collider)
460{
461 auto& bodyPonderable = game_.getEntityManager().
462 getComponent<PonderableComponent>(body);
463
464 auto& colliderPonderable = game_.getEntityManager().
465 getComponent<PonderableComponent>(collider);
466
467 switch (colliderPonderable.getColliderType())
468 {
469 case PonderableComponent::ColliderType::event:
470 {
471 auto& callback = colliderPonderable.
472 getEventCallback(bodyPonderable.getColliderType());
473
474 if (callback)
475 {
476 callback(game_);
477 }
478
479 break;
480 }
481
482 default:
483 {
484 // Do nothing.
485
486 break;
487 }
488 }
489}
diff --git a/src/systems/pondering.h b/src/systems/pondering.h index d70525b..7e342df 100644 --- a/src/systems/pondering.h +++ b/src/systems/pondering.h
@@ -14,7 +14,14 @@ public:
14 14
15 void tick(double dt); 15 void tick(double dt);
16 16
17 void initializeBody(id_type entity, PonderableComponent::Type type); 17 void initializeBody(
18 id_type entity,
19 PonderableComponent::BodyType bodyType,
20 PonderableComponent::ColliderType colliderType);
21
22private:
23
24 void processBodyCollision(id_type body, id_type collider);
18 25
19}; 26};
20 27
diff --git a/src/world.cpp b/src/world.cpp index 3b6bd41..d239067 100644 --- a/src/world.cpp +++ b/src/world.cpp
@@ -1,19 +1,8 @@
1#include "world.h" 1#include "world.h"
2#include <libxml/parser.h>
3#include <stdexcept> 2#include <stdexcept>
4#include <cstring> 3#include <cstring>
5#include "consts.h" 4#include "consts.h"
6 5#include "xml.h"
7inline xmlChar* getProp(xmlNodePtr node, const char* attr)
8{
9 xmlChar* key = xmlGetProp(node, reinterpret_cast<const xmlChar*>(attr));
10 if (key == nullptr)
11 {
12 throw std::invalid_argument("Error parsing world file");
13 }
14
15 return key;
16}
17 6
18World::World(std::string filename) 7World::World(std::string filename)
19{ 8{
@@ -67,6 +56,7 @@ World::World(std::string filename)
67 Map::Adjacent rightAdj; 56 Map::Adjacent rightAdj;
68 Map::Adjacent upAdj; 57 Map::Adjacent upAdj;
69 Map::Adjacent downAdj; 58 Map::Adjacent downAdj;
59 std::list<Map::Object> objects;
70 60
71 for (xmlNodePtr mapNode = node->xmlChildrenNode; 61 for (xmlNodePtr mapNode = node->xmlChildrenNode;
72 mapNode != nullptr; 62 mapNode != nullptr;
@@ -77,6 +67,10 @@ World::World(std::string filename)
77 reinterpret_cast<const xmlChar*>("environment"))) 67 reinterpret_cast<const xmlChar*>("environment")))
78 { 68 {
79 key = xmlNodeGetContent(mapNode); 69 key = xmlNodeGetContent(mapNode);
70 if (key == nullptr)
71 {
72 throw std::invalid_argument("Error parsing XML file");
73 }
80 74
81 mapTiles.clear(); 75 mapTiles.clear();
82 mapTiles.push_back(atoi(strtok(reinterpret_cast<char*>(key), ",\n"))); 76 mapTiles.push_back(atoi(strtok(reinterpret_cast<char*>(key), ",\n")));
@@ -88,6 +82,52 @@ World::World(std::string filename)
88 xmlFree(key); 82 xmlFree(key);
89 } else if (!xmlStrcmp( 83 } else if (!xmlStrcmp(
90 mapNode->name, 84 mapNode->name,
85 reinterpret_cast<const xmlChar*>("entity")))
86 {
87 key = getProp(mapNode, "type");
88 std::string entType(reinterpret_cast<char*>(key));
89 xmlFree(key);
90
91 key = getProp(mapNode, "x");
92 int entX = atoi(reinterpret_cast<char*>(key));
93 xmlFree(key);
94
95 key = getProp(mapNode, "y");
96 int entY = atoi(reinterpret_cast<char*>(key));
97 xmlFree(key);
98
99 key = getProp(mapNode, "index");
100 int entIndex = atoi(reinterpret_cast<char*>(key));
101 xmlFree(key);
102
103 std::map<std::string, int> items;
104
105 for (xmlNodePtr entityNode = mapNode->xmlChildrenNode;
106 entityNode != nullptr;
107 entityNode = entityNode->next)
108 {
109 key = getProp(entityNode, "id");
110 std::string itemId(reinterpret_cast<char*>(key));
111 xmlFree(key);
112
113 key = xmlNodeGetContent(entityNode);
114 if (key == nullptr)
115 {
116 throw std::invalid_argument("Error parsing XML file");
117 }
118
119 items[itemId] = atoi(reinterpret_cast<char*>(key));
120 xmlFree(key);
121 }
122
123 objects.emplace_back(
124 std::move(entType),
125 entX,
126 entY,
127 entIndex,
128 std::move(items));
129 } else if (!xmlStrcmp(
130 mapNode->name,
91 reinterpret_cast<const xmlChar*>("adjacent"))) 131 reinterpret_cast<const xmlChar*>("adjacent")))
92 { 132 {
93 key = getProp(mapNode, "type"); 133 key = getProp(mapNode, "type");
@@ -147,7 +187,8 @@ World::World(std::string filename)
147 leftAdj, 187 leftAdj,
148 rightAdj, 188 rightAdj,
149 upAdj, 189 upAdj,
150 downAdj)); 190 downAdj,
191 std::move(objects)));
151 } 192 }
152 } 193 }
153 194
diff --git a/src/xml.cpp b/src/xml.cpp new file mode 100644 index 0000000..f6f60ea --- /dev/null +++ b/src/xml.cpp
@@ -0,0 +1,13 @@
1#include "xml.h"
2#include <stdexcept>
3
4xmlChar* getProp(xmlNodePtr node, const char* attr)
5{
6 xmlChar* key = xmlGetProp(node, reinterpret_cast<const xmlChar*>(attr));
7 if (key == nullptr)
8 {
9 throw std::invalid_argument("Error parsing XML file");
10 }
11
12 return key;
13}
diff --git a/src/xml.h b/src/xml.h new file mode 100644 index 0000000..8ecf639 --- /dev/null +++ b/src/xml.h
@@ -0,0 +1,8 @@
1#ifndef XML_H_E5E95685
2#define XML_H_E5E95685
3
4#include <libxml/parser.h>
5
6xmlChar* getProp(xmlNodePtr node, const char* attr);
7
8#endif /* end of include guard: XML_H_E5E95685 */