PRC8/nwn/nwnprc/trunk/include/prc_inc_sbheir.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
Updated AMS marker feats.  Removed arcane & divine marker feats.  Updated Dread Necromancer for epic progression. Updated weapon baseitem models.  Updated new weapons for crafting & npc equip.
 Updated prefix.  Updated release archive.
2024-02-11 14:01:05 -05:00

170 lines
7.3 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Shining Blade of Heironeous include
//:: prc_inc_sbheir
//::///////////////////////////////////////////////
#include "prc_inc_util"
#include "inc_item_props"
const int SHINING_BLADE_LEVEL_SHOCK = 1;
const int SHINING_BLADE_LEVEL_HOLY = 2;
const int SHINING_BLADE_LEVEL_BRILLIANT = 3;
const string PRC_ShiningBlade_Generation = "PRC_ShiningBlade_Generation";
const string PRC_ShiningBlade_Level = "PRC_ShiningBladeLevel";
const string PRC_ShiningBlade_Duration = "PRC_ShiningBladeDuration";
void ShiningBlade_RemoveProperties(object oWeapon, int nLevel)
{
itemproperty iTest = GetFirstItemProperty(oWeapon);
while(GetIsItemPropertyValid(iTest))
{
int bRemove = FALSE;
if (GetItemPropertyDurationType(iTest) == DURATION_TYPE_TEMPORARY)
{
switch(GetItemPropertyType(iTest))
{
case ITEM_PROPERTY_DAMAGE_BONUS:
if (nLevel >= SHINING_BLADE_LEVEL_SHOCK)
bRemove = (GetItemPropertySubType(iTest) == IP_CONST_DAMAGETYPE_ELECTRICAL) && (GetItemPropertyCostTableValue(iTest) == DAMAGE_BONUS_1d6);
break;
case ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP:
if (nLevel >= SHINING_BLADE_LEVEL_HOLY)
bRemove = (GetItemPropertySubType(iTest) == IP_CONST_ALIGNMENTGROUP_EVIL) && (GetItemPropertyParam1Value(iTest) == IP_CONST_DAMAGETYPE_DIVINE) && (GetItemPropertyCostTableValue(iTest) == DAMAGE_BONUS_2d6);
break;
case ITEM_PROPERTY_LIGHT:
if (nLevel >= SHINING_BLADE_LEVEL_BRILLIANT)
bRemove = TRUE;
break;
}
}
if (bRemove)
RemoveItemProperty(oWeapon, iTest);
iTest = GetNextItemProperty(oWeapon);
}
}
void ShockBlade_ApplyProperties(object oWeapon, int nDuration)
{
//Remove any old properties
ShiningBlade_RemoveProperties(oWeapon, SHINING_BLADE_LEVEL_SHOCK);
//Add the new properties
if (nDuration)
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, DAMAGE_BONUS_1d6), oWeapon, RoundsToSeconds(nDuration));
}
void HolyBlade_ApplyProperties(object oWeapon, int nDuration)
{
//Remove any old properties
ShiningBlade_RemoveProperties(oWeapon, SHINING_BLADE_LEVEL_HOLY);
//Add the new properties
if (nDuration)
{
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, DAMAGE_BONUS_1d6), oWeapon, RoundsToSeconds(nDuration));
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL, IP_CONST_DAMAGETYPE_DIVINE, DAMAGE_BONUS_2d6), oWeapon, RoundsToSeconds(nDuration));
}
}
void BrilliantBlade_ApplyProperties(object oWeapon, int nDuration)
{
//Remove any old properies
ShiningBlade_RemoveProperties(oWeapon, SHINING_BLADE_LEVEL_BRILLIANT);
//Add the new properties
if (nDuration)
{
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, DAMAGE_BONUS_1d6), oWeapon, RoundsToSeconds(nDuration));
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL, IP_CONST_DAMAGETYPE_DIVINE, DAMAGE_BONUS_2d6), oWeapon, RoundsToSeconds(nDuration));
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyLight(IP_CONST_LIGHTBRIGHTNESS_BRIGHT, IP_CONST_LIGHTCOLOR_WHITE), oWeapon, RoundsToSeconds(nDuration));
}
}
void BrilliantBlade_ApplyAttackBonuses(object oPC, int bOnHand, int bOffHand)
{
//ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectAttackIncrease(20, nAttackBonusHand)), oPC, RoundsToSeconds(nDuration));
//This applies the attack bonus only to hands currently containing longsword,
//but incorrectly the bonus is still active if the longsword is exchanged for another weapon.
//AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonus(20), oWeapon, RoundsToSeconds(nDuration));
//This adds the bonus only to the correct wielded weapon(s), but won't increase AB with
//a longsword that one is not wielding at the time the bonus is applied.
//Note: theoretically, we should increase the AB of the weapon by 20, not set it to 20; however, since the AB
//cap is 20, and the AB of a weapon is included in the cap, it makes little practical difference.
//NOTE: this provide +20 DR penetration, so it's a no-go (see http://nwn.wikia.com/wiki/Damage_reduction)
SetCompositeAttackBonus(oPC, "SB_BrilliantBlade_R", bOnHand?20:0, ATTACK_BONUS_ONHAND);
SetCompositeAttackBonus(oPC, "SB_BrilliantBlade_L", bOffHand?20:0, ATTACK_BONUS_OFFHAND);
}
void ShiningBlade_ApplyProperties(object oWeapon, int nDuration, int nLevel)
{
switch(nLevel)
{
case SHINING_BLADE_LEVEL_SHOCK:
ShockBlade_ApplyProperties(oWeapon, nDuration);
break;
case SHINING_BLADE_LEVEL_HOLY:
HolyBlade_ApplyProperties(oWeapon, nDuration);
break;
case SHINING_BLADE_LEVEL_BRILLIANT:
BrilliantBlade_ApplyProperties(oWeapon, nDuration);
break;
}
}
void ShiningBlade_ApplyAttackBonuses(object oPC, int bOnHand, int bOffHand, int nLevel)
{
if (nLevel >= SHINING_BLADE_LEVEL_BRILLIANT)
BrilliantBlade_ApplyAttackBonuses(oPC, bOnHand, bOffHand);
else
BrilliantBlade_ApplyAttackBonuses(oPC, FALSE, FALSE);
}
void ShiningBlade_ExpireBonuses(object oPC, int nGeneration, int nLevel)
{
int nShiningBladeGeneration = GetLocalInt(oPC, PRC_ShiningBlade_Generation);
if (nGeneration == nShiningBladeGeneration)
{
if (DEBUG) DoDebug("Expiring Shining Blade bonuses");
//Zero out variables so that equipping a weapon doesn't reapply the expired bonuses
SetLocalInt(oPC, PRC_ShiningBlade_Duration, 0);
SetLocalInt(oPC, PRC_ShiningBlade_Level, 0);
//Expire bonsues on wielded weapons
object oOnHandWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
object oOffHandWeapon = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
if (GetBaseItemType(oOnHandWeapon) == BASE_ITEM_LONGSWORD)
ShiningBlade_RemoveProperties(oOnHandWeapon, nLevel);
if (GetBaseItemType(oOffHandWeapon) == BASE_ITEM_LONGSWORD)
ShiningBlade_RemoveProperties(oOffHandWeapon, nLevel);
//Expire attack bonuses
ShiningBlade_ApplyAttackBonuses(oPC, FALSE, FALSE, nLevel);
}
else
{
//The Brilliant/Holy/Shock Blade feat has been used again since this removal was scheduled,
//so don't expire--the next application of the feat will expire them
//when *it's* time runs out.
if (DEBUG) DoDebug("Not expiring Shining Blade bonuses: " + IntToString(nGeneration) + ", " + IntToString(nShiningBladeGeneration));
}
}
void ShiningBlade_ScheduleBonusExpiration(object oPC, int nDuration, int nLevel)
{
int nGeneration = PRC_NextGeneration(GetLocalInt(oPC, PRC_ShiningBlade_Generation));
SetLocalInt(oPC, PRC_ShiningBlade_Generation, nGeneration);
DelayCommand(RoundsToSeconds(nDuration), ShiningBlade_ExpireBonuses(oPC, nGeneration, nLevel));
}