Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
void StickyCombatModes::SetCombatModeHook(API::CNWSCreature* thisPtr, uint8_t newMode, bool forceNewMode)
{
if (thisPtr->m_bPlayerCharacter)
{
if (g_plugin->ShouldSkip(thisPtr, newMode))
{
return;
}
const uint8_t currentMode = thisPtr->m_nCombatMode;
if (g_plugin->m_dispatchMessages && currentMode != newMode)
{
// ToggleMode gets called with modes which are +1 to what the script constants expect.
// It then calls SetCombatMode with the 'proper' modes.
// To simplify things, we just correct the mode we dispatch here, so the game events
// receive what they expect to.
auto messaging = g_plugin->GetServices()->m_messaging.get();
if (currentMode != 0)
{
messaging->BroadcastMessage("NWNX_EVENT_PUSH_EVENT_DATA", { "MODE", std::to_string(currentMode + 1) } );
messaging->BroadcastMessage("NWNX_EVENT_SIGNAL_EVENT", { "NWNX_ON_MODE_OFF", ObjectIDToString(thisPtr->m_idSelf) });
}
if (newMode != 0)
{
messaging->BroadcastMessage("NWNX_EVENT_PUSH_EVENT_DATA", { "MODE", std::to_string(newMode + 1) } );
messaging->BroadcastMessage("NWNX_EVENT_SIGNAL_EVENT", { "NWNX_ON_MODE_ON", ObjectIDToString(thisPtr->m_idSelf) });
}
}
}
return g_setCombatModeHook->CallOriginal<void>(thisPtr, newMode, forceNewMode);
}
MI::TMI(const Plugin::CreateParams& params)
: Plugin(params)
{
using namespace NWNXLib::Services;
GetServices()->m_events->RegisterEvent("GET_TMI", [this](Events::ArgumentStack&&)
{
Events::ArgumentStack stack;
Events::InsertArgument(stack, GetTMI());
return stack;
});
GetServices()->m_events->RegisterEvent("SET_TMI", [this](Events::ArgumentStack&& args)
{
SetTMI(Events::ExtractArgument<int32_t>(args));
return Events::ArgumentStack();
});
SetTMI(GetTMI() * GetServices()->m_config->Get<int32_t>("MULTIPLIER", 1));
}
TMI::~TMI()
{
}
int32_t TMI::GetTMI()
{
int32_t tmi = 0;
memcpy(&tmi, reinterpret_cast<int32_t*>(TMI_ADDR), 4);
return tmi;
}
void TMI::SetTMI(const int32_t newTmi)
{
if (GetServices()->m_patching->PatchExists(TMI_ADDR))
{
GetServices()->m_patching->ClearPatch(TMI_ADDR);
}
GetServices()->m_patching->PatchWithValue(TMI_ADDR, newTmi);
}
//The patching service is very flexible. You can do stuff like ...
patcher->PatchWithCall(0x0804BBEE, 0x0804BBFE - 0x0804BBEE, &SleepTiming); NWNX_EXPECT_VERSION(8109);
//Or ...
patcher->PatchWithNoop(0x08096164, 0x08096169 - 0x08096164); NWNX_EXPECT_VERSION(8109);
GetServices()->m_patching->PatchWithInstructionsTrampoline(0x0807340D, 0x08073418 - 0x0807340D,
PushRegMemByteInstruction(Register::EBP, 16), // pAreaObject
PushRegMemByteInstruction(Register::EBP, 12), // pPlayer
CallRelInstruction(&ClientToPlayerID),
AddRegImmByteInstruction(Register::ESP, 4),
PushRegInstruction(Register::EAX),
PushRegMemByteInstruction(Register::EBP, 8), // this
CallRelInstruction(&WriteLastName)
); NWNX_EXPECT_VERSION(8109);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.