Skip to content

Commit

Permalink
GetObjectAtConnectPoint, fixes ObjectReference.GetConnectPointsLatent…
Browse files Browse the repository at this point in the history
…, TransmitConnectedPowerLatent (thanks shad0wshayd3)
  • Loading branch information
ianpatt committed May 13, 2024
1 parent 21ed592 commit 7ad9b82
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 17 deletions.
65 changes: 65 additions & 0 deletions f4se/GameWorkshop.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "f4se/GameWorkshop.h"
#include "f4se/GameAPI.h"

RelocAddr <PowerUtils::_UpdateMovingWirelessItem> PowerUtils::UpdateMovingWirelessItem(0x0033A570); // Usually paired with LinkPower
// this was inlined everywhere
Expand All @@ -12,3 +13,67 @@ RelocAddr <Workshop::_ScrapReference> Workshop::ScrapReference(0x0033F7F0);

RelocPtr<BSPointerHandle<TESObjectREFR>> Workshop::hCurrentWorkshop(0x02E75154);
RelocAddr<Workshop::_FindNearestValidWorkshop> Workshop::FindNearestValidWorkshop(0x00330FE0);

namespace BSConnectPoint
{
class Parent :
public BSIntrusiveRefCounted
{
public:
// members
BSAutoFixedString parentName; // 08
BSAutoFixedString name; // 10
NiQuaternion rotation; // 18
NiPoint3 position; // 28
float scale; // 34

void Release()
{
if(!InterlockedDecrement(&m_refCount))
{
this->~Parent();
Heap_Free(this);
}
}
};
STATIC_ASSERT(sizeof(Parent) == 0x38);
}

enum SnappedReferencePointStatusEnum : std::int32_t
{
kNoReference = 0,
kNoSnapPoint,
kSnapPointFound,
kNonReferenceHit,
kCount
};

struct SnappedReferencePointStatus
{
public:
~SnappedReferencePointStatus()
{
// in clib this would be easy, kludge it up here
if(foundSnapPoint)
foundSnapPoint->Release();
}

// members
SnappedReferencePointStatusEnum status{ SnappedReferencePointStatusEnum::kCount }; // 00
BSConnectPoint::Parent * foundSnapPoint{ nullptr }; // 08 - BSTSmartPointer
};

STATIC_ASSERT(sizeof(SnappedReferencePointStatus) == 0x10);

TESObjectREFR * GetSnappedReferenceImpl(const TESObjectREFR & a_refr, const NiPoint3 & a_connectPointWS, const bhkWorld & a_physicsWorld, SnappedReferencePointStatus & a_status, float a_radius)
{
using func_t = decltype(&GetSnappedReferenceImpl);
RelocAddr <func_t> func(0x00369CC0);
return func(a_refr, a_connectPointWS, a_physicsWorld, a_status, a_radius);
}

TESObjectREFR * GetObjectAtConnectPoint(const TESObjectREFR & a_refr, NiPoint3 & a_connectPointWS, const bhkWorld & a_physicsWorld, float a_radius)
{
SnappedReferencePointStatus status;
return GetSnappedReferenceImpl(a_refr, a_connectPointWS, a_physicsWorld, status, a_radius);
}
4 changes: 1 addition & 3 deletions f4se/GameWorkshop.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,4 @@ typedef void(*_EstablishTerminalLinks)(TESObjectREFR* akWireRef);
extern RelocAddr <_EstablishTerminalLinks> EstablishTerminalLinks;
}

typedef TESObjectREFR * (*_GetObjectAtConnectPoint)(TESObjectREFR * source, NiPoint3 * connectPos, bhkWorld * world, float unk1);
extern RelocAddr <_GetObjectAtConnectPoint> GetObjectAtConnectPoint;

TESObjectREFR * GetObjectAtConnectPoint(const TESObjectREFR & source, NiPoint3 & connectPos, const bhkWorld & world, float radius);
14 changes: 2 additions & 12 deletions f4se/PapyrusObjectReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ namespace papyrusObjectReference {

TESObjectREFR* AttachWireLatent(UInt32 stackId, TESObjectREFR* refA, TESObjectREFR* refB, TESForm* splineForm)
{
// disabled, needs rework after 1.10.980
#if 0
TESObjectREFR * wireRef = nullptr;
VirtualMachine* vm = (*g_gameVM)->m_virtualMachine;

Expand Down Expand Up @@ -190,8 +188,6 @@ namespace papyrusObjectReference {

*Workshop::hCurrentWorkshop = currentWorkshop;
return wireRef;
#endif
return nullptr;
}

DECLARE_DELAY_FUNCTOR(F4SEAttachWireFunctor, 2, AttachWireLatent, TESObjectREFR, TESObjectREFR*, TESObjectREFR*, TESForm*);
Expand Down Expand Up @@ -443,13 +439,10 @@ namespace papyrusObjectReference {
if(parent != root && refr->parentCell) {
bhkWorld * world = CALL_MEMBER_FN(refr->parentCell, GetHavokWorld)();
if(world) {
// needs rework for 1.10.980
#if 0
TESObjectREFR * connected = GetObjectAtConnectPoint(refr, &worldPos, world, 8.0f);
TESObjectREFR * connected = GetObjectAtConnectPoint(*refr, worldPos, *world, 8.0f);
if(connected) {
point.Set<TESObjectREFR*>("object", connected);
}
#endif
}
}

Expand Down Expand Up @@ -540,9 +533,7 @@ namespace papyrusObjectReference {
if(parent != root && refr->parentCell) {
bhkWorld * world = CALL_MEMBER_FN(refr->parentCell, GetHavokWorld)();
if(world) {
// disabled for rework after 1.10.980
#if 0
TESObjectREFR * connected = GetObjectAtConnectPoint(refr, &worldPos, world, 8.0f);
TESObjectREFR * connected = GetObjectAtConnectPoint(*refr, worldPos, *world, 8.0f);
if(connected) {
try // Probably wont make a difference but doesnt hurt to try
{
Expand All @@ -554,7 +545,6 @@ namespace papyrusObjectReference {
_MESSAGE("Power link error!");
}
}
#endif
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions f4se_whatsnew.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
0.7.2
- support for runtime 1.10.984 "next generation" hotfix
- support for runtime 1.10.984
- fix loading some plugins with additional exports
- remove user-facing text referencing starfield
- SplineUtils::ConnectSpline
- SplineUtils::ConnectSpline (fixes ObjectReference.AttachWireLatent)
- fix BSHash::operator() generic specialization
- GetObjectAtConnectPoint, fixes ObjectReference.GetConnectPointsLatent, TransmitConnectedPowerLatent (thanks shad0wshayd3)

0.7.1
- fix GetGameSetting and related functions
Expand Down

0 comments on commit 7ad9b82

Please sign in to comment.