#pragma once #include "skse64_common/Utilities.h" #include "GameTypes.h" #include "GameForms.h" class TESObjectREFR; class Actor; class TESObjectBOOK; class TESFullName; class TESQuest; class TESObjectWEAP; class TESWordOfPower; class Character; class TESShout; class TESFaction; class BGSLocation; template class BSTEventSink; enum EventResult { kEvent_Continue = 0, kEvent_Abort }; // 058 template class EventDispatcher { typedef BSTEventSink SinkT; tArray eventSinks; // 000 tArray addBuffer; // 018 - schedule for add tArray removeBuffer; // 030 - schedule for remove SimpleLock lock; // 048 bool stateFlag; // 050 - some internal state changed while sending char pad[7]; // 051 // Note: in SE there are multiple identical copies of all these functions MEMBER_FN_PREFIX(EventDispatcher); // 9FCA8C7632C2FC6D6E342E554B43402121BC4E44+66 DEFINE_MEMBER_FN(AddEventSink_Internal, void, 0x00587E20, SinkT * eventSink); // ??_7BGSProcedureShoutExecState@@6B@ xref +21 last call DEFINE_MEMBER_FN(RemoveEventSink_Internal, void, 0x0043C400, SinkT * eventSink); // FB59C2DDF89F5248DF43230E39A6FECF8C997BA6+466 DEFINE_MEMBER_FN(SendEvent_Internal, void, 0x00181CB0, EventArgT * evn); public: EventDispatcher() : stateFlag(false) {} void AddEventSink(SinkT * eventSink) { CALL_MEMBER_FN(this,AddEventSink_Internal)(eventSink); } void RemoveEventSink(SinkT * eventSink) { CALL_MEMBER_FN(this,RemoveEventSink_Internal)(eventSink); } void SendEvent(EventArgT * evn) { CALL_MEMBER_FN(this,SendEvent_Internal)(evn); } }; STATIC_ASSERT(sizeof(EventDispatcher) == 0x58); // 08 template class BSTEventSink { public: virtual ~BSTEventSink() { }; virtual EventResult ReceiveEvent(T * evn, EventDispatcher * dispatcher) { return kEvent_Continue; }; // pure // void ** _vtbl; // 00 }; // 58 template class BSTEventSource { public: tArray unk00; // 08 UnkArray unk18; // 18 UnkArray unk30; // 30 UInt32 unk48; // 48 UInt32 unk4C; // 4C UInt8 unk50; // 50 UInt8 pad51[7]; // 51 }; STATIC_ASSERT(sizeof(BSTEventSource) == 0x58); // 08 struct TESSleepStartEvent { float startTime; // 00 float endTime; // 04 }; // 10 struct MenuOpenCloseEvent { BSFixedString menuName; // 00 bool opening; // 08 char pad[7]; }; // Todo struct MenuModeChangeEvent { }; class TESObjectREFR; class TESForm; class ActiveEffect; struct TESActiveEffectApplyRemoveEvent { TESObjectREFR * caster; // 0 TESObjectREFR * target; // 8 UInt16 unk10; // 10 UInt8 unk12; // 12 }; struct TESQuestStageEvent { void * finishedCallback; // 0 UInt32 formId; // 8 UInt16 stage; // C UInt8 unk0E; // E UInt8 pad; // F }; // This isn't necessarily correct, just there to receive events struct TESHarvestEvent { struct ItemHarvested { TESForm* object; TESForm* player; }; }; struct LevelIncrease { struct Event { TESForm * character; UInt32 level; }; }; struct SkillIncrease { struct Event { TESForm* character; UInt32 avId; }; }; struct WordLearned { struct Event { bool first; }; }; struct WordUnlocked { struct Event { bool third; }; }; struct Inventory { struct Event { TESForm* character; }; }; struct Bounty { struct Event { TESFaction* faction; UInt32 before; UInt32 after; }; }; struct QuestStatus { struct Event { TESQuest* quest; UInt32 status; }; }; struct ObjectiveState { struct Event { TESQuest::Objective* objective; UInt32 oldState; UInt32 newState; }; }; struct Trespass { struct Event { // Unknown }; }; struct FinePaid { struct Event { // Unknown }; }; struct HoursPassed { struct Event { // Unknown }; }; struct DaysPassed { struct Event { // Unknown }; }; struct DaysJailed { struct Event { UInt32 days; BGSLocation* location; TESFaction* faction; UInt32 bounty; }; }; struct CriticalHitEvent { struct Event { // Unknown }; }; struct DisarmedEvent { struct Event { // Unknown }; }; struct ItemsPickpocketed { struct Event { // Unknown }; }; struct ItemSteal { struct Event { // Unknown }; }; struct ItemCrafted { struct Event { // Unknown }; }; struct LocationDiscovery { struct Event { TESFullName * name; const char * world; }; }; struct Jailing { struct Event { // Unknown }; }; struct ChestsLooted { struct Event { // Unknown }; }; struct TimesTrained { struct Event { // Unknown }; }; struct TimesBartered { struct Event { // Unknown }; }; struct ContractedDisease { struct Event { // Unknown }; }; struct SpellsLearned { struct Event { // Unknown }; }; struct DragonSoulGained { struct Event { float souls; }; }; struct SoulGemsUsed { struct Event { // Unknown }; }; struct SoulsTrapped { struct Event { TESObjectREFR* player; TESObjectREFR* target; }; }; struct PoisonedWeapon { struct Event { // Unknown }; }; struct ShoutAttack { struct Event { TESShout* shout; }; }; struct JailEscape { struct Event { // Unknown }; }; struct GrandTheftHorse { struct Event { // Unknown }; }; struct AssaultCrime { struct Event { UInt8 pad; TESObjectREFR* target; }; }; struct MurderCrime { struct Event { UInt8 pad; TESObjectREFR* source; TESObjectREFR* target; }; }; struct LocksPicked { struct Event { // Unknown }; }; struct ShoutMastered { struct Event { // Unknown }; }; struct TESCombatEvent { TESObjectREFR * source; // 00 TESObjectREFR * target; // 08 UInt32 state; // 10 }; struct TESDeathEvent { TESObjectREFR * source; // 00 TESObjectREFR * killer; // 08 UInt8 state; // 10 - 0 - dying; 1 - death }; struct TESHitEvent { TESObjectREFR * target; // 00 TESObjectREFR * caster; // 08 UInt32 sourceFormID; // 10 UInt32 projectileFormID; // 14 enum { kFlag_PowerAttack = (1 << 0), kFlag_SneakAttack = (1 << 1), kFlag_Bash = (1 << 2), kFlag_Blocked = (1 << 3) }; UInt32 flags; // 18 ?? }; struct TESUniqueIDChangeEvent { UInt32 oldOwnerFormId; // 0 UInt32 newOwnerFormId; // 4 UInt32 formId; // 8 UInt16 oldUniqueId; // C UInt16 newUniqueId; // E }; struct TESContainerChangedEvent { UInt32 fromFormId; // 0 UInt32 toFormId; // 4 UInt32 itemFormId; // 8 UInt32 count; // C UInt32 toReference; // 10 UInt16 unk14; // 14 }; struct TESObjectLoadedEvent { UInt32 formId; // 00 UInt8 loaded; // 04 - 01 - loaded, 00 - unloaded }; struct TESCellAttachDetachEvent { TESObjectREFR * reference; // 00 UInt8 attached; // 08 - 01 - attached, 00 - detached }; struct TESCellFullyLoadedEvent { TESObjectCELL* cell; }; struct TESMoveAttachDetachEvent { TESObjectREFR * reference; // 00 UInt8 attached; // 08 - 01 - attached, 00 - detached }; struct TESInitScriptEvent { TESObjectREFR * reference; }; struct BGSFootstepEvent { UInt32 actorHandle; }; struct TESFurnitureEvent { TESObjectREFR* character; TESObjectREFR* furniture; UInt32 state; }; struct TESLoadGameEvent { // empty }; struct TESLockChangedEvent { TESObjectREFR* lock; TESObjectREFR* unlocker; }; struct TESQuestInitEvent { UInt32 formId; }; struct TESQuestStartStopEvent { UInt32 formId; }; struct TESTrackedStatsEvent { BSFixedString statName; UInt32 newValue; }; struct TESWaitStartEvent { float current; float desired; }; struct TESWaitStopEvent { //empty? }; struct TESSwitchRaceCompleteEvent { Actor* actor; }; struct LocationCleared { struct Event { //empty? }; }; struct BookRead { struct Event { TESObjectBOOK* book; }; }; struct HourPassed { struct Event { UInt32 sleep; }; }; struct ActorKill { struct Event { TESObjectREFR* killer; TESObjectREFR* victim; }; }; struct CriticalHit { struct Event { TESForm* character; TESObjectWEAP* weapon; }; }; struct Disarmed { struct Event { TESObjectREFR* source; TESObjectREFR* target; }; }; struct WeaponAttack { struct Event { TESObjectWEAP* weapon; Character* wielder; //unk }; }; struct DefaultObjectsReadyEvent { struct Event { //g_defaultObjectManager ? }; }; class EventDispatcherList { public: EventDispatcher unk00; // 00 EventDispatcher unk58; // 58 - sink offset 010 EventDispatcher unkB0; // B0 - sink offset 018 EventDispatcher unk108; // 108 - sink offset 020 EventDispatcher unk160; // 160 - sink offset 028 EventDispatcher unk1B8; // 1B8 - sink offset 030 EventDispatcher unk210; // 210 - sink offset 038 EventDispatcher unk2C0; // 2C0 - sink offset 040 EventDispatcher combatDispatcher; // 318 - sink offset 048 EventDispatcher unk370; // 370 - sink offset 050 EventDispatcher deathDispatcher; // 3C8 - sink offset 058 EventDispatcher unk420; // 420 - sink offset 068 EventDispatcher unk478; // 478 - sink offset 070 EventDispatcher unk4D0; // 4D0 - sink offset 078 EventDispatcher unk528; // 528 - sink offset 080 EventDispatcher unk580; // 580 - sink offset 088 EventDispatcher unk5D8; // 5D8 - sink offset 090 EventDispatcher unk630; // 630 - sink offset 098 EventDispatcher initScriptDispatcher; // 688 - sink offset 0A0 EventDispatcher loadGameEventDispatcher;// 6E0 - sink offset 0A8 EventDispatcher unk738; // 738 - sink offset 0B0 EventDispatcher unk790; // 790 - sink offset 0B8 EventDispatcher unk7E8; // 7E8 - sink offset 0C0 EventDispatcher unk840; // 840 - sink offset 0C8 EventDispatcher objectLoadedDispatcher; // 898 - sink offset 0D0 EventDispatcher unk8F0; // 8F0 - sink offset 0D8 EventDispatcher unk948; // 948 - sink offset 0E0 EventDispatcher unk9A0; // 9A0 - sink offset 0E8 EventDispatcher unk9F8; // 9F8 - sink offset 0F0 EventDispatcher unkA50; // A50 - sink offset 0F8 EventDispatcher unkAA8; // AA8 - sink offset 100 EventDispatcher unkB00; // B00 - sink offset 108 EventDispatcher unkB58; // B58 - sink offset 110 EventDispatcher unkBB0; // BB0 - sink offset 118 EventDispatcher unkC08; // C08 - sink offset 120 EventDispatcher unkC60; // C60 - sink offset 128 EventDispatcher unkCB8; // CB8 - sink offset 130 EventDispatcher unkD10; // D10 - sink offset 138 EventDispatcher unkD68; // D68 - sink offset 140 EventDispatcher unkDC0; // DC0 - sink offset 148 EventDispatcher unkE18; // E18 - sink offset 150 EventDispatcher unkE70; // E70 - sink offset 158 EventDispatcher unkEC8; // EC8 - sink offset 160 EventDispatcher unkF20; // F20 - sink offset 168 EventDispatcher unkF78; // F78 - sink offset 170 EventDispatcher unkFD0; // FD0 - sink offset 178 EventDispatcher unk1028; // 1028 - sink offset 180 EventDispatcher unk1080; // 1080 - sink offset 188 EventDispatcher unk10D8; // 10D8 - sink offset 190 EventDispatcher uniqueIdChangeDispatcher; // 1130 - sink offset 198 EventDispatcher unk1188; // 1188 - sink offset 200 EventDispatcher unk11E0; // 11E0 - sink offset 208 EventDispatcher unk1238; // 1238 - sink offset 210 EventDispatcher unk1290; // 1290 - sink offset 218 }; STATIC_ASSERT(offsetof(EventDispatcherList, uniqueIdChangeDispatcher) == 0x10D8); typedef EventDispatcherList*(*_GetEventDispatcherList)(); extern RelocAddr<_GetEventDispatcherList> GetEventDispatcherList; // For testing //extern EventDispatcher * g_sleepStartEventDispatcher; //extern EventDispatcher * g_combatEventDispatcher; //extern EventDispatcher * g_deathEventDispatcher; //extern EventDispatcher * g_footstepEventDispatcher; //extern EventDispatcher * g_questStageEventDispatcher; //extern EventDispatcher * g_harvestEventDispatcher; //extern EventDispatcher * g_levelIncreaseEventDispatcher; //extern EventDispatcher * g_hitEventDispatcher; //extern EventDispatcher * g_containerChangedEventDispatcher; //extern EventDispatcher * g_changeUniqueIDEventDispatcher; //extern EventDispatcher * g_objectLoadedEventDispatcher; //extern EventDispatcher * g_initScriptEventDispatcher; //extern EventDispatcher * g_cellAttachDetachEventDispatcher; //extern EventDispatcher * g_moveAttachDetachEventDispatcher;