Skip to content

Commit

Permalink
Sync AttachArrow events
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbeBryssinck committed Oct 3, 2021
1 parent e2485c7 commit d665a43
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 4 deletions.
10 changes: 10 additions & 0 deletions Code/client/Events/ArrowAttachedEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

struct ArrowAttachedEvent
{
ArrowAttachedEvent(uint32_t aFormID) : FormID(aFormID)
{
}

uint32_t FormID;
};
2 changes: 2 additions & 0 deletions Code/client/Games/Animation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ uint8_t TP_MAKE_THISCALL(HookPerformAction, ActorMediator, TESActionData* apActi
action.TargetEventName = apAction->targetEventName.AsAscii();
action.IdleId = apAction->idleForm ? apAction->idleForm->formID : 0;

/*
if (apAction->eventName.AsAscii() != String("") || apAction->targetEventName.AsAscii() != String(""))
spdlog::info("Animation triggered, eventName: '{}', targetEventName: '{}'", apAction->eventName.AsAscii(),
apAction->targetEventName.AsAscii());
*/

// Save for later
if (res)
Expand Down
26 changes: 26 additions & 0 deletions Code/client/Games/Skyrim/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <Events/HealthChangeEvent.h>
#include <Events/InventoryChangeEvent.h>
#include <Events/ArrowAttachedEvent.h>

#include <World.h>
#include <Services/PapyrusService.h>
Expand Down Expand Up @@ -75,6 +76,7 @@ TP_THIS_FUNCTION(TCharacterConstructor2, Actor*, Actor, uint8_t aUnk);
TP_THIS_FUNCTION(TCharacterDestructor, Actor*, Actor);
TP_THIS_FUNCTION(TAddInventoryItem, void, Actor, TESBoundObject* apItem, BSExtraDataList* apExtraData, uint32_t aCount, TESObjectREFR* apOldOwner);
TP_THIS_FUNCTION(TPickUpItem, void*, Actor, TESObjectREFR* apObject, int32_t aCount, bool aUnk1, float aUnk2);
TP_THIS_FUNCTION(TAttachArrow, void, Actor, void*);

using TGetLocation = TESForm *(TESForm *);
static TGetLocation *FUNC_GetActorLocation;
Expand All @@ -85,6 +87,7 @@ TCharacterDestructor* RealCharacterDestructor;

static TAddInventoryItem* RealAddInventoryItem = nullptr;
static TPickUpItem* RealPickUpItem = nullptr;
static TAttachArrow* RealAttachArrow = nullptr;

Actor* TP_MAKE_THISCALL(HookCharacterConstructor, Actor)
{
Expand Down Expand Up @@ -403,6 +406,17 @@ void Actor::Respawn() noexcept
Reset();
}

/*
void* Actor::GetBiped() const noexcept
{
TP_THIS_FUNCTION(TGetBiped, void*, Actor);
POINTER_SKYRIMSE(TGetBiped, s_getBiped, 0x140693DF0 - 0x140000000);
ThisCall(s_getBiped, this);
}
*/

TP_THIS_FUNCTION(TForceState, void, Actor, const NiPoint3&, float, float, TESObjectCELL*, TESWorldSpace*, bool);
static TForceState* RealForceState = nullptr;

Expand Down Expand Up @@ -528,6 +542,15 @@ void* TP_MAKE_THISCALL(HookPickUpItem, Actor, TESObjectREFR* apObject, int32_t a
return ThisCall(RealPickUpItem, apThis, apObject, aCount, aUnk1, aUnk2);
}

void TP_MAKE_THISCALL(HookAttachArrow, Actor, void* apBiped)
{
const auto pExActor = apThis->GetExtension();
if (pExActor->IsLocal())
World::Get().GetRunner().Trigger(ArrowAttachedEvent(apThis->formID));

ThisCall(RealAttachArrow, apThis, apBiped);
}

static TiltedPhoques::Initializer s_actorHooks([]()
{
POINTER_SKYRIMSE(TCharacterConstructor, s_characterCtor, 0x1406928C0 - 0x140000000);
Expand All @@ -541,6 +564,7 @@ static TiltedPhoques::Initializer s_actorHooks([]()
POINTER_SKYRIMSE(TRegenAttributes, s_regenAttributes, 0x140620900 - 0x140000000);
POINTER_SKYRIMSE(TAddInventoryItem, s_addInventoryItem, 0x1405E6F20 - 0x140000000);
POINTER_SKYRIMSE(TPickUpItem, s_pickUpItem, 0x1405E6580 - 0x140000000);
POINTER_SKYRIMSE(TAttachArrow, s_attachArrow, 0x140624090 - 0x140000000);

FUNC_GetActorLocation = s_GetActorLocation.Get();
RealCharacterConstructor = s_characterCtor.Get();
Expand All @@ -552,6 +576,7 @@ static TiltedPhoques::Initializer s_actorHooks([]()
RealRegenAttributes = s_regenAttributes.Get();
RealAddInventoryItem = s_addInventoryItem.Get();
RealPickUpItem = s_pickUpItem.Get();
RealAttachArrow = s_attachArrow.Get();

TP_HOOK(&RealCharacterConstructor, HookCharacterConstructor);
TP_HOOK(&RealCharacterConstructor2, HookCharacterConstructor2);
Expand All @@ -562,5 +587,6 @@ static TiltedPhoques::Initializer s_actorHooks([]()
TP_HOOK(&RealRegenAttributes, HookRegenAttributes);
TP_HOOK(&RealAddInventoryItem, HookAddInventoryItem);
TP_HOOK(&RealPickUpItem, HookPickUpItem);
TP_HOOK(&RealAttachArrow, HookAttachArrow);

});
5 changes: 4 additions & 1 deletion Code/client/Games/Skyrim/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ struct Actor : TESObjectREFR
virtual void sub_CA();
virtual void sub_CB();
virtual void sub_CC();
virtual void AttachArrow();
virtual void AttachArrow(void* apBiped);
virtual void sub_CE();
virtual void sub_CF();
virtual void sub_D0();
Expand Down Expand Up @@ -170,6 +170,9 @@ struct Actor : TESObjectREFR
virtual void sub_125();
virtual void sub_126();
virtual void sub_127();

// Should be virtual
//void* GetBiped() const noexcept;

// Real functions
void DualCastSpell(TESObjectREFR* apDesiredTarget);
Expand Down
2 changes: 1 addition & 1 deletion Code/client/Games/Skyrim/TESObjectREFR.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ struct TESObjectREFR : TESForm
virtual void sub_7C();
virtual void sub_7D();
virtual void* sub_7E(bool aUnk);
virtual void sub_7F();
virtual void* GetBiped();
virtual void sub_80();
virtual void sub_81();
virtual void sub_82();
Expand Down
6 changes: 6 additions & 0 deletions Code/client/Services/CharacterService.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ struct NotifySpawnData;
struct NotifyOwnershipTransfer;
struct SpellCastEvent;
struct NotifySpellCast;
struct ArrowAttachedEvent;
struct NotifyAttachArrow;

struct Actor;
struct World;
Expand Down Expand Up @@ -44,6 +46,8 @@ struct CharacterService
void OnRemoteSpawnDataReceived(const NotifySpawnData& acEvent) const noexcept;
void OnSpellCastEvent(const SpellCastEvent& acSpellCastEvent) const noexcept;
void OnNotifySpellCast(const NotifySpellCast& acMessage) const noexcept;
void OnArrowAttachedEvent(const ArrowAttachedEvent& acEvent) const noexcept;
void OnNotifyAttachArrow(const NotifyAttachArrow& acMessage) const noexcept;

private:

Expand Down Expand Up @@ -76,4 +80,6 @@ struct CharacterService
entt::scoped_connection m_remoteSpawnDataReceivedConnection;
entt::scoped_connection m_spellCastEventConnection;
entt::scoped_connection m_notifySpellCastConnection;
entt::scoped_connection m_arrowAttachedEvent;
entt::scoped_connection m_notifyAttachArrowConnection;
};
61 changes: 61 additions & 0 deletions Code/client/Services/Generic/CharacterService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <Events/EquipmentChangeEvent.h>
#include <Events/UpdateEvent.h>
#include <Events/SpellCastEvent.h>
#include <Events/ArrowAttachedEvent.h>

#include <Structs/ActionEvent.h>
#include <Messages/CancelAssignmentRequest.h>
Expand All @@ -50,6 +51,8 @@
#include <Messages/RequestOwnershipClaim.h>
#include <Messages/SpellCastRequest.h>
#include <Messages/NotifySpellCast.h>
#include <Messages/AttachArrowRequest.h>
#include <Messages/NotifyAttachArrow.h>

#include <World.h>
#include <Games/TES.h>
Expand Down Expand Up @@ -80,6 +83,8 @@ CharacterService::CharacterService(World& aWorld, entt::dispatcher& aDispatcher,
m_remoteSpawnDataReceivedConnection = m_dispatcher.sink<NotifySpawnData>().connect<&CharacterService::OnRemoteSpawnDataReceived>(this);
m_spellCastEventConnection = m_dispatcher.sink<SpellCastEvent>().connect<&CharacterService::OnSpellCastEvent>(this);
m_notifySpellCastConnection = m_dispatcher.sink<NotifySpellCast>().connect<&CharacterService::OnNotifySpellCast>(this);
m_arrowAttachedEvent = m_dispatcher.sink<ArrowAttachedEvent>().connect<&CharacterService::OnArrowAttachedEvent>(this);
m_notifyAttachArrowConnection = m_dispatcher.sink<NotifyAttachArrow>().connect<&CharacterService::OnNotifyAttachArrow>(this);
}

void CharacterService::OnFormIdComponentAdded(entt::registry& aRegistry, const entt::entity aEntity) const noexcept
Expand Down Expand Up @@ -1063,3 +1068,59 @@ void CharacterService::OnNotifySpellCast(const NotifySpellCast& acMessage) const
}
#endif
}

void CharacterService::OnArrowAttachedEvent(const ArrowAttachedEvent& acEvent) const noexcept
{
#if TP_SKYRIM64
uint32_t formId = acEvent.FormID;

auto view = m_world.view<FormIdComponent, LocalComponent>();
const auto shooterEntityIt = std::find_if(std::begin(view), std::end(view), [formId, view](entt::entity entity)
{
return view.get<FormIdComponent>(entity).Id == formId;
});

if (shooterEntityIt == std::end(view))
return;

auto& localComponent = view.get<LocalComponent>(*shooterEntityIt);

AttachArrowRequest request;
request.ShooterId = localComponent.Id;

spdlog::info("Sending attach arrow request for {:X}", localComponent.Id);

m_transport.Send(request);
#endif
}

void CharacterService::OnNotifyAttachArrow(const NotifyAttachArrow& acMessage) const noexcept
{
#if TP_SKYRIM64
auto remoteView = m_world.view<RemoteComponent, FormIdComponent>();
const auto remoteIt = std::find_if(std::begin(remoteView), std::end(remoteView), [remoteView, Id = acMessage.ShooterId](auto entity)
{
return remoteView.get<RemoteComponent>(entity).Id == Id;
});

if (remoteIt == std::end(remoteView))
{
spdlog::warn("Shooter with remote id {:X} not found.", acMessage.ShooterId);
return;
}

auto formIdComponent = remoteView.get<FormIdComponent>(*remoteIt);

auto* pForm = TESForm::GetById(formIdComponent.Id);
auto* pActor = RTTI_CAST(pForm, TESForm, Actor);

void* pBiped = pActor->GetBiped();
pActor->AttachArrow(pBiped);

// TODO: set attack state flags when attaching arrow? look at ArrowAttachHandler
pActor->actorState.flags1 &= 0xFFFFFFFu;
pActor->actorState.flags1 |= 0x90000000;

spdlog::info("Attached arrow");
#endif
}
13 changes: 13 additions & 0 deletions Code/encoding/Messages/AttachArrowRequest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <Messages/AttachArrowRequest.h>

void AttachArrowRequest::SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept
{
Serialization::WriteVarInt(aWriter, ShooterId);
}

void AttachArrowRequest::DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept
{
ClientMessage::DeserializeRaw(aReader);

ShooterId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF;
}
25 changes: 25 additions & 0 deletions Code/encoding/Messages/AttachArrowRequest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "Message.h"

#include <Structs/GameId.h>

struct AttachArrowRequest final : ClientMessage
{
static constexpr ClientOpcode Opcode = kAttachArrowRequest;

AttachArrowRequest() : ClientMessage(Opcode)
{
}

void SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept override;
void DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept override;

bool operator==(const AttachArrowRequest& acRhs) const noexcept
{
return ShooterId == acRhs.ShooterId &&
GetOpcode() == acRhs.GetOpcode();
}

uint32_t ShooterId;
};
3 changes: 2 additions & 1 deletion Code/encoding/Messages/ClientMessageFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <Messages/RequestOwnershipClaim.h>
#include <Messages/RequestObjectInventoryChanges.h>
#include <Messages/SpellCastRequest.h>
#include <Messages/AttachArrowRequest.h>

using TiltedPhoques::UniquePtr;

Expand All @@ -46,7 +47,7 @@ struct ClientMessageFactory
RequestActorValueChanges, RequestActorMaxValueChanges, EnterExteriorCellRequest,
RequestHealthChangeBroadcast, RequestSpawnData, ActivateRequest, LockChangeRequest,
AssignObjectsRequest, RequestDeathStateChange, ShiftGridCellRequest, RequestOwnershipTransfer,
RequestOwnershipClaim, RequestObjectInventoryChanges, SpellCastRequest>;
RequestOwnershipClaim, RequestObjectInventoryChanges, SpellCastRequest, AttachArrowRequest>;

return s_visitor(std::forward<T>(func));
}
Expand Down
13 changes: 13 additions & 0 deletions Code/encoding/Messages/NotifyAttachArrow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <Messages/NotifyAttachArrow.h>

void NotifyAttachArrow::SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept
{
Serialization::WriteVarInt(aWriter, ShooterId);
}

void NotifyAttachArrow::DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept
{
ServerMessage::DeserializeRaw(aReader);

ShooterId = Serialization::ReadVarInt(aReader) & 0xFFFFFFFF;
}
23 changes: 23 additions & 0 deletions Code/encoding/Messages/NotifyAttachArrow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include "Message.h"

struct NotifyAttachArrow final : ServerMessage
{
static constexpr ServerOpcode Opcode = kNotifyAttachArrow;

NotifyAttachArrow() : ServerMessage(Opcode)
{
}

void SerializeRaw(TiltedPhoques::Buffer::Writer& aWriter) const noexcept override;
void DeserializeRaw(TiltedPhoques::Buffer::Reader& aReader) noexcept override;

bool operator==(const NotifyAttachArrow& acRhs) const noexcept
{
return ShooterId == acRhs.ShooterId &&
GetOpcode() == acRhs.GetOpcode();
}

uint32_t ShooterId;
};
3 changes: 2 additions & 1 deletion Code/encoding/Messages/ServerMessageFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <Messages/NotifyOwnershipTransfer.h>
#include <Messages/NotifyObjectInventoryChanges.h>
#include <Messages/NotifySpellCast.h>
#include <Messages/NotifyAttachArrow.h>

using TiltedPhoques::UniquePtr;

Expand All @@ -44,7 +45,7 @@ struct ServerMessageFactory
NotifyPartyInfo, NotifyPartyInvite, NotifyActorValueChanges,
NotifyActorMaxValueChanges, NotifyHealthChangeBroadcast, NotifySpawnData, NotifyActivate,
NotifyLockChange, AssignObjectsResponse, NotifyDeathStateChange, NotifyOwnershipTransfer,
NotifyObjectInventoryChanges, NotifySpellCast>;
NotifyObjectInventoryChanges, NotifySpellCast, NotifyAttachArrow>;

return s_visitor(std::forward<T>(func));
}
Expand Down
2 changes: 2 additions & 0 deletions Code/encoding/Opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum ClientOpcode : unsigned char
kRequestObjectInventoryChanges,
kRequestCharacterInventoryChanges,
kSpellCastRequest,
kAttachArrowRequest,
kClientOpcodeMax
};

Expand Down Expand Up @@ -59,5 +60,6 @@ enum ServerOpcode : unsigned char
kNotifyObjectInventoryChanges,
kNotifyCharacterInventoryChanges,
kNotifySpellCast,
kNotifyAttachArrow,
kServerOpcodeMax
};
Loading

0 comments on commit d665a43

Please sign in to comment.