Removed overuse of polymorphisim

This commit is contained in:
Ethan 2025-03-31 17:23:33 -04:00
parent 1b6f5cff5b
commit dccd19ac80
19 changed files with 5766 additions and 154 deletions

Binary file not shown.

Binary file not shown.

View file

@ -35,6 +35,7 @@ add_executable (YuppleMayham
"src/thirdparty/glad.c" "src/thirdparty/glad.c"
"src/sound/engine.cpp" "src/sound/engine.cpp"
"src/sound/audiostream.cpp" "src/sound/audiostream.cpp"
"src/sound/soundeffect.cpp"
"include/thirdparty/stb_vorbis.c" "include/thirdparty/stb_vorbis.c"
"src/utility/data/font_data.c" "src/utility/data/font_data.c"
"src/utility/ftfont.cpp" "src/utility/ftfont.cpp"
@ -102,6 +103,6 @@ endif()
target_include_directories(YuppleMayham PRIVATE "${PROJECT_SOURCE_DIR}/YuppleMayham/include" ${LuaJIT_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIR_ft2build}) target_include_directories(YuppleMayham PRIVATE "${PROJECT_SOURCE_DIR}/YuppleMayham/include" ${LuaJIT_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIR_ft2build})
target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image openal glm::glm-header-only sol2 tinyxml2 freetype ${LuaJIT_LINK_LIBRARIES}) target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image openal glm::glm-header-only tinyxml2 freetype ${LuaJIT_LINK_LIBRARIES})
# TODO: Add tests and install targets if needed. # TODO: Add tests and install targets if needed.

View file

@ -42,6 +42,8 @@ public:
void update(double deltaTime); void update(double deltaTime);
void draw(); void draw();
const std::string getType() const { return weaponType; }
struct BulletData { struct BulletData {
glm::vec3 origin; glm::vec3 origin;
glm::vec2 direction; glm::vec2 direction;
@ -70,6 +72,8 @@ public:
private: private:
void adjustWeapon(); void adjustWeapon();
std::string weaponType;
glm::vec2 weaponSize; glm::vec2 weaponSize;
glm::vec2 weaponOffset; glm::vec2 weaponOffset;
// TODO: Add reloading // TODO: Add reloading

View file

@ -5,6 +5,7 @@
#include "thirdparty/stb_vorbis.c" #include "thirdparty/stb_vorbis.c"
#include "utility/logger.h" #include "utility/logger.h"
#include "util.h"
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
@ -13,11 +14,6 @@
#include <mutex> #include <mutex>
#include <thread> #include <thread>
namespace AUDIO {
constexpr size_t CHUNK_SIZE = 4096;
constexpr int SAMPLE_RATE = 44100;
}
class AudioStream class AudioStream
{ {
public: public:

View file

@ -0,0 +1,38 @@
/* Resource manager is going to hold a list of soundeffects for each item and the state that item is in.
* ie. A shotgun is reloading, so the shotgun is the item, and the state (reloading) has a list of different reloading sounds
* this is so we don't have annoying repeats.
*
* The sound engine is going to handle global events that are passed from these objects which will contain their entity ID
* and event specific information, such as event location and in special cases the type of item that is triggering the event
* such as my shotgun has fired so I will have my audio engine look through a list of shotgun firing sound effects to play,
* Once the engine knows what sound to play, it will look for the next available source, load the buffer onto that source and play.
* Every frame the engine is responsible for checking every source and pull off buffers that are no longer in use
*/
#ifndef _H_SOUNDEFFECT_H
#define _H_SOUNDEFFECT_H
#define STB_VORBIS_HEADER_ONLY
#include "thirdparty/stb_vorbis.c"
#include "utility/logger.h"
#include "util.h"
#include <AL/al.h>
#include <string>
class SoundEffect
{
public:
SoundEffect(const std::string& filename);
~SoundEffect();
private:
bool loadFile(const std::string &filename);
ALuint buffer;
};
#endif // _H_SOUNDEFFECT_H

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,11 @@
namespace UTIL namespace UTIL
{ {
namespace AUDIO {
constexpr size_t CHUNK_SIZE = 4096;
constexpr int SAMPLE_RATE = 44100;
}
constexpr float INF_TIME = -99.6875f; constexpr float INF_TIME = -99.6875f;
void flip_surface(SDL_Surface* surface); void flip_surface(SDL_Surface* surface);

View file

@ -2,6 +2,7 @@
#define _H_EVENTS_H #define _H_EVENTS_H
#include <string> #include <string>
#include <typeindex>
#include <memory> #include <memory>
#include <functional> #include <functional>
#include <unordered_map> #include <unordered_map>
@ -12,124 +13,91 @@
class Bullet; class Bullet;
struct PhysicsComponent; struct PhysicsComponent;
class Event { struct BulletFiredEvent {
public: std::weak_ptr<Bullet> bullet;
virtual ~Event() { };
virtual std::string getType() const = 0;
}; };
class BulletFiredEvent : public Event { struct BulletDiedEvent {
public:
BulletFiredEvent(const std::shared_ptr<Bullet>& bullet) : bullet(bullet) {};
std::string getType() const override { return "OnBulletFired"; }
std::shared_ptr<Bullet> bullet;
};
class BulletDiedEvent : public Event {
public:
BulletDiedEvent(const std::shared_ptr<PhysicsComponent>& physObj) : physObj(physObj) {};
std::string getType() const override { return "OnBulletDied"; }
std::shared_ptr<PhysicsComponent> physObj; std::shared_ptr<PhysicsComponent> physObj;
}; };
class BulletCollideEvent : public Event { struct BulletCollideEvent {
public:
BulletCollideEvent(const unsigned int ownerID, const unsigned int victimID, const std::shared_ptr<PhysicsComponent>& bullet, const glm::vec2& normal)
: ownerID(ownerID), victimID(victimID), bullet(bullet), normal(normal){}
std::string getType() const override { return "OnBulletCollide"; }
unsigned int ownerID; unsigned int ownerID;
unsigned int victimID; unsigned int victimID;
std::shared_ptr<PhysicsComponent> bullet; std::shared_ptr<PhysicsComponent> bullet;
glm::vec2 normal; glm::vec2 normal;
}; };
class DirectionChangeEvent : public Event { struct DirectionChangeEvent {
public: int entityid;
DirectionChangeEvent(const int entityid, Direction direction) : direction(direction), entityid(entityid) {}
std::string getType() const override { return "OnDirectionChange"; }
Direction direction; Direction direction;
};
struct EntityMoveEvent {
int entityid; int entityid;
}; };
class EntityMoveEvent : public Event { struct EntityStopEvent {
public:
EntityMoveEvent(const int entityid) : entityid(entityid) {}
std::string getType() const override { return "OnEntityMove"; }
int entityid; int entityid;
}; };
class EntityStopEvent : public Event { struct EntityReloadEvent {
public: int entityid;
EntityStopEvent(const int entityid) : entityid(entityid) {} glm::vec3 position;
std::string getType() const override { return "OnEntityStop"; } std::string weaponType;
};
struct EntityFinishReloadEvent {
int entityid; int entityid;
}; };
class EntityReloadEvent : public Event { struct EntityFireEvent {
public:
EntityReloadEvent(const int entityid) : entityid(entityid) {}
std::string getType() const override { return "OnEntityReload"; }
int entityid;
};
class EntityFinishReloadEvent : public Event {
public:
EntityFinishReloadEvent(const int entityid) : entityid(entityid) {}
std::string getType() const override { return "OnEntityFinishReload"; }
int entityid;
};
class EntityFireEvent : public Event {
public:
EntityFireEvent(const int entityid, const float fireDelay) : entityid(entityid), fireDelay(fireDelay) {}
std::string getType() const override { return "OnEntityFire"; }
int entityid; int entityid;
float fireDelay; float fireDelay;
glm::vec3 firePosition;
std::string weaponType;
}; };
class AnimationFinishedEvent : public Event { struct AnimationFinishedEvent {
public:
AnimationFinishedEvent(const int entityid, const std::string animType) : animType(animType), entityid(entityid) {}
std::string getType() const override { return "OnAnimationFinished"; }
std::string animType;
int entityid; int entityid;
std::string animType;
}; };
class ScreenShakeEvent : public Event { struct ScreenShakeEvent {
public:
ScreenShakeEvent(float intensity, float duration) : intensity(intensity), duration(duration) {}
std::string getType() const override { return "OnScreenShake"; }
float intensity; float intensity;
float duration; float duration;
}; };
class ScreenBlurEvent : public Event { struct ScreenBlurEvent {
public:
ScreenBlurEvent(float intensity, float duration) : intensity(intensity), duration(duration) {}
std::string getType() const override { return "OnScreenBlur"; }
float intensity; float intensity;
float duration; float duration;
}; };
class EventManager { class EventManager {
public: public:
using EventCallback = std::function<void(std::shared_ptr<Event>)>; template <typename T>
using EventCallback = std::function<void(const T&)>;
void subscribe(std::string eventType, EventCallback callback) { template <typename T>
listeners[eventType].push_back(callback); void subscribe(EventCallback<T> cb) {
auto wrapper = [cb](void *ev) {
cb(*static_cast<T*>(ev));
};
callbacks[typeid(T)].push_back(wrapper);
} }
void notify(const std::shared_ptr<Event>& event) { template <typename T>
auto iterator = listeners.find(event->getType()); void notify(const T& event) {
if (iterator != listeners.end()) auto iterator = callbacks.find(typeid(T));
if (iterator != callbacks.end())
{ {
for (auto& callback : iterator->second) for (auto& cb : iterator->second)
{ {
callback(event); cb((void*)&event);
} }
} }
} }
private: private:
std::unordered_map <std::string, std::vector <EventCallback>> listeners; std::unordered_map <std::type_index, std::vector <std::function<void(void*)>>> callbacks;
}; };
#endif //_H_EVENTS_H #endif //_H_EVENTS_H

View file

@ -40,7 +40,7 @@ void GameActor::setRotation(const float& rotation)
if (auto eventManager = sceneContext->getEventManager().lock()) { if (auto eventManager = sceneContext->getEventManager().lock()) {
Direction newDir = getDirectionFromRotation(rotation); Direction newDir = getDirectionFromRotation(rotation);
if (getDirectionFromRotation(this->rotation) != newDir) if (getDirectionFromRotation(this->rotation) != newDir)
eventManager->notify(std::make_shared<DirectionChangeEvent>(entityid, newDir)); eventManager->notify<DirectionChangeEvent>((DirectionChangeEvent){ entityid, newDir });
} }
} }
this->rotation = rotation; this->rotation = rotation;
@ -59,14 +59,14 @@ void GameActor::update(double deltaTime)
if (isMoving && !wasMoving) if (isMoving && !wasMoving)
{ {
if (auto event = sceneContext->getEventManager().lock()) { if (auto event = sceneContext->getEventManager().lock()) {
event->notify(std::make_shared<EntityMoveEvent>(entityid)); event->notify<EntityMoveEvent>((EntityMoveEvent){ entityid });
} }
wasMoving = true; wasMoving = true;
} }
else if (!isMoving && wasMoving) else if (!isMoving && wasMoving)
{ {
if (auto event = sceneContext->getEventManager().lock()) { if (auto event = sceneContext->getEventManager().lock()) {
event->notify(std::make_shared<EntityStopEvent>(entityid)); event->notify<EntityStopEvent>((EntityStopEvent){ entityid });
} }
wasMoving = false; wasMoving = false;
} }
@ -99,8 +99,8 @@ void GameActor::fireWeapon()const {
if (weapon->shoot()) { if (weapon->shoot()) {
if (sceneContext->getPlayerID() == entityid) { if (sceneContext->getPlayerID() == entityid) {
if (auto gEvent = sceneContext->getGlobalEventManager().lock()) { if (auto gEvent = sceneContext->getGlobalEventManager().lock()) {
gEvent->notify(std::make_shared<ScreenShakeEvent>(0.01f, 0.8f)); gEvent->notify<ScreenShakeEvent>((ScreenShakeEvent){0.01f, 0.8f});
gEvent->notify(std::make_shared<ScreenBlurEvent>(1.f, 0.8f)); gEvent->notify<ScreenBlurEvent>((ScreenBlurEvent){1.f, 0.8f});
} }
} }
} }
@ -134,7 +134,7 @@ void GameActor::followMouse(const MouseState& mouse_state)
float newRotation = glm::degrees(glm::atan(direction.y, direction.x)); float newRotation = glm::degrees(glm::atan(direction.y, direction.x));
if (getDirectionFromRotation(rotation) != getDirectionFromRotation(newRotation)) { if (getDirectionFromRotation(rotation) != getDirectionFromRotation(newRotation)) {
if (auto event = sceneContext->getEventManager().lock()) { if (auto event = sceneContext->getEventManager().lock()) {
event->notify(std::make_shared<DirectionChangeEvent>(entityid, getDirectionFromRotation(newRotation))); event->notify<DirectionChangeEvent>((DirectionChangeEvent){ entityid, getDirectionFromRotation(newRotation) });
} }
} }
//setRotation(glm::degrees(glm::atan(direction.y, direction.x))); //setRotation(glm::degrees(glm::atan(direction.y, direction.x)));

View file

@ -4,18 +4,16 @@
#include "utility/logger.h" #include "utility/logger.h"
#include <iostream>
void PhysicsEngine::hookEventManager(const std::shared_ptr<EventManager>& eventManager) void PhysicsEngine::hookEventManager(const std::shared_ptr<EventManager>& eventManager)
{ {
this->eventManager = eventManager; this->eventManager = eventManager;
this->eventManager->subscribe("OnBulletFired", [this](std::shared_ptr<Event> e) { this->eventManager->subscribe<BulletFiredEvent>([this](const BulletFiredEvent& event) {
auto bulletEvent = std::static_pointer_cast<BulletFiredEvent>(e); if (auto bullet = event.bullet.lock()) {
this->addObject(bulletEvent->bullet->getPhysicsComponent()); this->addObject(bullet->getPhysicsComponent());
}
}); });
this->eventManager->subscribe("OnBulletDied", [this](std::shared_ptr<Event> e) { this->eventManager->subscribe<BulletDiedEvent>([this](const BulletDiedEvent& event) {
auto bulletEvent = std::static_pointer_cast<BulletDiedEvent>(e); this->removeObject(event.physObj);
this->removeObject(bulletEvent->physObj);
}); });
} }

View file

@ -214,14 +214,13 @@ void Scene::unloadScene()
void Scene::hookSceneEvents() void Scene::hookSceneEvents()
{ {
std::weak_ptr<Scene> weakSelf = shared_from_this(); std::weak_ptr<Scene> weakSelf = shared_from_this();
eventManager->subscribe("OnBulletCollide", [weakSelf](std::shared_ptr<Event> e) { eventManager->subscribe<BulletCollideEvent>([weakSelf](const BulletCollideEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto collideEvent = std::static_pointer_cast<BulletCollideEvent>(e); GameActor* shooter = self->getGameActorByID(e.ownerID);
GameActor* shooter = self->getGameActorByID(collideEvent->ownerID); GameActor* target = self->getGameActorByID(e.victimID);
GameActor* target = self->getGameActorByID(collideEvent->victimID);
if (shooter && target) if (shooter && target)
if (auto& weapon = shooter->getHeldWeapon()) if (auto& weapon = shooter->getHeldWeapon())
weapon->onHitCallback(target, collideEvent->bullet.get(), collideEvent->normal); weapon->onHitCallback(target, e.bullet.get(), e.normal);
} }
}); });
} }

View file

@ -14,11 +14,10 @@ void BulletManager::hookEventManager(std::weak_ptr<EventManager> eventManager)
this->eventManager = eventManager; this->eventManager = eventManager;
if (auto event = this->eventManager.lock()) { if (auto event = this->eventManager.lock()) {
std::weak_ptr<BulletManager> weakSelf = shared_from_this(); std::weak_ptr<BulletManager> weakSelf = shared_from_this();
event->subscribe("OnBulletDied", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<BulletDiedEvent>([weakSelf](const BulletDiedEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto bulletEvent = std::static_pointer_cast<BulletDiedEvent>(e);
auto iterator = std::find_if(self->bullets.begin(), self->bullets.end(), [&](std::shared_ptr<Bullet> bullet) { auto iterator = std::find_if(self->bullets.begin(), self->bullets.end(), [&](std::shared_ptr<Bullet> bullet) {
return bullet->getPhysicsComponent() == bulletEvent->physObj; return bullet->getPhysicsComponent() == e.physObj;
}); });
if (iterator != self->bullets.end()) if (iterator != self->bullets.end())
self->bullets.erase(iterator); self->bullets.erase(iterator);
@ -57,7 +56,7 @@ void BulletManager::update(double deltaTime)
if (distance > bullet->getBulletDrop() || glm::length(bullet->getPhysicsComponent()->rigidBody.velocity) < 100.0f) if (distance > bullet->getBulletDrop() || glm::length(bullet->getPhysicsComponent()->rigidBody.velocity) < 100.0f)
{ {
if (auto event = eventManager.lock()) if (auto event = eventManager.lock())
event->notify(std::make_shared<BulletDiedEvent>(bullet->getPhysicsComponent())); event->notify<BulletDiedEvent>((BulletDiedEvent){ bullet->getPhysicsComponent() });
//bullets.erase(std::remove(bullets.begin(), bullets.end(), bullet)); //bullets.erase(std::remove(bullets.begin(), bullets.end(), bullet));
} }
} }

View file

@ -17,6 +17,7 @@
Weapon::Weapon(std::shared_ptr<WeaponData> data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager) Weapon::Weapon(std::shared_ptr<WeaponData> data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager)
: :
Entity (weaponShaderID), Entity (weaponShaderID),
weaponType (data->name),
weaponSize (glm::vec2(data->sizeX, data->sizeY)), weaponSize (glm::vec2(data->sizeX, data->sizeY)),
weaponOffset (glm::vec2(data->offsetX, data->offsetY)), weaponOffset (glm::vec2(data->offsetX, data->offsetY)),
weaponMag (data->clipSize), weaponMag (data->clipSize),
@ -51,10 +52,9 @@ void Weapon::addComponent(std::unique_ptr<Component> comp) {
void Weapon::reload() void Weapon::reload()
{ {
// TODO: Create reload event that will be captured by the gun animation set, to start the reloading animation
if (auto event = eventManager.lock()) if (auto event = eventManager.lock())
{ {
event->notify(std::make_shared<EntityReloadEvent>(entityid)); event->notify<EntityReloadEvent>((EntityReloadEvent){ entityid, wielder->getPosition(), weaponType });
reloading = true; reloading = true;
if (weaponAmmo < weaponMagSize) { if (weaponAmmo < weaponMagSize) {
weaponMag = weaponAmmo; weaponMag = weaponAmmo;
@ -79,7 +79,7 @@ bool Weapon::shoot()
{ {
shotsFired = true; shotsFired = true;
if (auto event = eventManager.lock()) if (auto event = eventManager.lock())
event->notify(std::make_shared<EntityFireEvent>(entityid, fireSpeed)); event->notify<EntityFireEvent>((EntityFireEvent){entityid, fireSpeed, wielder->getPosition(), weaponType});
if (!weaponScript || !weaponScript->lua["onShoot"].valid()) if (!weaponScript || !weaponScript->lua["onShoot"].valid())
{ {
// create bullet using this generated data // create bullet using this generated data
@ -120,10 +120,9 @@ void Weapon::hookEventManager(std::weak_ptr<EventManager> eventManager)
if (auto event = this->eventManager.lock()) { if (auto event = this->eventManager.lock()) {
std::weak_ptr<Weapon> selfWeak = shared_from_this(); std::weak_ptr<Weapon> selfWeak = shared_from_this();
event->subscribe("OnAnimationFinished", [selfWeak](std::shared_ptr<Event> e) { event->subscribe<AnimationFinishedEvent>([selfWeak](const AnimationFinishedEvent& e) {
if (auto self = selfWeak.lock()) { if (auto self = selfWeak.lock()) {
auto animFinished = std::static_pointer_cast<AnimationFinishedEvent>(e); if (e.entityid == self->entityid && e.animType == "reload")
if (animFinished->entityid == self->entityid && animFinished->animType == "reload")
{ {
if (self->reloading) if (self->reloading)
{ {
@ -173,7 +172,7 @@ void Weapon::update(double deltaTime)
{ {
wasReloading = false; wasReloading = false;
if (auto event = eventManager.lock()) { if (auto event = eventManager.lock()) {
event->notify(std::make_shared<EntityFinishReloadEvent>(entityid)); event->notify<EntityFinishReloadEvent>((EntityFinishReloadEvent){entityid});
} }
} }
} }
@ -259,7 +258,7 @@ void Weapon::createBullet(const Weapon::BulletData& data)
bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * data.direction / data.mass; bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * data.direction / data.mass;
if (auto event = eventManager.lock()) if (auto event = eventManager.lock())
event->notify(std::make_shared<BulletFiredEvent>(bullet)); event->notify<BulletFiredEvent>((BulletFiredEvent){bullet});
bulletManager->addBullet(bullet); bulletManager->addBullet(bullet);
} }

View file

@ -109,18 +109,18 @@ void AnimationSet::attachEventManager(std::weak_ptr<EventManager> e)
if (auto event = eventManager.lock()) { if (auto event = eventManager.lock()) {
std::weak_ptr<AnimationSet> weakSelf = shared_from_this(); std::weak_ptr<AnimationSet> weakSelf = shared_from_this();
event->subscribe("OnDirectionChange", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<DirectionChangeEvent>([weakSelf](const DirectionChangeEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto directionEvent = std::static_pointer_cast<DirectionChangeEvent>(e); if (e.entityid == self->entityid) {
if (directionEvent->entityid == self->entityid) Direction d = e.direction;
self->setFacingDir(directionEvent->direction); self->setFacingDir(d);
}
} }
}); });
event->subscribe("OnEntityMove", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<EntityMoveEvent>([weakSelf](const EntityMoveEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto moveEvent = std::static_pointer_cast<EntityMoveEvent>(e); if (e.entityid == self->entityid)
if (moveEvent->entityid == self->entityid)
{ {
if (self->isDirectional) if (self->isDirectional)
{ {
@ -133,10 +133,9 @@ void AnimationSet::attachEventManager(std::weak_ptr<EventManager> e)
} }
}); });
event->subscribe("OnEntityStop", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<EntityStopEvent>([weakSelf](const EntityStopEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto stopEvent = std::static_pointer_cast<EntityStopEvent>(e); if (e.entityid == self->entityid)
if (stopEvent->entityid == self->entityid)
{ {
if (self->isDirectional) if (self->isDirectional)
{ {
@ -149,24 +148,22 @@ void AnimationSet::attachEventManager(std::weak_ptr<EventManager> e)
} }
}); });
event->subscribe("OnEntityReload", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<EntityReloadEvent>([weakSelf](const EntityReloadEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto reloadEvent = std::static_pointer_cast<EntityReloadEvent>(e); if (e.entityid == self->entityid)
if (reloadEvent->entityid == self->entityid)
{ {
if (self->anims["reload"] != NULL) if (self->anims["reload"] != NULL)
{ {
self->curAnim = self->anims["reload"].get();
self->curAnim->reset(); self->curAnim->reset();
self->curAnim = self->anims["reload"].get();
} }
} }
} }
}); });
event->subscribe("OnEntityFinishReload", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<EntityFinishReloadEvent>([weakSelf](const EntityFinishReloadEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto reloadEvent = std::static_pointer_cast<EntityFinishReloadEvent>(e); if (e.entityid == self->entityid)
if (reloadEvent->entityid == self->entityid)
{ {
if (self->anims["idle"] != NULL) if (self->anims["idle"] != NULL)
self->curAnim = self->anims["idle"].get(); self->curAnim = self->anims["idle"].get();
@ -174,26 +171,24 @@ void AnimationSet::attachEventManager(std::weak_ptr<EventManager> e)
} }
}); });
event->subscribe("OnEntityFire", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<EntityFireEvent>([weakSelf](const EntityFireEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto fireEvent = std::static_pointer_cast<EntityFireEvent>(e); if (e.entityid == self->entityid)
if (fireEvent->entityid == self->entityid)
{ {
if (self->anims["fire"] != NULL) if (self->anims["fire"] != NULL)
{ {
self->curAnim = self->anims["fire"].get(); self->curAnim = self->anims["fire"].get();
self->curAnim->reset(); self->curAnim->reset();
float newFPS = (1000.f / fireEvent->fireDelay) * 15.f; float newFPS = (1000.f / e.fireDelay) * 15.f;
self->curAnim->setFPS(newFPS); self->curAnim->setFPS(newFPS);
} }
} }
} }
}); });
event->subscribe("OnAnimationFinished", [weakSelf](std::shared_ptr<Event> e) { event->subscribe<AnimationFinishedEvent>([weakSelf](const AnimationFinishedEvent& e) {
if (auto self = weakSelf.lock()) { if (auto self = weakSelf.lock()) {
auto animEvent = std::static_pointer_cast<AnimationFinishedEvent>(e); if (e.entityid == self->entityid && e.animType == "fire")
if (animEvent->entityid == self->entityid && animEvent->animType == "fire")
{ {
if (self->anims["idle"] != NULL) if (self->anims["idle"] != NULL)
self->curAnim = self->anims["idle"].get(); self->curAnim = self->anims["idle"].get();
@ -220,7 +215,7 @@ void AnimationSet::draw()
// If the animation has cycled, we send this event after every cycle // If the animation has cycled, we send this event after every cycle
if ((curAnim->getCycles() - lastCycle) > 0) { if ((curAnim->getCycles() - lastCycle) > 0) {
if (auto event = eventManager.lock()) { if (auto event = eventManager.lock()) {
event->notify(std::make_shared<AnimationFinishedEvent>(entityid, curAnim->getType())); event->notify((AnimationFinishedEvent){entityid, curAnim->getType()});
} }
} }
} }

View file

@ -21,18 +21,16 @@ Renderer::Renderer(const std::shared_ptr<ResourceManager>& r)
void Renderer::hookEventManager(std::weak_ptr<EventManager> eventManager) void Renderer::hookEventManager(std::weak_ptr<EventManager> eventManager)
{ {
if (auto e = eventManager.lock()) { if (auto e = eventManager.lock()) {
e->subscribe("OnScreenShake", [this](std::shared_ptr<Event> event) { e->subscribe<ScreenShakeEvent>([this](const ScreenShakeEvent& event) {
auto shakeEvent = std::dynamic_pointer_cast<ScreenShakeEvent>(event);
postProcessor->ApplyEffect(Postprocessor::SHAKE, postProcessor->ApplyEffect(Postprocessor::SHAKE,
shakeEvent->intensity, event.intensity,
shakeEvent->duration event.duration
); );
}); });
e->subscribe("OnScreenBlur", [this](std::shared_ptr<Event> event) { e->subscribe<ScreenBlurEvent>([this](const ScreenBlurEvent& event) {
auto blurEvent = std::dynamic_pointer_cast<ScreenBlurEvent>(event);
postProcessor->ApplyEffect(Postprocessor::BLUR, postProcessor->ApplyEffect(Postprocessor::BLUR,
blurEvent->intensity, event.intensity,
blurEvent->duration event.duration
); );
}); });
} }

View file

@ -1,8 +1,6 @@
#include "graphics/sprite.h" #include "graphics/sprite.h"
#include "graphics/texture.h" #include "graphics/texture.h"
#include "graphics/quad.h" #include "graphics/quad.h"
#include "util.h"
#include "utility/events.h"
bool Sprite::loaded() const { return (texture != nullptr); } bool Sprite::loaded() const { return (texture != nullptr); }

View file

@ -1,12 +1,10 @@
#include "sound/audiostream.h" #include "sound/audiostream.h"
#include <AL/al.h>
#include <thread>
AudioStream::AudioStream() AudioStream::AudioStream()
{ {
alGenBuffers(4, buffers); alGenBuffers(4, buffers);
alGenSources(1, &source); alGenSources(1, &source);
data = (short *)std::malloc(AUDIO::CHUNK_SIZE * sizeof(short) * 2); // Make space for stereo even if we are playing mono data = (short *)std::malloc(UTIL::AUDIO::CHUNK_SIZE * sizeof(short) * 2); // Make space for stereo even if we are playing mono
stopThread = false; stopThread = false;
eof = true; eof = true;
paused = true; paused = true;
@ -46,14 +44,14 @@ bool AudioStream::openFile(std::string fileName)
return false; return false;
} }
info = stb_vorbis_get_info(file); info = stb_vorbis_get_info(file);
if (info.sample_rate != AUDIO::SAMPLE_RATE) { if (info.sample_rate != UTIL::AUDIO::SAMPLE_RATE) {
LOG(ERROR, "Failed to open file: '{}', make sure to convert sample rate to 44100!", CurStreamName()); LOG(ERROR, "Failed to open file: '{}', make sure to convert sample rate to 44100!", CurStreamName());
stb_vorbis_close(file); stb_vorbis_close(file);
return false; return false;
} }
stb_vorbis_seek_start(file); stb_vorbis_seek_start(file);
std::free(data); std::free(data);
data = (short *)std::malloc(AUDIO::CHUNK_SIZE * sizeof(short) * info.channels); data = (short *)std::malloc(UTIL::AUDIO::CHUNK_SIZE * sizeof(short) * info.channels);
return true; return true;
} }
@ -66,7 +64,7 @@ int AudioStream::loadChunk(ALuint buffer)
if (info.channels == 0) { if (info.channels == 0) {
return sample; return sample;
} }
sample = stb_vorbis_get_samples_short_interleaved(file, info.channels, data, AUDIO::CHUNK_SIZE); sample = stb_vorbis_get_samples_short_interleaved(file, info.channels, data, UTIL::AUDIO::CHUNK_SIZE);
if (sample == 0) if (sample == 0)
return sample; return sample;
format = info.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; format = info.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;

View file

@ -0,0 +1,32 @@
#include "sound/soundeffect.h"
#include "util.h"
#include <AL/al.h>
SoundEffect::SoundEffect(const std::string& filename)
{
if (!loadFile(filename)) {
return;
}
}
// load the whole file into a buffer, this should only be used for small sound effects. Never with music or sounds exceeding 10MB!
bool SoundEffect::loadFile(const std::string& filename)
{
short *data = (short *)std::malloc(UTIL::AUDIO::CHUNK_SIZE * sizeof(short) * 2);
int channels, sample_rate, samples;
samples = stb_vorbis_decode_filename(filename.c_str(), &channels, &sample_rate, &data);
if (samples == 0) {
LOG(ERROR, "Failed to load sound effect '{}'", filename);
return false;
}
alGenBuffers(1, &buffer);
alBufferData(buffer, channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, data, samples * channels * sizeof(short), sample_rate);
std::free(data);
return true;
}
SoundEffect::~SoundEffect()
{
alDeleteBuffers(1, &buffer);
}