#include "gameplay/gameactor.h" #include "gameplay/entity.h" #include "gameplay/physics.h" #include "gameplay/weapons/weapon.h" #include "utility/events.h" #include "utility/direction.h" #include "utility/component.h" GameActor::~GameActor() { } void GameActor::addComponent(std::shared_ptr component) { component->ownerid = entityid; components.push_back(component); } const std::optional> GameActor::getHeldWeapon() const { return (weapons.empty() || currentWeaponIndex >= weapons.size()) ? std::nullopt : std::make_optional(weapons[currentWeaponIndex]); } void GameActor::pickupWeapon(std::shared_ptr weapon) { weapon->setWielder(std::shared_ptr(this)); weapons.push_back(weapon); // wield the newly picked up weapon. getHeldWeapon().value()->putaway(); currentWeaponIndex = weapons.size() - 1; getHeldWeapon().value()->wield(); } void GameActor::hookEventManager(std::shared_ptr eventManager) { this->eventManager = eventManager; for (auto& weapon : weapons) weapon->hookEventManager(eventManager); } void GameActor::setRotation(const float& rotation) { if (!isRotatable && eventManager) { Direction newDir = getDirectionFromRotation(rotation); if (getDirectionFromRotation(this->rotation) != newDir) eventManager->notify(std::make_shared(entityid, newDir)); } this->rotation = rotation; updateModelMatrix(); } void GameActor::update(float deltaTime) { Entity::update(deltaTime); for (auto& component : components) component->update(); for (auto& weapon : weapons) weapon->update(deltaTime); if (eventManager) { if (isMoving && !wasMoving) { eventManager->notify(std::make_shared(entityid)); wasMoving = true; } else if (!isMoving && wasMoving) { eventManager->notify(std::make_shared(entityid)); wasMoving = false; } } isMoving = false; } void GameActor::render(const std::shared_ptr& camera) { Entity::render(camera); // regular loop through components, but if the component returns true to kill, we erase it. // Components are always assumed to be smart pointers! for (auto& component : components) { component->bind(); component->render(); } for (auto& weapon : weapons) weapon->render(camera); } void GameActor::moveUp() { if (physics) physics->rigidBody.applyForce(glm::vec3( 0.f,-1.f, 0.f), 1500.25f); isMoving = true; } void GameActor::moveDown() { if (physics) physics->rigidBody.applyForce(glm::vec3( 0.f, 1.f, 0.f), 1500.25f); isMoving = true; } void GameActor::moveLeft() { if (physics) physics->rigidBody.applyForce(glm::vec3(-1.f, 0.f, 0.f), 1500.25f); isMoving = true; } void GameActor::moveRight(){ if (physics) physics->rigidBody.applyForce(glm::vec3( 1.f, 0.f, 0.f), 1500.25f); isMoving = true; } // top-down shooter mode controls void GameActor::fireWeapon()const { if (auto& weapon = getHeldWeapon()) weapon.value()->shoot(); } void GameActor::cycleUpWeapons() { if (!weapons.empty()) { weapons[currentWeaponIndex]->putaway(); currentWeaponIndex = (currentWeaponIndex + 1) % weapons.size(); weapons[currentWeaponIndex]->wield(); } } void GameActor::cycleDownWeapons() { if (!weapons.empty()) { weapons[currentWeaponIndex]->putaway(); currentWeaponIndex = (currentWeaponIndex + weapons.size() - 1) % weapons.size(); weapons[currentWeaponIndex]->wield(); } } void GameActor::cycleWeapons(const MouseState& mouse_state) { if (mouse_state.scroll < 0) cycleUpWeapons(); else if (mouse_state.scroll > 0) cycleDownWeapons(); } void GameActor::followMouse(const MouseState& mouse_state) { glm::vec2 direction = glm::vec2(mouse_state.x, mouse_state.y) - glm::vec2(localPosition.x + 0.5f * scale.x, localPosition.y + 0.5f * scale.y); float newRotation = glm::degrees(glm::atan(direction.y, direction.x)); if (getDirectionFromRotation(rotation) != getDirectionFromRotation(newRotation)) if (eventManager) eventManager->notify(std::make_shared(entityid, getDirectionFromRotation(newRotation))); //setRotation(glm::degrees(glm::atan(direction.y, direction.x))); this->rotation = newRotation; } void GameActor::strafeLeft() { position.x += sin(glm::radians(rotation)) * speed; position.y -= cos(glm::radians(rotation)) * speed; } void GameActor::strafeRight() { position.x -= sin(glm::radians(rotation)) * speed; position.y += cos(glm::radians(rotation)) * speed; } void GameActor::moveBackward() { position.x -= cos(glm::radians(rotation)) * speed; position.y -= sin(glm::radians(rotation)) * speed; } void GameActor::moveForward() { if (physics) { physics->rigidBody.velocity.x += cos(glm::radians(rotation)) * speed; physics->rigidBody.velocity.y += sin(glm::radians(rotation)) * speed; } isMoving = true; }