Open Darsiniux opened 1 month ago
Example of one of the scripts I wrote to fix monk speed.
#include "nwnx_events"
#include "nwnx_creature"
void main()
{
string sEvent = NWNX_Events_GetCurrentEvent();
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, OBJECT_SELF);
int iFeat = StringToInt(NWNX_Events_GetEventData("FEAT_ID"));
if(iFeat == FEAT_MONK_ENDURANCE)
{
if(sEvent == "NWNX_ON_USE_FEAT_BEFORE")
{
if(iMonk >= 3 && GetLocalInt(OBJECT_SELF, "ONE") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "ONE", TRUE);
}
if(iMonk >= 6 && GetLocalInt(OBJECT_SELF, "TWO") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "TWO", TRUE);
}
if(iMonk >= 9 && GetLocalInt(OBJECT_SELF, "THREE") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "THREE", TRUE);
}
if(iMonk == 12 && GetLocalInt(OBJECT_SELF, "FOUR") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "FOUR", TRUE);
}
if(iMonk == 15 && GetLocalInt(OBJECT_SELF, "FIVE") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "FIVE", TRUE);
}
if(iMonk == 18 && GetLocalInt(OBJECT_SELF, "SIX") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "SIX", TRUE);
}
if(iMonk == 21 && GetLocalInt(OBJECT_SELF, "SEVEN") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "SEVEN", TRUE);
}
if(iMonk == 24 && GetLocalInt(OBJECT_SELF, "EIGHT") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "EIGHT", TRUE);
}
if(iMonk == 27 && GetLocalInt(OBJECT_SELF, "NINE") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "NINE", TRUE);
}
if(iMonk == 30 && GetLocalInt(OBJECT_SELF, "TEN") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "TEN", TRUE);
}
if(iMonk == 33 && GetLocalInt(OBJECT_SELF, "ELEVEN") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "ELEVEN", TRUE);
}
if(iMonk == 36 && GetLocalInt(OBJECT_SELF, "TWELVE") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "TWELVE", TRUE);
}
if(iMonk == 39 && GetLocalInt(OBJECT_SELF, "THIRTEEN") == FALSE)
{
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, NWNX_Creature_GetMovementRateFactor(OBJECT_SELF)+0.10);
SetLocalInt(OBJECT_SELF, "THIRTEEN", TRUE);
}
NWNX_Events_SkipEvent();
}
}
}
Barbarian speed fix...
#include "nwnx_events"
#include "nwnx_creature"
void main()
{
// Initialize a variable to check the event data. Checks if user of the event is using the correct feat.
int iHasFeat = StringToInt(NWNX_Events_GetEventData("FEAT_ID"));
string sEvent = NWNX_Events_GetCurrentEvent();
if(sEvent == "NWNX_ON_USE_FEAT_BEFORE")
{
if(iHasFeat == FEAT_BARBARIAN_ENDURANCE)
{
float fSpeed = NWNX_Creature_GetMovementRateFactor(OBJECT_SELF) + 0.10;
NWNX_Creature_SetMovementRateFactor(OBJECT_SELF, fSpeed);
NWNX_Events_SkipEvent();
}
}
}
While doing all this I also realized that the vanilla NWN monk speed is completely bugged at level 15 monk. It doesn't apply the correct movement speed. Also, when you use a haste item with barbarian, and then remove the haste item, the barbarian speed isn't retained where it should be at 1.1 without haste.
Unfortunately, none of the above fixes work when a vanilla speed increase/decrease occurs from encumberance, haste, slow, grease, acid fog, or any other thing effecting speed in the base game. I was literally in the process of rewriting everything but it's pointless when you can't do anything about encumberance. I was about to redo everything including called shot leg.
NWNX_Creature_SetMovementRateFactorCap causes lots of bugs to happen.
I even re-wrote the vanilla nwn haste property.
#include "nwnx_events"
#include "nwnx_effect"
#include "nwnx_creature"
// Skips the haste item property on items and replaces it.
void main()
{
string sEvent = NWNX_Events_GetCurrentEvent();
int iProperty = StringToInt(NWNX_Events_GetEventData("PROPERTY"));
object oPC = StringToObject(NWNX_Events_GetEventData("CREATURE"));
int bLoading = StringToInt(NWNX_Events_GetEventData("LOADING_GAME"));
effect eAPR = ExtraordinaryEffect(EffectModifyAttacks(1));
effect eHaste = ExtraordinaryEffect(EffectIcon(EFFECT_ICON_HASTE));
effect eHasteAC = ExtraordinaryEffect(EffectACIncrease(4));
if(sEvent == NWNX_ON_ITEMPROPERTY_EFFECT_APPLIED_BEFORE)
{
if(StringToInt(NWNX_Events_GetEventData("PROPERTY")) == ITEM_PROPERTY_HASTE)
{
if(GetLocalInt(oPC, "SPEED") == FALSE)
{
if(!bLoading)
{
ApplyEffectToObject(DURATION_TYPE_EQUIPPED, eAPR, oPC);
ApplyEffectToObject(DURATION_TYPE_EQUIPPED, eHaste, oPC);
ApplyEffectToObject(DURATION_TYPE_EQUIPPED, eHasteAC, oPC);
NWNX_Creature_SetMovementRateFactor(oPC, NWNX_Creature_GetMovementRateFactor(oPC) + 0.50);
SetLocalInt(oPC, "SPEED", TRUE);
//SendMessageToPC(oEquipped, "APPLIED BEFORE.");
}
}
NWNX_Events_SkipEvent();
}
}
if(sEvent == NWNX_ON_ITEMPROPERTY_EFFECT_REMOVED_AFTER)
{
if(iProperty == ITEM_PROPERTY_HASTE)
{
if(GetLocalInt(oPC, "SPEED") == TRUE)
{
RemoveEffect(oPC, ExtraordinaryEffect(EffectModifyAttacks(1)));
RemoveEffect(oPC, ExtraordinaryEffect(EffectIcon(EFFECT_ICON_HASTE)));
RemoveEffect(oPC, ExtraordinaryEffect(EffectACIncrease(4)));
NWNX_Creature_SetMovementRateFactor(oPC, NWNX_Creature_GetMovementRateFactor(oPC) - 0.50);
SetLocalInt(oPC, "SPEED", FALSE);
//SendMessageToPC(oEquipped, "REMOVED AFTER.");
}
}
}
}
Am I just using these wrong? Is there a better way to do all this without running into problems? It's so bugged in so many ways that it begs the question what is this even used for?
Need a way to replace the base games movement speed decrease with an event that uses the nwnx_creature functions to reduce the speed instead.
Either that or encumbrance events are needed like ENCUMBERED_BEFORE and NOT_ENCUMBERED_AFTER.
Does anybody know what LimitMovementSpeed = 59 is?? I was hoping it was for encumber but it's not. https://github.com/nwnxee/unified/blob/master/NWNXLib/API/Constants/Effect.hpp#L8 |
I incorrectly stated that the vanilla NWN stuff with movement speed is bugged. It's only bugged when you increase the movement rate cap with the nwnx_creature function, NWNX_Creature_SetMovementRateFactorCap(oPC, 3.0);
I thought it was vanilla NWN because I forgot to remove the cap increase.
It would probably be simpler for you to hook GetMovementRateFactor and do your own thing there and not modify what the game thinks obj->cre_move_rate
should be, no clue what the actual variable is named.
Here is an example in Lua from an older project:
local Hook = require 'solstice.hooks'
local ffi = require 'ffi'
local C = ffi.C
local max = math.max
-- CNWSCreature::GetMovementRateFactor(void) 0x08123FD8
local Orig_GetMovementRateFactor
local function Hook_GetMovementRateFactor(obj)
local cre = Game.GetObjectByID(obj.obj.obj_id)
if cre:GetType() == OBJECT_TYPE_CREATURE then
local mo, ba, ta = 0, 0, 0
local can, level = Rules.CanUseClassAbilities(cre, CLASS_TYPE_MONK)
if can and level > 3 then
mo = 0.2
end
if cre:GetLevelByClass(CLASS_TYPE_BARBARIAN) >= 1 then
ba = 0.1
end
ta = (cre['TA_MOVE_SPEED'] or 0) / 100 -- This is where you'd add in your custom factors, I used a local var
local mr = obj.cre_move_rate
if mr > 1.5 then mr = 1.5 end
return mr + ta + max(mo, ba)
end
return Orig_GetMovementRateFactor(cre)
end
Orig_GetMovementRateFactor = Hook.hook {
name = "GetMovementRateFactor",
func = Hook_GetMovementRateFactor,
length = 5,
address = 0x08123FD8,
type = 'double (*)(CNWSCreature *)',
}
Hi, great work on all these functions. I really appreciate what you guys did here. I'm posting because i'm having a bit of trouble understanding how i'm supposed to be using the NWNX_Creature_SetMovementRateFactor & NWNX_Creature_GetMovementRateFactor. No matter what I do I run into a laundry list of bugs. When I use these functions with the base NWN EffectMovementSpeedIncrease it causes issues with barbarian speed & monk speed among other things. They don't work well with the vanilla NWN haste property either. I literally attempted to rewrite every spell/feat, and even the haste itemproperty to make this work before realizing that I have no way of dealing with encumbrance causing a movement speed decrease which breaks everything.