From 08708d80209d0b2cebc8f5f849a9b66e34202d6f Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 7 Mar 2017 18:17:51 -0500 Subject: attacks? --- .gitignore | 2 ++ include/attack.hpp | 39 ++++++++++++++++++++++++++++++++++++ include/components.hpp | 6 +++++- include/vector2.hpp | 4 ++++ src/attack.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/components.cpp | 2 +- src/engine.cpp | 3 +++ src/player.cpp | 4 ++++ xml/entities.xml | 2 +- 9 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 include/attack.hpp create mode 100644 src/attack.cpp diff --git a/.gitignore b/.gitignore index d913368..a554d64 100644 --- a/.gitignore +++ b/.gitignore @@ -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 + +#include + +#include + +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, public entityx::Receiver { +private: + std::forward_list attacks; + +public: + explicit AttackSystem() = default; + + void configure(entityx::EventManager& ev) { + ev.subscribe(*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 +#include +#include +#include + +constexpr int shortSlashLength = 100; +constexpr int longSlashLength = 200; + +// math helpers because we don't trust stdlib +template +inline T abs(const T& n) { + static_assert(std::is_arithmetic::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( + [&a](entityx::Entity e, Position& pos, Solid& dim, Health& h) { + (void)e; + if (e.has_component()) + 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()->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()) { float width = entity.component()->width; auto& health = *entity.component(); - width /= health.health / health.maxHealth; + width *= health.health / static_cast(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 #include #include +#include Engine::Engine(void) : shouldRun(true), systems(game::entities, game::events) @@ -35,6 +36,7 @@ void Engine::init(void) { systems.add(); systems.add(); + systems.add(); systems.configure(); @@ -54,6 +56,7 @@ void Engine::update(entityx::TimeDelta dt) //systems.update(dt); // doesn't do anything systems.update(dt); systems.update(dt); + systems.update(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 #include #include +#include static const char *spriteXML = " \ @@ -70,6 +71,7 @@ static const char *animationXML = void PlayerSystem::create(void) { player = game::entities.create(); + player.assign(); player.assign(0.0f, 100.0f); player.assign(0.0f, 0.0f); //player.assign(-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(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 @@ - + -- cgit v1.2.3