2026/02/09 Update

Added and activated PRCX.
Updated PRC8 includes.
This commit is contained in:
Jaysyn904
2026-02-09 08:18:11 -05:00
parent fde89f634f
commit 157382e60d
48 changed files with 1684 additions and 1834 deletions

View File

@@ -355,6 +355,16 @@ int _DoGrappleCheck(object oPC, object oTarget, int nExtraBonus, int nSwitch = -
int nPCCheck = nPCBAB + nPCStr + nPCBonus + 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
SendMessageToPC(oPC, "PC Grapple Check: "+IntToString(nPCCheck)+" vs "+IntToString(nTargetCheck));
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);
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);
SetLocalInt(oPC, "GrappleOriginator", TRUE);
effect eHold = EffectCutsceneParalyze();
@@ -1526,23 +1575,43 @@ int DoGrapple(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TR
effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, 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 (GetIsDead(oTarget) || !GetIsObjectValid(oTarget))
{
EndGrapple(oPC, oTarget);
// 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);
FloatingTextStringOnCreature("Your target is dead, ending grapple", oPC, FALSE);
}
else
{
// Hook in the events and save the target for an ongoing grapple
if(DEBUG) DoDebug("prc_grapple: Adding eventhooks");
SetGrappleTarget(oPC, oTarget);
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);
// 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
@@ -1555,12 +1624,16 @@ int DoGrapple(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TR
void SetGrapple(object oTarget)
{
SetLocalInt(oTarget, "IsGrappled", TRUE);
if(DEBUG) DoDebug("SetGrapple called on " + GetName(oTarget));
SetLocalInt(oTarget, "IsGrappled", TRUE);
}
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)
@@ -1591,16 +1664,20 @@ void BreakPin(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(oPC, "GrappleHeartbeatTimer");
DeleteLocalInt(oTarget, "PinnedRounds");
DeleteLocalObject(oPC, "GrappleTarget");
DeleteLocalObject(oTarget, "GrappledBy");
DeleteLocalInt(oTarget, "UnconsciousGrapple");
DeleteLocalInt(oPC, "GrappleOriginator");
DeleteLocalInt(oPC, "ScorpionLight");
DeleteLocalInt(oPC, "Flay_Grapple");
RemoveEventScript(oPC, EVENT_ITEM_ONHIT, "wol_m_flay", TRUE, FALSE);
BreakPin(oTarget);
BreakPin(oTarget);
effect eBad = GetFirstEffect(oTarget);
//Search for negative effects
while(GetIsEffectValid(eBad))
@@ -1679,6 +1756,20 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
int nPen = -4;
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"));
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
@@ -1730,6 +1821,7 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
// Now hit them with an unarmed strike
object oWeap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
effect eDam = GetAttackDamage(oTarget, oPC, oWeap, GetWeaponBonusDamage(oWeap, oTarget), GetMagicalBonusDamage(oPC, oTarget));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
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);
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)
{
@@ -1765,14 +1872,24 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
{
// Remove the hooks
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);
}
else
{
// Remove the hooks
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);
// Target is valid and we know it's an enemy and we're in combat
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_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
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;
}
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)
{
// You may use any weapon in a grapple with this stance.