Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding new functions: NWNX_ON_PLACEABLE_OPEN_{OPEN|CLOSE}_{BEFORE|AFTER} #1691

Merged
merged 15 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ https://github.com/nwnxee/unified/compare/build8193.35.40...HEAD
- Events: added event `NWNX_ON_SPELL_FAILED_{BEFORE|AFTER}` which fires when the casting of a spell did not finish for any reason.
- Tweaks: added `NWNX_TWEAKS_FIX_AUTOMAP_CRASH` which fixes a server crash that happens when automap data is outdated for a player.
- Events: added event `NWNX_ON_ATTACK_TARGET_CHANGE_{BEFORE|AFTER}` which fires when a creature changes its attack target.
- Events: added `NWNX_ON_PLACEABLE_OPEN_{BEFORE|AFTER}` which fires when player opens a placeable.
- Events: added `NWNX_ON_PLACEABLE_CLOSE_{BEFORE|AFTER}` which fires when player closes a placeable.

##### New Plugins
- Resources: Adds `RESOURCES_*` variables for adding NWSync as a resource source, and specifying a replacement hak list.
Expand Down
49 changes: 49 additions & 0 deletions Plugins/Events/Events/ObjectEvents.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Events.hpp"
#include "API/CNWSObject.hpp"
#include "API/CNWSPlaceable.hpp"

namespace Events {

Expand All @@ -10,11 +11,15 @@ using namespace NWNXLib::API::Constants;
static NWNXLib::Hooks::Hook s_AddLockObjectActionHook;
static NWNXLib::Hooks::Hook s_AddUnlockObjectActionHook;
static NWNXLib::Hooks::Hook s_AddUseObjectActionHook;
static NWNXLib::Hooks::Hook s_OpenInventoryHook;
static NWNXLib::Hooks::Hook s_CloseInventoryHook;
static NWNXLib::Hooks::Hook s_BroadcastSafeProjectileHook;

static int32_t AddLockObjectActionHook(CNWSObject*, ObjectID);
static int32_t AddUnlockObjectActionHook(CNWSObject*, ObjectID, ObjectID, int32_t);
static int32_t AddUseObjectActionHook(CNWSObject*, ObjectID);
static void OpenInventoryHook(CNWSPlaceable*, ObjectID);
static void CloseInventoryHook(CNWSPlaceable*, ObjectID, BOOL);
static void BroadcastSafeProjectileHook(CNWSObject*, ObjectID, ObjectID, Vector, Vector, uint32_t, uint8_t, uint32_t, uint8_t, uint8_t);

void ObjectEvents() __attribute__((constructor));
Expand All @@ -34,6 +39,16 @@ void ObjectEvents()
s_AddUseObjectActionHook = Hooks::HookFunction(&CNWSObject::AddUseObjectAction,
(void*)&AddUseObjectActionHook, Hooks::Order::Early);
});

InitOnFirstSubscribe("NWNX_ON_PLACEABLE_OPEN_.*", []() {
s_OpenInventoryHook = Hooks::HookFunction(&CNWSPlaceable::OpenInventory,
(void*)&OpenInventoryHook, Hooks::Order::Early);
});

InitOnFirstSubscribe("NWNX_ON_PLACEABLE_CLOSE_.*", []() {
s_CloseInventoryHook = Hooks::HookFunction(&CNWSPlaceable::CloseInventory,
(void*)&CloseInventoryHook, Hooks::Order::Early);
});

InitOnFirstSubscribe("NWNX_ON_BROADCAST_SAFE_PROJECTILE_.*", []() {
s_BroadcastSafeProjectileHook = Hooks::HookFunction(&CNWSObject::BroadcastSafeProjectile,
Expand Down Expand Up @@ -117,6 +132,40 @@ int32_t AddUseObjectActionHook(CNWSObject *thisPtr, ObjectID oidObjectToUse)
return retVal;
}

void OpenInventoryHook(CNWSPlaceable *thisPtr, ObjectID oidOpener)
{
auto PushAndSignal = [&](const std::string& ev) -> bool {
PushEventData("OBJECT", Utils::ObjectIDToString(oidOpener));
return SignalEvent(ev, thisPtr->m_idSelf);
};

bool skipped = false;
if (PushAndSignal("NWNX_ON_PLACEABLE_OPEN_BEFORE"))
{
s_OpenInventoryHook->CallOriginal<int32_t>(thisPtr, oidOpener);
}
else
{
skipped = true;
}

PushEventData("BEFORE_SKIPPED", std::to_string(skipped));
PushAndSignal("NWNX_ON_PLACEABLE_OPEN_AFTER");
}

void CloseInventoryHook(CNWSPlaceable *thisPtr, ObjectID oidCloser, BOOL bUpdatePlayer = true)
{
auto PushAndSignal = [&](const std::string& ev) -> bool {
PushEventData("OBJECT", Utils::ObjectIDToString(oidCloser));
return SignalEvent(ev, thisPtr->m_idSelf);
};

// don't allow SkipEvent on close event, otherwise it hangs client ui.
PushAndSignal("NWNX_ON_PLACEABLE_CLOSE_BEFORE");
s_CloseInventoryHook->CallOriginal<int32_t>(thisPtr, oidCloser, bUpdatePlayer);
PushAndSignal("NWNX_ON_PLACEABLE_CLOSE_AFTER");
}

void BroadcastSafeProjectileHook(CNWSObject *thisPtr, ObjectID oidOriginator, ObjectID oidTarget, Vector vOriginator, Vector vTarget, uint32_t nDelta,
uint8_t nProjectileType, uint32_t nSpellID, uint8_t nAttackResult, uint8_t nProjectilePathType)
{
Expand Down
27 changes: 27 additions & 0 deletions Plugins/Events/NWScript/nwnx_events.nss
Original file line number Diff line number Diff line change
Expand Up @@ -1602,6 +1602,29 @@ _______________________________________
Event Data Tag | Type | Notes
----------------------|--------|-------
OBJECT | object | The Object being used |
_______________________________________
## Placeable Open Events (Placeables with inventory)
- NWNX_ON_PLACEABLE_OPEN_BEFORE
- NWNX_ON_PLACEABLE_OPEN_AFTER

`OBJECT_SELF` = The placeable being openeed.

Event Data Tag | Type | Notes
----------------------|--------|-------
OBJECT | object | The player opening. |
BEFORE_SKIPPED | int | TRUE/FALSE, only in _AFTER events|
_______________________________________
## Placeable Close Events (Placeables with inventory)
- NWNX_ON_PLACEABLE_CLOSE_BEFORE
- NWNX_ON_PLACEABLE_CLOSE_AFTER

`OBJECT_SELF` = The placeable being closed.

Event Data Tag | Type | Notes
----------------------|--------|-------
OBJECT | object | The player closing. |

@note Skipping event is not allowed (since otherwise client UI will hang and be glitchy)
_______________________________________
## Broadcast Safe Projectile Events
- NWNX_ON_BROADCAST_SAFE_PROJECTILE_BEFORE
Expand Down Expand Up @@ -2002,6 +2025,10 @@ const string NWNX_ON_RUN_EVENT_SCRIPT_BEFORE = "NWNX_ON_RUN_EVENT_SCRIPT_BEFORE"
const string NWNX_ON_RUN_EVENT_SCRIPT_AFTER = "NWNX_ON_RUN_EVENT_SCRIPT_AFTER";
const string NWNX_ON_OBJECT_USE_BEFORE = "NWNX_ON_OBJECT_USE_BEFORE";
const string NWNX_ON_OBJECT_USE_AFTER = "NWNX_ON_OBJECT_USE_AFTER";
const string NWNX_ON_PLACEABLE_OPEN_BEFORE = "NWNX_ON_PLACEABLE_OPEN_BEFORE";
const string NWNX_ON_PLACEABLE_OPEN_AFTER = "NWNX_ON_PLACEABLE_OPEN_AFTER";
const string NWNX_ON_PLACEABLE_CLOSE_BEFORE = "NWNX_ON_PLACEABLE_CLOSE_BEFORE";
const string NWNX_ON_PLACEABLE_CLOSE_AFTER = "NWNX_ON_PLACEABLE_CLOSE_AFTER";
const string NWNX_ON_BROADCAST_SAFE_PROJECTILE_BEFORE = "NWNX_ON_BROADCAST_SAFE_PROJECTILE_BEFORE";
const string NWNX_ON_BROADCAST_SAFE_PROJECTILE_AFTER = "NWNX_ON_BROADCAST_SAFE_PROJECTILE_AFTER";
const string NWNX_ON_BROADCAST_ATTACK_OF_OPPORTUNITY_BEFORE = "NWNX_ON_BROADCAST_ATTACK_OF_OPPORTUNITY_BEFORE";
Expand Down