diff options
| -rw-r--r-- | CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/collision.h | 1 | ||||
| -rw-r--r-- | src/components/mappable.h | 6 | ||||
| -rw-r--r-- | src/components/playable.h | 2 | ||||
| -rw-r--r-- | src/components/ponderable.h | 44 | ||||
| -rw-r--r-- | src/game.cpp | 4 | ||||
| -rw-r--r-- | src/game.h | 9 | ||||
| -rw-r--r-- | src/map.h | 66 | ||||
| -rw-r--r-- | src/prototype.cpp | 55 | ||||
| -rw-r--r-- | src/prototype.h | 45 | ||||
| -rw-r--r-- | src/prototype_manager.cpp | 71 | ||||
| -rw-r--r-- | src/prototype_manager.h | 23 | ||||
| -rw-r--r-- | src/systems/mapping.cpp | 14 | ||||
| -rw-r--r-- | src/systems/playing.cpp | 33 | ||||
| -rw-r--r-- | src/systems/playing.h | 2 | ||||
| -rw-r--r-- | src/systems/pondering.cpp | 88 | ||||
| -rw-r--r-- | src/systems/pondering.h | 9 | ||||
| -rw-r--r-- | src/world.cpp | 67 | ||||
| -rw-r--r-- | src/xml.cpp | 13 | ||||
| -rw-r--r-- | src/xml.h | 8 |
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 | |||
| 128 | private: | 133 | private: |
| 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 | |||
| 8 | class Game; | ||
| 5 | 9 | ||
| 6 | class PonderableComponent : public Component { | 10 | class PonderableComponent : public Component { |
| 7 | public: | 11 | public: |
| 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 | |||
| 93 | private: | 125 | private: |
| 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 | ||
| 31 | Game::Game() : world_("res/maps.xml") | 31 | Game::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 | ||
| 9 | class Game { | 10 | class Game { |
| 10 | public: | 11 | public: |
| @@ -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 | ||
| 10 | class Map { | 9 | class 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 | |||
| 100 | private: | 159 | private: |
| 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 | |||
| 10 | id_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 | |||
| 9 | class Game; | ||
| 10 | |||
| 11 | class Prototype { | ||
| 12 | public: | ||
| 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 | |||
| 37 | private: | ||
| 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 | |||
| 6 | PrototypeManager::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 | |||
| 8 | class PrototypeManager { | ||
| 9 | public: | ||
| 10 | |||
| 11 | PrototypeManager(std::string path); | ||
| 12 | |||
| 13 | inline const Prototype& getPrototype(std::string name) const | ||
| 14 | { | ||
| 15 | return prototypes_.at(name); | ||
| 16 | } | ||
| 17 | |||
| 18 | private: | ||
| 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 | |||
| 179 | void 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 | ||
| 400 | void PonderingSystem::initializeBody( | 445 | void 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 | |||
| 459 | void 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 | |||
| 22 | private: | ||
| 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" | |
| 7 | inline 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 | ||
| 18 | World::World(std::string filename) | 7 | World::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 | |||
| 4 | xmlChar* 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 | |||
| 6 | xmlChar* getProp(xmlNodePtr node, const char* attr); | ||
| 7 | |||
| 8 | #endif /* end of include guard: XML_H_E5E95685 */ | ||
