forked from Jaysyn/PRC8
Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
135 lines
5.8 KiB
Plaintext
135 lines
5.8 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: Dragonfire Strike
|
|
//:: prc_dragfire_atk.nss
|
|
//::///////////////////////////////////////////////
|
|
/*
|
|
Handles converting the damage on Dragonfire Strike
|
|
and similar feats
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By: Fox
|
|
//:: Created On: Nov 23, 2007
|
|
//:://////////////////////////////////////////////
|
|
|
|
#include "prc_inc_combat"
|
|
#include "prc_inc_sneak"
|
|
|
|
void DoDragonfireSneak(object oPC, object oTarget, object oWeapon)
|
|
{
|
|
if(DEBUG) DoDebug("Performing Strike");
|
|
effect eStrike;
|
|
int nType = GetDragonfireDamageType(oPC);
|
|
int nDice = GetTotalSneakAttackDice(oPC);
|
|
int nSneakDamage = GetSneakAttackDamage(nDice);
|
|
int nDamage = nSneakDamage;
|
|
|
|
struct DamageReducers drTotalReduced= GetTotalReduction(oPC, oTarget, oWeapon);
|
|
nDamage = nDamage * (100 - drTotalReduced.nPercentReductions) / 100;
|
|
nDamage -= drTotalReduced.nStaticReductions;
|
|
if(nDamage < 0 ) nDamage = 0;
|
|
effect eHealed = EffectHeal(nDamage);
|
|
|
|
if(GetHasFeat(FEAT_DRAGONFIRE_STRIKE, oPC) && GetLocalInt(oPC, "DragonFireOn"))
|
|
nSneakDamage += d6();
|
|
if(GetHasFeat(FEAT_IMP_DRAGONFIRE_STRIKE, oPC) && GetLocalInt(oPC, "DragonFireOn"))
|
|
nSneakDamage += nDice;
|
|
|
|
effect eSneakDamage = EffectDamage(nSneakDamage, nType);
|
|
if(!GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT))
|
|
eStrike = EffectLinkEffects(eSneakDamage, eHealed);
|
|
else
|
|
eStrike = eSneakDamage;
|
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eStrike, oTarget);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
int nEvent = GetRunningEvent();
|
|
if(DEBUG) DoDebug("prc_dragfire_atk running, event: " + IntToString(nEvent));
|
|
|
|
// Get the PC. This is event-dependent
|
|
object oPC;
|
|
switch(nEvent)
|
|
{
|
|
case EVENT_ONPLAYEREQUIPITEM: oPC = GetItemLastEquippedBy(); break;
|
|
case EVENT_ONPLAYERUNEQUIPITEM: oPC = GetItemLastUnequippedBy(); break;
|
|
|
|
default:
|
|
oPC = OBJECT_SELF;
|
|
}
|
|
|
|
object oItem;
|
|
object oAmmo;
|
|
|
|
if(nEvent == EVENT_ONPLAYEREQUIPITEM)
|
|
{
|
|
oItem = GetItemLastEquipped();
|
|
if(DEBUG) DoDebug("prc_dragfire_atk - OnEquip");
|
|
|
|
// Only applies to weapons - Note: IPGetIsMeleeWeapon is bugged and returns true on items it should not
|
|
if(oItem == GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)
|
|
|| (oItem == GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC) && !GetIsShield(oItem))
|
|
|| GetWeaponRanged(oItem))
|
|
{
|
|
// Add eventhook to the item
|
|
AddEventScript(oItem, EVENT_ITEM_ONHIT, "prc_dragfire_atk", TRUE, FALSE);
|
|
|
|
// Add the OnHitCastSpell: Unique needed to trigger the event
|
|
// Makes sure to get ammo if its a ranged weapon
|
|
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
|
|
oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oPC);
|
|
IPSafeAddItemProperty(oAmmo, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
|
|
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oPC);
|
|
IPSafeAddItemProperty(oAmmo, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
|
|
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oPC);
|
|
IPSafeAddItemProperty(oAmmo, 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)
|
|
{
|
|
oItem = GetItemLastUnequipped();
|
|
if(DEBUG) DoDebug("prc_dragfire_atk - OnUnEquip");
|
|
|
|
// Only applies to weapons - Note: if statement still returns true for armor/shield? o.O
|
|
if(IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem))
|
|
{
|
|
// Add eventhook to the item
|
|
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "prc_dragfire_atk", TRUE, FALSE);
|
|
|
|
// Remove the temporary OnHitCastSpell: Unique
|
|
// Makes sure to get ammo if its a ranged weapon
|
|
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
|
|
oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oPC);
|
|
RemoveSpecificProperty(oAmmo, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
|
|
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oPC);
|
|
RemoveSpecificProperty(oAmmo, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
|
|
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oPC);
|
|
RemoveSpecificProperty(oAmmo, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
}
|
|
}
|
|
else if(nEvent == EVENT_ITEM_ONHIT)
|
|
{
|
|
//get the thing hit
|
|
object oTarget = PRCGetSpellTargetObject();
|
|
oItem = GetSpellCastItem();
|
|
|
|
if(!(IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem))) //Note: if statement still returns false for armor/shield? o.O
|
|
return;
|
|
|
|
if(DEBUG) DoDebug("Weapon Used: " + GetName(oItem));
|
|
if(DEBUG) DoDebug("CanSneakAttack: " + IntToString(GetCanSneakAttack(oTarget, oPC)));
|
|
if(DEBUG) DoDebug("Dice: " + IntToString(GetTotalSneakAttackDice(oPC)));
|
|
//check to see if both Sneak Attack and DFS apply, and if so, strike
|
|
if(GetCanSneakAttack(oTarget, oPC)
|
|
&& GetTotalSneakAttackDice(oPC)
|
|
&& GetLocalInt(oPC, "DragonFireOn"))
|
|
DoDragonfireSneak(oPC, oTarget, oItem);
|
|
}
|
|
} |