diff --git a/nwn/nwnprc/trunk/2das/feat.2da b/nwn/nwnprc/trunk/2das/feat.2da
index 3ff025f2..50fdfe12 100644
--- a/nwn/nwnprc/trunk/2das/feat.2da
+++ b/nwn/nwnprc/trunk/2das/feat.2da
@@ -2463,7 +2463,7 @@
2459 TactileTrapsmith 16824612 16824613 ife_lightflex **** **** **** **** **** **** **** **** **** **** 0 0 1 **** **** **** **** 1 **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
2460 AugmentHealing 16824614 16824615 ife_X1ResDis **** **** **** **** **** **** **** **** **** **** 0 0 1 **** **** **** **** 1 **** **** **** **** **** **** **** **** 4 4 **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
2461 DetectEvil 16827574 16827575 is_detect_evil **** **** **** **** **** **** **** **** **** **** 0 0 0 15 5 3201 **** 0.5 -1 **** **** **** **** **** **** **** **** **** **** **** FEAT_DEATH_DOMAIN_POWER 6 **** **** **** **** **** 0 1
-2462 InscribeRune 16831916 16831917 ife_X2PlnrTurn **** **** **** 13 **** **** **** **** **** **** 0 0 1 **** **** 1621 **** 1 **** **** 1 **** **** **** **** **** 38 1 **** **** FEAT_INSCRIBE_RUNE 4 **** **** **** **** **** 0 0
+2462 InscribeRune 16831916 16831917 ife_X2PlnrTurn **** **** **** 13 **** **** **** **** **** **** 0 0 1 **** **** 1621 **** 1 **** **** 1 **** **** **** **** **** 25 1 **** **** FEAT_INSCRIBE_RUNE 4 **** **** **** **** **** 0 0
2463 RuneCraft 16831973 16831974 ife_legendaryart **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
2464 RunePower 16831975 16831976 Ife_epMagmaBurst **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
2465 ImprovedRunecasting 16831977 16831978 ife_dweomerthief **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 1624 **** 1 -1 **** 1 **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 0
diff --git a/nwn/nwnprc/trunk/newcompilespells.bat b/nwn/nwnprc/trunk/newcompilespells.bat
new file mode 100644
index 00000000..d5b47834
--- /dev/null
+++ b/nwn/nwnprc/trunk/newcompilespells.bat
@@ -0,0 +1,33 @@
+REM echo Current dir: %cd%
+REM dir ..
+REM dir ..\psionics
+REM pause
+
+@ECHO OFF
+
+cls
+
+REM nwn_script_comp.exe -c -j4 -y -O0 --root "C:\Games\Steam\steamapps\common\Neverwinter Nights" --dirs "C:\Users\Jason\Documents\Neverwinter Nights\modules\temp0,D:\NWN Repos\PRC8\nwn\nwnprc\trunk\include" "C:\Users\Jason\Documents\Neverwinter Nights\modules\temp0"
+
+REM nwn_script_comp.exe -c -j4 -y --max-include-depth=32 ^
+ REM --root "C:\Games\Steam\steamapps\common\Neverwinter Nights" ^
+ REM --dirs ".\psionics,.\include" ^
+ REM -d ".\psionicsobjs" ^
+ REM ".\psionics"
+
+nwn_script_comp.exe -c -j4 -y . --max-include-depth=32 -d ".\spellobjs" --dirs ".\spells,.\include" ".\spells"
+
+
+REM :loop
+REM "C:\NWN Work\nwnsc.exe" -s -o -w -n "C:\Games\Steam\steamapps\common\Neverwinter Nights" -i "C:\Users\Jason\Documents\Neverwinter Nights\modules\temp0";"D:\NWN Repos\PRC8\nwn\nwnprc\trunk\include" "C:\Users\Jason\Documents\Neverwinter Nights\modules\temp0\*.nss"
+REM if %errorLevel% == -1 goto :loop
+pause
+
+
+
+REM @echo on
+
+REM tools\nwnsc -w -i "include" -n "C:\Games\Steam\steamapps\common\Neverwinter Nights" -b "psionicsobjs" "psionics\*.nss"
+REM tools\nwn_erf.exe -e hak --quiet -c -f CompiledResources\prc8_psionics.hak .\psionics .\psionicsobjs
+REM pause
+REM :end
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk
index 807192fd..63f9a6bd 100644
Binary files a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk and b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk differ
diff --git a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml
index b3fb7cde..6741d990 100644
--- a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml
+++ b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml
@@ -40753,7 +40753,7 @@ Epic Levels:
####END_OF_NEW_SPELLBOOK_RESERVE
Inscribe Rune
Type of Feat: Item Creation
-Prerequisite: Intelligence 13, Divine Spells level 2.
+Prerequisite: Intelligence 13, Divine Spells level 2, Craft Armor 1 rank
Specifics: You can cast any divine spell you have prepared as a rune. The caster must have the spell memorized to be able to create the rune. Crafting a rune costs Spell level * Caster level * 50 in gold pieces for a normal caster (half the base cost of Spell level * Caster level * 100), and Spell level * Caster level * 25 for a Runecaster (half again). It also takes XP equal to 1/25th of the base cost. If you cannot pay the casting cost or the XP loss would drop you a level, the crafting will fail, and the spell will be lost. Crafting the rune requires a craft check vs DC 20 + Spell Level. If the craft check fails, the spell is lost, but the caster does not pay the gold and experience. A rune is permanent until used, and all spells are centred on the user.
Use: Selected.
Cast Rune
diff --git a/nwn/nwnprc/trunk/tlk/prc_consortium.tlk b/nwn/nwnprc/trunk/tlk/prc_consortium.tlk
index 807192fd..63f9a6bd 100644
Binary files a/nwn/nwnprc/trunk/tlk/prc_consortium.tlk and b/nwn/nwnprc/trunk/tlk/prc_consortium.tlk differ
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_epicspellfnc.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_epicspellfnc.nss
new file mode 100644
index 00000000..151392d4
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_epicspellfnc.nss
@@ -0,0 +1,274 @@
+
+int GetFeatForSeed(int nSeedID);
+int GetIPForSeed(int nSeedID);
+int GetDCForSeed(int nSeedID);
+int GetClassForSeed(int nSeedID);
+int GetCanLearnSeed(object oPC, int nSeedID);
+int GetSeedFromAbrev(string sAbrev);
+string GetNameForSeed(int nSeedID);
+
+int GetDCForSpell(int nSpellID);
+int GetFeatForSpell(int nSpellID);
+int GetResearchFeatForSpell(int nSpellID);
+int GetIPForSpell(int nSpellID);
+int GetResearchIPForSpell(int nSpellID);
+int GetCastXPForSpell(int nSpellID);
+string GetSchoolForSpell(int nSpellID);
+int GetR1ForSpell(int nSpellID);
+int GetR2ForSpell(int nSpellID);
+int GetR3ForSpell(int nSpellID);
+int GetR4ForSpell(int nSpellID);
+string GetNameForSpell(int nSpellID);
+int GetSpellFromAbrev(string sAbrev);
+
+//////////////////////////////////////////////////
+/* Includes */
+//////////////////////////////////////////////////
+
+#include "inc_utility"
+//#include "inc_epicspelldef"
+#include "inc_epicspells"
+
+// SEED FUNCTIONS
+
+int GetFeatForSeed(int nSeedID)
+{
+ return StringToInt(Get2DACache("epicspellseeds", "FeatID", nSeedID));
+}
+
+int GetIPForSeed(int nSeedID)
+{
+ return StringToInt(Get2DACache("epicspellseeds", "FeatIPID", nSeedID));
+}
+
+int GetDCForSeed(int nSeedID)
+{
+ return StringToInt(Get2DACache("epicspellseeds", "DC", nSeedID));
+}
+
+int GetClassForSeed(int nSeedID)
+{
+ return StringToInt(Get2DACache("epicspellseeds", "Class", nSeedID));
+}
+
+int GetSeedFromAbrev(string sAbrev)
+{
+ sAbrev = GetStringLowerCase(sAbrev);
+ if(GetStringLeft(sAbrev, 8) == "epic_sd_")
+ sAbrev = GetStringRight(sAbrev, GetStringLength(sAbrev)-8);
+ int i = 0;
+ string sLabel = GetStringLowerCase(Get2DACache("epicspellseeds", "LABEL", i));
+ while(sLabel != "")
+ {
+ if(sAbrev == sLabel)
+ return i;
+ i++;
+ sLabel = GetStringLowerCase(Get2DACache("epicspellseeds", "LABEL", i));
+ }
+ return -1;
+}
+
+string GetNameForSeed(int nSeedID)
+{
+ int nFeat = GetFeatForSeed(nSeedID);
+ string sName = GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat)));
+ return sName;
+}
+
+/*
+Bit-flags set in epicspellseeds.2da in Class column
+used to restrict access to epic spell seeds for some classes
+ie: 13 means that only clerics, sorcerers and wizards can learn that seed (1 + 4 + 8),
+all classes can use == 32767
+*/
+int _Class2BitFlag(int nClass)
+{
+ switch(nClass)
+ {
+ case CLASS_TYPE_CLERIC: return 1;
+ case CLASS_TYPE_DRUID: return 2;
+ case CLASS_TYPE_SORCERER: return 4;
+ case CLASS_TYPE_WIZARD: return 8;
+ case CLASS_TYPE_HEALER: return 16;
+ case CLASS_TYPE_BEGUILER: return 32;
+ case CLASS_TYPE_SUBLIME_CHORD: return 64;
+ case CLASS_TYPE_DREAD_NECROMANCER: return 128;
+ case CLASS_TYPE_MYSTIC: return 256;
+ case CLASS_TYPE_ARCHIVIST: return 512;
+ case CLASS_TYPE_SHAMAN: return 4096;
+ case CLASS_TYPE_FAVOURED_SOUL: return 8192;
+ case CLASS_TYPE_WARMAGE: return 16384;
+ case CLASS_TYPE_UR_PRIEST: return 1;
+ case CLASS_TYPE_BLIGHTER: return 2;
+ }
+ return -1;
+}
+
+int _CheckEpicSpellcastingForClass(object oPC, int nClass)
+{
+ if(GetHitDice(oPC) < 21)
+ return FALSE;
+
+ switch(nClass)
+ {
+ case CLASS_TYPE_CLERIC: return GetIsEpicCleric(oPC);
+ case CLASS_TYPE_DRUID: return GetIsEpicDruid(oPC);
+ case CLASS_TYPE_SORCERER: return GetIsEpicSorcerer(oPC);
+ case CLASS_TYPE_WIZARD: return GetIsEpicWizard(oPC);
+ case CLASS_TYPE_HEALER: return GetIsEpicHealer(oPC);
+ case CLASS_TYPE_BEGUILER: return GetIsEpicBeguiler(oPC);
+ case CLASS_TYPE_SUBLIME_CHORD: return GetIsEpicSublimeChord(oPC);
+ case CLASS_TYPE_DREAD_NECROMANCER: return GetIsEpicDreadNecromancer(oPC);
+ case CLASS_TYPE_ARCHIVIST: return GetIsEpicArchivist(oPC);
+ case CLASS_TYPE_SHAMAN: return GetIsEpicShaman(oPC);
+ case CLASS_TYPE_FAVOURED_SOUL: return GetIsEpicFavSoul(oPC);
+ case CLASS_TYPE_WARMAGE: return GetIsEpicWarmage(oPC);
+ case CLASS_TYPE_BLIGHTER: return GetIsEpicBlighter(oPC);
+ case CLASS_TYPE_UR_PRIEST: return GetIsEpicUrPriest(oPC);
+ }
+ return FALSE;
+}
+
+int GetCanLearnSeed(object oPC, int nSeedID)
+{
+ int nRestr = GetClassForSeed(nSeedID);
+ int i, nClass;
+ for(i = 1; i <= 8; i++)
+ {
+ nClass = GetClassByPosition(i, oPC);
+ if(_CheckEpicSpellcastingForClass(oPC, nClass)//this class has epic spellcasting
+ && (nRestr & _Class2BitFlag(nClass)))//and was added to class column in epicspellseeds.2da
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// SPELL FUNCTIONS
+
+int GetDCForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "DC", nSpellID));
+}
+
+int GetFeatForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "SpellFeatID", nSpellID));
+}
+
+int GetResearchFeatForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "ResFeatID", nSpellID));
+}
+
+int GetIPForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "SpellFeatIPID", nSpellID));
+}
+
+int GetResearchIPForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "ResFeatIPID", nSpellID));
+}
+
+int GetCastXPForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "CastingXP", nSpellID));
+}
+
+string GetSchoolForSpell(int nSpellID)
+{
+ return Get2DACache("epicspells", "School", nSpellID);
+}
+
+int GetR1ForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "Prereq1", nSpellID));
+}
+
+int GetR2ForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "Prereq2", nSpellID));
+}
+
+int GetR3ForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "Prereq3", nSpellID));
+}
+
+int GetR4ForSpell(int nSpellID)
+{
+ return StringToInt(Get2DACache("epicspells", "Prereq4", nSpellID));
+}
+
+int GetS1ForSpell(int nSpellID)
+{
+ string sSeed = Get2DACache("epicspells", "PrereqSeed1", nSpellID);
+ if(sSeed == "")
+ return -1;
+ return StringToInt(sSeed);
+}
+
+int GetS2ForSpell(int nSpellID)
+{
+ string sSeed = Get2DACache("epicspells", "PrereqSeed2", nSpellID);
+ if(sSeed == "")
+ return -1;
+ return StringToInt(sSeed);
+}
+
+int GetS3ForSpell(int nSpellID)
+{
+ string sSeed = Get2DACache("epicspells", "PrereqSeed3", nSpellID);
+ if(sSeed == "")
+ return -1;
+ return StringToInt(sSeed);
+}
+
+int GetS4ForSpell(int nSpellID)
+{
+ string sSeed = Get2DACache("epicspells", "PrereqSeed4", nSpellID);
+ if(sSeed == "")
+ return -1;
+ return StringToInt(sSeed);
+}
+
+int GetS5ForSpell(int nSpellID)
+{
+ string sSeed = Get2DACache("epicspells", "PrereqSeed5", nSpellID);
+ if(sSeed == "")
+ return -1;
+ return StringToInt(sSeed);
+}
+
+int GetSpellFromAbrev(string sAbrev)
+{
+ sAbrev = GetStringLowerCase(sAbrev);
+ if(GetStringLeft(sAbrev, 8) == "epic_sp_")
+ sAbrev = GetStringRight(sAbrev, GetStringLength(sAbrev)-8);
+ if(DEBUG) DoDebug("sAbrev to check vs: " + sAbrev);
+ int i = 0;
+ string sLabel = GetStringLowerCase(Get2DACache("epicspells", "LABEL", i));
+ while(sLabel != "")
+ {
+ if(DEBUG) DoDebug("sLabel to check vs: " + sLabel);
+ if(sAbrev == sLabel)
+ {
+ if(DEBUG) DoDebug("SpellID: " + IntToString(i));
+ return i;
+ }
+ i++;
+ sLabel = GetStringLowerCase(Get2DACache("epicspells", "LABEL", i));
+ }
+ return -1;
+}
+
+string GetNameForSpell(int nSpellID)
+{
+ int nFeat = GetFeatForSpell(nSpellID);
+ string sName = GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat)));
+ return sName;
+}
+
+//:: void main (){}
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_rend.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_rend.nss
new file mode 100644
index 00000000..d54d46a8
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_rend.nss
@@ -0,0 +1,239 @@
+//::///////////////////////////////////////////////
+//:: Rend OnHit include
+//:: inc_rend
+//:://////////////////////////////////////////////
+//:://////////////////////////////////////////////
+//:: Created By: Ornedan
+//:: Created On: 23.01.2005
+//:://////////////////////////////////////////////
+
+//////////////////////////////////////////////////
+/* Constant defintions */
+//////////////////////////////////////////////////
+
+const string REND_1ST_HIT_DONE = "RendingHit1stHit";
+const string REND_DONE = "RendingHitDone";
+
+const string FROST_1ST_HIT_DONE = "FrostRendHit1stHit";
+const string FROST_DONE = "FrostRendHitDone";
+
+const string SPINE_1ST_HIT_DONE = "SpineRendHit1stHit";
+const string SPINE_DONE = "SpineRendHitDone";
+
+int GetMainHandAttacks(object oPC, int iBABBonus = 0, int bIgnoreCrossBow = FALSE);
+
+//////////////////////////////////////////////////
+/* Function prototypes */
+//////////////////////////////////////////////////
+
+void DoRend(object oTarget, object oAttacker, object oWeapon);
+int GetDamageFromConstant(int nIPConst);
+
+void DoFrostRend(object oTarget, object oAttacker, object oWeapon);
+
+#include "moi_inc_moifunc"
+
+//////////////////////////////////////////////////
+/* Function defintions */
+//////////////////////////////////////////////////
+
+void DoRend(object oTarget, object oAttacker, object oWeapon)
+{
+ if (DEBUG) DoDebug("DoRend running");
+ // Only one rend allowed per round for the sake of clearness
+ if(GetLocalInt(oAttacker, REND_DONE))
+ return;
+
+ if(GetLocalObject(oAttacker, REND_1ST_HIT_DONE) == oTarget)
+ {
+ if (DEBUG) DoDebug("DoRend second hit");
+ // First, find the weapon base damage
+ int nIPConst;
+ itemproperty ipCheck = GetFirstItemProperty(oWeapon);
+ while(GetIsItemPropertyValid(ipCheck))
+ {
+ if(GetItemPropertyType(ipCheck) == ITEM_PROPERTY_MONSTER_DAMAGE)
+ {
+ nIPConst = GetItemPropertyCostTableValue(ipCheck);
+ break;
+ }
+ ipCheck = GetNextItemProperty(oWeapon);
+ }
+
+ int nDamage = GetDamageFromConstant(nIPConst);
+ int nStrBon = GetAbilityModifier(ABILITY_STRENGTH, oAttacker);
+ nStrBon = nStrBon < 0 ? 0 : nStrBon;
+ nDamage += nStrBon;
+ if (GetLevelByClass(CLASS_TYPE_BLACK_BLOOD_CULTIST, oAttacker) >= 6) nDamage *= 2;
+ if (GetIsMeldBound(oAttacker, MELD_GIRALLON_ARMS) == CHAKRA_ARMS) nDamage *= 2;
+ if (GetHasSpellEffect(VESTIGE_IPOS, oAttacker) >= 6) nDamage *= 2;
+
+ int nDamageType;
+ switch(GetBaseItemType(oWeapon))
+ {
+ case BASE_ITEM_CBLUDGWEAPON:
+ nDamageType = DAMAGE_TYPE_BLUDGEONING;
+ break;
+ case BASE_ITEM_CPIERCWEAPON:
+ nDamageType = DAMAGE_TYPE_PIERCING;
+ break;
+ // Both slashing and slashing & piercing weapons do slashing damage from rend
+ // because it's not possible to make the damage be of both types in any
+ // elegant way
+ case BASE_ITEM_CSLASHWEAPON:
+ case BASE_ITEM_CSLSHPRCWEAP:
+ nDamageType = DAMAGE_TYPE_SLASHING;
+ break;
+
+ default:
+ WriteTimestampedLogEntry("Unexpected weapon type in DoRend()!");
+ return;
+ }
+
+ // Apply damage and VFX
+ effect eDamage = EffectDamage(nDamage, nDamageType);
+ effect eLink = EffectLinkEffects(eDamage, EffectVisualEffect(VFX_COM_BLOOD_CRT_RED));
+
+ ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget);
+
+ // Tell people what happened
+ // * AttackerName rends TargetName *
+ FloatingTextStringOnCreature("* " + GetName(oAttacker) + " " + GetStringByStrRef(0x01000000 + 51197) + " " + GetName(oTarget) + " *", oAttacker, TRUE);
+
+ // Note the rend having happened in the locals
+ SetLocalInt(oAttacker, REND_DONE, TRUE);
+ DelayCommand(4.5, DeleteLocalInt(oAttacker, REND_DONE));
+ }// end if - the target had a local signifying that rend is possible
+ else
+ {
+ SetLocalObject(oAttacker, REND_1ST_HIT_DONE, oTarget);
+ if (DEBUG) DoDebug("DoRend first hit");
+ }
+}
+
+void DoFrostRend(object oTarget, object oAttacker, object oWeapon)
+{
+ // Only one rend allowed per round for the sake of clearness
+ if(GetLocalInt(oAttacker, FROST_DONE))
+ return;
+
+ float fDelay1 = 6.0 - (6.0 / GetMainHandAttacks(oAttacker));
+ float fDelay2 = 6.0 - 2 * (6.0 - fDelay1);
+
+ if(GetLocalObject(oAttacker, FROST_1ST_HIT_DONE) == oTarget)
+ {
+ // First, find the weapon base damage
+ int nIPConst;
+ itemproperty ipCheck = GetFirstItemProperty(oWeapon);
+ while(GetIsItemPropertyValid(ipCheck))
+ {
+ if(GetItemPropertyType(ipCheck) == ITEM_PROPERTY_MONSTER_DAMAGE)
+ {
+ nIPConst = GetItemPropertyCostTableValue(ipCheck);
+ break;
+ }
+ ipCheck = GetNextItemProperty(oWeapon);
+ }
+
+
+ int nDamage = GetDamageFromConstant(nIPConst);
+ int nStrBon = GetAbilityModifier(ABILITY_STRENGTH, oAttacker);
+ nStrBon = nStrBon < 0 ? 0 : nStrBon;
+ // nDamage += nStrBon;
+ // nDamage += FloatToInt(nStrBon/2); //1.5x Strength damage
+ nDamage += FloatToInt(nStrBon * 1.5);
+
+ int nDamageType = DAMAGE_TYPE_BLUDGEONING; // It's an unarmed strike, so always bludgeoning for this
+
+ // Apply damage and VFX
+ effect eDamage = EffectDamage(nDamage, nDamageType);
+ effect eLink = EffectLinkEffects(eDamage, EffectVisualEffect(VFX_IMP_FROST_L));
+ eLink = EffectLinkEffects(eLink, EffectDamage(d6(), DAMAGE_TYPE_COLD));
+
+ ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget);
+
+ // Tell people what happened
+ // * AttackerName rends TargetName *
+ FloatingTextStringOnCreature("* " + GetName(oAttacker) + " " + GetStringByStrRef(0x01000000 + 51197) + " " + GetName(oTarget) + " *",
+ oAttacker,
+ TRUE);
+
+ // Note the rend having happened in the locals
+ SetLocalInt(oAttacker, FROST_DONE, TRUE);
+ DelayCommand(fDelay2, DeleteLocalInt(oAttacker, FROST_DONE));
+ }// end if - the target had a local signifying that rend is possible
+ else
+ {
+ SetLocalObject(oAttacker, FROST_1ST_HIT_DONE, oTarget);
+ DelayCommand(fDelay1, DeleteLocalObject(oAttacker, FROST_1ST_HIT_DONE));
+ }
+}
+
+void DoSpineRend(object oTarget, object oAttacker, object oWeapon)
+{
+ // Only one rend allowed per round for the sake of clearness
+ if(GetLocalInt(oAttacker, SPINE_DONE))
+ return;
+
+ float fDelay1 = 6.0 - (6.0 / GetMainHandAttacks(oAttacker));
+ float fDelay2 = 6.0 - 2 * (6.0 - fDelay1);
+
+ if(GetLocalObject(oAttacker, SPINE_1ST_HIT_DONE) == oTarget)
+ {
+ int nStrBon = GetAbilityModifier(ABILITY_STRENGTH, oAttacker);
+ nStrBon = nStrBon < 0 ? 0 : nStrBon;
+ int nDamage = FloatToInt(nStrBon * 1.5);
+
+ // Apply damage and VFX
+ effect eDamage = EffectDamage(nDamage + d6(2), DAMAGE_TYPE_PIERCING);
+ effect eLink = EffectLinkEffects(eDamage, EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM));
+
+ ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget);
+
+ // Tell people what happened
+ // * AttackerName rends TargetName *
+ FloatingTextStringOnCreature("* " + GetName(oAttacker) + " " + GetStringByStrRef(0x01000000 + 51197) + " " + GetName(oTarget) + " *", oAttacker, TRUE);
+
+ // Note the rend having happened in the locals
+ SetLocalInt(oAttacker, SPINE_DONE, TRUE);
+ DelayCommand(fDelay2, DeleteLocalInt(oAttacker, SPINE_DONE));
+ }// end if - the target had a local signifying that rend is possible
+ else
+ {
+ SetLocalObject(oAttacker, SPINE_1ST_HIT_DONE, oTarget);
+ DelayCommand(fDelay1, DeleteLocalObject(oAttacker, SPINE_1ST_HIT_DONE));
+ }
+}
+
+int GetDamageFromConstant(int nIPConst)
+{
+ // First, handle the values outside the main series
+ switch(nIPConst)
+ {
+ case IP_CONST_MONSTERDAMAGE_1d2: return d2(1);
+ case IP_CONST_MONSTERDAMAGE_1d3: return d3(1);
+ case IP_CONST_MONSTERDAMAGE_1d4: return d4(1);
+ case IP_CONST_MONSTERDAMAGE_2d4: return d4(2);
+ case IP_CONST_MONSTERDAMAGE_3d4: return d4(3);
+ case IP_CONST_MONSTERDAMAGE_4d4: return d4(4);
+ case IP_CONST_MONSTERDAMAGE_5d4: return d4(5);
+ case IP_CONST_MONSTERDAMAGE_7d4: return d4(7);
+ }
+
+
+ int nDieNum = ((nIPConst - 8) % 10) + 1;
+
+ switch((nIPConst - 8) / 10)
+ {
+ case 0: return d6(nDieNum);
+ case 1: return d8(nDieNum);
+ case 2: return d10(nDieNum);
+ case 3: return d12(nDieNum);
+ case 4: return d20(nDieNum);
+ }
+
+ WriteTimestampedLogEntry("Unknown IP_CONST_MONSTERDAMAGE_* constant passed to GetDamageFromConstant()!");
+ return 0;
+}
+
+//:: void main (){}
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_sp_gain_mem.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_sp_gain_mem.nss
new file mode 100644
index 00000000..8bce82e0
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_sp_gain_mem.nss
@@ -0,0 +1,384 @@
+//:://////////////////////////////////////////////
+//:: Name: new spellbook spellgain / spell memorization include
+//:: File: inc_sp_gain_mem.nss
+//:://////////////////////////////////////////////
+/**
+contains helper functions for the two dynamic conversation scripts
+- prc_s_spellb.nss
+- prc_s_spellgain.nss
+that handle learning / gaining new spells at level up (prc_s_spellgain)
+or preparing what spells to learn at next rest (prc_s_spellb)
+
+Author: motu99
+Created: May 1, 2008
+*/
+
+//#include "prc_inc_core" //granted access via parent (inc_newspellbook)
+#include "prc_inc_switch"
+#include "inc_debug"
+
+//:: Updated for .35 by Jaysyn 2023/03/11
+
+//:: Test Void
+//void main (){}
+
+//:://////////////////////////////////////////////
+//:: Constants
+//:://////////////////////////////////////////////
+
+// max. number of classes a PC (or creature) can take (8 for NWN, 4 for NWN2)
+const int MAX_CLASSES = 8;
+
+//////////////////////////////////////////////////
+/* Aid functions */
+//////////////////////////////////////////////////
+
+string GetNSBDefinitionFileName(int nClass);
+int GetCasterLevelByClass(int nClass, object oPC);
+
+int GetSpellsKnown_MaxCount(int nCasterLevel, int nClass, int nSpellLevel, object oPC);
+int GetSpellsInClassSpellbook_Count(int nClass, int nSpellLevel);
+string GetClassString(int nClass);
+int GetMaxSpellLevelForCasterLevel(int nClass, int nCasterLevel);
+int GetMinSpellLevelForCasterLevel(int nClass, int nCasterLevel);
+
+void WipeSpellFromHide(int nIPFeatID, object oPC);
+
+string GetSpellsKnown_Array(int nClass, int nSpellLevel = -1);
+object GetSpellsOfClass_Token(int nClass, int nSpellLevel);
+string GetSpellsOfClass_Array();
+string GetSpellsMemorized_Array(int nClass);
+string GetSpellsToBeMemorized_Array(int nClass, int nSpellSlotLevel);
+
+void array_set_size(object oPC, string sArrayName, int nSize);
+int array_has_string(object oPC, string sArrayName, string sValue, int nFirst = 0, int nSize = 0);
+int array_has_int(object oPC, string sArrayName, int nValue, int nFirst = 0, int nSize = 0);
+int persistant_array_has_string(object oPC, string sArrayName, string sValue, int nFirst = 0, int nSize = 0);
+int persistant_array_has_int(object oPC, string sArrayName, int nValue, int nFirst = 0, int nSize = 0);
+int array_extract_string(object oPC, string sArrayName, string sValue, int nFirst = 0);
+int array_extract_int(object oPC, string sArrayName, int nValue, int nFirst = 0);
+int persistant_array_extract_string(object oPC, string sArrayName, string sValue, int nFirst = 0);
+int persistant_array_extract_int(object oPC, string sArrayName, int nValue, int nFirst = 0);
+
+string GetMetaMagicString_Short(int nMetaMagic);
+string GetMetaMagicString(int nMetaMagic);
+int GetMetaMagicFromFeat(int nFeat);
+int GetMetaMagicOfCaster(object oPC = OBJECT_SELF);
+
+string DebugIProp2Str(itemproperty iprop);
+void DoDebug(string sString, object oAdditionalRecipient = OBJECT_INVALID);
+int GetSpellbookTypeForClass(int nClass);
+string GetFileForClass(int nClass);
+int GetSpellslotLevel(int nClass, object oPC);
+int GetSpellKnownMaxCount(int nCasterLevel, int nSpellLevel, int nClass, object oPC);
+int persistant_array_get_size(object store, string name);
+string Get2DACache(string s2DA, string sColumn, int nRow);
+object GetPCSkin(object oPC);
+void SetPersistantLocalInt(object oPC, string sName, int nValue);
+int GetPersistantLocalInt(object oPC, string sName);
+void SetPersistantLocalString(object oPC, string sName, string sValue);
+string GetPersistantLocalString(object oPC, string sName);
+
+
+
+// name of the new spellbook file (cls_spell_*)
+string GetNSBDefinitionFileName(int nClass)
+{
+ return GetFileForClass(nClass);
+}
+
+// gets the caster level (without special modifications due to feats), by which the max spell slot level is determined
+int GetCasterLevelByClass(int nClass, object oPC)
+{
+ return GetSpellslotLevel(nClass, oPC);
+ // return GetPrCAdjustedCasterLevel(nClass, oPC, TRUE);
+}
+
+// gets the maximum nr of spells that oPC can know with a given nCasterLevel, nClass and nSpellLevel
+int GetSpellsKnown_MaxCount(int nCasterLevel, int nClass, int nSpellLevel, object oPC)
+{
+ return GetSpellKnownMaxCount(nCasterLevel, nSpellLevel, nClass, oPC);
+}
+
+
+// gets the total nr of spells available at nSpellLevel for nClass
+int GetSpellsInClassSpellbook_Count(int nClass, int nSpellLevel)
+{
+ return persistant_array_get_size(GetSpellsOfClass_Token(nClass, nSpellLevel), GetSpellsOfClass_Array());
+}
+
+string GetClassString(int nClass)
+{
+ // get the name of the feats table 2da
+ string sClass = Get2DACache("classes", "FeatsTable", nClass);
+ // truncate the first 8 characters (the "cls_feat" part), leaving the "_" part
+ sClass = GetStringRight(sClass, GetStringLength(sClass) - 8);
+ return sClass;
+}
+
+// gets the maximum spell level that nClass can cast at nCasterLevel
+int GetMaxSpellLevelForCasterLevel(int nClass, int nCasterLevel)
+{
+ string sFile;
+ // Bioware casters use their classes.2da-specified tables
+ //if(GetIsBioSpellCastClass(nClass))
+ //{
+ sFile = Get2DACache("classes", "SpellGainTable", nClass);
+ //}
+ //else
+ //{
+ // sFile = "cls_spbk" + GetClassString(nClass);
+ //}
+
+ // row nr in the files is nCasterLevel minus 1
+ nCasterLevel--;
+ int nSpellLevel;
+
+ if (Get2DACache(sFile, "NumSpellLevels", 9) != "")
+ {
+ string sTemp = Get2DACache(sFile, "NumSpellLevels", nCasterLevel);
+ if (sTemp != "")
+ {
+ nSpellLevel = StringToInt(sTemp)-1;
+ if (nSpellLevel <= 0) nSpellLevel = 0;
+ }
+ }
+ else
+ {
+ for (nSpellLevel=9; nSpellLevel >= 0; nSpellLevel--)
+ {
+ string sTemp = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nCasterLevel);
+ if (sTemp != "")
+ {
+ break;
+ }
+ }
+ }
+ return nSpellLevel;
+}
+
+// gets the minimum spell level that nClass can cast at nCasterLevel
+int GetMinSpellLevelForCasterLevel(int nClass, int nCasterLevel)
+{
+ string sFile;
+ // Bioware casters use their classes.2da-specified tables
+ //if(GetIsBioSpellCastClass(nClass))
+ //{
+ sFile = Get2DACache("classes", "SpellGainTable", nClass);
+ //}
+ //else
+ //{
+ // sFile = "cls_spbk" + GetClassString(nClass);
+ //}
+
+ // row nr in the files is nCasterLevel minus 1
+ nCasterLevel--;
+
+ int bFound = 0;
+
+ int nSpellLevel;
+ for (nSpellLevel=0; nSpellLevel <= 9; nSpellLevel++)
+ {
+ string sTemp = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nCasterLevel);
+ if (sTemp != "")
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+
+ if (!bFound) nSpellLevel = -1;
+ return nSpellLevel;
+}
+
+// wipes the IPbonusfeat from the hide
+void WipeSpellFromHide(int nIPFeatID, object oPC)
+{
+ // go through all item properties on the hide
+ object oHide = GetPCSkin(oPC);
+ itemproperty ipTest = GetFirstItemProperty(oHide);
+ while(GetIsItemPropertyValid(ipTest))
+ {
+ // is it a bonus feat?
+ if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_BONUS_FEAT)
+ {
+ // get the row nr of the bonus feat in iprp_feat.2da
+ // is it the ipfeat to delete?
+ if (GetItemPropertySubType(ipTest) == nIPFeatID)
+ {
+ RemoveItemProperty(oHide, ipTest);
+ if(DEBUG) DoDebug("WipeSpellFromHide: Removing item property " + DebugIProp2Str(ipTest));
+ }
+ }
+ ipTest = GetNextItemProperty(oHide);
+ }
+}
+
+// one array for each class (array holds all spell levels, but only non-metamagicked masterspells)
+string GetSpellsKnown_Array(int nClass, int nSpellLevel = -1)
+{
+ int nSpellbookType = GetSpellbookTypeForClass(nClass);
+ if(nSpellbookType == 1) //SPELLBOOK_TYPE_PREPARED
+ return "Spellbook_Known_" + IntToString(nClass) + "_" + IntToString(nSpellLevel);
+ return "Spellbook" + IntToString(nClass);
+}
+
+// class spellbook (one storage token for each spell level and class)
+object GetSpellsOfClass_Token(int nClass, int nSpellLevel)
+{
+ return GetObjectByTag("SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel));
+}
+
+string GetSpellsOfClass_Array()
+{
+ return "Lkup";
+}
+
+string GetSpellsMemorized_Array(int nClass)
+{
+ return "NewSpellbookMem_" + IntToString(nClass);
+}
+
+string GetSpellsToBeMemorized_Array(int nClass, int nSpellSlotLevel)
+{
+ return "Spellbook" + IntToString(nSpellSlotLevel) + "_" + IntToString(nClass);
+}
+
+
+void array_set_size(object oPC, string sArrayName, int nSize)
+{
+ SetPersistantLocalInt(oPC, sArrayName, nSize+1);
+}
+
+int array_has_string(object oPC, string sArrayName, string sValue, int nFirst = 0, int nSize = 0)
+{
+ // get array size, if size not already supplied
+ if (nSize == 0) nSize = GetPersistantLocalInt(oPC, sArrayName) -1;
+ int i;
+
+ for (i = nFirst; i < nSize; i++)
+ {
+ if (sValue == GetPersistantLocalString(oPC, sArrayName + "_" + IntToString(i)))
+ return i;
+ }
+ return -1;
+}
+
+int array_has_int(object oPC, string sArrayName, int nValue, int nFirst = 0, int nSize = 0)
+{
+ // array values are stored as strings, so convert nValue to a string
+ return array_has_string(oPC, sArrayName, IntToString(nValue), nFirst, nSize);
+}
+
+int persistant_array_has_string(object oPC, string sArrayName, string sValue, int nFirst = 0, int nSize = 0)
+{
+ return array_has_string(oPC, sArrayName, sValue, nFirst, nSize);
+}
+
+int persistant_array_has_int(object oPC, string sArrayName, int nValue, int nFirst = 0, int nSize = 0)
+{
+ return array_has_string(oPC, sArrayName, IntToString(nValue), nFirst, nSize);
+}
+
+int array_extract_string(object oPC, string sArrayName, string sValue, int nFirst = 0)
+{
+ // get array size
+ int nSize = GetPersistantLocalInt(oPC, sArrayName)-1;
+ if (nSize <= nFirst) return -1;
+
+ // position of the first found; -1 if not found
+ int nPos = array_has_string(oPC, sArrayName, sValue, nFirst, nSize);
+ if (nPos < 0) return -1;
+
+ // Is is not the last element?
+ if (nPos < nSize-1)
+ {
+ // then swap nPos (or rather nPos-1) with the last element (nSize-1)
+ string sTemp = GetPersistantLocalString(oPC, sArrayName + "_" + IntToString(nSize-1));
+ SetPersistantLocalString(oPC, sArrayName + "_" + IntToString(nPos), sTemp);
+ }
+
+ // now decrement the array size (note that we already subtracted one in the beginning)
+ SetPersistantLocalInt(oPC, sArrayName, nSize);
+
+ return nPos;
+}
+
+// extracts the integer value nValue from a persistant sArray on oPC
+// extracts the first instance of nValue that it finds
+// extracts it by swapping the last array element to the position of the extracted element and reducing the array size by one
+// returns the position where the extracted element was found
+int array_extract_int(object oPC, string sArrayName, int nValue, int nFirst = 0)
+{
+ // array values are stored as strings, so convert nValue to a string
+ return array_extract_string(oPC, sArrayName, IntToString(nValue), nFirst);
+}
+
+int persistant_array_extract_string(object oPC, string sArrayName, string sValue, int nFirst = 0)
+{
+ return array_extract_string(oPC, sArrayName, sValue, nFirst);
+}
+
+int persistant_array_extract_int(object oPC, string sArrayName, int nValue, int nFirst = 0)
+{
+ // array values are stored as strings, so convert nValue to a string
+ return array_extract_string(oPC, sArrayName, IntToString(nValue), nFirst);
+}
+
+string GetMetaMagicString_Short(int nMetaMagic)
+{
+ string s;
+ if (nMetaMagic == 0) return s;
+
+ if (nMetaMagic & METAMAGIC_EXTEND) s += "ext ";
+ if (nMetaMagic & METAMAGIC_SILENT) s += "sil ";
+ if (nMetaMagic & METAMAGIC_STILL) s += "sti ";
+ if (nMetaMagic & METAMAGIC_EMPOWER) s += "emp ";
+ if (nMetaMagic & METAMAGIC_MAXIMIZE) s += "max ";
+ if (nMetaMagic & METAMAGIC_QUICKEN) s += "qui ";
+
+ return GetStringLeft(s, GetStringLength(s)-1);
+}
+
+string GetMetaMagicString(int nMetaMagic)
+{
+ string s;
+ if (nMetaMagic == 0) return s;
+
+ if (nMetaMagic & METAMAGIC_EXTEND) s += "extend ";
+ if (nMetaMagic & METAMAGIC_SILENT) s += "silent ";
+ if (nMetaMagic & METAMAGIC_STILL) s += "still ";
+ if (nMetaMagic & METAMAGIC_EMPOWER) s += "empower ";
+ if (nMetaMagic & METAMAGIC_MAXIMIZE) s += "maximize ";
+ if (nMetaMagic & METAMAGIC_QUICKEN) s += "quicken ";
+
+ return GetStringLeft(s, GetStringLength(s)-1);
+}
+
+int GetMetaMagicFromFeat(int nFeat)
+{
+ switch(nFeat)
+ {
+ case FEAT_EMPOWER_SPELL: return METAMAGIC_EMPOWER;
+ case FEAT_EXTEND_SPELL: return METAMAGIC_EXTEND;
+ case FEAT_MAXIMIZE_SPELL: return METAMAGIC_MAXIMIZE;
+ case FEAT_QUICKEN_SPELL: return METAMAGIC_QUICKEN;
+ case FEAT_SILENCE_SPELL: return METAMAGIC_SILENT;
+ case FEAT_STILL_SPELL: return METAMAGIC_STILL;
+ }
+ return METAMAGIC_NONE;
+}
+
+int GetMetaMagicOfCaster(object oPC = OBJECT_SELF)
+{
+ int nMetaMagic;
+
+ if (GetHasFeat(FEAT_EMPOWER_SPELL, oPC)) nMetaMagic |= METAMAGIC_EMPOWER;
+ if (GetHasFeat(FEAT_EXTEND_SPELL, oPC)) nMetaMagic |= METAMAGIC_EXTEND;
+ if (GetHasFeat(FEAT_MAXIMIZE_SPELL, oPC)) nMetaMagic |= METAMAGIC_MAXIMIZE;
+ if (GetHasFeat(FEAT_QUICKEN_SPELL, oPC)) nMetaMagic |= METAMAGIC_QUICKEN;
+ if (GetHasFeat(FEAT_SILENCE_SPELL, oPC)) nMetaMagic |= METAMAGIC_SILENT;
+ if (GetHasFeat(FEAT_STILL_SPELL, oPC)) nMetaMagic |= METAMAGIC_STILL;
+
+ return nMetaMagic;
+}
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_switch_setup.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_switch_setup.nss
new file mode 100644
index 00000000..51a489e0
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inc_switch_setup.nss
@@ -0,0 +1,1156 @@
+/** @file inc_switch_setup
+ Functions for switch setups. Most only used on
+ mod load. Get/Set individual switches is done
+ via prc_inc_switch.
+ DO NOT include this file if you just want to
+ use Set/GetPRCSwitch as it's not needed.
+*/
+
+//////////////////////////////////////////////////
+/* Function prototypes */
+//////////////////////////////////////////////////
+
+/**
+ * Controls which itemproperties can be added to
+ * the samurai weapon.
+ * @see PRC_SAMURAI_BAN_ in prc_inc_switch and the
+ * function difinition for more info.
+ */
+void DoSamuraiBanDefaults();
+
+/**
+ * Sets the epic spell switches to their default values.
+ *
+ * If PRC_EPIC_INGORE_DEFAULTS is set, this does nothing.
+ */
+void DoEpicSpellDefaults();
+
+/**
+ * Sets the file end markers to their default values.
+ *
+ * If FILE_END_MANUAL is set, this does nothing.
+ */
+void SetDefaultFileEnds();
+
+/**
+ * This creates an array of all switch names on a waypoint
+ * It is used for the switch setting convo to loop over switches easily
+ */
+void CreateSwitchNameArray();
+
+//////////////////////////////////////////////////
+/* Include section */
+//////////////////////////////////////////////////
+
+#include "prc_inc_array" // Needs direct include instead of inc_utility
+#include "prc_inc_switch"
+#include "inc_2dacache"
+
+//////////////////////////////////////////////////
+/* Function definitions */
+//////////////////////////////////////////////////
+
+void DoSamuraiBanDefaults()
+{
+ if(GetPRCSwitch(PRC_SAMURAI_DISABLE_DEFAULT_BAN))
+ return;
+ //remove all penalty iprops
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"10_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"21_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"24_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"27_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"28_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"29_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"47_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"49_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"50_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"60_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"62_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"63_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"64_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"65_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"66_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"81_*_*_*", TRUE);
+ //PRCs restrictions
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"86_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"87_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"88_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"89_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"90_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"91_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"120_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"121_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"122_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"123_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"124_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"125_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"126_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"127_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"134_*_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"150_*_*_*", TRUE);
+ //only allow elemental damages 6,7,9,10,13
+ //damage
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"16_5_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"16_8_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"16_11_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"16_12_*_*", TRUE);
+ //damage vs race
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"17_*_5_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"17_*_8_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"17_*_11_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"17_*_12_*", TRUE);
+ //damage vs alignment
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"18_*_5_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"18_*_8_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"18_*_11_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"18_*_12_*", TRUE);
+ //damage vs specific alignment
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"19_*_5_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"19_*_8_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"19_*_11_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"19_*_12_*", TRUE);
+ //damage immunity
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_5_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_8_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_11_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_12_*_*", TRUE);
+ //damage resist
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_5_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_8_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_11_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"20_12_*_*", TRUE);
+ //slays
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"48_21_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"48_22_*_*", TRUE);
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"48_23_*_*", TRUE);
+ //vorpal
+ SetPRCSwitch(PRC_SAMURAI_BAN_+"48_24_*_*", TRUE);
+}
+
+void DoEpicSpellDefaults()
+{
+ if(GetPRCSwitch(PRC_EPIC_INGORE_DEFAULTS))
+ return;
+ SetPRCSwitch(PRC_EPIC_XP_COSTS, TRUE);
+ SetPRCSwitch(PRC_EPIC_BACKLASH_DAMAGE, TRUE);
+ SetPRCSwitch(PRC_EPIC_FOCI_ADJUST_DC, TRUE);
+ SetPRCSwitch(PRC_EPIC_GOLD_MULTIPLIER, 9000);
+ SetPRCSwitch(PRC_EPIC_XP_FRACTION, 25);
+ SetPRCSwitch(PRC_EPIC_FAILURE_FRACTION_GOLD, 2);
+ SetPRCSwitch(PRC_EPIC_BOOK_DESTRUCTION, 50);
+}
+
+void SetDefaultFileEnds()
+{
+ // Overridden values: (TMI prevention)
+ //
+ // feat.2da - 390
+ // spells.2da - 539
+
+ //START AUTO-GENERATED FILEENDS
+ SetPRCSwitch("PRC_FILE_END_actions", 43);
+ SetPRCSwitch("PRC_FILE_END_ambientmusic", 95);
+ SetPRCSwitch("PRC_FILE_END_ambientsound", 113);
+ SetPRCSwitch("PRC_FILE_END_ammunitiontypes", 35);
+ SetPRCSwitch("PRC_FILE_END_appearance", 870);
+ SetPRCSwitch("PRC_FILE_END_appearancesndset", 31);
+ SetPRCSwitch("PRC_FILE_END_areaeffects", 2);
+ SetPRCSwitch("PRC_FILE_END_armor", 8);
+ SetPRCSwitch("PRC_FILE_END_armorparts", 0);
+ SetPRCSwitch("PRC_FILE_END_armourtypes", 42);
+ SetPRCSwitch("PRC_FILE_END_baseitems", 204);
+ SetPRCSwitch("PRC_FILE_END_bodybag", 6);
+ SetPRCSwitch("PRC_FILE_END_caarmorclass", 7);
+ SetPRCSwitch("PRC_FILE_END_capart", 18);
+ SetPRCSwitch("PRC_FILE_END_categories", 22);
+ SetPRCSwitch("PRC_FILE_END_catype", 4);
+ SetPRCSwitch("PRC_FILE_END_chargenclothes", 15);
+ SetPRCSwitch("PRC_FILE_END_classes", 254);
+ SetPRCSwitch("PRC_FILE_END_cloakmodel", 16);
+ SetPRCSwitch("PRC_FILE_END_cls_atk_1", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_atk_2", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_atk_3", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_atk_4", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_atk_adst", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_invkn_dfa", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_invkn_warlok", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_inv_dfa", 43);
+ SetPRCSwitch("PRC_FILE_END_cls_inv_warlok", 112);
+ SetPRCSwitch("PRC_FILE_END_cls_ivcr_dfa", 22);
+ SetPRCSwitch("PRC_FILE_END_cls_ivcr_warlok", 93);
+ SetPRCSwitch("PRC_FILE_END_cls_move_crusdr", 211);
+ SetPRCSwitch("PRC_FILE_END_cls_move_swdsge", 211);
+ SetPRCSwitch("PRC_FILE_END_cls_move_warbld", 211);
+ SetPRCSwitch("PRC_FILE_END_cls_mvcr_crusdr", 207);
+ SetPRCSwitch("PRC_FILE_END_cls_mvcr_swdsge", 207);
+ SetPRCSwitch("PRC_FILE_END_cls_mvcr_warbld", 207);
+ SetPRCSwitch("PRC_FILE_END_cls_mvkn_crusdr", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_mvkn_swdsge", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_mvkn_warbld", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_psbk_foz", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_psbk_psion", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_psbk_psywar", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_psbk_warmnd", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_psbk_wilder", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_psicr_foz", 154);
+ SetPRCSwitch("PRC_FILE_END_cls_psicr_psion", 196);
+ SetPRCSwitch("PRC_FILE_END_cls_psicr_psywar", 169);
+ SetPRCSwitch("PRC_FILE_END_cls_psicr_warmnd", 154);
+ SetPRCSwitch("PRC_FILE_END_cls_psicr_wilder", 196);
+ SetPRCSwitch("PRC_FILE_END_cls_psipw_foz", 226);
+ SetPRCSwitch("PRC_FILE_END_cls_psipw_psion", 285);
+ SetPRCSwitch("PRC_FILE_END_cls_psipw_psywar", 246);
+ SetPRCSwitch("PRC_FILE_END_cls_psipw_warmnd", 226);
+ SetPRCSwitch("PRC_FILE_END_cls_psipw_wilder", 285);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_barb", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_bard", 60);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_cler", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_cons", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_dru", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_fight", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_lich", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_monk", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_pal", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_rang", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_rog", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_sorc", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_wild", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_savthr_wiz", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_antipl", 42);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_archv", 502);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_asasin", 39);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_bard", 144);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_beguil", 142);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_blkgrd", 47);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_dnecro", 138);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_duskbl", 69);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_favsol", 300);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_harper", 35);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_healer", 77);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_hexbl", 73);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_justww", 34);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_kchal", 48);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_kotmc", 26);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_myst", 290);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_ocu", 209);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_schord", 244);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_shaman", 205);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_sod", 33);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_sohei", 57);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_sol", 38);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_sorc", 430);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_suel", 117);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_templ", 112);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_tfshad", 27);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_vassal", 31);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_vigil", 41);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_witch", 252);
+ SetPRCSwitch("PRC_FILE_END_cls_spcr_wrmage", 135);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_antipl", 115);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_archv", 2720);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_asasin", 52);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_bard", 169);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_beguil", 119);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_blkgrd", 163);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_dnecro", 135);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_duskbl", 84);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_favsol", 373);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_harper", 21);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_healer", 271);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_hexbl", 79);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_justww", 26);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_kchal", 137);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_kotmc", 70);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_myst", 363);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_ocu", 905);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_schord", 308);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_shaman", 667);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_sod", 110);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_sohei", 131);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_sol", 114);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_sorc", 550);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_suel", 160);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_templ", 95);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_tfshad", 70);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_vassal", 104);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_vigil", 75);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_witch", 193);
+ SetPRCSwitch("PRC_FILE_END_cls_spell_wrmage", 147);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_antipl", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_archv", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_asasin", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_bard", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_beguil", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_blkgrd", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_cler", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_dnecro", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_dru", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_duskbl", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_favsol", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_harper", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_healer", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_hexbl", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_justww", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_kchal", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_kotmc", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_myst", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_ocu", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_pal", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_rang", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_schord", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_shaman", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_sod", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_sohei", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_sol", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_sorc", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_suel", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_templ", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_tfshad", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_vassal", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_vigil", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_witch", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_wiz", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spgn_wrmage", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_asasin", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_bard", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_beguil", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_dnecro", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_duskbl", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_favsol", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_harper", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_hexbl", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_justww", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_myst", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_schord", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_sorc", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_suel", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_templ", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_witch", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_spkn_wrmage", 59);
+ SetPRCSwitch("PRC_FILE_END_cls_true_known", 39);
+ SetPRCSwitch("PRC_FILE_END_cls_true_maxlvl", 39);
+ SetPRCSwitch("PRC_FILE_END_cls_true_utter", 166);
+ SetPRCSwitch("PRC_FILE_END_colours", 175);
+ SetPRCSwitch("PRC_FILE_END_combatmodes", 3);
+ SetPRCSwitch("PRC_FILE_END_craft_armour", 63);
+ SetPRCSwitch("PRC_FILE_END_craft_golem", 40);
+ SetPRCSwitch("PRC_FILE_END_craft_ring", 41);
+ SetPRCSwitch("PRC_FILE_END_craft_weapon", 46);
+ SetPRCSwitch("PRC_FILE_END_craft_wondrous", 115);
+ SetPRCSwitch("PRC_FILE_END_creaturesize", 5);
+ SetPRCSwitch("PRC_FILE_END_creaturespeed", 8);
+ SetPRCSwitch("PRC_FILE_END_crtemplates", 10);
+ SetPRCSwitch("PRC_FILE_END_cursors", 10);
+ SetPRCSwitch("PRC_FILE_END_damagehitvisual", 11);
+ SetPRCSwitch("PRC_FILE_END_damagelevels", 5);
+ SetPRCSwitch("PRC_FILE_END_defaultacsounds", 8);
+ SetPRCSwitch("PRC_FILE_END_des_blumburg", 17);
+ SetPRCSwitch("PRC_FILE_END_des_conf_treas", 1);
+ SetPRCSwitch("PRC_FILE_END_des_crft_amat", 1);
+ SetPRCSwitch("PRC_FILE_END_des_crft_aparts", 17);
+ SetPRCSwitch("PRC_FILE_END_des_crft_appear", 53);
+ SetPRCSwitch("PRC_FILE_END_des_crft_armor", 41);
+ SetPRCSwitch("PRC_FILE_END_des_crft_bmat", 13);
+ SetPRCSwitch("PRC_FILE_END_des_crft_drop", 476);
+ SetPRCSwitch("PRC_FILE_END_des_crft_mat", 2);
+ SetPRCSwitch("PRC_FILE_END_des_crft_poison", 100);
+ SetPRCSwitch("PRC_FILE_END_des_crft_props", 27);
+ SetPRCSwitch("PRC_FILE_END_des_crft_scroll", 3999);
+ SetPRCSwitch("PRC_FILE_END_des_crft_spells", 20000);
+ SetPRCSwitch("PRC_FILE_END_des_crft_weapon", 29);
+ SetPRCSwitch("PRC_FILE_END_des_cutconvdur", 26);
+ SetPRCSwitch("PRC_FILE_END_des_feat2item", 1000);
+ SetPRCSwitch("PRC_FILE_END_des_matcomp", 510);
+ SetPRCSwitch("PRC_FILE_END_des_mechupgrades", 6);
+ SetPRCSwitch("PRC_FILE_END_des_pcstart_arm", 1);
+ SetPRCSwitch("PRC_FILE_END_des_pcstart_weap", 1);
+ SetPRCSwitch("PRC_FILE_END_des_prayer", 9);
+ SetPRCSwitch("PRC_FILE_END_des_restsystem", 21);
+ SetPRCSwitch("PRC_FILE_END_des_treas_ammo", 28);
+ SetPRCSwitch("PRC_FILE_END_des_treas_disp", 417);
+ SetPRCSwitch("PRC_FILE_END_des_treas_enh", 60);
+ SetPRCSwitch("PRC_FILE_END_des_treas_gold", 8);
+ SetPRCSwitch("PRC_FILE_END_des_treas_items", 15);
+ SetPRCSwitch("PRC_FILE_END_des_xp_rewards", 220);
+ SetPRCSwitch("PRC_FILE_END_diffsettings", 6);
+ SetPRCSwitch("PRC_FILE_END_disease", 62);
+ SetPRCSwitch("PRC_FILE_END_dmgxp", 59);
+ SetPRCSwitch("PRC_FILE_END_domains", 59);
+ SetPRCSwitch("PRC_FILE_END_doortype", 2);
+ SetPRCSwitch("PRC_FILE_END_doortypes", 238);
+ SetPRCSwitch("PRC_FILE_END_ECL", 254);
+ SetPRCSwitch("PRC_FILE_END_effectanim", 0);
+ SetPRCSwitch("PRC_FILE_END_effecticons", 129);
+ SetPRCSwitch("PRC_FILE_END_encdifficulty", 4);
+ SetPRCSwitch("PRC_FILE_END_encumbrance", 255);
+ SetPRCSwitch("PRC_FILE_END_environment", 25);
+ SetPRCSwitch("PRC_FILE_END_epicattacks", 235);
+ SetPRCSwitch("PRC_FILE_END_epicsaves", 59);
+ SetPRCSwitch("PRC_FILE_END_epicspells", 70);
+ SetPRCSwitch("PRC_FILE_END_epicspellseeds", 27);
+ SetPRCSwitch("PRC_FILE_END_excitedduration", 2);
+ SetPRCSwitch("PRC_FILE_END_exptable", 40);
+ SetPRCSwitch("PRC_FILE_END_feat", 24439);
+ SetPRCSwitch("PRC_FILE_END_fileends", 20);
+ SetPRCSwitch("PRC_FILE_END_footstepsounds", 17);
+ SetPRCSwitch("PRC_FILE_END_fractionalcr", 4);
+ SetPRCSwitch("PRC_FILE_END_gamespyrooms", 12);
+ SetPRCSwitch("PRC_FILE_END_gender", 4);
+ SetPRCSwitch("PRC_FILE_END_genericdoors", 25);
+ SetPRCSwitch("PRC_FILE_END_hen_companion", 18);
+ SetPRCSwitch("PRC_FILE_END_hen_familiar", 12);
+ SetPRCSwitch("PRC_FILE_END_inventorysnds", 32);
+ SetPRCSwitch("PRC_FILE_END_iprp_abilities", 5);
+ SetPRCSwitch("PRC_FILE_END_iprp_acmodtype", 4);
+ SetPRCSwitch("PRC_FILE_END_iprp_addcost", 1);
+ SetPRCSwitch("PRC_FILE_END_iprp_additional", 1);
+ SetPRCSwitch("PRC_FILE_END_iprp_aligngrp", 5);
+ SetPRCSwitch("PRC_FILE_END_iprp_alignment", 8);
+ SetPRCSwitch("PRC_FILE_END_iprp_ammocost", 15);
+ SetPRCSwitch("PRC_FILE_END_iprp_ammotype", 2);
+ SetPRCSwitch("PRC_FILE_END_iprp_amount", 4);
+ SetPRCSwitch("PRC_FILE_END_iprp_aoe", 7);
+ SetPRCSwitch("PRC_FILE_END_iprp_arcspell", 19);
+ SetPRCSwitch("PRC_FILE_END_iprp_base1", -1);
+ SetPRCSwitch("PRC_FILE_END_iprp_bladecost", 5);
+ SetPRCSwitch("PRC_FILE_END_iprp_bonuscost", 12);
+ SetPRCSwitch("PRC_FILE_END_iprp_casterlvl", 60);
+ SetPRCSwitch("PRC_FILE_END_iprp_chargecost", 13);
+ SetPRCSwitch("PRC_FILE_END_iprp_color", 6);
+ SetPRCSwitch("PRC_FILE_END_iprp_combatdam", 2);
+ SetPRCSwitch("PRC_FILE_END_iprp_costtable", 39);
+ SetPRCSwitch("PRC_FILE_END_iprp_damagecost", 70);
+ SetPRCSwitch("PRC_FILE_END_iprp_damagetype", 13);
+ SetPRCSwitch("PRC_FILE_END_iprp_damvulcost", 7);
+ SetPRCSwitch("PRC_FILE_END_iprp_decvalue1", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_decvalue2", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_feats", 26999);
+ SetPRCSwitch("PRC_FILE_END_iprp_immuncost", 7);
+ SetPRCSwitch("PRC_FILE_END_iprp_immunity", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_incvalue1", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_incvalue2", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_kitcost", 50);
+ SetPRCSwitch("PRC_FILE_END_iprp_lightcost", 4);
+ SetPRCSwitch("PRC_FILE_END_iprp_matcost", 77);
+ SetPRCSwitch("PRC_FILE_END_iprp_material", 77);
+ SetPRCSwitch("PRC_FILE_END_iprp_maxpp", 8);
+ SetPRCSwitch("PRC_FILE_END_iprp_meleecost", 20);
+ SetPRCSwitch("PRC_FILE_END_iprp_metamagic", 6);
+ SetPRCSwitch("PRC_FILE_END_iprp_monstcost", 58);
+ SetPRCSwitch("PRC_FILE_END_iprp_monsterdam", 14);
+ SetPRCSwitch("PRC_FILE_END_iprp_monsterhit", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_neg10cost", 50);
+ SetPRCSwitch("PRC_FILE_END_iprp_neg5cost", 10);
+ SetPRCSwitch("PRC_FILE_END_iprp_onhit", 25);
+ SetPRCSwitch("PRC_FILE_END_iprp_onhitcost", 70);
+ SetPRCSwitch("PRC_FILE_END_iprp_onhitdur", 27);
+ SetPRCSwitch("PRC_FILE_END_iprp_onhitspell", 209);
+ SetPRCSwitch("PRC_FILE_END_iprp_paramtable", 11);
+ SetPRCSwitch("PRC_FILE_END_iprp_poison", 5);
+ SetPRCSwitch("PRC_FILE_END_iprp_protection", 19);
+ SetPRCSwitch("PRC_FILE_END_iprp_qualcost", 15);
+ SetPRCSwitch("PRC_FILE_END_iprp_quality", 15);
+ SetPRCSwitch("PRC_FILE_END_iprp_redcost", 5);
+ SetPRCSwitch("PRC_FILE_END_iprp_resistcost", 28);
+ SetPRCSwitch("PRC_FILE_END_iprp_saveelement", 21);
+ SetPRCSwitch("PRC_FILE_END_iprp_savingthrow", 3);
+ SetPRCSwitch("PRC_FILE_END_iprp_skillcost", 50);
+ SetPRCSwitch("PRC_FILE_END_iprp_slotscost", -1);
+ SetPRCSwitch("PRC_FILE_END_iprp_soakcost", 50);
+ SetPRCSwitch("PRC_FILE_END_iprp_speed_dec", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_speed_enh", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_spellcost", 298);
+ SetPRCSwitch("PRC_FILE_END_iprp_spellcstr", 42);
+ SetPRCSwitch("PRC_FILE_END_iprp_spelllvcost", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_spelllvlimm", 9);
+ SetPRCSwitch("PRC_FILE_END_iprp_spells", 1552);
+ SetPRCSwitch("PRC_FILE_END_iprp_spellshl", 7);
+ SetPRCSwitch("PRC_FILE_END_iprp_srcost", 99);
+ SetPRCSwitch("PRC_FILE_END_iprp_staminacost", -1);
+ SetPRCSwitch("PRC_FILE_END_iprp_storedpp", 16);
+ SetPRCSwitch("PRC_FILE_END_iprp_terraintype", -1);
+ SetPRCSwitch("PRC_FILE_END_iprp_trapcost", 11);
+ SetPRCSwitch("PRC_FILE_END_iprp_traps", 4);
+ SetPRCSwitch("PRC_FILE_END_iprp_trapsize", 3);
+ SetPRCSwitch("PRC_FILE_END_iprp_visualfx", 6);
+ SetPRCSwitch("PRC_FILE_END_iprp_walk", 1);
+ SetPRCSwitch("PRC_FILE_END_iprp_weightcost", 6);
+ SetPRCSwitch("PRC_FILE_END_iprp_weightinc", 5);
+ SetPRCSwitch("PRC_FILE_END_itempropdef", 199);
+ SetPRCSwitch("PRC_FILE_END_itemprops", 199);
+ SetPRCSwitch("PRC_FILE_END_itemvalue", 59);
+ SetPRCSwitch("PRC_FILE_END_itmwizammo", 54);
+ SetPRCSwitch("PRC_FILE_END_itmwizarmor", 72);
+ SetPRCSwitch("PRC_FILE_END_itmwizhelmet", 71);
+ SetPRCSwitch("PRC_FILE_END_itmwizmelee", 47);
+ SetPRCSwitch("PRC_FILE_END_itmwizpotion", 38);
+ SetPRCSwitch("PRC_FILE_END_itmwizranged", 46);
+ SetPRCSwitch("PRC_FILE_END_itmwizrods", 41);
+ SetPRCSwitch("PRC_FILE_END_itmwizscroll", 38);
+ SetPRCSwitch("PRC_FILE_END_itmwizstaves", 60);
+ SetPRCSwitch("PRC_FILE_END_itmwizthrow", 48);
+ SetPRCSwitch("PRC_FILE_END_itmwiztrap", 43);
+ SetPRCSwitch("PRC_FILE_END_itmwizwands", 38);
+ SetPRCSwitch("PRC_FILE_END_keymap", 70);
+ SetPRCSwitch("PRC_FILE_END_lightcolor", 32);
+ SetPRCSwitch("PRC_FILE_END_loadhints", 101);
+ SetPRCSwitch("PRC_FILE_END_loadscreens", 259);
+ SetPRCSwitch("PRC_FILE_END_masterfeats", 125);
+ SetPRCSwitch("PRC_FILE_END_materialcomp", 200);
+ SetPRCSwitch("PRC_FILE_END_metamagic", 6);
+ SetPRCSwitch("PRC_FILE_END_namefilter", 3);
+ SetPRCSwitch("PRC_FILE_END_nwconfig", 6);
+ SetPRCSwitch("PRC_FILE_END_nwconfig2", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqbarb1", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqbarb3", 7);
+ SetPRCSwitch("PRC_FILE_END_packeqbarb4", 4);
+ SetPRCSwitch("PRC_FILE_END_packeqbarb5", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqbard1", 11);
+ SetPRCSwitch("PRC_FILE_END_packeqcler1", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqcler2", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqcler3", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqcler4", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqcler5", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqdruid1", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqfight1", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqfight2", 7);
+ SetPRCSwitch("PRC_FILE_END_packeqfight6", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqfightc", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqmonk1", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqmonk2", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqmonk4", 5);
+ SetPRCSwitch("PRC_FILE_END_packeqmonk5", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqpala1", 6);
+ SetPRCSwitch("PRC_FILE_END_packeqpala2", 7);
+ SetPRCSwitch("PRC_FILE_END_packeqpala3", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrang1", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrang2", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrang3", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrang4", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrang5", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrog1", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrog2", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrog3", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrog5", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqrogd", 8);
+ SetPRCSwitch("PRC_FILE_END_packeqsor1", 11);
+ SetPRCSwitch("PRC_FILE_END_packeqwiz1", 11);
+ SetPRCSwitch("PRC_FILE_END_packeqwizb", 11);
+ SetPRCSwitch("PRC_FILE_END_packftarch", 168);
+ SetPRCSwitch("PRC_FILE_END_packftassa", 220);
+ SetPRCSwitch("PRC_FILE_END_packftbarb1", 222);
+ SetPRCSwitch("PRC_FILE_END_packftbarb2", 219);
+ SetPRCSwitch("PRC_FILE_END_packftbarb3", 220);
+ SetPRCSwitch("PRC_FILE_END_packftbarb4", 222);
+ SetPRCSwitch("PRC_FILE_END_packftbarb5", 221);
+ SetPRCSwitch("PRC_FILE_END_packftbarbf", 37);
+ SetPRCSwitch("PRC_FILE_END_packftbard1", 177);
+ SetPRCSwitch("PRC_FILE_END_packftbard2", 173);
+ SetPRCSwitch("PRC_FILE_END_packftbard3", 176);
+ SetPRCSwitch("PRC_FILE_END_packftbard4", 169);
+ SetPRCSwitch("PRC_FILE_END_packftbard5", 168);
+ SetPRCSwitch("PRC_FILE_END_packftbard6", 67);
+ SetPRCSwitch("PRC_FILE_END_packftbardg", 42);
+ SetPRCSwitch("PRC_FILE_END_packftblck", 335);
+ SetPRCSwitch("PRC_FILE_END_packftcler1", 161);
+ SetPRCSwitch("PRC_FILE_END_packftcler2", 166);
+ SetPRCSwitch("PRC_FILE_END_packftcler3", 165);
+ SetPRCSwitch("PRC_FILE_END_packftcler4", 165);
+ SetPRCSwitch("PRC_FILE_END_packftcler5", 163);
+ SetPRCSwitch("PRC_FILE_END_packftcler6", 160);
+ SetPRCSwitch("PRC_FILE_END_packftclere", 46);
+ SetPRCSwitch("PRC_FILE_END_packftcrea1", 23);
+ SetPRCSwitch("PRC_FILE_END_packftdrdis", 254);
+ SetPRCSwitch("PRC_FILE_END_packftdruid1", 196);
+ SetPRCSwitch("PRC_FILE_END_packftdruid2", 204);
+ SetPRCSwitch("PRC_FILE_END_packftdruid3", 199);
+ SetPRCSwitch("PRC_FILE_END_packftdruid4", 198);
+ SetPRCSwitch("PRC_FILE_END_packftdruid5", 198);
+ SetPRCSwitch("PRC_FILE_END_packftdruid6", 196);
+ SetPRCSwitch("PRC_FILE_END_packftdwdef", 337);
+ SetPRCSwitch("PRC_FILE_END_packftfight1", 382);
+ SetPRCSwitch("PRC_FILE_END_packftfight2", 383);
+ SetPRCSwitch("PRC_FILE_END_packftfight3", 383);
+ SetPRCSwitch("PRC_FILE_END_packftfight4", 383);
+ SetPRCSwitch("PRC_FILE_END_packftfight5", 382);
+ SetPRCSwitch("PRC_FILE_END_packftfight6", 383);
+ SetPRCSwitch("PRC_FILE_END_packftfightc", 45);
+ SetPRCSwitch("PRC_FILE_END_packftharp", 191);
+ SetPRCSwitch("PRC_FILE_END_packftmonk1", 275);
+ SetPRCSwitch("PRC_FILE_END_packftmonk2", 275);
+ SetPRCSwitch("PRC_FILE_END_packftmonk3", 275);
+ SetPRCSwitch("PRC_FILE_END_packftmonk4", 275);
+ SetPRCSwitch("PRC_FILE_END_packftmonk5", 275);
+ SetPRCSwitch("PRC_FILE_END_packftmonk6", 275);
+ SetPRCSwitch("PRC_FILE_END_packftpala1", 213);
+ SetPRCSwitch("PRC_FILE_END_packftpala2", 213);
+ SetPRCSwitch("PRC_FILE_END_packftpala3", 212);
+ SetPRCSwitch("PRC_FILE_END_packftpala4", 212);
+ SetPRCSwitch("PRC_FILE_END_packftpalah", 32);
+ SetPRCSwitch("PRC_FILE_END_packftrang1", 155);
+ SetPRCSwitch("PRC_FILE_END_packftrang2", 158);
+ SetPRCSwitch("PRC_FILE_END_packftrang3", 158);
+ SetPRCSwitch("PRC_FILE_END_packftrang4", 159);
+ SetPRCSwitch("PRC_FILE_END_packftrang5", 158);
+ SetPRCSwitch("PRC_FILE_END_packftrang6", 157);
+ SetPRCSwitch("PRC_FILE_END_packftrog1", 298);
+ SetPRCSwitch("PRC_FILE_END_packftrog2", 303);
+ SetPRCSwitch("PRC_FILE_END_packftrog3", 302);
+ SetPRCSwitch("PRC_FILE_END_packftrog5", 322);
+ SetPRCSwitch("PRC_FILE_END_packftrog6", 315);
+ SetPRCSwitch("PRC_FILE_END_packftrog7", 321);
+ SetPRCSwitch("PRC_FILE_END_packftrogd", 37);
+ SetPRCSwitch("PRC_FILE_END_packftshad", 287);
+ SetPRCSwitch("PRC_FILE_END_packftshift", 148);
+ SetPRCSwitch("PRC_FILE_END_packftsor1", 174);
+ SetPRCSwitch("PRC_FILE_END_packftsor2", 157);
+ SetPRCSwitch("PRC_FILE_END_packftsor3", 157);
+ SetPRCSwitch("PRC_FILE_END_packftsor4", 157);
+ SetPRCSwitch("PRC_FILE_END_packftsor5", 157);
+ SetPRCSwitch("PRC_FILE_END_packftsor6", 172);
+ SetPRCSwitch("PRC_FILE_END_packftsor7", 170);
+ SetPRCSwitch("PRC_FILE_END_packftsor8", 174);
+ SetPRCSwitch("PRC_FILE_END_packftsor9", 199);
+ SetPRCSwitch("PRC_FILE_END_packftsora", 174);
+ SetPRCSwitch("PRC_FILE_END_packfttorm", 360);
+ SetPRCSwitch("PRC_FILE_END_packftwiz1", 174);
+ SetPRCSwitch("PRC_FILE_END_packftwiz2", 157);
+ SetPRCSwitch("PRC_FILE_END_packftwiz3", 157);
+ SetPRCSwitch("PRC_FILE_END_packftwiz4", 157);
+ SetPRCSwitch("PRC_FILE_END_packftwiz5", 157);
+ SetPRCSwitch("PRC_FILE_END_packftwiz6", 172);
+ SetPRCSwitch("PRC_FILE_END_packftwiz7", 170);
+ SetPRCSwitch("PRC_FILE_END_packftwiz8", 176);
+ SetPRCSwitch("PRC_FILE_END_packftwiz9", 199);
+ SetPRCSwitch("PRC_FILE_END_packftwiza", 174);
+ SetPRCSwitch("PRC_FILE_END_packftwizb", 43);
+ SetPRCSwitch("PRC_FILE_END_packftwm", 259);
+ SetPRCSwitch("PRC_FILE_END_packskarch", 10);
+ SetPRCSwitch("PRC_FILE_END_packskassa", 13);
+ SetPRCSwitch("PRC_FILE_END_packskbarb1", 20);
+ SetPRCSwitch("PRC_FILE_END_packskbarb2", 20);
+ SetPRCSwitch("PRC_FILE_END_packskbarb3", 20);
+ SetPRCSwitch("PRC_FILE_END_packskbarb4", 20);
+ SetPRCSwitch("PRC_FILE_END_packskbarb5", 20);
+ SetPRCSwitch("PRC_FILE_END_packskbarb6", 20);
+ SetPRCSwitch("PRC_FILE_END_packskbarb7", 8);
+ SetPRCSwitch("PRC_FILE_END_packskbard1", 22);
+ SetPRCSwitch("PRC_FILE_END_packskbard2", 22);
+ SetPRCSwitch("PRC_FILE_END_packskbard3", 22);
+ SetPRCSwitch("PRC_FILE_END_packskbard4", 22);
+ SetPRCSwitch("PRC_FILE_END_packskbard5", 22);
+ SetPRCSwitch("PRC_FILE_END_packskbard6", 22);
+ SetPRCSwitch("PRC_FILE_END_packskbard7", 12);
+ SetPRCSwitch("PRC_FILE_END_packskblck", 9);
+ SetPRCSwitch("PRC_FILE_END_packskcler1", 22);
+ SetPRCSwitch("PRC_FILE_END_packskcler2", 21);
+ SetPRCSwitch("PRC_FILE_END_packskcler3", 21);
+ SetPRCSwitch("PRC_FILE_END_packskcler4", 21);
+ SetPRCSwitch("PRC_FILE_END_packskcler5", 4);
+ SetPRCSwitch("PRC_FILE_END_packskcrea1", 4);
+ SetPRCSwitch("PRC_FILE_END_packskdrdis", 10);
+ SetPRCSwitch("PRC_FILE_END_packskdruid1", 21);
+ SetPRCSwitch("PRC_FILE_END_packskdruid2", 21);
+ SetPRCSwitch("PRC_FILE_END_packskdruid3", 21);
+ SetPRCSwitch("PRC_FILE_END_packskdruid4", 21);
+ SetPRCSwitch("PRC_FILE_END_packskdruid5", 22);
+ SetPRCSwitch("PRC_FILE_END_packskdwdef", 9);
+ SetPRCSwitch("PRC_FILE_END_packskfight1", 20);
+ SetPRCSwitch("PRC_FILE_END_packskfight2", 20);
+ SetPRCSwitch("PRC_FILE_END_packskfight3", 21);
+ SetPRCSwitch("PRC_FILE_END_packskfight5", 20);
+ SetPRCSwitch("PRC_FILE_END_packskfight6", 4);
+ SetPRCSwitch("PRC_FILE_END_packskharp", 11);
+ SetPRCSwitch("PRC_FILE_END_packskmonk1", 19);
+ SetPRCSwitch("PRC_FILE_END_packskmonk6", 20);
+ SetPRCSwitch("PRC_FILE_END_packskpala1", 18);
+ SetPRCSwitch("PRC_FILE_END_packskpala4", 19);
+ SetPRCSwitch("PRC_FILE_END_packskpalah", 21);
+ SetPRCSwitch("PRC_FILE_END_packskrang1", 24);
+ SetPRCSwitch("PRC_FILE_END_packskrang2", 24);
+ SetPRCSwitch("PRC_FILE_END_packskrang3", 24);
+ SetPRCSwitch("PRC_FILE_END_packskrog1", 23);
+ SetPRCSwitch("PRC_FILE_END_packskrog2", 23);
+ SetPRCSwitch("PRC_FILE_END_packskrog3", 23);
+ SetPRCSwitch("PRC_FILE_END_packskrog4", 22);
+ SetPRCSwitch("PRC_FILE_END_packskrog5", 21);
+ SetPRCSwitch("PRC_FILE_END_packskrog6", 13);
+ SetPRCSwitch("PRC_FILE_END_packskrog7", 23);
+ SetPRCSwitch("PRC_FILE_END_packskshad", 11);
+ SetPRCSwitch("PRC_FILE_END_packsksor10", 19);
+ SetPRCSwitch("PRC_FILE_END_packsktorm", 23);
+ SetPRCSwitch("PRC_FILE_END_packskwiz1", 19);
+ SetPRCSwitch("PRC_FILE_END_packskwizb", 23);
+ SetPRCSwitch("PRC_FILE_END_packspbar1", 67);
+ SetPRCSwitch("PRC_FILE_END_packspbar2", 47);
+ SetPRCSwitch("PRC_FILE_END_packspbar3", 34);
+ SetPRCSwitch("PRC_FILE_END_packspcleric1", 56);
+ SetPRCSwitch("PRC_FILE_END_packspcleric2", 53);
+ SetPRCSwitch("PRC_FILE_END_packspdruid1", 56);
+ SetPRCSwitch("PRC_FILE_END_packspnpc1", 101);
+ SetPRCSwitch("PRC_FILE_END_packsppala1", 26);
+ SetPRCSwitch("PRC_FILE_END_packsprang1", 63);
+ SetPRCSwitch("PRC_FILE_END_packspwiz1", 146);
+ SetPRCSwitch("PRC_FILE_END_packspwiz2", 47);
+ SetPRCSwitch("PRC_FILE_END_packspwiz3", 47);
+ SetPRCSwitch("PRC_FILE_END_packspwiz4", 50);
+ SetPRCSwitch("PRC_FILE_END_packspwiz5", 48);
+ SetPRCSwitch("PRC_FILE_END_packspwiz6", 47);
+ SetPRCSwitch("PRC_FILE_END_packspwiz7", 47);
+ SetPRCSwitch("PRC_FILE_END_packspwiz8", 49);
+ SetPRCSwitch("PRC_FILE_END_packspwiz9", 44);
+ SetPRCSwitch("PRC_FILE_END_packspwizb", 35);
+ SetPRCSwitch("PRC_FILE_END_parts_belt", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_bicep", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_chest", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_foot", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_forearm", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_hand", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_legs", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_neck", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_pelvis", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_robe", 38);
+ SetPRCSwitch("PRC_FILE_END_parts_shin", 200);
+ SetPRCSwitch("PRC_FILE_END_parts_shoulder", 200);
+ SetPRCSwitch("PRC_FILE_END_phenotype", 33);
+ SetPRCSwitch("PRC_FILE_END_placeableobjsnds", 50);
+ SetPRCSwitch("PRC_FILE_END_placeables", 846);
+ SetPRCSwitch("PRC_FILE_END_placeabletypes", 8);
+ SetPRCSwitch("PRC_FILE_END_poison", 146);
+ SetPRCSwitch("PRC_FILE_END_poisontypedef", 3);
+ SetPRCSwitch("PRC_FILE_END_polymorph", 155);
+ SetPRCSwitch("PRC_FILE_END_portraits", 1300);
+ SetPRCSwitch("PRC_FILE_END_prc_craft_alchem", 37);
+ SetPRCSwitch("PRC_FILE_END_prc_craft_gen_it", 253);
+ SetPRCSwitch("PRC_FILE_END_prc_craft_poison", 62);
+ SetPRCSwitch("PRC_FILE_END_prc_domains", 59);
+ SetPRCSwitch("PRC_FILE_END_prc_familiar", 10);
+ SetPRCSwitch("PRC_FILE_END_prc_polymorph", 401);
+ SetPRCSwitch("PRC_FILE_END_prc_rune_craft", 7);
+ SetPRCSwitch("PRC_FILE_END_prc_spells", 4071);
+ SetPRCSwitch("PRC_FILE_END_prc_weap_items", 58);
+ SetPRCSwitch("PRC_FILE_END_pregen", 44);
+ SetPRCSwitch("PRC_FILE_END_prioritygroups", 21);
+ SetPRCSwitch("PRC_FILE_END_pvpsettings", 3);
+ SetPRCSwitch("PRC_FILE_END_racialappear", 254);
+ SetPRCSwitch("PRC_FILE_END_racialtypes", 254);
+ SetPRCSwitch("PRC_FILE_END_ranges", 13);
+ SetPRCSwitch("PRC_FILE_END_repadjust", 3);
+ SetPRCSwitch("PRC_FILE_END_replacetexture", 1);
+ SetPRCSwitch("PRC_FILE_END_repute", 4);
+ SetPRCSwitch("PRC_FILE_END_resistancecost", -1);
+ SetPRCSwitch("PRC_FILE_END_restduration", 60);
+ SetPRCSwitch("PRC_FILE_END_rrf_nss", 19);
+ SetPRCSwitch("PRC_FILE_END_rrf_wav", 40);
+ SetPRCSwitch("PRC_FILE_END_shft_packages", 9);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_animal", 67);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_constrct", 15);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_dragon", 49);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_element", 15);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_gen1", 30);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_gen2", 43);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_outsider", 47);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_rogue", 66);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_undead", 43);
+ SetPRCSwitch("PRC_FILE_END_shft_pk_warrior", 88);
+ SetPRCSwitch("PRC_FILE_END_shifter_abilitie", 119);
+ SetPRCSwitch("PRC_FILE_END_shifter_feats", 425);
+ SetPRCSwitch("PRC_FILE_END_shifter_races", 30);
+ SetPRCSwitch("PRC_FILE_END_skills", 38);
+ SetPRCSwitch("PRC_FILE_END_skillvsitemcost", 55);
+ SetPRCSwitch("PRC_FILE_END_skyboxes", 6);
+ SetPRCSwitch("PRC_FILE_END_soundcatfilters", 14);
+ SetPRCSwitch("PRC_FILE_END_sounddefaultspos", 3);
+ SetPRCSwitch("PRC_FILE_END_sounddefaultstim", 5);
+ SetPRCSwitch("PRC_FILE_END_soundeax", 112);
+ SetPRCSwitch("PRC_FILE_END_soundgain", 14);
+ SetPRCSwitch("PRC_FILE_END_soundprovider", 12);
+ SetPRCSwitch("PRC_FILE_END_soundset", 453);
+ SetPRCSwitch("PRC_FILE_END_soundsettype", 4);
+ SetPRCSwitch("PRC_FILE_END_soundtypes", 1);
+ SetPRCSwitch("PRC_FILE_END_spells", 19400);
+ //SetPRCSwitch("PRC_FILE_END_spellschools", 9);
+ SetPRCSwitch("PRC_FILE_END_statescripts", 35);
+ SetPRCSwitch("PRC_FILE_END_stringtokens", 92);
+ SetPRCSwitch("PRC_FILE_END_surfacemat", 30);
+ SetPRCSwitch("PRC_FILE_END_swearfilter", 171);
+ SetPRCSwitch("PRC_FILE_END_tailmodel", 572);
+ SetPRCSwitch("PRC_FILE_END_tbw01_edge", 7);
+ SetPRCSwitch("PRC_FILE_END_tcn01doors", 0);
+ SetPRCSwitch("PRC_FILE_END_tcn01_edge", 27);
+ SetPRCSwitch("PRC_FILE_END_tdc01_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_tde01_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_tdm01_edge", 13);
+ SetPRCSwitch("PRC_FILE_END_tdr01_edge", 18);
+ SetPRCSwitch("PRC_FILE_END_tds01_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_tdt01_edge", 11);
+ SetPRCSwitch("PRC_FILE_END_templates", 250);
+ SetPRCSwitch("PRC_FILE_END_tib01_edge", 3);
+ SetPRCSwitch("PRC_FILE_END_tic01_edge", 18);
+ SetPRCSwitch("PRC_FILE_END_tid01_edge", 10);
+ SetPRCSwitch("PRC_FILE_END_tii01_edge", 6);
+ SetPRCSwitch("PRC_FILE_END_tilecolor", 15);
+ SetPRCSwitch("PRC_FILE_END_tin01doors", 0);
+ SetPRCSwitch("PRC_FILE_END_tin01_edge", 15);
+ SetPRCSwitch("PRC_FILE_END_tms01_edge", 6);
+ SetPRCSwitch("PRC_FILE_END_tni01_edge", 15);
+ SetPRCSwitch("PRC_FILE_END_tni02_edge", 19);
+ SetPRCSwitch("PRC_FILE_END_tno01_edge", 67);
+ SetPRCSwitch("PRC_FILE_END_traps", 101);
+ SetPRCSwitch("PRC_FILE_END_treasurescale", 4);
+ SetPRCSwitch("PRC_FILE_END_tsw01_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_ttd01_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_ttf01_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_tti01_edge", 10);
+ SetPRCSwitch("PRC_FILE_END_ttr01doors", 0);
+ SetPRCSwitch("PRC_FILE_END_ttr01_edge", 23);
+ SetPRCSwitch("PRC_FILE_END_tts01doors", 2);
+ SetPRCSwitch("PRC_FILE_END_tts01_edge", 25);
+ SetPRCSwitch("PRC_FILE_END_ttu01_edge", 36);
+ SetPRCSwitch("PRC_FILE_END_ttz01_edge", 28);
+ SetPRCSwitch("PRC_FILE_END_twc03_edge", 12);
+ SetPRCSwitch("PRC_FILE_END_unarmed_dmg", 13);
+ SetPRCSwitch("PRC_FILE_END_vfx_fire_forget", 16);
+ SetPRCSwitch("PRC_FILE_END_vfx_persistent", 254);
+ SetPRCSwitch("PRC_FILE_END_videoquality", 9);
+ SetPRCSwitch("PRC_FILE_END_visualeffects", 1373);
+ SetPRCSwitch("PRC_FILE_END_waypoint", 4);
+ SetPRCSwitch("PRC_FILE_END_weaponsounds", 21);
+ SetPRCSwitch("PRC_FILE_END_wingmodel", 89);
+ SetPRCSwitch("PRC_FILE_END_x3restrict", 899);
+ SetPRCSwitch("PRC_FILE_END_xpbaseconst", 16);
+ SetPRCSwitch("PRC_FILE_END_xptable", 39);
+ //END AUTO-GENERATED FILEENDS
+
+
+ //Overriding fileends
+ SetPRCSwitch("PRC_FILE_END_feat", 390);
+ SetPRCSwitch("PRC_FILE_END_spells", 539);
+ //SetPRCSwitch("PRC_FILE_END_iprp_feats", 17993);
+ SetPRCSwitch("PRC_FILE_END_iprp_feats", 40);
+ //SetPRCSwitch("PRC_FILE_END_iprp_spells", 1379);
+
+
+ //there is also the fileends.2da file, but that
+ //isnt read in here yet. may be later though
+ if(GetPRCSwitch(FILE_END_MANUAL))
+ return;
+ SetPRCSwitch(FILE_END_CLASSES, PRCGetFileEnd("classes"));
+ SetPRCSwitch(FILE_END_RACIALTYPES, PRCGetFileEnd("racialtypes"));
+ SetPRCSwitch(FILE_END_GENDER, 1);//overriden to 1 for convoCC m/f only choice
+ SetPRCSwitch(FILE_END_PORTRAITS, PRCGetFileEnd("portraits"));
+ SetPRCSwitch(FILE_END_SKILLS, PRCGetFileEnd("skills"));
+ SetPRCSwitch(FILE_END_CLASS_FEAT, 600);
+ SetPRCSwitch(FILE_END_CLASS_POWER, 300);
+ SetPRCSwitch(FILE_END_CLASS_SPELLBOOK, PRCGetFileEnd("cls_spell_archv")); //
+ SetPRCSwitch(FILE_END_FEAT, PRCGetFileEnd("feat"));
+ SetPRCSwitch(FILE_END_FAMILIAR, PRCGetFileEnd("hen_familiar"));
+ SetPRCSwitch(FILE_END_ANIMALCOMP, PRCGetFileEnd("hen_companion"));
+ SetPRCSwitch(FILE_END_DOMAINS, PRCGetFileEnd("domains"));
+ SetPRCSwitch(FILE_END_SOUNDSET, PRCGetFileEnd("soundset"));
+ SetPRCSwitch(FILE_END_SPELLS, PRCGetFileEnd("spells"));
+ //SetPRCSwitch(FILE_END_SPELLSCHOOL, PRCGetFileEnd("spellschools"));
+ SetPRCSwitch(FILE_END_APPEARANCE, PRCGetFileEnd("appearance"));
+ SetPRCSwitch(FILE_END_WINGS, PRCGetFileEnd("wingmodel"));
+ SetPRCSwitch(FILE_END_TAILS, PRCGetFileEnd("tailmodel"));
+ SetPRCSwitch(FILE_END_BASEITEMS, PRCGetFileEnd("baseitems"));
+}
+
+void CreateSwitchNameArray()
+{
+ object oWP = GetWaypointByTag("PRC_Switch_Name_WP");
+ if(!GetIsObjectValid(oWP))
+ oWP = CreateObject(OBJECT_TYPE_WAYPOINT, "NW_WAYPOINT001", GetStartingLocation(), FALSE, "PRC_Switch_Name_WP");
+ if(!GetIsObjectValid(oWP))
+ PrintString("CreateSwitchNameArray: Problem creating waypoint.");
+ array_create(oWP, "Switch_Name");
+ //if you add more switches, add them to this list
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEBUG);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_COMBAT_DEBUG);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_MATERIAL_COMPONENTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_COMPONENTS_SHOP);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_TRUESEEING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_TRUESEEING_SPOT_BONUS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_GRRESTORE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_HEAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_MASS_HEAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_HARM);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_NEUTRALIZE_POISON);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_REMOVE_DISEASE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOWED_TO_REMOVE_FRIENDLY_SPELLS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOWED_TO_SEE_HOSTILE_SPELLS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIO_UNLEARN);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_UNLEARN_SPELL_MAXNR);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_BIOWARE_DURATION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_LOCAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_NO_HOSTILE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_BLANK_PC);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_AFTS_EXTRA_DAMAGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_ELEMENTAL_SWARM);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_FEAR_AURAS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_TENSERS_TRANSFORMATION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_BLACK_BLADE_OF_DISASTER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_FIND_TRAPS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_DARKNESS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_DARKNESS_35ED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_ANIMATE_DEAD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_UNDEAD_PERMANENT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_UNDEAD_UNCONTROLLED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_NEC_TERM_PERMADEATH);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SPELL_ALIGNMENT_RESTRICT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_35ED_WORD_OF_FAITH);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SLEEP_NO_HD_CAP);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_165_DEATH_IMMUNITY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CASTERLEVEL_FIRST_CLASS_RULE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USE_NEW_IMBUE_ARROW);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DRAGON_DISCIPLE_SIZE_CHANGES);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SAMURAI_ALLOW_STOLEN_SACRIFICE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SAMURAI_ALLOW_UNIDENTIFIED_SACRIFICE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SAMURAI_SACRIFICE_SCALAR_x100);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SAMURAI_VALUE_SCALAR_x100);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ORC_WARLORD_COHORT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LICH_ALTER_SELF_DISABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUE_NECROMANCER_ALTERNATE_VISUAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_THRALLHERD_LEADERSHIP);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_XP_COSTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_TAKE_TEN_RULE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_PRIMARY_ABILITY_MODIFIER_RULE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_BACKLASH_DAMAGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_FOCI_ADJUST_DC);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_GOLD_MULTIPLIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_XP_FRACTION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_FAILURE_FRACTION_GOLD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_BOOK_DESTRUCTION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_UNIMPINGED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_IMPENETRABILITY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_DULLBLADES);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_CHAMPIONS_VALOR);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_EPIC_CONVO_LEARNING_DISABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_STAFF_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_NPC_HAS_PC_SPELLCASTING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ECL_USES_XP_NOT_HD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_DEMILICH);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SPELLSLAB);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SPELLSLAB_NOSCROLLS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_ABILITY_DAMAGE_EFFECTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SUPPLY_BASED_REST);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_REST_HEALING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_REST_TIME);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_REST_LIMIT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_SPELL_SCHOOLS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PLAYER_TIME);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_SOMATIC_COMPOMENTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_SOMATIC_ITEMS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_MULTISUMMON);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SUMMON_ROUND_PER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ENABLE_SPELL_SHARING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_ANIMAL_COMPANIONS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_FAMILIARS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_FAMILIAR_FEEDING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_FAMILIARS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_NO_FREE_WIZ_SPELLS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_POWER_ATTACK);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_POWER_ATTACK_STACK_WITH_BW);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_NO_PETRIFY_GUI);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_SWITCH_CHANGING_CONVO);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_DOMAIN_ENFORCEMENT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BONUS_COHORTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CUSTOM_COHORTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_STANDARD_COHORTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_REGISTER_COHORTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_SLINGS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BEBILITH_CLAWS_DESTROY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_AUTO_IDENTIFY_ON_ACQUIRE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_AUTO_UNIDENTIFY_ON_UNACQUIRE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SPELLFIRE_DISALLOW_CHARGE_SELF);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SPELLFIRE_DISALLOW_DRAIN_SCROLL_POTION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SORC_DISALLOW_NEWSPELLBOOK);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BARD_DISALLOW_NEWSPELLBOOK);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BARD_LIGHT_ARMOR_SPELLCASTING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CWSAMURAI_NO_HEIRLOOM_DAISHO);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CONVO_TEMPLATE_GAIN);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_ARMOR_SPEED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_RACIAL_SPEED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_FAST_TRAVEL_SPEED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_REMOVE_PLAYER_SPEED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ENFORCE_RACIAL_APPEARANCE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_NPC_FORCE_RACE_ACQUIRE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DYNAMIC_CLOAK_AUTOCOLOUR_DISABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_STABLE_TO_DISABLED_CHANCE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_STABLE_TO_BLEED_CHANCE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_BLEED_TO_STABLE_CHANCE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_HEAL_FROM_STABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_DAMAGE_FROM_STABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_DAMAGE_FROM_BLEEDING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEATH_OR_BLEED);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_DEATH_ENABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ACP_MANUAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ACP_AUTOMATIC);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ACP_NPC_AUTOMATIC);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ACP_DELAY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USE_TAGBASED_INDEX_FOR_POISON);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USES_PER_ITEM_POISON_COUNT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USES_PER_ITEM_POISON_DIE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOW_ONLY_SHARP_WEAPONS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOW_ALL_POISONS_ON_WEAPONS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEXBASED_WEAPON_POISONING_FAILURE_CHANCE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USES_PER_WEAPON_POISON_COUNT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USES_PER_WEAPON_POISON_DIE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_POISON_ALLOW_CLEAN_IN_EQUIP);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_POISON_USE_INGREDIENTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PSI_ASTRAL_CONSTRUCT_USE_2DA);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PSI_ASTRAL_CONSTRUCT_DUR_MOD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_RAPID_METABOLISM);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PSI_IMP_METAPSIONICS_USE_SUM);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_USECR);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_HUGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_LARGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_MEDIUM);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_SMALL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_TINY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_OUTSIDER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ELEMENTAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_CONSTRUCT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_UNDEAD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_DRAGON);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ABERRATION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_OOZE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_MAGICALBEAST);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_GIANT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_VERMIN);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_BEAST);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ANIMAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_MONSTROUSHUMANOID);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_HUMANOID);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_ELEMENTAL_DAMAGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SPELL_SNEAK_DISABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_3_5e_FIST_DAMAGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BRAWLER_SIZE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_APPEARANCE_SIZE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_MONK_ATTACKS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SMALL_CREATURE_FINESSE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_DIVINE_POWER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOW_SWITCH_OF_TARGET);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_COUP_DE_GRACE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_FLAME_WEAPON_DAMAGE_MAX);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DARKFIRE_DAMAGE_MAX);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TELEPORT_MAX_TARGET_LOCATIONS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_TELEPORTATION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_TIME);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_PC_AUTOEXPORT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_HP_TRACKING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_LOCATION_TRACKING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_MAPPIN_TRACKING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_DEATH_TRACKING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PW_SPELL_TRACKING);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_XP_USE_BIOWARE_XPTABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_XP_USE_SIMPLE_LA);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_XP_USE_SIMPLE_RACIAL_HD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_XP_USE_SIMPLE_RACIAL_HD_NO_FREE_XP);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_XP_USE_SIMPLE_RACIAL_HD_NO_SELECTION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_XP_USE_SETXP);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USE_DATABASE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USE_BIOWARE_DATABASE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DB_PRECACHE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DB_SQLITE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DB_SQLITE_INTERVAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DB_MYSQL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USE_LETOSCRIPT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LETOSCRIPT_PHEONIX_SYNTAX);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LETOSCRIPT_FIX_ABILITIES);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LETOSCRIPT_UNICORN_SQL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LETOSCRIPT_GETNEWESTBIC);
+
+//craft
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CRAFT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MULTIPLIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MAX);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MIN);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BREW_POTION_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SCRIBE_SCROLL_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_WAND_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_ROD_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_STAFF_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_BASE_ITEMS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_BREWPOTION_MAXLEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_BREWPOTION_COSTMODIFIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_SCRIBESCROLL_COSTMODIFIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CRAFTWAND_MAXLEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CRAFTWAND_COSTMODIFIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CREATEINFUSION_COSTMODIFIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_ARBITRARY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_COST_SCALE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_TIME_SCALE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_CASTER_LEVEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_OPTIONAL_HERBS);
+
+//spells
+
+//shifter
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_WEREWOLF_HYBRID_USE_SHIFTER_SHAPECHANGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_USECR);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_HUGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_LARGE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_MEDIUM);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_SMALL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_TINY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_OUTSIDER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ELEMENTAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_CONSTRUCT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_UNDEAD);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_DRAGON);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ABERRATION);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_OOZE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_MAGICALBEAST);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_GIANT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_VERMIN);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_BEAST);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ANIMAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_MONSTROUSHUMANOID);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_HUMANOID);
+
+//general
+
+//PW
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENABLE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_AVARIEL_WINGS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_FEYRI_WINGS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_AASIMAR_WINGS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_FEYRI_TAIL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_TIEFLING_TAIL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_DROW_ENFORCE_GENDER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_GENASI_ENFORCE_DOMAINS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_RAKSHASA_FEMALE_APPEARANCE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENFORCE_PNP_RACIAL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENFORCE_FEATS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_DISALLOW_CUSTOMISE_WINGS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_DISALLOW_CUSTOMISE_TAIL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_DISALLOW_CUSTOMISE_MODEL);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_USE_RACIAL_APPEARANCES);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_USE_RACIAL_PORTRAIT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ONLY_PLAYER_VOICESETS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_RESTRICT_VOICESETS_BY_SEX);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ALLOW_TO_KEEP_VOICESET);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ALLOW_TO_KEEP_PORTRAIT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_RESTRICT_PORTRAIT_BY_SEX);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENABLE_RACIAL_HITDICE);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ALLOW_SKILL_POINT_ROLLOVER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_USE_XP_FOR_NEW_CHAR);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_ENCRYPTION_KEY);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_STAT_POINTS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_BONUS_FEATS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_MAX_STAT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_SKILL_MULTIPLIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_SKILL_BONUS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CONVOCC_CUSTOM_EXIT_SCRIPT);
+
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_CR_MULTIPLIER);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_LEVEL_BONUS);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TRUENAME_DC_CONSTANT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PERFECTED_MAP_CONSTANT);
+ array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PERFECTED_MAP_MULTIPLIER);
+}
+
+
+//:: void main(){}
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_blast.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_blast.nss
new file mode 100644
index 00000000..08d122c1
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_blast.nss
@@ -0,0 +1,166 @@
+#include "prc_inc_clsfunc"
+
+int SpellSneakAttackDamage(object oCaster, object oTarget);
+
+int GetBlastDamageDices(object oInvoker, int nInvokerLevel)
+{
+ int nDmgDice;
+ if(nInvokerLevel < 13)
+ nDmgDice = (nInvokerLevel + 1) / 2;
+ else if(nInvokerLevel < 20)
+ nDmgDice = (nInvokerLevel + 7) / 3;
+ else
+ nDmgDice = 9 + (nInvokerLevel - 20) / 2;
+
+ //check for the epic feats
+ if(GetHasFeat(FEAT_EPIC_ELDRITCH_BLAST_I, oInvoker))
+ {
+ int nFeatAmt = 0;
+ int bDone = FALSE;
+ while(!bDone)
+ { if(nFeatAmt >= 9)
+ bDone = TRUE;
+ else if(GetHasFeat(FEAT_EPIC_ELDRITCH_BLAST_II + nFeatAmt, oInvoker))
+ nFeatAmt++;
+ else
+ bDone = TRUE;
+ }
+ nDmgDice += nFeatAmt;
+ }
+
+ return nDmgDice;
+}
+
+// Spellblast should use only AoE spells but Dispel Magic can be cast as AoE or single target
+// we make sure here that we use AoE version
+int CheckSpecialTarget(int nSpellID)
+{
+ return nSpellID == SPELL_DISPEL_MAGIC
+ || nSpellID == SPELL_GREATER_DISPELLING
+ || nSpellID == SPELL_LESSER_DISPEL
+ || nSpellID == SPELL_MORDENKAINENS_DISJUNCTION
+ || nSpellID == SPELL_POWER_WORD_KILL;
+}
+
+void DoSpellBlast(object oPC, int bHit)
+{
+ int nSpellbookID = GetLocalInt(oPC, "ET_SPELL_CURRENT");
+//DoDebug("nSpellbookID = "+IntToString(nSpellbookID));
+ if(nSpellbookID)
+ {
+ object oTarget = GetSpellTargetObject();
+ if(GetIsObjectValid(oTarget))
+ {
+ nSpellbookID--;
+ DeleteLocalInt(oPC, "ET_SPELL_CURRENT");
+ int nSpellID = GetLocalInt(oPC, "ET_REAL_SPELL_CURRENT");
+//DoDebug("nSpellID = "+IntToString(nSpellID));
+ string sArray = GetLocalString(oPC, "ET_SPELL_CURRENT");
+//DoDebug("sArray = "+sArray);
+ int nUses = sArray == "" ? GetHasSpell(nSpellbookID, oPC) :
+ persistant_array_get_int(oPC, sArray, nSpellbookID);
+
+ if(nUses)
+ {
+ // expend spell use
+ if(sArray == "")
+ {
+ DecrementRemainingSpellUses(oPC, nSpellID);
+ }
+ else
+ {
+ nUses--;
+ persistant_array_set_int(oPC, sArray, nSpellbookID, nUses);
+ }
+
+ // use AoE Dispel Magic
+ int bTargetOverride = CheckSpecialTarget(nSpellID);
+
+ if(bHit)
+ {
+ int nCastingClass = GetETArcaneClass(oPC);
+ int nDC = 10 + PRCGetSpellLevelForClass(nSpellID, nCastingClass) + GetDCAbilityModForClass(nCastingClass, oPC);
+ //clear action queue to apply spell effect right after blast effect
+ ClearAllActions();
+ //override PRCDoMeleeTouchAttack() - we already know that blast hit
+ ActionDoCommand(SetLocalInt(oPC, "AttackHasHit", bHit));
+ SetLocalInt(oPC, "EldritchSpellBlast", TRUE);
+ if(DEBUG) DoDebug("inv_inc_blast >> EldritchSpellBlast Set");
+ ActionCastSpell(nSpellID, 0, nDC, 0, METAMAGIC_NONE, nCastingClass, FALSE, bTargetOverride);
+ ActionDoCommand(DeleteLocalInt(oPC, "AttackHasHit"));
+ DelayCommand(0.5, DeleteLocalInt(oPC, "EldritchSpellBlast"));
+ }
+ }
+ }
+ }
+}
+
+void ApplyBlastDamage(object oCaster, object oTarget, int iAttackRoll, int iSR, int iDamage, int iDamageType, int iDamageType2, int nHellFire, int bSneak = TRUE, int nMsg = FALSE)
+{
+ if (DEBUG) DoDebug("ApplyBlastDamage oCaster "+GetName(oCaster)+" oTarget "+GetName(oTarget)+" iAttackRoll "+IntToString(iAttackRoll)+" iSR "+IntToString(iSR)+" iDamage "+IntToString(iDamage)+" iDamageType "+IntToString(iDamageType)+" iDamageType2 "+IntToString(iDamageType2)+" nHellFire "+IntToString(nHellFire)+" bSneak "+IntToString(bSneak)+" nMsg "+IntToString(nMsg));
+
+ // Is it a critical hit?
+ iDamage *= iAttackRoll;
+ if(iAttackRoll)
+ {
+ // Heal the Undead
+ if (iDamageType == DAMAGE_TYPE_NEGATIVE && (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD || GetLocalInt(oTarget, "AcererakHealing") || (GetHasFeat(FEAT_TOMB_TAINTED_SOUL, oTarget) && GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD)))
+ {
+ //Set the heal effect
+ effect eHeal = EffectHeal(iDamage);
+ ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
+ }
+ else // Other targets
+ {
+ if(!GetPRCSwitch(PRC_SPELL_SNEAK_DISABLE) && bSneak)
+ iDamage += SpellSneakAttackDamage(oCaster, oTarget);
+
+ effect eDamage;
+ if(!iSR)
+ {
+ if(iDamageType == iDamageType2)
+ eDamage = EffectDamage(iDamage, iDamageType);
+ else
+ {
+ eDamage = EffectDamage(iDamage / 2, iDamageType);
+ eDamage = EffectLinkEffects(eDamage, EffectDamage(iDamage / 2, iDamageType2));
+ }
+ if(nHellFire)
+ eDamage = EffectLinkEffects(eDamage, EffectDamage(d6(nHellFire), DAMAGE_TYPE_DIVINE));
+ }
+ else if(iDamageType == DAMAGE_TYPE_ACID || iDamageType2 == DAMAGE_TYPE_ACID)
+ {
+ if(iDamageType == iDamageType2)
+ eDamage = EffectDamage(iDamage, iDamageType);
+ else
+ eDamage = EffectDamage(iDamage / 2, iDamageType);
+ }
+
+ ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
+ }
+ }
+}
+
+int HellFireConDamage(object oPC)
+{
+ if(GetIsImmune(oPC, IMMUNITY_TYPE_ABILITY_DECREASE))
+ {
+ if(DEBUG) DoDebug("HellFireConDamage: Immune to ability damage!");
+ return FALSE;
+ }
+
+ ApplyAbilityDamage(oPC, ABILITY_CONSTITUTION, 1, DURATION_TYPE_TEMPORARY, TRUE, -1.0);
+ return TRUE;
+}
+
+int GetIsHellFireBlast(object oPC)
+{
+ if(GetLocalInt(oPC, "INV_HELLFIRE"))
+ {
+ DeleteLocalInt(oPC, "INV_HELLFIRE");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//:: void main (){}
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_invknown.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_invknown.nss
new file mode 100644
index 00000000..1293080d
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_invknown.nss
@@ -0,0 +1,531 @@
+//::///////////////////////////////////////////////
+//:: Invocation include: Invocations Known
+//:: inv_inc_invknown
+//::///////////////////////////////////////////////
+/** @file
+ Defines functions for adding & removing
+ Invocations known.
+
+ Data stored:
+
+ - For each Class list
+ -- Total number of Invocations known
+ -- A modifier value to maximum Invocations known on this list to account for feats and classes that add Invocations
+ -- An array related to Invocations the knowledge of which is not dependent on character level
+ --- Each array entry specifies the spells.2da row of the known Invocations's class-specific entry
+ -- For each character level on which Invocations have been gained from this list
+ --- An array of Invocations gained on this level
+ ---- Each array entry specifies the spells.2da row of the known Invocations's class-specific entry
+
+ @author Fox
+ @date Created - 2008.01.25
+*/
+//:://////////////////////////////////////////////
+//:://////////////////////////////////////////////
+
+// Included here to provide the values for the constants below
+#include "prc_class_const"
+
+//////////////////////////////////////////////////
+/* Constants */
+//////////////////////////////////////////////////
+
+const int INVOCATION_LIST_DRAGONFIRE_ADEPT = CLASS_TYPE_DRAGONFIRE_ADEPT;
+const int INVOCATION_LIST_WARLOCK = CLASS_TYPE_WARLOCK;
+const int INVOCATION_LIST_DRAGON_SHAMAN = CLASS_TYPE_DRAGON_SHAMAN;
+
+/// Special Maneuver list. Maneuvers gained via Extra Invocation or other sources.
+const int INVOCATION_LIST_EXTRA = CLASS_TYPE_INVALID;//-1;
+const int INVOCATION_LIST_EXTRA_EPIC = /*CLASS_TYPE_INVALID - 1;*/-2; //needs a constant in there to compile properly
+
+const string _INVOCATION_LIST_NAME_BASE = "PRC_InvocationList_";
+const string _INVOCATION_LIST_TOTAL_KNOWN = "_TotalKnown";
+const string _INVOCATION_LIST_MODIFIER = "_KnownModifier";
+const string _INVOCATION_LIST_EXTRA_ARRAY = "_InvocationsKnownExtraArray";
+const string _INVOCATION_LIST_EXTRA_EPIC_ARRAY = "_InvocationsKnownExtraEpicArray";
+const string _INVOCATION_LIST_LEVEL_ARRAY = "_InvocationsKnownLevelArray_";
+const string _INVOCATION_LIST_GENERAL_ARRAY = "_InvocationsKnownGeneralArray";
+
+int GetPrimaryInvocationClass(object oCreature);
+int GetInvocationPRCLevels(object oCreature);
+
+//////////////////////////////////////////////////
+/* Function prototypes */
+//////////////////////////////////////////////////
+
+/**
+ * Gives the creature the control feats for the given Invocation and marks the Invocation
+ * in a Invocations known array.
+ * If the Invocation's data is already stored in one of the Invocations known arrays for
+ * the list or adding the Invocation's data to the array fails, the function aborts.
+ *
+ * @param oCreature The creature to gain the Invocation
+ * @param nList The list the Invocation comes from. One of INVOCATION_LIST_*
+ * @param n2daRow The 2da row in the lists's 2da file that specifies the Invocation.
+ * @param bLevelDependent If this is TRUE, the Invocation is tied to a certain level and can
+ * be lost via level loss. If FALSE, the Invocation is not dependent
+ * of a level and cannot be lost via level loss.
+ * @param nLevelToTieTo If bLevelDependent is TRUE, this specifies the level the Invocation
+ * is gained on. Otherwise, it's ignored.
+ * The default value (-1) means that the current level of oCreature
+ * will be used.
+ *
+ * @return TRUE if the Invocation was successfully stored and control feats added.
+ * FALSE otherwise.
+ */
+int AddInvocationKnown(object oCreature, int nList, int n2daRow, int bLevelDependent = FALSE, int nLevelToTieTo = -1);
+
+/**
+ * Removes all Invocations gained from each list on the given level.
+ *
+ * @param oCreature The creature whose Invocations to remove
+ * @param nLevel The level to clear
+ */
+void RemoveInvocationsKnownOnLevel(object oCreature, int nLevel);
+
+/**
+ * Gets the value of the Invocations known modifier, which is a value that is added
+ * to the 2da-specified maximum Invocations known to determine the actual maximum.
+ *
+ * @param oCreature The creature whose modifier to get
+ * @param nList The list the maximum Invocations known from which the modifier
+ * modifies. One of INVOCATION_LIST_*
+ */
+int GetKnownInvocationsModifier(object oCreature, int nList);
+
+/**
+ * Sets the value of the Invocations known modifier, which is a value that is added
+ * to the 2da-specified maximum Invocations known to determine the actual maximum.
+ *
+ * @param oCreature The creature whose modifier to set
+ * @param nList The list the maximum Invocations known from which the modifier
+ * modifies. One of INVOCATION_LIST_*
+ */
+void SetKnownInvocationsModifier(object oCreature, int nList, int nNewValue);
+
+/**
+ * Gets the number of Invocations a character character possesses from a
+ * specific list and lexicon
+ *
+ * @param oCreature The creature whose Invocations to check
+ * @param nList The list to check. One of INVOCATION_LIST_*
+ * @return The number of Invocations known oCreature has from nList
+ */
+int GetInvocationCount(object oCreature, int nList);
+
+/**
+ * Gets the maximum number of Invocations a character may posses from a given list
+ * at this time. Calculated based on class levels, feats and a misceallenous
+ * modifier. There are three Types of Invocations, so it checks each seperately.
+ *
+ * @param oCreature Character to determine maximum Invocations for
+ * @param nList INVOCATION_LIST_* of the list to determine maximum Invocations for
+ * @return Maximum number of Invocations that oCreature may know from the given list.
+ */
+int GetMaxInvocationCount(object oCreature, int nList);
+
+/**
+ * Determines whether a character has a given Invocation, gained via some Invocation list.
+ *
+ * @param nInvocation INVOKE_* of the Invocation to test
+ * @param oCreature Character to test for the possession of the Invocation
+ * @return TRUE if the character has the Invocation, FALSE otherwise
+ */
+int GetHasInvocation(int nInvocation, object oCreature = OBJECT_SELF);
+
+//////////////////////////////////////////////////
+/* Includes */
+//////////////////////////////////////////////////
+
+#include "inc_item_props"
+#include "prc_x2_itemprop"
+#include "inc_lookups"
+#include "prc_inc_nwscript"
+
+//////////////////////////////////////////////////
+/* Internal functions */
+//////////////////////////////////////////////////
+
+void _InvocationRecurseRemoveArray(object oCreature, string sArrayName, string sInvocFile, int nArraySize, int nCurIndex)
+{
+ if(DEBUG) DoDebug("_InvocationRecurseRemoveArray():\n"
+ + "oCreature = " + DebugObject2Str(oCreature) + "\n"
+ + "sArrayName = '" + sArrayName + "'\n"
+ + "sInvocFile = '" + sInvocFile + "'\n"
+ + "nArraySize = " + IntToString(nArraySize) + "\n"
+ + "nCurIndex = " + IntToString(nCurIndex) + "\n"
+ );
+
+ // Determine whether we've already parsed the whole array or not
+ if(nCurIndex >= nArraySize)
+ {
+ if(DEBUG) DoDebug("_InvocationRecurseRemoveArray(): Running itemproperty removal loop.");
+ // Loop over itemproperties on the skin and remove each match
+ object oSkin = GetPCSkin(oCreature);
+ itemproperty ipTest = GetFirstItemProperty(oSkin);
+ while(GetIsItemPropertyValid(ipTest))
+ {
+ // Check if the itemproperty is a bonus feat that has been marked for removal
+ if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_BONUS_FEAT &&
+ GetLocalInt(oCreature, "PRC_InvocFeatRemovalMarker_" + IntToString(GetItemPropertySubType(ipTest)))
+ )
+ {
+ if(DEBUG) DoDebug("_InvocationRecurseRemoveArray(): Removing bonus feat itemproperty:\n" + DebugIProp2Str(ipTest));
+ // If so, remove it
+ RemoveItemProperty(oSkin, ipTest);
+ }
+
+ ipTest = GetNextItemProperty(oSkin);
+ }
+ }
+ // Still parsing the array
+ else
+ {
+ // Set the marker
+ string sName = "PRC_InvocFeatRemovalMarker_" + Get2DACache(sInvocFile, "IPFeatID",
+ GetPowerfileIndexFromSpellID(persistant_array_get_int(oCreature, sArrayName, nCurIndex))
+ );
+ if(DEBUG) DoDebug("_InvocationRecurseRemoveArray(): Recursing through array, marker set:\n" + sName);
+
+ SetLocalInt(oCreature, sName, TRUE);
+ // Recurse to next array index
+ _InvocationRecurseRemoveArray(oCreature, sArrayName, sInvocFile, nArraySize, nCurIndex + 1);
+ // After returning, delete the local
+ DeleteLocalInt(oCreature, sName);
+ }
+}
+
+void _RemoveInvocationArray(object oCreature, int nList, int nLevel)
+{
+ if(DEBUG) DoDebug("_RemoveInvocationArray():\n"
+ + "oCreature = " + DebugObject2Str(oCreature) + "\n"
+ + "nList = " + IntToString(nList) + "\n"
+ );
+
+ string sBase = _INVOCATION_LIST_NAME_BASE + IntToString(nList);
+ string sArray = sBase + _INVOCATION_LIST_LEVEL_ARRAY + IntToString(nLevel);
+ int nSize = persistant_array_get_size(oCreature, sArray);
+
+ // Reduce the total by the array size
+ SetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN,
+ GetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN) - nSize
+ );
+
+ // Remove each Invocation in the array
+ _InvocationRecurseRemoveArray(oCreature, sArray, GetAMSDefinitionFileName(nList), nSize, 0);
+
+ // Remove the array itself
+ persistant_array_delete(oCreature, sArray);
+}
+
+//////////////////////////////////////////////////
+/* Function definitions */
+//////////////////////////////////////////////////
+
+int AddInvocationKnown(object oCreature, int nList, int n2daRow, int bLevelDependent = FALSE, int nLevelToTieTo = -1)
+{
+ string sBase = _INVOCATION_LIST_NAME_BASE + IntToString(nList);
+ string sArray = sBase;
+ string sPowerFile = GetAMSDefinitionFileName(/*PowerListToClassType(*/nList/*)*/);
+ if(nList == -2 || nList == CLASS_TYPE_INVALID)
+ {
+ sPowerFile = GetAMSDefinitionFileName(GetPrimaryInvocationClass(oCreature));
+ }
+ string sTestArray;
+ int i, j, nSize, bReturn;
+
+ // Get the spells.2da row corresponding to the cls_psipw_*.2da row
+ int nSpells2daRow = StringToInt(Get2DACache(sPowerFile, "SpellID", n2daRow));
+
+ // Determine the array name.
+ if(bLevelDependent)
+ {
+ // If no level is specified, default to the creature's current level
+ if(nLevelToTieTo == -1)
+ nLevelToTieTo = GetHitDice(oCreature);
+
+ sArray += _INVOCATION_LIST_LEVEL_ARRAY + IntToString(nLevelToTieTo);
+ }
+ else
+ {
+ sArray += _INVOCATION_LIST_GENERAL_ARRAY;
+ }
+
+ // Make sure the power isn't already in an array. If it is, abort and return FALSE
+ // Loop over each level array and check that it isn't there.
+ if(DEBUG) DoDebug("inv_inc_invknown: Checking first array set for duplicates.");
+ for(i = 1; i <= GetHitDice(oCreature); i++)
+ {
+ sTestArray = sBase + _INVOCATION_LIST_LEVEL_ARRAY + IntToString(i);
+ if(persistant_array_exists(oCreature, sTestArray))
+ {
+ nSize = persistant_array_get_size(oCreature, sTestArray);
+ for(j = 0; j < nSize; j++)
+ if(persistant_array_get_int(oCreature, sArray, j) == nSpells2daRow)
+ return FALSE;
+ }
+ }
+ // Check the non-level-dependent array
+ if(DEBUG) DoDebug("inv_inc_invknown: Checking second array set for duplicates.");
+ sTestArray = sBase + _INVOCATION_LIST_GENERAL_ARRAY;
+ if(persistant_array_exists(oCreature, sTestArray))
+ {
+ nSize = persistant_array_get_size(oCreature, sTestArray);
+ for(j = 0; j < nSize; j++)
+ if(persistant_array_get_int(oCreature, sArray, j) == nSpells2daRow)
+ return FALSE;
+ }
+
+ // All checks are made, now start adding the new power
+ // Create the array if it doesn't exist yet
+ if(!persistant_array_exists(oCreature, sArray))
+ persistant_array_create(oCreature, sArray);
+
+ // Store the power in the array
+ if(DEBUG) DoDebug("inv_inc_invknown: Adding to invocation array.");
+ if(persistant_array_set_int(oCreature, sArray, persistant_array_get_size(oCreature, sArray), nSpells2daRow) != SDL_SUCCESS)
+ {
+ if(DEBUG) DoDebug("inv_inc_invknown: AddPowerKnown(): ERROR: Unable to add power to known array\n"
+ + "oCreature = " + DebugObject2Str(oCreature) + "\n"
+ + "nList = " + IntToString(nList) + "\n"
+ + "n2daRow = " + IntToString(n2daRow) + "\n"
+ + "bLevelDependent = " + DebugBool2String(bLevelDependent) + "\n"
+ + "nLevelToTieTo = " + IntToString(nLevelToTieTo) + "\n"
+ + "nSpells2daRow = " + IntToString(nSpells2daRow) + "\n"
+ );
+ return FALSE;
+ }
+
+ // Increment Invocations known total
+ SetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN,
+ GetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN) + 1
+ );
+
+ // Give the power's control feats
+ object oSkin = GetPCSkin(oCreature);
+ string sPowerFeatIP = Get2DACache(sPowerFile, "IPFeatID", n2daRow);
+ itemproperty ipFeat = PRCItemPropertyBonusFeat(StringToInt(sPowerFeatIP));
+ IPSafeAddItemProperty(oSkin, ipFeat, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
+ // Second power feat, if any
+ sPowerFeatIP = Get2DACache(sPowerFile, "IPFeatID2", n2daRow);
+ if(sPowerFeatIP != "")
+ {
+ ipFeat = PRCItemPropertyBonusFeat(StringToInt(sPowerFeatIP));
+ IPSafeAddItemProperty(oSkin, ipFeat, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
+ }
+
+ return TRUE;
+}
+
+void RemoveInvocationsKnownOnLevel(object oCreature, int nLevel)
+{
+ if(DEBUG) DoDebug("inv_inc_invknown: RemoveInvocationKnownOnLevel():\n"
+ + "oCreature = " + DebugObject2Str(oCreature) + "\n"
+ + "nLevel = " + IntToString(nLevel) + "\n"
+ );
+
+ string sPostFix = _INVOCATION_LIST_LEVEL_ARRAY + IntToString(nLevel);
+ // For each Invocation list, determine if an array exists for this level.
+ if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_DRAGONFIRE_ADEPT) + sPostFix))
+ // If one does exist, clear it
+ _RemoveInvocationArray(oCreature, INVOCATION_LIST_DRAGONFIRE_ADEPT, nLevel);
+
+ if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_WARLOCK) + sPostFix))
+ _RemoveInvocationArray(oCreature, INVOCATION_LIST_WARLOCK, nLevel);
+
+ if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_DRAGON_SHAMAN) + sPostFix))
+ _RemoveInvocationArray(oCreature, INVOCATION_LIST_DRAGON_SHAMAN, nLevel);
+
+ if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_EXTRA) + sPostFix))
+ _RemoveInvocationArray(oCreature, INVOCATION_LIST_EXTRA, nLevel);
+
+ if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_EXTRA_EPIC) + sPostFix))
+ _RemoveInvocationArray(oCreature, INVOCATION_LIST_EXTRA_EPIC, nLevel);
+}
+
+int GetKnownInvocationsModifier(object oCreature, int nList)
+{
+ return GetPersistantLocalInt(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(nList) + _INVOCATION_LIST_MODIFIER);
+}
+
+void SetKnownInvocationsModifier(object oCreature, int nList, int nNewValue)
+{
+ SetPersistantLocalInt(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(nList) + _INVOCATION_LIST_MODIFIER, nNewValue);
+}
+
+int GetInvocationCount(object oCreature, int nList)
+{
+ return GetPersistantLocalInt(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(nList) + _INVOCATION_LIST_TOTAL_KNOWN);
+}
+
+int GetMaxInvocationCount(object oCreature, int nList)
+{
+ int nMaxInvocations = 0;
+
+ switch(nList)
+ {
+ case INVOCATION_LIST_DRAGONFIRE_ADEPT:{
+ // Determine base Invocations known
+ int nLevel = GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oCreature);
+ nLevel += GetPrimaryInvocationClass(oCreature) == CLASS_TYPE_DRAGONFIRE_ADEPT ? GetInvocationPRCLevels(oCreature) : 0;
+ if(nLevel == 0)
+ break;
+ nMaxInvocations = StringToInt(Get2DACache(GetAMSKnownFileName(CLASS_TYPE_DRAGONFIRE_ADEPT), "InvocationKnown", nLevel - 1));
+
+ // Calculate feats
+
+ // Add in the custom modifier
+ nMaxInvocations += GetKnownInvocationsModifier(oCreature, nList);
+ break;
+ }
+
+ case INVOCATION_LIST_WARLOCK:{
+ // Determine base Invocations known
+ int nLevel = GetLevelByClass(CLASS_TYPE_WARLOCK, oCreature);
+ nLevel += GetPrimaryInvocationClass(oCreature) == CLASS_TYPE_WARLOCK ? GetInvocationPRCLevels(oCreature) : 0;
+ if(nLevel == 0)
+ break;
+ nMaxInvocations = StringToInt(Get2DACache(GetAMSKnownFileName(CLASS_TYPE_WARLOCK), "InvocationKnown", nLevel - 1));
+
+ // Calculate feats
+
+ // Add in the custom modifier
+ nMaxInvocations += GetKnownInvocationsModifier(oCreature, nList);
+ break;
+ }
+
+ case INVOCATION_LIST_DRAGON_SHAMAN:{
+ // Determine base Invocations known
+ int nLevel = GetLevelByClass(CLASS_TYPE_DRAGON_SHAMAN, oCreature);
+ nLevel += GetPrimaryInvocationClass(oCreature) == CLASS_TYPE_DRAGON_SHAMAN ? GetInvocationPRCLevels(oCreature) : 0;
+ if(nLevel == 0)
+ break;
+ nMaxInvocations = StringToInt(Get2DACache(GetAMSKnownFileName(CLASS_TYPE_DRAGON_SHAMAN), "InvocationKnown", nLevel - 1));
+
+ // Calculate feats
+
+ // Add in the custom modifier
+ nMaxInvocations += GetKnownInvocationsModifier(oCreature, nList);
+ break;
+ }
+
+ case INVOCATION_LIST_EXTRA:
+ nMaxInvocations = GetHasFeat(FEAT_EXTRA_INVOCATION_I, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_II, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_III, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_IV, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_V, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_VI, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_VII, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_VIII, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_IX, oCreature) +
+ GetHasFeat(FEAT_EXTRA_INVOCATION_X, oCreature);
+ break;
+
+ case INVOCATION_LIST_EXTRA_EPIC:
+ nMaxInvocations = GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_I, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_II, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_III, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_IV, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_V, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_VI, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_VII, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_VIII, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_IX, oCreature) +
+ GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_X, oCreature);
+ break;
+
+ default:{
+ string sErr = "GetMaxInvocationCount(): ERROR: Unknown power list value: " + IntToString(nList);
+ if(DEBUG) DoDebug(sErr);
+ else WriteTimestampedLogEntry(sErr);
+ }
+ }
+
+ return nMaxInvocations;
+}
+
+int GetHasInvocation(int nInvocation, object oCreature = OBJECT_SELF)
+{
+ if((GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oCreature)
+ && GetHasFeat(GetClassFeatFromPower(nInvocation, CLASS_TYPE_DRAGONFIRE_ADEPT), oCreature)
+ ) ||
+ (GetLevelByClass(CLASS_TYPE_WARLOCK, oCreature)
+ && GetHasFeat(GetClassFeatFromPower(nInvocation, CLASS_TYPE_WARLOCK), oCreature)
+ ) ||
+ (GetLevelByClass(CLASS_TYPE_DRAGON_SHAMAN, oCreature)
+ && GetHasFeat(GetClassFeatFromPower(nInvocation, CLASS_TYPE_DRAGON_SHAMAN), oCreature)
+ )
+ // add new Invocation classes here
+ )
+ return TRUE;
+ return FALSE;
+}
+
+string DebugListKnownInvocations(object oCreature)
+{
+ string sReturn = "Invocations known by " + DebugObject2Str(oCreature) + ":\n";
+ int i, j, k, numPowerLists = 6;
+ int nPowerList, nSize;
+ string sTemp, sArray, sArrayBase, sPowerFile;
+ // Loop over all power lists
+ for(i = 1; i <= numPowerLists; i++)
+ {
+ // Some padding
+ sReturn += " ";
+ // Get the power list for this loop
+ switch(i)
+ {
+ case 1: nPowerList = INVOCATION_LIST_DRAGONFIRE_ADEPT; sReturn += "Dragonfire Adept"; break;
+
+ case 2: nPowerList = INVOCATION_LIST_WARLOCK; sReturn += "Warlock"; break;
+ case 3: nPowerList = INVOCATION_LIST_DRAGON_SHAMAN; sReturn += "Dragon Shaman"; break;
+
+ // This should always be last
+ case 5: nPowerList = INVOCATION_LIST_EXTRA; sReturn += "Extra"; break;
+ case 6: nPowerList = INVOCATION_LIST_EXTRA_EPIC; sReturn += "Epic Extra"; break;
+ }
+ sReturn += " Invocations known:\n";
+
+ // Determine if the character has any Invocations from this list
+ sPowerFile = GetAMSDefinitionFileName(nPowerList);
+ sArrayBase = _INVOCATION_LIST_NAME_BASE + IntToString(nPowerList);
+
+ // Loop over levels
+ for(j = 1; j <= GetHitDice(oCreature); j++)
+ {
+ sArray = sArrayBase + _INVOCATION_LIST_LEVEL_ARRAY + IntToString(j);
+ if(persistant_array_exists(oCreature, sArray))
+ {
+ sReturn += " Gained on level " + IntToString(j) + ":\n";
+ nSize = persistant_array_get_size(oCreature, sArray);
+ for(k = 0; k < nSize; k++)
+ sReturn += " " + GetStringByStrRef(StringToInt(Get2DACache(sPowerFile, "Name",
+ GetPowerfileIndexFromSpellID(persistant_array_get_int(oCreature, sArray, k))
+ )
+ )
+ )
+ + "\n";
+ }
+ }
+
+ // Non-leveldependent Invocations
+ sArray = sArrayBase + _INVOCATION_LIST_GENERAL_ARRAY;
+ if(persistant_array_exists(oCreature, sArray))
+ {
+ sReturn += " Non-leveldependent:\n";
+ nSize = persistant_array_get_size(oCreature, sArray);
+ for(k = 0; k < nSize; k++)
+ sReturn += " " + GetStringByStrRef(StringToInt(Get2DACache(sPowerFile, "Name",
+ GetPowerfileIndexFromSpellID(persistant_array_get_int(oCreature, sArray, k))
+ )
+ )
+ )
+ + "\n";
+ }
+ }
+
+ return sReturn;
+}
+// Test main
+//void main(){}
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_invoke.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_invoke.nss
new file mode 100644
index 00000000..c9dcb99a
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/inv_inc_invoke.nss
@@ -0,0 +1,582 @@
+//::///////////////////////////////////////////////
+//:: Invocation include: Casting
+//:: inv_inc_invoke
+//::///////////////////////////////////////////////
+/** @file
+ Defines structures and functions for handling
+ initiating a invocation
+
+ @author Fox
+ @date Created - 2008.1.26
+ @thanks to Ornedan for his work on Psionics upon which this is based.
+*/
+//:://////////////////////////////////////////////
+//:://////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////
+/* Constants */
+//////////////////////////////////////////////////
+
+const string PRC_INVOKING_CLASS = "PRC_CurrentInvocation_InitiatingClass";
+const string PRC_INVOCATION_LEVEL = "PRC_CurrentInvocation_Level";
+const string INV_DEBUG_IGNORE_CONSTRAINTS = "INV_DEBUG_IGNORE_CONSTRAINTS";
+
+/**
+ * The variable in which the invocation token is stored. If no token exists,
+ * the variable is set to point at the invoker itself. That way OBJECT_INVALID
+ * means the variable is unitialised.
+ */
+//const string PRC_INVOCATION_TOKEN_VAR = "PRC_InvocationToken";
+//const string PRC_INVOCATION_TOKEN_NAME = "PRC_INVOKETOKEN";
+//const float PRC_INVOCATION_HB_DELAY = 0.5f;
+
+
+ int GetInvokerLevel(object oInvoker = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID, int bPracticedInvoker = TRUE);
+ int GetInvocationLevel(object oInvoker);
+ int GetInvokingClass(object oInvoker = OBJECT_SELF);
+
+
+//////////////////////////////////////////////////
+/* Structures */
+//////////////////////////////////////////////////
+
+/**
+ * A structure that contains common data used during invocation.
+ */
+struct invocation{
+ /* Generic stuff */
+ /// The creature Truespeaking the Invocation
+ object oInvoker;
+ /// Whether the invocation is successful or not
+ int bCanInvoke;
+ /// The creature's invoker level in regards to this invocation
+ int nInvokerLevel;
+ /// The invocation's spell ID
+ int nInvocationId;
+};
+
+//////////////////////////////////////////////////
+/* Function prototypes */
+//////////////////////////////////////////////////
+
+/**
+ * Determines if the invocation that is currently being attempted to be TrueSpoken
+ * can in fact be truespoken. Determines metainvocations used.
+ *
+ * @param oInvoker A creature attempting to truespeak a invocation at this moment.
+ * @param oTarget The target of the invocation, if any. For pure Area of Effect.
+ * invocations, this should be OBJECT_INVALID. Otherwise the main
+ * target of the invocation as returned by PRCGetSpellTargetObject().
+ *
+ * @return A invocation structure that contains the data about whether
+ * the invocation was successfully initiated and some other
+ * commonly used data, like the PC's invoker level for this invocation.
+ */
+struct invocation EvaluateInvocation(object oInvoker, object oTarget);
+
+/**
+ * Causes OBJECT_SELF to use the given invocation.
+ *
+ * @param nInvocation The index of the invocation to use in spells.2da or an UTTER_*
+ * @param nClass The index of the class to use the invocation as in classes.2da or a CLASS_TYPE_*
+ * @param nLevelOverride An optional override to normal invoker level.
+ * @param bInstant If true invocation will be used without casting animations (eldritch sculptor)
+ * Default: 0, which means the parameter is ignored.
+ */
+void UseInvocation(int nInvocation, int nClass, int nLevelOverride = 0, int bInstant = FALSE);
+
+/**
+ * A debugging function. Takes a invocation structure and
+ * makes a string describing the contents.
+ *
+ * @param move A set of invocation data
+ * @return A string describing the contents of move
+ */
+string DebugInvocation2Str(struct invocation invoked);
+
+/**
+ * Stores a invocation structure as a set of local variables. If
+ * a structure was already stored with the same name on the same object,
+ * it is overwritten.
+ *
+ * @param oObject The object on which to store the structure
+ * @param sName The name under which to store the structure
+ * @param move The invocation structure to store
+ */
+void SetLocalInvocation(object oObject, string sName, struct invocation invoked);
+
+/**
+ * Retrieves a previously stored invocation structure. If no structure is stored
+ * by the given name, the structure returned is empty.
+ *
+ * @param oObject The object from which to retrieve the structure
+ * @param sName The name under which the structure is stored
+ * @return The structure built from local variables stored on oObject under sName
+ */
+struct invocation GetLocalInvocation(object oObject, string sName);
+
+/**
+ * Deletes a stored invocation structure.
+ *
+ * @param oObject The object on which the structure is stored
+ * @param sName The name under which the structure is stored
+ */
+void DeleteLocalInvocation(object oObject, string sName);
+
+//////////////////////////////////////////////////
+/* Includes */
+//////////////////////////////////////////////////
+
+//#include "inv_inc_invfunc" //Access in parent
+#include "prc_spellf_inc"
+
+//////////////////////////////////////////////////
+/* Internal functions */
+//////////////////////////////////////////////////
+
+/** Internal function.
+ * Handles Spellfire absorption when a utterance is used on a friendly spellfire
+ * user.
+ */
+struct invocation _DoInvocationSpellfireFriendlyAbsorption(struct invocation invoked, object oTarget)
+{
+ if(GetLocalInt(oTarget, "SpellfireAbsorbFriendly") &&
+ GetIsFriend(oTarget, invoked.oInvoker)
+ )
+ {
+ if(CheckSpellfire(invoked.oInvoker, oTarget, TRUE))
+ {
+ PRCShowSpellResist(invoked.oInvoker, oTarget, SPELL_RESIST_MANTLE);
+ invoked.bCanInvoke = FALSE;
+ }
+ }
+
+ return invoked;
+}
+
+/** Internal function.
+ * Sets invocation-related local variables.
+ *
+ * @param oInvoker The creature currently casting invocation
+ * @param nClass Invocation casting class constant
+ * @param nLevel Invocation level
+ */
+void _SetInvocationVariables(object oInvoker, int nClass, int nLevel)
+{
+ if (DEBUG) FloatingTextStringOnCreature(GetName(oInvoker)+" is a "+IntToString(nClass)+" at "+IntToString(nLevel)+" invocation level", oInvoker);
+ SetLocalInt(oInvoker, PRC_INVOKING_CLASS, nClass + 1);
+ SetLocalInt(oInvoker, PRC_INVOCATION_LEVEL, nLevel);
+}
+
+
+/** Internal function.
+ * Deletes invocation-related local variables.
+ *
+ * @param oInvoker The creature currently initiating a invocation
+ */
+void _CleanInvocationVariables(object oInvoker)
+{
+ DeleteLocalInt(oInvoker, PRC_INVOKING_CLASS);
+ DeleteLocalInt(oInvoker, PRC_INVOCATION_LEVEL);
+}
+
+/** Internal function.
+ * Determines whether a invocation token exists. If one does, returns it.
+ *
+ * @param oInvoker A creature whose invocation token to get
+ * @return The invocation token if it exists, OBJECT_INVALID otherwise.
+ */
+/*object _GetInvocationToken(object oInvoker)
+{
+ object oInvokeToken = GetLocalObject(oInvoker, PRC_INVOCATION_TOKEN_VAR);
+
+ // If the token object is no longer valid, set the variable to point at invoker
+ if(!GetIsObjectValid(oInvokeToken))
+ {
+ oInvokeToken = oInvoker;
+ SetLocalObject(oInvoker, PRC_INVOCATION_TOKEN_VAR, oInvokeToken);
+ }
+
+
+ // Check if there is no token
+ if(oInvokeToken == oInvoker)
+ oInvokeToken = OBJECT_INVALID;
+
+ return oInvokeToken;
+}*/
+
+/** Internal function.
+ * Destroys the given invocation token and sets the creature's invocation token variable
+ * to point at itself.
+ *
+ * @param oInvoker The invoker whose token to destroy
+ * @param oInvokeToken The token to destroy
+ */
+/*void _DestroyInvocationToken(object oInvoker, object oInvokeToken)
+{
+ DestroyObject(oInvokeToken);
+ SetLocalObject(oInvoker, PRC_INVOCATION_TOKEN_VAR, oInvoker);
+}*/
+
+/** Internal function.
+ * Destroys the previous invocation token, if any, and creates a new one.
+ *
+ * @param oInvoker A creature for whom to create a invocation token
+ * @return The newly created token
+ */
+/*object _CreateInvocationToken(object oInvoker)
+{
+ object oInvokeToken = _GetInvocationToken(oInvoker);
+ object oStore = GetObjectByTag("PRC_MANIFTOKEN_STORE"); //GetPCSkin(oInvoker);
+
+ // Delete any previous tokens
+ if(GetIsObjectValid(oInvokeToken))
+ _DestroyInvocationToken(oInvoker, oInvokeToken);
+
+ // Create new token and store a reference to it
+ oInvokeToken = CreateItemOnObject(PRC_INVOCATION_TOKEN_NAME, oStore);
+ SetLocalObject(oInvoker, PRC_INVOCATION_TOKEN_VAR, oInvokeToken);
+
+ Assert(GetIsObjectValid(oInvokeToken), "GetIsObjectValid(oInvokeToken)", "ERROR: Unable to create invocation token! Store object: " + DebugObject2Str(oStore), "inv_inc_invoke", "_CreateInvocationToken()");
+
+ return oInvokeToken;
+}*/
+
+/** Internal function.
+ * Determines whether the given invoker is doing something that would
+ * interrupt initiating a invocation or affected by an effect that would do
+ * the same.
+ *
+ * @param oInvoker A creature on which _InvocationHB() is running
+ * @return TRUE if the creature can continue initiating,
+ * FALSE otherwise
+ */
+/*int _InvocationStateCheck(object oInvoker)
+{
+ int nAction = GetCurrentAction(oInvoker);
+ // If the current action is not among those that could either be used to truespeak the invocation or movement, the invocation fails
+ if(!(nAction || ACTION_CASTSPELL || nAction == ACTION_INVALID ||
+ nAction || ACTION_ITEMCASTSPELL || nAction == ACTION_MOVETOPOINT ||
+ nAction || ACTION_USEOBJECT || nAction == ACTION_WAIT
+ ) )
+ return FALSE;
+
+ // Affected by something that prevents one from initiating
+ effect eTest = GetFirstEffect(oInvoker);
+ int nEType;
+ while(GetIsEffectValid(eTest))
+ {
+ nEType = GetEffectType(eTest);
+ if(nEType == EFFECT_TYPE_CUTSCENE_PARALYZE ||
+ nEType == EFFECT_TYPE_DAZED ||
+ nEType == EFFECT_TYPE_PARALYZE ||
+ nEType == EFFECT_TYPE_PETRIFY ||
+ nEType == EFFECT_TYPE_SLEEP ||
+ nEType == EFFECT_TYPE_STUNNED
+ )
+ return FALSE;
+
+ // Get next effect
+ eTest = GetNextEffect(oInvoker);
+ }
+
+ return TRUE;
+}*/
+
+/** Internal function.
+ * Runs while the given creature is initiating. If they move, take other actions
+ * that would cause them to interrupt initiating the invocation or are affected by an
+ * effect that would cause such interruption, deletes the invocation token.
+ * Stops if such condition occurs or something else destroys the token.
+ *
+ * @param oInvoker A creature initiating a invocation
+ * @param lInvoker The location where the invoker was when starting the invocation
+ * @param oInvokeToken The invocation token that controls the ongoing invocation
+ */
+/*void _InvocationHB(object oInvoker, location lInvoker, object oInvokeToken)
+{
+ if(DEBUG) DoDebug("_InvocationHB() running:\n"
+ + "oInvoker = " + DebugObject2Str(oInvoker) + "\n"
+ + "lInvoker = " + DebugLocation2Str(lInvoker) + "\n"
+ + "oInvokeToken = " + DebugObject2Str(oInvokeToken) + "\n"
+ + "Distance between invocation start location and current location: " + FloatToString(GetDistanceBetweenLocations(lInvoker, GetLocation(oInvoker))) + "\n"
+ );
+ if(GetIsObjectValid(oInvokeToken))
+ {
+ // Continuance check
+ if(GetDistanceBetweenLocations(lInvoker, GetLocation(oInvoker)) > 2.0f || // Allow some variance in the location to account for dodging and random fidgeting
+ !_InvocationStateCheck(oInvoker) // Action and effect check
+ )
+ {
+ if(DEBUG) DoDebug("_InvocationHB(): invoker moved or lost concentration, destroying token");
+ _DestroyInvocationToken(oInvoker, oInvokeToken);
+
+ // Inform invoker
+ FloatingTextStrRefOnCreature(16832980, oInvoker, FALSE); // "You have lost concentration on the invocation you were attempting to cast!"
+ }
+ // Schedule next HB
+ else
+ DelayCommand(PRC_INVOCATION_HB_DELAY, _InvocationHB(oInvoker, lInvoker, oInvokeToken));
+ }
+}*/
+
+/** Internal function.
+ * Checks if the invoker is in range to use the invocation they are trying to use.
+ * If not, queues commands to make the invoker to run into range.
+ *
+ * @param oInvoker A creature initiating a invocation
+ * @param nInvocation SpellID of the invocation being initiated
+ * @param lTarget The target location or the location of the target object
+ */
+/*void _InvocationRangeCheck(object oInvoker, int nInvocation, location lTarget)
+{
+ float fDistance = GetDistanceBetweenLocations(GetLocation(oInvoker), lTarget);
+ float fRangeLimit;
+ string sRange = Get2DACache("spells", "Range", nInvocation);
+
+ // Personal range invocations are always in range
+ if(sRange == "P")
+ return;
+ // Ranges according to the CCG spells.2da page
+ else if(sRange == "T")
+ fRangeLimit = 2.25f;
+ else if(sRange == "S")
+ fRangeLimit = 8.0f;
+ else if(sRange == "M")
+ fRangeLimit = 20.0f;
+ else if(sRange == "L")
+ fRangeLimit = 40.0f;
+
+ // See if we are out of range
+ if(fDistance > fRangeLimit)
+ {
+ // Create waypoint for the movement
+ object oWP = CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", lTarget);
+
+ // Move into range, with a bit of fudge-factor
+ //ActionMoveToObject(oWP, TRUE, fRangeLimit - 0.15f);
+
+ // CleanUp
+ ActionDoCommand(DestroyObject(oWP));
+
+ // CleanUp, paranoia
+ AssignCommand(oWP, ActionDoCommand(DestroyObject(oWP, 60.0f)));
+ }
+}*/
+
+/** Internal function.
+ * Assigns the fakecast command that is used to display the conjuration VFX when using an invocation.
+ * Separated from UseInvocation() due to a bug with ActionFakeCastSpellAtObject(), which requires
+ * use of ClearAllActions() to work around.
+ * The problem is that if the target is an item on the ground, if the actor is out of spell
+ * range when doing the fakecast, they will run on top of the item instead of to the edge of
+ * the spell range. This only happens if there was a "real action" in the actor's action queue
+ * immediately prior to the fakecast.
+ */
+/*void _AssignUseInvocationFakeCastCommands(object oInvoker, object oTarget, location lTarget, int nSpellID)
+{
+ // Nuke actions to prevent the fakecast action from bugging
+ ClearAllActions();
+
+ if(GetIsObjectValid(oTarget))
+ ActionCastFakeSpellAtObject(nSpellID, oTarget, PROJECTILE_PATH_TYPE_DEFAULT);
+ else
+ ActionCastFakeSpellAtLocation(nSpellID, lTarget, PROJECTILE_PATH_TYPE_DEFAULT);
+}*/
+
+
+/** Internal function.
+ * Places the cheatcasting of the real invocation into the invoker's action queue.
+ */
+/*void _UseInvocationAux(object oInvoker, object oInvokeToken, int nSpellId,
+ object oTarget, location lTarget,
+ int nInvocation, int nClass, int nLevelOverride)
+{
+ if(DEBUG) DoDebug("_UseInvocationAux() running:\n"
+ + "oInvoker = " + DebugObject2Str(oInvoker) + "\n"
+ + "oInvokeToken = " + DebugObject2Str(oInvokeToken) + "\n"
+ + "nSpellId = " + IntToString(nSpellId) + "\n"
+ + "oTarget = " + DebugObject2Str(oTarget) + "\n"
+ + "lTarget = " + DebugLocation2Str(lTarget) + "\n"
+ + "nInvocation = " + IntToString(nInvocation) + "\n"
+ + "nClass = " + IntToString(nClass) + "\n"
+ + "nLevelOverride = " + IntToString(nLevelOverride) + "\n"
+ );
+
+ // Make sure nothing has interrupted this invocation
+ if(GetIsObjectValid(oInvokeToken))
+ {
+ if(DEBUG) DoDebug("_UseInvocationAux(): Token was valid, queueing actual invocation");
+ // Set the class to cast as
+ SetLocalInt(oInvoker, PRC_INVOKING_CLASS, nClass + 1);
+
+ // Set the invocation's level
+ SetLocalInt(oInvoker, PRC_INVOCATION_LEVEL, StringToInt(lookup_spell_innate(nSpellId)));
+
+ if(nLevelOverride != 0)
+ AssignCommand(oInvoker, ActionDoCommand(SetLocalInt(oInvoker, PRC_CASTERLEVEL_OVERRIDE, nLevelOverride)));
+ if(GetIsObjectValid(oTarget))
+ AssignCommand(oInvoker, ActionCastSpellAtObject(nInvocation, oTarget, METAMAGIC_NONE, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
+ else
+ AssignCommand(oInvoker, ActionCastSpellAtLocation(nInvocation, lTarget, METAMAGIC_NONE, TRUE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
+ if(nLevelOverride != 0)
+ AssignCommand(oInvoker, ActionDoCommand(DeleteLocalInt(oInvoker, PRC_CASTERLEVEL_OVERRIDE)));
+
+ // Destroy the invocation token for this invocation
+ _DestroyInvocationToken(oInvoker, oInvokeToken);
+ }
+}*/
+
+//////////////////////////////////////////////////
+/* Function definitions */
+//////////////////////////////////////////////////
+
+struct invocation EvaluateInvocation(object oInvoker, object oTarget)
+{
+ /* Get some data */
+ int bIgnoreConstraints = (DEBUG) ? GetLocalInt(oInvoker, INV_DEBUG_IGNORE_CONSTRAINTS) : FALSE;
+ // invoker-related stuff
+ int nInvokerLevel = GetInvokerLevel(oInvoker);
+ int nInvocationLevel = GetInvocationLevel(oInvoker);
+ int nClass = GetInvokingClass(oInvoker);
+
+ /* Initialise the invocation structure */
+ struct invocation invoked;
+ invoked.oInvoker = oInvoker;
+ invoked.bCanInvoke = TRUE; // Assume successfull invocation by default
+ invoked.nInvokerLevel = nInvokerLevel;
+ invoked.nInvocationId = PRCGetSpellId();
+
+ if (DEBUG) FloatingTextStringOnCreature(GetName(oInvoker)+" is a "+IntToString(nClass)+" casting invocation "+IntToString(invoked.nInvocationId)+", a "+IntToString(nInvocationLevel)+" level invocation, at "+IntToString(nInvokerLevel)+" invoker level", oInvoker);
+
+ // Skip doing anything if something has prevented a successful invocation already by this point
+ //if(invoked.bCanInvoke)
+ //{
+ invoked = _DoInvocationSpellfireFriendlyAbsorption(invoked, oTarget);
+ //}//end if
+
+ if(DEBUG) DoDebug("EvaluateInvocation(): Final result:\n" + DebugInvocation2Str(invoked));
+
+ // Initiate invocation-related variable CleanUp
+ //DelayCommand(0.5f, _CleanInvocationVariables(oInvoker));
+
+ return invoked;
+}
+
+void UseInvocation(int nInvocation, int nClass, int nLevelOverride = 0, int bInstant = FALSE)
+{
+ if(nClass < 0)
+ nClass = CLASS_TYPE_WARLOCK;
+ object oInvoker = OBJECT_SELF;
+// object oSkin = GetPCSkin(oInvoker);
+// object oTarget = PRCGetSpellTargetObject();
+// object oInvokeToken;
+// location lTarget = PRCGetSpellTargetLocation();
+// int nSpellID = PRCGetSpellId();
+ //int nInvocationDur = StringToInt(Get2DACache("spells", "ConjTime", nInvocation)) + StringToInt(Get2DACache("spells", "CastTime", nInvocation));
+ // This is a test case to speed up the impact of the melee attacks, as PerformAttackRound takes the full 6 second.
+// int nInvocationDur = 0;
+
+
+ // Setup invocation-related variables
+ ActionDoCommand(_SetInvocationVariables(oInvoker, nClass, StringToInt(lookup_spell_innate(nInvocation))));
+
+ // Cast the actual invocation
+ ActionCastSpell(nInvocation, nLevelOverride, 0, 0, METAMAGIC_NONE, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, bInstant);
+
+ // Initiate invocation-related variable CleanUp
+ ActionDoCommand(_CleanInvocationVariables(oInvoker));
+ // Normally swift action invocations check
+ /*if(Get2DACache("feat", "Constant", GetClassFeatFromPower(nInvocation, nClass)) == "SWIFT_ACTION" && // The invocation is swift action to use
+ TakeSwiftAction(oInvoker) // And the invoker can take a swift action now
+ )
+ {
+ nInvocationDur = 0;
+ }*/
+
+ /*if(DEBUG) DoDebug("UseInvocation(): invoker is " + DebugObject2Str(oInvoker) + "\n"
+ + "nInvocation = " + IntToString(nInvocation) + "\n"
+ + "nClass = " + IntToString(nClass) + "\n"
+ + "nLevelOverride = " + IntToString(nLevelOverride) + "\n"
+ + "invocation duration = " + IntToString(nInvocationDur) + "ms \n"
+ //+ "Token exists = " + DebugBool2String(GetIsObjectValid(oInvokeToken))
+ );*/
+
+ // Create the invocation token. Deletes any old tokens and cancels corresponding invocations as a side effect
+ //oInvokeToken = _CreateInvocationToken(oInvoker);
+
+ /// @todo Hook to the invoker's OnDamaged event for the concentration checks to avoid losing the invocation
+
+ // Nuke action queue to prevent cheating with creative invocation stacking.
+ // Probably not necessary anymore - Ornedan
+ //if(DEBUG) SendMessageToPC(oInvoker, "Clearing all actions in preparation for second stage of the invocation.");
+ //ClearAllActions();
+
+ // If out of range, move to range
+ //_InvocationRangeCheck(oInvoker, nInvocation, GetIsObjectValid(oTarget) ? GetLocation(oTarget) : lTarget);
+
+ // Start the invocation monitor HB
+ //DelayCommand(IntToFloat(nInvocationDur), ActionDoCommand(_InvocationHB(oInvoker, GetLocation(oInvoker), oInvokeToken)));
+
+ // Assuming the spell isn't used as a swift action, fakecast for visuals
+ /*if(nInvocationDur > 0)
+ {
+ // Hack. Workaround of a bug with the fakecast actions. See function comment for details
+ ActionDoCommand(_AssignUseInvocationFakeCastCommands(oInvoker, oTarget, lTarget, nSpellID));
+ }*/
+
+ // Action queue the function that will cheatcast the actual invocation
+ //DelayCommand(IntToFloat(nInvocationDur), AssignCommand(oInvoker, ActionDoCommand(_UseInvocationAux(oInvoker, oInvokeToken, nSpellID, oTarget, lTarget, nInvocation, nClass, nLevelOverride))));
+}
+
+string DebugInvocation2Str(struct invocation invoked)
+{
+ string sRet;
+
+ sRet += "oInvoker = " + DebugObject2Str(invoked.oInvoker) + "\n";
+ sRet += "bCanInvoke = " + DebugBool2String(invoked.bCanInvoke) + "\n";
+ sRet += "nInvokerLevel = " + IntToString(invoked.nInvokerLevel);
+
+ return sRet;
+}
+
+void SetLocalInvocation(object oObject, string sName, struct invocation invoked)
+{
+ //SetLocal (oObject, sName + "_", );
+ SetLocalObject(oObject, sName + "_oInvoker", invoked.oInvoker);
+
+ SetLocalInt(oObject, sName + "_bCanInvoke", invoked.bCanInvoke);
+ SetLocalInt(oObject, sName + "_nInvokerLevel", invoked.nInvokerLevel);
+ SetLocalInt(oObject, sName + "_nSpellID", invoked.nInvocationId);
+}
+
+struct invocation GetLocalInvocation(object oObject, string sName)
+{
+ struct invocation invoked;
+ invoked.oInvoker = GetLocalObject(oObject, sName + "_oInvoker");
+
+ invoked.bCanInvoke = GetLocalInt(oObject, sName + "_bCanInvoke");
+ invoked.nInvokerLevel = GetLocalInt(oObject, sName + "_nInvokerLevel");
+ invoked.nInvocationId = GetLocalInt(oObject, sName + "_nSpellID");
+
+ return invoked;
+}
+
+void DeleteLocalInvocation(object oObject, string sName)
+{
+ DeleteLocalObject(oObject, sName + "_oInvoker");
+
+ DeleteLocalInt(oObject, sName + "_bCanInvoke");
+ DeleteLocalInt(oObject, sName + "_nInvokerLevel");
+ DeleteLocalInt(oObject, sName + "_nSpellID");
+}
+
+void InvocationDebugIgnoreConstraints(object oInvoker)
+{
+ SetLocalInt(oInvoker, INV_DEBUG_IGNORE_CONSTRAINTS, TRUE);
+ DelayCommand(0.0f, DeleteLocalInt(oInvoker, INV_DEBUG_IGNORE_CONSTRAINTS));
+}
+
+// Test main
+//void main(){}
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prc_add_spl_pen.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prc_add_spl_pen.nss
new file mode 100644
index 00000000..5f4cf063
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prc_add_spl_pen.nss
@@ -0,0 +1,446 @@
+//::///////////////////////////////////////////////
+//:: Spells include: Spell Penetration
+//:: prc_add_spl_pen
+//::///////////////////////////////////////////////
+/** @file
+ Defines functions that may have something to do
+ with modifying a spell's caster level in regards
+ to Spell Resistance penetration.
+*/
+//:://////////////////////////////////////////////
+//:://////////////////////////////////////////////
+
+//////////////////////////////////////////////////
+/* Forward Declarations */
+//////////////////////////////////////////////////
+
+int PRCGetMetaMagicFeat(object oCaster = OBJECT_SELF, int bClearFeatFlags = TRUE);
+int GetIsElementalSpell(int nSpellID, int nDescriptor = -1);
+int ShadowWeave(object oCaster, int iSpellID, int nSpellSchool = -1);
+int HexToInt(string sHex);
+int GetIsDeniedDexBonusToAC(object oDefender, object oAttacker, int nIgnoreUD = FALSE);
+object PRCGetSpellTargetObject(object oCaster = OBJECT_SELF);
+int PRCGetSpellId(object oCaster = OBJECT_SELF);
+int GetSpellSchool(int iSpellId);
+int GetEssentiaInvested(object oMeldshaper, int nMeld = -1);
+int PRCGetCasterLevel(object oCaster = OBJECT_SELF);
+int GetEssentiaInvestedFeat(object oMeldshaper, int nFeat);
+
+//////////////////////////////////////////////////
+/* Function prototypes */
+//////////////////////////////////////////////////
+
+int GetHeartWarderPene(int spell_id, object oCaster = OBJECT_SELF);
+
+int ElementalSavantSP(int spell_id, object oCaster = OBJECT_SELF);
+
+int RedWizardSP(int spell_id, int nSchool, object oCaster = OBJECT_SELF);
+
+int GetSpellPenetreFocusSchool(int nSchool, object oCaster = OBJECT_SELF);
+
+int GetSpellPowerBonus(object oCaster = OBJECT_SELF);
+
+int ShadowWeavePen(int spell_id, int nSchool, object oCaster = OBJECT_SELF);
+
+int KOTCSpellPenVsDemons(object oCaster, object oTarget);
+
+int RunecasterRunePowerSP(object oCaster);
+
+int MarshalDeterminedCaster(object oCaster);
+
+int DuskbladeSpellPower(object oCaster, object oTarget);
+
+int DraconicMagicPower(object oCaster);
+
+int TrueCastingSpell(object oCaster);
+
+string ChangedElementalType(int spell_id, object oCaster = OBJECT_SELF);
+
+// Use this function to get the adjustments to a spell or SLAs spell penetration
+// from the various class effects
+// Update this function if any new classes change spell pentration
+int add_spl_pen(object oCaster = OBJECT_SELF);
+
+int SPGetPenetr(object oCaster = OBJECT_SELF);
+
+int SPGetPenetrAOE(object oCaster = OBJECT_SELF, int nCasterLvl = 0);
+
+//////////////////////////////////////////////////
+/* Includes */
+//////////////////////////////////////////////////
+
+//#include "prc_inc_spells"
+//#include "prc_alterations"
+//#include "prcsp_archmaginc"
+//#include "prc_inc_racial"
+#include "inc_2dacache"
+#include "prc_feat_const"
+#include "prc_class_const"
+#include "prc_inc_descrptr"
+#include "prc_inc_racial"
+#include "prc_spell_const"
+#include "inv_invoc_const"
+
+//////////////////////////////////////////////////
+/* Function definitions */
+//////////////////////////////////////////////////
+
+//
+// Determine if a spell type is elemental
+//
+int IsSpellTypeElemental(string type)
+{
+ return type == "Acid"
+ || type == "Cold"
+ || type == "Electricity"
+ || type == "Fire"
+ || type == "Sonic";
+}
+
+int GetHeartWarderPene(int spell_id, object oCaster = OBJECT_SELF)
+{
+ // Guard Expensive Calculations
+ if(!GetHasFeat(FEAT_VOICE_SIREN, oCaster))
+ return 0;
+
+ // Bonus Requires Verbal Spells
+ string VS = GetStringLowerCase(Get2DACache("spells", "VS", spell_id));
+ if(FindSubString(VS, "v") == -1)
+ return 0;
+
+ // These feats provide greater bonuses or remove the Verbal requirement
+ if(PRCGetMetaMagicFeat(oCaster, FALSE) & METAMAGIC_SILENT
+ || GetHasFeat(FEAT_SPELL_PENETRATION, oCaster)
+ || GetHasFeat(FEAT_GREATER_SPELL_PENETRATION, oCaster)
+ || GetHasFeat(FEAT_EPIC_SPELL_PENETRATION, oCaster))
+ return 0;
+
+ return 2;
+}
+
+//
+// Calculate Elemental Savant Contributions
+//
+int ElementalSavantSP(int spell_id, object oCaster = OBJECT_SELF)
+{
+ // get spell elemental type
+ int element = GetIsElementalSpell(spell_id);
+
+ //not an elemental spell
+ if(!element)
+ return 0;
+
+ int nSP = 0;
+
+ // All Elemental Savants will have this feat
+ // when they first gain a penetration bonus.
+ // Otherwise this would require checking ~4 items (class or specific feats)
+ if(GetHasFeat(FEAT_ES_PEN_1, oCaster))
+ {
+ int feat, nES;
+ nES = GetLevelByClass(CLASS_TYPE_ELEMENTAL_SAVANT, oCaster);
+
+ // Specify the elemental type rather than lookup by class?
+ if(element & DESCRIPTOR_FIRE)
+ {
+ feat = FEAT_ES_FIRE;
+ }
+ else if(element & DESCRIPTOR_COLD)
+ {
+ feat = FEAT_ES_COLD;
+ }
+ else if(element & DESCRIPTOR_ELECTRICITY)
+ {
+ feat = FEAT_ES_ELEC;
+ }
+ else if(element & DESCRIPTOR_ACID)
+ {
+ feat = FEAT_ES_ACID;
+ }
+
+ // Now determine the bonus
+ if(feat && GetHasFeat(feat, oCaster))
+ nSP = nES / 3;
+ }
+// SendMessageToPC(GetFirstPC(), "Your Elemental Penetration modifier is " + IntToString(nSP));
+ return nSP;
+}
+
+//Red Wizard SP boost based on spell school specialization
+int RedWizardSP(int spell_id, int nSchool, object oCaster = OBJECT_SELF)
+{
+ int iRedWizard = GetLevelByClass(CLASS_TYPE_RED_WIZARD, oCaster);
+ int nSP;
+
+ if(iRedWizard)
+ {
+ int iRWSpec;
+ switch(nSchool)
+ {
+ case SPELL_SCHOOL_ABJURATION: iRWSpec = FEAT_RW_TF_ABJ; break;
+ case SPELL_SCHOOL_CONJURATION: iRWSpec = FEAT_RW_TF_CON; break;
+ case SPELL_SCHOOL_DIVINATION: iRWSpec = FEAT_RW_TF_DIV; break;
+ case SPELL_SCHOOL_ENCHANTMENT: iRWSpec = FEAT_RW_TF_ENC; break;
+ case SPELL_SCHOOL_EVOCATION: iRWSpec = FEAT_RW_TF_EVO; break;
+ case SPELL_SCHOOL_ILLUSION: iRWSpec = FEAT_RW_TF_ILL; break;
+ case SPELL_SCHOOL_NECROMANCY: iRWSpec = FEAT_RW_TF_NEC; break;
+ case SPELL_SCHOOL_TRANSMUTATION: iRWSpec = FEAT_RW_TF_TRS; break;
+ }
+
+ if(iRWSpec && GetHasFeat(iRWSpec, oCaster))
+ nSP = (iRedWizard / 2) + 1;
+ }
+// SendMessageToPC(GetFirstPC(), "Your Spell Power modifier is " + IntToString(nSP));
+ return nSP;
+}
+
+int GetSpellPenetreFocusSchool(int nSchool, object oCaster = OBJECT_SELF)
+{
+ if(nSchool)
+ {
+ if(GetHasFeat(FEAT_FOCUSED_SPELL_PENETRATION_ABJURATION+nSchool-1, oCaster))
+ return 4;
+ }
+
+ return 0;
+}
+
+int GetSpellPowerBonus(object oCaster = OBJECT_SELF)
+{
+ if(GetHasFeat(FEAT_SPELLPOWER_10, oCaster))
+ return 10;
+ else if(GetHasFeat(FEAT_SPELLPOWER_8, oCaster))
+ return 8;
+ else if(GetHasFeat(FEAT_SPELLPOWER_6, oCaster))
+ return 6;
+ else if(GetHasFeat(FEAT_SPELLPOWER_4, oCaster))
+ return 4;
+ else if(GetHasFeat(FEAT_SPELLPOWER_2, oCaster))
+ return 2;
+
+ return 0;
+}
+
+// Shadow Weave Feat
+// +1 caster level vs SR (school Ench,Illu,Necro)
+int ShadowWeavePen(int spell_id, int nSchool, object oCaster = OBJECT_SELF)
+{
+ int iShadow = GetLevelByClass(CLASS_TYPE_SHADOW_ADEPT, oCaster);
+ int nSP;
+
+ // Apply changes if the caster has level in Shadow Adept class
+ // and this spell is eligible for the spell penetration check increase
+ if (iShadow > 0 && ShadowWeave(oCaster, spell_id, nSchool) == 1)
+ // Shadow Spell Power
+ nSP = iShadow / 3;
+
+ return nSP;
+}
+
+int KOTCSpellPenVsDemons(object oCaster, object oTarget)
+{
+ if(GetLevelByClass(CLASS_TYPE_KNIGHT_CHALICE, oCaster) >= 1)
+ {
+ if(MyPRCGetRacialType(oTarget) == RACIAL_TYPE_OUTSIDER)
+ {
+ if(GetAlignmentGoodEvil(oTarget) == ALIGNMENT_EVIL)
+ {
+ return 2;
+ }
+ }
+ }
+ return 0;
+}
+
+int RunecasterRunePowerSP(object oCaster)
+{
+ int nSP = 0;
+
+ // casting from a rune
+ if(GetResRef(GetSpellCastItem()) == "prc_rune_1")
+ {
+ nSP = StringToInt(GetTag(GetSpellCastItem()));
+ }
+ // caster is runechanting
+ else if(GetHasSpellEffect(SPELL_RUNE_CHANT))
+ {
+ int nClass = GetLevelByClass(CLASS_TYPE_RUNECASTER, oCaster);
+
+ if (nClass >= 30) nSP = 10;
+ else if (nClass >= 27) nSP = 9;
+ else if (nClass >= 24) nSP = 8;
+ else if (nClass >= 21) nSP = 7;
+ else if (nClass >= 18) nSP = 6;
+ else if (nClass >= 15) nSP = 5;
+ else if (nClass >= 12) nSP = 4;
+ else if (nClass >= 9) nSP = 3;
+ else if (nClass >= 5) nSP = 2;
+ else if (nClass >= 2) nSP = 1;
+ }
+
+ return nSP;
+}
+
+int MarshalDeterminedCaster(object oCaster)
+{
+ return GetLocalInt(oCaster,"Marshal_DetCast");
+}
+
+int DuskbladeSpellPower(object oCaster, object oTarget)
+{
+ int nSP = 0;
+ if(GetLocalInt(oTarget, "DuskbladeSpellPower"))
+ {
+ int nClass = GetLevelByClass(CLASS_TYPE_DUSKBLADE, oCaster);
+
+ if(nClass >= 38) nSP = 10;
+ else if(nClass >= 36) nSP = 9;
+ else if(nClass >= 31) nSP = 8;
+ else if(nClass >= 26) nSP = 7;
+ else if(nClass >= 21) nSP = 6;
+ else if(nClass >= 18) nSP = 5;
+ else if(nClass >= 16) nSP = 4;
+ else if(nClass >= 11) nSP = 3;
+ else if(nClass >= 6) nSP = 2;
+ }
+
+ return nSP;
+}
+
+int DraconicMagicPower(object oCaster)
+{
+ return GetLocalInt(oCaster,"MagicPowerAura");
+}
+
+int TrueCastingSpell(object oCaster)
+{
+ if(GetHasSpellEffect(SPELL_TRUE_CASTING, oCaster))
+ return 10;
+
+ return 0;
+}
+
+// Beguilers of level 8+ gain +2 bonus to SR agianst enemis that are denided DEX bonus to AC
+int CloakedCastingSR(object oCaster, object oTarget)
+{
+ if(GetLevelByClass(CLASS_TYPE_BEGUILER, oCaster) >= 8)
+ {
+ if(GetIsDeniedDexBonusToAC(oTarget, oCaster, TRUE))
+ return 2;
+ }
+
+ return 0;
+}
+
+int PenetratingBlast(object oCaster, object oTarget)
+{
+ if(oTarget == GetLocalObject(oCaster, "SPELLWEAVE_TARGET"))
+ {
+ if(GetLocalInt(oCaster, "BlastEssence") == INVOKE_PENETRATING_BLAST)
+ return 4;
+ }
+ return 0;
+}
+
+int add_spl_pen(object oCaster = OBJECT_SELF)
+{
+ object oTarget = PRCGetSpellTargetObject();
+ int spell_id = PRCGetSpellId();
+ int nSchool = GetSpellSchool(spell_id);
+
+ int nSP = ElementalSavantSP(spell_id, oCaster);
+ nSP += GetHeartWarderPene(spell_id, oCaster);
+ nSP += RedWizardSP(spell_id, nSchool, oCaster);
+ nSP += GetSpellPowerBonus(oCaster);
+ nSP += GetSpellPenetreFocusSchool(nSchool, oCaster);
+ nSP += ShadowWeavePen(spell_id, nSchool, oCaster);
+ nSP += RunecasterRunePowerSP(oCaster);
+ nSP += MarshalDeterminedCaster(oCaster);
+ nSP += DraconicMagicPower(oCaster);
+ nSP += TrueCastingSpell(oCaster);
+ nSP += GetEssentiaInvestedFeat(oCaster, FEAT_SOULTOUCHED_SPELLCASTING);
+ if(GetIsObjectValid(oTarget))
+ {
+ nSP += CloakedCastingSR(oCaster, oTarget);
+ nSP += PenetratingBlast(oCaster, oTarget);
+ nSP += KOTCSpellPenVsDemons(oCaster, oTarget);
+ nSP += DuskbladeSpellPower(oCaster, oTarget);
+ }
+
+ return nSP;
+}
+
+//
+// This function converts elemental types as needed
+//
+string ChangedElementalType(int spell_id, object oCaster = OBJECT_SELF)
+{
+ // Lookup the spell type
+ string spellType = Get2DACache("spells", "ImmunityType", spell_id);//lookup_spell_type(spell_id);
+
+ // Check if an override is set
+ string sType = GetLocalString(oCaster, "archmage_mastery_elements_name");
+
+ // If so, check if the spell qualifies for a change
+ if (sType == "" || !IsSpellTypeElemental(spellType))
+ sType = spellType;
+
+ return sType;
+}
+
+//////////////////////////////////////////////////
+/* Function definitions */
+//////////////////////////////////////////////////
+
+//
+// Get the Spell Penetration Bonuses
+//
+int SPGetPenetr(object oCaster = OBJECT_SELF)
+{
+ int nPenetr = 0;
+
+ // This is a deliberate optimization attempt.
+ // The first feat determines if the others even need
+ // to be referenced.
+ if(GetHasFeat(FEAT_SPELL_PENETRATION, oCaster))
+ {
+ nPenetr += 2;
+ if(GetHasFeat(FEAT_EPIC_SPELL_PENETRATION, oCaster))
+ nPenetr += 4;
+ else if (GetHasFeat(FEAT_GREATER_SPELL_PENETRATION, oCaster))
+ nPenetr += 2;
+ }
+
+ // Check for additional improvements
+ nPenetr += add_spl_pen(oCaster);
+
+ return nPenetr;
+}
+
+//
+// Interface for specific AOE requirements
+// TODO: Determine who or what removes the cached local var (bug?)
+// TODO: Try and remove this function completely? It does 2 things the
+// above function doesnt: Effective Caster Level and Cache
+//
+int SPGetPenetrAOE(object oCaster = OBJECT_SELF, int nCasterLvl = 0)
+{
+ // Check the cache
+ int nPenetr = GetLocalInt(OBJECT_SELF, "nPenetre");
+
+ // Compute the result
+ if (!nPenetr) {
+ nPenetr = (nCasterLvl) ? nCasterLvl : PRCGetCasterLevel(oCaster);
+
+ // Factor in Penetration Bonuses
+ nPenetr += SPGetPenetr(oCaster);
+
+ // Who removed this?
+ SetLocalInt(OBJECT_SELF,"nPenetre",nPenetr);
+ }
+
+ return nPenetr;
+}
+
+// Test main
+//void main(){}
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prc_inc_core.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prc_inc_core.nss
new file mode 100644
index 00000000..2efcffe7
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prc_inc_core.nss
@@ -0,0 +1,766 @@
+/* Core functions taken from high up the branch
+ which are needed lower. */
+
+//:: Updated for .35 by Jaysyn 2023/03/10
+//////////////////////////////////////////////////
+/* Forward Declarations */
+//////////////////////////////////////////////////
+
+int GetSpellLevel(int nSpell, int nClass);
+string GetFileForClass(int nClass);
+int GetSpellbookTypeForClass(int nClass);
+
+//////////////////////////////////////////////////
+/* Function Prototypes */
+//////////////////////////////////////////////////
+
+//:: Returns true if oCaster's race can naturally cast sorcerer spells.
+int GetIsRHDSorcerer(object oCaster = OBJECT_SELF);
+
+//:: Returns true if oCaster's race can naturally cast bard spells.
+int GetIsRHDBard(object oCaster = OBJECT_SELF);
+
+// wrapper for getspelltargetlocation
+location PRCGetSpellTargetLocation(object oCaster = OBJECT_SELF);
+
+// Avoids adding passive spellcasting to the character's action queue by
+// creating an object specifically to cast the spell on the character.
+//
+// NOTE: The spell script must refer to the PC as PRCGetSpellTargetObject()
+// otherwise this function WILL NOT WORK. Do not make any assumptions
+// about the PC being OBJECT_SELF.
+void ActionCastSpellOnSelf(int iSpell, int nMetaMagic = METAMAGIC_NONE, object oTarget = OBJECT_SELF);
+
+// This is a wrapper function that causes OBJECT_SELF to fire the defined spell
+// at the defined level. The target is automatically the object or location
+// that the user selects. Useful for SLA's to perform the casting of a true
+// spell. This is useful because:
+//
+// 1) If the original's spell script is updated, so is this one.
+// 2) The spells are identified as the true spell. That is, they ARE the true spell.
+// 3) Spellhooks (such as item crafting) that can only identify true spells
+// will easily work.
+//
+// This function should only be used when SLA's are meant to simulate true
+// spellcasting abilities, such as those seen when using feats with subradials
+// to simulate spellbooks.
+void ActionCastSpell(int iSpell, int iCasterLev = 0, int iBaseDC = 0, int iTotalDC = 0,
+ int nMetaMagic = METAMAGIC_NONE, int nClass = CLASS_TYPE_INVALID,
+ int bUseOverrideTargetLocation=FALSE, int bUseOverrideTargetObject=FALSE,
+ object oOverrideTarget=OBJECT_INVALID, int bInstantCast=TRUE, int bUseOverrideMetaMagic=FALSE);
+
+/**
+ * Checks whether the given creature is committing an action, or
+ * under such effects that cause a breach of concentration.
+ *
+ * @param oConcentrator The creature to test
+ * @return TRUE if concentration is broken, FALSE otherwise
+ */
+int GetBreakConcentrationCheck(object oConcentrator);
+
+/**
+ * Checks for breaks in concentration for an ongoing effect, and removes
+ * the effect if concentration is broken.
+ *
+ * @param oCaster The creature who cast the effect
+ * @param SpellID The id of the spell the effect belongs to
+ * @param oTarget The creature or object that is the target of the effect
+ * @param nDuration The duration the effect lasts in seconds.
+ */
+void CheckConcentrationOnEffect(object oCaster, int SpellID, object oTarget, int nDuration);
+
+// gets the spell level adjustment to the nMetaMagic, including boni from the Improved Metamagic (epic) feat
+int GetMetaMagicSpellLevelAdjustment(int nMetaMagic);
+
+// Returns true if a spellcaster
+int GetIsBioSpellCastClass(int nClass);
+
+// Returns true for spell casters with spellbooks
+int GetIsNSBClass(int nClass);
+
+// returns the spelllevel of nSpell as it can be cast by oCreature
+int PRCGetSpellLevel(object oCreature, int nSpell);
+
+// returns if a character should be using the newspellbook when casting
+int UseNewSpellBook(object oCreature);
+
+// wrapper for GetHasSpell, works for newspellbook 'fake' spells too
+// should return 0 if called with a normal spell when a character should be using the newspellbook
+int PRCGetHasSpell(int nRealSpellID, object oCreature = OBJECT_SELF);
+
+// checks if oPC knows the specified spell
+// only works for classes that use the PRC spellbook, there is currently no way to do this for Bioware spellcasters
+int PRCGetIsRealSpellKnown(int nRealSpellID, object oPC = OBJECT_SELF);
+
+// checks if oPC knows the specified spell
+// only works for classes that use the PRC spellbook, there is currently no way to do this for Bioware spellcasters
+// this will only check the spellbook of the class specified
+int PRCGetIsRealSpellKnownByClass(int nRealSpellID, int nClass, object oPC = OBJECT_SELF);
+
+//routes to action cast spell, but puts a wrapper around to tell other functions its a
+//SLA, so dont craft etc
+//also defaults the totalDC to 10+spellevel+chamod
+// moved from prc_inc_racial
+void DoRacialSLA(int nSpellID, int nCasterlevel = 0, int nTotalDC = 0, int bInstantCast = FALSE);
+
+/**
+ * Deletes a stored manifestation structure.
+ *
+ * @param oObject The object on which the structure is stored
+ * @param sName The name under which the structure is stored
+ */
+void DeleteLocalManifestation(object oObject, string sName);
+
+/**
+ * Deletes a stored mystery structure.
+ *
+ * @param oObject The object on which the structure is stored
+ * @param sName The name under which the structure is stored
+ */
+void DeleteLocalMystery(object oObject, string sName);
+
+//////////////////////////////////////////////////
+/* Constants */
+//////////////////////////////////////////////////
+
+// metamagic spell level adjustments for Bioware provided metamagic feats
+const int METAMAGIC_EXTEND_LEVEL = 1;
+const int METAMAGIC_SILENT_LEVEL = 1;
+const int METAMAGIC_STILL_LEVEL = 1;
+const int METAMAGIC_EMPOWER_LEVEL = 2;
+const int METAMAGIC_MAXIMIZE_LEVEL = 3;
+const int METAMAGIC_QUICKEN_LEVEL = 4;
+
+//////////////////////////////////////////////////
+/* Includes */
+//////////////////////////////////////////////////
+
+#include "lookup_2da_spell"
+#include "inc_lookups"
+#include "prc_inc_damage"
+#include "prc_inc_sb_const" // Spell Book Constants
+#include "x0_i0_position"
+
+/*
+ access to prc_inc_nwscript via prc_inc_damage
+ access to PRCGetSpell* via prc_inc_damage
+*/
+
+
+//////////////////////////////////////////////////
+/* Function Definitions */
+//////////////////////////////////////////////////
+
+//:: Returns true if oCaster's race can naturally cast sorcerer spells.
+int GetIsRHDSorcerer(object oCaster = OBJECT_SELF)
+{
+ int nRace = GetRacialType(oCaster);
+
+ return (nRace == RACIAL_TYPE_ARANEA ||
+ nRace == RACIAL_TYPE_ARKAMOI ||
+ nRace == RACIAL_TYPE_DRIDER ||
+ nRace == RACIAL_TYPE_HOBGOBLIN_WARSOUL ||
+ nRace == RACIAL_TYPE_MARRUTACT ||
+ nRace == RACIAL_TYPE_RAKSHASA ||
+ nRace == RACIAL_TYPE_REDSPAWN_ARCANISS);
+}
+
+//:: Returns true if oCaster's race can naturally cast bard spells.
+int GetIsRHDBard(object oCaster = OBJECT_SELF)
+{
+ int nRace = GetRacialType(oCaster);
+
+ return (nRace == RACIAL_TYPE_GLOURA);
+}
+
+//wrapper for GetSpellTargetLocation()
+location PRCGetSpellTargetLocation(object oCaster = OBJECT_SELF)
+{
+ // check if there is an override location on the module, and return that
+ // bioware did not define a LOCATION_INVALID const, so we must signal a valid override location by setting a local int on the module
+ if(GetLocalInt(GetModule(), PRC_SPELL_TARGET_LOCATION_OVERRIDE))
+ {
+ if (DEBUG) DoDebug("PRCGetSpellTargetLocation: found override target location on module");
+ return GetLocalLocation(GetModule(), PRC_SPELL_TARGET_LOCATION_OVERRIDE);
+ }
+
+
+ // check if there is an override location on the caster, and return that
+ // bioware did not define a LOCATION_INVALID const, so we signal a valid override location by setting a local int on oCaster
+ if (GetLocalInt(oCaster, PRC_SPELL_TARGET_LOCATION_OVERRIDE))
+ {
+ if (DEBUG) DoDebug("PRCGetSpellTargetLocation: found override target location on caster "+GetName(oCaster));
+ return GetLocalLocation(oCaster, PRC_SPELL_TARGET_LOCATION_OVERRIDE);
+ }
+
+
+ // The rune/gem/skull always targets the one who activates it.
+ object oItem = PRCGetSpellCastItem(oCaster);
+ if(GetIsObjectValid(oItem) && (GetResRef(oItem) == "prc_rune_1" ||
+ GetResRef(oItem) == "prc_skulltalis" || GetTag(oItem) == "prc_attunegem"))
+ return GetLocation(GetItemPossessor(oItem));
+
+ if (GetLocalInt(oCaster, "BlackLabyrinth") && d10() < 3)
+ return GenerateNewLocationFromLocation(GetSpellTargetLocation(), FeetToMeters(5.0*d4()), IntToFloat(Random(360)), IntToFloat(Random(360)));
+
+ // if we made it here, we must use Bioware's function
+ return GetSpellTargetLocation();
+}
+
+void ActionCastSpellOnSelf(int iSpell, int nMetaMagic = METAMAGIC_NONE, object oTarget = OBJECT_SELF)
+{
+ if(!GetIsObjectValid(oTarget)) oTarget = OBJECT_SELF;
+ object oCastingObject = CreateObject(OBJECT_TYPE_PLACEABLE, "x0_rodwonder", GetLocation(oTarget));
+
+ AssignCommand(oCastingObject, ActionCastSpellAtObject(iSpell, oTarget, nMetaMagic, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
+ if (DEBUG) DoDebug("ActionCastSpellOnSelf: Casting Spell "+IntToString(iSpell)+" on "+GetName(oTarget));
+
+ DestroyObject(oCastingObject, 6.0);
+}
+
+void ActionCastSpell(int iSpell, int iCasterLev = 0, int iBaseDC = 0, int iTotalDC = 0,
+ int nMetaMagic = METAMAGIC_NONE, int nClass = CLASS_TYPE_INVALID,
+ int bUseOverrideTargetLocation=FALSE, int bUseOverrideTargetObject=FALSE,
+ object oOverrideTarget=OBJECT_INVALID, int bInstantCast=TRUE, int bUseOverrideMetaMagic=FALSE)
+{
+
+ //if its a hostile spell, clear the action queue
+ //this stops people stacking hostile spells to be instacast
+ //at the end, for example when coming out of invisibility
+ // X - hope this is not needed if spells are cast normally
+ //if(Get2DACache("spells", "HostileSetting", iSpell) == "1" && bInstantCast)
+ // ClearAllActions();
+
+ object oTarget = PRCGetSpellTargetObject();
+ location lLoc = PRCGetSpellTargetLocation();
+
+ //set the overriding values
+ if (iCasterLev != 0)
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_CASTERLEVEL_OVERRIDE, iCasterLev));
+ if (iTotalDC != 0)
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_DC_TOTAL_OVERRIDE, iTotalDC));
+ if (iBaseDC != 0)
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_DC_BASE_OVERRIDE, iBaseDC));
+ if (nClass != CLASS_TYPE_INVALID)
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_CASTERCLASS_OVERRIDE, nClass));
+ if (bUseOverrideMetaMagic)
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_METAMAGIC_OVERRIDE, nMetaMagic));
+ else if (nMetaMagic != METAMAGIC_NONE)
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_METAMAGIC_ADJUSTMENT, nMetaMagic));
+ if (bUseOverrideTargetLocation)
+ {
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_SPELL_TARGET_LOCATION_OVERRIDE, TRUE));
+ //location must be set outside of this function at the moment
+ //cant pass a location into a function as an optional parameter
+ //go bioware for not defining an invalid location constant
+ }
+ if (bUseOverrideTargetObject)
+ {
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, PRC_SPELL_TARGET_OBJECT_OVERRIDE, TRUE));
+ ActionDoCommand(SetLocalObject(OBJECT_SELF, PRC_SPELL_TARGET_OBJECT_OVERRIDE, oOverrideTarget));
+ }
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, "UsingActionCastSpell", TRUE));
+
+ if(DEBUG) DoDebug("ActionCastSpell SpellId: " + IntToString(iSpell));
+ if(DEBUG) DoDebug("ActionCastSpell Caster Level: " + IntToString(iCasterLev));
+ if(DEBUG) DoDebug("ActionCastSpell Base DC: " + IntToString(iBaseDC));
+ if(DEBUG) DoDebug("ActionCastSpell Total DC: " + IntToString(iTotalDC));
+ if(DEBUG) DoDebug("ActionCastSpell Metamagic: " + IntToString(nMetaMagic));
+ if(DEBUG) DoDebug("ActionCastSpell Caster Class: " + IntToString(nClass));
+ if(DEBUG) DoDebug("ActionCastSpell Target: " + GetName(oTarget));
+ if(DEBUG) DoDebug("ActionCastSpell Override Target: " + GetName(oOverrideTarget));
+
+ //cast the spell
+ if (GetIsObjectValid(oOverrideTarget))
+ ActionCastSpellAtObject(iSpell, oOverrideTarget, nMetaMagic, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantCast);
+ else if (GetIsObjectValid(oTarget))
+ ActionCastSpellAtObject(iSpell, oTarget, nMetaMagic, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, bInstantCast);
+ else
+ ActionCastSpellAtLocation(iSpell, lLoc, nMetaMagic, TRUE, PROJECTILE_PATH_TYPE_DEFAULT, bInstantCast);
+
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, "UsingActionCastSpell"));
+
+ //clean up afterwards
+ if(bInstantCast)//give scripts time to read the variables
+ {
+ if (iCasterLev != 0)
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_CASTERLEVEL_OVERRIDE)));
+ if (iTotalDC != 0)
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_DC_TOTAL_OVERRIDE)));
+ if (iBaseDC != 0)
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_DC_BASE_OVERRIDE)));
+ if (nClass != CLASS_TYPE_INVALID)
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_CASTERCLASS_OVERRIDE)));
+ if (nMetaMagic != METAMAGIC_NONE)
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_METAMAGIC_OVERRIDE)));
+ if (bUseOverrideTargetLocation)
+ {
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_SPELL_TARGET_LOCATION_OVERRIDE)));
+ //location must be set outside of this function at the moment
+ //cant pass a location into a function as an optional parameter
+ //go bioware for not defining an invalid location constant
+ }
+ if (bUseOverrideTargetObject)
+ {
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_SPELL_TARGET_OBJECT_OVERRIDE)));
+ ActionDoCommand(DelayCommand(1.0, DeleteLocalObject(OBJECT_SELF, PRC_SPELL_TARGET_OBJECT_OVERRIDE)));
+ }
+ }
+ else
+ {
+ if (iCasterLev != 0)
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_CASTERLEVEL_OVERRIDE));
+ if (iTotalDC != 0)
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_DC_TOTAL_OVERRIDE));
+ if (iBaseDC != 0)
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_DC_BASE_OVERRIDE));
+ if (nClass != CLASS_TYPE_INVALID)
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_CASTERCLASS_OVERRIDE));
+ if (bUseOverrideMetaMagic)
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_METAMAGIC_OVERRIDE));
+ else if (nMetaMagic != METAMAGIC_NONE)
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_METAMAGIC_ADJUSTMENT));
+ if (bUseOverrideTargetLocation)
+ {
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_SPELL_TARGET_LOCATION_OVERRIDE));
+ //location must be set outside of this function at the moment
+ //cant pass a location into a function as an optional parameter
+ //go bioware for not defining an invalid location constant
+ }
+ if (bUseOverrideTargetObject)
+ {
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, PRC_SPELL_TARGET_OBJECT_OVERRIDE));
+ ActionDoCommand(DeleteLocalObject(OBJECT_SELF, PRC_SPELL_TARGET_OBJECT_OVERRIDE));
+ }
+ }
+
+
+/*
+//The problem with this approace is that the effects are then applies by the original spell, which could go wrong. What to do?
+ SetLocalInt(OBJECT_SELF, PRC_SPELLID_OVERRIDE, GetSpellId());
+ DelayCommand(1.0, DeleteLocalInt(OBJECT_SELF, PRC_SPELLID_OVERRIDE));
+ string sScript = Get2DACache("spells", "ImpactScript", iSpell);
+ ExecuteScript(sScript, OBJECT_SELF);
+*/
+}
+
+int GetBreakConcentrationCheck(object oConcentrator)
+{
+ if (GetHasSpellEffect(VESTIGE_DAHLVERNAR, oConcentrator) && !GetLocalInt(oConcentrator, "PactQuality"+IntToString(VESTIGE_DAHLVERNAR))) return TRUE;
+
+ int nAction = GetCurrentAction(oConcentrator);
+ // creature doing anything that requires attention and breaks concentration
+ if (nAction == ACTION_DISABLETRAP || nAction == ACTION_TAUNT ||
+ nAction == ACTION_PICKPOCKET || nAction == ACTION_ATTACKOBJECT ||
+ nAction == ACTION_COUNTERSPELL || nAction == ACTION_FLAGTRAP ||
+ nAction == ACTION_CASTSPELL || nAction == ACTION_ITEMCASTSPELL)
+ {
+ return TRUE;
+ }
+ //suffering a mental effect
+ effect e1 = GetFirstEffect(oConcentrator);
+ int nType;
+ while (GetIsEffectValid(e1))
+ {
+ nType = GetEffectType(e1);
+ if (nType == EFFECT_TYPE_STUNNED || nType == EFFECT_TYPE_PARALYZE ||
+ nType == EFFECT_TYPE_SLEEP || nType == EFFECT_TYPE_FRIGHTENED ||
+ nType == EFFECT_TYPE_PETRIFY || nType == EFFECT_TYPE_CONFUSED ||
+ nType == EFFECT_TYPE_DOMINATED || nType == EFFECT_TYPE_POLYMORPH)
+ {
+ return TRUE;
+ }
+ e1 = GetNextEffect(oConcentrator);
+ }
+ // add to on damage event
+ AddEventScript(oConcentrator, EVENT_VIRTUAL_ONDAMAGED, "prc_od_conc", FALSE, FALSE);
+ if(GetLocalInt(oConcentrator, "CONC_BROKEN")) // won't be set first time around regardless
+ {
+ DeleteLocalInt(oConcentrator, "CONC_BROKEN"); // reset for next spell
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CheckConcentrationOnEffect(object oCaster, int SpellID, object oTarget, int nDuration)
+{
+ int nDur = GetLocalInt(oCaster, "Conc" + IntToString(SpellID));
+ if(GetBreakConcentrationCheck(oCaster) == TRUE && nDur < nDuration)
+ {
+ FloatingTextStringOnCreature("*Concentration Broken*", oCaster);
+ DeleteLocalInt(oCaster, "Conc" + IntToString(SpellID));
+ PRCRemoveSpellEffects(SpellID, oCaster, oTarget);
+ }
+ else if(nDur < nDuration)
+ {
+ SetLocalInt(oCaster, "Conc" + IntToString(SpellID), nDur + 3);
+ DelayCommand(3.0, CheckConcentrationOnEffect(oCaster, SpellID, oTarget, nDuration));
+ }
+ else
+ {
+ DeleteLocalInt(oCaster, "Conc" + IntToString(SpellID));
+ }
+}
+
+int PRCGetSpellLevelForClass(int nSpell, int nClass)
+{
+ string sSpellLevel = "";
+ if (nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER)
+ sSpellLevel = Get2DACache("spells", "Wiz_Sorc", nSpell);
+ else if (nClass == CLASS_TYPE_RANGER)
+ sSpellLevel = Get2DACache("spells", "Ranger", nSpell);
+ else if (nClass == CLASS_TYPE_PALADIN)
+ sSpellLevel = Get2DACache("spells", "Paladin", nSpell);
+ else if (nClass == CLASS_TYPE_DRUID)
+ sSpellLevel = Get2DACache("spells", "Druid", nSpell);
+ else if (nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_UR_PRIEST || nClass == CLASS_TYPE_OCULAR)
+ sSpellLevel = Get2DACache("spells", "Cleric", nSpell);
+ else if (nClass == CLASS_TYPE_BARD)
+ sSpellLevel = Get2DACache("spells", "Bard", nSpell);
+ else if (nClass == CLASS_TYPE_ASSASSIN)
+ sSpellLevel = Get2DACache("spells", "Assassin", nSpell);
+ else if (nClass == CLASS_TYPE_CULTIST_SHATTERED_PEAK)
+ sSpellLevel = Get2DACache("spells", "Cultist", nSpell);
+ else if (nClass == CLASS_TYPE_NENTYAR_HUNTER)
+ sSpellLevel = Get2DACache("spells", "Nentyar", nSpell);
+ else if (nClass == CLASS_TYPE_SHADOWLORD)
+ sSpellLevel = Get2DACache("spells", "Telflammar", nSpell);
+ else if (nClass == CLASS_TYPE_SLAYER_OF_DOMIEL)
+ sSpellLevel = Get2DACache("spells", "Domiel", nSpell);
+ else if (nClass == CLASS_TYPE_SOHEI)
+ sSpellLevel = Get2DACache("spells", "Sohei", nSpell);
+ else if (nClass == CLASS_TYPE_VASSAL)
+ sSpellLevel = Get2DACache("spells", "Bahamut", nSpell);
+ else if (nClass == CLASS_TYPE_BLACKGUARD)
+ sSpellLevel = Get2DACache("spells", "Blackguard", nSpell);
+ else if (nClass == CLASS_TYPE_KNIGHT_CHALICE)
+ sSpellLevel = Get2DACache("spells", "Chalice", nSpell);
+ else if (nClass == CLASS_TYPE_KNIGHT_MIDDLECIRCLE)
+ sSpellLevel = Get2DACache("spells", "MiddleCircle", nSpell);
+ else if (nClass == CLASS_TYPE_SOLDIER_OF_LIGHT)
+ sSpellLevel = Get2DACache("spells", "SoLight", nSpell);
+ else if (nClass == CLASS_TYPE_BLIGHTER)
+ sSpellLevel = Get2DACache("spells", "Blighter", nSpell);
+ else if (nClass == CLASS_TYPE_HEALER)
+ sSpellLevel = Get2DACache("spells", "Healer", nSpell);
+ else if (nClass == CLASS_TYPE_SHAMAN)
+ sSpellLevel = Get2DACache("spells", "Shaman", nSpell);
+ else if (nClass == CLASS_TYPE_INVALID)
+ sSpellLevel = Get2DACache("spells", "Innate", nSpell);
+
+ if (sSpellLevel != "")
+ return StringToInt(sSpellLevel);
+
+ // 2009-9-21: Support real spell ID's. -N-S
+ // PRCGetSpellLevel() is called several times in the Bioware spellhooking script.
+ // That means it will always pass a "real" spell ID to this function, but new-spellbook users won't have the real spell!
+ // GetSpellLevel() takes the fake spell ID, so this function was always failing.
+ //int nSpellLevel = GetSpellLevel(nSpell, nClass);
+ int nSpellLevel = -1;
+ int nSpellbookID = RealSpellToSpellbookID(nClass, nSpell);
+ if (nSpellbookID == -1)
+ nSpellLevel = GetSpellLevel(nSpell, nClass);
+ else
+ {
+ string sFile = GetFileForClass(nClass);
+ string sSpellLevel = Get2DACache(sFile, "Level", nSpellbookID);
+ if (sSpellLevel != "")
+ nSpellLevel = StringToInt(sSpellLevel);
+ }
+
+ return nSpellLevel;
+}
+
+// returns the spell circle level of nSpell as it can be cast by oCreature
+int PRCGetSpellLevel(object oCreature, int nSpell)
+{
+ /*if (!PRCGetHasSpell(nSpell, oCreature))
+ return -1;*/
+
+ int nClass = PRCGetLastSpellCastClass();
+ int nSpellLevel = PRCGetSpellLevelForClass(nSpell, nClass);
+ if (nSpellLevel != -1)
+ return nSpellLevel;
+
+ int i;
+ for (i=1;i<=8;i++)
+ {
+ nClass = GetClassByPosition(i, oCreature);
+ int nCharLevel = GetLevelByClass(nClass, oCreature);
+ if (nCharLevel)
+ {
+ nSpellLevel = PRCGetSpellLevelForClass(nSpell, nClass);
+ if (nSpellLevel != -1)
+ return nSpellLevel;
+ }
+ }
+
+ //return innate level
+ return StringToInt(Get2DACache("spells", "Innate", nSpell));
+}
+
+// gets the spell level adjustment to the nMetaMagic, including boni from the Improved Metamagic (epic) feat
+int GetMetaMagicSpellLevelAdjustment(int nMetaMagic)
+{
+ int nAdj;
+ if (nMetaMagic == 0) return nAdj;
+
+ if (nMetaMagic & METAMAGIC_EXTEND) nAdj += METAMAGIC_EXTEND_LEVEL;
+ if (nMetaMagic & METAMAGIC_SILENT) nAdj += METAMAGIC_SILENT_LEVEL;
+ if (nMetaMagic & METAMAGIC_STILL) nAdj += METAMAGIC_STILL_LEVEL;
+ if (nMetaMagic & METAMAGIC_EMPOWER) nAdj += METAMAGIC_EMPOWER_LEVEL;
+ if (nMetaMagic & METAMAGIC_MAXIMIZE) nAdj += METAMAGIC_MAXIMIZE_LEVEL;
+ if (nMetaMagic & METAMAGIC_QUICKEN) nAdj += METAMAGIC_QUICKEN_LEVEL;
+
+ return nAdj;
+}
+
+int GetIsBioSpellCastClass(int nClass)
+{
+ return nClass == CLASS_TYPE_WIZARD
+ || nClass == CLASS_TYPE_SORCERER && !GetIsRHDSorcerer()
+ || nClass == CLASS_TYPE_BARD && !GetIsRHDBard()
+ || nClass == CLASS_TYPE_CLERIC
+ || nClass == CLASS_TYPE_HEALER
+ || nClass == CLASS_TYPE_BLIGHTER
+ || nClass == CLASS_TYPE_BLACKGUARD
+ || nClass == CLASS_TYPE_UR_PRIEST
+ || nClass == CLASS_TYPE_OCULAR
+ || nClass == CLASS_TYPE_SLAYER_OF_DOMIEL
+ || nClass == CLASS_TYPE_CULTIST_SHATTERED_PEAK
+ || nClass == CLASS_TYPE_NENTYAR_HUNTER
+ || nClass == CLASS_TYPE_SHADOWLORD
+ || nClass == CLASS_TYPE_SOHEI
+ || nClass == CLASS_TYPE_SOLDIER_OF_LIGHT
+ || nClass == CLASS_TYPE_VASSAL
+ || nClass == CLASS_TYPE_KNIGHT_MIDDLECIRCLE
+ || nClass == CLASS_TYPE_KNIGHT_CHALICE
+ || nClass == CLASS_TYPE_SHAMAN
+ || nClass == CLASS_TYPE_DRUID
+ || nClass == CLASS_TYPE_PALADIN
+ || nClass == CLASS_TYPE_RANGER;
+}
+
+int GetIsNSBClass(int nClass)
+{
+ return !GetIsBioSpellCastClass(nClass)
+ && GetSpellbookTypeForClass(nClass) != SPELLBOOK_TYPE_INVALID;
+}
+
+// returns if a character should be using the newspellbook when casting
+int UseNewSpellBook(object oCreature)
+{
+ int i;
+ for (i = 1; i <= 8; i++)
+ {
+ int nClass = GetClassByPosition(i, oCreature);
+ if(GetIsNSBClass(nClass))
+ return TRUE;
+ }
+
+ // Special case
+ if(GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oCreature))
+ return TRUE;
+
+ int nPrimaryArcane = GetPrimaryArcaneClass(oCreature);
+
+ //check they have bard/sorc in first arcane slot
+ if(nPrimaryArcane != CLASS_TYPE_BARD && nPrimaryArcane != CLASS_TYPE_SORCERER)
+ return FALSE;
+ //check they have arcane PrC or Draconic Breath/Arcane Grace
+ if(!GetArcanePRCLevels(oCreature, nPrimaryArcane)
+ && !(GetHasFeat(FEAT_DRACONIC_GRACE, oCreature) || GetHasFeat(FEAT_DRACONIC_BREATH, oCreature)))
+ return FALSE;
+ //check if the newspellbooks are disabled
+ if((GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK) && nPrimaryArcane == CLASS_TYPE_SORCERER) ||
+ (GetPRCSwitch(PRC_BARD_DISALLOW_NEWSPELLBOOK) && nPrimaryArcane == CLASS_TYPE_BARD))
+ return FALSE;
+ //check they have bard/sorc levels
+ if(!GetLevelByClass(CLASS_TYPE_BARD) && !GetLevelByClass(CLASS_TYPE_SORCERER))
+ return FALSE;
+
+ //at this point, they should be using the new spellbook
+ return TRUE;
+}
+
+// wrapper for GetHasSpell, works for newspellbook 'fake' spells too (and metamagic)
+// should return 0 if called with a normal spell when a character should be using the newspellbook
+int PRCGetHasSpell(int nRealSpellID, object oCreature = OBJECT_SELF)
+{
+ if(!PRCGetIsRealSpellKnown(nRealSpellID, oCreature))
+ return 0;
+ int nUses = GetHasSpell(nRealSpellID, oCreature);
+
+ int nClass, nSpellbookID, nCount, nMeta, i, j;
+ int nSpellbookType, nSpellLevel;
+ string sFile, sFeat;
+ for(i = 1; i <= 8; i++)
+ {
+ nClass = GetClassByPosition(i, oCreature);
+ sFile = GetFileForClass(nClass);
+ nSpellbookType = GetSpellbookTypeForClass(nClass);
+ nSpellbookID = RealSpellToSpellbookID(nClass, nRealSpellID);
+ nMeta = RealSpellToSpellbookIDCount(nClass, nRealSpellID);
+ if (nSpellbookID != -1)
+ { //non-spellbook classes should return -1
+ for(j = nSpellbookID; j <= nSpellbookID + nMeta; j++)
+ {
+ sFeat = Get2DACache(sFile, "ReqFeat", j);
+ if(sFeat != "")
+ {
+ if(!GetHasFeat(StringToInt(sFeat), oCreature))
+ continue;
+ }
+ if(nSpellbookType == SPELLBOOK_TYPE_PREPARED)
+ {
+ nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), j);
+ if(DEBUG) DoDebug("prc_inc_core >> PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
+ if(nCount > 0)
+ {
+ nUses += nCount;
+ }
+ }
+ else if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS)
+ {
+ nSpellLevel = StringToInt(Get2DACache(sFile, "Level", j));
+ nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel);
+ if(DEBUG) DoDebug("prc_inc_core >> PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
+ if(nCount > 0)
+ {
+ nUses += nCount;
+ }
+ }
+ }
+ }
+ }
+
+ if(DEBUG) DoDebug("PRCGetHasSpell: RealSpellID = " + IntToString(nRealSpellID) + ", Uses = " + IntToString(nUses));
+ return nUses;
+}
+
+// checks if oPC knows the specified spell
+// only works for classes that use the PRC spellbook, there is currently no way to do this for Bioware spellcasters
+int PRCGetIsRealSpellKnown(int nRealSpellID, object oPC = OBJECT_SELF)
+{
+ if(GetHasSpell(nRealSpellID, oPC)) //FUGLY HACK: bioware class having uses of the spell
+ return TRUE; // means they know the spell (close enough)
+ int nClass;
+ int nClassSlot = 1;
+ while(nClassSlot <= 8)
+ {
+ nClass = GetClassByPosition(nClassSlot, oPC);
+ if(GetIsDivineClass(nClass) || GetIsArcaneClass(nClass))
+ if(PRCGetIsRealSpellKnownByClass(nRealSpellID, nClass, oPC))
+ return TRUE;
+ nClassSlot++;
+ }
+ // got here means no match
+ return FALSE;
+}
+
+// checks if oPC knows the specified spell
+// only works for classes that use the PRC spellbook, there is currently no way to do this for Bioware spellcasters
+// this will only check the spellbook of the class specified
+int PRCGetIsRealSpellKnownByClass(int nRealSpellID, int nClass, object oPC = OBJECT_SELF)
+{
+ // check for whether bard and sorc are using the prc spellbooks
+ if (nClass == CLASS_TYPE_BARD || nClass == CLASS_TYPE_SORCERER)
+ {
+ if(!UseNewSpellBook(oPC))
+ return FALSE;
+ }
+
+ // get the cls_spell_***.2da index for the real spell
+ int nSpellbookSpell = RealSpellToSpellbookID(nClass, nRealSpellID);
+ // if the spell does not exist in the spellbook, return FALSE
+ if (nSpellbookSpell == -1)
+ return FALSE;
+ // next check if the PC is high enough level to know the spell
+ string sFile = GetFileForClass(nClass);
+ int nSpellLevel = -1;
+ string sSpellLevel = Get2DACache(sFile, "Level", nSpellbookSpell);
+ if (sSpellLevel != "")
+ nSpellLevel = StringToInt(sSpellLevel);
+ if ((GetLevelByClass(nClass) < nSpellLevel) || nSpellLevel == -1)
+ return FALSE; // not high enough level
+ // at this stage, prepared casters know the spell and only spontaneous classes need checking
+ // there are exceptions and these need hardcoding:
+
+ if((GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) && nClass != CLASS_TYPE_ARCHIVIST)
+ return TRUE;
+
+ // spontaneous casters have all their known spells as hide feats
+ // get the featID of the spell
+ int nFeatID = StringToInt(Get2DACache(sFile, "FeatID", nSpellbookSpell));
+ if (GetHasFeat(nFeatID, oPC))
+ return TRUE;
+
+ return FALSE;
+}
+
+//routes to action cast spell, but puts a wrapper around to tell other functions its a
+//SLA, so dont craft etc
+//also defaults th totalDC to 10+spellevel+chamod
+//this is Base DC, not total DC. SLAs are still spells, so spell focus should still apply.
+void DoRacialSLA(int nSpellID, int nCasterlevel = 0, int nTotalDC = 0, int bInstantCast = FALSE)
+{
+ if(DEBUG) DoDebug("Spell DC passed to DoRacialSLA: " + IntToString(nTotalDC));
+ if(nTotalDC == 0)
+ nTotalDC = 10
+ +StringToInt(Get2DACache("spells", "Innate", nSpellID))
+ +GetAbilityModifier(ABILITY_CHARISMA);
+
+ ActionDoCommand(SetLocalInt(OBJECT_SELF, "SpellIsSLA", TRUE));
+ if(DEBUG) DoDebug("Spell DC entered in ActionCastSpell: " + IntToString(nTotalDC));
+ ActionCastSpell(nSpellID, nCasterlevel, 0, nTotalDC, METAMAGIC_NONE, CLASS_TYPE_INVALID, FALSE, FALSE, OBJECT_INVALID, bInstantCast);
+ //ActionCastSpell(nSpellID, nCasterlevel, 0, nTotalDC);
+ ActionDoCommand(DeleteLocalInt(OBJECT_SELF, "SpellIsSLA"));
+}
+
+void DeleteLocalManifestation(object oObject, string sName)
+{
+ DeleteLocalObject(oObject, sName + "_oManifester");
+
+ DeleteLocalInt(oObject, sName + "_bCanManifest");
+ DeleteLocalInt(oObject, sName + "_nPPCost");
+ DeleteLocalInt(oObject, sName + "_nPsiFocUsesRemain");
+ DeleteLocalInt(oObject, sName + "_nManifesterLevel");
+ DeleteLocalInt(oObject, sName + "_nSpellID");
+
+ DeleteLocalInt(oObject, sName + "_nTimesAugOptUsed_1");
+ DeleteLocalInt(oObject, sName + "_nTimesAugOptUsed_2");
+ DeleteLocalInt(oObject, sName + "_nTimesAugOptUsed_3");
+ DeleteLocalInt(oObject, sName + "_nTimesAugOptUsed_4");
+ DeleteLocalInt(oObject, sName + "_nTimesAugOptUsed_5");
+ DeleteLocalInt(oObject, sName + "_nTimesGenericAugUsed");
+
+ DeleteLocalInt(oObject, sName + "_bChain");
+ DeleteLocalInt(oObject, sName + "_bEmpower");
+ DeleteLocalInt(oObject, sName + "_bExtend");
+ DeleteLocalInt(oObject, sName + "_bMaximize");
+ DeleteLocalInt(oObject, sName + "_bSplit");
+ DeleteLocalInt(oObject, sName + "_bTwin");
+ DeleteLocalInt(oObject, sName + "_bWiden");
+ DeleteLocalInt(oObject, sName + "_bQuicken");
+}
+
+void DeleteLocalMystery(object oObject, string sName)
+{
+ DeleteLocalObject(oObject, sName + "_oShadow");
+
+ DeleteLocalInt(oObject, sName + "_bCanMyst");
+ DeleteLocalInt(oObject, sName + "_nShadowcasterLevel");
+ DeleteLocalInt(oObject, sName + "_nMystId");
+ DeleteLocalInt(oObject, sName + "_nPen");
+ DeleteLocalInt(oObject, sName + "_bIgnoreSR");
+
+ DeleteLocalInt(oObject, sName + "_bEmpower");
+ DeleteLocalInt(oObject, sName + "_bExtend");
+ DeleteLocalInt(oObject, sName + "_bMaximize");
+ DeleteLocalInt(oObject, sName + "_bQuicken");
+
+ DeleteLocalInt(oObject, sName + "_nSaveDC");
+ DeleteLocalFloat(oObject, sName + "_fDur");
+}
+
+//::void main (){}
\ No newline at end of file
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prcsp_archmaginc.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prcsp_archmaginc.nss
new file mode 100644
index 00000000..58082638
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prcsp_archmaginc.nss
@@ -0,0 +1,203 @@
+//
+// Wrapper Functions for the Archmage Class and Feats
+//
+
+//
+// Notes: Normal use is to include prc_alterations.
+// If this file if to be included elsewhere add the following lines
+// to the target file:
+// #include "prcsp_reputation"
+// #include "prcsp_archmaginc"
+//
+
+//////////////////////////////////////////////////
+/* Constants */
+//////////////////////////////////////////////////
+
+/// @todo Change these to TLK reads
+
+const string MASTERY_OF_ELEMENTS_TAG = "archmage_mastery_elements";
+const string MASTERY_OF_ELEMENTS_NAME_TAG = "archmage_mastery_elements_name";
+const string MASTERY_OF_SHAPE_TAG = "archmage_mastery_shaping";
+const string MASTERY_OF_SHAPE_ON = "Shaping spells to protect allies.";
+const string MASTERY_OF_SHAPE_OFF = "Spell shaping is disabled, allies may be effected.";
+const string MASTERY_OF_ELEMENTS_ACID = "Elemental spell damage set to acid.";
+const string MASTERY_OF_ELEMENTS_COLD = "Elemental spell damage set to cold.";
+const string MASTERY_OF_ELEMENTS_ELECTRICAL = "Elemental spell damage set to electrical.";
+const string MASTERY_OF_ELEMENTS_FIRE = "Elemental spell damage set to fire.";
+const string MASTERY_OF_ELEMENTS_SONIC = "Elemental spell damage set to sonic.";
+const string MASTERY_OF_ELEMENTS_OFF = "Elemental spell damage returned to normal.";
+
+const int FEAT_INACTIVE = 0;
+const int FEAT_ACTIVE = 1;
+
+const int MASTERY_OF_SHAPE_EFFECT = 460;
+const int MASTERY_OF_ELEMENTS_EFFECT_ACID = 448;
+const int MASTERY_OF_ELEMENTS_EFFECT_ELECTRICAL = 463;
+const int MASTERY_OF_ELEMENTS_EFFECT_OFF = 460;
+
+const int SPELL_MASTERY_ELEMENTS_NORMAL = 2000;
+const int SPELL_MASTERY_ELEMENTS_ACID = 2003;
+const int SPELL_MASTERY_ELEMENTS_COLD = 2002;
+const int SPELL_MASTERY_ELEMENTS_ELECTRICITY = 2004;
+const int SPELL_MASTERY_ELEMENTS_FIRE = 2001;
+const int SPELL_MASTERY_ELEMENTS_SONIC = 2005;
+
+const int TIME_1_ROUND = 1;
+
+int PRCGetSpellLevel(object oCreature, int nSpell);
+int PRCGetSpellId(object oCaster = OBJECT_SELF);
+object PRCGetSpellTargetObject(object oCaster = OBJECT_SELF);
+
+//////////////////////////////////////////////////
+/* Function prototypes */
+//////////////////////////////////////////////////
+
+/**
+ * Determines if Master of Shapes is active and applies in regards to the
+ * given target.
+ *
+ * @param oCaster A creature casting an area-affecting spell
+ * @param oTarget A creature that is in the affected area
+ * @return TRUE if the creature should be exempt from the spell due to
+ * Mastery of Shapes. FALSE otherwise
+ */
+int CheckMasteryOfShapes(object oCaster, object oTarget);
+
+void SetFeatVisualEffects(object oCaster, int nEffect, string sMessage);
+
+void ToggleMasteryOfShapes(object oCaster);
+
+void SetMasteryOfElements();
+
+//////////////////////////////////////////////////
+/* Includes */
+//////////////////////////////////////////////////
+
+//#include "lookup_2da_spell"
+#include "prcsp_reputation"
+//#include "prc_inc_spells"
+
+
+//////////////////////////////////////////////////
+/* Function definitions */
+//////////////////////////////////////////////////
+
+int CheckMasteryOfShapes(object oCaster, object oTarget)
+{
+ int bRetVal = FALSE;
+
+ // This variable should not be set without the feat being available.
+ // If someone wants to cheat, let them.
+ if (GetLocalInt(oCaster, MASTERY_OF_SHAPE_TAG) == FEAT_ACTIVE && !GetIsReactionTypeHostile(oTarget, oCaster))
+ {
+ bRetVal = TRUE;
+ }
+
+ return bRetVal;
+}
+
+int ExtraordinarySpellAim(object oCaster, object oTarget)
+{
+ int bRetVal = FALSE;
+
+ // This variable should not be set without the feat being available.
+ // If someone wants to cheat, let them.
+ if(GetHasFeat(FEAT_EXTRAORDINARY_SPELL_AIM, oCaster)
+ && !GetLocalInt(oCaster, "ExtraordinarySpellAim")
+ && GetIsFriend(oTarget, oCaster))
+ {
+ // Only once per spell
+ SetLocalInt(oCaster, "ExtraordinarySpellAim", TRUE);
+ DelayCommand(1.0, DeleteLocalInt(oCaster, "ExtraordinarySpellAim"));
+ if(GetIsSkillSuccessful(oCaster, SKILL_SPELLCRAFT, 25 + PRCGetSpellLevel(oCaster, PRCGetSpellId())))
+ bRetVal = TRUE;
+ }
+
+ return bRetVal;
+}
+
+//
+// Help with Visual Effects when setting feats
+//
+void SetFeatVisualEffects(object oCaster, int nEffect, string sMessage)
+{
+ ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(nEffect),
+ oCaster, RoundsToSeconds(TIME_1_ROUND));
+
+ FloatingTextStringOnCreature(sMessage, OBJECT_SELF, FALSE);
+}
+
+//
+// Enable/Disable Mastery of Shapes
+//
+void ToggleMasteryOfShapes(object oCaster)
+{
+ if (GetLocalInt(OBJECT_SELF, MASTERY_OF_SHAPE_TAG) == FEAT_INACTIVE) {
+ SetLocalInt(OBJECT_SELF, MASTERY_OF_SHAPE_TAG, FEAT_ACTIVE);
+ SetFeatVisualEffects(oCaster, MASTERY_OF_SHAPE_EFFECT, MASTERY_OF_SHAPE_ON);
+ }
+ else {
+ SetLocalInt(OBJECT_SELF, MASTERY_OF_SHAPE_TAG, FEAT_INACTIVE);
+ SetFeatVisualEffects(oCaster, MASTERY_OF_SHAPE_EFFECT, MASTERY_OF_SHAPE_OFF);
+ }
+}
+
+//
+// This function sets the Mastery of Elements feat to a specific element
+//
+void SetMasteryOfElements()
+{
+ string msg = MASTERY_OF_ELEMENTS_OFF;
+ string sElem = "";
+ int nEffect = MASTERY_OF_ELEMENTS_EFFECT_OFF;
+ int dmgType = FEAT_INACTIVE;
+
+ switch (PRCGetSpellId()) {
+ case SPELL_MASTERY_ELEMENTS_ACID:
+ nEffect = MASTERY_OF_ELEMENTS_EFFECT_ACID;
+ dmgType = DAMAGE_TYPE_ACID;
+ msg = MASTERY_OF_ELEMENTS_ACID;
+ sElem = "Acid";
+ break;
+
+ case SPELL_MASTERY_ELEMENTS_COLD:
+ nEffect = VFX_IMP_AC_BONUS;
+ dmgType = DAMAGE_TYPE_COLD;
+ msg = MASTERY_OF_ELEMENTS_COLD;
+ sElem = "Cold";
+ break;
+
+ case SPELL_MASTERY_ELEMENTS_ELECTRICITY:
+ nEffect = MASTERY_OF_ELEMENTS_EFFECT_ELECTRICAL;
+ dmgType = DAMAGE_TYPE_ELECTRICAL;
+ msg = MASTERY_OF_ELEMENTS_ELECTRICAL;
+ sElem = "Electricity";
+ break;
+
+ case SPELL_MASTERY_ELEMENTS_FIRE:
+ nEffect = VFX_IMP_ELEMENTAL_PROTECTION;
+ dmgType = DAMAGE_TYPE_FIRE;
+ msg = MASTERY_OF_ELEMENTS_FIRE;
+ sElem = "Fire";
+ break;
+
+ case SPELL_MASTERY_ELEMENTS_SONIC:
+ nEffect = VFX_FNF_SOUND_BURST;
+ dmgType = DAMAGE_TYPE_SONIC;
+ msg = MASTERY_OF_ELEMENTS_SONIC;
+ sElem = "Sonic";
+ break;
+
+ default:
+ // Use the default initialized variables
+ break;
+ }
+
+ SetLocalInt(OBJECT_SELF, MASTERY_OF_ELEMENTS_TAG, dmgType);
+ SetLocalString(OBJECT_SELF, MASTERY_OF_ELEMENTS_NAME_TAG, sElem);
+ SetFeatVisualEffects(PRCGetSpellTargetObject(), nEffect, msg);
+}
+
+// Test main
+//void main(){}
diff --git a/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prcsp_engine.nss b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prcsp_engine.nss
new file mode 100644
index 00000000..0a1603c9
--- /dev/null
+++ b/nwn/nwnprc/trunk/users/Jaysyn/20251210_TestChangesStash/prcsp_engine.nss
@@ -0,0 +1,419 @@
+
+// Module Constants
+const float CACHE_TIMEOUT_CAST = 2.0;
+const string CASTER_LEVEL_TAG = "PRCEffectiveCasterLevel";
+
+// Constants that dictate ResistSpell results
+const int SPELL_RESIST_FAIL = 0;
+const int SPELL_RESIST_PASS = 1;
+const int SPELL_RESIST_GLOBE = 2;
+const int SPELL_RESIST_MANTLE = 3;
+
+//////////////////////////////////////////////////
+/* Forward Declarations */
+//////////////////////////////////////////////////
+
+int PRCDoResistSpell(object oCaster, object oTarget, int nEffCasterLvl=0, float fDelay = 0.0);
+int CheckSpellfire(object oCaster, object oTarget, int bFriendly = FALSE);
+int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF);
+int GetIsArcaneClass(int nClass, object oCaster = OBJECT_SELF);
+int GetIsDivineClass(int nClass, object oCaster = OBJECT_SELF);
+int GetIsIncarnumUser(object oMeldshaper);
+int GetIsMeldBound(object oMeldshaper, int nMeld = -1);
+int GetEssentiaInvestedFeat(object oMeldshaper, int nFeat);
+void SetPersistantLocalInt(object oPC, string sName, int nValue);
+int GetPersistantLocalInt(object oPC, string sName);
+
+//////////////////////////////////////////////////
+/* Included Files */
+//////////////////////////////////////////////////
+
+
+#include "prc_inc_racial"
+//#include "prc_feat_const"
+//#include "prc_class_const"
+//#include "prcsp_reputation"
+#include "prcsp_archmaginc"
+//#include "prc_add_spell_dc"
+#include "prc_add_spl_pen"
+#include "moi_meld_const"
+
+//
+// This function is a wrapper should someone wish to rewrite the Bioware
+// version. This is where it should be done.
+//
+int PRCResistSpell(object oCaster, object oTarget)
+{
+ return ResistSpell(oCaster, oTarget);
+}
+
+//
+// This function is a wrapper should someone wish to rewrite the Bioware
+// version. This is where it should be done.
+//
+int PRCGetSpellResistance(object oTarget, object oCaster)
+{
+ int iSpellRes = GetSpellResistance(oTarget);
+ int nHD = GetHitDice(oTarget);
+
+ //racial pack SR
+ int iRacialSpellRes = 0;
+ if(GetHasFeat(FEAT_SPELL27, oTarget))
+ iRacialSpellRes = 27 + nHD;
+ else if(GetHasFeat(FEAT_SPELL25, oTarget))
+ iRacialSpellRes = 25 + nHD;
+ else if(GetHasFeat(FEAT_SPELL23, oTarget))
+ iRacialSpellRes = 23 + nHD;
+ else if(GetHasFeat(FEAT_SPELL22, oTarget))
+ iRacialSpellRes = 22 + nHD;
+ else if(GetHasFeat(FEAT_SPELL21, oTarget))
+ iRacialSpellRes = 21 + nHD;
+ else if(GetHasFeat(FEAT_SPELL20, oTarget))
+ iRacialSpellRes = 20 + nHD;
+ else if(GetHasFeat(FEAT_SPELL19, oTarget))
+ iRacialSpellRes = 19 + nHD;
+ else if(GetHasFeat(FEAT_SPELL18, oTarget))
+ iRacialSpellRes = 18 + nHD;
+ else if(GetHasFeat(FEAT_SPELL17, oTarget))
+ iRacialSpellRes = 17 + nHD;
+ else if(GetHasFeat(FEAT_SPELL16, oTarget))
+ iRacialSpellRes = 16 + nHD;
+ else if(GetHasFeat(FEAT_SPELL15, oTarget))
+ iRacialSpellRes = 15 + nHD;
+ else if(GetHasFeat(FEAT_SPELL14, oTarget))
+ iRacialSpellRes = 14 + nHD;
+ else if(GetHasFeat(FEAT_SPELL13, oTarget))
+ iRacialSpellRes = 13 + nHD;
+ else if(GetHasFeat(FEAT_SPELL11, oTarget))
+ iRacialSpellRes = 11 + nHD;
+ else if(GetHasFeat(FEAT_SPELL10, oTarget))
+ iRacialSpellRes = 10 + nHD;
+ else if(GetHasFeat(FEAT_SPELL8, oTarget))
+ iRacialSpellRes = 8 + nHD;
+ else if(GetHasFeat(FEAT_SPELL5, oTarget))
+ iRacialSpellRes = 5 + nHD;
+ if(iRacialSpellRes > iSpellRes)
+ iSpellRes = iRacialSpellRes;
+
+ // Exalted Companion, can also be used for Celestial Template
+ if(GetLocalInt(oTarget, "CelestialTemplate") || GetLocalInt(oTarget, "PseudonaturalTemplate"))
+ {
+ int nSR = nHD * 2;
+ if (nSR > 25) nSR = 25;
+ if (nSR > iSpellRes) iSpellRes = nSR;
+ }
+
+ // Enlightened Fist SR = 10 + monk level + enlightened fist level
+ if(GetHasFeat(FEAT_EF_DIAMOND_SOUL, oTarget))
+ {
+ int nEF = 10 + GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oTarget) + GetLevelByClass(CLASS_TYPE_MONK, oTarget);
+ if(nEF > iSpellRes)
+ iSpellRes = nEF;
+ }
+
+ // Contemplative SR = 15 + contemplative level
+ if(GetHasFeat(FEAT_DIVINE_SOUL, oTarget))
+ {
+ int nCont = 15 + GetLevelByClass(CLASS_TYPE_CONTEMPLATIVE, oTarget);
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+
+ // Marrutact
+ if(GetRacialType(oTarget) == RACIAL_TYPE_MARRUTACT)
+ {
+ int nCont = 9 + GetHitDice(oTarget);
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+
+ // Hobgoblin Wsrsoul
+ if(GetRacialType(oTarget) == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
+ {
+ int nCont = 8 + GetHitDice(oTarget);
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+
+ // Exordius Weapon of Legacy
+ if(GetLocalInt(oTarget, "ExordiusSR"))
+ {
+ int nCont = 5 + GetHitDice(oTarget);
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+
+ // Hammer of Witches Weapon of Legacy
+ if(GetLocalInt(oTarget, "HammerWitchesSR"))
+ {
+ // SR vs arcane only
+ if(GetIsArcaneClass(PRCGetLastSpellCastClass(oCaster)))
+ {
+ int nCont = 5 + GetHitDice(oTarget);
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+ }
+
+ // 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
+ if(GetIsDivineClass(PRCGetLastSpellCastClass(oCaster)))
+ {
+ int nCont = 15;
+ if (GetLevelByClass(CLASS_TYPE_UR_PRIEST, oTarget) >= 8) nCont = 20;
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+ } */
+
+ // Dread Carapace Heart Bind
+ if(GetIsIncarnumUser(oTarget))
+ {
+ if (GetIsMeldBound(oTarget, MELD_DREAD_CARAPACE) == CHAKRA_CROWN)
+ {
+ int nCont = 5 + (4 * GetEssentiaInvested(oTarget, MELD_DREAD_CARAPACE));
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+ if (GetHasSpellEffect(MELD_SPELLWARD_SHIRT, oTarget)) // MELD_SPELLWARD_SHIRT
+ {
+ int nCont = 5 + (4 * GetEssentiaInvested(oTarget, MELD_SPELLWARD_SHIRT));
+ if(nCont > iSpellRes)
+ iSpellRes = nCont;
+ }
+ }
+
+ // Foe Hunter SR stacks with normal SR when a spell is cast by their hated enemy
+ if(GetHasFeat(FEAT_HATED_ENEMY_SR, oTarget) && GetLocalInt(oTarget, "HatedFoe") == MyPRCGetRacialType(oCaster))
+ {
+ iSpellRes += 15 + GetLevelByClass(CLASS_TYPE_FOE_HUNTER, oTarget);
+ }
+
+ // Adds +4 to SR
+ if(GetHasFeat(FEAT_PSYCHIC_REFUSAL, oTarget))
+ iSpellRes += 4;
+
+ // Forsaker SR adds to existing
+ if(GetLevelByClass(CLASS_TYPE_FORSAKER, oTarget))
+ iSpellRes = iSpellRes + 10 + GetLevelByClass(CLASS_TYPE_FORSAKER, oTarget);
+
+ return iSpellRes;
+}
+
+//
+// If a spell is resisted, display the effect
+//
+void PRCShowSpellResist(object oCaster, object oTarget, int nResist, float fDelay = 0.0)
+{
+ // If either caster/target is a PC send them a message
+ if (GetIsPC(oCaster))
+ {
+ string message = nResist == SPELL_RESIST_FAIL ?
+ "Target is affected by the spell." : "Target resisted the spell.";
+ SendMessageToPC(oCaster, message);
+ }
+ if (GetIsPC(oTarget))
+ {
+ string message = nResist == SPELL_RESIST_FAIL ?
+ "You are affected by the spell." : "You resisted the spell.";
+ SendMessageToPC(oTarget, message);
+ }
+
+ if (nResist != SPELL_RESIST_FAIL) {
+ // Default to a standard resistance
+ int eve = VFX_IMP_MAGIC_RESISTANCE_USE;
+
+ // Check for other resistances
+ if (nResist == SPELL_RESIST_GLOBE)
+ eve = VFX_IMP_GLOBE_USE;
+ else if (nResist == SPELL_RESIST_MANTLE)
+ eve = VFX_IMP_SPELL_MANTLE_USE;
+
+ // Render the effect
+ DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,
+ EffectVisualEffect(eve), oTarget));
+ }
+}
+
+//
+// This function overrides the BioWare MyResistSpell.
+// TODO: Change name to PRCMyResistSpell.
+//
+int PRCDoResistSpell(object oCaster, object oTarget, int nEffCasterLvl=0, float fDelay = 0.0)
+{
+ int nResist;
+
+ // Check if the archmage shape mastery applies to this target
+ if (CheckSpellfire(oCaster, oTarget) || CheckMasteryOfShapes(oCaster, oTarget) || ExtraordinarySpellAim(oCaster, oTarget) || (GetLocalInt(oCaster, "WOL_DesertWindFireball") && GetSpellId() == SPELL_FIREBALL))
+ nResist = SPELL_RESIST_MANTLE;
+ else if(GetLevelByClass(CLASS_TYPE_BEGUILER, oCaster) >= 20 && GetIsDeniedDexBonusToAC(oTarget, oCaster, TRUE))
+ {
+ //Beguilers of level 20+ automatically overcome SR of targets denied Dex bonus to AC
+ nResist = SPELL_RESIST_FAIL;
+ }
+ else if(GetLocalInt(oCaster, "CunningBreach"))
+ {
+ //Factotum can pay to breach all SR for a round
+ nResist = SPELL_RESIST_FAIL;
+ }
+ //using vitriolic blast with eldritch spellweave
+ else if(oTarget == GetLocalObject(oCaster, "SPELLWEAVE_TARGET")
+ && GetLocalInt(oCaster, "BlastEssence") == INVOKE_VITRIOLIC_BLAST)
+ {
+ nResist = SPELL_RESIST_FAIL;
+ }
+ else {
+ // Check immunities and mantles, otherwise ignore the result completely
+ nResist = PRCResistSpell(oCaster, oTarget);
+
+ //Resonating Resistance
+ if((nResist <= SPELL_RESIST_PASS) && (GetHasSpellEffect(SPELL_RESONATING_RESISTANCE, oTarget)))
+ {
+ nResist = PRCResistSpell(oCaster, oTarget);
+ }
+
+ if (nResist <= SPELL_RESIST_PASS)
+ {
+ nResist = SPELL_RESIST_FAIL;
+
+ // Because the version of this function was recently changed to
+ // optionally allow the caster level, we must calculate it here.
+ // The result will be cached for a period of time.
+ if (!nEffCasterLvl) {
+ nEffCasterLvl = GetLocalInt(oCaster, CASTER_LEVEL_TAG);
+ if (!nEffCasterLvl) {
+ nEffCasterLvl = PRCGetCasterLevel(oCaster) + SPGetPenetr();
+ SetLocalInt(oCaster, CASTER_LEVEL_TAG, nEffCasterLvl);
+ DelayCommand(CACHE_TIMEOUT_CAST,
+ DeleteLocalInt(oCaster, CASTER_LEVEL_TAG));
+ }
+ }
+
+ // Pernicious Magic
+ // +4 caster level vs SR Weave user (not Evoc & Trans spells)
+ int iWeav;
+ if (GetHasFeat(FEAT_PERNICIOUSMAGIC,oCaster))
+ {
+ if (!GetHasFeat(FEAT_SHADOWWEAVE,oTarget))
+ {
+ int nSchool = GetLocalInt(oCaster, "X2_L_LAST_SPELLSCHOOL_VAR");
+ if ( nSchool != SPELL_SCHOOL_EVOCATION && nSchool != SPELL_SCHOOL_TRANSMUTATION )
+ iWeav=4;
+ }
+ }
+
+
+ // A tie favors the caster.
+ if ((nEffCasterLvl + d20(1)+iWeav) < PRCGetSpellResistance(oTarget, oCaster))
+ nResist = SPELL_RESIST_PASS;
+ }
+ }
+
+ // Karsites heal from resisting a spell
+ if(GetRacialType(oTarget) == RACIAL_TYPE_KARSITE && nResist == SPELL_RESIST_PASS)
+ {
+ int nSpellLevel = StringToInt(Get2DACache("spells", "Innate", PRCGetSpellId()));
+ ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nSpellLevel*2), oTarget);
+ }
+
+ PRCShowSpellResist(oCaster, oTarget, nResist, fDelay);
+
+ return nResist;
+}
+
+//Returns the maximum number of spellfire levels oPC can store
+int SpellfireMax(object oPC)
+{
+ //can't absorb spells without feat
+ if(!GetHasFeat(FEAT_SPELLFIRE_WIELDER, oPC)) return 0;
+
+ int nCON = GetAbilityScore(oPC, ABILITY_CONSTITUTION);
+
+ int i, nCount;
+ for (i = FEAT_EPIC_SPELLFIRE_WIELDER_I; i <= FEAT_EPIC_SPELLFIRE_WIELDER_X; i++)
+ {
+ if (GetHasFeat(i, oPC))
+ nCON = nCON + 4;
+ }
+ if (DEBUG) DoDebug("SpellfireMax nCon is "+IntToString(nCON));
+
+ int nStorage = ((GetLevelByClass(CLASS_TYPE_SPELLFIRE, oPC) + 1) / 2) + 1;
+ if(nStorage > 5) nStorage = 5;
+ return nCON * nStorage;
+}
+
+//Increases the number of stored spellfire levels on a creature
+void AddSpellfireLevels(object oPC, int nLevels)
+{
+ int nMax = SpellfireMax(oPC);
+ int nStored = GetPersistantLocalInt(oPC, "SpellfireLevelStored");
+ nStored += nLevels;
+ if(nStored > nMax) nStored = nMax; //capped
+ SetPersistantLocalInt(oPC, "SpellfireLevelStored", nStored);
+}
+
+//Checks if spell target can absorb spells by being a spellfire wielder
+int CheckSpellfire(object oCaster, object oTarget, int bFriendly = FALSE)
+{
+ //can't absorb spells without feat
+ if(!GetHasFeat(FEAT_SPELLFIRE_WIELDER, oTarget)) return 0;
+
+ //Can't absorb own spells/powers if switch is set
+ if(GetPRCSwitch(PRC_SPELLFIRE_DISALLOW_CHARGE_SELF) && oTarget == oCaster) return 0;
+
+ //abilities rely on access to weave
+ if(GetHasFeat(FEAT_SHADOWWEAVE, oTarget)) return 0;
+
+ int nSpellID = PRCGetSpellId();
+ if(!bFriendly && GetLocalInt(oCaster, "IsAOE_" + IntToString(nSpellID)))
+ return 0; //can't absorb hostile AOE spells
+
+ int nSpellfireLevel = GetPersistantLocalInt(oTarget, "SpellfireLevelStored");
+ if(DEBUG) DoDebug("CheckSpellfire: " + IntToString(nSpellfireLevel) + " levels stored", oTarget);
+
+ int nMax = SpellfireMax(oTarget);
+
+ if(DEBUG) DoDebug("CheckSpellfire: Maximum " + IntToString(nMax), oTarget);
+
+ //can't absorb any more spells, sanity check
+ if(nSpellfireLevel >= nMax) return 0;
+
+ //increasing stored levels
+ int nSpellLevel = GetLocalInt(oCaster, "PRC_CurrentManifest_PowerLevel"); //replicates GetPowerLevel(oCaster);
+ if(!nSpellLevel) //not a power //avoids compiler problems
+ { //with includes
+ string sInnate = Get2DACache("spells", "Innate", nSpellID);//lookup_spell_innate(nSpellID);
+ if(sInnate == "") return 0; //no innate level, unlike cantrips
+ nSpellLevel = StringToInt(sInnate);
+ }
+ /*
+ string sInnate = Get2DACache("spells", "Innate", nSpellID);
+ if(sInnate == "") return 0; //no innate level, unlike cantrips
+ int nSpellLevel = StringToInt(sInnate);
+ */
+
+ AddSpellfireLevels(oTarget, nSpellLevel);
+
+ //absorbed
+ return 1;
+}
+
+//:: void main(){}
\ No newline at end of file