mirror of
https://github.com/araxiaonline/mod-mythic-plus.git
synced 2026-06-13 03:02:24 -04:00
Added new event handler system for creature events to allow for balancing
This commit is contained in:
@@ -1,81 +1,50 @@
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "Creature.h"
|
||||
#include "CreatureHooks.h"
|
||||
#include "MpLogger.h"
|
||||
|
||||
void CreatureHooks::RegisterJustDied(uint32 entry, CreatureHook<Creature*, Unit*> callback) {
|
||||
(*_JustDiedHandlers)[entry].push_back(callback);
|
||||
}
|
||||
|
||||
class CreatureHooks {
|
||||
private:
|
||||
// Define type aliases for cleaner code
|
||||
using EventCallback = std::function<void(Creature*)>;
|
||||
using EventList = std::vector<EventCallback>;
|
||||
using EventMap = std::unordered_map<uint32, EventList>;
|
||||
void CreatureHooks::RegisterOnSpawn(uint32 entry, CreatureHook<Creature*>callback) {
|
||||
(*_OnSpawnHandlers)[entry].push_back(callback);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
CreatureHooks() = default;
|
||||
void CreatureHooks::RegisterOnAddToInstance(uint32 entry, uint32 mapId, uint32 instanceId, CreatureHook<Creature*> callback) {
|
||||
(*_OnAddToInstanceHandlers)[entry].push_back(callback);
|
||||
}
|
||||
|
||||
// Use the type aliases for readability
|
||||
std::unique_ptr<EventMap> _spawnedEvents = std::make_unique<EventMap>();
|
||||
std::unique_ptr<EventMap> _isDeadEvents = std::make_unique<EventMap>();
|
||||
std::unique_ptr<std::unordered_map<uint32, std::unordered_map<uint8, EventList>>> _healthPercentEvents
|
||||
= std::make_unique<std::unordered_map<uint32, std::unordered_map<uint8, EventList>>>();
|
||||
// Call health events if the creature's health is at or below the percentage
|
||||
// void CheckHealthEvents(Creature* creature) {
|
||||
// uint32 entry = creature->GetEntry();
|
||||
// uint32 currentHealthPct = creature->GetHealthPct();
|
||||
|
||||
public:
|
||||
// Singleton instance access method
|
||||
static CreatureHooks* instance() {
|
||||
static CreatureHooks instance;
|
||||
return &instance;
|
||||
}
|
||||
// if (_healthPercentEvents->contains(entry)) {
|
||||
// for (const auto& [percent, callbacks] : _healthPercentEvents->at(entry)) {
|
||||
// if (currentHealthPct <= percent) {
|
||||
// for (auto& callback : callbacks) {
|
||||
// callback(creature); // Trigger custom behavior
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Register events for health at a certain percentage
|
||||
void RegisterHealthAtPercentHook(uint32 entry, uint8 percent, EventCallback callback) {
|
||||
(*_healthPercentEvents)[entry][percent].push_back(callback);
|
||||
}
|
||||
void CreatureHooks::JustDied(Creature* creature, Unit* killer) {
|
||||
uint32 entry = creature->GetEntry();
|
||||
|
||||
// Register "Is Dead" events
|
||||
void RegisterIsDeadHook(uint32 entry, EventCallback callback) {
|
||||
(*_isDeadEvents)[entry].push_back(callback);
|
||||
}
|
||||
|
||||
// Register "Spawned" events
|
||||
void RegisterSpawnedHook(uint32 entry, EventCallback callback) {
|
||||
(*_spawnedEvents)[entry].push_back(callback);
|
||||
}
|
||||
|
||||
// Call health events if the creature's health is at or below the percentage
|
||||
void CheckHealthEvents(Creature* creature) {
|
||||
uint32 entry = creature->GetEntry();
|
||||
uint32 currentHealthPct = creature->GetHealthPct();
|
||||
|
||||
if (_healthPercentEvents->contains(entry)) {
|
||||
for (const auto& [percent, callbacks] : _healthPercentEvents->at(entry)) {
|
||||
if (currentHealthPct <= percent) {
|
||||
for (auto& callback : callbacks) {
|
||||
callback(creature); // Trigger custom behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_JustDiedHandlers->contains(entry)) {
|
||||
for (auto& callback : _JustDiedHandlers->at(entry)) {
|
||||
callback(creature, killer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call "Is Dead" events if the creature is dead
|
||||
void CheckIsDeadEvent(Creature* creature) {
|
||||
uint32 entry = creature->GetEntry();
|
||||
if (!creature->IsAlive() && _isDeadEvents->contains(entry)) {
|
||||
for (auto& callback : _isDeadEvents->at(entry)) {
|
||||
callback(creature); // Trigger custom behavior
|
||||
}
|
||||
void CreatureHooks::JustSpawned(Creature* creature) {
|
||||
uint32 entry = creature->GetEntry();
|
||||
|
||||
if (_OnSpawnHandlers->contains(entry)) {
|
||||
for (auto& callback : _OnSpawnHandlers->at(entry)) {
|
||||
callback(creature);
|
||||
}
|
||||
}
|
||||
|
||||
// Call "Spawned" events when the creature spawns
|
||||
void CheckSpawnedEvent(Creature* creature) {
|
||||
uint32 entry = creature->GetEntry();
|
||||
if (_spawnedEvents->contains(entry)) {
|
||||
for (auto& callback : _spawnedEvents->at(entry)) {
|
||||
callback(creature); // Trigger custom behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
74
src/CreatureHooks.h
Normal file
74
src/CreatureHooks.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef CREATUREHOOKS_H
|
||||
#define CREATUREHOOKS_H
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "Creature.h"
|
||||
#include "ObjectGuid.h"
|
||||
|
||||
// Struct to store the state of which handlers have been fired for a creature
|
||||
struct CreatureEventState {
|
||||
bool onDeathEventFired = false;
|
||||
bool onSpawnEventFired = false;
|
||||
bool onAddedToInstanceEventFired = false;
|
||||
uint8 deaths = 0; // Count of deaths
|
||||
};
|
||||
|
||||
// Type aliases for creature event handling
|
||||
// using CreatureHook = std::function<void(Creature*)>;
|
||||
// using HookList = std::vector<CreatureHook>;
|
||||
// using HandlerMap = std::unordered_map<uint32, HookList>;
|
||||
|
||||
// Type alias for variadic event hooks
|
||||
template<typename... Args>
|
||||
using CreatureHook = std::function<void(Args...)>;
|
||||
|
||||
// Type alias for a list of hooks that take varying arguments
|
||||
template<typename... Args>
|
||||
using HandlersList = std::vector<CreatureHook<Args...>>;
|
||||
|
||||
// HandlerMap using variadic templates
|
||||
template<typename... Args>
|
||||
using HandlerMap = std::unordered_map<uint32, HandlersList<Args...>>;
|
||||
|
||||
using CreatureEventStateMap = std::map<ObjectGuid, CreatureEventState>;
|
||||
|
||||
class CreatureHooks {
|
||||
private:
|
||||
|
||||
CreatureHooks() { }
|
||||
~CreatureHooks() { }
|
||||
|
||||
// ensure we only ever have one instance of this class
|
||||
CreatureHooks(const CreatureHooks&) = delete;
|
||||
CreatureHooks& operator=(const CreatureHooks&) = delete;
|
||||
|
||||
// Data members for storing event handlers
|
||||
std::unique_ptr<HandlerMap<Creature*>> _OnSpawnHandlers;
|
||||
std::unique_ptr<HandlerMap<Creature*, Unit*>> _JustDiedHandlers;
|
||||
std::unique_ptr<HandlerMap<Creature*>> _OnAddToInstanceHandlers;
|
||||
|
||||
// Tracks state to know which handlers need to be fired again
|
||||
std::unique_ptr<CreatureEventStateMap> _eventStates;
|
||||
|
||||
public:
|
||||
static CreatureHooks* instance() {
|
||||
static CreatureHooks instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
// Register events for specific actions
|
||||
void RegisterJustDied(uint32 entry, CreatureHook<Creature*, Unit*> callback);
|
||||
void RegisterOnSpawn(uint32 entry, CreatureHook<Creature*> callback);
|
||||
void RegisterOnAddToInstance(uint32 entry, uint32 mapId, uint32 instanceId, CreatureHook<Creature*> callback);
|
||||
|
||||
// Event triggers
|
||||
void JustDied(Creature* creature, Unit* killer);
|
||||
void JustSpawned(Creature* creature);
|
||||
};
|
||||
|
||||
#define sCreatureHooks CreatureHooks::instance()
|
||||
|
||||
#endif // CREATUREHOOKS_H
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef MP_EVENT_HANDLER_H
|
||||
#define MP_EVENT_HANDLER_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
// Template class for handling different function signatures
|
||||
template<typename... Args>
|
||||
class MpEventHandler
|
||||
{
|
||||
public:
|
||||
using EventCallback = std::function<void(Args...)>;
|
||||
|
||||
// Constructor to initialize with a callback function
|
||||
EventCallback(CallbackFunction func);
|
||||
|
||||
// Method to call the stored function with arguments
|
||||
void Call(Args... args);
|
||||
|
||||
private:
|
||||
CallbackFunction _func;
|
||||
};
|
||||
|
||||
#endif // MP_EVENT_HANDLER_H
|
||||
61
src/MpScriptAI.h
Normal file
61
src/MpScriptAI.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "CreatureHooks.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
#ifdef _ELUNA_CREATURE_AI_H
|
||||
#include "ElunaCreatureAI.h"
|
||||
#endif
|
||||
|
||||
|
||||
class MpScriptAI : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
MpScriptAI(Creature* creature) : ScriptedAI(creature) {
|
||||
#ifdef _ELUNA_CREATURE_AI_H
|
||||
// Check if Eluna is attached to the creature
|
||||
if (ElunaCreatureAI* eluna = dynamic_cast<ElunaCreatureAI*>(creature->AI())) {
|
||||
elunaAI = eluna; // Store a pointer to the Eluna AI
|
||||
} else {
|
||||
elunaAI = nullptr; // No Eluna AI attached
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Example for JustDied event
|
||||
void JustDied(Unit* killer) override {
|
||||
sCreatureHooks->JustDied(me, killer);
|
||||
|
||||
#ifdef _ELUNA_CREATURE_AI_H
|
||||
// If Eluna is attached, call its JustDied event
|
||||
if (elunaAI){
|
||||
elunaAI->JustDied(killer);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// If Eluna is not installed or not attached, call the default AI handler
|
||||
ScriptedAI::JustDied(killer);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override {
|
||||
#ifdef _ELUNA_CREATURE_AI_H
|
||||
// If Eluna is attached, call its Reset event
|
||||
if (elunaAI){
|
||||
elunaAI->Reset();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Call the default AI handler
|
||||
ScriptedAI::Reset();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef ENABLE_ELUNA
|
||||
ElunaCreatureAI* elunaAI; // Store a pointer to Eluna's AI if attached
|
||||
#endif
|
||||
};
|
||||
Reference in New Issue
Block a user