diff --git a/Resources/sounds/gun/mach_pew.ogg b/Resources/sounds/gun/mach_pew.ogg
new file mode 100644
index 0000000..9f69035
Binary files /dev/null and b/Resources/sounds/gun/mach_pew.ogg differ
diff --git a/Resources/sounds/gun/reload.ogg b/Resources/sounds/gun/reload.ogg
new file mode 100644
index 0000000..7738d87
Binary files /dev/null and b/Resources/sounds/gun/reload.ogg differ
diff --git a/Resources/sounds/gun_effects.xml b/Resources/sounds/gun_effects.xml
index ce9f250..187b7ec 100644
--- a/Resources/sounds/gun_effects.xml
+++ b/Resources/sounds/gun_effects.xml
@@ -6,5 +6,9 @@
+
+
+
+
diff --git a/YuppleMayham/include/gameplay/gameactor.h b/YuppleMayham/include/gameplay/gameactor.h
index de16286..47a66e7 100644
--- a/YuppleMayham/include/gameplay/gameactor.h
+++ b/YuppleMayham/include/gameplay/gameactor.h
@@ -5,17 +5,17 @@
#include
#include
#include
+#include
#include "gameplay/entity.h"
+#include "gameplay/weapons/weapon.h"
#include "utility/mousestate.h"
#include
class AI;
-class Weapon;
class ISceneContext;
-// TODO: Finish weapon cycling code and add default weapon to every actor
// TODO: Add ammo system, then work on some basic UI design
class GameActor : public Entity
@@ -25,11 +25,12 @@ public:
~GameActor();
void addComponent(std::unique_ptr component);
- void pickupWeapon(std::shared_ptr weapon);
+ void pickupWeapon(std::unique_ptr weapon);
void update(double deltaTime) override;
void draw() override;
- const std::shared_ptr getHeldWeapon() const;
+ Weapon* getHeldWeapon() const;
+ std::span getAllWeapons();
void setRotation(const float& rotation) override;
@@ -49,14 +50,12 @@ public:
void cycleWeapons(const MouseState&);
void followMouse(const MouseState&);
private:
- using component_vector_t = std::vector>;
- using weapon_vector_t = std::vector>;
-
- component_vector_t components;
- weapon_vector_t weapons;
+ std::vector> components;
+ std::vector> weapons;
+ std::vector weaponCache;
size_t currentWeaponIndex = 0;
ISceneContext* sceneContext;
};
-#endif //_H_GAMEACTOR_H
\ No newline at end of file
+#endif //_H_GAMEACTOR_H
diff --git a/YuppleMayham/include/gameplay/weapons/weapon.h b/YuppleMayham/include/gameplay/weapons/weapon.h
index 0994e68..8cf1047 100644
--- a/YuppleMayham/include/gameplay/weapons/weapon.h
+++ b/YuppleMayham/include/gameplay/weapons/weapon.h
@@ -24,7 +24,7 @@ class WeaponScript;
struct PhysicsComponent;
struct WeaponData;
-class Weapon : public Entity, public std::enable_shared_from_this
+class Weapon : public Entity
{
public:
Weapon(const WeaponData* data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager);
diff --git a/YuppleMayham/include/sound/soundmanager.h b/YuppleMayham/include/sound/soundmanager.h
index bfde6c0..33e947e 100644
--- a/YuppleMayham/include/sound/soundmanager.h
+++ b/YuppleMayham/include/sound/soundmanager.h
@@ -15,6 +15,7 @@ public:
private:
struct AudioSource {
ALuint source;
+ ALuint buffer;
bool inUse;
int priority;
};
diff --git a/YuppleMayham/include/utility/resourcemanager.h b/YuppleMayham/include/utility/resourcemanager.h
index 23016ea..a5af8ac 100644
--- a/YuppleMayham/include/utility/resourcemanager.h
+++ b/YuppleMayham/include/utility/resourcemanager.h
@@ -43,7 +43,7 @@ public:
const unsigned loadSoundEffect (const std::string& id);
std::unique_ptr loadAIScript (const std::string& path);
std::unique_ptr loadWeaponScript (const std::string& path);
- std::shared_ptr loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
+ std::unique_ptr loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
std::shared_ptr loadAnimationSet (const std::string& name, int entityid = 0);
const unsigned loadShader (const std::string& name, const std::string& vertexPath, const std::string& fragPath);
@@ -62,7 +62,7 @@ private:
std::unordered_map shaderIDs;
std::unordered_map> sounds;
std::unordered_map> sprites;
- std::unordered_map> weapons;
+ //std::unordered_map> weapons;
//std::unordered_map scripts;
std::unordered_map> backgrounds;
std::unordered_map> tileSets;
diff --git a/YuppleMayham/src/gameplay/gameactor.cpp b/YuppleMayham/src/gameplay/gameactor.cpp
index b1cc8f8..be45128 100644
--- a/YuppleMayham/src/gameplay/gameactor.cpp
+++ b/YuppleMayham/src/gameplay/gameactor.cpp
@@ -16,18 +16,24 @@ void GameActor::addComponent(std::unique_ptr component)
components.push_back(std::move(component));
}
-const std::shared_ptr GameActor::getHeldWeapon() const
+Weapon* GameActor::getHeldWeapon() const
{
- return (weapons.empty() || currentWeaponIndex >= weapons.size()) ? nullptr : weapons[currentWeaponIndex];
+ return (weapons.empty() || currentWeaponIndex >= weapons.size()) ? nullptr : weapons[currentWeaponIndex].get();
}
-void GameActor::pickupWeapon(std::shared_ptr weapon)
+std::span GameActor::getAllWeapons()
+{
+ return weaponCache;
+}
+
+void GameActor::pickupWeapon(std::unique_ptr weapon)
{
weapon->setWielder(this);
if (auto eventManager = sceneContext->getEventManager().lock()) {
weapon->hookEventManager(eventManager);
}
- weapons.push_back(weapon);
+ weaponCache.push_back(weapon.get());
+ weapons.push_back(std::move(weapon));
// wield the newly picked up weapon.
getHeldWeapon()->putaway();
currentWeaponIndex = weapons.size() - 1;
@@ -40,7 +46,7 @@ void GameActor::setRotation(const float& rotation)
if (auto eventManager = sceneContext->getEventManager().lock()) {
Direction newDir = getDirectionFromRotation(rotation);
if (getDirectionFromRotation(this->rotation) != newDir)
- eventManager->notify((DirectionChangeEvent){ entityid, newDir });
+ eventManager->notify({ entityid, newDir });
}
}
this->rotation = rotation;
@@ -59,14 +65,14 @@ void GameActor::update(double deltaTime)
if (isMoving && !wasMoving)
{
if (auto event = sceneContext->getEventManager().lock()) {
- event->notify((EntityMoveEvent){ entityid });
+ event->notify({ entityid });
}
wasMoving = true;
}
else if (!isMoving && wasMoving)
{
if (auto event = sceneContext->getEventManager().lock()) {
- event->notify((EntityStopEvent){ entityid });
+ event->notify({ entityid });
}
wasMoving = false;
}
@@ -95,12 +101,12 @@ void GameActor::moveRight(){ if (physics) physics->rigidBody.applyForce(glm::vec
// top-down shooter mode controls
void GameActor::fireWeapon()const {
- if (auto& weapon = getHeldWeapon()) {
+ if (auto weapon = getHeldWeapon()) {
if (weapon->shoot()) {
if (sceneContext->getPlayerID() == entityid) {
if (auto gEvent = sceneContext->getGlobalEventManager().lock()) {
- gEvent->notify((ScreenShakeEvent){0.01f, 0.8f});
- gEvent->notify((ScreenBlurEvent){1.f, 0.8f});
+ gEvent->notify({0.01f, 0.8f});
+ gEvent->notify({1.f, 0.8f});
}
}
}
@@ -134,7 +140,7 @@ void GameActor::followMouse(const MouseState& mouse_state)
float newRotation = glm::degrees(glm::atan(direction.y, direction.x));
if (getDirectionFromRotation(rotation) != getDirectionFromRotation(newRotation)) {
if (auto event = sceneContext->getEventManager().lock()) {
- event->notify((DirectionChangeEvent){ entityid, getDirectionFromRotation(newRotation) });
+ event->notify({ entityid, getDirectionFromRotation(newRotation) });
}
}
//setRotation(glm::degrees(glm::atan(direction.y, direction.x)));
diff --git a/YuppleMayham/src/gameplay/scene.cpp b/YuppleMayham/src/gameplay/scene.cpp
index ff42dc9..670a2a2 100644
--- a/YuppleMayham/src/gameplay/scene.cpp
+++ b/YuppleMayham/src/gameplay/scene.cpp
@@ -92,8 +92,8 @@ void Scene::loadDebugShooterScene()
auto defaultWeapon = resourceManager->loadWeapon("gun/pistol", weaponShader, bubbleShader);
auto entityWeapon = resourceManager->loadWeapon(entityData.weapon, weaponShader, bubbleShader);
- entity->pickupWeapon(defaultWeapon);
- entity->pickupWeapon(entityWeapon);
+ entity->pickupWeapon(std::move(defaultWeapon));
+ entity->pickupWeapon(std::move(entityWeapon));
entity->setPosition(glm::vec3(entityData.x * mapData->tileSize, entityData.y * mapData->tileSize, 0.f));
entity->setScale(glm::vec3(mapData->tileSize, mapData->tileSize, 1.f));
@@ -166,9 +166,12 @@ void Scene::render(std::shared_ptr renderer)
//e->draw();
renderer->addDrawable(RenderLayer::GameObjects, e.get());
if (e->getHeldWeapon()) {
- renderer->addDrawable(RenderLayer::GameObjects, e->getHeldWeapon().get());
- for (const auto& bullet : e->getHeldWeapon()->getBulletManager()->getBullets()) {
- renderer->addDrawable(RenderLayer::GameObjects, bullet.get());
+ renderer->addDrawable(RenderLayer::GameObjects, e->getHeldWeapon());
+ const auto& weapons = e->getAllWeapons();
+ for (auto& w : weapons) {
+ for (auto b : w->getBulletManager()->getBullets()) {
+ renderer->addDrawable(RenderLayer::GameObjects, b.get());
+ }
}
}
}
@@ -222,7 +225,7 @@ void Scene::hookSceneEvents()
GameActor* shooter = self->getGameActorByID(e.ownerID);
GameActor* target = self->getGameActorByID(e.victimID);
if (shooter && target)
- if (auto& weapon = shooter->getHeldWeapon())
+ if (auto weapon = shooter->getHeldWeapon())
weapon->onHitCallback(target, e.bullet.get(), e.normal);
}
});
diff --git a/YuppleMayham/src/gameplay/weapons/weapon.cpp b/YuppleMayham/src/gameplay/weapons/weapon.cpp
index ce48c6a..8926315 100644
--- a/YuppleMayham/src/gameplay/weapons/weapon.cpp
+++ b/YuppleMayham/src/gameplay/weapons/weapon.cpp
@@ -119,9 +119,9 @@ void Weapon::hookEventManager(std::weak_ptr eventManager)
}
if (auto event = this->eventManager.lock()) {
- std::weak_ptr selfWeak = shared_from_this();
- event->subscribe([selfWeak](const AnimationFinishedEvent& e) {
- if (auto self = selfWeak.lock()) {
+ auto self = this;
+ event->subscribe([self](const AnimationFinishedEvent& e) {
+ if (self) {
if (e.entityid == self->entityid && e.animType == "reload")
{
if (self->reloading)
diff --git a/YuppleMayham/src/sound/engine.cpp b/YuppleMayham/src/sound/engine.cpp
index e8031fc..65d217c 100644
--- a/YuppleMayham/src/sound/engine.cpp
+++ b/YuppleMayham/src/sound/engine.cpp
@@ -28,15 +28,25 @@ void AudioEngine::hookSceneManager(std::weak_ptr _events)
sceneEventManager = _events;
if (auto weak = sceneEventManager.lock()) {
std::weak_ptr weakSelf = shared_from_this();
- weak->subscribe([weakSelf](const EntityFireEvent& e){
+ auto play_sound = [weakSelf](const std::string& id, int priority, const std::optional& pos = std::nullopt) {
if (auto self = weakSelf.lock()) {
if (auto res = self->resourceManager.lock()) {
- auto buf = res->loadSoundEffect(e.weaponType + "/shoot");
+ auto buf = res->loadSoundEffect(id);
if (buf != 0) {
- self->soundManager->playSound(buf, 10, e.firePosition);
+ if (pos != std::nullopt)
+ self->soundManager->playSound(buf, priority, pos.value());
+ else
+ self->soundManager->playSound(buf, priority);
}
}
}
+ };
+
+ weak->subscribe([weakSelf,play_sound](const EntityFireEvent& e){
+ play_sound(e.weaponType + "/shoot", 10, e.firePosition);
+ });
+ weak->subscribe([weakSelf,play_sound](const EntityReloadEvent& e) {
+ play_sound(e.weaponType + "/reload", 9, e.position);
});
}
}
diff --git a/YuppleMayham/src/sound/soundmanager.cpp b/YuppleMayham/src/sound/soundmanager.cpp
index 44c754c..8e1b13f 100644
--- a/YuppleMayham/src/sound/soundmanager.cpp
+++ b/YuppleMayham/src/sound/soundmanager.cpp
@@ -10,7 +10,7 @@ SoundManager::SoundManager()
s.priority = 0;
alSourcef(s.source, AL_REFERENCE_DISTANCE, 1.0f);
alSourcef(s.source, AL_MAX_DISTANCE, 10000.f);
- alSourcef(s.source, AL_ROLLOFF_FACTOR, 1.0f);
+ alSourcef(s.source, AL_ROLLOFF_FACTOR, 0.3f);
}
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
}
@@ -25,6 +25,7 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
if (!sources[ring].inUse) {
sources[ring].inUse = true;
sources[ring].priority = priority;
+ sources[ring].buffer = buffer;
alSourcei(sources[ring].source, AL_BUFFER, buffer);
if (pos != glm::vec3(0)) {
//alSourcei(sources[ring].source, AL_SOURCE_RELATIVE, 1);
@@ -40,6 +41,7 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
if (!sources[ring].inUse) {
sources[ring].inUse = true;
sources[ring].priority = priority;
+ sources[ring].buffer = buffer;
alSourcei(sources[ring].source, AL_BUFFER, buffer);
if (pos != glm::vec3(0)) {
//alSourcei(sources[ring].source, AL_SOURCE_RELATIVE, 1);
@@ -48,12 +50,12 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
//alSourcei(sources[ring].source, AL_SOURCE_RELATIVE, 0);
}
alSourcePlay(sources[ring].source);
- lastUsed = ring;
+ lastUsed = nextIndex(ring);
return;
}
- if (sources[ring].priority <= priority) {
+ if (sources[ring].priority > priority || (sources[ring].buffer != buffer && sources[ring].priority == priority)) {
if (nextBest) {
- if (nextBest->priority > sources[ring].priority) {
+ if (nextBest->priority >= sources[ring].priority) {
nextBest = &sources[ring];
secIndex = ring;
}
@@ -65,7 +67,9 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
}
if (nextBest) {
nextBest->priority = priority;
+ alSourcei(nextBest->source, AL_BUFFER, 0);
alSourcei(nextBest->source, AL_BUFFER, buffer);
+ nextBest->buffer = buffer;
if (pos != glm::vec3(0)) {
//alSourcei(nextBest->source, AL_SOURCE_RELATIVE, 1);
alSourcefv(nextBest->source, AL_POSITION, glm::value_ptr(pos));
@@ -86,6 +90,7 @@ void SoundManager::pollSources()
alGetSourcei(s.source, AL_SOURCE_STATE, &state);
if (state == AL_STOPPED) {
s.inUse = false;
+ s.buffer = 0;
alSourcei(s.source, AL_BUFFER, 0);
}
//else if (state != AL_PLAYING)
diff --git a/YuppleMayham/src/utility/resourcemanager.cpp b/YuppleMayham/src/utility/resourcemanager.cpp
index 202eb89..8f19ff9 100644
--- a/YuppleMayham/src/utility/resourcemanager.cpp
+++ b/YuppleMayham/src/utility/resourcemanager.cpp
@@ -78,17 +78,17 @@ Background* ResourceManager::loadBackground(const std::string& path)
// We attach our script after we create our weapon because we are passing a reference to the weapon into the script and we don't want to pass an
// incomplete reference to our script.
-std::shared_ptr ResourceManager::loadWeapon(const std::string& id, const unsigned weaponShaderID, const unsigned bulletShaderID)
+std::unique_ptr ResourceManager::loadWeapon(const std::string& id, const unsigned weaponShaderID, const unsigned bulletShaderID)
{
const WeaponData* data = xmlLoader->getWeaponData(id);
if (!data) {
LOG(ERROR, "Could not load weapon id '{}', falling back to pistol", id);
data = xmlLoader->getWeaponData("gun/pistol");// using this as a fallback for now
}
- auto weapon = std::make_shared(data, weaponShaderID, bulletShaderID, this);
+ auto weapon = std::make_unique(data, weaponShaderID, bulletShaderID, this);
if (!data->script.empty())
weapon->attachScript(loadWeaponScript(data->script));
- return weapon;
+ return std::move(weapon);
}
const unsigned ResourceManager::loadSoundEffect(const std::string& id)
@@ -139,7 +139,6 @@ void ResourceManager::clearResources()
sprites.clear();
shaders.clear();
shaderIDs.clear();
- weapons.clear();
tileSets.clear();
}
diff --git a/compile_flags.txt b/compile_flags.txt
new file mode 100644
index 0000000..e23b2ae
--- /dev/null
+++ b/compile_flags.txt
@@ -0,0 +1 @@
+-std=c++20