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.
230 lines
8.8 KiB
Plaintext
230 lines
8.8 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: Power Attack script
|
|
//:: ft_poweratk
|
|
//::///////////////////////////////////////////////
|
|
/*
|
|
This script handles the PRC power attack feats.
|
|
|
|
<Ornedan> For PA, I was thinking 3 radials
|
|
<Ornedan> One for the presets
|
|
<Ornedan> One for +0, +1, +2, +3, +4
|
|
<Ornedan> One for +0, +5, +10, +15, +20
|
|
<Ornedan> And a bunch of switches to control it:
|
|
<Ornedan> PRC_POWER_ATTACK - 3 values:
|
|
<Ornedan> -1 -- Disabled. Never apply the PRC PA feats to hide
|
|
<Ornedan> 0 -- Default. As it is now, you can't go higher than the equivalent BW feat you have
|
|
<Ornedan> 1 -- Full PnP. Ignores the BW IPA
|
|
<Ornedan> PRC_POWER_ATTACK_STACK_WITH_BW
|
|
<Ornedan> 0 - Default. Allow people to use both at the same time
|
|
<Ornedan> 1 - Add the BW effects in when limiting to BAB
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:://////////////////////////////////////////////
|
|
|
|
#include "prc_inc_combat"
|
|
#include "inc_addragebonus"
|
|
//#include "prc_inc_sneak" //for Dragonfire damage type resolving
|
|
|
|
/*
|
|
const int SINGLE_START = 2171;
|
|
const int SINGLE_LAST = 2175;
|
|
const int FIVES_START = 2177;
|
|
const int FIVES_LAST = 2181;
|
|
*/
|
|
|
|
// Converts the given amount of bonus damage to equivalent DAMAGE_BONUS constant
|
|
// Due to the bonus cap, bonuses are cropped to +20
|
|
int BonusAtk(int nDmg)
|
|
{
|
|
switch (nDmg)
|
|
{
|
|
case 1: return DAMAGE_BONUS_1;
|
|
case 2: return DAMAGE_BONUS_2;
|
|
case 3: return DAMAGE_BONUS_3;
|
|
case 4: return DAMAGE_BONUS_4;
|
|
case 5: return DAMAGE_BONUS_5;
|
|
case 6: return DAMAGE_BONUS_6;
|
|
case 7: return DAMAGE_BONUS_7;
|
|
case 8: return DAMAGE_BONUS_8;
|
|
case 9: return DAMAGE_BONUS_9;
|
|
case 10: return DAMAGE_BONUS_10;
|
|
case 11: return DAMAGE_BONUS_11;
|
|
case 12: return DAMAGE_BONUS_12;
|
|
case 13: return DAMAGE_BONUS_13;
|
|
case 14: return DAMAGE_BONUS_14;
|
|
case 15: return DAMAGE_BONUS_15;
|
|
case 16: return DAMAGE_BONUS_16;
|
|
case 17: return DAMAGE_BONUS_17;
|
|
case 18: return DAMAGE_BONUS_18;
|
|
case 19: return DAMAGE_BONUS_19;
|
|
case 20: return DAMAGE_BONUS_20;
|
|
}
|
|
if(nDmg > 20) return DAMAGE_BONUS_20;
|
|
|
|
return -1; // Invalid value received
|
|
}
|
|
|
|
/*
|
|
int CalculatePower(object oUser)
|
|
{
|
|
int nPower = GetLocalInt(oUser, "PRC_PowerAttack_Level");
|
|
int nSID = GetSpellID();
|
|
|
|
// Changing the value of +0,+1,+2,+3,+4 radial
|
|
if(nSID >= SINGLE_START && <= SINGLE_LAST)
|
|
{
|
|
// Extract the old fives value
|
|
nPower = (nPower / 5) * 5;
|
|
// Add in the new single value
|
|
nPower += nSID - SINGLE_START;
|
|
}
|
|
// Changing the value of +0,+5,+10,+15,+20 radial
|
|
else if(nSID >= FIVES_START && <= FIVES_LAST)
|
|
{
|
|
// Extract the old single value
|
|
nPower = nPower % 5;
|
|
// Add in the new fives value
|
|
nPower += (nSID - FIVES_START) * 5;
|
|
}
|
|
// Unknown SpellId
|
|
else
|
|
{
|
|
WriteTimestampedLogEntry("ft_poweratk called with unknown SpellID: " + IntToString(nSID));
|
|
nPower = 0;
|
|
}
|
|
|
|
// Cache the new PA level
|
|
SetLocalInt(oUser, "PRC_PowerAttack_Level", nPower);
|
|
|
|
return nPower;
|
|
}
|
|
*/
|
|
void main()
|
|
{
|
|
object oUser = OBJECT_SELF;
|
|
int nPower = GetLocalInt(oUser, "PRC_PowerAttack_Level");
|
|
|
|
// The PRC Power Attack must be active for this to do anything
|
|
if(GetPRCSwitch(PRC_POWER_ATTACK) == PRC_POWER_ATTACK_DISABLED)
|
|
return;
|
|
|
|
// Get the old Power Attack, if any
|
|
int nOld = GetLocalInt(oUser, "PRC_PowerAttackSpellID");
|
|
|
|
// Remove effects from it
|
|
if(nOld)
|
|
{
|
|
PRCRemoveSpellEffects(nOld, oUser, oUser);
|
|
DeleteLocalInt(oUser, "PRC_PowerAttackSpellID");
|
|
DeleteLocalInt(oUser, "PRC_PowerAttack_DamageBonus");
|
|
}
|
|
|
|
// Activate Power Attack if the new value is non-zero
|
|
if(nPower)
|
|
{
|
|
// Requires the appropriate BW PA feat.
|
|
if(!GetHasFeat(FEAT_POWER_ATTACK))
|
|
{
|
|
FloatingTextStrRefOnCreature(16823148, oUser, FALSE); //Prereq: Power Attack feat
|
|
return;
|
|
}
|
|
if(nPower > 5 && // If the power attack is in BW IPA range
|
|
!GetHasFeat(FEAT_IMPROVED_POWER_ATTACK) && // And they don't have IPA
|
|
GetPRCSwitch(PRC_POWER_ATTACK) != PRC_POWER_ATTACK_FULL_PNP) // And full PnP PA, which ignores BW IPA isn't active
|
|
{
|
|
FloatingTextStrRefOnCreature(16823149, oUser, FALSE); // Prereq: Improved Power Attack feat
|
|
return;
|
|
}
|
|
|
|
// This script is for the melee weapon PA. If Power Shot is implemented using the same script
|
|
// at some future date, change this.
|
|
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oUser);
|
|
int nBase = GetBaseItemType(oWeapon);
|
|
int nThrow = FALSE;
|
|
if (GetIsThrowingWeaponType(nBase) && GetHasFeat(FEAT_POWER_THROW, oUser)) nThrow = TRUE; // Power throw allows power attacking with throwing weapons
|
|
if(GetWeaponRanged(oWeapon) && !nThrow)
|
|
{
|
|
FloatingTextStrRefOnCreature(16823150, oUser, FALSE); // You may not use this feat with a ranged weapon.
|
|
return;
|
|
}
|
|
|
|
// All checks are done, initialize variables for calculating the effect.
|
|
int nDamageBonusType = GetDamageTypeOfWeapon(INVENTORY_SLOT_RIGHTHAND, oUser);
|
|
if(GetLocalInt(oUser, "DragonFireAssOn")) nDamageBonusType = GetDragonfireDamageType(oUser);
|
|
int nDmg, nHit, nDex, nTemp;
|
|
effect eDamage;
|
|
effect eToHit;
|
|
|
|
// Initialize the calculation with the power attack value given by the user.
|
|
nHit = nPower;
|
|
|
|
// Check if we are set to care about BW power attack being active
|
|
if(GetPRCSwitch(PRC_POWER_ATTACK_STACK_WITH_BW))
|
|
{
|
|
nTemp += GetActionMode(oUser, ACTION_MODE_POWER_ATTACK) ? 5 : 0;
|
|
nTemp += GetActionMode(oUser, ACTION_MODE_IMPROVED_POWER_ATTACK) ? 10 : 0;
|
|
}
|
|
// The attack bonus paid to PA is limited to one's BAB
|
|
if(GetBaseAttackBonus(oUser) < (nHit + nTemp))
|
|
{
|
|
nHit = GetBaseAttackBonus(oUser) - ((GetActionMode(oUser, ACTION_MODE_POWER_ATTACK) ? 5 : 0) +
|
|
(GetActionMode(oUser, ACTION_MODE_IMPROVED_POWER_ATTACK ? 10 : 0)));
|
|
if(nHit < 0) nHit = 0;
|
|
|
|
FloatingTextStrRefOnCreature(16823151, oUser, FALSE); // Your base attack bonus isn't high enough to pay for chosen Power Attack level.
|
|
}
|
|
|
|
// Focused Strike adds Dex mod to damage, limited to number of AB paid.
|
|
if(GetHasFeat(FEAT_FOCUSED_STRIKE))
|
|
{
|
|
// Negative Dex mod won't reduce damage
|
|
nDex = GetAbilityModifier(ABILITY_DEXTERITY) > 0 ? GetAbilityModifier(ABILITY_DEXTERITY) : 0;
|
|
if(nDex > nHit) nDex = nHit;
|
|
}
|
|
|
|
// Calculate in Frenzied Berserker PA feats
|
|
nTemp = GetHasFeat(FEAT_SUPREME_POWER_ATTACK, oUser) ? nHit * 2 :
|
|
GetHasFeat(FEAT_FREBZK_IMPROVED_POWER_ATTACK, oUser) ? FloatToInt(1.5 * nHit) :
|
|
nHit;
|
|
|
|
// Calculate the damage. Supreme Power Attack doubles the damage
|
|
nDmg = BonusAtk(nTemp + nDex + GetEssentiaInvestedFeat(oUser, FEAT_COBALT_POWER));
|
|
|
|
eDamage = EffectDamageIncrease(nDmg, nDamageBonusType);
|
|
eToHit = EffectAttackDecrease(nHit);
|
|
|
|
effect eLink = ExtraordinaryEffect(EffectLinkEffects(eDamage, eToHit));
|
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oUser);
|
|
|
|
// Cache the spellid of the power attack used. Also acts as a marker
|
|
SetLocalInt(oUser, "PRC_PowerAttackSpellID", PRCGetSpellId());
|
|
// Cache the amount of damage granted. This is used by the PRC combat engine
|
|
SetLocalInt(oUser, "PRC_PowerAttack_DamageBonus", nDmg);
|
|
// Add an eventscript that makes sure the PC does not use a ranged weapon with Power Attack
|
|
AddEventScript(oUser, EVENT_ONPLAYEREQUIPITEM, "prc_powatk_equ", TRUE, FALSE);
|
|
|
|
// Power Attack Activated
|
|
string sMes = "*" + GetStringByStrRef(417) + " " + IntToString(nHit) + " " + GetStringByStrRef(63798) + "*";
|
|
FloatingTextStringOnCreature(sMes, oUser, FALSE);
|
|
|
|
if (GetHasFeat(FEAT_FAVORED_POWER_ATTACK, oUser))
|
|
{
|
|
ActionCastSpellAtObject(SPELL_UR_FAVORITE_ENEMY, oUser, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
}
|
|
// Turn Power Attack off
|
|
else
|
|
{
|
|
RemoveEventScript(oUser, EVENT_ONPLAYEREQUIPITEM, "prc_powatk_equ", TRUE);
|
|
|
|
// Power Attack Mode Deactivated
|
|
string sMes = "* " + GetStringByStrRef(58282) + " *";
|
|
FloatingTextStringOnCreature(sMes, oUser, FALSE);
|
|
|
|
if(GetHasFeat(FEAT_FAVORED_POWER_ATTACK, oUser))
|
|
{
|
|
ActionCastSpellAtObject(SPELL_UR_FAVORITE_ENEMY, oUser, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
}
|
|
}
|