Updated Vow of Poverty. Added Sanctify Ki Strike, Holy Strike, Fist of Heavens, Vow of Abstinence, Vow of Chastity & Gift of Faith. (@fenac). Turned off the Taunt & Parry skills. Re-disabled AC & save bonuses from Tumble & Spellcraft. Updated min() & max() to PRCmin() & PRCmax() to not conflict with similarly named NUI adjacent functions. Set Point Blank Shot to 30' per PnP. Added icon for Chosen of Evil. Started work on Hidden Talent. Created Psionics function cheatsheet. Updated release archive.
177 lines
8.1 KiB
Plaintext
177 lines
8.1 KiB
Plaintext
//::///////////////////////////////////////////////
|
||
//:: Two-Weapon Rend
|
||
//:: prc_tw_rend
|
||
//:://////////////////////////////////////////////
|
||
/** @file
|
||
TWO-WEAPON REND [EPIC]
|
||
Prerequisites: Dex 15, base attack bonus +9,
|
||
Improved Two-Weapon Fighting, Two-Weapon Fighting.
|
||
|
||
Benefit: If the character hits an opponent with a
|
||
weapon in each hand in the same round, he or she
|
||
may automatically rend the opponent. This deals
|
||
additional damage equal to the base damage of the
|
||
smaller weapon (if both weapons are of same size,
|
||
the weapon in main hand is used) plus 1 1/2 times
|
||
the character’s Strength modifier. Base weapon
|
||
damage includes an enhancement bonus on damage,
|
||
if any.
|
||
The character can only rend once per round,
|
||
regardless of how many successful attacks he or
|
||
she makes.
|
||
|
||
@author Ornedan
|
||
@date Created - 2006.07.05
|
||
*/
|
||
//:://////////////////////////////////////////////
|
||
//:://////////////////////////////////////////////
|
||
|
||
#include "prc_alterations"
|
||
|
||
const string REND_FIRST_MAINHAND_HIT_PREFIX = "PRC_TWRend_MainHandHitBy_";
|
||
const string REND_FIRST_OFFHAND_HIT_PREFIX = "PRC_TWRend_OffHandHitBy_";
|
||
const string REND_LOCK = "PRC_TWRend_Used";
|
||
|
||
void main()
|
||
{
|
||
object oPC, oItem;
|
||
int nEvent = GetRunningEvent();
|
||
|
||
if(DEBUG) DoDebug("prc_tw_rend running, event: " + IntToString(nEvent));
|
||
|
||
// We're being called from the OnHit eventhook, so deal the damage
|
||
if(nEvent == EVENT_ITEM_ONHIT)
|
||
{
|
||
oPC = OBJECT_SELF;
|
||
oItem = GetSpellCastItem();
|
||
object oTarget = PRCGetSpellTargetObject();
|
||
if(DEBUG) DoDebug("prc_tw_rend: OnHit:\n"
|
||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||
+ "oItem = " + DebugObject2Str(oItem) + "\n"
|
||
+ "oTarget = " + DebugObject2Str(oTarget) + "\n"
|
||
);
|
||
|
||
// Only run if called by a melee weapon and rend hasn't already been used for this round
|
||
if(IPGetIsMeleeWeapon(oItem) && !GetLocalInt(oPC, REND_LOCK))
|
||
{
|
||
string sPCOID = ObjectToString(oPC);
|
||
|
||
// Determine if the weapon is the mainhand one or the offhand one
|
||
int bIsMainHand = oItem == GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||
|
||
// Determine if the other hand has hit
|
||
int bBothHandsHit;
|
||
if(bIsMainHand)
|
||
bBothHandsHit = GetLocalInt(oTarget, REND_FIRST_OFFHAND_HIT_PREFIX + sPCOID);
|
||
else
|
||
bBothHandsHit = GetLocalInt(oTarget, REND_FIRST_MAINHAND_HIT_PREFIX + sPCOID);
|
||
|
||
if(DEBUG) DoDebug("prc_tw_rend: OnHit: bBothHandsHit = " + DebugBool2String(bBothHandsHit));
|
||
|
||
// If both hands did hit, run the rending code
|
||
if(bBothHandsHit)
|
||
{
|
||
// Get the equipped weapons
|
||
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
|
||
|
||
// Make sure both are valid before continuing. If the PC is changing their loadout mid-battle,
|
||
// they are not going to be able to rend things at the same time.
|
||
if(!GetIsObjectValid(oRightHand) || !GetIsObjectValid(oLeftHand))
|
||
{
|
||
if(DEBUG) DoDebug("prc_tw_rend: OnHit: One of the weapons was not present:\n"
|
||
+ "oRightHand = " + DebugObject2Str(oRightHand) + "\n"
|
||
+ "oLeftHand = " + DebugObject2Str(oLeftHand) + "\n"
|
||
);
|
||
return;
|
||
}
|
||
|
||
// Determine which is smaller, preferring the right hand in case of equal size
|
||
int nRightSize = StringToInt(Get2DACache("baseitems", "WeaponSize", GetBaseItemType(oRightHand)));
|
||
int nLeftSize = StringToInt(Get2DACache("baseitems", "WeaponSize", GetBaseItemType(oLeftHand)));
|
||
object oSmaller = nRightSize >= nLeftSize ? oRightHand : oLeftHand;
|
||
int nSmaller = GetBaseItemType(oSmaller);
|
||
|
||
// Determine dice to roll
|
||
int nDieSize = StringToInt(Get2DACache("baseitems", "DieToRoll", nSmaller));
|
||
int nNumDice = StringToInt(Get2DACache("baseitems", "NumDice", nSmaller));
|
||
|
||
// Determine damage bonus from enhancement
|
||
int nBonus = 0;
|
||
itemproperty ipTest = GetFirstItemProperty(oSmaller);
|
||
while(GetIsItemPropertyValid(ipTest))
|
||
{
|
||
// Get the highest enhancement bonus property on the item
|
||
if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_ENHANCEMENT_BONUS)
|
||
nBonus = PRCMax(nBonus, GetItemPropertyCostTableValue(ipTest));
|
||
|
||
ipTest = GetNextItemProperty(oSmaller);
|
||
}
|
||
|
||
// Add STR modifier to damage bonus
|
||
nBonus += FloatToInt(1.5f * GetAbilityModifier(ABILITY_STRENGTH, oPC));
|
||
|
||
// Start with bonus and add damage rolls
|
||
int nDamage = nBonus;
|
||
for(; nNumDice > 0; nNumDice--)
|
||
nDamage += Random(nDieSize) + 1;
|
||
|
||
// Apply effects. Damage type is slashing, since it seems most appropriate
|
||
effect eLink = EffectDamage(nDamage, DAMAGE_TYPE_SLASHING);
|
||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_COM_BLOOD_CRT_RED));
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget);
|
||
|
||
// Do some feedback
|
||
// * PCName rends TargetName *
|
||
FloatingTextStringOnCreature("* " + GetName(oPC) + " " + GetStringByStrRef(0x01000000 + 51197) + " " + GetName(oTarget) + " *",
|
||
oPC,
|
||
TRUE);
|
||
|
||
// Set the feat used for this round, queue lock variable deletion
|
||
SetLocalInt(oPC, REND_LOCK, TRUE);
|
||
DelayCommand(6.0f, DeleteLocalInt(oPC, REND_LOCK));
|
||
}
|
||
else
|
||
{
|
||
// Just a single hit in so far, set marker local and queue it's deletion
|
||
string sVar = (bIsMainHand ? REND_FIRST_MAINHAND_HIT_PREFIX : REND_FIRST_OFFHAND_HIT_PREFIX) + sPCOID;
|
||
SetLocalInt(oTarget, sVar, TRUE);
|
||
DelayCommand(6.0f, DeleteLocalInt(oTarget, sVar));
|
||
}
|
||
}// end if - Item is a melee weapon and Two-Weapon Rend hasn't already been used up for the round
|
||
}// end if - Running OnHit event
|
||
// We are called from the OnPlayerEquipItem eventhook. Add OnHitCast: Unique Power to oPC's weapon
|
||
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
|
||
{
|
||
oPC = GetItemLastEquippedBy();
|
||
oItem = GetItemLastEquipped();
|
||
if(DEBUG) DoDebug("prc_tw_rend - OnEquip");
|
||
|
||
// Only applies to melee weapons
|
||
if(IPGetIsMeleeWeapon(oItem))
|
||
{
|
||
// Add eventhook to the item
|
||
AddEventScript(oItem, EVENT_ITEM_ONHIT, "prc_tw_rend", TRUE, FALSE);
|
||
|
||
// Add the OnHitCastSpell: Unique needed to trigger the event
|
||
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||
}
|
||
}
|
||
// We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oPC's weapon
|
||
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
|
||
{
|
||
oPC = GetItemLastUnequippedBy();
|
||
oItem = GetItemLastUnequipped();
|
||
if(DEBUG) DoDebug("prc_tw_rend - OnUnEquip");
|
||
|
||
// Only applies to melee weapons
|
||
if(IPGetIsMeleeWeapon(oItem))
|
||
{
|
||
// Add eventhook to the item
|
||
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "prc_tw_rend", TRUE, FALSE);
|
||
|
||
// Remove the temporary OnHitCastSpell: Unique
|
||
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", 1, DURATION_TYPE_TEMPORARY);
|
||
}
|
||
}
|
||
} |