#include <player.hpp> #include <brice.hpp> #include <ui.hpp> #include <gametime.hpp> #include <world.hpp> #include <particle.hpp> #include <attack.hpp> static const char *spriteXML = "<Sprite> \ <frame> \ <src limb='0' offset='0,0' size='15,16' drawOffset='0,9'>assets/player/player.png</src> \ <src limb='1' offset='0,16' size='13,12' drawOffset='0,20'>assets/player/player.png</src>\ <src limb='2' offset='15,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ <src limb='3' offset='15,14' size='15,13' drawOffset='0,9'>assets/player/player.png</src>\ </frame> \ </Sprite>"; static const char *animationXML = "<Animation>\ <movement>\ <limb update='60.0' id='2'>\ <frame>\ <src offset='15,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='29,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='43,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='57,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='71,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='85,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='99,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='113,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='127,0' size='14,11' drawOffset='1,0'>assets/player/player.png</src>\ </frame>\ </limb>\ </movement>\ <movement>\ <limb update='250.0' id='3'>\ <frame>\ <src offset='15,14' size='15,13' drawOffset='0,9'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='32,14' size='14,13' drawOffset='0,9'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='50,14' size='14,13' drawOffset='0,9'>assets/player/player.png</src>\ </frame>\ <frame>\ <src offset='68,14' size='17,13' drawOffset='-1,9'>assets/player/player.png</src>\ </frame>\ </limb>\ </movement>\ </Animation>"; 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); player.assign<Physics>(); player.assign<Visible>(-0.2f); player.assign<Health>(100); auto sprite = player.assign<Sprite>(); XMLDocument xmld; xmld.Parse(spriteXML); auto frame = developFrame(xmld.FirstChildElement("Sprite")); if (frame.size() > 0) sprite->sprite = frame.at(0); vec2 dim = player.component<Sprite>().get()->getSpriteSize(); float cdat[2] = {dim.x, dim.y}; player.assign<Solid>(cdat[0], cdat[1]); // handle player animation xmld.Parse(animationXML); player.assign<Animate>(nullptr, xmld.FirstChildElement()); } void PlayerSystem::configure(entityx::EventManager &ev) { ev.subscribe<KeyUpEvent>(*this); ev.subscribe<KeyDownEvent>(*this); ev.subscribe<UseItemEvent>(*this); } void PlayerSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) { (void)en; (void)ev; (void)dt; if (player.component<Health>()->health <= 0) abort(); auto& vel = *player.component<Direction>().get(); if (moveLeft & !moveRight) vel.x = -PLAYER_SPEED_CONSTANT; else if (!moveLeft & moveRight) vel.x = PLAYER_SPEED_CONSTANT; else vel.x = 0; vel.x *= speed; if (std::stoi(game::getValue("Slow")) == 1) vel.x /= 2.0f; } void PlayerSystem::receive(const KeyUpEvent &kue) { auto kc = kue.keycode; if (kc == getControl(1)) { moveLeft = false; } else if (kc == getControl(2)) { moveRight = false; } else if (kc == getControl(3) || kc == getControl(4)) { speed = 1.0f; } else if (kc == getControl(5)) { /*if (p->inv->invHover) { p->inv->invHover = false; } else { if (!p->inv->selected) p->inv->invOpening ^= true; else p->inv->selected = false; p->inv->mouseSel = false; }*/ } } void PlayerSystem::receive(const KeyDownEvent &kde) { auto kc = kde.keycode; auto& loc = *player.component<Position>().get(); auto& vel = *player.component<Direction>().get(); if ((kc == SDLK_SPACE) && game::canJump && ((vel.y > -0.01) & (vel.y < 0.01))) { loc.y += HLINES(2); vel.y = 0.05f; vel.grounded = false; } else if (!UISystem::isDialog()) { if (kc == getControl(0)) { if (!UISystem::isFading()) WorldSystem::goWorldPortal(loc); } else if (kc == getControl(1)) { if (!UISystem::isFading()) { moveLeft = true; moveRight = false; WorldSystem::goWorldLeft(loc); } } else if (kc == getControl(2)) { if (!UISystem::isFading()) { moveLeft = false; moveRight = true; WorldSystem::goWorldRight(loc, *player.component<Solid>().get()); } } else if (kc == getControl(3)) { if (game::canSprint) speed = 2.0f; game::engine.getSystem<ParticleSystem>()->addMultiple(10, ParticleType::SmallBlast, [&](){ return vec2(loc.x, loc.y); }, 500, 7); } else if (kc == getControl(4)) { speed = .5; } else if (kc == getControl(5)) { //static int heyOhLetsGo = 0; //edown = true; // start hover counter? //if (!heyOhLetsGo) { // heyOhLetsGo = game::time::getTickCount(); // p->inv->mouseSel = false; //} // run hover thing //if (game::time::getTickCount() - heyOhLetsGo >= 2 && !(p->inv->invOpen) && !(p->inv->selected)) // p->inv->invHover = true; } } else if (kc == SDLK_DELETE) { game::endGame(); } else if (kc == SDLK_t) { game::time::tick(50); } } vec2 PlayerSystem::getPosition(void) const { auto& loc = *game::entities.component<Position>(player.id()).get(); return vec2(loc.x, loc.y); } void PlayerSystem::receive(const UseItemEvent& uie) { static std::atomic_bool cool (true); if (cool.load()) { if (uie.item->sound != nullptr) Mix_PlayChannel(0, uie.item->sound, 0); if (uie.item->type == "Sword") { auto loc = getPosition(); auto &solid = *player.component<Solid>().get(); loc.x += solid.width / 2, loc.y += solid.height / 2; game::events.emit<AttackEvent>(loc, AttackType::ShortSlash, true); } else if (uie.item->type == "Bow") { if (game::engine.getSystem<InventorySystem>()->take("Arrow", 1)) { auto e = game::entities.create(); auto pos = getPosition(); e.assign<Position>(pos.x, pos.y + 10); auto angle = std::atan2(uie.curs.y - pos.y, uie.curs.x - pos.x); e.assign<Direction>(0.25f * std::cos(angle), 0.25f * std::sin(angle)); e.assign<Visible>(-5); e.assign<Physics>(); auto sprite = e.assign<Sprite>(); auto tex = game::engine.getSystem<InventorySystem>()->getItem("Arrow"); sprite->addSpriteSegment(SpriteData(tex.sprite), 0); auto dim = HLINES(sprite->getSpriteSize()); e.assign<Solid>(dim.x, dim.y); e.assign<Hit>(10, false); } } cool.store(false); std::thread([&](unsigned int ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); cool.store(true); }, uie.item->cooldown).detach(); } }