2026/02/09 Update
Added and activated PRCX. Updated PRC8 includes.
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user