private int OnSendServerToPlayerPlayerListAdd(void *pMessage, uint nPlayerId, void *pNewPlayer) { if (PlayerListNameType == OverrideNameType.Original) { return(sendServerToPlayerPlayerListAddHook.CallOriginal(pMessage, nPlayerId, pNewPlayer)); } if (!ShowOverridesToDM && nPlayerId == PlayerIdConstants.AllGameMasters) { return(sendServerToPlayerPlayerListAddHook.CallOriginal(pMessage, nPlayerId, pNewPlayer)); } NwPlayer?observer = NwPlayer.FromPlayerId(nPlayerId); NwPlayer?target = CNWSPlayer.FromPointer(pNewPlayer).ToNwPlayer(); if (target == null) { return(sendServerToPlayerPlayerListAddHook.CallOriginal(pMessage, nPlayerId, pNewPlayer)); } PlayerNameOverride?nameOverride = GetPlayerNameOverride(target, observer); ApplyNameOverride(target, nameOverride, PlayerListNameType); int retVal = sendServerToPlayerPlayerListAddHook.CallOriginal(pMessage, nPlayerId, pNewPlayer); renameAddedToPlayerList.Add(target); RestoreNameOverride(target, nameOverride, PlayerListNameType); return(retVal); }
private float OnGetWalkRate(void *pCreature) { NwCreature?creature = CNWSCreature.FromPointer(pCreature).ToNwObject <NwCreature>(); if (creature == null) { return(walkRateHook.CallOriginal(pCreature)); } InternalVariableFloat rateCap = InternalVariables.WalkRateCap(creature); return(rateCap.HasValue ? rateCap.Value : walkRateHook.CallOriginal(pCreature)); }
private void OnObjectDestructor(void *pObject) { CNWSObject gameObject = CNWSObject.FromPointer(pObject); objectDestructorHook.CallOriginal(pObject); DestroyObjectStorage(gameObject); }
private int OnGetRangedDamageBonus(void *pStats) { int damageBonus = getRangedDamageBonusHook.CallOriginal(pStats); CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats); CNWSItem weapon = stats.m_pBaseCreature.m_pInventory.GetItemInSlot((uint)EquipmentSlot.RightHand); if (weapon == null) { return(damageBonus); } uint baseItem = weapon.m_nBaseItem; bool hasApplicableFeat = false; bool applicableFeatExists = greaterWeaponSpecializationMap.TryGetValue(baseItem, out HashSet <ushort>?types); if (applicableFeatExists) { foreach (ushort feat in types !) { hasApplicableFeat = stats.HasFeat(feat).ToBool(); if (hasApplicableFeat) { break; } } } if (applicableFeatExists && hasApplicableFeat) { return(damageBonus + GreaterWeaponSpecializationDamageBonus); } return(damageBonus); }
private void OnAreaDestructor(void *pArea) { CNWSArea area = CNWSArea.FromPointer(pArea); areaDestructorHook.CallOriginal(pArea); DestroyObjectStorage(area); }
private void OnRunScript(void *pDialog, void *pNWSObjectOwner, void *sScript, void *scriptParams) { dialog = CNWSDialog.FromPointer(pDialog); CurrentScriptType = ScriptType.ActionTaken; runScriptHook.CallOriginal(pDialog, pNWSObjectOwner, sScript, scriptParams); CurrentScriptType = ScriptType.Other; }
private int OnSendServerToPlayerDungeonMasterUpdatePartyList(void *pMessage, uint nPlayerID) { NwPlayer?observer = NwPlayer.FromPlayerId(nPlayerID); if (observer == null) { return(sendServerToPlayerDungeonMasterUpdatePartyListHook.CallOriginal(pMessage, nPlayerID)); } Dictionary <NwPlayer, PlayerNameOverride> nameOverrides = GetOverridesForObserver(observer, true); ApplyObserverOverrides(nameOverrides, PlayerListNameType); int retVal = sendServerToPlayerDungeonMasterUpdatePartyListHook.CallOriginal(pMessage, nPlayerID); RestoreObserverOverrides(nameOverrides, PlayerListNameType); return(retVal); }
private int OnLoadFromGff(void *pUUID, void *pRes, void *pStruct) { CNWSUUID uuid = CNWSUUID.FromPointer(pUUID); CResGFF resGff = CResGFF.FromPointer(pRes); CResStruct resStruct = CResStruct.FromPointer(pStruct); bool hasAnvilPos = resGff.TryReadCExoString(resStruct, AnvilGffFieldNamePtr, out CExoString anvilSerialized); bool hasNwnxPos = resGff.TryReadCExoString(resStruct, NWNXGffFieldNamePtr, out CExoString nwnxSerialized); if (!hasAnvilPos && !hasNwnxPos) { return(loadFromGffHook.CallOriginal(pUUID, pRes, pStruct)); } ObjectStorage storage = GetObjectStorage(uuid.m_parent); storage.Clear(); if (hasNwnxPos) { try { storage.Deserialize(nwnxSerialized.ToString()); } catch (Exception e) { Log.Error(e, "Failed to import NWNX object storage"); } } if (hasAnvilPos) { try { storage.Deserialize(anvilSerialized.ToString()); } catch (Exception e) { Log.Error(e, "Failed to load Anvil object storage"); } } return(loadFromGffHook.CallOriginal(pUUID, pRes, pStruct)); }
private int OnTestObjectVisible(void *pMessage, void *pAreaObject, void *pPlayerGameObject) { NwGameObject?areaObject = CNWSObject.FromPointer(pAreaObject).ToNwObjectSafe <NwGameObject>(); NwCreature? playerGameObject = CNWSObject.FromPointer(pPlayerGameObject).ToNwObjectSafe <NwCreature>(); NwPlayer? controllingPlayer = playerGameObject?.ControllingPlayer; if (areaObject == null || controllingPlayer == null || areaObject == playerGameObject) { return(testObjectVisibleHook.CallOriginal(pMessage, pAreaObject, pPlayerGameObject)); } VisibilityMode personalOverride = GetPersonalOverride(controllingPlayer, areaObject); VisibilityMode globalOverride = GetGlobalOverride(areaObject); VisibilityMode visibilityOverride = personalOverride != VisibilityMode.Default ? personalOverride : globalOverride != VisibilityMode.Default ? globalOverride : VisibilityMode.Default; int retVal; switch (visibilityOverride) { case VisibilityMode.Hidden: retVal = false.ToInt(); break; case VisibilityMode.DMOnly: retVal = controllingPlayer.IsDM ? testObjectVisibleHook.CallOriginal(pMessage, pAreaObject, pPlayerGameObject) : false.ToInt(); break; case VisibilityMode.AlwaysVisible: retVal = true.ToInt(); break; case VisibilityMode.AlwaysVisibleDMOnly: retVal = controllingPlayer.IsDM.ToInt(); break; case VisibilityMode.Default: case VisibilityMode.Visible: default: retVal = testObjectVisibleHook.CallOriginal(pMessage, pAreaObject, pPlayerGameObject); break; } return(retVal); }
private int OnRemoveLimitMovementSpeed(void *pEffectListHandler, void *pObject, void *pEffect) { NwObject?nwObject = CNWSObject.FromPointer(pObject).ToNwObject(); if (nwObject != null && InternalVariables.AlwaysWalk(nwObject)) { return(1); } return(removeLimitMovementSpeedHook.CallOriginal(pEffectListHandler, pObject, pEffect)); }
private int OnGetDamageBonus(void *pStats, void *pCreature, int bOffHand) { int damageBonus = getDamageBonusHook.CallOriginal(pStats, pCreature, bOffHand); CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats); CNWSCreature creature = stats.m_pBaseCreature; bool offHand = bOffHand.ToBool(); CNWSItem?weapon = GetEquippedWeapon(creature, offHand); uint baseItem = weapon != null ? weapon.m_nBaseItem : (uint)BaseItem.Gloves; bool hasApplicableFeat = false; bool applicableFeatExists = greaterWeaponSpecializationMap.TryGetValue(baseItem, out HashSet <ushort>?types); if (applicableFeatExists) { foreach (ushort feat in types !) { hasApplicableFeat = stats.HasFeat(feat).ToBool(); if (hasApplicableFeat) { break; } } } if (applicableFeatExists && hasApplicableFeat) { damageBonus += GreaterWeaponSpecializationDamageBonus; if ((*NWNXLib.EnableCombatDebugging()).ToBool() && stats.m_bIsPC.ToBool()) { CNWSCombatAttackData currentAttack = creature.m_pcCombatRound.GetAttack(creature.m_pcCombatRound.m_nCurrentAttack); StringBuilder debugMessage = new StringBuilder(currentAttack.m_sDamageDebugText.ToString()); debugMessage.Append(" + "); if (currentAttack.m_nAttackResult == 3) { int criticalThreat = stats.GetCriticalHitMultiplier(bOffHand); debugMessage.Append(GreaterWeaponSpecializationDamageBonus * criticalThreat); debugMessage.Append(" (Greater Weapon Specialization Feat) (Critical x"); debugMessage.Append(criticalThreat); debugMessage.Append(")"); } else { debugMessage.Append(GreaterWeaponSpecializationDamageBonus); debugMessage.Append(" (Greater Weapon Specialization Feat) "); } currentAttack.m_sDamageDebugText = debugMessage.ToString().ToExoString(); } } return(damageBonus); }
private uint OnGetStartEntry(void *pDialog, void *pNWSObjectOwner) { dialog = CNWSDialog.FromPointer(pDialog); CurrentNodeIndex = 0; stateStack.Push(DialogState.Start); uint retVal = getStartEntryHook.CallOriginal(pDialog, pNWSObjectOwner); stateStack.Pop(); return(retVal); }
private int OnGetStartEntryOneLiner(void *pDialog, void *pNWSObjectOwner, void *sOneLiner, void *sSound, void *sScript, void *scriptParams) { dialog = CNWSDialog.FromPointer(pDialog); CurrentNodeIndex = 0; stateStack.Push(DialogState.Start); int retVal = getStartEntryOneLinerHook.CallOriginal(pDialog, pNWSObjectOwner, sOneLiner, sSound, sScript, scriptParams); stateStack.Pop(); return(retVal); }
private void OnSaveToGff(void *pUUID, void *pRes, void *pStruct) { CNWSUUID uuid = CNWSUUID.FromPointer(pUUID); CResGFF resGff = CResGFF.FromPointer(pRes); CResStruct resStruct = CResStruct.FromPointer(pStruct); string?serialized = GetObjectStorage(uuid.m_parent).Serialize(); resGff.WriteFieldCExoString(resStruct, serialized.ToExoString(), AnvilGffFieldNamePtr); saveToGffHook.CallOriginal(pUUID, pRes, pStruct); }
private void OnWriteGameObjUpdateUpdateObject(void *pMessage, void *pPlayer, void *pAreaObject, void *pLastUpdateObject, uint nObjectUpdatesRequired, uint nObjectAppearanceUpdatesRequired) { CNWSObject areaObject = CNWSObject.FromPointer(pAreaObject); NwPlayer? targetPlayer = areaObject.m_idSelf.ToNwPlayer(PlayerSearch.Controlled); NwPlayer? observerPlayer = CNWSPlayer.FromPointer(pPlayer).ToNwPlayer(); PlayerNameOverride?nameOverride = GetPlayerNameOverride(targetPlayer, observerPlayer); ApplyNameOverride(targetPlayer, nameOverride, OverrideNameType.Original); writeGameObjUpdateUpdateObjectHook.CallOriginal(pMessage, pPlayer, pAreaObject, pLastUpdateObject, nObjectUpdatesRequired, nObjectAppearanceUpdatesRequired); RestoreNameOverride(targetPlayer, nameOverride, OverrideNameType.Original); }
private int OnSendServerToPlayerPlayerListDelete(void *pMessage, uint nPlayerId, void *pNewPlayer) { if (PlayerListNameType == OverrideNameType.Original) { return(sendServerToPlayerPlayerListDeleteHook.CallOriginal(pMessage, nPlayerId, pNewPlayer)); } if (!ShowOverridesToDM && nPlayerId == PlayerIdConstants.AllGameMasters) { return(sendServerToPlayerPlayerListDeleteHook.CallOriginal(pMessage, nPlayerId, pNewPlayer)); } NwPlayer?newPlayer = CNWSPlayer.FromPointer(pNewPlayer).ToNwPlayer(); if (newPlayer != null) { renameAddedToPlayerList.Remove(newPlayer); } return(sendServerToPlayerPlayerListDeleteHook.CallOriginal(pMessage, nPlayerId, pNewPlayer)); }
private int OnSendDialogReplies(void *pDialog, void *pNWSObjectOwner, uint nPlayerIdGUIOnly) { dialog = CNWSDialog.FromPointer(pDialog); CurrentNodeIndex = 0; stateStack.Push(DialogState.SendReplies); int retVal = sendDialogRepliesHook.CallOriginal(pDialog, pNWSObjectOwner, nPlayerIdGUIOnly); stateStack.Pop(); return(retVal); }
private int OnSendServerToPlayerExamineGuiCreatureData(void *pMessage, void *pPlayer, uint oidCreatureID) { NwPlayer? targetPlayer = oidCreatureID.ToNwPlayer(PlayerSearch.Controlled); NwPlayer? observerPlayer = CNWSPlayer.FromPointer(pPlayer).ToNwPlayer(); PlayerNameOverride?nameOverride = GetPlayerNameOverride(targetPlayer, observerPlayer); ApplyNameOverride(targetPlayer, nameOverride, OverrideNameType.Original); int retVal = sendServerToPlayerExamineGuiCreatureDataHook.CallOriginal(pMessage, pPlayer, oidCreatureID); RestoreNameOverride(targetPlayer, nameOverride, OverrideNameType.Original); return(retVal); }
private uint OnAIActionRest(void *pCreature, void *pNode) { CNWSCreature creature = CNWSCreature.FromPointer(pCreature); NwCreature? nwCreature = creature.ToNwObject <NwCreature>(); if (nwCreature != null && restDurationOverrides.TryGetValue(nwCreature, out int durationOverride)) { byte creatureLevel = creature.m_pStats.GetLevel(0); int originalValue; C2DA durationTable = NWNXLib.Rules().m_p2DArrays.m_pRestDurationTable; durationTable.GetINTEntry(creatureLevel, DurationTableKey, &originalValue); durationTable.SetINTEntry(creatureLevel, DurationTableKey, durationOverride); uint retVal = aiActionRestHook.CallOriginal(pCreature, pNode); durationTable.SetINTEntry(creatureLevel, DurationTableKey, originalValue); return(retVal); } return(aiActionRestHook.CallOriginal(pCreature, pNode)); }
private int OnSendServerToPlayerChatTell(void *pMessage, uint nPlayerId, uint oidSpeaker, void *sSpeakerMessage) { NwPlayer? targetPlayer = oidSpeaker.ToNwPlayer(PlayerSearch.Controlled); NwPlayer? observerPlayer = NwPlayer.FromPlayerId(nPlayerId); PlayerNameOverride?nameOverride = GetPlayerNameOverride(targetPlayer, observerPlayer); ApplyNameOverride(targetPlayer, nameOverride, OverrideNameType.Original); int retVal = sendServerToPlayerChatTellHook.CallOriginal(pMessage, nPlayerId, oidSpeaker, sSpeakerMessage); RestoreNameOverride(targetPlayer, nameOverride, OverrideNameType.Original); return(retVal); }
private int OnSendDialogEntry(void *pDialog, void *pNWSObjectOwner, uint nPlayerIdGUIOnly, uint iEntry, int bPlayHelloSound) { dialog = CNWSDialog.FromPointer(pDialog); CurrentNodeIndex = 0; stateStack.Push(DialogState.SendEntry); indexEntry = iEntry; int retVal = sendDialogEntryHook.CallOriginal(pDialog, pNWSObjectOwner, nPlayerIdGUIOnly, iEntry, bPlayHelloSound); stateStack.Pop(); return(retVal); }
private void OnEatTURD(void *pPlayer, void *pTURD) { CNWSPlayer player = CNWSPlayer.FromPointer(pPlayer); CNWSPlayerTURD turd = CNWSPlayerTURD.FromPointer(pTURD); ICGameObject?playerObj = player.m_oidNWSObject.ToNwObject()?.Object; if (playerObj != null) { objectStorage[playerObj.Pointer] = GetObjectStorage(turd).Clone(); } eatTURDHook.CallOriginal(pPlayer, pTURD); }
private int OnSendServerToPlayerPlayerListAll(void *pMessage, void *pPlayer) { if (PlayerListNameType == OverrideNameType.Original) { return(sendServerToPlayerPlayerListAllHook.CallOriginal(pMessage, pPlayer)); } NwPlayer?observer = CNWSPlayer.FromPointer(pPlayer).ToNwPlayer(); if (observer == null) { return(sendServerToPlayerPlayerListAllHook.CallOriginal(pMessage, pPlayer)); } Dictionary <NwPlayer, PlayerNameOverride> nameOverrides = GetOverridesForObserver(observer, true); ApplyObserverOverrides(nameOverrides, PlayerListNameType); int retVal = sendServerToPlayerPlayerListAllHook.CallOriginal(pMessage, pPlayer); RestoreObserverOverrides(nameOverrides, PlayerListNameType); return(retVal); }
private int OnHandleReply(void *pDialog, uint nPlayerID, void *pNWSObjectOwner, uint nReplyIndex, int bEscapeDialog, uint currentEntryIndex) { dialog = CNWSDialog.FromPointer(pDialog); CurrentNodeIndex = 0; stateStack.Push(DialogState.HandleReply); indexEntry = currentEntryIndex; indexReply = nReplyIndex; int retVal = handleReplyHook.CallOriginal(pDialog, nPlayerID, pNWSObjectOwner, nReplyIndex, bEscapeDialog, currentEntryIndex); stateStack.Pop(); return(retVal); }
private byte OnGetDamageLevel(void *pObject) { NwCreature?creature = CNWSObject.FromPointer(pObject).ToNwObject <NwCreature>(); if (creature != null) { DamageLevelEntry?levelOverride = GetDamageLevelOverride(creature); if (levelOverride != null) { return((byte)levelOverride.RowIndex); } } return(damageLevelHook.CallOriginal(pObject)); }
private int OnGetEpicWeaponDevastatingCritical(void *pStats, void *pWeapon) { CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats); CNWSItem weapon = CNWSItem.FromPointer(pWeapon); uint weaponType = weapon == null ? (uint)BaseItem.Gloves : CNWSItem.FromPointer(pWeapon).m_nBaseItem; bool hasApplicableFeat = false; bool applicableFeatExists = epicWeaponDevastatingCriticalMap.TryGetValue(weaponType, out HashSet <ushort>?types); if (applicableFeatExists) { foreach (ushort feat in types !) { hasApplicableFeat = stats.HasFeat(feat).ToBool(); if (hasApplicableFeat) { break; } } } bool canUseFeat = applicableFeatExists && hasApplicableFeat || getEpicWeaponDevastatingCriticalHook.CallOriginal(pStats, pWeapon).ToBool(); if (weapon != null && canUseFeat && OnDevastatingCriticalHit != null) { CNWSCreature creature = stats.m_pBaseCreature; CNWSCombatRound combatRound = creature.m_pcCombatRound; CNWSCombatAttackData attackData = combatRound.GetAttack(combatRound.m_nCurrentAttack); DevastatingCriticalData devastatingCriticalData = new DevastatingCriticalData { Weapon = weapon.ToNwObject <NwItem>() !, Target = creature.m_oidAttackTarget.ToNwObject <NwGameObject>() !, Damage = attackData.GetTotalDamage(1), }; OnDevastatingCriticalHit(devastatingCriticalData); if (devastatingCriticalData.Bypass) { attackData.m_bKillingBlow = 0; return(0); } } return(canUseFeat.ToInt()); }
private int OnGetRangedAttackBonus(void *pStats, int bIncludeBase, int bTouchAttack) { int attackBonus = getRangedAttackBonusHook.CallOriginal(pStats, bIncludeBase, bTouchAttack); if (bTouchAttack.ToBool()) { return(attackBonus); } CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats); CNWSItem weapon = stats.m_pBaseCreature.m_pInventory.GetItemInSlot((uint)EquipmentSlot.RightHand); if (weapon == null) { return(attackBonus); } uint baseItem = weapon.m_nBaseItem; bool hasApplicableFeat = false; bool applicableFeatExists = greaterWeaponFocusMap.TryGetValue(baseItem, out HashSet <ushort>?types); if (applicableFeatExists) { foreach (ushort feat in types !) { hasApplicableFeat = stats.HasFeat(feat).ToBool(); if (hasApplicableFeat) { break; } } } if (applicableFeatExists && hasApplicableFeat) { attackBonus += GreaterWeaponFocusAttackBonus; } if (EnableSlingGoodAimFeat && baseItem == (uint)BaseItem.Sling && stats.m_nRace != (ushort)RacialType.Halfling && stats.HasFeat((ushort)Feat.GoodAim).ToBool()) { attackBonus += 1; } return(attackBonus); }
private int OnSendServerToPlayerPopUpGUIPanel(void *pMessage, uint observerOid, int nGuiPanel, int bGUIOption1, int bGUIOption2, int nStringReference, void **psStringReference) { if (nGuiPanel == 1) // Party invite popup { CNWSCreature?observerCreature = LowLevel.ServerExoApp.GetCreatureByGameObjectID(observerOid); NwPlayer? observerPlayer = observerCreature?.ToNwObject <NwCreature>()?.ControllingPlayer; NwPlayer? targetPlayer = observerCreature?.m_oidInvitedToPartyBy.ToNwPlayer(); if (targetPlayer != null) { PlayerNameOverride?name = GetPlayerNameOverride(targetPlayer, observerPlayer); if (name != null) { *psStringReference = (void *)name.CharacterNameInternal.Pointer; } } } return(sendServerToPlayerPopUpGUIPanelHook.CallOriginal(pMessage, observerOid, nGuiPanel, bGUIOption1, bGUIOption2, nStringReference, psStringReference)); }
private int OnGetIsWeaponOfChoice(void *pStats, uint nBaseItem) { CNWSCreatureStats stats = CNWSCreatureStats.FromPointer(pStats); bool hasApplicableFeat = false; bool applicableFeatExists = weaponOfChoiceMap.TryGetValue(nBaseItem, out HashSet <ushort>?types); if (applicableFeatExists) { foreach (ushort feat in types !) { hasApplicableFeat = stats.HasFeat(feat).ToBool(); if (hasApplicableFeat) { break; } } } return(applicableFeatExists && hasApplicableFeat ? 1 : getIsWeaponOfChoiceHook.CallOriginal(pStats, nBaseItem)); }
private void OnDropTURD(void *pPlayer) { dropTURDHook.CallOriginal(pPlayer); // Be very, very paranoid. Bad things happen when the TURD list doesn't exist // This can happen when you BootPC() the very first PC to connect to your sever // https://github.com/nwnxee/unified/issues/319 CExoLinkedListInternal turdList = NwModule.Instance.Module.m_lstTURDList.m_pcExoLinkedListInternal; CExoLinkedListNode pHead; if (turdList != null && (pHead = turdList.pHead) != null && pHead.pObject != null) { CNWSPlayer player = CNWSPlayer.FromPointer(pPlayer); CNWSPlayerTURD turd = CNWSPlayerTURD.FromPointer(pHead.pObject); ICGameObject?playerObj = player.m_oidNWSObject.ToNwObject()?.Object; if (playerObj != null) { objectStorage[turd.Pointer] = GetObjectStorage(playerObj).Clone(); } } }