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