invalidate();
}
+void Entity::kill(void) {
+ assign<Killed>();
+}
+
+
std::bitset<entityx::MAX_COMPONENTS> Entity::component_mask() const {
return manager_->component_mask(id_);
}
template <typename C, typename EM = EntityManager>
class ComponentHandle;
-
+struct Killed {};
/** A convenience handle around an Entity::Id.
*
std::bitset<entityx::MAX_COMPONENTS> component_mask() const;
+ void kill();
+
private:
EntityManager *manager_ = nullptr;
Entity::Id id_ = INVALID;
public:
template <typename T> struct identity { typedef T type; };
- void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f) {
+ void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f, bool dead = false) {
static std::mutex locked;
locked.lock();
- for (auto it : *this)
- f(it, *(it.template component<Components>().get())...);
+ for (auto it : *this) {
+ if (dead || !it.has_component<Killed>())
+ f(it, *(it.template component<Components>().get())...);
+ }
locked.unlock();
}
template <typename T> struct identity { typedef T type; };
template <typename ... Components>
- void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f) {
- return entities_with_components<Components...>().each(f);
+ void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f, bool dead = false) {
+ return entities_with_components<Components...>().each(f, dead);
}
/**
/**
* Constructor that sets the variables, with 0 health as default.
*/
- Health(int h = 0, int m = 0) : health(h), maxHealth(m) {}
+ Health(int m = 1, int h = 0)
+ : health(h != 0 ? h : m), maxHealth(m) {}
- int health;
- int maxHealth;
+ int health; /**< The current amount of health */
+ int maxHealth; /**< The maximum amount of health */
};
struct Portal {
// TODO initialX and range?
if (entity.has_component<Aggro>()) {
auto ppos = game::engine.getSystem<PlayerSystem>()->getPosition();
- if (ppos.x > position.x && ppos.x < position.x + entity.component<Solid>()->width)
- arena = entity.component<Aggro>()->arena;
- else
+ if (ppos.x > position.x && ppos.x < position.x + entity.component<Solid>()->width) {
+ auto& h = entity.component<Health>()->health;
+ if (h > 0) {
+ arena = entity.component<Aggro>()->arena;
+ h = 0;
+ }
+ } else
direction.x = (ppos.x > position.x) ? .05 : -.05;
} else if (entity.has_component<Wander>()) {
auto& countdown = entity.component<Wander>()->countdown;
glUniform1i(Render::worldShader.uniform[WU_texture], 0);
glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords);
- glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coord);
+ glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex_coord);
glDrawArrays(GL_TRIANGLES, 0, 6);
//glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
its-=.01;
}
glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
+
+ if (entity.has_component<Health>()) {
+ float width = entity.component<Solid>()->width;
+ auto& health = *entity.component<Health>();
+ width /= health.health / health.maxHealth;
+
+ GLfloat health_coord[] = {
+ pos.x, pos.y, -9, 0, 0,
+ pos.x + width, pos.y, -9, 0, 0,
+ pos.x + width, pos.y - 5, -9, 0, 0,
+ pos.x + width, pos.y - 5, -9, 0, 0,
+ pos.x, pos.y - 5, -9, 0, 0,
+ pos.x, pos.y, -9, 0, 0,
+ };
+
+ Colors::red.use();
+ glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), health_coord);
+ glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), health_coord + 3);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ }
});
Render::worldShader.disable();
player = game::entities.create();
player.assign<Position>(0.0f, 100.0f);
player.assign<Direction>(0.0f, 0.0f);
- // The new g value is a multiplier for the gravity constant. This allows for air resistance simulation.
//player.assign<Physics>(-0.001f);
player.assign<Physics>(1);
player.assign<Visible>(-0.2f);
+ player.assign<Health>(100);
auto sprite = player.assign<Sprite>();
XMLDocument xmld;
xmld.Parse(spriteXML);
#include <ui.hpp>
+#include <atomic>
+
+static std::atomic_bool doScreenshot;
+
void WindowSystem::receive(const ScreenshotEvent &scr)
{
- // Make the BYTE array, factor of 3 because it's RBG.
- static GLubyte* pixels;
- pixels = new GLubyte[ 3 * scr.w * scr.h];
- //glReadPixels(0, 0, scr.w, scr.h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
- for(int i = 0; i < (3 * scr.w * scr.h); i++) {
- pixels[i] = 255;
- }
-
- ui::takeScreenshot(pixels);
- std::cout << "Triggered\n";
+ (void)scr;
+ doScreenshot.store(true);
}
void WindowSystem::render(void)
{
+ if (doScreenshot.load()) {
+ doScreenshot.store(false);
+ // Make the BYTE array, factor of 3 because it's RBG.
+ static GLubyte* pixels;
+ int count = 3 * game::SCREEN_WIDTH * game::SCREEN_HEIGHT;
+ pixels = new GLubyte[count];
+ glReadPixels(0, 0, game::SCREEN_WIDTH, game::SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ //for(int i = 0; i < count; i++)
+ // pixels[i] = 255;
+ ui::takeScreenshot(pixels);
+ std::cout << "Triggered\n";
+ }
+
SDL_GL_SwapWindow(window);
}
// save dialog, if exists
if (entity.has_component<Dialog>())
save << "d " << entity.component<Dialog>()->index << ' ';
- });
+
+ if (entity.has_component<Health>())
+ save << "h " << entity.component<Health>()->health << ' ';
+ }, true);
save.close();
return true;
if (file.empty())
return;
+ // insert smiley face showing teeth as if we're doing something bad
+ save();
+
// load file data to string
auto xmlPath = xmlFolder + file;
auto xmlRaw = readFile(xmlPath);
entity.assign<Wander>();
} else if (tname == "Hop" ) {
entity.assign<Hop>();
+ } else if (tname == "Health") {
+ entity.assign<Health>();
} else if (tname == "Aggro" ) {
entity.assign<Aggro>(abcd->Attribute("arena"));
} else if (tname == "Animation") {
save >> pos->x >> pos->y;
save >> id;
- while (id != 'p') {
+ while (!save.eof() && id != 'p') {
switch (id) {
case 'd':
save >> entity.component<Dialog>()->index;
break;
+ case 'h':
+ save >> entity.component<Health>()->health;
+ break;
}
save >> id;
void WorldSystem::detect(entityx::TimeDelta dt)
{
+ game::entities.each<Health>(
+ [](entityx::Entity e, Health& h) {
+ if (h.health <= 0)
+ e.kill();
+ //e.destroy();
+ });
+
game::entities.each<Grounded, Position, Solid>(
[&](entityx::Entity e, Grounded &g, Position &loc, Solid &dim) {
(void)e;
</frame>
</Sprite>
<Direction />
+ <Health />
<Solid />
<Physics />
<Name value="SKIRL" />