PRC8/nwn/nwnprc/trunk/scripts/prc_shft_effap.nss
Jaysyn904 880d0e5527 2025/05/02 Update
Updated Foresight to use EffectBonusFeat.
Updated PRCRemoveProtections to not dispel extraordinary & supernatural effects.
Expanded DAMAGE_BONUS cap to 50.
Expanded various functions to use new DAMAGE_BONUS cap.
2025-05-02 14:38:26 -04:00

256 lines
12 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Shifting effects application spellscript
//:: prc_shft_effap
//::///////////////////////////////////////////////
/** @file prc_shft_effap
Applies those effects of shifting that
need an effect placed on the shifter in order
to bind said effects to a specific spellID.
@author Ornedan
@date Created - 2006.07.02
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//////////////////////////////////////////////////
/* Constants */
//////////////////////////////////////////////////
//////////////////////////////////////////////////
/* Function prototypes */
//////////////////////////////////////////////////
//////////////////////////////////////////////////
/* Includes */
//////////////////////////////////////////////////
#include "prc_alterations"
#include "prc_inc_shifting"
const string PRC_Shifter_ApplyEffects_Generation = "PRC_Shifter_ApplyEffects_Generation";
//////////////////////////////////////////////////
/* Function definitions */
//////////////////////////////////////////////////
void main()
{
object oApplier = OBJECT_SELF;
object oShifter = PRCGetSpellTargetObject();
if (GetLocalInt(oShifter, PRC_Shifter_ApplyEffects_EvalPRC_Generation) != GetLocalInt(oShifter, PRC_EvalPRCFeats_Generation))
{
//EvalPRCFeats has been called again since this application was scheduled,
//so don't apply--let the application scheduled by the later call to EvalPRCFeats
//do it instead.
return;
}
int nGeneration = PRC_NextGeneration(GetLocalInt(oShifter, PRC_Shifter_ApplyEffects_Generation));
SetLocalInt(oShifter, PRC_Shifter_ApplyEffects_Generation, nGeneration);
int bApplyAll = GetLocalInt(oShifter, "PRC_SHIFTER_APPLY_ALL_SPELL_EFFECTS");
DeleteLocalInt(oShifter, "PRC_SHIFTER_APPLY_ALL_SPELL_EFFECTS");
int nSTR_AttackBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_AttackBonus");
int nSTR_DamageBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_DamageBonus");
int nSTR_DamageType = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_DamageType");
int nSTR_SaveAndSkillBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_SaveAndSkillBonus");
int nDEX_ACBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraDEX_ACBonus");
int nDEX_SaveAndSkillBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraDEX_SaveAndSkillBonus");
int nCON_HPBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraCON_HPBonus");
int nCON_SaveAndSkillBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraCON_SaveAndSkillBonus");
//Remove any old effects
_prc_inc_shifting_RemoveSpellEffects(oShifter, bApplyAll);
//Add any new effects
//STR-based attack bonus
if(nSTR_AttackBonus > 0)
{
int nAttackIncrease = nSTR_AttackBonus;
if (nAttackIncrease > 20)
nAttackIncrease = 20;
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectAttackIncrease(nAttackIncrease, ATTACK_BONUS_MISC)), oShifter);
}
else if (nSTR_AttackBonus < 0)
{
int nAttackDecrease = -nSTR_AttackBonus;
if (nAttackDecrease > 20) //TODO: What's the actual cap?
nAttackDecrease = 20;
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectAttackDecrease(nAttackDecrease, ATTACK_BONUS_MISC)), oShifter);
}
//STR-based damage bonus
if(nSTR_DamageBonus > 0)
{
int nDamageBonusConstant;
switch(nSTR_DamageBonus)
{
case 1 : nDamageBonusConstant = DAMAGE_BONUS_1 ; break;
case 2 : nDamageBonusConstant = DAMAGE_BONUS_2 ; break;
case 3 : nDamageBonusConstant = DAMAGE_BONUS_3 ; break;
case 4 : nDamageBonusConstant = DAMAGE_BONUS_4 ; break;
case 5 : nDamageBonusConstant = DAMAGE_BONUS_5 ; break;
case 6 : nDamageBonusConstant = DAMAGE_BONUS_6 ; break;
case 7 : nDamageBonusConstant = DAMAGE_BONUS_7 ; break;
case 8 : nDamageBonusConstant = DAMAGE_BONUS_8 ; break;
case 9 : nDamageBonusConstant = DAMAGE_BONUS_9 ; break;
case 10: nDamageBonusConstant = DAMAGE_BONUS_10; break;
case 11: nDamageBonusConstant = DAMAGE_BONUS_11; break;
case 12: nDamageBonusConstant = DAMAGE_BONUS_12; break;
case 13: nDamageBonusConstant = DAMAGE_BONUS_13; break;
case 14: nDamageBonusConstant = DAMAGE_BONUS_14; break;
case 15: nDamageBonusConstant = DAMAGE_BONUS_15; break;
case 16: nDamageBonusConstant = DAMAGE_BONUS_16; break;
case 17: nDamageBonusConstant = DAMAGE_BONUS_17; break;
case 18: nDamageBonusConstant = DAMAGE_BONUS_18; break;
case 19: nDamageBonusConstant = DAMAGE_BONUS_19; break;
case 20: nDamageBonusConstant = DAMAGE_BONUS_20; break;
case 21: nDamageBonusConstant = DAMAGE_BONUS_21; break;
case 22: nDamageBonusConstant = DAMAGE_BONUS_22; break;
case 23: nDamageBonusConstant = DAMAGE_BONUS_23; break;
case 24: nDamageBonusConstant = DAMAGE_BONUS_24; break;
case 25: nDamageBonusConstant = DAMAGE_BONUS_25; break;
case 26: nDamageBonusConstant = DAMAGE_BONUS_26; break;
case 27: nDamageBonusConstant = DAMAGE_BONUS_27; break;
case 28: nDamageBonusConstant = DAMAGE_BONUS_28; break;
case 29: nDamageBonusConstant = DAMAGE_BONUS_29; break;
case 30: nDamageBonusConstant = DAMAGE_BONUS_30; break;
case 31: nDamageBonusConstant = DAMAGE_BONUS_31; break;
case 32: nDamageBonusConstant = DAMAGE_BONUS_32; break;
case 33: nDamageBonusConstant = DAMAGE_BONUS_33; break;
case 34: nDamageBonusConstant = DAMAGE_BONUS_34; break;
case 35: nDamageBonusConstant = DAMAGE_BONUS_35; break;
case 36: nDamageBonusConstant = DAMAGE_BONUS_36; break;
case 37: nDamageBonusConstant = DAMAGE_BONUS_37; break;
case 38: nDamageBonusConstant = DAMAGE_BONUS_38; break;
case 39: nDamageBonusConstant = DAMAGE_BONUS_39; break;
case 40: nDamageBonusConstant = DAMAGE_BONUS_40; break;
case 41: nDamageBonusConstant = DAMAGE_BONUS_41; break;
case 42: nDamageBonusConstant = DAMAGE_BONUS_42; break;
case 43: nDamageBonusConstant = DAMAGE_BONUS_43; break;
case 44: nDamageBonusConstant = DAMAGE_BONUS_44; break;
case 45: nDamageBonusConstant = DAMAGE_BONUS_45; break;
case 46: nDamageBonusConstant = DAMAGE_BONUS_46; break;
case 47: nDamageBonusConstant = DAMAGE_BONUS_47; break;
case 48: nDamageBonusConstant = DAMAGE_BONUS_48; break;
case 49: nDamageBonusConstant = DAMAGE_BONUS_49; break;
default: nDamageBonusConstant = DAMAGE_BONUS_50; // The value is >= 50
}
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectDamageIncrease(nDamageBonusConstant, nSTR_DamageType)), oShifter);
}
else if(nSTR_DamageBonus < 0)
{
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectDamageDecrease(-nSTR_DamageBonus, nSTR_DamageType)), oShifter);
}
//DEX-based AC bonus
if (nDEX_ACBonus > 0)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectACIncrease(nDEX_ACBonus)), oShifter);
else if (nDEX_ACBonus < 0)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectACDecrease(-nDEX_ACBonus)), oShifter);
//DEX-based save bonus
if (nDEX_SaveAndSkillBonus > 0)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nDEX_SaveAndSkillBonus)), oShifter);
else if (nDEX_SaveAndSkillBonus < 0)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_REFLEX, -nDEX_SaveAndSkillBonus)), oShifter);
//TODO: what about forms that are immune to saving throw decrease? Use code similar to _prc_inc_shifting_BypassItemProperties()?
//CON-based save bonus
if (nCON_SaveAndSkillBonus > 0)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, nCON_SaveAndSkillBonus)), oShifter);
else if (nCON_SaveAndSkillBonus < 0)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, -nCON_SaveAndSkillBonus)), oShifter);
//TODO: what about forms that are immune to saving throw decrease? Use code similar to _prc_inc_shifting_BypassItemProperties()?
//STR, DEX, and CON based skill bonuses
int i = 0;
string sSkillKeyAbility;
effect eTotalSkillEffect;
int bHaveTotalSkillEffect = FALSE;
while((sSkillKeyAbility = Get2DACache("skills", "KeyAbility", i)) != "")
{
int nSaveAndSkillBonus = 0;
if (sSkillKeyAbility == "STR")
nSaveAndSkillBonus = nSTR_SaveAndSkillBonus;
else if (sSkillKeyAbility == "DEX")
nSaveAndSkillBonus = nDEX_SaveAndSkillBonus;
else if (sSkillKeyAbility == "CON")
nSaveAndSkillBonus = nCON_SaveAndSkillBonus;
effect eSkillEffect;
if(nSaveAndSkillBonus > 0)
{
eSkillEffect = EffectLinkEffects(eTotalSkillEffect, EffectSkillIncrease(i, nSaveAndSkillBonus));
}
else if (nSaveAndSkillBonus < 0)
{
eSkillEffect = EffectLinkEffects(eTotalSkillEffect, EffectSkillDecrease(i, -nSaveAndSkillBonus));
//TODO: what about forms that are immune to skill decrease? Use code similar to _prc_inc_shifting_BypassItemProperties()?
}
if (!bHaveTotalSkillEffect)
{
eTotalSkillEffect = eSkillEffect;
bHaveTotalSkillEffect = TRUE;
}
else
eTotalSkillEffect = EffectLinkEffects(eTotalSkillEffect, eSkillEffect);
i += 1;
}
if (bHaveTotalSkillEffect)
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(eTotalSkillEffect), oShifter);
//Natural AC
if(GetLocalInt(oShifter, "PRC_Shifter_NaturalAC"))
{
int nNaturalAC = GetLocalInt(oShifter, "PRC_Shifter_NaturalAC");
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectACIncrease(nNaturalAC, AC_NATURAL_BONUS)), oShifter);
}
//Harmlessly invisible
if (bApplyAll)
{
if(GetLocalInt(oShifter, "PRC_Shifter_HarmlessInvisible"))
{
if(DEBUG_EFFECTS || DEBUG)
DoDebug("Applying Harmless Invisibility effect");
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectInvisibility(INVISIBILITY_TYPE_NORMAL)), oShifter);
}
}
//CON-based HP bonus
if (bApplyAll)
{
if(DEBUG_EFFECTS || DEBUG)
DoDebug("Applying Temporary HP effect: " + IntToString(nCON_HPBonus));
//Apply temporary HP separately from other effects--linking it with other effects
//causes those other effects to be removed when the temporary HP is used up.
if (nCON_HPBonus > 0)
{
DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectTemporaryHitpoints(nCON_HPBonus)), oShifter);
}
else if (nCON_HPBonus < 0)
{
//TODO
}
}
if (GetIsObjectValid(oApplier) && GetResRef(oApplier) == "x0_rodwonder")
{
//Queue deletion of the applicator object
DestroyObject(oApplier, 6.0f);
}
}