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:
Jaysyn904
2025-04-15 18:10:14 -04:00
parent 41ac396fe0
commit 0f43e5cbd2
40 changed files with 5604 additions and 3382 deletions

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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";

View File

@@ -285,7 +285,7 @@ int FindUnarmedDamage(object oCreature)
if (GetBaseAC(oArmor) > 0 || bShieldEq)
{
iMonkDamage = 1;
}
}
}
// Shou Disciples can wear light armor

View File

@@ -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))

View File

@@ -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));
}
}
}