2025-04-15 Update
Added Elven blades to Weaponmaster prereqs Fixed Beckon the Frozen Fixed bug with Fire Brand Fixed duration bug with Improved Invisibility Added Soul Eater to Shifter prereqs Fixed ability based class prereqs in prc_prereq.nss Update Eye of Gruumsh for epic levels Update Ur-Priest for epic levels Update Forsaker for epic levels Update Anima Mage for epic levels Update Serene Guardian for epic levels Bladesinger abilities can use chain shirts Fixed Elemental Abjuration Fixed bug with prc cache creature. Forsakers can use non-magic items (heal kits, alchemy, etc) Updated ruleset.2da for NWNEE update Updated AotS bonus feats -Notes Added 3.5e Template index Added 3.5e update booklet Removed release archive
This commit is contained in:
@@ -1426,6 +1426,160 @@ void DeleteNamedComposites(object oItem, string sBase)
|
||||
}
|
||||
|
||||
int GetIsMagicItem(object oItem)
|
||||
{
|
||||
// Exclusion for specific item resrefs: if the item is one of these, it's non-magical.
|
||||
string sResRef = GetResRef(oItem);
|
||||
if(sResRef == "x1_wmgrenade001" ||
|
||||
sResRef == "prc_it_acidfire" ||
|
||||
sResRef == "prc_agony" ||
|
||||
sResRef == "prc_it_alcslpgas." ||
|
||||
sResRef == "x1_wmgrenade002" ||
|
||||
sResRef == "prc_it_alcfrost" ||
|
||||
sResRef == "prc_it_alcspark" ||
|
||||
sResRef == "prc_it_antitox" ||
|
||||
sResRef == "prc_baccaran" ||
|
||||
sResRef == "prc_it_biledrp" ||
|
||||
sResRef == "prc_it_blendcrm" ||
|
||||
sResRef == "prc_brittlebn" ||
|
||||
sResRef == "prc_it_crcklpdr" ||
|
||||
sResRef == "prc_devilweed" ||
|
||||
sResRef == "prc_it_emblmfr" ||
|
||||
sResRef == "prc_it_fareyeoil" ||
|
||||
sResRef == "prc_it_festerbmb" ||
|
||||
sResRef == "prc_it_flashplt" ||
|
||||
sResRef == "prc_it_healblm" ||
|
||||
sResRef == "prc_it_keenear" ||
|
||||
sResRef == "prc_it_lockslip" ||
|
||||
sResRef == "prc_luhix" ||
|
||||
sResRef == "prc_mshrm_pwdr" ||
|
||||
sResRef == "prc_it_natdrgt" ||
|
||||
sResRef == "prc_it_nerv" ||
|
||||
sResRef == "prc_sannish" ||
|
||||
sResRef == "prc_it_scrmflsk" ||
|
||||
sResRef == "prc_it_shedden" ||
|
||||
sResRef == "prc_it_shedden2" ||
|
||||
sResRef == "prc_it_shedden3" ||
|
||||
sResRef == "prc_it_shedden4" ||
|
||||
sResRef == "prc_it_shedden5" ||
|
||||
sResRef == "prc_it_softfoot" ||
|
||||
sResRef == "x1_wmgrenade006" ||
|
||||
sResRef == "prc_terran_brndy" ||
|
||||
sResRef == "x1_wmgrenade007" ||
|
||||
sResRef == "prc_vodare" ||
|
||||
sResRef == "prc_it_weepstn")
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Exception for torches:
|
||||
// If the only permanent property is the Light property (44), it's not magical.
|
||||
if(GetBaseItemType(oItem) == BASE_ITEM_TORCH)
|
||||
{
|
||||
int nCount = 0;
|
||||
int nOnlyType = -1;
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
while(GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT)
|
||||
{
|
||||
nCount++;
|
||||
nOnlyType = GetItemPropertyType(ip);
|
||||
}
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
if(nCount == 1 && nOnlyType == 44)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Exception for healer's kits:
|
||||
// If the only permanent property is type 80, it's not magical.
|
||||
if(GetBaseItemType(oItem) == BASE_ITEM_HEALERSKIT)
|
||||
{
|
||||
int nCount = 0;
|
||||
int nOnlyType = -1;
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
while(GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT)
|
||||
{
|
||||
nCount++;
|
||||
nOnlyType = GetItemPropertyType(ip);
|
||||
}
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
if(nCount == 1 && nOnlyType == 80)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Exception for thief's tools:
|
||||
// If the only permanent property is type 55, it's not magical.
|
||||
if(GetBaseItemType(oItem) == BASE_ITEM_THIEVESTOOLS)
|
||||
{
|
||||
int nCount = 0;
|
||||
int nOnlyType = -1;
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
while(GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT)
|
||||
{
|
||||
nCount++;
|
||||
nOnlyType = GetItemPropertyType(ip);
|
||||
}
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
if(nCount == 1 && nOnlyType == 55)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal magic property checking
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
int nType;
|
||||
int nSubtype;
|
||||
while(GetIsItemPropertyValid(ip)) // loop through item properties looking for a magical one
|
||||
{
|
||||
if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT)
|
||||
{ // ignore temporary properties
|
||||
nType = GetItemPropertyType(ip);
|
||||
if((nType >= 0 && nType <= 9) || // read from itempropdef.2da
|
||||
(nType >= 13 && nType <= 20) ||
|
||||
(nType == 26) ||
|
||||
(nType >= 32 && nType <= 44) ||
|
||||
(nType == 46) ||
|
||||
(nType >= 51 && nType <= 59) ||
|
||||
(nType == 61) ||
|
||||
(nType >= 67 && nType <= 69) ||
|
||||
(nType >= 71 && nType <= 80) ||
|
||||
(nType == 82) ||
|
||||
(nType == 84) ||
|
||||
(nType >= 100 && nType <= 105) ||
|
||||
(nType >= 133 && nType <= 134))
|
||||
{
|
||||
return 1; // magical property found
|
||||
}
|
||||
nSubtype = GetItemPropertySubType(ip);
|
||||
if(nType == ITEM_PROPERTY_BONUS_FEAT)
|
||||
{
|
||||
if(GetBaseItemType(oItem) == BASE_ITEM_WHIP)
|
||||
{
|
||||
if(nSubtype != IP_CONST_FEAT_DISARM_WHIP)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* int GetIsMagicItem(object oItem)
|
||||
{
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
int nType;
|
||||
@@ -1467,7 +1621,7 @@ int GetIsMagicItem(object oItem)
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} */
|
||||
|
||||
int FeatToIprop(int nFeat)
|
||||
{
|
||||
|
@@ -239,7 +239,8 @@ int _ReorderEffects(int nSpellID, object oTarget, object oCaster = OBJECT_SELF){
|
||||
/* Function Definitions */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
object GetObjectToApplyNewEffect(string sTag, object oPC, int nStripEffects = TRUE){
|
||||
object GetObjectToApplyNewEffect(string sTag, object oPC, int nStripEffects = TRUE)
|
||||
{
|
||||
object oWP = GetObjectByTag(sTag);
|
||||
object oLimbo = GetObjectByTag("HEARTOFCHAOS");
|
||||
location lLimbo = GetLocation(oLimbo);
|
||||
@@ -251,17 +252,16 @@ object GetObjectToApplyNewEffect(string sTag, object oPC, int nStripEffects = TR
|
||||
//has to be a creature so it can be jumped around
|
||||
//re-used the 2da cache blueprint since it has no scripts
|
||||
oWP = CreateObject(OBJECT_TYPE_CREATURE, "prc_2da_cache", lLimbo, FALSE, sTag);
|
||||
if(!GetIsObjectValid(oWP) && DEBUG)
|
||||
{
|
||||
DoDebug(sTag+" is not valid");
|
||||
}
|
||||
//make sure the player can never interact with WP
|
||||
SetPlotFlag(oWP, TRUE);
|
||||
SetCreatureAppearanceType(oWP, APPEARANCE_TYPE_INVISIBLE_HUMAN_MALE);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oWP);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oWP);
|
||||
}
|
||||
if(!GetIsObjectValid(oWP)
|
||||
&& DEBUG)
|
||||
{
|
||||
DoDebug(sTag+" is not valid");
|
||||
}
|
||||
//make sure the player can never interact with WP
|
||||
SetPlotFlag(oWP, TRUE);
|
||||
SetCreatureAppearanceType(oWP, APPEARANCE_TYPE_INVISIBLE_HUMAN_MALE);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oWP);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oWP);
|
||||
//remove previous effects
|
||||
if(nStripEffects)
|
||||
{
|
||||
|
@@ -32,6 +32,7 @@ const int FEAT_EPIC_OCULAR = 3425;
|
||||
const int FEAT_EPIC_RAVAGER = 2395;
|
||||
const int FEAT_EPIC_RED_AVENGER = 2753;
|
||||
const int FEAT_EPIC_TEMPEST = 5470;
|
||||
const int FEAT_EPIC_UP_PRIEST = 25996;
|
||||
|
||||
//:: Web Enhancement Feats
|
||||
const int FEAT_CHARMING_THE_ARROW = 25997;
|
||||
|
@@ -378,7 +378,7 @@ void EvalPRCFeats(object oPC)
|
||||
ExecuteScript("ft_sanctmartial", oPC);
|
||||
|
||||
//hook in the weapon size restrictions script
|
||||
//ExecuteScript("prc_restwpnsize", oPC);
|
||||
//ExecuteScript("prc_restwpnsize", oPC); //<- Script no longer exists
|
||||
|
||||
//Route the event to the appropriate class specific scripts
|
||||
int i, iData;
|
||||
@@ -1434,6 +1434,16 @@ void FeatNinja (object oPC)
|
||||
SetLocalInt(oPC, "prc_ninja_ki", nUsesLeft);
|
||||
}
|
||||
|
||||
void EyeOfGruumsh(object oPC)
|
||||
{
|
||||
if (GetLevelByClass(CLASS_TYPE_PRC_EYE_OF_GRUUMSH, oPC) < 4) return;
|
||||
|
||||
int iEOGLevel = GetLevelByClass(CLASS_TYPE_PRC_EYE_OF_GRUUMSH, oPC);
|
||||
int nUses = 2 + 2 * ((iEOGLevel - 4) / 3);
|
||||
|
||||
FeatUsePerDay(oPC, FEAT_BLINDING_SPITTLE, -1, nUses);
|
||||
}
|
||||
|
||||
void BarbarianRage(object oPC)
|
||||
{
|
||||
if(!GetHasFeat(FEAT_BARBARIAN_RAGE, oPC)) return;
|
||||
@@ -1900,6 +1910,36 @@ void CrusaderSmite(object oPC)
|
||||
}
|
||||
|
||||
void AnimaMage(object oPC)
|
||||
{
|
||||
int nClass = GetLevelByClass(CLASS_TYPE_ANIMA_MAGE, oPC);
|
||||
if(nClass > 0)
|
||||
{
|
||||
int nUses;
|
||||
// Levels 1-6: 1 use
|
||||
if(nClass < 7)
|
||||
{
|
||||
nUses = 1;
|
||||
}
|
||||
// Levels 7-8: 2 uses
|
||||
else if(nClass < 9)
|
||||
{
|
||||
nUses = 2;
|
||||
}
|
||||
// Levels 9-10: 3 uses
|
||||
else if(nClass <= 10)
|
||||
{
|
||||
nUses = 3;
|
||||
}
|
||||
// Levels above 10: 1 additional use per 3 levels
|
||||
else
|
||||
{
|
||||
nUses = 3 + ((nClass - 10) / 3);
|
||||
}
|
||||
FeatUsePerDay(oPC, FEAT_ANIMA_VESTIGE_METAMAGIC, -1, 0, nUses);
|
||||
}
|
||||
}
|
||||
|
||||
/* void AnimaMage(object oPC)
|
||||
{
|
||||
int nClass = GetLevelByClass(CLASS_TYPE_ANIMA_MAGE, oPC);
|
||||
if(nClass > 0)
|
||||
@@ -1911,7 +1951,7 @@ void AnimaMage(object oPC)
|
||||
else
|
||||
FeatUsePerDay(oPC, FEAT_ANIMA_VESTIGE_METAMAGIC, -1, 0, 1);
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
void FeatSpecialUsePerDay(object oPC)
|
||||
{
|
||||
@@ -2022,6 +2062,7 @@ void FeatSpecialUsePerDay(object oPC)
|
||||
SLAUses(oPC);
|
||||
DomainUses(oPC);
|
||||
BardSong(oPC);
|
||||
EyeOfGruumsh(oPC);
|
||||
BarbarianRage(oPC);
|
||||
FeatVirtuoso(oPC);
|
||||
ResetExtraStunfistUses(oPC);
|
||||
|
@@ -2953,7 +2953,7 @@ void AugmentSummonedCreature(string sResRef)
|
||||
{
|
||||
effect eLink = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
|
||||
eLink = EffectLinkEffects(eLink, EffectAbilityIncrease(ABILITY_CONSTITUTION, 4));
|
||||
eLink = SupernaturalEffect(eLink);
|
||||
eLink = UnyieldingEffect(eLink);
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oSummon);
|
||||
SetLocalInt(oSummon, "Augmented", TRUE);
|
||||
@@ -2984,10 +2984,11 @@ void AugmentSummonedCreature(string sResRef)
|
||||
{
|
||||
if(GetResRef(oSummon) == sResRef && !GetLocalInt(oSummon, "BeckonTheFrozen"))
|
||||
{
|
||||
effect eLink = EffectVisualEffect(VFX_DUR_ELEMENTAL_SHIELD);
|
||||
effect eLink = EffectVisualEffect(VFX_DUR_CHILL_SHIELD);
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageImmunityDecrease(DAMAGE_TYPE_FIRE, 50));
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 100));
|
||||
eLink = SupernaturalEffect(eLink);
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageIncrease(DAMAGE_BONUS_1d6, DAMAGE_TYPE_COLD));
|
||||
eLink = UnyieldingEffect(eLink);
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oSummon);
|
||||
SetLocalInt(oSummon, "BeckonTheFrozen", TRUE);
|
||||
|
@@ -1918,7 +1918,7 @@ const string PRC_CRAFT_TIMER_MIN = "PRC_CRAFT_TIMER_MIN";
|
||||
*/
|
||||
const string PRC_BREW_POTION_CASTER_LEVEL = "PRC_BREW_POTION_CASTER_LEVEL";
|
||||
|
||||
/**
|
||||
/*
|
||||
* These three switches modify Bioware crafting so that the items produced have the
|
||||
* casterlevel of the spellcaster who created them. Normally under Bioware, it is possible
|
||||
* for a level 3 caster to produce level 9 items and for a level 40 caster to only produce
|
||||
@@ -1930,7 +1930,7 @@ const string PRC_BREW_POTION_CASTER_LEVEL = "PRC_BREW_POTION_CASTER_L
|
||||
*/
|
||||
const string PRC_SCRIBE_SCROLL_CASTER_LEVEL = "PRC_SCRIBE_SCROLL_CASTER_LEVEL";
|
||||
|
||||
/**
|
||||
/*
|
||||
* These three switches modify Bioware crafting so that the items produced have the
|
||||
* casterlevel of the spellcaster who created them. Normally under Bioware, it is possible
|
||||
* for a level 3 caster to produce level 9 items and for a level 40 caster to only produce
|
||||
@@ -1942,12 +1942,12 @@ const string PRC_SCRIBE_SCROLL_CASTER_LEVEL = "PRC_SCRIBE_SCROLL_CASTER
|
||||
*/
|
||||
const string PRC_CRAFT_WAND_CASTER_LEVEL = "PRC_CRAFT_WAND_CASTER_LEVEL";
|
||||
|
||||
/**
|
||||
/*
|
||||
* As above, except it applies to rods
|
||||
*/
|
||||
const string PRC_CRAFT_ROD_CASTER_LEVEL = "PRC_CRAFT_ROD_CASTER_LEVEL";
|
||||
|
||||
/**
|
||||
/*
|
||||
* As above, except it applies to staffs
|
||||
*/
|
||||
const string PRC_CRAFT_STAFF_CASTER_LEVEL = "PRC_CRAFT_STAFF_CASTER_LEVEL";
|
||||
|
@@ -285,7 +285,7 @@ int FindUnarmedDamage(object oCreature)
|
||||
if (GetBaseAC(oArmor) > 0 || bShieldEq)
|
||||
{
|
||||
iMonkDamage = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shou Disciples can wear light armor
|
||||
|
@@ -139,7 +139,23 @@ int PRCGetSpellResistance(object oTarget, object oCaster)
|
||||
}
|
||||
}
|
||||
|
||||
// Ur-Priest
|
||||
// Ur-Priest
|
||||
int nPriestLevel = GetLevelByClass(CLASS_TYPE_UR_PRIEST, oTarget);
|
||||
if(nPriestLevel >= 4)
|
||||
{
|
||||
// SR vs divine only
|
||||
if(GetIsDivineClass(PRCGetLastSpellCastClass(oCaster)))
|
||||
{
|
||||
//if(nPriestLevel > 50) nPriestLevel = 50; //:: cap if needed
|
||||
|
||||
// Calculate bonus: 15 at level 4, then +5 for every additional 4 levels
|
||||
int nCont = 15 + (((nPriestLevel - 4) / 4) * 5);
|
||||
|
||||
if(nCont > iSpellRes)
|
||||
iSpellRes = nCont;
|
||||
}
|
||||
}
|
||||
/* // Ur-Priest
|
||||
if(GetLevelByClass(CLASS_TYPE_UR_PRIEST, oTarget) >= 4)
|
||||
{
|
||||
// SR vs divine only
|
||||
@@ -150,7 +166,7 @@ int PRCGetSpellResistance(object oTarget, object oCaster)
|
||||
if(nCont > iSpellRes)
|
||||
iSpellRes = nCont;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
// Dread Carapace Heart Bind
|
||||
if(GetIsIncarnumUser(oTarget))
|
||||
|
@@ -1250,17 +1250,31 @@ void EnergyAbjuration(object oCaster, int nSchool, int nSpellLevel)
|
||||
if(nSchool == SPELL_SCHOOL_ABJURATION)
|
||||
{
|
||||
int nAmount = (1 + nSpellLevel) * 5;
|
||||
|
||||
int nDamageType = DAMAGE_TYPE_ACID | DAMAGE_TYPE_COLD | DAMAGE_TYPE_ELECTRICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_SONIC;
|
||||
|
||||
effect eLink = EffectDamageResistance(DAMAGE_TYPE_COLD, nAmount, nAmount);
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_FIRE, nAmount, nAmount));
|
||||
effect eResist = EffectDamageResistance(nDamageType, nAmount, nAmount);
|
||||
|
||||
effect eDur = EffectVisualEffect(VFX_DUR_PROTECTION_ELEMENTS);
|
||||
effect eVfx = EffectVisualEffect(VFX_IMP_ELEMENTAL_PROTECTION);
|
||||
effect eEnd = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||
|
||||
effect eLink = EffectLinkEffects(eResist, eDur);
|
||||
eLink = EffectLinkEffects(eLink, eEnd);
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVfx, oCaster);
|
||||
|
||||
|
||||
/* eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_FIRE, nAmount, nAmount));
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_ACID, nAmount, nAmount));
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_SONIC, nAmount, nAmount));
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, nAmount, nAmount));
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_PROTECTION_ELEMENTS));
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_IMP_ELEMENTAL_PROTECTION));
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE));
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE)); */
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oCaster);
|
||||
if (DEBUG) DoDebug("Energy Abjuration triggered! DR Amount: " + IntToString(nAmount));
|
||||
DelayCommand(0.0, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oCaster));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user