/// @addtogroup damage Damage /// @brief Run a script before damage and attack events allowing for modification. Includes function to arbitrarily apply damage. /// @{ /// @file nwnx_damage.nss #include "nwnx" const string NWNX_Damage = "NWNX_Damage"; ///< @private /// @struct NWNX_Damage_DamageEventData /// @brief Damage Event Data struct NWNX_Damage_DamageEventData { object oDamager; ///< The object that inflicted the damage. int iBludgeoning; ///< Bludgeoning damage int iPierce; ///< Piercing damage int iSlash; ///< Slashing damage int iMagical; ///< Magical damage int iAcid; ///< Acid damage int iCold; ///< Cold damage int iDivine; ///< Divine damage int iElectrical; ///< Electrical damage int iFire; ///< Fire damage int iNegative; ///< Negative damage int iPositive; ///< Positive damage int iSonic; ///< Sonic damage int iBase; ///< Base damage }; /// @struct NWNX_Damage_AttackEventData /// @brief Attack Event Data struct NWNX_Damage_AttackEventData { object oTarget; ///< The target who took the damage int iBludgeoning; ///< Bludgeoning damage int iPierce; ///< Piercing damage int iSlash; ///< Slashing damage int iMagical; ///< Magical damage int iAcid; ///< Acid damage int iCold; ///< Cold damage int iDivine; ///< Divine damage int iElectrical; ///< Electrical damage int iFire; ///< Fire damage int iNegative; ///< Negative damage int iPositive; ///< Positive damage int iSonic; ///< Sonic damage int iBase; ///< Base damage int iAttackNumber; ///< 1-based index of the attack in current combat round int iAttackResult; ///< 1=hit, 3=critical hit, 4=miss, 8=concealed int iAttackType; ///< 1=main hand, 2=offhand, 3-5=creature, 6=haste int iSneakAttack; ///< 0=neither, 1=sneak attack, 2=death attack, 3=both }; /// @struct NWNX_Damage_DamageData /// @brief Used for DealDamage struct NWNX_Damage_DamageData { int iBludgeoning; ///< Bludgeoning damage int iPierce; ///< Piercing damage int iSlash; ///< Slashing damage int iMagical; ///< Magical damage int iAcid; ///< Acid damage int iCold; ///< Cold damage int iDivine; ///< Divine damage int iElectrical; ///< Electrical damage int iFire; ///< Fire damage int iNegative; ///< Negative damage int iPositive; ///< Positive damage int iSonic; ///< Sonic damage int iPower; ///< For overcoming DR }; /// @brief Sets the script to run with a damage event. /// @param sScript The script that will handle the damage event. /// @param oOwner An object if only executing for a specific object or OBJECT_INVALID for global. void NWNX_Damage_SetDamageEventScript(string sScript, object oOwner=OBJECT_INVALID); /// @brief Get Damage Event Data /// @return A NWNX_Damage_DamageEventData struct. /// @note To use only in the Damage Event Script. struct NWNX_Damage_DamageEventData NWNX_Damage_GetDamageEventData(); /// @brief Set Damage Event Data /// @param data A NWNX_Damage_DamageEventData struct. /// @note To use only in the Damage Event Script. void NWNX_Damage_SetDamageEventData(struct NWNX_Damage_DamageEventData data); /// @brief Sets the script to run with an attack event. /// @param sScript The script that will handle the attack event. /// @param oOwner An object if only executing for a specific object or OBJECT_INVALID for global. void NWNX_Damage_SetAttackEventScript(string sScript, object oOwner=OBJECT_INVALID); /// @brief Get Attack Event Data /// @return A NWNX_Damage_AttackEventData struct. /// @note To use only in the Attack Event Script. struct NWNX_Damage_AttackEventData NWNX_Damage_GetAttackEventData(); /// @brief Set Attack Event Data /// @param data A NWNX_Damage_AttackEventData struct. /// @note To use only in the Attack Event Script. void NWNX_Damage_SetAttackEventData(struct NWNX_Damage_AttackEventData data); /// @brief Deal damage to a target. /// @remark Permits multiple damage types and checks enhancement bonus for overcoming DR. /// @param data A NWNX_Damage_DamageData struct. /// @param oTarget The target object on whom the damage is dealt. /// @param oSource The source of the damage. /// @param iRanged Whether the attack should be treated as ranged by the engine (for example when considering damage inflicted by Acid Sheath and other such effects) void NWNX_Damage_DealDamage(struct NWNX_Damage_DamageData data, object oTarget, object oSource=OBJECT_SELF, int iRanged = FALSE); /// @} void NWNX_Damage_SetDamageEventScript(string sScript, object oOwner=OBJECT_INVALID) { string sFunc = "SetEventScript"; NWNX_PushArgumentObject(NWNX_Damage, sFunc, oOwner); NWNX_PushArgumentString(NWNX_Damage, sFunc, sScript); NWNX_PushArgumentString(NWNX_Damage, sFunc, "DAMAGE"); NWNX_CallFunction(NWNX_Damage, sFunc); } struct NWNX_Damage_DamageEventData NWNX_Damage_GetDamageEventData() { string sFunc = "GetDamageEventData"; struct NWNX_Damage_DamageEventData data; NWNX_CallFunction(NWNX_Damage, sFunc); data.oDamager = NWNX_GetReturnValueObject(NWNX_Damage, sFunc); data.iBludgeoning = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iPierce = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iSlash = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iMagical = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iAcid = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iCold = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iDivine = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iElectrical = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iFire = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iNegative = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iPositive = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iSonic = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iBase = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); return data; } void NWNX_Damage_SetDamageEventData(struct NWNX_Damage_DamageEventData data) { string sFunc = "SetDamageEventData"; NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iBase); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iSonic); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPositive); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iNegative); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iFire); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iElectrical); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iDivine); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iCold); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iAcid); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iMagical); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iSlash); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPierce); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iBludgeoning); NWNX_CallFunction(NWNX_Damage, sFunc); } void NWNX_Damage_SetAttackEventScript(string sScript, object oOwner=OBJECT_INVALID) { string sFunc = "SetEventScript"; NWNX_PushArgumentObject(NWNX_Damage, sFunc, oOwner); NWNX_PushArgumentString(NWNX_Damage, sFunc, sScript); NWNX_PushArgumentString(NWNX_Damage, sFunc, "ATTACK"); NWNX_CallFunction(NWNX_Damage, sFunc); } struct NWNX_Damage_AttackEventData NWNX_Damage_GetAttackEventData() { string sFunc = "GetAttackEventData"; struct NWNX_Damage_AttackEventData data; NWNX_CallFunction(NWNX_Damage, sFunc); data.oTarget = NWNX_GetReturnValueObject(NWNX_Damage, sFunc); data.iBludgeoning = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iPierce = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iSlash = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iMagical = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iAcid = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iCold = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iDivine = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iElectrical = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iFire = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iNegative = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iPositive = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iSonic = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iBase = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iAttackNumber = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iAttackResult = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iAttackType = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); data.iSneakAttack = NWNX_GetReturnValueInt(NWNX_Damage, sFunc); return data; } void NWNX_Damage_SetAttackEventData(struct NWNX_Damage_AttackEventData data) { string sFunc = "SetAttackEventData"; NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iAttackResult); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iBase); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iSonic); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPositive); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iNegative); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iFire); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iElectrical); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iDivine); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iCold); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iAcid); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iMagical); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iSlash); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPierce); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iBludgeoning); NWNX_CallFunction(NWNX_Damage, sFunc); } void NWNX_Damage_DealDamage(struct NWNX_Damage_DamageData data, object oTarget, object oSource, int iRanged = FALSE) { string sFunc = "DealDamage"; NWNX_PushArgumentInt(NWNX_Damage, sFunc, iRanged); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPower); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iSonic); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPositive); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iNegative); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iFire); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iElectrical); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iDivine); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iCold); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iAcid); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iMagical); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iSlash); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iPierce); NWNX_PushArgumentInt(NWNX_Damage, sFunc, data.iBludgeoning); NWNX_PushArgumentObject(NWNX_Damage, sFunc, oTarget); NWNX_PushArgumentObject(NWNX_Damage, sFunc, oSource); NWNX_CallFunction(NWNX_Damage, sFunc); }