Skip to content

Commit

Permalink
fix: new addresses for object animations
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbeBryssinck committed Nov 25, 2021
1 parent 1d64003 commit 6e042c1
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
41 changes: 36 additions & 5 deletions Code/client/Games/Skyrim/TESObjectREFR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ TP_THIS_FUNCTION(TActivate, void, TESObjectREFR, TESObjectREFR* apActivator, uin
TP_THIS_FUNCTION(TAddInventoryItem, void*, TESObjectREFR, TESBoundObject* apItem, BSExtraDataList* apExtraData, uint32_t aCount, TESObjectREFR* apOldOwner);
TP_THIS_FUNCTION(TRemoveInventoryItem, void*, TESObjectREFR, float* apUnk0, TESBoundObject* apItem, uint32_t aCount, uint32_t aUnk1, BSExtraDataList* apExtraData, TESObjectREFR* apNewOwner, NiPoint3* apUnk2, NiPoint3* apUnk3);
TP_THIS_FUNCTION(TPlayAnimationAndWait, bool, void, uint32_t auiStackID, TESObjectREFR* apSelf, BSFixedString* apAnimation, BSFixedString* apEventName);
TP_THIS_FUNCTION(TPlayAnimation, bool, void, uint32_t auiStackID, TESObjectREFR* apSelf, BSFixedString* apEventName);

static TActivate* RealActivate = nullptr;
static TAddInventoryItem* RealAddInventoryItem = nullptr;
static TRemoveInventoryItem* RealRemoveInventoryItem = nullptr;
static TPlayAnimationAndWait* RealPlayAnimationAndWait = nullptr;
static TPlayAnimation* RealPlayAnimation = nullptr;

#ifdef SAVE_STUFF

Expand Down Expand Up @@ -131,28 +133,54 @@ void TESObjectREFR::Activate(TESObjectREFR* apActivator, uint8_t aUnk1, TESBound
return ThisCall(RealActivate, this, apActivator, aUnk1, aObjectToGet, aCount, aDefaultProcessing);
}

static thread_local bool s_cancelAnimationEvent = false;
static thread_local bool s_cancelAnimationWaitEvent = false;

bool TESObjectREFR::PlayAnimationAndWait(BSFixedString* apAnimation, BSFixedString* apEventName) noexcept
{
using ObjectReference = TESObjectREFR;

PAPYRUS_FUNCTION(bool, ObjectReference, PlayAnimationAndWait, BSFixedString*, BSFixedString*);

s_cancelAnimationEvent = true;
s_cancelAnimationWaitEvent = true;
bool result = s_pPlayAnimationAndWait(this, apAnimation, apEventName);
s_cancelAnimationEvent = false;
s_cancelAnimationWaitEvent = false;
return result;
}

bool TP_MAKE_THISCALL(HookPlayAnimationAndWait, void, uint32_t auiStackID, TESObjectREFR* apSelf, BSFixedString* apAnimation, BSFixedString* apEventName)
{
if (!s_cancelAnimationEvent && (apSelf->formID < 0xFF000000))
spdlog::info("Animation: {}, EventName: {}", apAnimation->AsAscii(), apEventName->AsAscii());

if (!s_cancelAnimationWaitEvent && (apSelf->formID < 0xFF000000))
World::Get().GetRunner().Trigger(ScriptAnimationEvent(apSelf->formID, apAnimation->AsAscii(), apEventName->AsAscii()));

return ThisCall(RealPlayAnimationAndWait, apThis, auiStackID, apSelf, apAnimation, apEventName);
}

static thread_local bool s_cancelAnimationEvent = false;

bool TESObjectREFR::PlayAnimation(BSFixedString* apEventName) noexcept
{
using ObjectReference = TESObjectREFR;

PAPYRUS_FUNCTION(bool, ObjectReference, PlayAnimation, BSFixedString*);

s_cancelAnimationEvent = true;
bool result = s_pPlayAnimation(this, apEventName);
s_cancelAnimationEvent = false;
return result;
}

bool TP_MAKE_THISCALL(HookPlayAnimation, void, uint32_t auiStackID, TESObjectREFR* apSelf, BSFixedString* apEventName)
{
spdlog::info("EventName: {}", apEventName->AsAscii());

if (!s_cancelAnimationEvent && (apSelf->formID < 0xFF000000))
World::Get().GetRunner().Trigger(ScriptAnimationEvent(apSelf->formID, String{}, apEventName->AsAscii()));

return ThisCall(RealPlayAnimation, apThis, auiStackID, apSelf, apEventName);
}

void TP_MAKE_THISCALL(HookActivate, TESObjectREFR, TESObjectREFR* apActivator, uint8_t aUnk1, TESBoundObject* apObjectToGet, int32_t aCount, char aDefaultProcessing)
{
auto* pActivator = RTTI_CAST(apActivator, TESObjectREFR, Actor);
Expand Down Expand Up @@ -189,15 +217,18 @@ static TiltedPhoques::Initializer s_objectReferencesHooks([]() {
POINTER_SKYRIMSE(TActivate, s_activate, 0x1402A9180 - 0x140000000);
POINTER_SKYRIMSE(TAddInventoryItem, s_addInventoryItem, 0x1402A0930 - 0x140000000);
POINTER_SKYRIMSE(TRemoveInventoryItem, s_removeInventoryItem, 0x14029FCB0 - 0x140000000);
POINTER_SKYRIMSE(TPlayAnimationAndWait, s_playAnimationAndWait, 0x140995800 - 0x140000000);
POINTER_SKYRIMSE(TPlayAnimationAndWait, s_playAnimationAndWait, 0x1409BD960 - 0x140000000);
POINTER_SKYRIMSE(TPlayAnimation, s_playAnimation, 0x1409BD8E0 - 0x140000000);

RealActivate = s_activate.Get();
RealAddInventoryItem = s_addInventoryItem.Get();
RealRemoveInventoryItem = s_removeInventoryItem.Get();
RealPlayAnimationAndWait = s_playAnimationAndWait.Get();
RealPlayAnimation = s_playAnimation.Get();

TP_HOOK(&RealActivate, HookActivate);
TP_HOOK(&RealAddInventoryItem, HookAddInventoryItem);
TP_HOOK(&RealRemoveInventoryItem, HookRemoveInventoryItem);
TP_HOOK(&RealPlayAnimationAndWait, HookPlayAnimationAndWait);
TP_HOOK(&RealPlayAnimation, HookPlayAnimation);
});
1 change: 1 addition & 0 deletions Code/client/Games/Skyrim/TESObjectREFR.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ struct TESObjectREFR : TESForm
void Activate(TESObjectREFR* apActivator, uint8_t aUnk1, TESBoundObject* apObjectToGet, int32_t aCount, char aDefaultProcessing) noexcept;

bool PlayAnimationAndWait(BSFixedString* apAnimation, BSFixedString* apEventName) noexcept;
bool PlayAnimation(BSFixedString* apEventName) noexcept;

Lock* CreateLock() noexcept;
void LockChange() noexcept;
Expand Down
14 changes: 10 additions & 4 deletions Code/client/Services/Generic/EnvironmentService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ void EnvironmentService::OnLockChangeNotify(const NotifyLockChange& acMessage) n

void EnvironmentService::OnScriptAnimationEvent(const ScriptAnimationEvent& acEvent) noexcept
{
ScriptAnimationRequest request;
ScriptAnimationRequest request{};
request.FormID = acEvent.FormID;
request.Animation = acEvent.Animation;
request.EventName = acEvent.EventName;
Expand All @@ -345,10 +345,16 @@ void EnvironmentService::OnNotifyScriptAnimation(const NotifyScriptAnimation& ac
return;
}

BSFixedString animation(acMessage.Animation.c_str());
BSFixedString eventName(acMessage.EventName.c_str());

pObject->PlayAnimationAndWait(&animation, &eventName);
if (acMessage.Animation == String{})
{
pObject->PlayAnimation(&eventName);
}
else
{
BSFixedString animation(acMessage.Animation.c_str());
pObject->PlayAnimationAndWait(&animation, &eventName);
}
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion Code/server/Services/EnvironmentService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void EnvironmentService::OnScriptAnimationRequest(const PacketEvent<ScriptAnimat
{
auto packet = acMessage.Packet;

NotifyScriptAnimation message;
NotifyScriptAnimation message{};
message.FormID = packet.FormID;
message.Animation = packet.Animation;
message.EventName = packet.EventName;
Expand Down

0 comments on commit 6e042c1

Please sign in to comment.