137 lines
4.7 KiB
C++
137 lines
4.7 KiB
C++
#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)
|
|
{
|
|
component->ownerid = entityid;
|
|
components.push_back(component);
|
|
}
|
|
|
|
const std::optional<std::shared_ptr<Weapon>> GameActor::getHeldWeapon() const
|
|
{
|
|
return (weapons.empty() || currentWeaponIndex >= weapons.size()) ? std::nullopt : std::make_optional(weapons[currentWeaponIndex]);
|
|
}
|
|
|
|
void GameActor::pickupWeapon(std::shared_ptr<Weapon> weapon)
|
|
{
|
|
weapon->setWielder(std::shared_ptr<GameActor>(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> 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<DirectionChangeEvent>(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<EntityMoveEvent>(entityid));
|
|
wasMoving = true;
|
|
}
|
|
else if (!isMoving && wasMoving)
|
|
{
|
|
eventManager->notify(std::make_shared<EntityStopEvent>(entityid));
|
|
wasMoving = false;
|
|
}
|
|
}
|
|
isMoving = false;
|
|
}
|
|
|
|
void GameActor::render(const std::shared_ptr<Camera>& 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<DirectionChangeEvent>(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;
|
|
}
|