1 Commits
1.05 ... 1.06

Author SHA1 Message Date
Jaysyn904
157382e60d 2026/02/09 Update
Added and activated PRCX.
Updated PRC8 includes.
2026-02-09 08:18:11 -05:00
48 changed files with 1684 additions and 1834 deletions

View File

@@ -880,7 +880,8 @@ void SetCompositeBonusT(object oItem, string sBonus, int iVal, int iType, int iS
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonusVsSAlign(iSubType, iCurVal + iChange), oItem,9999.0); AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonusVsSAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break; break;
case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP: case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType); //iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20) if ((iCurVal + iChange) > 20)
{ {
iVal -= iCurVal + iChange - 20; iVal -= iCurVal + iChange - 20;
@@ -888,7 +889,8 @@ void SetCompositeBonusT(object oItem, string sBonus, int iVal, int iType, int iS
iChange = 0; iChange = 0;
} }
if(iCurVal+iChange > 0) if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem); //AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
break; break;
case ITEM_PROPERTY_DECREASED_ABILITY_SCORE: case ITEM_PROPERTY_DECREASED_ABILITY_SCORE:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType); iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);

View File

@@ -2,21 +2,23 @@
/* Combined wrappers for both Win32 and Linux NWNX funcs */ /* Combined wrappers for both Win32 and Linux NWNX funcs */
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
#include "inc_debug"
////////////////////////////////////////////////// //////////////////////////////////////////////////
/* Function prototypes */ /* Function prototypes */
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Used in OnModuleLoad event to auto-detect if NWNX_Funcs plugin is enabled // Used in OnModuleLoad event to auto-detect if NWNX_Funcs plugin is enabled (DEFUNCT)
void PRC_Funcs_Init(object oModule); void PRC_Funcs_Init(object oModule);
// Sets the amount of hitpoints oObject has currently to nHP // Sets the amount of hitpoints oObject has currently to nHP
void PRC_Funcs_SetCurrentHitPoints(object oCreature, int nHP); void PRC_Funcs_SetCurrentHitPoints(object oCreature, int nHP);
// Sets the amount of hitpoints oObject can maximally have to nHP // Sets the amount of hitpoints oObject can maximally have to nHP
void PRC_Funcs_SetMaxHitPoints(object oCreature, int nHP); void PRC_Funcs_SetMaxHitPoints(object oCreature, int nHP, int nLevel = 0);
// Changes the skill ranks for nSkill on oObject by iValue // Changes the skill ranks for nSkill on oObject by iValue
void PRC_Funcs_ModSkill(object oCreature, int nSkill, int nValue); void PRC_Funcs_ModSkill(object oCreature, int nSkill, int nValue, int nLevel = 0);
// Sets a base ability score nAbility (ABILITY_STRENGTH, ABILITY_DEXTERITY, etc) to nValue // Sets a base ability score nAbility (ABILITY_STRENGTH, ABILITY_DEXTERITY, etc) to nValue
// The range of nValue is 3 to 255 // The range of nValue is 3 to 255
@@ -44,17 +46,17 @@ void PRC_Funcs_SetBaseNaturalAC(object oCreature, int nValue);
int PRC_Funcs_GetBaseNaturalAC(object oCreature); int PRC_Funcs_GetBaseNaturalAC(object oCreature);
// Sets the specialist spell school of a Wizard // Sets the specialist spell school of a Wizard
void PRC_Funcs_SetWizardSpecialization(object oCreature, int iSpecialization); void PRC_Funcs_SetWizardSpecialization(object oCreature, int iSpecialization, int nClass = CLASS_TYPE_WIZARD);
// Returns the specialist spell school of a Wizard // Returns the specialist spell school of a Wizard
int PRC_Funcs_GetWizardSpecialization(object oCreature); int PRC_Funcs_GetWizardSpecialization(object oCreature, int nClass = CLASS_TYPE_WIZARD);
////////////////////////////////////////////////// //////////////////////////////////////////////////
/* Function definitions */ /* Function definitions */
////////////////////////////////////////////////// //////////////////////////////////////////////////
int _PRC_NWNXFuncsZero(object oObject, string sFunc) { int _PRC_NWNXFuncsZero(object oObject, string sFunc) {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
SetLocalString(oObject, sFunc, "-"); SetLocalString(oObject, sFunc, "-");
else if (nVersion == 2) else if (nVersion == 2)
@@ -65,7 +67,7 @@ int _PRC_NWNXFuncsZero(object oObject, string sFunc) {
} }
int _PRC_NWNXFuncsOne(object oObject, string sFunc, int nVal1) { int _PRC_NWNXFuncsOne(object oObject, string sFunc, int nVal1) {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
SetLocalString(oObject, sFunc, IntToString(nVal1)); SetLocalString(oObject, sFunc, IntToString(nVal1));
else if (nVersion == 2) else if (nVersion == 2)
@@ -76,7 +78,7 @@ int _PRC_NWNXFuncsOne(object oObject, string sFunc, int nVal1) {
} }
int _PRC_NWNXFuncsTwo(object oObject, string sFunc, int nVal1, int nVal2) { int _PRC_NWNXFuncsTwo(object oObject, string sFunc, int nVal1, int nVal2) {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
SetLocalString(oObject, sFunc, IntToString(nVal1) + " " + IntToString(nVal2)); SetLocalString(oObject, sFunc, IntToString(nVal1) + " " + IntToString(nVal2));
else if (nVersion == 2) else if (nVersion == 2)
@@ -87,7 +89,7 @@ int _PRC_NWNXFuncsTwo(object oObject, string sFunc, int nVal1, int nVal2) {
} }
int _PRC_NWNXFuncsThree(object oObject, string sFunc, int nVal1, int nVal2, int nVal3) { int _PRC_NWNXFuncsThree(object oObject, string sFunc, int nVal1, int nVal2, int nVal3) {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
SetLocalString(oObject, sFunc, IntToString(nVal1) + " " + IntToString(nVal2) + " " + IntToString(nVal3)); SetLocalString(oObject, sFunc, IntToString(nVal1) + " " + IntToString(nVal2) + " " + IntToString(nVal3));
else if (nVersion == 2) else if (nVersion == 2)
@@ -98,7 +100,7 @@ int _PRC_NWNXFuncsThree(object oObject, string sFunc, int nVal1, int nVal2, int
} }
int _PRC_NWNXFuncsFour(object oObject, string sFunc, int nVal1, int nVal2, int nVal3, int nVal4) { int _PRC_NWNXFuncsFour(object oObject, string sFunc, int nVal1, int nVal2, int nVal3, int nVal4) {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
SetLocalString(oObject, sFunc, IntToString(nVal1) + " " + IntToString(nVal2) + " " + IntToString(nVal3) + " " + IntToString(nVal4)); SetLocalString(oObject, sFunc, IntToString(nVal1) + " " + IntToString(nVal2) + " " + IntToString(nVal3) + " " + IntToString(nVal4));
else if (nVersion == 2) else if (nVersion == 2)
@@ -114,13 +116,13 @@ void PRC_Funcs_Init(object oModule)
string sTestVariable = "PRC_TEST_NWNX_FUNCS"; string sTestVariable = "PRC_TEST_NWNX_FUNCS";
SetLocalString(oModule, sTestVariable, "1"); SetLocalString(oModule, sTestVariable, "1");
SetLocalString(oModule, "NWNX!FUNCS!GETHASLOCALVARIABLE", sTestVariable + " 3"); //3 is the variable type SetLocalString(oModule, "NWNX!FUNCS!GETHASLOCALVARIABLE", sTestVariable + " 3"); //3 is the variable type
//NOTE: don't use _PRC_NWNXFuncsX functions here; they depend on the PRC_NWNX_FUNCS that we haven't set yet //NOTE: don't use _PRC_NWNXFuncsX functions here; they depend on the PRC_NWNXEE_ENABLED that we haven't set yet
int iTest = StringToInt(GetLocalString(oModule, "NWNX!FUNCS!GETHASLOCALVARIABLE")); int iTest = StringToInt(GetLocalString(oModule, "NWNX!FUNCS!GETHASLOCALVARIABLE"));
DeleteLocalString(oModule, "NWNX!FUNCS!GETHASLOCALVARIABLE"); DeleteLocalString(oModule, "NWNX!FUNCS!GETHASLOCALVARIABLE");
DeleteLocalString(oModule, sTestVariable); DeleteLocalString(oModule, sTestVariable);
if (iTest) if (iTest)
SetLocalInt(oModule, "PRC_NWNX_FUNCS", 1); //1 == win32 SetLocalInt(oModule, "PRC_NWNXEE_ENABLED", 1); //1 == win32
else else
{ {
//NWNX GetLocalVariableCount behaves differently for win32 and linux, //NWNX GetLocalVariableCount behaves differently for win32 and linux,
@@ -132,7 +134,7 @@ void PRC_Funcs_Init(object oModule)
//the call failed because NWNX funcs is not present. //the call failed because NWNX funcs is not present.
string sFunc = "NWNX!FUNCS!GETLOCALVARIABLECOUNT"; string sFunc = "NWNX!FUNCS!GETLOCALVARIABLECOUNT";
SetLocalString(oModule, sFunc, " "); SetLocalString(oModule, sFunc, " ");
//NOTE: don't use _PRC_NWNXFuncsX functions here; they depend on the PRC_NWNX_FUNCS that we haven't set yet //NOTE: don't use _PRC_NWNXFuncsX functions here; they depend on the PRC_NWNXEE_ENABLED that we haven't set yet
//NOTE: the number being returned by GetLocalVariableCount() on Linux seems bogus to me (it's huge, e.g. 294,654,504), //NOTE: the number being returned by GetLocalVariableCount() on Linux seems bogus to me (it's huge, e.g. 294,654,504),
//but it does seem to be reliably zero when NWNX funcs is not present, and so far has been reliably non-zero //but it does seem to be reliably zero when NWNX funcs is not present, and so far has been reliably non-zero
//when it is present. That's all we need here. //when it is present. That's all we need here.
@@ -140,50 +142,116 @@ void PRC_Funcs_Init(object oModule)
int nVariables = StringToInt(GetLocalString(oModule, sFunc)); int nVariables = StringToInt(GetLocalString(oModule, sFunc));
DeleteLocalString(oModule, sFunc); DeleteLocalString(oModule, sFunc);
if (nVariables) if (nVariables)
SetLocalInt(oModule, "PRC_NWNX_FUNCS", 2); //2 == linux SetLocalInt(oModule, "PRC_NWNXEE_ENABLED", 2); //2 == linux
} }
} }
void PRC_Funcs_SetMaxHitPoints(object oCreature, int nHP) void PRC_Funcs_SetMaxHitPoints(object oCreature, int nHP, int nLevel = 0)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Default to total hit dice if not provided
if (nLevel <= 0)
nLevel = GetHitDice(oCreature);
//:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_MAXHP", nHP);
SetLocalInt(oCreature, "PRC_EE_MAXHP_LEVEL", nLevel);
//:: Fire NWNxEE shim
ExecuteScript("prcx_set_maxhp", oCreature);
}
/* void PRC_Funcs_SetMaxHitPoints(object oCreature, int nHP)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1 || nVersion == 2) if (nVersion == 1 || nVersion == 2)
{ {
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETMAXHITPOINTS", nHP); _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETMAXHITPOINTS", nHP);
DeleteLocalString(oCreature, "NWNX!FUNCS!SETMAXHITPOINTS"); DeleteLocalString(oCreature, "NWNX!FUNCS!SETMAXHITPOINTS");
} }
} */
void PRC_Funcs_ModSkill(object oCreature, int nSkill, int nValue, int nLevel = 0)
{
//:: Default to current level if not provided
if (nLevel <= 0)
nLevel = GetHitDice(oCreature);
//:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_SKILL", nSkill);
SetLocalInt(oCreature, "PRC_EE_SKILL_DELTA", nValue);
SetLocalInt(oCreature, "PRC_EE_SKILL_LEVEL", nLevel);
//:: Fire NWNxEE shim
ExecuteScript("prcx_mod_skill", oCreature);
} }
void PRC_Funcs_ModSkill(object oCreature, int nSkill, int nValue) /* void PRC_Funcs_ModSkill(object oCreature, int nSkill, int nValue)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
_PRC_NWNXFuncsThree(oCreature, "NWNX!FUNCS!SETSKILL", nSkill, nValue, 1); //The 1 is a flag specifying modify instead of set _PRC_NWNXFuncsThree(oCreature, "NWNX!FUNCS!SETSKILL", nSkill, nValue, 1); //The 1 is a flag specifying modify instead of set
else if (nVersion == 2) else if (nVersion == 2)
_PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!MODIFYSKILLRANK", nSkill, nValue); _PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!MODIFYSKILLRANK", nSkill, nValue);
} } */
void PRC_Funcs_SetAbilityScore(object oCreature, int nAbility, int nValue) void PRC_Funcs_SetAbilityScore(object oCreature, int nAbility, int nValue)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_ABILITY", nAbility);
SetLocalInt(oCreature, "PRC_EE_ABILITY_VALUE", nValue);
//:: Fire NWNxEE shim
ExecuteScript("prcx_set_ability", oCreature);
}
/* void PRC_Funcs_SetAbilityScore(object oCreature, int nAbility, int nValue)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
_PRC_NWNXFuncsFour(oCreature, "NWNX!FUNCS!SETABILITYSCORE", nAbility, nValue, 0, 0); //The first 0 is a flag specifying set instead of modify _PRC_NWNXFuncsFour(oCreature, "NWNX!FUNCS!SETABILITYSCORE", nAbility, nValue, 0, 0); //The first 0 is a flag specifying set instead of modify
else if (nVersion == 2) else if (nVersion == 2)
_PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!SETABILITYSCORE", nAbility, nValue); _PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!SETABILITYSCORE", nAbility, nValue);
} } */
void PRC_Funcs_ModAbilityScore(object oCreature, int nAbility, int nValue) void PRC_Funcs_ModAbilityScore(object oCreature, int nAbility, int nValue)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); if(DEBUG) DoDebug("============================================");
if(DEBUG) DoDebug("PRC_Funcs_ModAbiltyScore: Starting function.");
if(DEBUG) DoDebug("============================================");
//:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_ABILITY", nAbility);
SetLocalInt(oCreature, "PRC_EE_ABILITY_DELTA", nValue);
if(DEBUG) DoDebug("PRC_Funcs_ModAbiltyScore: Variables Set");
//:: Fire NWNxEE shim
if(DEBUG) DoDebug("PRC_Funcs_ModAbiltyScore: Firing prc_mod_ability");
ExecuteScript("prcx_mod_ability", oCreature);
}
/* void PRC_Funcs_ModAbilityScore(object oCreature, int nAbility, int nValue)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
_PRC_NWNXFuncsFour(oCreature, "NWNX!FUNCS!SETABILITYSCORE", nAbility, nValue, 1, 0); //The 1 is a flag specifying modify instead of set _PRC_NWNXFuncsFour(oCreature, "NWNX!FUNCS!SETABILITYSCORE", nAbility, nValue, 1, 0); //The 1 is a flag specifying modify instead of set
else if (nVersion == 2) else if (nVersion == 2)
_PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!MODIFYABILITYSCORE", nAbility, nValue); _PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!MODIFYABILITYSCORE", nAbility, nValue);
} */
void PRC_Funcs_AddFeat(object oCreature, int nFeat, int nLevel = 0)
{
//:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_FEAT", nFeat);
SetLocalInt(oCreature, "PRC_EE_FEAT_LEVEL", nLevel);
//:: Fire NWNxEE shim
ExecuteScript("prcx_add_feat", oCreature);
} }
void PRC_Funcs_AddFeat(object oCreature, int nFeat, int nLevel=0) /* void PRC_Funcs_AddFeat(object oCreature, int nFeat, int nLevel=0)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
{ {
if (!nLevel) if (!nLevel)
@@ -198,21 +266,88 @@ void PRC_Funcs_AddFeat(object oCreature, int nFeat, int nLevel=0)
else if(nLevel > 0) else if(nLevel > 0)
_PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!ADDKNOWNFEATATLEVEL", nLevel, nFeat); _PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!ADDKNOWNFEATATLEVEL", nLevel, nFeat);
} }
} } */
/**
* @brief Determines whether a creature inherently knows a feat.
*
* This function returns TRUE only if the specified feat is an inherent
* (true) feat possessed by the creature. Bonus feats granted via
* EFFECT_TYPE_BONUS_FEAT effects are explicitly ignored.
*
* This allows reliable differentiation between permanent feats
* (e.g. class, racial, or template feats) and temporary or granted
* bonus feats applied through effects.
*
* No NWNxEE shim is required; this function operates entirely using
* stock NWScript functionality.
*
* @param oCreature The creature to check.
* @param nFeatIndex The feat constant to test.
*
* @return TRUE if the creature inherently knows the feat and does not
* possess it solely via a bonus feat effect; FALSE otherwise.
*/
int PRC_Funcs_GetFeatKnown(object oCreature, int nFeatIndex) int PRC_Funcs_GetFeatKnown(object oCreature, int nFeatIndex)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Check for an EffectBonusFeat with this feat ID
effect eCheck = GetFirstEffect(oCreature);
int bHasBonusFeatEffect = FALSE;
while (GetIsEffectValid(eCheck))
{
if (GetEffectType(eCheck) == EFFECT_TYPE_BONUS_FEAT && GetEffectInteger(eCheck, 0) == nFeatIndex)
{
bHasBonusFeatEffect = TRUE;
break;
}
eCheck = GetNextEffect(oCreature);
}
//;: Return TRUE only if inherent and no matching bonus feat effect
return (!bHasBonusFeatEffect && GetHasFeat(nFeatIndex, oCreature));
}
/* int PRC_Funcs_GetFeatKnown(object oCreature, int nFeatIndex)
{
//:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_FEAT", nFeatIndex);
//:: Fire NWNxEE shim
ExecuteScript("prcx_knows_feat", oCreature);
//:: Read result
int nResult = GetLocalInt(oCreature, "PRC_EE_FEAT_RESULT");
//:: Clean up locals
DeleteLocalInt(oCreature, "PRC_EE_FEAT");
DeleteLocalInt(oCreature, "PRC_EE_FEAT_RESULT");
return nResult;
} */
/* int PRC_Funcs_GetFeatKnown(object oCreature, int nFeatIndex)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
return _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!GETFEATKNOWN", nFeatIndex); return _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!GETFEATKNOWN", nFeatIndex);
else if (nVersion == 2) else if (nVersion == 2)
return _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!GETKNOWNFEAT", nFeatIndex); return _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!GETKNOWNFEAT", nFeatIndex);
return 0; return 0;
} } */
void PRC_Funcs_ModSavingThrowBonus(object oCreature, int nSavingThrow, int nValue) void PRC_Funcs_ModSavingThrowBonus(object oCreature, int nSavingThrow, int nValue)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_STYPE", nSavingThrow);
SetLocalInt(oCreature, "PRC_EE_SDELTA", nValue);
//:: Fire NWNxEE shim
ExecuteScript("prcx_mod_save", oCreature);
}
/* void PRC_Funcs_ModSavingThrowBonus(object oCreature, int nSavingThrow, int nValue)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
_PRC_NWNXFuncsThree(oCreature, "NWNX!FUNCS!SETSAVINGTHROWBONUS", nSavingThrow, nValue, 1); //The 1 is a flag specifying modify instead of set _PRC_NWNXFuncsThree(oCreature, "NWNX!FUNCS!SETSAVINGTHROWBONUS", nSavingThrow, nValue, 1); //The 1 is a flag specifying modify instead of set
else if (nVersion == 2) else if (nVersion == 2)
@@ -224,61 +359,133 @@ void PRC_Funcs_ModSavingThrowBonus(object oCreature, int nSavingThrow, int nValu
nNewValue = 127; nNewValue = 127;
_PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!SETSAVINGTHROWBONUS", nSavingThrow, nNewValue); _PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!SETSAVINGTHROWBONUS", nSavingThrow, nNewValue);
} }
} } */
void PRC_Funcs_SetBaseNaturalAC(object oCreature, int nValue) void PRC_Funcs_SetBaseNaturalAC(object oCreature, int nValue)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Payload for NWNxEE shim
SetLocalInt(oCreature, "PRC_EE_BASEAC", nValue);
//:: Fire NWNxEE shim
ExecuteScript("prcx_set_ac", oCreature);
}
/* void PRC_Funcs_SetBaseNaturalAC(object oCreature, int nValue)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
_PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!SETBASEAC", nValue, AC_NATURAL_BONUS); _PRC_NWNXFuncsTwo(oCreature, "NWNX!FUNCS!SETBASEAC", nValue, AC_NATURAL_BONUS);
else if (nVersion == 2) else if (nVersion == 2)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETACNATURALBASE", nValue); _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETACNATURALBASE", nValue);
} } */
int PRC_Funcs_GetBaseNaturalAC(object oCreature) int PRC_Funcs_GetBaseNaturalAC(object oCreature)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Fire NWNxEE shim
ExecuteScript("prcx_get_ac", oCreature);
//:: Read result
int nAC = GetLocalInt(oCreature, "PRC_EE_BASEAC_RESULT");
//:: Clean up
DeleteLocalInt(oCreature, "PRC_EE_BASEAC_RESULT");
return nAC;
}
/* int PRC_Funcs_GetBaseNaturalAC(object oCreature)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
return _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!GETBASEAC", AC_NATURAL_BONUS); return _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!GETBASEAC", AC_NATURAL_BONUS);
else if (nVersion == 2) else if (nVersion == 2)
return _PRC_NWNXFuncsZero(oCreature, "NWNX!FUNCS!GETACNATURALBASE"); return _PRC_NWNXFuncsZero(oCreature, "NWNX!FUNCS!GETACNATURALBASE");
return 0; return 0;
} } */
void PRC_Funcs_SetCurrentHitPoints(object oCreature, int nHP) void PRC_Funcs_SetCurrentHitPoints(object oCreature, int nHP)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Sanity check
if (nVersion == 1 || nVersion == 2) if (nHP < 0)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETCURRENTHITPOINTS", nHP); nHP = 0;
//:: Set current hit points directly
//:: Was this not a native function in the past?
SetCurrentHitPoints(oCreature, nHP);
} }
void PRC_Funcs_SetCreatureSize (object oCreature, int nSize) /* void PRC_Funcs_SetCurrentHitPoints(object oCreature, int nHP)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1 || nVersion == 2)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETCURRENTHITPOINTS", nHP);
} */
void PRC_Funcs_SetCreatureSize(object oCreature, int nSize)
{
//:: Pass parameters via locals
SetLocalInt(oCreature, "PRC_EE_CREATURESIZE", nSize);
//:: Fire NWNxEE shim
ExecuteScript("prcx_set_size", oCreature);
}
/* void PRC_Funcs_SetCreatureSize (object oCreature, int nSize)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1 || nVersion == 2) if (nVersion == 1 || nVersion == 2)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETCREATURESIZE", nSize); _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETCREATURESIZE", nSize);
} } */
void PRC_Funcs_SetRace(object oCreature, int nRace) void PRC_Funcs_SetRace(object oCreature, int nRace)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); //:: Pass parameters via locals
SetLocalInt(oCreature, "PRC_EE_RACETYPE", nRace);
//:: Fire NWNxEE shim
ExecuteScript("prcx_set_race", oCreature);
}
/* void PRC_Funcs_SetRace(object oCreature, int nRace)
{
int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1) if (nVersion == 1)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETRACE", nRace); _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETRACE", nRace);
else if (nVersion == 2) else if (nVersion == 2)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETRACIALTYPE", nRace); _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETRACIALTYPE", nRace);
} */
void PRC_Funcs_SetWizardSpecialization(object oCreature, int iSpecialization, int nClass = CLASS_TYPE_WIZARD)
{
//:: Pass parameters via locals
SetLocalInt(oCreature, "PRC_EE_WIZCLASS", nClass);
SetLocalInt(oCreature, "PRC_EE_WIZSCHOOL", iSpecialization);
//:: Fire NWNxEE shim
ExecuteScript("prcx_set_spec", oCreature);
} }
void PRC_Funcs_SetWizardSpecialization(object oCreature, int iSpecialization) /* void PRC_Funcs_SetWizardSpecialization(object oCreature, int iSpecialization)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1 || nVersion == 2) if (nVersion == 1 || nVersion == 2)
_PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETWIZARDSPECIALIZATION", iSpecialization); _PRC_NWNXFuncsOne(oCreature, "NWNX!FUNCS!SETWIZARDSPECIALIZATION", iSpecialization);
} */
//:: This is a native function now.
int PRC_Funcs_GetWizardSpecialization(object oCreature, int nClass = CLASS_TYPE_WIZARD)
{
return GetSpecialization(oCreature, nClass);
} }
int PRC_Funcs_GetWizardSpecialization(object oCreature) /* int PRC_Funcs_GetWizardSpecialization(object oCreature)
{ {
int nVersion = GetLocalInt(GetModule(), "PRC_NWNX_FUNCS"); int nVersion = GetLocalInt(GetModule(), "PRC_NWNXEE_ENABLED");
if (nVersion == 1 || nVersion == 2) if (nVersion == 1 || nVersion == 2)
return _PRC_NWNXFuncsZero(oCreature, "NWNX!FUNCS!GETWIZARDSPECIALIZATION"); return _PRC_NWNXFuncsZero(oCreature, "NWNX!FUNCS!GETWIZARDSPECIALIZATION");
return 0; return 0;
} } */
//:: void main(){}

View File

@@ -686,3 +686,16 @@ string SQLocalsPlayer_GetLastUpdated_UTC(object oPlayer, string sVarName, int nT
else else
return ""; return "";
} }
// Returns the current Unix timestamp (seconds since 1970-01-01)
int GetCurrentUnixTimestamp()
{
sqlquery sql = SqlPrepareQueryObject(GetModule(),
"SELECT strftime('%s','now');");
if (SqlStep(sql))
return SqlGetInt(sql, 0);
else
return 0;
}

View File

@@ -867,6 +867,7 @@ void CreateSwitchNameArray()
//if you add more switches, add them to this list //if you add more switches, add them to this list
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEBUG); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEBUG);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_COMBAT_DEBUG); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_COMBAT_DEBUG);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PRCX_ENABLED);
//craft //craft
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CRAFT); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CRAFT);
@@ -892,6 +893,7 @@ void CreateSwitchNameArray()
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_OPTIONAL_HERBS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_OPTIONAL_HERBS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_SCEPTER_CASTER_LEVEL); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_SCEPTER_CASTER_LEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SHOW_SR_CHECK_DETAILS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_MATERIAL_COMPONENTS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_MATERIAL_COMPONENTS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_COMPONENTS_SHOP); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_COMPONENTS_SHOP);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_TRUESEEING); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_TRUESEEING);
@@ -1115,7 +1117,8 @@ void CreateSwitchNameArray()
//general //general
//PW //PW
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENABLE); // ConvoCC is unneeded now.
/* array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENABLE);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_AVARIEL_WINGS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_AVARIEL_WINGS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_FEYRI_WINGS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_FEYRI_WINGS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_AASIMAR_WINGS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_AASIMAR_WINGS);
@@ -1145,7 +1148,7 @@ void CreateSwitchNameArray()
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_MAX_STAT); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_MAX_STAT);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_SKILL_MULTIPLIER); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_SKILL_MULTIPLIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_SKILL_BONUS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_SKILL_BONUS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_CUSTOM_EXIT_SCRIPT); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_CUSTOM_EXIT_SCRIPT); */
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_CR_MULTIPLIER); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_CR_MULTIPLIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_LEVEL_BONUS); array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_LEVEL_BONUS);

View File

@@ -39,8 +39,10 @@ int InvocationASFCheck(object oInvoker, int nClass)
case 1: nASF -= 5; break;//light case 1: nASF -= 5; break;//light
case 2: nASF -= 10; break;//light case 2: nASF -= 10; break;//light
case 3: nASF -= 20; break;//light case 3: nASF -= 20; break;//light
case 4: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 20 : 0; break;//medium; //case 4: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 20 : 0; break; //medium;
case 5: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 30 : 0; break;//medium //case 5: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 30 : 0; break; //medium
case 4: nASF = GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 0 : nASF; break; //medium
case 5: nASF = GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 0 : nASF; break; //medium;
default: break; default: break;
} }
} }

View File

@@ -40,6 +40,7 @@ struct ipstruct GetIpStructFromString(string sIp);
//#include "prc_inc_listener" //#include "prc_inc_listener"
#include "prc_inc_chat" #include "prc_inc_chat"
#include "prc_x2_craft" #include "prc_x2_craft"
#include "prc_inc_material"
const int NUM_MAX_PROPERTIES = 200; const int NUM_MAX_PROPERTIES = 200;
const int NUM_MAX_SUBTYPES = 256; const int NUM_MAX_SUBTYPES = 256;
@@ -1807,6 +1808,11 @@ int GetCraftingDC(object oItem)
void MakeMasterwork(object oItem) void MakeMasterwork(object oItem)
{ {
if(GetPlotFlag(oItem)) return; //sanity check if(GetPlotFlag(oItem)) return; //sanity check
itemproperty ip = ItemPropertyQuality(IP_CONST_QUALITY_MASTERWORK);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
int nBase = GetBaseItemType(oItem); int nBase = GetBaseItemType(oItem);
if((nBase == BASE_ITEM_ARMOR) || if((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) || (nBase == BASE_ITEM_SMALLSHIELD) ||
@@ -1816,6 +1822,70 @@ void MakeMasterwork(object oItem)
{ {
//no armour check penalty here //no armour check penalty here
if(GetItemArmourCheckPenalty(oItem) == 0) return; if(GetItemArmourCheckPenalty(oItem) == 0) return;
ip = ItemPropertySkillBonus(SKILL_BALANCE, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_CLIMB, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_HIDE, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_PICK_POCKET, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_SET_TRAP, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_TUMBLE, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_JUMP, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
else if(GetWeaponType(nBase))
{
ip = ItemPropertyAttackBonus(1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
else if(StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == PRC_CRAFT_ITEM_TYPE_AMMO)
{
ip = ItemPropertyAttackBonus(1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
else
return;
}
/* void MakeMasterwork(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
int nBase = GetBaseItemType(oItem);
if((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD)
)
{
//no armour check penalty here
if(GetItemArmourCheckPenalty(oItem) == 0) return;
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_HIDE, 1) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_HIDE, 1) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, 1), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, 1), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_PICK_POCKET, 1) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_PICK_POCKET, 1) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
@@ -1829,17 +1899,226 @@ void MakeMasterwork(object oItem)
} }
else if(StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == PRC_CRAFT_ITEM_TYPE_AMMO) else if(StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == PRC_CRAFT_ITEM_TYPE_AMMO)
{ {
/*
int nDamageType = (nBase == BASE_ITEM_BULLET) ? DAMAGE_TYPE_BLUDGEONING : DAMAGE_TYPE_PIERCING; //int nDamageType = (nBase == BASE_ITEM_BULLET) ? DAMAGE_TYPE_BLUDGEONING : DAMAGE_TYPE_PIERCING;
itemproperty ip1 = ItemPropertyDamageBonus(nDamageType, IP_CONST_DAMAGEBONUS_1); //itemproperty ip1 = ItemPropertyDamageBonus(nDamageType, IP_CONST_DAMAGEBONUS_1);
*/
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(1), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(1), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
} }
else else
return; return;
} }
*/
void MakeAdamantine(object oItem) void MakeAdamantine(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
{
int nBonus = 0;
switch(GetItemBaseAC(oItem))
{
case 1:
case 2:
case 3: nBonus = IP_CONST_DAMAGERESIST_1; break;
case 4:
case 5: nBonus = IP_CONST_DAMAGERESIST_2; break;
case 6:
case 7:
case 8: nBonus = IP_CONST_DAMAGERESIST_3; break;
}
if(nBonus)
{
itemproperty ip = ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_BLUDGEONING, nBonus);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_PIERCING, nBonus);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_SLASHING, nBonus);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyMaterial(IP_MATERIAL_ADAMANTINE);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
}
void MakeDarkwood(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
itemproperty ip = ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
int nBase = GetBaseItemType(oItem);
if(((nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD))
)
{
int nBonus = 2;
if(nBase == BASE_ITEM_SMALLSHIELD) nBonus = 1;
ip = ItemPropertySkillBonus(SKILL_BALANCE, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_CLIMB, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_HIDE, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_PICK_POCKET, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_TUMBLE, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_JUMP, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyMaterial(IP_MATERIAL_WOOD_DARKWOOD_ZALANTAR);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
void MakeDragonhide(object oItem)
{
//Does nothing so far
}
void MakeMithral(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
itemproperty ip = ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
int nBase = GetBaseItemType(oItem);
if(GetWeaponType(nBase))
{
ip = ItemPropertyMaterial(IP_MATERIAL_MITHRAL);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
else if(((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD))
)
{
int nBonus = 3;
int nPenalty = GetItemArmourCheckPenalty(oItem);
if(nBonus > nPenalty) nBonus = nPenalty;
ip = ItemPropertySkillBonus(SKILL_BALANCE, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_CLIMB, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_HIDE, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_PICK_POCKET, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_TUMBLE, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_JUMP, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyMaterial(IP_MATERIAL_MITHRAL);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
if(GetItemBaseAC(oItem) == 1)
{
ip = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
else
{
ip = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
}
void MakeColdIron(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_COLD_IRON);
ip = TagItemProperty(ip, "Material_ColdIron");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeSilver(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_SILVER);
ip = TagItemProperty(ip, "Material_ColdIron");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeMundaneCrystal(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_MUNDANE);
ip = TagItemProperty(ip, "Material_MundaneCrystal");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeDeepCrystal(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_DEEP);
ip = TagItemProperty(ip, "Material_DeepCrystal");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
/* void MakeAdamantine(object oItem)
{ {
if(GetPlotFlag(oItem)) return; //sanity check if(GetPlotFlag(oItem)) return; //sanity check
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR) if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
@@ -1861,11 +2140,14 @@ void MakeAdamantine(object oItem)
IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_BLUDGEONING, nBonus), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_BLUDGEONING, nBonus), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_PIERCING, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_PIERCING, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_SLASHING, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_SLASHING, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
itemproperty ipAdamantine = ItemPropertyMaterial(IP_MATERIAL_ADAMANTINE);
IPSafeAddItemProperty(oItem, ipAdamantine, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
} }
} } */
void MakeDarkwood(object oItem) /* void MakeDarkwood(object oItem)
{ {
if(GetPlotFlag(oItem)) return; //sanity check if(GetPlotFlag(oItem)) return; //sanity check
IPSafeAddItemProperty(oItem, ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
@@ -1883,10 +2165,14 @@ void MakeDarkwood(object oItem)
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_TUMBLE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_TUMBLE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_JUMP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_JUMP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
itemproperty ipDarkwood = ItemPropertyMaterial(IP_MATERIAL_WOOD_DARKWOOD_ZALANTAR);
IPSafeAddItemProperty(oItem, ipDarkwood, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
} }
*/
void MakeDragonhide(object oItem) /* void MakeDragonhide(object oItem)
{ {
//Does nothing so far //Does nothing so far
} }
@@ -1911,34 +2197,50 @@ void MakeMithral(object oItem)
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_TUMBLE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_TUMBLE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_JUMP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_JUMP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_BALANCE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_BALANCE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_CLIMB, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_CLIMB, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
if(GetItemBaseAC(oItem) == 1) if(GetItemBaseAC(oItem) == 1)
IPSafeAddItemProperty(oItem, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
else else
IPSafeAddItemProperty(oItem, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); IPSafeAddItemProperty(oItem, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
itemproperty ipMithral = ItemPropertyMaterial(IP_MATERIAL_MITHRAL);
IPSafeAddItemProperty(oItem, ipMithral, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
} }
*/
void MakeColdIron(object oItem) /* void MakeColdIron(object oItem)
{ {
//Does nothing so far //Does nothing so far
itemproperty ipColdIron = ItemPropertyMaterial(IP_MATERIAL_COLD_IRON);
IPSafeAddItemProperty(oItem, ipColdIron, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
*/
void MakeSilver(object oItem) /* void MakeSilver(object oItem)
{ {
//Does nothing so far //Does nothing so far
itemproperty ipSilver = ItemPropertyMaterial(IP_MATERIAL_SILVER);
IPSafeAddItemProperty(oItem, ipSilver, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
*/
void MakeMundaneCrystal(object oItem) /* void MakeMundaneCrystal(object oItem)
{ {
//Does nothing so far //Does nothing so far
itemproperty ipCrystal = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_MUNDANE);
IPSafeAddItemProperty(oItem, ipCrystal, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
*/
void MakeDeepCrystal(object oItem) /* void MakeDeepCrystal(object oItem)
{ {
//Does nothing so far //Does nothing so far
itemproperty ipDeepCrystal = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_DEEP);
IPSafeAddItemProperty(oItem, ipDeepCrystal, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
} }
*/
//Creates an item on oOwner, from the baseitemtype and base AC (for armour) //Creates an item on oOwner, from the baseitemtype and base AC (for armour)
object CreateStandardItem(object oOwner, int nBaseItemType, int nBaseAC = -1) object CreateStandardItem(object oOwner, int nBaseItemType, int nBaseAC = -1)
@@ -2967,4 +3269,4 @@ int ITEM_APPR_WEAPON_COLOR_MIDDLE = 1;
int ITEM_APPR_WEAPON_COLOR_TOP = 2; int ITEM_APPR_WEAPON_COLOR_TOP = 2;
*/ */
// void main () {} //:: void main () {}

View File

@@ -498,6 +498,7 @@ effect EffectFatigue(){
effect eReturn = EffectAbilityDecrease(ABILITY_STRENGTH, 2); effect eReturn = EffectAbilityDecrease(ABILITY_STRENGTH, 2);
eReturn = EffectLinkEffects(eReturn, EffectAbilityDecrease(ABILITY_DEXTERITY, 2)); eReturn = EffectLinkEffects(eReturn, EffectAbilityDecrease(ABILITY_DEXTERITY, 2));
eReturn = EffectLinkEffects(eReturn, EffectMovementSpeedDecrease(25)); eReturn = EffectLinkEffects(eReturn, EffectMovementSpeedDecrease(25));
eReturn = EffectLinkEffects(eReturn, EffectIcon(EFFECT_ICON_FATIGUE));
eReturn = TagEffect(eReturn, "PRCFatigue"); eReturn = TagEffect(eReturn, "PRCFatigue");
return eReturn; return eReturn;
} }

View File

@@ -341,6 +341,16 @@ const int FEAT_FOG_CLOUD_BREATH = 5434; //:: Spiretop Dragon
const int FEAT_LTSENSE = 4700; const int FEAT_LTSENSE = 4700;
const int FEAT_LTBLIND = 4701; const int FEAT_LTBLIND = 4701;
const int FEAT_RESIST_SONIC5 = 26398; //:: Shyft
const int FEAT_SHYFT_ETHEREAL_JAUNT = 26399;
const int FEAT_MECHA_ELECTRICY_HEALING = 4431; //:: Mechanatrix
const int FEAT_MECHA_SHOCKING_GRASP = 4432;
const int FEAT_WISPLING_CHANGE_SHAPE = 4433; //:: Wispling
const int FEAT_MAELUTH_FIEND_HAMMER = 4434; //:: Maeluth
const int FEAT_SPELL5 = 4702; const int FEAT_SPELL5 = 4702;
const int FEAT_SPELL10 = 4420; const int FEAT_SPELL10 = 4420;
const int FEAT_SPELL11 = 4703; const int FEAT_SPELL11 = 4703;
@@ -404,6 +414,8 @@ const int FEAT_CONSTRICT = 4740;
const int FEAT_REGEN5 = 4741; const int FEAT_REGEN5 = 4741;
const int FEAT_REND = 4742; const int FEAT_REND = 4742;
const int FEAT_RESIST_FIRE5 = 4743; const int FEAT_RESIST_FIRE5 = 4743;
const int FEAT_RESIST_COLD5 = 4430;
const int FEAT_SUFFOCATION = 4744; const int FEAT_SUFFOCATION = 4744;
const int FEAT_VERYHEROIC = 4745; const int FEAT_VERYHEROIC = 4745;
const int FEAT_VULN_COLD = 4746; const int FEAT_VULN_COLD = 4746;
@@ -966,32 +978,35 @@ const int FEAT_KOB_DRAGONWROUGHT_SR = 3855;
const int FEAT_DRAGON_AUGMENT_STR_1 = 3857; const int FEAT_DRAGON_AUGMENT_STR_1 = 3857;
const int FEAT_DRAGON_AUGMENT_STR_2 = 3858; const int FEAT_DRAGON_AUGMENT_STR_2 = 3858;
const int FEAT_DRAGON_AUGMENT_STR_3 = 3859; const int FEAT_DRAGON_AUGMENT_STR_3 = 3859;
const int FEAT_DRAGON_AUGMENT_STR_4 = 26382; const int FEAT_DRAGON_AUGMENT_STR_4 = 25645;
const int FEAT_DRAGON_AUGMENT_STR_5 = 26383; const int FEAT_DRAGON_AUGMENT_STR_5 = 25646;
const int FEAT_DRAGON_AUGMENT_STR_6 = 26384; const int FEAT_DRAGON_AUGMENT_STR_6 = 25647;
const int FEAT_DRAGON_AUGMENT_STR_7 = 26385; const int FEAT_DRAGON_AUGMENT_STR_7 = 25648;
const int FEAT_DRAGON_AUGMENT_STR_8 = 26386; const int FEAT_DRAGON_AUGMENT_STR_8 = 25649;
const int FEAT_DRAGON_AUGMENT_STR_9 = 26387; const int FEAT_DRAGON_AUGMENT_STR_9 = 25650;
const int FEAT_DRAGON_AUGMENT_STR_10 = 25651;
const int FEAT_DRAGON_AUGMENT_DEX_1 = 3860; const int FEAT_DRAGON_AUGMENT_DEX_1 = 3860;
const int FEAT_DRAGON_AUGMENT_DEX_2 = 3861; const int FEAT_DRAGON_AUGMENT_DEX_2 = 3861;
const int FEAT_DRAGON_AUGMENT_DEX_3 = 3862; const int FEAT_DRAGON_AUGMENT_DEX_3 = 3862;
const int FEAT_DRAGON_AUGMENT_DEX_4 = 26388; const int FEAT_DRAGON_AUGMENT_DEX_4 = 25653;
const int FEAT_DRAGON_AUGMENT_DEX_5 = 26389; const int FEAT_DRAGON_AUGMENT_DEX_5 = 25654;
const int FEAT_DRAGON_AUGMENT_DEX_6 = 26390; const int FEAT_DRAGON_AUGMENT_DEX_6 = 25655;
const int FEAT_DRAGON_AUGMENT_DEX_7 = 26391; const int FEAT_DRAGON_AUGMENT_DEX_7 = 25656;
const int FEAT_DRAGON_AUGMENT_DEX_8 = 26392; const int FEAT_DRAGON_AUGMENT_DEX_8 = 25657;
const int FEAT_DRAGON_AUGMENT_DEX_9 = 26393; const int FEAT_DRAGON_AUGMENT_DEX_9 = 25658;
const int FEAT_DRAGON_AUGMENT_DEX_10 = 25659;
const int FEAT_DRAGON_AUGMENT_CON_1 = 3863; const int FEAT_DRAGON_AUGMENT_CON_1 = 3863;
const int FEAT_DRAGON_AUGMENT_CON_2 = 3864; const int FEAT_DRAGON_AUGMENT_CON_2 = 3864;
const int FEAT_DRAGON_AUGMENT_CON_3 = 3865; const int FEAT_DRAGON_AUGMENT_CON_3 = 3865;
const int FEAT_DRAGON_AUGMENT_CON_4 = 26394; const int FEAT_DRAGON_AUGMENT_CON_4 = 25661;
const int FEAT_DRAGON_AUGMENT_CON_5 = 26395; const int FEAT_DRAGON_AUGMENT_CON_5 = 25662;
const int FEAT_DRAGON_AUGMENT_CON_6 = 26396; const int FEAT_DRAGON_AUGMENT_CON_6 = 25663;
const int FEAT_DRAGON_AUGMENT_CON_7 = 26397; const int FEAT_DRAGON_AUGMENT_CON_7 = 25664;
const int FEAT_DRAGON_AUGMENT_CON_8 = 26398; const int FEAT_DRAGON_AUGMENT_CON_8 = 25665;
const int FEAT_DRAGON_AUGMENT_CON_9 = 26399; const int FEAT_DRAGON_AUGMENT_CON_9 = 25666;
const int FEAT_DRAGON_AUGMENT_CON_10 = 25667;
const int FEAT_CHANNEL_DRACLAWS = 3866; const int FEAT_CHANNEL_DRACLAWS = 3866;
const int FEAT_PSIONIC_BREATH = 3867; const int FEAT_PSIONIC_BREATH = 3867;
@@ -1482,9 +1497,13 @@ const int FEAT_VILE_MARTIAL_MINDBLADE = 3624;
const int FEAT_VILE_MARTIAL_WHIP = 3598; const int FEAT_VILE_MARTIAL_WHIP = 3598;
const int FEAT_VILE_MARTIAL_TRIDENT = 3599; const int FEAT_VILE_MARTIAL_TRIDENT = 3599;
// Weapon Focus (Ray) //:: Spell-like Weapons
const int FEAT_WEAPON_FOCUS_RAY = 4819; const int FEAT_WEAPON_FOCUS_RAY = 4819;
const int FEAT_EPIC_WEAPON_FOCUS_RAY = 4820; const int FEAT_EPIC_WEAPON_FOCUS_RAY = 4820;
const int FEAT_IMPROVED_CRITICAL_TOUCH = 26009;
const int FEAT_IMPROVED_CRITICAL_RAY = 26010;
const int FEAT_WEAPON_FOCUS_TOUCH = 26011;
const int FEAT_EPIC_WEAPON_FOCUS_TOUCH = 26012;
// Battleguard Tempus // Battleguard Tempus
const int TEMPUS_ABILITY_ENHANC1 = 1; const int TEMPUS_ABILITY_ENHANC1 = 1;
@@ -3025,6 +3044,7 @@ const int FEAT_SPLIT_PSIONIC_RAY = 4941;
const int FEAT_TWIN_POWER = 4942; const int FEAT_TWIN_POWER = 4942;
const int FEAT_WIDEN_POWER = 4943; const int FEAT_WIDEN_POWER = 4943;
const int FEAT_QUICKEN_POWER = 4944; const int FEAT_QUICKEN_POWER = 4944;
const int FEAT_DEFENSIVE_MANIFESTATION = 2350;
// Sanctified Mind // Sanctified Mind
const int FEAT_SANCMIND_PARTITION_MIND = 2231; const int FEAT_SANCMIND_PARTITION_MIND = 2231;
@@ -6335,6 +6355,13 @@ const int FEAT_HIDDEN_TALENT_THICKSKIN = 25944;
const int FEAT_HIDDEN_TALENT_VIGOR = 25945; const int FEAT_HIDDEN_TALENT_VIGOR = 25945;
const int FEAT_HIDDEN_TALENT_GRIP_IRON = 25946; const int FEAT_HIDDEN_TALENT_GRIP_IRON = 25946;
//:: Player's Handbook II feats
const int FEAT_COMBAT_FOCUS = -9999;
const int FEAT_COMBAT_STABILITY = -9998;
const int FEAT_COMBAT_DEFENSE = -9997;
const int FEAT_COMBAT_VIGOR = -9996;
const int FEAT_COMBAT_AWARENESS = -9995;
const int FEAT_COMBAT_STRIKE = -9994;

View File

@@ -244,7 +244,7 @@ void ApplyPseudonatural(object oFamiliar, object oFamSkin)
void ApplyIllmaster(object oCompanion, object oCompSkin) void ApplyIllmaster(object oCompanion, object oCompSkin)
{ {
//Give the companion permanent Str +4, Con +2, Wis -2, and Cha -2 //Give the companion permanent Str +4, Con +2, Wis -2, and Cha -2
if(GetPRCSwitch(PRC_NWNX_FUNCS)) if(GetPRCSwitch(PRC_NWNXEE_ENABLED))
{ {
PRC_Funcs_ModAbilityScore(oCompanion, ABILITY_STRENGTH, 4); PRC_Funcs_ModAbilityScore(oCompanion, ABILITY_STRENGTH, 4);
PRC_Funcs_ModAbilityScore(oCompanion, ABILITY_CONSTITUTION, 2); PRC_Funcs_ModAbilityScore(oCompanion, ABILITY_CONSTITUTION, 2);
@@ -305,7 +305,7 @@ void WinterWolfProperties(object oCompanion, int nLevel)
object oCreR = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oCompanion); object oCreR = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oCompanion);
if(GetPRCSwitch(PRC_NWNX_FUNCS)) if(GetPRCSwitch(PRC_NWNXEE_ENABLED))
{ {
if(iStr > 0) if(iStr > 0)
PRC_Funcs_ModAbilityScore(oCompanion, ABILITY_STRENGTH, iStr); PRC_Funcs_ModAbilityScore(oCompanion, ABILITY_STRENGTH, iStr);
@@ -358,7 +358,10 @@ void WinterWolfProperties(object oCompanion, int nLevel)
void ApplyPnPFamiliarProperties(object oPC, object oFam) void ApplyPnPFamiliarProperties(object oPC, object oFam)
{ {
int bFuncs = GetPRCSwitch(PRC_NWNX_FUNCS); int nNWNxEE = GetPRCSwitch(PRC_NWNXEE_ENABLED);
int nPRCx = GetPRCSwitch(PRC_PRCX_ENABLED);
int bFuncs = (nNWNxEE && nPRCx);
effect eBonus; effect eBonus;
//get familiar level //get familiar level

View File

@@ -168,8 +168,8 @@ void ExhaleImmunity(object oDragon, int nDamageType, location lTargetArea)
effect eLink = EffectLinkEffects(eImmune, eVis2); effect eLink = EffectLinkEffects(eImmune, eVis2);
//apply effects //apply effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmune, oTarget, fDuration)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmune, oTarget, fDuration));
} }
} }
@@ -603,15 +603,15 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC, SAVING_THROW_TYPE_NONE)) if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC, SAVING_THROW_TYPE_NONE))
{ {
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_POISON_L), oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_POISON_L), oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSickened(), oTarget, 12.0)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSickened(), oTarget, 12.0));
} }
//1 round otherwise //1 round otherwise
else else
{ {
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_POISON_L), oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_POISON_L), oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSickened(), oTarget, 6.0)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSickened(), oTarget, 6.0));
} }
} }
@@ -659,16 +659,16 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC, SAVING_THROW_TYPE_NONE)) if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC, SAVING_THROW_TYPE_NONE))
{ {
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nSlowDuration))); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nSlowDuration)));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
} }
//Adept breath effect still lasts for one round if save is made //Adept breath effect still lasts for one round if save is made
else if(IsAdeptBreath()) else if(IsAdeptBreath())
{ {
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(1))); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(1)));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
} }
} }
@@ -685,10 +685,10 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
//Set Damage and VFX - Bioware Gold used VFX_IMP_REDUCE_ABILITY_SCORE originally //Set Damage and VFX - Bioware Gold used VFX_IMP_REDUCE_ABILITY_SCORE originally
eVis = EffectVisualEffect(VFX_IMP_POISON_L); eVis = EffectVisualEffect(VFX_IMP_POISON_L);
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
//adept breath penalty only last 4 rounds on failure, gold breath has no duration //adept breath penalty only last 4 rounds on failure, gold breath has no duration
if(IsAdeptBreath()) if(IsAdeptBreath())
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAbilityDecrease(ABILITY_STRENGTH, BreathUsed.nDiceNumber), oTarget, 24.0)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAbilityDecrease(ABILITY_STRENGTH, BreathUsed.nDiceNumber), oTarget, 24.0));
else else
DelayCommand(fDelay, ApplyAbilityDamage(oTarget, ABILITY_STRENGTH, BreathUsed.nDiceNumber, DURATION_TYPE_PERMANENT, TRUE)); DelayCommand(fDelay, ApplyAbilityDamage(oTarget, ABILITY_STRENGTH, BreathUsed.nDiceNumber, DURATION_TYPE_PERMANENT, TRUE));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
@@ -699,8 +699,8 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
//Set Damage and VFX - Bioware Gold used VFX_IMP_REDUCE_ABILITY_SCORE originally //Set Damage and VFX - Bioware Gold used VFX_IMP_REDUCE_ABILITY_SCORE originally
eVis = EffectVisualEffect(VFX_IMP_POISON_L); eVis = EffectVisualEffect(VFX_IMP_POISON_L);
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAbilityDecrease(ABILITY_STRENGTH, BreathUsed.nDiceNumber), oTarget, 12.0)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAbilityDecrease(ABILITY_STRENGTH, BreathUsed.nDiceNumber), oTarget, 12.0));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
} }
bCanCling = TRUE; bCanCling = TRUE;
@@ -729,7 +729,7 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC, SAVING_THROW_TYPE_NONE)) if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC, SAVING_THROW_TYPE_NONE))
{ {
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nParalDuration))); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nParalDuration)));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
} }
} }
@@ -749,8 +749,8 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
eBreath = EffectNegativeLevel(nLevelDrain); eBreath = EffectNegativeLevel(nLevelDrain);
eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY); eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
} }
} }
@@ -769,11 +769,11 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
if (nAdjustedDamage > 0) if (nAdjustedDamage > 0)
{ {
//Set Damage and VFX //Set Damage and VFX
eBreath = EffectDamage(nAdjustedDamage, BreathUsed.nDamageType); eBreath = PRCEffectDamage(oTarget, nAdjustedDamage, BreathUsed.nDamageType);
eVis = EffectVisualEffect(VFX_IMP_SUNSTRIKE); eVis = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
bCanCling = TRUE; bCanCling = TRUE;
} }
@@ -830,8 +830,8 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
if(GetLocalInt(oTarget, "DragonWard")) if(GetLocalInt(oTarget, "DragonWard"))
nAdjustedDamage -= 40; nAdjustedDamage -= 40;
effect eBreath1 = EffectDamage(nAdjustedDamage/2, DAMAGE_TYPE_FIRE); effect eBreath1 = PRCEffectDamage(oTarget, nAdjustedDamage/2, DAMAGE_TYPE_FIRE);
effect eBreath2 = EffectDamage(nAdjustedDamage/2, DAMAGE_TYPE_SONIC); effect eBreath2 = PRCEffectDamage(oTarget, nAdjustedDamage/2, DAMAGE_TYPE_SONIC);
eBreath = EffectLinkEffects(eBreath1, eBreath2); eBreath = EffectLinkEffects(eBreath1, eBreath2);
eVis = EffectVisualEffect(chVisual); eVis = EffectVisualEffect(chVisual);
} }
@@ -839,12 +839,12 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
{ {
if(GetLocalInt(oTarget, "DragonWard")) if(GetLocalInt(oTarget, "DragonWard"))
nAdjustedDamage -= 20; nAdjustedDamage -= 20;
eBreath = EffectDamage(nAdjustedDamage, BreathUsed.nDamageType); eBreath = PRCEffectDamage(oTarget, nAdjustedDamage, BreathUsed.nDamageType);
eVis = EffectVisualEffect(nVisualType); eVis = EffectVisualEffect(nVisualType);
} }
//Apply the VFX impact and effects //Apply the VFX impact and effects
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget));
SetLocalInt(oTarget, "AffectedByBreath", TRUE); SetLocalInt(oTarget, "AffectedByBreath", TRUE);
bCanCling = TRUE; bCanCling = TRUE;
} }
@@ -859,7 +859,7 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nKnockdownDC, SAVING_THROW_TYPE_NONE)) if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nKnockdownDC, SAVING_THROW_TYPE_NONE))
{ {
effect eWindblown = EffectKnockdown(); effect eWindblown = EffectKnockdown();
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWindblown, oTarget, 6.0)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWindblown, oTarget, 6.0));
} }
} }
} }
@@ -879,10 +879,10 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
//Warforged are only healed for half //Warforged are only healed for half
if(GetIsWarforged(oTarget)) nHeal /= 2; if(GetIsWarforged(oTarget)) nHeal /= 2;
eBreath = EffectHeal(nHeal); eBreath = PRCEffectHeal(nHeal, oTarget);
effect eHealVis = EffectVisualEffect(VFX_IMP_HEALING_S); effect eHealVis = EffectVisualEffect(VFX_IMP_HEALING_S);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eBreath, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHealVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHealVis, oTarget));
} }
//Entangling Exhalation //Entangling Exhalation
@@ -896,22 +896,22 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
//only does damage if the original breath did damage //only does damage if the original breath did damage
if(BreathUsed.nDamageType > 0) if(BreathUsed.nDamageType > 0)
{ {
effect eDamage = EffectDamage(d6(), BreathUsed.nDamageType); effect eDamage = PRCEffectDamage(oTarget, d6(), BreathUsed.nDamageType);
switch(nEntangleRounds) switch(nEntangleRounds)
{ {
case 4: case 4:
DelayCommand(fDelay + RoundsToSeconds(4), ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget)); DelayCommand(fDelay + RoundsToSeconds(4), SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
case 3: case 3:
DelayCommand(fDelay + RoundsToSeconds(3), ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget)); DelayCommand(fDelay + RoundsToSeconds(3), SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
case 2: case 2:
DelayCommand(fDelay + RoundsToSeconds(2), ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget)); DelayCommand(fDelay + RoundsToSeconds(2), SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
case 1: case 1:
DelayCommand(fDelay + RoundsToSeconds(1), ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget)); break; DelayCommand(fDelay + RoundsToSeconds(1), SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget)); break;
} }
} }
//but always entangles if the breath affects the target //but always entangles if the breath affects the target
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEntangled, oTarget, RoundsToSeconds(nEntangleRounds))); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEntangled, oTarget, RoundsToSeconds(nEntangleRounds)));
} }
DeleteLocalInt(oTarget, "AffectedByBreath"); DeleteLocalInt(oTarget, "AffectedByBreath");
@@ -937,18 +937,18 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
{ {
if(nAdjustedDamage < 3) nCount = BreathUsed.nClinging; if(nAdjustedDamage < 3) nCount = BreathUsed.nClinging;
effect eBreath1 = EffectDamage(nAdjustedDamage/2, DAMAGE_TYPE_FIRE); effect eBreath1 = PRCEffectDamage(oTarget, nAdjustedDamage/2, DAMAGE_TYPE_FIRE);
effect eBreath2 = EffectDamage(nAdjustedDamage/2, DAMAGE_TYPE_SONIC); effect eBreath2 = PRCEffectDamage(oTarget, nAdjustedDamage/2, DAMAGE_TYPE_SONIC);
effect eAfterBreath = EffectLinkEffects(eBreath1, eBreath2); effect eAfterBreath = EffectLinkEffects(eBreath1, eBreath2);
DelayCommand(fNewDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eAfterBreath, oTarget)); DelayCommand(fNewDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eAfterBreath, oTarget));
} }
else else
{ {
if(nAdjustedDamage < 2) nCount = BreathUsed.nClinging; if(nAdjustedDamage < 2) nCount = BreathUsed.nClinging;
effect eAfterBreath = EffectDamage(nAdjustedDamage, BreathUsed.nDamageType); effect eAfterBreath = PRCEffectDamage(oTarget, nAdjustedDamage, BreathUsed.nDamageType);
DelayCommand(fNewDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eAfterBreath, oTarget)); DelayCommand(fNewDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eAfterBreath, oTarget));
} }
DelayCommand(fNewDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fNewDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
} }
} }
} }
@@ -988,3 +988,5 @@ void PRCPlayDragonBattleCry()
PlayVoiceChat(VOICE_CHAT_BATTLECRY2); PlayVoiceChat(VOICE_CHAT_BATTLECRY2);
} }
} }
//:: void main() {}

View File

@@ -576,7 +576,7 @@ int PRCGetCasterLevel(object oCaster = OBJECT_SELF)
} }
// Casting as a bard but don't have any levels in the class //:: Double-dipping? // Casting as a bard but don't have any levels in the class //:: Double-dipping?
/* if(iCastingClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oCaster)) if(iCastingClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
{ {
int nRace = GetRacialType(oCaster); int nRace = GetRacialType(oCaster);
@@ -584,7 +584,7 @@ int PRCGetCasterLevel(object oCaster = OBJECT_SELF)
//otherwise use RHD instead of bard levels //otherwise use RHD instead of bard levels
if(nRace == RACIAL_TYPE_GLOURA) if(nRace == RACIAL_TYPE_GLOURA)
iReturnLevel = GetLevelByClass(CLASS_TYPE_FEY); iReturnLevel = GetLevelByClass(CLASS_TYPE_FEY);
} */ }
//Spell Rage ability //Spell Rage ability
if(GetHasSpellEffect(SPELL_SPELL_RAGE, oCaster) if(GetHasSpellEffect(SPELL_SPELL_RAGE, oCaster)
@@ -797,6 +797,10 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if (nCastingClass == CLASS_TYPE_BARD || GetLevelByClass(CLASS_TYPE_BARD, oCaster)) if (nCastingClass == CLASS_TYPE_BARD || GetLevelByClass(CLASS_TYPE_BARD, oCaster))
{ {
// Don't execute for Gloura Fey spellcasters - they're handled in the Fey section
if(GetRacialType(oCaster) == RACIAL_TYPE_GLOURA && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
return nArcane;
//:: Includes RHD as bard. If they started with bard levels, then it //:: Includes RHD as bard. If they started with bard levels, then it
//:: counts as a prestige class, otherwise RHD is used instead of bard levels. //:: counts as a prestige class, otherwise RHD is used instead of bard levels.
if(nRace == RACIAL_TYPE_GLOURA) if(nRace == RACIAL_TYPE_GLOURA)
@@ -960,7 +964,7 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
} }
//:: End Bard Arcane PrC casting calculations //:: End Bard Arcane PrC casting calculations
if(nCastingClass == CLASS_TYPE_BARD || nCastingClass == CLASS_TYPE_BARD && nRace == RACIAL_TYPE_GLOURA && !GetLevelByClass(CLASS_TYPE_BARD, oCaster)) if(nCastingClass == CLASS_TYPE_BARD || nCastingClass == CLASS_TYPE_FEY && nRace == RACIAL_TYPE_GLOURA && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
{ {
if(DEBUG) DoDebug("prc_inc_castlvl >> Found Fey RHD caster (not bard)"); if(DEBUG) DoDebug("prc_inc_castlvl >> Found Fey RHD caster (not bard)");

View File

@@ -480,7 +480,7 @@ int Debug_ProcessChatCommand(object oPC, string sCommand)
HelpText(oPC, "=== INT: " + IntToString(GetAbilityScore(oTarget, ABILITY_INTELLIGENCE, TRUE)) + " / " + IntToString(GetAbilityScore(oTarget, ABILITY_INTELLIGENCE, FALSE))); HelpText(oPC, "=== INT: " + IntToString(GetAbilityScore(oTarget, ABILITY_INTELLIGENCE, TRUE)) + " / " + IntToString(GetAbilityScore(oTarget, ABILITY_INTELLIGENCE, FALSE)));
HelpText(oPC, "=== WIS: " + IntToString(GetAbilityScore(oTarget, ABILITY_WISDOM, TRUE)) + " / " + IntToString(GetAbilityScore(oTarget, ABILITY_WISDOM, FALSE))); HelpText(oPC, "=== WIS: " + IntToString(GetAbilityScore(oTarget, ABILITY_WISDOM, TRUE)) + " / " + IntToString(GetAbilityScore(oTarget, ABILITY_WISDOM, FALSE)));
HelpText(oPC, "=== CHA: " + IntToString(GetAbilityScore(oTarget, ABILITY_CHARISMA, TRUE)) + " / " + IntToString(GetAbilityScore(oTarget, ABILITY_CHARISMA, FALSE))); HelpText(oPC, "=== CHA: " + IntToString(GetAbilityScore(oTarget, ABILITY_CHARISMA, TRUE)) + " / " + IntToString(GetAbilityScore(oTarget, ABILITY_CHARISMA, FALSE)));
if (GetPersistantLocalInt(oTarget, SHIFTER_ISSHIFTED_MARKER) && GetPRCSwitch(PRC_NWNX_FUNCS)) if (GetPersistantLocalInt(oTarget, SHIFTER_ISSHIFTED_MARKER) && GetPRCSwitch(PRC_NWNXEE_ENABLED))
{ {
int iSTR = GetPersistantLocalInt(oTarget, "Shifting_NWNXSTRAdjust"); int iSTR = GetPersistantLocalInt(oTarget, "Shifting_NWNXSTRAdjust");
int iDEX = GetPersistantLocalInt(oTarget, "Shifting_NWNXDEXAdjust"); int iDEX = GetPersistantLocalInt(oTarget, "Shifting_NWNXDEXAdjust");
@@ -664,7 +664,7 @@ int Debug_ProcessChatCommand(object oPC, string sCommand)
} }
/* else if (GetStringMatchesAbbreviation(sChangeWhat, CMD_ABILITY)) /* else if (GetStringMatchesAbbreviation(sChangeWhat, CMD_ABILITY))
{ {
if (!GetPRCSwitch(PRC_NWNX_FUNCS)) if (!GetPRCSwitch(PRC_NWNXEE_ENABLED))
HelpText(oPC, "This command only works if NWNX funcs is installed"); HelpText(oPC, "This command only works if NWNX funcs is installed");
else else
{ {

View File

@@ -265,7 +265,8 @@ struct WeaponFeat GetAllFeatsOfWeaponType(int iWeaponType);
// Returns the low end of oWeap's critical threat range // Returns the low end of oWeap's critical threat range
// Accounts for Keen and Improved Critical bonuses // Accounts for Keen and Improved Critical bonuses
int GetWeaponCriticalRange(object oPC, object oWeap); //int GetWeaponCriticalRange(object oPC, object oWeap);
int GetWeaponCriticalRange(object oPC, object oWeap, int iTouchAttackType = FALSE);
// returns the critical multiplier of the weapons base type // returns the critical multiplier of the weapons base type
int GetCriticalMultiplierOfWeaponType(int iWeaponType); int GetCriticalMultiplierOfWeaponType(int iWeaponType);
@@ -1999,11 +2000,37 @@ object GetAmmunitionFromWeapon(object oWeapon, object oAttacker)
return GetAmmunitionFromWeaponType(GetBaseItemType(oWeapon), oAttacker); return GetAmmunitionFromWeaponType(GetBaseItemType(oWeapon), oAttacker);
} }
int GetWeaponCriticalRange(object oPC, object oWeap) //int GetWeaponCriticalRange(object oPC, object oWeap)
// for a ranged weapon we should call this *after* we have ammo equipped, because it checks the ammo for keen // for a ranged weapon we should call this *after* we have ammo equipped, because it checks the ammo for keen
// if we (re)equip the ammo later, we don't get the right keen property // if we (re)equip the ammo later, we don't get the right keen property
int GetWeaponCriticalRange(object oPC, object oWeap, int iTouchAttackType = FALSE)
{ {
//no weapon, touch attacks mainly // Check for spell-based touch attacks
if(iTouchAttackType == TOUCH_ATTACK_MELEE_SPELL)
{
if (DEBUG) DoDebug("prc_inc_combat >> GetWeaponCriticalRange() | TOUCH_ATTACK_MELEE_SPELL detected.");
// Spell-based melee touch attacks
if(GetHasFeat(FEAT_IMPROVED_CRITICAL_TOUCH, oPC))
{
if (DEBUG) DoDebug("prc_inc_combat >> GetWeaponCriticalRange() | Improved Critical: Touch detected.");
return 19; // Doubles threat range from 20 to 19-20
}
else
return 20;
}
else if(iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL)
{
if (DEBUG) DoDebug("prc_inc_combat >> GetWeaponCriticalRange() | TOUCH_ATTACK_RANGED_SPELL detected.");
// Ray attacks
if(GetHasFeat(FEAT_IMPROVED_CRITICAL_RAY, oPC))
{
if (DEBUG) DoDebug("prc_inc_combat >> GetWeaponCriticalRange() | Improved Critical: Ray detected.");
return 19; // Doubles threat range from 20 to 19-20
}
else
return 20;
}
//no weapon, touch attacks mainly
if(!GetIsObjectValid(oWeap)) if(!GetIsObjectValid(oWeap))
return 20; return 20;
@@ -3306,7 +3333,33 @@ int GetAttackBonus(object oDefender, object oAttacker, object oWeap, int iOffhan
// weapon specific feats // weapon specific feats
sWeaponFeat = GetAllFeatsOfWeaponType(iWeaponType); sWeaponFeat = GetAllFeatsOfWeaponType(iWeaponType);
int bFocus = 0; int bFocus = 0;
int bEpicFocus = 0;
int bIsRangedTouchAttack = iTouchAttackType == TOUCH_ATTACK_RANGED || iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL;
int bIsMeleeTouchAttack = iTouchAttackType == TOUCH_ATTACK_MELEE_SPELL;
if(bIsRangedTouchAttack)
{
// Weapon Focus(Ray) applies to ranged touch attacks
bFocus = GetHasFeat(FEAT_WEAPON_FOCUS_RAY, oAttacker);
if (bFocus) // no need to look for epic focus, if we don't have focus
bEpicFocus = GetHasFeat(FEAT_EPIC_WEAPON_FOCUS_RAY, oAttacker);
}
else if(bIsMeleeTouchAttack)
{
// Weapon Focus(Touch Attack) applies to melee touch attacks
bFocus = GetHasFeat(FEAT_WEAPON_FOCUS_TOUCH, oAttacker);
if (bFocus) // no need to look for epic focus, if we don't have focus
bEpicFocus = GetHasFeat(FEAT_EPIC_WEAPON_FOCUS_TOUCH, oAttacker);
}
else
{ // no touch attack, normal weapon focus feats
bFocus = GetHasFeat(sWeaponFeat.Focus, oAttacker);
if (bFocus) // no need to look for epic focus, if we don't have focus
bEpicFocus = GetHasFeat(sWeaponFeat.EpicFocus, oAttacker);
}
/* int bFocus = 0;
int bEpicFocus = 0; int bEpicFocus = 0;
int bIsRangedTouchAttack = iTouchAttackType == TOUCH_ATTACK_RANGED || iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL; int bIsRangedTouchAttack = iTouchAttackType == TOUCH_ATTACK_RANGED || iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL;
@@ -3322,7 +3375,7 @@ int GetAttackBonus(object oDefender, object oAttacker, object oWeap, int iOffhan
bFocus = GetHasFeat(sWeaponFeat.Focus, oAttacker); bFocus = GetHasFeat(sWeaponFeat.Focus, oAttacker);
if (bFocus) // no need to look for epic focus, if we don't have focus if (bFocus) // no need to look for epic focus, if we don't have focus
bEpicFocus = GetHasFeat(sWeaponFeat.EpicFocus, oAttacker); bEpicFocus = GetHasFeat(sWeaponFeat.EpicFocus, oAttacker);
} } */
int bEpicProwess = GetHasFeat(FEAT_EPIC_PROWESS, oAttacker); int bEpicProwess = GetHasFeat(FEAT_EPIC_PROWESS, oAttacker);
@@ -3937,7 +3990,7 @@ int GetAttackRoll(object oDefender, object oAttacker, object oWeapon, int iOffha
//if (bDebug) sDebugFeedback = COLOR_WHITE + "Attack Roll = " + IntToString(iAttackBonus + iDiceRoll) + ": " + sDebugFeedback; //if (bDebug) sDebugFeedback = COLOR_WHITE + "Attack Roll = " + IntToString(iAttackBonus + iDiceRoll) + ": " + sDebugFeedback;
//if (DEBUG) DoDebug("GetAttackRoll: End Section #1"); //if (DEBUG) DoDebug("GetAttackRoll: End Section #1");
int iWeaponType = GetBaseItemType(oWeapon); int iWeaponType = GetBaseItemType(oWeapon);
int iCritThreat = GetWeaponCriticalRange(oAttacker, oWeapon); int iCritThreat = GetWeaponCriticalRange(oAttacker, oWeapon, iTouchAttackType);
//If using Killing Shot, ciritical range improves by 2; //If using Killing Shot, ciritical range improves by 2;
if(GetLocalInt(oAttacker, "KillingShotCritical") ) if(GetLocalInt(oAttacker, "KillingShotCritical") )

View File

@@ -355,6 +355,16 @@ int _DoGrappleCheck(object oPC, object oTarget, int nExtraBonus, int nSwitch = -
int nPCCheck = nPCBAB + nPCStr + nPCBonus + d20(); int nPCCheck = nPCBAB + nPCStr + nPCBonus + d20();
int nTargetCheck = nTargetBAB + nTargetStr + nTargetBonus + d20(); int nTargetCheck = nTargetBAB + nTargetStr + nTargetBonus + d20();
if (DEBUG)
{
DoDebug("Grapple Check - " + GetName(oPC) + ": " + IntToString(nPCCheck) +
" vs " + GetName(oTarget) + ": " + IntToString(nTargetCheck));
DoDebug("PC BAB:" + IntToString(nPCBAB) + " STR:" + IntToString(nPCStr) +
" Bonus:" + IntToString(nPCBonus));
DoDebug("Target BAB:" + IntToString(nTargetBAB) + " STR:" + IntToString(nTargetStr) +
" Bonus:" + IntToString(nTargetBonus));
}
// Now roll the ability check // Now roll the ability check
SendMessageToPC(oPC, "PC Grapple Check: "+IntToString(nPCCheck)+" vs "+IntToString(nTargetCheck)); SendMessageToPC(oPC, "PC Grapple Check: "+IntToString(nPCCheck)+" vs "+IntToString(nTargetCheck));
if (GetIsPC(oTarget)) if (GetIsPC(oTarget))
@@ -1502,7 +1512,46 @@ int DoGrapple(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TR
{ {
FloatingTextStringOnCreature("You have successfully grappled " + GetName(oTarget), oPC, FALSE); FloatingTextStringOnCreature("You have successfully grappled " + GetName(oTarget), oPC, FALSE);
int nBearFang = GetLocalInt(oPC, "BearFangGrapple"); int nBearFang = GetLocalInt(oPC, "BearFangGrapple");
SetGrapple(oPC);
SetGrapple(oPC);
SetGrapple(oTarget);
SetLocalInt(oPC, "GrappleOriginator", TRUE);
SetLocalObject(oTarget, "GrappledBy", oPC);
SetGrappleTarget(oPC, oTarget);
if (DEBUG)
{
DoDebug("DoGrapple: Set grapple state for " + GetName(oPC) + " -> " + GetName(oTarget));
DoDebug("DoGrapple: oPC IsGrappled = " + IntToString(GetLocalInt(oPC, "IsGrappled")));
DoDebug("DoGrapple: oTarget IsGrappled = " + IntToString(GetLocalInt(oTarget, "IsGrappled")));
DoDebug("DoGrapple: oPC GrappleTarget = " + GetName(GetLocalObject(oPC, "GrappleTarget")));
}
effect eHold = EffectCutsceneParalyze();
effect eEntangle = EffectVisualEffect(VFX_DUR_SPELLTURNING_R);
effect eLink = EffectLinkEffects(eHold, eEntangle);
if (!GetLocalInt(oPC, "Flay_Grapple"))
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oPC, 9999.0);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oTarget, 9999.0);
nSucceed = TRUE;
if (nBearFang)
{
//DelayCommand(0.1, PerformAttack(oTarget, oPC, eNone, 0.0, -4, 0, 0, "Bear Fang Attack Hit", "Bear Fang Attack Miss"));
PerformAttack(oTarget, oPC, eNone, 0.0, -4, 0, 0, "Bear Fang Attack Hit", "Bear Fang Attack Miss");
DeleteLocalInt(oPC, "BearFangGrapple");
}
else
{
object oWeap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, oTarget));
//DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget)); // Delay damage
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
}
/* SetGrapple(oPC);
SetGrapple(oTarget); SetGrapple(oTarget);
SetLocalInt(oPC, "GrappleOriginator", TRUE); SetLocalInt(oPC, "GrappleOriginator", TRUE);
effect eHold = EffectCutsceneParalyze(); effect eHold = EffectCutsceneParalyze();
@@ -1526,7 +1575,7 @@ int DoGrapple(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TR
effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, oTarget)); effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, oTarget));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
} }
_HeartOfFireGrapple(oPC, oTarget); */ _HeartOfFireGrapple(oPC, oTarget);
// If you kill them with this, best to clean up right away // If you kill them with this, best to clean up right away
if (GetIsDead(oTarget) || !GetIsObjectValid(oTarget)) if (GetIsDead(oTarget) || !GetIsObjectValid(oTarget))
@@ -1539,10 +1588,30 @@ int DoGrapple(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TR
} }
else else
{ {
// Hook in the events and save the target for an ongoing grapple // //::Hook in the events and save the target for an ongoing grapple
if(DEBUG) DoDebug("prc_grapple: Adding eventhooks"); // if(DEBUG) DoDebug("prc_grapple: Adding eventhooks");
SetGrappleTarget(oPC, oTarget); // SetGrappleTarget(oPC, oTarget);
AddEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE); // AddEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
// Hook in the events and save the target for an ongoing grapple
if(DEBUG) DoDebug("prc_grapple: Adding eventhooks");
SetGrappleTarget(oPC, oTarget);
if(GetIsPC(oPC) || GetIsDMPossessed(oPC))
{
AddEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
if(DEBUG) DoDebug("DoGrapple: Set Heartbeat event for " + GetName(oPC));
}
else
{
// For summons, set a flag that prc_npc_hb.nss can check
SetLocalInt(oPC, "GrappleHeartbeatTimer", 1);
if(DEBUG) DoDebug("DoGrapple: Set GrappleHeartbeatTimer for " + GetName(oPC));
// Add this debug to verify the timer was set
if(DEBUG) DoDebug("DoGrapple: Verification - GrappleHeartbeatTimer = " +
IntToString(GetLocalInt(oPC, "GrappleHeartbeatTimer")));
}
} }
} }
else else
@@ -1555,12 +1624,16 @@ int DoGrapple(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TR
void SetGrapple(object oTarget) void SetGrapple(object oTarget)
{ {
SetLocalInt(oTarget, "IsGrappled", TRUE); if(DEBUG) DoDebug("SetGrapple called on " + GetName(oTarget));
SetLocalInt(oTarget, "IsGrappled", TRUE);
} }
int GetGrapple(object oTarget) int GetGrapple(object oTarget)
{ {
return GetLocalInt(oTarget, "IsGrappled"); int nResult = GetLocalInt(oTarget, "IsGrappled");
if(DEBUG) DoDebug("GetGrapple(" + GetName(oTarget) + ") = " + IntToString(nResult));
return nResult;
//return GetLocalInt(oTarget, "IsGrappled");
} }
void SetGrappleTarget(object oPC, object oTarget) void SetGrappleTarget(object oPC, object oTarget)
@@ -1591,10 +1664,14 @@ void BreakPin(object oTarget)
void EndGrapple(object oPC, object oTarget) void EndGrapple(object oPC, object oTarget)
{ {
DeleteLocalInt(oPC, "IsGrappled"); if(DEBUG) DoDebug("EndGrapple called for " + GetName(oPC) + " -> " + GetName(oTarget));
DeleteLocalInt(oPC, "IsGrappled");
DeleteLocalInt(oTarget, "IsGrappled"); DeleteLocalInt(oTarget, "IsGrappled");
DeleteLocalInt(oPC, "GrappleHeartbeatTimer");
DeleteLocalInt(oTarget, "PinnedRounds"); DeleteLocalInt(oTarget, "PinnedRounds");
DeleteLocalObject(oPC, "GrappleTarget"); DeleteLocalObject(oPC, "GrappleTarget");
DeleteLocalObject(oTarget, "GrappledBy");
DeleteLocalInt(oTarget, "UnconsciousGrapple"); DeleteLocalInt(oTarget, "UnconsciousGrapple");
DeleteLocalInt(oPC, "GrappleOriginator"); DeleteLocalInt(oPC, "GrappleOriginator");
DeleteLocalInt(oPC, "ScorpionLight"); DeleteLocalInt(oPC, "ScorpionLight");
@@ -1679,6 +1756,20 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
int nPen = -4; int nPen = -4;
if (GetLocalInt(oPC, "ScorpionLight")) nPen = 0; if (GetLocalInt(oPC, "ScorpionLight")) nPen = 0;
DelayCommand(0.0, PerformAttack(oTarget, oPC, eNone, 0.0, nPen, 0, 0, "Grapple Light Weapon Attack Hit", "Grapple Light Weapon Attack Miss")); DelayCommand(0.0, PerformAttack(oTarget, oPC, eNone, 0.0, nPen, 0, 0, "Grapple Light Weapon Attack Hit", "Grapple Light Weapon Attack Miss"));
if (GetIsDead(oPC) || GetIsDead(oTarget) || !GetIsObjectValid(oPC) || !GetIsObjectValid(oTarget))
{
EndGrapple(oPC, oTarget);
//RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
if(GetIsPC(oPC) || GetIsDMPossessed(oPC))
RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
else
DeleteLocalInt(oPC, "PRC_GrappleActive");
if (GetIsDead(oPC)) FloatingTextStringOnCreature("You have died, ending grapple", oPC, FALSE);
if (GetIsDead(oTarget)) FloatingTextStringOnCreature("Your target is dead, ending grapple", oPC, FALSE);
return nSuccess;
}
} }
} }
else else
@@ -1730,6 +1821,7 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
// Now hit them with an unarmed strike // Now hit them with an unarmed strike
object oWeap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC); object oWeap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, oTarget)); effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, oTarget));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
FloatingTextStringOnCreature("Grapple Unarmed Damage Hit",oPC, FALSE); FloatingTextStringOnCreature("Grapple Unarmed Damage Hit",oPC, FALSE);
} }
@@ -1743,6 +1835,21 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam), oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam), oTarget);
FloatingTextStringOnCreature("Zagan Constrict Hit",oPC, FALSE); FloatingTextStringOnCreature("Zagan Constrict Hit",oPC, FALSE);
} }
if (GetIsDead(oPC) || GetIsDead(oTarget) || !GetIsObjectValid(oPC) || !GetIsObjectValid(oTarget))
{
EndGrapple(oPC, oTarget);
//RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
if(GetIsPC(oPC) || GetIsDMPossessed(oPC))
RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
else
DeleteLocalInt(oPC, "PRC_GrappleActive");
if (GetIsDead(oPC)) FloatingTextStringOnCreature("You have died, ending grapple", oPC, FALSE);
if (GetIsDead(oTarget)) FloatingTextStringOnCreature("Your target is dead, ending grapple", oPC, FALSE);
return nSuccess;
}
} }
else if (nSwitch == GRAPPLE_ESCAPE) else if (nSwitch == GRAPPLE_ESCAPE)
{ {
@@ -1765,14 +1872,24 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
{ {
// Remove the hooks // Remove the hooks
if(DEBUG) DoDebug("prc_grapple: Removing eventhooks"); if(DEBUG) DoDebug("prc_grapple: Removing eventhooks");
RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE); //RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
if(GetIsPC(oPC) || GetIsDMPossessed(oPC))
RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
else
DeleteLocalInt(oPC, "PRC_GrappleActive");
FloatingTextStringOnCreature("You have escaped the grapple", oPC, FALSE); FloatingTextStringOnCreature("You have escaped the grapple", oPC, FALSE);
} }
else else
{ {
// Remove the hooks // Remove the hooks
if(DEBUG) DoDebug("prc_grapple: Removing eventhooks"); if(DEBUG) DoDebug("prc_grapple: Removing eventhooks");
RemoveEventScript(oTarget, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE); //RemoveEventScript(oTarget, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
if(GetIsPC(oPC) || GetIsDMPossessed(oPC))
RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
else
DeleteLocalInt(oPC, "PRC_GrappleActive");
FloatingTextStringOnCreature("Your target has escaped your grapple", oTarget, FALSE); FloatingTextStringOnCreature("Your target has escaped your grapple", oTarget, FALSE);
// Target is valid and we know it's an enemy and we're in combat // Target is valid and we know it's an enemy and we're in combat
DelayCommand(0.25, AssignCommand(oTarget, ActionAttack(oPC))); DelayCommand(0.25, AssignCommand(oTarget, ActionAttack(oPC)));
@@ -1830,6 +1947,22 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam, DAMAGE_TYPE_BLUDGEONING), oTarget); ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam, DAMAGE_TYPE_BLUDGEONING), oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectACDecrease(4)), oPC, 6.0); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectACDecrease(4)), oPC, 6.0);
} }
else
FloatingTextStringOnCreature("You have failed your Grapple Pin Attempt",oPC, FALSE);
if (GetIsDead(oPC) || GetIsDead(oTarget) || !GetIsObjectValid(oPC) || !GetIsObjectValid(oTarget))
{
EndGrapple(oPC, oTarget);
//RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
if(GetIsPC(oPC) || GetIsDMPossessed(oPC))
RemoveEventScript(oPC, EVENT_ONHEARTBEAT, "prc_grapple", TRUE, FALSE);
else
DeleteLocalInt(oPC, "PRC_GrappleActive");
if (GetIsDead(oPC)) FloatingTextStringOnCreature("You have died, ending grapple", oPC, FALSE);
if (GetIsDead(oTarget)) FloatingTextStringOnCreature("Your target is dead, ending grapple", oPC, FALSE);
return nSuccess;
}
} }
else else
FloatingTextStringOnCreature("You have failed your Grapple Pin Attempt",oPC, FALSE); FloatingTextStringOnCreature("You have failed your Grapple Pin Attempt",oPC, FALSE);
@@ -1844,6 +1977,54 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
return nSuccess; return nSuccess;
} }
int OptimalGrapple(object oPC, object oTarget)
{
int nMauler = GetLevelByClass(CLASS_TYPE_REAPING_MAULER, oPC);
int nBBC = GetLevelByClass(CLASS_TYPE_BLACK_BLOOD_CULTIST, oPC);
int nDC = 10 + nMauler + GetAbilityModifier(ABILITY_WISDOM, oPC);
if (GetLocalInt(oPC, "Flay_Grapple"))
return GRAPPLE_DAMAGE;
// You need a greater than 10% chance of it happening to trigger these options
if (nMauler && (nDC > GetFortitudeSavingThrow(oTarget) + 2))
{
if (nMauler == 5 && !GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT)) // Devastating Grapple
return GRAPPLE_PIN;
if (nMauler >= 3 && !GetLocalInt(oTarget, "UnconsciousGrapple") && !GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT)) // Target isn't unconscious
return GRAPPLE_PIN;
}
if (GetHasSpellEffect(MOVE_SD_CRUSHING_WEIGHT, oPC))
return GRAPPLE_TOB_CRUSHING;
if ((nBBC >= 8 && GetHasSpellEffect(SPELLABILITY_BARBARIAN_RAGE, oPC)) || nBBC >= 10 || GetHasSpellEffect(VESTIGE_ZAGAN, oPC) && GetLocalInt(oPC, "ExploitVestige") != VESTIGE_ZAGAN_CONSTRICT)
return GRAPPLE_DAMAGE;
if (GetIsMeldBound(oPC, MELD_RAGECLAWS) == CHAKRA_TOTEM)
return GRAPPLE_ATTACK;
// You've got an ability that wants a light weapon
if (GetHasSpellEffect(MOVE_TC_WOLVERINE_STANCE, oPC) || GetLevelByClass(CLASS_TYPE_WARFORGED_JUGGERNAUT, oPC) || GetLocalInt(oPC, "ScorpionLight"))
return GRAPPLE_ATTACK;
if (GetHasFeat(FEAT_EARTHS_EMBRACE, oPC) && !GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT)) // Earth's Embrace
return GRAPPLE_PIN;
if (FindUnarmedDamage(oPC) > 2)
return GRAPPLE_DAMAGE;
object oPCWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
object oMonster = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
int nPCGold;
int nMonster;
if(GetIsLightWeapon(oTarget)) nMonster = GetGoldPieceValue(oMonster);
if(GetIsLightWeapon(oPC)) nPCGold = GetGoldPieceValue(oPCWeapon);
if (nMonster > nPCGold)
return GRAPPLE_OPPONENT_WEAPON;
else if (GetIsLightWeapon(oPC))
return GRAPPLE_ATTACK;
return GRAPPLE_DAMAGE;
}
int GetIsLightWeapon(object oPC) int GetIsLightWeapon(object oPC)
{ {
// You may use any weapon in a grapple with this stance. // You may use any weapon in a grapple with this stance.

View File

@@ -7,6 +7,8 @@
/* Function Prototypes */ /* Function Prototypes */
////////////////////////////////////////////////// //////////////////////////////////////////////////
string GetSpellsKnown_Array(int nClass, int nSpellLevel = -1);
//:: Returns true if oCaster's race can naturally cast sorcerer spells. //:: Returns true if oCaster's race can naturally cast sorcerer spells.
int GetIsRHDSorcerer(object oCaster = OBJECT_SELF); int GetIsRHDSorcerer(object oCaster = OBJECT_SELF);
@@ -680,8 +682,36 @@ int PRCGetIsRealSpellKnownByClass(int nRealSpellID, int nClass, object oPC = OBJ
// at this stage, prepared casters know the spell and only spontaneous classes need checking // at this stage, prepared casters know the spell and only spontaneous classes need checking
// there are exceptions and these need hardcoding: // there are exceptions and these need hardcoding:
if((GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) && nClass != CLASS_TYPE_ARCHIVIST) // Archivist special case - check both feats and persistant arrays
return TRUE; if (nClass == CLASS_TYPE_ARCHIVIST)
{
// First check feat system (for backward compatibility)
int nFeatID = StringToInt(Get2DACache(sFile, "FeatID", nSpellbookSpell));
if (GetHasFeat(nFeatID, oPC))
return TRUE;
// Then check persistant spell arrays using GetSpellsKnown_Array()
int nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookSpell));
string sSpellbookArray = GetSpellsKnown_Array(nClass, nSpellLevel);
int nSize = persistant_array_get_size(oPC, sSpellbookArray);
int i;
for (i = 0; i < nSize; i++)
{
int nStoredSpellbookID = persistant_array_get_int(oPC, sSpellbookArray, i);
if (nStoredSpellbookID == nSpellbookSpell)
return TRUE;
}
return FALSE;
}
// Other prepared casters use original logic
if((GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) && nClass != CLASS_TYPE_ARCHIVIST)
return TRUE;
/* if((GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) && nClass != CLASS_TYPE_ARCHIVIST)
return TRUE; */
// spontaneous casters have all their known spells as hide feats // spontaneous casters have all their known spells as hide feats
// get the featID of the spell // get the featID of the spell

View File

@@ -187,6 +187,7 @@ void SetupCharacterData(object oPC)
case CLASS_TYPE_MASTER_OF_SHADOW: sScript = "shd_mastershadow"; break; case CLASS_TYPE_MASTER_OF_SHADOW: sScript = "shd_mastershadow"; break;
case CLASS_TYPE_MIGHTY_CONTENDER_KORD: sScript = "prc_contendkord"; break; case CLASS_TYPE_MIGHTY_CONTENDER_KORD: sScript = "prc_contendkord"; break;
case CLASS_TYPE_MORNINGLORD: sScript = "prc_morninglord"; break; case CLASS_TYPE_MORNINGLORD: sScript = "prc_morninglord"; break;
case CLASS_TYPE_MONK: sScript = "prc_monk"; break;
case CLASS_TYPE_NIGHTSHADE: sScript = "prc_nightshade"; break; case CLASS_TYPE_NIGHTSHADE: sScript = "prc_nightshade"; break;
case CLASS_TYPE_NINJA: sScript = "prc_ninjca"; break; case CLASS_TYPE_NINJA: sScript = "prc_ninjca"; break;
case CLASS_TYPE_OLLAM: sScript = "prc_ollam"; break; case CLASS_TYPE_OLLAM: sScript = "prc_ollam"; break;
@@ -366,7 +367,7 @@ void EvalPRCFeats(object oPC)
SetLocalInt(oPC, PRC_EvalPRCFeats_Generation, nGeneration); SetLocalInt(oPC, PRC_EvalPRCFeats_Generation, nGeneration);
//permanent ability changes //permanent ability changes
if(GetPRCSwitch(PRC_NWNX_FUNCS)) if(GetPRCSwitch(PRC_NWNXEE_ENABLED))
ExecuteScript("prc_nwnx_funcs", oPC); ExecuteScript("prc_nwnx_funcs", oPC);
//Add IP Feats to the hide //Add IP Feats to the hide
@@ -1571,7 +1572,7 @@ void BarbarianRage(object oPC)
if (nLevel > 0) if (nLevel > 0)
{ {
// Spell Rage: starts at 1st level, +1 use every 5 Rage Mage levels // Spell Rage: starts at 1st level, +1 use every 5 Rage Mage levels
int nUses = 1 + ((nLevel - 1) / 5); int nUses = 1 + (nLevel / 5);
FeatUsePerDay(oPC, FEAT_SPELL_RAGE, -1, nUses); FeatUsePerDay(oPC, FEAT_SPELL_RAGE, -1, nUses);
} }

View File

@@ -582,8 +582,6 @@ effect CelestialTemplateEffects(int nHD)
return eEffects; return eEffects;
} }
void ReallyEquipItemInSlot(object oNPC, object oItem, int nSlot) void ReallyEquipItemInSlot(object oNPC, object oItem, int nSlot)
{ {
if (GetItemInSlot(nSlot) != oItem) if (GetItemInSlot(nSlot) != oItem)
@@ -688,6 +686,148 @@ void ApplyPseudonaturalEffects(object oCreature)
//:: JSON functions | //:: JSON functions |
//::---------------------------------------------| //::---------------------------------------------|
//:: Get the first spell ID that a creature knows (not memorized, but known)
//:: Returns -1 if no spells are found
int json_GetFirstKnownSpell(json jCreature)
{
// Store the creature JSON for later use by GetNext
SetLocalJson(GetModule(), "JSON_SPELL_CREATURE", jCreature);
SetLocalInt(GetModule(), "JSON_SPELL_CLASS_INDEX", 0);
SetLocalInt(GetModule(), "JSON_SPELL_LEVEL", 0);
SetLocalInt(GetModule(), "JSON_SPELL_INDEX", 0);
// Get the ClassList
json jClassList = GffGetList(jCreature, "ClassList");
if (jClassList == JsonNull())
{
if(DEBUG) DoDebug("json_GetFirstKnownSpell: No ClassList found");
return -1;
}
int nClassCount = JsonGetLength(jClassList);
int iClass, iSpellLevel, iSpell;
// Iterate through all classes
for (iClass = 0; iClass < nClassCount; iClass++)
{
json jClass = JsonArrayGet(jClassList, iClass);
if (jClass == JsonNull()) continue;
// Check all spell levels (0-9)
for (iSpellLevel = 0; iSpellLevel <= 9; iSpellLevel++)
{
string sKnownList = "KnownList" + IntToString(iSpellLevel);
json jKnownList = GffGetList(jClass, sKnownList);
if (jKnownList == JsonNull()) continue;
int nSpellCount = JsonGetLength(jKnownList);
// Look for the first spell
for (iSpell = 0; iSpell < nSpellCount; iSpell++)
{
json jSpell = JsonArrayGet(jKnownList, iSpell);
if (jSpell == JsonNull()) continue;
json jSpellID = GffGetWord(jSpell, "Spell");
if (jSpellID != JsonNull())
{
int nSpellID = JsonGetInt(jSpellID);
// Update tracking variables for next call
SetLocalInt(GetModule(), "JSON_SPELL_CLASS_INDEX", iClass);
SetLocalInt(GetModule(), "JSON_SPELL_LEVEL", iSpellLevel);
SetLocalInt(GetModule(), "JSON_SPELL_INDEX", iSpell + 1);
return nSpellID;
}
}
}
}
// Clean up when done
DeleteLocalJson(GetModule(), "JSON_SPELL_CREATURE");
DeleteLocalInt(GetModule(), "JSON_SPELL_CLASS_INDEX");
DeleteLocalInt(GetModule(), "JSON_SPELL_LEVEL");
DeleteLocalInt(GetModule(), "JSON_SPELL_INDEX");
return -1; // No more spells found
}
//:: Get the next spell ID from the creature's known spells
//:: Returns -1 if no more spells are found
int json_GetNextKnownSpell()
{
json jCreature = GetLocalJson(GetModule(), "JSON_SPELL_CREATURE");
if (jCreature == JsonNull())
return -1;
int nClassIndex = GetLocalInt(GetModule(), "JSON_SPELL_CLASS_INDEX");
int nSpellLevel = GetLocalInt(GetModule(), "JSON_SPELL_LEVEL");
int nSpellIndex = GetLocalInt(GetModule(), "JSON_SPELL_INDEX");
// Get the ClassList
json jClassList = GffGetList(jCreature, "ClassList");
if (jClassList == JsonNull())
return -1;
int nClassCount = JsonGetLength(jClassList);
int iClass, iSpellLevel, iSpell;
// Continue from where we left off
for (iClass = nClassIndex; iClass < nClassCount; iClass++)
{
json jClass = JsonArrayGet(jClassList, iClass);
if (jClass == JsonNull()) continue;
// Check all spell levels (0-9)
for (iSpellLevel = nSpellLevel; iSpellLevel <= 9; iSpellLevel++)
{
string sKnownList = "KnownList" + IntToString(iSpellLevel);
json jKnownList = GffGetList(jClass, sKnownList);
if (jKnownList == JsonNull()) continue;
int nSpellCount = JsonGetLength(jKnownList);
// Start from saved index if same class and level, otherwise start from 0
int nStartIndex = (iClass == nClassIndex && iSpellLevel == nSpellLevel) ? nSpellIndex : 0;
for (iSpell = nStartIndex; iSpell < nSpellCount; iSpell++)
{
json jSpell = JsonArrayGet(jKnownList, iSpell);
if (jSpell == JsonNull()) continue;
json jSpellID = GffGetWord(jSpell, "Spell");
if (jSpellID != JsonNull())
{
int nSpellID = JsonGetInt(jSpellID);
// Update tracking variables for next call
SetLocalInt(GetModule(), "JSON_SPELL_CLASS_INDEX", iClass);
SetLocalInt(GetModule(), "JSON_SPELL_LEVEL", iSpellLevel);
SetLocalInt(GetModule(), "JSON_SPELL_INDEX", iSpell + 1);
return nSpellID;
}
}
// Reset spell index for next spell level
nSpellIndex = 0;
}
// Reset spell level for next class
nSpellLevel = 0;
}
// Clean up when done
DeleteLocalJson(GetModule(), "JSON_SPELL_CREATURE");
DeleteLocalInt(GetModule(), "JSON_SPELL_CLASS_INDEX");
DeleteLocalInt(GetModule(), "JSON_SPELL_LEVEL");
DeleteLocalInt(GetModule(), "JSON_SPELL_INDEX");
return -1; // No more spells found
}
//:: Returns the Constitution value from a GFF creature UTC //:: Returns the Constitution value from a GFF creature UTC
int json_GetCONValue(json jCreature) int json_GetCONValue(json jCreature)
{ {

View File

@@ -249,7 +249,7 @@ void CancelGreatFeats(object oSpawn)
else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_1, oSpawn)) nGreatCha = 1; else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_1, oSpawn)) nGreatCha = 1;
//apply penalties to counter the GreatX feats //apply penalties to counter the GreatX feats
if(GetPRCSwitch(PRC_NWNX_FUNCS)) if(GetPRCSwitch(PRC_NWNXEE_ENABLED))
{ {
if(nGreatStr) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_STRENGTH, -nGreatStr); if(nGreatStr) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_STRENGTH, -nGreatStr);
if(nGreatDex) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_DEXTERITY, -nGreatDex); if(nGreatDex) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_DEXTERITY, -nGreatDex);

View File

@@ -174,20 +174,31 @@ void DoNaturalAttack(object oWeapon)
if(DEBUG) DoDebug(PRC_TEXT_WHITE + "initiating a secondary natural attack with "+GetName(oWeapon)+", attack mod " + IntToString(nAttackMod) + ", nStrHalf " + IntToString(nStrHalf)); if(DEBUG) DoDebug(PRC_TEXT_WHITE + "initiating a secondary natural attack with "+GetName(oWeapon)+", attack mod " + IntToString(nAttackMod) + ", nStrHalf " + IntToString(nStrHalf));
PerformAttack(oTarget, PerformAttack(oTarget,
oPC, // oPC, //
eInvalid, //effect eSpecialEffect, eInvalid, //effect eSpecialEffect,
0.0, //float eDuration = 0.0 0.0, //float eDuration = 0.0
nAttackMod, //int iAttackBonusMod = 0 nAttackMod, //int iAttackBonusMod = 0
nStrHalf, //int iDamageModifier = Half strength nStrHalf, //int iDamageModifier = Half strength
DAMAGE_TYPE_SLASHING, //int iDamageType = DAMAGE_TYPE_SLASHING, otherwise it uses magical damage. DAMAGE_TYPE_SLASHING, //int iDamageType = DAMAGE_TYPE_SLASHING, otherwise it uses magical damage.
sMessageSuccess, //sMessageSuccess sMessageSuccess, //sMessageSuccess
sMessageFailure, //sMessageFailure sMessageFailure, //sMessageFailure
FALSE, //int iTouchAttackType = FALSE FALSE, //int iTouchAttackType = FALSE
oWeaponR, // we should have something in the right hand (might need it for some calculations) oWeaponR, // we should have something in the right hand (might need it for some calculations)
oWeapon, // we put the creature weapon in the left hand slot oWeapon, // we put the creature weapon in the left hand slot
FALSE, //offhand override (for half strength) FALSE, //offhand override (for half strength)
bCombatMode // prc scripted combat mode bCombatMode // prc scripted combat mode
); );
//:: onHit processing for secondary natural attacks
if(GetLocalInt(oPC, "PRCCombat_StruckByAttack"))
{
// Apply onHit abilities from the creature weapon
ApplyAllOnHitCastSpellsOnItemExcludingSubType(
IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, oTarget, oWeapon, oPC);
// Clear the combat struck flag
DeleteLocalInt(oPC, "PRCCombat_StruckByAttack");
}
} }
void DoOffhandAttack(int nAttackMod) void DoOffhandAttack(int nAttackMod)

View File

@@ -9,6 +9,8 @@ const int PRC_SIZEMASK_SIMPLE = 4; // 'simple' size changes that have si
const int PRC_SIZEMASK_ALL = 7; // PRC_SIZEMASK_NORMAL | PRC_SIZEMASK_NOABIL | PRC_SIZEMASK_SIMPLE const int PRC_SIZEMASK_ALL = 7; // PRC_SIZEMASK_NORMAL | PRC_SIZEMASK_NOABIL | PRC_SIZEMASK_SIMPLE
const int PRC_SIZEMASK_PRC = 0x08; // For systems that need PRC size scale
//wrapper for biowares GetSpellId() //wrapper for biowares GetSpellId()
//used for actioncastspell //used for actioncastspell
int PRCGetSpellId(object oCaster = OBJECT_SELF); int PRCGetSpellId(object oCaster = OBJECT_SELF);
@@ -559,7 +561,6 @@ int PRCGetCreatureSize(object oObject = OBJECT_SELF, int nSizeMask = PRC_SIZEMAS
if (DEBUG) DoDebug("PRCGetCreatureSize, returning size: "+IntToString(nSize)); if (DEBUG) DoDebug("PRCGetCreatureSize, returning size: "+IntToString(nSize));
return nSize; return nSize;
} }
int GetIsChakraBound(object oMeldshaper, int nChakra) int GetIsChakraBound(object oMeldshaper, int nChakra)
{ {
int nTest = GetLocalInt(oMeldshaper, "BoundMeld"+IntToString(nChakra)); int nTest = GetLocalInt(oMeldshaper, "BoundMeld"+IntToString(nChakra));

View File

@@ -97,7 +97,9 @@ int GetIsWarforged(object oCreature)
{ {
int nRace = GetRacialType(oCreature); int nRace = GetRacialType(oCreature);
if (nRace == RACIAL_TYPE_WARFORGED || nRace == RACIAL_TYPE_WARFORGED_CHARGER) return TRUE; if (nRace == RACIAL_TYPE_WARFORGED ||
nRace == RACIAL_TYPE_WARFORGED_CHARGER ||
nRace == RACIAL_TYPE_WARFORGED_SCOUT) return TRUE;
return FALSE; return FALSE;
} }

View File

@@ -2459,6 +2459,7 @@ int GetCanShiftIntoCreature(object oShifter, int nShifterType, object oTemplate)
nRacialType == RACIAL_TYPE_HALFELF || nRacialType == RACIAL_TYPE_HALFELF ||
nRacialType == RACIAL_TYPE_HALFLING || nRacialType == RACIAL_TYPE_HALFLING ||
nRacialType == RACIAL_TYPE_HUMANOID_ORC || nRacialType == RACIAL_TYPE_HUMANOID_ORC ||
nRacialType == RACIAL_TYPE_HUMANOID_GOBLINOID ||
nRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN nRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN
)) ))
{ {
@@ -2488,6 +2489,7 @@ int GetCanShiftIntoCreature(object oShifter, int nShifterType, object oTemplate)
nRacialType == RACIAL_TYPE_HALFELF || nRacialType == RACIAL_TYPE_HALFELF ||
nRacialType == RACIAL_TYPE_HALFLING || nRacialType == RACIAL_TYPE_HALFLING ||
nRacialType == RACIAL_TYPE_HUMANOID_ORC || nRacialType == RACIAL_TYPE_HUMANOID_ORC ||
nRacialType == RACIAL_TYPE_HUMANOID_GOBLINOID ||
nRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN nRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN
)) ))
{ {
@@ -2523,6 +2525,7 @@ int GetCanShiftIntoCreature(object oShifter, int nShifterType, object oTemplate)
nTargetRacialType == RACIAL_TYPE_HALFORC || nTargetRacialType == RACIAL_TYPE_HALFORC ||
nTargetRacialType == RACIAL_TYPE_HALFELF || nTargetRacialType == RACIAL_TYPE_HALFELF ||
nTargetRacialType == RACIAL_TYPE_HALFLING || nTargetRacialType == RACIAL_TYPE_HALFLING ||
nTargetRacialType == RACIAL_TYPE_HUMANOID_GOBLINOID ||
nTargetRacialType == RACIAL_TYPE_HUMANOID_ORC || nTargetRacialType == RACIAL_TYPE_HUMANOID_ORC ||
nTargetRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN nTargetRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN
) && ) &&
@@ -2533,6 +2536,7 @@ int GetCanShiftIntoCreature(object oShifter, int nShifterType, object oTemplate)
nShifterRacialType == RACIAL_TYPE_HALFORC || nShifterRacialType == RACIAL_TYPE_HALFORC ||
nShifterRacialType == RACIAL_TYPE_HALFELF || nShifterRacialType == RACIAL_TYPE_HALFELF ||
nShifterRacialType == RACIAL_TYPE_HALFLING || nShifterRacialType == RACIAL_TYPE_HALFLING ||
nShifterRacialType == RACIAL_TYPE_HUMANOID_GOBLINOID ||
nShifterRacialType == RACIAL_TYPE_HUMANOID_ORC || nShifterRacialType == RACIAL_TYPE_HUMANOID_ORC ||
nShifterRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN nShifterRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN
)) ))
@@ -3094,7 +3098,7 @@ void HandleApplyShiftTemplate(object oPC)
int PnPShifterFeats() int PnPShifterFeats()
{ {
if(GetPRCSwitch(PRC_NWNX_FUNCS)) if(GetPRCSwitch(PRC_NWNXEE_ENABLED))
{ {
//If any stats have been changed by NWNX, this could qualify the PC for feats they should //If any stats have been changed by NWNX, this could qualify the PC for feats they should
//not actually qualify for, so force unshifting before levelling up. //not actually qualify for, so force unshifting before levelling up.

View File

@@ -112,13 +112,13 @@ int PerformJump(object oPC, location lLoc, int bDoKnockDown = TRUE)
if (Ninja_AbilitiesEnabled(oPC)) if (Ninja_AbilitiesEnabled(oPC))
{ {
bIsRunningJump = TRUE; bIsRunningJump = TRUE;
iBonus = 4; iBonus += 4;
} }
} }
if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC)) if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
{ {
bIsRunningJump = TRUE; bIsRunningJump = TRUE;
//iBonus = 10; //:: This is granted in the stance. //iBonus += 10; //:: This is handled in the stance now.
} }
// PnP rules are height * 6 for run and height * 2 for jump. // PnP rules are height * 6 for run and height * 2 for jump.
// I can't get height so that is assumed to be 6. // I can't get height so that is assumed to be 6.

View File

@@ -47,7 +47,7 @@ int PRCDoRangedTouchAttack(object oTarget, int nDisplayFeedback = TRUE, object o
{ {
SetLocalInt(oCaster, "RangedRecall", nRecall+1); SetLocalInt(oCaster, "RangedRecall", nRecall+1);
// Reroll with a -5 penalty // Reroll with a -5 penalty
nResult = GetAttackRoll(oTarget,oCaster,OBJECT_INVALID,0,nAttackBonus-5,0,nDisplayFeedback,0.0,TOUCH_ATTACK_MELEE_SPELL); nResult = GetAttackRoll(oTarget,oCaster,OBJECT_INVALID,0,nAttackBonus-5,0,nDisplayFeedback,0.0,TOUCH_ATTACK_RANGED_SPELL);
} }
} }
} }

View File

@@ -417,7 +417,10 @@ int GetPrCAdjustedClassLevel(int nClass, object oCaster = OBJECT_SELF)
// is it arcane, divine or neither? // is it arcane, divine or neither?
if(GetIsArcaneClass(nClass, oCaster) && nClass != CLASS_TYPE_SUBLIME_CHORD) if(GetIsArcaneClass(nClass, oCaster) && nClass != CLASS_TYPE_SUBLIME_CHORD)
{ {
if (GetPrimaryArcaneClass(oCaster) == nClass) // adjust for any PrCs if(nClass == CLASS_TYPE_FEY && GetRacialType(oCaster) == RACIAL_TYPE_GLOURA)
iTemp = GetArcanePRCLevels(oCaster, nClass);
else if (GetPrimaryArcaneClass(oCaster) == nClass) // adjust for any PrCs
iTemp = GetArcanePRCLevels(oCaster, nClass); iTemp = GetArcanePRCLevels(oCaster, nClass);
} }
else if(GetIsDivineClass(nClass, oCaster)) else if(GetIsDivineClass(nClass, oCaster))
@@ -1069,6 +1072,10 @@ int PRCMySavingThrow(int nSavingThrow, object oTarget, int nDC, int nSaveType =
nDC -= 1 + (GetHitDice(oTarget) / 5); nDC -= 1 + (GetHitDice(oTarget) / 5);
else if(GetHasFeat(FEAT_HARD_ELEC, oTarget)) else if(GetHasFeat(FEAT_HARD_ELEC, oTarget))
nDC -= 2; nDC -= 2;
//:: Mechanatrix always fail saves vs electricity.
if(GetRacialType(oTarget) == RACIAL_TYPE_MECHANATRIX)
return 0;
} }
else if(nSaveType == SAVING_THROW_TYPE_SONIC) else if(nSaveType == SAVING_THROW_TYPE_SONIC)
{ {
@@ -2788,6 +2795,19 @@ effect PRCEffectDamage(object oTarget, int nDamageAmount, int nDamageType=DAMAGE
effect eEffect; effect eEffect;
return eEffect; //Doesn't hurt him return eEffect; //Doesn't hurt him
} }
// Mechanatrix heals from electrical damage. +1 HP for every 3 electrical damage.
if (GetRacialType(oTarget) == RACIAL_TYPE_MECHANATRIX && nDamageType == DAMAGE_TYPE_ELECTRICAL)
{
nDamageAmount /= 3;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nDamageAmount), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HEAD_ELECTRICITY), oTarget);
FloatingTextStringOnCreature("Electricty Healing restored " + IntToString(nDamageAmount) +" HP.", oTarget, FALSE);
effect eEffect;
return eEffect; //Doesn't hurt him
}
// Phoenix Belt gains fast healing when hit by fire damage // Phoenix Belt gains fast healing when hit by fire damage
if (GetHasSpellEffect(MELD_PHOENIX_BELT, oTarget) && nDamageType == DAMAGE_TYPE_FIRE) if (GetHasSpellEffect(MELD_PHOENIX_BELT, oTarget) && nDamageType == DAMAGE_TYPE_FIRE)
{ {

View File

@@ -76,7 +76,7 @@
/* This variable MUST be updated with every new version of the PRC!!! */ /* This variable MUST be updated with every new version of the PRC!!! */
const string PRC_VERSION = "PRC8 4.76"; const string PRC_VERSION = "PRC8 4.84";
/* This variable MUST be updated every time 'assemble_spellbooks.bat' is run!!! */ /* This variable MUST be updated every time 'assemble_spellbooks.bat' is run!!! */
@@ -86,6 +86,13 @@
* Spell switches * * Spell switches *
\******************************************************************************/ \******************************************************************************/
/**
* Show detailed spell resistance check information to the caster
* When enabled, displays the roll vs SR values when checking spell resistance
*/
const string PRC_SHOW_SR_CHECK_DETAILS = "PRC_SHOW_SR_CHECK_DETAILS";
/** Material Components /** Material Components
* Set switch to 1 to activate this * Set switch to 1 to activate this
* This allows material components in NWN through the materialcomp.2da * This allows material components in NWN through the materialcomp.2da
@@ -2386,7 +2393,15 @@ const string PRC_XP_MAX_LEVEL_DIFF = "PRC_XP_MAX_LEVEL_DIFF";
*/ */
const string PRC_XP_GIVE_XP_TO_NON_PC_FACTIONS = "PRC_XP_GIVE_XP_TO_NON_PC_FACTIONS"; const string PRC_XP_GIVE_XP_TO_NON_PC_FACTIONS = "PRC_XP_GIVE_XP_TO_NON_PC_FACTIONS";
/******************************************************************************\
* NWNxEE switches *
\******************************************************************************/
//:: This switch enables the PRC8 -> NWNxEE shims. Don't use without NWNxEE
const string PRC_PRCX_ENABLED = "PRC_PRCX_ENABLED";
//:: This switch is set automatically after prc_onmodload detects NWNxEE.
const string PRC_NWNXEE_ENABLED = "PRC_NWNXEE_ENABLED";
/******************************************************************************\ /******************************************************************************\
@@ -2510,10 +2525,6 @@ const string PRC_LETOSCRIPT_PORTAL_PASSWORD = "PRC_LETOSCRIPT_PORTAL_PA
*/ */
const string PRC_LETOSCRIPT_GETNEWESTBIC = "PRC_LETOSCRIPT_GETNEWESTBIC"; const string PRC_LETOSCRIPT_GETNEWESTBIC = "PRC_LETOSCRIPT_GETNEWESTBIC";
//This switch is set automatically after prc_onmodload detects NWNX_Funcs plugin
const string PRC_NWNX_FUNCS = "PRC_NWNX_FUNCS";
/******************************************************************************\ /******************************************************************************\
* ConvoCC switches [DEFUNCT] * * ConvoCC switches [DEFUNCT] *
\******************************************************************************/ \******************************************************************************/

View File

@@ -275,163 +275,6 @@ void ApplyUnarmedAttackEffects(object oCreature)
// Monk: 1d6 at level 1, 1d8 at level 4, 1d10 at level 8, 2d6 at level 12, 2d8 at level 16, 2d10 at level 20 // Monk: 1d6 at level 1, 1d8 at level 4, 1d10 at level 8, 2d6 at level 12, 2d8 at level 16, 2d10 at level 20
// Frostrager: 1d6 at level 1, 1d8 at level 4 // Frostrager: 1d6 at level 1, 1d8 at level 4
int FindUnarmedDamage(object oCreature) int FindUnarmedDamage(object oCreature)
{
int iDamage = 0;
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
int iShou = GetLevelByClass(CLASS_TYPE_SHOU, oCreature);
int iBrawler = GetLevelByClass(CLASS_TYPE_BRAWLER, oCreature);
int iSacredFist = GetLevelByClass(CLASS_TYPE_SACREDFIST, oCreature);
int iEnlightenedFist = GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oCreature);
int iHenshin = GetLevelByClass(CLASS_TYPE_HENSHIN_MYSTIC, oCreature);
int iZuoken = GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oCreature);
int iShadowSunNinja = GetLevelByClass(CLASS_TYPE_SHADOW_SUN_NINJA, oCreature);
int iFrost = GetLevelByClass(CLASS_TYPE_FROSTRAGER, oCreature);
int iAscetic = GetLevelByClass(CLASS_TYPE_NINJA, oCreature);
int iRonove = 0;
int iMonkDamage = 1;
int iShouDamage = 1;
int iBrawlerDamage = 1;
int iFrostDamage = 1;
int iSUSDamage = 1;
int iDieIncrease = 0;
int iSize;
if (GetHasSpellEffect(VESTIGE_RONOVE, oCreature) && GetLevelByClass(CLASS_TYPE_BINDER, oCreature))
iRonove = GetLocalInt(oCreature, "RonovesFists");
//:: Determine creature size
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
{
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
}
else
{
iSize = 5; // medium
if (GetHasFeat(FEAT_TINY, oCreature)) iSize = 3;
if (GetHasFeat(FEAT_SMALL, oCreature)) iSize = 4;
if (GetHasFeat(FEAT_LARGE, oCreature)) iSize = 6;
if (GetHasFeat(FEAT_HUGE, oCreature)) iSize = 7;
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
if (iSize < 1) iSize = 1;
if (iSize > 9) iSize = 9;
}
// Sacred Fist code break protection
if (GetHasFeat(FEAT_SF_CODE, oCreature)) iSacredFist = 0;
// Combine monk-like levels
iMonk += iSacredFist + iHenshin + iEnlightenedFist + iShou + iZuoken + iShadowSunNinja;
// Superior Unarmed Strike
if (GetHasFeat(FEAT_SUPERIOR_UNARMED_STRIKE, oCreature))
{
iMonk += 4;
int nHD = GetHitDice(oCreature);
if (nHD >= 16) iSUSDamage = IP_CONST_MONSTERDAMAGE_2d6;
else if (nHD >= 12) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d10;
else if (nHD >= 8) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d8;
else if (nHD >= 4) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d6;
else if (nHD >= 3) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d4;
}
// Ascetic Stalker
if (GetHasFeat(FEAT_ASCETIC_STALKER, oCreature))
iMonk += iAscetic;
// Cap monk progression
if (iMonk > 16 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE)) iMonk = 16;
else if (iMonk > 20) iMonk = 20;
// Ronove replacement
if (iRonove > iMonk) iMonk = iRonove;
// Monk damage calculation (2DA row)
if (iMonk > 0) iMonkDamage = iMonk / 4 + 3;
if (iSize == 5 && iMonkDamage == 7 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
iMonkDamage = 8;
// Shou Disciple base damage
if (iShou > 0)
{
int nRow;
if (iShou == 1) nRow = 3;
else if (iShou == 2) nRow = 4;
else if (iShou == 3) nRow = 5;
else if (iShou == 4) nRow = 5;
else if (iShou == 5) nRow = 6;
else nRow = 3;
if (nRow > 6) nRow = 6;
iShouDamage = StringToInt(Get2DACache("unarmed_dmg", "size" + IntToString(iSize), nRow));
}
// Frostrager
if (iFrost > 0) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d6;
if (iFrost > 3) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d8;
// Brawler
if (iBrawler > 0) iBrawlerDamage = iBrawler / 6 + 3;
if (iBrawler >= 36) iBrawlerDamage += 2;
// Armor/shield penalties
if (iMonkDamage > 1)
{
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
int bShieldEq = GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD ||
GetBaseItemType(oShield) == BASE_ITEM_LARGESHIELD ||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
if (GetBaseAC(oArmor) > 0 || bShieldEq)
iMonkDamage = 1;
}
if (iShouDamage > 1)
{
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
int bShieldEq = GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD ||
GetBaseItemType(oShield) == BASE_ITEM_LARGESHIELD ||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
if (GetBaseAC(oArmor) > 3 || bShieldEq)
iShouDamage = 1;
}
// Determine IoDM die increase
if (GetHasFeat(FEAT_INCREASE_DAMAGE2, oCreature)) iDieIncrease = 2;
else if (GetHasFeat(FEAT_INCREASE_DAMAGE1, oCreature)) iDieIncrease = 1;
// Lookup monk damage in 2DA
iMonkDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage));
// 3.0e monk special cases
if (iSize <= 5 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
{
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d6) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d12;
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d10) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d20;
}
// Apply IoDM die increase last, after 2DA lookups
if (iMonkDamage > 0) iMonkDamage = StepDie(iMonkDamage, iDieIncrease);
if (iShouDamage > 0) iShouDamage = StepDie(iShouDamage, iDieIncrease);
if (iBrawlerDamage > 0) iBrawlerDamage = StepDie(iBrawlerDamage, iDieIncrease);
if (iFrostDamage > 0) iFrostDamage = StepDie(iFrostDamage, iDieIncrease);
if (iSUSDamage > 0) iSUSDamage = StepDie(iSUSDamage, iDieIncrease);
// Select best damage
iDamage = iMonkDamage;
iDamage = (DamageAvg(iShouDamage ) > DamageAvg(iDamage)) ? iShouDamage : iDamage;
iDamage = (DamageAvg(iFrostDamage ) > DamageAvg(iDamage)) ? iFrostDamage : iDamage;
iDamage = (DamageAvg(iSUSDamage ) > DamageAvg(iDamage)) ? iSUSDamage : iDamage;
iDamage = (DamageAvg(iBrawlerDamage) > DamageAvg(iDamage)) ? iBrawlerDamage : iDamage;
if (DEBUG) DoDebug("prc_inc_unarmed: iDamage "+IntToString(iDamage));
return iDamage;
}
/* int FindUnarmedDamage(object oCreature)
{ {
int iDamage = 0; int iDamage = 0;
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk"); int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
@@ -598,7 +441,6 @@ int FindUnarmedDamage(object oCreature)
return iDamage; return iDamage;
} }
*/
// Adds appropriate feats to the skin. Stolen from SoulTaker + expanded with overwhelming/devastating critical. // Adds appropriate feats to the skin. Stolen from SoulTaker + expanded with overwhelming/devastating critical.

View File

@@ -1074,8 +1074,8 @@ void DoWeaponEquip(object oPC, object oItem, int nHand)
if(GetTag(oItem) == "PRC_PYRO_LASH_WHIP") return; if(GetTag(oItem) == "PRC_PYRO_LASH_WHIP") return;
//initialize variables //initialize variables
int nRealSize = PRCGetCreatureSize(oPC); //size for Finesse/TWF int nRealSize = PRCGetCreatureSize(oPC); //:: size for Finesse/TWF
int nSize = nRealSize; //size for equipment restrictions int nSize = nRealSize-2; //:: size for equipment restrictions
int nWeaponSize = GetWeaponSize(oItem); int nWeaponSize = GetWeaponSize(oItem);
int nStrMod = GetAbilityModifier(ABILITY_STRENGTH, oPC); int nStrMod = GetAbilityModifier(ABILITY_STRENGTH, oPC);
int nElfFinesse = GetAbilityModifier(ABILITY_DEXTERITY, oPC) - nStrMod; int nElfFinesse = GetAbilityModifier(ABILITY_DEXTERITY, oPC) - nStrMod;
@@ -1209,6 +1209,12 @@ void DoWeaponEquip(object oPC, object oItem, int nHand)
DoEquipCourtblade(oPC, oItem); DoEquipCourtblade(oPC, oItem);
DoRacialEquip(oPC, nBaseType); DoRacialEquip(oPC, nBaseType);
if(DEBUG) DoDebug("GetWeaponRanged: " + IntToString(GetWeaponRanged(oItem)));
if(DEBUG) DoDebug("PRCLargeWeaponCheck: " + IntToString(PRCLargeWeaponCheck(nBaseType, nWeaponSize)));
if(DEBUG) DoDebug("Size check - Weapon: " + IntToString(nWeaponSize) + ", Size: " + IntToString(nSize) + ", RealSize: " + IntToString(nRealSize));
if(DEBUG) DoDebug("Offhand empty: " + IntToString(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC) == OBJECT_INVALID));
if(DEBUG) DoDebug("RealSize > Small: " + IntToString(nRealSize > CREATURE_SIZE_SMALL));
} }
void DoWeaponsEquip(object oPC) void DoWeaponsEquip(object oPC)

View File

@@ -2529,6 +2529,78 @@ int IsRequiredForOtherManeuvers(int nClass, int prereq, string discipline, objec
} }
int HasPreRequisitesForManeuver(int nClass, int spellbookId, object oPC=OBJECT_SELF) int HasPreRequisitesForManeuver(int nClass, int spellbookId, object oPC=OBJECT_SELF)
{
string sFile = GetClassSpellbookFile(nClass);
int prereqs = StringToInt(Get2DACache(sFile, "Prereqs", spellbookId));
string discipline = Get2DACache(sFile, "Discipline", spellbookId);
// First check if this class is allowed to access this discipline
if (!IsAllowedDiscipline(nClass, spellbookId, oPC))
return FALSE;
// If no prerequisites required and class has access, allow it
if (!prereqs)
return TRUE;
// For maneuvers with prerequisites, count across all Blade Magic classes
json discInfo = GetDisciplineInfoObject(nClass, oPC);
json classDisc2Info = JsonObject();
json classDisc3Info = JsonObject();
if (nClass == CLASS_TYPE_SWORDSAGE)
{
if (GetLevelByClass(CLASS_TYPE_WARBLADE, oPC))
classDisc2Info = GetDisciplineInfoObject(CLASS_TYPE_WARBLADE, oPC);
if (GetLevelByClass(CLASS_TYPE_CRUSADER, oPC))
classDisc3Info = GetDisciplineInfoObject(CLASS_TYPE_CRUSADER, oPC);
}
if (nClass == CLASS_TYPE_CRUSADER)
{
if (GetLevelByClass(CLASS_TYPE_WARBLADE, oPC))
classDisc2Info = GetDisciplineInfoObject(CLASS_TYPE_WARBLADE, oPC);
if (GetLevelByClass(CLASS_TYPE_SWORDSAGE, oPC))
classDisc3Info = GetDisciplineInfoObject(CLASS_TYPE_SWORDSAGE, oPC);
}
if (nClass == CLASS_TYPE_WARBLADE)
{
if (GetLevelByClass(CLASS_TYPE_CRUSADER, oPC))
classDisc2Info = GetDisciplineInfoObject(CLASS_TYPE_CRUSADER, oPC);
if (GetLevelByClass(CLASS_TYPE_SWORDSAGE, oPC))
classDisc3Info = GetDisciplineInfoObject(CLASS_TYPE_SWORDSAGE, oPC);
}
// Sum up maneuver counts from all classes for this discipline
int nManCount = 0;
// Check primary class
json chosenDisc = JsonObjectGet(discInfo, discipline);
if (chosenDisc != JsonNull())
{
nManCount += JsonGetInt(JsonObjectGet(chosenDisc, IntToString(MANEUVER_TYPE_MANEUVER)));
nManCount += JsonGetInt(JsonObjectGet(chosenDisc, IntToString(MANEUVER_TYPE_STANCE)));
}
// Check second class
chosenDisc = JsonObjectGet(classDisc2Info, discipline);
if (chosenDisc != JsonNull())
{
nManCount += JsonGetInt(JsonObjectGet(chosenDisc, IntToString(MANEUVER_TYPE_MANEUVER)));
nManCount += JsonGetInt(JsonObjectGet(chosenDisc, IntToString(MANEUVER_TYPE_STANCE)));
}
// Check third class
chosenDisc = JsonObjectGet(classDisc3Info, discipline);
if (chosenDisc != JsonNull())
{
nManCount += JsonGetInt(JsonObjectGet(chosenDisc, IntToString(MANEUVER_TYPE_MANEUVER)));
nManCount += JsonGetInt(JsonObjectGet(chosenDisc, IntToString(MANEUVER_TYPE_STANCE)));
}
// Check if we have enough maneuvers for the prerequisite
return nManCount >= prereqs;
}
/* int HasPreRequisitesForManeuver(int nClass, int spellbookId, object oPC=OBJECT_SELF)
{ {
string sFile = GetClassSpellbookFile(nClass); string sFile = GetClassSpellbookFile(nClass);
int prereqs = StringToInt(Get2DACache(sFile, "Prereqs", spellbookId)); int prereqs = StringToInt(Get2DACache(sFile, "Prereqs", spellbookId));
@@ -2546,7 +2618,7 @@ int HasPreRequisitesForManeuver(int nClass, int spellbookId, object oPC=OBJECT_S
} }
return FALSE; return FALSE;
} } */
int GetMaxInitiatorCircle(int nClass, object oPC=OBJECT_SELF) int GetMaxInitiatorCircle(int nClass, object oPC=OBJECT_SELF)
{ {

View File

@@ -362,6 +362,12 @@ int IsSpellKnown(object oPlayer, int nClass, int spellId)
return GetHasFeat(featID, oPlayer); return GetHasFeat(featID, oPlayer);
} }
// Divine Surge Greater hardcoding to fix NUI display issue
if (spellId == 15840 || spellId == 16051 || spellId == 16262)
{
spellId = MOVE_DS_GREATER_DIVINE_SURGE; // 17337
}
int currentSpell = spellId; int currentSpell = spellId;
int masterSpell = StringToInt(Get2DACache("spells", "Master", currentSpell)); int masterSpell = StringToInt(Get2DACache("spells", "Master", currentSpell));
if (masterSpell) // If this is not 0 then this is a radial spell, check the radial master if (masterSpell) // If this is not 0 then this is a radial spell, check the radial master
@@ -843,3 +849,5 @@ int IsSpellbookNUIOpen(object oPC)
return FALSE; return FALSE;
} }
//:: void main(){}

View File

@@ -29,6 +29,7 @@ const int RACIAL_TYPE_SILVANESTI_ELF = 999;
const int RACIAL_TYPE_TINK_GNOME = 999; const int RACIAL_TYPE_TINK_GNOME = 999;
//Eberron Races //Eberron Races
const int RACIAL_TYPE_WARFORGED_SCOUT = 144;
const int RACIAL_TYPE_WARFORGED_CHARGER = 145; const int RACIAL_TYPE_WARFORGED_CHARGER = 145;
const int RACIAL_TYPE_SHIFTER = 146; const int RACIAL_TYPE_SHIFTER = 146;
const int RACIAL_TYPE_CHANGELING = 147; const int RACIAL_TYPE_CHANGELING = 147;
@@ -39,15 +40,15 @@ const int RACIAL_TYPE_EMPTY_VESSEL = 154;
//Planescape Races //Planescape Races
const int RACIAL_TYPE_BARIAUR = 207; const int RACIAL_TYPE_BARIAUR = 207;
const int RACIAL_TYPE_BLADELING = 195; const int RACIAL_TYPE_BLADELING = 999;
const int RACIAL_TYPE_CHAOND = 196; const int RACIAL_TYPE_CHAOND = 999;
const int RACIAL_TYPE_NATHRI = 237; const int RACIAL_TYPE_NATHRI = 237;
const int RACIAL_TYPE_TULADHARA = 197; const int RACIAL_TYPE_TULADHARA = 999;
const int RACIAL_TYPE_ZENYRTHRI = 206; const int RACIAL_TYPE_ZENYRTHRI = 999;
//Ravenloft Races //Ravenloft Races
const int RACIAL_TYPE_HVISTANI = 146; const int RACIAL_TYPE_HVISTANI = 999;
const int RACIAL_TYPE_VISTANI = 147; const int RACIAL_TYPE_VISTANI = 999;
//:: Rokugan/Kara-Tur Races //:: Rokugan/Kara-Tur Races
const int RACIAL_TYPE_TASLOI = 140; const int RACIAL_TYPE_TASLOI = 140;
@@ -57,85 +58,89 @@ const int RACIAL_TYPE_NEZUMI = 246;
//Spelljammer Races //Spelljammer Races
const int RACIAL_TYPE_SCRO = 182; const int RACIAL_TYPE_SCRO = 999;
const int RACIAL_TYPE_XIXCHIL = 181; const int RACIAL_TYPE_XIXCHIL = 999;
// DMG // DMG
const int RACIAL_TYPE_PLANT = 52; const int RACIAL_TYPE_PLANT = 52;
//Draconic Races //Draconic Races
const int RACIAL_TYPE_DRAGONBORN = 128; const int RACIAL_TYPE_DRAGONBORN = 999;
const int RACIAL_TYPE_SPELLSCALE = 129; const int RACIAL_TYPE_SPELLSCALE = 999;
const int RACIAL_TYPE_REDSPAWN_ARCANISS = 72; const int RACIAL_TYPE_REDSPAWN_ARCANISS = 72;
const int RACIAL_TYPE_SPIRETOPDRAGON = 77; const int RACIAL_TYPE_SPIRETOPDRAGON = 77;
//Fey-type Races //Fey-type Races
const int RACIAL_TYPE_BRALANI = 159; const int RACIAL_TYPE_BRALANI = 159;
const int RACIAL_TYPE_BROWNIE = 53; const int RACIAL_TYPE_BROWNIE = 53;
const int RACIAL_TYPE_GRIG = 133; const int RACIAL_TYPE_GRIG = 999;
const int RACIAL_TYPE_JAEBRIN = 78; const int RACIAL_TYPE_JAEBRIN = 78;
const int RACIAL_TYPE_NIXIE = 134; const int RACIAL_TYPE_NIXIE = 999;
const int RACIAL_TYPE_NYMPH = 135; const int RACIAL_TYPE_NYMPH = 999;
const int RACIAL_TYPE_PIXIE = 226; const int RACIAL_TYPE_PIXIE = 226;
const int RACIAL_TYPE_SATYR = 136; const int RACIAL_TYPE_SATYR = 999;
const int RACIAL_TYPE_HYBSIL = 66; const int RACIAL_TYPE_HYBSIL = 66;
//Outsider Races //Outsider Races
const int RACIAL_TYPE_ASURA = 80; const int RACIAL_TYPE_ASURA = 999;
const int RACIAL_TYPE_AZER = 227; const int RACIAL_TYPE_AZER = 227;
const int RACIAL_TYPE_BUOMMANS = 238; const int RACIAL_TYPE_BUOMMANS = 238;
const int RACIAL_TYPE_DJINNI = 81; const int RACIAL_TYPE_DJINNI = 999;
const int RACIAL_TYPE_EFREETI = 82; const int RACIAL_TYPE_EFREETI = 999;
const int RACIAL_TYPE_FORMIAN = 232; const int RACIAL_TYPE_FORMIAN = 999;
const int RACIAL_TYPE_GITHYANKI = 222; const int RACIAL_TYPE_GITHYANKI = 222;
const int RACIAL_TYPE_GITHZERAI = 223; const int RACIAL_TYPE_GITHZERAI = 223;
const int RACIAL_TYPE_GLOAMING = 83; const int RACIAL_TYPE_GLOAMING = 999;
const int RACIAL_TYPE_HOUND_ARCHON = 84; const int RACIAL_TYPE_HOUND_ARCHON = 84;
const int RACIAL_TYPE_KHAASTA = 94; const int RACIAL_TYPE_KHAASTA = 94;
const int RACIAL_TYPE_JANNI = 85; const int RACIAL_TYPE_JANNI = 999;
const int RACIAL_TYPE_MEPHIT_AIR = 86; const int RACIAL_TYPE_MEPHIT_AIR = 999;
const int RACIAL_TYPE_MEPHIT_EARTH = 87; const int RACIAL_TYPE_MEPHIT_EARTH = 999;
const int RACIAL_TYPE_MEPHIT_FIRE = 88; const int RACIAL_TYPE_MEPHIT_FIRE = 999;
const int RACIAL_TYPE_MEPHIT_WATER = 89; const int RACIAL_TYPE_MEPHIT_WATER = 999;
const int RACIAL_TYPE_MEPHLING_AIR = 90; const int RACIAL_TYPE_MEPHLING_AIR = 90;
const int RACIAL_TYPE_MEPHLING_EARTH = 91; const int RACIAL_TYPE_MEPHLING_EARTH = 91;
const int RACIAL_TYPE_MEPHLING_FIRE = 92; const int RACIAL_TYPE_MEPHLING_FIRE = 92;
const int RACIAL_TYPE_MEPHLING_WATER = 93; const int RACIAL_TYPE_MEPHLING_WATER = 93;
const int RACIAL_TYPE_NERAPHIM = 235; const int RACIAL_TYPE_NERAPHIM = 235;
const int RACIAL_TYPE_RAKSHASA = 224; const int RACIAL_TYPE_RAKSHASA = 224;
const int RACIAL_TYPE_SALAMANDER = 95; const int RACIAL_TYPE_SALAMANDER = 999;
const int RACIAL_TYPE_SHADE = 210; const int RACIAL_TYPE_SHADE = 999;
const int RACIAL_TYPE_SPIKER = 239; const int RACIAL_TYPE_SPIKER = 239;
const int RACIAL_TYPE_WILDREN = 240; const int RACIAL_TYPE_WILDREN = 240;
const int RACIAL_TYPE_NAZTHARUNE_RAKSHASA = 96; const int RACIAL_TYPE_NAZTHARUNE_RAKSHASA = 96;
const int RACIAL_TYPE_RETH_DEKALA = 67; const int RACIAL_TYPE_RETH_DEKALA = 67;
//Planetouched Races //Planetouched Races
const int RACIAL_TYPE_AASIMAR = 198; const int RACIAL_TYPE_WISPLING = 195;
const int RACIAL_TYPE_AIR_GEN = 199; const int RACIAL_TYPE_SHYFT = 196;
const int RACIAL_TYPE_EARTH_GEN = 200; const int RACIAL_TYPE_MECHANATRIX = 197;
const int RACIAL_TYPE_FEYRI = 201; const int RACIAL_TYPE_AASIMAR = 198;
const int RACIAL_TYPE_FIRE_GEN = 202; const int RACIAL_TYPE_AIR_GEN = 199;
const int RACIAL_TYPE_MORTIF = 132; const int RACIAL_TYPE_EARTH_GEN = 200;
const int RACIAL_TYPE_TANARUKK = 203; const int RACIAL_TYPE_FEYRI = 201;
const int RACIAL_TYPE_TIEFLING = 204; const int RACIAL_TYPE_FIRE_GEN = 202;
const int RACIAL_TYPE_WATER_GEN = 205; const int RACIAL_TYPE_MAELUTH = 206;
const int RACIAL_TYPE_SHADOWSWYFT = 236; const int RACIAL_TYPE_MORTIF = 999;
const int RACIAL_TYPE_TANARUKK = 203;
const int RACIAL_TYPE_TIEFLING = 204;
const int RACIAL_TYPE_WATER_GEN = 205;
const int RACIAL_TYPE_SHADOWSWYFT = 236;
//Serpent Kingdom and Reptillian Races //Serpent Kingdom and Reptillian Races
const int RACIAL_TYPE_ABOM_YUAN = 228; const int RACIAL_TYPE_ABOM_YUAN = 999;
const int RACIAL_TYPE_ASABI = 999; const int RACIAL_TYPE_ASABI = 999;
const int RACIAL_TYPE_ASABI_STINGTAIL = 999; const int RACIAL_TYPE_ASABI_STINGTAIL = 999;
const int RACIAL_TYPE_KUOTOA = 999; const int RACIAL_TYPE_KUOTOA = 999;
const int RACIAL_TYPE_LIZARDFOLK = 219; const int RACIAL_TYPE_LIZARDFOLK = 219;
const int RACIAL_TYPE_LIZARDKING = 68; const int RACIAL_TYPE_LIZARDKING = 999;
const int RACIAL_TYPE_MEDUSA = 69; const int RACIAL_TYPE_MEDUSA = 999;
const int RACIAL_TYPE_OPHIDIAN = 999; const int RACIAL_TYPE_OPHIDIAN = 999;
const int RACIAL_TYPE_POISON_DUSK = 248; const int RACIAL_TYPE_POISON_DUSK = 248;
const int RACIAL_TYPE_PURE_YUAN = 220; const int RACIAL_TYPE_PURE_YUAN = 220;
const int RACIAL_TYPE_SAHUAGIN = 71; const int RACIAL_TYPE_SAHUAGIN = 999;
const int RACIAL_TYPE_SK_YUANTI = 233; const int RACIAL_TYPE_SK_YUANTI = 999;
const int RACIAL_TYPE_TREN = 72; const int RACIAL_TYPE_TREN = 999;
const int RACIAL_TYPE_VILETOOTH_LIZARDFOLK = 112; const int RACIAL_TYPE_VILETOOTH_LIZARDFOLK = 112;
const int RACIAL_TYPE_MUCKDWELLER = 74; const int RACIAL_TYPE_MUCKDWELLER = 74;
@@ -143,32 +148,32 @@ const int RACIAL_TYPE_MUCKDWELLER = 74;
const int RACIAL_TYPE_ARANEA = 75; const int RACIAL_TYPE_ARANEA = 75;
const int RACIAL_TYPE_BEHOLDER = -1; const int RACIAL_TYPE_BEHOLDER = -1;
const int RACIAL_TYPE_DRIDER = 50; const int RACIAL_TYPE_DRIDER = 50;
const int RACIAL_TYPE_GRIMLOCK = 77; const int RACIAL_TYPE_GRIMLOCK = 999;
const int RACIAL_TYPE_ILLITHID = 225; const int RACIAL_TYPE_ILLITHID = 225;
const int RACIAL_TYPE_IMASKARI = 230; const int RACIAL_TYPE_IMASKARI = 230;
const int RACIAL_TYPE_SLYTH = 78; const int RACIAL_TYPE_SLYTH = 999;
const int RACIAL_TYPE_TROGLODYTE = 234; const int RACIAL_TYPE_TROGLODYTE = 234;
const int RACIAL_TYPE_UMBER_HULK = 79; const int RACIAL_TYPE_UMBER_HULK = 999;
const int RACIAL_TYPE_GLOURA = 73; const int RACIAL_TYPE_GLOURA = 73;
//Other Monsterous Races //Other Monsterous Races
const int RACIAL_TYPE_CENTAUR = 208; const int RACIAL_TYPE_CENTAUR = 208;
const int RACIAL_TYPE_CATFOLK = 209; const int RACIAL_TYPE_CATFOLK = 209;
const int RACIAL_TYPE_DIABOLUS = 113; const int RACIAL_TYPE_DIABOLUS = 999;
const int RACIAL_TYPE_DIOPSID = 114; const int RACIAL_TYPE_DIOPSID = 999;
const int RACIAL_TYPE_DRAGONKIN = 58; const int RACIAL_TYPE_DRAGONKIN = 999;
const int RACIAL_TYPE_ETTERCAP = 73; const int RACIAL_TYPE_ETTERCAP = 999;
const int RACIAL_TYPE_FIRENEWT = 59; const int RACIAL_TYPE_FIRENEWT = 999;
const int RACIAL_TYPE_GARGOYLE = 185; const int RACIAL_TYPE_GARGOYLE = 999;
const int RACIAL_TYPE_KIRLANAN = 60; const int RACIAL_TYPE_KIRLANAN = 999;
const int RACIAL_TYPE_LUPIN = 186; const int RACIAL_TYPE_LUPIN = 999;
const int RACIAL_TYPE_PTERAFOLK = 61; const int RACIAL_TYPE_PTERAFOLK = 999;
const int RACIAL_TYPE_RAPTORAN = 130; const int RACIAL_TYPE_RAPTORAN = 999;
const int RACIAL_TYPE_SAURIAL_BLADEBACK = 62; const int RACIAL_TYPE_SAURIAL_BLADEBACK = 999;
const int RACIAL_TYPE_SAURIAL_FINHEAD = 63; const int RACIAL_TYPE_SAURIAL_FINHEAD = 999;
const int RACIAL_TYPE_SAURIAL_FLYER = 64; const int RACIAL_TYPE_SAURIAL_FLYER = 999;
const int RACIAL_TYPE_SAURIAL_HORNHEAD = 65; const int RACIAL_TYPE_SAURIAL_HORNHEAD = 999;
const int RACIAL_TYPE_TORTLE = 118; const int RACIAL_TYPE_TORTLE = 999;
const int RACIAL_TYPE_VOLODNI = 131; const int RACIAL_TYPE_VOLODNI = 131;
const int RACIAL_TYPE_WEMIC = 51; const int RACIAL_TYPE_WEMIC = 51;
const int RACIAL_TYPE_ARKAMOI = 68; const int RACIAL_TYPE_ARKAMOI = 68;
@@ -226,7 +231,7 @@ const int RACIAL_TYPE_MARRUSAULT = 119;
const int RACIAL_TYPE_MARRUTACT = 120; const int RACIAL_TYPE_MARRUTACT = 120;
//Stormwrack //Stormwrack
const int RACIAL_TYPE_DARFELLAN = 117; const int RACIAL_TYPE_DARFELLAN = 999;
const int RACIAL_TYPE_HADOZEE = 180; const int RACIAL_TYPE_HADOZEE = 180;
//Champions of Ruin //Champions of Ruin
@@ -257,7 +262,7 @@ const int RACIAL_TYPE_GREY_ELF = 169;
//:: Dwarf //:: Dwarf
const int RACIAL_TYPE_ARC_DWARF = 151; const int RACIAL_TYPE_ARC_DWARF = 151;
const int RACIAL_TYPE_DREAM_DWARF = 157; const int RACIAL_TYPE_DREAM_DWARF = 999;
const int RACIAL_TYPE_FIREBLOOD_DWARF = 106; const int RACIAL_TYPE_FIREBLOOD_DWARF = 106;
const int RACIAL_TYPE_FROST_DWARF = 158; const int RACIAL_TYPE_FROST_DWARF = 158;
const int RACIAL_TYPE_GOLD_DWARF = 152; const int RACIAL_TYPE_GOLD_DWARF = 152;
@@ -267,11 +272,11 @@ const int RACIAL_TYPE_URDINNIR = 155;
const int RACIAL_TYPE_WILD_DWARF = 156; const int RACIAL_TYPE_WILD_DWARF = 156;
//:: Gnome //:: Gnome
const int RACIAL_TYPE_CHAOS_GNOME = 177; const int RACIAL_TYPE_CHAOS_GNOME = 999;
const int RACIAL_TYPE_DEEP_GNOME = 174; const int RACIAL_TYPE_DEEP_GNOME = 174;
const int RACIAL_TYPE_FIRE_GNOME = 173; const int RACIAL_TYPE_FIRE_GNOME = 173;
const int RACIAL_TYPE_FOR_GNOME = 175; const int RACIAL_TYPE_FOR_GNOME = 175;
const int RACIAL_TYPE_ICE_GNOME = 178; const int RACIAL_TYPE_ICE_GNOME = 999;
const int RACIAL_TYPE_ROCK_GNOME = 176; const int RACIAL_TYPE_ROCK_GNOME = 176;
const int RACIAL_TYPE_STONEHUNTER_GNOME = 105; const int RACIAL_TYPE_STONEHUNTER_GNOME = 105;
const int RACIAL_TYPE_SVIRFNEBLIN = 174; const int RACIAL_TYPE_SVIRFNEBLIN = 174;

View File

@@ -93,7 +93,9 @@ struct _prc_inc_ability_info_struct _prc_inc_CountItemAbilities(object oCreature
struct _prc_inc_ability_info_struct _prc_inc_shifter_GetAbilityInfo(object oTemplate, object oShifter) struct _prc_inc_ability_info_struct _prc_inc_shifter_GetAbilityInfo(object oTemplate, object oShifter)
{ {
int bFuncs = GetPRCSwitch(PRC_NWNX_FUNCS); int nNWNxEE = GetPRCSwitch(PRC_NWNXEE_ENABLED);
int nPRCx = GetPRCSwitch(PRC_PRCX_ENABLED);
int bFuncs = (nNWNxEE && nPRCx);
//Initialize with item ability bonuses //Initialize with item ability bonuses

View File

@@ -443,14 +443,14 @@ const int SPELL_PHANTOM_STEED = 2347;
const int SPELL_GASEOUS_FORM = 2348; const int SPELL_GASEOUS_FORM = 2348;
//:: Racial spell additions //:: Racial spell additions
const int SPIRETOP_FOG_CLOUD_BREATH = 1487; //:: Spiretop Dragon const int SPIRETOP_FOG_CLOUD_BREATH = 1487; //:: Spiretop Dragon
const int MEPHLING_BREATH_WEAPON = 1488; //:: Mephlings const int MEPHLING_BREATH_WEAPON = 1488; //:: Mephlings
const int SPELL_ARANEA_ALTER = 1489; //:: Aranea const int SPELL_ARANEA_ALTER = 1489; //:: Aranea
const int SPELL_ARANEA_ALTER_HUMANOID = 1490; const int SPELL_ARANEA_ALTER_HUMANOID = 1490;
const int SPELL_ARANEA_ALTER_HYBRID = 1491; const int SPELL_ARANEA_ALTER_HYBRID = 1491;
const int SPELL_ARANEA_ALTER_SPIDER = 1492; const int SPELL_ARANEA_ALTER_SPIDER = 1492;
const int SPELL_ARANEA_WEB = 1493; const int SPELL_ARANEA_WEB = 1493;
const int SPELL_MUCK_SQUIRT = 1494; //:: Muckdweller const int SPELL_MUCK_SQUIRT = 1494; //:: Muckdweller
const int SPELL_RAKSHASA_DISGUISE = 1951; const int SPELL_RAKSHASA_DISGUISE = 1951;
const int SPELL_FEYRI_ALTER = 1955; const int SPELL_FEYRI_ALTER = 1955;
const int SPELL_NIXIE_WATERBREATHING = 1956; const int SPELL_NIXIE_WATERBREATHING = 1956;
@@ -547,6 +547,18 @@ const int SPELL_TURLEMOI_STRENGTH = 19013;
const int SPELL_HADRIMOI_STRENGTH = 19014; const int SPELL_HADRIMOI_STRENGTH = 19014;
const int SPELL_GLOURA_GRACE = 19015; const int SPELL_GLOURA_GRACE = 19015;
const int SPELL_SHYFT_ETHEREAL_JAUNT = 17977; //:: Shyft
const int SPELL_MECHA_SHOCKING_GRASP = 17978; //:: Mechanatrix
const int SPELL_MAELUTH_FIEND_HAMMER = 17979; //:: Maeloth
const int SPELL_WISPLING_CHANGE_SHAPE_LEARN = 17980; //:: Wispling
const int SPELL_WISPLING_CHANGE_SHAPE_OPTIONS = 17981;
const int SPELL_WISPLING_CHANGE_SHAPE_TRUE = 17982;
const int SPELL_WISPLING_CHANGE_SHAPE_QS1 = 17983;
const int SPELL_WISPLING_CHANGE_SHAPE_QS2 = 17984;
// Poison system spells // Poison system spells
const int SPELL_POISONED_WEAPON = 2880; const int SPELL_POISONED_WEAPON = 2880;
const int SPELL_GRENADE_POISONVIAL = 2881; const int SPELL_GRENADE_POISONVIAL = 2881;
@@ -555,7 +567,6 @@ const int SPELL_POISON_ITEM = 2883;
const int SPELL_POISON_FOOD = 2884; const int SPELL_POISON_FOOD = 2884;
const int SPELL_CLEAN_POISON_OFF = 2885; const int SPELL_CLEAN_POISON_OFF = 2885;
// Psionic feat spells // Psionic feat spells
const int SPELL_FEAT_SPEED_OF_THOUGHT_BONUS = 2820; const int SPELL_FEAT_SPEED_OF_THOUGHT_BONUS = 2820;

View File

@@ -120,6 +120,10 @@ const int PRC_GEM_PERLEVEL = 6;
// Craft Skull Talisman constants // Craft Skull Talisman constants
const int PRC_SKULL_BASECOST = 7; const int PRC_SKULL_BASECOST = 7;
int GetWeaponType(int nBaseItem);
void RemoveMasterworkProperties(object oItem);
// * Returns TRUE if an item is a Craft Base Item // * Returns TRUE if an item is a Craft Base Item
// * to be used in spellscript that can be cast on items - i.e light // * to be used in spellscript that can be cast on items - i.e light
int CIGetIsCraftFeatBaseItem( object oItem ); int CIGetIsCraftFeatBaseItem( object oItem );
@@ -214,6 +218,78 @@ int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0)
/* Function definitions */ /* Function definitions */
////////////////////////////////////////////////// //////////////////////////////////////////////////
void RemoveMasterworkProperties(object oItem)
{
if(DEBUG) DoDebug("RemoveMasterworkProperties() called on: " + DebugObject2Str(oItem));
int nBase = GetBaseItemType(oItem);
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Item base type: " + IntToString(nBase));
int nRemoved = 0;
// For armor/shields: remove only the Quality property, keep skill bonuses
if((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD))
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Processing armor/shield");
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
string sTag = GetItemPropertyTag(ip);
int nType = GetItemPropertyType(ip);
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Found property - Type: " + IntToString(nType) +
", Tag: " + sTag +
", String: " + DebugIProp2Str(ip));
if(sTag == "Quality_Masterwork" && nType == ITEM_PROPERTY_QUALITY)
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Removing Quality property");
RemoveItemProperty(oItem, ip);
nRemoved++;
ip = GetFirstItemProperty(oItem); // Restart iteration
continue;
}
ip = GetNextItemProperty(oItem);
}
}
// For weapons/ammo: remove both Quality and Attack Bonus properties
if(GetWeaponType(nBase) ||
StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == 4)
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Processing weapon/ammo");
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
string sTag = GetItemPropertyTag(ip);
int nType = GetItemPropertyType(ip);
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Found property - Type: " + IntToString(nType) +
", Tag: " + sTag +
", String: " + DebugIProp2Str(ip));
// Check for both Quality and Attack Bonus with Quality_Masterwork tag
if(sTag == "Quality_Masterwork" &&
(nType == ITEM_PROPERTY_QUALITY || nType == ITEM_PROPERTY_ATTACK_BONUS))
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Removing property type " + IntToString(nType));
RemoveItemProperty(oItem, ip);
nRemoved++;
ip = GetFirstItemProperty(oItem); // Restart iteration
continue;
}
ip = GetNextItemProperty(oItem);
}
}
if(DEBUG) DoDebug("prc_x2_craft: RemoveMasterworkProperties() completed. Removed " +
IntToString(nRemoved) + " properties.");
}
// * Returns the innate level of a spell. If bDefaultZeroToOne is given // * Returns the innate level of a spell. If bDefaultZeroToOne is given
// * Level 0 spell will be returned as level 1 spells // * Level 0 spell will be returned as level 1 spells
@@ -2417,7 +2493,7 @@ int CIDoCraftItemFromConversation(int nNumber)
DeleteLocalObject(oPC,"X2_CI_CRAFT_MAJOR"); DeleteLocalObject(oPC,"X2_CI_CRAFT_MAJOR");
DeleteLocalObject(oPC,"X2_CI_CRAFT_MINOR"); DeleteLocalObject(oPC,"X2_CI_CRAFT_MINOR");
if (!GetIsObjectValid(oMajor)) if (!GetIsObjectValid(oMajor))
{ {
FloatingTextStrRefOnCreature(83374,oPC); //"Invalid target" FloatingTextStrRefOnCreature(83374,oPC); //"Invalid target"
DeleteLocalInt(oPC,"X2_CRAFT_SUCCESS"); DeleteLocalInt(oPC,"X2_CRAFT_SUCCESS");
@@ -2481,7 +2557,9 @@ int CIDoCraftItemFromConversation(int nNumber)
if (GetIsObjectValid(oRet)) if (GetIsObjectValid(oRet))
{ {
// ----------------------------------------------------------------------- RemoveMasterworkProperties(oMajor);
// -----------------------------------------------------------------------
// Copy all item properties from the major object on the resulting item // Copy all item properties from the major object on the resulting item
// Through we problably won't use this, its a neat thing to have for the // Through we problably won't use this, its a neat thing to have for the
// community // community
@@ -2499,7 +2577,8 @@ int CIDoCraftItemFromConversation(int nNumber)
{ {
//TakeGoldFromCreature(stItem.nCost, oPC,TRUE); //TakeGoldFromCreature(stItem.nCost, oPC,TRUE);
SpendGP(oPC, stItem.nCost); SpendGP(oPC, stItem.nCost);
IPCopyItemProperties(oMajor,oRet); RemoveMasterworkProperties(oMajor);
IPCopyItemProperties(oMajor,oRet);
} }
// set success variable for conversation // set success variable for conversation
SetLocalInt(oPC,"X2_CRAFT_SUCCESS",TRUE); SetLocalInt(oPC,"X2_CRAFT_SUCCESS",TRUE);

View File

@@ -210,6 +210,7 @@ int IPDamageConstant(int nDamBon);
#include "prc_ipfeat_const" #include "prc_ipfeat_const"
#include "inc_utility" #include "inc_utility"
#include "prc_craft_inc"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// I M P L E M E N T A T I O N // I M P L E M E N T A T I O N

View File

@@ -304,10 +304,31 @@ int PRCDoResistSpell(object oCaster, object oTarget, int nEffCasterLvl=0, float
} }
} }
//:: A tie favors the caster.
int nSRValue = PRCGetSpellResistance(oTarget, oCaster);
int nD20Roll = d20(1);
int nCasterTotal = nEffCasterLvl + nD20Roll + iWeav;
// A tie favors the caster. if (nCasterTotal < nSRValue)
nResist = SPELL_RESIST_PASS;
//:: Optional Detailed SR check to caster
if (GetIsPC(oCaster) && nResist != SPELL_RESIST_MANTLE && nResist != SPELL_RESIST_GLOBE && nSRValue > 0 && GetPRCSwitch(PRC_SHOW_SR_CHECK_DETAILS))
{
string message = nResist == SPELL_RESIST_FAIL ?
"Target affected. Roll: " + IntToString(nCasterTotal) + " vs SR: " + IntToString(nSRValue) :
"Target resisted. Roll: " + IntToString(nCasterTotal) + " vs SR: " + IntToString(nSRValue) +
" (missed by " + IntToString(nSRValue - nCasterTotal) + ")";
SendMessageToPC(oCaster, message);
}
//:: Basic pass/fail messages
PRCShowSpellResist(oCaster, oTarget, nResist, fDelay);
/* // A tie favors the caster.
if ((nEffCasterLvl + d20(1)+iWeav) < PRCGetSpellResistance(oTarget, oCaster)) if ((nEffCasterLvl + d20(1)+iWeav) < PRCGetSpellResistance(oTarget, oCaster))
nResist = SPELL_RESIST_PASS; nResist = SPELL_RESIST_PASS; */
} }
} }
@@ -399,3 +420,5 @@ int CheckSpellfire(object oCaster, object oTarget, int bFriendly = FALSE)
//absorbed //absorbed
return 1; return 1;
} }
//:; void main(){}

View File

@@ -713,5 +713,8 @@ void SetAugmentationOverride(object oCreature, struct user_augment_profile uap)
SetLocalInt(oCreature, PRC_AUGMENT_OVERRIDE, _EncodeProfile(uap) + 1); SetLocalInt(oCreature, PRC_AUGMENT_OVERRIDE, _EncodeProfile(uap) + 1);
} }
// Test main // Test main
//void main(){} //void main(){}

View File

@@ -70,6 +70,7 @@ const int METAPSIONIC_WIDEN = 0x80;
/// Quicken Power /// Quicken Power
const int METAPSIONIC_QUICKEN = 0x100; const int METAPSIONIC_QUICKEN = 0x100;
/// How much PP Chain Power costs to use /// How much PP Chain Power costs to use
const int METAPSIONIC_CHAIN_COST = 6; const int METAPSIONIC_CHAIN_COST = 6;
/// How much PP Empower Power costs to use /// How much PP Empower Power costs to use

View File

@@ -443,6 +443,8 @@ struct manifestation{
int bWiden; int bWiden;
/// Whether Quicken Power was used with this manifestation /// Whether Quicken Power was used with this manifestation
int bQuicken; int bQuicken;
//:: Whether Defensive Manifesation was used with this manifestation
int bDefensive;
}; };
////////////////////////////////////////////////// //////////////////////////////////////////////////
@@ -1722,7 +1724,7 @@ int IsHiddenTalent(object oPC = OBJECT_SELF)
GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC) ||
GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC) ||
GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC) ||
//GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC) ||
GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC) ||
GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC) ||
GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC) || GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC) ||
@@ -1834,7 +1836,7 @@ int GetHiddenTalentCount(object oPC = OBJECT_SELF)
if (GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC)) nCount++;
if (GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC)) nCount++;
if (GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC)) nCount++;
//if (GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) nCount++;
if (GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC)) nCount++;
if (GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC)) nCount++;
if (GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC)) nCount++; if (GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC)) nCount++;
@@ -1887,7 +1889,10 @@ int GetIsHiddenTalentPower(object oPC, int nPower)
if(nPower == POWER_ELFSIGHT && GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC)) return TRUE; if(nPower == POWER_ELFSIGHT && GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC)) return TRUE;
if(nPower == POWER_EMPATHY && GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC)) return TRUE; if(nPower == POWER_EMPATHY && GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC)) return TRUE;
if(nPower == POWER_EMPTYMIND && GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC)) return TRUE; if(nPower == POWER_EMPTYMIND && GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC)) return TRUE;
//if(nPower == POWER_ENERGYRAY && GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) return TRUE; if(nPower == POWER_ENERGYRAY_FIRE && GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) return TRUE;
if(nPower == POWER_ENERGYRAY_COLD && GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) return TRUE;
if(nPower == POWER_ENERGYRAY_ELEC && GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) return TRUE;
if(nPower == POWER_ENERGYRAY_SONIC && GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) return TRUE;
if(nPower == POWER_ENTANGLE && GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC)) return TRUE; if(nPower == POWER_ENTANGLE && GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC)) return TRUE;
if(nPower == POWER_EXPANSION && GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC)) return TRUE; if(nPower == POWER_EXPANSION && GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC)) return TRUE;
if(nPower == POWER_FARHAND && GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC)) return TRUE; if(nPower == POWER_FARHAND && GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC)) return TRUE;

View File

@@ -29,7 +29,7 @@
*/ */
//::////////////////////////////////////////////// //:://////////////////////////////////////////////
//::////////////////////////////////////////////// //:://////////////////////////////////////////////
#include "prc_inc_spells"
////////////////////////////////////////////////// //////////////////////////////////////////////////
/* Constants */ /* Constants */
////////////////////////////////////////////////// //////////////////////////////////////////////////
@@ -572,32 +572,49 @@ int GetMaxPowerCount(object oCreature, int nList)
int GetHasPower(int nPower, object oCreature = OBJECT_SELF) int GetHasPower(int nPower, object oCreature = OBJECT_SELF)
{ {
// Check MISC list first (for Hidden Talent and similar feats) // Debug output
if(GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_INVALID), oCreature)) if (DEBUG) DoDebug("GetHasPower: Checking power " + IntToString(nPower));
return TRUE;
if((GetLevelByClass(CLASS_TYPE_PSION, oCreature) // Check if it's a subradial spell first
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSION), oCreature) if (GetIsSubradialSpell(nPower))
) || {
(GetLevelByClass(CLASS_TYPE_PSYWAR, oCreature) if(DEBUG) DoDebug("GetHasPower: " + IntToString(nPower) + " is a subradial");
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSYWAR), oCreature) int nMasterSpell = GetMasterSpellFromSubradial(nPower);
) || if (nMasterSpell != -1)
(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oCreature) {
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSYCHIC_ROGUE), oCreature) if(DEBUG) DoDebug("GetHasPower: Master spell is " + IntToString(nMasterSpell));
) || nPower = nMasterSpell;
(GetLevelByClass(CLASS_TYPE_WILDER, oCreature) }
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_WILDER), oCreature) }
) ||
(GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oCreature)
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_FIST_OF_ZUOKEN), oCreature) // Check MISC list first (for Hidden Talent and similar feats)
) || if(GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_INVALID), oCreature))
(GetLevelByClass(CLASS_TYPE_WARMIND, oCreature) return TRUE;
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_WARMIND), oCreature)
) if((GetLevelByClass(CLASS_TYPE_PSION, oCreature)
// add new psionic classes here && GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSION), oCreature)
) ) ||
return TRUE; (GetLevelByClass(CLASS_TYPE_PSYWAR, oCreature)
return FALSE; && GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSYWAR), oCreature)
) ||
(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oCreature)
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSYCHIC_ROGUE), oCreature)
) ||
(GetLevelByClass(CLASS_TYPE_WILDER, oCreature)
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_WILDER), oCreature)
) ||
(GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oCreature)
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_FIST_OF_ZUOKEN), oCreature)
) ||
(GetLevelByClass(CLASS_TYPE_WARMIND, oCreature)
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_WARMIND), oCreature)
)
// add new psionic classes here
)
return TRUE;
return FALSE;
} }
string DebugListKnownPowers(object oCreature) string DebugListKnownPowers(object oCreature)

View File

@@ -558,6 +558,9 @@ void _ManifestationHB(object oManifester, location lManifester, object oMfToken)
if(DEBUG) DoDebug("_ManifestationHB(): Manifester moved or lost concentration, destroying token"); if(DEBUG) DoDebug("_ManifestationHB(): Manifester moved or lost concentration, destroying token");
_DestroyManifestationToken(oManifester, oMfToken); _DestroyManifestationToken(oManifester, oMfToken);
//:: Clean up variables
_CleanManifestationVariables(oManifester);
// Inform manifester // Inform manifester
FloatingTextStrRefOnCreature(16828435, oManifester, FALSE); // "You have lost concentration on the power you were attempting to manifest!" FloatingTextStrRefOnCreature(16828435, oManifester, FALSE); // "You have lost concentration on the power you were attempting to manifest!"
} }
@@ -810,6 +813,25 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
manif.bCanManifest = FALSE; manif.bCanManifest = FALSE;
} }
// Check defensive manifestation BEFORE PP deduction
if(GetLocalInt(oManifester, "PRC_DefensiveManifestActive"))
{
int nPowerLevel = GetPowerLevel(oManifester);
int nDC = 15 + nPowerLevel;
if(!GetPRCIsSkillSuccessful(oManifester, SKILL_CONCENTRATION, nDC))
{
// Failed - deduct PP and prevent manifestation
LosePowerPoints(oManifester, manif.nPPCost, TRUE);
PayMetapsionicsFocuses(manif);
manif.bCanManifest = FALSE;
SendMessageToPC(oManifester, "Defensive manifestation concentration check failed.");
return manif;
}
manif.bDefensive = TRUE;
}
// Psi-like abilities ignore PP costs and metapsi // Psi-like abilities ignore PP costs and metapsi
if(!bIsPsiLike) if(!bIsPsiLike)
{ {
@@ -820,6 +842,25 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
PayMetapsionicsFocuses(manif); PayMetapsionicsFocuses(manif);
} }
/* if(GetLocalInt(oManifester, "PRC_DefensiveManifestActive"))
{
// Concentration check (DC 15 + power level)
int nPowerLevel = GetPowerLevel(oManifester);
int nDC = 15 + nPowerLevel;
if(!GetPRCIsSkillSuccessful(oManifester, SKILL_CONCENTRATION, nDC))
{
// Failed - PP already deducted, but prevent manifestation
manif.bCanManifest = FALSE;
SendMessageToPC(oManifester, "Defensive manifestion concentration check failed.");
return manif;
}
// Set defensive flag for any other systems that need it
SendMessageToPC(oManifester, "Defensive manifestion concentration check successful.");
manif.bDefensive = TRUE;
} */
//* APPLY SIDE-EFFECTS THAT RESULT FROM SUCCESSFULL MANIFESTATION HERE *// //* APPLY SIDE-EFFECTS THAT RESULT FROM SUCCESSFULL MANIFESTATION HERE *//
// Psicraft for all those who can see // Psicraft for all those who can see
IdentifyPower(oManifester, manif.nSpellID); IdentifyPower(oManifester, manif.nSpellID);
@@ -1099,4 +1140,4 @@ struct manifestation EvaluateDiaDragChannel(object oManifester, object oTarget,
} }
// Test main // Test main
//void main(){} //:: void main(){}

View File

@@ -1,3 +1,6 @@
const int DEFENSIVE_MANIFESTATION = 2375;
//real power spell constants //real power spell constants
// Level 1 Powers // Level 1 Powers
@@ -173,6 +176,7 @@ const int POWER_PSYCHICREFORMATION = 14155;
const int POWER_TELEKINETICMANEUVER = 14156; const int POWER_TELEKINETICMANEUVER = 14156;
const int POWER_DIMENSIONALANCHOR = 14157; const int POWER_DIMENSIONALANCHOR = 14157;
const int POWER_DISMISSAL = 14158; const int POWER_DISMISSAL = 14158;
const int POWER_DIMENSIONDOOR = 14162;
const int POWER_DIMENSIONDOOR_SELFONLY = 14159; const int POWER_DIMENSIONDOOR_SELFONLY = 14159;
const int POWER_DIMENSIONDOOR_PARTY = 14160; const int POWER_DIMENSIONDOOR_PARTY = 14160;
const int POWER_DOMINATE = 14161; const int POWER_DOMINATE = 14161;
@@ -183,6 +187,7 @@ const int POWER_ENERGYBALL_ELEC = 14166;
const int POWER_ENERGYBALL_FIRE = 14167; const int POWER_ENERGYBALL_FIRE = 14167;
const int POWER_ENERGYBALL_SONIC = 14168; const int POWER_ENERGYBALL_SONIC = 14168;
const int POWER_PSYCHICVAMPIRE = 14169; const int POWER_PSYCHICVAMPIRE = 14169;
const int POWER_CLAW_ENERGY = 14350;
const int POWER_CLAW_ENERGY_COLD = 14170; const int POWER_CLAW_ENERGY_COLD = 14170;
const int POWER_CLAW_ENERGY_ELEC = 14171; const int POWER_CLAW_ENERGY_ELEC = 14171;
const int POWER_CLAW_ENERGY_FIRE = 14172; const int POWER_CLAW_ENERGY_FIRE = 14172;

View File

@@ -783,12 +783,16 @@ int GetFirstBladeMagicClassPosition(object oCreature = OBJECT_SELF)
int CheckManeuverPrereqs(int nClass, int nPrereqs, int nDiscipline, object oPC) int CheckManeuverPrereqs(int nClass, int nPrereqs, int nDiscipline, object oPC)
{ {
// Checking to see what the name of the feat is, and the row number // Checking to see what the name of the feat is, and the row number
/*if (DEBUG) /* if (DEBUG)
{ {
DoDebug("CheckManeuverPrereqs: nFeat: " + IntToString(nFeat)); DoDebug("CheckManeuverPrereqs: nFeat: " + IntToString(nFeat));
string sFeatName = GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))); string sFeatName = GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat)));
DoDebug("CheckManeuverPrereqs: sFeatName: " + sFeatName); DoDebug("CheckManeuverPrereqs: sFeatName: " + sFeatName);
}*/ } */
DoDebug("CheckManeuverPrereqs: nClass=" + IntToString(nClass) +
" nDiscipline=" + IntToString(nDiscipline) +
" nPrereqs=" + IntToString(nPrereqs));
// Prestige classes can only access certain disciplines // Prestige classes can only access certain disciplines
if(!_AllowedDiscipline(oPC, nClass, nDiscipline)) if(!_AllowedDiscipline(oPC, nClass, nDiscipline))

View File

@@ -327,8 +327,25 @@ int ArcaneSpellFailure(object oCaster, int nCastingClass, int nSpellLevel, int n
default: break; default: break;
} }
} }
// Hexblade can cast in light/medium armour and while using small shield.
else if(nCastingClass == CLASS_TYPE_HEXBLADE) // Hexblade can cast in light armour only.
else if(nCastingClass == CLASS_TYPE_HEXBLADE)
{
//armors
switch(nAC)
{
case 1: nASF -= 5; break; //light
case 2: nASF -= 10; break; //light
case 3: nASF -= 20; break; //light
case 4: nASF = bBattleCaster ? 0 : nASF; break; //medium with Battlecaster
case 5: nASF = bBattleCaster ? 0 : nASF; break; //medium with Battlecaster
default: break;
}
}
// WRONG: Hexblade can cast in light/medium armour and while using small shield.
//:: RIGHT: Hexblades are proficient with all simple and martial weapons, and with light armor but not with shields.
/* else if(nCastingClass == CLASS_TYPE_HEXBLADE)
{ {
//shields //shields
if(GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD) nASF -= 5; if(GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD) nASF -= 5;
@@ -345,7 +362,7 @@ int ArcaneSpellFailure(object oCaster, int nCastingClass, int nSpellLevel, int n
case 8: nASF -= bBattleCaster ? 45 : 0; break; case 8: nASF -= bBattleCaster ? 45 : 0; break;
default: break; default: break;
} }
} } */
// Bards cannot cast in light armour and while using small shield in 3e // Bards cannot cast in light armour and while using small shield in 3e
/* else if(nCastingClass == CLASS_TYPE_BARD) /* else if(nCastingClass == CLASS_TYPE_BARD)
{ {
@@ -2161,10 +2178,35 @@ int PRCSpellEffects(object oCaster, object oTarget, int nSpellID, int nSpellLeve
{ {
// Pnp Tensers Transformation // Pnp Tensers Transformation
if(GetPRCSwitch(PRC_PNP_TENSERS_TRANSFORMATION)) if(GetPRCSwitch(PRC_PNP_TENSERS_TRANSFORMATION))
{ {
if(GetHasSpellEffect(SPELL_TENSERS_TRANSFORMATION, oCaster))
{
// Allow potions - they are not spell trigger/completion items
object oSpellCastItem = PRCGetSpellCastItem();
if(GetIsObjectValid(oSpellCastItem))
{
int nItemType = GetBaseItemType(oSpellCastItem);
if(nItemType == BASE_ITEM_ENCHANTED_POTION
|| nItemType == BASE_ITEM_POTIONS)
{
// Continue with other checks
}
else
{
return FALSE; // Block other magic items
}
}
else
{
return FALSE; // Block regular spellcasting
}
}
}
/* {
if(GetHasSpellEffect(SPELL_TENSERS_TRANSFORMATION, oCaster)) if(GetHasSpellEffect(SPELL_TENSERS_TRANSFORMATION, oCaster))
return FALSE; return FALSE;
} } */
// Gaseous Form check // Gaseous Form check
if(GetHasSpellEffect(SPELL_GASEOUS_FORM, oCaster)) if(GetHasSpellEffect(SPELL_GASEOUS_FORM, oCaster))
@@ -3757,4 +3799,4 @@ int X2PreSpellCastCode2()
// Test main // Test main
//::void main(){} //:: void main(){}

View File

@@ -2545,6 +2545,13 @@
"value": "peps_prc8" "value": "peps_prc8"
} }
}, },
{
"__struct_id": 8,
"Mod_Hak": {
"type": "cexostring",
"value": "prcx_shims"
}
},
{ {
"__struct_id": 8, "__struct_id": 8,
"Mod_Hak": { "Mod_Hak": {
@@ -3050,6 +3057,21 @@
"type": "int", "type": "int",
"value": 1 "value": 1
} }
},
{
"__struct_id": 0,
"Name": {
"type": "cexostring",
"value": "PRC_PRCX_ENABLED"
},
"Type": {
"type": "dword",
"value": 1
},
"Value": {
"type": "int",
"value": 1
}
} }
] ]
} }

View File

@@ -1,113 +0,0 @@
//::///////////////////////////////////////////////
//:: NUI Constants
//:: prc_nui_consts
//:://////////////////////////////////////////////
/*
This file holds all the constants used by the various PRC NUI scripts.
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 24.05.2005
//:://////////////////////////////////////////////
const int NUI_PAYLOAD_BUTTON_LEFT_CLICK = 0;
const int NUI_PAYLOAD_BUTTON_MIDDLE_CLICK = 1;
const int NUI_PAYLOAD_BUTTON_RIGHT_CLICK = 2;
//////////////////////////////////////////////////
// //
// NUI Spellbook //
// //
//////////////////////////////////////////////////
// This is the NUI Spellbook window ID
const string PRC_SPELLBOOK_NUI_WINDOW_ID = "prcSpellbookNui";
// This is the base Id for the Class buttons in the NUI Spellbook, the ID will
// have the ClassID attached to it (i.e. spellbookClassButton_123)
const string PRC_SPELLBOOK_NUI_CLASS_BUTTON_BASEID = "spellbookClassButton_";
// This is the base Id for the Spell Circle buttons in the NUI Spellbook, the ID will
// have the Circle attached to it (i.e. spellbookCircleButton__6)
const string PRC_SPELLBOOK_NUI_CIRCLE_BUTTON_BASEID = "spellbookCircleButton_";
// This is the base Id for the Spell Buttons in the NUI Spellbook, the ID will
// have the SpellbookId (the row of the class's spell's 2da or equivalent)
// attached to it (i.e. spellbookSpellButton_6)
const string PRC_SPELLBOOK_NUI_SPELL_BUTTON_BASEID = "spellbookSpellButton_";
// This is the base Id for the Meta Feat buttons in the NUI Spellbook, the ID will
// have the FeatID attached to it (i.e. spellbookMetaButton_12345)
const string PRC_SPELLBOOK_NUI_META_BUTTON_BASEID = "spellbookMetaButton_";
// This is the selected ClassID var used to store what class was selected to the Player
// locally
const string PRC_SPELLBOOK_SELECTED_CLASSID_VAR = "prcSpellbookSelectedClassID";
// This is the selected Circle var used to store what spell circle was selected
// to the Player locally
const string PRC_SPELLBOOK_SELECTED_CIRCLE_VAR = "prcSpellbookSelectedCircle";
// This is the Spellbook NUI geomeotry var, used to allow the location and sizing
// of the NUI to be remembered if it is ever rerendered.
const string PRC_SPELLBOOK_NUI_GEOMETRY_VAR = "sbNuiGeometry";
// This is the Selected SpellID Var, used to tell the OnTarget script what spell
// we are using after manual targetting
const string NUI_SPELLBOOK_SELECTED_SPELLID_VAR = "NUI_Spellbook_SpellId";
// This is the Selected FeatID Var, used to tell the OnTarget script what feat
// we are using after manual targetting
const string NUI_SPELLBOOK_SELECTED_FEATID_VAR = "NUI_Spellbook_FeatID";
// This is the Selected SubSpellID Var, used in conjuncture with the Selected FeatID
// to allow radial spells to work (it needs the master spell's featID and the sub spell's
// SpellID for it to work.
const string NUI_SPELLBOOK_SELECTED_SUBSPELL_SPELLID_VAR = "NUI_Spellbook_SubSpellID";
// This is the OnTarget action var saved to the player locally to say if we are
// using the NUI Spellbook spell or not.
const string NUI_SPELLBOOK_ON_TARGET_ACTION_VAR = "ONPLAYERTARGET_ACTION";
// This is a Boolean to tell the target script if the selected feat is a persoanl feat
// and can only be used on the executing object.
const string NUI_SPELLBOOK_ON_TARGET_IS_PERSONAL_FEAT = "NUI_Spellbook_IsPersonalFeat";
const string NUI_SPELL_DESCRIPTION_WINDOW_ID = "NUI_Spell_Description";
const string NUI_SPELL_DESCRIPTION_OK_BUTTON = "NUIDescriptionOKButton";
// This is the limit of how many spell buttons we can have in a row before we
// need to start a new row on the NUI Spellbook.
const int NUI_SPELLBOOK_SPELL_BUTTON_LENGTH = 9;
const string NUI_SPELLBOOK_BINDER_DICTIONARY_CACHE_VAR = "NUI_Spellbook_GetBinderSpellToFeatDictionaryCache";
const string NUI_SPELLBOOK_CLASS_STANCES_CACHE_BASE_VAR = "NUI_Spellbook_GetToBStanceSpellListCache_";
const string NUI_SPELLBOOK_CLASS_SHAPES_CACHE_BASE_VAR = "NUI_Spellbook_GetInvokerShapeSpellListCache_";
const string NUI_SPELLBOOK_CLASS_ESSENCE_CACHE_BASE_VAR = "NUISpellbookClassEssence_";
//////////////////////////////////////////////////
// //
// NUI Power Attack //
// //
//////////////////////////////////////////////////
// The Window ID for the Power Attack NUI
const string NUI_PRC_POWER_ATTACK_WINDOW = "nui_prc_power_attack_window";
// LocalVar for the geometry of the Power Attack NUI window
const string NUI_PRC_PA_GEOMETRY_VAR = "paNuiGeometry";
// Event For Left "-" button of the Power Attack NUI
const string NUI_PRC_PA_LEFT_BUTTON_EVENT = "nui_prc_pa_left_button_event";
// Event For Right "+" Button of the Power Attack NUI
const string NUI_PRC_PA_RIGHT_BUTTON_EVENT = "nui_prc_pa_right_button_event";
// Bind for Text of the Power Attack NUI saying what the current Power Attack level is
const string NUI_PRC_PA_TEXT_BIND = "nui_prc_pa_text_bind";
// Left Button Enabled Bind for Power Attack NUI
const string NUI_PRC_PA_LEFT_BUTTON_ENABLED_BIND = "leftButtonEnabled";
// Right Button Enabled Bind for Power Attack NUI
const string NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND = "rightButtonEnabled";

File diff suppressed because it is too large Load Diff

View File

@@ -1,98 +0,0 @@
//::///////////////////////////////////////////////
//:: PRC Spellbook Description NUI
//:: prc_nui_sbd_inc
//:://////////////////////////////////////////////
/*
This is the view for the Spell Description NUI
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 29.05.2005
//:://////////////////////////////////////////////
#include "nw_inc_nui"
#include "prc_nui_consts"
#include "inc_2dacache"
//
// CreateSpellDescriptionNUI
// Creates a Spell Description NUI mimicing the description GUI of NWN
//
// Arguments:
// oPlayer:Object the player object
// featID:int the FeatID
// spellId:int the SpellID
// realSpellId:int the RealSpellID
//
void CreateSpellDescriptionNUI(object oPlayer, int featID, int spellId=0, int realSpellId=0);
void CreateSpellDescriptionNUI(object oPlayer, int featID, int spellId=0, int realSpellId=0)
{
// look for existing window and destroy
int nPreviousToken = NuiFindWindow(OBJECT_SELF, NUI_SPELL_DESCRIPTION_WINDOW_ID);
if(nPreviousToken != 0)
{
NuiDestroy(OBJECT_SELF, nPreviousToken);
}
// in order of accuracy for names it goes RealSpellID > SpellID > FeatID
string spellName;
if (realSpellId)
spellName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", realSpellId)));
else if (spellId)
spellName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellId)));
else
spellName = GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", featID)));
// Descriptions and Icons are accuratly stored on the feat
string spellDesc = GetStringByStrRef(StringToInt(Get2DACache("feat", "DESCRIPTION", featID)));
string spellIcon = Get2DACache("feat", "ICON", featID);
json jRoot = JsonArray();
json jGroup = JsonArray();
json jRow = JsonArray();
json jImage = NuiImage(JsonString(spellIcon), JsonInt(NUI_ASPECT_EXACT), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_TOP));
jImage = NuiWidth(jImage, 32.0f);
jRow = JsonArrayInsert(jRow, jImage);
jRow = NuiCol(jRow);
jGroup = JsonArrayInsert(jGroup, jRow);
jRow = JsonArray();
json jText = NuiText(JsonString(spellDesc), FALSE, NUI_SCROLLBARS_AUTO);
jRow = JsonArrayInsert(jRow, jText);
jRow = NuiCol(jRow);
jGroup = JsonArrayInsert(jGroup, jRow);
jGroup = NuiRow(jGroup);
jGroup = NuiGroup(jGroup, TRUE, NUI_SCROLLBARS_NONE);
jRoot = JsonArrayInsert(jRoot, jGroup);
jRow = JsonArray();
jRow = JsonArrayInsert(jRow, NuiSpacer());
json jButton = NuiId(NuiButton(JsonString("OK")), NUI_SPELL_DESCRIPTION_OK_BUTTON);
jButton = NuiWidth(jButton, 175.0f);
jButton = NuiHeight(jButton, 48.0f);
jRow = JsonArrayInsert(jRow, jButton);
jRow = NuiRow(jRow);
jRoot = JsonArrayInsert(jRoot, jRow);
jRoot = NuiCol(jRoot);
// This is the main window with jRoot as the main pane. It includes titles and parameters (more on those later)
json nui = NuiWindow(jRoot, JsonString(spellName), NuiBind("geometry"), NuiBind("resizable"), JsonBool(FALSE), NuiBind("closable"), NuiBind("transparent"), NuiBind("border"));
// finally create it and it'll return us a non-zero token.
int nToken = NuiCreate(oPlayer, nui, NUI_SPELL_DESCRIPTION_WINDOW_ID);
// get the geometry of the window in case we opened this before and have a
// preference for location
json geometry = NuiRect(893.0f,346.0f, 426.0f, 446.0f);
// Set the binds to their default values
NuiSetBind(oPlayer, nToken, "geometry", geometry);
NuiSetBind(oPlayer, nToken, "resizable", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "closable", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "transparent", JsonBool(FALSE));
NuiSetBind(oPlayer, nToken, "border", JsonBool(TRUE));
}