diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | include/attack.hpp | 39 | ||||
-rw-r--r-- | include/components.hpp | 6 | ||||
-rw-r--r-- | include/vector2.hpp | 4 | ||||
-rw-r--r-- | src/attack.cpp | 54 | ||||
-rw-r--r-- | src/components.cpp | 2 | ||||
-rw-r--r-- | src/engine.cpp | 3 | ||||
-rw-r--r-- | src/player.cpp | 4 | ||||
-rw-r--r-- | xml/entities.xml | 2 |
9 files changed, 113 insertions, 3 deletions
@@ -6,3 +6,5 @@ brice.dat config/settings.xml
setup.mk
TODOS
+out/*
+screenshots/*
diff --git a/include/attack.hpp b/include/attack.hpp new file mode 100644 index 0000000..412694e --- /dev/null +++ b/include/attack.hpp @@ -0,0 +1,39 @@ +#ifndef FIGHT_HPP_ +#define FIGHT_HPP_ + +#include <entityx/entityx.h> + +#include <forward_list> + +#include <vector2.hpp> + +enum class AttackType : char { + ShortSlash, + LongSlash +}; + +struct AttackEvent { + AttackEvent(vec2 p, AttackType at, int pow = 10) + : pos(p), type(at), power(pow) {} + + vec2 pos; + AttackType type; + int power; +}; + +class AttackSystem : public entityx::System<AttackSystem>, public entityx::Receiver<AttackSystem> { +private: + std::forward_list<AttackEvent> attacks; + +public: + explicit AttackSystem() = default; + + void configure(entityx::EventManager& ev) { + ev.subscribe<AttackEvent>(*this); + } + + void receive(const AttackEvent& ae); + void update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) override; +}; + +#endif // FIGHT_HPP_ diff --git a/include/components.hpp b/include/components.hpp index 541f0f8..0fb8ec6 100644 --- a/include/components.hpp +++ b/include/components.hpp @@ -172,7 +172,9 @@ struct Health : public Component { (void)imp; (void)def; // TODO - health = maxHealth = 1; + if (def->QueryIntAttribute("value", &health) != XML_NO_ERROR) + health = 1; + maxHealth = health; } }; @@ -208,6 +210,8 @@ struct Name : public Component { } }; +struct Player {}; + struct ItemDrop { ItemDrop(InventoryEntry& ie) : item(ie) {} diff --git a/include/vector2.hpp b/include/vector2.hpp index c1148da..828654c 100644 --- a/include/vector2.hpp +++ b/include/vector2.hpp @@ -84,6 +84,10 @@ struct vector2 { return (x < v.x) && (y < v.y); } + bool operator<=(const T& n) const { + return (x <= n) && (y <= n); + } + // other functions std::string toString(void) const { return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; diff --git a/src/attack.cpp b/src/attack.cpp new file mode 100644 index 0000000..226fe2f --- /dev/null +++ b/src/attack.cpp @@ -0,0 +1,54 @@ +#include <attack.hpp> +#include <components.hpp> +#include <engine.hpp> +#include <particle.hpp> + +constexpr int shortSlashLength = 100; +constexpr int longSlashLength = 200; + +// math helpers because we don't trust stdlib +template<typename T> +inline T abs(const T& n) { + static_assert(std::is_arithmetic<T>::value, "abs expects numbers"); + return n >= 0 ? n : -n; +} + + +void AttackSystem::receive(const AttackEvent& ae) +{ + attacks.emplace_front(ae); +} + +void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) +{ + (void)en; + (void)ev; + (void)dt; + + for (const auto& a : attacks) { + switch (a.type) { + case AttackType::ShortSlash: + en.each<Position, Solid, Health>( + [&a](entityx::Entity e, Position& pos, Solid& dim, Health& h) { + (void)e; + if (e.has_component<Player>()) + return; + vec2 eloc (pos.x + dim.width / 2, pos.y + dim.height / 2); + if (abs(eloc.x - a.pos.x) <= shortSlashLength) { + h.health -= a.power; + game::engine.getSystem<ParticleSystem>()->addMultiple(10, ParticleType::SmallBlast, + [&](){ return eloc; }, 500, 7); + } + } + ); + break; + case AttackType::LongSlash: + break; + default: + break; + } + } + + attacks.clear(); +} + diff --git a/src/components.cpp b/src/components.cpp index 644d504..f4ac01e 100644 --- a/src/components.cpp +++ b/src/components.cpp @@ -182,7 +182,7 @@ void RenderSystem::render(void) if (entity.has_component<Health>()) { float width = entity.component<Solid>()->width; auto& health = *entity.component<Health>(); - width /= health.health / health.maxHealth; + width *= health.health / static_cast<float>(health.maxHealth); GLfloat health_coord[] = { pos.x, pos.y, -9, 0, 0, diff --git a/src/engine.cpp b/src/engine.cpp index ee35d06..640356e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -11,6 +11,7 @@ #include <quest.hpp> #include <particle.hpp> #include <weather.hpp> +#include <attack.hpp> Engine::Engine(void) : shouldRun(true), systems(game::entities, game::events) @@ -35,6 +36,7 @@ void Engine::init(void) { systems.add<ParticleSystem>(); systems.add<WeatherSystem>(); + systems.add<AttackSystem>(); systems.configure(); @@ -54,6 +56,7 @@ void Engine::update(entityx::TimeDelta dt) //systems.update<QuestSystem>(dt); // doesn't do anything systems.update<WeatherSystem>(dt); systems.update<ParticleSystem>(dt); + systems.update<AttackSystem>(dt); } diff --git a/src/player.cpp b/src/player.cpp index bcde388..0a85459 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -5,6 +5,7 @@ #include <gametime.hpp> #include <world.hpp> #include <particle.hpp> +#include <attack.hpp> static const char *spriteXML = "<Sprite> \ @@ -70,6 +71,7 @@ static const char *animationXML = void PlayerSystem::create(void) { player = game::entities.create(); + player.assign<Player>(); player.assign<Position>(0.0f, 100.0f); player.assign<Direction>(0.0f, 0.0f); //player.assign<Physics>(-0.001f); @@ -198,6 +200,8 @@ void PlayerSystem::receive(const KeyDownEvent &kde) } else if (kc == SDLK_t) { game::time::tick(50); } + if (kc == SDLK_j) + game::events.emit<AttackEvent>(vec2(loc.x, loc.y), AttackType::ShortSlash); } vec2 PlayerSystem::getPosition(void) const diff --git a/xml/entities.xml b/xml/entities.xml index 5e33b92..fb69086 100644 --- a/xml/entities.xml +++ b/xml/entities.xml @@ -62,7 +62,7 @@ </frame> </Sprite> <Direction /> - <Health /> + <Health value="200" /> <Solid /> <Physics /> <Name value="SKIRL" /> |