diff --git a/trunk/include/inc_epicspellfnc.nss b/trunk/include/inc_epicspellfnc.nss deleted file mode 100644 index f345ac5f..00000000 --- a/trunk/include/inc_epicspellfnc.nss +++ /dev/null @@ -1,275 +0,0 @@ - -//:: Updated for .35 by Jaysyn 2023/03/10 - -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" - -// 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("sAbrew 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; -} \ No newline at end of file diff --git a/trunk/include/inc_newspellbook.nss b/trunk/include/inc_newspellbook.nss deleted file mode 100644 index 57217e0f..00000000 --- a/trunk/include/inc_newspellbook.nss +++ /dev/null @@ -1,1340 +0,0 @@ - - -/* Steps for adding a new spellbook - -Prepared: -Make cls_spgn_*.2da -Make cls_spcr_*.2da -Make blank cls_spell_*.2da -Add cls_spgn_*.2da to classes.2da -Add class entry in prc_classes.2da -Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level -Add class to GetSpellbookTypeForClass() below -Add class to GetAbilityScoreForClass() below -Add class to bKnowsAllClassSpells() below if necessary -Add class to GetIsArcaneClass() or GetIsDivineClass() in prc_inc_castlvl as appropriate -Add class to GetCasterLevelModifier() in prc_inc_castlvl if necessary -Add class to SetupLookupStage() in inc_lookups -Add class to GetCasterLvl() in prc_inc_spells -Add Practiced Spellcaster feat to feat.2da and to PracticedSpellcasting() in prc_inc_castlvl -Run the assemble_spellbooks.bat file -Make the prc_* scripts in newspellbook. The filenames can be found under the spell entries for the class in spells.2da. - -Spont: -Make cls_spgn_*.2da -Make cls_spkn_*.2da -Make cls_spcr_*.2da -Make blank cls_spell_*.2da -Add cls_spkn_*.2da and cls_spgn_*.2da to classes.2da -Add class entry in prc_classes.2da -Add class to GetSpellbookTypeForClass() below -Add class to GetAbilityScoreForClass() below -Add class to bKnowsAllClassSpells() below if necessary -Add class to GetIsArcaneClass() or GetIsDivineClass() in prc_inc_castlvl as appropriate -Add class to GetCasterLevelModifier() in prc_inc_castlvl if necessary -Add class to SetupLookupStage() in inc_lookups -Add class to GetCasterLvl() in prc_inc_spells -Add Practiced Spellcaster feat to feat.2da and to PracticedSpellcasting() in prc_inc_castlvl -Add class to prc_amagsys_gain if(CheckMissingSpells(oPC, CLASS_TYPE_SORCERER, MinimumSpellLevel, MaximumSpellLevel)) -Add class to ExecuteScript("prc_amagsys_gain", oPC) list in EvalPRCFeats in prc_inc_function -Run the assemble_spellbooks.bat file -Make the prc_* scripts in newspellbook - -prc_classes.2da entry: -Label - name for the class -Name - tlk file strref -SpellCaster - does the class cast spells? 0 = No, 1 = Yes (used for bonus spellslot item properties) -SBType - S = spontaneous, P = prepared -AL - does the class use Advanced Learning of any type? 0 = No, 1 = Yes -*/ - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -int GetSpellbookTypeForClass(int nClass); -int GetAbilityScoreForClass(int nClass, object oPC); - -/** - * Determines the given character's DC-modifying ability modifier for - * the given class' spells. Handles split-score casters. - * - * @param nClass The spellcasting class for whose spells to determine ability mod to DC for - * @param oPC The character whose abilities to examine - * @return The DC-modifying ability score's ability modifier value - */ -int GetDCAbilityModForClass(int nClass, object oPC); - -string GetFileForClass(int nClass); -int GetSpellslotLevel(int nClass, object oPC); -int GetItemBonusSlotCount(object oPC, int nClass, int nSpellLevel); -int GetSlotCount(int nLevel, int nSpellLevel, int nAbilityScore, int nClass, object oItemPosessor = OBJECT_INVALID); -int bKnowsAllClassSpells(int nClass); -int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC); -int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass); -int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass); -void AddSpellUse(object oPC, int nSpellbookID, int nClass, string sFile, string sArrayName, int nSpellbookType, object oSkin, int nFeatID, int nIPFeatID, string sIDX = ""); -void RemoveSpellUse(object oPC, int nSpellID, int nClass); -// int GetSpellUses(object oPC, int nSpellID, int nClass); -int GetSpellLevel(int nSpellID, int nClass); -void SetupSpells(object oPC, int nClass); -void CheckAndRemoveFeat(object oHide, itemproperty ipFeat); -void WipeSpellbookHideFeats(object oPC); -void CheckNewSpellbooks(object oPC); -void NewSpellbookSpell(int nClass, int nSpellbookType, int nMetamagic = METAMAGIC_NONE, int bInstantSpell = FALSE); -void CastSpontaneousSpell(int nClass, int bInstantSpell = FALSE); -void CastPreparedSpell(int nClass, int nMetamagic = METAMAGIC_NONE, int bInstantSpell = FALSE); - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -/* stored in "prc_inc_sb_const" - Accessed via "prc_inc_core" */ - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -// ** THIS ORDER IS IMPORTANT ** - -//#include "prc_effect_inc" //access via prc_inc_core -//#include "inc_lookups" //access via prc_inc_core -#include "prc_inc_core" -#include "inc_sp_gain_mem" //providing child access to prc_inc_core - //Must load in this order. -//#include "prc_inc_castlvl" //access via prc_inc_core -//#include "prc_inc_descrptr" //access via prc_inc_core - - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetSpellbookTypeForClass(int nClass) -{ - switch(nClass) - { - case CLASS_TYPE_ARCHIVIST: - case CLASS_TYPE_BLACKGUARD: - case CLASS_TYPE_BLIGHTER: - case CLASS_TYPE_CLERIC: - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: - case CLASS_TYPE_DRUID: - case CLASS_TYPE_HEALER: - case CLASS_TYPE_KNIGHT_CHALICE: - case CLASS_TYPE_KNIGHT_MIDDLECIRCLE: - case CLASS_TYPE_NENTYAR_HUNTER: - case CLASS_TYPE_OCULAR: - case CLASS_TYPE_PALADIN: - case CLASS_TYPE_RANGER: - case CLASS_TYPE_SHADOWLORD: - case CLASS_TYPE_SHAMAN: - case CLASS_TYPE_SLAYER_OF_DOMIEL: - case CLASS_TYPE_SOHEI: - case CLASS_TYPE_SOLDIER_OF_LIGHT: - case CLASS_TYPE_UR_PRIEST: - case CLASS_TYPE_VASSAL: - case CLASS_TYPE_VIGILANT: - case CLASS_TYPE_WIZARD: - return SPELLBOOK_TYPE_PREPARED; - case CLASS_TYPE_ASSASSIN: - case CLASS_TYPE_BARD: - case CLASS_TYPE_BEGUILER: - case CLASS_TYPE_CELEBRANT_SHARESS: - case CLASS_TYPE_DREAD_NECROMANCER: - case CLASS_TYPE_DUSKBLADE: - case CLASS_TYPE_FAVOURED_SOUL: - case CLASS_TYPE_HARPER: - case CLASS_TYPE_HEXBLADE: - case CLASS_TYPE_JUSTICEWW: - case CLASS_TYPE_KNIGHT_WEAVE: - case CLASS_TYPE_SORCERER: - case CLASS_TYPE_SUBLIME_CHORD: - case CLASS_TYPE_SUEL_ARCHANAMACH: - case CLASS_TYPE_WARMAGE: - return SPELLBOOK_TYPE_SPONTANEOUS; - // shapechanger HD count as sorcerer for aranea. - case CLASS_TYPE_SHAPECHANGER: - return SPELLBOOK_TYPE_SPONTANEOUS; - // Multiple races - case CLASS_TYPE_MONSTROUS: - return SPELLBOOK_TYPE_SPONTANEOUS; - // Gloura as Bard - case CLASS_TYPE_FEY: - return SPELLBOOK_TYPE_SPONTANEOUS; - // Drider as Sorc - case CLASS_TYPE_ABERRATION: - return SPELLBOOK_TYPE_SPONTANEOUS; - //outsider HD count as sorc for raks - case CLASS_TYPE_OUTSIDER: { - /// @todo Will eventually need to add a check here to differentiate between races. Not all are sorcerers, just most - return SPELLBOOK_TYPE_SPONTANEOUS; - } - } - return SPELLBOOK_TYPE_INVALID; -} - -int GetAbilityScoreForClass(int nClass, object oPC) -{ - switch(nClass) - { - case CLASS_TYPE_BLACKGUARD: - case CLASS_TYPE_BLIGHTER: - case CLASS_TYPE_CLERIC: - case CLASS_TYPE_DRUID: - case CLASS_TYPE_FIST_OF_ZUOKEN: - case CLASS_TYPE_HEALER: - case CLASS_TYPE_JUSTICEWW: - case CLASS_TYPE_KNIGHT_CHALICE: - case CLASS_TYPE_KNIGHT_MIDDLECIRCLE: - case CLASS_TYPE_NENTYAR_HUNTER: - case CLASS_TYPE_OCULAR: - case CLASS_TYPE_PALADIN: - case CLASS_TYPE_PSYWAR: - case CLASS_TYPE_RANGER: - case CLASS_TYPE_SHAMAN: - case CLASS_TYPE_SLAYER_OF_DOMIEL: - case CLASS_TYPE_SOHEI: - case CLASS_TYPE_SOLDIER_OF_LIGHT: - case CLASS_TYPE_UR_PRIEST: - case CLASS_TYPE_VASSAL: - case CLASS_TYPE_VIGILANT: - case CLASS_TYPE_WARMIND: - return GetAbilityScore(oPC, ABILITY_WISDOM); - case CLASS_TYPE_ARCHIVIST: - case CLASS_TYPE_ASSASSIN: - case CLASS_TYPE_BEGUILER: - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: - case CLASS_TYPE_DUSKBLADE: - case CLASS_TYPE_PSION: - case CLASS_TYPE_PSYCHIC_ROGUE: - case CLASS_TYPE_SHADOWCASTER: - case CLASS_TYPE_SHADOWLORD: - case CLASS_TYPE_WIZARD: - return GetAbilityScore(oPC, ABILITY_INTELLIGENCE); - case CLASS_TYPE_BARD: - case CLASS_TYPE_CELEBRANT_SHARESS: - case CLASS_TYPE_DREAD_NECROMANCER: - case CLASS_TYPE_FAVOURED_SOUL: - case CLASS_TYPE_HARPER: - case CLASS_TYPE_HEXBLADE: - case CLASS_TYPE_KNIGHT_WEAVE: - case CLASS_TYPE_SORCERER: - case CLASS_TYPE_SUBLIME_CHORD: - case CLASS_TYPE_SUEL_ARCHANAMACH: - case CLASS_TYPE_WARMAGE: - case CLASS_TYPE_WILDER: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - //shapeshifter HD count as sorc for aranea - case CLASS_TYPE_SHAPECHANGER: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - // Multiple races - case CLASS_TYPE_MONSTROUS: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - // Gloura as Bard - case CLASS_TYPE_FEY: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - // Drider as Sorc - case CLASS_TYPE_ABERRATION: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - //outsider HD count as sorc for raks - case CLASS_TYPE_OUTSIDER: { - /// @todo Will eventually need to add a check here to differentiate between races. Not all are sorcerers, just most - return GetAbilityScore(oPC, ABILITY_CHARISMA); - } - } - return GetAbilityScore(oPC, ABILITY_CHARISMA); //default for SLAs? -} - -int GetDCAbilityModForClass(int nClass, object oPC) -{ - switch(nClass) - { - case CLASS_TYPE_BLACKGUARD: - case CLASS_TYPE_BLIGHTER: - case CLASS_TYPE_CLERIC: - case CLASS_TYPE_DRUID: - case CLASS_TYPE_FAVOURED_SOUL: - case CLASS_TYPE_FIST_OF_ZUOKEN: - case CLASS_TYPE_JUSTICEWW: - case CLASS_TYPE_KNIGHT_CHALICE: - case CLASS_TYPE_KNIGHT_MIDDLECIRCLE: - case CLASS_TYPE_OCULAR: - case CLASS_TYPE_NENTYAR_HUNTER: - case CLASS_TYPE_PALADIN: - case CLASS_TYPE_PSYWAR: - case CLASS_TYPE_RANGER: - case CLASS_TYPE_SHAMAN: - case CLASS_TYPE_SLAYER_OF_DOMIEL: - case CLASS_TYPE_SOHEI: - case CLASS_TYPE_SOLDIER_OF_LIGHT: - case CLASS_TYPE_UR_PRIEST: - case CLASS_TYPE_VASSAL: - case CLASS_TYPE_VIGILANT: - case CLASS_TYPE_WARMIND: - return GetAbilityModifier(ABILITY_WISDOM, oPC); - case CLASS_TYPE_ARCHIVIST: - case CLASS_TYPE_ASSASSIN: - case CLASS_TYPE_BEGUILER: - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: - case CLASS_TYPE_DUSKBLADE: - case CLASS_TYPE_PSION: - case CLASS_TYPE_PSYCHIC_ROGUE: - case CLASS_TYPE_SHADOWLORD: - case CLASS_TYPE_WIZARD: - return GetAbilityModifier(ABILITY_INTELLIGENCE, oPC); - case CLASS_TYPE_BARD: - case CLASS_TYPE_CELEBRANT_SHARESS: - case CLASS_TYPE_DREAD_NECROMANCER: - case CLASS_TYPE_HARPER: - case CLASS_TYPE_HEALER: - case CLASS_TYPE_HEXBLADE: - case CLASS_TYPE_SHADOWCASTER: - case CLASS_TYPE_SORCERER: - case CLASS_TYPE_SUBLIME_CHORD: - case CLASS_TYPE_SUEL_ARCHANAMACH: - case CLASS_TYPE_WARMAGE: - case CLASS_TYPE_WILDER: - return GetAbilityModifier(ABILITY_CHARISMA, oPC); - //shapechanger HD count as sorc for aranea - case CLASS_TYPE_SHAPECHANGER: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - // Multiple races - case CLASS_TYPE_MONSTROUS: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - // Gloura as Bard - case CLASS_TYPE_FEY: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - // Drider as Sorc - case CLASS_TYPE_ABERRATION: - return GetAbilityScore(oPC, ABILITY_CHARISMA); - //outsider HD count as sorc for raks - case CLASS_TYPE_OUTSIDER: { - /// @todo Will eventually need to add a check here to differentiate between races. Not all are sorcerers, just most - return GetAbilityModifier(ABILITY_CHARISMA, oPC); - } - } - return GetAbilityModifier(ABILITY_CHARISMA, oPC); //default for SLAs? -} - -string GetFileForClass(int nClass) -{ - string sFile = Get2DACache("classes", "FeatsTable", nClass); - sFile = "cls_spell" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061231 - //if(DEBUG) DoDebug("GetFileForClass(" + IntToString(nClass) + ") = " + sFile); - return sFile; -} - -int GetSpellslotLevel(int nClass, object oPC) -{ - int nLevel = GetLevelByClass(nClass, oPC); - - //Raks cast as sorcs - if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_RAKSHASA) - nLevel = GetLevelByClass(CLASS_TYPE_OUTSIDER, oPC); - else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_ARKAMOI) //Arkamoi cast as sorcs - nLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS, oPC); - else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_DRIDER) //Driders cast as sorcs - nLevel = GetLevelByClass(CLASS_TYPE_ABERRATION, oPC); - else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_REDSPAWN_ARCANISS) //Redspawn Arcaniss cast as 3/4 sorcs - nLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS, oPC)*3/4; - else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_MARRUTACT) //Marrutact cast as 6/7 sorcs - nLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS, oPC)*6/7; - else if(nClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oPC) && GetRacialType(oPC) == RACIAL_TYPE_GLOURA) //Gloura cast as bards - nLevel = GetLevelByClass(CLASS_TYPE_FEY, oPC); - else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_ARANEA) //Aranea cast as sorcs - nLevel = GetLevelByClass(CLASS_TYPE_SHAPECHANGER, oPC); - - int nArcSpellslotLevel; - int nDivSpellslotLevel; - int i; - for(i = 1; i <= 8; i++) - { - int nTempClass = GetClassByPosition(i, oPC); - //spellcasting prc - int nArcSpellMod = StringToInt(Get2DACache("classes", "ArcSpellLvlMod", nTempClass)); - int nDivSpellMod = StringToInt(Get2DACache("classes", "DivSpellLvlMod", nTempClass)); - /*//special case for combat medic class - if(nTempClass == CLASS_TYPE_COMBAT_MEDIC && (nClass == CLASS_TYPE_BARD || nClass == CLASS_TYPE_WITCH)) - nArcSpellMod = 1;*/ - - if(nArcSpellMod == 1) - nArcSpellslotLevel += GetLevelByClass(nTempClass, oPC); - else if(nArcSpellMod > 1) - nArcSpellslotLevel += (GetLevelByClass(nTempClass, oPC) + 1) / nArcSpellMod; - if(nDivSpellMod == 1) - nDivSpellslotLevel += GetLevelByClass(nTempClass, oPC); - else if(nDivSpellMod > 1) - nDivSpellslotLevel += (GetLevelByClass(nTempClass, oPC) + 1) / nDivSpellMod; - } - - if(GetPrimaryArcaneClass(oPC) == nClass) - nLevel += nArcSpellslotLevel; - if(GetPrimaryDivineClass(oPC) == nClass) - nLevel += nDivSpellslotLevel; - - // For this special instance, we know that this is the only prestige class - if (nClass == CLASS_TYPE_SORCERER && GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oPC)) - nLevel = GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oPC) + GetLevelByClass(CLASS_TYPE_SORCERER, oPC); - - if(DEBUG) DoDebug("GetSpellslotLevel(" + IntToString(nClass) + ", " + GetName(oPC) + ") = " + IntToString(nLevel)); - return nLevel; -} - -int GetItemBonusSlotCount(object oPC, int nClass, int nSpellLevel) -{ - // Value maintained by CheckPRCLimitations() - return GetLocalInt(oPC, "PRC_IPRPBonSpellSlots_" + IntToString(nClass) + "_" + IntToString(nSpellLevel)); -} - -int GetSlotCount(int nLevel, int nSpellLevel, int nAbilityScore, int nClass, object oItemPosessor = OBJECT_INVALID) -{ - // Ability score limit rule: Must have casting ability score of at least 10 + spel level to be able to cast spells of that level at all - if(nAbilityScore < nSpellLevel + 10) - return 0; - int nSlots; - string sFile; - /*// Bioware casters use their classes.2da-specified tables - if( nClass == CLASS_TYPE_WIZARD - || nClass == CLASS_TYPE_SORCERER - || nClass == CLASS_TYPE_BARD - || nClass == CLASS_TYPE_CLERIC - || nClass == CLASS_TYPE_DRUID - || nClass == CLASS_TYPE_PALADIN - || nClass == CLASS_TYPE_RANGER) - {*/ - sFile = Get2DACache("classes", "SpellGainTable", nClass); - /*} - // New spellbook casters use the cls_spbk_* tables - else - { - sFile = Get2DACache("classes", "FeatsTable", nClass); - sFile = "cls_spbk" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061231 - }*/ - - string sSlots = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1); - if(sSlots == "") - { - nSlots = -1; - //if(DEBUG) DoDebug("GetSlotCount: Problem getting slot numbers for " + IntToString(nSpellLevel) + " " + IntToString(nLevel) + " " + sFile); - } - else - nSlots = StringToInt(sSlots); - if(nSlots == -1) - return 0; - - // Add spell slots from items - if(GetIsObjectValid(oItemPosessor)) - nSlots += GetItemBonusSlotCount(oItemPosessor, nClass, nSpellLevel); - - // Add spell slots from high ability score. Level 0 spells are exempt - if(nSpellLevel == 0) - return nSlots; - else - { - int nAbilityMod = nClass == CLASS_TYPE_ARCHIVIST ? GetAbilityModifier(ABILITY_WISDOM, oItemPosessor) : (nAbilityScore - 10) / 2; - if(nAbilityMod >= nSpellLevel) // Need an ability modifier at least equal to the spell level to gain bonus slots - nSlots += ((nAbilityMod - nSpellLevel) / 4) + 1; - return nSlots; - } -} - -//if the class doesn't learn all available spells on level-up add it here -int bKnowsAllClassSpells(int nClass) -{ - switch(nClass) - { - //case CLASS_TYPE_WIZARD: - case CLASS_TYPE_ARCHIVIST: - case CLASS_TYPE_ASSASSIN: - case CLASS_TYPE_BARD: - case CLASS_TYPE_CELEBRANT_SHARESS: - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: - case CLASS_TYPE_DUSKBLADE: - case CLASS_TYPE_FAVOURED_SOUL: - case CLASS_TYPE_HEXBLADE: - case CLASS_TYPE_JUSTICEWW: - case CLASS_TYPE_KNIGHT_WEAVE: - case CLASS_TYPE_SORCERER: - case CLASS_TYPE_SUBLIME_CHORD: - case CLASS_TYPE_SUEL_ARCHANAMACH: - return FALSE; - - // Everyone else - default: - return TRUE; - } - return TRUE; -} - -int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC) -{ - // If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either - /// @todo Check rules. There might be cases where this doesn't hold - if(!GetSlotCount(nLevel, nSpellLevel, GetAbilityScoreForClass(nClass, oPC), nClass)) - return 0; - int nKnown; - string sFile; - // Bioware casters use their classes.2da-specified tables - /*if( nClass == CLASS_TYPE_WIZARD - || nClass == CLASS_TYPE_SORCERER - || nClass == CLASS_TYPE_BARD - || nClass == CLASS_TYPE_CLERIC - || nClass == CLASS_TYPE_DRUID - || nClass == CLASS_TYPE_PALADIN - || nClass == CLASS_TYPE_RANGER) - {*/ - sFile = Get2DACache("classes", "SpellKnownTable", nClass); - /*} - else - { - sFile = Get2DACache("classes", "FeatsTable", nClass); - sFile = "cls_spkn" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061231 - }*/ - - string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1); - if(DEBUG) DoDebug("GetSpellKnownMaxCount(" + IntToString(nLevel) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ", " + GetName(oPC) + ") = " + sKnown); - if(sKnown == "") - { - nKnown = -1; - //if(DEBUG) DoDebug("GetSpellKnownMaxCount: Problem getting known numbers for " + IntToString(nSpellLevel) + " " + IntToString(nLevel) + " " + sFile); - } - else - nKnown = StringToInt(sKnown); - if(nKnown == -1) - return 0; - - // Bard and Sorcerer only have new spellbook spells known if they have taken prestige classes that increase spellcasting - if(nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_BARD) - { - if((GetLevelByClass(nClass) == nLevel) //no PrC - && !(GetHasFeat(FEAT_DRACONIC_GRACE, oPC) || GetHasFeat(FEAT_DRACONIC_BREATH, oPC))) //no Draconic feats that apply - return 0; - } - return nKnown; -} - -int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass) -{ - // Check short-term cache - string sClassNum = IntToString(nClass); - if(GetLocalInt(oPC, "GetSKCCCache_" + IntToString(nSpellLevel) + "_" + sClassNum)) - return GetLocalInt(oPC, "GetSKCCCache_" + IntToString(nSpellLevel) + "_" + sClassNum) - 1; - - // Loop over all spells known and count the number of spells of each level known - int i; - int nKnown; - int nKnown0, nKnown1, nKnown2, nKnown3, nKnown4; - int nKnown5, nKnown6, nKnown7, nKnown8, nKnown9; - string sFile = GetFileForClass(nClass); - for(i = 0; i < persistant_array_get_size(oPC, "Spellbook" + sClassNum); i++) - { - int nNewSpellbookID = persistant_array_get_int(oPC, "Spellbook" + sClassNum, i); - int nLevel = StringToInt(Get2DACache(sFile, "Level", nNewSpellbookID)); - switch(nLevel) - { - case 0: nKnown0++; break; case 1: nKnown1++; break; - case 2: nKnown2++; break; case 3: nKnown3++; break; - case 4: nKnown4++; break; case 5: nKnown5++; break; - case 6: nKnown6++; break; case 7: nKnown7++; break; - case 8: nKnown8++; break; case 9: nKnown9++; break; - } - } - - // Pick the level requested for returning - switch(nSpellLevel) - { - case 0: nKnown = nKnown0; break; case 1: nKnown = nKnown1; break; - case 2: nKnown = nKnown2; break; case 3: nKnown = nKnown3; break; - case 4: nKnown = nKnown4; break; case 5: nKnown = nKnown5; break; - case 6: nKnown = nKnown6; break; case 7: nKnown = nKnown7; break; - case 8: nKnown = nKnown8; break; case 9: nKnown = nKnown9; break; - } - if(DEBUG) DoDebug("GetSpellKnownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + sClassNum + ") = " + IntToString(nKnown)); - if(DEBUG) DoDebug("GetSpellKnownCurrentCount(i " + IntToString(i) + ", nKnown0 " + IntToString(nKnown0) + ", nKnown1 " + IntToString(nKnown1) + ", nKnown2 " + IntToString(nKnown2) + ", nKnown3 " + IntToString(nKnown3) + ", nKnown4 " + IntToString(nKnown4) + ", nKnown5 " + IntToString(nKnown5) + ", nKnown6 " + IntToString(nKnown6) + ", nKnown7 " + IntToString(nKnown7) + ", nKnown8 " + IntToString(nKnown8) + ", nKnown9 " + IntToString(nKnown9)); - if(DEBUG) DoDebug("GetSpellKnownCurrentCount(persistant_array_get_size "+IntToString(persistant_array_get_size(oPC, "Spellbook" + sClassNum))); - - // Cache the values for 1 second - SetLocalInt(oPC, "GetSKCCCache_0_" + sClassNum, nKnown0 + 1); - SetLocalInt(oPC, "GetSKCCCache_1_" + sClassNum, nKnown1 + 1); - SetLocalInt(oPC, "GetSKCCCache_2_" + sClassNum, nKnown2 + 1); - SetLocalInt(oPC, "GetSKCCCache_3_" + sClassNum, nKnown3 + 1); - SetLocalInt(oPC, "GetSKCCCache_4_" + sClassNum, nKnown4 + 1); - SetLocalInt(oPC, "GetSKCCCache_5_" + sClassNum, nKnown5 + 1); - SetLocalInt(oPC, "GetSKCCCache_6_" + sClassNum, nKnown6 + 1); - SetLocalInt(oPC, "GetSKCCCache_7_" + sClassNum, nKnown7 + 1); - SetLocalInt(oPC, "GetSKCCCache_8_" + sClassNum, nKnown8 + 1); - SetLocalInt(oPC, "GetSKCCCache_9_" + sClassNum, nKnown9 + 1); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_0_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_1_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_2_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_3_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_4_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_5_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_6_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_7_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_8_" + sClassNum)); - DelayCommand(1.0, DeleteLocalInt(oPC, "GetSKCCCache_9_" + sClassNum)); - - return nKnown; -} - -int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass) -{ - // Get the lookup token created by MakeSpellbookLevelLoop() - string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel); - object oCache = GetObjectByTag(sTag); - if(!GetIsObjectValid(oCache)) - { - if(DEBUG) DoDebug("GetSpellUnknownCurrentCount: " + sTag + " is not valid"); - return 0; - } - // Read the total number of spells on the given level and determine how many are already known - int nTotal = array_get_size(oCache, "Lkup"); - int nKnown = GetSpellKnownCurrentCount(oPC, nSpellLevel, nClass); - int nUnknown = nTotal - nKnown; - - if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown)); - return nUnknown; -} - -void AddSpellUse(object oPC, int nSpellbookID, int nClass, string sFile, string sArrayName, int nSpellbookType, object oSkin, int nFeatID, int nIPFeatID, string sIDX = "") -{ - /* - string sFile = GetFileForClass(nClass); - string sArrayName = "NewSpellbookMem_"+IntToString(nClass); - int nSpellbookType = GetSpellbookTypeForClass(nClass); - object oSkin = GetPCSkin(oPC); - int nFeatID = StringToInt(Get2DACache(sFile, "FeatID", nSpellbookID)); - //add the feat only if they dont already have it - int nIPFeatID = StringToInt(Get2DACache(sFile, "IPFeatID", nSpellbookID)); - */ - object oToken = GetHideToken(oPC); - - // Add the spell use feats and set a marker local that tells for CheckAndRemoveFeat() to skip removing this feat - string sIPFeatID = IntToString(nIPFeatID); - SetLocalInt(oSkin, "NewSpellbookTemp_" + sIPFeatID, TRUE); - AddSkinFeat(nFeatID, nIPFeatID, oSkin, oPC); - - // Increase the current number of uses - if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) - { - //sanity test - if(!persistant_array_exists(oPC, sArrayName)) - { - if(DEBUG) DoDebug("ERROR: AddSpellUse: " + sArrayName + " array does not exist, creating"); - persistant_array_create(oPC, sArrayName); - } - - int nUses = persistant_array_get_int(oPC, sArrayName, nSpellbookID); - nUses++; - persistant_array_set_int(oPC, sArrayName, nSpellbookID, nUses); - if(DEBUG) DoDebug("AddSpellUse: " + sArrayName + "[" + IntToString(nSpellbookID) + "] = " + IntToString(array_get_int(oPC, sArrayName, nSpellbookID))); - - //Create index array - to avoid duplicates mark only 1st use of nSpellbookID - if(nUses == 1) - { - if(!persistant_array_exists(oPC, sIDX)) - persistant_array_create(oPC, sIDX); - - persistant_array_set_int(oPC, sIDX, array_get_size(oPC, sIDX), nSpellbookID); - } - } - else if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) - { - //sanity test - if(!persistant_array_exists(oPC, sArrayName)) - { - if(DEBUG) DoDebug("ERROR: AddSpellUse: " + sArrayName + " array does not exist, creating"); - persistant_array_create(oPC, sArrayName); - } - /*int nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookID)); - int nCount = persistant_array_get_int(oPC, sArrayName, nSpellLevel); - if(nCount < 1) - { - int nLevel = GetSpellslotLevel(nClass, oPC); - int nAbility = GetAbilityScoreForClass(nClass, oPC); - nCount = GetSlotCount(nLevel, nSpellLevel, nAbility, nClass, oPC); - array_set_int(oPC, sArrayName, nSpellLevel, nCount); - }*/ - if(DEBUG) DoDebug("AddSpellUse() called on spontaneous spellbook. nIPFeatID = " + sIPFeatID); - } -} - -void RemoveSpellUse(object oPC, int nSpellID, int nClass) -{ - string sFile = GetFileForClass(nClass); - int nSpellbookID = SpellToSpellbookID(nSpellID); - if(nSpellbookID == -1) - { - if(DEBUG) DoDebug("ERROR: RemoveSpellUse: Unable to resolve spell to spellbookID: " + IntToString(nSpellID) + " in file " + sFile); - return; - } - if(!persistant_array_exists(oPC, "NewSpellbookMem_"+IntToString(nClass))) - { - if(DEBUG) DoDebug("RemoveSpellUse: NewSpellbookMem_" + IntToString(nClass) + " does not exist, creating."); - persistant_array_create(oPC, "NewSpellbookMem_"+IntToString(nClass)); - } - - // Reduce the remaining uses of the given spell by 1 (except never reduce uses below 0). - // Spontaneous spellbooks reduce the number of spells of the spell's level remaining - int nSpellbookType = GetSpellbookTypeForClass(nClass); - if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) - { - int nCount = persistant_array_get_int(oPC, "NewSpellbookMem_" + IntToString(nClass), nSpellbookID); - if(nCount > 0) - persistant_array_set_int(oPC, "NewSpellbookMem_" + IntToString(nClass), nSpellbookID, nCount - 1); - } - else if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) - { - int nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookID)); - int nCount = persistant_array_get_int(oPC, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel); - if(nCount > 0) - persistant_array_set_int(oPC, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel, nCount - 1); - } -} - -int GetSpellLevel(int nSpellID, int nClass) -{ - string sFile = GetFileForClass(nClass); - int nSpellbookID = SpellToSpellbookID(nSpellID); - if(nSpellbookID == -1) - { - if(DEBUG) DoDebug("ERROR: GetSpellLevel: Unable to resolve spell to spellbookID: "+IntToString(nSpellID)+" "+sFile); - return -1; - } - - // get spell level - int nSpellLevel = -1; - string sSpellLevel = Get2DACache(sFile, "Level", nSpellbookID); - - if (sSpellLevel != "") - nSpellLevel = StringToInt(sSpellLevel); - - return nSpellLevel; -} - -//called inside for loop in SetupSpells(), delayed to prevent TMI -void SpontaneousSpellSetupLoop(object oPC, int nClass, string sFile, object oSkin, int i) -{ - int nSpellbookID = persistant_array_get_int(oPC, "Spellbook" + IntToString(nClass), i); - string sIPFeatID = Get2DACache(sFile, "IPFeatID", nSpellbookID); - int nIPFeatID = StringToInt(sIPFeatID); - int nFeatID = StringToInt(Get2DACache(sFile, "FeatID", nSpellbookID)); - //int nRealSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", nSpellbookID)); - SetLocalInt(oSkin, "NewSpellbookTemp_" + sIPFeatID, TRUE); - - AddSkinFeat(nFeatID, nIPFeatID, oSkin, oPC); -} - -void SetupSpells(object oPC, int nClass) -{ - string sFile = GetFileForClass(nClass); - string sClass = IntToString(nClass); - string sArrayName = "NewSpellbookMem_" + sClass; - object oSkin = GetPCSkin(oPC); - int nLevel = GetSpellslotLevel(nClass, oPC); - int nAbility = GetAbilityScoreForClass(nClass, oPC); - int nSpellbookType = GetSpellbookTypeForClass(nClass); - - if(DEBUG) DoDebug("SetupSpells\n" - + "nClass = " + IntToString(nClass) + "\n" - + "nSpellslotLevel = " + IntToString(nLevel) + "\n" - + "nAbility = " + IntToString(nAbility) + "\n" - + "nSpellbookType = " + IntToString(nSpellbookType) + "\n" - + "sFile = " + sFile + "\n" - ); - - // For spontaneous spellbooks, set up an array that tells how many spells of each level they can cast - // And add casting feats for each spell known to the caster's hide - - if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) - { - // Spell slots - int nSpellLevel, nSlots; - for(nSpellLevel = 0; nSpellLevel <= 9; nSpellLevel++) - { - nSlots = GetSlotCount(nLevel, nSpellLevel, nAbility, nClass, oPC); - persistant_array_set_int(oPC, sArrayName, nSpellLevel, nSlots); - } - - int i; - for(i = 0; i < persistant_array_get_size(oPC, "Spellbook" + sClass); i++) - { //adding feats - SpontaneousSpellSetupLoop(oPC, nClass, sFile, oSkin, i); - } - }// end if - Spontaneous spellbook - - // For prepared spellbooks, add spell uses and use feats according to spells memorised list - else if(nSpellbookType == SPELLBOOK_TYPE_PREPARED && !GetIsBioSpellCastClass(nClass)) - { - int nSpellLevel, nSlot, nSlots, nSpellbookID; - string sArrayName2, sIDX; - for(nSpellLevel = 0; nSpellLevel <= 9; nSpellLevel++) - { - sArrayName2 = "Spellbook" + IntToString(nSpellLevel) + "_" + sClass; // Minor optimisation: cache the array name string for multiple uses - sIDX = "SpellbookIDX" + IntToString(nSpellLevel) + "_" + sClass; - nSlots = GetSlotCount(nLevel, nSpellLevel, nAbility, nClass, oPC); - nSlot; - for(nSlot = 0; nSlot < nSlots; nSlot++) - { - //done when spells are added to it - nSpellbookID = persistant_array_get_int(oPC, sArrayName2, nSlot); - if(nSpellbookID != 0) - { - AddSpellUse(oPC, nSpellbookID, nClass, sFile, sArrayName, nSpellbookType, oSkin, - StringToInt(Get2DACache(sFile, "FeatID", nSpellbookID)), - StringToInt(Get2DACache(sFile, "IPFeatID", nSpellbookID)), - sIDX); - } - } - } - } -} - -void CheckAndRemoveFeat(object oHide, itemproperty ipFeat) -{ - int nSubType = GetItemPropertySubType(ipFeat); - if(!GetLocalInt(oHide, "NewSpellbookTemp_" + IntToString(nSubType))) - { - RemoveItemProperty(oHide, ipFeat); - DeleteLocalInt(oHide, "NewSpellbookTemp_" + IntToString(nSubType)); - if(DEBUG) DoDebug("CheckAndRemoveFeat: DeleteLocalInt(oHide, NewSpellbookTemp_" + IntToString(nSubType) + ");"); - if(DEBUG) DoDebug("CheckAndRemoveFeat: Removing item property"); - } - else - { - DeleteLocalInt(oHide, "NewSpellbookTemp_" + IntToString(nSubType)); - if(DEBUG) DoDebug("CheckAndRemoveFeat: DeleteLocalInt(oHide, NewSpellbookTemp_" + IntToString(nSubType) + ");"); - } -} - -void WipeSpellbookHideFeats(object oPC) -{ - object oHide = GetPCSkin(oPC); - itemproperty ipTest = GetFirstItemProperty(oHide); - while(GetIsItemPropertyValid(ipTest)) - { - int nSubType = GetItemPropertySubType(ipTest); - if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_BONUS_FEAT && - ((nSubType > SPELLBOOK_IPRP_FEATS_START && nSubType < SPELLBOOK_IPRP_FEATS_END) || - (nSubType > SPELLBOOK_IPRP_FEATS_START2 && nSubType < SPELLBOOK_IPRP_FEATS_END2)) - ) - { - DelayCommand(1.0f, CheckAndRemoveFeat(oHide, ipTest)); - } - ipTest = GetNextItemProperty(oHide); - } -} - -void CheckNewSpellbooks(object oPC) -{ - WipeSpellbookHideFeats(oPC); - int i; - for(i = 1; i <= 8; i++) - { - int nClass = GetClassByPosition(i, oPC); - int nLevel = GetLevelByClass(nClass, oPC); - - if(DEBUG) DoDebug("CheckNewSpellbooks\n" - + "nClass = " + IntToString(nClass) + "\n" - + "nLevel = " + IntToString(nLevel) + "\n" - ); - //if bard/sorc newspellbook is disabled after selecting - //remove those from radial - if( (GetPRCSwitch(PRC_BARD_DISALLOW_NEWSPELLBOOK) && nClass == CLASS_TYPE_BARD) - ||(GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK) && nClass == CLASS_TYPE_SORCERER)) - { - //do nothing - } - else if(nLevel) - { - //Aranea cast as sorcs - if(nClass == CLASS_TYPE_SHAPECHANGER - && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_ARANEA) - nClass = CLASS_TYPE_SORCERER; - //raks cast as sorcs - if(nClass == CLASS_TYPE_OUTSIDER - && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_RAKSHASA) - nClass = CLASS_TYPE_SORCERER; - - //Arkamoi cast as sorcs - if(nClass == CLASS_TYPE_MONSTROUS - && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_ARKAMOI) - nClass = CLASS_TYPE_SORCERER; - - //Redspawn cast as sorcs - if(nClass == CLASS_TYPE_MONSTROUS - && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_REDSPAWN_ARCANISS) - nClass = CLASS_TYPE_SORCERER; - - //Marrutact cast as sorcs - if(nClass == CLASS_TYPE_MONSTROUS - && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_MARRUTACT) - nClass = CLASS_TYPE_SORCERER; - - //Driders cast as sorcs - if(nClass == CLASS_TYPE_ABERRATION - && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_DRIDER) - nClass = CLASS_TYPE_SORCERER; - - //Gloura cast as bards - if(nClass == CLASS_TYPE_FEY - && !GetLevelByClass(CLASS_TYPE_BARD, oPC) - && GetRacialType(oPC) == RACIAL_TYPE_GLOURA) - nClass = CLASS_TYPE_BARD; - //remove persistant locals used to track when all spells cast - string sArrayName = "NewSpellbookMem_"+IntToString(nClass); - if(persistant_array_exists(oPC, sArrayName)) - { - if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) - { - int nSpellLevel, i, Max; - string sIDX, sSpellbookID, sClass = IntToString(nClass); - for(nSpellLevel = 0; nSpellLevel <= 9; nSpellLevel++) - { - sIDX = "SpellbookIDX" + IntToString(nSpellLevel) + "_" + sClass; - Max = persistant_array_get_size(oPC, sIDX); - for(i = 0; i < Max; i++) - { - sSpellbookID = persistant_array_get_string(oPC, sIDX, i); - if(sSpellbookID != "") - { - DeletePersistantLocalString(oPC, sArrayName+"_"+sSpellbookID); - } - } - persistant_array_delete(oPC, sIDX); - } - } - else - { - persistant_array_delete(oPC, sArrayName); - persistant_array_create(oPC, sArrayName); - } - } - //delay it so wipespellbookhidefeats has time to start to run - //but before the deletes actually happen - DelayCommand(0.1, SetupSpells(oPC, nClass)); - } - } -} - -//NewSpellbookSpell() helper functions -int bTargetingAllowed(int nSpellID); -void CheckPrepSlots(int nClass, int nSpellID, int nSpellbookID, int bIsAction = FALSE); -void CheckSpontSlots(int nClass, int nSpellID, int nSpellSlotLevel, int bIsAction = FALSE); -void DoCleanUp(int nMetamagic); - -void CastSpontaneousSpell(int nClass, int bInstantSpell = FALSE) -{ - //get the spellbook ID - int nFakeSpellID = GetSpellId(); - int nSpellID = GetPowerFromSpellID(nFakeSpellID); - if(nSpellID == -1) nSpellID = 0; - - //Check the target first - if(!bTargetingAllowed(nSpellID)) - return; - - // if OBJECT_SELF is fighting - stop fighting and cast spell - if(GetCurrentAction() == ACTION_ATTACKOBJECT) - ClearAllActions(); - - //if its a subradial spell, get the master - int nMasterFakeSpellID = StringToInt(Get2DACache("spells", "Master", nFakeSpellID)); - if(!nMasterFakeSpellID) - nMasterFakeSpellID = nFakeSpellID; - - int nSpellbookID = SpellToSpellbookID(nMasterFakeSpellID); - - // Paranoia - It should not be possible to get here without having the spells available array existing - if(!persistant_array_exists(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass))) - { - if(DEBUG) DoDebug("ERROR: NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + " array does not exist"); - persistant_array_create(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass)); - } - - int nSpellLevel = StringToInt(Get2DACache(GetFileForClass(nClass), "Level", nSpellbookID)); - - // Make sure the caster has uses of this spell remaining - // 2009-9-20: Add metamagic feat abilities. -N-S - int nMetamagic = GetLocalInt(OBJECT_SELF, "MetamagicFeatAdjust"); - if(nMetamagic) - { - //Need to check if metamagic can be applied to a spell - int nMetaTest; - int nMetaType = HexToInt(Get2DACache("spells", "MetaMagic", nSpellID)); - - int nSpellSlotLevel = nSpellLevel; - switch(nMetamagic) - { - case METAMAGIC_NONE: nMetaTest = 1; break; //no need to change anything - case METAMAGIC_EMPOWER: nMetaTest = nMetaType & 1; nSpellLevel += 2; break; - case METAMAGIC_EXTEND: nMetaTest = nMetaType & 2; nSpellLevel += 1; break; - case METAMAGIC_MAXIMIZE: nMetaTest = nMetaType & 4; nSpellLevel += 3; break; - case METAMAGIC_QUICKEN: nMetaTest = nMetaType & 8; nSpellLevel += 4; break; - case METAMAGIC_SILENT: nMetaTest = nMetaType & 16; nSpellLevel += 1; break; - case METAMAGIC_STILL: nMetaTest = nMetaType & 32; nSpellLevel += 1; break; - } - - if(!nMetaTest)//can't use selected metamagic with this spell - { - nMetamagic = METAMAGIC_NONE; - ActionDoCommand(SendMessageToPC(OBJECT_SELF, "You can't use "+GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)))+"with selected metamagic.")); - nSpellLevel = nSpellSlotLevel; - } - else if(nSpellLevel > 9)//now test the spell level - { - nMetamagic = METAMAGIC_NONE; - ActionDoCommand(SendMessageToPC(OBJECT_SELF, "Modified spell level is to high! Casting spell without metamagic")); - nSpellLevel = nSpellSlotLevel; - } - else if(GetLocalInt(OBJECT_SELF, "PRC_metamagic_state") == 1) - SetLocalInt(OBJECT_SELF, "MetamagicFeatAdjust", 0); - } - - CheckSpontSlots(nClass, nSpellID, nSpellLevel); - if(GetLocalInt(OBJECT_SELF, "NSB_Cast")) - ActionDoCommand(CheckSpontSlots(nClass, nSpellID, nSpellLevel, TRUE)); - else - return; - - // Calculate DC. 10 + spell level on the casting class's list + DC increasing ability mod - //int nDC = 10 + nSpellLevel + GetDCAbilityModForClass(nClass, OBJECT_SELF); - // This is wrong and is breaking things, and is already calculated in the function it calls anyway - Strat - - //remove any old effects - //seems cheat-casting breaks hardcoded removal - //and cant remove effects because I dont know all the targets! - if(!bInstantSpell) - { - //Handle quicken metamagic and Duskblade's Quick Cast - if((nMetamagic & METAMAGIC_QUICKEN) || GetLocalInt(OBJECT_SELF, "QuickCast")) - { - //Adding Auto-Quicken III - deleted after casting has finished. - object oSkin = GetPCSkin(OBJECT_SELF); - int nCastDur = StringToInt(Get2DACache("spells", "ConjTime", nSpellID)) + StringToInt(Get2DACache("spells", "CastTime", nSpellID)); - itemproperty ipAutoQuicken = ItemPropertyBonusFeat(IP_CONST_NSB_AUTO_QUICKEN); - ActionDoCommand(AddItemProperty(DURATION_TYPE_TEMPORARY, ipAutoQuicken, oSkin, nCastDur/1000.0f)); - DeleteLocalInt(OBJECT_SELF, "QuickCast"); - } - } - - //cast the spell - //dont need to override level, the spellscript will calculate it - //class is read from "NSB_Class" - ActionCastSpell(nSpellID, 0, -1, 0, nMetamagic, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, bInstantSpell); - - //Clean up - ActionDoCommand(DoCleanUp(nMetamagic)); -} - -void CastPreparedSpell(int nClass, int nMetamagic = METAMAGIC_NONE, int bInstantSpell = FALSE) -{ - object oPC = OBJECT_SELF; - - //get the spellbook ID - int nFakeSpellID = GetSpellId(); - int nSpellID = GetPowerFromSpellID(nFakeSpellID); - if(nSpellID == -1) nSpellID = 0; - - //Check the target first - if(!bTargetingAllowed(nSpellID)) - return; - - // if OBJECT_SELF is fighting - stop fighting and cast spell - if(GetCurrentAction() == ACTION_ATTACKOBJECT) - ClearAllActions(); - - //if its a subradial spell, get the master - int nMasterFakeSpellID = StringToInt(Get2DACache("spells", "Master", nFakeSpellID)); - if(!nMasterFakeSpellID) - nMasterFakeSpellID = nFakeSpellID; - - int nSpellbookID = SpellToSpellbookID(nMasterFakeSpellID); - - // Paranoia - It should not be possible to get here without having the spells available array existing - if(!persistant_array_exists(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass))) - { - if(DEBUG) DoDebug("ERROR: NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + " array does not exist"); - persistant_array_create(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass)); - } - - int nSpellLevel = StringToInt(Get2DACache(GetFileForClass(nClass), "Level", nSpellbookID)); - - // Make sure the caster has uses of this spell remaining - CheckPrepSlots(nClass, nSpellID, nSpellbookID); - if(GetLocalInt(OBJECT_SELF, "NSB_Cast")) - ActionDoCommand(CheckPrepSlots(nClass, nSpellID, nSpellbookID, TRUE)); - else - return; - - // Calculate DC. 10 + spell level on the casting class's list + DC increasing ability mod - //int nDC = 10 + nSpellLevel + GetDCAbilityModForClass(nClass, OBJECT_SELF); - // This is wrong and is breaking things, and is already calculated in the function it calls anyway - Strat - - //remove any old effects - //seems cheat-casting breaks hardcoded removal - //and cant remove effects because I dont know all the targets! - if(!bInstantSpell) - { - //Handle quicken metamagic and Duskblade's Quick Cast - if((nMetamagic & METAMAGIC_QUICKEN) || GetLocalInt(OBJECT_SELF, "QuickCast")) - { - //Adding Auto-Quicken III - deleted after casting has finished. - object oSkin = GetPCSkin(OBJECT_SELF); - int nCastDur = StringToInt(Get2DACache("spells", "ConjTime", nSpellID)) + StringToInt(Get2DACache("spells", "CastTime", nSpellID)); - itemproperty ipAutoQuicken = ItemPropertyBonusFeat(IP_CONST_NSB_AUTO_QUICKEN); - ActionDoCommand(AddItemProperty(DURATION_TYPE_TEMPORARY, ipAutoQuicken, oSkin, nCastDur/1000.0f)); - DeleteLocalInt(OBJECT_SELF, "QuickCast"); - } - else if(nClass == CLASS_TYPE_HEALER) - { - if(GetHasFeat(FEAT_EFFORTLESS_HEALING) - && GetIsOfSubschool(nSpellID, SUBSCHOOL_HEALING)) - { - object oSkin = GetPCSkin(OBJECT_SELF); - //all spells from healing subschool except Close Wounds have casting time of 2.5s - float fCastDur = nSpellID == SPELL_CLOSE_WOUNDS ? 1.0f : 2.5f; - itemproperty ipImpCombatCast = ItemPropertyBonusFeat(IP_CONST_NSB_IMP_COMBAT_CAST); - ActionDoCommand(AddItemProperty(DURATION_TYPE_TEMPORARY, ipImpCombatCast, oSkin, fCastDur)); - } - } - } - - //cast the spell - //dont need to override level, the spellscript will calculate it - //class is read from "NSB_Class" - ActionCastSpell(nSpellID, 0, -1, 0, nMetamagic, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, bInstantSpell); - - //Clean up - ActionDoCommand(DoCleanUp(nMetamagic)); -} - -void NewSpellbookSpell(int nClass, int nSpellbookType, int nMetamagic = METAMAGIC_NONE, int bInstantSpell = FALSE) -{ - object oPC = OBJECT_SELF; - - // if oPC is fighting - stop fighting and cast spell - if(GetCurrentAction(oPC) == ACTION_ATTACKOBJECT) - ClearAllActions(); - - //get the spellbook ID - int nFakeSpellID = GetSpellId(); - int nSpellID = GetPowerFromSpellID(nFakeSpellID); - if(nSpellID == -1) nSpellID = 0; - - //Check the target first - if(!bTargetingAllowed(nSpellID)) - return; - - //if its a subradial spell, get the master - int nMasterFakeSpellID = StringToInt(Get2DACache("spells", "Master", nFakeSpellID)); - if(!nMasterFakeSpellID) - nMasterFakeSpellID = nFakeSpellID; - - int nSpellbookID = SpellToSpellbookID(nMasterFakeSpellID); - - // Paranoia - It should not be possible to get here without having the spells available array existing - if(!persistant_array_exists(oPC, "NewSpellbookMem_" + IntToString(nClass))) - { - if(DEBUG) DoDebug("ERROR: NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + " array does not exist"); - persistant_array_create(oPC, "NewSpellbookMem_" + IntToString(nClass)); - } - - string sFile = GetFileForClass(nClass); - int nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookID)); - - // Make sure the caster has uses of this spell remaining - // 2009-9-20: Add metamagic feat abilities. -N-S - if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) - { - CheckPrepSlots(nClass, nSpellID, nSpellbookID); - if(GetLocalInt(oPC, "NSB_Cast")) - ActionDoCommand(CheckPrepSlots(nClass, nSpellID, nSpellbookID, TRUE)); - else - return; - } - else if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) - { - nMetamagic = GetLocalInt(oPC, "MetamagicFeatAdjust"); - if(nMetamagic) - { - //Need to check if metamagic can be applied to a spell - int nMetaTest; - int nMetaType = HexToInt(Get2DACache("spells", "MetaMagic", nSpellID)); - - int nSpellSlotLevel = nSpellLevel; - switch(nMetamagic) - { - case METAMAGIC_NONE: nMetaTest = 1; break; //no need to change anything - case METAMAGIC_EMPOWER: nMetaTest = nMetaType & 1; nSpellLevel += 2; break; - case METAMAGIC_EXTEND: nMetaTest = nMetaType & 2; nSpellLevel += 1; break; - case METAMAGIC_MAXIMIZE: nMetaTest = nMetaType & 4; nSpellLevel += 3; break; - case METAMAGIC_QUICKEN: nMetaTest = nMetaType & 8; nSpellLevel += 4; break; - case METAMAGIC_SILENT: nMetaTest = nMetaType & 16; nSpellLevel += 1; break; - case METAMAGIC_STILL: nMetaTest = nMetaType & 32; nSpellLevel += 1; break; - } - - if(!nMetaTest)//can't use selected metamagic with this spell - { - nMetamagic = METAMAGIC_NONE; - ActionDoCommand(SendMessageToPC(oPC, "You can't use "+GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)))+"with selected metamagic.")); - nSpellLevel = nSpellSlotLevel; - } - else if(nSpellLevel > 9)//now test the spell level - { - nMetamagic = METAMAGIC_NONE; - ActionDoCommand(SendMessageToPC(oPC, "Modified spell level is to high! Casting spell without metamagic")); - nSpellLevel = nSpellSlotLevel; - } - else if(GetLocalInt(oPC, "PRC_metamagic_state") == 1) - SetLocalInt(oPC, "MetamagicFeatAdjust", 0); - } - - CheckSpontSlots(nClass, nSpellID, nSpellLevel); - if(GetLocalInt(oPC, "NSB_Cast")) - ActionDoCommand(CheckSpontSlots(nClass, nSpellID, nSpellLevel, TRUE)); - else - return; - } - - // Calculate DC. 10 + spell level on the casting class's list + DC increasing ability mod - //int nDC = 10 + nSpellLevel + GetDCAbilityModForClass(nClass, OBJECT_SELF); - // This is wrong and is breaking things, and is already calculated in the function it calls anyway - Strat - - //remove any old effects - //seems cheat-casting breaks hardcoded removal - //and cant remove effects because I dont know all the targets! - if(!bInstantSpell) - { - //Handle quicken metamagic and Duskblade's Quick Cast - if((nMetamagic & METAMAGIC_QUICKEN) || GetLocalInt(oPC, "QuickCast")) - { - //Adding Auto-Quicken III - deleted after casting has finished. - object oSkin = GetPCSkin(oPC); - int nCastDur = StringToInt(Get2DACache("spells", "ConjTime", nSpellID)) + StringToInt(Get2DACache("spells", "CastTime", nSpellID)); - itemproperty ipAutoQuicken = ItemPropertyBonusFeat(IP_CONST_NSB_AUTO_QUICKEN); - ActionDoCommand(AddItemProperty(DURATION_TYPE_TEMPORARY, ipAutoQuicken, oSkin, nCastDur/1000.0f)); - DeleteLocalInt(oPC, "QuickCast"); - } - else if(nClass == CLASS_TYPE_HEALER) - { - if(GetHasFeat(FEAT_EFFORTLESS_HEALING) - && GetIsOfSubschool(nSpellID, SUBSCHOOL_HEALING)) - { - object oSkin = GetPCSkin(oPC); - //all spells from healing subschool except Close Wounds have casting time of 2.5s - float fCastDur = nSpellID == SPELL_CLOSE_WOUNDS ? 1.0f : 2.5f; - itemproperty ipImpCombatCast = ItemPropertyBonusFeat(IP_CONST_NSB_IMP_COMBAT_CAST); - ActionDoCommand(AddItemProperty(DURATION_TYPE_TEMPORARY, ipImpCombatCast, oSkin, fCastDur)); - } - } - } - - //cast the spell - //dont need to override level, the spellscript will calculate it - //class is read from "NSB_Class" - ActionCastSpell(nSpellID, 0, -1, 0, nMetamagic, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, bInstantSpell); - - //Clean up - ActionDoCommand(DoCleanUp(nMetamagic)); -} - -int bTargetingAllowed(int nSpellID) -{ - object oTarget = GetSpellTargetObject(); - if(GetIsObjectValid(oTarget)) - { - int nTargetType = ~(HexToInt(Get2DACache("spells", "TargetType", nSpellID))); - - //test targetting self - if(oTarget == OBJECT_SELF) - { - if(nTargetType & 1) - { - if(DEBUG) DoDebug("bTargetingAllowed: You cannot target yourself."); - return FALSE; - } - } - //test targetting others - else if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE) - { - if(nTargetType & 2) - { - if(DEBUG) DoDebug("bTargetingAllowed: You cannot target creatures."); - return FALSE; - } - } - } - return TRUE; -} - -void CheckPrepSlots(int nClass, int nSpellID, int nSpellbookID, int bIsAction = FALSE) -{ - DeleteLocalInt(OBJECT_SELF, "NSB_Cast"); - int nCount = persistant_array_get_int(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass), nSpellbookID); - if(DEBUG) DoDebug("NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(nSpellbookID) + "] = " + IntToString(nCount)); - if(nCount < 1) - { - string sSpellName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); - // "You have no castings of " + sSpellName + " remaining" - string sMessage = ReplaceChars(GetStringByStrRef(16828411), "", sSpellName); - - FloatingTextStringOnCreature(sMessage, OBJECT_SELF, FALSE); - if(bIsAction) - ClearAllActions(); - } - else - { - SetLocalInt(OBJECT_SELF, "NSB_Cast", 1); - if(bIsAction) - { - SetLocalInt(OBJECT_SELF, "NSB_Class", nClass); - SetLocalInt(OBJECT_SELF, "NSB_SpellbookID", nSpellbookID); - } - } -} - -void CheckSpontSlots(int nClass, int nSpellID, int nSpellSlotLevel, int bIsAction = FALSE) -{ - DeleteLocalInt(OBJECT_SELF, "NSB_Cast"); - int nCount = persistant_array_get_int(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass), nSpellSlotLevel); - if(DEBUG) DoDebug("NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(nSpellSlotLevel) + "] = " + IntToString(nCount)); - if(nCount < 1) - { - // "You have no castings of spells of level " + IntToString(nSpellLevel) + " remaining" - string sMessage = ReplaceChars(GetStringByStrRef(16828409), "", IntToString(nSpellSlotLevel)); - FloatingTextStringOnCreature(sMessage, OBJECT_SELF, FALSE); - if(bIsAction) - ClearAllActions(); - } - else - { - SetLocalInt(OBJECT_SELF, "NSB_Cast", 1); - if(bIsAction) - { - SetLocalInt(OBJECT_SELF, "NSB_Class", nClass); - SetLocalInt(OBJECT_SELF, "NSB_SpellLevel", nSpellSlotLevel); - } - } -} - -void DoCleanUp(int nMetamagic) -{ - if(nMetamagic & METAMAGIC_QUICKEN) - { - object oSkin = GetPCSkin(OBJECT_SELF); - RemoveItemProperty(oSkin, ItemPropertyBonusFeat(IP_CONST_NSB_AUTO_QUICKEN)); - } - DeleteLocalInt(OBJECT_SELF, "NSB_Class"); - DeleteLocalInt(OBJECT_SELF, "NSB_SpellLevel"); - DeleteLocalInt(OBJECT_SELF, "NSB_SpellbookID"); -} \ No newline at end of file diff --git a/trunk/include/inv_inc_invfunc.nss b/trunk/include/inv_inc_invfunc.nss deleted file mode 100644 index c78ec4d4..00000000 --- a/trunk/include/inv_inc_invfunc.nss +++ /dev/null @@ -1,496 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Invocation include: Miscellaneous -//:: inv_inc_invfunc -//:://///////////////////////////////////////////// -/** @file - Defines various functions and other stuff that - do something related to Invocation implementation. - - Also acts as inclusion nexus for the general - invocation includes. In other words, don't include - them directly in your scripts, instead include this. - - @author Fox - @date Created - 2008.1.25 - - Updated for .35 by Jaysyn 2023/03/10 -*/ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -const int INVOCATION_DRACONIC = 1; -const int INVOCATION_WARLOCK = 2; - -const int INVOCATION_LEAST = 2; -const int INVOCATION_LESSER = 4; -const int INVOCATION_GREATER = 6; -const int INVOCATION_DARK = 8; - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Determines from what class's invocation list the currently casted - * invocation is cast from. - * - * @param oInvoker A creature invoking at this moment - * @return CLASS_TYPE_* constant of the class - */ -int GetInvokingClass(object oInvoker = OBJECT_SELF); - -/** - * Determines the given creature's Invoker level. If a class is specified, - * then returns the Invoker level for that class. Otherwise, returns - * the Invoker level for the currently active invocation. - * - * @param oInvoker The creature whose Invoker level to determine - * @param nSpecificClass The class to determine the creature's Invoker - * level in. - * @param bPracticedInvoker If this is set, it will add the bunus from - * Practiced Invoker feat. - * @return The Invoker level - */ -int GetInvokerLevel(object oInvoker = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID, int bPracticedInvoker = TRUE); - -/** - * Determines whether a given creature uses Invocations. - * Requires either levels in an invocation-related class or - * natural Invocation ability based on race. - * - * @param oCreature Creature to test - * @return TRUE if the creature can use Invocations, FALSE otherwise. - */ -int GetIsInvocationUser(object oCreature); - -/** - * Determines the given creature's highest undmodified Invoker level among it's - * invoking classes. - * - * @param oCreature Creature whose highest Invoker level to determine - * @return The highest unmodified Invoker level the creature can have - */ -int GetHighestInvokerLevel(object oCreature); - -/** - * Determines whether a given class is an invocation-related class or not. - * - * @param nClass CLASS_TYPE_* of the class to test - * @return TRUE if the class is an invocation-related class, FALSE otherwise - */ -int GetIsInvocationClass(int nClass); - -/** - * Gets the level of the invocation being currently cast. - * WARNING: Return value is not defined when an invocation is not being cast. - * - * @param oInvoker The creature currently casting an invocation - * @return The level of the invocation being cast - */ -int GetInvocationLevel(object oInvoker); - -/** - * Returns the name of the invocation - * - * @param nSpellId SpellId of the invocation - */ -string GetInvocationName(int nSpellId); - -/** - * Calculates how many invoker levels are gained by a given creature from - * it's levels in prestige classes. - * - * @param oCreature Creature to calculate added invoker levels for - * @return The number of invoker levels gained - */ -int GetInvocationPRCLevels(object oCaster); - -/** - * Determines which of the character's classes is their highest or first invocation - * casting class, if any. This is the one which gains invoker level raise benefits - * from prestige classes. - * - * @param oCreature Creature whose classes to test - * @return CLASS_TYPE_* of the first invocation casting class, - * CLASS_TYPE_INVALID if the creature does not possess any. - */ -int GetPrimaryInvocationClass(object oCreature = OBJECT_SELF); - -/** - * Determines the position of a creature's first invocation casting class, if any. - * - * @param oCreature Creature whose classes to test - * @return The position of the first invocation class {1, 2, 3} or 0 if - * the creature possesses no levels in invocation classes. - */ -int GetFirstInvocationClassPosition(object oCreature = OBJECT_SELF); - -/** - * Ruterns the number of damage dices that oInvokers eldritch blast has - * - * @param oInvoker Creature whose blast to test - * @param nInvokerLevel Invoker level - * @return The number of damage dices - */ -int GetBlastDamageDices(object oInvoker, int nInvokerLevel); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -//#include "prc_alterations" -#include "inv_inc_invknown" -#include "inv_inc_invoke" -#include "inv_inc_blast" -#include "prc_add_spell_dc" - -////////////////////////////////////////////////// -/* Internal functions */ -////////////////////////////////////////////////// - - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetInvokingClass(object oInvoker = OBJECT_SELF) -{ - return GetLocalInt(oInvoker, PRC_INVOKING_CLASS) - 1; -} - -/*int PracticedInvoker(object oInvoker, int iInvokingClass, int iInvokingLevels) -{ - int nFeat; - int iAdjustment = GetHitDice(oInvoker) - iInvokingLevels; - if(iAdjustment > 4) iAdjustment = 4; - if(iAdjustment < 0) iAdjustment = 0; - - switch(iInvokingClass) - { - case CLASS_TYPE_DRAGONFIRE_ADEPT: nFeat = FEAT_PRACTICED_INVOKER_DRAGONFIRE_ADEPT; break; - case CLASS_TYPE_WARLOCK: nFeat = FEAT_PRACTICED_INVOKER_WARLOCK; break; - default: return 0; - } - - if(GetHasFeat(nFeat, oInvoker)) - return iAdjustment; - - return 0; -}*/ - -int GetInvokerLevel(object oInvoker = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID, int bPracticedInvoker = TRUE) -{ - int nAdjust = GetLocalInt(oInvoker, PRC_CASTERLEVEL_ADJUSTMENT); - int nLevel = GetLocalInt(oInvoker, PRC_CASTERLEVEL_OVERRIDE); - - // For when you want to assign the caster level. - if(nLevel) - { - if(DEBUG) SendMessageToPC(oInvoker, "Forced-level Invoking at level " + IntToString(GetCasterLevel(oInvoker))); - //DelayCommand(1.0, DeleteLocalInt(oInvoker, PRC_CASTERLEVEL_OVERRIDE)); - return nLevel + nAdjust; - } - - if(nSpecificClass == CLASS_TYPE_INVALID) - nSpecificClass = GetInvokingClass(oInvoker); - - if(nSpecificClass != -1) - { - if(!GetIsInvocationClass(nSpecificClass)) - return 0; - - if(nSpecificClass == CLASS_TYPE_DRAGON_SHAMAN) - nLevel = max(GetLevelByClass(nSpecificClass, oInvoker) - 4, 1); // Can't go below 1 - else - nLevel = GetLevelByClass(nSpecificClass, oInvoker); - if(DEBUG) DoDebug("Invoker Class Level is: " + IntToString(nLevel)); - if(GetPrimaryInvocationClass(oInvoker) == nSpecificClass) - { - //Invoker level is class level + any arcane spellcasting or invoking levels in any PRCs - nLevel += GetInvocationPRCLevels(oInvoker); - } - /*if(bPracticedInvoker) - nLevel += PracticedInvoker(oInvoker, nSpecificClass, nLevel);*/ - } - else - nLevel = GetLevelByClass(GetPrimaryInvocationClass(oInvoker), oInvoker); - - nLevel += nAdjust; - SetLocalInt(oInvoker, "InvokerLevel", nLevel); - return nLevel; -} - -int GetIsInvocationUser(object oCreature) -{ - return !!(GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oCreature) || - GetLevelByClass(CLASS_TYPE_WARLOCK, oCreature) || - GetLevelByClass(CLASS_TYPE_DRAGON_SHAMAN, oCreature) - ); -} - - -int GetHighestInvokerLevel(object oCreature) -{ - int n = 0; - int nHighest; - int nTemp; - - while(n <= 8) - { - if(GetClassByPosition(n, oCreature) != CLASS_TYPE_INVALID) - { - nTemp = GetInvokerLevel(oCreature, GetClassByPosition(n, oCreature)); - - if(nTemp > nHighest) - nHighest = nTemp; - } - n++; - - } - - return nHighest; -} - -/* int GetHighestInvokerLevel(object oCreature) -{ - return max(max(GetClassByPosition(1, oCreature) != CLASS_TYPE_INVALID ? GetInvokerLevel(oCreature, GetClassByPosition(1, oCreature)) : 0, - GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID ? GetInvokerLevel(oCreature, GetClassByPosition(2, oCreature)) : 0 - ), - GetClassByPosition(3, oCreature) != CLASS_TYPE_INVALID ? GetInvokerLevel(oCreature, GetClassByPosition(3, oCreature)) : 0 - ); -} */ - -int GetIsInvocationClass(int nClass) -{ - int bTest = nClass == CLASS_TYPE_DRAGONFIRE_ADEPT - || nClass == CLASS_TYPE_WARLOCK - || nClass == CLASS_TYPE_DRAGON_SHAMAN; - return bTest; -} - -int GetInvocationLevel(object oInvoker) -{ - return GetLocalInt(oInvoker, PRC_INVOCATION_LEVEL); -} - -string GetInvocationName(int nSpellId) -{ - return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellId))); -} - -int GetInvocationPRCLevels(object oCaster) -{ - int nLevel = GetLevelByClass(CLASS_TYPE_HELLFIRE_WARLOCK, oCaster) - + GetLevelByClass(CLASS_TYPE_ELDRITCH_DISCIPLE, oCaster) - + GetLevelByClass(CLASS_TYPE_ELDRITCH_THEURGE, oCaster); - - //_some_ arcane spellcasting levels boost invocations - if(GetLocalInt(oCaster, "INV_Caster") == 2) - nLevel += (GetLevelByClass(CLASS_TYPE_ACOLYTE, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_DISCIPLE_OF_ASMODEUS, oCaster) + 1) / 2 - + GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oCaster) - + GetLevelByClass(CLASS_TYPE_MAESTER, oCaster) - + (GetLevelByClass(CLASS_TYPE_TALON_OF_TIAMAT, oCaster) + 1) / 2; - - return nLevel; -} - -int GetPrimaryInvocationClass(object oCreature = OBJECT_SELF) -{ - int nClass; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) //: Kinda pointless for .35 - { - int nInvocationPos = GetFirstInvocationClassPosition(oCreature); - if (!nInvocationPos) return CLASS_TYPE_INVALID; // no invoking class - - nClass = GetClassByPosition(nInvocationPos, oCreature); - } - else - { - int nClassLvl; - int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8; - int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl; - - nClass1 = GetClassByPosition(1, oCreature); - nClass2 = GetClassByPosition(2, oCreature); - nClass3 = GetClassByPosition(3, oCreature); - nClass4 = GetClassByPosition(4, oCreature); - nClass5 = GetClassByPosition(5, oCreature); - nClass6 = GetClassByPosition(6, oCreature); - nClass7 = GetClassByPosition(7, oCreature); - nClass8 = GetClassByPosition(8, oCreature); - - if(GetIsInvocationClass(nClass1)) nClass1Lvl = GetLevelByClass(nClass1, oCreature); - if(GetIsInvocationClass(nClass2)) nClass2Lvl = GetLevelByClass(nClass2, oCreature); - if(GetIsInvocationClass(nClass3)) nClass3Lvl = GetLevelByClass(nClass3, oCreature); - if(GetIsInvocationClass(nClass4)) nClass4Lvl = GetLevelByClass(nClass4, oCreature); - if(GetIsInvocationClass(nClass5)) nClass5Lvl = GetLevelByClass(nClass5, oCreature); - if(GetIsInvocationClass(nClass6)) nClass6Lvl = GetLevelByClass(nClass6, oCreature); - if(GetIsInvocationClass(nClass7)) nClass7Lvl = GetLevelByClass(nClass7, oCreature); - if(GetIsInvocationClass(nClass8)) nClass8Lvl = GetLevelByClass(nClass8, oCreature); - - nClass = nClass1; - nClassLvl = nClass1Lvl; - - if(nClass2Lvl > nClassLvl) - { - nClass = nClass2; - nClassLvl = nClass2Lvl; - } - if(nClass3Lvl > nClassLvl) - { - nClass = nClass3; - nClassLvl = nClass3Lvl; - } - if(nClass4Lvl > nClassLvl) - { - nClass = nClass4; - nClassLvl = nClass4Lvl; - } - if(nClass5Lvl > nClassLvl) - { - nClass = nClass5; - nClassLvl = nClass5Lvl; - } - if(nClass6Lvl > nClassLvl) - { - nClass = nClass6; - nClassLvl = nClass6Lvl; - } - if(nClass7Lvl > nClassLvl) - { - nClass = nClass7; - nClassLvl = nClass7Lvl; - } - if(nClass8Lvl > nClassLvl) - { - nClass = nClass8; - nClassLvl = nClass8Lvl; - } - - if(nClassLvl == 0) - nClass = CLASS_TYPE_INVALID; - } - - return nClass; -} - -int GetFirstInvocationClassPosition(object oCreature = OBJECT_SELF) -{ - if (GetIsInvocationClass(GetClassByPosition(1, oCreature))) - return 1; - if (GetIsInvocationClass(GetClassByPosition(2, oCreature))) - return 2; - if (GetIsInvocationClass(GetClassByPosition(3, oCreature))) - return 3; - if (GetIsInvocationClass(GetClassByPosition(4, oCreature))) - return 4; - if (GetIsInvocationClass(GetClassByPosition(5, oCreature))) - return 5; - if (GetIsInvocationClass(GetClassByPosition(6, oCreature))) - return 6; - if (GetIsInvocationClass(GetClassByPosition(7, oCreature))) - return 7; - if (GetIsInvocationClass(GetClassByPosition(8, oCreature))) - return 8; - - return 0; -} - -int GetInvocationSaveDC(object oTarget, object oCaster, int nSpellID = -1) -{ - int nDC; - // For when you want to assign the caster DC - //this does not take feat/race/class into account, it is an absolute override - if (GetLocalInt(oCaster, PRC_DC_TOTAL_OVERRIDE) != 0) - { - nDC = GetLocalInt(oCaster, PRC_DC_TOTAL_OVERRIDE); - DoDebug("Forced-DC PRC_DC_TOTAL_OVERRIDE casting at DC " + IntToString(nDC)); - return nDC; - } - // For when you want to assign the caster DC - //this does take feat/race/class into account, it only overrides the baseDC - if(GetLocalInt(oCaster, PRC_DC_BASE_OVERRIDE) > 0) - { - nDC = GetLocalInt(oCaster, PRC_DC_BASE_OVERRIDE); - if(DEBUG) DoDebug("Forced Base-DC casting at DC " + IntToString(nDC)); - } - else - { - if(nSpellID == -1) nSpellID = PRCGetSpellId(); - //10+spelllevel+stat(cha default) - nDC = 10; - nDC += StringToInt(Get2DACache("Spells", "Innate", nSpellID)); - nDC += GetAbilityModifier(ABILITY_CHARISMA, oCaster); - } - nDC += GetChangesToSaveDC(oTarget, oCaster, nSpellID, 0); - - return nDC; -} - -void ClearInvocationLocalVars(object oPC) -{ - //Invocations - if (DEBUG) DoDebug("Clearing invocation flags"); - DeleteLocalObject(oPC, "ChillingFog"); - //Endure Exposure wearing off - array_delete(oPC, "BreathProtected"); - DeleteLocalInt(oPC, "DragonWard"); - - //cleaning targets of Endure exposure cast by resting caster - if (array_exists(oPC, "BreathProtectTargets")) - { - if(DEBUG) DoDebug("Checking for casts of Endure Exposure"); - int nBPTIndex = 0; - int bCasterDone = FALSE; - int bTargetDone = FALSE; - object oBreathTarget; - while(!bCasterDone) - { - oBreathTarget = array_get_object(oPC, "BreathProtectTargets", nBPTIndex); - if(DEBUG) DoDebug("Possible target: " + GetName(oBreathTarget) + " - " + ObjectToString(oBreathTarget)); - if(oBreathTarget != OBJECT_INVALID) - { - //replace caster with target... always immune to own breath, so good way to erase caster from array without deleting whole array - int nBPIndex = 0; - - while(!bTargetDone) - { - if(DEBUG) DoDebug("Checking " + GetName(oBreathTarget)); - //if it matches, remove and end - if(array_get_object(oBreathTarget, "BreathProtected", nBPIndex) == oPC) - { - array_set_object(oBreathTarget, "BreathProtected", nBPIndex, oBreathTarget); - bTargetDone = TRUE; - if(DEBUG) DoDebug("Found caster, clearing."); - } - //if it is not end of array, keep going - else if(array_get_object(oBreathTarget, "BreathProtected", nBPTIndex) != OBJECT_INVALID) - { - nBPIndex++; - } - else - bTargetDone = TRUE; - - } - - nBPTIndex++; - bTargetDone = FALSE; - - } - else - { - array_delete(oPC, "BreathProtectTargets"); - bCasterDone = TRUE; - } - } - } -} - -// Test main -//void main(){} diff --git a/trunk/include/moi_inc_moifunc.nss b/trunk/include/moi_inc_moifunc.nss deleted file mode 100644 index 05a10903..00000000 --- a/trunk/include/moi_inc_moifunc.nss +++ /dev/null @@ -1,1559 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Meldshaping/Incarnum main include: Miscellaneous -//:: moi_inc_moifunc -//:://///////////////////////////////////////////// -/** @file - Defines various functions and other stuff that - do something related to Meldshaping. - - Also acts as inclusion nexus for the general - meldshaping includes. In other words, don't include - them directly in your scripts, instead include this. - - @author Stratovarius - @date Created - 2019.12.28 - - Updated for .35 by Jaysyn 2023/03/10 -*/ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -//:: Test Void -//void main () {} - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Determines the given creature's Meldshaper level. - * - * @param oMeldshaper The creature whose Meldshaper level to determine - * @param nSpecificClass The class to determine the creature's Meldshaper - * level in. - * @param nMeld The meld to test, since Incarnum does level by meld - * - * @return The Meldshaper level - */ -int GetMeldshaperLevel(object oMeldshaper, int nSpecificClass, int nMeld); - -/** - * Determines the given creature's highest unmodified Meldshaper level among its - * Meldshaping classes. - * - * @param oMeldshaper Creature whose highest Meldshaper level to determine - * @return The highest unmodified Meldshaper level the creature can have - */ -int GetHighestMeldshaperLevel(object oMeldshaper); - -/** - * Determines whether a given class is a Incarnum-related class or not. - * - * @param nClass CLASS_TYPE_* of the class to test - * @return TRUE if the class is a Incarnum-related class, FALSE otherwise - */ -int GetIsIncarnumClass(int nClass); - -/** - * Calculates how many Meldshaper levels are gained by a given creature from - * it's levels in prestige classes. - * - * @param oMeldshaper Creature to calculate added Meldshaper levels for - * @return The number of Meldshaper levels gained - */ -int GetIncarnumPRCLevels(object oMeldshaper); - -/** - * Determines which of the character's classes is their highest or first - * Meldshaping class, if any. This is the one which gains Meldshaper - * level raise benefits from prestige classes. - * - * @param oMeldshaper Creature whose classes to test - * @return CLASS_TYPE_* of the first Meldshaping class, - * CLASS_TYPE_INVALID if the creature does not possess any. - */ -int GetPrimaryIncarnumClass(object oMeldshaper = OBJECT_SELF); - -/** - * Determines the position of a creature's first Meldshaping class, if any. - * - * @param oMeldshaper Creature whose classes to test - * @return The position of the first Meldshaping class {1, 2, 3} or 0 if - * the creature possesses no levels in Meldshaping classes. - */ -int GetFirstIncarnumClassPosition(object oMeldshaper = OBJECT_SELF); - -/** - * Checks every second to see if temporary essentia has been lost - * - * @param oMeldshaper The meldshaper - */ -void SpawnTempEssentiaChecker(object oMeldshaper); - -/** - * Returns total value of temporary essentia for the meldshaper - * - * @param oMeldshaper The meldshaper - * - * @return Total value of temporary essentia - */ -int GetTemporaryEssentia(object oMeldshaper); - -/** - * Essentia put into feats is locked away for 24 hours/until next rest - * - * @param oMeldshaper The meldshaper - * - * @return Total value of locked essentia - */ -int GetFeatLockedEssentia(object oMeldshaper); - -/** - * Total essentia a character has access to - * - * @param oMeldshaper The meldshaper - * - * @return Total value of essentia available - */ -int GetTotalEssentia(object oMeldshaper); - -/** - * Total essentia a character has access to, minus feat locked essentia - * - * @param oMeldshaper The meldshaper - * - * @return Total value of essentia available, minus feat locked essentia - */ -int GetTotalUsableEssentia(object oMeldshaper); - -/** - * Returns the slot associated to a given chakra - * - * @param nChakra Chakra constant - * - * @return Slot constant - */ -int ChakraToSlot(int nChakra); - -/** - * Returns the total binds the character can have for that class and level - * - * @param oMeldshaper The meldshaper - * @param nClass The class to check - * - * @return Slot constant - */ -int GetMaxBindCount(object oMeldshaper, int nClass); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "prc_inc_natweap" -#include "prc_inc_function" - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetMeldshaperLevel(object oMeldshaper, int nSpecificClass, int nMeld) -{ - int nLevel; - - if (DEBUG) DoDebug("GetMeldshaperLevel: "+GetName(oMeldshaper)+" is a "+IntToString(nSpecificClass)); - - if(GetIsIncarnumClass(nSpecificClass)) - { - // Meldshaper level is class level + prestige - nLevel = GetLevelByClass(nSpecificClass, oMeldshaper); - if(nLevel) - { - // Prevents people double-dipping prestige levels - if (nSpecificClass == GetPrimaryIncarnumClass(oMeldshaper)) - { - nLevel += GetIncarnumPRCLevels(oMeldshaper); - nLevel += GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper); // Necrocarnate is here because it doesn't add to anything other than meldshaper level - } - if (nSpecificClass == CLASS_TYPE_SOULBORN) nLevel /= 2; - } - } - - if(DEBUG) DoDebug("Meldshaper Level: " + IntToString(nLevel)); - // Being bound to the Totem Chakra increases the level by one. - if (GetIsMeldBound(oMeldshaper, nMeld) == CHAKRA_TOTEM) nLevel++; - return nLevel; -} - -int GetIncarnumLevelForClass(int nSpecificClass, object oMeldshaper) -{ - int nLevel; - - if (DEBUG) DoDebug("GetMeldshaperLevel: "+GetName(oMeldshaper)+" is a "+IntToString(nSpecificClass)); - - if(GetIsIncarnumClass(nSpecificClass)) - { - // Meldshaper level is class level + prestige - nLevel = GetLevelByClass(nSpecificClass, oMeldshaper); - if(nLevel) - { - // Prevents people double-dipping prestige levels - if (nSpecificClass == GetPrimaryIncarnumClass(oMeldshaper)) nLevel += GetIncarnumPRCLevels(oMeldshaper); - } - } - if(nSpecificClass == CLASS_TYPE_UMBRAL_DISCIPLE || nSpecificClass == CLASS_TYPE_INCANDESCENT_CHAMPION || nSpecificClass == CLASS_TYPE_NECROCARNATE) - nLevel = GetLevelByClass(nSpecificClass, oMeldshaper); - - if(DEBUG) DoDebug("GetIncarnumLevelForClass: " + IntToString(nLevel)); - return nLevel; -} - -int GetHighestMeldshaperLevel(object oMeldshaper) -{ - int n = 0; - int nHighest; - int nTemp; - - while(n <= 8) - { - if(GetClassByPosition(n, oMeldshaper) != CLASS_TYPE_INVALID) - { - nTemp = GetMeldshaperLevel(oMeldshaper, GetClassByPosition(n, oMeldshaper), -1); - - if(nTemp > nHighest) - nHighest = nTemp; - } - n++; - - } - - return nHighest; -} - -/* int GetHighestMeldshaperLevel(object oMeldshaper) -{ - return max(max(GetClassByPosition(1, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(1, oMeldshaper), -1) : 0, - GetClassByPosition(2, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(2, oMeldshaper), -1) : 0 - ), - GetClassByPosition(3, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(3, oMeldshaper), -1) : 0 - ); -} */ - -int GetIsIncarnumClass(int nClass) -{ - return nClass == CLASS_TYPE_INCARNATE - || nClass == CLASS_TYPE_SOULBORN - || nClass == CLASS_TYPE_TOTEMIST - || nClass == CLASS_TYPE_SPINEMELD_WARRIOR; -} - -int GetIncarnumPRCLevels(object oMeldshaper) -{ - int nLevel = GetLevelByClass(CLASS_TYPE_SAPPHIRE_HIERARCH, oMeldshaper); - nLevel += GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper); - - // These two don't add at 1st level - if (GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper)) - nLevel += GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper) - 1; - // Totem Rager - if (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >= 6) - nLevel += (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper)) -2; - else if (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper)) - nLevel += (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper)) -1; - //This is an odd one - if (GetLevelByClass(CLASS_TYPE_WITCHBORN_BINDER, oMeldshaper)) - { - nLevel += (GetLevelByClass(CLASS_TYPE_WITCHBORN_BINDER, oMeldshaper)+1)/2; - - if (GetLevelByClass(CLASS_TYPE_WITCHBORN_BINDER, oMeldshaper) >= 10) nLevel += 1; - } - - /*if (GetLevelByClass(CLASS_TYPE_MASTER_OF_SHADOW, oMeldshaper)) - nLevel += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHADOW, oMeldshaper) - 1; -*/ - return nLevel; -} - -int GetPrimaryIncarnumClass(object oMeldshaper = OBJECT_SELF) -{ - int nClass = CLASS_TYPE_INVALID; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) - { - int nIncarnumPos = GetFirstIncarnumClassPosition(oMeldshaper); - if (!nIncarnumPos) return CLASS_TYPE_INVALID; // no Blade Magic Meldshaping class - - nClass = GetClassByPosition(nIncarnumPos, oMeldshaper); - } - else - { - int nClassLvl; - int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8; - int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl; - - nClass1 = GetClassByPosition(1, oMeldshaper); - nClass2 = GetClassByPosition(2, oMeldshaper); - nClass3 = GetClassByPosition(3, oMeldshaper); - nClass4 = GetClassByPosition(4, oMeldshaper); - nClass5 = GetClassByPosition(5, oMeldshaper); - nClass6 = GetClassByPosition(6, oMeldshaper); - nClass7 = GetClassByPosition(7, oMeldshaper); - nClass8 = GetClassByPosition(8, oMeldshaper); - - if(GetIsIncarnumClass(nClass1)) nClass1Lvl = GetLevelByClass(nClass1, oMeldshaper); - if(GetIsIncarnumClass(nClass2)) nClass2Lvl = GetLevelByClass(nClass2, oMeldshaper); - if(GetIsIncarnumClass(nClass3)) nClass3Lvl = GetLevelByClass(nClass3, oMeldshaper); - if(GetIsIncarnumClass(nClass4)) nClass4Lvl = GetLevelByClass(nClass4, oMeldshaper); - if(GetIsIncarnumClass(nClass5)) nClass5Lvl = GetLevelByClass(nClass5, oMeldshaper); - if(GetIsIncarnumClass(nClass6)) nClass6Lvl = GetLevelByClass(nClass6, oMeldshaper); - if(GetIsIncarnumClass(nClass7)) nClass7Lvl = GetLevelByClass(nClass7, oMeldshaper); - if(GetIsIncarnumClass(nClass8)) nClass8Lvl = GetLevelByClass(nClass8, oMeldshaper); - - nClass = nClass1; - nClassLvl = nClass1Lvl; - - if(nClass2Lvl > nClassLvl) - { - nClass = nClass2; - nClassLvl = nClass2Lvl; - } - if(nClass3Lvl > nClassLvl) - { - nClass = nClass3; - nClassLvl = nClass3Lvl; - } - if(nClass4Lvl > nClassLvl) - { - nClass = nClass4; - nClassLvl = nClass4Lvl; - } - if(nClass5Lvl > nClassLvl) - { - nClass = nClass5; - nClassLvl = nClass5Lvl; - } - if(nClass6Lvl > nClassLvl) - { - nClass = nClass6; - nClassLvl = nClass6Lvl; - } - if(nClass7Lvl > nClassLvl) - { - nClass = nClass7; - nClassLvl = nClass7Lvl; - } - if(nClass8Lvl > nClassLvl) - { - nClass = nClass8; - nClassLvl = nClass8Lvl; - } - - if(nClassLvl == 0) - nClass = CLASS_TYPE_INVALID; - } - - return nClass; -} - -int GetFirstIncarnumClassPosition(object oMeldshaper = OBJECT_SELF) -{ - if (GetIsIncarnumClass(GetClassByPosition(1, oMeldshaper))) - return 1; - if (GetIsIncarnumClass(GetClassByPosition(2, oMeldshaper))) - return 2; - if (GetIsIncarnumClass(GetClassByPosition(3, oMeldshaper))) - return 3; - if (GetIsIncarnumClass(GetClassByPosition(4, oMeldshaper))) - return 4; - if (GetIsIncarnumClass(GetClassByPosition(5, oMeldshaper))) - return 5; - if (GetIsIncarnumClass(GetClassByPosition(6, oMeldshaper))) - return 6; - if (GetIsIncarnumClass(GetClassByPosition(7, oMeldshaper))) - return 7; - if (GetIsIncarnumClass(GetClassByPosition(8, oMeldshaper))) - return 8; - - return 0; -} - -string GetMeldFile(int nClass = -1) -{ - //string sFile; - //if (nClass == CLASS_TYPE_INCARNATE) sFile = "cls_meld_incarn"; - - return "soulmelds"; -} - -string GetMeldshapingClassFile(int nClass) -{ - string sFile; - if (nClass == CLASS_TYPE_INCARNATE) sFile = "cls_mlkn_incarn"; - else if (nClass == CLASS_TYPE_SOULBORN) sFile = "cls_mlkn_soulbn"; - else if (nClass == CLASS_TYPE_TOTEMIST) sFile = "cls_mlkn_totem"; - else if (nClass == CLASS_TYPE_SPINEMELD_WARRIOR) sFile = "cls_mlkn_spnmld"; - else if (nClass == CLASS_TYPE_UMBRAL_DISCIPLE) sFile = "cls_mlkn_umbral"; - else if (nClass == CLASS_TYPE_INCANDESCENT_CHAMPION) sFile = "cls_mlkn_incand"; - else if (nClass == CLASS_TYPE_NECROCARNATE) sFile = "cls_mlkn_necrnm"; - - return sFile; -} - -int GetMeldshapingClass(object oMeldshaper) -{ - int nClass = -1; - // If there's levels in the class and haven't already done it - if (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) && !GetLocalInt(oMeldshaper, "FirstMeldDone")) nClass = CLASS_TYPE_INCARNATE; - else if (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) && !GetLocalInt(oMeldshaper, "SecondMeldDone")) nClass = CLASS_TYPE_SOULBORN; - else if (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) && !GetLocalInt(oMeldshaper, "ThirdMeldDone")) nClass = CLASS_TYPE_TOTEMIST; - else if (GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper) && !GetLocalInt(oMeldshaper, "FourthMeldDone")) nClass = CLASS_TYPE_SPINEMELD_WARRIOR; - if (DEBUG) DoDebug("GetMeldshapingClass is "+IntToString(nClass)); - return nClass; -} - -int GetMaxShapeSoulmeldCount(object oMeldshaper, int nClass) -{ - int nMax = StringToInt(Get2DACache(GetMeldshapingClassFile(nClass), "Soulmelds", GetIncarnumLevelForClass(nClass, oMeldshaper)-1)); - if (nClass == GetPrimaryIncarnumClass(oMeldshaper)) - { - nMax += StringToInt(Get2DACache(GetMeldshapingClassFile(CLASS_TYPE_NECROCARNATE), "Soulmelds", GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper))); - int i; - for(i = FEAT_BONUS_SOULMELD_1; i <= FEAT_BONUS_SOULMELD_10; i++) - if(GetHasFeat(i, oMeldshaper)) nMax++; - } - - int nCon = GetAbilityScore(oMeldshaper, ABILITY_CONSTITUTION, TRUE)-10; - if (GetHasFeat(FEAT_UNDEAD_MELDSHAPER, oMeldshaper)) nCon = GetAbilityScore(oMeldshaper, ABILITY_WISDOM, TRUE)-10; - //Limited to Con score - 10 or class limit, whichever is less - nMax = min(nMax, nCon); - - if (DEBUG) DoDebug("GetMaxShapeSoulmeldCount is "+IntToString(nMax)); - return nMax; -} - -int GetTotalSoulmeldCount(object oMeldshaper) -{ - int nMax = GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_INCARNATE); - nMax += GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_SOULBORN); - nMax += GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_TOTEMIST); - nMax += GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_SPINEMELD_WARRIOR); - nMax += GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_NECROCARNATE); - - if (DEBUG) DoDebug("GetTotalSoulmeldCount is "+IntToString(nMax)); - return nMax; -} - -int GetMaxBindCount(object oMeldshaper, int nClass) -{ - int nMax = StringToInt(Get2DACache(GetMeldshapingClassFile(nClass), "ChakraBinds", GetIncarnumLevelForClass(nClass, oMeldshaper)-1)); - if (nClass == GetPrimaryIncarnumClass(oMeldshaper)) - { - nMax += StringToInt(Get2DACache(GetMeldshapingClassFile(CLASS_TYPE_NECROCARNATE), "ChakraBinds", GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper))); - int i; - for(i = FEAT_EXTRA_CHAKRA_BIND_1; i <= FEAT_EXTRA_CHAKRA_BIND_10; i++) - if(GetHasFeat(i, oMeldshaper)) nMax += 1; - } - if (DEBUG) DoDebug("GetMaxBindCount is "+IntToString(nMax)); - return nMax; -} - -void ShapeSoulmeld(object oMeldshaper, int nMeld) -{ - PRCRemoveSpellEffects(nMeld, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(nMeld, oMeldshaper, FALSE); - ActionCastSpellOnSelf(nMeld); - if (DEBUG) DoDebug("Shaping Soulmeld "+IntToString(nMeld)+" on "+GetName(oMeldshaper)); -} - -void MarkMeldShaped(object oMeldshaper, int nMeld, int nClass) -{ - if (DEBUG) DoDebug("MarkMeldShaped nMeld is "+IntToString(nMeld)); - int nCont = TRUE; - int nTest, i; - while (nCont) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(nClass)+IntToString(i)); - if (DEBUG) DoDebug("MarkMeldShaped nTest is "+IntToString(nTest)); - if (!nTest) // If it's blank - { - SetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(nClass)+IntToString(i), nMeld); - if (DEBUG) DoDebug("MarkMeldShaped SetLocal"); - nCont = FALSE; // Break the loop - } - else - i++; // Increment the counter to check - } -} - -void ClearMeldShapes(object oMeldshaper) -{ - object oSkin = GetPCSkin(oMeldshaper); - ScrubPCSkin(oMeldshaper, oSkin); - int i; - for (i = 0; i <= 22; i++) - { - DeleteLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_INCARNATE)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_SOULBORN)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_TOTEMIST)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_SPINEMELD_WARRIOR)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "UsedMeld"+IntToString(CLASS_TYPE_SPINEMELD_WARRIOR)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "UsedMeld"+IntToString(CLASS_TYPE_INCARNATE)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "UsedMeld"+IntToString(CLASS_TYPE_SOULBORN)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "UsedMeld"+IntToString(CLASS_TYPE_TOTEMIST)+IntToString(i)); - DeleteLocalInt(oMeldshaper, "BoundMeld"+IntToString(i)); - int nTest = GetLocalInt(oMeldshaper, "SpellInvestCheck"+IntToString(i)); - if (nTest) - DeleteLocalInt(oMeldshaper, "SpellEssentia"+IntToString(nTest)); - DeleteLocalInt(oMeldshaper, "SpellInvestCheck"+IntToString(i)); - DeleteLocalInt(oMeldshaper, "ExpandedSoulmeld"+IntToString(i)); - DeleteLocalInt(oMeldshaper, "UsedBladeMeld"+IntToString(i)); - } - for (i = 18700; i < 18799; i++) - { - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i)); - } - for (i = 8869; i < 8889; i++) - { - DeleteLocalInt(oMeldshaper, "FeatEssentia"+IntToString(i)); - } - DeleteLocalInt(oMeldshaper, "ArcaneFocusBound"); - if (GetLocalInt(oMeldshaper, "DiademPurelight")) - { - SetLocalInt(oMeldshaper, "PRCInLight", GetLocalInt(oMeldshaper, "PRCInLight")-1); - DeleteLocalInt(oMeldshaper, "DiademPurelight"); - } - - if (GetLocalInt(oMeldshaper, "PlanarChasubleLimit") > 7) - DeleteLocalInt(oMeldshaper, "PlanarChasubleLimit"); - else - SetLocalInt(oMeldshaper, "PlanarChasubleLimit", GetLocalInt(oMeldshaper, "PlanarChasubleLimit")+1); - - DeleteLocalInt(oMeldshaper, "GorgonMaskLimit"); - DeleteLocalInt(oMeldshaper, "IncarnateAvatarSpeed"); - DeleteLocalInt(oMeldshaper, "LamiaBeltSpeed"); - DeleteLocalInt(oMeldshaper, "LifebondVestmentsTimer"); - DeleteLocalInt(oMeldshaper, "MidnightAugPower"); - DeleteLocalInt(oMeldshaper, "MeldEssentia18973"); // MELD_DUSKLING_SPEED - DeleteLocalInt(oMeldshaper, "MeldEssentia18691"); // MELD_SPINE_ENHANCEMENT - DeleteLocalInt(oMeldshaper, "MeldEssentia18687"); // MELD_IRONSOUL_SHIELD - DeleteLocalInt(oMeldshaper, "MeldEssentia18685"); // MELD_IRONSOUL_ARMOR - DeleteLocalInt(oMeldshaper, "MeldEssentia18683"); // MELD_IRONSOUL_WEAPON - DeleteLocalInt(oMeldshaper, "MeldEssentia18681"); // MELD_UMBRAL_STEP - DeleteLocalInt(oMeldshaper, "MeldEssentia18679"); // MELD_UMBRAL_SHADOW - DeleteLocalInt(oMeldshaper, "MeldEssentia18677"); // MELD_UMBRAL_SIGHT - DeleteLocalInt(oMeldshaper, "MeldEssentia18675"); // MELD_UMBRAL_SOUL - DeleteLocalInt(oMeldshaper, "MeldEssentia18673"); // MELD_UMBRAL_KISS - DeleteLocalInt(oMeldshaper, "MeldEssentia18670"); // MELD_INCANDESCENT_STRIKE - DeleteLocalInt(oMeldshaper, "MeldEssentia18668"); // MELD_INCANDESCENT_HEAL - DeleteLocalInt(oMeldshaper, "MeldEssentia18666"); // MELD_INCANDESCENT_COUNTENANCE - DeleteLocalInt(oMeldshaper, "MeldEssentia18663"); // MELD_INCANDESCENT_RAY - DeleteLocalInt(oMeldshaper, "MeldEssentia18659"); // MELD_INCANDESCENT_AURA - DeleteLocalInt(oMeldshaper, "MeldEssentia18634"); // MELD_WITCH_MELDSHIELD - DeleteLocalInt(oMeldshaper, "MeldEssentia18636"); // MELD_WITCH_DISPEL - DeleteLocalInt(oMeldshaper, "MeldEssentia18638"); // MELD_WITCH_SHACKLES - DeleteLocalInt(oMeldshaper, "MeldEssentia18640"); // MELD_WITCH_ABROGATION - DeleteLocalInt(oMeldshaper, "MeldEssentia18642"); // MELD_WITCH_SPIRITFLAY - DeleteLocalInt(oMeldshaper, "MeldEssentia18644"); // MELD_WITCH_INTEGUMENT - DeleteLocalInt(oMeldshaper, "NecrocarnumCircletPen"); - DeleteLocalInt(oMeldshaper, "AstralVambraces"); - DeleteLocalInt(oMeldshaper, "TemporaryEssentia"); - DestroyObject(GetItemPossessedBy(oMeldshaper, "moi_incarnatewpn")); // Remove any weapons created by Incarnate Weapon - - // Clean up any the natural weapons that are lying around - ClearNaturalWeapons(oMeldshaper); - // Nuke the creature weapons. If the normal form is supposed to have natural weapons, they'll get re-constructed - if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper))) MyDestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper)); - if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper))) MyDestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper)); - if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper))) MyDestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper)); - - if (GetLocalInt(oMeldshaper, "ClearEventTotem")) ClearEventScriptList(oMeldshaper, EVENT_ITEM_ONHIT, TRUE, TRUE); -} - -int GetShapedMeldsCount(object oMeldshaper) -{ - int i, nCount, nTest; - for (i = 0; i <= 20; i++) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_INCARNATE)+IntToString(i)); - if (nTest) // If it's not blank - nCount++; - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_SOULBORN)+IntToString(i)); - if (nTest) // If it's not blank - nCount++; - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_TOTEMIST)+IntToString(i)); - if (nTest) // If it's not blank - nCount++; - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_SPINEMELD_WARRIOR)+IntToString(i)); - if (nTest) // If it's not blank - nCount++; - } - if (DEBUG) DoDebug("GetTotalShapedMelds is "+IntToString(nCount)); - return nCount; -} - -int GetTotalShapedMelds(object oMeldshaper, int nClass) -{ - int i, nCount, nTest; - for (i = 0; i <= 20; i++) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(nClass)+IntToString(i)); - if (nTest) // If it's not blank - nCount++; - } - if (DEBUG) DoDebug("GetTotalShapedMelds is "+IntToString(nCount)); - return nCount; -} - -int CheckSplitChakra(object oMeldshaper, int nSlot) -{ - if (nSlot == INVENTORY_SLOT_HEAD && GetHasFeat(FEAT_SPLIT_CHAKRA_CROWN , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_BOOTS && GetHasFeat(FEAT_SPLIT_CHAKRA_FEET , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_ARMS && GetHasFeat(FEAT_SPLIT_CHAKRA_HANDS , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_ARMS && GetHasFeat(FEAT_SPLIT_CHAKRA_ARMS , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_HEAD && GetHasFeat(FEAT_SPLIT_CHAKRA_BROW , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_CLOAK && GetHasFeat(FEAT_SPLIT_CHAKRA_SHOULDERS, oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_NECK && GetHasFeat(FEAT_SPLIT_CHAKRA_THROAT , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_BELT && GetHasFeat(FEAT_SPLIT_CHAKRA_WAIST , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_CHEST && GetHasFeat(FEAT_SPLIT_CHAKRA_HEART , oMeldshaper)) return TRUE; - if (nSlot == INVENTORY_SLOT_CHEST && GetHasFeat(FEAT_SPLIT_CHAKRA_SOUL , oMeldshaper)) return TRUE; - - return FALSE; -} - -void BindMeldToChakra(object oMeldshaper, int nMeld, int nChakra, int nClass) -{ - // Make sure it's not in use already, and that you have any binds to make - if (!GetIsChakraBound(oMeldshaper, nChakra) && GetMaxBindCount(oMeldshaper, nClass)) - { - //FloatingTextStringOnCreature("BindMeldToChakra: nMeld "+IntToString(nMeld)+" nChakra "+IntToString(nChakra), oMeldshaper); - SetLocalInt(oMeldshaper, "BoundMeld"+IntToString(nChakra), nMeld); - ShapeSoulmeld(oMeldshaper, nMeld); - int nSlot = ChakraToSlot(DoubleChakraToChakra(nChakra)); // Can't have an item in a bound slot, unless Split Chakra - if (!CheckSplitChakra(oMeldshaper, nSlot)) ForceUnequip(oMeldshaper, GetItemInSlot(nSlot, oMeldshaper), nSlot); - } -} - -int GetTotalBoundMelds(object oMeldshaper) -{ - int i, nCount, nTest; - for (i = 0; i <= 22; i++) - { - nTest = GetLocalInt(oMeldshaper, "BoundMeld"+IntToString(i)); - if (nTest) // If it's not blank - nCount++; - } - if (DEBUG) DoDebug("GetTotalBoundMelds is "+IntToString(nCount)); - return nCount; -} - -int GetIsChakraUsed(object oMeldshaper, int nChakra, int nClass) -{ - int nTest = GetLocalInt(oMeldshaper, "UsedMeld"+IntToString(nClass)+IntToString(nChakra)); - - if (DEBUG) DoDebug("GetIsChakraUsed is "+IntToString(nTest)); - return nTest; -} - -void SetChakraUsed(object oMeldshaper, int nMeld, int nChakra, int nClass) -{ - // This isn't the same as binding, but can only have one soulmeld in each chakra - // Each class has its own limit on this, as per p20 of MoI - if (!GetIsChakraUsed(oMeldshaper, nChakra, nClass)) - { - SetLocalInt(oMeldshaper, "UsedMeld"+IntToString(nClass)+IntToString(nChakra), nMeld); - } -} - -int ChakraToSlot(int nChakra) -{ - if (nChakra == CHAKRA_CROWN ) return INVENTORY_SLOT_HEAD; - if (nChakra == CHAKRA_FEET ) return INVENTORY_SLOT_BOOTS; - if (nChakra == CHAKRA_HANDS ) return INVENTORY_SLOT_ARMS; - if (nChakra == CHAKRA_ARMS ) return INVENTORY_SLOT_ARMS; - if (nChakra == CHAKRA_BROW ) return INVENTORY_SLOT_HEAD; - if (nChakra == CHAKRA_SHOULDERS) return INVENTORY_SLOT_CLOAK; - if (nChakra == CHAKRA_THROAT ) return INVENTORY_SLOT_NECK; - if (nChakra == CHAKRA_WAIST ) return INVENTORY_SLOT_BELT; - if (nChakra == CHAKRA_HEART ) return INVENTORY_SLOT_CHEST; - if (nChakra == CHAKRA_SOUL ) return INVENTORY_SLOT_CHEST; - if (nChakra == CHAKRA_TOTEM ) return -1; // no slot associated - - return -1; -} - -void ChakraBindUnequip(object oMeldshaper, object oItem) -{ - int nTest = FALSE; - if (GetItemInSlot(INVENTORY_SLOT_HEAD, oMeldshaper) == oItem && (GetIsChakraBound(oMeldshaper, CHAKRA_CROWN) || GetIsChakraBound(oMeldshaper, CHAKRA_BROW))) nTest = INVENTORY_SLOT_HEAD + 1; - else if (GetItemInSlot(INVENTORY_SLOT_BOOTS, oMeldshaper) == oItem && GetIsChakraBound(oMeldshaper, CHAKRA_FEET)) nTest = INVENTORY_SLOT_BOOTS + 1; - else if (GetItemInSlot(INVENTORY_SLOT_ARMS, oMeldshaper) == oItem && (GetIsChakraBound(oMeldshaper, CHAKRA_ARMS) || GetIsChakraBound(oMeldshaper, CHAKRA_HANDS))) nTest = INVENTORY_SLOT_ARMS + 1; - else if (GetItemInSlot(INVENTORY_SLOT_CLOAK, oMeldshaper) == oItem && GetIsChakraBound(oMeldshaper, CHAKRA_SHOULDERS)) nTest = INVENTORY_SLOT_CLOAK + 1; - else if (GetItemInSlot(INVENTORY_SLOT_NECK, oMeldshaper) == oItem && GetIsChakraBound(oMeldshaper, CHAKRA_THROAT)) nTest = INVENTORY_SLOT_NECK + 1; - else if (GetItemInSlot(INVENTORY_SLOT_BELT, oMeldshaper) == oItem && GetIsChakraBound(oMeldshaper, CHAKRA_WAIST)) nTest = INVENTORY_SLOT_BELT + 1; - else if (GetItemInSlot(INVENTORY_SLOT_CHEST, oMeldshaper) == oItem && (GetIsChakraBound(oMeldshaper, CHAKRA_SOUL) || GetIsChakraBound(oMeldshaper, CHAKRA_HEART))) nTest = INVENTORY_SLOT_CHEST + 1; - if (DEBUG) DoDebug("ChakraBindUnequip is "+IntToString(nTest-1)); - if (nTest && !CheckSplitChakra(oMeldshaper, nTest-1) && GetIsItemPropertyValid(GetFirstItemProperty(oItem)) && oItem != GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper) && oItem != GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper) && - oItem != GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper) && oItem != GetItemInSlot(INVENTORY_SLOT_CARMOUR, oMeldshaper)) // If it's bound you can't equip in that slot - { - nTest = nTest - 1; - ForceUnequip(oMeldshaper, GetItemInSlot(nTest, oMeldshaper), nTest); - FloatingTextStringOnCreature("You cannot equip a magical item when you have bound a meld to the same chakra!", oMeldshaper, FALSE); - } -} - -string ChakraToString(int nChakra) -{ - string sReturn = ""; - if (nChakra == CHAKRA_CROWN || nChakra == CHAKRA_DOUBLE_CROWN ) sReturn = "Crown"; - if (nChakra == CHAKRA_FEET || nChakra == CHAKRA_DOUBLE_FEET ) sReturn = "Feet"; - if (nChakra == CHAKRA_HANDS || nChakra == CHAKRA_DOUBLE_HANDS ) sReturn = "Hands"; - if (nChakra == CHAKRA_ARMS || nChakra == CHAKRA_DOUBLE_ARMS ) sReturn = "Arms"; - if (nChakra == CHAKRA_BROW || nChakra == CHAKRA_DOUBLE_BROW ) sReturn = "Brow"; - if (nChakra == CHAKRA_SHOULDERS || nChakra == CHAKRA_DOUBLE_SHOULDERS) sReturn = "Shoulders"; - if (nChakra == CHAKRA_THROAT || nChakra == CHAKRA_DOUBLE_THROAT ) sReturn = "Throat"; - if (nChakra == CHAKRA_WAIST || nChakra == CHAKRA_DOUBLE_WAIST ) sReturn = "Waist"; - if (nChakra == CHAKRA_HEART || nChakra == CHAKRA_DOUBLE_HEART ) sReturn = "Heart"; - if (nChakra == CHAKRA_SOUL || nChakra == CHAKRA_DOUBLE_SOUL ) sReturn = "Soul"; - if (nChakra == CHAKRA_TOTEM || nChakra == CHAKRA_DOUBLE_TOTEM ) sReturn = "Totem"; - - if (DEBUG) DoDebug("ChakraToString is "+IntToString(nChakra)+", Return is "+sReturn); - return sReturn; -} - -int GetCanBindChakra(object oMeldshaper, int nChakra) -{ - if (nChakra == CHAKRA_CROWN && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 2)) return TRUE; - else if (nChakra == CHAKRA_FEET && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 4)) return TRUE; - else if (nChakra == CHAKRA_HANDS && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 4)) return TRUE; - else if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 9)) return TRUE; - else if (nChakra == CHAKRA_BROW && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 9)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 9)) return TRUE; - else if (nChakra == CHAKRA_THROAT && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_WAIST && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_HEART && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 16)) return TRUE; - else if (nChakra == CHAKRA_SOUL && - (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper) >= 19)) return TRUE; - - if (nChakra == CHAKRA_CROWN && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_FEET && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_HANDS && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_BROW && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_THROAT && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 18)) return TRUE; - else if (nChakra == CHAKRA_WAIST && - (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) >= 18)) return TRUE; - - if (nChakra == CHAKRA_CROWN && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 5)) return TRUE; - else if (nChakra == CHAKRA_FEET && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 5)) return TRUE; - else if (nChakra == CHAKRA_HANDS && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 5)) return TRUE; - else if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 9)) return TRUE; - else if (nChakra == CHAKRA_BROW && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 9)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 9)) return TRUE; - else if (nChakra == CHAKRA_THROAT && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_WAIST && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 14)) return TRUE; - else if (nChakra == CHAKRA_HEART && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 17)) return TRUE; - else if (nChakra == CHAKRA_TOTEM && - (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) >= 2)) return TRUE; - - if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper) >= 7)) return TRUE; - - if (nChakra == CHAKRA_CROWN && - (GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper) >= 3)) return TRUE; - else if (nChakra == CHAKRA_FEET && - (GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper) >= 3)) return TRUE; - else if (nChakra == CHAKRA_HANDS && - (GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper) >= 3)) return TRUE; - else if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_BROW && - (GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_SOULCASTER, oMeldshaper) >= 8)) return TRUE; - - if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper) >= 4)) return TRUE; - else if (nChakra == CHAKRA_WAIST && - (GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper) >= 6)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_HEART && - (GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper) >= 10)) return TRUE; - - if (nChakra == CHAKRA_CROWN && - (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >=4)) return TRUE; - else if (nChakra == CHAKRA_FEET && - (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >=4)) return TRUE; - else if (nChakra == CHAKRA_HANDS && - (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >=4)) return TRUE; - else if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >=9)) return TRUE; - else if (nChakra == CHAKRA_BROW && - (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >=9)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper) >=9)) return TRUE; - - if (nChakra == CHAKRA_ARMS && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 3)) return TRUE; - else if (nChakra == CHAKRA_BROW && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 3)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 3)) return TRUE; - else if (nChakra == CHAKRA_THROAT && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_WAIST && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 8)) return TRUE; - else if (nChakra == CHAKRA_HEART && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 11)) return TRUE; - else if (nChakra == CHAKRA_SOUL && - (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper) >= 13)) return TRUE; - - if (nChakra == CHAKRA_CROWN && GetHasFeat(FEAT_OPEN_LEAST_CHAKRA_CROWN, oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_FEET && GetHasFeat(FEAT_OPEN_LEAST_CHAKRA_FEET , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_HANDS && GetHasFeat(FEAT_OPEN_LEAST_CHAKRA_HANDS , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_ARMS && GetHasFeat(FEAT_OPEN_LESSER_CHAKRA_ARMS , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_BROW && GetHasFeat(FEAT_OPEN_LESSER_CHAKRA_BROW , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_SHOULDERS && GetHasFeat(FEAT_OPEN_LESSER_CHAKRA_SHOULDERS, oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_THROAT && GetHasFeat(FEAT_OPEN_GREATER_CHAKRA_THROAT , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_WAIST && GetHasFeat(FEAT_OPEN_GREATER_CHAKRA_WAIST , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_HEART && GetHasFeat(FEAT_OPEN_HEART_CHAKRA , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_SOUL && GetHasFeat(FEAT_OPEN_SOUL_CHAKRA , oMeldshaper)) return TRUE; - - if (nChakra == CHAKRA_DOUBLE_CROWN && GetHasFeat(FEAT_DOUBLE_CHAKRA_CROWN, oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_FEET && GetHasFeat(FEAT_DOUBLE_CHAKRA_FEET , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_HANDS && GetHasFeat(FEAT_DOUBLE_CHAKRA_HANDS , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_ARMS && GetHasFeat(FEAT_DOUBLE_CHAKRA_ARMS , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_BROW && GetHasFeat(FEAT_DOUBLE_CHAKRA_BROW , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_SHOULDERS && GetHasFeat(FEAT_DOUBLE_CHAKRA_SHOULDERS, oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_THROAT && GetHasFeat(FEAT_DOUBLE_CHAKRA_THROAT , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_WAIST && GetHasFeat(FEAT_DOUBLE_CHAKRA_WAIST , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_HEART && GetHasFeat(FEAT_DOUBLE_CHAKRA_HEART , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_SOUL && GetHasFeat(FEAT_DOUBLE_CHAKRA_SOUL , oMeldshaper)) return TRUE; - else if (nChakra == CHAKRA_DOUBLE_TOTEM && GetHasFeat(FEAT_DOUBLE_CHAKRA_TOTEM , oMeldshaper)) return TRUE; - - return FALSE; -} - -int GetMaxEssentiaCount(object oMeldshaper, int nClass) -{ - int nMax = StringToInt(Get2DACache(GetMeldshapingClassFile(nClass), "Essentia", GetIncarnumLevelForClass(nClass, oMeldshaper)-1)); - if (DEBUG) DoDebug("GetMaxEssentiaCount is "+IntToString(nMax)); - return nMax; -} - -void SpawnTempEssentiaChecker(object oMeldshaper) -{ - int nCur = GetTemporaryEssentia(oMeldshaper); - int nPrv = GetLocalInt(oMeldshaper, "TempEssTest"); - int nRed = nPrv - nCur; - // If we've lost some - if (nPrv > nCur) - { - int i, nCount, nTest; - for (i = 18700; i < 18799; i++) - { - nTest = GetLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(i)); - if (nTest) // If it's not blank - { - if (DEBUG) DoDebug("Found "+IntToString(nTest)+" Temp Essentia in Meld "+IntToString(i)); - // There's still some temp essentia left in the meld - if (nTest > nRed) - { - int nChange = nTest-nRed; - SetLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(i), nChange); - SetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i), GetEssentiaInvested(oMeldshaper, i)-nChange); - ShapeSoulmeld(oMeldshaper, i); - if (DEBUG) DoDebug("Reducing Essentia in Meld "+IntToString(i)+" by "+IntToString(nChange)); - } - else // Means the reduction is higher than the temp essentia ammount - { - // No more temp essentia here - DeleteLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(i)); - SetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i), GetEssentiaInvested(oMeldshaper, i)-nTest); - ShapeSoulmeld(oMeldshaper, i); - if (DEBUG) DoDebug("Deleted Temp Essentia in Meld "+IntToString(i)+", total "+IntToString(nTest)); - } - - // Reduce the remaining amount of reduction by the amount we just used up - nRed = nRed - nTest; - if (DEBUG) DoDebug("Remaining Temp Essentia to reduce "+IntToString(nRed)); - if (0 >= nRed) break; // End the loop if we're done - } - } - } - // If we still have some left - if (nCur > 0) - { - SetLocalInt(oMeldshaper, "TempEssTest", nCur); - DelayCommand(1.0, SpawnTempEssentiaChecker(oMeldshaper)); - } - else - DeleteLocalInt(oMeldshaper, "TempEssTest"); -} - -void InvestEssentia(object oMeldshaper, int nMeld, int nEssentia) -{ - // Use up expanded soulmeld capacity - if (nEssentia > 1000) - { - nEssentia -= 1000; - SetIsSoulmeldCapacityUsed(oMeldshaper, nMeld); - } - int nClass = GetMeldShapedClass(oMeldshaper, nMeld); - // Special capacity of 1/2 class level - if (nMeld == MELD_SPINE_ENHANCEMENT) nEssentia = min(nEssentia, (GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper)/2)); - else if (nEssentia > GetMaxEssentiaCapacity(oMeldshaper, nClass, nMeld)) nEssentia = GetMaxEssentiaCapacity(oMeldshaper, nClass, nMeld); - // Can't invest more than you have - if (nEssentia > GetTotalUsableEssentia(oMeldshaper)) nEssentia = GetTotalUsableEssentia(oMeldshaper); - - // All of this garbage to handle temporary essentia - if (GetLocalInt(oMeldshaper, "InvestingTempEssentia")) - { - SetLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(nMeld), nEssentia); - SpawnTempEssentiaChecker(oMeldshaper); - DeleteLocalInt(oMeldshaper, "InvestingTempEssentia"); - } - - FloatingTextStringOnCreature("Investing "+IntToString(nEssentia)+" essentia into "+GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nMeld))), oMeldshaper, FALSE); - SetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(nMeld), nEssentia); - SetLocalInt(oMeldshaper, "EssentiaRound"+IntToString(nMeld), TRUE); // This is used by Melds that only trigger on the round that essentia is invested into it - DelayCommand(6.0, DeleteLocalInt(oMeldshaper, "EssentiaRound"+IntToString(nMeld))); -} - -int GetTotalEssentiaInvested(object oMeldshaper) -{ - int i, nCount, nTest; - for (i = 18700; i < 18799; i++) - { - nTest = GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i)); - if (nTest) // If it's not blank - nCount += nTest; - } - nCount += GetFeatLockedEssentia(oMeldshaper); - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_SPINE_ENHANCEMENT)); // MELD_SPINE_ENHANCEMENT - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_IRONSOUL_SHIELD)); // MELD_IRONSOUL_SHIELD - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_IRONSOUL_ARMOR)); // MELD_IRONSOUL_ARMOR - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_IRONSOUL_WEAPON)); // MELD_IRONSOUL_WEAPON - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_STEP )); // MELD_UMBRAL_STEP - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_SHADOW)); // MELD_UMBRAL_SHADOW - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_SIGHT )); // MELD_UMBRAL_SIGHT - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_SOUL )); // MELD_UMBRAL_SOUL - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_KISS )); // MELD_UMBRAL_KISS - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_DUSKLING_SPEED)); // MELD_DUSKLING_SPEED - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_STRIKE)); // MELD_INCANDESCENT_STRIKE - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_HEAL )); // MELD_INCANDESCENT_HEAL - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_COUNTENANCE)); // MELD_INCANDESCENT_COUNTENANCE - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_RAY )); // MELD_INCANDESCENT_RAY - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_AURA )); // MELD_INCANDESCENT_AURA - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_MELDSHIELD)); // MELD_WITCH_MELDSHIELD - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_DISPEL )); // MELD_WITCH_DISPEL - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_SHACKLES )); // MELD_WITCH_SHACKLES - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_ABROGATION)); // MELD_WITCH_ABROGATION - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_SPIRITFLAY)); // MELD_WITCH_SPIRITFLAY - nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_INTEGUMENT)); // MELD_WITCH_INTEGUMENT - if (DEBUG) DoDebug("GetTotalEssentiaInvested is "+IntToString(nCount)); - return nCount; -} - -int EssentiaIDToRealID(int nEssentiaID) -{ - int i, nReal, nTest; - for (i = 1; i < 100; i++) - { - nTest = StringToInt(Get2DACache("soulmelds", "EssentiaID", i)); - if (nTest == nEssentiaID) // If it's been found - { - nReal = StringToInt(Get2DACache("soulmelds", "SpellID", i)); - break; - } - } - - if (nEssentiaID == 18690) nReal = MELD_SPINE_ENHANCEMENT; - else if (nEssentiaID == 18686) nReal = MELD_IRONSOUL_SHIELD; - else if (nEssentiaID == 18684) nReal = MELD_IRONSOUL_ARMOR; - else if (nEssentiaID == 18682) nReal = MELD_IRONSOUL_WEAPON; - else if (nEssentiaID == 18680) nReal = MELD_UMBRAL_STEP; - else if (nEssentiaID == 18678) nReal = MELD_UMBRAL_SHADOW; - else if (nEssentiaID == 18676) nReal = MELD_UMBRAL_SIGHT; - else if (nEssentiaID == 18674) nReal = MELD_UMBRAL_SOUL; - else if (nEssentiaID == 18672) nReal = MELD_UMBRAL_KISS; - else if (nEssentiaID == 18669) nReal = MELD_INCANDESCENT_STRIKE; - else if (nEssentiaID == 18667) nReal = MELD_INCANDESCENT_HEAL ; - else if (nEssentiaID == 18665) nReal = MELD_INCANDESCENT_COUNTENANCE; - else if (nEssentiaID == 18662) nReal = MELD_INCANDESCENT_RAY ; - else if (nEssentiaID == 18661) nReal = MELD_INCANDESCENT_AURA ; - else if (nEssentiaID == 18633) nReal = MELD_WITCH_MELDSHIELD; - else if (nEssentiaID == 18635) nReal = MELD_WITCH_DISPEL; - else if (nEssentiaID == 18637) nReal = MELD_WITCH_SHACKLES; - else if (nEssentiaID == 18639) nReal = MELD_WITCH_ABROGATION; - else if (nEssentiaID == 18641) nReal = MELD_WITCH_SPIRITFLAY; - else if (nEssentiaID == 18643) nReal = MELD_WITCH_INTEGUMENT; - - if (DEBUG) DoDebug("EssentiaToRealID: nEssentiaID "+IntToString(nEssentiaID)+" nReal "+IntToString(nReal)); - return nReal; // Return the real spellID -} - -void DrainEssentia(object oMeldshaper) -{ - //FloatingTextStringOnCreature("DrainEssentia", oMeldshaper); - int i; - for (i = 18700; i < 18799; i++) - { - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i)); - } - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_DUSKLING_SPEED)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_SPINE_ENHANCEMENT)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_IRONSOUL_SHIELD)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_IRONSOUL_ARMOR)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_IRONSOUL_WEAPON)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_STEP )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_SHADOW)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_SIGHT )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_SOUL )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_UMBRAL_KISS )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_STRIKE)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_HEAL )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_COUNTENANCE)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_RAY )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_INCANDESCENT_AURA )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_MELDSHIELD)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_DISPEL )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_SHACKLES )); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_ABROGATION)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_SPIRITFLAY)); - DeleteLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_INTEGUMENT)); -} - -void WipeMelds(object oMeldshaper) -{ - //FloatingTextStringOnCreature("WipeMelds", oMeldshaper); - int i; - for (i = 18700; i < 18799; i++) - { - PRCRemoveSpellEffects(i, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(i, oMeldshaper, FALSE); - } - PRCRemoveSpellEffects(MELD_DUSKLING_SPEED, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_DUSKLING_SPEED, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_SPINE_ENHANCEMENT, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_SPINE_ENHANCEMENT, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_IRONSOUL_SHIELD, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_IRONSOUL_SHIELD, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_IRONSOUL_ARMOR, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_IRONSOUL_ARMOR, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_IRONSOUL_WEAPON, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_IRONSOUL_WEAPON, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_UMBRAL_STEP, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_UMBRAL_STEP, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_UMBRAL_SHADOW, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_UMBRAL_SHADOW, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_UMBRAL_SIGHT, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_UMBRAL_SIGHT, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_UMBRAL_SOUL, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_UMBRAL_SOUL, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_UMBRAL_KISS, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_UMBRAL_KISS, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_INCANDESCENT_STRIKE, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_INCANDESCENT_STRIKE, oMeldshaper, FALSE); - PRCRemoveSpellEffects(MELD_WITCH_MELDSHIELD, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(MELD_WITCH_MELDSHIELD, oMeldshaper, FALSE); - for (i = 18647; i < 18657; i++) - { - PRCRemoveSpellEffects(i, oMeldshaper, oMeldshaper); - GZPRCRemoveSpellEffects(i, oMeldshaper, FALSE); - } -} - -void ReshapeMelds(object oMeldshaper) -{ - // Check each class and run the loop - if (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper)) - { - int i, nTest; - for (i = 0; i <= 20; i++) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_INCARNATE)+IntToString(i)); - if (nTest) // If it's not blank, recast it - { - //FloatingTextStringOnCreature("ReshapeMelds: CLASS_TYPE_INCARNATE nTest "+IntToString(nTest), oMeldshaper); - ActionCastSpellOnSelf(nTest); - } - } - } - if (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper)) - { - int i, nTest; - for (i = 0; i <= 20; i++) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_SOULBORN)+IntToString(i)); - if (nTest) // If it's not blank, recast it - { - //FloatingTextStringOnCreature("ReshapeMelds: CLASS_TYPE_SOULBORN nTest "+IntToString(nTest), oMeldshaper); - ActionCastSpellOnSelf(nTest); - } - } - } - if (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper)) - { - int i, nTest; - for (i = 0; i <= 20; i++) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_TOTEMIST)+IntToString(i)); - if (nTest) // If it's not blank, recast it - { - //FloatingTextStringOnCreature("ReshapeMelds: CLASS_TYPE_TOTEMIST nTest "+IntToString(nTest), oMeldshaper); - ActionCastSpellOnSelf(nTest); - } - } - } - if (GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper)) - { - ActionCastSpellOnSelf(MELD_SPINE_ENHANCEMENT); - int i, nTest; - for (i = 0; i <= 20; i++) - { - nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(CLASS_TYPE_SPINEMELD_WARRIOR)+IntToString(i)); - if (nTest) // If it's not blank, recast it - { - //FloatingTextStringOnCreature("ReshapeMelds: CLASS_TYPE_TOTEMIST nTest "+IntToString(nTest), oMeldshaper); - ActionCastSpellOnSelf(nTest); - } - } - } - int nIron = GetLevelByClass(CLASS_TYPE_IRONSOUL_FORGEMASTER, oMeldshaper); - if (nIron) - { - ActionCastSpellOnSelf(MELD_IRONSOUL_SHIELD); - if (nIron >= 5) ActionCastSpellOnSelf(MELD_IRONSOUL_ARMOR); - if (nIron >= 9) ActionCastSpellOnSelf(MELD_IRONSOUL_WEAPON); - } - int nUmbral = GetLevelByClass(CLASS_TYPE_UMBRAL_DISCIPLE, oMeldshaper); - if (nUmbral) - { - ActionCastSpellOnSelf(MELD_UMBRAL_STEP); - if (nUmbral >= 3) ActionCastSpellOnSelf(MELD_UMBRAL_SHADOW); - if (nUmbral >= 7) ActionCastSpellOnSelf(MELD_UMBRAL_SIGHT); - if (nUmbral >= 9) ActionCastSpellOnSelf(MELD_UMBRAL_SOUL); - if (nUmbral >= 10) ActionCastSpellOnSelf(MELD_UMBRAL_KISS); - } - int nIncand = GetLevelByClass(CLASS_TYPE_INCANDESCENT_CHAMPION, oMeldshaper); - if (nIncand) - { - ActionCastSpellOnSelf(MELD_INCANDESCENT_STRIKE); - } - if(GetLevelByClass(CLASS_TYPE_WITCHBORN_BINDER, oMeldshaper)) ActionCastSpellOnSelf(MELD_WITCH_MELDSHIELD); - if (GetRacialType(oMeldshaper) == RACIAL_TYPE_DUSKLING) ActionCastSpellOnSelf(MELD_DUSKLING_SPEED); -} - -int EssentiaToD4(int nEssentia) -{ - if (nEssentia == 1 ) return IP_CONST_DAMAGEBONUS_1d4; - else if (nEssentia == 2) return IP_CONST_DAMAGEBONUS_2d4; - else if (nEssentia == 3) return IP_CONST_DAMAGEBONUS_3d4; - else if (nEssentia == 4) return IP_CONST_DAMAGEBONUS_4d4; - else if (nEssentia == 5) return IP_CONST_DAMAGEBONUS_5d4; - else if (nEssentia == 6) return IP_CONST_DAMAGEBONUS_6d4; - else if (nEssentia == 7) return IP_CONST_DAMAGEBONUS_7d4; - else if (nEssentia == 8) return IP_CONST_DAMAGEBONUS_8d4; - else if (nEssentia == 9) return IP_CONST_DAMAGEBONUS_9d4; - else if (nEssentia >= 10) return IP_CONST_DAMAGEBONUS_10d4; - - return -1; -} - -int IncarnateAlignment(object oMeldshaper) -{ - int nReturn = FALSE; - - if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_LAWFUL && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_NEUTRAL) - { - nReturn = TRUE; - } - else if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_CHAOTIC && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_NEUTRAL) - { - nReturn = TRUE; - } - else if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_NEUTRAL && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_GOOD) - { - nReturn = TRUE; - } - else if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_NEUTRAL && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_EVIL) - { - nReturn = TRUE; - } - - return nReturn; -} - -int GetOpposition(object oMeldshaper, object oTarget) -{ - int nReturn = FALSE; - if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_LAWFUL && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_GOOD && (GetAlignmentGoodEvil(oTarget) == ALIGNMENT_EVIL || GetAlignmentLawChaos(oTarget) == ALIGNMENT_CHAOTIC)) - nReturn = TRUE; - if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_LAWFUL && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_EVIL && (GetAlignmentGoodEvil(oTarget) == ALIGNMENT_GOOD || GetAlignmentLawChaos(oTarget) == ALIGNMENT_CHAOTIC)) - nReturn = TRUE; - if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_CHAOTIC && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_GOOD && (GetAlignmentGoodEvil(oTarget) == ALIGNMENT_EVIL || GetAlignmentLawChaos(oTarget) == ALIGNMENT_LAWFUL)) - nReturn = TRUE; - if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_CHAOTIC && GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_EVIL && (GetAlignmentGoodEvil(oTarget) == ALIGNMENT_GOOD || GetAlignmentLawChaos(oTarget) == ALIGNMENT_LAWFUL)) - nReturn = TRUE; - - return nReturn; -} - -void SetTemporaryEssentia(object oMeldshaper, int nEssentia) -{ - if (DEBUG) DoDebug("Set Temporary Essentia from "+IntToString(GetLocalInt(oMeldshaper, "TemporaryEssentia"))+" to "+IntToString(GetLocalInt(oMeldshaper, "TemporaryEssentia")+nEssentia)); - SetLocalInt(oMeldshaper, "TemporaryEssentia", GetLocalInt(oMeldshaper, "TemporaryEssentia")+nEssentia); -} - -int GetTemporaryEssentia(object oMeldshaper) -{ - return GetLocalInt(oMeldshaper, "TemporaryEssentia"); -} - -int GetMaxEssentiaCapacityFeat(object oMeldshaper) -{ - int nMax = 1; // Always can invest one - int nHD = GetHitDice(oMeldshaper); - if (nHD >= 31) nMax = 5; - else if (nHD >= 18) nMax = 4; - else if (nHD >= 12) nMax = 3; - else if (nHD >= 6) nMax = 2; - - if (GetLocalInt(oMeldshaper, "DivineSoultouch")) nMax += 1; - if (GetLocalInt(oMeldshaper, "IncandescentOverload")) nMax += max(GetAbilityModifier(ABILITY_CHARISMA, oMeldshaper), 1); - if (GetHasFeat(FEAT_IMPROVED_ESSENTIA_CAPACITY, oMeldshaper)) nMax += 1; - - // Don't allow more than they have - if (nMax > GetTotalUsableEssentia(oMeldshaper)) nMax = GetTotalUsableEssentia(oMeldshaper); - - if (DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax)); - return nMax; -} - -void SapphireSmiteUses(object oMeldshaper, int nEssentia) -{ - int i; - - for (i = 1; i <= nEssentia; i++) - { - IncrementRemainingFeatUses(oMeldshaper, FEAT_SMITE_GOOD_ALIGN); // Fist of Raziel - IncrementRemainingFeatUses(oMeldshaper, FEAT_SMITE_EVIL); // Paladin - IncrementRemainingFeatUses(oMeldshaper, FEAT_SMITE_GOOD); // Blackguard - IncrementRemainingFeatUses(oMeldshaper, FEAT_KIAI_SMITE); // CW Samurai - IncrementRemainingFeatUses(oMeldshaper, FEAT_CRUSADER_SMITE); // Crusader - IncrementRemainingFeatUses(oMeldshaper, FEAT_SMITE_UNDEAD); // Soldier of Light - IncrementRemainingFeatUses(oMeldshaper, FEAT_SHADOWBANE_SMITE); // Shadowbane - IncrementRemainingFeatUses(oMeldshaper, FEAT_KILLOREN_ASPECT_D); // Killoren - IncrementRemainingFeatUses(oMeldshaper, FEAT_SMITE_OPPOSITION); // Soulborn - IncrementRemainingFeatUses(oMeldshaper, FEAT_CULTIST_SMITE_MAGE); // Cultist of the Shattered Peak - } -} - -void AzureEnmity(object oMeldshaper, int nEssentia) -{ - effect eLink = EffectLinkEffects(EffectSkillIncrease(SKILL_BLUFF, nEssentia), EffectSkillIncrease(SKILL_LISTEN, nEssentia)); - eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_SENSE_MOTIVE, nEssentia)); - eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_SPOT, nEssentia)); - eLink = EffectLinkEffects(eLink, EffectDamageIncrease(IPGetDamageBonusConstantFromNumber(nEssentia), DAMAGE_TYPE_BASE_WEAPON)); - - if(GetHasFeat(FEAT_FAVORED_ENEMY_ABERRATION, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_ABERRATION)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_ANIMAL, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_ANIMAL)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_BEAST, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_BEAST)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_CONSTRUCT, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_CONSTRUCT)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_DRAGON, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_DRAGON)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_DWARF, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_DWARF)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_ELEMENTAL, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_ELEMENTAL)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_ELF, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_ELF)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_FEY, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_FEY)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_GIANT, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_GIANT)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_GNOME, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_GNOME)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_GOBLINOID, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HUMANOID_GOBLINOID)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_HALFELF, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HALFELF)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_HALFLING, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HALFLING)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_HALFORC, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HALFORC)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_HUMAN, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HUMAN)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_MAGICAL_BEAST, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_MAGICAL_BEAST)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_MONSTROUS, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HUMANOID_MONSTROUS)), oMeldshaper, 9999.0); - if(GetHasFeat(RACIAL_TYPE_HUMANOID_ORC, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HUMANOID_ORC)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_OUTSIDER, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_OUTSIDER)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_REPTILIAN, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_HUMANOID_REPTILIAN)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_SHAPECHANGER, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_SHAPECHANGER)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_UNDEAD, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_UNDEAD)), oMeldshaper, 9999.0); - if(GetHasFeat(FEAT_FAVORED_ENEMY_VERMIN, oMeldshaper)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusRacialTypeEffect(eLink, RACIAL_TYPE_VERMIN)), oMeldshaper, 9999.0); -} - -void DoFeatBonus(object oMeldshaper, int nFeat, int nEssentia) -{ - effect eLink; - if (nFeat == FEAT_CERULEAN_FORTITUDE) eLink = EffectSavingThrowIncrease(SAVING_THROW_FORT, nEssentia); - else if (nFeat == FEAT_CERULEAN_REFLEXES) eLink = EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nEssentia); - else if (nFeat == FEAT_CERULEAN_WILL) eLink = EffectSavingThrowIncrease(SAVING_THROW_WILL, nEssentia); - else if (nFeat == FEAT_AZURE_TALENT) ExecuteScript("moi_ft_aztalent", oMeldshaper); - else if (nFeat == FEAT_AZURE_TOUGHNESS) eLink = EffectTemporaryHitpoints(3*nEssentia); - else if (nFeat == FEAT_HEALING_SOUL) FeatUsePerDay(oMeldshaper, FEAT_HEALING_SOUL, -1, 0, nEssentia); - else if (nFeat == FEAT_SAPPHIRE_SMITE) SapphireSmiteUses(oMeldshaper, nEssentia); - else if (nFeat == FEAT_AZURE_ENMITY) AzureEnmity(oMeldshaper, nEssentia); - - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oMeldshaper, 9999.0); -} - -void InvestEssentiaFeat(object oMeldshaper, int nFeat, int nEssentia) -{ - // Jump out if there's no feat - if (!GetHasFeat(nFeat, oMeldshaper)) return; - - int nMax = GetMaxEssentiaCapacityFeat(oMeldshaper); - - // Bonuses to specific feat caps - if (nFeat == FEAT_COBALT_RAGE && GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oMeldshaper)) nMax++; - - // No breaking the rules - if (nEssentia > nMax) nEssentia = nMax; - // Can't invest more than you have - if (nEssentia > GetTotalUsableEssentia(oMeldshaper)) nEssentia = GetTotalUsableEssentia(oMeldshaper); - - FloatingTextStringOnCreature("Investing "+IntToString(nEssentia)+" essentia into "+GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))), oMeldshaper); - DoFeatBonus(oMeldshaper, nFeat, nEssentia); - SetLocalInt(oMeldshaper, "FeatEssentia"+IntToString(nFeat), nEssentia); -} - -void DoClassBonus(object oMeldshaper, int nFeat, int nEssentia) -{ - -} - -void InvestEssentiaClass(object oMeldshaper, int nFeat, int nEssentia) -{ - // Jump out if there's no feat - if (!GetHasFeat(nFeat, oMeldshaper)) return; - - // No breaking the rules - if (nEssentia > GetMaxEssentiaCapacityFeat(oMeldshaper)) nEssentia = GetMaxEssentiaCapacityFeat(oMeldshaper); - // Can't invest more than you have - if (nEssentia > GetTotalUsableEssentia(oMeldshaper)) nEssentia = GetTotalUsableEssentia(oMeldshaper); - - FloatingTextStringOnCreature("Investing "+IntToString(nEssentia)+" essentia into "+GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))), oMeldshaper); - DoClassBonus(oMeldshaper, nFeat, nEssentia); - SetLocalInt(oMeldshaper, "ClassEssentia"+IntToString(nFeat), nEssentia); -} - -void InvestEssentiaSpell(object oMeldshaper, int nFeat, int nEssentia) -{ - FloatingTextStringOnCreature("Investing "+IntToString(nEssentia)+" essentia into "+GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nFeat))), oMeldshaper); - SetLocalInt(oMeldshaper, "SpellEssentia"+IntToString(nFeat), nEssentia); - if (!GetLocalInt(oMeldshaper, "SpellInvestCheck1")) SetLocalInt(oMeldshaper, "SpellInvestCheck1", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck2")) SetLocalInt(oMeldshaper, "SpellInvestCheck2", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck3")) SetLocalInt(oMeldshaper, "SpellInvestCheck3", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck4")) SetLocalInt(oMeldshaper, "SpellInvestCheck4", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck5")) SetLocalInt(oMeldshaper, "SpellInvestCheck5", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck6")) SetLocalInt(oMeldshaper, "SpellInvestCheck6", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck7")) SetLocalInt(oMeldshaper, "SpellInvestCheck7", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck8")) SetLocalInt(oMeldshaper, "SpellInvestCheck8", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck9")) SetLocalInt(oMeldshaper, "SpellInvestCheck9", nFeat); - else if (!GetLocalInt(oMeldshaper, "SpellInvestCheck10")) SetLocalInt(oMeldshaper, "SpellInvestCheck10", nFeat); -} - -int GetFeatLockedEssentia(object oMeldshaper) -{ - int nTotal, i, nTest; - for (i = 8869; i < 8889; i++) - { - nTest = GetLocalInt(oMeldshaper, "FeatEssentia"+IntToString(i)); - if (nTest) // If it's not blank - nTotal += nTest; - } - for (i = 0; i < 11; i++) - { - nTest = GetLocalInt(oMeldshaper, "SpellInvestCheck"+IntToString(i)); - if (nTest) // If it's not blank - nTotal += GetLocalInt(oMeldshaper, "SpellEssentia"+IntToString(nTest)); - } - if (DEBUG) DoDebug("GetFeatLockedEssentia return value "+IntToString(nTotal)); - return nTotal; -} - -int IncarnumFeats(object oMeldshaper) -{ - int nEssentia; - - if (GetHasFeat(FEAT_AZURE_ENMITY, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_CERULEAN_FORTITUDE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_CERULEAN_REFLEXES, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_CERULEAN_WILL, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_AZURE_TALENT, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_AZURE_TOUCH, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_AZURE_TOUGHNESS, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_AZURE_TURNING, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_AZURE_WILD_SHAPE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_COBALT_CHARGE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_COBALT_EXPERTISE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_COBALT_POWER, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_COBALT_RAGE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_HEALING_SOUL, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_INCARNUM_SPELLSHAPING, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_INDIGO_STRIKE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_MIDNIGHT_AUGMENTATION, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_MIDNIGHT_DODGE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_MIDNIGHT_METAMAGIC, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_PSYCARNUM_BLADE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_SAPPHIRE_SMITE, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_SOULTOUCHED_SPELLCASTING, oMeldshaper)) nEssentia += 1; - if (GetHasFeat(FEAT_BONUS_ESSENTIA, oMeldshaper)) - { - nEssentia += 1; - if(GetIsIncarnumUser(oMeldshaper)) - nEssentia += 1; // Yes, this is correct - } - if (GetRacialType(oMeldshaper) == RACIAL_TYPE_DUSKLING) nEssentia += 1; - if (GetRacialType(oMeldshaper) == RACIAL_TYPE_AZURIN) nEssentia += 1; - - int i; - for(i = FEAT_EPIC_ESSENTIA_1; i <= FEAT_EPIC_ESSENTIA_6; i++) - if(GetHasFeat(i, oMeldshaper)) nEssentia += 3; - - if (DEBUG) DoDebug("IncarnumFeats return value "+IntToString(nEssentia)); - return nEssentia; -} - -void AddNecrocarnumEssentia(object oMeldshaper, int nEssentia) -{ - int nNecrocarnum = GetLocalInt(oMeldshaper, "NecrocarnumEssentia"); - SetLocalInt(oMeldshaper, "NecrocarnumEssentia", nNecrocarnum+nEssentia); - // It lasts for 24 hours, then remove it back out - DelayCommand(HoursToSeconds(24), SetLocalInt(oMeldshaper, "NecrocarnumEssentia", GetLocalInt(oMeldshaper, "NecrocarnumEssentia")-nEssentia)); -} - -int GetTotalEssentia(object oMeldshaper) -{ - int nEssentia; - - if (GetLevelByClass(CLASS_TYPE_INCARNATE, oMeldshaper)) nEssentia += GetMaxEssentiaCount(oMeldshaper, CLASS_TYPE_INCARNATE); - if (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper)) nEssentia += GetMaxEssentiaCount(oMeldshaper, CLASS_TYPE_SOULBORN); - if (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper)) nEssentia += GetMaxEssentiaCount(oMeldshaper, CLASS_TYPE_TOTEMIST); - if (GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper)) nEssentia += GetMaxEssentiaCount(oMeldshaper, CLASS_TYPE_SPINEMELD_WARRIOR); - if (GetLevelByClass(CLASS_TYPE_UMBRAL_DISCIPLE, oMeldshaper)) nEssentia += GetMaxEssentiaCount(oMeldshaper, CLASS_TYPE_UMBRAL_DISCIPLE); - if (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper)) nEssentia += GetLocalInt(oMeldshaper, "NecrocarnumEssentia"); - if (GetLevelByClass(CLASS_TYPE_WITCHBORN_BINDER, oMeldshaper) >= 2) nEssentia += 1; - if (GetLevelByClass(CLASS_TYPE_WITCHBORN_BINDER, oMeldshaper) >= 6) nEssentia += 1; - - nEssentia += IncarnumFeats(oMeldshaper); - if (DEBUG) DoDebug("GetTotalEssentia return value "+IntToString(nEssentia)); - return nEssentia; -} - -int GetTotalUsableEssentia(object oMeldshaper) -{ - return GetTotalEssentia(oMeldshaper) - GetFeatLockedEssentia(oMeldshaper); -} - -int GetIncarnumFeats(object oMeldshaper) -{ - int nTotal, i; - for (i = 8868; i < 8910; i++) - { - if (GetHasFeat(i, oMeldshaper)) - nTotal += 1; - } - if (DEBUG) DoDebug("GetIncarnumFeats return value "+IntToString(nTotal)); - return nTotal; -} - -int GetIsBlademeldUsed(object oMeldshaper, int nChakra) -{ - int nTest = GetLocalInt(oMeldshaper, "UsedBladeMeld"+IntToString(nChakra)); - - if (DEBUG) DoDebug("GetIsBlademeldUsed is "+IntToString(nTest)); - return nTest; -} - -void SetBlademeldUsed(object oMeldshaper, int nChakra) -{ - if (!GetIsBlademeldUsed(oMeldshaper, nChakra)) - { - SetLocalInt(oMeldshaper, "UsedBladeMeld"+IntToString(nChakra), nChakra); - } -} - -string GetBlademeldDesc(int nChakra) -{ - string sString; - if (nChakra == CHAKRA_CROWN ) sString = "You gain a +4 bonus on disarm checks and on Sense Motive"; - if (nChakra == CHAKRA_FEET ) sString = "You gain a +2 bonus on Initiative"; - if (nChakra == CHAKRA_HANDS ) sString = "You gain a +1 bonus on damage"; - if (nChakra == CHAKRA_ARMS ) sString = "You gain a +2 bonus on attack rolls"; - if (nChakra == CHAKRA_BROW ) sString = "You gain the Blind-Fight feat"; - if (nChakra == CHAKRA_SHOULDERS) sString = "You gain immunity to criticals but not sneak attacks"; - if (nChakra == CHAKRA_THROAT ) sString = "At will as a standard action, each enemy within 60 feet who can hear you shout must save or become shaken for 1 round (Will DC 10 + incarnum blade level + Con modifier)."; - if (nChakra == CHAKRA_WAIST ) sString = "You gain a +10 bonus on checks made to avoid being bull rushed, grappled, tripped, or overrun. You also gain Uncanny Dodge"; - if (nChakra == CHAKRA_HEART ) sString = "You gain temporary hit points equal to twice your character level (maximum +40)"; - if (nChakra == CHAKRA_SOUL ) sString = "You break DR up to +3, and deal 1d6 damage to creatures of one opposed alignment"; - - return sString; -} - -int ChakraToBlademeld(int nChakra) -{ - int nMeld; - if (nChakra == CHAKRA_CROWN ) nMeld = MELD_BLADEMELD_CROWN; - if (nChakra == CHAKRA_FEET ) nMeld = MELD_BLADEMELD_FEET; - if (nChakra == CHAKRA_HANDS ) nMeld = MELD_BLADEMELD_HANDS; - if (nChakra == CHAKRA_ARMS ) nMeld = MELD_BLADEMELD_ARMS; - if (nChakra == CHAKRA_BROW ) nMeld = MELD_BLADEMELD_BROW; - if (nChakra == CHAKRA_SHOULDERS) nMeld = MELD_BLADEMELD_SHOULDERS; - if (nChakra == CHAKRA_THROAT ) nMeld = MELD_BLADEMELD_THROAT; - if (nChakra == CHAKRA_WAIST ) nMeld = MELD_BLADEMELD_WAIST; - if (nChakra == CHAKRA_HEART ) nMeld = MELD_BLADEMELD_HEART; - if (nChakra == CHAKRA_SOUL ) nMeld = MELD_BLADEMELD_SOUL; - - return nMeld; -} \ No newline at end of file diff --git a/trunk/include/nw_o2_coninclude.nss b/trunk/include/nw_o2_coninclude.nss deleted file mode 100644 index 4a250bd0..00000000 --- a/trunk/include/nw_o2_coninclude.nss +++ /dev/null @@ -1,4791 +0,0 @@ -//:://///////////////////////////////////////////// -//:: NW_O2_CONINCLUDE.nss -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - This include file handles the random treasure - distribution for treasure from creatures and containers - - [ ] Documented -*/ -//::////////////////////////////////////////////// -//:: Created By: Brent, Andrew -//:: Created On: November - May -//:: -//:: Updated for .35 by Jaysyn 2023/03/10 -//::////////////////////////////////////////////// -// :: MODS -// April 23 2002: Removed animal parts. They were silly. -// May 6 2002: Added Undead to the EXCLUSION treasure list (they drop nothing now) -// - redistributed treasure (to lessen amoun t of armor and increase 'class specific treasure' -// - Rangers with heavy armor prof. will be treated as Fighters else as Barbarians -// - Gave wizards, druids and monk their own function -// MAY 29 2002: Removed the heal potion from treasure -// Moved nymph cloak +4 to treasure bracket 6 -// Added Monk Enhancement items to random treasure - -#include "prc_class_const" - -// * --------- -// * CONSTANTS -// * --------- - -// * tweaking constants - - // * SIX LEVEL RANGES - const int RANGE_1_MIN = 0; - const int RANGE_1_MAX = 5; - const int RANGE_2_MIN = 6; - const int RANGE_2_MAX = 8; - - const int RANGE_3_MIN = 9; - const int RANGE_3_MAX = 10; - - const int RANGE_4_MIN = 11; - const int RANGE_4_MAX = 13; - - const int RANGE_5_MIN = 14; - const int RANGE_5_MAX = 16; - - const int RANGE_6_MIN = 17; - const int RANGE_6_MAX = 100; - - // * NUMBER OF ITEMS APPEARING - const int NUMBER_LOW_ONE = 100; const int NUMBER_MED_ONE = 60; const int NUMBER_HIGH_ONE = 40; const int NUMBER_BOSS_ONE = 100; - const int NUMBER_LOW_TWO = 0; const int NUMBER_MED_TWO = 30; const int NUMBER_HIGH_TWO = 40; const int NUMBER_BOSS_TWO = 0; - const int NUMBER_LOW_THREE = 0; const int NUMBER_MED_THREE = 10; const int NUMBER_HIGH_THREE = 20; const int NUMBER_BOSS_THREE = 0; - - const int NUMBER_BOOK_ONE = 75; - const int NUMBER_BOOK_TWO = 20; - const int NUMBER_BOOK_THREE = 5; - - // * AMOUNT OF GOLD BY VALUE - const float LOW_MOD_GOLD = 0.5; const float MEDIUM_MOD_GOLD = 1.0; const float HIGH_MOD_GOLD = 3.0; - // * FREQUENCY OF ITEM TYPE APPEARING BY TREASURE TYPE - const int LOW_PROB_BOOK = 1; const int MEDIUM_PROB_BOOK = 1; const int HIGH_PROB_BOOK =1; - const int LOW_PROB_ANIMAL = 0; const int MEDIUM_PROB_ANIMAL = 0; const int HIGH_PROB_ANIMAL = 0; - const int LOW_PROB_JUNK = 2; const int MEDIUM_PROB_JUNK = 1; const int HIGH_PROB_JUNK = 1; - const int LOW_PROB_GOLD = 43; const int MEDIUM_PROB_GOLD = 38; const int HIGH_PROB_GOLD = 15; - const int LOW_PROB_GEM = 9; const int MEDIUM_PROB_GEM = 15; const int HIGH_PROB_GEM = 15; - const int LOW_PROB_JEWEL = 4; const int MEDIUM_PROB_JEWEL = 6; const int HIGH_PROB_JEWEL = 15; - const int LOW_PROB_ARCANE = 3; const int MEDIUM_PROB_ARCANE = 3; const int HIGH_PROB_ARCANE = 3; - const int LOW_PROB_DIVINE = 3; const int MEDIUM_PROB_DIVINE = 3; const int HIGH_PROB_DIVINE = 3; - const int LOW_PROB_AMMO = 10; const int MEDIUM_PROB_AMMO = 5; const int HIGH_PROB_AMMO = 3; - const int LOW_PROB_KIT = 5; const int MEDIUM_PROB_KIT = 5; const int HIGH_PROB_KIT = 5; - const int LOW_PROB_POTION =17; const int MEDIUM_PROB_POTION = 20; const int HIGH_PROB_POTION= 9; - const int LOW_PROB_TABLE2 = 3; const int MEDIUM_PROB_TABLE2 = 3; const int HIGH_PROB_TABLE2= 30; - - -// * readability constants - -const int TREASURE_LOW = 1; -const int TREASURE_MEDIUM = 2; -const int TREASURE_HIGH = 3; -const int TREASURE_BOSS = 4; -const int TREASURE_BOOK = 5; - - -// * JUMP_LEVEL is used in a Specific item function -// * in the case where a generic item is called for within that function -// * it will create a generic item by adding JUMP_LEVEL to the character's -// * hit die for the purposes of the treasure evaluation. -// * May 2002: Lowered JUMP_LEVEL from 3 to 2 - -const int JUMP_LEVEL = 2; - - -//* Declarations - void CreateGenericExotic(object oTarget, object oAdventurer, int nModifier = 0); - void CreateGenericMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0); - void CreateSpecificMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0); - void CreateGenericDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0); - void CreateSpecificDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0); - void CreateGenericWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0); - void CreateSpecificWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0); - int nDetermineClassToUse(object oCharacter); - - -// * -// * IMPLEMENTATION -// * - -// * Comment the speakstring in to debug treasure generation -void dbSpeak(string s) -{ -// SpeakString(s); -} - -//* made this function to help with debugging -void dbCreateItemOnObject(string sItemTemplate, object oTarget = OBJECT_SELF, int nStackSize = 1) -{ -/* - if (sItemTemplate == "") - { - PrintString("blank item passed into dbCreateItemOnObject. Please report as bug to Brent."); - } - dbSpeak(sItemTemplate); -*/ - - //sItemTemplate = GetStringLowerCase - - if (nStackSize == 1) - { - // * checks to see if this is a throwing item and if it is - // * it creates more - - string sRoot = GetSubString(sItemTemplate, 0, 6); - //dbSpeak("ROOT: " + sRoot); - if (GetStringLowerCase(sRoot) == "nw_wth") - { - nStackSize = Random(30) + 1; - } - } - object oItem = CreateItemOnObject(sItemTemplate, oTarget, nStackSize); -/* - if (GetIsObjectValid(oItem) == FALSE && sItemTemplate != "NW_IT_GOLD001") - { - - // * check to see if item is there in a stack, if not give warning - if (GetIsObjectValid(GetItemPossessedBy(oTarget, GetStringUpperCase(sItemTemplate))) == FALSE && - GetIsObjectValid(GetItemPossessedBy(oTarget, GetStringLowerCase(sItemTemplate))) == FALSE) - { - PrintString("**DESIGN***"); - PrintString("******" + sItemTemplate + " is an invalid item template. Please report as bug to Brent."); - PrintString("*******"); - } - } -*/ -} - - -// * -// * GET FUNCTIONS -// * - -// * Returns the object that either last opened the container or destroyed it -object GetLastOpener() -{ - if (GetIsObjectValid(GetLastOpenedBy()) == TRUE) - { - //dbSpeak("LastOpener: GetLastOpenedBy " + GetTag(GetLastOpenedBy())); - return GetLastOpenedBy(); - } - else - if (GetIsObjectValid(GetLastKiller()) == TRUE) - { - //dbSpeak("LastOpener: GetLastAttacker"); - return GetLastKiller(); - } - //dbSpeak("LastOpener: The Object is Invalid you weenie!"); - return OBJECT_INVALID; -} - -//:://///////////////////////////////////////////// -//:: GetRange -//:: Copyright (c) 2002 Bioware Corp. -//::////////////////////////////////////////////// -/* - Returns true if nHD matches the correct - level range for the indicated nCategory. - (i.e., First to Fourth level characters - are considered Range1) -*/ -//::////////////////////////////////////////////// -//:: Created By: Brent -//:: Created On: -//::////////////////////////////////////////////// -int GetRange(int nCategory, int nHD) -{ - int nMin = 0; int nMax = 0; - switch (nCategory) - { - case 6: nMin = RANGE_6_MIN; nMax = RANGE_6_MAX; break; - case 5: nMin = RANGE_5_MIN; nMax = RANGE_5_MAX; break; - case 4: nMin = RANGE_4_MIN; nMax = RANGE_4_MAX; break; - case 3: nMin = RANGE_3_MIN; nMax = RANGE_3_MAX; break; - case 2: nMin = RANGE_2_MIN; nMax = RANGE_2_MAX; break; - case 1: nMin = RANGE_1_MIN; nMax = RANGE_1_MAX; break; - } - - //dbSpeak("nMin = " + IntToString(nMin)); - //dbSpeak("nMax = " + IntToString(nMax)); - //dbSpeak("GetRange.nHD = " + IntToString(nHD)); - if (nHD >= nMin && nHD <= nMax) - { - return TRUE; - } - - return FALSE; - -} - -//:://///////////////////////////////////////////// -//:: GetNumberOfItems -//:: Copyright (c) 2002 Bioware Corp. -//::////////////////////////////////////////////// -/* - Returns the number of items to create. -*/ -//::////////////////////////////////////////////// -//:: Created By: Brent -//:: Created On: -//::////////////////////////////////////////////// -int GetNumberOfItems(int nTreasureType) -{ - int nItems = 0; - int nRandom = 0; - - int nProbThreeItems = 0; - int nProbTwoItems = 0; - int nProbOneItems = 0; - - if (nTreasureType == TREASURE_LOW) - { - nProbThreeItems = NUMBER_LOW_THREE; - nProbTwoItems = NUMBER_LOW_TWO; - nProbOneItems = NUMBER_LOW_ONE; - } - else - if (nTreasureType == TREASURE_MEDIUM) - { - nProbThreeItems = NUMBER_MED_THREE; - nProbTwoItems = NUMBER_MED_TWO; - nProbOneItems = NUMBER_MED_ONE; - } - else - if (nTreasureType == TREASURE_HIGH) - { - nProbThreeItems = NUMBER_HIGH_THREE; - nProbTwoItems = NUMBER_HIGH_TWO; - nProbOneItems = NUMBER_HIGH_ONE; - } - else - if (nTreasureType == TREASURE_BOSS) - { - nProbThreeItems = NUMBER_BOSS_THREE; - nProbTwoItems = NUMBER_BOSS_TWO; - nProbOneItems = NUMBER_BOSS_ONE; - } - else - if (nTreasureType == TREASURE_BOOK) - { - nProbThreeItems = NUMBER_BOOK_THREE; - nProbTwoItems = NUMBER_BOOK_TWO; - nProbOneItems = NUMBER_BOOK_ONE; - } - - - nRandom = d100(); - if (nRandom <= nProbThreeItems) - { - nItems = 3; - } - else - if (nRandom <= nProbTwoItems + nProbThreeItems) - { - nItems = 2; - } - else - { - nItems = 1; - } - - // * May 13 2002: Cap number of items, in case of logic error - if (nItems > 3) - { - nItems = 3; - } - - return nItems; -} - - -// * -// * TREASURE GENERATION FUNCTIONS -// * - // * - // * Non-Scaling Treasure - // * - void CreateBook(object oTarget) - { - int nBook1 = Random(31) + 1; - string sRes = "NW_IT_BOOK01"; - - if (nBook1 < 10) - { - sRes = "NW_IT_BOOK00" + IntToString(nBook1); - } - else - { - sRes = "NW_IT_BOOK0" + IntToString(nBook1); - } - //dbSpeak("Create book"); - dbCreateItemOnObject(sRes, oTarget); - } - - void CreateAnimalPart(object oTarget) - { - - string sRes = ""; - int nResult = Random(3) + 1; - switch (nResult) - { - case 1: sRes = "NW_IT_MSMLMISC20"; break; - case 2: sRes = "NW_IT_MMIDMISC05"; break; - case 3: sRes = "NW_IT_MMIDMISC06"; break; - } - //dbSpeak("animal"); - dbCreateItemOnObject(sRes, oTarget); - } - - void CreateJunk(object oTarget) - { - string sRes = "NW_IT_TORCH001"; - int NUM_ITEMS = 6; - int nResult = Random(NUM_ITEMS) + 1; - int nKit = 0; - switch (nResult) - { - case 1: sRes = "NW_IT_MPOTION021"; break; //ale - case 2: sRes = "NW_IT_MPOTION021"; break; // ale - case 3: sRes = "NW_IT_MPOTION023"; break; // wine - case 4: sRes = "NW_IT_MPOTION021"; break; // ale - case 5: sRes = "NW_IT_MPOTION022"; break; // spirits - case 6: sRes = "NW_IT_TORCH001"; break; //torch - } - //dbSpeak("CreateJunk"); - dbCreateItemOnObject(sRes, oTarget); - } - // * - // * Scaling Treasure - // * - void CreateGold(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - int nAmount = 0; - - if (GetRange(1, nHD)) - { - nAmount = d10(); - } - else if (GetRange(2, nHD)) - { - nAmount = d20(); - } - else if (GetRange(3, nHD)) - { - nAmount = d20(2); - } - else if (GetRange(4, nHD)) - { - nAmount = d20(5); - } - else if (GetRange(5, nHD)) - { - nAmount = d20(8); - } - else if (GetRange(6, nHD)) - { - nAmount = d20(10); - } - float nMod = 0.0; - if (nTreasureType == TREASURE_LOW) nMod = LOW_MOD_GOLD; - else if (nTreasureType == TREASURE_MEDIUM) nMod = MEDIUM_MOD_GOLD; - else if (nTreasureType == TREASURE_HIGH) nMod = HIGH_MOD_GOLD; - - // * always at least 1gp is created - nAmount = FloatToInt(nAmount * nMod); - if (nAmount <= 0) - { - nAmount = 1; - } - //dbSpeak("gold"); - dbCreateItemOnObject("NW_IT_GOLD001", oTarget, nAmount); - } - void CreateGem(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sGem = "nw_it_gem001"; - if (GetRange(1, nHD)) - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sGem = "nw_it_gem001"; break; - case 2: sGem = "nw_it_gem007"; break; - case 3: sGem = "nw_it_gem002"; break; - case 4: case 5: sGem = "nw_it_gem004"; break; - case 6: case 7: sGem = "nw_it_gem014"; break; - case 8: sGem = "nw_it_gem003"; break; - case 9: sGem = "nw_it_gem015"; break; - } - } - else if (GetRange(2, nHD)) // 30 GP Avg; 150 gp Max - { - int nRandom = d12(); - switch (nRandom) - { - case 1: sGem = "nw_it_gem001"; break; - case 2: sGem = "nw_it_gem007"; break; - case 3: sGem = "nw_it_gem002"; break; - case 4: sGem = "nw_it_gem004"; break; - case 5: case 6: sGem = "nw_it_gem014"; break; - case 7: case 8: sGem = "nw_it_gem003"; break; - case 9: case 10: sGem = "nw_it_gem015"; break; - case 11: sGem = "nw_it_gem011"; break; - case 12: sGem = "nw_it_gem013"; break; - } - - } - else if (GetRange(3, nHD)) // 75GP Avg; 500 gp max - { - int nRandom = d2(); - switch (nRandom) - { - case 1: sGem = "nw_it_gem013"; break; - case 2: sGem = "nw_it_gem010"; break; - } - - } - else if (GetRange(4, nHD)) // 150 gp avg; 1000 gp max - { - int nRandom = d3(); - switch (nRandom) - { - case 1: sGem = "nw_it_gem013"; break; - case 2: sGem = "nw_it_gem010"; break; - case 3: sGem = "nw_it_gem008"; break; - } - } - else if (GetRange(5, nHD)) // 300 gp avg; any - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sGem = "nw_it_gem013"; break; - case 2: sGem = "nw_it_gem010"; break; - case 3: case 4: sGem = "nw_it_gem008"; break; - case 5: sGem = "nw_it_gem009"; break; - case 6: sGem = "nw_it_gem009"; break; - } - } - else if (GetRange(6, nHD))// * Anything higher than level 15 500 gp avg; any - { - int nRandom = Random(8) + 1; - switch (nRandom) - { - case 1: sGem = "nw_it_gem013"; break; - case 2: sGem = "nw_it_gem010"; break; - case 3: case 4: sGem = "nw_it_gem008"; break; - case 5: sGem = "nw_it_gem009"; break; - case 6: sGem = "nw_it_gem009"; break; - case 7: sGem = "nw_it_gem006"; break; - case 8: sGem = "nw_it_gem012"; break; - } - } - //dbSpeak("Create Gem"); - dbCreateItemOnObject(sGem, oTarget, 1); - } - void CreateJewel(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sJewel = ""; - - if (GetRange(1, nHD)) // 15 gp avg; 75 gp max - { - int nRandom = d2(); - switch (nRandom) - { - case 1: sJewel = "nw_it_mring021"; break; - case 2: sJewel = "nw_it_mneck020"; break; - } - } - else if (GetRange(2, nHD)) // 30 GP Avg; 150 gp Max - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sJewel = "nw_it_mring021"; break; - case 2: case 3: sJewel = "nw_it_mneck020"; break; - case 4: sJewel = "nw_it_mring022"; break; - case 5: case 6: sJewel = "nw_it_mneck023"; break; } - } - else if (GetRange(3, nHD)) // 75GP Avg; 500 gp max - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sJewel = "nw_it_mring021"; break; - case 2: case 3: sJewel = "nw_it_mneck020"; break; - case 4: case 5: sJewel = "nw_it_mring022"; break; - case 6: sJewel = "nw_it_mneck021"; break; - } - } - else if (GetRange(4, nHD)) // 150 gp avg; 1000 gp max - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sJewel = "nw_it_mring021"; break; - case 2: sJewel = "nw_it_mring022"; break; - case 3: case 4: case 5: sJewel = "nw_it_mneck021"; break; - case 6: sJewel = "nw_it_mring023"; break; - } - } - else if (GetRange(5, nHD)) // 300 gp avg; any - { - int nRandom = d8(); - switch (nRandom) - { - case 1: sJewel = "nw_it_mring022"; break; - case 2: case 3: sJewel = "nw_it_mneck021"; break; - case 4: case 5: case 6: sJewel = "nw_it_mring023"; break; - case 7: case 8: sJewel = "nw_it_mneck022"; break; - } - } - else if (GetRange(6, nHD)) - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sJewel = "nw_it_mring022"; break; - case 2: sJewel = "nw_it_mneck021"; break; - case 3: case 4: sJewel = "nw_it_mring023"; break; - case 5: case 6: sJewel = "nw_it_mneck022"; break; - } - } - //dbSpeak("Create Jewel"); - - dbCreateItemOnObject(sJewel, oTarget, 1); - - } - // * returns the valid upper limit for any arcane spell scroll - int TrimLevel(int nScroll, int nLevel) - { int nMax = 5; - switch (nLevel) - { - case 0: nMax = 4; break; - case 1: nMax = 13; break; - case 2: nMax = 21; break; - case 3: nMax = 15; break; - case 4: nMax = 17; break; - case 5: nMax = 13; break; - case 6: nMax = 14; break; - case 7: nMax = 8; break; - case 8: nMax = 9; break; - case 9: nMax = 12; break; - } - if (nScroll > nMax) nScroll = nMax; - return nScroll; - - } - // * nModifier is to 'raise' the level of the oAdventurer - void CreateArcaneScroll(object oTarget, object oAdventurer, int nModifier = 0) - { - int nMaxSpells = 21; - int nHD = GetHitDice(oAdventurer) + nModifier; - int nScroll = 1; - int nLevel = 1; - - if (GetRange(1, nHD)) // l 1-2 - { - nLevel = d2(); - nScroll = Random(nMaxSpells) + 1; - } - else if (GetRange(2, nHD)) // l 1-4 - { - nLevel = d4(); - nScroll = Random(nMaxSpells) + 1; - } - else if (GetRange(3, nHD)) // l 2-6 - { - nLevel = d6(); - if (nLevel < 2) nLevel = 2; - - nScroll = Random(nMaxSpells) + 1; - } - else if (GetRange(4, nHD)) // l 3-8 - { - nLevel = d8(); - if (nLevel < 3) nLevel = 3; - - nScroll = Random(nMaxSpells) + 1; - } - else if (GetRange(5, nHD)) // l 4-9 - { - nLevel = d8() + 1; - if (nLevel < 4) nLevel = 4; - - nScroll = Random(nMaxSpells) + 1; - } - else if (GetRange(6, nHD)) // 5 -9 - { - nLevel = d8() + 1; - if (nLevel < 5) nLevel = 5; - - nScroll = Random(nMaxSpells) + 1; - } - - // * Trims the level of the scroll to match the max # of scrolls in each level range - nScroll = TrimLevel(nScroll, nLevel); - - string sRes = "nw_it_sparscr216"; - - if (nScroll < 10) - { - sRes = "NW_IT_SPARSCR" + IntToString(nLevel) + "0" + IntToString(nScroll); - } - else - { - sRes = "NW_IT_SPARSCR" + IntToString(nLevel) + IntToString(nScroll); - } - dbCreateItemOnObject(sRes, oTarget, 1); - } - - void CreateDivineScroll(object oTarget, object oAdventurer, int nModifier=0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sScroll = ""; - if (GetRange(1, nHD)) - { - int nRandom = d4(); - switch (nRandom) - { - case 1: sScroll = "nw_it_spdvscr201"; break; - case 2: sScroll = "nw_it_spdvscr202"; break; - case 3: sScroll = "nw_it_spdvscr203"; break; - case 4: sScroll = "nw_it_spdvscr204"; break; - } - } - else if (GetRange(2, nHD)) - { - int nRandom = d8(); - switch (nRandom) - { - case 1: sScroll = "nw_it_spdvscr201"; break; - case 2: sScroll = "nw_it_spdvscr202";break; - case 3: sScroll = "nw_it_spdvscr203"; break; - case 4: sScroll = "nw_it_spdvscr204"; break; - case 5: sScroll = "nw_it_spdvscr301"; break; - case 6: sScroll = "nw_it_spdvscr302"; break; - case 7: sScroll = "nw_it_spdvscr401"; break; - case 8: sScroll = "nw_it_spdvscr402"; break; - } - - } - else if (GetRange(3, nHD)) - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sScroll = "nw_it_spdvscr201"; break; - case 2: sScroll = "nw_it_spdvscr202"; break; - case 3: sScroll = "nw_it_spdvscr203"; break; - case 4: sScroll = "nw_it_spdvscr204"; break; - case 5: sScroll = "nw_it_spdvscr301"; break; - case 6: sScroll = "nw_it_spdvscr302"; break; - case 7: sScroll = "nw_it_spdvscr401"; break; - case 8: sScroll = "nw_it_spdvscr402"; break; - case 9: sScroll = "nw_it_spdvscr501"; break; - } - - } - else - { - int nRandom = Random(7) + 1; - switch (nRandom) - { - case 1: sScroll = "nw_it_spdvscr301"; break; - case 2: sScroll = "nw_it_spdvscr302"; break; - case 3: sScroll = "nw_it_spdvscr401"; break; - case 4: sScroll = "nw_it_spdvscr402"; break; - case 5: sScroll = "nw_it_spdvscr501"; break; - case 6: sScroll = "nw_it_spdvscr701"; break; - case 7: sScroll = "nw_it_spdvscr702"; break; - } - } - //dbSpeak("Divine Scroll"); - - dbCreateItemOnObject(sScroll, oTarget, 1); - - } - void CreateAmmo(object oTarget, object oAdventurer, int nModifier=0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sAmmo = ""; - - if (GetRange(1, nHD)) // * 200 gp max - { - int nRandom = d3(); - switch (nRandom) - { - case 1: sAmmo = "nw_wamar001"; break; - case 2: sAmmo = "nw_wambo001"; break; - case 3: sAmmo = "nw_wambu001"; break; - } - } - else if (GetRange(2, nHD)) // * 800 gp max - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sAmmo = "nw_wamar001"; break; - case 2: sAmmo = "nw_wambo001"; break; - case 3: sAmmo = "nw_wambu001"; break; - case 4: sAmmo = "nw_wammar001"; break; - case 5: sAmmo = "nw_wammbo001"; break; - case 6: sAmmo = "nw_wammbo002"; break; - } - } - else if (GetRange(3, nHD)) // * - 2500 gp - { - int nRandom = d20(); - switch (nRandom) - { - case 1: sAmmo = "nw_wamar001"; break; - case 2: sAmmo = "nw_wambo001"; break; - case 3: sAmmo = "nw_wambu001"; break; - case 4: sAmmo = "nw_wammar001"; break; - case 5: sAmmo = "nw_wammbo001"; break; - case 6: sAmmo = "nw_wammbo002"; break; - case 7: sAmmo = "nw_wammbo003"; break; - case 8: sAmmo = "nw_wammbu002"; break; - case 9: sAmmo = "nw_wammar002"; break; - case 10: sAmmo = "nw_wammar001"; break; - case 11: sAmmo = "nw_wammar003"; break; - case 12: sAmmo = "nw_wammar004"; break; - case 13: sAmmo = "nw_wammar005"; break; - case 14: sAmmo = "nw_wammar006"; break; - case 15: sAmmo = "nw_wammbo004"; break; - case 16: sAmmo = "nw_wammbo005"; break; - case 17: sAmmo = "nw_wammbu004"; break; - case 18: sAmmo = "nw_wammbu005"; break; - case 19: sAmmo = "nw_wammbu006"; break; - case 20: sAmmo = "nw_wammbu007"; break; - } - } - else - { - int nRandom = d20(); - switch (nRandom) - { - case 1: sAmmo = "nw_wamar001"; break; - case 2: sAmmo = "nw_wammbu001"; break; - case 3: sAmmo = "nw_wammbu003"; break; - case 4: sAmmo = "nw_wammar001"; break; - case 5: sAmmo = "nw_wammbo001"; break; - case 6: sAmmo = "nw_wammbo002"; break; - case 7: sAmmo = "nw_wammbo003"; break; - case 8: sAmmo = "nw_wammbu002"; break; - case 9: sAmmo = "nw_wammar002"; break; - case 10: sAmmo = "nw_wammar001"; break; - case 11: sAmmo = "nw_wammar003"; break; - case 12: sAmmo = "nw_wammar004"; break; - case 13: sAmmo = "nw_wammar005"; break; - case 14: sAmmo = "nw_wammar006"; break; - case 15: sAmmo = "nw_wammbo004"; break; - case 16: sAmmo = "nw_wammbo005"; break; - case 17: sAmmo = "nw_wammbu004"; break; - case 18: sAmmo = "nw_wammbu005"; break; - case 19: sAmmo = "nw_wammbu006"; break; - case 20: sAmmo = "nw_wammbu007"; break; - } - } - //dbSpeak("ammo"); - dbCreateItemOnObject(sAmmo, oTarget, Random(30) + 1); // create up to 30 of the specified ammo type - } - - void CreateTrapKit(object oTarget, object oAdventurer, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sKit = ""; - if (GetRange(1, nHD)) // 200 - { - int nRandom = d3(); - switch (nRandom) - { - case 1: sKit = "nw_it_trap001"; break; - case 2: sKit = "nw_it_trap029"; break; - case 3: sKit = "nw_it_trap033"; break; - } - } - else if (GetRange(2, nHD)) // 800 - { - int nRandom = d12(); - switch (nRandom) - { - case 1: sKit = "nw_it_trap001"; break; - case 2: sKit = "nw_it_trap029"; break; - case 3: sKit = "nw_it_trap033"; break; - case 4: sKit = "nw_it_trap002"; break; - case 5: sKit = "nw_it_trap030"; break; - case 6: sKit = "nw_it_trap037"; break; - case 7: sKit = "nw_it_trap034"; break; - case 8: sKit = "nw_it_trap005"; break; - case 9: sKit = "nw_it_trap038"; break; - case 10: sKit = "nw_it_trap041"; break; - case 11: sKit = "nw_it_trap003"; break; - case 12: sKit = "nw_it_trap031"; break; - } - - } - else if (GetRange(3, nHD)) // 200 - 2500 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_trap002"; break; - case 2: sKit = "nw_it_trap030"; break; - case 3: sKit = "nw_it_trap037"; break; - case 4: sKit = "nw_it_trap034"; break; - case 5: sKit = "nw_it_trap005"; break; - case 6: sKit = "nw_it_trap038"; break; - case 7: sKit = "nw_it_trap041"; break; - case 8: sKit = "nw_it_trap003"; break; - case 9: sKit = "nw_it_trap031"; break; - case 10: sKit = "nw_it_trap035"; break; - case 11: sKit = "nw_it_trap006"; break; - case 12: sKit = "nw_it_trap042"; break; - case 13: sKit = "nw_it_trap004"; break; - case 14: sKit = "nw_it_trap032"; break; - case 15: sKit = "nw_it_trap039"; break; - case 16: sKit = "nw_it_trap009"; break; - case 17: sKit = "nw_it_trap036"; break; - } - - } - else if (GetRange(4, nHD)) // 800 - 10000 - { - int nRandom = Random(19) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_trap035"; break; - case 2: sKit = "nw_it_trap006"; break; - case 3: sKit = "nw_it_trap042"; break; - case 4: sKit = "nw_it_trap004"; break; - case 5: sKit = "nw_it_trap032"; break; - case 6: sKit = "nw_it_trap039"; break; - case 7: sKit = "nw_it_trap009"; break; - case 8: sKit = "nw_it_trap036"; break; - case 9: sKit = "nw_it_trap013"; break; - case 10: sKit = "nw_it_trap040"; break; - case 11: sKit = "nw_it_trap007"; break; - case 12: sKit = "nw_it_trap043"; break; - case 13: sKit = "nw_it_trap010"; break; - case 14: sKit = "nw_it_trap017"; break; - case 15: sKit = "nw_it_trap021"; break; - case 16: sKit = "nw_it_trap014"; break; - case 17: sKit = "nw_it_trap025"; break; - case 18: sKit = "nw_it_trap008"; break; - case 19: sKit = "nw_it_trap044"; break; - } - - } - else if (GetRange(5, nHD)) // 2000 -16500 - { - int nRandom = Random(18) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_trap039"; break; - case 2: sKit = "nw_it_trap009"; break; - case 3: sKit = "nw_it_trap036"; break; - case 4: sKit = "nw_it_trap013"; break; - case 5: sKit = "nw_it_trap040"; break; - case 6: sKit = "nw_it_trap007"; break; - case 7: sKit = "nw_it_trap043"; break; - case 8: sKit = "nw_it_trap010"; break; - case 9: sKit = "nw_it_trap017"; break; - case 10: sKit = "nw_it_trap021"; break; - case 11: sKit = "nw_it_trap014"; break; - case 12: sKit = "nw_it_trap025"; break; - case 13: sKit = "nw_it_trap008"; break; - case 14: sKit = "nw_it_trap044"; break; - case 15: sKit = "nw_it_trap018"; break; - case 16: sKit = "nw_it_trap011"; break; - case 17: sKit = "nw_it_trap022"; break; - case 18: sKit = "nw_it_trap026"; break; - } - - } - else if (GetRange(6, nHD)) // 2000 - ? - { - int nRandom = Random(27) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_trap039"; break; - case 2: sKit = "nw_it_trap009"; break; - case 3: sKit = "nw_it_trap036"; break; - case 4: sKit = "nw_it_trap013"; break; - case 5: sKit = "nw_it_trap040"; break; - case 6: sKit = "nw_it_trap007"; break; - case 7: sKit = "nw_it_trap043"; break; - case 8: sKit = "nw_it_trap010"; break; - case 9: sKit = "nw_it_trap017"; break; - case 10: sKit = "nw_it_trap021"; break; - case 11: sKit = "nw_it_trap014"; break; - case 12: sKit = "nw_it_trap025"; break; - case 13: sKit = "nw_it_trap008"; break; - case 14: sKit = "nw_it_trap044"; break; - case 15: sKit = "nw_it_trap018"; break; - case 16: sKit = "nw_it_trap011"; break; - case 17: sKit = "nw_it_trap022"; break; - case 18: sKit = "nw_it_trap026"; break; - case 19: sKit = "nw_it_trap015"; break; - case 20: sKit = "nw_it_trap012"; break; - case 21: sKit = "nw_it_trap019"; break; - case 22: sKit = "nw_it_trap023"; break; - case 23: sKit = "nw_it_trap016"; break; - case 24: sKit = "nw_it_trap027"; break; - case 25: sKit = "nw_it_trap020"; break; - case 26: sKit = "nw_it_trap024"; break; - case 27: sKit = "nw_it_trap028"; break; - } - - } - //dbSpeak("Create Trapkit"); - dbCreateItemOnObject(sKit, oTarget, 1); - - } - void CreateHealingKit(object oTarget, object oAdventurer, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sKit = ""; - if (GetRange(1, nHD)) // 200 - { - int nRandom = Random(1) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_medkit001"; break; - } - } - else if (GetRange(2, nHD)) // 800 - { - int nRandom = Random(2) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_medkit001"; break; - case 2: sKit = "nw_it_medkit002"; break; - } - - } - else if (GetRange(3, nHD)) // 200 - 2500 - { - int nRandom = Random(2) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_medkit002"; break; - case 2: sKit = "nw_it_medkit003"; break; - } - - } - else if (GetRange(4, nHD)) // 800 - 10000 - { - int nRandom = Random(2) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_medkit003";break; - case 2: sKit = "nw_it_medkit004"; break; - } - - } - else if (GetRange(5, nHD)) // 2000 -16500 - { - int nRandom = Random(2) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_medkit003"; break; - case 2: sKit = "nw_it_medkit004";break; - } - - } - else if (GetRange(6, nHD)) // 2000 - ? - { - int nRandom = Random(2) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_medkit003"; break; - case 2: sKit = "nw_it_medkit004";break; - } - - } - //dbSpeak("Create Healing Kit"); - - dbCreateItemOnObject(sKit, oTarget, 1); - - } - void CreateLockPick(object oTarget, object oAdventurer, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sKit = ""; - if (GetRange(1, nHD)) // 200 - { - int nRandom = d8(); - switch (nRandom) - { - case 1: sKit = "nw_it_picks001"; break; - case 2: sKit = "nw_it_picks002"; break; - case 3: sKit = "nw_it_picks001"; break; - case 4: sKit = "nw_it_picks001"; break; - case 5: sKit = "nw_it_picks001"; break; - case 6: sKit = "nw_it_picks001"; break; - case 7: sKit = "nw_it_picks001"; break; - case 8: sKit = "nw_it_picks001"; break; - } - } - else if (GetRange(2, nHD)) // 800 - { - int nRandom = d6(); - switch (nRandom) - { - case 1: sKit = "nw_it_picks001"; break; - case 2: sKit = "nw_it_picks002"; break; - case 3: sKit = "nw_it_picks003"; break; - case 4: sKit = "nw_it_picks002"; break; - case 5: sKit = "nw_it_picks002"; break; - case 6: sKit = "nw_it_picks002"; break; - } - - } - else if (GetRange(3, nHD)) // 200 - 2500 - { - int nRandom = Random(2) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_picks003"; break; - case 2: sKit = "nw_it_picks004"; break; - } - - } - else if (GetRange(4, nHD)) // 800 - 10000 - { - int nRandom = Random(1) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_picks004"; break; - } - - } - else if (GetRange(5, nHD)) // 2000 -16500 - { - int nRandom = Random(1) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_picks004"; break; - } - - } - else if (GetRange(6, nHD)) // 2000 - ? - { - int nRandom = Random(1) + 1; - switch (nRandom) - { - case 1: sKit = "nw_it_picks004"; break; - } - - } - //dbSpeak("Create Lockpick"); - - dbCreateItemOnObject(sKit, oTarget, 1); - - } - void CreateKit(object oTarget, object oAdventurer, int nModifier = 0) - { - // * April 23 2002: Major restructuring of this function - // * to allow me to - - switch (Random(8) + 1) - { - case 1: CreateTrapKit(oTarget, oAdventurer, nModifier); break; - case 2: case 3: case 4: case 5: CreateHealingKit(oTarget, oAdventurer, nModifier); break; - case 6: case 7: case 8: CreateLockPick(oTarget, oAdventurer, nModifier); break; - } - } - - void CreatePotion(object oTarget, object oAdventurer, int nModifier = 0) - { - string sPotion = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) - { - int nRandom = d10(); - switch (nRandom) - { - case 1: case 2: case 3: case 4: sPotion = "nw_it_mpotion001"; break; - case 5: case 6: case 7: sPotion = "nw_it_mpotion020"; break; - case 8: sPotion = "nw_it_mpotion002"; break; - case 9: sPotion = "nw_it_mpotion009"; break; - case 10: sPotion = "nw_it_mpotion005"; break; - } - - } - else if (GetRange(2, nHD)) - { - int nRandom = Random(29) + 1; - switch (nRandom) - { - case 1: case 2: case 3: sPotion = "nw_it_mpotion001"; break; - case 4: case 5: case 6: case 7: case 8: sPotion = "nw_it_mpotion020"; break; - case 9: case 10: case 11: case 12: sPotion = "nw_it_mpotion002"; break; - case 13: case 14: sPotion = "nw_it_mpotion003"; break; - case 15: sPotion = "nw_it_mpotion009"; break; - case 16: sPotion = "nw_it_mpotion005"; break; - case 17: sPotion = "nw_it_mpotion007"; break; - case 18: sPotion = "nw_it_mpotion008"; break; - case 19: sPotion = "nw_it_mpotion010"; break; - case 20: sPotion = "nw_it_mpotion011"; break; - case 21: sPotion = "nw_it_mpotion013"; break; - case 22: sPotion = "nw_it_mpotion014"; break; - case 23: sPotion = "nw_it_mpotion015"; break; - case 24: sPotion = "nw_it_mpotion016"; break; - case 25: sPotion = "nw_it_mpotion017"; break; - case 26: sPotion = "nw_it_mpotion018"; break; - case 27: sPotion = "nw_it_mpotion019"; break; - case 28: sPotion = "nw_it_mpotion004"; break; - case 29: sPotion = "nw_it_mpotion006"; break; - } - } - else if (GetRange(3, nHD)) - { - int nRandom = Random(29) + 1; - switch (nRandom) - { - case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: - case 9: case 10: case 11: case 12: - case 13: case 14: sPotion = "nw_it_mpotion003"; break; - case 15: sPotion = "nw_it_mpotion009"; break; - case 16: sPotion = "nw_it_mpotion005"; break; - case 17: sPotion = "nw_it_mpotion007"; break; - case 18: sPotion = "nw_it_mpotion008"; break; - case 19: sPotion = "nw_it_mpotion010"; break; - case 20: sPotion = "nw_it_mpotion011"; break; - case 21: sPotion = "nw_it_mpotion013"; break; - case 22: sPotion = "nw_it_mpotion014"; break; - case 23: sPotion = "nw_it_mpotion015"; break; - case 24: sPotion = "nw_it_mpotion016"; break; - case 25: sPotion = "nw_it_mpotion017"; break; - case 26: sPotion = "nw_it_mpotion018"; break; - case 27: sPotion = "nw_it_mpotion019"; break; - case 28: sPotion = "nw_it_mpotion004"; break; - case 29: sPotion = "nw_it_mpotion006"; break; - } - } - else if (GetRange(4, nHD)) - { - int nRandom = Random(29) + 1; - switch (nRandom) - { - case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: - case 9: case 10: case 11: case 12: sPotion = "nw_it_mpotion003"; break; - case 13: case 14: sPotion = "nw_it_mpotion003"; break; - case 15: sPotion = "nw_it_mpotion009"; break; - case 16: sPotion = "nw_it_mpotion005"; break; - case 17: sPotion = "nw_it_mpotion007"; break; - case 18: sPotion = "nw_it_mpotion008"; break; - case 19: sPotion = "nw_it_mpotion010"; break; - case 20: sPotion = "nw_it_mpotion011"; break; - case 21: sPotion = "nw_it_mpotion013"; break; - case 22: sPotion = "nw_it_mpotion014"; break; - case 23: sPotion = "nw_it_mpotion015"; break; - case 24: sPotion = "nw_it_mpotion016"; break; - case 25: sPotion = "nw_it_mpotion017"; break; - case 26: sPotion = "nw_it_mpotion018"; break; - case 27: sPotion = "nw_it_mpotion019"; break; - case 28: sPotion = "nw_it_mpotion004"; break; - case 29: sPotion = "nw_it_mpotion006"; break; - } - } - else // keep 5 and 6 the same - { - int nRandom = Random(29) + 1; - switch (nRandom) - { - case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: - case 9: sPotion = "nw_it_mpotion003" ; - case 10: case 11: case 12: case 13: case 14: sPotion = "nw_it_mpotion003"; break; - case 15: sPotion = "nw_it_mpotion009"; break; - case 16: sPotion = "nw_it_mpotion005"; break; - case 17: sPotion = "nw_it_mpotion007"; break; - case 18: sPotion = "nw_it_mpotion008"; break; - case 19: sPotion = "nw_it_mpotion010"; break; - case 20: sPotion = "nw_it_mpotion011"; break; - case 21: sPotion = "nw_it_mpotion013"; break; - case 22: sPotion = "nw_it_mpotion014"; break; - case 23: sPotion = "nw_it_mpotion015"; break; - case 24: sPotion = "nw_it_mpotion016"; break; - case 25: sPotion = "nw_it_mpotion017"; break; - case 26: sPotion = "nw_it_mpotion018"; break; - case 27: sPotion = "nw_it_mpotion019"; break; - case 28: sPotion = "nw_it_mpotion004"; break; - case 29: sPotion = "nw_it_mpotion006"; break; - } - } - //dbSpeak("Create Potion"); - dbCreateItemOnObject(sPotion, oTarget, 1); - } - //:://///////////////////////////////////////////// - //:: CreateTable2GenericItem - //:: Copyright (c) 2002 Bioware Corp. - //::////////////////////////////////////////////// - /* - Creates an item based upon the class of - oAdventurer - */ - //::////////////////////////////////////////////// - //:: Created By: Brent - //:: Created On: - //::////////////////////////////////////////////// - void CreateGenericMiscItem(object oTarget, object oAdventurer, int nModifier=0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sItem = ""; - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mglove004"; break; - case 2: sItem = "nw_it_mglove004"; break; - case 3: sItem = "nw_it_mglove005"; break; - case 4: sItem = "nw_it_mglove006"; break; - case 5: sItem = "nw_it_mglove007"; break; - case 6: sItem = "nw_it_mglove008"; break; - case 7: sItem = "nw_it_mglove009"; break; - case 8: sItem = "nw_mcloth006"; break; - case 9: sItem = "nw_it_mglove012"; break; - } - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(25) + 1; - switch (nRandom) - { - case 1: sItem = "nw_mcloth006"; break; - case 2: sItem = "nw_it_mring009"; break; - case 3: sItem = "nw_it_mring009"; break; - case 4: sItem = "nw_it_mring010"; break; - case 5: sItem = "nw_it_mring011"; break; - case 6: sItem = "nw_it_mboots010"; break; - case 7: sItem = "nw_it_mneck024"; break; - case 8: sItem = "nw_mcloth007"; break; - case 9: sItem = "nw_it_mring024"; break; - case 10: sItem = "nw_it_mring012"; break; - case 11: sItem = "nw_mcloth008"; break; - case 12: sItem = "nw_it_mglove010"; break; - case 13: sItem = "nw_it_mglove011"; break; - case 14: sItem = "nw_it_mglove013"; break; - case 15: sItem = "nw_it_mglove014"; break; - case 16: sItem = "nw_it_mglove015"; break; - case 17: sItem = "nw_maarcl097"; break; - case 18: sItem = "nw_maarcl097"; break; - case 19: sItem = "nw_maarcl099"; break; - case 20: sItem = "nw_it_mneck032"; break; - case 21: sItem = "nw_mcloth010"; break; - case 22: sItem = "nw_it_mbracer002"; break; - case 23: sItem = "nw_it_mneck001"; break; - case 24: sItem = "nw_maarcl055"; break; - case 25: sItem = "nw_mcloth009"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(44) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mring009"; break; - case 2: sItem = "nw_it_mring009"; break; - case 3: sItem = "nw_it_mring010"; break; - case 4: sItem = "nw_it_mring011"; break; - case 5: sItem = "nw_it_mboots010"; break; - case 6: sItem = "nw_it_mneck024"; break; - case 7: sItem = "nw_mcloth007"; break; - case 8: sItem = "nw_it_mring024"; break; - case 9: sItem = "nw_it_mring012"; break; - case 10: sItem = "nw_mcloth008"; break; - case 11: sItem = "nw_it_mglove010"; break; - case 12: sItem = "nw_it_mglove011"; break; - case 13: sItem = "nw_it_mglove013"; break; - case 14: sItem = "nw_it_mglove014"; break; - case 15: sItem = "nw_it_mglove015"; break; - case 16: sItem = "nw_it_contain003"; break; - case 17: sItem = "nw_maarcl097"; break; - case 18: sItem = "nw_maarcl099"; break; - case 19: sItem = "nw_it_mneck032"; break; - case 20: sItem = "nw_mcloth010"; break; - case 21: sItem = "nw_it_mbracer002"; break; - case 22: sItem = "nw_it_mneck001"; break; - case 23: sItem = "nw_maarcl055"; break; - case 24: sItem = "nw_mcloth009"; break; - case 25: sItem = "nw_it_mring001"; break; - case 26: sItem = "nw_it_mboots001"; break; - case 27: sItem = "nw_it_mbracer001"; break; - case 28: sItem = "nw_it_mneck007"; break; - case 29: sItem = "nw_maarcl096"; break; - case 30: sItem = "nw_it_mglove003"; break; - case 31: sItem = "nw_it_contain004"; break; - case 32: sItem = "nw_it_mneck031"; break; - case 33: sItem = "nw_it_mring006"; break; - case 34: sItem = "nw_it_mneck006"; break; - case 35: sItem = "nw_it_mneck029"; break; - case 36: sItem = "nw_it_mring013"; break; - case 37: sItem = "nw_it_mboots011"; break; - case 38: sItem = "nw_it_mneck025"; break; - case 39: sItem = "nw_it_mbelt009"; break; - case 40: sItem = "nw_it_mbelt010"; break; - case 41: sItem = "nw_it_mbelt011"; break; - case 42: sItem = "nw_it_mring025"; break; - case 43: sItem = "nw_it_mring025"; break; - case 44: sItem = "nw_maarcl031"; break; - - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(48) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mring001"; break; - case 2: sItem = "nw_it_mboots001"; break; - case 3: sItem = "nw_it_mbracer001"; break; - case 4: sItem = "nw_it_mneck007"; break; - case 5: sItem = "nw_maarcl096"; break; - case 6: sItem = "nw_it_mglove003"; break; - case 7: sItem = "nw_it_mneck031"; break; - case 8: sItem = "nw_it_mneck031"; break; - case 9: sItem = "nw_it_mring006"; break; - case 10: sItem = "nw_it_mneck006"; break; - case 11: sItem = "nw_it_mneck029"; break; - case 12: sItem = "nw_it_mring013"; break; - case 13: sItem = "nw_it_mboots011"; break; - case 14: sItem = "nw_it_mneck025"; break; - case 15: sItem = "nw_it_mbelt009"; break; - case 16: sItem = "nw_it_mbelt010"; break; - case 17: sItem = "nw_it_mbelt011"; break; - case 18: sItem = "nw_it_mring025"; break; - case 19: sItem = "nw_it_mring025"; break; - case 20: sItem = "nw_it_mbracer007"; break; - case 21: sItem = "nw_it_mbracer007"; break; - case 22: sItem = "nw_it_mneck012"; break; - case 23: sItem = "nw_maarcl088"; break; - case 24: sItem = "nw_it_mboots012"; break; - case 25: sItem = "nw_it_mneck026"; break; - case 26: sItem = "nw_it_mboots006"; break; - case 27: sItem = "nw_it_mbracer003"; break; - case 28: sItem = "nw_it_mneck008"; break; - case 29: sItem = "nw_it_mring008"; break; - case 30: sItem = "nw_maarcl056"; break; - case 31: sItem = "nw_maarcl092"; break; - case 32: sItem = "nw_it_mring014"; break; - case 33: sItem = "nw_it_mneck016"; break; - case 34: sItem = "nw_it_mboots013"; break; - case 35: sItem = "nw_it_mneck027"; break; - case 36: sItem = "nw_it_mbracer008"; break; - case 37: sItem = "nw_it_mneck013"; break; - case 38: sItem = "nw_maarcl089"; break; - case 39: sItem = "nw_it_mbelt012"; break; - case 40: sItem = "nw_it_mbelt013"; break; - case 41: sItem = "nw_it_mbelt014"; break; - case 42: sItem = "nw_it_mring027"; break; - case 43: sItem = "nw_it_mboots007"; break; - case 44: sItem = "nw_it_mbracer004"; break; - case 45: sItem = "nw_it_mneck009"; break; - case 46: sItem = "nw_it_mring018"; break; - case 47: sItem = "nw_maarcl093"; break; - case 48: sItem = "nw_it_mboots002"; break; - - } - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(42) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mbracer007"; break; - case 2: sItem = "nw_it_mbracer007"; break; - case 3: sItem = "nw_it_mneck012"; break; - case 4: sItem = "nw_maarcl088"; break; - case 5: sItem = "nw_it_mboots012"; break; - case 6: sItem = "nw_it_mneck026"; break; - case 7: sItem = "nw_it_mboots006"; break; - case 8: sItem = "nw_it_mbracer003"; break; - case 9: sItem = "nw_it_mneck008"; break; - case 10: sItem = "nw_it_mring008"; break; - case 11: sItem = "nw_maarcl056"; break; - case 12: sItem = "nw_maarcl092"; break; - case 13: sItem = "nw_it_mring014"; break; - case 14: sItem = "nw_it_mneck016"; break; - case 15: sItem = "nw_it_mboots013"; break; - case 16: sItem = "nw_it_mneck027"; break; - case 17: sItem = "nw_it_mbracer008"; break; - case 18: sItem = "nw_it_mneck013"; break; - case 19: sItem = "nw_maarcl089"; break; - case 20: sItem = "nw_it_mbelt012"; break; - case 21: sItem = "nw_it_mbelt013"; break; - case 22: sItem = "nw_it_mbelt014"; break; - case 23: sItem = "nw_it_mring027"; break; - case 24: sItem = "nw_it_mboots007"; break; - case 25: sItem = "nw_it_mbracer004"; break; - case 26: sItem = "nw_it_mneck009"; break; - case 27: sItem = "nw_it_mring018"; break; - case 28: sItem = "nw_maarcl093"; break; - case 29: sItem = "nw_it_mboots002"; break; - case 30: sItem = "nw_it_mboots014"; break; - case 31: sItem = "nw_it_mneck028"; break; - case 32: sItem = "nw_it_mring015"; break; - case 33: sItem = "nw_it_mbracer009"; break; - case 34: sItem = "nw_it_mneck014"; break; - case 35: sItem = "nw_maarcl090"; break; - case 36: sItem = "nw_it_mring028"; break; - case 37: sItem = "nw_it_mneck017"; break; - case 38: sItem = "nw_it_mboots008"; break; - case 39: sItem = "nw_it_mbracer005"; break; - case 40: sItem = "nw_it_mneck010"; break; - case 41: sItem = "nw_it_mmidmisc02"; break; - case 42: sItem = "nw_it_mring019"; break; - } - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(30) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mring027"; break; - case 2: sItem = "nw_it_mboots007"; break; - case 3: sItem = "nw_it_mbracer004"; break; - case 4: sItem = "nw_it_mneck009"; break; - case 5: sItem = "nw_it_mring018"; break; - case 6: sItem = "nw_maarcl093"; break; - case 7: sItem = "nw_it_mboots002"; break; - case 8: sItem = "nw_it_mboots014"; break; - case 9: sItem = "nw_it_mneck028"; break; - case 10: sItem = "nw_it_mring015"; break; - case 11: sItem = "nw_it_mbracer009"; break; - case 12: sItem = "nw_it_mneck014"; break; - case 13: sItem = "nw_maarcl090"; break; - case 14: sItem = "nw_it_mring028"; break; - case 15: sItem = "nw_it_mneck017"; break; - case 16: sItem = "nw_it_mboots008"; break; - case 17: sItem = "nw_it_mbracer005"; break; - case 18: sItem = "nw_it_mneck010"; break; - case 19: sItem = "nw_it_mmidmisc02"; break; - case 20: sItem = "nw_maarcl094"; break; - case 21: sItem = "nw_it_mring019"; break; - case 22: sItem = "nw_it_mring016"; break; - case 23: sItem = "nw_it_mbracer010"; break; - case 24: sItem = "nw_it_mneck015"; break; - case 25: sItem = "nw_maarcl091"; break; - case 26: sItem = "nw_it_mboots009"; break; - case 27: sItem = "nw_it_mbracer006"; break; - case 28: sItem = "nw_it_mneck011"; break; - case 29: sItem = "nw_maarcl095"; break; - case 30: sItem = "nw_it_mneck018"; break; - } - } - //dbSpeak("Create Misc"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - - // * this function just returns an item that is more appropriate - // * for this class. Only wizards, sorcerers, clerics, monks, rogues and bards get this - void CreateGenericClassItem(object oTarget, object oAdventurer, int nSpecific =0) - { - - - if (GetLevelByClass(CLASS_TYPE_DRUID, oAdventurer)>= 1) - { - if (nSpecific == 0) - { - CreateGenericDruidWeapon(oTarget, oAdventurer); - } - else - { - CreateSpecificDruidWeapon(oTarget, oAdventurer); - } - } - else - if (GetLevelByClass(CLASS_TYPE_WIZARD, oAdventurer)>= 1 || GetLevelByClass(CLASS_TYPE_SORCERER, oAdventurer) >= 1) - { - // * 30% chance of getting a magic scroll else get a weapon suited for a wizard - if (Random(100) + 1 > 70) - { - // * grab an arcane scroll as if the wizard had +4 levels - CreateArcaneScroll(oTarget, oAdventurer, 4); - } - else - if (nSpecific == 0) - { - CreateGenericWizardWeapon(oTarget, oAdventurer); - } - else - { - CreateSpecificWizardWeapon(oTarget, oAdventurer); - } - - - } - else - if (GetLevelByClass(CLASS_TYPE_CLERIC, oAdventurer)>= 1) - { - int nRandom = Random(4) + 1; - string sItem = "nw_it_medkit001"; - switch (nRandom) - { - case 1: sItem = "nw_it_medkit001"; break; - case 2: sItem = "nw_it_medkit002"; break; - case 3: sItem = "nw_it_medkit003"; break; - case 4: sItem = "nw_it_medkit004"; break; - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - else - if (GetLevelByClass(CLASS_TYPE_MONK, oAdventurer)>= 1) - { - //dbSpeak("in monk function"); - if (nSpecific == 0) - { - CreateGenericMonkWeapon(oTarget, oAdventurer); - } - else - { - CreateSpecificMonkWeapon(oTarget, oAdventurer); - } - } - else - if (GetLevelByClass(CLASS_TYPE_ROGUE, oAdventurer)>= 1) - { - // * give a misc item as if a couple levels higher - CreateGenericMiscItem(oTarget, oAdventurer, 2); - } - else - if (GetLevelByClass(CLASS_TYPE_BARD, oAdventurer)>= 1) - { - // * give a misc item as if a couple levels higher - CreateGenericMiscItem(oTarget, oAdventurer, 2); - } - - } - void CreateGenericRodStaffWand(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgwn013"; break; - case 2: sItem = "nw_wmgwn006"; break; - case 3: sItem = "nw_it_gem002"; break; // gem for variety - } - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgwn013"; break; - case 2: sItem = "nw_wmgwn006"; break; - case 3: sItem = "nw_it_gem002"; break;// gem for variety - } - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(4) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgwn006"; break; - case 2: sItem = "nw_wmgwn004"; break; - case 3: sItem = "nw_wmgrd002"; break; - case 4: sItem = "nw_wmgwn012"; break; - } - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(11) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgwn004"; break; - case 2: sItem = "nw_wmgwn002"; break; - case 3: sItem = "nw_wmgwn007"; break; - case 4: sItem = "nw_wmgwn003"; break; - case 5: sItem = "nw_wmgwn010"; break; - case 6: sItem = "nw_wmgwn011"; break; - case 7: sItem = "nw_wmgwn005"; break; - case 8: sItem = "nw_wmgwn008"; break; - case 9: sItem = "nw_wmgwn009"; break; - case 10: sItem = "nw_wmgrd002"; break; - case 11: sItem = "nw_wmgwn012"; break; - } - - } - else // * 2500 - 16500 - { - int nRandom = d8(); - switch (nRandom) - { - case 1: sItem = "nw_wmgwn002"; break; - case 2: sItem = "nw_wmgwn007"; break; - case 3: sItem = "nw_wmgwn003"; break; - case 4: sItem = "nw_wmgwn010"; break; - case 5: sItem = "nw_wmgwn011"; break; - case 6: sItem = "nw_wmgwn005"; break; - case 7: sItem = "nw_wmgwn008"; break; - case 8: sItem = "nw_wmgwn009"; break; - } - - } - //dbSpeak("Generic Rod staff wand"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - - void CreateGenericMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthsh001"; break; - case 2: sItem = "nw_wblcl001"; break; - case 3: sItem = "nw_wdbqs001"; break; - case 4: sItem = "nw_wbwsl001"; break; - case 5: sItem = "nw_wswdg001"; break; - case 6: sItem = "nw_wspka001"; break; - case 7: sItem = "nw_wbwxh001"; break; - case 8: sItem = "nw_waxhn001"; break; - case 9: sItem = "nw_wbwxl001"; break; - case 10: sItem = "nw_wthmsh002"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(14) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthsh001"; break; - case 2: sItem = "nw_wblcl001"; break; - case 3: sItem = "nw_wdbqs001"; break; - case 4: sItem = "nw_wbwsl001"; break; - case 5: sItem = "nw_wswdg001"; break; - case 6: sItem = "nw_wspka001"; break; - case 7: sItem = "nw_wbwxh001"; break; - case 8: sItem = "nw_waxhn001"; break; - case 9: sItem = "nw_wbwxl001"; break; - case 10: sItem = "nw_wthmsh002"; break; - case 11: sItem = "nw_wbwmsl001"; break; - case 12: sItem = "nw_wbwmxh002"; break; - case 13: sItem = "nw_wthmsh008"; break; - case 14: sItem = "nw_wbwmxl002"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmsl001"; break; - case 2: sItem = "nw_wbwmxh002"; break; - case 3: sItem = "nw_wthmsh008"; break; - case 4: sItem = "nw_wbwmxl002"; break; - case 5: sItem = "nw_wthmsh009"; break; - case 6: sItem = "nw_wblmcl002"; break; - case 7: sItem = "nw_wdbmqs002"; break; - case 8: sItem = "nw_wswmdg002"; break; - case 9: sItem = "nw_wspmka002"; break; - case 10: sItem = "nw_waxmhn002"; break; - case 11: sItem = "nw_wbwmsl009"; break; - case 12: sItem = "nw_wbwmxh008"; break; - case 13: sItem = "nw_wbwmxl008"; break; - } - - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmsh009"; break; - case 2: sItem = "nw_wblmcl002"; break; - case 3: sItem = "nw_wdbmqs002"; break; - case 4: sItem = "nw_wswmdg002"; break; - case 5: sItem = "nw_wspmka002"; break; - case 6: sItem = "nw_waxmhn002"; break; - case 7: sItem = "nw_wbwmsl009"; break; - case 8: sItem = "nw_wbwmxh008"; break; - case 9: sItem = "nw_wbwmxl008"; break; - case 10: sItem = "nw_wbwmsl010"; break; - case 11: sItem = "nw_wbwmxh009"; break; - case 12: sItem = "nw_wbwmxl009"; break; - case 13: sItem = "nw_wblmcl010"; break; - case 14: sItem = "nw_wdbmqs008"; break; - case 15: sItem = "nw_wswmdg008"; break; - case 16: sItem = "nw_wspmka008"; break; - case 17: sItem = "nw_waxmhn010"; break; - } - } - else // * 2500 - 16500 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmsl010"; break; - case 2: sItem = "nw_wbwmxh009"; break; - case 3: sItem = "nw_wbwmxl009"; break; - case 4: sItem = "nw_wblmcl010"; break; - case 5: sItem = "nw_wdbmqs008"; break; - case 6: sItem = "nw_wswmdg008"; break; - case 7: sItem = "nw_wspmka008"; break; - case 8: sItem = "nw_waxmhn010"; break; - case 9: sItem = "nw_wblmcl011"; break; - case 10: sItem = "nw_wdbmqs009"; break; - case 11: sItem = "nw_wswmdg009"; break; - case 12: sItem = "nw_wspmka009"; break; - case 13: sItem = "nw_waxmhn011"; break; - } - } - //dbSpeak("Generic Monk Weapon"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0) - { - - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 800 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmsh003"; break; - case 2: sItem = "nw_wthmsh006"; break; - case 3: CreateGenericMonkWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; break; - } - - } - else if (GetRange(2, nHD)) // * 2500 - { - int nRandom = Random(8) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmsh003"; break; - case 2: sItem = "nw_wthmsh006"; break; - case 3: sItem = "nw_wthmsh004"; break; - case 4: sItem = "nw_wthmsh007"; break; - case 5: sItem = "NW_IT_MGLOVE016"; break; - case 6: sItem = "NW_IT_MGLOVE021"; break; - case 7: sItem = "NW_IT_MGLOVE026"; break; - case 8: CreateGenericMonkWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; break; - } - - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(21) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmsh006"; break; - case 2: sItem = "nw_wthmsh004"; break; - case 3: sItem = "nw_wthmsh007"; break; - case 4: sItem = "nw_wbwmsl005"; break; - case 5: sItem = "nw_wbwmxh005"; break; - case 6: sItem = "nw_wspmka004"; break; - case 7: sItem = "nw_wbwmxl005"; break; - case 8: sItem = "nw_wspmka007"; break; - case 9: sItem = "nw_wswmdg006"; break; - case 10: sItem = "nw_wspmka005"; break; - case 11: sItem = "NW_IT_MGLOVE016"; break; - case 12: sItem = "NW_IT_MGLOVE021"; break; - case 13: sItem = "NW_IT_MGLOVE026"; break; - - case 14: sItem = "NW_IT_MGLOVE017"; break; - case 15: sItem = "NW_IT_MGLOVE022"; break; - case 16: sItem = "NW_IT_MGLOVE027"; break; - - case 17: sItem = "NW_IT_MGLOVE018"; break; - case 18: sItem = "NW_IT_MGLOVE023"; break; - case 19: sItem = "NW_IT_MGLOVE028"; break; - - case 20: sItem = "NW_IT_MGLOVE029"; break; - case 21: sItem = "NW_IT_MGLOVE030"; break; - - - } - - } - else if (GetRange(4, nHD)) // * 2500 -16500 - { - int nRandom = Random(22) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmsl005"; break; - case 2: sItem = "nw_wbwmxh005"; break; - case 3: sItem = "nw_wspmka004"; break; - case 4: sItem = "nw_wbwmxl005"; break; - case 5: sItem = "nw_wspmka007"; break; - case 6: sItem = "nw_wswmdg006"; break; - case 7: sItem = "nw_wspmka005"; break; - case 8: sItem = "nw_wblmcl004"; break; - case 9: sItem = "nw_wblmcl003"; break; - case 10: sItem = "nw_wbwmsl003"; break; - case 11: sItem = "nw_wbwmxh003"; break; - case 12: sItem = "nw_waxmhn004"; break; - case 13: sItem = "nw_wbwmxl003"; break; - - case 14: sItem = "NW_IT_MGLOVE017"; break; - case 15: sItem = "NW_IT_MGLOVE022"; break; - - case 16: sItem = "NW_IT_MGLOVE018"; break; - case 17: sItem = "NW_IT_MGLOVE023"; break; - case 18: sItem = "NW_IT_MGLOVE028"; break; - - case 19: sItem = "NW_IT_MGLOVE029"; break; - case 20: sItem = "NW_IT_MGLOVE030"; break; - - case 21: sItem = "NW_IT_MGLOVE019"; break; - case 22: sItem = "NW_IT_MGLOVE024"; break; - - - } - - } - else // * 16000 + - { - int nRandom = Random(24) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmxl003"; break; - case 2: sItem = "nw_wspmka006"; break; - case 3: sItem = "nw_wbwmxl004"; break; - case 4: sItem = "nw_wspmka003"; break; - case 5: sItem = "nw_wbwmxl007"; break; - case 6: sItem = "nw_waxmhn003"; break; - case 7: sItem = "nw_wblmcl005"; break; - case 8: sItem = "nw_wswmdg004"; break; - case 9: sItem = "nw_wbwmsl007"; break; - case 10: sItem = "nw_wbwmxh004"; break; - case 11: sItem = "nw_waxmhn005"; break; - case 12: sItem = "nw_wbwmxh007"; break; - case 13: sItem = "nw_wswmdg003"; break; - case 14: sItem = "nw_wswmdg007"; break; - case 15: sItem = "nw_wbwmsl006"; break; - case 16: sItem = "nw_wbwmsl008"; break; - case 17: sItem = "nw_wblmcl006"; break; - case 18: sItem = "nw_wbwmsl004"; break; - case 19: sItem = "nw_waxmhn006"; break; - case 20: sItem = "nw_wbwmxh006"; break; - case 21: sItem = "nw_wswmdg005"; break; - case 22: sItem = "nw_wbwmxl006"; break; - - case 23: sItem = "NW_IT_MGLOVE020"; break; - case 24: sItem = "NW_IT_MGLOVE025"; break; - - } - - } - //dbSpeak("Specific Monk Weapon"); - - dbCreateItemOnObject(sItem, oTarget, 1); - - } - - void CreateGenericDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(8) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthdt001"; break; - case 2: sItem = "nw_wblcl001"; break; - case 3: sItem = "nw_wdbqs001"; break; - case 4: sItem = "nw_wplss001"; break; - case 5: sItem = "nw_wswdg001"; break; - case 6: sItem = "nw_wspsc001"; break; - case 7: sItem = "nw_wswsc001"; break; - case 8: sItem = "nw_wthmdt002"; break; - } - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(11) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthdt001"; break; - case 2: sItem = "nw_wblcl001"; break; - case 3: sItem = "nw_wdbqs001"; break; - case 4: sItem = "nw_wplss001"; break; - case 5: sItem = "nw_wswdg001"; break; - case 6: sItem = "nw_wspsc001"; break; - case 7: sItem = "nw_wswsc001"; break; - case 8: sItem = "nw_wthmdt002"; break; - case 9: sItem = "nw_wthmdt005"; break; - case 10: sItem = "nw_wbwmsl001"; break; - case 11: sItem = "nw_wthmdt008"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmdt005"; break; - case 2: sItem = "nw_wbwmsl001"; break; - case 3: sItem = "nw_wthmdt008"; break; - case 4: sItem = "nw_wthmdt009"; break; - case 5: sItem = "nw_wthmdt006"; break; - case 6: sItem = "nw_wblmcl002"; break; - case 7: sItem = "nw_wdbmqs002"; break; - case 8: sItem = "nw_wplmss002"; break; - case 9: sItem = "nw_wswmdg002"; break; - case 10: sItem = "nw_wspmsc002"; break; - case 11: sItem = "nw_wswmsc002"; break; - case 12: sItem = "nw_wthmdt003"; break; - case 13: sItem = "nw_wbwmsl009"; break; - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(19) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmdt009"; break; - case 2: sItem = "nw_wthmdt006"; break; - case 3: sItem = "nw_wblmcl002"; break; - case 4: sItem = "nw_wdbmqs002"; break; - case 5: sItem = "nw_wplmss002"; break; - case 6: sItem = "nw_wswmdg002"; break; - case 7: sItem = "nw_wspmsc002"; break; - case 8: sItem = "nw_wswmsc002"; break; - case 9: sItem = "nw_wthmdt003"; break; - case 10: sItem = "nw_wbwmsl009"; break; - case 11: sItem = "nw_wthmdt007"; break; - case 12: sItem = "nw_wthmdt004"; break; - case 13: sItem = "nw_wbwmsl010"; break; - case 14: sItem = "nw_wblmcl010"; break; - case 15: sItem = "nw_wdbmqs008"; break; - case 16: sItem = "nw_wplmss010"; break; - case 17: sItem = "nw_wswmdg008"; break; - case 18: sItem = "nw_wspmsc010"; break; - case 19: sItem = "nw_wswmsc010"; break; - } - - } - else // * 2500 - 16500 - { - int nRandom = Random(15) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmdt007"; break; - case 2: sItem = "nw_wthmdt004"; break; - case 3: sItem = "nw_wbwmsl010"; break; - case 4: sItem = "nw_wblmcl010"; break; - case 5: sItem = "nw_wdbmqs008"; break; - case 6: sItem = "nw_wplmss010"; break; - case 7: sItem = "nw_wswmdg008"; break; - case 8: sItem = "nw_wspmsc010"; break; - case 9: sItem = "nw_wswmsc010"; break; - case 10: sItem = "nw_wblmcl011"; break; - case 11: sItem = "nw_wdbmqs009"; break; - case 12: sItem = "nw_wplmss011"; break; - case 13: sItem = "nw_wswmdg009"; break; - case 14: sItem = "nw_wspmsc011"; break; - case 15: sItem = "nw_wswmsc011"; break; - } - - } - //dbSpeak("Generic Druid weapon"); - - dbCreateItemOnObject(sItem, oTarget, 1); - - - } - void CreateSpecificDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0) - { - - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericDruidWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; - - } - else if (GetRange(2, nHD)) // * 2500 - { - CreateGenericDruidWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs005"; break; - case 2: sItem = "nw_wdbmqs006"; break; - case 3: sItem = "nw_wbwmsl005"; break; - case 4: sItem = "nw_wswmdg006"; break; - case 5: CreateGenericDruidWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 -16500 - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs005"; break; - case 2: sItem = "nw_wdbmqs006"; break; - case 3: sItem = "nw_wbwmsl005"; break; - case 4: sItem = "nw_wswmdg006"; break; - case 5: sItem = "nw_wblmcl004"; break; - case 6: sItem = "nw_wdbmqs004"; break; - case 7: sItem = "nw_wblmcl003"; break; - case 8: sItem = "nw_wbwmsl003"; break; - case 9: sItem = "nw_wswmsc004"; break; - case 10: sItem = "nw_wplmss005"; break; - } - - } - else // * 16000 + - { - int nRandom = Random(18) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs003"; break; - case 2: sItem = "nw_wblmcl005"; break; - case 3: sItem = "nw_wplmss007"; break; - case 4: sItem = "nw_wswmdg004"; break; - case 5: sItem = "nw_wbwmsl007"; break; - case 6: sItem = "nw_wplmss006"; break; - case 7: sItem = "nw_wswmsc006"; break; - case 8: sItem = "nw_wswmdg003"; break; - case 9: sItem = "nw_wswmdg007"; break; - case 10: sItem = "nw_wswmsc007"; break; - case 11: sItem = "nw_wbwmsl006"; break; - case 12: sItem = "nw_wbwmsl008"; break; - case 13: sItem = "nw_wdbmqs007"; break; - case 14: sItem = "nw_wblmcl006"; break; - case 15: sItem = "nw_wbwmsl004"; break; - case 16: sItem = "nw_wswmsc005"; break; - case 17: sItem = "nw_wplmss004"; break; - case 18: sItem = "nw_wswmdg005"; break; - } - - } - //dbSpeak("specific druid weapon"); - - dbCreateItemOnObject(sItem, oTarget, 1); - - } - - void CreateGenericWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblcl001"; break; - case 2: sItem = "nw_wdbqs001"; break; - case 3: sItem = "nw_wswdg001"; break; - case 4: sItem = "nw_wbwxh001"; break; - case 5: sItem = "nw_wbwxl001"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(6) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblcl001"; break; - case 2: sItem = "nw_wdbqs001"; break; - case 3: sItem = "nw_wswdg001"; break; - case 4: sItem = "nw_wbwxh001"; break; - case 5: sItem = "nw_wbwxl001"; break; - case 6: sItem = "nw_wbwmxl002"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(6) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmxl002"; break; - case 2: sItem = "nw_wblmcl002"; break; - case 3: sItem = "nw_wdbmqs002"; break; - case 4: sItem = "nw_wswmdg002"; break; - case 5: sItem = "nw_wbwmxh008"; break; - case 6: sItem = "nw_wbwmxl008"; break; - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmcl002"; break; - case 2: sItem = "nw_wdbmqs002"; break; - case 3: sItem = "nw_wswmdg002"; break; - case 4: sItem = "nw_wbwmxh008"; break; - case 5: sItem = "nw_wbwmxl008"; break; - case 6: sItem = "nw_wbwmxh009"; break; - case 7: sItem = "nw_wbwmxl009"; break; - case 8: sItem = "nw_wblmcl010"; break; - case 9: sItem = "nw_wdbmqs008"; break; - case 10: sItem = "nw_wswmdg008"; break; - } - - } - else // * 2500 - 16500 - { - int nRandom = Random(8) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmxh009"; break; - case 2: sItem = "nw_wbwmxl009"; break; - case 3: sItem = "nw_wblmcl010"; break; - case 4: sItem = "nw_wdbmqs008"; break; - case 5: sItem = "nw_wswmdg008"; break; - case 6: sItem = "nw_wblmcl011"; break; - case 7: sItem = "nw_wdbmqs009"; break; - case 8: sItem = "nw_wswmdg009"; break; - } - - } - //dbSpeak("Generic Wizard or Sorcerer Weapon"); - - dbCreateItemOnObject(sItem, oTarget, 1); - - } - void CreateSpecificWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0) - { - - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericWizardWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; - } - else if (GetRange(2, nHD)) // * 2500 - { - CreateGenericWizardWeapon(oTarget, oAdventurer, JUMP_LEVEL); return; - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs005"; break; - case 2: sItem = "nw_wdbmqs006"; break; - case 3: sItem = "nw_wbwmxh005"; break; - case 4: sItem = "nw_wbwmxl005"; break; - case 5: sItem = "nw_wswmdg006"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 -16500 - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs005"; break; - case 2: sItem = "nw_wdbmqs006"; break; - case 3: sItem = "nw_wbwmxh005"; break; - case 4: sItem = "nw_wbwmxl005"; break; - case 5: sItem = "nw_wswmdg006"; break; - case 6: sItem = "nw_wblmcl004"; break; - case 7: sItem = "nw_wdbmqs004"; break; - case 8: sItem = "nw_wblmcl003"; break; - case 9: sItem = "nw_wbwmxh003"; break; - case 10: sItem = "nw_wbwmxl003"; break; - } - - } - else // * 16000 + - { - int nRandom = Random(15) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmxl003"; break; - case 2: sItem = "nw_wdbmqs003"; break; - case 3: sItem = "nw_wbwmxl004"; break; - case 4: sItem = "nw_wbwmxl007"; break; - case 5: sItem = "nw_wblmcl005"; break; - case 6: sItem = "nw_wswmdg004"; break; - case 7: sItem = "nw_wbwmxh004"; break; - case 8: sItem = "nw_wbwmxh007"; break; - case 9: sItem = "nw_wswmdg003"; break; - case 10: sItem = "nw_wswmdg007"; break; - case 11: sItem = "nw_wdbmqs007"; break; - case 12: sItem = "nw_wblmcl006"; break; - case 13: sItem = "nw_wbwmxh006"; break; - case 14: sItem = "nw_wswmdg005"; break; - case 15: sItem = "nw_wbwmxl006"; break; - } - - } - //dbSpeak("Specific Wizard or Sorcerer Weapon"); - - dbCreateItemOnObject(sItem, oTarget, 1); - - } - - void CreateGenericSimple(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = d12(); - switch (nRandom) - { - case 1: sItem = "nw_wthdt001"; break; - case 2: sItem = "nw_wblcl001"; break; - case 3: sItem = "nw_wbwsl001"; break; - case 4: sItem = "nw_wplss001"; break; - case 5: sItem = "nw_wdbqs001"; break; - case 6: sItem = "nw_wswdg001"; break; - case 7: sItem = "nw_wblml001"; break; - case 8: sItem = "nw_wbwxh001"; break; - case 9: sItem = "nw_wspsc001"; break; - case 10: sItem = "nw_wblms001"; break; - case 11: sItem = "nw_wbwxl001"; break; - case 12: sItem = "nw_wthmdt002"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthdt001"; break; - case 2: sItem = "nw_wblcl001"; break; - case 3: sItem = "nw_wbwsl001"; break; - case 4: sItem = "nw_wplss001"; break; - case 5: sItem = "nw_wdbqs001"; break; - case 6: sItem = "nw_wswdg001"; break; - case 7: sItem = "nw_wblml001"; break; - case 8: sItem = "nw_wbwxh001"; break; - case 9: sItem = "nw_wspsc001"; break; - case 10: sItem = "nw_wblms001"; break; - case 11: sItem = "nw_wbwxl001"; break; - case 12: sItem = "nw_wthmdt002"; break; - case 13: sItem = "nw_wthmdt005"; break; - case 14: sItem = "nw_wbwmsl001"; break; - case 15: sItem = "nw_wbwmxh002"; break; - case 16: sItem = "nw_wthmdt008"; break; - case 17: sItem = "nw_wbwmxl002"; break; - } - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(19) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmdt005"; break; - case 2: sItem = "nw_wbwmsl001"; break; - case 3: sItem = "nw_wbwmxh002"; break; - case 4: sItem = "nw_wthmdt008"; break; - case 5: sItem = "nw_wbwmxl002"; break; - case 6: sItem = "nw_wthmdt009"; break; - case 7: sItem = "nw_wthmdt006"; break; - case 8: sItem = "nw_wblmcl002"; break; - case 9: sItem = "nw_wplmss002"; break; - case 10: sItem = "nw_wdbmqs002"; break; - case 11: sItem = "nw_wswmdg002"; break; - case 12: sItem = "nw_wblmml002"; break; - case 13: sItem = "nw_wspmsc002"; break; - case 14: sItem = "nw_wblmms002"; break; - case 15: sItem = "nw_wthmdt003"; break; - case 16: sItem = "nw_wthmdt003"; break; - case 17: sItem = "nw_wbwmsl009"; break; - case 18: sItem = "nw_wbwmxh008"; break; - case 19: sItem = "nw_wbwmxl008"; break; - } - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(27) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmdt009"; break; - case 2: sItem = "nw_wthmdt006"; break; - case 3: sItem = "nw_wblmcl002"; break; - case 4: sItem = "nw_wplmss002"; break; - case 5: sItem = "nw_wdbmqs002"; break; - case 6: sItem = "nw_wswmdg002"; break; - case 7: sItem = "nw_wblmml002"; break; - case 8: sItem = "nw_wspmsc002"; break; - case 9: sItem = "nw_wblmms002"; break; - case 10: sItem = "nw_wthmdt003"; break; - case 11: sItem = "nw_wthmdt003"; break; - case 12: sItem = "nw_wbwmsl009"; break; - case 13: sItem = "nw_wbwmxh008"; break; - case 14: sItem = "nw_wbwmxl008"; break; - case 15: sItem = "nw_wthmdt007"; break; - case 16: sItem = "nw_wthmdt004"; break; - case 17: sItem = "nw_wbwmsl010"; break; - case 18: sItem = "nw_wbwmxh009"; break; - case 19: sItem = "nw_wbwmxl009"; break; - case 20: sItem = "nw_wbwmsl005"; break; - case 21: sItem = "nw_wblmcl010"; break; - case 22: sItem = "nw_wplmss010"; break; - case 23: sItem = "nw_wdbmqs008"; break; - case 24: sItem = "nw_wswmdg008"; break; - case 25: sItem = "nw_wblmml011"; break; - case 26: sItem = "nw_wspmsc010"; break; - case 27: sItem = "nw_wblmms010"; break; - - - - } - - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(23) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmdt007"; break; - case 2: sItem = "nw_wthmdt004"; break; - case 3: sItem = "nw_wbwmsl010"; break; - case 4: sItem = "nw_wbwmxh009"; break; - case 5: sItem = "nw_wbwmxl009"; break; - case 6: sItem = "nw_wbwmsl005"; break; - case 7: sItem = "nw_wblmcl010"; break; - case 8: sItem = "nw_wplmss010"; break; - case 9: sItem = "nw_wdbmqs008"; break; - case 10: sItem = "nw_wswmdg008"; break; - case 11: sItem = "nw_wblmml011"; break; - case 12: sItem = "nw_wspmsc010"; break; - case 13: sItem = "nw_wblmms010"; break; - case 14: sItem = "nw_wblmms010"; break; - case 15: sItem = "nw_wblmms010"; break; - case 16: sItem = "nw_wblmms010"; break; - case 17: sItem = "nw_wblmcl011"; break; - case 18: sItem = "nw_wplmss011"; break; - case 19: sItem = "nw_wdbmqs009"; break; - case 20: sItem = "nw_wswmdg009"; break; - case 21: sItem = "nw_wblmml012"; break; - case 22: sItem = "nw_wspmsc011"; break; - case 23: sItem = "nw_wblmms011"; break; - - - - } - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(7) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmcl011"; break; - case 2: sItem = "nw_wplmss011"; break; - case 3: sItem = "nw_wdbmqs009"; break; - case 4: sItem = "nw_wswmdg009"; break; - case 5: sItem = "nw_wblmml012"; break; - case 6: sItem = "nw_wspmsc011"; break; - case 7: sItem = "nw_wblmms011"; break; - - - - } - } - //dbSpeak("Create Generic SImple; Specific = " + IntToString(nModifier)); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateGenericMartial(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - - int nHD = GetHitDice(oAdventurer) +nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthax001"; break; - case 2: sItem = "nw_wblhl001"; break; - case 3: sItem = "nw_waxhn001"; break; - case 4: sItem = "nw_wblfl001"; break; - case 5: sItem = "nw_waxbt001"; break; - case 6: sItem = "nw_wplhb001"; break; - case 7: sItem = "nw_wswss001"; break; - case 8: sItem = "nw_wblhw001"; break; - case 9: sItem = "nw_wblfh001"; break; - case 10: sItem = "nw_wswls001"; break; - case 11: sItem = "nw_wswsc001"; break; - case 12: sItem = "nw_waxgr001"; break; - case 13: sItem = "nw_wswrp001"; break; - case 14: sItem = "nw_wbwsh001"; break; - case 15: sItem = "nw_wswbs001"; break; - case 16: sItem = "nw_wswgs001"; break; - case 17: sItem = "nw_wbwln001"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(20) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthax001"; break; - case 2: sItem = "nw_wblhl001"; break; - case 3: sItem = "nw_waxhn001"; break; - case 4: sItem = "nw_wblfl001"; break; - case 5: sItem = "nw_waxbt001"; break; - case 6: sItem = "nw_wplhb001"; break; - case 7: sItem = "nw_wswss001"; break; - case 8: sItem = "nw_wblhw001"; break; - case 9: sItem = "nw_wblfh001"; break; - case 10: sItem = "nw_wswls001"; break; - case 11: sItem = "nw_wswsc001"; break; - case 12: sItem = "nw_waxgr001"; break; - case 13: sItem = "nw_wswrp001"; break; - case 14: sItem = "nw_wbwsh001"; break; - case 15: sItem = "nw_wswbs001"; break; - case 16: sItem = "nw_wswgs001"; break; - case 17: sItem = "nw_wbwln001"; break; - case 18: sItem = "nw_wthmax002"; break; - case 19: sItem = "nw_wbwmsh002"; break; - case 20: sItem = "nw_wbwmln002"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(20) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmax002"; break; - case 2: sItem = "nw_wbwmsh002"; break; - case 3: sItem = "nw_wbwmln002"; break; - case 4: sItem = "nw_wblmhl002"; break; - case 5: sItem = "nw_waxmhn002"; break; - case 6: sItem = "nw_wblmfl002"; break; - case 7: sItem = "nw_waxmbt002"; break; - case 8: sItem = "nw_wplmhb002"; break; - case 9: sItem = "nw_wblmhw002"; break; - case 10: sItem = "nw_wblmfh002"; break; - case 11: sItem = "nw_wswmls002"; break; - case 12: sItem = "nw_wswmsc002"; break; - case 13: sItem = "nw_waxmgr002"; break; - case 14: sItem = "nw_wswmrp002"; break; - case 15: sItem = "nw_wswmbs002"; break; - case 16: sItem = "nw_wswmgs002"; break; - case 17: sItem = "nw_wthmax008"; break; - case 18: sItem = "nw_wbwmsh008"; break; - case 19: sItem = "nw_wbwmln008"; break; - case 20: sItem = "nw_wswmss002"; break; - - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(33) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmhl002"; break; - case 2: sItem = "nw_waxmhn002"; break; - case 3: sItem = "nw_wblmfl002"; break; - case 4: sItem = "nw_waxmbt002"; break; - case 5: sItem = "nw_wplmhb002"; break; - case 6: sItem = "nw_wblmhw002"; break; - case 7: sItem = "nw_wblmfh002"; break; - case 8: sItem = "nw_wswmls002"; break; - case 9: sItem = "nw_wswmsc002"; break; - case 10: sItem = "nw_waxmgr002"; break; - case 11: sItem = "nw_wswmrp002"; break; - case 12: sItem = "nw_wswmbs002"; break; - case 13: sItem = "nw_wswmgs002"; break; - case 14: sItem = "nw_wthmax008"; break; - case 15: sItem = "nw_wbwmsh008"; break; - case 16: sItem = "nw_wbwmln008"; break; - case 17: sItem = "nw_wbwmsh009"; break; - case 18: sItem = "nw_wbwmln009"; break; - case 19: sItem = "nw_wblmhl010"; break; - case 20: sItem = "nw_waxmhn010"; break; - case 21: sItem = "nw_wblmfl010"; break; - case 22: sItem = "nw_waxmbt010"; break; - case 23: sItem = "nw_wplmhb010"; break; - case 24: sItem = "nw_wblmhw011"; break; - case 25: sItem = "nw_wblmfh010"; break; - case 26: sItem = "nw_wswmls010"; break; - case 27: sItem = "nw_waxmgr009"; break; - case 28: sItem = "nw_wswmbs009"; break; - case 29: sItem = "nw_wswmgs011"; break; - case 30: sItem = "nw_wswmrp010"; break; - case 31: sItem = "nw_wswmsc010"; break; - case 32: sItem = "nw_wswmss002"; break; - case 33: sItem = "nw_wswmss009"; break; - } - - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(20) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmsh009"; break; - case 2: sItem = "nw_wbwmln009"; break; - case 3: sItem = "nw_wblmhl010"; break; - case 4: sItem = "nw_waxmhn010"; break; - case 5: sItem = "nw_wblmfl010"; break; - case 6: sItem = "nw_waxmbt010"; break; - case 7: sItem = "nw_wplmhb010"; break; - case 8: sItem = "nw_wblmhw011"; break; - case 9: sItem = "nw_wblmfh010"; break; - case 10: sItem = "nw_wswmls010"; break; - case 11: sItem = "nw_waxmgr009"; break; - case 12: sItem = "nw_wswmbs009"; break; - case 13: sItem = "nw_wswmgs011"; break; - case 14: sItem = "nw_wthmax009"; break; - case 15: sItem = "nw_wswmrp010"; break; - case 16: sItem = "nw_wswmrp011"; break; - case 17: sItem = "nw_wswmsc010"; break; - case 18: sItem = "nw_wswmss009"; break; - case 19: sItem = "nw_wswmsc011"; break; - case 20: sItem = "nw_wswmss011"; break; - } - - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(14) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmax009"; break; - case 2: sItem = "nw_waxmhn011"; break; - case 3: sItem = "nw_wblmfl011"; break; - case 4: sItem = "nw_waxmbt011"; break; - case 5: sItem = "nw_wplmhb011"; break; - case 6: sItem = "nw_wblmhw012"; break; - case 7: sItem = "nw_wblmfh011"; break; - case 8: sItem = "nw_wswmls012"; break; - case 9: sItem = "nw_waxmgr011"; break; - case 10: sItem = "nw_wswmbs010"; break; - case 11: sItem = "nw_wswmgs012"; break; - case 12: sItem = "nw_wswmrp011"; break; - case 13: sItem = "nw_wswmsc011"; break; - case 14: sItem = "nw_wswmss011"; break; - } - - } - - //dbSpeak("Create Generic Martial"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateGenericExotic(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthsh001"; break; - case 2: sItem = "nw_wspka001"; break; - case 3: sItem = "nw_wspku001"; break; - case 4: sItem = "nw_wplsc001"; break; - case 5: sItem = "nw_wdbax001"; break; - case 6: sItem = "nw_wdbma001"; break; - case 7: sItem = "nw_wswka001"; break; - case 8: sItem = "nw_wthmsh002"; break; - case 9: sItem = "nw_wdbsw001"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthsh001"; break; - case 2: sItem = "nw_wspka001"; break; - case 3: sItem = "nw_wspku001"; break; - case 4: sItem = "nw_wplsc001"; break; - case 5: sItem = "nw_wdbax001"; break; - case 6: sItem = "nw_wdbma001"; break; - case 7: sItem = "nw_wswka001"; break; - case 8: sItem = "nw_wthmsh002"; break; - case 9: sItem = "nw_wdbsw001"; break; - case 10: sItem = "nw_wthmsh005"; break; - case 11: sItem = "nw_wspmka002"; break; - case 12: sItem = "nw_wspmku002"; break; - case 13: sItem = "nw_wplmsc002"; break; - case 14: sItem = "nw_wdbmax002"; break; - case 15: sItem = "nw_wdbmma002"; break; - case 16: sItem = "nw_wswmka002"; break; - case 17: sItem = "nw_wdbmsw002"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbsw001"; break; - case 2: sItem = "nw_wthmsh005"; break; - case 3: sItem = "nw_wspmka002"; break; - case 4: sItem = "nw_wspmku002"; break; - case 5: sItem = "nw_wplmsc002"; break; - case 6: sItem = "nw_wdbmax002"; break; - case 7: sItem = "nw_wdbmma002"; break; - case 8: sItem = "nw_wswmka002"; break; - case 9: sItem = "nw_wdbmsw002"; break; - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmsh005"; break; - case 2: sItem = "nw_wspmka002"; break; - case 3: sItem = "nw_wspmku002"; break; - case 4: sItem = "nw_wplmsc002"; break; - case 5: sItem = "nw_wdbmax002"; break; - case 6: sItem = "nw_wdbmma002"; break; - case 7: sItem = "nw_wswmka002"; break; - case 8: sItem = "nw_wdbmsw002"; break; - case 9: sItem = "nw_wthmsh008"; break; - case 10: sItem = "nw_wspmka008"; break; - case 11: sItem = "nw_wspmku008"; break; - case 12: sItem = "nw_wplmsc010"; break; - case 13: sItem = "nw_wdbmax010"; break; - case 14: sItem = "nw_wdbmma010"; break; - case 15: sItem = "nw_wswmka010"; break; - case 16: sItem = "nw_wdbmsw010"; break; - case 17: sItem = "nw_wthmsh009"; break; - } - - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wspmka008"; break; - case 2: sItem = "nw_wspmku008"; break; - case 3: sItem = "nw_wplmsc010"; break; - case 4: sItem = "nw_wdbmax010"; break; - case 5: sItem = "nw_wdbmma010"; break; - case 6: sItem = "nw_wswmka010"; break; - case 7: sItem = "nw_wdbmsw010"; break; - case 8: sItem = "nw_wthmsh009"; break; - case 9: sItem = "nw_wspmka009"; break; - case 10: sItem = "nw_wspmku009"; break; - case 11: sItem = "nw_wplmsc011"; break; - case 12: sItem = "nw_wdbmax011"; break; - case 13: sItem = "nw_wdbmma011"; break; - } - - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmsw010"; break; - case 2: sItem = "nw_wthmsh009"; break; - case 3: sItem = "nw_wspmka009"; break; - case 4: sItem = "nw_wspmku009"; break; - case 5: sItem = "nw_wplmsc011"; break; - case 6: sItem = "nw_wdbmax011"; break; - case 7: sItem = "nw_wdbmma011"; break; - case 8: sItem = "nw_wswmka011"; break; - case 9: sItem = "nw_wdbmsw011"; break; - } - - } - //dbSpeak("Create generic exotic"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateGenericLightArmor(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_aarcl009"; break; - case 2: sItem = "nw_ashsw001"; break; - case 3: sItem = "nw_aarcl001"; break; - case 4: sItem = "nw_aarcl002"; break; - case 5: sItem = "nw_aarcl012"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_aarcl009"; break; - case 2: sItem = "nw_ashsw001"; break; - case 3: sItem = "nw_aarcl001"; break; - case 4: sItem = "nw_aarcl002"; break; - case 5: sItem = "nw_aarcl012"; break; - case 6: sItem = "nw_maarcl043"; break; - case 7: sItem = "nw_ashmsw002"; break; - case 8: sItem = "nw_maarcl044"; break; - case 9: sItem = "nw_maarcl045"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(8) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl043"; break; - case 2: sItem = "nw_ashmsw002"; break; - case 3: sItem = "nw_maarcl044"; break; - case 4: sItem = "nw_maarcl045"; break; - case 5: sItem = "nw_maarcl072"; break; - case 6: sItem = "nw_ashmsw008"; break; - case 7: sItem = "nw_maarcl071"; break; - case 8: sItem = "nw_maarcl075"; break; - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl072"; break; - case 2: sItem = "nw_ashmsw008"; break; - case 3: sItem = "nw_maarcl071"; break; - case 4: sItem = "nw_maarcl075"; break; - case 5: sItem = "nw_maarcl084"; break; - case 6: sItem = "nw_ashmsw009"; break; - case 7: sItem = "nw_maarcl083"; break; - case 8: sItem = "nw_maarcl087"; break; - case 9: sItem = "nw_maarcl079"; break; - } - - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl084"; break; - case 2: sItem = "nw_ashmsw009"; break; - case 3: sItem = "nw_maarcl083"; break; - case 4: sItem = "nw_maarcl087"; break; - case 5: sItem = "nw_maarcl079"; break; - } - - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl084"; break; - case 2: sItem = "nw_ashmsw009"; break; - case 3: sItem = "nw_maarcl083"; break; - case 4: sItem = "nw_maarcl087"; break; - case 5: sItem = "nw_maarcl079"; break; - } - - } - //dbSpeak("Create Generic light"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateGenericMediumArmor(object oTarget, object oAdventurer, int nModifier = 0) - { - int nHD = GetHitDice(oAdventurer) + nModifier; - string sItem = ""; - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_arhe001"; break; - case 2: sItem = "nw_arhe002"; break; - case 3: sItem = "nw_arhe003"; break; - case 4: sItem = "nw_arhe004"; break; - case 5: sItem = "nw_arhe005"; break; - case 6: sItem = "nw_aarcl008"; break; - case 7: sItem = "nw_ashlw001"; break; - case 8: sItem = "nw_aarcl003"; break; - case 9: sItem = "nw_aarcl004"; break; - case 10: sItem = "nw_aarcl010"; break; - } - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_arhe001"; break; - case 2: sItem = "nw_arhe002"; break; - case 3: sItem = "nw_arhe003"; break; - case 4: sItem = "nw_arhe004"; break; - case 5: sItem = "nw_arhe005"; break; - case 6: sItem = "nw_aarcl008"; break; - case 7: sItem = "nw_ashlw001"; break; - case 8: sItem = "nw_aarcl003"; break; - case 9: sItem = "nw_aarcl004"; break; - case 10: sItem = "nw_aarcl010"; break; - case 11: sItem = "nw_maarcl047"; break; - case 12: sItem = "nw_ashmlw002"; break; - case 13: sItem = "nw_maarcl046"; break; - case 14: sItem = "nw_maarcl048"; break; - case 15: sItem = "nw_maarcl035"; break; - case 16: sItem = "nw_maarcl049"; break; - case 17: sItem = "nw_maarcl050"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl047"; break; - case 2: sItem = "nw_ashmlw002"; break; - case 3: sItem = "nw_maarcl046"; break; - case 4: sItem = "nw_maarcl048"; break; - case 5: sItem = "nw_maarcl035"; break; - case 6: sItem = "nw_maarcl049"; break; - case 7: sItem = "nw_maarcl050"; break; - case 8: sItem = "nw_maarcl070"; break; - case 9: sItem = "nw_ashmlw008"; break; - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(14) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl035"; break; - case 2: sItem = "nw_maarcl049"; break; - case 3: sItem = "nw_maarcl050"; break; - case 4: sItem = "nw_maarcl070"; break; - case 5: sItem = "nw_ashmlw008"; break; - case 6: sItem = "nw_maarcl067"; break; - case 7: sItem = "nw_maarcl073"; break; - case 8: sItem = "nw_maarcl065"; break; - case 9: sItem = "nw_maarcl066"; break; - case 10: sItem = "nw_maarcl082"; break; - case 11: sItem = "nw_ashmlw009"; break; - case 12: sItem = "nw_maarcl085"; break; - case 13: sItem = "nw_maarcl077"; break; - case 14: sItem = "nw_maarcl078"; break; - } - - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(11) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl070"; break; - case 2: sItem = "nw_ashmlw008"; break; - case 3: sItem = "nw_maarcl067"; break; - case 4: sItem = "nw_maarcl073"; break; - case 5: sItem = "nw_maarcl065"; break; - case 6: sItem = "nw_maarcl066"; break; - case 7: sItem = "nw_maarcl082"; break; - case 8: sItem = "nw_ashmlw009"; break; - case 9: sItem = "nw_maarcl085"; break; - case 10: sItem = "nw_maarcl077"; break; - case 11: sItem = "nw_maarcl078"; break; - } - - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(11) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl070"; break; - case 2: sItem = "nw_ashmlw008"; break; - case 3: sItem = "nw_maarcl067"; break; - case 4: sItem = "nw_maarcl073"; break; - case 5: sItem = "nw_maarcl065"; break; - case 6: sItem = "nw_maarcl066"; break; - case 7: sItem = "nw_maarcl082"; break; - case 8: sItem = "nw_ashmlw009"; break; - case 9: sItem = "nw_maarcl085"; break; - case 10: sItem = "nw_maarcl077"; break; - case 11: sItem = "nw_maarcl078"; break; - } - - } - //dbSpeak("Create Generic medium"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateGenericHeavyArmor(object oTarget, object oAdventurer, int nModifier = 0) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer) + nModifier; - - if (GetRange(1, nHD)) // * 200 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: sItem = "nw_ashto001"; break; - case 2: sItem = "nw_aarcl005"; break; - case 3: sItem = "nw_aarcl011"; break; - } - - } - else if (GetRange(2, nHD)) // * 800 - { - int nRandom = Random(6) + 1; - switch (nRandom) - { - case 1: sItem = "nw_ashto001"; break; - case 2: sItem = "nw_aarcl005"; break; - case 3: sItem = "nw_aarcl011"; break; - case 4: sItem = "nw_aarcl006"; break; - case 5: sItem = "nw_ashmto002"; break; - case 6: sItem = "nw_maarcl051"; break; - } - - } - else if (GetRange(3, nHD)) // * 200 - 2500 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_aarcl005"; break; - case 2: sItem = "nw_aarcl011"; break; - case 3: sItem = "nw_aarcl006"; break; - case 4: sItem = "nw_ashmto002"; break; - case 5: sItem = "nw_maarcl051"; break; - case 6: sItem = "nw_maarcl052"; break; - case 7: sItem = "nw_aarcl007"; break; - case 8: sItem = "nw_maarcl053"; break; - case 9: sItem = "nw_ashmto008"; break; - } - - } - else if (GetRange(4, nHD)) // * 800 - 10000 - { - int nRandom = Random(15) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl051"; break; - case 2: sItem = "nw_maarcl052"; break; - case 3: sItem = "nw_aarcl007"; break; - case 4: sItem = "nw_maarcl053"; break; - case 5: sItem = "nw_ashmto008"; break; - case 6: sItem = "nw_maarcl064"; break; - case 7: sItem = "nw_maarcl074"; break; - case 8: sItem = "nw_maarcl069"; break; - case 9: sItem = "nw_maarcl068"; break; - case 10: sItem = "nw_ashmto003"; break; - case 11: sItem = "nw_ashmto009"; break; - case 12: sItem = "nw_maarcl076"; break; - case 13: sItem = "nw_maarcl086"; break; - case 14: sItem = "nw_maarcl081"; break; - case 15: sItem = "nw_maarcl080"; break; - } - - } - else if (GetRange(5, nHD)) // * 2500 - 16500 - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_ashmto008"; break; - case 2: sItem = "nw_maarcl064"; break; - case 3: sItem = "nw_maarcl074"; break; - case 4: sItem = "nw_maarcl069"; break; - case 5: sItem = "nw_maarcl068"; break; - case 6: sItem = "nw_ashmto009"; break; - case 7: sItem = "nw_maarcl076"; break; - case 8: sItem = "nw_maarcl086"; break; - case 9: sItem = "nw_maarcl081"; break; - case 10: sItem = "nw_maarcl080"; break; - } - - - } - else if (GetRange(6, nHD)) // * 8000 - 25000 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_ashmto009"; break; - case 2: sItem = "nw_maarcl076"; break; - case 3: sItem = "nw_maarcl086"; break; - case 4: sItem = "nw_maarcl081"; break; - case 5: sItem = "nw_maarcl080"; break; - } - - } - // dbSpeak("Create Generic heavy"); - - dbCreateItemOnObject(sItem, oTarget, 1); - } - // * - // * SPECIC TREASURE ITEMS (re: Named Items) - // * - void CreateSpecificMiscItem(object oTarget,object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericMiscItem(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: CreateGenericMiscItem(oTarget, oAdventurer, JUMP_LEVEL); return; break; - case 2: sItem = "nw_maarcl057"; break; - case 3: sItem = "nw_it_mbelt005"; break; - } - - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl057"; break; - case 2: sItem = "nw_it_mbelt005"; break; - case 3: sItem = "nw_maarcl101"; break; - case 4: sItem = "nw_maarcl102"; break; - case 5: sItem = "nw_maarcl103"; break; - case 6: sItem = "nw_it_mglove001"; break; - case 7: sItem = "nw_maarcl100"; break; - case 8: sItem = "nw_it_mbracer011"; break; - case 9: sItem = "nw_it_mmidmisc04"; break; - case 10: sItem = "nw_it_mring003"; break; - case 11: sItem = "nw_it_mbelt006"; break; - case 12: sItem = "nw_it_mbelt002"; break; - case 13: sItem = "nw_it_mmidmisc03"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(19) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl101"; break; - case 2: sItem = "nw_maarcl101"; break; - case 3: sItem = "nw_maarcl102"; break; - case 4: sItem = "nw_maarcl103"; break; - case 5: sItem = "nw_it_mglove001"; break; - case 6: sItem = "nw_maarcl100"; break; - case 7: sItem = "nw_it_mbracer011"; break; - case 8: sItem = "nw_it_mmidmisc04"; break; - case 9: sItem = "nw_it_mring003"; break; - case 10: sItem = "nw_it_mbelt006"; break; - case 11: sItem = "nw_it_mbelt002"; break; - case 12: sItem = "nw_it_mmidmisc03"; break; - case 13: sItem = "nw_it_mring002"; break; - case 14: sItem = "nw_it_mbelt004"; break; - case 15: sItem = "nw_it_mring005"; break; - case 16: sItem = "nw_it_mboots005"; break; - case 17: sItem = "nw_it_mring007"; break; - case 18: sItem = "nw_it_mneck003"; break; - case 19: sItem = "nw_it_mbelt007"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(15) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mbelt002"; break; - case 2: sItem = "nw_it_mbelt002"; break; - case 3: sItem = "nw_it_mmidmisc03"; break; - case 4: sItem = "nw_it_mring002"; break; - case 5: sItem = "nw_it_mbelt004"; break; - case 6: sItem = "nw_it_mring005"; break; - case 7: sItem = "nw_it_mboots005"; break; - case 8: sItem = "nw_it_mring007"; break; - case 9: sItem = "nw_it_mneck003"; break; - case 10: sItem = "nw_it_mbelt007"; break; - case 11: sItem = "nw_it_mboots004"; break; - case 12: sItem = "nw_it_mboots003"; break; - case 13: sItem = "nw_it_mneck005"; break; - case 14: sItem = "nw_it_mbelt008"; break; - case 15: sItem = "nw_it_mring020"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(19) + 1; - switch (nRandom) - { - case 1: sItem = "nw_it_mboots004"; break; - case 2: sItem = "nw_it_mboots004"; break; - case 3: sItem = "nw_it_mboots003"; break; - case 4: sItem = "nw_it_mneck005"; break; - case 5: sItem = "nw_it_mbelt008"; break; - case 6: sItem = "nw_it_mring020"; break; - case 7: sItem = "nw_it_mbelt001"; break; - case 8: sItem = "nw_it_mring017"; break; - case 9: sItem = "nw_mcloth001"; break; - case 10: sItem = "nw_it_mneck019"; break; - case 11: sItem = "nw_it_mneck002"; break; - case 12: sItem = "nw_it_mneck004"; break; - case 13: sItem = "nw_it_mmidmisc01"; break; - case 14: sItem = "nw_mcloth002"; break; - case 15: sItem = "nw_mcloth003"; break; - case 16: sItem = "nw_mcloth004"; break; - case 17: sItem = "nw_it_mbelt003"; break; - // * new items - case 18: sItem = "NW_IT_MBELT020"; break; - case 19: sItem = "NW_IT_MBELT021"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificRodStaffWand(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericRodStaffWand(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - CreateGenericRodStaffWand(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(4) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgst004"; break; - case 2: sItem = "nw_wmgst006"; break; - case 3: sItem = "nw_wmgmrd003"; break; - case 4: sItem = "nw_wmgst004"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(7) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgmrd003"; break; - case 2: sItem = "nw_wmgst006"; break; - case 3: sItem = "nw_wmgmrd003"; break; - case 4: sItem = "nw_wmgst004"; break; - case 5: sItem = "nw_wmgst005"; break; - case 6: sItem = "nw_wmgmrd004"; break; - case 7: sItem = "nw_wmgrd002"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(8) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmcl012"; break; - case 2: sItem = "nw_wmgmrd003"; break; - case 3: sItem = "nw_wmgst004"; break; - case 4: sItem = "nw_wmgst005"; break; - case 5: sItem = "nw_wblmcl012"; break; - case 6: sItem = "nw_wmgmrd004"; break; - case 7: sItem = "nw_wmgst002"; break; - case 8: sItem = "nw_wmgmrd005"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(6) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wmgmrd004"; break; - case 2: sItem = "nw_wmgst002"; break; - case 3: sItem = "nw_wmgmrd005"; break; - case 4: sItem = "nw_wmgmrd002"; break; - case 5: sItem = "nw_wmgst003"; break; - case 6: sItem = "nw_wblmcl012"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - - - void CreateSpecificSimple(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericSimple(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - CreateGenericSimple(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs005"; break; - case 2: sItem = "nw_wdbmqs005"; break; - case 3: sItem = "nw_wdbmqs006"; break; - case 4: sItem = "nw_wbwmxh005"; break; - case 5: sItem = "nw_wbwmxl005"; break; - case 6: sItem = "nw_wswmdg006"; break; - case 7: sItem = "nw_wblmml006"; break; - case 8: sItem = "nw_wspmsc004"; break; - case 9: sItem = "nw_wblmms007"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(22) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmqs006"; break; - case 2: sItem = "nw_wdbmqs005"; break; - case 3: sItem = "nw_wdbmqs006"; break; - case 4: sItem = "nw_wbwmxh005"; break; - case 5: sItem = "nw_wbwmxl005"; break; - case 6: sItem = "nw_wswmdg006"; break; - case 7: sItem = "nw_wblmml006"; break; - case 8: sItem = "nw_wspmsc004"; break; - case 9: sItem = "nw_wblmms007"; break; - case 10: sItem = "nw_wblmms003"; break; - case 11: sItem = "nw_wblmcl004"; break; - case 12: sItem = "nw_wspmsc006"; break; - case 13: sItem = "nw_wspmsc006"; break; - case 14: sItem = "nw_wdbmqs004"; break; - case 15: sItem = "nw_wblmcl003"; break; - case 16: sItem = "nw_wbwmsl003"; break; - case 17: sItem = "nw_wbwmxh003"; break; - case 18: sItem = "nw_wspmsc003"; break; - case 19: sItem = "nw_wplmss005"; break; - case 20: sItem = "nw_wplmss005"; break; - case 21: sItem = "nw_wbwmxl003"; break; - case 22: sItem = "nw_wblmml004"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(27) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmms003"; break; - case 2: sItem = "nw_wblmms003"; break; - case 3: sItem = "nw_wblmcl004"; break; - case 4: sItem = "nw_wspmsc006"; break; - case 5: sItem = "nw_wspmsc006"; break; - case 6: sItem = "nw_wdbmqs004"; break; - case 7: sItem = "nw_wblmcl003"; break; - case 8: sItem = "nw_wbwmsl003"; break; - case 9: sItem = "nw_wbwmxh003"; break; - case 10: sItem = "nw_wspmsc003"; break; - case 11: sItem = "nw_wplmss005"; break; - case 12: sItem = "nw_wplmss005"; break; - case 13: sItem = "nw_wbwmxl003"; break; - case 14: sItem = "nw_wblmml004"; break; - case 15: sItem = "nw_wdbmqs003"; break; - case 16: sItem = "nw_wbwmxl004"; break; - case 17: sItem = "nw_wbwmxl007"; break; - case 18: sItem = "nw_wblmml005"; break; - case 19: sItem = "nw_wblmcl005"; break; - case 20: sItem = "nw_wplmss007"; break; - case 21: sItem = "nw_wswmdg004"; break; - case 22: sItem = "nw_wbwmsl007"; break; - case 23: sItem = "nw_wblmml007"; break; - case 24: sItem = "nw_wblmml007"; break; - case 25: sItem = "nw_wbwmxh004"; break; - case 26: sItem = "nw_wplmss006"; break; - case 27: sItem = "nw_wbwmxh007"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(31) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wbwmxl003"; break; - case 2: sItem = "nw_wbwmxl003"; break; - case 3: sItem = "nw_wblmml004"; break; - case 4: sItem = "nw_wdbmqs003"; break; - case 5: sItem = "nw_wbwmxl004"; break; - case 6: sItem = "nw_wbwmxl007"; break; - case 7: sItem = "nw_wblmml005"; break; - case 8: sItem = "nw_wblmcl005"; break; - case 9: sItem = "nw_wplmss007"; break; - case 10: sItem = "nw_wswmdg004"; break; - case 11: sItem = "nw_wbwmsl007"; break; - case 12: sItem = "nw_wblmml007"; break; - case 13: sItem = "nw_wblmml007"; break; - case 14: sItem = "nw_wbwmxh004"; break; - case 15: sItem = "nw_wplmss006"; break; - case 16: sItem = "nw_wbwmxh007"; break; - case 17: sItem = "nw_wblmms006"; break; - case 18: sItem = "nw_wswmdg003"; break; - case 19: sItem = "nw_wswmdg007"; break; - case 20: sItem = "nw_wblmms004"; break; - case 21: sItem = "nw_wbwmsl006"; break; - case 22: sItem = "nw_wbwmsl008"; break; - case 23: sItem = "nw_wblmml008"; break; - case 24: sItem = "nw_wdbmqs007"; break; - case 25: sItem = "nw_wblmcl006"; break; - case 26: sItem = "nw_wbwmsl004"; break; - case 27: sItem = "nw_wbwmxh006"; break; - case 28: sItem = "nw_wplmss004"; break; - case 29: sItem = "nw_wswmdg005"; break; - case 30: sItem = "nw_wbwmxl006"; break; - case 31: sItem = "nw_wspmsc005"; break; - - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificMartial(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericMartial(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: CreateGenericMartial(oTarget, oAdventurer, JUMP_LEVEL); return; break; - case 2: sItem = "nw_wthmax005"; break; - case 3: sItem = "nw_wthmax007"; break; - } - - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(14) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmax003"; break; - case 2: sItem = "nw_wthmax005"; break; - case 3: sItem = "nw_wthmax007"; break; - case 4: sItem = "nw_wthmax003"; break; - case 5: sItem = "nw_wthmax004"; break; - case 6: sItem = "nw_wthmax006"; break; - case 7: sItem = "nw_wswmrp004"; break; - case 8: sItem = "nw_wswmrp004"; break; - case 9: sItem = "nw_wblmfl004"; break; - case 10: sItem = "nw_wblmhl004"; break; - case 11: sItem = "nw_wbwmsh003"; break; - case 12: sItem = "nw_wblmhw006"; break; - case 13: sItem = "nw_wblmhw006"; break; - case 14: sItem = "nw_wbwmln004"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(28) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmfl005"; break; - case 2: sItem = "nw_wthmax007"; break; - case 3: sItem = "nw_wthmax003"; break; - case 4: sItem = "nw_wthmax004"; break; - case 5: sItem = "nw_wthmax006"; break; - case 6: sItem = "nw_wswmrp004"; break; - case 7: sItem = "nw_wswmrp004"; break; - case 8: sItem = "nw_wblmfl004"; break; - case 9: sItem = "nw_wblmhl004"; break; - case 10: sItem = "nw_wbwmsh003"; break; - case 11: sItem = "nw_wblmhw006"; break; - case 12: sItem = "nw_wblmhw006"; break; - case 13: sItem = "nw_wbwmln004"; break; - case 14: sItem = "nw_wblmfl005"; break; - case 15: sItem = "nw_wswmgs006"; break; - case 16: sItem = "nw_waxmgr003"; break; - case 17: sItem = "nw_wplmhb004"; break; - case 18: sItem = "nw_wblmhw005"; break; - case 19: sItem = "nw_wblmfh004"; break; - case 20: sItem = "nw_wblmfh008"; break; - case 21: sItem = "nw_wbwmsh006"; break; - case 22: sItem = "nw_wswmsc004"; break; - case 23: sItem = "nw_waxmgr006"; break; - case 24: sItem = "nw_wswmrp005"; break; - case 25: sItem = "nw_wswmls007"; break; - case 26: sItem = "nw_wswmgs004"; break; - case 27: sItem = "nw_waxmhn004"; break; - case 28: sItem = "nw_wswmbs005"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(42) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmhw006"; break; - case 2: sItem = "nw_wblmhw006"; break; - case 3: sItem = "nw_wblmhw006"; break; - case 4: sItem = "nw_wbwmln004"; break; - case 5: sItem = "nw_wblmfl005"; break; - case 6: sItem = "nw_wswmgs006"; break; - case 7: sItem = "nw_waxmgr003"; break; - case 8: sItem = "nw_wplmhb004"; break; - case 9: sItem = "nw_wblmhw005"; break; - case 10: sItem = "nw_wblmfh004"; break; - case 11: sItem = "nw_wblmfh008"; break; - case 12: sItem = "nw_wbwmsh006"; break; - case 13: sItem = "nw_wswmsc004"; break; - case 14: sItem = "nw_waxmgr006"; break; - case 15: sItem = "nw_wswmrp005"; break; - case 16: sItem = "nw_wswmls007"; break; - case 17: sItem = "nw_wswmgs004"; break; - case 18: sItem = "nw_waxmhn004"; break; - case 19: sItem = "nw_wswmbs005"; break; - case 20: sItem = "nw_wblmhl005"; break; - case 21: sItem = "nw_wblmhl011"; break; - case 22: sItem = "nw_wswmss005"; break; - case 23: sItem = "nw_wplmhb003"; break; - case 24: sItem = "nw_wbwmln007"; break; - case 25: sItem = "nw_wbwmln007"; break; - case 26: sItem = "nw_wbwmsh007"; break; - case 27: sItem = "nw_waxmbt006"; break; - case 28: sItem = "nw_wswmbs006"; break; - case 29: sItem = "nw_wblmfl007"; break; - case 30: sItem = "nw_waxmhn003"; break; - case 31: sItem = "nw_wblmhl006"; break; - case 32: sItem = "nw_wblmfl006"; break; - case 33: sItem = "nw_wswmls005"; break; - case 34: sItem = "nw_wswmss004"; break; - case 35: sItem = "nw_wbwmln006"; break; - case 36: sItem = "nw_wblmhw003"; break; - case 37: sItem = "nw_wblmfh006"; break; - case 38: sItem = "nw_wswmsc006"; break; - case 39: sItem = "nw_waxmhn005"; break; - case 40: sItem = "nw_wblmfh003"; break; - case 41: sItem = "nw_wswmls006"; break; - case 42: sItem = "nw_wswmrp007"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(55) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wblmhl005"; break; - case 2: sItem = "nw_wblmhl005"; break; - case 3: sItem = "nw_wblmhl011"; break; - case 4: sItem = "nw_wswmss005"; break; - case 5: sItem = "nw_wplmhb003"; break; - case 6: sItem = "nw_wbwmln007"; break; - case 7: sItem = "nw_wbwmln007"; break; - case 8: sItem = "nw_wbwmsh007"; break; - case 9: sItem = "nw_waxmbt006"; break; - case 10: sItem = "nw_wswmbs006"; break; - case 11: sItem = "nw_wblmfl007"; break; - case 12: sItem = "nw_waxmhn003"; break; - case 13: sItem = "nw_wblmhl006"; break; - case 14: sItem = "nw_wblmfl006"; break; - case 15: sItem = "nw_wswmls005"; break; - case 16: sItem = "nw_wswmss004"; break; - case 17: sItem = "nw_wbwmln006"; break; - case 18: sItem = "nw_wblmhw003"; break; - case 19: sItem = "nw_wblmfh006"; break; - case 20: sItem = "nw_wswmsc006"; break; - case 21: sItem = "nw_waxmhn005"; break; - case 22: sItem = "nw_wblmfh003"; break; - case 23: sItem = "nw_wswmls006"; break; - case 24: sItem = "nw_wswmrp007"; break; - case 25: sItem = "nw_wswmgs005"; break; - case 26: sItem = "nw_wswmgs005"; break; - case 27: sItem = "nw_waxmgr005"; break; - case 28: sItem = "nw_wplmhb007"; break; - case 29: sItem = "nw_wswmsc007"; break; - case 30: sItem = "nw_wswmrp006"; break; - case 31: sItem = "nw_wswmss006"; break; - case 32: sItem = "nw_wblmhl009"; break; - case 33: sItem = "nw_wswmbs007"; break; - case 34: sItem = "nw_wbwmln005"; break; - case 35: sItem = "nw_wblmfh005"; break; - case 36: sItem = "nw_wswmgs003"; break; - case 37: sItem = "nw_waxmbt003"; break; - case 38: sItem = "nw_wswmls004"; break; - case 39: sItem = "nw_wbwmsh005"; break; - case 40: sItem = "nw_wbwmsh005"; break; - case 41: sItem = "nw_waxmbt004"; break; - case 42: sItem = "nw_waxmbt004"; break; - case 43: sItem = "nw_wblmhl003"; break; - case 44: sItem = "nw_wblmhl003"; break; - case 45: sItem = "nw_wswmbs003"; break; - case 46: sItem = "nw_waxmbt005"; break; - case 47: sItem = "nw_waxmhn006"; break; - case 48: sItem = "nw_wswmss003"; break; - case 49: sItem = "nw_wswmsc005"; break; - case 50: sItem = "nw_wplmhb006"; break; - case 51: sItem = "nw_wbwmsh004"; break; - case 52: sItem = "nw_wswmbs004"; break; - case 53: sItem = "nw_wbwmln003"; break; - case 54: sItem = "nw_wblmhw004"; break; - case 55: sItem = "nw_waxmgr004"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificExotic(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: CreateGenericExotic(oTarget, oAdventurer, JUMP_LEVEL); return; break; - case 2: sItem = "nw_wthmsh003"; break; - case 3: sItem = "nw_wthmsh006"; break; - } - - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: CreateGenericExotic(oTarget, oAdventurer, JUMP_LEVEL); return; break; - case 2: sItem = "nw_wthmsh003"; break; - case 3: sItem = "nw_wthmsh006"; break; - case 4: sItem = "nw_wthmsh004"; break; - case 5: sItem = "nw_wthmsh007"; break; - } - - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(14) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wthmsh006"; break; - case 2: sItem = "nw_wthmsh006"; break; - case 3: sItem = "nw_wthmsh004"; break; - case 4: sItem = "nw_wthmsh007"; break; - case 5: sItem = "nw_wspmku006"; break; - case 6: sItem = "nw_wdbmma003"; break; - case 7: sItem = "nw_wswmka005"; break; - case 8: sItem = "nw_wspmka004"; break; - case 9: sItem = "nw_wspmka007"; break; - case 10: sItem = "nw_wdbmax006"; break; - case 11: sItem = "nw_wdbmsw006"; break; - case 12: sItem = "nw_wspmku005"; break; - case 13: sItem = "nw_wdbmsw007"; break; - case 14: sItem = "nw_wspmka005"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(16) + 1; - switch (nRandom) - { - case 1:sItem = "nw_wthmsh007"; break; - case 2: sItem = "nw_wthmsh007"; break; - case 3: sItem = "nw_wspmku006"; break; - case 4: sItem = "nw_wdbmma003"; break; - case 5: sItem = "nw_wswmka005"; break; - case 6: sItem = "nw_wspmka004"; break; - case 7: sItem = "nw_wspmka007"; break; - case 8: sItem = "nw_wdbmax006"; break; - case 9: sItem = "nw_wdbmsw006"; break; - case 10: sItem = "nw_wspmku005"; break; - case 11: sItem = "nw_wdbmsw007"; break; - case 12: sItem = "nw_wspmka005"; break; - case 13: sItem = "nw_wplmsc003"; break; - case 14: sItem = "nw_wdbmax005"; break; - case 15: sItem = "nw_wspmku004"; break; - case 16: sItem = "nw_wdbmma005"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(17) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wplmsc003"; break; - case 2: sItem = "nw_wspmka005"; break; - case 3: sItem = "nw_wplmsc003"; break; - case 4: sItem = "nw_wdbmax005"; break; - case 5: sItem = "nw_wspmku004"; break; - case 6: sItem = "nw_wdbmma005"; break; - case 7: sItem = "nw_wdbmma005"; break; - case 8: sItem = "nw_wdbmax004"; break; - case 9: sItem = "nw_wdbmma004"; break; - case 10: sItem = "nw_wswmka007"; break; - case 11: sItem = "nw_wdbmsw005"; break; - case 12: sItem = "nw_wspmka006"; break; - case 13: sItem = "nw_wspmka003"; break; - case 14: sItem = "nw_wdbmax007"; break; - case 15: sItem = "nw_wplmsc006"; break; - case 16: sItem = "nw_wspmku007"; break; - case 17: sItem = "nw_wdbmma006"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(21) + 1; - switch (nRandom) - { - case 1: sItem = "nw_wdbmma005"; break; - case 2: sItem = "nw_wdbmma005"; break; - case 3: sItem = "nw_wdbmma005"; break; - case 4: sItem = "nw_wdbmax004"; break; - case 5: sItem = "nw_wdbmma004"; break; - case 6: sItem = "nw_wswmka007"; break; - case 7: sItem = "nw_wdbmsw005"; break; - case 8: sItem = "nw_wspmka006"; break; - case 9: sItem = "nw_wspmka003"; break; - case 10: sItem = "nw_wdbmax007"; break; - case 11: sItem = "nw_wplmsc006"; break; - case 12: sItem = "nw_wspmku007"; break; - case 13: sItem = "nw_wdbmma006"; break; - case 14: sItem = "nw_wspmku003"; break; - case 15: sItem = "nw_wswmka006"; break; - case 16: sItem = "nw_wplmsc005"; break; - case 17: sItem = "nw_wplmsc005"; break; - case 18: sItem = "nw_wswmka004"; break; - case 19: sItem = "nw_wswmka004"; break; - case 20: sItem = "nw_wdbmsw004"; break; - case 21: sItem = "nw_wplmsc004"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificLightArmor(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericLightArmor(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - int nRandom = Random(3) + 1; - switch (nRandom) - { - case 1: CreateGenericLightArmor(oTarget, oAdventurer, JUMP_LEVEL); return; break; - case 2: sItem = "nw_ashmsw011"; break; - case 3: sItem = "nw_ashmsw010"; break; - } - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_ashmsw011"; break; - case 2: sItem = "nw_ashmsw011"; break; - case 3: sItem = "nw_ashmsw010"; break; - case 4: sItem = "nw_maarcl011"; break; - case 5: sItem = "nw_ashmsw006"; break; - case 6: sItem = "nw_maarcl017"; break; - case 7: sItem = "nw_ashmsw005"; break; - case 8: sItem = "nw_maarcl013"; break; - case 9: sItem = "nw_maarcl012"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl011"; break; - case 2: sItem = "nw_maarcl011"; break; - case 3: sItem = "nw_ashmsw006"; break; - case 4: sItem = "nw_maarcl017"; break; - case 5: sItem = "nw_ashmsw005"; break; - case 6: sItem = "nw_maarcl013"; break; - case 7: sItem = "nw_maarcl012"; break; - case 8: sItem = "nw_ashmsw004"; break; - case 9: sItem = "nw_maarcl006"; break; - case 10: sItem = "nw_maarcl032"; break; - case 11: sItem = "nw_maarcl003"; break; - case 12: sItem = "nw_maarcl002"; break; - case 13: sItem = "nw_maarcl007"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(11) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl012"; break; - case 2: sItem = "nw_maarcl012"; break; - case 3: sItem = "nw_ashmsw004"; break; - case 4: sItem = "nw_maarcl006"; break; - case 5: sItem = "nw_maarcl032"; break; - case 6: sItem = "nw_maarcl003"; break; - case 7: sItem = "nw_maarcl002"; break; - case 8: sItem = "nw_maarcl005"; break; - case 9: sItem = "nw_ashmsw003"; break; - case 10: sItem = "nw_maarcl001"; break; - case 11: sItem = "nw_maarcl034"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(11) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl005"; break; - case 2: sItem = "nw_maarcl005"; break; - case 3: sItem = "nw_ashmsw003"; break; - case 4: sItem = "nw_maarcl001"; break; - case 5: sItem = "nw_maarcl034"; break; - case 6: sItem = "nw_maarcl008"; break; - case 7: sItem = "nw_ashmsw007"; break; - case 8: sItem = "nw_maarcl033"; break; - case 9: sItem = "nw_mcloth005"; break; - case 10: sItem = "nw_maarcl009"; break; - case 11: sItem = "nw_maarcl004"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificMediumArmor(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericMediumArmor(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - CreateGenericMediumArmor(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(5) + 1; - switch (nRandom) - { - case 1: sItem = "nw_armhe008"; break; - case 2: sItem = "nw_armhe008"; break; - case 3: sItem = "nw_armhe007"; break; - case 4: sItem = "nw_armhe009"; break; - case 5: sItem = "nw_armhe010"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(9) + 1; - switch (nRandom) - { - case 1: sItem = "nw_armhe008"; break; - case 2: sItem = "nw_armhe008"; break; - case 3: sItem = "nw_armhe007"; break; - case 4: sItem = "nw_armhe009"; break; - case 5: sItem = "nw_armhe010"; break; - case 6: sItem = "nw_armhe006"; break; - case 7: sItem = "nw_ashmlw007"; break; - case 8: sItem = "nw_ashmlw005"; break; - case 9: sItem = "nw_maarcl016"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(12) + 1; - switch (nRandom) - { - case 1: sItem = "nw_armhe009"; break; - case 2: sItem = "nw_armhe009"; break; - case 3: sItem = "nw_armhe010"; break; - case 4: sItem = "nw_armhe006"; break; - case 5: sItem = "nw_ashmlw007"; break; - case 6: sItem = "nw_ashmlw005"; break; - case 7: sItem = "nw_maarcl016"; break; - case 8: sItem = "nw_maarcl036"; break; - case 9: sItem = "nw_ashmlw004"; break; - case 10: sItem = "nw_maarcl037"; break; - case 11: sItem = "nw_maarcl040"; break; - case 12: sItem = "nw_ashmlw006"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(12) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl016"; break; - case 2: sItem = "nw_maarcl016"; break; - case 3: sItem = "nw_maarcl036"; break; - case 4: sItem = "nw_ashmlw004"; break; - case 5: sItem = "nw_maarcl037"; break; - case 6: sItem = "nw_maarcl040"; break; - case 7: sItem = "nw_ashmlw006"; break; - case 8: sItem = "nw_ashmlw003"; break; - case 9: sItem = "nw_maarcl014"; break; - case 10: sItem = "nw_maarcl039"; break; - case 11: sItem = "nw_maarcl010"; break; - case 12: sItem = "nw_maarcl015"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - } - void CreateSpecificHeavyArmor(object oTarget, object oAdventurer) - { - string sItem = ""; - int nHD = GetHitDice(oAdventurer); - - if (GetRange(1, nHD)) // * 800 - { - CreateGenericHeavyArmor(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(2, nHD)) // * 200 - 2500 - { - CreateGenericHeavyArmor(oTarget, oAdventurer, JUMP_LEVEL); - return; - } - else if (GetRange(3, nHD)) // * 800 - 10000 - { - int nRandom = Random(6) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl026"; break; - case 2: sItem = "nw_maarcl026"; break; - case 3: sItem = "nw_maarcl021"; break; - case 4: sItem = "nw_ashmto003"; break; - case 5: sItem = "nw_maarcl029"; break; - case 6: sItem = "nw_maarcl020"; break; - } - - } - else if (GetRange(4, nHD)) // * 2500 - 16500 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl021"; break; - case 2: sItem = "nw_maarcl026"; break; - case 3: sItem = "nw_maarcl021"; break; - case 4: sItem = "nw_ashmto003"; break; - case 5: sItem = "nw_maarcl029"; break; - case 6: sItem = "nw_maarcl020"; break; - case 7: sItem = "nw_ashmto006"; break; - case 8: sItem = "nw_maarcl041"; break; - case 9: sItem = "nw_ashmto005"; break; - case 10: sItem = "nw_ashmto007"; break; - case 11: sItem = "nw_ashmto010"; break; - case 12: sItem = "nw_maarcl022"; break; - case 13: sItem = "nw_maarcl018"; break; - } - - } - else if (GetRange(5, nHD)) // * 8000 - 25000 - { - int nRandom = Random(13) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl020"; break; - case 2: sItem = "nw_maarcl020"; break; - case 3: sItem = "nw_ashmto006"; break; - case 4: sItem = "nw_maarcl041"; break; - case 5: sItem = "nw_ashmto005"; break; - case 6: sItem = "nw_ashmto007"; break; - case 7: sItem = "nw_ashmto010"; break; - case 8: sItem = "nw_maarcl022"; break; - case 9: sItem = "nw_maarcl018"; break; - case 10: sItem = "nw_maarcl024"; break; - case 11: sItem = "nw_ashmto011"; break; - case 12: sItem = "nw_maarcl042"; break; - case 13: sItem = "nw_maarcl054"; break; - } - - } - else if (GetRange(6, nHD)) // * 16000 and up - { - int nRandom = Random(10) + 1; - switch (nRandom) - { - case 1: sItem = "nw_maarcl018"; break; - case 2: sItem = "nw_maarcl018"; break; - case 3: sItem = "nw_maarcl024"; break; - case 4: sItem = "nw_ashmto011"; break; - case 5: sItem = "nw_maarcl042"; break; - case 6: sItem = "nw_maarcl054"; break; - case 7: sItem = "nw_ashmto004"; break; - case 8: sItem = "nw_maarcl025"; break; - case 9: sItem = "nw_maarcl028"; break; - case 10: sItem = "nw_maarcl027"; break; - } - - } - dbCreateItemOnObject(sItem, oTarget, 1); - - } - // * if nSpecific is = 1 then spawn in 'named' items at the higher levels - void CreateTable2Item(object oTarget, object oAdventurer, int nSpecific=0) - { - //dbSpeak("In CreateTable2Item"); - string sItem = ""; - int nProbMisc = 0; - int nProbClass = 0; - int nProbRodStaffWand = 0; - int nProbSimple = 0; - int nProbMartial = 0; - int nProbExotic = 0; - int nProbLight = 0; - int nProbMedium = 0; - int nProbHeavy = 0; - - int nSpecialRanger = 0; // 2 Means to treat the ranger as a barbarian. A 1 is to treat it as a fighter - - - // * May 2002: Changed using Preston's multiclass function - // * it randomly chooses one of your classes - int nClass = nDetermineClassToUse(oAdventurer); - - - // * SPECIAL RANGER BEHAVIOR - // * If the ranger has the Heavy Armor proficiency, will treat the ranger - if ( nClass == CLASS_TYPE_RANGER && GetHasFeat(FEAT_ARMOR_PROFICIENCY_HEAVY)) - { - nSpecialRanger = 1; - } - else - if (nClass == CLASS_TYPE_RANGER) - { - nSpecialRanger = 2; - } - - - - //* SETUP probabilities based on Class - if ( nClass == CLASS_TYPE_FIGHTER || nClass == CLASS_TYPE_PALADIN || nSpecialRanger == 1 - || nClass == CLASS_TYPE_ANTI_PALADIN || nClass == CLASS_TYPE_BRAWLER || nClass == CLASS_TYPE_CRUSADER - || nClass == CLASS_TYPE_DUSKBLADE || nClass == CLASS_TYPE_KNIGHT || nClass == CLASS_TYPE_MARSHAL - || nClass == CLASS_TYPE_PSYWAR || nClass == CLASS_TYPE_SOHEI) - { - //dbSpeak("I am fighter or paladin or heavy ranger"); - nProbMisc = 20; - nProbClass = 0; - nProbRodStaffWand = 5; - nProbSimple = 5; - nProbMartial = 20; - nProbExotic = 10; - nProbLight = 5; - nProbMedium = 15; - nProbHeavy = 20; - } - else - if (nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER) - { - //dbSpeak("I am wizard or sorcerer"); - nProbMisc = 40; - nProbClass = 30; - nProbRodStaffWand = 15; - nProbSimple = 3; - nProbMartial = 3; - nProbExotic = 3; - nProbLight = 2; - nProbMedium = 2; - nProbHeavy = 2; - } - else - if (nClass == CLASS_TYPE_BARBARIAN || nSpecialRanger == 2 || nClass == CLASS_TYPE_BOWMAN - || nClass == CLASS_TYPE_HEXBLADE || nClass == CLASS_TYPE_WARBLADE) - { - //dbSpeak("I am barbarian or light ranger"); - - nProbMisc = 20; - nProbClass = 0; - nProbRodStaffWand = 5; - nProbSimple = 17; - nProbMartial = 27; - nProbExotic = 15; - nProbLight = 8; - nProbMedium = 5; - nProbHeavy = 3; - } - else - if (nClass == CLASS_TYPE_ARCHIVIST || nClass == CLASS_TYPE_DRAGON_SHAMAN || nClass == CLASS_TYPE_FAVOURED_SOUL - || nClass == CLASS_TYPE_MYSTIC || nClass == CLASS_TYPE_WARMAGE || nClass == CLASS_TYPE_TEMPLAR) - { - //type 1 - nProbMisc = 25; - nProbClass = 0; - nProbRodStaffWand = 15; - nProbSimple = 15; - nProbMartial = 8; - nProbExotic = 6; - nProbLight = 15; - nProbMedium = 10; - nProbHeavy = 6; - } - else - if (nClass == CLASS_TYPE_NOBLE || nClass == CLASS_TYPE_SWASHBUCKLER || nClass == CLASS_TYPE_SWORDSAGE - || nClass == CLASS_TYPE_ULTIMATE_RANGER) - { - //type 2 - nProbMisc = 27; - nProbClass = 0; - nProbRodStaffWand = 5; - nProbSimple = 15; - nProbMartial = 20; - nProbExotic = 10; - nProbLight = 10; - nProbMedium = 8; - nProbHeavy = 5; - } - else - if (nClass == CLASS_TYPE_BEGUILER || nClass == CLASS_TYPE_DREAD_NECROMANCER || nClass == CLASS_TYPE_HEALER - || nClass == CLASS_TYPE_SCOUT || nClass == CLASS_TYPE_SHAMAN || nClass == CLASS_TYPE_SOULKNIFE - || nClass == CLASS_TYPE_TRUENAMER || nClass == CLASS_TYPE_WARLOCK || nClass == CLASS_TYPE_WILDER) - { - //type 3 - nProbMisc = 45; - nProbClass = 0; - nProbRodStaffWand = 7; - nProbSimple = 15; - nProbMartial = 5; - nProbExotic = 5; - nProbLight = 15; - nProbMedium = 4; - nProbHeavy = 4; - } - else - if (nClass == CLASS_TYPE_DRAGONFIRE_ADEPT || nClass == CLASS_TYPE_PSION || nClass == CLASS_TYPE_WITCH) - { - //type 4 - nProbMisc = 50; - nProbClass = 0; - nProbRodStaffWand = 10; - nProbSimple = 20; - nProbMartial = 5; - nProbExotic = 5; - nProbLight = 4; - nProbMedium = 3; - nProbHeavy = 3; - } - else - if (nClass == CLASS_TYPE_NINJA) - { - //type 5 - nProbMisc = 45; - nProbClass = 0; - nProbRodStaffWand = 2; - nProbSimple = 12; - nProbMartial = 6; - nProbExotic = 26; - nProbLight = 3; - nProbMedium = 3; - nProbHeavy = 3; - } - else - if (nClass == CLASS_TYPE_CW_SAMURAI || nClass == CLASS_TYPE_SAMURAI) - { - //type 6 - nProbMisc = 25; - nProbClass = 0; - nProbRodStaffWand = 5; - nProbSimple = 5; - nProbMartial = 10; - nProbExotic = 20; - nProbLight = 10; - nProbMedium = 20; - nProbHeavy = 5; - } - else - if (nClass == CLASS_TYPE_CLERIC) - { - //dbSpeak("I am cleric"); - - nProbMisc = 20; - nProbClass = 10; - nProbRodStaffWand = 10; - nProbSimple = 25; - nProbMartial = 7; - nProbExotic = 5; - nProbLight = 5; - nProbMedium = 8; - nProbHeavy = 10; - } - else - if (nClass == CLASS_TYPE_DRUID) - { - //dbSpeak("I am druid"); - - nProbMisc = 20; - nProbClass = 25; - nProbRodStaffWand = 15; - nProbSimple = 10; - nProbMartial = 5; - nProbExotic = 5; - nProbLight = 10; - nProbMedium = 5; - nProbHeavy = 5; - } - else - if (nClass == CLASS_TYPE_MONK) - { - //dbSpeak("I am monk"); - nProbMisc = 20; - nProbClass = 50; - nProbRodStaffWand = 2; - nProbSimple = 7; - nProbMartial = 2; - nProbExotic = 7; - nProbLight = 4; - nProbMedium = 4; - nProbHeavy = 4; - } - else - if (nClass == CLASS_TYPE_ROGUE || nClass == CLASS_TYPE_PSYCHIC_ROGUE) - { - //dbSpeak("I am rogue"); - - nProbMisc = 25; - nProbClass = 10; - nProbRodStaffWand = 10; - nProbSimple = 25; - nProbMartial = 5; - nProbExotic = 5; - nProbLight = 10; - nProbMedium = 5; - nProbHeavy = 5; - } - else - if (nClass == CLASS_TYPE_BARD) - { - //dbSpeak("I am bard"); - - nProbMisc = 25; - nProbClass = 5; - nProbRodStaffWand = 5; - nProbSimple = 25; - nProbMartial = 10; - nProbExotic = 10; - nProbLight = 10; - nProbMedium = 5; - nProbHeavy = 5; - } - //else - //{ - // dbSpeak("No Valid Class"); - //} - //dbSpeak("Table2Item: After Class Distribution"); - //* Create Items based on Probabilities - int nRandom = d100(); - if (nRandom <= nProbMisc) - { - if (nSpecific == 0) CreateGenericMiscItem(oTarget, oAdventurer); - else CreateSpecificMiscItem(oTarget, oAdventurer); - - } - else - if (nRandom <= nProbMisc + nProbClass) - { // * no need for a seperate specific function here - CreateGenericClassItem(oTarget, oAdventurer, nSpecific); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand) - { - if (nSpecific == 0) CreateGenericRodStaffWand(oTarget, oAdventurer); - else CreateSpecificRodStaffWand(oTarget, oAdventurer); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand + nProbSimple) - { - if (nSpecific == 0) CreateGenericSimple(oTarget, oAdventurer); - else CreateSpecificSimple(oTarget, oAdventurer); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand + nProbSimple + nProbMartial) - { - - if (nSpecific == 0) CreateGenericMartial(oTarget, oAdventurer); - else CreateSpecificMartial(oTarget, oAdventurer); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand + nProbSimple + nProbMartial + nProbExotic) - { - if (nSpecific == 0) CreateGenericExotic(oTarget, oAdventurer); - else CreateSpecificExotic(oTarget, oAdventurer); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand + nProbSimple + nProbMartial + nProbExotic + nProbLight) - { - if (nSpecific == 0) CreateGenericLightArmor(oTarget, oAdventurer); - else CreateSpecificLightArmor(oTarget, oAdventurer); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand + nProbSimple + nProbMartial + nProbExotic + nProbLight + nProbMedium) - { - if (nSpecific == 0) CreateGenericMediumArmor(oTarget, oAdventurer); - else CreateSpecificMediumArmor(oTarget, oAdventurer); - } - else - if (nRandom <= nProbMisc + nProbClass + nProbRodStaffWand + nProbSimple + nProbMartial + nProbExotic + nProbLight + nProbMedium + nProbHeavy) - { - if (nSpecific == 0) CreateGenericHeavyArmor(oTarget, oAdventurer); - else CreateSpecificHeavyArmor(oTarget, oAdventurer); - } - //else - //{ - // dbSpeak("Generic Generic or Specific; error: 3524"); - //} - } - -//:://///////////////////////////////////////////// -//:: GenerateTreasure -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - Generate Treasure - NOTE: When used by NPCs, the treasure is scaled - to how powerful the NPC is. - - If used by containers, it is scaled by how - powerful the PC is. - - PARAMETERS - oLastOpener = The creature that opened the container - oCreateOn = The place to put the treasure. If this is - invalid then the treasure is placed on oLastOpener - - -*/ -//::////////////////////////////////////////////// -//:: Created By: Andrew -//:: Created On: -//::////////////////////////////////////////////// -void GenerateTreasure(int nTreasureType, object oLastOpener, object oCreateOn) -{ - - //dbSpeak("*********************NEW TREASURE*************************"); - - // * abort treasure if no one opened the container - if (GetIsObjectValid(oLastOpener) == FALSE) - { - //dbSpeak("Aborted. No valid Last Opener"); - return; - } - - // * if no valid create on object, then create on oLastOpener - if (oCreateOn == OBJECT_INVALID) - { - oCreateOn = oLastOpener; - } - - // * if an Animal then generate 100% animal treasure - - // not done yet - // * VARIABLES - int nProbBook = 0; - int nProbAnimal = 0; - int nProbJunk = 0; - int nProbGold = 0; - int nProbGem = 0; - int nProbJewel = 0; - int nProbArcane = 0; - int nProbDivine = 0; - int nProbAmmo = 0; - int nProbKit = 0; - int nProbPotion = 0; - int nProbTable2 = 0; - - int nSpecific = 0; - int i = 0; - int nNumberItems = GetNumberOfItems(nTreasureType); - - // * Set Treasure Type Values - if (nTreasureType == TREASURE_LOW) - { - nProbBook = LOW_PROB_BOOK; - nProbAnimal = LOW_PROB_ANIMAL; - nProbJunk = LOW_PROB_JUNK; - nProbGold = LOW_PROB_GOLD; - nProbGem = LOW_PROB_GEM; - nProbJewel = LOW_PROB_JEWEL; - nProbArcane = LOW_PROB_ARCANE; - nProbDivine = LOW_PROB_DIVINE; - nProbAmmo = LOW_PROB_AMMO ; - nProbKit = LOW_PROB_KIT; - nProbPotion = LOW_PROB_POTION; - nProbTable2 = LOW_PROB_TABLE2; - } - else if (nTreasureType == TREASURE_MEDIUM) - { - nProbBook = MEDIUM_PROB_BOOK; - nProbAnimal = MEDIUM_PROB_ANIMAL; - nProbJunk = MEDIUM_PROB_JUNK; - nProbGold = MEDIUM_PROB_GOLD; - nProbGem = MEDIUM_PROB_GEM; - nProbJewel = MEDIUM_PROB_JEWEL; - nProbArcane = MEDIUM_PROB_ARCANE; - nProbDivine = MEDIUM_PROB_DIVINE; - nProbAmmo = MEDIUM_PROB_AMMO ; - nProbKit = MEDIUM_PROB_KIT; - nProbPotion = MEDIUM_PROB_POTION; - nProbTable2 = MEDIUM_PROB_TABLE2; - } - else if (nTreasureType == TREASURE_HIGH) - { - nProbBook = HIGH_PROB_BOOK; - nProbAnimal = HIGH_PROB_ANIMAL; - nProbJunk = HIGH_PROB_JUNK; - nProbGold = HIGH_PROB_GOLD; - nProbGem = HIGH_PROB_GEM; - nProbJewel = HIGH_PROB_JEWEL; - nProbArcane = HIGH_PROB_ARCANE; - nProbDivine = HIGH_PROB_DIVINE; - nProbAmmo = HIGH_PROB_AMMO ; - nProbKit = HIGH_PROB_KIT; - nProbPotion = HIGH_PROB_POTION; - nProbTable2 = HIGH_PROB_TABLE2; - } - else if (nTreasureType == TREASURE_BOSS) - { //dbSpeak("boss"); - nProbTable2 = 100; - nSpecific = 1; - } - else if (nTreasureType == TREASURE_BOOK) - { - nProbBook = 90; - nProbArcane = 6; - nProbDivine = 4; - } - - //dbSpeak("Generate Treasure nSpecific = " + IntToString(nSpecific)); - - for (i = 1; i <= nNumberItems; i++) - { - int nRandom = d100(); - if (nRandom <= nProbBook) - CreateBook(oCreateOn); // * Book - else if (nRandom <= nProbBook + nProbAnimal) - CreateAnimalPart(oCreateOn); // * Animal - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk) - CreateJunk(oCreateOn); // * Junk - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold) - CreateGold(oCreateOn, oLastOpener, nTreasureType); // * Gold - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem) - CreateGem(oCreateOn, oLastOpener, nTreasureType); // * Gem - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel) - CreateJewel(oCreateOn, oLastOpener, nTreasureType); // * Jewel - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel + nProbArcane) - CreateArcaneScroll(oCreateOn, oLastOpener); // * Arcane Scroll - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel + nProbArcane + nProbDivine) - CreateDivineScroll(oCreateOn, oLastOpener); // * Divine Scroll - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel + nProbArcane + nProbDivine + nProbAmmo) - CreateAmmo(oCreateOn, oLastOpener); // * Ammo - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel + nProbArcane + nProbDivine + nProbAmmo + nProbKit) - CreateKit(oCreateOn, oLastOpener); // * Healing, Trap, or Thief kit - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel + nProbArcane + nProbDivine + nProbAmmo + nProbKit + nProbPotion) - CreatePotion(oCreateOn, oLastOpener); // * Potion - else if (nRandom <= nProbBook + nProbAnimal + nProbJunk + nProbGold + nProbGem + nProbJewel + nProbArcane + nProbDivine + nProbAmmo + nProbKit + nProbPotion + nProbTable2) - { - CreateTable2Item(oCreateOn, oLastOpener, nSpecific); // * Weapons, Armor, Misc - Class based - } - //else - // dbSpeak("other stuff"); - - - - } -} -void GenerateLowTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) -{ - GenerateTreasure(TREASURE_LOW, oLastOpener, oCreateOn); -} -void GenerateMediumTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) -{ - GenerateTreasure(TREASURE_MEDIUM, oLastOpener, oCreateOn); -} -void GenerateHighTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) -{ - GenerateTreasure(TREASURE_HIGH, oLastOpener, oCreateOn); -} -void GenerateBossTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) -{ - GenerateTreasure(TREASURE_BOSS, oLastOpener, oCreateOn); -} -void GenerateBookTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) -{ - GenerateTreasure(TREASURE_BOOK, oLastOpener, oCreateOn); -} -//:://///////////////////////////////////////////// -//:: GenerateNPCTreasure -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - Preferrably called from OnSpawn scripts. - Use the random treasure functions to generate - appropriate treasure for the creature to drop. -*/ -//::////////////////////////////////////////////// -//:: Created By: Brent -//:: Created On: January 2002 -//::////////////////////////////////////////////// - -void GenerateNPCTreasure(int nTreasureValue=1, object oTreasureGetter=OBJECT_SELF, object oKiller=OBJECT_SELF) -{ - //DestroyObject(OBJECT_SELF); - // * if I am an animal ,then give me animal stuff instead - if (GetObjectType(oTreasureGetter) == OBJECT_TYPE_CREATURE) - { - if ( - (GetRacialType(oTreasureGetter) == RACIAL_TYPE_UNDEAD) || - (GetRacialType(oTreasureGetter) == RACIAL_TYPE_ANIMAL) || - (GetRacialType(oTreasureGetter) == RACIAL_TYPE_BEAST) || - (GetRacialType(oTreasureGetter) == RACIAL_TYPE_MAGICAL_BEAST) || - (GetRacialType(oTreasureGetter) == RACIAL_TYPE_VERMIN) - ) - { - //CreateAnimalPart(oTreasureGetter); - // April 23 2002: Removed animal parts. They are silly. - return; - } - } - - if (nTreasureValue == 1) - { - // April 2002: 30% chance of not getting any treasure now - // if a creature - if (Random(100)+1 >= 75) - { - GenerateTreasure(TREASURE_LOW, oTreasureGetter, oKiller); - } - } - else - if (nTreasureValue == 2) - { - GenerateTreasure(TREASURE_MEDIUM, oTreasureGetter, oKiller); - } - else - if (nTreasureValue == 3) - { - GenerateTreasure(TREASURE_HIGH, oTreasureGetter, oKiller); - } - else - if (nTreasureValue == 4) - { - GenerateBossTreasure(oKiller, oTreasureGetter); - } - -} - -// * -// * Theft Prevention -// * - -//:://///////////////////////////////////////////// -//:: ShoutDisturbed -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - -*/ -//::////////////////////////////////////////////// -//:: Created By: -//:: Created On: -//::////////////////////////////////////////////// - -// * Container shouts if disturbed -void ShoutDisturbed() -{ - if (GetIsDead(OBJECT_SELF) == TRUE) - { - object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE); - //Cycle through the targets within the spell shape until an invalid object is captured. - while (GetIsObjectValid(oTarget)) - { - if (GetFactionEqual(oTarget, OBJECT_SELF) == TRUE) - { - // * Make anyone who is a member of my faction hostile if I am violated - object oAttacker = GetLastAttacker(); - SetIsTemporaryEnemy(oAttacker,oTarget); - AssignCommand(oTarget, ActionAttack(oAttacker)); - } - oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE); - } - } - else if (GetIsOpen(OBJECT_SELF) == TRUE) - { - object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE); - //Cycle through the targets within the spell shape until an invalid object is captured. - while (GetIsObjectValid(oTarget)) - { - if (GetFactionEqual(oTarget, OBJECT_SELF) == TRUE) - { - // * Make anyone who is a member of my faction hostile if I am violated - object oAttacker = GetLastOpener(); - SetIsTemporaryEnemy(oAttacker,oTarget); - AssignCommand(oTarget, ActionAttack(oAttacker)); - - } - oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE); - } - } -} - -int nGetIsBaseClass(int nClass) -{ - return (nClass <= CLASS_TYPE_WIZARD || - nClass == CLASS_TYPE_ANTI_PALADIN || - nClass == CLASS_TYPE_ARCHIVIST || - nClass == CLASS_TYPE_BEGUILER || - nClass == CLASS_TYPE_BOWMAN || - nClass == CLASS_TYPE_BRAWLER || - nClass == CLASS_TYPE_CRUSADER || - nClass == CLASS_TYPE_DRAGON_SHAMAN || - nClass == CLASS_TYPE_DRAGONFIRE_ADEPT || - nClass == CLASS_TYPE_DREAD_NECROMANCER || - nClass == CLASS_TYPE_DUSKBLADE || - nClass == CLASS_TYPE_FAVOURED_SOUL || - nClass == CLASS_TYPE_HEALER || - nClass == CLASS_TYPE_HEXBLADE || - nClass == CLASS_TYPE_KNIGHT || - nClass == CLASS_TYPE_MARSHAL || - nClass == CLASS_TYPE_MYSTIC || - nClass == CLASS_TYPE_NINJA || - nClass == CLASS_TYPE_NOBLE || - nClass == CLASS_TYPE_PSION || - nClass == CLASS_TYPE_PSYWAR || - nClass == CLASS_TYPE_PSYCHIC_ROGUE || - nClass == CLASS_TYPE_SAMURAI || - nClass == CLASS_TYPE_CW_SAMURAI || - nClass == CLASS_TYPE_SCOUT || - nClass == CLASS_TYPE_SHAMAN || - nClass == CLASS_TYPE_SOHEI || - nClass == CLASS_TYPE_SOULKNIFE || - nClass == CLASS_TYPE_SWASHBUCKLER || - nClass == CLASS_TYPE_SWORDSAGE || - nClass == CLASS_TYPE_TRUENAMER || - nClass == CLASS_TYPE_ULTIMATE_RANGER || - nClass == CLASS_TYPE_WARBLADE || - nClass == CLASS_TYPE_WARLOCK || - nClass == CLASS_TYPE_WARMAGE || - nClass == CLASS_TYPE_WILDER || - nClass == CLASS_TYPE_WITCH || - nClass == CLASS_TYPE_TEMPLAR); -} - -//:://///////////////////////////////////////////// -//:: Determine Class to Use -//:: Copyright (c) 2002 Bioware Corp. -//::////////////////////////////////////////////// -/* - Determines which of a NPCs three classes to - use in the random treasure system -*/ -//::////////////////////////////////////////////// -//:: Created By: Preston Watamaniuk -//:: Created On: April 4, 2002 -//::////////////////////////////////////////////// - -int nDetermineClassToUse(object oCharacter) -{ - int nClass; - int nTotal = GetHitDice(oCharacter); - //dbSpeak("Hit dice " + IntToString(nTotal)); - if (nTotal < 1) - { - nTotal = 1; - } -/* - float fTotal = IntToFloat(nTotal); - //if (GetIsObjectValid(oCharacter) == FALSE) - //{ - // dbSpeak("DetermineClassToUse: This character is invalid"); - //} - - int nClass1 = GetClassByPosition(1, oCharacter); - int nState1 = FloatToInt((IntToFloat(GetLevelByClass(nClass1, oCharacter)) / fTotal) * 100); - //dbSpeak("Level 1 Class Level = " + IntToString(GetLevelByClass(nClass1,oCharacter))); - - //PrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetTag(oCharacter) + "Class 1 " + IntToString(nState1)); - //dbSpeak("State 1 " + IntToString(nState1)); - int nClass2 = GetClassByPosition(2, oCharacter); - int nState2 = FloatToInt((IntToFloat(GetLevelByClass(nClass2, oCharacter)) / fTotal) * 100) + nState1; - //PrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetTag(oCharacter) + "Class 2 " + IntToString(nState2)); - - int nClass3 = GetClassByPosition(3, oCharacter); - int nState3 = FloatToInt((IntToFloat(GetLevelByClass(nClass3, oCharacter)) / fTotal) * 100) + nState2; - //PrintString("GENERIC SCRIPT DEBUG STRING ********** " + GetTag(oCharacter) + "Class 3 " + IntToString(nState3)); -*/ - int nClass1 = GetClassByPosition(1, oCharacter); - int nClass2 = GetClassByPosition(2, oCharacter); - int nClass3 = GetClassByPosition(3, oCharacter); - int nClass4 = GetClassByPosition(4, oCharacter); - int nClass5 = GetClassByPosition(5, oCharacter); - int nClass6 = GetClassByPosition(6, oCharacter); - int nClass7 = GetClassByPosition(7, oCharacter); - int nClass8 = GetClassByPosition(8, oCharacter); - - int nState1 = GetLevelByClass(nClass1, oCharacter) * 100 / nTotal; - int nState2 = GetLevelByClass(nClass2, oCharacter) * 100 / nTotal + nState1; - int nState3 = GetLevelByClass(nClass3, oCharacter) * 100 / nTotal + nState2; - int nState4 = GetLevelByClass(nClass4, oCharacter) * 100 / nTotal + nState3; - int nState5 = GetLevelByClass(nClass5, oCharacter) * 100 / nTotal + nState4; - int nState6 = GetLevelByClass(nClass6, oCharacter) * 100 / nTotal + nState5; - int nState7 = GetLevelByClass(nClass7, oCharacter) * 100 / nTotal + nState6; - - // nState8 will always be 100 if there is an eigth class, or 0 if there isn't - //int nState8 = GetLevelByClass(nClass3, oCharacter) * 100 / nTotal + nState7; - - // correct for unrecognized classes - assumes the first class will be a non-prestige player class - if(nClass2 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass2)) - { - nClass2 = CLASS_TYPE_INVALID; - nState1 = nState2; - } - if(nClass3 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass3)) - { - nClass3 = CLASS_TYPE_INVALID; - nState1 = nState3; - } - if(nClass4 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass4)) - { - nClass4 = CLASS_TYPE_INVALID; - nState1 = nState4; - } - if(nClass5 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass5)) - { - nClass5 = CLASS_TYPE_INVALID; - nState1 = nState5; - } - if(nClass6 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass6)) - { - nClass6 = CLASS_TYPE_INVALID; - nState1 = nState6; - } - if(nClass7 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass7)) - { - nClass7 = CLASS_TYPE_INVALID; - nState1 = nState7; - } - if(nClass8 != CLASS_TYPE_INVALID && !nGetIsBaseClass(nClass8)) - { - nClass8 = CLASS_TYPE_INVALID; - if(nClass7 != CLASS_TYPE_INVALID) - nState7 = 100; - else nState1 = 100; - } - - int nUseClass = d100(); - //PrintString("GENERIC SCRIPT DEBUG STRING ********** " + "D100 Roll " +IntToString(nUseClass)); - - - //dbSpeak("Before comparison : " + IntToString(nClass1)); - if(nUseClass <= nState1) - { - nClass = nClass1; - } - else if(nUseClass > nState1 && nUseClass <= nState2) - { - nClass = nClass2; - } - else - { - // might be possible to end up here by accident because of a rounding error - // so just in case... - if(nClass3 == CLASS_TYPE_INVALID) nClass = nClass1; - else nClass = nClass3; - } - - //dbSpeak("Class from determineClass " + IntToString(nClass)); - return nClass; -} - -//:: Test Void -//void main () {} - diff --git a/trunk/include/prc_inc_castlvl.nss b/trunk/include/prc_inc_castlvl.nss deleted file mode 100644 index 58c911f0..00000000 --- a/trunk/include/prc_inc_castlvl.nss +++ /dev/null @@ -1,1823 +0,0 @@ - - -/** - * @file - * - * This file contains PRCGetCasterLevel() and all its accessory functions. - * Functions that modify caster level go in this include. Keep out irrelevent - * functions. If this ends up like prc_inc_spells, you get slapped. - */ - -//:: Updated for .35 by Jaysyn 2023/03/10 - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Returns the caster level when used in spells. You can use PRCGetCasterLevel() - * to determine a caster level from within a true spell script. In spell-like- - * abilities & items, it will only return GetCasterLevel. - * - * @param oCaster The creature casting the spell. - * - * @return The caster level the spell was cast at. - */ -int PRCGetCasterLevel(object oCaster = OBJECT_SELF); - -/** - * A lookup for caster level progression for divine and arcane base classes - * @return an int that can be used in caster level calculations note: these use int division - */ -int GetCasterLevelModifier(int nClass); - -/** - * To override for custom spellcasting classes. Looks for the - * local int "PRC_CASTERCLASS_OVERRIDE" on oCaster. If set, - * this is used as the casting class, else GetLastSpellCastClass() - * is used. - * - * @param oCaster The creature that last cast a spell - * - * @return The class used to cast the spell. - */ -int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF); - -/** - * Returns if the given class is an arcane class. - * - * Arcane base classes are *hardcoded* into here, so new arcane - * base classes need adding to this function. - * Note: PrCs with their own spellbook eg. assassin count as base casters for this function - * - * @param oCaster The creature to check (outsiders can have sorc caster levels) - * - * @return TRUE if nClass is an arcane spellcasting class, FALSE otherwise - */ -int GetIsArcaneClass(int nClass, object oCaster = OBJECT_SELF); - -/** - * Returns if the given class is an arcane class. - * - * Divine base classes are *hardcoded* into here, so new divine - * base classes need adding to this function. - * Note: PrCs with their own spellbook eg. blackguard count as base casters for this function - * - * @param oCaster The creature to check (not currently used) - * - * @return TRUE if nClass is a divine spellcasting class, FALSE otherwise - */ -int GetIsDivineClass(int nClass, object oCaster = OBJECT_SELF); - -// Returns the best "natural" arcane levels of the PC in question. Does not -// consider feats that situationally adjust caster level. -int GetLevelByTypeArcane(object oCaster = OBJECT_SELF); - -// Returns the best "natural" divine levels of the PC in question. Does not -// consider feats that situationally adjust caster level. -int GetLevelByTypeDivine(object oCaster = OBJECT_SELF); - -/** - * Works out the total arcane caster levels from arcane PrCs. - * - * Arcane prestige classes are *hardcoded* into this function, so new arcane caster - * classes need adding to it. Rakshasa RHD count as sorc PrC levels if they also have some levels in sorc - * note: PrCs with their own spellbook eg. assassin are not PrCs for this function - * - * @param oCaster The creature to check - * @param nCastingClass Casting class, only ever used for UM - * - * @return Number of arcane caster levels contributed by PrCs. - */ -int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID); - -/** - * Works out the total divine caster levels from arcane PrCs. - * - * Divine prestige classes are *hardcoded* into this function, so new divine caster - * classes need adding to it. - * note: PrCs with their own spellbook eg. blackguard are not PrCs for this function - * - * @param oCaster The creature to check - * - * @return Number of divine caster levels contributed by PrCs. - */ -int GetDivinePRCLevels(object oCaster); - -/** - * Gets the position of the first arcane base class. - * - * @param oCaster The creature to check - * - * @return The position (1,2 or 3) of the first arcane *base* class of oCaster - */ -int GetFirstArcaneClassPosition(object oCaster = OBJECT_SELF); - -/** - * Gets the position of the first divine base class. - * - * @param oCaster The creature to check - * - * @return The position (1,2 or 3) of the first divine *base* class of oCaster - */ -int GetFirstDivineClassPosition(object oCaster = OBJECT_SELF); - -/** - * Gets the highest or first (by position) *base* arcane class type or, - * if oCaster has no arcane class levels, returns CLASS_TYPE_INVALID. - * - * This will get rakshasa RHD 'class' if oCaster doesn't have sorc levels. - * - * @param oCaster The creature to check - * - * @return CLASS_TYPE_* of first base arcane class or CLASS_TYPE_INVALID - */ -int GetPrimaryArcaneClass(object oCaster = OBJECT_SELF); - -/** - * Gets the highest first (by position) *base* divine class type or, - * if oCaster has no divine class levels, returns CLASS_TYPE_INVALID. - * - * @param oCaster The creature to check - * - * @return CLASS_TYPE_* of first base divine class or CLASS_TYPE_INVALID - */ -int GetPrimaryDivineClass(object oCaster = OBJECT_SELF); - -/** - * Gets the highest *base* arcane or divine class type or, - * if oCaster has no spellcasting class levels, returns CLASS_TYPE_INVALID. - * - * @param oCaster The creature to check - * - * @return CLASS_TYPE_* of first base arcane/divine class or CLASS_TYPE_INVALID - */ -int GetPrimarySpellcastingClass(object oCaster = OBJECT_SELF); - -/** - * Gets the caster level adjustment from the Practiced Spellcaster feats. - * - * @param oCaster The creature to check - * @param iCastingClass The CLASS_TYPE* that the spell was cast by. - * @param iCastingLevels The caster level for the spell calculated so far - * ie. BEFORE Practiced Spellcaster. - */ -int PracticedSpellcasting(object oCaster, int iCastingClass, int iCastingLevels); - -/** - * Returns the spell school of the spell passed to it. - * - * @param iSpellId The spell to get the school of. - * - * @return The SPELL_SCHOOL_* of the spell. - */ -int GetSpellSchool(int iSpellId); - -/** - * Healing spell filter. - * - * Gets if the given spell is a healing spell based on a hardcoded list. New - * healing spells need to be added to this. - * - * @author GaiaWerewolf - * @date 18 July 2005 - * - * @param nSpellId The spell to check - * - * @return TRUE if it is a healing spell, FALSE otherwise. - */ -int GetIsHealingSpell(int nSpellId); - -/** - * Gets the contribution of the archmage's High Arcana Spell Power - * feat to caster level. - * - * @param oCaster The creature to check - * - * @return caster level modifier from archmage Spell Power feats. - */ -int ArchmageSpellPower(object oCaster); - -/** - * Gets the caster level modifier from the Shadow Weave feat. - * - * Schools of Enchantment, Illusion, and Necromancy, and spells with the darkness - * descriptor altered by +1, Evocation or Transmutation (except spells with the - * darkness descriptor) altered by -1. - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * @param nSpellSchool The spell school the cast spell is from - * if none is specified, uses GetSpellSchool() - * - * @return caster level modifier for Shadow Weave feat. - */ -int ShadowWeave(object oCaster, int iSpellID, int nSpellSchool = -1); - -/** - * Gets the caster level modifier from the Divination Power class feature. - * - * Divination spells +1/3 Unseen Seer levels, all others -1/3 Unseer Seer levels - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * @param nSpellSchool The spell school the cast spell is from - * if none is specified, uses GetSpellSchool() - * - * @return caster level modifier for Divination Power feat. - */ -int DivinationPower(object oCaster, int nSpellSchool); - -/** - * Handles feats that modify caster level of spells with the fire - * descriptor. - * - * Currently this is Disciple of Meph's Fire Adept feat and Bloodline of Fire feat. - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * - * @return Caster level modifier for fire related feats. - */ -int FireAdept(object oCaster, int iSpellID); - -/** - * Handles feats that modify caster level of spells with the air - * descriptor. - * - * Currently this is the Air Mephling's Type feat - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * - * @return Caster level modifier for fire related feats. - */ -int AirAdept(object oCaster, int iSpellID); - -/** - * Handles feats that modify caster level of spells with the air - * descriptor. - * - * Currently this is the Air Mephling's Type feat - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * - * @return Caster level modifier for fire related feats. - */ -int WaterAdept(object oCaster, int iSpellID); - -/** - * Handles feats that modify caster level of spells with the earth - * descriptor. - * - * Currently this is Drift Magic feat. - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * - * @return Caster level modifier for earth related feats. - */ -int DriftMagic(object oCaster, int iSpellID); - -/** - * Soulcaster boost to caster level based on invested essentia - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * - * @return Caster level modifier - */ -int Soulcaster(object oCaster, int iSpellID); - -/** - * Gets the caster level modifier from the Storm Magic feat. - * - * Get +1 caster level if raining or snowing in area - * - * @param oCaster The creature to check - * - * @return Caster level modifier for Storm Magic feat. - */ -int StormMagic(object oCaster); - -/** - * Gets the caster level modifier from the Cormanthyran Moon Magic feat. - * - * Get +1 caster level if outdoors, at night, with no rain. - * - * @param oCaster The creature to check - * - * @return Caster level modifier for Cormanthyran Moon Magic feat. - */ -int CormanthyranMoonMagic(object oCaster); - -/** - * Gets the caster level modifier from various domains. - * - * @param oCaster The creature to check - * @param nSpellID The spell ID of the spell - * @param nSpellSchool The spell school the cast spell is from - * if none is specified, uses GetSpellSchool() - * - * @return caster level modifier from domain powers - */ -int DomainPower(object oCaster, int nSpellID, int nSpellSchool = -1); - -/** - * Gets the caster level modifier from the Therapeutic Mantle Meld. - * - * @param oCaster The creature to check - * - * @return caster level modifier - */ -int TherapeuticMantle(object oCaster, int nSpellID); - -/** - * Gets the caster level modifier from the antipaladin's Death Knell SLA. - * - * @param oCaster The creature to check - * - * @return caster level modifier from the Death Knell SLA - */ -int DeathKnell(object oCaster); - -/** - * Gets the caster level modifier from the Draconic Power feat. - * - * Feat gives +1 to caster level. - * - * @param oCaster The creature to check - * - * @return caster level modifier from the Draconic power feat. - */ -int DraconicPower(object oCaster = OBJECT_SELF); - -/** - * Gets the caster level modifier from Song of Arcane Power effect. - * - * @param oCaster The creature to check - * - * @return caster level modifier from the Draconic power feat. - */ -int SongOfArcanePower(object oCaster = OBJECT_SELF); - -/** - * Gets the caster level modifier to necromancy spells for the - * True Necromancer PrC (all spellcasting levels are counted, both - * arcane and divine). - * - * @param oCaster The creature to check - * @param iSpellID The spell ID of the spell - * @param sType "ARCANE" or "DIVINE" spell - * @param nSpellSchool The spell school the cast spell is from - * if none is specified, uses GetSpellSchool() - * - * @return caster level modifier for True Necro - */ -int TrueNecromancy(object oCaster, int iSpellID, string sType, int nSpellSchool = -1); - -// Nentyar Hunter casting boost -int Nentyar(object oCaster, int nCastingClass); - -// +1 on spells that target armor or shields -int ShieldDwarfWarder(object oCaster); - -// +1 while this feat is active -int DarkSpeech(object oCaster); - -// Adds 1/2 level in all other casting classes. -int UrPriestCL(object oCaster, int nCastingClass); - -// Adds Druid levels to Blighter caster level -int BlighterCL(object oCaster, int nCastingClass); - -//ebonfowl: Adds CL boosts from reserve feats -int ReserveFeatCL(object oCaster, int iSpellId); - -////////////////////////////////////////////////// -/* Include section */ -////////////////////////////////////////////////// - -//#include "prc_racial_const" -// Not needed as it has acccess via prc_inc_newip -//#include "prc_inc_nwscript" // gets inc_2da_cache, inc_debug, prc_inc_switch -#include "prc_inc_newip" -//#include "prc_inc_spells" -#include "prc_inc_descrptr" - -////////////////////////////////////////////////// -/* Internal functions */ -////////////////////////////////////////////////// - -// stolen from prcsp_archmaginc.nss, modified to work in FireAdept() function -string _GetChangedElementalType(int nSpellID, object oCaster = OBJECT_SELF) -{ - string spellType = Get2DACache("spells", "ImmunityType", nSpellID);//lookup_spell_type(spell_id); - string sType = GetLocalString(oCaster, "archmage_mastery_elements_name"); - - if (sType == "") sType = spellType; - - return sType; -} - -//ebonfowl: Adding this function to check if a spell belongs to a given domain based on the Reserve Feat 2das -//Only works with Death, Destruction and War domains as only those domain 2das have been created -int GetIsFromDomain (int iSpellId, string sDomain) -{ - string sFile = "prc_desc_" + sDomain; - - int i; - int nListSpellID; - - for (i = 0; i < 15; i++) // Adjust max i to reflect something close to the highest row number in the 2das - { - nListSpellID = StringToInt(Get2DACache(sFile, "SpellID", i)); - if (nListSpellID == iSpellId) return TRUE; - } - return FALSE; -} - -////////////////////////////////////////////////// -/* Function Definitions */ -////////////////////////////////////////////////// - -int GetCasterLevelModifier(int nClass) -{ - switch(nClass) // do not change to return zero as this is used as a divisor - { - // add in new base half-caster classes here - case CLASS_TYPE_HEXBLADE: - case CLASS_TYPE_RANGER: - case CLASS_TYPE_PALADIN: - case CLASS_TYPE_ANTI_PALADIN: - return 2; - } - return 1; // normal progression -} - -int PRCGetCasterLevel(object oCaster = OBJECT_SELF) -{ - int nAdjust = GetLocalInt(oCaster, PRC_CASTERLEVEL_ADJUSTMENT);//this is for builder use - nAdjust += GetLocalInt(oCaster, "TrueCasterLens"); - nAdjust += GetHasSpellEffect(SPELL_VIRTUOSO_MAGICAL_MELODY, oCaster); - - // For when you want to assign the caster level. - int iReturnLevel = GetLocalInt(oCaster, PRC_CASTERLEVEL_OVERRIDE); - if (iReturnLevel) - { - if (DEBUG) DoDebug("PRCGetCasterLevel: found override caster level = "+IntToString(iReturnLevel)+" with adjustment = " + IntToString(nAdjust)+", original level = "+IntToString(GetCasterLevel(oCaster))); - return iReturnLevel+nAdjust; - } - - // if we made it here, iReturnLevel = 0; - - int iCastingClass = PRCGetLastSpellCastClass(oCaster); // might be CLASS_TYPE_INVALID - if(iCastingClass == CLASS_TYPE_SUBLIME_CHORD) - iCastingClass = GetPrimaryArcaneClass(oCaster); - int iSpellId = PRCGetSpellId(oCaster); - object oItem = PRCGetSpellCastItem(oCaster); - - // Item Spells - // this check is unreliable because of Bioware's implementation (GetSpellCastItem returns - // the last object from which a spell was cast, even if we are not casting from an item) - if(GetIsObjectValid(oItem)) - { - int nType = GetBaseItemType(oItem); - if(DEBUG) DoDebug("PRCGetCasterLevel: found valid item = "+GetName(oItem)); - // double check, just to make sure - if(GetItemPossessor(oItem) == oCaster) // likely item casting - { - if(GetPRCSwitch(PRC_STAFF_CASTER_LEVEL) - && ((nType == BASE_ITEM_MAGICSTAFF) || - (nType == BASE_ITEM_CRAFTED_STAFF)) - ) - { - iCastingClass = GetPrimarySpellcastingClass(oCaster); - } - else - { - //code for getting new ip type - itemproperty ipTest = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(ipTest)) - { - if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_CAST_SPELL_CASTER_LEVEL) - { - int nSubType = GetItemPropertySubType(ipTest); - nSubType = StringToInt(Get2DACache("iprp_spells", "SpellIndex", nSubType)); - if(nSubType == iSpellId) - { - iReturnLevel = GetItemPropertyCostTableValue(ipTest); - if (DEBUG) DoDebug("PRCGetCasterLevel: caster level from item = "+IntToString(iReturnLevel)); - break; // exit the while loop - } - } - ipTest = GetNextItemProperty(oItem); - } - // if we didn't find a caster level on the item, it must be Bioware item casting - if(!iReturnLevel) - { - iReturnLevel = GetCasterLevel(oCaster); - if (DEBUG) DoDebug("PRCGetCasterLevel: bioware item casting with caster level = "+IntToString(iReturnLevel)); - } - } - - if(nType == BASE_ITEM_MAGICWAND || nType == BASE_ITEM_ENCHANTED_WAND) - { - if (DEBUG) DoDebug("PRCGetCasterLevel - Casting Item is a Wand at level "+IntToString(iReturnLevel)); - if (GetHasFeat(FEAT_RECKLESS_WAND_WIELDER, oCaster) && GetLocalInt(oCaster, "RecklessWand")) // This burns an extra charge to increase caster level by 2 - { - if (DEBUG) DoDebug("PRCGetCasterLevel - Reckless Wand Active"); - if (GetItemCharges(oItem) > 0) // Make sure we have an extra charge to burn - { - iReturnLevel += 2; - if (!GetLocalInt(oCaster, "RecklessWandDelay")) SetItemCharges(oItem, GetItemCharges(oItem)-1); - SetLocalInt(oCaster, "RecklessWandDelay", TRUE); - DelayCommand(0.5, DeleteLocalInt(oCaster, "RecklessWandDelay")); - if (DEBUG) DoDebug("PRCGetCasterLevel - Reckless Wand Triggered at level "+IntToString(iReturnLevel)); - } - } - if (GetHasFeat(FEAT_WAND_MASTERY, oCaster)) - iReturnLevel += 2; - } - } - if (DEBUG) DoDebug("PRCGetCasterLevel: total item casting caster level = "+IntToString(iReturnLevel)); - } - - // get spell school here as many of the following fns use it - int nSpellSchool = GetSpellSchool(iSpellId); - - // no item casting, and arcane caster? - if(!iReturnLevel && GetIsArcaneClass(iCastingClass, oCaster)) - { - iReturnLevel = GetLevelByClass(iCastingClass, oCaster) / GetCasterLevelModifier(iCastingClass); - - // Casting as a sorc but don't have any levels in the class - if(iCastingClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oCaster)) - { - int nRace = GetRacialType(oCaster); - - //if the player has sorcerer levels, then it counts as a prestige class - //otherwise use RHD instead of sorc levels - if(nRace == RACIAL_TYPE_RAKSHASA) - iReturnLevel = GetLevelByClass(CLASS_TYPE_OUTSIDER); - else if(nRace == RACIAL_TYPE_DRIDER) - iReturnLevel = GetLevelByClass(CLASS_TYPE_ABERRATION); - else if(nRace == RACIAL_TYPE_ARKAMOI) - iReturnLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS); - else if(nRace == RACIAL_TYPE_REDSPAWN_ARCANISS) - iReturnLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS)*3/4; - else if(nRace == RACIAL_TYPE_MARRUTACT) - iReturnLevel = (GetLevelByClass(CLASS_TYPE_MONSTROUS)*6/7)-1; - else if(nRace == RACIAL_TYPE_ARANEA) - iReturnLevel = GetLevelByClass(CLASS_TYPE_SHAPECHANGER); - - } - // Casting as a bard but don't have any levels in the class - if(iCastingClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oCaster)) - { - int nRace = GetRacialType(oCaster); - - //if the player has bard levels, then it counts as a prestige class - //otherwise use RHD instead of bard levels - if(nRace == RACIAL_TYPE_GLOURA) - iReturnLevel = GetLevelByClass(CLASS_TYPE_FEY); - } - - //Spell Rage ability - if(GetHasSpellEffect(SPELL_SPELL_RAGE, oCaster) - && (nSpellSchool == SPELL_SCHOOL_ABJURATION - || nSpellSchool == SPELL_SCHOOL_CONJURATION - || nSpellSchool == SPELL_SCHOOL_EVOCATION - || nSpellSchool == SPELL_SCHOOL_NECROMANCY - || nSpellSchool == SPELL_SCHOOL_TRANSMUTATION)) - { - iReturnLevel = GetHitDice(oCaster); - } - - else if(GetPrimaryArcaneClass(oCaster) == iCastingClass) - iReturnLevel += GetArcanePRCLevels(oCaster); - else if(GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oCaster)) - iReturnLevel += GetArcanePRCLevels(oCaster, iCastingClass); - - iReturnLevel += PracticedSpellcasting(oCaster, iCastingClass, iReturnLevel); - - iReturnLevel += TrueNecromancy(oCaster, iSpellId, "ARCANE", nSpellSchool) - + ShadowWeave(oCaster, iSpellId, nSpellSchool) - + FireAdept(oCaster, iSpellId) - + AirAdept(oCaster, iSpellId) - + WaterAdept(oCaster, iSpellId) - + ArchmageSpellPower(oCaster) - + StormMagic(oCaster) - + CormanthyranMoonMagic(oCaster) - + DomainPower(oCaster, iSpellId, nSpellSchool) - + DivinationPower(oCaster, nSpellSchool) - + DeathKnell(oCaster) - + DraconicPower(oCaster) - + DriftMagic(oCaster, iSpellId) - + Soulcaster(oCaster, iSpellId) - + TherapeuticMantle(oCaster, iSpellId) - + DarkSpeech(oCaster) - + ShieldDwarfWarder(oCaster) - + SongOfArcanePower(oCaster) - + ReserveFeatCL(oCaster, iSpellId); - - if (GetLocalInt(oCaster, "CaptureMagic")) - { - iReturnLevel += GetLocalInt(oCaster, "CaptureMagic"); - DeleteLocalInt(oCaster, "CaptureMagic"); - } - - // Get stance level bonus for Jade Phoenix Mage - if(GetLevelByClass(CLASS_TYPE_JADE_PHOENIX_MAGE, oCaster)) - { - if (_GetChangedElementalType(iSpellId, oCaster) == "Fire" && GetLocalInt(oCaster, "ToB_JPM_FireB")) - iReturnLevel += 3; - iReturnLevel += GetLocalInt(oCaster, "ToB_JPM_MystP"); - } - // Abjurant Champion uses its Base AB as Caster Level if higher - if(GetHasFeat(FEAT_MARTIAL_ARCANIST)) - { - //Get the caster's base AB - int nBaseAB = GetBaseAttackBonus(oCaster); - if(nBaseAB > iReturnLevel) - { - iReturnLevel = nBaseAB; - } - } - if (DEBUG) DoDebug("PRCGetCasterLevel: total arcane caster level = "+IntToString(iReturnLevel)); - } - - // no item casting and divine caster? - else if(!iReturnLevel && GetIsDivineClass(iCastingClass, oCaster)) - { - iReturnLevel = GetLevelByClass(iCastingClass, oCaster) / GetCasterLevelModifier(iCastingClass); - if(GetPrimaryDivineClass(oCaster) == iCastingClass) - iReturnLevel += GetDivinePRCLevels(oCaster); - - iReturnLevel += PracticedSpellcasting(oCaster, iCastingClass, iReturnLevel); - - iReturnLevel += TrueNecromancy(oCaster, iSpellId, "DIVINE", nSpellSchool) - + ShadowWeave(oCaster, iSpellId, nSpellSchool) - + FireAdept(oCaster, iSpellId) - + StormMagic(oCaster) - + CormanthyranMoonMagic(oCaster) - + Nentyar(oCaster, iCastingClass) - + DomainPower(oCaster, iSpellId, nSpellSchool) - + DriftMagic(oCaster, iSpellId) - + AirAdept(oCaster, iSpellId) - + WaterAdept(oCaster, iSpellId) - + Soulcaster(oCaster, iSpellId) - + ShieldDwarfWarder(oCaster) - + DarkSpeech(oCaster) - + DeathKnell(oCaster) - + UrPriestCL(oCaster, iCastingClass) - + BlighterCL(oCaster, iCastingClass) - + ReserveFeatCL(oCaster, iSpellId); - - if (DEBUG) DoDebug("PRCGetCasterLevel: total divine caster level = "+IntToString(iReturnLevel)); - } - - //at this point it must be a SLA or similar - if(!iReturnLevel) - { - iReturnLevel = GetCasterLevel(oCaster); - if (DEBUG) DoDebug("PRCGetCasterLevel: bioware caster level = "+IntToString(iReturnLevel)); - } - - iReturnLevel -= GetLocalInt(oCaster, "WoLCasterPenalty"); - if (GetLocalInt(oCaster, "EldritchDisrupt")) - iReturnLevel -= 4; - if (GetLocalInt(oCaster, "EldritchVortex")) - iReturnLevel -= 4; - if (DEBUG) DoDebug("PRCGetCasterLevel: caster level pre adjust = "+IntToString(iReturnLevel)); - iReturnLevel += nAdjust; - if (DEBUG) DoDebug("PRCGetCasterLevel: total caster level = "+IntToString(iReturnLevel)); - - return iReturnLevel; -} - -int PRCGetLastSpellCastClass(object oCaster = OBJECT_SELF) -{ - // note that a barbarian has a class type constant of zero. So nClass == 0 could in principle mean - // that a barbarian cast the spell, However, barbarians cannot cast spells, so it doesn't really matter - // beware of Barbarians with UMD, though. Also watch out for spell like abilities - // might have to provide a fix for these (for instance: if(nClass == -1) nClass = 0; - int nClass = GetLocalInt(oCaster, PRC_CASTERCLASS_OVERRIDE); - if(nClass) - { - if(DEBUG) DoDebug("PRCGetLastSpellCastClass: found override caster class = "+IntToString(nClass)+", original class = "+IntToString(GetLastSpellCastClass())); - return nClass; - } - nClass = GetLastSpellCastClass(); - //if casting class is invalid and the spell was not cast form an item it was probably cast from the new spellbook - int NSB_Class = GetLocalInt(oCaster, "NSB_Class"); - if(nClass == CLASS_TYPE_INVALID && GetSpellCastItem() == OBJECT_INVALID && NSB_Class) - nClass = NSB_Class; - - if(DEBUG) DoDebug("PRCGetLastSpellCastClass: returning caster class = "+IntToString(nClass)+" NSB_Class = "+IntToString(NSB_Class)); - return nClass; -} - -int GetIsArcaneClass(int nClass, object oCaster = OBJECT_SELF) -{ - return nClass == CLASS_TYPE_ASSASSIN - || nClass == CLASS_TYPE_BARD - || nClass == CLASS_TYPE_BEGUILER - || nClass == CLASS_TYPE_CELEBRANT_SHARESS - || nClass == CLASS_TYPE_CULTIST_SHATTERED_PEAK - || nClass == CLASS_TYPE_DREAD_NECROMANCER - || nClass == CLASS_TYPE_DUSKBLADE - || nClass == CLASS_TYPE_HARPER - || nClass == CLASS_TYPE_HEXBLADE - || nClass == CLASS_TYPE_KNIGHT_WEAVE - || nClass == CLASS_TYPE_SHADOWLORD - || nClass == CLASS_TYPE_SORCERER - || nClass == CLASS_TYPE_SUBLIME_CHORD - || nClass == CLASS_TYPE_SUEL_ARCHANAMACH - || nClass == CLASS_TYPE_WARMAGE - || nClass == CLASS_TYPE_WIZARD - || (nClass == CLASS_TYPE_SHAPECHANGER - && GetRacialType(oCaster) == RACIAL_TYPE_ARANEA - && !GetLevelByClass(CLASS_TYPE_SORCERER)) - || (nClass == CLASS_TYPE_OUTSIDER - && GetRacialType(oCaster) == RACIAL_TYPE_RAKSHASA - && !GetLevelByClass(CLASS_TYPE_SORCERER)) - || (nClass == CLASS_TYPE_ABERRATION - && GetRacialType(oCaster) == RACIAL_TYPE_DRIDER - && !GetLevelByClass(CLASS_TYPE_SORCERER)) - || (nClass == CLASS_TYPE_MONSTROUS - && GetRacialType(oCaster) == RACIAL_TYPE_ARKAMOI - && !GetLevelByClass(CLASS_TYPE_SORCERER)) - || (nClass == CLASS_TYPE_MONSTROUS - && GetRacialType(oCaster) == RACIAL_TYPE_REDSPAWN_ARCANISS - && !GetLevelByClass(CLASS_TYPE_SORCERER)) - || (nClass == CLASS_TYPE_MONSTROUS - && GetRacialType(oCaster) == RACIAL_TYPE_MARRUTACT - && !GetLevelByClass(CLASS_TYPE_SORCERER)) - || (nClass == CLASS_TYPE_FEY - && GetRacialType(oCaster) == RACIAL_TYPE_GLOURA - && !GetLevelByClass(CLASS_TYPE_BARD)); -} - -int GetIsDivineClass(int nClass, object oCaster = OBJECT_SELF) -{ - return nClass == CLASS_TYPE_ARCHIVIST - || nClass == CLASS_TYPE_BLACKGUARD - || nClass == CLASS_TYPE_BLIGHTER - || nClass == CLASS_TYPE_CLERIC - || nClass == CLASS_TYPE_DRUID - || nClass == CLASS_TYPE_FAVOURED_SOUL - || nClass == CLASS_TYPE_HEALER - || nClass == CLASS_TYPE_JUSTICEWW - || nClass == CLASS_TYPE_KNIGHT_CHALICE - || nClass == CLASS_TYPE_KNIGHT_MIDDLECIRCLE - || nClass == CLASS_TYPE_NENTYAR_HUNTER - || nClass == CLASS_TYPE_OCULAR - || nClass == CLASS_TYPE_PALADIN - || nClass == CLASS_TYPE_RANGER - || nClass == CLASS_TYPE_SHAMAN - || nClass == CLASS_TYPE_SLAYER_OF_DOMIEL - || nClass == CLASS_TYPE_SOHEI - || nClass == CLASS_TYPE_SOLDIER_OF_LIGHT - || nClass == CLASS_TYPE_UR_PRIEST - || nClass == CLASS_TYPE_VASSAL - || nClass == CLASS_TYPE_VIGILANT; -} - -int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) -{ - int nArcane; - int nOozeMLevel = GetLevelByClass(CLASS_TYPE_OOZEMASTER, oCaster); - int nUM = GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oCaster); - - int nFirstClass = GetClassByPosition(1, oCaster); - int nSecondClass = GetClassByPosition(2, oCaster); - int nThirdClass = GetClassByPosition(3, oCaster); - int nFourthClass = GetClassByPosition(4, oCaster); - int nFifthClass = GetClassByPosition(5, oCaster); - int nSixthClass = GetClassByPosition(6, oCaster); - int nSeventhClass = GetClassByPosition(7, oCaster); - int nEightClass = GetClassByPosition(8, oCaster); - - if (GetFirstArcaneClassPosition(oCaster)) nArcane += GetLevelByClass(CLASS_TYPE_SOULCASTER, oCaster); - - nArcane += GetLevelByClass(CLASS_TYPE_ABJURANT_CHAMPION, oCaster) - + GetLevelByClass(CLASS_TYPE_ALIENIST, oCaster) - + GetLevelByClass(CLASS_TYPE_ANIMA_MAGE, oCaster) - + GetLevelByClass(CLASS_TYPE_ARCANE_HIEROPHANT, oCaster) - + GetLevelByClass(CLASS_TYPE_ARCHMAGE, oCaster) - + GetLevelByClass(CLASS_TYPE_ARCTRICK, oCaster) - + GetLevelByClass(CLASS_TYPE_CEREBREMANCER, oCaster) - + GetLevelByClass(CLASS_TYPE_DIABOLIST, oCaster) - + GetLevelByClass(CLASS_TYPE_DRAGONHEART_MAGE, oCaster) - + GetLevelByClass(CLASS_TYPE_ELDRITCH_KNIGHT, oCaster) - + GetLevelByClass(CLASS_TYPE_ELDRITCH_THEURGE, oCaster) - + GetLevelByClass(CLASS_TYPE_ELEMENTAL_SAVANT,oCaster) - + GetLevelByClass(CLASS_TYPE_FMM, oCaster) - + GetLevelByClass(CLASS_TYPE_FROST_MAGE, oCaster) - + GetLevelByClass(CLASS_TYPE_HARPERMAGE, oCaster) - + GetLevelByClass(CLASS_TYPE_JADE_PHOENIX_MAGE, oCaster) - + GetLevelByClass(CLASS_TYPE_MAGEKILLER, oCaster) - + GetLevelByClass(CLASS_TYPE_MASTER_ALCHEMIST, oCaster) - + GetLevelByClass(CLASS_TYPE_MASTER_HARPER, oCaster) - + GetLevelByClass(CLASS_TYPE_MYSTIC_THEURGE, oCaster) - + GetLevelByClass(CLASS_TYPE_NOCTUMANCER, oCaster) - + GetLevelByClass(CLASS_TYPE_SPELLDANCER, oCaster) - + GetLevelByClass(CLASS_TYPE_TRUENECRO, oCaster) - + GetLevelByClass(CLASS_TYPE_RED_WIZARD, oCaster) - + GetLevelByClass(CLASS_TYPE_SHADOW_ADEPT, oCaster) - + GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster) - + GetLevelByClass(CLASS_TYPE_UNSEEN_SEER, oCaster) - + GetLevelByClass(CLASS_TYPE_VIRTUOSO, oCaster) - + GetLevelByClass(CLASS_TYPE_WAR_WIZARD_OF_CORMYR, oCaster) - - + (GetLevelByClass(CLASS_TYPE_BLADESINGER, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_BONDED_SUMMONNER, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_PALEMASTER, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_HATHRAN, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_HAVOC_MAGE, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_SPELLSWORD, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_THRALL_OF_GRAZZT_A, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_TALON_OF_TIAMAT, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_RAGE_MAGE, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_WAYFARER_GUIDE, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_JUDICATOR, oCaster) + 1) / 3; - - int nClass = GetLevelByClass(CLASS_TYPE_WILD_MAGE, oCaster); - if (nClass) - nArcane += nClass - 3 + d6(); - - //The following changes are to prevent a mage/invoker from gaining bonus caster levels in both base classes. - - if(GetLocalInt(oCaster, "INV_Caster") == 1 || - (!GetLevelByClass(CLASS_TYPE_WARLOCK, oCaster) && !GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oCaster))) - nArcane += (GetLevelByClass(CLASS_TYPE_ACOLYTE, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_DISCIPLE_OF_ASMODEUS, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_TALON_OF_TIAMAT, oCaster) + 1) / 2 - + GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oCaster) - + GetLevelByClass(CLASS_TYPE_MAESTER, oCaster); - - - /* oozemaster levels count towards arcane caster level if: - * - * first class slot is arcane OR - * first class slot is NOT divine AND second class slot is arcane OR - * first AND second class slot is NOT divine AND 3rd class slot is arcane - */ - if (nOozeMLevel) //:: [PRC .35] This needs marker feats. - { - if (GetIsArcaneClass(nFirstClass, oCaster) - || (!GetIsDivineClass(nFirstClass, oCaster) - && GetIsArcaneClass(nSecondClass, oCaster)) - || (!GetIsDivineClass(nFirstClass, oCaster) - && !GetIsDivineClass(nSecondClass, oCaster) - && GetIsArcaneClass(nThirdClass, oCaster))) - nArcane += nOozeMLevel / 2; - } - - if (nUM) - { - int nBoost = nUM - 1; //Prep caster always loses a level on first level of the class - if (nUM >= 4) nBoost = nUM - 2; - if (nUM >= 7) nBoost = nUM - 3; - nArcane += nBoost; - - if (nCastingClass == CLASS_TYPE_SORCERER) - { - int nBoost = 1; //Sorcerer gets the lost levels back - if (nUM >= 4) nBoost = 2; - if (nUM >= 7) nBoost = 3; - nArcane += nBoost; - } - } - if(GetLevelByClass(CLASS_TYPE_SORCERER, oCaster)) - { - int nRace = GetRacialType(oCaster); - - //includes RHD HD as sorc - //if they have sorcerer levels, then it counts as a prestige class - //otherwise its used instead of sorc levels - if(nRace == RACIAL_TYPE_ARANEA) - nArcane += GetLevelByClass(CLASS_TYPE_SHAPECHANGER); - if(nRace == RACIAL_TYPE_RAKSHASA) - nArcane += GetLevelByClass(CLASS_TYPE_OUTSIDER); - if(nRace == RACIAL_TYPE_DRIDER) - nArcane += GetLevelByClass(CLASS_TYPE_ABERRATION); - if(nRace == RACIAL_TYPE_ARKAMOI) - nArcane += GetLevelByClass(CLASS_TYPE_MONSTROUS); - if(nRace == RACIAL_TYPE_REDSPAWN_ARCANISS) - nArcane += GetLevelByClass(CLASS_TYPE_MONSTROUS)*3/4; - if(nRace == RACIAL_TYPE_MARRUTACT) - nArcane += (GetLevelByClass(CLASS_TYPE_MONSTROUS)*6/7)-1; - } - - if(GetLevelByClass(CLASS_TYPE_BARD, oCaster)) - { - int nRace = GetRacialType(oCaster); - - //includes RHD HD as bard - //if they have bard levels, then it counts as a prestige class - //otherwise its used instead of bard levels - if(nRace == RACIAL_TYPE_GLOURA) - nArcane += GetLevelByClass(CLASS_TYPE_FEY); - } - - return nArcane; -} - -int GetDivinePRCLevels(object oCaster) -{ - int nDivine; - int nOozeMLevel = GetLevelByClass(CLASS_TYPE_OOZEMASTER, oCaster); - - int nFirstClass = GetClassByPosition(1, oCaster); - int nSecondClass = GetClassByPosition(2, oCaster); - int nThirdClass = GetClassByPosition(3, oCaster); - int nFourthClass = GetClassByPosition(4, oCaster); - int nFifthClass = GetClassByPosition(5, oCaster); - int nSixthClass = GetClassByPosition(6, oCaster); - int nSeventhClass = GetClassByPosition(7, oCaster); - int nEightClass = GetClassByPosition(8, oCaster); - - // This section accounts for full progression classes - nDivine += GetLevelByClass(CLASS_TYPE_ARCANE_HIEROPHANT, oCaster) - + GetLevelByClass(CLASS_TYPE_BLIGHTLORD, oCaster) - + GetLevelByClass(CLASS_TYPE_COMBAT_MEDIC, oCaster) - + GetLevelByClass(CLASS_TYPE_CONTEMPLATIVE, oCaster) - + GetLevelByClass(CLASS_TYPE_ELDRITCH_DISCIPLE, oCaster) - + GetLevelByClass(CLASS_TYPE_FORESTMASTER, oCaster) - + GetLevelByClass(CLASS_TYPE_FISTRAZIEL, oCaster) - + GetLevelByClass(CLASS_TYPE_HEARTWARDER, oCaster) - + GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster) - + GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster) - + GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster) - + GetLevelByClass(CLASS_TYPE_MORNINGLORD, oCaster) - + GetLevelByClass(CLASS_TYPE_MYSTIC_THEURGE, oCaster) - + GetLevelByClass(CLASS_TYPE_PSYCHIC_THEURGE, oCaster) - + GetLevelByClass(CLASS_TYPE_RUBY_VINDICATOR, oCaster) - + GetLevelByClass(CLASS_TYPE_RUNECASTER, oCaster) - + GetLevelByClass(CLASS_TYPE_SACREDPURIFIER, oCaster) - + GetLevelByClass(CLASS_TYPE_SAPPHIRE_HIERARCH, oCaster) - + GetLevelByClass(CLASS_TYPE_SHADOWBANE_STALKER,oCaster) - + GetLevelByClass(CLASS_TYPE_STORMLORD, oCaster) - + GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster) - + GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster) - - + (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_BRIMSTONE_SPEAKER, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_HATHRAN, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_MIGHTY_CONTENDER_KORD, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_OLLAM, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_ORCUS, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_SHINING_BLADE, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_TEMPUS, oCaster) + 1) / 2 - + (GetLevelByClass(CLASS_TYPE_WARPRIEST, oCaster) + 1) / 2 - - + (GetLevelByClass(CLASS_TYPE_JUDICATOR, oCaster) + 1) / 3; - - if (!GetHasFeat(FEAT_SF_CODE, oCaster)) - { - nDivine += GetLevelByClass(CLASS_TYPE_SACREDFIST, oCaster); - } - - if (nOozeMLevel) //:: [PRC .35] This needs marker feats. - { - if (GetIsDivineClass(nFirstClass, oCaster) - || (!GetIsArcaneClass(nFirstClass, oCaster) - && GetIsDivineClass(nSecondClass, oCaster)) - || (!GetIsArcaneClass(nFirstClass, oCaster) - && !GetIsArcaneClass(nSecondClass, oCaster) - && GetIsDivineClass(nThirdClass, oCaster))) - nDivine += nOozeMLevel / 2; - } - - return nDivine; -} - -int GetFirstArcaneClassPosition(object oCaster = OBJECT_SELF) -{ - int i; - for(i = 1; i < 9; i++) - { - if(GetIsArcaneClass(GetClassByPosition(i, oCaster), oCaster)) - return i; - } - - return 0; -} - -int GetFirstDivineClassPosition(object oCaster = OBJECT_SELF) -{ - int i; - for(i = 1; i < 9; i++) - { - if(GetIsDivineClass(GetClassByPosition(i, oCaster), oCaster)) - return i; - } - - return 0; -} - -int GetPrimaryArcaneClass(object oCaster = OBJECT_SELF) -{ - int nClass; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) - { - int iArcanePos = GetFirstArcaneClassPosition(oCaster); - if (!iArcanePos) return CLASS_TYPE_INVALID; // no arcane casting class - - nClass = GetClassByPosition(iArcanePos, oCaster); - } - else - { - int i, nClassTmp, nClassLvl; - for(i = 1; i < 9; i++) - { - nClassTmp = GetClassByPosition(i, oCaster); - if(GetIsArcaneClass(nClassTmp, oCaster) && nClassTmp != CLASS_TYPE_SUBLIME_CHORD) - { - if(GetLevelByClass(nClassTmp, oCaster) > nClassLvl) - { - nClass = nClassTmp; - nClassLvl = GetLevelByClass(nClass, oCaster); - } - } - } - if(!nClassLvl) - return CLASS_TYPE_INVALID; - } - - //raks, Arkamoi, driders and dragons cast as sorcs - if(nClass == CLASS_TYPE_OUTSIDER - || nClass == CLASS_TYPE_SHAPECHANGER - || nClass == CLASS_TYPE_ABERRATION - || nClass == CLASS_TYPE_DRAGON - || nClass == CLASS_TYPE_MONSTROUS) - nClass = CLASS_TYPE_SORCERER; - - if(nClass == CLASS_TYPE_FEY) - nClass = CLASS_TYPE_BARD; - - return nClass; -} - -int GetPrimaryDivineClass(object oCaster = OBJECT_SELF) -{ - int nClass; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) - { - int iDivinePos = GetFirstDivineClassPosition(oCaster); - if (!iDivinePos) return CLASS_TYPE_INVALID; // no Divine casting class - - nClass = GetClassByPosition(iDivinePos, oCaster); - } - else - { - int i, nClassTmp, nClassLvl; - for(i = 1; i < 9; i++) - { - nClassTmp = GetClassByPosition(i, oCaster); - if(GetIsDivineClass(nClassTmp, oCaster)) - { - if(GetLevelByClass(nClassTmp, oCaster) > nClassLvl) - { - nClass = nClassTmp; - nClassLvl = GetLevelByClass(nClass, oCaster); - } - } - } - if(!nClassLvl) - return CLASS_TYPE_INVALID; - } - - return nClass; -} - -int GetPrimarySpellcastingClass(object oCaster = OBJECT_SELF) -{ - int bFirst = GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE); - int nClass; - - int i, nClassTmp, nClassLvl; - for(i = 1; i < 9; i++) - { - nClassTmp = GetClassByPosition(i, oCaster); - if(GetIsArcaneClass(nClassTmp, oCaster) - || GetIsDivineClass(nClassTmp, oCaster) - && nClassTmp != CLASS_TYPE_SUBLIME_CHORD) - { - if(bFirst) - { - return nClass; - } - else if(GetLevelByClass(nClassTmp, oCaster) > nClassLvl) - { - nClass = nClassTmp; - nClassLvl = GetLevelByClass(nClass, oCaster); - } - } - } - if(!nClassLvl) - return CLASS_TYPE_INVALID; - - return nClass; -} - -int PracticedSpellcasting(object oCaster, int iCastingClass, int iCastingLevels) -{ - int nFeat; - int iAdjustment = GetHitDice(oCaster) - iCastingLevels; - if (iAdjustment > 4) iAdjustment = 4; - if (iAdjustment < 0) iAdjustment = 0; - - switch(iCastingClass) - { - case CLASS_TYPE_BARD: nFeat = FEAT_PRACTICED_SPELLCASTER_BARD; break; - case CLASS_TYPE_SORCERER: nFeat = FEAT_PRACTICED_SPELLCASTER_SORCERER; break; - case CLASS_TYPE_WIZARD: nFeat = FEAT_PRACTICED_SPELLCASTER_WIZARD; break; - case CLASS_TYPE_CLERIC: nFeat = FEAT_PRACTICED_SPELLCASTER_CLERIC; break; - case CLASS_TYPE_DRUID: nFeat = FEAT_PRACTICED_SPELLCASTER_DRUID; break; - case CLASS_TYPE_PALADIN: nFeat = FEAT_PRACTICED_SPELLCASTER_PALADIN; break; - case CLASS_TYPE_RANGER: nFeat = FEAT_PRACTICED_SPELLCASTER_RANGER; break; - case CLASS_TYPE_ASSASSIN: nFeat = FEAT_PRACTICED_SPELLCASTER_ASSASSIN; break; - case CLASS_TYPE_BLACKGUARD: nFeat = FEAT_PRACTICED_SPELLCASTER_BLACKGUARD; break; - case CLASS_TYPE_OCULAR: nFeat = FEAT_PRACTICED_SPELLCASTER_OCULAR; break; - case CLASS_TYPE_HEXBLADE: nFeat = FEAT_PRACTICED_SPELLCASTER_HEXBLADE; break; - case CLASS_TYPE_DUSKBLADE: nFeat = FEAT_PRACTICED_SPELLCASTER_DUSKBLADE; break; - case CLASS_TYPE_HEALER: nFeat = FEAT_PRACTICED_SPELLCASTER_HEALER; break; - case CLASS_TYPE_KNIGHT_CHALICE: nFeat = FEAT_PRACTICED_SPELLCASTER_KNIGHT_CHALICE; break; - case CLASS_TYPE_NENTYAR_HUNTER: nFeat = FEAT_PRACTICED_SPELLCASTER_NENTYAR; break; - case CLASS_TYPE_VASSAL: nFeat = FEAT_PRACTICED_SPELLCASTER_VASSAL; break; - case CLASS_TYPE_UR_PRIEST: nFeat = FEAT_PRACTICED_SPELLCASTER_UR_PRIEST; break; - case CLASS_TYPE_SOLDIER_OF_LIGHT: nFeat = FEAT_PRACTICED_SPELLCASTER_SOLDIER_OF_LIGHT; break; - case CLASS_TYPE_SHADOWLORD: nFeat = FEAT_PRACTICED_SPELLCASTER_SHADOWLORD; break; - case CLASS_TYPE_JUSTICEWW: nFeat = FEAT_PRACTICED_SPELLCASTER_JUSTICEWW; break; - case CLASS_TYPE_KNIGHT_MIDDLECIRCLE: nFeat = FEAT_PRACTICED_SPELLCASTER_KNIGHT_MIDDLECIRCLE; break; - case CLASS_TYPE_SHAMAN: nFeat = FEAT_PRACTICED_SPELLCASTER_SHAMAN; break; - case CLASS_TYPE_SLAYER_OF_DOMIEL: nFeat = FEAT_PRACTICED_SPELLCASTER_SLAYER_OF_DOMIEL; break; - case CLASS_TYPE_SUEL_ARCHANAMACH: nFeat = FEAT_PRACTICED_SPELLCASTER_SUEL_ARCHANAMACH; break; - case CLASS_TYPE_FAVOURED_SOUL: nFeat = FEAT_PRACTICED_SPELLCASTER_FAVOURED_SOUL; break; - case CLASS_TYPE_SOHEI: nFeat = FEAT_PRACTICED_SPELLCASTER_SOHEI; break; - case CLASS_TYPE_CELEBRANT_SHARESS: nFeat = FEAT_PRACTICED_SPELLCASTER_CELEBRANT_SHARESS; break; - case CLASS_TYPE_WARMAGE: nFeat = FEAT_PRACTICED_SPELLCASTER_WARMAGE; break; - case CLASS_TYPE_DREAD_NECROMANCER: nFeat = FEAT_PRACTICED_SPELLCASTER_DREAD_NECROMANCER; break; - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: nFeat = FEAT_PRACTICED_SPELLCASTER_CULTIST; break; - case CLASS_TYPE_ARCHIVIST: nFeat = FEAT_PRACTICED_SPELLCASTER_ARCHIVIST; break; - case CLASS_TYPE_BEGUILER: nFeat = FEAT_PRACTICED_SPELLCASTER_BEGUILER; break; - case CLASS_TYPE_BLIGHTER: nFeat = FEAT_PRACTICED_SPELLCASTER_BLIGHTER; break; - case CLASS_TYPE_HARPER: nFeat = FEAT_PRACTICED_SPELLCASTER_HARPER; break; - default: return 0; - } - - if(GetHasFeat(nFeat, oCaster)) - return iAdjustment; - - return 0; -} - -int GetSpellSchool(int iSpellId) -{ - string sSpellSchool = Get2DACache("spells", "School", iSpellId);//lookup_spell_school(iSpellId); - - if (sSpellSchool == "A") return SPELL_SCHOOL_ABJURATION; - else if (sSpellSchool == "C") return SPELL_SCHOOL_CONJURATION; - else if (sSpellSchool == "D") return SPELL_SCHOOL_DIVINATION; - else if (sSpellSchool == "E") return SPELL_SCHOOL_ENCHANTMENT; - else if (sSpellSchool == "V") return SPELL_SCHOOL_EVOCATION; - else if (sSpellSchool == "I") return SPELL_SCHOOL_ILLUSION; - else if (sSpellSchool == "N") return SPELL_SCHOOL_NECROMANCY; - else if (sSpellSchool == "T") return SPELL_SCHOOL_TRANSMUTATION; - else return SPELL_SCHOOL_GENERAL; - - return -1; -} - -/*int GetIsHealingSpell(int nSpellId) -{ - if ( nSpellId == SPELL_CURE_CRITICAL_WOUNDS - || nSpellId == SPELL_CURE_LIGHT_WOUNDS - || nSpellId == SPELL_CURE_MINOR_WOUNDS - || nSpellId == SPELL_CURE_MODERATE_WOUNDS - || nSpellId == SPELL_CURE_SERIOUS_WOUNDS - || nSpellId == SPELL_GREATER_RESTORATION - || nSpellId == SPELL_HEAL - || nSpellId == SPELL_HEALING_CIRCLE - || nSpellId == SPELL_MASS_HEAL - || nSpellId == SPELL_MONSTROUS_REGENERATION - || nSpellId == SPELL_REGENERATE - //End of stock NWN spells - || nSpellId == SPELL_MASS_CURE_LIGHT - || nSpellId == SPELL_MASS_CURE_MODERATE - || nSpellId == SPELL_MASS_CURE_SERIOUS - || nSpellId == SPELL_MASS_CURE_CRITICAL - || nSpellId == SPELL_PANACEA - ) - return TRUE; - - return FALSE; -}*/ - -int ArchmageSpellPower(object oCaster) -{ - if(GetHasFeat(FEAT_SPELL_POWER_V, oCaster)) - return 5; - if(GetHasFeat(FEAT_SPELL_POWER_IV, oCaster)) - return 4; - if(GetHasFeat(FEAT_SPELL_POWER_III, oCaster)) - return 3; - if(GetHasFeat(FEAT_SPELL_POWER_II, oCaster)) - return 2; - if(GetHasFeat(FEAT_SPELL_POWER_I, oCaster)) - return 1; - - return 0; -} - -int ShadowWeave(object oCaster, int iSpellID, int nSpellSchool = -1) -{ - if(!GetHasFeat(FEAT_SHADOWWEAVE,oCaster)) - return 0; - - if (nSpellSchool == -1) - nSpellSchool = GetSpellSchool(iSpellID); - - // Bonus for spells of Enhancement, Necromancy and Illusion schools and spells with Darkness descriptor - if(nSpellSchool == SPELL_SCHOOL_ENCHANTMENT - || nSpellSchool == SPELL_SCHOOL_NECROMANCY - || nSpellSchool == SPELL_SCHOOL_ILLUSION - || GetHasDescriptor(iSpellID, DESCRIPTOR_DARKNESS)) - { - return 1; - } - // Penalty to spells of Evocation and Transmutation schools, except for those with Darkness descriptor - else if(nSpellSchool == SPELL_SCHOOL_EVOCATION - || nSpellSchool == SPELL_SCHOOL_TRANSMUTATION) - { - return -1; - } - - return 0; -} - -int AirAdept(object oCaster, int iSpellID) -{ - if(!GetHasDescriptor(iSpellID, DESCRIPTOR_AIR)) - return 0; - - int nBoost = 0; - - if(GetHasFeat(FEAT_AIR_MEPHLING, oCaster)) - nBoost += 1; - - return nBoost; -} - -int WaterAdept(object oCaster, int iSpellID) -{ - if(!GetHasDescriptor(iSpellID, DESCRIPTOR_WATER)) - return 0; - - int nBoost = 0; - - if(GetHasFeat(FEAT_WATER_MEPHLING, oCaster)) - nBoost += 1; - - return nBoost; -} - -int FireAdept(object oCaster, int iSpellID) -{ - if(!GetHasDescriptor(iSpellID, DESCRIPTOR_FIRE)) - return 0; - - int nBoost = 0; - - if(GetHasFeat(FEAT_FIRE_ADEPT, oCaster)) - nBoost += 1; - - if(GetHasFeat(FEAT_FIRE_MEPHLING, oCaster)) - nBoost += 1; - - if(GetHasFeat(FEAT_BLOODLINE_OF_FIRE, oCaster)) - nBoost += 2; - - if(GetRacialType(oCaster) == RACIAL_TYPE_REDSPAWN_ARCANISS) - nBoost += 2; - - return nBoost; -} - -int DriftMagic(object oCaster, int iSpellID) -{ - if(!GetHasDescriptor(iSpellID, DESCRIPTOR_EARTH)) - return 0; - - int nBoost = 0; - - if(GetHasFeat(FEAT_DRIFT_MAGIC, oCaster)) - nBoost += 1; - - if(GetHasFeat(FEAT_EARTH_MEPHLING, oCaster)) - nBoost += 1; - - return nBoost; -} -/*int DriftMagic(object oCaster, int iSpellID) -{ - if(GetHasDescriptor(iSpellID, DESCRIPTOR_EARTH) && GetHasFeat(FEAT_DRIFT_MAGIC, oCaster)) - return 1; - - else if(GetHasDescriptor(iSpellID, DESCRIPTOR_EARTH) && GetHasFeat(FEAT_EARTH_MEPHLING, oCaster)) - return 1; - - return 0; -}*/ - -int Soulcaster(object oCaster, int iSpellID) -{ - if(GetLocalInt(oCaster, "SpellEssentia"+IntToString(iSpellID))) - { - int nReturn = GetLocalInt(oCaster, "SpellEssentia"+IntToString(iSpellID)); - DelayCommand(1.0, DeleteLocalInt(oCaster, "SpellEssentia"+IntToString(iSpellID))); - return nReturn; - } - - return 0; -} - -int StormMagic(object oCaster) -{ - if(!GetHasFeat(FEAT_STORMMAGIC, oCaster) && !GetHasFeat(FEAT_FROZEN_MAGIC, oCaster)) return 0; - - int nBoost = 0; - - int nWeather = GetWeather(GetArea(oCaster)); - if(nWeather == WEATHER_RAIN && GetHasFeat(FEAT_STORMMAGIC, oCaster)) - nBoost += 1; - if(nWeather == WEATHER_SNOW && GetHasFeat(FEAT_STORMMAGIC, oCaster)) - nBoost += 1; - if(nWeather == WEATHER_SNOW && GetHasFeat(FEAT_FROZEN_MAGIC, oCaster)) - nBoost += 2; - if (GetLocalInt(GetArea(oCaster),"FrozenMagic") && GetHasFeat(FEAT_FROZEN_MAGIC, oCaster) && nWeather != WEATHER_SNOW) - nBoost += 2; - - return nBoost; -} - -int DivinationPower(object oCaster, int nSpellSchool) -{ - int nClass = GetLevelByClass(CLASS_TYPE_UNSEEN_SEER, oCaster); - if(!nClass) return 0; - - int nBoost = (nClass + 2) / 3; - - if (nSpellSchool != SPELL_SCHOOL_DIVINATION) - nBoost *= -1; // Negative if it's not a divination spell - - return nBoost; -} - -int CormanthyranMoonMagic(object oCaster) -{ - if (!GetHasFeat(FEAT_CORMANTHYRAN_MOON_MAGIC, oCaster)) return 0; - - object oArea = GetArea(oCaster); - - // The moon must be visible. Thus, outdoors, at night, with no rain. - if (GetWeather(oArea) != WEATHER_RAIN && GetWeather(oArea) != WEATHER_SNOW && - GetIsNight() && !GetIsAreaInterior(oArea)) - { - return 2; - } - return 0; -} - -int Nentyar(object oCaster, int nCastingClass) -{ - if (nCastingClass == CLASS_TYPE_NENTYAR_HUNTER) - { - int nBonus = GetLevelByClass(CLASS_TYPE_DRUID, oCaster) + GetLevelByClass(CLASS_TYPE_CLERIC, oCaster) + GetLevelByClass(CLASS_TYPE_RANGER, oCaster)/2; - return nBonus; - } - return 0; -} - -int ShieldDwarfWarder(object oCaster) -{ - if (!GetHasFeat(FEAT_SHIELD_DWARF_WARDER, oCaster)) return 0; - - object oTarget = PRCGetSpellTargetObject(); - // If it's an item that grants an AC bonus - int nBase = GetBaseItemType(oTarget); - if (nBase == BASE_ITEM_SMALLSHIELD || nBase == BASE_ITEM_LARGESHIELD || nBase == BASE_ITEM_TOWERSHIELD || nBase == BASE_ITEM_ARMOR) - return 1; - - return 0; -} - -int DarkSpeech(object oCaster) -{ - if (GetHasSpellEffect(SPELL_DARK_SPEECH_POWER, oCaster)) - { - ExecuteScript("prc_dark_power", oCaster); - return 1; - } - return 0; -} - -int DomainPower(object oCaster, int nSpellID, int nSpellSchool = -1) -{ - int nBonus = 0; - if (nSpellSchool == -1) - nSpellSchool = GetSpellSchool(nSpellID); - - // Boosts Caster level with the Illusion school by 1 - if (nSpellSchool == SPELL_SCHOOL_ILLUSION && GetHasFeat(FEAT_DOMAIN_POWER_GNOME, oCaster)) - nBonus += 1; - - // Boosts Caster level with the Illusion school by 1 - if (nSpellSchool == SPELL_SCHOOL_ILLUSION && GetHasFeat(FEAT_DOMAIN_POWER_ILLUSION, oCaster)) - nBonus += 1; - - // Boosts Caster level with healing spells - if (GetIsOfSubschool(nSpellID, SUBSCHOOL_HEALING) && GetHasFeat(FEAT_HEALING_DOMAIN_POWER, oCaster)) - nBonus += 1; - - // Boosts Caster level with the Divination school by 1 - if (nSpellSchool == SPELL_SCHOOL_DIVINATION && GetHasFeat(FEAT_KNOWLEDGE_DOMAIN_POWER, oCaster)) - nBonus += 1; - - // Boosts Caster level with evil spells by 1 - if (GetHasDescriptor(nSpellID, DESCRIPTOR_EVIL) && GetHasFeat(FEAT_EVIL_DOMAIN_POWER, oCaster)) - nBonus += 1; - - // Boosts Caster level with good spells by 1 - if (GetHasDescriptor(nSpellID, DESCRIPTOR_GOOD) && GetHasFeat(FEAT_GOOD_DOMAIN_POWER, oCaster)) - nBonus += 1; - - return nBonus; -} - -int TherapeuticMantle(object oCaster, int nSpellID) -{ - int nReturn; - // Boosts Caster level with healing spells - if (GetIsMeldBound(oCaster, MELD_THERAPEUTIC_MANTLE) == CHAKRA_SHOULDERS && GetIsOfSubschool(nSpellID, SUBSCHOOL_HEALING)) - nReturn = GetEssentiaInvested(oCaster, MELD_THERAPEUTIC_MANTLE); - - return nReturn; -} - -int DeathKnell(object oCaster) -{ - // If you do have the spell effect, return a +1 bonus to caster level - return GetHasSpellEffect(SPELL_DEATH_KNELL, oCaster); -} - -int DraconicPower(object oCaster = OBJECT_SELF) -{ - return GetHasFeat(FEAT_DRACONIC_POWER, oCaster); -} - -int SongOfArcanePower(object oCaster = OBJECT_SELF) -{ - int nBonus = GetLocalInt(oCaster, "SongOfArcanePower"); - DeleteLocalInt(oCaster, "SongOfArcanePower"); - - int nLevel = GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oCaster); - nBonus += (nLevel + 2)/3; - - if(nBonus) - return nBonus; - - return 0; -} - -int TrueNecromancy(object oCaster, int iSpellID, string sType, int nSpellSchool = -1) -{ - int iTNLevel = GetLevelByClass(CLASS_TYPE_TRUENECRO, oCaster); - if (!iTNLevel) - return 0; - if (nSpellSchool == -1) - nSpellSchool = GetSpellSchool(iSpellID); - if (nSpellSchool != SPELL_SCHOOL_NECROMANCY) - return 0; - - if (sType == "ARCANE") - return GetLevelByTypeDivine(oCaster); // TN and arcane levels already added. - - if (sType == "DIVINE") - return GetLevelByTypeArcane(oCaster); - - return 0; -} - -int UrPriestCL(object oCaster, int nCastingClass) -{ - // Add 1/2 levels in all other casting classes except cleric - if (nCastingClass == CLASS_TYPE_UR_PRIEST) - { - int nTotal = 0; - int iFirstDivine = GetPrimaryDivineClass(oCaster); - int iBest = 0; - int iClass1 = GetClassByPosition(1, oCaster); - int iClass2 = GetClassByPosition(2, oCaster); - int iClass3 = GetClassByPosition(3, oCaster); - int iClass4 = GetClassByPosition(4, oCaster); - int iClass5 = GetClassByPosition(5, oCaster); - int iClass6 = GetClassByPosition(6, oCaster); - int iClass7 = GetClassByPosition(7, oCaster); - int iClass8 = GetClassByPosition(8, oCaster); - - int iClass1Lev = GetLevelByPosition(1, oCaster); - int iClass2Lev = GetLevelByPosition(2, oCaster); - int iClass3Lev = GetLevelByPosition(3, oCaster); - int iClass4Lev = GetLevelByPosition(4, oCaster); - int iClass5Lev = GetLevelByPosition(5, oCaster); - int iClass6Lev = GetLevelByPosition(6, oCaster); - int iClass7Lev = GetLevelByPosition(7, oCaster); - int iClass8Lev = GetLevelByPosition(8, oCaster); - - /*if (iClass1 == CLASS_TYPE_PALADIN || iClass1 == CLASS_TYPE_RANGER) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass2 == CLASS_TYPE_PALADIN || iClass2 == CLASS_TYPE_RANGER) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - if (iClass3 == CLASS_TYPE_PALADIN || iClass3 == CLASS_TYPE_RANGER) iClass3Lev = (iClass3Lev >= 4) ? (iClass3Lev / 2) : 0; - - if (iClass1 == iFirstDivine) iClass1Lev += GetDivinePRCLevels(oCaster); - if (iClass2 == iFirstDivine) iClass2Lev += GetDivinePRCLevels(oCaster); - if (iClass3 == iFirstDivine) iClass3Lev += GetDivinePRCLevels(oCaster); - - iClass1Lev += PracticedSpellcasting(oCaster, iClass1, iClass1Lev); - iClass2Lev += PracticedSpellcasting(oCaster, iClass2, iClass2Lev); - iClass3Lev += PracticedSpellcasting(oCaster, iClass3, iClass3Lev); - - if (!GetIsDivineClass(iClass1, oCaster) || iClass1 == CLASS_TYPE_UR_PRIEST) iClass1Lev = 0; - if (!GetIsDivineClass(iClass2, oCaster) || iClass2 == CLASS_TYPE_UR_PRIEST) iClass2Lev = 0; - if (!GetIsDivineClass(iClass3, oCaster) || iClass3 == CLASS_TYPE_UR_PRIEST) iClass3Lev = 0; - - nTotal += iClass1Lev + iClass2Lev + iClass3Lev; - if (DEBUG) DoDebug("UrPriestCL Divine - iClass1Lev "+IntToString(iClass1Lev)+" iClass2Lev "+IntToString(iClass2Lev)+" iClass3Lev "+IntToString(iClass3Lev));*/ - - int iFirstArcane = GetPrimaryArcaneClass(oCaster); - iClass1 = GetClassByPosition(1, oCaster); - iClass2 = GetClassByPosition(2, oCaster); - iClass3 = GetClassByPosition(3, oCaster); - iClass4 = GetClassByPosition(4, oCaster); - iClass5 = GetClassByPosition(5, oCaster); - iClass6 = GetClassByPosition(6, oCaster); - iClass7 = GetClassByPosition(7, oCaster); - iClass8 = GetClassByPosition(8, oCaster); - - iClass1Lev = GetLevelByPosition(1, oCaster); - iClass2Lev = GetLevelByPosition(2, oCaster); - iClass3Lev = GetLevelByPosition(3, oCaster); - iClass4Lev = GetLevelByPosition(4, oCaster); - iClass5Lev = GetLevelByPosition(5, oCaster); - iClass6Lev = GetLevelByPosition(6, oCaster); - iClass7Lev = GetLevelByPosition(7, oCaster); - iClass8Lev = GetLevelByPosition(8, oCaster); - - if (iClass1 == CLASS_TYPE_HEXBLADE) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass2 == CLASS_TYPE_HEXBLADE) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - if (iClass3 == CLASS_TYPE_HEXBLADE) iClass3Lev = (iClass3Lev >= 4) ? (iClass3Lev / 2) : 0; - if (iClass4 == CLASS_TYPE_HEXBLADE) iClass4Lev = (iClass4Lev >= 4) ? (iClass4Lev / 2) : 0; - if (iClass5 == CLASS_TYPE_HEXBLADE) iClass5Lev = (iClass5Lev >= 4) ? (iClass5Lev / 2) : 0; - if (iClass6 == CLASS_TYPE_HEXBLADE) iClass6Lev = (iClass6Lev >= 4) ? (iClass6Lev / 2) : 0; - if (iClass7 == CLASS_TYPE_HEXBLADE) iClass7Lev = (iClass7Lev >= 4) ? (iClass7Lev / 2) : 0; - if (iClass8 == CLASS_TYPE_HEXBLADE) iClass8Lev = (iClass8Lev >= 4) ? (iClass8Lev / 2) : 0; - - if (iClass1 == iFirstArcane) iClass1Lev += GetArcanePRCLevels(oCaster); - if (iClass2 == iFirstArcane) iClass2Lev += GetArcanePRCLevels(oCaster); - if (iClass3 == iFirstArcane) iClass3Lev += GetArcanePRCLevels(oCaster); - if (iClass4 == iFirstArcane) iClass4Lev += GetArcanePRCLevels(oCaster); - if (iClass5 == iFirstArcane) iClass5Lev += GetArcanePRCLevels(oCaster); - if (iClass6 == iFirstArcane) iClass6Lev += GetArcanePRCLevels(oCaster); - if (iClass7 == iFirstArcane) iClass7Lev += GetArcanePRCLevels(oCaster); - if (iClass8 == iFirstArcane) iClass8Lev += GetArcanePRCLevels(oCaster); - - iClass1Lev += PracticedSpellcasting(oCaster, iClass1, iClass1Lev); - iClass2Lev += PracticedSpellcasting(oCaster, iClass2, iClass2Lev); - iClass3Lev += PracticedSpellcasting(oCaster, iClass3, iClass3Lev); - iClass4Lev += PracticedSpellcasting(oCaster, iClass4, iClass4Lev); - iClass5Lev += PracticedSpellcasting(oCaster, iClass5, iClass5Lev); - iClass6Lev += PracticedSpellcasting(oCaster, iClass6, iClass5Lev); - iClass7Lev += PracticedSpellcasting(oCaster, iClass7, iClass6Lev); - iClass8Lev += PracticedSpellcasting(oCaster, iClass8, iClass7Lev); - - if (!GetIsArcaneClass(iClass1, oCaster)) iClass1Lev = 0; - if (!GetIsArcaneClass(iClass2, oCaster)) iClass2Lev = 0; - if (!GetIsArcaneClass(iClass3, oCaster)) iClass3Lev = 0; - if (!GetIsArcaneClass(iClass4, oCaster)) iClass4Lev = 0; - if (!GetIsArcaneClass(iClass5, oCaster)) iClass5Lev = 0; - if (!GetIsArcaneClass(iClass6, oCaster)) iClass6Lev = 0; - if (!GetIsArcaneClass(iClass7, oCaster)) iClass7Lev = 0; - if (!GetIsArcaneClass(iClass8, oCaster)) iClass8Lev = 0; - - - nTotal += iClass1Lev + iClass2Lev + iClass3Lev + iClass4Lev + iClass5Lev + iClass6Lev + iClass7Lev + iClass8Lev; - - if (DEBUG) DoDebug("UrPriestCL Arcane - iClass1Lev "+IntToString(iClass1Lev)+" iClass2Lev " - +IntToString(iClass2Lev)+" iClass3Lev " - +IntToString(iClass3Lev)+" iClass4Lev " - +IntToString(iClass4Lev)+" iClass5Lev " - +IntToString(iClass5Lev)+" iClass6Lev " - +IntToString(iClass6Lev)+" iClass7Lev " - +IntToString(iClass7Lev)+" iClass8Lev " - +IntToString(iClass8Lev)); - - if (DEBUG) DoDebug("UrPriestCL Total - nTotal "+IntToString(nTotal)); - return nTotal/2; - } - return 0; -} - -int BlighterCL(object oCaster, int nCastingClass) -{ - if (nCastingClass == CLASS_TYPE_BLIGHTER) - { - int nBonus = GetLevelByClass(CLASS_TYPE_DRUID, oCaster); - return nBonus; - } - return 0; -} - -int ReserveFeatCL(object oCaster, int iSpellId) -{ - int nSpellSchool = GetSpellSchool(iSpellId); - int nCLBonus = 0; - - if (GetLocalInt(oCaster, "ReserveFeatsRunning") == TRUE) - { - if (GetHasDescriptor(iSpellId, DESCRIPTOR_ACID) && GetHasFeat(FEAT_ACIDIC_SPLATTER, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_FIRE) && GetHasFeat(FEAT_FIERY_BURST, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_COLD) && GetHasFeat(FEAT_WINTERS_BLAST, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_ELECTRICITY) && GetHasFeat(FEAT_STORM_BOLT, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_SONIC) && GetHasFeat(FEAT_CLAP_OF_THUNDER, oCaster)) nCLBonus += 1; - if (GetIsOfSubschool(iSpellId, SUBSCHOOL_HEALING) && GetHasFeat(FEAT_TOUCH_OF_HEALING, oCaster)) nCLBonus += 1; - if (GetIsOfSubschool(iSpellId, SUBSCHOOL_TELEPORTATION) && GetHasFeat(FEAT_DIMENSIONAL_JAUNT, oCaster)) nCLBonus += 1; - if (nSpellSchool == SPELL_SCHOOL_ABJURATION && GetHasFeat(FEAT_MYSTIC_BACKLASH, oCaster)) nCLBonus += 1; - if (nSpellSchool == SPELL_SCHOOL_NECROMANCY && GetHasFeat(FEAT_SICKENING_GRASP, oCaster)) nCLBonus += 1; - if (GetIsFromDomain(iSpellId, "wardom") && GetHasFeat(FEAT_HOLY_WARRIOR, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_EARTH) && GetHasFeat(FEAT_CLUTCH_OF_EARTH, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_AIR) && GetHasFeat(FEAT_BORNE_ALOFT, oCaster)) nCLBonus += 1; - if ((nSpellSchool == SPELL_SCHOOL_ABJURATION) && GetHasFeat(FEAT_PROTECTIVE_WARD, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_DARKNESS) && GetHasFeat(FEAT_SHADOW_VEIL, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_LIGHT) && GetHasFeat(FEAT_SUNLIGHT_EYES, oCaster)) nCLBonus += 1; - if ((nSpellSchool == SPELL_SCHOOL_ENCHANTMENT) && GetHasFeat(FEAT_TOUCH_OF_DISTRACTION, oCaster)) nCLBonus += 1; - if (GetIsFromDomain(iSpellId, "dethdom") && GetHasFeat(FEAT_CHARNEL_MIASMA, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_WATER) && GetHasFeat(FEAT_DROWNING_GLANCE, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_FORCE) && GetHasFeat(FEAT_INVISIBLE_NEEDLE, oCaster)) nCLBonus += 1; - if (GetIsOfSubschool(iSpellId, SUBSCHOOL_SUMMONING) && GetHasFeat(FEAT_SUMMON_ELEMENTAL, oCaster)) nCLBonus += 1; - if (GetIsOfSubschool(iSpellId, SUBSCHOOL_SUMMONING) && GetHasFeat(FEAT_DIMENSIONAL_REACH, oCaster)) nCLBonus += 1; - if (GetHasDescriptor(iSpellId, DESCRIPTOR_AIR) && GetHasFeat(FEAT_HURRICANE_BREATH, oCaster)) nCLBonus += 1; - if (GetIsOfSubschool(iSpellId, SUBSCHOOL_POLYMORPH) && GetHasFeat(FEAT_MINOR_SHAPESHIFT, oCaster)) nCLBonus += 1; - if (GetIsOfSubschool(iSpellId, SUBSCHOOL_GLAMER) && GetHasFeat(FEAT_FACECHANGER, oCaster)) nCLBonus += 1; - return nCLBonus; - } - else return 0; -} - -int GetLevelByTypeArcane(object oCaster = OBJECT_SELF) -{ - int iFirstArcane = GetPrimaryArcaneClass(oCaster); - int iBest = 0; - int iClass1 = GetClassByPosition(1, oCaster); - int iClass2 = GetClassByPosition(2, oCaster); - int iClass3 = GetClassByPosition(3, oCaster); - int iClass4 = GetClassByPosition(4, oCaster); - int iClass5 = GetClassByPosition(5, oCaster); - int iClass6 = GetClassByPosition(6, oCaster); - int iClass7 = GetClassByPosition(8, oCaster); - int iClass8 = GetClassByPosition(8, oCaster); - - int iClass1Lev = GetLevelByPosition(1, oCaster); - int iClass2Lev = GetLevelByPosition(2, oCaster); - int iClass3Lev = GetLevelByPosition(3, oCaster); - int iClass4Lev = GetLevelByPosition(4, oCaster); - int iClass5Lev = GetLevelByPosition(5, oCaster); - int iClass6Lev = GetLevelByPosition(6, oCaster); - int iClass7Lev = GetLevelByPosition(7, oCaster); - int iClass8Lev = GetLevelByPosition(8, oCaster); - - if (iClass1 == CLASS_TYPE_HEXBLADE) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass2 == CLASS_TYPE_HEXBLADE) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - if (iClass3 == CLASS_TYPE_HEXBLADE) iClass3Lev = (iClass3Lev >= 4) ? (iClass3Lev / 2) : 0; - if (iClass4 == CLASS_TYPE_HEXBLADE) iClass4Lev = (iClass4Lev >= 4) ? (iClass4Lev / 2) : 0; - if (iClass5 == CLASS_TYPE_HEXBLADE) iClass5Lev = (iClass5Lev >= 4) ? (iClass5Lev / 2) : 0; - if (iClass6 == CLASS_TYPE_HEXBLADE) iClass6Lev = (iClass6Lev >= 4) ? (iClass6Lev / 2) : 0; - if (iClass7 == CLASS_TYPE_HEXBLADE) iClass7Lev = (iClass7Lev >= 4) ? (iClass7Lev / 2) : 0; - if (iClass8 == CLASS_TYPE_HEXBLADE) iClass8Lev = (iClass8Lev >= 4) ? (iClass8Lev / 2) : 0; - - if (iClass1 == iFirstArcane) iClass1Lev += GetArcanePRCLevels(oCaster); - if (iClass2 == iFirstArcane) iClass2Lev += GetArcanePRCLevels(oCaster); - if (iClass3 == iFirstArcane) iClass3Lev += GetArcanePRCLevels(oCaster); - if (iClass4 == iFirstArcane) iClass4Lev += GetArcanePRCLevels(oCaster); - if (iClass5 == iFirstArcane) iClass5Lev += GetArcanePRCLevels(oCaster); - if (iClass6 == iFirstArcane) iClass6Lev += GetArcanePRCLevels(oCaster); - if (iClass7 == iFirstArcane) iClass7Lev += GetArcanePRCLevels(oCaster); - if (iClass8 == iFirstArcane) iClass8Lev += GetArcanePRCLevels(oCaster); - - iClass1Lev += PracticedSpellcasting(oCaster, iClass1, iClass1Lev); - iClass2Lev += PracticedSpellcasting(oCaster, iClass2, iClass2Lev); - iClass3Lev += PracticedSpellcasting(oCaster, iClass3, iClass3Lev); - iClass4Lev += PracticedSpellcasting(oCaster, iClass4, iClass4Lev); - iClass5Lev += PracticedSpellcasting(oCaster, iClass5, iClass5Lev); - iClass6Lev += PracticedSpellcasting(oCaster, iClass6, iClass5Lev); - iClass7Lev += PracticedSpellcasting(oCaster, iClass7, iClass6Lev); - iClass8Lev += PracticedSpellcasting(oCaster, iClass8, iClass7Lev); - - if (!GetIsArcaneClass(iClass1, oCaster)) iClass1Lev = 0; - if (!GetIsArcaneClass(iClass2, oCaster)) iClass2Lev = 0; - if (!GetIsArcaneClass(iClass3, oCaster)) iClass3Lev = 0; - if (!GetIsArcaneClass(iClass4, oCaster)) iClass4Lev = 0; - if (!GetIsArcaneClass(iClass5, oCaster)) iClass5Lev = 0; - if (!GetIsArcaneClass(iClass6, oCaster)) iClass6Lev = 0; - if (!GetIsArcaneClass(iClass7, oCaster)) iClass7Lev = 0; - if (!GetIsArcaneClass(iClass8, oCaster)) iClass8Lev = 0; - - if (iClass1Lev > iBest) iBest = iClass1Lev; - if (iClass2Lev > iBest) iBest = iClass2Lev; - if (iClass3Lev > iBest) iBest = iClass3Lev; - if (iClass4Lev > iBest) iBest = iClass4Lev; - if (iClass5Lev > iBest) iBest = iClass5Lev; - if (iClass6Lev > iBest) iBest = iClass6Lev; - if (iClass7Lev > iBest) iBest = iClass7Lev; - if (iClass8Lev > iBest) iBest = iClass8Lev; - - return iBest; -} - -int GetLevelByTypeDivine(object oCaster = OBJECT_SELF) -{ - int iFirstDivine = GetPrimaryDivineClass(oCaster); - int iBest = 0; - int iClass1 = GetClassByPosition(1, oCaster); - int iClass2 = GetClassByPosition(2, oCaster); - int iClass3 = GetClassByPosition(3, oCaster); - int iClass4 = GetClassByPosition(4, oCaster); - int iClass5 = GetClassByPosition(5, oCaster); - int iClass6 = GetClassByPosition(6, oCaster); - int iClass7 = GetClassByPosition(8, oCaster); - int iClass8 = GetClassByPosition(8, oCaster); - - int iClass1Lev = GetLevelByPosition(1, oCaster); - int iClass2Lev = GetLevelByPosition(2, oCaster); - int iClass3Lev = GetLevelByPosition(3, oCaster); - int iClass4Lev = GetLevelByPosition(4, oCaster); - int iClass5Lev = GetLevelByPosition(5, oCaster); - int iClass6Lev = GetLevelByPosition(6, oCaster); - int iClass7Lev = GetLevelByPosition(7, oCaster); - int iClass8Lev = GetLevelByPosition(8, oCaster); - - if (iClass1 == CLASS_TYPE_PALADIN || iClass1 == CLASS_TYPE_RANGER) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass2 == CLASS_TYPE_PALADIN || iClass2 == CLASS_TYPE_RANGER) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - if (iClass3 == CLASS_TYPE_PALADIN || iClass3 == CLASS_TYPE_RANGER) iClass3Lev = (iClass3Lev >= 4) ? (iClass3Lev / 2) : 0; - if (iClass4 == CLASS_TYPE_PALADIN || iClass4 == CLASS_TYPE_RANGER) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass5 == CLASS_TYPE_PALADIN || iClass5 == CLASS_TYPE_RANGER) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - if (iClass6 == CLASS_TYPE_PALADIN || iClass6 == CLASS_TYPE_RANGER) iClass3Lev = (iClass3Lev >= 4) ? (iClass3Lev / 2) : 0; - if (iClass7 == CLASS_TYPE_PALADIN || iClass7 == CLASS_TYPE_RANGER) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass8 == CLASS_TYPE_PALADIN || iClass8 == CLASS_TYPE_RANGER) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - - if (iClass1 == iFirstDivine) iClass1Lev += GetDivinePRCLevels(oCaster); - if (iClass2 == iFirstDivine) iClass2Lev += GetDivinePRCLevels(oCaster); - if (iClass3 == iFirstDivine) iClass3Lev += GetDivinePRCLevels(oCaster); - if (iClass4 == iFirstDivine) iClass4Lev += GetDivinePRCLevels(oCaster); - if (iClass5 == iFirstDivine) iClass5Lev += GetDivinePRCLevels(oCaster); - if (iClass6 == iFirstDivine) iClass6Lev += GetDivinePRCLevels(oCaster); - if (iClass7 == iFirstDivine) iClass7Lev += GetDivinePRCLevels(oCaster); - if (iClass8 == iFirstDivine) iClass8Lev += GetDivinePRCLevels(oCaster); - - iClass1Lev += PracticedSpellcasting(oCaster, iClass1, iClass1Lev); - iClass2Lev += PracticedSpellcasting(oCaster, iClass2, iClass2Lev); - iClass3Lev += PracticedSpellcasting(oCaster, iClass3, iClass3Lev); - iClass4Lev += PracticedSpellcasting(oCaster, iClass4, iClass4Lev); - iClass5Lev += PracticedSpellcasting(oCaster, iClass5, iClass5Lev); - iClass6Lev += PracticedSpellcasting(oCaster, iClass6, iClass5Lev); - iClass7Lev += PracticedSpellcasting(oCaster, iClass7, iClass6Lev); - iClass8Lev += PracticedSpellcasting(oCaster, iClass8, iClass7Lev); - - if (!GetIsDivineClass(iClass1, oCaster)) iClass1Lev = 0; - if (!GetIsDivineClass(iClass2, oCaster)) iClass2Lev = 0; - if (!GetIsDivineClass(iClass3, oCaster)) iClass3Lev = 0; - if (!GetIsDivineClass(iClass4, oCaster)) iClass4Lev = 0; - if (!GetIsDivineClass(iClass5, oCaster)) iClass5Lev = 0; - if (!GetIsDivineClass(iClass6, oCaster)) iClass6Lev = 0; - if (!GetIsDivineClass(iClass7, oCaster)) iClass7Lev = 0; - if (!GetIsDivineClass(iClass8, oCaster)) iClass8Lev = 0; - - if (iClass1Lev > iBest) iBest = iClass1Lev; - if (iClass2Lev > iBest) iBest = iClass2Lev; - if (iClass3Lev > iBest) iBest = iClass3Lev; - if (iClass4Lev > iBest) iBest = iClass4Lev; - if (iClass5Lev > iBest) iBest = iClass5Lev; - if (iClass6Lev > iBest) iBest = iClass6Lev; - if (iClass7Lev > iBest) iBest = iClass7Lev; - if (iClass8Lev > iBest) iBest = iClass8Lev; - - return iBest; -} - -//:: Test Void -//void main (){} \ No newline at end of file diff --git a/trunk/include/prc_inc_clsfunc.nss b/trunk/include/prc_inc_clsfunc.nss deleted file mode 100644 index 89c26dc8..00000000 --- a/trunk/include/prc_inc_clsfunc.nss +++ /dev/null @@ -1,1618 +0,0 @@ -/* - Class functions. - This scripts holds all functions used for classes in includes. - This prevents us from having one include for each class or set of classes. - - Stratovarius -*/ - -//:: Updated for .35 by Jaysyn 2023/03/10 - -////////////////Begin Generic//////////////// - -// Function Definitions: - -// Include Files: -#include "prc_inc_spells" -//#include "prc_alterations" -//#include "prcsp_engine" -//#include "prc_inc_function" -//#include "prc_x2_itemprop" -//#include "prc_class_const" -//#include "prc_feat_const" -//#include "prc_ipfeat_const" -//#include "inc_utility" -// -//#include "pnp_shft_poly" -//#include "x2_inc_spellhook" -//#include "prc_inc_combat" -//#include "prc_inc_sp_tch" - -////////////////End Generic//////////////// - -////////////////Begin Drunken Master////////////////////// - - -// Function Definitions: - -// Searches oPC's inventory and finds the first valid alcoholic beverage container -// (empty) and returns TRUE if a proper container was found. This function takes -// action and returns a boolean. -int UseBottle(object oPC); - -// Searches oPC's inventory for an alcoholic beverage and if one is found it's -// destroyed and replaced by an empty container. This function is only used in -// the Breath of Fire spell script. -int UseAlcohol(object oPC = OBJECT_SELF); - -// Removes all Alcohol effects for oTarget. Used in B o Flame. -void RemoveAlcoholEffects(object oTarget = OBJECT_SELF); - -// Creates an empty bottle on oPC. -// sTag: the tag of the alcoholic beverage used (ale, spirits, wine) -void CreateBottleOnObject(object oPC, string sTag); - - -// Applies Drunk Like a Demno effects -void DrunkLikeDemon(); - -// Add the non-drunken master drinking effects. -void MakeDrunk(int nSpellID); - -// Have the drunken master say one of 6 phrases. -void DrunkenMasterSpeakString(); - -// Creates an empty bottle on oPC. -// nBeverage: the spell id of the alcoholic beverage used (ale, spirits, wine) -void DrunkenMasterCreateEmptyBottle(int nSpellID); - -// Determines the DC needed to save against the cast spell-like ability -// replace PRCGetSaveDC -int GetSpellDCSLA(object oCaster, int iSpelllvl,int iAbi = ABILITY_WISDOM); - -void DoArchmageHeirophantSLA(object oPC, object oTarget, location lTarget, int nSLAID); - -// Functions: -int UseBottle(object oPC) -{ - object oItem = GetFirstItemInInventory(oPC); - //search oPC for a bottle: - string sTag; - while(oItem != OBJECT_INVALID) - { - sTag = GetTag(oItem); - if(sTag == "NW_IT_THNMISC001" - || sTag == "NW_IT_THNMISC002" - || sTag == "NW_IT_THNMISC003" - || sTag == "NW_IT_THNMISC004") - { - SetPlotFlag(oItem, FALSE); - DestroyObject(oItem); - return TRUE; - } - else - oItem = GetNextItemInInventory(); - } - return FALSE; -} - -int UseAlcohol(object oPC = OBJECT_SELF) -{ - object oItem = GetFirstItemInInventory(oPC); - //search oPC for alcohol: - string sTag = GetTag(oItem); - while(oItem != OBJECT_INVALID) - { - if(sTag == "NW_IT_MPOTION021" - || sTag == "NW_IT_MPOTION022" - || sTag == "NW_IT_MPOTION023" - || sTag == "DragonsBreath") - { - SetPlotFlag(oItem, FALSE); - if(GetItemStackSize(oItem) > 1) - { - SetItemStackSize(oItem, GetItemStackSize(oItem) - 1); - // Create an Empty Bottle: - CreateBottleOnObject(oPC, sTag); - return TRUE; - } - else - { - DestroyObject(oItem); - // Create an Empty Bottle: - CreateBottleOnObject(oPC, sTag); - return TRUE; - } - } - else - oItem = GetNextItemInInventory(); - } - return FALSE; -} - -void CreateBottleOnObject(object oPC, string sTag) -{ - if(sTag == "NW_IT_MPOTION021") // Ale - { - CreateItemOnObject("nw_it_thnmisc002", oPC); - } - else if(sTag == "NW_IT_MPOTION022") // Spirits - { - CreateItemOnObject("nw_it_thnmisc003", oPC); - } - else if(sTag == "NW_IT_MPOTION023") // Wine - { - CreateItemOnObject("nw_it_thnmisc004", oPC); - } - else // Other beverage - { - CreateItemOnObject("nw_it_thnmisc001", oPC); - } -} - -int GetIsDrunk(object oTarget = OBJECT_SELF) -{ - return GetHasSpellEffect(406, oTarget) - || GetHasSpellEffect(407, oTarget) - || GetHasSpellEffect(408, oTarget); -} - -void RemoveAlcoholEffects(object oTarget = OBJECT_SELF) -{ - PRCRemoveSpellEffects(406, OBJECT_SELF, oTarget); - PRCRemoveSpellEffects(407, OBJECT_SELF, oTarget); - PRCRemoveSpellEffects(408, OBJECT_SELF, oTarget); -} - -void DrunkenRage() -{ - float fDuration = GetLevelByClass(CLASS_TYPE_DRUNKEN_MASTER) > 9 ? HoursToSeconds(3) : HoursToSeconds(1); - - effect eLink = EffectLinkEffects(EffectAbilityIncrease(ABILITY_STRENGTH, 4), EffectAbilityIncrease(ABILITY_CONSTITUTION, 4)); - eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2)); - eLink = EffectLinkEffects(eLink, EffectACDecrease(2)); - eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_BLUR)); - eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_AURA_FIRE)); - eLink = ExtraordinaryEffect(eLink); - - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, fDuration); - - FloatingTextStringOnCreature("Drunken Rage Activated", OBJECT_SELF); -} - -void DrunkLikeDemon() -{ - // A Drunken Master has had a drink. Add effects: - effect eLink = EffectLinkEffects(EffectAbilityIncrease(ABILITY_STRENGTH, 1), EffectAbilityIncrease(ABILITY_CONSTITUTION, 1)); - eLink = EffectLinkEffects(eLink, EffectAbilityDecrease(ABILITY_WISDOM, 1)); - eLink = EffectLinkEffects(eLink, EffectAbilityDecrease(ABILITY_INTELLIGENCE, 1)); - eLink = EffectLinkEffects(eLink, EffectAbilityDecrease(ABILITY_DEXTERITY, 1)); - eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_BLUR)); - - //run checks to see if Dex Modifier will be changed: - if(!(GetAbilityModifier(ABILITY_DEXTERITY) % 2)) - { - //restore AC, Ref save and Tumble to previous values - eLink = EffectLinkEffects(eLink, EffectACIncrease(1)); - eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 1)); - eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_TUMBLE, 1)); - } - eLink = ExtraordinaryEffect(eLink); - - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, HoursToSeconds(1)); - - FloatingTextStringOnCreature("You are Drunk Like a Demon", OBJECT_SELF); -} - -void MakeDrunk(int nSpellID) -{ - if(Random(100) < 40) - AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING)); - else - AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_DRUNK)); - - int nPoints; - switch(nSpellID) - { - case 406: nPoints = 1; break;//Ale - case 407: nPoints = 2; break;//Wine - case 408: nPoints = 3; break;//Spirits - } - - //ApplyAbilityDamage(oTarget, ABILITY_INTELLIGENCE, nPoints, DURATION_TYPE_TEMPORARY, TRUE, 60.0); - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectAbilityDecrease(ABILITY_INTELLIGENCE, nPoints)), OBJECT_SELF, 60.0); - AssignCommand(OBJECT_SELF, ActionSpeakStringByStrRef(10499)); -} - -void DrunkenMasterSpeakString() -{ - switch(d6()) - { - case 1: AssignCommand(OBJECT_SELF, ActionSpeakString("Now that's the stuff!")); break; - case 2: AssignCommand(OBJECT_SELF, ActionSpeakString("That one really hit the spot!")); break; - case 3: AssignCommand(OBJECT_SELF, ActionSpeakString("That should keep me warm!")); break; - case 4: AssignCommand(OBJECT_SELF, ActionSpeakString("Good stuff!")); break; - case 5: AssignCommand(OBJECT_SELF, ActionSpeakString("Bless the Wine Gods!")); break; - case 6: AssignCommand(OBJECT_SELF, ActionSpeakString("Just what I needed!")); break; - } -} - -void DrunkenMasterCreateEmptyBottle(int nSpellID) -{ - switch(nSpellID) - { - case 406: CreateItemOnObject("nw_it_thnmisc002", OBJECT_SELF); break;//Ale - case 407: CreateItemOnObject("nw_it_thnmisc004", OBJECT_SELF); break;//Wine - case 408: CreateItemOnObject("nw_it_thnmisc003", OBJECT_SELF); break;//Spirits - default: CreateItemOnObject("nw_it_thnmisc001", OBJECT_SELF); break;//Other - } -} - -////////////////End Drunken Master////////////////// - -////////////////Begin Samurai////////////////// - -// This function is probably utterly broken: the match found variable is not reset in the loop and the returned value will be equal to the last match - Ornedan -int GetPropertyValue(object oWeapon, int iType, int iSubType = -1, int bDebug = FALSE); - -int GetPropertyValue(object oWeapon, int iType, int iSubType = -1, int bDebug = FALSE) -{ - int bReturn = -1; - if(oWeapon == OBJECT_INVALID){return FALSE;} - int bMatch = FALSE; - if (GetItemHasItemProperty(oWeapon, iType)) - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("It has the property."));} - itemproperty ip = GetFirstItemProperty(oWeapon); - while(GetIsItemPropertyValid(ip)) - { - if(GetItemPropertyType(ip) == iType) - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Again..."));} - bMatch = TRUE; - if (iSubType > -1) - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Subtype Required."));} - if(GetItemPropertySubType(ip) != iSubType) - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Subtype wrong."));} - bMatch = FALSE; - } - else - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Subtype Correct."));} - } - } - } - if (bMatch) - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Match found."));} - if (GetItemPropertyCostTableValue(ip) > -1) - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Cost value found, returning."));} - bReturn = GetItemPropertyCostTableValue(ip); - } - else - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("No cost value for property, returning TRUE."));} - bReturn = 1; - } - } - else - { - if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Match not found."));} - } - ip = GetNextItemProperty(oWeapon); - } - } - return bReturn; -} - - -void WeaponUpgradeVisual(); - -object GetSamuraiToken(object oSamurai); - -void WeaponUpgradeVisual() -{ - object oPC = GetPCSpeaker(); - int iCost = GetLocalInt(oPC, "CODI_SAM_WEAPON_COST"); - object oToken = GetSamuraiToken(oPC); - int iToken = StringToInt(GetTag(oToken)); - int iGold = GetGold(oPC); - if(iGold + iToken < iCost) - { - SendMessageToPC(oPC, "You sense the gods are angered!"); - AdjustAlignment(oPC, ALIGNMENT_CHAOTIC, 25, FALSE); - object oWeapon = GetItemPossessedBy(oPC, "codi_sam_mw"); - DestroyObject(oWeapon); - return; - } - else if(iToken <= iCost) - { - iCost = iCost - iToken; - DestroyObject(oToken); - TakeGoldFromCreature(iCost, oPC, TRUE); - } - else if (iToken > iCost) - { - object oNewToken = CopyObject(oToken, GetLocation(oPC), oPC, IntToString(iToken - iCost)); - DestroyObject(oToken); - } - effect eVis = EffectVisualEffect(VFX_FNF_DISPEL_DISJUNCTION); - AssignCommand(oPC, ClearAllActions()); - AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,6.0)); - AssignCommand(oPC, ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY2)); - DelayCommand(0.1, SetCommandable(FALSE, oPC)); - DelayCommand(6.5, SetCommandable(TRUE, oPC)); - DelayCommand(5.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC))); -} - -object GetSamuraiToken(object oSamurai) -{ - object oItem = GetFirstItemInInventory(oSamurai); - while(oItem != OBJECT_INVALID) - { - if(GetResRef(oItem) == "codi_sam_token") - { - return oItem; - } - oItem = GetNextItemInInventory(oSamurai); - } - return OBJECT_INVALID; -} - - - - -////////////////End Samurai////////////////// - -////////////////Begin Vile Feat////////////////// - - -int Vile_Feat(int iTypeWeap) -{ - switch(iTypeWeap) - { - case BASE_ITEM_BASTARDSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_BASTARDSWORD); - case BASE_ITEM_BATTLEAXE: return GetHasFeat(FEAT_VILE_MARTIAL_BATTLEAXE); - case BASE_ITEM_CLUB: return GetHasFeat(FEAT_VILE_MARTIAL_CLUB); - case BASE_ITEM_DAGGER: return GetHasFeat(FEAT_VILE_MARTIAL_DAGGER); - case BASE_ITEM_DART: return GetHasFeat(FEAT_VILE_MARTIAL_DART); - case BASE_ITEM_DIREMACE: return GetHasFeat(FEAT_VILE_MARTIAL_DIREMACE); - case BASE_ITEM_DOUBLEAXE: return GetHasFeat(FEAT_VILE_MARTIAL_DOUBLEAXE); - case BASE_ITEM_DWARVENWARAXE: return GetHasFeat(FEAT_VILE_MARTIAL_DWAXE); - case BASE_ITEM_GREATAXE: return GetHasFeat(FEAT_VILE_MARTIAL_GREATAXE); - case BASE_ITEM_GREATSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_GREATSWORD); - case BASE_ITEM_HALBERD: return GetHasFeat(FEAT_VILE_MARTIAL_HALBERD); - case BASE_ITEM_HANDAXE: return GetHasFeat(FEAT_VILE_MARTIAL_HANDAXE); - case BASE_ITEM_HEAVYCROSSBOW: return GetHasFeat(FEAT_VILE_MARTIAL_HEAVYCROSSBOW); - case BASE_ITEM_HEAVYFLAIL: return GetHasFeat(FEAT_VILE_MARTIAL_HEAVYFLAIL); - case BASE_ITEM_KAMA: return GetHasFeat(FEAT_VILE_MARTIAL_KAMA); - case BASE_ITEM_KATANA: return GetHasFeat(FEAT_VILE_MARTIAL_KATANA); - case BASE_ITEM_KUKRI: return GetHasFeat(FEAT_VILE_MARTIAL_KUKRI); - case BASE_ITEM_LIGHTCROSSBOW: return GetHasFeat(FEAT_VILE_MARTIAL_LIGHTCROSSBOW); - case BASE_ITEM_LIGHTFLAIL: return GetHasFeat(FEAT_VILE_MARTIAL_LIGHTFLAIL); - case BASE_ITEM_LIGHTHAMMER: return GetHasFeat(FEAT_VILE_MARTIAL_LIGHTHAMMER); - case BASE_ITEM_LIGHTMACE: return GetHasFeat(FEAT_VILE_MARTIAL_MACE); - case BASE_ITEM_LONGBOW: return GetHasFeat(FEAT_VILE_MARTIAL_LONGBOW); - case BASE_ITEM_LONGSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_LONGSWORD); - case BASE_ITEM_MORNINGSTAR: return GetHasFeat(FEAT_VILE_MARTIAL_MORNINGSTAR); - case BASE_ITEM_QUARTERSTAFF: return GetHasFeat(FEAT_VILE_MARTIAL_QUARTERSTAFF); - case BASE_ITEM_RAPIER: return GetHasFeat(FEAT_VILE_MARTIAL_RAPIER); - case BASE_ITEM_SCIMITAR: return GetHasFeat(FEAT_VILE_MARTIAL_SCIMITAR); - case BASE_ITEM_SCYTHE: return GetHasFeat(FEAT_VILE_MARTIAL_SCYTHE); - case BASE_ITEM_SHORTBOW: return GetHasFeat(FEAT_VILE_MARTIAL_SHORTBOW); - case BASE_ITEM_SHORTSPEAR: return GetHasFeat(FEAT_VILE_MARTIAL_SPEAR); - case BASE_ITEM_SHORTSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_SHORTSWORD); - case BASE_ITEM_SHURIKEN: return GetHasFeat(FEAT_VILE_MARTIAL_SHURIKEN); - case BASE_ITEM_SLING: return GetHasFeat(FEAT_VILE_MARTIAL_SLING); - case BASE_ITEM_SICKLE: return GetHasFeat(FEAT_VILE_MARTIAL_SICKLE); - case BASE_ITEM_TWOBLADEDSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_TWOBLADED); - case BASE_ITEM_WARHAMMER: return GetHasFeat(FEAT_VILE_MARTIAL_WARHAMMER); - case BASE_ITEM_WHIP: return GetHasFeat(FEAT_VILE_MARTIAL_WHIP); - case BASE_ITEM_TRIDENT: return GetHasFeat(FEAT_VILE_MARTIAL_TRIDENT); - - //new items - case BASE_ITEM_ELVEN_LIGHTBLADE: return (GetHasFeat(FEAT_VILE_MARTIAL_SHORTSWORD) || GetHasFeat(FEAT_VILE_MARTIAL_RAPIER)); - case BASE_ITEM_ELVEN_THINBLADE: return (GetHasFeat(FEAT_VILE_MARTIAL_LONGSWORD) || GetHasFeat(FEAT_VILE_MARTIAL_RAPIER)); - case BASE_ITEM_ELVEN_COURTBLADE: return GetHasFeat(FEAT_VILE_MARTIAL_GREATSWORD); - } - - return FALSE; - -} - -////////////////End Vile Feat////////////////// - -////////////////Begin Soul Inc////////////////// - -const int IPRP_CONST_ONHIT_DURATION_5_PERCENT_1_ROUNDS = 20; - -int Sanctify_Feat(int iTypeWeap) -{ - switch(iTypeWeap) - { - case BASE_ITEM_BASTARDSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_BASTARDSWORD); - case BASE_ITEM_BATTLEAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_BATTLEAXE); - case BASE_ITEM_CLUB: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_CLUB); - case BASE_ITEM_DAGGER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DAGGER); - case BASE_ITEM_DART: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DART); - case BASE_ITEM_DIREMACE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DIREMACE); - case BASE_ITEM_DOUBLEAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DOUBLEAXE); - case BASE_ITEM_DWARVENWARAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DWAXE); - case BASE_ITEM_GREATAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_GREATAXE); - case BASE_ITEM_GREATSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_GREATSWORD); - case BASE_ITEM_HALBERD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HALBERD); - case BASE_ITEM_HANDAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HANDAXE); - case BASE_ITEM_HEAVYCROSSBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HEAVYCROSSBOW); - case BASE_ITEM_HEAVYFLAIL: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HEAVYFLAIL); - case BASE_ITEM_KAMA: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_KAMA); - case BASE_ITEM_KATANA: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_KATANA); - case BASE_ITEM_KUKRI: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_KUKRI); - case BASE_ITEM_LIGHTCROSSBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LIGHTCROSSBOW); - case BASE_ITEM_LIGHTFLAIL: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LIGHTFLAIL); - case BASE_ITEM_LIGHTHAMMER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LIGHTHAMMER); - case BASE_ITEM_LIGHTMACE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_MACE); - case BASE_ITEM_LONGBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGBOW); - case BASE_ITEM_LONGSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGSWORD); - case BASE_ITEM_MORNINGSTAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_MORNINGSTAR); - case BASE_ITEM_QUARTERSTAFF: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF); - case BASE_ITEM_RAPIER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER); - case BASE_ITEM_SCIMITAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SCIMITAR); - case BASE_ITEM_SCYTHE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SCYTHE); - case BASE_ITEM_SHORTBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHORTBOW); - case BASE_ITEM_SHORTSPEAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SPEAR); - case BASE_ITEM_SHORTSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHORTSWORD); - case BASE_ITEM_SHURIKEN: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHURIKEN); - case BASE_ITEM_SLING: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SLING); - case BASE_ITEM_SICKLE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SICKLE); - case BASE_ITEM_TWOBLADEDSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_TWOBLADED); - case BASE_ITEM_WARHAMMER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_WARHAMMER); - case BASE_ITEM_WHIP: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_WHIP); - case BASE_ITEM_TRIDENT: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_TRIDENT); - - //new items - case BASE_ITEM_ELVEN_LIGHTBLADE: return (GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHORTSWORD) || GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER)); - case BASE_ITEM_ELVEN_THINBLADE: return (GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGSWORD) || GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER)); - case BASE_ITEM_ELVEN_COURTBLADE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_GREATSWORD); - } - - return FALSE; -} - -int DamageConv(int iMonsDmg) -{ - - switch(iMonsDmg) - { - case IP_CONST_MONSTERDAMAGE_1d4: return 1; - case IP_CONST_MONSTERDAMAGE_1d6: return 2; - case IP_CONST_MONSTERDAMAGE_1d8: return 3; - case IP_CONST_MONSTERDAMAGE_1d10: return 4; - case IP_CONST_MONSTERDAMAGE_1d12: return 5; - case IP_CONST_MONSTERDAMAGE_1d20: return 6; - - case IP_CONST_MONSTERDAMAGE_2d4: return 10; - case IP_CONST_MONSTERDAMAGE_2d6: return 11; - case IP_CONST_MONSTERDAMAGE_2d8: return 12; - case IP_CONST_MONSTERDAMAGE_2d10: return 13; - case IP_CONST_MONSTERDAMAGE_2d12: return 14; - case IP_CONST_MONSTERDAMAGE_2d20: return 15; - - case IP_CONST_MONSTERDAMAGE_3d4: return 20; - case IP_CONST_MONSTERDAMAGE_3d6: return 21; - case IP_CONST_MONSTERDAMAGE_3d8: return 22; - case IP_CONST_MONSTERDAMAGE_3d10: return 23; - case IP_CONST_MONSTERDAMAGE_3d12: return 24; - case IP_CONST_MONSTERDAMAGE_3d20: return 25; - - - } - - - return 0; -} - -int ConvMonsterDmg(int iMonsDmg) -{ - - switch(iMonsDmg) - { - case 1: return IP_CONST_MONSTERDAMAGE_1d4; - case 2: return IP_CONST_MONSTERDAMAGE_1d6; - case 3: return IP_CONST_MONSTERDAMAGE_1d8; - case 4: return IP_CONST_MONSTERDAMAGE_1d10; - case 5: return IP_CONST_MONSTERDAMAGE_1d12; - case 6: return IP_CONST_MONSTERDAMAGE_1d20; - case 10: return IP_CONST_MONSTERDAMAGE_2d4; - case 11: return IP_CONST_MONSTERDAMAGE_2d6; - case 12: return IP_CONST_MONSTERDAMAGE_2d8; - case 13: return IP_CONST_MONSTERDAMAGE_2d10; - case 14: return IP_CONST_MONSTERDAMAGE_2d12; - case 15: return IP_CONST_MONSTERDAMAGE_2d20; - case 20: return IP_CONST_MONSTERDAMAGE_3d4; - case 21: return IP_CONST_MONSTERDAMAGE_3d6; - case 22: return IP_CONST_MONSTERDAMAGE_3d8; - case 23: return IP_CONST_MONSTERDAMAGE_3d10; - case 24: return IP_CONST_MONSTERDAMAGE_3d12; - case 25: return IP_CONST_MONSTERDAMAGE_3d20; - - } - - return 0; -} - -int MonsterDamage(object oItem) -{ - int iBonus; - int iTemp; - itemproperty ip = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(ip)) - { - if(GetItemPropertyType(ip) == ITEM_PROPERTY_MONSTER_DAMAGE) - { - iTemp = GetItemPropertyCostTableValue(ip); - iBonus = iTemp > iBonus ? iTemp : iBonus; - } - ip = GetNextItemProperty(oItem); - } - - return iBonus; -} - -int FeatIniDmg(object oItem) -{ - itemproperty ip = GetFirstItemProperty(oItem); - while (GetIsItemPropertyValid(ip)) - { - if(GetItemPropertyType(ip) == ITEM_PROPERTY_BONUS_FEAT) - { - if(GetItemPropertySubType(ip) == IP_CONST_FEAT_WeapFocCreature) - return 1; - } - ip = GetNextItemProperty(oItem); - } - return 0; -} - - -void AddIniDmg(object oPC) -{ - - int bUnarmedDmg = GetHasFeat(FEAT_INCREASE_DAMAGE1, oPC) - + GetHasFeat(FEAT_INCREASE_DAMAGE2, oPC); - - if(!bUnarmedDmg) - return; - - object oCweapB = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC); - object oCweapL = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC); - object oCweapR = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC); - - int iDmg; - int iConv; - int iStr = GetAbilityModifier(ABILITY_STRENGTH, oPC); - int iWis = GetAbilityModifier(ABILITY_WISDOM, oPC); - iWis = iWis > iStr ? iWis : 0; - - - /*if(GetHasFeat(FEAT_INTUITIVE_ATTACK, oPC)) - { - SetCompositeBonusT(oCweapB,"",iWis,ITEM_PROPERTY_ATTACK_BONUS); - SetCompositeBonusT(oCweapL,"",iWis,ITEM_PROPERTY_ATTACK_BONUS); - SetCompositeBonusT(oCweapR,"",iWis,ITEM_PROPERTY_ATTACK_BONUS); - } - if (GetHasFeat(FEAT_RAVAGEGOLDENICE, oPC)) - { - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_RAVAGEGOLDENICE,2),oCweapB,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_RAVAGEGOLDENICE,2),oCweapL,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_RAVAGEGOLDENICE,2),oCweapR,9999.0); - }*/ - - - if ( oCweapB != OBJECT_INVALID && !FeatIniDmg(oCweapB)) - { - iDmg = MonsterDamage(oCweapB); - iConv = DamageConv(iDmg) + bUnarmedDmg; - iConv = (iConv > 6 && iConv < 10) ? 6 : iConv; - iConv = (iConv > 15 && iConv < 20) ? 15 : iConv; - iConv = (iConv > 25) ? 25 : iConv; - iConv = ConvMonsterDmg(iConv); - TotalAndRemoveProperty(oCweapB,ITEM_PROPERTY_MONSTER_DAMAGE,-1); - AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyMonsterDamage(iConv),oCweapB); - //AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oCweapB); - IPSafeAddItemProperty(oCweapB, PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } - if ( oCweapL != OBJECT_INVALID && !FeatIniDmg(oCweapL)) - { - iDmg = MonsterDamage(oCweapL); - iConv = DamageConv(iDmg) + bUnarmedDmg; - iConv = (iConv > 6 && iConv < 10) ? 6 : iConv; - iConv = (iConv > 15 && iConv < 20) ? 15 : iConv; - iConv = (iConv > 25) ? 25 : iConv; - iConv = ConvMonsterDmg(iConv); - TotalAndRemoveProperty(oCweapL,ITEM_PROPERTY_MONSTER_DAMAGE,-1); - AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyMonsterDamage(iConv),oCweapL); - //AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oCweapL); - IPSafeAddItemProperty(oCweapL, PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } - if ( oCweapR != OBJECT_INVALID && !FeatIniDmg(oCweapR)) - { - iDmg = MonsterDamage(oCweapR); - iConv = DamageConv(iDmg) + bUnarmedDmg; - iConv = (iConv > 6 && iConv < 10) ? 6 : iConv; - iConv = (iConv > 15 && iConv < 20) ? 15 : iConv; - iConv = (iConv > 25) ? 25 : iConv; - iConv = ConvMonsterDmg(iConv); - TotalAndRemoveProperty(oCweapR,ITEM_PROPERTY_MONSTER_DAMAGE,-1); - AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyMonsterDamage(iConv),oCweapR); - //AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oCweapR); - IPSafeAddItemProperty(oCweapR, PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } -} - -void AddCriti(object oPC,object oSkin,int ip_feat_crit,int nFeat) -{ - // Do not add multiple instances of the same bonus feat iprop, it lags the game - AddSkinFeat(nFeat, ip_feat_crit, oSkin, oPC); -} - -void ImpCrit(object oPC,object oSkin) -{ - if(GetHasFeat(FEAT_WEAPON_FOCUS_BASTARD_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_BASTARD_SWORD, FEAT_IMPROVED_CRITICAL_BASTARD_SWORD); - if(GetHasFeat(FEAT_WEAPON_FOCUS_BATTLE_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_BATTLE_AXE, FEAT_IMPROVED_CRITICAL_BATTLE_AXE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_CLUB, FEAT_IMPROVED_CRITICAL_CLUB); - if(GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DAGGER, FEAT_IMPROVED_CRITICAL_DAGGER); - if(GetHasFeat(FEAT_WEAPON_FOCUS_DART, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DART, FEAT_IMPROVED_CRITICAL_DART); - if(GetHasFeat(FEAT_WEAPON_FOCUS_DIRE_MACE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DIRE_MACE, FEAT_IMPROVED_CRITICAL_DIRE_MACE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_DOUBLE_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DOUBLE_AXE, FEAT_IMPROVED_CRITICAL_DOUBLE_AXE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_DWAXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DWAXE, FEAT_IMPROVED_CRITICAL_DWAXE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_GREAT_AXE, FEAT_IMPROVED_CRITICAL_GREAT_AXE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_GREAT_SWORD, FEAT_IMPROVED_CRITICAL_GREAT_SWORD); - if(GetHasFeat(FEAT_WEAPON_FOCUS_HALBERD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HALBERD, FEAT_IMPROVED_CRITICAL_HALBERD); - if(GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HAND_AXE, FEAT_IMPROVED_CRITICAL_HAND_AXE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HEAVY_CROSSBOW, FEAT_IMPROVED_CRITICAL_HEAVY_CROSSBOW); - if(GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_FLAIL, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HEAVY_FLAIL, FEAT_IMPROVED_CRITICAL_HEAVY_FLAIL); - if(GetHasFeat(FEAT_WEAPON_FOCUS_KAMA, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_KAMA, FEAT_IMPROVED_CRITICAL_KAMA); - if(GetHasFeat(FEAT_WEAPON_FOCUS_KATANA, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_KATANA, FEAT_IMPROVED_CRITICAL_KATANA); - if(GetHasFeat(FEAT_WEAPON_FOCUS_KUKRI, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_KUKRI, FEAT_IMPROVED_CRITICAL_KUKRI); - if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_CROSSBOW, FEAT_IMPROVED_CRITICAL_LIGHT_CROSSBOW); - if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_FLAIL, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_FLAIL, FEAT_IMPROVED_CRITICAL_LIGHT_FLAIL); - if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_HAMMER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_HAMMER, FEAT_IMPROVED_CRITICAL_LIGHT_HAMMER); - if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_MACE, FEAT_IMPROVED_CRITICAL_LIGHT_MACE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LONG_SWORD, FEAT_IMPROVED_CRITICAL_LONG_SWORD); - if(GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LONGBOW, FEAT_IMPROVED_CRITICAL_LONGBOW); - if(GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_MORNING_STAR, FEAT_IMPROVED_CRITICAL_MORNING_STAR); - if(GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_RAPIER, FEAT_IMPROVED_CRITICAL_RAPIER); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SCIMITAR, FEAT_IMPROVED_CRITICAL_SCIMITAR); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SCYTHE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SCYTHE, FEAT_IMPROVED_CRITICAL_SCYTHE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SHORT_SWORD, FEAT_IMPROVED_CRITICAL_SHORT_SWORD); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SHORTBOW, FEAT_IMPROVED_CRITICAL_SHORTBOW); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SHURIKEN, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SHURIKEN, FEAT_IMPROVED_CRITICAL_SHURIKEN); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SICKLE, FEAT_IMPROVED_CRITICAL_SICKLE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SLING, FEAT_IMPROVED_CRITICAL_SLING); - if(GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SPEAR, FEAT_IMPROVED_CRITICAL_SPEAR); - if(GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_STAFF, FEAT_IMPROVED_CRITICAL_STAFF); - if(GetHasFeat(FEAT_WEAPON_FOCUS_THROWING_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_THROWING_AXE, FEAT_IMPROVED_CRITICAL_THROWING_AXE); - if(GetHasFeat(FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_TWO_BLADED_SWORD, FEAT_IMPROVED_CRITICAL_TWO_BLADED_SWORD); - if(GetHasFeat(FEAT_WEAPON_FOCUS_WAR_HAMMER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_WAR_HAMMER, FEAT_IMPROVED_CRITICAL_WAR_HAMMER); - if(GetHasFeat(FEAT_WEAPON_FOCUS_WHIP, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_WHIP, FEAT_IMPROVED_CRITICAL_WHIP); - -} - -////////////////End Soul Inc////////////////// - -////////////////Begin Martial Strike////////////////// - -void MartialStrike() -{ - object oItem; - object oPC = OBJECT_SELF; - - int iEquip=GetLocalInt(oPC,"ONEQUIP"); - int iType; - - if (iEquip==2) - { - - if (!GetHasFeat(FEAT_HOLY_MARTIAL_STRIKE)) return; - - oItem=GetItemLastEquipped(); - iType= GetBaseItemType(oItem); - - switch (iType) - { - case BASE_ITEM_BOLT: - case BASE_ITEM_BULLET: - case BASE_ITEM_ARROW: - iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); - break; - case BASE_ITEM_SHORTBOW: - case BASE_ITEM_LONGBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS); - break; - case BASE_ITEM_LIGHTCROSSBOW: - case BASE_ITEM_HEAVYCROSSBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS); - break; - case BASE_ITEM_SLING: - oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS); - break; - } - - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_HOLY),oItem,9999.0); - SetLocalInt(oItem,"MartialStrik",1); - } - else if (iEquip==1) - { - oItem=GetItemLastUnequipped(); - iType= GetBaseItemType(oItem); - - switch (iType) - { - case BASE_ITEM_BOLT: - case BASE_ITEM_BULLET: - case BASE_ITEM_ARROW: - iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); - break; - case BASE_ITEM_SHORTBOW: - case BASE_ITEM_LONGBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS); - break; - case BASE_ITEM_LIGHTCROSSBOW: - case BASE_ITEM_HEAVYCROSSBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS); - break; - case BASE_ITEM_SLING: - oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS); - break; - } - - if ( GetLocalInt(oItem,"MartialStrik")) - { - RemoveSpecificProperty(oItem,ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP,IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGEBONUS_2d6, 1,"",IP_CONST_DAMAGETYPE_DIVINE,DURATION_TYPE_TEMPORARY); - RemoveSpecificProperty(oItem,ITEM_PROPERTY_VISUALEFFECT,ITEM_VISUAL_HOLY,-1,1,"",-1,DURATION_TYPE_TEMPORARY); - DeleteLocalInt(oItem,"MartialStrik"); - } - - } - else - { - - if (!GetHasFeat(FEAT_HOLY_MARTIAL_STRIKE)) return; - - oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC); - iType= GetBaseItemType(oItem); - - switch (iType) - { - case BASE_ITEM_BOLT: - case BASE_ITEM_BULLET: - case BASE_ITEM_ARROW: - iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); - break; - case BASE_ITEM_SHORTBOW: - case BASE_ITEM_LONGBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS); - break; - case BASE_ITEM_LIGHTCROSSBOW: - case BASE_ITEM_HEAVYCROSSBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS); - break; - case BASE_ITEM_SLING: - oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS); - break; - } - - if (!GetLocalInt(oItem,"MartialStrik")) - { - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_HOLY),oItem,9999.0); - SetLocalInt(oItem,"MartialStrik",1); - } - oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC); - iType= GetBaseItemType(oItem); - if ( !GetLocalInt(oItem,"MartialStrik")) - { - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_HOLY),oItem,9999.0); - SetLocalInt(oItem,"MartialStrik",1); - } - } - - -} - - -void UnholyStrike() -{ - object oItem; - object oPC = OBJECT_SELF; - - int iEquip=GetLocalInt(oPC,"ONEQUIP"); - int iType; - - if (iEquip==2) - { - - if (!GetHasFeat(FEAT_UNHOLY_STRIKE)) return; - - oItem=GetItemLastEquipped(); - iType= GetBaseItemType(oItem); - - switch (iType) - { - case BASE_ITEM_BOLT: - case BASE_ITEM_BULLET: - case BASE_ITEM_ARROW: - iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); - break; - case BASE_ITEM_SHORTBOW: - case BASE_ITEM_LONGBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS); - break; - case BASE_ITEM_LIGHTCROSSBOW: - case BASE_ITEM_HEAVYCROSSBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS); - break; - case BASE_ITEM_SLING: - oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS); - break; - } - - - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_EVIL),oItem,9999.0); - SetLocalInt(oItem,"UnholyStrik",1); - } - else if (iEquip==1) - { - oItem=GetItemLastUnequipped(); - iType= GetBaseItemType(oItem); - - switch (iType) - { - case BASE_ITEM_BOLT: - case BASE_ITEM_BULLET: - case BASE_ITEM_ARROW: - iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); - break; - case BASE_ITEM_SHORTBOW: - case BASE_ITEM_LONGBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS); - break; - case BASE_ITEM_LIGHTCROSSBOW: - case BASE_ITEM_HEAVYCROSSBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS); - break; - case BASE_ITEM_SLING: - oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS); - break; - } - - if ( GetLocalInt(oItem,"UnholyStrik")) - { - RemoveSpecificProperty(oItem,ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP,IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGEBONUS_2d6, 1,"",IP_CONST_DAMAGETYPE_DIVINE,DURATION_TYPE_TEMPORARY); - RemoveSpecificProperty(oItem,ITEM_PROPERTY_VISUALEFFECT,ITEM_VISUAL_EVIL,-1,1,"",-1,DURATION_TYPE_TEMPORARY); - DeleteLocalInt(oItem,"UnholyStrik"); - } - - } - else - { - - if (!GetHasFeat(FEAT_UNHOLY_STRIKE)) return; - - oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC); - iType= GetBaseItemType(oItem); - - switch (iType) - { - case BASE_ITEM_BOLT: - case BASE_ITEM_BULLET: - case BASE_ITEM_ARROW: - iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); - break; - case BASE_ITEM_SHORTBOW: - case BASE_ITEM_LONGBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS); - break; - case BASE_ITEM_LIGHTCROSSBOW: - case BASE_ITEM_HEAVYCROSSBOW: - oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS); - break; - case BASE_ITEM_SLING: - oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS); - break; - } - - if (!GetLocalInt(oItem,"UnholyStrik")) - { - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_EVIL),oItem,9999.0); - SetLocalInt(oItem,"UnholyStrik",1); - } - oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC); - iType= GetBaseItemType(oItem); - if ( !GetLocalInt(oItem,"UnholyStrik")) - { - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0); - AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_EVIL),oItem,9999.0); - SetLocalInt(oItem,"UnholyStrik",1); - } - } - - -} - -////////////////End Martial Strike////////////////// - -////////////////Begin Soldier of Light Spells////////////////// -/* As far as I can tell, not used at all - Ornedan -void spellsCureMod(int nCasterLvl ,int nDamage, int nMaxExtraDamage, int nMaximized, int vfx_impactHurt, int vfx_impactHeal, int nSpellID) -{ - //Declare major variables - object oTarget = PRCGetSpellTargetObject(); - int nHeal; - int nMetaMagic = PRCGetMetaMagicFeat(); - effect eVis = EffectVisualEffect(vfx_impactHurt); - effect eVis2 = EffectVisualEffect(vfx_impactHeal); - effect eHeal, eDam; - - int nExtraDamage = nCasterLvl; // * figure out the bonus damage - if (nExtraDamage > nMaxExtraDamage) - { - nExtraDamage = nMaxExtraDamage; - } - // * if low or normal difficulty is treated as MAXIMIZED - if(GetIsPC(oTarget) && GetGameDifficulty() < GAME_DIFFICULTY_CORE_RULES) - { - nDamage = nMaximized + nExtraDamage; - } - else - { - nDamage = nDamage + nExtraDamage; - } - - - //Make metamagic checks - int iBlastFaith = BlastInfidelOrFaithHeal(OBJECT_SELF, oTarget, DAMAGE_TYPE_POSITIVE, TRUE); - if (nMetaMagic & METAMAGIC_MAXIMIZE || iBlastFaith) - { - nDamage = nMaximized + nExtraDamage; - // * if low or normal difficulty then MAXMIZED is doubled. - if(GetIsPC(OBJECT_SELF) && GetGameDifficulty() < GAME_DIFFICULTY_CORE_RULES) - { - nDamage = nDamage + nExtraDamage; - } - } - if (nMetaMagic & METAMAGIC_EMPOWER || GetHasFeat(FEAT_HEALING_DOMAIN_POWER)) - { - nDamage = nDamage + (nDamage/2); - } - - - if (MyPRCGetRacialType(oTarget) != RACIAL_TYPE_UNDEAD) - { - //Figure out the amount of damage to heal - nHeal = nDamage; - //Set the heal effect - eHeal = EffectHeal(nHeal); - //Apply heal effect and VFX impact - SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget); - SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget); - //Fire cast spell at event for the specified target - SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpellID, FALSE)); - - - } - //Check that the target is undead - else - { - int nTouch = PRCDoMeleeTouchAttack(oTarget);; - if (nTouch > 0) - { - if(!GetIsReactionTypeFriendly(oTarget)) - { - //Fire cast spell at event for the specified target - SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpellID)); - if (!PRCDoResistSpell(OBJECT_SELF, oTarget,nCasterLvl+add_spl_pen(OBJECT_SELF))) - { - eDam = EffectDamage(nDamage,DAMAGE_TYPE_NEGATIVE); - //Apply the VFX impact and effects - DelayCommand(1.0, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget)); - SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); - } - } - } - } -} -*/ -////////////////End Soldier of Light Spells////////////////// - -////////////////Begin Master Harper Instruments////////////////// - -void ActiveModeCIMM(object oTarget) -{ - if(!GetLocalInt(oTarget,"use_CIMM") ) - { - string sScript = GetModuleOverrideSpellscript(); - if (sScript != "mh_spell_at_inst") - { - SetLocalString(OBJECT_SELF,"temp_spell_at_inst",sScript); - SetLocalString(OBJECT_SELF, "PRC_OVERRIDE_SPELLSCRIPT", "mh_spell_at_inst"); - } - SetLocalInt(OBJECT_SELF,"nb_spell_at_inst",GetLocalInt(OBJECT_SELF,"nb_spell_at_inst")+1); - FloatingTextStrRefOnCreature(16825240,oTarget); - SetLocalInt(oTarget,"use_CIMM",TRUE); - } -} - -void UnactiveModeCIMM(object oTarget) -{ - if(GetLocalInt(oTarget,"use_CIMM") ) - { - string sScript = GetModuleOverrideSpellscript(); - SetLocalInt(OBJECT_SELF,"nb_spell_at_inst",GetLocalInt(OBJECT_SELF,"nb_spell_at_inst")-1); - if (sScript == "mh_spell_at_inst" && GetLocalInt(OBJECT_SELF,"nb_spell_at_inst") == 0) - { - SetLocalString(OBJECT_SELF, "PRC_OVERRIDE_SPELLSCRIPT", GetLocalString(OBJECT_SELF,"temp_spell_at_inst")); - GetLocalString(OBJECT_SELF,"temp_spell_at_inst"); - SetLocalString(OBJECT_SELF,"temp_spell_at_inst",""); - } - FloatingTextStrRefOnCreature(16825241,oTarget); - SetLocalInt(oTarget,"use_CIMM",FALSE); - } -} - -////////////////End Master Harper Instruments////////////////// - -////////////////Begin Minstrel of the Edge////////////////// - -// Goes a bit further than RemoveSpellEffects -- makes sure to remove ALL effects -// made by the Singer+Song. -void RemoveSongEffects(int iSong, object oCaster, object oTarget) -{ - effect eCheck = GetFirstEffect(oTarget); - while (GetIsEffectValid(eCheck)) - { - if (GetEffectCreator(eCheck) == oCaster && GetEffectSpellId(eCheck) == iSong) - RemoveEffect(oTarget, eCheck); - eCheck = GetNextEffect(oTarget); - } -} - -// Stores a Song recipient to the PC as a local variable, and creates a list by using -// an index variable. -void StoreSongRecipient(object oRecipient, object oSinger, int iSongID, int iDuration = 0) -{ - int iSlot = GetLocalInt(oSinger, "SONG_SLOT"); - int iIndex = GetLocalInt(oSinger, "SONG_INDEX_" + IntToString(iSlot)) + 1; - string sIndex = "SONG_INDEX_" + IntToString(iSlot); - string sRecip = "SONG_RECIPIENT_" + IntToString(iIndex) + "_" + IntToString(iSlot); - string sSong = "SONG_IN_USE_" + IntToString(iSlot); - - // Store the recipient into the current used slot - SetLocalObject(oSinger, sRecip, oRecipient); - - // Store the song information - SetLocalInt(oSinger, sSong, iSongID); - - // Store the index of creatures we're on - SetLocalInt(oSinger, sIndex, iIndex); -} - -// Removes all effects given by the previous song from all creatures who recieved it. -// Now allows for two "slots", which means you can perform two songs at a time. -void RemoveOldSongEffects(object oSinger, int iSongID) -{ - object oCreature; - int iSlotNow = GetLocalInt(oSinger, "SONG_SLOT"); - int iSlot; - int iNumRecip; - int iSongInUse; - int iIndex; - string sIndex; - string sRecip; - string sSong; - - if (GetHasFeat(FEAT_MINSTREL_GREATER_MINSTREL_SONG, oSinger)) - { - // If you use the same song twice in a row you - // should deal with the same slot again... - if (GetLocalInt(oSinger, "SONG_IN_USE_" + IntToString(iSlotNow)) == iSongID) - iSlot = iSlotNow; - // Otherwise, we should toggle between slot "1" and slot "0" - else - iSlot = (iSlotNow == 1) ? 0 : 1; - } - else - { - iSlot = 0; - } - - // Save the toggle we're on for later. - SetLocalInt(oSinger, "SONG_SLOT", iSlot); - - // Find the proper variable names based on slot - sIndex = "SONG_INDEX_" + IntToString(iSlot); - sSong = "SONG_IN_USE_" + IntToString(iSlot); - - // Store the local variables into script variables - iNumRecip = GetLocalInt(oSinger, sIndex); - iSongInUse = GetLocalInt(oSinger, sSong); - - // Reset the local variables - SetLocalInt(oSinger, sIndex, 0); - SetLocalInt(oSinger, sSong, 0); - - // Removes any effects from the caster first - RemoveSongEffects(iSongInUse, oSinger, oSinger); - - // Removes any effects from the recipients - for (iIndex = 1 ; iIndex <= iNumRecip ; iIndex++) - { - sRecip = "SONG_RECIPIENT_" + IntToString(iIndex) + "_" + IntToString(iSlot); - oCreature = GetLocalObject(oSinger, sRecip); - - RemoveSongEffects(iSongInUse, oSinger, oCreature); - } -} - - -////////////////End Minstrel of the Edge////////////////// - -////////////////Begin Arcane Duelist////////////////// - -void FlurryEffects(object oPC) -{ - effect Effect1 = EffectModifyAttacks(1); - effect Effect2 = EffectAttackDecrease(2, ATTACK_BONUS_MISC); - - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, Effect1, oPC, RoundsToSeconds(10)); - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, Effect2, oPC, RoundsToSeconds(10)); - -} - -void CheckCombatDexAttack(object oPC) -{ -//object oPC = GetLocalObject(OBJECT_SELF, "PC_IN_COMBAT_WITH_DEXATTACK_ON"); -int iCombat = GetIsInCombat(oPC); -object oWeapon = GetLocalObject(oPC, "CHOSEN_WEAPON"); - - if(iCombat == TRUE && GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC) == oWeapon) - { - DelayCommand(6.0, CheckCombatDexAttack(oPC)); - } - else - { - FloatingTextStringOnCreature("Dexterous Attack Mode Deactivated", oPC, FALSE); - effect eEffects = GetFirstEffect(oPC); - while (GetIsEffectValid(eEffects)) - { - - if (GetEffectType(eEffects) == EFFECT_TYPE_ATTACK_INCREASE && GetEffectSpellId(eEffects) == 1761) // dextrous attack - { - RemoveEffect(oPC, eEffects); - } - - eEffects = GetNextEffect(oPC); - } - DeleteLocalObject(OBJECT_SELF, "PC_IN_COMBAT_WITH_DEXATTACK_ON"); - } -} - -void SPMakeAttack(object oTarget, object oImage) -{ - int iDead = GetIsDead(oTarget); - - if(iDead == FALSE) - { - PrintString("TARGET AINT DEAD"); - DelayCommand(6.0, SPMakeAttack(oTarget, oImage)); - AssignCommand(oImage, ActionAttack(oTarget, FALSE)); - } - if(iDead == TRUE) - { - PrintString("TARGET BE DEAD AS A DOORNAIL"); - DestroyObject(oImage, 0.0); - ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3), GetLocation(oImage), 0.0); - } - -} - -////////////////End Arcane Duelist////////////////// - -////////////////Begin Corpsecrafter////////////// - -void CorpseCrafter(object oPC, object oSummon) -{ - // Hijacking this function because it's already in the right places - if (GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oPC) >= 8) - { - if (DEBUG) DoDebug("Corpsecrafter: Dread Necro"); - int nHD = GetHitDice(oSummon); - effect eHP = EffectTemporaryHitpoints(nHD * 2); - effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 4); - effect eDex = EffectAbilityIncrease(ABILITY_DEXTERITY, 4); - eHP = SupernaturalEffect(eHP); - eStr = SupernaturalEffect(EffectLinkEffects(eStr, eDex)); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHP, oSummon); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon); - } - if (GetHasFeat(FEAT_CORPSECRAFTER, oPC)) - { - if (DEBUG) DoDebug("Corpsecrafter: Corpsecrafter"); - int nHD = GetHitDice(oSummon); - effect eHP = EffectTemporaryHitpoints(nHD * 2); - effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 4); - eHP = SupernaturalEffect(eHP); - eStr = SupernaturalEffect(eStr); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHP, oSummon); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon); - } - if (GetHasFeat(FEAT_BOLSTER_RESISTANCE, oPC)) - { - if (DEBUG) DoDebug("Corpsecrafter: Bolster Resistance"); - effect eTurn = EffectTurnResistanceIncrease(4); - eTurn = SupernaturalEffect(eTurn); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTurn, oSummon); - } - if (GetHasFeat(FEAT_DEADLY_CHILL, oPC)) - { - if (DEBUG) DoDebug("Corpsecrafter: Deadly Chill"); - effect eChill = EffectDamageIncrease(DAMAGE_BONUS_1d6, DAMAGE_TYPE_COLD); - eChill = SupernaturalEffect(eChill); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eChill, oSummon); - } - if (GetHasFeat(FEAT_HARDENED_FLESH, oPC)) - { - if (DEBUG) DoDebug("Corpsecrafter: Hardened Flesh"); - effect eAC = EffectACIncrease(2); - eAC = SupernaturalEffect(eAC); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAC, oSummon); - } - if (GetHasFeat(FEAT_NIMBLE_BONES, oPC)) - { - if (DEBUG) DoDebug("Corpsecrafter: Nimble Bones"); - object oSkin = GetPCSkin(oPC); - itemproperty iInit = PRCItemPropertyBonusFeat(IP_CONST_FEAT_IMPROVED_INIT); - //AddItemProperty(DURATION_TYPE_PERMANENT, iInit, oSkin); - IPSafeAddItemProperty(oSkin, iInit, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - - // Speed boost, average speed is 30 feet, so a 10 foot boost is a 33% boost - effect eSpeed = EffectMovementSpeedIncrease(33); - eSpeed = SupernaturalEffect(eSpeed); - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSpeed, oSummon); - } - if (GetHasFeat(FEAT_DESTRUCTION_RETRIBUTION, oPC)) - { - if (DEBUG) DoDebug("Corpsecrafter: Destruction Retribution"); - SetLocalInt(oSummon, "DestructionRetribution", TRUE); - } -} - -////////////////Begin Ninja////////////// - -void Ninja_DecrementKi (object oPC, int iExcept = -1) -{ - if (iExcept != FEAT_KI_POWER) - DecrementRemainingFeatUses(oPC, FEAT_KI_POWER); - if (iExcept != FEAT_GHOST_STEP) - DecrementRemainingFeatUses(oPC, FEAT_GHOST_STEP); - if (iExcept != FEAT_GHOST_STRIKE) - DecrementRemainingFeatUses(oPC, FEAT_GHOST_STRIKE); - if (iExcept != FEAT_GHOST_WALK) - DecrementRemainingFeatUses(oPC, FEAT_GHOST_WALK); - if (iExcept != FEAT_KI_DODGE) - DecrementRemainingFeatUses(oPC, FEAT_KI_DODGE); - // for testing only - SetLocalInt(oPC, "prc_ninja_ki", GetLocalInt(oPC, "prc_ninja_ki") - 1); - ExecuteScript("prc_ninjca", oPC); -} - -int Ninja_AbilitiesEnabled (object oPC) -{ - object oLefthand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC); - - if (GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) > 0 || - GetBaseItemType(oLefthand) == BASE_ITEM_SMALLSHIELD || - GetBaseItemType(oLefthand) == BASE_ITEM_LARGESHIELD || - GetBaseItemType(oLefthand) == BASE_ITEM_TOWERSHIELD) - return FALSE; - // all Ki powers will not function when encumbered - if (GetIsEncumbered(oPC)) - return FALSE; - return TRUE; -} - -////////////////End Ninja////////////// - -////////////////Begin Virtuoso////////////// - -//Decrements the daily uses of Virtuoso Performance by the -// correct amount, returns FALSE if there are insufficient -// uses remaining to use the current feat -int VirtuosoPerformanceDecrement(object oPC, int nSpellID) -{ - int nDecrement = 0; - int nDifference = 1122; //hack, difference in number between feat and spell 2da lines - switch(nSpellID) - { - case SPELL_VIRTUOSO_SUSTAINING_SONG: - case SPELL_VIRTUOSO_CALUMNY: - case SPELL_VIRTUOSO_GREATER_CALUMNY: nDecrement = 1; break; - - case SPELL_VIRTUOSO_MINDBENDING_MELODY: - case SPELL_VIRTUOSO_MAGICAL_MELODY: - case SPELL_VIRTUOSO_REVEALING_MELODY: nDecrement = 2; break; - - case SPELL_VIRTUOSO_SHARP_NOTE: - case SPELL_VIRTUOSO_JARRING_SONG: - case SPELL_VIRTUOSO_SONG_OF_FURY: nDecrement = 3; break; - } - if(!nDecrement) return FALSE; //sanity check - int nUses = GetPersistantLocalInt(oPC, "Virtuoso_Performance_Uses"); - if(nUses >= nDecrement) - { - SetPersistantLocalInt(oPC, "Virtuoso_Performance_Uses", nUses - nDecrement); - int nFeat, nDec; - for(nFeat = FEAT_VIRTUOSO_SUSTAINING_SONG; nFeat <= FEAT_VIRTUOSO_PERFORMANCE; nFeat++) - { - nDec = nDecrement; - if(nFeat == (nSpellID + nDifference)) - nDec--; //already decremented once by being used - for(; nDec > 0; nDec--) - DecrementRemainingFeatUses(oPC, nFeat); - } - return TRUE; - } - else - { //refund feat use :P - IncrementRemainingFeatUses(oPC, nSpellID + nDifference); - return FALSE; - } -} - -////////////////End Virtuoso////////////// - - -///////////////Archmage & Heirophant SLAs /////////// - -void DoArchmageHeirophantSLA(object oPC, object oTarget, location lTarget, int nSLAID) -{ - int nSLAFeatID = -1; //feat ID of the SLA in use - int nSLASpellID = -1;//spell ID of the SLA in use NOT THE SPELL BEING CAST - //get the SLAFeatID - int SLA_ID; - switch(SLA_ID) - { - case 1: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_1; break; - case 2: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_2; break; - case 3: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_3; break; - case 4: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_4; break; - case 5: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_5; break; - } - //get the spellID of the spell your trying to cast - //+1 offset for unassigned - int nSpellID = GetPersistantLocalInt(oPC, "PRC_SLA_SpellID_"+IntToString(nSLAID))-1; - //test if already stored - if(nSpellID == -1) - { - //not stored - FloatingTextStringOnCreature("This SLA has not been stored yet\nThe next spell you cast will be assigned to this SLA", oPC); - SetLocalInt(oPC, "PRC_SLA_Store", nSLAID); - DelayCommand(18.0, - DeleteLocalInt(oPC, "PRC_SLA_Store")); - return; - } - else - { - //stored, recast it - int nSpellClass = GetPersistantLocalInt(oPC, "PRC_SLA_Class_"+IntToString(nSLAID)); - int nMetamagic = GetPersistantLocalInt(oPC, "PRC_SLA_Meta_"+IntToString(nSLAID)); - int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nSpellClass); - int nBaseDC = 10 + nSpellLevel + GetDCAbilityModForClass(nSpellClass, oPC); - //since this is targetted using a generic feat, - //make sure were within range and target is valid for this spell - //get current distance - /*string sRange = Get2DACache("spells", "Range", nSpellID); - float fDist; - if(GetIsObjectValid(oTarget)) - fDist = GetDistanceToObject(oTarget); - else - fDist = GetDistanceBetweenLocations(GetLocation(oPC), lTarget); - //check distance is allowed - if(fDist < 0.0 - || (sRange == "T" && fDist > 2.25) - || (sRange == "S" && fDist > 8.0 ) - || (sRange == "M" && fDist > 20.0 ) - || (sRange == "L" && fDist > 40.0 ) - ) - { - //out of range - FloatingTextStringOnCreature("You are out of range", oPC); - //replace the useage - IncrementRemainingFeatUses(oPC, nSLAFeatID); - //end the script - return; - }*/ - //check object type - int nTargetType = HexToInt(Get2DACache("spells", "TargetType", nSpellID)); - /* - # 0x01 = 1 = Self - # 0x02 = 2 = Creature - # 0x04 = 4 = Area/Ground - # 0x08 = 8 = Items - # 0x10 = 16 = Doors - # 0x20 = 32 = Placeables - */ - int nCaster = nTargetType & 1; - int nCreature = nTargetType & 2; - int nLocation = nTargetType & 4; - int nItem = nTargetType & 8; - int nDoor = nTargetType & 16; - int nPlaceable = nTargetType & 32; - int nTargetValid = TRUE; - //test targetting self - if(oTarget == OBJECT_SELF) - { - if(!nCaster) - { - nTargetValid = FALSE; - FloatingTextStringOnCreature("You cannot target yourself", oPC); - } - } - //test targetting others - else if(GetIsObjectValid(oTarget)) - { - switch(GetObjectType(oTarget)) - { - case OBJECT_TYPE_CREATURE: - if(!nCreature) - { - nTargetValid = FALSE; - FloatingTextStringOnCreature("You cannot target creatures", oPC); - } - break; - case OBJECT_TYPE_ITEM: - if(!nItem) - { - nTargetValid = FALSE; - FloatingTextStringOnCreature("You cannot target items", oPC); - } - break; - case OBJECT_TYPE_DOOR: - if(!nDoor) - { - nTargetValid = FALSE; - FloatingTextStringOnCreature("You cannot target doors", oPC); - } - break; - case OBJECT_TYPE_PLACEABLE: - if(!nPlaceable) - { - nTargetValid = FALSE; - FloatingTextStringOnCreature("You cannot target placeables", oPC); - } - break; - } - } - //test if can target a location - else if(GetIsObjectValid(GetAreaFromLocation(lTarget))) - { - if(!nLocation) - { - nTargetValid = FALSE; - FloatingTextStringOnCreature("You cannot target locations", oPC); - } - } - //target was not valid, abort - if(!nTargetValid) - { - //replace the useage - IncrementRemainingFeatUses(oPC, nSLAFeatID); - //end the script - return; - } - //actually cast it at this point - //note that these are instant-spells, so we have to add the animation part too - /*if(GetIsObjectValid(oTarget)) - ActionCastFakeSpellAtObject(nSpellID, oTarget); - else - ActionCastFakeSpellAtLocation(nSpellID, lTarget);*/ - ActionDoCommand(ActionCastSpell(nSpellID, 0, nBaseDC, 0, nMetamagic, nSpellClass, 0, 0, OBJECT_INVALID, FALSE)); - } -} - -/////////////// End Archmage & Heirophant SLAs /////////// - -////////////////////////Alienist////////////////////////// -int GetPhobia(object oPC) -{ - int nPhobia = GetPersistantLocalInt(oPC, "Alienist_Phobia"); - if(nPhobia < 1) - { - nPhobia = Random(16) + 1; - SetPersistantLocalInt(oPC, "Alienist_Phobia", nPhobia); - } - return nPhobia; -} - -int GetPhobiaRace(int nPhobia) -{ - switch(nPhobia) - { - case 1: return RACIAL_TYPE_ABERRATION; - case 2: return RACIAL_TYPE_ANIMAL; - case 3: return RACIAL_TYPE_BEAST; - case 4: return RACIAL_TYPE_CONSTRUCT; - case 5: return RACIAL_TYPE_DRAGON; - case 6: return RACIAL_TYPE_HUMANOID_GOBLINOID; - case 7: return RACIAL_TYPE_HUMANOID_MONSTROUS; - case 8: return RACIAL_TYPE_HUMANOID_ORC; - case 9: return RACIAL_TYPE_HUMANOID_REPTILIAN; - case 10: return RACIAL_TYPE_ELEMENTAL; - case 11: return RACIAL_TYPE_FEY; - case 12: return RACIAL_TYPE_GIANT; - case 13: return RACIAL_TYPE_MAGICAL_BEAST; - case 14: return RACIAL_TYPE_SHAPECHANGER; - case 15: return RACIAL_TYPE_UNDEAD; - case 16: return RACIAL_TYPE_VERMIN; - } - return -1;//error -} - -int GetPhobiaFeat(int nPhobia) -{ - switch(nPhobia) - { - case 1: return IP_CONST_PHOBIA_ABERRATION; - case 2: return IP_CONST_PHOBIA_ANIMAL; - case 3: return IP_CONST_PHOBIA_BEAST; - case 4: return IP_CONST_PHOBIA_CONSTRUCT; - case 5: return IP_CONST_PHOBIA_DRAGON; - case 6: return IP_CONST_PHOBIA_GOBLINOID; - case 7: return IP_CONST_PHOBIA_MONSTROUS; - case 8: return IP_CONST_PHOBIA_ORC; - case 9: return IP_CONST_PHOBIA_REPTILIAN; - case 10: return IP_CONST_PHOBIA_ELEMENTAL; - case 11: return IP_CONST_PHOBIA_FEY; - case 12: return IP_CONST_PHOBIA_GIANT; - case 13: return IP_CONST_PHOBIA_MAGICAL_BEAST; - case 14: return IP_CONST_PHOBIA_SHAPECHANGER; - case 15: return IP_CONST_PHOBIA_UNDEAD; - case 16: return IP_CONST_PHOBIA_VERMIN; - } - return -1;//error -} - -/////////////////////DragonSong Lyrist//////////////////////// - -void RemoveOldSongs(object oPC) -{ - if(GetHasSpellEffect(SPELL_DSL_SONG_STRENGTH, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_STRENGTH); - if(GetHasSpellEffect(SPELL_DSL_SONG_COMPULSION, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_COMPULSION); - if(GetHasSpellEffect(SPELL_DSL_SONG_SPEED, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_SPEED); - if(GetHasSpellEffect(SPELL_DSL_SONG_FEAR, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_FEAR); - if(GetHasSpellEffect(SPELL_DSL_SONG_HEALING, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_HEALING); -} - - -// Eldritch Theurge class requires arcane spellcasting and eldritch blast. -// If a character is an Eldritch Theruge we know that she must have levels in Warlock -// since in NWN character can have max 3 classes. We also know that Eldritch Theurge -// is at positon 3 (unless player is cheating). -// So we just need to check the third class. - -//:: [PRC .35] This function will require marker feats -int GetETArcaneClass(object oPC) -{ - int nClass = GetClassByPosition(1, oPC); - if(nClass == CLASS_TYPE_WARLOCK) - nClass = GetClassByPosition(2, oPC); - return nClass; -} - diff --git a/trunk/include/prc_inc_core.nss b/trunk/include/prc_inc_core.nss deleted file mode 100644 index 3ab2def1..00000000 --- a/trunk/include/prc_inc_core.nss +++ /dev/null @@ -1,729 +0,0 @@ -/* Core functions taken from high up the branch - which are needed lower. */ - -//:: Updated for .35 by Jaysyn 2023/03/10 - -////////////////////////////////////////////////// -/* Function Prototypes */ -////////////////////////////////////////////////// - -// 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 */ -////////////////////////////////////////////////// - - -//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_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 spelllevel 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 - || nClass == CLASS_TYPE_BARD - || 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) - && !(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("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("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"); -} - diff --git a/trunk/include/prc_inc_domain.nss b/trunk/include/prc_inc_domain.nss deleted file mode 100644 index d0709086..00000000 --- a/trunk/include/prc_inc_domain.nss +++ /dev/null @@ -1,585 +0,0 @@ -//:://///////////////////////////////////////////// -//:: PRC Bonus Domains -//:: prc_inc_domain.nss -//::////////////////////////////////////////////// -//:: Handles all of the code for bonus domains. -//::////////////////////////////////////////////// -//:: Created By: Stratovarius. -//:: Created On: August 31st, 2005 -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/10 - - -// Function returns the domain in the input slot. -// A person can have a maximum of 5 bonus domains. -int GetBonusDomain(object oPC, int nSlot); - -// Function will add a bonus domain to the stored list on the character. -void AddBonusDomain(object oPC, int nDomain); - -// Uses the slot and level to find the appropriate spell, then casts it using ActionCastSpell -// It will also decrement a spell from that level -// If the domain does not have an appropriate spell for that level, an error message appears and nothing happens -void CastDomainSpell(object oPC, int nSlot, int nLevel); - -// Takes the domain and spell level and uses it to find the appropriate spell. -// Right now it uses 2da reads on the domains.2da, although it could be scripted if desired. -int GetDomainSpell(int nDomain, int nLevel, object oPC); - -// Takes the spell level, and returns the radial feat for that level. -// Used in case there is no spell of the appropriate level. -int SpellLevelToFeat(int nLevel); - -// Will return the domain name as a string -// This is used to tell a PC what domains he has in what slot -string GetDomainName(int nDomain); - -// This is the starter function, and fires from Enter and Levelup -// It checks all of the bonus domain feats, and gives the PC the correct domains -void CheckBonusDomains(object oPC); - -// Returns the spell to be burned for CastDomainSpell -int GetBurnableSpell(object oPC, int nLevel); - -// Returns the Domain Power feat -int GetDomainFeat(int nDomain); - -// Returns the Uses per day of the feat entered -int GetDomainFeatUsesPerDay(int nFeat, object oPC); - -// This counts down the number of times a domain has been used in a day -// Returns TRUE if the domain use is valid -// Returns FALSE if the player is out of uses per day -int DecrementDomainUses(int nDomain, object oPC); - -// Used to determine which domain has cast the Turn Undead spell -// Returns the domain constant -int GetTurningDomain(int nSpell); - -// Checks to see if the player has a domain. -// Looks for the domain power constants since every domain has those -int GetHasDomain(object oPC, int nDomain); - -// Cleans the ints that limit the domain spells to being cast 1/day -void BonusDomainRest(object oPC); - -//#include "prc_inc_clsfunc" -#include "prc_alterations" -#include "prc_getbest_inc" -#include "inc_dynconv" - -int GetBonusDomain(object oPC, int nSlot) -{ - /*string sName = "PRCBonusDomain" + IntToString(nSlot); - // Return value in case there is nothing in the slot - int nDomain = 0; - nDomain = GetPersistantLocalInt(oPC, sName);*/ - - return GetPersistantLocalInt(oPC, "PRCBonusDomain" + IntToString(nSlot)); -} - -void AddBonusDomain(object oPC, int nDomain) -{ - //if(DEBUG) DoDebug("AddBonusDomain is running."); - - // Loop through the domain slots to see if there is an open one. - int nSlot = 1; - int nTest = GetBonusDomain(oPC, nSlot); - while(nTest > 0 && 5 >= nSlot) - { - nSlot += 1; - // If the test domain and the domain to be added are the same - // shut down the function, since you don't want to add a domain twice. - if(nTest == nDomain) - { - //FloatingTextStringOnCreature("You already have this domain as a bonus domain.", oPC, FALSE); - return; - } - nTest = GetBonusDomain(oPC, nSlot); - } - // If you run out of slots, display message and end function - if (nSlot > 5) - { - FloatingTextStringOnCreature("You have more than 5 bonus domains, your last domain is lost.", oPC, FALSE); - return; - } - - // If we're here, we know we have an open slot, so we add the domain into it. - string sName = "PRCBonusDomain" + IntToString(nSlot); - SetPersistantLocalInt(oPC, sName, nDomain); - FloatingTextStringOnCreature("You have " + GetStringByStrRef(StringToInt(Get2DACache("prc_domains", "Name", nDomain - 1))) + " as a bonus domain", oPC, FALSE); -} - -int TestSpellTarget(object oPC, object oTarget, int nSpell) -{ - int nTargetType = ~(HexToInt(Get2DACache("spells", "TargetType", nSpell))); - - if(oTarget == oPC && nTargetType & 1) - { - SendMessageToPC(oPC, "You cannot target yourself!"); - return FALSE; - } - else if(GetIsObjectValid(oTarget)) - { - int nObjectType = GetObjectType(oTarget); - if(nObjectType == OBJECT_TYPE_CREATURE && nTargetType & 2) - { - SendMessageToPC(oPC, "You cannot target creatures"); - return FALSE; - } - else if(nObjectType == OBJECT_TYPE_ITEM && nTargetType & 8) - { - SendMessageToPC(oPC, "You cannot target items"); - return FALSE; - } - else if(nObjectType == OBJECT_TYPE_DOOR && nTargetType & 16) - { - SendMessageToPC(oPC, "You cannot target doors"); - return FALSE; - } - else if(nObjectType == OBJECT_TYPE_PLACEABLE && nTargetType & 32) - { - SendMessageToPC(oPC, "You cannot target placeables"); - return FALSE; - } - } - else if(nTargetType & 4) - { - SendMessageToPC(oPC, "You cannot target locations"); - return FALSE; - } - return TRUE; -} - -// Classes using new spellbook systems are handeled separately -int GetIsBioDivineClass(int nClass) -{ - return nClass == CLASS_TYPE_CLERIC - || nClass == CLASS_TYPE_DRUID - || nClass == CLASS_TYPE_PALADIN - || nClass == CLASS_TYPE_UR_PRIEST - || nClass == CLASS_TYPE_RANGER; -} - -void CastDomainSpell(object oPC, int nSlot, int nLevel) -{ - if(GetLocalInt(oPC, "DomainCastSpell" + IntToString(nLevel))) //Already cast a spell of this level? - { - FloatingTextStringOnCreature("You have already cast your domain spell for level " + IntToString(nLevel), oPC, FALSE); - return; - } - - int nSpell = GetDomainSpell(GetBonusDomain(oPC, nSlot), nLevel, oPC); - // If there is no spell for that level, you cant cast it. - if(nSpell == -1) - return; - - // Subradial spells are handled through conversation - int bSubRadial = Get2DACache("spells", "SubRadSpell1", nSpell) != ""; - - // Domain casting feats use generic targeting, so check if spell can be cast at selected target - object oTarget = GetSpellTargetObject(); - if(!bSubRadial && !TestSpellTarget(oPC, oTarget, nSpell)) - return; - - int nClass, nCount, nMetamagic = METAMAGIC_NONE; - - // Mystic is a special case - checked first - if(GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) || GetLevelByClass(CLASS_TYPE_NIGHTSTALKER, oPC)) - { - // Mystics can use metamagic with domain spells - nClass = GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) ? CLASS_TYPE_MYSTIC : CLASS_TYPE_NIGHTSTALKER; - nMetamagic = GetLocalInt(oPC, "MetamagicFeatAdjust"); - int nSpellLevel = nLevel; - if(nMetamagic) - { - //Need to check if metamagic can be applied to a spell - int nMetaTest; - int nMetaType = HexToInt(Get2DACache("spells", "MetaMagic", nSpell)); - - switch(nMetamagic) - { - case METAMAGIC_NONE: nMetaTest = 1; break; //no need to change anything - case METAMAGIC_EMPOWER: nMetaTest = nMetaType & 1; nSpellLevel += 2; break; - case METAMAGIC_EXTEND: nMetaTest = nMetaType & 2; nSpellLevel += 1; break; - case METAMAGIC_MAXIMIZE: nMetaTest = nMetaType & 4; nSpellLevel += 3; break; - case METAMAGIC_QUICKEN: nMetaTest = nMetaType & 8; nSpellLevel += 4; break; - case METAMAGIC_SILENT: nMetaTest = nMetaType & 16; nSpellLevel += 1; break; - case METAMAGIC_STILL: nMetaTest = nMetaType & 32; nSpellLevel += 1; break; - } - if(!nMetaTest)//can't use selected metamagic with this spell - { - nMetamagic = METAMAGIC_NONE; - ActionDoCommand(SendMessageToPC(oPC, "You can't use "+GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpell)))+"with selected metamagic.")); - nSpellLevel = nLevel; - } - else if(nLevel > 9)//now test the spell level - { - nMetamagic = METAMAGIC_NONE; - ActionDoCommand(SendMessageToPC(oPC, "Modified spell level is to high! Casting spell without metamagic")); - nSpellLevel = nLevel; - } - else if(GetLocalInt(oPC, "PRC_metamagic_state") == 1) - SetLocalInt(oPC, "MetamagicFeatAdjust", 0); - } - - nCount = persistant_array_get_int(oPC, "NewSpellbookMem_" + IntToString(CLASS_TYPE_MYSTIC), nSpellLevel); - // we can't cast metamagiced version of the spell - assuming that player want to cast the spell anyway - if(!nCount) - nCount = persistant_array_get_int(oPC, "NewSpellbookMem_" + IntToString(CLASS_TYPE_MYSTIC), nLevel); - // Do we have slots available? - if(nCount) - { - // Prepare to cast the spell - nLevel = nSpellLevel;//correct the spell level if we're using metamagic - SetLocalInt(oPC, "NSB_Class", nClass); - SetLocalInt(oPC, "NSB_SpellLevel", nLevel); - } - } - - // checking 'newspellbook' classes is much faster than checking bioware spellbooks - if(!nCount) - { - int n; - for(n = 1; n < 8; n++) - { - nClass = GetClassByPosition(n, oPC); - - // Check to see if you can burn a spell of that slot or if the person has already - // cast all of their level X spells for the day - if(!GetIsBioDivineClass(nClass)) - { - int nSpellbook = GetSpellbookTypeForClass(nClass); - if(nSpellbook == SPELLBOOK_TYPE_SPONTANEOUS) - { - nCount = persistant_array_get_int(oPC, "NewSpellbookMem_" + IntToString(nClass), nLevel); - if(nCount) - {// Prepare to cast the spell - SetLocalInt(oPC, "NSB_Class", nClass); - SetLocalInt(oPC, "NSB_SpellLevel", nLevel); - } - } - else if(nSpellbook == SPELLBOOK_TYPE_PREPARED) - { - string sArray = "NewSpellbookMem_"+IntToString(nClass); - string sIDX = "SpellbookIDX" + IntToString(nLevel) + "_" + IntToString(nClass); - int i, nSpellbookID, nMax = persistant_array_get_size(oPC, sIDX); - for(i = 0; i < nMax; i++) - { - nSpellbookID = persistant_array_get_int(oPC, sIDX, i); - nCount = persistant_array_get_int(oPC, sArray, nSpellbookID); - if(nCount) - { - SetLocalInt(oPC, "NSB_Class", nClass); - SetLocalInt(oPC, "NSB_SpellbookID", nSpellbookID); - break; - } - } - } - } - if(nCount) - //we have found valid spell slot, no point in running this loop again - break; - } - } - - // test bioware spellbooks - if(!nCount) - { - nCount = GetBurnableSpell(oPC, nLevel) + 1;//fix for Acid Fog spell - if(nCount) - { - SetLocalInt(oPC, "Domain_BurnableSpell", nCount); - nClass = GetPrimaryDivineClass(oPC); - } - } - - //No spell left to burn? Tell the player that. - if(!nCount) - { - FloatingTextStringOnCreature("You have no spells left to trade for a domain spell.", oPC, FALSE); - return; - } - - SetLocalInt(oPC, "DomainCast", nLevel); - if(bSubRadial) - { - SetLocalInt(oPC, "DomainOrigSpell", nSpell); - SetLocalInt(oPC, "DomainCastClass", nClass); - SetLocalObject(oPC, "DomainTarget", oTarget); - SetLocalLocation(oPC, "DomainTarget", GetSpellTargetLocation()); - StartDynamicConversation("prc_domain_conv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); - } - else - { - if(nMetamagic & METAMAGIC_QUICKEN) - { - //Adding Auto-Quicken III for one round - deleted after casting is finished. - object oSkin = GetPCSkin(oPC); - int nCastDur = StringToInt(Get2DACache("spells", "ConjTime", nSpell)) + StringToInt(Get2DACache("spells", "CastTime", nSpell)); - itemproperty ipAutoQuicken = ItemPropertyBonusFeat(IP_CONST_NSB_AUTO_QUICKEN); - ActionDoCommand(AddItemProperty(DURATION_TYPE_TEMPORARY, ipAutoQuicken, oSkin, nCastDur/1000.0f)); - } - int nDC = 10 + nLevel + GetDCAbilityModForClass(nClass, oPC); - ActionCastSpell(nSpell, 0, nDC, 0, nMetamagic, nClass, FALSE, FALSE, OBJECT_INVALID, FALSE); - ActionDoCommand(DeleteLocalInt(oPC, "DomainCast")); - } -} - -int GetDomainSpell(int nDomain, int nLevel, object oPC) -{ - // The -1 on nDomains is to adjust from a base 1 to a base 0 system. - string sSpell = Get2DACache("prc_domains", "Level_" + IntToString(nLevel), (nDomain - 1)); - if (DEBUG) DoDebug("Domain Spell: " + sSpell); - //if (DEBUG) DoDebug("GetDomainSpell has fired"); - int nSpell = -1; - if(sSpell == "") - { - FloatingTextStringOnCreature("You do not have a domain spell of that level.", oPC, FALSE); - //int nFeat = SpellLevelToFeat(nLevel); - //IncrementRemainingFeatUses(oPC, nFeat); - } - else - { - nSpell = StringToInt(sSpell); - } - - return nSpell; -} - -int SpellLevelToFeat(int nLevel) -{ - switch(nLevel) - { - case 1: return FEAT_CAST_DOMAIN_LEVEL_ONE; - case 2: return FEAT_CAST_DOMAIN_LEVEL_TWO; - case 3: return FEAT_CAST_DOMAIN_LEVEL_THREE; - case 4: return FEAT_CAST_DOMAIN_LEVEL_FOUR; - case 5: return FEAT_CAST_DOMAIN_LEVEL_FIVE; - case 6: return FEAT_CAST_DOMAIN_LEVEL_SIX; - case 7: return FEAT_CAST_DOMAIN_LEVEL_SEVEN; - case 8: return FEAT_CAST_DOMAIN_LEVEL_EIGHT; - case 9: return FEAT_CAST_DOMAIN_LEVEL_NINE; - } - - return -1; -} - -string GetDomainName(int nDomain) -{ - string sName; - // Check that the domain slot is not empty - if(nDomain) - { - sName = Get2DACache("prc_domains", "Name", (nDomain - 1)); - sName = GetStringByStrRef(StringToInt(sName)); - } - else - sName = GetStringByStrRef(6497); // "Empty Slot" - - return sName; -} - -void CheckBonusDomains(object oPC) -{ - int nBonusDomain, nDomainFeat; - int nSlot = 1; - while(nSlot < 6) - { - nBonusDomain = GetBonusDomain(oPC, nSlot); - nDomainFeat = GetDomainFeat(nBonusDomain); - if(!GetHasFeat(nDomainFeat, oPC)) SetPersistantLocalInt(oPC, "PRCBonusDomain" + IntToString(nSlot), 0); - //SendMessageToPC(oPC, "PRCBonusDomain"+IntToString(nSlot)" = "+IntToString(nBonusDomain)); - //SendMessageToPC(oPC, "PRCBonusDomain"+IntToString(nSlot)" feat = "+IntToString(GetDomainFeat(nDomainFeat))); - nSlot += 1; - } - - if (GetHasFeat(FEAT_BONUS_DOMAIN_AIR, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_AIR); - if (GetHasFeat(FEAT_BONUS_DOMAIN_ANIMAL, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_ANIMAL); - if (GetHasFeat(FEAT_BONUS_DOMAIN_DEATH, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_DEATH); - if (GetHasFeat(FEAT_BONUS_DOMAIN_DESTRUCTION, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_DESTRUCTION); - if (GetHasFeat(FEAT_BONUS_DOMAIN_EARTH, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_EARTH); - if (GetHasFeat(FEAT_BONUS_DOMAIN_EVIL, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_EVIL); - if (GetHasFeat(FEAT_BONUS_DOMAIN_FIRE, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_FIRE); - if (GetHasFeat(FEAT_BONUS_DOMAIN_GOOD, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_GOOD); - if (GetHasFeat(FEAT_BONUS_DOMAIN_HEALING, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_HEALING); - if (GetHasFeat(FEAT_BONUS_DOMAIN_KNOWLEDGE, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_KNOWLEDGE); - if (GetHasFeat(FEAT_BONUS_DOMAIN_MAGIC, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_MAGIC); - if (GetHasFeat(FEAT_BONUS_DOMAIN_PLANT, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_PLANT); - if (GetHasFeat(FEAT_BONUS_DOMAIN_PROTECTION, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_PROTECTION); - if (GetHasFeat(FEAT_BONUS_DOMAIN_STRENGTH, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_STRENGTH); - if (GetHasFeat(FEAT_BONUS_DOMAIN_SUN, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_SUN); - if (GetHasFeat(FEAT_BONUS_DOMAIN_TRAVEL, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_TRAVEL); - if (GetHasFeat(FEAT_BONUS_DOMAIN_TRICKERY, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_TRICKERY); - if (GetHasFeat(FEAT_BONUS_DOMAIN_WAR, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_WAR); - if (GetHasFeat(FEAT_BONUS_DOMAIN_WATER, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_WATER); - if (GetHasFeat(FEAT_BONUS_DOMAIN_DARKNESS, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_DARKNESS); - if (GetHasFeat(FEAT_BONUS_DOMAIN_STORM, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_STORM); - if (GetHasFeat(FEAT_BONUS_DOMAIN_METAL, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_METAL); - if (GetHasFeat(FEAT_BONUS_DOMAIN_PORTAL, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_PORTAL); - if (GetHasFeat(FEAT_BONUS_DOMAIN_FORCE, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_FORCE); - if (GetHasFeat(FEAT_BONUS_DOMAIN_SLIME, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_SLIME); - if (GetHasFeat(FEAT_BONUS_DOMAIN_TYRANNY, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_TYRANNY); - if (GetHasFeat(FEAT_BONUS_DOMAIN_DOMINATION, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_DOMINATION); - if (GetHasFeat(FEAT_BONUS_DOMAIN_SPIDER, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_SPIDER); - if (GetHasFeat(FEAT_BONUS_DOMAIN_UNDEATH, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_UNDEATH); - if (GetHasFeat(FEAT_BONUS_DOMAIN_TIME, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_TIME); - if (GetHasFeat(FEAT_BONUS_DOMAIN_DWARF, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_DWARF); - if (GetHasFeat(FEAT_BONUS_DOMAIN_CHARM, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_CHARM); - if (GetHasFeat(FEAT_BONUS_DOMAIN_ELF, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_ELF); - if (GetHasFeat(FEAT_BONUS_DOMAIN_FAMILY, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_FAMILY); - if (GetHasFeat(FEAT_BONUS_DOMAIN_FATE, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_FATE); - if (GetHasFeat(FEAT_BONUS_DOMAIN_GNOME, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_GNOME); - if (GetHasFeat(FEAT_BONUS_DOMAIN_ILLUSION, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_ILLUSION); - if (GetHasFeat(FEAT_BONUS_DOMAIN_HATRED, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_HATRED); - if (GetHasFeat(FEAT_BONUS_DOMAIN_HALFLING, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_HALFLING); - if (GetHasFeat(FEAT_BONUS_DOMAIN_NOBILITY, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_NOBILITY); - if (GetHasFeat(FEAT_BONUS_DOMAIN_OCEAN, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_OCEAN); - if (GetHasFeat(FEAT_BONUS_DOMAIN_ORC, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_ORC); - if (GetHasFeat(FEAT_BONUS_DOMAIN_RENEWAL, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_RENEWAL); - if (GetHasFeat(FEAT_BONUS_DOMAIN_RETRIBUTION, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_RETRIBUTION); - if (GetHasFeat(FEAT_BONUS_DOMAIN_RUNE, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_RUNE); - if (GetHasFeat(FEAT_BONUS_DOMAIN_SPELLS, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_SPELLS); - if (GetHasFeat(FEAT_BONUS_DOMAIN_SCALEYKIND, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_SCALEYKIND); - if (GetHasFeat(FEAT_BONUS_DOMAIN_BLIGHTBRINGER, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_BLIGHTBRINGER); - if (GetHasFeat(FEAT_BONUS_DOMAIN_DRAGON, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_DRAGON); - if (GetHasFeat(FEAT_BONUS_DOMAIN_COLD, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_COLD); - if (GetHasFeat(FEAT_BONUS_DOMAIN_WINTER, oPC)) AddBonusDomain(oPC, PRC_DOMAIN_WINTER); - - //if (DEBUG) FloatingTextStringOnCreature("Check Bonus Domains is running", oPC, FALSE); -} - -int GetBurnableSpell(object oPC, int nLevel) -{ - int nBurnableSpell = -1; - - if (nLevel == 1) nBurnableSpell = GetBestL1Spell(oPC, nBurnableSpell); - else if (nLevel == 2) nBurnableSpell = GetBestL2Spell(oPC, nBurnableSpell); - else if (nLevel == 3) nBurnableSpell = GetBestL3Spell(oPC, nBurnableSpell); - else if (nLevel == 4) nBurnableSpell = GetBestL4Spell(oPC, nBurnableSpell); - else if (nLevel == 5) nBurnableSpell = GetBestL5Spell(oPC, nBurnableSpell); - else if (nLevel == 6) nBurnableSpell = GetBestL6Spell(oPC, nBurnableSpell); - else if (nLevel == 7) nBurnableSpell = GetBestL7Spell(oPC, nBurnableSpell); - else if (nLevel == 8) nBurnableSpell = GetBestL8Spell(oPC, nBurnableSpell); - else if (nLevel == 9) nBurnableSpell = GetBestL9Spell(oPC, nBurnableSpell); - - return nBurnableSpell; -} - -int GetDomainFeat(int nDomain) -{ - // The -1 on nDomain is to adjust from a base 1 to a base 0 system. - // Returns the domain power feat - return StringToInt(Get2DACache("domains", "GrantedFeat", nDomain - 1)); -} - -int GetDomainFeatUsesPerDay(int nFeat, object oPC) -{ - int nUses = StringToInt(Get2DACache("feat", "USESPERDAY", nFeat)); - // These are the domains that have ability based uses per day - if (nUses == 33) - { - // The Strength domain, which uses Strength when the Cleric has Kord levels - // Without Kord levels, its 1 use per day - if(nFeat == FEAT_STRENGTH_DOMAIN_POWER) - { - nUses = 1; - if(GetLevelByClass(CLASS_TYPE_MIGHTY_CONTENDER_KORD, oPC)) nUses = GetAbilityModifier(ABILITY_STRENGTH, oPC); - // Catching exceptions - if(nUses < 1) nUses = 1; - } - if(nFeat == FEAT_SUN_DOMAIN_POWER) - { - if(GetHasFeat(FEAT_BONUS_DOMAIN_SUN, oPC) && GetLevelByClass(CLASS_TYPE_MYSTIC, oPC)) - { - nUses = GetHasFeat(FEAT_EXTRA_TURNING, oPC) ? 7 : 3; - nUses += GetAbilityModifier(ABILITY_CHARISMA, oPC); - } - else - nUses = 1; - } - - // All other ones so far are the Charisma based turning domains - nUses = 3 + GetAbilityModifier(ABILITY_CHARISMA, oPC); - } - - return nUses; -} - -int DecrementDomainUses(int nDomain, object oPC) -{ - int nReturn = TRUE; - int nUses = GetLocalInt(oPC, "BonusDomainUsesPerDay" + GetDomainName(nDomain)); - // If there is still a valid use left, remove it - if (nUses >= 1) SetLocalInt(oPC, "BonusDomainUsesPerDay" + GetDomainName(nDomain), (nUses - 1)); - // Tell the player how many uses he has left - else // He has no more uses for the day - { - nReturn = FALSE; - } - - FloatingTextStringOnCreature("You have " + IntToString(nUses - 1) + " uses per day left of the " + GetDomainName(nDomain) + " power.", oPC, FALSE); - - return nReturn; -} - -int GetTurningDomain(int nSpell) -{ - switch(nSpell) - { - case SPELL_TURN_REPTILE: return PRC_DOMAIN_SCALEYKIND; - case SPELL_TURN_OOZE: return PRC_DOMAIN_SLIME; - case SPELL_TURN_SPIDER: return PRC_DOMAIN_SPIDER; - case SPELL_TURN_PLANT: return PRC_DOMAIN_PLANT; - case SPELL_TURN_AIR: return PRC_DOMAIN_AIR; - case SPELL_TURN_EARTH: return PRC_DOMAIN_EARTH; - case SPELL_TURN_FIRE: return PRC_DOMAIN_FIRE; - case SPELL_TURN_WATER: return PRC_DOMAIN_WATER; - case SPELL_TURN_BLIGHTSPAWNED: return PRC_DOMAIN_BLIGHTBRINGER; - } - - return -1; -} - -int GetHasDomain(object oPC, int nDomain) -{ - // Get the domain power feat for the appropriate domain - int nFeat = GetDomainFeat(nDomain); - - return GetHasFeat(nFeat, oPC); -} - -void BonusDomainRest(object oPC) -{ - // Bonus Domain ints that limit you to casting 1/day per level - int i; - for (i = 1; i < 10; i++) - { - DeleteLocalInt(oPC, "DomainCastSpell" + IntToString(i)); - } - - // This is code to stop you from using the Domain per day abilities more than you should be able to - int i2; - // Highest domain constant is 59 - for (i2 = 1; i2 < 60; i2++) - { - // This is to ensure they only get the ints set for the domains they do have - if (GetHasDomain(oPC, i2)) - { - // Store the number of uses a day here - SetLocalInt(oPC, "BonusDomainUsesPerDay" + GetDomainName(i2), GetDomainFeatUsesPerDay(GetDomainFeat(i2), oPC)); - } - } -} - -int GetDomainCasterLevel(object oPC) -{ - return GetLevelByClass(CLASS_TYPE_CLERIC, oPC) - + GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) - + GetLevelByClass(CLASS_TYPE_SHAMAN, oPC) - + GetLevelByClass(CLASS_TYPE_TEMPLAR, oPC) - + GetLevelByClass(CLASS_TYPE_BLIGHTLORD, oPC) - + GetLevelByClass(CLASS_TYPE_CONTEMPLATIVE, oPC) - + GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oPC); -} \ No newline at end of file diff --git a/trunk/include/prc_inc_function.nss b/trunk/include/prc_inc_function.nss deleted file mode 100644 index 2fa5d15c..00000000 --- a/trunk/include/prc_inc_function.nss +++ /dev/null @@ -1,1837 +0,0 @@ -//:://///////////////////////////////////////////// -//:: [PRC Feat Router] -//:: [inc_prc_function.nss] -//::////////////////////////////////////////////// -//:: This file serves as a hub for the various -//:: PRC passive feat functions. If you need to -//:: add passive feats for a new PRC, link them here. -//:: -//:: This file also contains a few multi-purpose -//:: PRC functions that need to be included in several -//:: places, ON DIFFERENT PRCS. Make local include files -//:: for any functions you use ONLY on ONE PRC. -//::////////////////////////////////////////////// -//:: Created By: Aaon Graywolf -//:: Created On: Dec 19, 2003 -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/10 - -//-------------------------------------------------------------------------- -// This is the "event" that is called to re-evalutate PRC bonuses. Currently -// it is fired by OnEquip, OnUnequip and OnLevel. If you want to move any -// classes into this event, just copy the format below. Basically, this function -// is meant to keep the code looking nice and clean by routing each class's -// feats to their own self-contained script -//-------------------------------------------------------------------------- - -//:: Test Void -//void main (){} - - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -const int TEMPLATE_SLA_START = 16304; -const int TEMPLATE_SLA_END = 16400; - -const string PRC_ScrubPCSkin_Generation = "PRC_ScrubPCSkin_Generation"; -const string PRC_EvalPRCFeats_Generation = "PRC_EvalPRCFeats_Generation"; - - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -void EvalPRCFeats(object oPC); - -int BlastInfidelOrFaithHeal(object oCaster, object oTarget, int iEnergyType, int iDisplayFeedback); - -void ScrubPCSkin(object oPC, object oSkin); - -void DeletePRCLocalInts(object oSkin); - -void DelayedAddIPFeats(int nExpectedGeneration, object oPC); - -void DelayedReApplyUnhealableAbilityDamage(int nExpectedGeneration, object oPC); - -int nbWeaponFocus(object oPC); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -// Minimalist includes -#include "prc_inc_util" -#include "prc_inc_spells" -#include "prc_inc_stunfist" -#include "inc_nwnx_funcs" -#include "prc_template_con" - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -void DeleteCharacterData(object oPC) -{ - DeletePersistantLocalString(oPC, "PRC_Class_Script1"); - DeletePersistantLocalString(oPC, "PRC_Class_Script2"); - DeletePersistantLocalString(oPC, "PRC_Class_Script3"); - DeletePersistantLocalString(oPC, "PRC_Class_Script4"); - DeletePersistantLocalString(oPC, "PRC_Class_Script5"); - DeletePersistantLocalString(oPC, "PRC_Class_Script6"); - DeletePersistantLocalString(oPC, "PRC_Class_Script7"); - DeletePersistantLocalString(oPC, "PRC_Class_Script8"); - DeletePersistantLocalInt(oPC, "PRC_Class_Data"); -} - -void SetupCharacterData(object oPC) -{ - // iData format: - // 0x01 - run alternate magic system setup - // 0x02 - add new metamagic feats for spontaneous casters - // 0x04 - run reduced arcane spell failure check - // use bitwise to combine flags - - int i, iData, iShifting; - for(i = 1; i <= 8; i++) - { - int nClassType = GetClassByPosition(i, oPC); - if(nClassType != CLASS_TYPE_INVALID) - { - string sScript; - switch(nClassType) - { - case CLASS_TYPE_ABJURANT_CHAMPION: sScript = "prc_abchamp"; break; - case CLASS_TYPE_ACOLYTE: sScript = "prc_acolyte"; break; - case CLASS_TYPE_ALIENIST: sScript = "prc_alienist"; break; - case CLASS_TYPE_ARCANE_DUELIST: sScript = "prc_arcduel"; break; - case CLASS_TYPE_ARCHIVIST: sScript = "prc_archivist"; iData |= 0x01; break; - case CLASS_TYPE_ASSASSIN: iData |= 0x03; break; - case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break; - case CLASS_TYPE_BARD: iData |= 0x07; break; - case CLASS_TYPE_BATTLESMITH: sScript = "prc_battlesmith"; break; - case CLASS_TYPE_BEGUILER: iData |= 0x03; break; - case CLASS_TYPE_BINDER: sScript = "bnd_binder"; break; - case CLASS_TYPE_BFZ: sScript = "prc_bfz"; break; - case CLASS_TYPE_BLACK_BLOOD_CULTIST: sScript = "prc_bbc"; break; - case CLASS_TYPE_BLACKGUARD: sScript = "prc_blackguard"; break; - case CLASS_TYPE_BLADESINGER: sScript = "prc_bladesinger"; iData |= 0x04; break; - case CLASS_TYPE_BLIGHTLORD: sScript = "prc_blightlord"; break; - case CLASS_TYPE_BLOODCLAW_MASTER: sScript = "tob_bloodclaw"; break; - case CLASS_TYPE_BONDED_SUMMONNER: sScript = "prc_bondedsumm"; break; - case CLASS_TYPE_CELEBRANT_SHARESS: iData |= 0x03; break; - case CLASS_TYPE_CHILD_OF_NIGHT: sScript = "shd_childnight"; break; - case CLASS_TYPE_COC: sScript = "prc_coc"; break; - case CLASS_TYPE_COMBAT_MEDIC: sScript = "prc_cbtmed"; break; - case CLASS_TYPE_CONTEMPLATIVE: sScript = "prc_contemplate"; break; - case CLASS_TYPE_CRUSADER: sScript = "tob_crusader"; iData |= 0x01; break; - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: sScript = "prc_shatterdpeak"; break; - case CLASS_TYPE_CW_SAMURAI: sScript = "prc_cwsamurai"; break; - case CLASS_TYPE_DEEPSTONE_SENTINEL: sScript = "tob_deepstone"; break; - case CLASS_TYPE_DIAMOND_DRAGON: sScript = "psi_diadra"; break; - case CLASS_TYPE_DISC_BAALZEBUL: sScript = "prc_baalzebul"; break; - case CLASS_TYPE_DISCIPLE_OF_ASMODEUS: sScript = "prc_discasmodeus"; break; - case CLASS_TYPE_DISCIPLE_OF_MEPH: sScript = "prc_discmeph"; break; - case CLASS_TYPE_DISPATER: sScript = "prc_dispater"; break; - case CLASS_TYPE_DRAGON_DEVOTEE: sScript = "prc_dragdev"; break; - case CLASS_TYPE_DRAGON_DISCIPLE: sScript = "prc_dradis"; break; - case CLASS_TYPE_DRAGON_SHAMAN: sScript = "prc_dragonshaman"; break; - case CLASS_TYPE_DRAGONFIRE_ADEPT: sScript = "inv_drgnfireadpt"; iData |= 0x01; break; - case CLASS_TYPE_DREAD_NECROMANCER: sScript = "prc_dreadnecro"; iData |= 0x03; break; - case CLASS_TYPE_DRUID: iShifting = TRUE; break; - case CLASS_TYPE_DRUNKEN_MASTER: sScript = "prc_drunk"; break; - case CLASS_TYPE_DUELIST: sScript = "prc_duelist"; break; - case CLASS_TYPE_DUSKBLADE: sScript = "prc_duskblade"; iData |= 0x03; break; - case CLASS_TYPE_ENLIGHTENEDFIST: sScript = "prc_enlfis"; break; - case CLASS_TYPE_ELEMENTAL_SAVANT: sScript = "prc_elemsavant"; break; - case CLASS_TYPE_ETERNAL_BLADE: sScript = "tob_eternalblade"; break; - case CLASS_TYPE_FACTOTUM: sScript = "prc_factotum"; break; - case CLASS_TYPE_FAVOURED_SOUL: sScript = "prc_favouredsoul"; iData |= 0x03; break; - case CLASS_TYPE_FIST_OF_ZUOKEN: sScript = "psi_zuoken"; iData |= 0x01; break; - case CLASS_TYPE_FOE_HUNTER: sScript = "prc_foe_hntr"; break; - case CLASS_TYPE_FORESTMASTER: sScript = "prc_forestmaster"; break; - case CLASS_TYPE_FORSAKER: sScript = "prc_forsaker"; break; - case CLASS_TYPE_FRE_BERSERKER: sScript = "prc_frebzk"; break; - case CLASS_TYPE_FROSTRAGER: sScript = "prc_frostrager"; break; - case CLASS_TYPE_FROST_MAGE: sScript = "prc_frostmage"; break; - case CLASS_TYPE_HALFLING_WARSLINGER: sScript = "prc_warsling"; break; - case CLASS_TYPE_HARPER: iData |= 0x03; break; - case CLASS_TYPE_HEARTWARDER: sScript = "prc_heartwarder"; break; - case CLASS_TYPE_HENSHIN_MYSTIC: sScript = "prc_henshin"; break; - case CLASS_TYPE_HEXBLADE: iData |= 0x03; break; - case CLASS_TYPE_HEXTOR: sScript = "prc_hextor"; break; - case CLASS_TYPE_IAIJUTSU_MASTER: sScript = "prc_iaijutsu_mst"; break; - case CLASS_TYPE_INCARNATE: sScript = "moi_incarnate"; break; - case CLASS_TYPE_INCARNUM_BLADE: sScript = "moi_iblade"; break; - case CLASS_TYPE_INITIATE_DRACONIC: sScript = "prc_initdraconic"; break; - case CLASS_TYPE_IRONMIND: sScript = "psi_ironmind"; break; - case CLASS_TYPE_IRONSOUL_FORGEMASTER: sScript = "moi_ironsoul"; break; - case CLASS_TYPE_JADE_PHOENIX_MAGE: sScript = "tob_jadephoenix"; break; - case CLASS_TYPE_JUDICATOR: sScript = "prc_judicator"; break; - case CLASS_TYPE_JUSTICEWW: iData |= 0x03; break; - case CLASS_TYPE_KNIGHT: sScript = "prc_knight"; break; - case CLASS_TYPE_KNIGHT_CHALICE: sScript = "prc_knghtch"; break; - case CLASS_TYPE_KNIGHT_WEAVE: iData |= 0x03; break; - case CLASS_TYPE_KNIGHT_SACRED_SEAL: sScript = "bnd_kss"; break; - case CLASS_TYPE_LASHER: sScript = "prc_lasher"; break; - case CLASS_TYPE_LEGENDARY_DREADNOUGHT: sScript = "prc_legendread"; break; - case CLASS_TYPE_LICH: sScript = "pnp_lich_level"; break; - case CLASS_TYPE_MAGEKILLER: sScript = "prc_magekill"; break; - case CLASS_TYPE_MASTER_HARPER: sScript = "prc_masterh"; break; - case CLASS_TYPE_MASTER_OF_NINE: sScript = "tob_masterofnine"; break; - case CLASS_TYPE_MASTER_OF_SHADOW: sScript = "shd_mastershadow"; break; - case CLASS_TYPE_MIGHTY_CONTENDER_KORD: sScript = "prc_contendkord"; break; - case CLASS_TYPE_MORNINGLORD: sScript = "prc_morninglord"; break; - case CLASS_TYPE_NIGHTSHADE: sScript = "prc_nightshade"; break; - case CLASS_TYPE_NINJA: sScript = "prc_ninjca"; break; - case CLASS_TYPE_OLLAM: sScript = "prc_ollam"; break; - case CLASS_TYPE_OOZEMASTER: sScript = "prc_oozemstr"; break; - case CLASS_TYPE_ORDER_BOW_INITIATE: sScript = "prc_ootbi"; break; - case CLASS_TYPE_PEERLESS: sScript = "prc_peerless"; break; - case CLASS_TYPE_PNP_SHIFTER : iShifting = TRUE; break; - case CLASS_TYPE_PRC_EYE_OF_GRUUMSH: sScript = "prc_eog"; break; - case CLASS_TYPE_PSION: iData |= 0x01; break; - case CLASS_TYPE_PSYWAR: iData |= 0x01; break; - case CLASS_TYPE_PSYCHIC_ROGUE: sScript = "psi_psyrogue"; iData |= 0x01; break; - case CLASS_TYPE_PYROKINETICIST: sScript = "psi_pyro"; break; - case CLASS_TYPE_RAGE_MAGE: iData |= 0x04; break; - case CLASS_TYPE_REAPING_MAULER : sScript = "prc_reapmauler"; break; - case CLASS_TYPE_RUBY_VINDICATOR: sScript = "tob_rubyknight"; break; - case CLASS_TYPE_RUNESCARRED: sScript = "prc_runescarred"; break; - case CLASS_TYPE_SACREDFIST: sScript = "prc_sacredfist"; break; - case CLASS_TYPE_SANCTIFIED_MIND: sScript = "psi_sancmind"; break; - case CLASS_TYPE_SAPPHIRE_HIERARCH: sScript = "moi_sapphire"; break; - case CLASS_TYPE_SCOUT: sScript = "prc_scout"; break; - case CLASS_TYPE_SERENE_GUARDIAN: sScript = "prc_sereneguard"; break; - case CLASS_TYPE_SHADOW_ADEPT: sScript = "prc_shadowadept"; break; - case CLASS_TYPE_SHADOWCASTER: sScript = "shd_shadowcaster"; iData |= 0x01; break; - case CLASS_TYPE_SHADOWSMITH: iData |= 0x01; break; - case CLASS_TYPE_SHADOW_SUN_NINJA: sScript = "tob_shadowsun"; break; - case CLASS_TYPE_SHADOWBLADE: sScript = "prc_sb_shdstlth"; break; - case CLASS_TYPE_SHADOWMIND: sScript = "psi_shadowmind"; break; - case CLASS_TYPE_SHADOWBANE_STALKER: sScript = "prc_shadstalker"; break; - case CLASS_TYPE_SHADOW_THIEF_AMN: sScript = "prc_amn"; break; - case CLASS_TYPE_SHAMAN: sScript = "prc_shaman"; break; - case CLASS_TYPE_SHINING_BLADE: sScript = "prc_sbheir"; break; - case CLASS_TYPE_SHOU: sScript = "prc_shou"; break; - case CLASS_TYPE_SKULLCLAN_HUNTER: sScript = "prc_skullclan"; break; - case CLASS_TYPE_SLAYER_OF_DOMIEL: sScript = "prc_slayerdomiel"; break; - case CLASS_TYPE_SOHEI: sScript = "prc_sohei"; break; - case CLASS_TYPE_SOLDIER_OF_LIGHT: sScript = "prc_soldoflight"; break; - case CLASS_TYPE_SORCERER: iData |= 0x03; break; - case CLASS_TYPE_SOULBORN: sScript = "moi_soulborn"; break; - case CLASS_TYPE_SOUL_EATER: iShifting = TRUE; break; - case CLASS_TYPE_SOULKNIFE: sScript = "psi_sk_clseval"; break; - case CLASS_TYPE_SPELLSWORD: sScript = "prc_spellswd"; iData |= 0x04; break; - case CLASS_TYPE_SPINEMELD_WARRIOR: sScript = "moi_spinemeld"; break; - case CLASS_TYPE_STORMLORD: sScript = "prc_stormlord"; break; - case CLASS_TYPE_SUBLIME_CHORD: sScript = "prc_schord"; iData |= 0x03; break; - case CLASS_TYPE_SUEL_ARCHANAMACH: iData |= 0x03; break; - case CLASS_TYPE_SWASHBUCKLER: sScript = "prc_swashbuckler"; break; - case CLASS_TYPE_SWIFT_WING: sScript = "prc_swiftwing"; break; - case CLASS_TYPE_SWORDSAGE: sScript = "tob_swordsage"; iData |= 0x01; break; - case CLASS_TYPE_TALON_OF_TIAMAT: sScript = "prc_talontiamat"; break; - case CLASS_TYPE_TEMPEST: sScript = "prc_tempest"; break; - case CLASS_TYPE_TEMPUS: sScript = "prc_battletempus"; break; - case CLASS_TYPE_TENEBROUS_APOSTATE: sScript = "bnd_tenebrous"; break; - case CLASS_TYPE_THAYAN_KNIGHT: sScript = "prc_thayknight"; break; - case CLASS_TYPE_THRALL_OF_GRAZZT_A: sScript = "tog"; break; - case CLASS_TYPE_THRALLHERD: sScript = "psi_thrallherd"; break; - case CLASS_TYPE_TOTEMIST: sScript = "moi_totemist"; break; - case CLASS_TYPE_TOTEM_RAGER: sScript = "moi_totemrager"; break; - case CLASS_TYPE_TRUENAMER: sScript = "true_truenamer"; iData |= 0x01; break; - case CLASS_TYPE_VASSAL: sScript = "prc_vassal"; break; - case CLASS_TYPE_VIGILANT: sScript = "prc_vigilant"; break; - case CLASS_TYPE_WARBLADE: sScript = "tob_warblade"; iData |= 0x01; break; - case CLASS_TYPE_WARCHIEF: sScript = "prc_warchief"; break; - case CLASS_TYPE_WARFORGED_JUGGERNAUT: sScript = "prc_juggernaut"; break; - case CLASS_TYPE_WARLOCK: sScript = "inv_warlock"; iData |= 0x01; break; - case CLASS_TYPE_WARMAGE: iData |= 0x03; break; - case CLASS_TYPE_WARMIND: sScript = "psi_warmind"; iData |= 0x01; break; - case CLASS_TYPE_WEREWOLF: sScript = "prc_werewolf"; break; - case CLASS_TYPE_WILDER: iData |= 0x01; break; - - // Races that can cast spells - case CLASS_TYPE_DRAGON: iData |= 0x03; break; - case CLASS_TYPE_SHAPECHANGER: iData |= 0x03; break; - case CLASS_TYPE_OUTSIDER: iData |= 0x03; break; - case CLASS_TYPE_ABERRATION: iData |= 0x03; break; - case CLASS_TYPE_MONSTROUS: iData |= 0x03; break; - case CLASS_TYPE_FEY: iData |= 0x03; break; - } - if(sScript != "") - SetPersistantLocalString(oPC, "PRC_Class_Script"+IntToString(i), sScript); - } - if (DEBUG) DoDebug("SetupCharacterData Class: " + IntToString(nClassType)); - if (DEBUG) DoDebug("SetupCharacterData Data: " + IntToString(iData)); - } - if(iData) - SetPersistantLocalInt(oPC, "PRC_Class_Data", iData); - - if(iShifting) - SetPersistantLocalInt(oPC, "PRC_UNI_SHIFT_SCRIPT", 1); - - //Setup class info for onleveldown script - int nCharData = ((GetClassByPosition(8, oPC) & 0xFF) << 56) | - ((GetClassByPosition(7, oPC) & 0xFF) << 48) | - ((GetClassByPosition(5, oPC) & 0xFF) << 40) | - ((GetClassByPosition(5, oPC) & 0xFF) << 32) | - ((GetClassByPosition(4, oPC) & 0xFF) << 24) | - ((GetClassByPosition(3, oPC) & 0xFF) << 16) | - ((GetClassByPosition(2, oPC) & 0xFF) << 8) | - (GetClassByPosition(1, oPC) & 0xFF); - - SetPersistantLocalInt(oPC, "PRC_Character_Data", nCharData); -} - -void DelayedExecuteScript(int nExpectedGeneration, string sScriptName, object oPC) -{ - if (nExpectedGeneration != GetLocalInt(oPC, PRC_EvalPRCFeats_Generation)) - { - //Generation has changed, so don't apply the effect - return; - } - ExecuteScript(sScriptName, oPC); -} - -void DelayedReApplyUnhealableAbilityDamage(int nExpectedGeneration, object oPC) -{ - if (nExpectedGeneration != GetLocalInt(oPC, PRC_ScrubPCSkin_Generation)) - { - //Generation has changed, so don't apply the effect - return; - } - ReApplyUnhealableAbilityDamage(oPC); -} - -int ToBFeats(object oPC) -{ - if(GetHasFeat(FEAT_SHADOW_BLADE, oPC) || - GetHasFeat(FEAT_RAPID_ASSAULT, oPC) || - GetHasFeat(FEAT_DESERT_WIND_DODGE, oPC) || - GetHasFeat(FEAT_DESERT_FIRE, oPC) || - GetHasFeat(FEAT_IRONHEART_AURA, oPC) || - GetHasFeat(FEAT_SHADOW_TRICKSTER, oPC) || - GetHasFeat(FEAT_WHITE_RAVEN_DEFENSE, oPC) || - GetHasFeat(FEAT_DEVOTED_BULWARK, oPC) || - GetHasFeat(FEAT_SNAP_KICK, oPC) || - GetHasFeat(FEAT_THREE_MOUNTAINS, oPC) || - GetHasFeat(FEAT_VAE_SCHOOL, oPC) || - GetHasFeat(FEAT_INLINDL_SCHOOL, oPC) || - GetHasFeat(FEAT_XANIQOS_SCHOOL, oPC) || - GetHasFeat(FEAT_SHIELD_WALL, oPC) || - GetHasFeat(FEAT_CROSSBOW_SNIPER, oPC) || - GetHasFeat(FEAT_CRESCENT_MOON, oPC) || - GetHasFeat(FEAT_QUICK_STAFF, oPC) || - GetHasFeat(FEAT_BEAR_FANG, oPC) || - GetHasFeat(FEAT_IMPROVED_RAPID_SHOT, oPC) || - GetHasFeat(FEAT_DIRE_FLAIL_SMASH, oPC) || - GetHasFeat(FEAT_SHIELD_SPECIALIZATION_LIGHT, oPC) || - GetHasFeat(FEAT_SHIELD_SPECIALIZATION_HEAVY, oPC) || - GetHasFeat(FEAT_FOCUSED_SHIELD, oPC) || - GetHasFeat(FEAT_SHIELDMATE, oPC) || - GetHasFeat(FEAT_IMPROVED_SHIELDMATE, oPC) || - GetHasFeat(FEAT_SHIELDED_CASTING, oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_DESERT_WIND , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_DEVOTED_SPIRIT, oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_DIAMOND_MIND , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_IRON_HEART , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_SETTING_SUN , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_SHADOW_HAND , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_STONE_DRAGON , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_TIGER_CLAW , oPC) || - GetHasFeat(FEAT_BLADE_MEDITATION_WHITE_RAVEN , oPC) || - GetRacialType(oPC) == RACIAL_TYPE_RETH_DEKALA || - GetRacialType(oPC) == RACIAL_TYPE_HADRIMOI) - return TRUE; - - return FALSE; -} - -void EvalPRCFeats(object oPC) -{ - // Player is currently making character in ConvoCC - // don't run EvalPRCFeats() yet - if(oPC == GetLocalObject(GetModule(), "ccc_active_pc")) - return; - - int nGeneration = PRC_NextGeneration(GetLocalInt(oPC, PRC_EvalPRCFeats_Generation)); - if (DEBUG > 1) DoDebug("EvalPRCFeats Generation: " + IntToString(nGeneration)); - SetLocalInt(oPC, PRC_EvalPRCFeats_Generation, nGeneration); - - //permanent ability changes - if(GetPRCSwitch(PRC_NWNX_FUNCS)) - ExecuteScript("prc_nwnx_funcs", oPC); - - //Add IP Feats to the hide - DelayCommand(0.0f, DelayedAddIPFeats(nGeneration, oPC)); - - // If there is a bonus domain, it will always be in the first slot, so just check that. - // It also runs things that clerics with those domains need - if (GetPersistantLocalInt(oPC, "PRCBonusDomain1") > 0 || GetLevelByClass(CLASS_TYPE_CLERIC, oPC)) - DelayCommand(0.1f, ExecuteScript("prc_domain_skin", oPC)); - - // special add atk bonus equal to Enhancement - ExecuteScript("ft_sanctmartial", oPC); - - //hook in the weapon size restrictions script - //ExecuteScript("prc_restwpnsize", oPC); - - //Route the event to the appropriate class specific scripts - int i, iData; - string sScript; - for (i = 1; i <= 3; i++) - { - sScript = GetPersistantLocalString(oPC, "PRC_Class_Script"+IntToString(i)); - if(sScript != "") - { - if (DEBUG) DoDebug("PRC_Class_Script: "+sScript); - ExecuteScript(sScript, oPC); - } - } - - iData = GetPersistantLocalInt(oPC, "PRC_Class_Data"); - - // Handle alternate caster types gaining new stuff - if(iData & 0x01) - ExecuteScript("prc_amagsys_gain", oPC); - - // Add ip feats for spontaneous casters using metamagic - if(iData & 0x02) - ExecuteScript("prc_metamagic", oPC); - - // Handle classes with reduced arcane spell failure - if(iData & 0x04) - ExecuteScript("prc_reducedasf", oPC); - - if(GetPersistantLocalInt(oPC, "PRC_UNI_SHIFT_SCRIPT")) - //Executing shifter-related stuff like this has these advantages: - //1) All races and classes that need it can get it without a different script needing to be created for each. - //2) PCs with shifter-related stuff from multiple classes or races don't run the same functions multiple times. - ExecuteScript("prc_uni_shift", oPC); - - // Templates - //these go here so feats can be reused - ExecuteScript("prc_templates", oPC); - - // Feats - //these are here so if templates add them the if check runs after the template was applied - ExecuteScript("prc_feats", oPC); - - if (ToBFeats(oPC)) - ExecuteScript("tob_feats", oPC); - - if (GetIsIncarnumUser(oPC)) - ExecuteScript("moi_events", oPC); - - if (GetIsBinder(oPC)) - ExecuteScript("bnd_events", oPC); - - // check if character with crafting feat has appropriate base item in her inventory - // x - moved from prc_onhb_indiv.nss - if(GetPRCSwitch(PRC_CRAFTING_BASE_ITEMS)) - DelayCommand(0.5f, ExecuteScript("prc_crftbaseitms", oPC)); - - // Add the teleport management feats. - // 2005.11.03: Now added to all base classes on 1st level - Ornedan -// ExecuteScript("prc_tp_mgmt_eval", oPC); - - // Size changes. Removed due to double-dipping most size adjustments - //ExecuteScript("prc_size", oPC); - - // Speed changes - // The local int is for when items are requipped too quickly and this script bugs out - if (!GetLocalInt(oPC, "PRCSpeedDelay")) - { - ExecuteScript("prc_speed", oPC); - SetLocalInt(oPC, "PRCSpeedDelay", TRUE); - DelayCommand(0.15, DeleteLocalInt(oPC, "PRCSpeedDelay")); - } - - // ACP system - if((GetIsPC(oPC) && - (GetPRCSwitch(PRC_ACP_MANUAL) || - GetPRCSwitch(PRC_ACP_AUTOMATIC) - ) - ) || - (!GetIsPC(oPC) && - GetPRCSwitch(PRC_ACP_NPC_AUTOMATIC) - ) - ) - ExecuteScript("acp_auto", oPC); - -// this is handled inside the PRC Options conversation now. -/* // Epic spells - if((GetCasterLvl(CLASS_TYPE_CLERIC, oPC) >= 21 || - GetCasterLvl(CLASS_TYPE_DRUID, oPC) >= 21 || - GetCasterLvl(CLASS_TYPE_SORCERER, oPC) >= 21 || - GetCasterLvl(CLASS_TYPE_FAVOURED_SOUL, oPC) >= 21 || - GetCasterLvl(CLASS_TYPE_HEALER, oPC) >= 21 || - GetCasterLvl(CLASS_TYPE_WIZARD, oPC) >= 21 - ) && - !GetHasFeat(FEAT_EPIC_SPELLCASTING_REST, oPC) - ) - { - IPSafeAddItemProperty(oSkin, PRCItemPropertyBonusFeat(IP_CONST_FEAT_EPIC_REST), 0.0f, - X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - }*/ - - // Miscellaneous - ExecuteScript("prc_sneak_att", oPC); - ExecuteScript("race_skin", oPC); - ExecuteScript("prc_mithral", oPC); - if(GetPRCSwitch(PRC_ENFORCE_RACIAL_APPEARANCE) && GetIsPC(oPC)) - ExecuteScript("race_appear", oPC); - - //Reserve Feats - if(!GetLocalInt(oPC, "ReserveFeatsRunning")) - { - if(GetHasFeat(FEAT_HOLY_WARRIOR, oPC) || - GetHasFeat(FEAT_MYSTIC_BACKLASH, oPC) || - GetHasFeat(FEAT_ACIDIC_SPLATTER, oPC) || - GetHasFeat(FEAT_FIERY_BURST, oPC) || - GetHasFeat(FEAT_STORM_BOLT, oPC) || - GetHasFeat(FEAT_WINTERS_BLAST, oPC) || - GetHasFeat(FEAT_CLAP_OF_THUNDER, oPC) || - GetHasFeat(FEAT_SICKENING_GRASP, oPC) || - GetHasFeat(FEAT_TOUCH_OF_HEALING, oPC) || - GetHasFeat(FEAT_DIMENSIONAL_JAUNT, oPC) || - GetHasFeat(FEAT_CLUTCH_OF_EARTH, oPC) || - GetHasFeat(FEAT_BORNE_ALOFT, oPC) || - GetHasFeat(FEAT_PROTECTIVE_WARD, oPC) || - GetHasFeat(FEAT_SHADOW_VEIL, oPC) || - GetHasFeat(FEAT_SUNLIGHT_EYES, oPC) || - GetHasFeat(FEAT_TOUCH_OF_DISTRACTION, oPC) || - GetHasFeat(FEAT_UMBRAL_SHROUD, oPC) || - GetHasFeat(FEAT_CHARNEL_MIASMA, oPC) || - GetHasFeat(FEAT_DROWNING_GLANCE, oPC) || - GetHasFeat(FEAT_INVISIBLE_NEEDLE, oPC) || - GetHasFeat(FEAT_SUMMON_ELEMENTAL, oPC) || - GetHasFeat(FEAT_DIMENSIONAL_REACH, oPC) || - GetHasFeat(FEAT_HURRICANE_BREATH, oPC) || - GetHasFeat(FEAT_MINOR_SHAPESHIFT, oPC) || - GetHasFeat(FEAT_FACECHANGER, oPC)) - { - ExecuteScript("prc_reservefeat", oPC); - } - } - - /*if(// Psionics - GetLevelByClass(CLASS_TYPE_PSION, oPC) || - GetLevelByClass(CLASS_TYPE_WILDER, oPC) || - GetLevelByClass(CLASS_TYPE_PSYWAR, oPC) || - GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oPC) || - GetLevelByClass(CLASS_TYPE_WARMIND, oPC) || - // New spellbooks - GetLevelByClass(CLASS_TYPE_BARD, oPC) || - GetLevelByClass(CLASS_TYPE_SORCERER, oPC) || - GetLevelByClass(CLASS_TYPE_SUEL_ARCHANAMACH, oPC) || - GetLevelByClass(CLASS_TYPE_FAVOURED_SOUL, oPC) || - GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) || - GetLevelByClass(CLASS_TYPE_HEXBLADE, oPC) || - GetLevelByClass(CLASS_TYPE_DUSKBLADE, oPC) || - GetLevelByClass(CLASS_TYPE_WARMAGE, oPC) || - GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER,oPC) || - GetLevelByClass(CLASS_TYPE_JUSTICEWW, oPC) || - GetLevelByClass(CLASS_TYPE_WITCH, oPC) || - GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oPC) || - GetLevelByClass(CLASS_TYPE_ARCHIVIST, oPC) || - GetLevelByClass(CLASS_TYPE_BEGUILER, oPC) || - GetLevelByClass(CLASS_TYPE_HARPER, oPC) || - GetLevelByClass(CLASS_TYPE_TEMPLAR, oPC) || - // Truenaming - GetLevelByClass(CLASS_TYPE_TRUENAMER, oPC) || - // Tome of Battle - GetLevelByClass(CLASS_TYPE_CRUSADER, oPC) || - GetLevelByClass(CLASS_TYPE_SWORDSAGE, oPC) || - GetLevelByClass(CLASS_TYPE_WARBLADE, oPC) || - // Invocations - GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oPC) || - GetLevelByClass(CLASS_TYPE_WARLOCK, oPC) || - // Racial casters - (GetLevelByClass(CLASS_TYPE_OUTSIDER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_RAKSHASA) - ) - { - DelayCommand(1.0, DelayedExecuteScript(nGeneration, "prc_amagsys_gain", oPC)); - - //add selectable metamagic feats for spontaneous spellcasters - ExecuteScript("prc_metamagic", oPC); - }*/ - - // Gathers all the calls to UnarmedFists & Feats to one place. - // Must be after all evaluationscripts that need said functions. - //if(GetLocalInt(oPC, "CALL_UNARMED_FEATS") || GetLocalInt(oPC, "CALL_UNARMED_FISTS")) // ExecuteScript() is pretty expensive, do not run it needlessly - 20060702, Ornedan - ExecuteScript("unarmed_caller", oPC); - - // Gathers all the calls to SetBaseAttackBonus() to one place - // Must be after all evaluationscripts that need said function. - ExecuteScript("prc_bab_caller", oPC); - -//:: [PRC .35] Needs marker feats - // Classes an invoker can take - if(GetLevelByClass(CLASS_TYPE_MAESTER, oPC) || - GetLevelByClass(CLASS_TYPE_ACOLYTE, oPC) || - GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oPC) || - GetLevelByClass(CLASS_TYPE_DISCIPLE_OF_ASMODEUS, oPC)) - { - //Set arcane or invocation bonus caster levels - - //Arcane caster first class position, take arcane - if(GetFirstArcaneClassPosition(oPC) == 1) - SetLocalInt(oPC, "INV_Caster", 1); - //Invoker first class position. take invoker - else if(GetClassByPosition(1, oPC) == CLASS_TYPE_WARLOCK || GetClassByPosition(1, oPC) == CLASS_TYPE_DRAGONFIRE_ADEPT) - SetLocalInt(oPC, "INV_Caster", 2); - //Non arcane first class position, invoker second. Take invoker - else if(GetFirstArcaneClassPosition(oPC) ==0 && (GetClassByPosition(2, oPC) == CLASS_TYPE_WARLOCK || GetClassByPosition(2, oPC) == CLASS_TYPE_DRAGONFIRE_ADEPT)) - SetLocalInt(oPC, "INV_Caster", 2); - //last cas would be Non-invoker first class position, arcane second position. take arcane. - else - SetLocalInt(oPC, "INV_Caster", 1); - } -} - -void DelayedAddIPFeats(int nExpectedGeneration, object oPC) -{ - if (nExpectedGeneration != GetLocalInt(oPC, PRC_EvalPRCFeats_Generation)) - { - //Generation has changed, so don't apply the effect - return; - } - - object oSkin = GetPCSkin(oPC); - - //Horse menu - AddSkinFeat(FEAT_HORSE_MENU, 40, oSkin, oPC); - - // Switch convo feat - //Now everyone gets it at level 1, but just to be on the safe side - AddSkinFeat(FEAT_OPTIONS_CONVERSATION, 229, oSkin, oPC); - - //PnP familiars - if(GetHasFeat(FEAT_SUMMON_FAMILIAR, oPC) && GetPRCSwitch(PRC_PNP_FAMILIARS)) - IPSafeAddItemProperty(oSkin, PRCItemPropertyBonusFeat(IP_CONST_PNP_FAMILIAR), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); - else if(!GetHasFeat(FEAT_SUMMON_FAMILIAR, oPC) || !GetPRCSwitch(PRC_PNP_FAMILIARS)) - RemoveItemProperty(oSkin, ItemPropertyBonusFeat(IP_CONST_PNP_FAMILIAR)); - - //PnP Spell Schools - if(GetPRCSwitch(PRC_PNP_SPELL_SCHOOLS) - && GetLevelByClass(CLASS_TYPE_WIZARD, oPC) - && !GetIsPolyMorphedOrShifted(oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_GENERAL, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_ABJURATION, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_CONJURATION, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_DIVINATION, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_ENCHANTMENT, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_EVOCATION, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_ILLUSION, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_NECROMANCY, oPC) - && !GetHasFeat(FEAT_PNP_SPELL_SCHOOL_TRANSMUTATION, oPC) - //&& !PRCGetHasEffect(EFFECT_TYPE_POLYMORPH, oPC) //so it doesnt pop up on polymorphing - //&& !GetLocalInt(oSkin, "nPCShifted") //so it doenst pop up on shifting - ) - { - if(GetXP(oPC))// ConvoCC compatibility fix - ExecuteScript("prc_pnp_shcc_s", oPC); - } - - /*//Arcane Archer old imbue arrow - if(GetLevelByClass(CLASS_TYPE_ARCANE_ARCHER, oPC) >= 2 - && !GetHasFeat(FEAT_PRESTIGE_IMBUE_ARROW, oPC) - && GetPRCSwitch(PRC_PNP_SPELL_SCHOOLS)) - { - //add the old feat to the hide - IPSafeAddItemProperty(oSkin, PRCItemPropertyBonusFeat(IP_CONST_FEAT_FEAT_PRESTIGE_IMBUE_ARROW), 0.0f, - X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - }*/ - - //handle PnP sling switch - if(GetPRCSwitch(PRC_PNP_SLINGS)) - { - if(GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)) == BASE_ITEM_SLING) - IPSafeAddItemProperty(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC), - ItemPropertyMaxRangeStrengthMod(20), - 999999.9); - } -} - -void TemplateSLAs(object oPC) -{ - int i; - for(i = TEMPLATE_SLA_START; i <= TEMPLATE_SLA_END; i++) - { - DeleteLocalInt(oPC, "TemplateSLA_"+IntToString(i)); - } -} - -void DeletePRCLocalInts(object oSkin) -{ - // This will get rid of any SetCompositeAttackBonus LocalInts: - object oPC = GetItemPossessor(oSkin); - DeleteLocalInt(oPC, "CompositeAttackBonusR"); - DeleteLocalInt(oPC, "CompositeAttackBonusL"); - - //Do not use DelayCommand for this--it's too dangerous: - //if SetCompositeAttackBonus is called at the wrong time the result will be incorrect. - DeleteNamedComposites(oPC, "PRC_ComAttBon"); - - // PRCGetClassByPosition and PRCGetLevelByPosition cleanup - // not needed now that GetClassByPosition() works for custom classes - // DeleteLocalInt(oPC, "PRC_ClassInPos1"); - // DeleteLocalInt(oPC, "PRC_ClassInPos2"); - // DeleteLocalInt(oPC, "PRC_ClassInPos3"); - // DeleteLocalInt(oPC, "PRC_ClassLevelInPos1"); - // DeleteLocalInt(oPC, "PRC_ClassLevelInPos2"); - // DeleteLocalInt(oPC, "PRC_ClassLevelInPos3"); - - //persistant local token object cache - //looks like logging off then back on without the server rebooting breaks it - //I guess because the token gets a new ID, but the local still points to the old one - DeleteLocalObject(oPC, "PRC_HideTokenCache"); - - DeleteLocalInt(oSkin, "PRC_ArcaneSpellFailure"); - - DeleteLocalInt(oPC, "PRC_SwiftActionUsed"); - DeleteLocalInt(oPC, "PRC_MoveActionUsed"); - - // In order to work with the PRC system we need to delete some locals for each - // PRC that has a hide - - //Do not use DelayCommand for this--it's too dangerous: - //if SetCompositeBonus is called between the time EvalPRCFeats removes item properties - //and the time this delayed command is executed, the result will be incorrect. - //Since this error case actually happens frequently with any delay here, just don't do it. - DeleteNamedComposites(oSkin, "PRC_CBon"); - - if (DEBUG) DoDebug("Clearing class flags"); - - // Elemental Savants - DeleteLocalInt(oSkin,"ElemSavantResist"); - DeleteLocalInt(oSkin,"ElemSavantPerfection"); - DeleteLocalInt(oSkin,"ElemSavantImmMind"); - DeleteLocalInt(oSkin,"ElemSavantImmParal"); - DeleteLocalInt(oSkin,"ElemSavantImmSleep"); - // HeartWarder - DeleteLocalInt(oSkin,"FeyType"); - // OozeMaster - DeleteLocalInt(oSkin,"IndiscernibleCrit"); - DeleteLocalInt(oSkin,"IndiscernibleBS"); - DeleteLocalInt(oSkin,"OneOozeMind"); - DeleteLocalInt(oSkin,"OneOozePoison"); - // Storm lord - DeleteLocalInt(oSkin,"StormLResElec"); - // Spell sword - DeleteLocalInt(oSkin,"SpellswordSFBonusNormal"); - DeleteLocalInt(oSkin,"SpellswordSFBonusEpic"); - // Acolyte of the skin - DeleteLocalInt(oSkin,"AcolyteSymbBonus"); - DeleteLocalInt(oSkin,"AcolyteResistanceCold"); - DeleteLocalInt(oSkin,"AcolyteResistanceFire"); - DeleteLocalInt(oSkin,"AcolyteResistanceAcid"); - DeleteLocalInt(oSkin,"AcolyteResistanceElectric"); - // Battleguard of Tempus - DeleteLocalInt(oSkin,"FEAT_WEAP_TEMPUS"); - // Bonded Summoner - DeleteLocalInt(oSkin,"BondResEle"); - DeleteLocalInt(oSkin,"BondSubType"); - // Disciple of Meph - DeleteLocalInt(oSkin,"DiscMephResist"); - DeleteLocalInt(oSkin,"DiscMephGlove"); - // Initiate of Draconic Mysteries - DeleteLocalInt(oSkin,"IniSR"); - DeleteLocalInt(oSkin,"IniStunStrk"); - // Man at Arms - DeleteLocalInt(oSkin,"ManArmsCore"); - // Telflammar Shadowlord - DeleteLocalInt(oSkin,"ShaDiscorp"); - // Vile Feats - DeleteLocalInt(oSkin,"DeformGaunt"); - DeleteLocalInt(oSkin,"DeformObese"); - // Sneak Attack - DeleteLocalInt(oSkin,"RogueSneakDice"); - DeleteLocalInt(oSkin,"BlackguardSneakDice"); - // Sacred Fist - DeleteLocalInt(oSkin,"SacFisMv"); - // Minstrel - DeleteLocalInt(oSkin,"MinstrelSFBonus"); /// @todo Make ASF reduction compositable - // Nightshade - DeleteLocalInt(oSkin,"ImmuNSWeb"); - DeleteLocalInt(oSkin,"ImmuNSPoison"); - // Soldier of Light - DeleteLocalInt(oSkin,"ImmuPF"); - // Ultimate Ranger - DeleteLocalInt(oSkin,"URImmu"); - // Thayan Knight - DeleteLocalInt(oSkin,"ThayHorror"); - DeleteLocalInt(oSkin,"ThayZulkFave"); - DeleteLocalInt(oSkin,"ThayZulkChamp"); - // Black Flame Zealot - DeleteLocalInt(oSkin,"BFZHeart"); - // Henshin Mystic - DeleteLocalInt(oSkin,"Happo"); - DeleteLocalInt(oSkin,"HMInvul"); - //Blightlord - DeleteLocalInt(oSkin, "WntrHeart"); - DeleteLocalInt(oSkin, "BlightBlood"); - // Contemplative - DeleteLocalInt(oSkin, "ContempDisease"); - DeleteLocalInt(oSkin, "ContempPoison"); - DeleteLocalInt(oSkin, "ContemplativeDR"); - DeleteLocalInt(oSkin, "ContemplativeSR"); - // Dread Necromancer - DeleteLocalInt(oSkin, "DNDamageResist"); - // Warsling Sniper - DeleteLocalInt(oPC, "CanRicochet"); - // Blood Magus - DeleteLocalInt(oSkin, "ThickerThanWater"); - - // Feats - DeleteLocalInt(oPC, "ForceOfPersonalityWis"); - DeleteLocalInt(oPC, "ForceOfPersonalityCha"); - DeleteLocalInt(oPC, "InsightfulReflexesInt"); - DeleteLocalInt(oPC, "InsightfulReflexesDex"); - DeleteLocalInt(oSkin, "TactileTrapsmithSearchIncrease"); - DeleteLocalInt(oSkin, "TactileTrapsmithDisableIncrease"); - DeleteLocalInt(oSkin, "TactileTrapsmithSearchDecrease"); - DeleteLocalInt(oSkin, "TactileTrapsmithDisableDecrease"); - - // Warmind - DeleteLocalInt(oSkin, "EnduringBody"); - - // Ironmind - DeleteLocalInt(oSkin, "IronMind_DR"); - - // Suel Archanamach - DeleteLocalInt(oSkin, "SuelArchanamachSpellFailure"); - - // Favoured Soul - DeleteLocalInt(oSkin, "FavouredSoulResistElementAcid"); - DeleteLocalInt(oSkin, "FavouredSoulResistElementCold"); - DeleteLocalInt(oSkin, "FavouredSoulResistElementElec"); - DeleteLocalInt(oSkin, "FavouredSoulResistElementFire"); - DeleteLocalInt(oSkin, "FavouredSoulResistElementSonic"); - DeleteLocalInt(oSkin, "FavouredSoulDR"); - - // Domains - DeleteLocalInt(oSkin, "StormDomainPower"); - - // Skullclan Hunter - DeleteLocalInt(oSkin, "SkullClanFear"); - DeleteLocalInt(oSkin, "SkullClanDisease"); - DeleteLocalInt(oSkin, "SkullClanProtectionEvil"); - DeleteLocalInt(oSkin, "SkullClanSwordLight"); - DeleteLocalInt(oSkin, "SkullClanParalysis"); - DeleteLocalInt(oSkin, "SkullClanAbilityDrain"); - DeleteLocalInt(oSkin, "SkullClanLevelDrain"); - - // Sohei - DeleteLocalInt(oSkin, "SoheiDamageResist"); - - // Dragon Disciple - DeleteLocalInt(oPC, "DragonDiscipleBreathWeaponUses"); - - //Dragon Shaman - DeleteLocalInt(oPC, "DragonShamanTotem"); - - //Warblade - DeleteLocalInt(oSkin, "PRC_WEAPON_APTITUDE_APPLIED"); - - //Shifter(PnP) - DeleteLocalInt(oSkin, "PRC_SHIFTER_TEMPLATE_APPLIED"); - - DeleteLocalInt(oPC, "ScoutFreeMove"); - DeleteLocalInt(oPC, "ScoutFastMove"); - DeleteLocalInt(oPC, "ScoutBlindsight"); - - //Truenamer - // Called elsewhere now - /*int UtterID; - for(UtterID = 3526; UtterID <= 3639; UtterID++) // All utterances - DeleteLocalInt(oPC, "PRC_LawOfResistance" + IntToString(UtterID)); - for(UtterID = 3418; UtterID <= 3431; UtterID++) // Syllable of Detachment to Word of Heaven, Greater - DeleteLocalInt(oPC, "PRC_LawOfResistance" + IntToString(UtterID));*/ - - //Invocations - DeleteLocalInt(oPC, "ChillingFogLock"); - //Endure Exposure wearing off - array_delete(oPC, "BreathProtected"); - DeleteLocalInt(oPC, "DragonWard"); - - //Scry on Familiar - DeleteLocalInt(oPC, "Scry_Familiar"); - - // Undead HD - DeleteLocalInt(oPC, "PRCUndeadHD"); - DeleteLocalInt(oPC, "PRCUndeadFSPen"); - - //Template Spell-Like Abilities - DelayCommand(0.5f, TemplateSLAs(oPC)); - - // future PRCs Go below here -} - -void ScrubPCSkin(object oPC, object oSkin) -{ - int nGeneration = PRC_NextGeneration(GetLocalInt(oPC, PRC_ScrubPCSkin_Generation)); - if (DEBUG > 1) DoDebug("ScrubPCSkin Generation: " + IntToString(nGeneration)); - SetLocalInt(oPC, PRC_ScrubPCSkin_Generation, nGeneration); - - int iCode = GetHasFeat(FEAT_SF_CODE,oPC); - int ipType, st; - if(!(/*GetIsPolyMorphedOrShifted(oPC) || */GetIsObjectValid(GetMaster(oPC)))) - { - itemproperty ip = GetFirstItemProperty(oSkin); - while(GetIsItemPropertyValid(ip)) - { - // Insert Logic here to determine if we spare a property - ipType = GetItemPropertyType(ip); - if(ipType == ITEM_PROPERTY_BONUS_FEAT) - { - // Check for specific Bonus Feats - // Reference iprp_feats.2da - st = GetItemPropertySubType(ip); - - // Spare 400 through 570 and 398 -- epic spells & spell effects - //also spare the new spellbook feats (1000-12000 & 17701-24704 - //also spare the psionic, trunaming, tob, invocation feats (12000-16000) - // spare template, tob stuff (16300-17700) - // changed by fluffyamoeba so that iprp weapon specialization, dev crit, epic weapon focus, epic weapon spec - // overwhelming crit and weapon of choice are no longer skipped. - if ((st < 400 || st > 570) - && st != 398 - && (st < 1000 || st > 13520) - //&& (st < 1000 || st > 13999) - //&& (st < 14501 || st > 15999) - && (st < 16300 || st > 24704) - && (st < 223 || st > 226) // draconic feats - && (st < 229 || st > 249) // Pnp spellschool feats and PRC options feat (231-249 & 229) - && st != 259 // 259 - psionic focus - && (st < 141 || st > 200) // 141 - shadowmaster shades, 142-151 bonus domains casting feats, 152 - 200 bonus domain powers - && ( (st == IP_CONST_FEAT_PRC_POWER_ATTACK_QUICKS_RADIAL || - st == IP_CONST_FEAT_POWER_ATTACK_SINGLE_RADIAL || - st == IP_CONST_FEAT_POWER_ATTACK_FIVES_RADIAL) ? // Remove the PRC Power Attack radials if the character no longer has Power Attack - !GetHasFeat(FEAT_POWER_ATTACK, oPC) : - TRUE // If the feat is not relevant to this clause, always pass - ) - ) - RemoveItemProperty(oSkin, ip); - } - else if(ipType == ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N) - { - //bonus spellslots code here - //st = GetItemPropertySubType(ip); - RemoveItemProperty(oSkin, ip); - } - else - RemoveItemProperty(oSkin, ip); - - // Get the next property - ip = GetNextItemProperty(oSkin); - } - } - if(iCode) - AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(381),oSkin); - - // Schedule restoring the unhealable ability damage - DelayCommand(0.1f, DelayedReApplyUnhealableAbilityDamage(nGeneration, oPC)); - - // Remove all natural weapons too - // ClearNaturalWeapons(oPC); - // Done this way to remove prc_inc_natweap and prc_inc_combat from the include - // Should help with compile speeds and the like - //array_delete(oPC, "ARRAY_NAT_SEC_WEAP_RESREF"); - //array_delete(oPC, "ARRAY_NAT_PRI_WEAP_RESREF"); - //array_delete(oPC, "ARRAY_NAT_PRI_WEAP_ATTACKS"); -} - -int BlastInfidelOrFaithHeal(object oCaster, object oTarget, int iEnergyType, int iDisplayFeedback) -{ - //Don't bother doing anything if iEnergyType isn't either positive/negative energy - if(iEnergyType != DAMAGE_TYPE_POSITIVE && iEnergyType != DAMAGE_TYPE_NEGATIVE) - return FALSE; - - //If the target is undead and damage type is negative - //or if the target is living and damage type is positive - //then we're healing. Otherwise, we're harming. - int iTombTainted = GetHasFeat(FEAT_TOMB_TAINTED_SOUL, oTarget) && GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD; - int iHeal = ( iEnergyType == DAMAGE_TYPE_NEGATIVE && (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD || iTombTainted)) || - ( iEnergyType == DAMAGE_TYPE_POSITIVE && MyPRCGetRacialType(oTarget) != RACIAL_TYPE_UNDEAD && !iTombTainted); - int iRetVal = FALSE; - int iAlignDif = CompareAlignment(oCaster, oTarget); - string sFeedback = ""; - - if(iHeal){ - if((GetHasFeat(FEAT_FAITH_HEALING, oCaster) && iAlignDif < 2)){ - iRetVal = TRUE; - sFeedback = "Faith Healing"; - } - } - else{ - if((GetHasFeat(FEAT_BLAST_INFIDEL, oCaster) && iAlignDif >= 2)){ - iRetVal = TRUE; - sFeedback = "Blast Infidel"; - } - } - - if(iDisplayFeedback) FloatingTextStringOnCreature(sFeedback, oCaster); - return iRetVal; -} - -int GetShiftingFeats(object oPC) -{ - int nNumFeats; - nNumFeats = GetHasFeat(FEAT_BEASTHIDE_ELITE, oPC) - + GetHasFeat(FEAT_DREAMSIGHT_ELITE, oPC) - + GetHasFeat(FEAT_GOREBRUTE_ELITE, oPC) - + GetHasFeat(FEAT_LONGSTRIDE_ELITE, oPC) - + GetHasFeat(FEAT_LONGTOOTH_ELITE, oPC) - + GetHasFeat(FEAT_RAZORCLAW_ELITE, oPC) - + GetHasFeat(FEAT_WILDHUNT_ELITE, oPC) - + GetHasFeat(FEAT_EXTRA_SHIFTER_TRAIT, oPC) - + GetHasFeat(FEAT_HEALING_FACTOR, oPC) - + GetHasFeat(FEAT_SHIFTER_AGILITY, oPC) - + GetHasFeat(FEAT_SHIFTER_DEFENSE, oPC) - + GetHasFeat(FEAT_GREATER_SHIFTER_DEFENSE, oPC) - + GetHasFeat(FEAT_SHIFTER_FEROCITY, oPC) - + GetHasFeat(FEAT_SHIFTER_INSTINCTS, oPC) - + GetHasFeat(FEAT_SHIFTER_SAVAGERY, oPC); - - return nNumFeats; -} - -//Including DelayedApplyEffectToObject here because it is often used in conjunction with EvalPRCFeats and I don't know a better place to put it -void DelayedApplyEffectToObject(int nExpectedGeneration, int nCurrentGeneration, int nDuration, effect eEffect, object oTarget, float fDuration) -{ - if (nExpectedGeneration != nCurrentGeneration) - { - //Generation has changed, so don't apply the effect - return; - } - ApplyEffectToObject(nDuration, eEffect, oTarget, fDuration); -} - -//Including DelayedApplyEffectToObject here because it is often used in conjunction with EvalPRCFeats and I don't know a better place to put it -void DelayApplyEffectToObject(float fDelay, string sGenerationName, int nDuration, effect eEffect, object oTarget, float fDuration = 0.0f) -{ - /* - There are a couple of problems that can arise in code that removes and reapplies effects; - this function helps deal with those problems. One example of a typical place where these problems - frequently arise is in the class scripts called by the EvalPRCFeats function. - - The first problem is that when code removes and immediately reapplies a series of effects, - some of those effects may not actually be reapplied. This is because the RemoveEffect() function - doesn't actually remove an effect, it marks it to be removed later--when the currently running - script finishes. If any of the effects we reapply matches one of the effects marked to be - removed, that reapplied effect will be removed when the currently running script finishes - and so will be unexpectedly missing. To illustrate: - 1) We start with effect A and B. - 2) The application function is called; it removes all effects and reapplies effects B and C. - 3) The actual removal happens when the script ends: effect A and B are removed. - End result: we have only effect C instead of the expected B and C. - The solution to this is to reapply the effects later using DelayCommand(). - - This introduces a new problem. If the function that removes and reapplies the effects is called - multiple times quickly, it can queue up a series of delayed applications. This causes two problems: - if the data on which the effects are calculated changes, the earlier delayed applications can - apply effects that should no longer be used, but they are anyway because the delayed code doesn't - know this. To illustrate: - 1) The application function is called; it removes all effects, schedules delayed application of effect A. - 2) The application function is called again; it removes all effects, schedules delayed application of effect B. - 3) Delayed application of effect A occurs. - 4) Delayed application of effect B occurs. - End result: we have both effect A and B instead of the expected result, B alone. - Another problem is that we can end up with multiple copies of the same effect. - If this happens enough, it can cause "Effect List overflow" errors. Also, if the effect stacks - with itself, this gives a greater bonus or penalty than it should. To illustrate: - 1) The application function is called; it removes all effects, schedules delayed application of effect C. - 2) The application function is called; it removes all effects, schedules delayed application of effect C. - 3) Delayed application of effect C occurs. - 4) Delayed application of effect C occurs. - End result: we have effect C twice instead of just once. - The solution is to both these problems is for the application function to increment an integer each time it - is called and to pass this to the delayed application function. The delayed application actually happens only - if the generation when it runs is the same as the generation when it was scheduled. To illustrate: - 1) We start with effect A and B applied. - 2) The application function is called: it increments generation to 2, schedules delayed application of effect B and C. - 3) The application function is called: it increments generation to 3, schedules delayed application of effect C. - 4) The generation 2 delayed application function executes: it sees that the current generation is 3 and simply exits, doing nothing. - 5) The generation 3 delayed application function executes: it sees that the current generation is 3, so it applies effect C. - End result: we have one copy of effect C, which is what we wanted. - */ - - if (fDelay < 0.0f || GetStringLength(sGenerationName) == 0) - { - ApplyEffectToObject(nDuration, eEffect, oTarget, fDuration); - } - else - { - int nExpectedGeneration = GetLocalInt(oTarget, sGenerationName); //This gets the generation now - DelayCommand( - fDelay, - DelayedApplyEffectToObject( - nExpectedGeneration, - GetLocalInt(oTarget, sGenerationName), //This is delayed by the DelayCommand, so it gets the generation when DelayedApplyEffectToObject is actually executed - nDuration, - eEffect, - oTarget, - fDuration - ) - ); - } -} - -//Including DelayedAddItemProperty here to keep it with DelayedApplyEffectToObject, though more properly it should probably be in inc_item_props.nss -void DelayedAddItemProperty(int nExpectedGeneration, int nCurrentGeneration, int nDurationType, itemproperty ipProperty, object oItem, float fDuration) -{ - if (nExpectedGeneration != nCurrentGeneration) - { - //Generation has changed, so don't apply the effect - return; - } - AddItemProperty(nDurationType, ipProperty, oItem, fDuration); -} - -//Including DelayAddItemProperty here to keep it with DelayApplyEffectToObject, though more properly it should probably be in inc_item_props.nss -void DelayAddItemProperty(float fDelay, object oGenerationHolder, string sGenerationName, int nDurationType, itemproperty ipProperty, object oItem, float fDuration = 0.0f) -{ - /* - There are a couple of problems that can arise in code that removes and reapplies item properties; - this function helps deal with those problems. One example of a typical place where these problems - frequently arise is in the class scripts called by the EvalPRCFeats function. - - The first problem is that when code removes and immediately reapplies a series of item properties, - some of those properties may not actually be reapplied. This is because the RemoveItemProperty() function - doesn't actually remove a property, it marks it to be removed later--when the currently running - script finishes. If any of the properties we reapply matches one of the properties marked to be - removed, that reapplied property will be removed when the currently running script finishes - and so will be unexpectedly missing. To illustrate: - 1) We start with properties A and B. - 2) The application function is called; it removes all properties and reapplies properties B and C. - 3) The actual removal happens when the script ends: property A and B are removed. - End result: we have only property C instead of the expected B and C. - The solution to this is to reapply the properties later using DelayCommand(). - - This introduces a new problem. If the function that removes and reapplies the properties is called - multiple times quickly, it can queue up a series of delayed applications. This causes two problems: - if the data on which the properties are calculated changes, the earlier delayed applications can - apply properties that should no longer be used, but they are anyway because the delayed code doesn't - know this. To illustrate: - 1) The application function is called; it removes all properties, schedules delayed application of property A. - 2) The application function is called again; it removes all properties, schedules delayed application of property B. - 3) Delayed application of property A occurs. - 4) Delayed application of property B occurs. - End result: we have both property A and B instead of the expected result, B alone. - Another problem is that we can end up with multiple copies of the same property. - If this happens enough, it can cause "Effect List overflow" errors. Also, if the property stacks - with itself, this gives a greater bonus or penalty than it should. To illustrate: - 1) The application function is called; it removes all properties, schedules delayed application of property C. - 2) The application function is called; it removes all properties, schedules delayed application of property C. - 3) Delayed application of property C occurs. - 4) Delayed application of property C occurs. - End result: we have property C twice instead of just once. - The solution is to both these problems is for the application function to increment an integer each time it - is called and to pass this to the delayed application function. The delayed application actually happens only - if the generation when it runs is the same as the generation when it was scheduled. To illustrate: - 1) We start with property A and B applied. - 2) The application function is called: it increments generation to 2, schedules delayed application of property B and C. - 3) The application function is called: it increments generation to 3, schedules delayed application of property C. - 4) The generation 2 delayed application function executes: it sees that the current generation is 3 and simply exits, doing nothing. - 5) The generation 3 delayed application function executes: it sees that the current generation is 3, so it applies property C. - End result: we have one copy of property C, which is what we wanted. - */ - - if (fDelay < 0.0f || GetStringLength(sGenerationName) == 0) - { - AddItemProperty(nDurationType, ipProperty, oItem, fDuration); - } - else - { - int nExpectedGeneration = GetLocalInt(oGenerationHolder, sGenerationName); //This gets the generation now - DelayCommand( - fDelay, - DelayedAddItemProperty( - nExpectedGeneration, - GetLocalInt(oGenerationHolder, sGenerationName), //This is delayed by the DelayCommand, so it gets the generation when DelayedAddItemProperty is actually executed - nDurationType, - ipProperty, - oItem, - fDuration - ) - ); - } -} - -void FeatUsePerDay(object oPC, int iFeat, int iAbiMod = ABILITY_CHARISMA, int iMod = 0, int iMin = 1) -{ - if(!GetHasFeat(iFeat,oPC)) - return; - - int iAbi = GetAbilityModifier(iAbiMod, oPC); - iAbi = (iAbi > 0) ? iAbi : 0; - - if (iAbiMod == -1) iAbi = 0; - iAbi += iMod; - - if(iAbi < iMin) - iAbi = iMin; - - while(GetHasFeat(iFeat, oPC)) - DecrementRemainingFeatUses(oPC, iFeat); - - while(iAbi) - { - IncrementRemainingFeatUses(oPC, iFeat); - iAbi--; - } -} - -void DomainUses(object oPC) -{ - int nUses; - if(!GetHasFeat(FEAT_BONUS_DOMAIN_STRENGTH, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_STRENGTH_DOMAIN_POWER)) - { - nUses = GetLevelByClass(CLASS_TYPE_MIGHTY_CONTENDER_KORD, oPC) ? GetAbilityModifier(ABILITY_STRENGTH, oPC) : 1; - FeatUsePerDay(oPC, FEAT_STRENGTH_DOMAIN_POWER, -1, nUses); - } - if(GetHasFeat(FEAT_BONUS_DOMAIN_SUN, oPC) && GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) && PRC_Funcs_GetFeatKnown(oPC, FEAT_SUN_DOMAIN_POWER)) - { - nUses = GetHasFeat(FEAT_EXTRA_TURNING, oPC) ? 7 : 3; - FeatUsePerDay(oPC, FEAT_SUN_DOMAIN_POWER, ABILITY_CHARISMA, nUses); - } - else if(!GetHasFeat(FEAT_BONUS_DOMAIN_SUN, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_SUN_DOMAIN_POWER)) - FeatUsePerDay(oPC, FEAT_SUN_DOMAIN_POWER, -1, 1); - - if(!GetHasFeat(FEAT_BONUS_DOMAIN_BLIGHTBRINGER, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_DOMAIN_POWER_BLIGHTBRINGER)) - FeatUsePerDay(oPC, FEAT_DOMAIN_POWER_BLIGHTBRINGER, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_AIR, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_AIR_DOMAIN_POWER)) - FeatUsePerDay(oPC, FEAT_AIR_DOMAIN_POWER, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_EARTH, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_EARTH_DOMAIN_POWER)) - FeatUsePerDay(oPC, FEAT_EARTH_DOMAIN_POWER, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_FIRE, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_FIRE_DOMAIN_POWER)) - FeatUsePerDay(oPC, FEAT_FIRE_DOMAIN_POWER, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_WATER, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_WATER_DOMAIN_POWER)) - FeatUsePerDay(oPC, FEAT_WATER_DOMAIN_POWER, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_SLIME, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_DOMAIN_POWER_SLIME)) - FeatUsePerDay(oPC, FEAT_DOMAIN_POWER_SLIME, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_SPIDER, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_DOMAIN_POWER_SPIDER)) - FeatUsePerDay(oPC, FEAT_DOMAIN_POWER_SPIDER, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_SCALEYKIND, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_DOMAIN_POWER_SCALEYKIND)) - FeatUsePerDay(oPC, FEAT_DOMAIN_POWER_SCALEYKIND, ABILITY_CHARISMA, 3); - if(!GetHasFeat(FEAT_BONUS_DOMAIN_PLANT, oPC) || PRC_Funcs_GetFeatKnown(oPC, FEAT_PLANT_DOMAIN_POWER)) - FeatUsePerDay(oPC, FEAT_PLANT_DOMAIN_POWER, ABILITY_CHARISMA, 3); -} - -void MephlingBreath(object oPC) //:: Mephlings -{ - if(!GetHasFeat(FEAT_MEPHLING_BREATH, oPC)) - return; - - int nMephBreath = ((1 + GetHitDice(oPC)) / 4); - - FeatUsePerDay(oPC, FEAT_MEPHLING_BREATH, -1, nMephBreath); -} - -void FeatAlaghar(object oPC) -{ - int iAlagharLevel = GetLevelByClass(CLASS_TYPE_ALAGHAR, oPC); - - if (!iAlagharLevel) return; - - int iClangStrike = iAlagharLevel/3; - int iClangMight = (iAlagharLevel - 1)/3; - int iRockburst = (iAlagharLevel + 2)/4; - - FeatUsePerDay(oPC, FEAT_CLANGEDDINS_STRIKE, -1, iClangStrike); - FeatUsePerDay(oPC, FEAT_CLANGEDDINS_MIGHT, -1, iClangMight); - FeatUsePerDay(oPC, FEAT_ALAG_ROCKBURST, -1, iRockburst); -} - - -void FeatDiabolist(object oPC) -{ - int Diabol = GetLevelByClass(CLASS_TYPE_DIABOLIST, oPC); - - if (!Diabol) return; - - int iUse = (Diabol + 3)/3; - - FeatUsePerDay(oPC,FEAT_DIABOL_DIABOLISM_1,-1,iUse); - FeatUsePerDay(oPC,FEAT_DIABOL_DIABOLISM_2,-1,iUse); - FeatUsePerDay(oPC,FEAT_DIABOL_DIABOLISM_3,-1,iUse); -} - -void FeatNinja (object oPC) -{ - int iNinjaLevel = GetLevelByClass(CLASS_TYPE_NINJA, oPC); - // Ascetic Stalker - if (GetHasFeat(FEAT_ASCETIC_STALKER, oPC)) - iNinjaLevel += GetLevelByClass(CLASS_TYPE_MONK, oPC);; - - if (!iNinjaLevel) return; - - int nUsesLeft = iNinjaLevel/2; - if (nUsesLeft < 1) - nUsesLeft = 1; - - // Expanded Ki Pool - if (GetHasFeat(FEAT_EXPANDED_KI_POOL, oPC)) nUsesLeft += 3; - - FeatUsePerDay(oPC, FEAT_KI_POWER, ABILITY_WISDOM, nUsesLeft); - FeatUsePerDay(oPC, FEAT_GHOST_STEP, ABILITY_WISDOM, nUsesLeft); - FeatUsePerDay(oPC, FEAT_GHOST_STRIKE, ABILITY_WISDOM, nUsesLeft); - FeatUsePerDay(oPC, FEAT_GHOST_WALK, ABILITY_WISDOM, nUsesLeft); - FeatUsePerDay(oPC, FEAT_KI_DODGE, ABILITY_WISDOM, nUsesLeft); - - SetLocalInt(oPC, "prc_ninja_ki", nUsesLeft); -} - -void BarbarianRage(object oPC) -{ - if(!GetHasFeat(FEAT_BARBARIAN_RAGE, oPC)) return; - - int nUses = (GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC) + GetLevelByClass(CLASS_TYPE_BLACK_BLOOD_CULTIST, oPC) + GetLevelByClass(CLASS_TYPE_PRC_EYE_OF_GRUUMSH, oPC)) / 4 + 1; - nUses += (GetLevelByClass(CLASS_TYPE_RAGE_MAGE, oPC) + 2) / 5; - nUses += (GetLevelByClass(CLASS_TYPE_BATTLERAGER, oPC) + 1) / 2; - nUses += (GetLevelByClass(CLASS_TYPE_CELEBRANT_SHARESS, oPC) + 2) / 4; - nUses += GetLevelByClass(CLASS_TYPE_RUNESCARRED, oPC) ? ((GetLevelByClass(CLASS_TYPE_RUNESCARRED, oPC) / 4) + 1) : 0; - nUses += (GetLevelByClass(CLASS_TYPE_TOTEM_RAGER, oPC) + 4) / 6; - - if(GetHasFeat(FEAT_EXTRA_RAGE, oPC)) nUses += 2; - - FeatUsePerDay(oPC, FEAT_BARBARIAN_RAGE, -1, nUses); - FeatUsePerDay(oPC, FEAT_GREATER_RAGE, -1, nUses); - - if(GetLevelByClass(CLASS_TYPE_RAGE_MAGE, oPC) > 0) - { - if(GetLevelByClass(CLASS_TYPE_RAGE_MAGE, oPC) > 9) - nUses = 3; - else if(GetLevelByClass(CLASS_TYPE_RAGE_MAGE, oPC) > 4) - nUses = 2; - else - nUses = 1; - - FeatUsePerDay(oPC, FEAT_SPELL_RAGE, -1, nUses); - } -} - -void BardSong(object oPC) -{ - // This is used to set the number of bardic song uses per day, as bardic PrCs can increase it - // or other classes can grant it on their own - if(!GetHasFeat(FEAT_BARD_SONGS, oPC)) return; - - int nTotal = GetLevelByClass(CLASS_TYPE_BARD, oPC); - nTotal += GetLevelByClass(CLASS_TYPE_DIRGESINGER, oPC); - nTotal += GetLevelByClass(CLASS_TYPE_VIRTUOSO, oPC); - nTotal += GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oPC) / 2; - - if(GetHasFeat(FEAT_EXTRA_MUSIC, oPC)) nTotal += 4; - - FeatUsePerDay(oPC, FEAT_BARD_SONGS, -1, nTotal); -} - -void FeatVirtuoso(object oPC) -{ - int iVirtuosoLevel = GetLevelByClass(CLASS_TYPE_VIRTUOSO, oPC); - if (!iVirtuosoLevel) return; - - int nUses = GetLevelByClass(CLASS_TYPE_BARD, oPC) + iVirtuosoLevel; - if(GetHasFeat(FEAT_EXTRA_MUSIC, oPC)) nUses += 4; - SetPersistantLocalInt(oPC, "Virtuoso_Performance_Uses", nUses); - int nFeat; - for(nFeat = FEAT_VIRTUOSO_SUSTAINING_SONG; nFeat <= FEAT_VIRTUOSO_PERFORMANCE; nFeat++) - { - FeatUsePerDay(oPC, nFeat, -1, nUses); - } -} - -void HexCurse(object oPC) -{ - int iHexLevel = GetLevelByClass(CLASS_TYPE_HEXBLADE, oPC); - - if (!iHexLevel) return; - - //Hexblade's Curse - int nUses = (iHexLevel + 3) / 4; // every 4 levels get 1 more use - FeatUsePerDay(oPC, FEAT_HEXCURSE, ABILITY_CHARISMA, nUses); - - //Swift Cast - if(iHexLevel > 13) - nUses = (iHexLevel + 2) / 4; - else if(iHexLevel > 10) - nUses = 3; - else if(iHexLevel > 7) - nUses = 2; - else if(iHexLevel > 5) - nUses = 1; - else - nUses = 0; - FeatUsePerDay(oPC, FEAT_SWIFT_CAST, -1, nUses); -} - -void FeatShadowblade(object oPC) -{ - int iShadowLevel = GetLevelByClass(CLASS_TYPE_SHADOWBLADE, oPC); - if (!iShadowLevel) return; - - FeatUsePerDay(oPC, FEAT_UNERRING_STRIKE, -1, iShadowLevel); - FeatUsePerDay(oPC, FEAT_UNEXPECTED_STRIKE, -1, iShadowLevel); - FeatUsePerDay(oPC, FEAT_EPHEMERAL_WEAPON, -1, iShadowLevel); - FeatUsePerDay(oPC, FEAT_SHADOWY_STRIKE, -1, iShadowLevel); - FeatUsePerDay(oPC, FEAT_FAR_SHADOW, -1, iShadowLevel); -} - -void FeatNoble(object oPC) -{ - int iNobleLevel = GetLevelByClass(CLASS_TYPE_NOBLE, oPC); - if (!iNobleLevel) return; - - int nBonus = 0; - if (iNobleLevel >= 17) nBonus = 5; - else if (iNobleLevel >= 13) nBonus = 4; - else if (iNobleLevel >= 9) nBonus = 3; - else if (iNobleLevel >= 5) nBonus = 2; - else if (iNobleLevel >= 2) nBonus = 1; - - FeatUsePerDay(oPC, FEAT_NOBLE_CONFIDENCE, -1, nBonus); - - nBonus = (iNobleLevel - 11) / 3 + 1; - - FeatUsePerDay(oPC, FEAT_NOBLE_GREATNESS, -1, nBonus); -} - -void DarkKnowledge(object oPC) -{ - int iArchivistLevel = GetLevelByClass(CLASS_TYPE_ARCHIVIST, oPC); - if(!iArchivistLevel) return; - - int nUses = (iArchivistLevel / 3) + 3; - FeatUsePerDay(oPC, FEAT_DK_TACTICS, -1, nUses); - FeatUsePerDay(oPC, FEAT_DK_PUISSANCE, -1, nUses); - FeatUsePerDay(oPC, FEAT_DK_FOE, -1, nUses); - FeatUsePerDay(oPC, FEAT_DK_DREADSECRET, -1, nUses); - FeatUsePerDay(oPC, FEAT_DK_FOREKNOWLEDGE, -1, nUses); -} - -void FeatImbueArrow(object oPC) -{ - if(GetPRCSwitch(PRC_USE_NEW_IMBUE_ARROW)) - FeatUsePerDay(oPC, FEAT_PRESTIGE_IMBUE_ARROW, -1, 0, 0); -} - -void DragonDisciple(object oPC) -{ - if(!GetHasFeat(FEAT_DRAGON_DIS_BREATH, oPC)) - return; - - //Dragon Disciples that do not possess any breath weapon - if(GetHasFeat(FEAT_CHIANG_LUNG_DRAGON, oPC) - || GetHasFeat(FEAT_PAN_LUNG_DRAGON, oPC) - || GetHasFeat(FEAT_SHEN_LUNG_DRAGON, oPC) - || GetHasFeat(FEAT_TUN_MI_LUNG_DRAGON, oPC) - || GetHasFeat(FEAT_YU_LUNG_DRAGON, oPC)) - DecrementRemainingFeatUses(oPC, FEAT_DRAGON_DIS_BREATH); -} - -void Warlock(object oPC) -{ - if(GetHasFeat(FEAT_FIENDISH_RESILIENCE, oPC)) - { - //Add daily Uses of Fiendish Resilience for epic warlock - if(GetHasFeat(FEAT_EPIC_FIENDISH_RESILIENCE_I, oPC)) - { - int nFeatAmt = 0; - int bDone = FALSE; - while(!bDone) - { - if(nFeatAmt >= 9) - bDone = TRUE; - else if(GetHasFeat(FEAT_EPIC_FIENDISH_RESILIENCE_II + nFeatAmt, oPC)) - nFeatAmt++; - else - bDone = TRUE; - } - nFeatAmt++; - FeatUsePerDay(oPC, FEAT_FIENDISH_RESILIENCE, -1, nFeatAmt); - } - else - FeatUsePerDay(oPC, FEAT_FIENDISH_RESILIENCE, -1, 1); - } - - //Hellfire infusion - int nCha = GetAbilityModifier(ABILITY_CHARISMA, oPC); - FeatUsePerDay(oPC, FEAT_HELLFIRE_INFUSION, -1, nCha); - - //Eldritch Spellweave - nCha += 3; - FeatUsePerDay(oPC, FEAT_ELDRITCH_SPELLWEAVE, -1, nCha); -} - -void KotMC(object oPC) -{ - int iKotMCLevel = GetLevelByClass(CLASS_TYPE_KNIGHT_MIDDLECIRCLE, oPC); - if(!iKotMCLevel) return; - - int nUses = iKotMCLevel / 3; - FeatUsePerDay(oPC, FEAT_KOTMC_TRUE_STRIKE, -1, nUses); -} - -void Templar(object oPC) -{ - if(!GetHasFeat(FEAT_SECULAR_AUTHORITY, oPC)) return; - - int nTemplar = GetLevelByClass(CLASS_TYPE_TEMPLAR, oPC); - int nUses = nTemplar + ((GetHitDice(oPC) - nTemplar) / 4); - FeatUsePerDay(oPC, FEAT_SECULAR_AUTHORITY, -1, nUses); -} - -void FeatRacial(object oPC) -{ - //Shifter bonus shifting uses - int nRace = GetRacialType(oPC); - if(nRace == RACIAL_TYPE_SHIFTER) - { - int nShiftFeats = GetShiftingFeats(oPC); - int nBonusShiftUses = (nShiftFeats / 2) + 1; - FeatUsePerDay(oPC, FEAT_SHIFTER_SHIFTING, -1, nBonusShiftUses); - } - else if(nRace == RACIAL_TYPE_FORESTLORD_ELF) - { - int nUses = GetHitDice(oPC) / 5 + 1; - FeatUsePerDay(oPC, FEAT_FORESTLORD_TREEWALK, -1, nUses); - } -} - -void CombatMedic(object oPC) -{ - int iCombMed = GetLevelByClass(CLASS_TYPE_COMBAT_MEDIC, oPC); - if(!iCombMed) return; - - FeatUsePerDay(oPC, FEAT_HEALING_KICKER_1, ABILITY_WISDOM, iCombMed); - FeatUsePerDay(oPC, FEAT_HEALING_KICKER_2, ABILITY_WISDOM, iCombMed); - FeatUsePerDay(oPC, FEAT_HEALING_KICKER_3, ABILITY_WISDOM, iCombMed); -} - -void MasterOfShrouds(object oPC) -{ - if(!GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oPC)) return; - - FeatUsePerDay(oPC, FEAT_MOS_UNDEAD_1, ABILITY_CHARISMA, 3); - FeatUsePerDay(oPC, FEAT_MOS_UNDEAD_2, ABILITY_CHARISMA, 3); - FeatUsePerDay(oPC, FEAT_MOS_UNDEAD_3, ABILITY_CHARISMA, 3); - FeatUsePerDay(oPC, FEAT_MOS_UNDEAD_4, ABILITY_CHARISMA, 3); -} - -void SLAUses(object oPC) -{ - if(!GetHasFeat(FEAT_SPELL_LIKE_ABILITY_1, oPC)) return; - - FeatUsePerDay(oPC, FEAT_SPELL_LIKE_ABILITY_1, -1, GetPersistantLocalInt(oPC, "PRC_SLA_Uses_1")); - FeatUsePerDay(oPC, FEAT_SPELL_LIKE_ABILITY_2, -1, GetPersistantLocalInt(oPC, "PRC_SLA_Uses_2")); - FeatUsePerDay(oPC, FEAT_SPELL_LIKE_ABILITY_3, -1, GetPersistantLocalInt(oPC, "PRC_SLA_Uses_3")); - FeatUsePerDay(oPC, FEAT_SPELL_LIKE_ABILITY_4, -1, GetPersistantLocalInt(oPC, "PRC_SLA_Uses_4")); - FeatUsePerDay(oPC, FEAT_SPELL_LIKE_ABILITY_5, -1, GetPersistantLocalInt(oPC, "PRC_SLA_Uses_5")); -} - -void ShadowShieldUses(object oPC) -{ - if(!GetHasFeat(FEAT_SA_SHIELDSHADOW, oPC)) return; - FeatUsePerDay(oPC, FEAT_SA_SHIELDSHADOW, -1, GetPrCAdjustedCasterLevelByType(TYPE_ARCANE, oPC)); -} - -void BlighterFeats(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_BLIGHTER, oPC); - if(0 >= nClass) return; - - if (nClass == 3) - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 1); - else if (nClass == 4) - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 2); - else if (nClass == 5) - { - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 2); - FeatUsePerDay(oPC, FEAT_CONTAGIOUS_TOUCH, -1, 1); - } - else if (nClass == 6) - { - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 3); - FeatUsePerDay(oPC, FEAT_CONTAGIOUS_TOUCH, -1, 1); - } - else if (nClass == 7) - { - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 3); - FeatUsePerDay(oPC, FEAT_CONTAGIOUS_TOUCH, -1, 2); - } - else if (nClass == 8) - { - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 4); - FeatUsePerDay(oPC, FEAT_CONTAGIOUS_TOUCH, -1, 2); - } - else if (nClass == 9) - { - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 4); - FeatUsePerDay(oPC, FEAT_CONTAGIOUS_TOUCH, -1, 3); - } - else - { - FeatUsePerDay(oPC, FEAT_UNDEAD_WILD_SHAPE, -1, 5); - FeatUsePerDay(oPC, FEAT_CONTAGIOUS_TOUCH, -1, 3); - } -} - -void MysteryFeats(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_CHILD_OF_NIGHT, oPC); - if(nClass > 0) - { - if (nClass >= 10) - FeatUsePerDay(oPC, FEAT_CLOAK_SHADOWS, -1, 2); - else if (nClass >= 6) - FeatUsePerDay(oPC, FEAT_CLOAK_SHADOWS, -1, 3); - else - FeatUsePerDay(oPC, FEAT_CLOAK_SHADOWS, -1, 1); - - if (nClass >= 7) - FeatUsePerDay(oPC, FEAT_DANCING_SHADOWS, -1, 2); - else - FeatUsePerDay(oPC, FEAT_DANCING_SHADOWS, -1, 1); - } - nClass = GetLevelByClass(CLASS_TYPE_NOCTUMANCER, oPC); - if(nClass > 0) - { - if (nClass >= 8) - FeatUsePerDay(oPC, FEAT_INNATE_COUNTERSPELL, -1, 3); - else if (nClass >= 5) - FeatUsePerDay(oPC, FEAT_INNATE_COUNTERSPELL, -1, 2); - else - FeatUsePerDay(oPC, FEAT_INNATE_COUNTERSPELL, -1, 1); - } - nClass = GetLevelByClass(CLASS_TYPE_SHADOWSMITH, oPC); - if(nClass > 0) - { - FeatUsePerDay(oPC, FEAT_TOUCH_SHADOW , -1, nClass); - FeatUsePerDay(oPC, FEAT_SHROUD_SHADOW , -1, nClass); - FeatUsePerDay(oPC, FEAT_SHADOW_CRAFT , -1, nClass/2); - FeatUsePerDay(oPC, FEAT_ARMOR_SHADOW , -1, nClass/2); - FeatUsePerDay(oPC, FEAT_ARMOR_SHADOW_Q, -1, nClass/2); - } -} - -void WildMage(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_WILD_MAGE, oPC); - if(nClass > 0) - { - if (nClass >= 8) - FeatUsePerDay(oPC, FEAT_WILD_MAGE_RANDOM_DEFLECTOR, -1, 2); - else if (nClass >= 5) - FeatUsePerDay(oPC, FEAT_WILD_MAGE_RANDOM_DEFLECTOR, -1, 3); - else - FeatUsePerDay(oPC, FEAT_WILD_MAGE_RANDOM_DEFLECTOR, -1, 1); - } -} - -void Factotum(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_FACTOTUM, oPC); - if(nClass > 0) - { - if (nClass >= 20) - { - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_TURN, ABILITY_WISDOM, 0, 6); - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_HEAL, ABILITY_WISDOM, 0, 6); - } - else if (nClass >= 15) - { - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_TURN, ABILITY_WISDOM, 0, 5); - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_HEAL, ABILITY_WISDOM, 0, 5); - } - else if (nClass >= 10) - { - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_TURN, ABILITY_WISDOM, 0, 4); - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_HEAL, ABILITY_WISDOM, 0, 4); - } - else - { - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_TURN, ABILITY_WISDOM, 0, 3); - FeatUsePerDay(oPC, FEAT_OPPORTUNISTIC_PIETY_HEAL, ABILITY_WISDOM, 0, 3); - } - } -} - -void Sharess(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_CELEBRANT_SHARESS, oPC); - if(nClass > 0) - { - FeatUsePerDay(oPC, FEAT_CELEBRANT_SHARESS_FASCINATE , -1, 0, nClass); - FeatUsePerDay(oPC, FEAT_CELEBRANT_SHARESS_CONFUSE , -1, 0, nClass); - FeatUsePerDay(oPC, FEAT_CELEBRANT_SHARESS_DOMINATE , -1, 0, nClass); - } -} - -void SoulbornDefense(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_SOULBORN, oPC); - if(nClass > 0) - { - if (nClass >= 37) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 8); - else if (nClass >= 33) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 7); - else if (nClass >= 29) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 6); - else if (nClass >= 25) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 5); - else if (nClass >= 21) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 4); - else if (nClass >= 17) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 3); - else if (nClass >= 13) - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 2); - else - FeatUsePerDay(oPC, FEAT_SHARE_INCARNUM_DEFENSE, -1, 0, 1); - } -} - -void TotemistReshape(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_TOTEMIST, oPC); - if(nClass > 0) - { - if (nClass >= 40) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 9); - else if (nClass >= 36) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 8); - else if (nClass >= 32) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 7); - else if (nClass >= 28) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 6); - else if (nClass >= 24) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 5); - else if (nClass >= 20) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 4); - else if (nClass >= 16) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 3); - else if (nClass >= 12) - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 2); - else - FeatUsePerDay(oPC, FEAT_REBIND_TOTEM_SOULMELD, -1, 0, 1); - } -} - -void CWSamurai(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_CW_SAMURAI, oPC); - if(nClass > 0) - { - if (nClass >= 17) - FeatUsePerDay(oPC, FEAT_KIAI_SMITE, -1, 0, 4); - else if (nClass >= 12) - FeatUsePerDay(oPC, FEAT_KIAI_SMITE, -1, 0, 3); - else if (nClass >= 7) - FeatUsePerDay(oPC, FEAT_KIAI_SMITE, -1, 0, 2); - else - FeatUsePerDay(oPC, FEAT_KIAI_SMITE, -1, 0, 1); - } -} - -void CrusaderSmite(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_CRUSADER, oPC); - if(nClass > 0) - { - if (nClass >= 18) - FeatUsePerDay(oPC, FEAT_CRUSADER_SMITE, -1, 0, 2); - else - FeatUsePerDay(oPC, FEAT_CRUSADER_SMITE, -1, 0, 1); - } -} - -void AnimaMage(object oPC) -{ - int nClass = GetLevelByClass(CLASS_TYPE_ANIMA_MAGE, oPC); - if(nClass > 0) - { - if (nClass >= 9) - FeatUsePerDay(oPC, FEAT_ANIMA_VESTIGE_METAMAGIC, -1, 0, 3); - else if (nClass >= 7) - FeatUsePerDay(oPC, FEAT_ANIMA_VESTIGE_METAMAGIC, -1, 0, 2); - else - FeatUsePerDay(oPC, FEAT_ANIMA_VESTIGE_METAMAGIC, -1, 0, 1); - } -} - -void FeatSpecialUsePerDay(object oPC) -{ - FeatUsePerDay(oPC, FEAT_WWOC_WIDEN_SPELL, ABILITY_CHARISMA, GetLevelByClass(CLASS_TYPE_WAR_WIZARD_OF_CORMYR, oPC)); - FeatUsePerDay(oPC, FEAT_FIST_DAL_QUOR_STUNNING_STRIKE, -1, GetLevelByClass(CLASS_TYPE_FIST_DAL_QUOR, oPC)); - FeatUsePerDay(oPC, FEAT_AD_FALSE_KEENNESS, -1, GetLevelByClass(CLASS_TYPE_ARCANE_DUELIST, oPC)); - FeatUsePerDay(oPC, FEAT_LASHER_STUNNING_SNAP, -1, GetLevelByClass(CLASS_TYPE_LASHER, oPC)); - FeatUsePerDay(oPC, FEAT_AD_BLUR, -1, GetLevelByClass(CLASS_TYPE_ARCANE_DUELIST, oPC)); - FeatUsePerDay(oPC, FEAT_SHADOW_RIDE, -1, GetLevelByClass(CLASS_TYPE_CRINTI_SHADOW_MARAUDER, oPC)); - FeatUsePerDay(oPC, FEAT_SHADOWJUMP, -1, GetLevelByClass(CLASS_TYPE_SHADOWLORD, oPC)); - FeatUsePerDay(oPC, FEAT_SHADOWBANE_SMITE, -1, (GetLevelByClass(CLASS_TYPE_SHADOWBANE_INQUISITOR, oPC)+2)/4); - FeatUsePerDay(oPC, FEAT_INCARNUM_RADIANCE, -1, (GetLevelByClass(CLASS_TYPE_INCARNATE, oPC)+2)/5); - FeatUsePerDay(oPC, FEAT_RAPID_MELDSHAPING, -1, (GetLevelByClass(CLASS_TYPE_INCARNATE, oPC)+1)/6); - FeatUsePerDay(oPC, FEAT_SMITE_OPPOSITION, -1, (GetLevelByClass(CLASS_TYPE_SOULBORN, oPC)+5)/5); - FeatUsePerDay(oPC, FEAT_SMITE_CHAOS, -1, (GetLevelByClass(CLASS_TYPE_SAPPHIRE_HIERARCH, oPC)+2)/3); - FeatUsePerDay(oPC, FEAT_INCANDESCENT_OVERLOAD, -1, (GetLevelByClass(CLASS_TYPE_INCANDESCENT_CHAMPION, oPC)-1)/3); - FeatUsePerDay(oPC, FEAT_NECROCARNATE_SOULSHIELD, -1, GetLevelByClass(CLASS_TYPE_NECROCARNATE, oPC)/2); - FeatUsePerDay(oPC, FEAT_SCION_DANTALION_SCHOLARSHIP, -1, GetLevelByClass(CLASS_TYPE_SCION_DANTALION, oPC)); - FeatUsePerDay(oPC, FEAT_SMITE_GOOD_ALIGN, -1, (GetLevelByClass(CLASS_TYPE_FISTRAZIEL, oPC)+1)/2); - FeatUsePerDay(oPC, FEAT_FIST_OF_IRON, ABILITY_WISDOM, 3); - FeatUsePerDay(oPC, FEAT_SMITE_UNDEAD, ABILITY_CHARISMA, 3); - FeatUsePerDay(oPC, FEAT_COC_WRATH, ABILITY_CHARISMA, 3); - FeatUsePerDay(oPC, FEAT_KILLOREN_ASPECT_D, ABILITY_CHARISMA); - FeatUsePerDay(oPC, FEAT_AVENGING_STRIKE, ABILITY_CHARISMA, 0, 1); - FeatUsePerDay(oPC, FEAT_INCARNUM_BLADE_REBIND, ABILITY_CONSTITUTION, 1); - FeatUsePerDay(oPC, FEAT_WITCHBORN_INTEGUMENT, ABILITY_CONSTITUTION, 1); - FeatUsePerDay(oPC, FEAT_LIPS_RAPTUR); - FeatUsePerDay(oPC, FEAT_COMMAND_SPIDERS, ABILITY_CHARISMA, 3); - FeatUsePerDay(oPC, FEAT_FM_FOREST_DOMINION, ABILITY_CHARISMA, 3); - FeatDiabolist(oPC); - FeatAlaghar(oPC); - ShadowShieldUses(oPC); - CombatMedic(oPC); - FeatNinja(oPC); - FeatNoble(oPC); - MasterOfShrouds(oPC); - HexCurse(oPC); - FeatRacial(oPC); - FeatShadowblade(oPC); - SoulbornDefense(oPC); - - int nDread = GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oPC); - if (nDread >= 17) - FeatUsePerDay(oPC, FEAT_DN_ENERVATING_TOUCH, -1, nDread); - else - FeatUsePerDay(oPC, FEAT_DN_ENERVATING_TOUCH, -1, nDread/2); - - SLAUses(oPC); - DomainUses(oPC); - BardSong(oPC); - BarbarianRage(oPC); - FeatVirtuoso(oPC); - ResetExtraStunfistUses(oPC); - DarkKnowledge(oPC); - FeatImbueArrow(oPC); - DragonDisciple(oPC); - Warlock(oPC); - KotMC(oPC); - Templar(oPC); - BlighterFeats(oPC); - MysteryFeats(oPC); - WildMage(oPC); - Factotum(oPC); - Sharess(oPC); - TotemistReshape(oPC); - CWSamurai(oPC); - CrusaderSmite(oPC); - AnimaMage(oPC); - MephlingBreath(oPC); -} - diff --git a/trunk/include/prc_inc_itmrstr.nss b/trunk/include/prc_inc_itmrstr.nss deleted file mode 100644 index 7f2ca808..00000000 --- a/trunk/include/prc_inc_itmrstr.nss +++ /dev/null @@ -1,561 +0,0 @@ -/* - - This include governs all the new itemproperties - Both restrictions and features - - - -*/ -//:: Updated for .35 by Jaysyn 2023/03/10 - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -const string PLAYER_SPEED_INCREASE = "player_speed_increase"; -const string PLAYER_SPEED_DECREASE = "player_speed_decrease"; - - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -int DoUMDCheck(object oItem, object oPC, int nDCMod); - -int CheckPRCLimitations(object oItem, object oPC = OBJECT_INVALID); - -/** - * Non-returning wrapper for CheckPRCLimitations. - */ -void VoidCheckPRCLimitations(object oItem, object oPC = OBJECT_INVALID); - -void CheckForPnPHolyAvenger(object oItem); - - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "inc_utility" -#include "prc_inc_newip" -#include "prc_inc_castlvl" -#include "inc_newspellbook" - -//:: Test Void -//void main (){} - -////////////////////////////////////////////////// -/* Internal functions */ -////////////////////////////////////////////////// - -/*void _prc_inc_itmrstr_ApplySpeedModification(object oPC, int nEffectType, int nSpeedMod) -{ - if(DEBUG) DoDebug("_prc_inc_itmrstr_ApplySpeedModification(" + DebugObject2Str(oPC) + ", " + IntToString(nEffectType) + ", " + IntToString(nSpeedMod) + ")"); - // The skin object should be OBJECT_SELF here - // Clean up existing speed modification - effect eTest = GetFirstEffect(oPC); - while(GetIsEffectValid(eTest)) - { - if(GetEffectCreator(eTest) == OBJECT_SELF && - GetEffectType(eTest) == nEffectType && - GetEffectSubType(eTest) == SUBTYPE_SUPERNATURAL - ) - RemoveEffect(oPC, eTest); - eTest = GetNextEffect(oPC); - } - - // Apply speed mod if there is any - if(nSpeedMod > 0) - { - effect eSpeedMod = SupernaturalEffect(nEffectType == EFFECT_TYPE_MOVEMENT_SPEED_INCREASE ? - EffectMovementSpeedIncrease(nSpeedMod) : - EffectMovementSpeedDecrease(nSpeedMod) - ); - /// @todo Determine if the delay is actually needed here - DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSpeedMod, oPC)); - } -} - -void _prc_inc_itmrstr_ApplySpeedIncrease(object oPC) -{ - // Get target speed modification value. Limit to 99, since that's the effect constructor maximum value - int nSpeedMod = min(99, GetLocalInt(oPC, PLAYER_SPEED_INCREASE)); - object oSkin = GetPCSkin(oPC); - - AssignCommand(oSkin, _prc_inc_itmrstr_ApplySpeedModification(oPC, EFFECT_TYPE_MOVEMENT_SPEED_INCREASE, nSpeedMod)); -} - - -void _prc_inc_itmrstr_ApplySpeedDecrease(object oPC) -{ - // Get target speed modification value. Limit to 99, since that's the effect constructor maximum value - int nSpeedMod = GetLocalInt(oPC, PLAYER_SPEED_DECREASE); - object oSkin = GetPCSkin(oPC); - - AssignCommand(oSkin, _prc_inc_itmrstr_ApplySpeedModification(oPC, EFFECT_TYPE_MOVEMENT_SPEED_DECREASE, nSpeedMod)); -}*/ - -void _prc_inc_itmrstr_ApplyAoE(object oPC, object oItem, int nSubType, int nCost) -{ - int nAoEID = StringToInt(Get2DACache("iprp_aoe", "AoEID", nSubType)); - string sTag = Get2DACache("vfx_persistent", "LABEL", nAoEID); - effect eAoE = EffectAreaOfEffect(nAoEID, - Get2DACache("iprp_aoe", "EnterScript", nSubType), - Get2DACache("iprp_aoe", "HBScript", nSubType), - Get2DACache("iprp_aoe", "ExitScript", nSubType)); - - // The item applies the AoE effect - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAoE, oPC); - - // Get an object reference to the newly created AoE - location lLoc = GetLocation(oPC); - object oAoE = GetFirstObjectInShape(SHAPE_SPHERE, 1.0f, lLoc, FALSE, OBJECT_TYPE_AREA_OF_EFFECT); - while(GetIsObjectValid(oAoE)) - { - // Test if we found the correct AoE - if(GetTag(oAoE) == sTag && - !GetLocalInt(oAoE, "PRC_AoE_IPRP_Init") - ) - { - SetLocalInt(oAoE, "PRC_AoE_IPRP_Init", TRUE); - break; - } - // Didn't find, get next - oAoE = GetNextObjectInShape(SHAPE_SPHERE, 1.0f, lLoc, FALSE, OBJECT_TYPE_AREA_OF_EFFECT); - } - if(!GetIsObjectValid(oAoE)) DoDebug("ERROR: _prc_inc_itmrstr_ApplyAoE: Can't find AoE created by " + DebugObject2Str(oItem)); - - // Set caster level override on the AoE - SetLocalInt(oAoE, PRC_CASTERLEVEL_OVERRIDE, nCost); - //if(DEBUG) DoDebug("_prc_inc_itmrstr_ApplyAoE: AoE level: " + IntToString(nCost)); -} - -void _prc_inc_itmrstr_ApplyWizardry(object oPC, object oItem, int nSpellLevel, string sType) -{ - //properties were already applied - happens when loading a saved game - if(GetLocalInt(oItem, "PRC_Wizardry"+IntToString(nSpellLevel))) - return; - - SetLocalInt(oItem, "PRC_Wizardry"+IntToString(nSpellLevel), TRUE); - int nClass, nSlots, i; - for(i = 1; i <= 8; i++) - { - nClass = GetClassByPosition(i, oPC); - if((sType == "A" && GetIsArcaneClass(nClass)) || (sType == "D" && GetIsDivineClass(nClass))) - { - if(GetAbilityScoreForClass(nClass, oPC) < nSpellLevel + 10) - continue; - - int nSpellSlotLevel = GetSpellslotLevel(nClass, oPC) - 1; - string sFile = Get2DACache("classes", "SpellGainTable", nClass); - nSlots = StringToInt(Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nSpellSlotLevel)); - //if(DEBUG) DoDebug("Adding "+IntToString(nSlots)" bonus slots for "+IntToString(nClass)" class."); - - if(nSlots) - { - string sVar = "PRC_IPRPBonSpellSlots_" + IntToString(nClass) + "_" + IntToString(nSpellLevel); - int j = 0; - while(j < nSlots) - { - //DoDebug(IntToString(j)); - AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusLevelSpell(nClass, nSpellLevel), oItem); - //nsb compatibility - SetLocalInt(oPC, sVar, (GetLocalInt(oPC, sVar) + 1)); - j++; - } - } - } - } - SetPlotFlag(oItem, TRUE); -} - -void _prc_inc_itmrstr_RemoveWizardry(object oPC, object oItem, int nSpellLevel, string sType) -{ - DeleteLocalInt(oItem, "PRC_Wizardry"+IntToString(nSpellLevel)); - SetPlotFlag(oItem, FALSE); - itemproperty ipTest = GetFirstItemProperty(oItem); - string sVar; - while(GetIsItemPropertyValid(ipTest)) - { - if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N) - { - if(GetItemPropertyCostTableValue(ipTest) == nSpellLevel) - { - int nClass = GetItemPropertySubType(ipTest); - if((sType == "A" && GetIsArcaneClass(nClass)) || (sType == "D" && GetIsDivineClass(nClass))) - { - RemoveItemProperty(oItem, ipTest); - //remove bonus slots from nsb classes - sVar = "PRC_IPRPBonSpellSlots_" + IntToString(nClass) + "_" + IntToString(nSpellLevel); - SetLocalInt(oPC, sVar, (GetLocalInt(oPC, sVar) - 1)); - int nCount, nSpellbook = GetSpellbookTypeForClass(nClass); - string sArray = "NewSpellbookMem_"+IntToString(nClass); - if(nSpellbook == SPELLBOOK_TYPE_SPONTANEOUS) - { - nCount = persistant_array_get_int(oPC, sArray, nSpellLevel); - if(nCount) - { - nCount--; - persistant_array_set_int(oPC, sArray, nSpellLevel, nCount); - } - } - else if(nSpellbook == SPELLBOOK_TYPE_PREPARED) - { - string sIDX = "SpellbookIDX" + IntToString(nSpellLevel) + "_" + IntToString(nClass); - int i, nSpellbookID, nMax = persistant_array_get_size(oPC, sIDX) - 1; - for(i = nMax; i >= 0; i--) - { - nSpellbookID = persistant_array_get_int(oPC, sIDX, i); - nCount = persistant_array_get_int(oPC, sArray, nSpellbookID); - if(nCount) - { - nCount--; - persistant_array_set_int(oPC, sArray, nSpellbookID, nCount); - break; - } - } - } - } - } - } - ipTest = GetNextItemProperty(oItem); - } -} - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetUMDForItemCost(object oItem) -{ - string s2DAEntry; - int nValue = GetGoldPieceValue(oItem); - int n2DAValue = StringToInt(s2DAEntry); - int i; - while(n2DAValue < nValue) - { - s2DAEntry = Get2DACache("skillvsitemcost", "DeviceCostMax", i); - n2DAValue = StringToInt(s2DAEntry); - i++; - } - i--; - string s2DAReqSkill = Get2DACache("skillvsitemcost", "SkillReq_Class", i); - if(s2DAReqSkill == "") - return -1; - return StringToInt(s2DAReqSkill); -} - -//this is a scripted version of the bioware UMD check for using restricted items -//this also applies effects relating to new itemproperties -int DoUMDCheck(object oItem, object oPC, int nDCMod) -{ - - //doesnt have UMD - if(!GetHasSkill(SKILL_USE_MAGIC_DEVICE, oPC)) - return FALSE; - - int nSkill = GetSkillRank(SKILL_USE_MAGIC_DEVICE, oPC); - int nReqSkill = GetUMDForItemCost(oItem); - //class is a dc20 test - nReqSkill = nReqSkill - 20 + nDCMod; - if(nReqSkill > nSkill) - return FALSE; - else - return TRUE; -} - -void VoidCheckPRCLimitations(object oItem, object oPC = OBJECT_INVALID) -{ - CheckPRCLimitations(oItem, oPC); -} - -//tests for use restrictions -//also appies effects for those IPs tat need them -/// @todo Rename. It's not just limitations anymore -int CheckPRCLimitations(object oItem, object oPC = OBJECT_INVALID) -{ - // Sanity check - the item needs to be valid - if(!GetIsObjectValid(oItem)) - return FALSE; /// @todo Might be better to auto-pass the limitation aspect in case of invalid item - - // In case no item owner was given, find it out - if(!GetIsObjectValid(oPC)) - oPC = GetItemPossessor(oItem); - - // Sanity check - the item needs to be in some creature's possession for this function to make sense - if(!GetIsObjectValid(oPC)) - return FALSE; - - // Equip and Unequip events need some special handling - int bUnequip = GetItemLastUnequipped() == oItem && GetLocalInt(oPC, "ONEQUIP") == 1; - int bEquip = GetItemLastEquipped() == oItem && GetLocalInt(oPC, "ONEQUIP") == 2; - - // Use restriction and UMD use - int bPass = TRUE; - int nUMDDC = 0; - - // Speed modification. Used to determine if effects need to be applied - int nSpeedIncrease = GetLocalInt(oPC, PLAYER_SPEED_INCREASE); - int nSpeedDecrease = GetLocalInt(oPC, PLAYER_SPEED_DECREASE); - - // Loop over all itemproperties on the item - itemproperty ipTest = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(ipTest)) - { - int ipType = GetItemPropertyType(ipTest); - /* Use restrictions. All of these can be skipped when unequipping */ - if(!bUnequip) - { - if (ipType == ITEM_PROPERTY_USE_LIMITATION_ABILITY_SCORE) - { - int nValue = GetItemPropertyCostTableValue(ipTest); - if(GetAbilityScore(oPC, GetItemPropertySubType(ipTest), TRUE) < nValue) - bPass = FALSE; - nUMDDC += nValue - 15; - } - else if(ipType == ITEM_PROPERTY_USE_LIMITATION_SKILL_RANKS) - { - int nValue = GetItemPropertyCostTableValue(ipTest); - if(GetSkillRank(GetItemPropertySubType(ipTest), oPC) < nValue) - bPass = FALSE; - nUMDDC += nValue - 10; - } - else if(ipType == ITEM_PROPERTY_USE_LIMITATION_SPELL_LEVEL) - { - int nLevel = GetItemPropertyCostTableValue(ipTest); - if(GetLocalInt(oPC, "PRC_AllSpell" + IntToString(nLevel))) - bPass = FALSE; - nUMDDC += (nLevel * 2) - 20; - } - else if(ipType == ITEM_PROPERTY_USE_LIMITATION_ARCANE_SPELL_LEVEL) - { - int nLevel = GetItemPropertyCostTableValue(ipTest); - if(GetLocalInt(oPC, "PRC_ArcSpell" + IntToString(nLevel))) - bPass = FALSE; - nUMDDC += (nLevel * 2) - 20; - } - else if(ipType == ITEM_PROPERTY_USE_LIMITATION_DIVINE_SPELL_LEVEL) - { - int nLevel = GetItemPropertyCostTableValue(ipTest); - if(GetLocalInt(oPC, "PRC_DivSpell" + IntToString(nLevel))) - bPass = FALSE; - nUMDDC += (nLevel * 2) - 20; - } - else if(ipType == ITEM_PROPERTY_USE_LIMITATION_SNEAK_ATTACK) - { - int nLevel = GetItemPropertyCostTableValue(ipTest); - if(GetLocalInt(oPC, "PRC_SneakLevel" + IntToString(nLevel))) - bPass = FALSE; - nUMDDC += (nLevel * 2) - 20; - } - else if(ipType == ITEM_PROPERTY_USE_LIMITATION_GENDER) - { - if(GetGender(oPC) != GetItemPropertySubType(ipTest)) - bPass = FALSE; - nUMDDC += 5; - } - } - - /* Properties that apply effects. Unequip should cause cleanup here */ - if(ipType == ITEM_PROPERTY_SPEED_INCREASE) - { - int iItemAdjust; - switch(GetItemPropertyCostTableValue(ipTest)) - { - case 0: iItemAdjust = 10; break; - case 1: iItemAdjust = 20; break; - case 2: iItemAdjust = 30; break; - case 3: iItemAdjust = 40; break; - case 4: iItemAdjust = 50; break; - case 5: iItemAdjust = 60; break; - case 6: iItemAdjust = 70; break; - case 7: iItemAdjust = 80; break; - case 8: iItemAdjust = 90; break; - case 9: iItemAdjust = 100; break; - } - if(bUnequip) - nSpeedIncrease -= iItemAdjust; - else if(bEquip) - nSpeedIncrease += iItemAdjust; - } - else if(ipType == ITEM_PROPERTY_SPEED_DECREASE) - { - int iItemAdjust; - switch(GetItemPropertyCostTableValue(ipTest)) - { - case 0: iItemAdjust = 10; break; - case 1: iItemAdjust = 20; break; - case 2: iItemAdjust = 30; break; - case 3: iItemAdjust = 40; break; - case 4: iItemAdjust = 50; break; - case 5: iItemAdjust = 60; break; - case 6: iItemAdjust = 70; break; - case 7: iItemAdjust = 80; break; - case 8: iItemAdjust = 90; break; - case 9: iItemAdjust = 99; break; - } - if(bUnequip) - nSpeedDecrease -= iItemAdjust; - else if(bEquip) - nSpeedDecrease += iItemAdjust; - } - else if(ipType == ITEM_PROPERTY_PNP_HOLY_AVENGER) - { - if(bEquip) - { - int nPaladinLevels = GetLevelByClass(CLASS_TYPE_PALADIN, oPC); - if(!nPaladinLevels) - { - //not a paladin? fake it - //not really a true PnP test - //instead it sets the paladin level - //to the UMD ranks minus the amount required - //to use a class restricted item of that value - int nSkill = GetSkillRank(SKILL_USE_MAGIC_DEVICE, oPC); - if(nSkill) - { - int nReqSkill = GetUMDForItemCost(oItem); - nSkill -= nReqSkill; - if(nSkill > 0) - nPaladinLevels = nSkill; - } - } - - // Add Holy Avenger specials for Paladins (or successfull fake-Paladins) - if(nPaladinLevels) - { - DelayCommand(0.1, IPSafeAddItemProperty(oItem, - ItemPropertyEnhancementBonus(5), 99999.9)); - DelayCommand(0.1, IPSafeAddItemProperty(oItem, - ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL, - IP_CONST_DAMAGETYPE_DIVINE, IP_CONST_DAMAGEBONUS_2d6), 99999.9)); - //this is a normal dispel magic useage, should be specific - DelayCommand(0.1, IPSafeAddItemProperty(oItem, - ItemPropertyCastSpell(IP_CONST_CASTSPELL_DISPEL_MAGIC_5, - IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE), 99999.9)); - DelayCommand(0.1, IPSafeAddItemProperty(oItem, - ItemPropertyCastSpellCasterLevel(SPELL_DISPEL_MAGIC, - nPaladinLevels), 99999.9)); - } - // Non-Paladin's get +2 enhancement bonus - else - { - DelayCommand(0.1, IPSafeAddItemProperty(oItem, - ItemPropertyEnhancementBonus(2), 99999.9)); - - // Remove Paladin specials - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS, DURATION_TYPE_TEMPORARY, -1); - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP, DURATION_TYPE_TEMPORARY, IP_CONST_ALIGNMENTGROUP_EVIL); - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_CAST_SPELL, DURATION_TYPE_TEMPORARY); - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_CAST_SPELL_CASTER_LEVEL, DURATION_TYPE_TEMPORARY); - } - } - else if(bUnequip) - { - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS, - DURATION_TYPE_TEMPORARY, -1); - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP, - DURATION_TYPE_TEMPORARY, IP_CONST_ALIGNMENTGROUP_EVIL); - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_CAST_SPELL, - DURATION_TYPE_TEMPORARY); - IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_CAST_SPELL_CASTER_LEVEL, - DURATION_TYPE_TEMPORARY); - } - } - else if(ipType == ITEM_PROPERTY_AREA_OF_EFFECT) - { - - // This should only happen on equip or unequip - if(bEquip || bUnequip) - { - // Remove existing AoE - effect eTest = GetFirstEffect(oPC); - while(GetIsEffectValid(eTest)) - { - if(GetEffectCreator(eTest) == oItem - && GetEffectType(eTest) == EFFECT_TYPE_AREA_OF_EFFECT) - { - RemoveEffect(oPC, eTest); - if(DEBUG) DoDebug("CheckPRCLimitations: Removing old AoE effect"); - } - eTest = GetNextEffect(oPC); - } - - // Create new AoE - Only when equipping - if(bEquip) - { - AssignCommand(oItem, _prc_inc_itmrstr_ApplyAoE(oPC, oItem, GetItemPropertySubType(ipTest), GetItemPropertyCostTable(ipTest))); - }// end if - Equip event - }// end if - Equip or Unequip event - }// end if - AoE iprp - else if(ipType == ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N) - { - // Only equippable items can provide bonus spell slots - if(bEquip || bUnequip) - { - int nSubType = GetItemPropertySubType(ipTest); - int nCost = GetItemPropertyCostTable(ipTest); - SetLocalInt(oPC, - "PRC_IPRPBonSpellSlots_" + IntToString(nSubType) + "_" + IntToString(nCost), - GetLocalInt(oPC, - "PRC_IPRPBonSpellSlots_" + IntToString(nSubType) + "_" + IntToString(nCost) - ) - + (bEquip ? 1 : -1) - ); - } - } - else if(ipType == ITEM_PROPERTY_WIZARDRY) - { - int nCost = GetItemPropertyCostTableValue(ipTest); - if(bEquip) - AssignCommand(oItem, _prc_inc_itmrstr_ApplyWizardry(oPC, oItem, nCost, "A")); - else if(bUnequip) - AssignCommand(oItem, _prc_inc_itmrstr_RemoveWizardry(oPC, oItem, nCost, "A")); - } - else if(ipType == ITEM_PROPERTY_DIVINITY) - { - int nCost = GetItemPropertyCostTableValue(ipTest); - if(bEquip) - AssignCommand(oItem, _prc_inc_itmrstr_ApplyWizardry(oPC, oItem, nCost, "D")); - else if(bUnequip) - AssignCommand(oItem, _prc_inc_itmrstr_RemoveWizardry(oPC, oItem, nCost, "D")); - } - - ipTest = GetNextItemProperty(oItem); - }// end while - Loop over all itemproperties - - // Determine if speed modification totals had changed - if(nSpeedDecrease != GetLocalInt(oPC, PLAYER_SPEED_DECREASE)) - { - SetLocalInt(oPC, PLAYER_SPEED_DECREASE, nSpeedDecrease); - //_prc_inc_itmrstr_ApplySpeedDecrease(oPC); - } - if(nSpeedIncrease != GetLocalInt(oPC, PLAYER_SPEED_INCREASE)) - { - SetLocalInt(oPC, PLAYER_SPEED_INCREASE, nSpeedIncrease); - //_prc_inc_itmrstr_ApplySpeedIncrease(oPC); - } - - // If some restriction would prevent item use, perform UMD skill check - // Skip in case of unequip - if(!bUnequip && !bPass) - bPass = DoUMDCheck(oItem, oPC, nUMDDC); - - return bPass; -} - -void CheckForPnPHolyAvenger(object oItem) -{ - if(!GetPRCSwitch(PRC_PNP_HOLY_AVENGER_IPROP)) - return; - itemproperty ipTest = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(ipTest)) - { - if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_HOLY_AVENGER) - { - DelayCommand(0.1, RemoveItemProperty(oItem, ipTest)); - DelayCommand(0.1, IPSafeAddItemProperty(oItem, ItemPropertyPnPHolyAvenger())); - } - ipTest = GetNextItemProperty(oItem); - } -} \ No newline at end of file diff --git a/trunk/include/prc_inc_leadersh.nss b/trunk/include/prc_inc_leadersh.nss deleted file mode 100644 index d305b67a..00000000 --- a/trunk/include/prc_inc_leadersh.nss +++ /dev/null @@ -1,1043 +0,0 @@ -//:: Updated for .35 by Jaysyn 2023/03/10 - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -const string COHORT_DATABASE = "PRCCOHORTS"; -const string COHORT_TAG = "prc_cohort"; - -//in the database there is the folloxing data structures: -/* - int CohortCount (total number of cohorts) - object Cohort_X_obj (cohort itself) - string Cohort_X_name (cohort name) - int Cohort_X_race (cohort race) - int Cohort_X_class1 (cohort class pos1) - int Cohort_X_class2 (cohort class pos2) - int Cohort_X_class3 (cohort class pos3) - int Cohort_X_order (cohort law/chaos measure) - int Cohort_X_moral (cohort good/evil measure) - int Cohort_X_ethran (cohort has ethran feat) - string Cohort_X_cdkey (cdkey of owning player) -*/ - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -int GetMaximumCohortCount(object oPC); -object GetCohort(int nID, object oPC); -int GetCurrentCohortCount(object oPC); -int GetCohortMaxLevel(int nLeadership, object oPC); -void RegisterAsCohort(object oPC); -object AddCohortToPlayer(int nCohortID, object oPC); -void AddCohortToPlayerByObject(object oCohort, object oPC, int bDoSetup = TRUE); -void RemoveCohortFromPlayer(object oCohort, object oPC); -int GetLeadershipScore(object oPC = OBJECT_SELF); -void CheckHB(object oPC); -void AddPremadeCohortsToDB(); -void StoreCohort(object oCohort); - - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "prc_feat_const" -#include "nw_o2_coninclude" -//#include "inc_utility" -#include "inc_ecl" -#include "inc_nwnx_funcs" -//#include "pnp_shft_poly" //for DoRandomAppearance - - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -object AddCohortToPlayer(int nCohortID, object oPC) -{ - object oCohort = RetrieveCampaignObject(COHORT_DATABASE, "Cohort_"+IntToString(nCohortID)+"_obj", GetLocation(oPC)); - //give it a tag - AssignCommand(oCohort, SetIsDestroyable(TRUE, FALSE, FALSE)); - DestroyObject(oCohort); - oCohort = CopyObject(oCohort, GetLocation(oPC), OBJECT_INVALID, COHORT_TAG); - SetLocalInt(oCohort, "CohortID", nCohortID); - //pass it to the next function - AddCohortToPlayerByObject(oCohort, oPC); - return oCohort; -} - -//changes portrait, head, and appearance -//based on the target race with a degree of randomization. -//This should only be used on NPCs, not players. -void DoRandomAppearance(int nRace, object oTarget = OBJECT_SELF) -{ - //store current appearance to be safe - int nAppearance; //appearance to change into - int nHeadMax; //max head ID, changed to random 1-max - int nGender = GetGender(oTarget); - int nPortraitMin;//minimum row in portraits.2da - int nPortraitMax;//maximum row in portraits.2da - switch(nRace) - { - case RACIAL_TYPE_DWARF: - nAppearance = APPEARANCE_TYPE_DWARF; - if(nGender == GENDER_MALE) - { nHeadMax = 10; nPortraitMin = 9; nPortraitMax = 17; } - else - { nHeadMax = 12; nPortraitMin = 1; nPortraitMax = 8; } - break; - case RACIAL_TYPE_ELF: - nAppearance = APPEARANCE_TYPE_ELF; - if(nGender == GENDER_MALE) - { nHeadMax = 10; nPortraitMin = 31; nPortraitMax = 40; } - else - { nHeadMax = 16; nPortraitMin = 18; nPortraitMax = 30; } - break; - case RACIAL_TYPE_HALFELF: - nAppearance = APPEARANCE_TYPE_HALF_ELF; - if(nGender == GENDER_MALE) - { nHeadMax = 18; nPortraitMin = 93; nPortraitMax = 112; } - else - { nHeadMax = 15; nPortraitMin = 67; nPortraitMax = 92; } - break; - case RACIAL_TYPE_HALFORC: - nAppearance = APPEARANCE_TYPE_HALF_ORC; - if(nGender == GENDER_MALE) - { nHeadMax = 11; nPortraitMin = 134; nPortraitMax = 139; } - else - { nHeadMax = 1; nPortraitMin = 130; nPortraitMax = 133; } - break; - case RACIAL_TYPE_HUMAN: - nAppearance = APPEARANCE_TYPE_HUMAN; - if(nGender == GENDER_MALE) - { nHeadMax = 18; nPortraitMin = 93; nPortraitMax = 112; } - else - { nHeadMax = 15; nPortraitMin = 67; nPortraitMax = 92; } - break; - case RACIAL_TYPE_HALFLING: - nAppearance = APPEARANCE_TYPE_HALFLING; - if(nGender == GENDER_MALE) - { nHeadMax = 8; nPortraitMin = 61; nPortraitMax = 66; } - else - { nHeadMax = 11; nPortraitMin = 54; nPortraitMax = 59; } - break; - case RACIAL_TYPE_GNOME: - nAppearance = APPEARANCE_TYPE_GNOME; - if(nGender == GENDER_MALE) - { nHeadMax = 11; nPortraitMin = 47; nPortraitMax = 53; } - else - { nHeadMax = 9; nPortraitMin = 41; nPortraitMax = 46; } - break; - default: //not a normal race, abort - return; - } - //change the appearance - SetCreatureAppearanceType(oTarget, nAppearance); - - //need to be delayed a bit otherwise you get "supergnome" and "exploded elf" effects - DelayCommand(1.1, SetCreatureBodyPart(CREATURE_PART_RIGHT_SHIN, d2(), oTarget)); - DelayCommand(1.2, SetCreatureBodyPart(CREATURE_PART_LEFT_SHIN, d2(), oTarget)); - DelayCommand(1.3, SetCreatureBodyPart(CREATURE_PART_RIGHT_THIGH, d2(), oTarget)); - DelayCommand(1.4, SetCreatureBodyPart(CREATURE_PART_LEFT_THIGH, d2(), oTarget)); - DelayCommand(1.5, SetCreatureBodyPart(CREATURE_PART_TORSO, d2(), oTarget)); - DelayCommand(1.6, SetCreatureBodyPart(CREATURE_PART_RIGHT_FOREARM, d2(), oTarget)); - DelayCommand(1.7, SetCreatureBodyPart(CREATURE_PART_LEFT_FOREARM, d2(), oTarget)); - DelayCommand(1.8, SetCreatureBodyPart(CREATURE_PART_RIGHT_BICEP, d2(), oTarget)); - DelayCommand(1.9, SetCreatureBodyPart(CREATURE_PART_LEFT_BICEP, d2(), oTarget)); - - //dont do these body parts, they dont have tattoos and weird things could happen - //SetCreatureBodyPart(CREATURE_PART_BELT, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_NECK, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_RIGHT_SHOULDER, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_LEFT_SHOULDER, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_RIGHT_HAND, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_LEFT_HAND, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_PELVIS, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_RIGHT_FOOT, d2(), oTarget); - //SetCreatureBodyPart(CREATURE_PART_LEFT_FOOT, d2(), oTarget); - //randomise the head - DelayCommand(2.0, SetCreatureBodyPart(CREATURE_PART_HEAD, Random(nHeadMax)+1, oTarget)); - - //remove any wings/tails - SetCreatureWingType(CREATURE_WING_TYPE_NONE, oTarget); - SetCreatureTailType(CREATURE_TAIL_TYPE_NONE, oTarget); - - int nPortraitID = Random(nPortraitMax-nPortraitMin+1)+nPortraitMin; - string sPortraitResRef = Get2DACache("portraits", "BaseResRef", nPortraitID); - sPortraitResRef = GetStringLeft(sPortraitResRef, GetStringLength(sPortraitResRef)-1); //trim the trailing _ - SetPortraitResRef(oTarget, sPortraitResRef); - SetPortraitId(oTarget, nPortraitID); -} - -void CancelGreatFeats(object oSpawn) -{ - //store how many Great X feats they have - //this is to fix a bioware bug where de-leveling doesnt remove the stat bonus - int nGreatStr; - int nGreatDex; - int nGreatCon; - int nGreatInt; - int nGreatWis; - int nGreatCha; - if (GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_10, oSpawn)) nGreatStr = 10; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_9, oSpawn)) nGreatStr = 9; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_8, oSpawn)) nGreatStr = 8; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_7, oSpawn)) nGreatStr = 7; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_6, oSpawn)) nGreatStr = 6; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_5, oSpawn)) nGreatStr = 5; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_4, oSpawn)) nGreatStr = 4; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_3, oSpawn)) nGreatStr = 3; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_2, oSpawn)) nGreatStr = 2; - else if(GetHasFeat(FEAT_EPIC_GREAT_STRENGTH_1, oSpawn)) nGreatStr = 1; - if (GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_10, oSpawn)) nGreatDex = 10; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_9, oSpawn)) nGreatDex = 9; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_8, oSpawn)) nGreatDex = 8; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_7, oSpawn)) nGreatDex = 7; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_6, oSpawn)) nGreatDex = 6; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_5, oSpawn)) nGreatDex = 5; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_4, oSpawn)) nGreatDex = 4; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_3, oSpawn)) nGreatDex = 3; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_2, oSpawn)) nGreatDex = 2; - else if(GetHasFeat(FEAT_EPIC_GREAT_DEXTERITY_1, oSpawn)) nGreatDex = 1; - if (GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_10, oSpawn)) nGreatCon = 10; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_9, oSpawn)) nGreatCon = 9; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_8, oSpawn)) nGreatCon = 8; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_7, oSpawn)) nGreatCon = 7; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_6, oSpawn)) nGreatCon = 6; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_5, oSpawn)) nGreatCon = 5; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_4, oSpawn)) nGreatCon = 4; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_3, oSpawn)) nGreatCon = 3; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_2, oSpawn)) nGreatCon = 2; - else if(GetHasFeat(FEAT_EPIC_GREAT_CONSTITUTION_1, oSpawn)) nGreatCon = 1; - if (GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_10, oSpawn)) nGreatInt = 10; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_9, oSpawn)) nGreatInt = 9; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_8, oSpawn)) nGreatInt = 8; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_7, oSpawn)) nGreatInt = 7; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_6, oSpawn)) nGreatInt = 6; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_5, oSpawn)) nGreatInt = 5; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_4, oSpawn)) nGreatInt = 4; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_3, oSpawn)) nGreatInt = 3; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_2, oSpawn)) nGreatInt = 2; - else if(GetHasFeat(FEAT_EPIC_GREAT_INTELLIGENCE_1, oSpawn)) nGreatInt = 1; - if (GetHasFeat(FEAT_EPIC_GREAT_WISDOM_10, oSpawn)) nGreatWis = 10; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_9, oSpawn)) nGreatWis = 9; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_8, oSpawn)) nGreatWis = 8; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_7, oSpawn)) nGreatWis = 7; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_6, oSpawn)) nGreatWis = 6; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_5, oSpawn)) nGreatWis = 5; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_4, oSpawn)) nGreatWis = 4; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_3, oSpawn)) nGreatWis = 3; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_2, oSpawn)) nGreatWis = 2; - else if(GetHasFeat(FEAT_EPIC_GREAT_WISDOM_1, oSpawn)) nGreatWis = 1; - if (GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_10, oSpawn)) nGreatCha = 10; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_9, oSpawn)) nGreatCha = 9; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_8, oSpawn)) nGreatCha = 8; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_7, oSpawn)) nGreatCha = 7; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_6, oSpawn)) nGreatCha = 6; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_5, oSpawn)) nGreatCha = 5; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_4, oSpawn)) nGreatCha = 4; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_3, oSpawn)) nGreatCha = 3; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_2, oSpawn)) nGreatCha = 2; - else if(GetHasFeat(FEAT_EPIC_GREAT_CHARISMA_1, oSpawn)) nGreatCha = 1; - - //apply penalties to counter the GreatX feats - if(GetPRCSwitch(PRC_NWNX_FUNCS)) - { - if(nGreatStr) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_STRENGTH, -nGreatStr); - if(nGreatDex) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_DEXTERITY, -nGreatDex); - if(nGreatCon) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_CONSTITUTION, -nGreatCon); - if(nGreatInt) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_INTELLIGENCE, -nGreatInt); - if(nGreatWis) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_WISDOM, -nGreatWis); - if(nGreatCha) PRC_Funcs_ModAbilityScore(oSpawn, ABILITY_CHARISMA, -nGreatCha); - } - else - { - if(nGreatStr) - ApplyEffectToObject(DURATION_TYPE_PERMANENT, - SupernaturalEffect(EffectAbilityDecrease(ABILITY_STRENGTH, nGreatStr)), - oSpawn); - if(nGreatDex) - ApplyEffectToObject(DURATION_TYPE_PERMANENT, - SupernaturalEffect(EffectAbilityDecrease(ABILITY_DEXTERITY, nGreatDex)), - oSpawn); - if(nGreatCon) - ApplyEffectToObject(DURATION_TYPE_PERMANENT, - SupernaturalEffect(EffectAbilityDecrease(ABILITY_CONSTITUTION, nGreatCon)), - oSpawn); - if(nGreatInt) - ApplyEffectToObject(DURATION_TYPE_PERMANENT, - SupernaturalEffect(EffectAbilityDecrease(ABILITY_INTELLIGENCE, nGreatInt)), - oSpawn); - if(nGreatWis) - ApplyEffectToObject(DURATION_TYPE_PERMANENT, - SupernaturalEffect(EffectAbilityDecrease(ABILITY_WISDOM, nGreatWis)), - oSpawn); - if(nGreatCha) - ApplyEffectToObject(DURATION_TYPE_PERMANENT, - SupernaturalEffect(EffectAbilityDecrease(ABILITY_CHARISMA, nGreatCha)), - oSpawn); - } -} - -void AddCohortToPlayerByObject(object oCohort, object oPC, int bDoSetup = TRUE) -{ - //add it to the pc - int nMaxHenchmen = GetMaxHenchmen(); - SetMaxHenchmen(99); - AddHenchman(oPC, oCohort); - SetMaxHenchmen(nMaxHenchmen); - object oSkin = GetPCSkin(oCohort); - - if(bDoSetup) - { - //if it was a premade one, give it a random name - //randomize its appearance using DoRandomAppearance - if(GetResRef(oCohort) != "") - { - string sName; - //first name - switch(MyPRCGetRacialType(oCohort)) - { - case RACIAL_TYPE_DWARF: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_DWARF_FEMALE); - else - sName += RandomName(NAME_FIRST_DWARF_MALE); - break; - case RACIAL_TYPE_ELF: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_ELF_FEMALE); - else - sName += RandomName(NAME_FIRST_ELF_MALE); - break; - case RACIAL_TYPE_GNOME: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_GNOME_FEMALE); - else - sName += RandomName(NAME_FIRST_GNOME_MALE); - break; - case RACIAL_TYPE_HUMAN: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_HUMAN_FEMALE); - else - sName += RandomName(NAME_FIRST_HUMAN_MALE); - break; - case RACIAL_TYPE_HALFELF: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_HALFELF_FEMALE); - else - sName += RandomName(NAME_FIRST_HALFELF_MALE); - break; - case RACIAL_TYPE_HALFORC: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_HALFORC_FEMALE); - else - sName += RandomName(NAME_FIRST_HALFORC_MALE); - break; - case RACIAL_TYPE_HALFLING: - if(GetGender(oCohort) == GENDER_FEMALE) - sName += RandomName(NAME_FIRST_HALFLING_FEMALE); - else - sName += RandomName(NAME_FIRST_HALFLING_MALE); - break; - } - sName += " "; - //surname - switch(MyPRCGetRacialType(oCohort)) - { - case RACIAL_TYPE_DWARF: - sName += RandomName(NAME_LAST_DWARF); - break; - case RACIAL_TYPE_ELF: - sName += RandomName(NAME_LAST_ELF); - break; - case RACIAL_TYPE_GNOME: - sName += RandomName(NAME_LAST_GNOME); - break; - case RACIAL_TYPE_HUMAN: - sName += RandomName(NAME_LAST_HUMAN); - break; - case RACIAL_TYPE_HALFELF: - sName += RandomName(NAME_LAST_HALFELF); - break; - case RACIAL_TYPE_HALFORC: - sName += RandomName(NAME_LAST_HALFORC); - break; - case RACIAL_TYPE_HALFLING: - sName += RandomName(NAME_LAST_HALFLING); - break; - } - //sanity check - if(sName == " ") - sName = ""; - //change the name - AssignCommand(oCohort, SetName(oCohort, sName)); - - //use disguise code to alter head etc - DoRandomAppearance(MyPRCGetRacialType(oCohort), oCohort); - - //DoRandomAppearance removed wings/tails need to re-add - if(GetRacialType(oCohort) == RACIAL_TYPE_FEYRI) - SetCreatureWingType(CREATURE_WING_TYPE_DEMON, oCohort); - else if(GetRacialType(oCohort) == RACIAL_TYPE_AVARIEL) - SetCreatureWingType(CREATURE_WING_TYPE_BIRD, oCohort); - } - //if its a custom made cohort, need to cancel GreatX feats - else - CancelGreatFeats(oCohort); - - //set it to the pcs level - int nLevel = GetCohortMaxLevel(GetLeadershipScore(oPC), oPC); - SetXP(oCohort, nLevel*(nLevel-1)*500); - SetLocalInt(oCohort, "MastersXP", GetXP(oPC)); - DelayCommand(1.0, AssignCommand(oCohort, SetIsDestroyable(FALSE, TRUE, TRUE))); - DelayCommand(1.0, AssignCommand(oCohort, SetLootable(oCohort, TRUE))); - //set its maximum level lag - if(GetCurrentCohortCount(oPC) <= GetPRCSwitch(PRC_BONUS_COHORTS)) - { - //bonus cohort, no cap - } - else if(GetPRCSwitch(PRC_THRALLHERD_LEADERSHIP) - && GetLevelByClass(CLASS_TYPE_THRALLHERD, oPC) - && GetCurrentCohortCount(oPC) <= GetPRCSwitch(PRC_BONUS_COHORTS)+1) - { - //thrallherd with switch, 1 level lag - SetLocalInt(oCohort, "CohortLevelLag", 1); - } - else if(GetPRCSwitch(PRC_THRALLHERD_LEADERSHIP) - && GetLevelByClass(CLASS_TYPE_THRALLHERD, oPC) >= 10 - && GetCurrentCohortCount(oPC) <= GetPRCSwitch(PRC_BONUS_COHORTS)+2) - { - //twofold master with switch, 2 level lag - SetLocalInt(oCohort, "CohortLevelLag", 2); - } - else - { - //other cohort have a 2 level lag - SetLocalInt(oCohort, "CohortLevelLag", 2); - } - - //strip its equipment & inventory - object oTest = GetFirstItemInInventory(oCohort); - object oToken = GetHideToken(oCohort); - while(GetIsObjectValid(oTest)) - { - if(GetHasInventory(oTest)) - { - object oTest2 = GetFirstItemInInventory(oTest); - while(GetIsObjectValid(oTest2)) - { - // Avoid blowing up the hide and token that just had the eventscripts stored on them - if(oTest2 != oSkin && oTest2 != oToken) - DestroyObject(oTest2); - oTest2 = GetNextItemInInventory(oTest); - } - } - // Avoid blowing up the hide and token that just had the eventscripts stored on them - if(oTest != oSkin && oTest != oToken) - DestroyObject(oTest); - oTest = GetNextItemInInventory(oCohort); - } - int nSlot; - for(nSlot = 0;nSlot<14;nSlot++) - { - oTest = GetItemInSlot(nSlot, oCohort); - DestroyObject(oTest); - } - //get rid of any gold it has - TakeGoldFromCreature(GetGold(oCohort), oCohort, TRUE); - } - //clean up any leftovers on the skin - ScrubPCSkin(oCohort, oSkin); - DeletePRCLocalInts(oSkin); - - //turn on its scripts - //normal MoB set - AddEventScript(oCohort, EVENT_VIRTUAL_ONPHYSICALATTACKED, "prc_ai_mob_attck", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONBLOCKED, "prc_ai_mob_block", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONCOMBATROUNDEND, "prc_ai_mob_combt", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONDAMAGED, "prc_ai_mob_damag", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONDISTURBED, "prc_ai_mob_distb", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONPERCEPTION, "prc_ai_mob_percp", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONSPAWNED, "prc_ai_mob_spawn", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONSPELLCASTAT, "prc_ai_mob_spell", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONDEATH, "prc_ai_mob_death", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONRESTED, "prc_ai_mob_rest", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONUSERDEFINED, "prc_ai_mob_userd", TRUE, FALSE); - //dont run this, cohort-specific script replaces it - //AddEventScript(oCohort, EVENT_VIRTUAL_ONCONVERSATION, "prc_ai_mob_conv", TRUE, TRUE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONHEARTBEAT, "prc_ai_mob_heart", TRUE, FALSE); - //cohort specific ones - AddEventScript(oCohort, EVENT_VIRTUAL_ONCONVERSATION, "prc_ai_coh_conv", TRUE, FALSE); - AddEventScript(oCohort, EVENT_VIRTUAL_ONHEARTBEAT, "prc_ai_coh_hb", TRUE, FALSE); - - //mark the master on the cohort - SetLocalObject(oCohort, "MasterObject", oPC); - - //DEBUG - //various tests - if (DEBUG) DoDebug("Cohort Name="+GetName(oCohort)); - if (DEBUG) DoDebug("Cohort HD="+IntToString(GetHitDice(oCohort))); - if (DEBUG) DoDebug("Cohort XP="+IntToString(GetXP(oCohort))); - if (DEBUG) DoDebug("Cohort GetIsPC="+IntToString(GetIsPC(oCohort))); - - // And now gear it up - if (!GetPRCSwitch(PRC_DISABLE_COHORT_STARTING_GEAR)) - { - int i; - int nHD = GetHitDice(oCohort); - for(i = 0;i= 3) nLeadership += GetLevelByClass(CLASS_TYPE_SHADOW_THIEF_AMN, oPC) - 2; - //without epic leadership its capped at 25 - if(!GetHasFeat(FEAT_EPIC_LEADERSHIP, oPC) && nLeadership > 25) - nLeadership = 25; - - return nLeadership; -} - -void StoreCohort(object oCohort) -{ - int nCohortCount = GetCampaignInt(COHORT_DATABASE, "CohortCount"); - int i; - for(i=0;i 1) - return; - SetLocalInt(oPC, "CohortCheckHB", GetLocalInt(oPC, "CohortCheckHB")+1); - DelayCommand(0.99, - SetLocalInt(oPC, "CohortCheckHB", GetLocalInt(oPC, "CohortCheckHB")-1)); - SetCommandable(FALSE, oPC); - if(GetHitDice(oPC) == 40) - { - StoreCohort(oPC); - //restore previous xp amound - SetXP(oPC, GetLocalInt(oPC, "OriginalXP")); - //tell the player what was done - SendMessageToPC(oPC, "Character registered as cohort."); - //remove the non-commandabiltiy - SetCommandable(TRUE, oPC); - // Clean up - DeletePersistantLocalInt(oPC, "RegisteringAsCohort"); - DeleteLocalInt(oPC, "OriginalXP"); - //stop the psuedoHB - return; - } - DelayCommand(1.0, CheckHB(oPC)); -} - -void RegisterAsCohort(object oPC) -{ - string sMessage; - sMessage += "This will register you character to be selected as a cohort.\n"; - sMessage += "As part of this process, you have to levelup to level 40.\n"; - sMessage += "Once you reach level 40, your character will be stored.\n"; - sMessage += "Then when the character is used as a cohort, it will follow that levelup path.\n"; - sMessage += "Any changes to the cohort will not apply to the original character.\n"; - //SendMessageToPC(oPC, sMessage); - FloatingTextStringOnCreature(sMessage, oPC); - - SetLocalInt(oPC, "OriginalXP", GetXP(oPC)); - SetXP(oPC, 40*(40-1)*500); - SetPersistantLocalInt(oPC, "RegisteringAsCohort", TRUE); - AssignCommand(GetModule(), CheckHB(oPC)); -} - -int LeadershipScore2CohortLevel(int nLeadership) -{ - switch(nLeadership) - { - case 1: return 0; - case 2: return 1; - case 3: return 2; - case 4: - case 5: return 3; - case 6: return 4; - case 7: - case 8: return 5; - case 9: return 6; - case 10: - case 11: return 7; - case 12: return 8; - case 13: return 9; - case 14: - case 15: return 10; - case 16: return 11; - case 17: - case 18: return 12; - case 19: return 13; - case 20: return 14; - case 21: - case 22: return 15; - case 23: return 16; - case 24: - case 25: return 17; - case 26: - case 27: return 18; - case 28: - case 29: return 19; - case 30: - case 31: return 20; - case 32: - case 33: return 21; - case 34: - case 35: return 22; - case 36: - case 37: return 23; - case 38: - case 39: return 24; - case 40: - case 41: return 25; - case 42: - case 43: return 26; - case 44: - case 45: return 27; - case 46: - case 47: return 28; - case 48: - case 49: return 29; - case 50: - case 51: return 30; - case 52: - case 53: return 31; - case 54: - case 55: return 32; - case 56: - case 57: return 33; - case 58: - case 59: return 34; - case 60: return 35; - case 61: - case 62: return 36; - case 63: - case 64: return 37; - case 65: - case 66: return 38; - case 67: - case 68: return 39; - case 69: - case 70: return 40; - } - return 0; -} - -int GetCohortMaxLevel(int nLeadership, object oPC) -{ - //if its a bonus cohort, use the players ECL - int nMasterLevel = GetECL(oPC); - if(GetCurrentCohortCount(oPC) <= GetPRCSwitch(PRC_BONUS_COHORTS)) - return nMasterLevel; - int nLevel = LeadershipScore2CohortLevel(nLeadership); - //apply a level lag - if(GetPRCSwitch(PRC_THRALLHERD_LEADERSHIP) - && GetLevelByClass(CLASS_TYPE_THRALLHERD, oPC) - && GetCurrentCohortCount(oPC) <= GetPRCSwitch(PRC_BONUS_COHORTS)+1) - { - //thrallherd with switch, 1 level lag - if(nLevel > nMasterLevel-1) - nLevel = nMasterLevel-1; - } - else if(GetPRCSwitch(PRC_THRALLHERD_LEADERSHIP) - && GetLevelByClass(CLASS_TYPE_THRALLHERD, oPC) >= 10 - && GetCurrentCohortCount(oPC) <= GetPRCSwitch(PRC_BONUS_COHORTS)+2) - { - //twofold master with switch, 2 level lag - if(nLevel > nMasterLevel-2) - nLevel = nMasterLevel-2; - } - else - { - //other cohort have a 2 level lag - if(nLevel > nMasterLevel-2) - nLevel = nMasterLevel-2; - if (GetHasFeat(FEAT_IMPROVED_COHORT, oPC)) nLevel += 1; - } - //really, leadership should be capped at 25 / 17HD - //but this is a sanity check - if(nLevel > 20 - && !GetHasFeat(FEAT_EPIC_LEADERSHIP, oPC)) - nLevel = 20; - return nLevel; -} - -int GetCurrentCohortCount(object oPC) -{ - int nCount; - object oTest; - object oOldTest; - int i = 1; - oTest = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, i); - while(GetIsObjectValid(oTest) && oTest != oOldTest) - { - if(GetTag(oTest) == COHORT_TAG) - nCount++; - i++; - oOldTest = oTest; - oTest = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, i); - } - return nCount; -} - -object GetCohort(int nID, object oPC) -{ - int nCount; - object oTest; - object oOldTest; - int i = 1; - oTest = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, i); - while(GetIsObjectValid(oTest) && oTest != oOldTest) - { - if(GetTag(oTest) == COHORT_TAG) - nCount++; - if(nCount == nID) - return oTest; - i++; - oOldTest = oTest; - oTest = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, i); - } - return OBJECT_INVALID; -} - -int GetMaximumCohortCount(object oPC) -{ - int nCount; - if(!GetLevelByClass(CLASS_TYPE_THRALLHERD, oPC)) - { - if(GetHasFeat(FEAT_LEADERSHIP, oPC)) - nCount++; - if(GetHasFeat(FEAT_LEGENDARY_COMMANDER, oPC)) - nCount++; - } - //thrallherd with switch - else if(GetPRCSwitch(PRC_THRALLHERD_LEADERSHIP)) - { - nCount++; - //twofold masteer - if(GetLevelByClass(CLASS_TYPE_THRALLHERD, oPC) > 9) - nCount++; - } - //hathran class - if(GetHasFeat(FEAT_HATH_COHORT, oPC)) - nCount++; - //orc warlord with switch - if(GetHasFeat(FEAT_GATHER_HORDE_I, oPC) - && GetPRCSwitch(PRC_ORC_WARLORD_COHORT)) - nCount++; - nCount += GetPRCSwitch(PRC_BONUS_COHORTS); - return nCount; -} - -int GetIsCohortChoiceValid(string sName, int nRace, int nClass1, int nClass2, int nClass3, int nOrder, int nMoral, int nEthran, string sKey, int nDeleted, object oPC) -{ - //has been deleted - if(nDeleted) - { - DoDebug("GetIsCohortChoiceValid() is FALSE because cohort had been deleted"); - return FALSE; - } - - int bIsValid = TRUE; - int nCohortCount = GetMaximumCohortCount(oPC); - int i; - //another players cohort - if(GetPCPublicCDKey(oPC) != "" - && GetPCPublicCDKey(oPC) != sKey) - { - DoDebug("GetIsCohortChoiceValid() is FALSE because cdkey is incorrect"); - bIsValid = FALSE; - } - //is character - if(bIsValid - && GetName(oPC) == sName) - { - DoDebug("GetIsCohortChoiceValid() is FALSE because name is in use"); - bIsValid = FALSE; - } - //is already a cohort - if(bIsValid && sName != "") - { - for(i=1;i<=nCohortCount;i++) - { - object oCohort = GetCohort(i, oPC); - if(GetName(oCohort) == sName) - { - DoDebug("GetIsCohortChoiceValid() is FALSE because cohort is already in use."); - bIsValid = FALSE; - } - } - } - //hathran - if(bIsValid - && GetHasFeat(FEAT_HATH_COHORT, oPC)) - { - int nEthranBarbarianCount = 0; - for(i=1;i<=nCohortCount;i++) - { - object oCohort = GetCohort(i, oPC); - if(GetIsObjectValid(oCohort) - &&(GetHasFeat(FEAT_HATH_COHORT, oCohort) - || GetLevelByClass(CLASS_TYPE_BARBARIAN, oCohort))) - nEthranBarbarianCount++; - } - //must have at least one ethran or barbarian - if(!nEthranBarbarianCount - && GetCurrentCohortCount(oPC) >= GetMaximumCohortCount(oPC)-1 - && !nEthran - && nClass1 != CLASS_TYPE_BARBARIAN - && nClass2 != CLASS_TYPE_BARBARIAN - && nClass3 != CLASS_TYPE_BARBARIAN) - bIsValid = FALSE; - } - //OrcWarlord - if(bIsValid - && GetHasFeat(FEAT_GATHER_HORDE_I, oPC) - && GetPRCSwitch(PRC_ORC_WARLORD_COHORT)) - { - int nOrcCount = 0; - for(i=1;i<=nCohortCount;i++) - { - object oCohort = GetCohort(i, oPC); - if(GetIsObjectValid(oCohort) - && (MyPRCGetRacialType(oCohort) == RACIAL_TYPE_HUMANOID_ORC - || MyPRCGetRacialType(oCohort) == RACIAL_TYPE_HALFORC)) - nOrcCount++; - } - //must have at least one orc - if(!nOrcCount - && GetCurrentCohortCount(oPC) >= GetMaximumCohortCount(oPC)-1 - && nRace != RACIAL_TYPE_HUMANOID_ORC - && nRace != RACIAL_TYPE_HALFORC - && nRace != RACIAL_TYPE_GRAYORC - && nRace != RACIAL_TYPE_OROG - && nRace != RACIAL_TYPE_TANARUKK - ) - bIsValid = FALSE; - } - //Undead Leadership - //Wild Cohort - //not implemented yet - //return result - return bIsValid; -} - -int GetIsCohortChoiceValidByID(int nID, object oPC) -{ - string sID = IntToString(nID); - string sName = GetCampaignString( COHORT_DATABASE, "Cohort_"+sID+"_name"); - int nRace = GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_race"); - int nClass1=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class1"); - int nClass2=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class2"); - int nClass3=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class3"); - int nOrder= GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_order"); - int nMoral= GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_moral"); - int nEthran=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_ethran"); - string sKey = GetCampaignString( COHORT_DATABASE, "Cohort_"+sID+"_cdkey"); - int nDeleted = GetCampaignInt(COHORT_DATABASE, "Cohort_"+sID+"_deleted"); - return GetIsCohortChoiceValid(sName, nRace, nClass1, nClass2, nClass3, nOrder, nMoral, nEthran, sKey, nDeleted, oPC); -} - -int GetCanRegister(object oPC) -{ - int bReturn = TRUE; - int i; - int nCohortCount = GetCampaignInt(COHORT_DATABASE, "CohortCount"); - for(i=0;i 0)) - { - if (GetIsArcaneClass(nClass1, oCaster)) nClass1Lvl = GetPrCAdjustedCasterLevel(nClass1, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass2, oCaster)) nClass2Lvl = GetPrCAdjustedCasterLevel(nClass2, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass3, oCaster)) nClass3Lvl = GetPrCAdjustedCasterLevel(nClass3, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass4, oCaster)) nClass4Lvl = GetPrCAdjustedCasterLevel(nClass4, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass5, oCaster)) nClass5Lvl = GetPrCAdjustedCasterLevel(nClass5, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass6, oCaster)) nClass6Lvl = GetPrCAdjustedCasterLevel(nClass6, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass7, oCaster)) nClass7Lvl = GetPrCAdjustedCasterLevel(nClass7, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsArcaneClass(nClass8, oCaster)) nClass8Lvl = GetPrCAdjustedCasterLevel(nClass8, oCaster, bAdjustForPractisedSpellcaster); - } - else if (nClassType == TYPE_DIVINE && (GetFirstDivineClassPosition(oCaster) > 0)) - { - if (GetIsDivineClass(nClass1, oCaster)) nClass1Lvl = GetPrCAdjustedCasterLevel(nClass1, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass2, oCaster)) nClass2Lvl = GetPrCAdjustedCasterLevel(nClass2, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass3, oCaster)) nClass3Lvl = GetPrCAdjustedCasterLevel(nClass3, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass4, oCaster)) nClass4Lvl = GetPrCAdjustedCasterLevel(nClass4, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass5, oCaster)) nClass5Lvl = GetPrCAdjustedCasterLevel(nClass5, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass6, oCaster)) nClass6Lvl = GetPrCAdjustedCasterLevel(nClass6, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass7, oCaster)) nClass7Lvl = GetPrCAdjustedCasterLevel(nClass7, oCaster, bAdjustForPractisedSpellcaster); - if (GetIsDivineClass(nClass8, oCaster)) nClass8Lvl = GetPrCAdjustedCasterLevel(nClass8, oCaster, bAdjustForPractisedSpellcaster); - } - int nHighest = nClass1Lvl; - if (nClass2Lvl > nHighest) nHighest = nClass2Lvl; - if (nClass3Lvl > nHighest) nHighest = nClass3Lvl; - if (nClass4Lvl > nHighest) nHighest = nClass4Lvl; - if (nClass5Lvl > nHighest) nHighest = nClass5Lvl; - if (nClass6Lvl > nHighest) nHighest = nClass6Lvl; - if (nClass7Lvl > nHighest) nHighest = nClass7Lvl; - if (nClass8Lvl > nHighest) nHighest = nClass8Lvl; - return nHighest; -} - -int GetLevelByTypeArcaneFeats(object oCaster = OBJECT_SELF, int iSpellID = -1) -{ - int iFirstArcane = GetPrimaryArcaneClass(oCaster); - int iBest = 0; - int iClass1 = GetClassByPosition(1, oCaster); - int iClass2 = GetClassByPosition(2, oCaster); - int iClass3 = GetClassByPosition(3, oCaster); - int iClass4 = GetClassByPosition(4, oCaster); - int iClass5 = GetClassByPosition(5, oCaster); - int iClass6 = GetClassByPosition(6, oCaster); - int iClass7 = GetClassByPosition(7, oCaster); - int iClass8 = GetClassByPosition(8, oCaster); - - int iClass1Lev = GetLevelByPosition(1, oCaster); - int iClass2Lev = GetLevelByPosition(2, oCaster); - int iClass3Lev = GetLevelByPosition(3, oCaster); - int iClass4Lev = GetLevelByPosition(4, oCaster); - int iClass5Lev = GetLevelByPosition(5, oCaster); - int iClass6Lev = GetLevelByPosition(6, oCaster); - int iClass7Lev = GetLevelByPosition(7, oCaster); - int iClass8Lev = GetLevelByPosition(8, oCaster); - - if (iSpellID = -1) iSpellID = PRCGetSpellId(oCaster); - - int iBoost = ShadowWeave(oCaster, iSpellID) + - FireAdept(oCaster, iSpellID) + - DomainPower(oCaster, iSpellID) + - StormMagic(oCaster) + - CormanthyranMoonMagic(oCaster) + - DraconicPower(oCaster); - - if (iClass1 == CLASS_TYPE_HEXBLADE) iClass1Lev = (iClass1Lev >= 4) ? (iClass1Lev / 2) : 0; - if (iClass2 == CLASS_TYPE_HEXBLADE) iClass2Lev = (iClass2Lev >= 4) ? (iClass2Lev / 2) : 0; - if (iClass3 == CLASS_TYPE_HEXBLADE) iClass3Lev = (iClass3Lev >= 4) ? (iClass3Lev / 2) : 0; - if (iClass4 == CLASS_TYPE_HEXBLADE) iClass4Lev = (iClass4Lev >= 4) ? (iClass4Lev / 2) : 0; - if (iClass5 == CLASS_TYPE_HEXBLADE) iClass5Lev = (iClass5Lev >= 4) ? (iClass5Lev / 2) : 0; - if (iClass6 == CLASS_TYPE_HEXBLADE) iClass6Lev = (iClass6Lev >= 4) ? (iClass6Lev / 2) : 0; - if (iClass7 == CLASS_TYPE_HEXBLADE) iClass7Lev = (iClass7Lev >= 4) ? (iClass7Lev / 2) : 0; - if (iClass8 == CLASS_TYPE_HEXBLADE) iClass8Lev = (iClass8Lev >= 4) ? (iClass8Lev / 2) : 0; - - if (iClass1 == iFirstArcane) iClass1Lev += GetArcanePRCLevels(oCaster); - if (iClass2 == iFirstArcane) iClass2Lev += GetArcanePRCLevels(oCaster); - if (iClass3 == iFirstArcane) iClass3Lev += GetArcanePRCLevels(oCaster); - if (iClass1 == iFirstArcane) iClass1Lev += GetArcanePRCLevels(oCaster); - if (iClass2 == iFirstArcane) iClass2Lev += GetArcanePRCLevels(oCaster); - if (iClass3 == iFirstArcane) iClass3Lev += GetArcanePRCLevels(oCaster); - if (iClass1 == iFirstArcane) iClass1Lev += GetArcanePRCLevels(oCaster); - if (iClass2 == iFirstArcane) iClass2Lev += GetArcanePRCLevels(oCaster); - if (iClass3 == iFirstArcane) iClass3Lev += GetArcanePRCLevels(oCaster); - - iClass1Lev += iBoost; - iClass2Lev += iBoost; - iClass3Lev += iBoost; - iClass4Lev += iBoost; - iClass5Lev += iBoost; - iClass6Lev += iBoost; - iClass7Lev += iBoost; - iClass8Lev += iBoost; - - iClass1Lev += PracticedSpellcasting(oCaster, iClass1, iClass1Lev); - iClass2Lev += PracticedSpellcasting(oCaster, iClass2, iClass2Lev); - iClass3Lev += PracticedSpellcasting(oCaster, iClass3, iClass3Lev); - iClass4Lev += PracticedSpellcasting(oCaster, iClass4, iClass1Lev); - iClass5Lev += PracticedSpellcasting(oCaster, iClass5, iClass2Lev); - iClass6Lev += PracticedSpellcasting(oCaster, iClass6, iClass3Lev); - iClass7Lev += PracticedSpellcasting(oCaster, iClass7, iClass1Lev); - iClass8Lev += PracticedSpellcasting(oCaster, iClass8, iClass2Lev); - - if (!GetIsArcaneClass(iClass1, oCaster)) iClass1Lev = 0; - if (!GetIsArcaneClass(iClass2, oCaster)) iClass2Lev = 0; - if (!GetIsArcaneClass(iClass3, oCaster)) iClass3Lev = 0; - if (!GetIsArcaneClass(iClass4, oCaster)) iClass4Lev = 0; - if (!GetIsArcaneClass(iClass5, oCaster)) iClass5Lev = 0; - if (!GetIsArcaneClass(iClass6, oCaster)) iClass6Lev = 0; - if (!GetIsArcaneClass(iClass7, oCaster)) iClass7Lev = 0; - if (!GetIsArcaneClass(iClass8, oCaster)) iClass8Lev = 0; - - if (iClass1Lev > iBest) iBest = iClass1Lev; - if (iClass2Lev > iBest) iBest = iClass2Lev; - if (iClass3Lev > iBest) iBest = iClass3Lev; - if (iClass4Lev > iBest) iBest = iClass4Lev; - if (iClass5Lev > iBest) iBest = iClass5Lev; - if (iClass6Lev > iBest) iBest = iClass6Lev; - if (iClass7Lev > iBest) iBest = iClass7Lev; - if (iClass8Lev > iBest) iBest = iClass8Lev; - - return iBest; -} - -int GetLevelByTypeDivineFeats(object oCaster = OBJECT_SELF, int iSpellID = -1) -{ - int iFirstDivine = GetPrimaryDivineClass(oCaster); - int iBest = 0; - int iClass1 = GetClassByPosition(1, oCaster); - int iClass2 = GetClassByPosition(2, oCaster); - int iClass3 = GetClassByPosition(3, oCaster); - int iClass4 = GetClassByPosition(4, oCaster); - int iClass5 = GetClassByPosition(5, oCaster); - int iClass6 = GetClassByPosition(6, oCaster); - int iClass7 = GetClassByPosition(7, oCaster); - int iClass8 = GetClassByPosition(8, oCaster); - - int iClass1Lev = GetLevelByPosition(1, oCaster); - int iClass2Lev = GetLevelByPosition(2, oCaster); - int iClass3Lev = GetLevelByPosition(3, oCaster); - int iClass4Lev = GetLevelByPosition(4, oCaster); - int iClass5Lev = GetLevelByPosition(5, oCaster); - int iClass6Lev = GetLevelByPosition(6, oCaster); - int iClass7Lev = GetLevelByPosition(7, oCaster); - int iClass8Lev = GetLevelByPosition(8, oCaster); - - if (iSpellID = -1) iSpellID = PRCGetSpellId(oCaster); - - int iBoost = ShadowWeave(oCaster, iSpellID) + - FireAdept(oCaster, iSpellID) + - DomainPower(oCaster, iSpellID) + - CormanthyranMoonMagic(oCaster) + - StormMagic(oCaster); - - if (iClass1 == CLASS_TYPE_PALADIN - || iClass1 == CLASS_TYPE_RANGER - || iClass1 == CLASS_TYPE_ANTI_PALADIN) - iClass1Lev = iClass1Lev / 2; - if (iClass2 == CLASS_TYPE_PALADIN - || iClass2 == CLASS_TYPE_RANGER - || iClass2 == CLASS_TYPE_ANTI_PALADIN) - iClass2Lev = iClass2Lev / 2; - if (iClass3 == CLASS_TYPE_PALADIN - || iClass3 == CLASS_TYPE_RANGER - || iClass3 == CLASS_TYPE_ANTI_PALADIN) - iClass3Lev = iClass3Lev / 2; - if (iClass4 == CLASS_TYPE_PALADIN - || iClass4 == CLASS_TYPE_RANGER - || iClass4 == CLASS_TYPE_ANTI_PALADIN) - iClass4Lev = iClass4Lev / 2; - if (iClass5 == CLASS_TYPE_PALADIN - || iClass5 == CLASS_TYPE_RANGER - || iClass5 == CLASS_TYPE_ANTI_PALADIN) - iClass5Lev = iClass5Lev / 2; - if (iClass6 == CLASS_TYPE_PALADIN - || iClass6 == CLASS_TYPE_RANGER - || iClass6 == CLASS_TYPE_ANTI_PALADIN) - iClass6Lev = iClass6Lev / 2; - if (iClass7 == CLASS_TYPE_PALADIN - || iClass7 == CLASS_TYPE_RANGER - || iClass7 == CLASS_TYPE_ANTI_PALADIN) - iClass7Lev = iClass7Lev / 2; - if (iClass8 == CLASS_TYPE_PALADIN - || iClass8 == CLASS_TYPE_RANGER - || iClass8 == CLASS_TYPE_ANTI_PALADIN) - iClass8Lev = iClass7Lev / 2; - - if (iClass1 == iFirstDivine) iClass1Lev += GetDivinePRCLevels(oCaster); - if (iClass2 == iFirstDivine) iClass2Lev += GetDivinePRCLevels(oCaster); - if (iClass3 == iFirstDivine) iClass3Lev += GetDivinePRCLevels(oCaster); - if (iClass4 == iFirstDivine) iClass4Lev += GetDivinePRCLevels(oCaster); - if (iClass5 == iFirstDivine) iClass5Lev += GetDivinePRCLevels(oCaster); - if (iClass6 == iFirstDivine) iClass6Lev += GetDivinePRCLevels(oCaster); - if (iClass7 == iFirstDivine) iClass7Lev += GetDivinePRCLevels(oCaster); - if (iClass8 == iFirstDivine) iClass8Lev += GetDivinePRCLevels(oCaster); - - iClass1Lev += iBoost; - iClass2Lev += iBoost; - iClass3Lev += iBoost; - iClass4Lev += iBoost; - iClass5Lev += iBoost; - iClass6Lev += iBoost; - iClass7Lev += iBoost; - iClass8Lev += iBoost; - - iClass1Lev += PracticedSpellcasting(oCaster, iClass1, iClass1Lev); - iClass2Lev += PracticedSpellcasting(oCaster, iClass2, iClass2Lev); - iClass3Lev += PracticedSpellcasting(oCaster, iClass3, iClass3Lev); - iClass4Lev += PracticedSpellcasting(oCaster, iClass4, iClass4Lev); - iClass5Lev += PracticedSpellcasting(oCaster, iClass5, iClass5Lev); - iClass6Lev += PracticedSpellcasting(oCaster, iClass6, iClass6Lev); - iClass7Lev += PracticedSpellcasting(oCaster, iClass1, iClass7Lev); - iClass8Lev += PracticedSpellcasting(oCaster, iClass2, iClass8Lev); - - if (!GetIsDivineClass(iClass1, oCaster)) iClass1Lev = 0; - if (!GetIsDivineClass(iClass2, oCaster)) iClass2Lev = 0; - if (!GetIsDivineClass(iClass3, oCaster)) iClass3Lev = 0; - if (!GetIsDivineClass(iClass4, oCaster)) iClass4Lev = 0; - if (!GetIsDivineClass(iClass5, oCaster)) iClass5Lev = 0; - if (!GetIsDivineClass(iClass6, oCaster)) iClass6Lev = 0; - if (!GetIsDivineClass(iClass7, oCaster)) iClass7Lev = 0; - if (!GetIsDivineClass(iClass8, oCaster)) iClass3Lev = 0; - - if (iClass1Lev > iBest) iBest = iClass1Lev; - if (iClass2Lev > iBest) iBest = iClass2Lev; - if (iClass3Lev > iBest) iBest = iClass3Lev; - if (iClass4Lev > iBest) iBest = iClass4Lev; - if (iClass5Lev > iBest) iBest = iClass5Lev; - if (iClass6Lev > iBest) iBest = iClass6Lev; - if (iClass7Lev > iBest) iBest = iClass7Lev; - if (iClass8Lev > iBest) iBest = iClass8Lev; - - return iBest; -} - -// looks up the spell level for the arcane caster classes (Wiz_Sorc, Bard) in spells.2da. -// Caveat: some onhitcast spells don't have any spell-levels listed for any class -int GetIsArcaneSpell (int iSpellId) -{ - return Get2DACache("spells", "Wiz_Sorc", iSpellId) != "" - || Get2DACache("spells", "Bard", iSpellId) != ""; -} - -// looks up the spell level for the divine caster classes (Cleric, Druid, Ranger, Paladin) in spells.2da. -// Caveat: some onhitcast spells don't have any spell-levels listed for any class -int GetIsDivineSpell (int iSpellId) -{ - return Get2DACache("spells", "Cleric", iSpellId) != "" - || Get2DACache("spells", "Druid", iSpellId) != "" - || Get2DACache("spells", "Ranger", iSpellId) != "" - || Get2DACache("spells", "Paladin", iSpellId) != ""; -} - -int BWSavingThrow(int nSavingThrow, object oTarget, int nDC, int nSaveType = SAVING_THROW_TYPE_NONE, object oSaveVersus = OBJECT_SELF, float fDelay = 0.0) -{ - // GZ: sanity checks to prevent wrapping around - if (nDC < 1) nDC = 1; - else if (nDC > 255) nDC = 255; - - int bValid = 0; - int nEff; - - //some maneuvers allow people to use skill check instead of a save - if(nSavingThrow == SAVING_THROW_FORT) - { - bValid = GetLocalInt(oTarget, "MindOverBody") ? - GetIsSkillSuccessful(oTarget, SKILL_CONCENTRATION, nDC) : - FortitudeSave(oTarget, nDC, nSaveType, oSaveVersus); - if(bValid == 1) nEff = VFX_IMP_FORTITUDE_SAVING_THROW_USE; - } - else if(nSavingThrow == SAVING_THROW_REFLEX) - { - bValid = GetLocalInt(oTarget, "ActionBeforeThought") ? - GetIsSkillSuccessful(oTarget, SKILL_CONCENTRATION, nDC) : - ReflexSave(oTarget, nDC, nSaveType, oSaveVersus); - if(bValid == 1) nEff = VFX_IMP_REFLEX_SAVE_THROW_USE; - } - else if(nSavingThrow == SAVING_THROW_WILL) - { - bValid = GetLocalInt(oTarget, "MomentOfPerfectMind") ? - GetIsSkillSuccessful(oTarget, SKILL_CONCENTRATION, nDC) : - WillSave(oTarget, nDC, nSaveType, oSaveVersus); - if(bValid == 1) nEff = VFX_IMP_WILL_SAVING_THROW_USE; - } - - /* - return 0 = FAILED SAVE - return 1 = SAVE SUCCESSFUL - return 2 = IMMUNE TO WHAT WAS BEING SAVED AGAINST - */ - if(bValid == 0) - { - int nSpellID = PRCGetSpellId(oSaveVersus); - if(nSaveType == SAVING_THROW_TYPE_DEATH - || nSpellID == SPELL_WEIRD - || nSpellID == SPELL_FINGER_OF_DEATH) - //&& nSpellID != SPELL_HORRID_WILTING) - { - if(fDelay > 0.0f) DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), oTarget)); - else ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), oTarget); - } - } - else //if(bValid == 1 || bValid == 2) - { - if(bValid == 2) nEff = VFX_IMP_MAGIC_RESISTANCE_USE; - - if(fDelay > 0.0f) DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nEff), oTarget)); - else ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nEff), oTarget); - } - return bValid; -} - -void PRCBonusDamage(object oTarget, object oCaster = OBJECT_SELF) -{ - // Does nothing, left here so files don't need to be edited. -} - -// Bonus damage to a spell for Spell Betrayal Ability -int SpellBetrayalDamage(object oTarget, object oCaster) -{ - int iDam = 0; - int ThrallLevel = GetLevelByClass(CLASS_TYPE_THRALL_OF_GRAZZT_A, oCaster) + GetLevelByClass(CLASS_TYPE_THRALL_OF_GRAZZT_D, oCaster); - - if(ThrallLevel >= 2) - { - if( GetIsDeniedDexBonusToAC(oTarget, oCaster, TRUE) ) - { - ThrallLevel /= 2; - iDam = d6(ThrallLevel); - } - } - - return iDam; -} - -// Bonus damage to a spell for Spellstrike Ability -int SpellStrikeDamage(object oTarget, object oCaster) -{ - int iDam = 0; - int ThrallLevel = GetLevelByClass(CLASS_TYPE_THRALL_OF_GRAZZT_A, oCaster) + GetLevelByClass(CLASS_TYPE_THRALL_OF_GRAZZT_D, oCaster); - - if(ThrallLevel >= 6) - { - if( GetIsAOEFlanked(oTarget, oCaster) ) - { - ThrallLevel /= 4; - iDam = d6(ThrallLevel); - } - } - - return iDam; -} - -// Adds the bonus damage from both Spell Betrayal and Spellstrike together -int ApplySpellBetrayalStrikeDamage(object oTarget, object oCaster, int bShowTextString = TRUE) -{ - int iDam = 0; - int iBetrayalDam = SpellBetrayalDamage(oTarget, oCaster); - int iStrikeDam = SpellStrikeDamage(oTarget, oCaster); - string sMes = ""; - - if(iStrikeDam > 0 && iBetrayalDam > 0) sMes ="*Spellstrike Betrayal Sucess*"; - else if(iBetrayalDam > 0) sMes ="*Spell Betrayal Sucess*"; - else if(iStrikeDam > 0) sMes ="*Spellstrike Sucess*"; - - if(bShowTextString) FloatingTextStringOnCreature(sMes, oCaster, TRUE); - - iDam = iBetrayalDam + iStrikeDam; - - // debug code - //sMes = "Spell Betrayal / Spellstrike Bonus Damage: " + IntToString(iBetrayalDam) + " + " + IntToString(iStrikeDam) + " = " + IntToString(iDam); - //DelayCommand( 1.0, FloatingTextStringOnCreature(sMes, oCaster, TRUE) ); - - return iDam; -} - -int SpellDamagePerDice(object oCaster, int nDice) -{ - // Arcane only - if (!GetIsArcaneClass(PRCGetLastSpellCastClass(oCaster))) - return 0; - - int nDam = 0; - nDam += GetLocalInt(oCaster, "StrengthFromMagic") * nDice * 2; - - if (DEBUG) DoDebug("SpellDamagePerDice returning "+IntToString(nDam)+" for "+GetName(oCaster)); - - return nDam; -} - -int PRCMySavingThrow(int nSavingThrow, object oTarget, int nDC, int nSaveType = SAVING_THROW_TYPE_NONE, object oSaveVersus = OBJECT_SELF, float fDelay = 0.0, int bImmunityCheck = FALSE) -{ - int nSpell = PRCGetSpellId(oSaveVersus); - int nSpellSchool = GetSpellSchool(nSpell); - - //If bImmunityCheck == FALSE: returns 0 if failure or immune, 1 if success - same as MySavingThrow - //If bImmunityCheck == TRUE: returns 0 if failure, 1 if success, 2 if immune - - // Enigma Helm Crown Bind - if (GetIsMeldBound(oTarget, MELD_ENIGMA_HELM) == CHAKRA_CROWN && GetIsOfSubschool(nSpell, SUBSCHOOL_CHARM)) - return 2; - - // Planar Ward - if (GetHasSpellEffect(MELD_PLANAR_WARD, oTarget) && (GetIsOfSubschool(nSpell, SUBSCHOOL_CHARM) || GetIsOfSubschool(nSpell, SUBSCHOOL_COMPULSION))) - return 2; - - // Chucoclops influence makes you autofail fear saves - if (GetHasSpellEffect(VESTIGE_CHUPOCLOPS, oTarget) && !GetLocalInt(oTarget, "PactQuality"+IntToString(VESTIGE_CHUPOCLOPS)) && nSaveType == SAVING_THROW_TYPE_FEAR) - return 1; - - // Iron Mind's Mind Over Body, allows them to treat other saves as will saves up to 3/day. - // No point in having it trigger when its a will save. - if(nSavingThrow != SAVING_THROW_WILL && GetLocalInt(oTarget, "IronMind_MindOverBody")) - { - nSavingThrow = SAVING_THROW_WILL; - DeleteLocalInt(oTarget, "IronMind_MindOverBody"); - } - - // Handle the target having Force of Will and being targeted by a psionic power - if(nSavingThrow != SAVING_THROW_WILL && - ((nSpell > 14000 && nSpell < 14360) || - (nSpell > 15350 && nSpell < 15470) - ) && - GetHasFeat(FEAT_FORCE_OF_WILL, oTarget) && - !GetLocalInt(oTarget, "ForceOfWillUsed") && - // Only use will save if it's better - ((nSavingThrow == SAVING_THROW_FORT ? GetFortitudeSavingThrow(oTarget) : GetReflexSavingThrow(oTarget)) > GetWillSavingThrow(oTarget)) - ) - { - nSavingThrow = SAVING_THROW_WILL; - SetLocalInt(oTarget, "ForceOfWillUsed", TRUE); - DelayCommand(6.0f, DeleteLocalInt(oTarget, "ForceOfWillUsed")); - // "Force of Will used for this round." - FloatingTextStrRefOnCreature(16826670, oTarget, FALSE); - } - - //TouchOfDistraction - if (GetLocalInt(oTarget, "HasTouchOfDistraction") && (nSavingThrow = SAVING_THROW_REFLEX)) - { - nDC += 2; - DeleteLocalInt(oTarget, "HasTouchOfDistraction"); - } - - //Diamond Defense - if(GetLocalInt(oTarget, "PRC_TOB_DIAMOND_DEFENSE")) - nDC -= GetLocalInt(oTarget, "PRC_TOB_DIAMOND_DEFENSE"); - - // Master of Nine - if(GetLevelByClass(CLASS_TYPE_MASTER_OF_NINE, oSaveVersus) > 2) - { - int nLastClass = GetLocalInt(oSaveVersus, "PRC_CurrentManeuver_InitiatingClass") - 1; - if(nLastClass == CLASS_TYPE_WARBLADE - || nLastClass == CLASS_TYPE_SWORDSAGE - || nLastClass == CLASS_TYPE_CRUSADER) - { - // Increases maneuver DCs by 1 - nDC += 1; - } - } - - // Incarnum Resistance - if(GetHasFeat(FEAT_INCARNUM_RESISTANCE, oTarget) && nSpell > 18900 && nSpell < 18969) - nDC -= 2; - - // This is done here because it is possible to tell the saving throw type here - // it works by lowering the DC rather than adding to the save - // same net effect but slightly different numbers - if(nSaveType == SAVING_THROW_TYPE_MIND_SPELLS) - { - //Thayan Knights auto-fail mind spells cast by red wizards - if(GetLevelByClass(CLASS_TYPE_RED_WIZARD, oSaveVersus) - && GetLevelByClass(CLASS_TYPE_THAYAN_KNIGHT, oTarget)) - return 0; - // Tyranny Domain increases the DC of mind spells by +2. - if(GetHasFeat(FEAT_DOMAIN_POWER_TYRANNY, oSaveVersus)) - nDC += 2; - // +2 bonus on saves against mind affecting, done here - if(GetLevelByClass(CLASS_TYPE_FIST_DAL_QUOR, oTarget) > 1) - nDC -= 2; - // Scorpion's Resolve gives a +4 bonus on mind affecting saves - if(GetHasFeat(FEAT_SCORPIONS_RESOLVE, oTarget)) - nDC -= 4; - // Warped Mind gives a bonus on mind affecting equal to half aberrant - if(GetHasFeat(FEAT_ABERRANT_WARPED_MIND, oTarget)) - nDC -= GetAberrantFeatCount(oTarget)/2; - } - else if(nSaveType == SAVING_THROW_TYPE_FEAR) - { - // Unnatural Will adds Charisma to saves against fear - if(GetHasFeat(FEAT_UNNATURAL_WILL, oTarget)) - nDC -= GetAbilityModifier(ABILITY_CHARISMA, oTarget); - // Krinth have +4 saves against Fear - if(GetRacialType(oTarget) == RACIAL_TYPE_KRINTH) - nDC -= 4; - // Turlemoi/Lashemoi have -4 saves against Fear - if(GetRacialType(oTarget) == RACIAL_TYPE_LASHEMOI || GetRacialType(oTarget) == RACIAL_TYPE_TURLEMOI || GetLocalInt(oTarget, "SpeedFromPain") >= 3) - nDC += 4; - } - else if(nSaveType == SAVING_THROW_TYPE_NEGATIVE) - { - // +4 bonus on saves against negative energy, done here - if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 8) - nDC -= 4; - // Jergal's Pact gives a +2 bonus on negative energy saves - if(GetHasFeat(FEAT_JERGALS_PACT, oTarget)) - nDC -= 2; - } - else if(nSaveType == SAVING_THROW_TYPE_DISEASE) - { - // Plague Resistant gives a +4 bonus on disease saves - if(GetHasFeat(FEAT_PLAGUE_RESISTANT, oTarget)) - nDC -= 4; - // +4/+2 bonus on saves against disease, done here - if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 13) - nDC -= 4; - else if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 3) - nDC -= 2; - } - else if(nSaveType == SAVING_THROW_TYPE_POISON) - { - // +4/+2 bonus on saves against poison, done here - if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 13) - nDC -= 4; - else if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 3) - nDC -= 2; - if(GetHasFeat(FEAT_POISON_4, oTarget)) - nDC -= 4; - if(GetHasFeat(FEAT_POISON_3, oTarget)) - nDC -= 3; - if(GetRacialType(oTarget) == RACIAL_TYPE_EXTAMINAAR && nSavingThrow == SAVING_THROW_FORT) - nDC -= 2; - if(GetRacialType(oTarget) == RACIAL_TYPE_MONGRELFOLK) - nDC -= 1; - } - else if(nSaveType == SAVING_THROW_TYPE_FIRE) - { - // Bloodline of Fire gives a +4 bonus on fire saves - if(GetHasFeat(FEAT_BLOODLINE_OF_FIRE, oTarget)) - nDC -= 4; - if(GetHasFeat(FEAT_HARD_FIRE, oTarget)) - nDC -= 1 + (GetHitDice(oTarget) / 5); - // +2 vs fire for Halfgiant - if(GetHasFeat(FEAT_ACCLIMATED_FIRE, oTarget)) - nDC -= 2; - // +2 vs fire for Heat Endurance feat - if(GetHasFeat(FEAT_HEAT_ENDURANCE, oTarget)) - nDC -= 2; - } - else if(nSaveType == SAVING_THROW_TYPE_COLD) - { - if(GetHasFeat(FEAT_HARD_WATER, oTarget)) - nDC -= 1 + (GetHitDice(oTarget) / 5); - // +2 vs cold for Cold Endurance feat - if(GetHasFeat(FEAT_COLD_ENDURANCE, oTarget)) - nDC -= 2; - // +2 vs cold for Winterhide Shifter trait - if(GetHasFeat(FEAT_SHIFTER_WINTERHIDE, oTarget)) - nDC -= 2; - } - else if(nSaveType == SAVING_THROW_TYPE_ELECTRICITY) - { - if(GetHasFeat(FEAT_HARD_AIR, oTarget)) - nDC -= 1 + (GetHitDice(oTarget) / 5); - else if(GetHasFeat(FEAT_HARD_ELEC, oTarget)) - nDC -= 2; - } - else if(nSaveType == SAVING_THROW_TYPE_SONIC) - { - if(GetHasFeat(FEAT_HARD_AIR, oTarget)) - nDC -= 1 + (GetHitDice(oTarget) / 5); - } - else if(nSaveType == SAVING_THROW_TYPE_ACID) - { - if(GetHasFeat(FEAT_HARD_EARTH, oTarget)) - nDC -= 1 + (GetHitDice(oTarget) / 5); - } - - // This is done here because it is possible to tell the spell school here - // it works by lowering the DC rather than adding to the save - // same net effect but slightly different numbers - if(nSpellSchool == SPELL_SCHOOL_TRANSMUTATION) - { - // Full Moon's Trick - +2 vs Transmutation spels - if(GetLocalInt(oTarget, "FullMoon_Trans")) - nDC -= 2; - if(GetLevelByClass(CLASS_TYPE_SAPPHIRE_HIERARCH, oTarget) >= 2) - nDC -= 4; - } - - // Sapphire Heirarch gets +4 against Chaos and Transmutation effects - if(GetLevelByClass(CLASS_TYPE_SAPPHIRE_HIERARCH, oTarget) >= 2 && GetHasDescriptor(nSpell, DESCRIPTOR_CHAOTIC)) - nDC -= 4; - - // Charming Veil Brow bind grants Essentia bonus on saves against charm and compulsion - if(GetIsOfSubschool(nSpell, SUBSCHOOL_CHARM) || GetIsOfSubschool(nSpell, SUBSCHOOL_COMPULSION)) - { - if (GetIsMeldBound(oTarget, MELD_CHARMING_VEIL) == CHAKRA_BROW) - nDC -= GetEssentiaInvested(oTarget, MELD_CHARMING_VEIL); - } - - // Krinth get +1 save against Shadow spells - if (GetIsOfSubschool(nSpell, SUBSCHOOL_SHADOW) && GetRacialType(oTarget) == RACIAL_TYPE_KRINTH) - nDC -= 1; - - //Psionic race save boosts - +1 vs all spells for Xeph - if(GetHasFeat(FEAT_XEPH_SPELLHARD, oTarget)) - nDC -= 1; - - // Apostate - 1/2 HD bonus to resist divine spells - if(GetHasFeat(FEAT_APOSTATE, oTarget)) - { - //if divine - if(GetIsDivineClass(PRCGetLastSpellCastClass(oSaveVersus))) - nDC -= GetHitDice(oTarget) / 2; - } - - // Hammer of Witches - +1 bonus against Arcane spells - if(GetIsObjectValid(GetItemPossessedBy(oTarget, "WOL_HammerWitches"))) - { - if(GetIsArcaneClass(PRCGetLastSpellCastClass(oSaveVersus))) - nDC -= 1; - } - - // Cultist of the Shattered Peak - +1 bonus against Arcane spells - if(GetLevelByClass(CLASS_TYPE_CULTIST_SHATTERED_PEAK, oTarget)) - { - if(GetIsArcaneClass(PRCGetLastSpellCastClass(oSaveVersus))) - nDC -= 1; - } - - //Insightful Divination - if(GetLocalInt(oTarget, "Insightful Divination")) - { - nDC -= GetLocalInt(oTarget, "Insightful Divination"); - DeleteLocalInt(oTarget, "Insightful Divination"); - } - - // Phierans Resolve - +4 bonus vs spells with evil descriptor - if(GetHasSpellEffect(SPELL_PHIERANS_RESOLVE, oTarget) && GetHasDescriptor(nSpell, DESCRIPTOR_EVIL)) - nDC -= 4; - - //spell school modificators - int nSchool = GetLocalInt(oSaveVersus, "X2_L_LAST_SPELLSCHOOL_VAR"); - if(nSchool == SPELL_SCHOOL_NECROMANCY) - { - // Necrotic Cyst penalty on Necromancy spells - if(GetPersistantLocalInt(oTarget, NECROTIC_CYST_MARKER)) - nDC += 2; - } - else if(nSchool == SPELL_SCHOOL_ILLUSION) - { - // Piercing Sight gives a +4 bonus on illusion saves - if(GetHasFeat(FEAT_PIERCING_SIGHT, oTarget)) - nDC -= 4; - // Adds +2 to Illusion DCs - if(GetLocalInt(oSaveVersus, "ShadowTrickster")) - nDC += 2; - // Illusion Veil Meld - if(GetHasSpellEffect(MELD_ILLUSION_VEIL, oSaveVersus)) - nDC += 1; - // Illusion Veil Meld - if(GetHasSpellEffect(MELD_ILLUSION_VEIL, oTarget)) - nDC -= GetEssentiaInvested(oTarget, MELD_ILLUSION_VEIL); - if(GetRacialType(oTarget) == RACIAL_TYPE_MONGRELFOLK) - nDC -= 1; - } - else if(nSchool == SPELL_SCHOOL_ENCHANTMENT) - { - //check if Unsettling Enchantment applies - if(GetHasFeat(FEAT_UNSETTLING_ENCHANTMENT, oSaveVersus) && !GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS)) - { - effect eLink = EffectLinkEffects(EffectACDecrease(2), EffectAttackDecrease(2)); - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, 6.0); - } - if(GetRacialType(oTarget) == RACIAL_TYPE_KILLOREN) - nDC -= 2; - if(GetLocalInt(oTarget, "KillorenAncient")) - nDC -= 2; - if(GetRacialType(oTarget) == RACIAL_TYPE_MONGRELFOLK) - nDC -= 1; - } - - // Hexblade gets a bonus against spells equal to his Charisma (Min +1) - if(nSchool && GetLevelByClass(CLASS_TYPE_HEXBLADE, oTarget)) - { - int nHexCha = GetAbilityModifier(ABILITY_CHARISMA, oTarget); - if (nHexCha < 1) nHexCha = 1; - nDC -= nHexCha; - } - - // Totemist gets a save v magical beasts - if(MyPRCGetRacialType(oSaveVersus) == RACIAL_TYPE_MAGICAL_BEAST && GetLevelByClass(CLASS_TYPE_TOTEMIST, oTarget) >= 3) - nDC -= 3; - - int nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - - // If the spell is save immune then the link must be applied in order to get the true immunity - // to be resisted. That is the reason for returing false and not true. True blocks the - // application of effects. - if(nSaveRoll == 2 && !bImmunityCheck) - return 0; - - // Failed the save - check if we can reroll - if(!nSaveRoll) - { - if(nSaveType == SAVING_THROW_TYPE_MIND_SPELLS) - { - // Bond Of Loyalty - if(GetLocalInt(oTarget, "BondOfLoyalty")) - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - DeleteLocalInt(oTarget, "BondOfLoyalty"); - } - } - else if(nSaveType == SAVING_THROW_TYPE_FEAR) - { - // Call To Battle Reroll - if(GetLocalInt(oTarget, "CallToBattle")) - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - DeleteLocalInt(oTarget, "CallToBattle"); - } - } - - // Second Chance power reroll - if(!nSaveRoll && GetLocalInt(oTarget, "PRC_Power_SecondChance_Active") // Second chance is active - && !GetLocalInt(oTarget, "PRC_Power_SecondChance_UserForRound")) // And hasn't yet been used for this round - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - - // Can't use this ability again for a round - SetLocalInt(oTarget, "PRC_Power_SecondChance_UserForRound", TRUE); - DelayCommand(6.0f, DeleteLocalInt(oTarget, "PRC_Power_SecondChance_UserForRound")); - } - - // Zealous Surge Reroll - if(!nSaveRoll && GetLocalInt(oTarget, "ZealousSurge")) - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - - // Ability Used - DeleteLocalInt(oTarget, "ZealousSurge"); - } - - // Balam's Cunning Reroll - if(!nSaveRoll && GetLocalInt(oTarget, "BalamCunning")) - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - - // Ability Used - DeleteLocalInt(oTarget, "BalamCunning"); - } - - if(!nSaveRoll) - { - if(nSavingThrow == SAVING_THROW_REFLEX) - { - // Dive for Cover reroll - if(GetHasFeat(FEAT_DIVE_FOR_COVER, oTarget)) - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oTarget, 6.0); - } - } - // Impetuous Endurance - fortitude or will save - else if(GetLevelByClass(CLASS_TYPE_KNIGHT, oTarget) > 16) - { - // Reroll - nSaveRoll = BWSavingThrow(nSavingThrow, oTarget, nDC, nSaveType, oSaveVersus, fDelay); - } - } - } - //Serene Guardian Unclouded Mind - int nSerene = GetLevelByClass(CLASS_TYPE_SERENE_GUARDIAN, oTarget); - //Applies on failed will saves from 9th level on - if (nSaveRoll == 1 && nSavingThrow == SAVING_THROW_WILL && nSerene >= 9) - { - if (GetIsSkillSuccessful(oTarget, SKILL_CONCENTRATION, nDC)) // Concentration check to beat the DC - nSaveRoll = 0; - } - - // Iron Mind Barbed Mind ability - if(nSaveRoll == 1 && nSaveType == SAVING_THROW_TYPE_MIND_SPELLS) - { - // Only works in Heavy Armour - if(GetLevelByClass(CLASS_TYPE_IRONMIND, oTarget) > 9 - && GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget)) > 5) - { - // Spell/Power caster takes 1d6 damage and 1 Wisdom damage - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), DAMAGE_TYPE_MAGICAL), oSaveVersus); - ApplyAbilityDamage(oSaveVersus, ABILITY_WISDOM, 1, DURATION_TYPE_TEMPORARY, TRUE, -1.0); - } - } - - return nSaveRoll; -} - - -int PRCGetReflexAdjustedDamage(int nDamage, object oTarget, int nDC, int nSaveType = SAVING_THROW_TYPE_NONE, object oSaveVersus = OBJECT_SELF) -{ - int nEvasion; - if(GetHasFeat(FEAT_IMPROVED_EVASION, oTarget)) - nEvasion = 2; - else if(GetHasFeat(FEAT_EVASION, oTarget)) - nEvasion = 1; - - // Grants evasion against dragons, don't override if they've already gotit - object oWOL = GetItemPossessedBy(oTarget, "WOL_CrimsonRuination"); - if(oWOL != GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget) && MyPRCGetRacialType(oSaveVersus) == RACIAL_TYPE_DRAGON && 1 > nEvasion) - nEvasion = 1; - - // This ability removes evasion from the target - if(GetLocalInt(oTarget, "TrueConfoundingResistance")) - { - if(nEvasion) - nEvasion -= 1; - else - nDC += 2; - } - - //Get saving throw result - int nSaveRoll = PRCMySavingThrow(SAVING_THROW_REFLEX, oTarget, nDC, nSaveType, oSaveVersus); - - //save success - if(nSaveRoll) - nDamage = nEvasion ? 0 : nDamage / 2; - //save failed - check improved evasion - else if(nEvasion == 2) - nDamage = nDamage / 2; - - return nDamage; -} - -// function for internal use in GetCasterLvl - -// caster level for arcane base classes (with practiced spellcaster feats) -int GetCasterLvlArcane(int iClassType, object oCaster) -{ - if (GetPrimaryArcaneClass(oCaster) == iClassType) - return GetLevelByTypeArcane(oCaster); - - int iTemp = GetLevelByClass(iClassType, oCaster); - iTemp += PracticedSpellcasting(oCaster, iClassType, iTemp); - return iTemp; -} - -// caster level for classes with half progression -int GetCasterLvlArcaneSemi(int iClassType, object oCaster) -{ - if (GetPrimaryArcaneClass(oCaster) == iClassType) - return GetLevelByTypeArcane(oCaster); - - int iTemp = GetLevelByClass(iClassType, oCaster) / 2; - iTemp += PracticedSpellcasting(oCaster, iClassType, iTemp); - return iTemp; -} - -// caster level for divine base classes (with practiced spellcaster feats) -int GetCasterLvlDivine(int iClassType, object oCaster) -{ - if (GetPrimaryDivineClass(oCaster) == iClassType) - return GetLevelByTypeDivine(oCaster); - - int iTemp = GetLevelByClass(iClassType, oCaster); - iTemp += PracticedSpellcasting(oCaster, iClassType, iTemp); - return iTemp; -} - -// caster level for classes with half progression -int GetCasterLvlDivineSemi(int iClassType, object oCaster) -{ - if (GetPrimaryDivineClass(oCaster) == iClassType) - return GetLevelByTypeDivine(oCaster); - - int iTemp = GetLevelByClass(iClassType, oCaster) / 2; - iTemp += PracticedSpellcasting(oCaster, iClassType, iTemp); - return iTemp; -} - -int GetCasterLvl(int iTypeSpell, object oCaster = OBJECT_SELF) -{ - switch (iTypeSpell) - { - case TYPE_ARCANE: - return GetLevelByTypeArcane(oCaster); - - case TYPE_DIVINE: - return GetLevelByTypeDivine(oCaster); - - case CLASS_TYPE_SORCERER: - { - if (GetPrimaryArcaneClass(oCaster) == CLASS_TYPE_SORCERER) - return GetLevelByTypeArcane(oCaster); - - if(!GetLevelByClass(CLASS_TYPE_SORCERER, oCaster)) - { - int iTemp; - int nRace = GetRacialType(oCaster); - - //Aranea include outsider HD as sorc - if(nRace == RACIAL_TYPE_ARANEA) - iTemp = GetLevelByClass(CLASS_TYPE_SHAPECHANGER, oCaster); - - //Rakshasa include outsider HD as sorc - if(nRace == RACIAL_TYPE_RAKSHASA) - iTemp = GetLevelByClass(CLASS_TYPE_OUTSIDER, oCaster); - - //Drider include aberration HD as sorc - if(nRace == RACIAL_TYPE_DRIDER) - iTemp = GetLevelByClass(CLASS_TYPE_ABERRATION, oCaster); - - //Arkamoi + Redspawn include MH HD as sorc - if(nRace == RACIAL_TYPE_ARKAMOI) - iTemp = GetLevelByClass(CLASS_TYPE_MONSTROUS, oCaster); - if(nRace == RACIAL_TYPE_REDSPAWN_ARCANISS) - iTemp = GetLevelByClass(CLASS_TYPE_MONSTROUS, oCaster)*3/4; - if(nRace == RACIAL_TYPE_MARRUTACT) - iTemp = GetLevelByClass(CLASS_TYPE_MONSTROUS, oCaster)*6/7; - - iTemp += PracticedSpellcasting(oCaster, CLASS_TYPE_SORCERER, iTemp); - iTemp += DraconicPower(oCaster); - return iTemp; - } - } - - case CLASS_TYPE_BARD: - { - if (GetPrimaryArcaneClass(oCaster) == CLASS_TYPE_BARD) - return GetLevelByTypeArcane(oCaster); - - if(!GetLevelByClass(CLASS_TYPE_BARD, oCaster)) - { - int iTemp; - int nRace = GetRacialType(oCaster); - - //Gloura include fey HD as bard - if(nRace == RACIAL_TYPE_GLOURA) - iTemp = GetLevelByClass(CLASS_TYPE_FEY, oCaster); - - iTemp += PracticedSpellcasting(oCaster, CLASS_TYPE_BARD, iTemp); - iTemp += DraconicPower(oCaster); - return iTemp; - } - } - - case CLASS_TYPE_ASSASSIN: - case CLASS_TYPE_CELEBRANT_SHARESS: - case CLASS_TYPE_BEGUILER: - case CLASS_TYPE_CULTIST_SHATTERED_PEAK: - case CLASS_TYPE_DREAD_NECROMANCER: - case CLASS_TYPE_DUSKBLADE: - case CLASS_TYPE_SHADOWLORD: - case CLASS_TYPE_SUEL_ARCHANAMACH: - case CLASS_TYPE_WARMAGE: - case CLASS_TYPE_WIZARD: - return GetCasterLvlArcane(iTypeSpell, oCaster); - - case CLASS_TYPE_HEXBLADE: - return GetCasterLvlArcaneSemi(iTypeSpell, oCaster); - - case CLASS_TYPE_ARCHIVIST: - case CLASS_TYPE_BLACKGUARD: - case CLASS_TYPE_BLIGHTER: - case CLASS_TYPE_CLERIC: - case CLASS_TYPE_DRUID: - case CLASS_TYPE_FAVOURED_SOUL: - case CLASS_TYPE_HEALER: - case CLASS_TYPE_KNIGHT_CHALICE: - case CLASS_TYPE_KNIGHT_MIDDLECIRCLE: - case CLASS_TYPE_NENTYAR_HUNTER: - case CLASS_TYPE_OCULAR: - case CLASS_TYPE_SHAMAN: - case CLASS_TYPE_SLAYER_OF_DOMIEL: - case CLASS_TYPE_SOLDIER_OF_LIGHT: - case CLASS_TYPE_UR_PRIEST: - case CLASS_TYPE_VASSAL: - return GetCasterLvlDivine(iTypeSpell, oCaster); - - case CLASS_TYPE_ANTI_PALADIN: - case CLASS_TYPE_PALADIN: - case CLASS_TYPE_RANGER: - case CLASS_TYPE_SOHEI: - return GetCasterLvlDivineSemi(iTypeSpell, oCaster); - } - return 0; -} - - -////////////////Begin Spellsword////////////////// - -void SetAllAoEInts(int SpellID, object oAoE, int nBaseSaveDC, int SpecDispel = 0, int nCasterLevel = 0) -{ - if(!GetLocalInt(oAoE, "X2_AoE_BaseSaveDC"))//DC should always be > 0 - { - SetLocalInt(oAoE, "X2_AoE_SpellID", SpellID); - SetLocalInt(oAoE, "X2_AoE_BaseSaveDC", nBaseSaveDC); - if(SpecDispel) SetLocalInt(oAoE, "X2_AoE_SpecDispel", SpecDispel); - if(!nCasterLevel) nCasterLevel = PRCGetCasterLevel(); - SetLocalInt(oAoE, "X2_AoE_Caster_Level", nCasterLevel); - if(GetHasFeat(FEAT_SHADOWWEAVE)) SetLocalInt(oAoE, "X2_AoE_Weave", TRUE); - } -} - -//GetNextObjectInShape wrapper for changing the AOE of the channeled spells -object MyNextObjectInShape(int nShape, - float fSize, location lTarget, - int bLineOfSight = FALSE, - int nObjectFilter = OBJECT_TYPE_CREATURE, - vector vOrigin=[0.0, 0.0, 0.0]) -{ - object oCaster = OBJECT_SELF; - - // War Wizard of Cormyr's Widen Spell ability - float fMulti = GetLocalFloat(oCaster, PRC_SPELL_AREA_SIZE_MULTIPLIER); - //if(DEBUG) DoDebug("Original Spell Size: " + FloatToString(fSize)+"\n" + "Widened Multiplier: " + FloatToString(fMulti)); - - float fHFInfusion = GetLocalFloat(oCaster, "PRC_HF_Infusion_Wid"); - if(fHFInfusion > 0.0f) - { - object oItem = PRCGetSpellCastItem(oCaster); - if(GetIsObjectValid(oItem) && GetItemPossessor(oItem) == oCaster) - { - //Hellfire Infusion - doesn't work on scrolls and potions - int nType = GetBaseItemType(oItem); - if(nType != BASE_ITEM_POTIONS && nType != BASE_ITEM_ENCHANTED_POTION - && nType != BASE_ITEM_SCROLL && nType != BASE_ITEM_ENCHANTED_SCROLL) - { - fMulti = fHFInfusion; - DelayCommand(1.0, DeleteLocalFloat(oCaster, "PRC_HF_Infusion_Wid")); - } - } - } - - if(fMulti > 0.0) - { - fSize *= fMulti; - if(DEBUG) DoDebug("New Spell Size: " + FloatToString(fSize)); - } - - if(GetLocalInt(oCaster, "spellswd_aoe") == 1) - { - return OBJECT_INVALID; - } - - return GetNextObjectInShape(nShape,fSize,lTarget,bLineOfSight,nObjectFilter,vOrigin); -} - -//GetFirstObjectInShape wrapper for changing the AOE of the channeled spells -object MyFirstObjectInShape(int nShape, - float fSize, location lTarget, - int bLineOfSight = FALSE, - int nObjectFilter = OBJECT_TYPE_CREATURE, - vector vOrigin=[0.0, 0.0, 0.0]) -{ - object oCaster = OBJECT_SELF; - - //int on caster for the benefit of spellfire wielder resistance - // string sName = "IsAOE_" + IntToString(GetSpellId()); - string sName = "IsAOE_" + IntToString(PRCGetSpellId(oCaster)); - - SetLocalInt(oCaster, sName, 1); - DelayCommand(0.1, DeleteLocalInt(oCaster, sName)); - - // War Wizard of Cormyr's Widen Spell ability - float fMulti = GetLocalFloat(oCaster, PRC_SPELL_AREA_SIZE_MULTIPLIER); - //if(DEBUG) DoDebug("Original Spell Size: " + FloatToString(fSize)+"\n" + "Widened Multiplier: " + FloatToString(fMulti)); - - float fHFInfusion = GetLocalFloat(oCaster, "PRC_HF_Infusion_Wid"); - if(fHFInfusion > 0.0f) - { - object oItem = PRCGetSpellCastItem(oCaster); - if(GetIsObjectValid(oItem) && GetItemPossessor(oItem) == oCaster) - { - //Hellfire Infusion - doesn't work on scrolls and potions - int nType = GetBaseItemType(oItem); - if(nType != BASE_ITEM_POTIONS && nType != BASE_ITEM_ENCHANTED_POTION - && nType != BASE_ITEM_SCROLL && nType != BASE_ITEM_ENCHANTED_SCROLL) - { - fMulti = fHFInfusion; - DelayCommand(1.0, DeleteLocalFloat(oCaster, "PRC_HF_Infusion_Wid")); - } - } - } - - if(fMulti > 0.0) - { - fSize *= fMulti; - if(DEBUG) DoDebug("New Spell Size: " + FloatToString(fSize)); - - // This allows it to affect the entire casting - DelayCommand(1.0, DeleteLocalFloat(oCaster, PRC_SPELL_AREA_SIZE_MULTIPLIER)); - } - - if(GetLocalInt(oCaster, "spellswd_aoe") == 1) - { - return PRCGetSpellTargetObject(oCaster); - } - - return GetFirstObjectInShape(nShape,fSize,lTarget,bLineOfSight,nObjectFilter,vOrigin); -} - - -//This checks if the spell is channeled and if there are multiple spells -//channeled, which one is it. Then it checks in either case if the spell -//has the metamagic feat the function gets and returns TRUE or FALSE accordingly -//Also used by the new spellbooks for the same purpose -/* replaced by wrapper for GetMetaMagicFeat instead - Not necessarily. This may still be a usefule level of abstraction - Ornedan - */ -int CheckMetaMagic(int nMeta,int nMMagic) -{ - return nMeta & nMMagic; -} - -int PRCGetMetaMagicFeat(object oCaster = OBJECT_SELF, int bClearFeatFlags = TRUE) -{ - int nOverride = GetLocalInt(oCaster, PRC_METAMAGIC_OVERRIDE); - if(nOverride) - { - if (DEBUG) DoDebug("PRCGetMetaMagicFeat: found override metamagic = "+IntToString(nOverride)+", original = "+IntToString(GetMetaMagicFeat())); - return nOverride; - } - - object oItem = PRCGetSpellCastItem(oCaster); - - // we assume that we are casting from an item, if the item is valid and the item belongs to oCaster - // however, we cannot be sure because of Bioware's inadequate implementation of GetSpellCastItem - if(GetIsObjectValid(oItem) && GetItemPossessor(oItem) == oCaster) - { - int nFeat; - - //check item for metamagic - itemproperty ipTest = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(ipTest)) - { - if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_CAST_SPELL_METAMAGIC) - { - int nSubType = GetItemPropertySubType(ipTest); - nSubType = StringToInt(Get2DACache("iprp_spells", "SpellIndex", nSubType)); - if(nSubType == PRCGetSpellId(oCaster)) - { - int nCostValue = GetItemPropertyCostTableValue(ipTest); - if(nCostValue == -1 && DEBUG) - DoDebug("Problem examining itemproperty"); - switch(nCostValue) - { - //bitwise "addition" equivalent to nFeat = (nFeat | nSSFeat) - case 1: nFeat |= METAMAGIC_QUICKEN; break; - case 2: nFeat |= METAMAGIC_EMPOWER; break; - case 3: nFeat |= METAMAGIC_EXTEND; break; - case 4: nFeat |= METAMAGIC_MAXIMIZE; break; - case 5: nFeat |= METAMAGIC_SILENT; break; - case 6: nFeat |= METAMAGIC_STILL; break; - } - } - } - ipTest = GetNextItemProperty(oItem); - } - if (DEBUG) DoDebug("PRCGetMetaMagicFeat: item casting with item = "+GetName(oItem)+", found metamagic = "+IntToString(nFeat)); - - //Hellfire Infusion - doesn't work on scrolls and potions - int nType = GetBaseItemType(oItem); - if(nType != BASE_ITEM_POTIONS && nType != BASE_ITEM_ENCHANTED_POTION - && nType != BASE_ITEM_SCROLL && nType != BASE_ITEM_ENCHANTED_SCROLL) - { - nFeat |= GetLocalInt(oCaster, "PRC_HF_Infusion"); - if(bClearFeatFlags) DeleteLocalInt(oCaster, "PRC_HF_Infusion"); - } - - //apply metamagic adjustment (chanell spell) - nFeat |= GetLocalInt(oCaster, PRC_METAMAGIC_ADJUSTMENT); - return nFeat; - } - - if(GetLocalInt(oCaster, "PRC_SPELL_EVENT")) - { - if (DEBUG) DoDebug("PRCGetMetaMagicFeat: found spell event metamagic = "+IntToString(GetLocalInt(oCaster, "PRC_SPELL_METAMAGIC"))+", original = "+IntToString(GetMetaMagicFeat())); - return GetLocalInt(oCaster, "PRC_SPELL_METAMAGIC"); - } - - int nFeat = GetMetaMagicFeat(); - if(nFeat == METAMAGIC_ANY) - // work around for spontaneous casters (bard or sorcerer) having all metamagic turned on when using ActionCastSpell* - nFeat = METAMAGIC_NONE; - - nFeat |= GetLocalInt(oCaster, PRC_METAMAGIC_ADJUSTMENT); - - int nClass = PRCGetLastSpellCastClass(oCaster); - // Suel Archanamach's Extend spells they cast on themselves. - // Only works for Suel Spells, and not any other caster type they might have - // Since this is a spellscript, it assumes OBJECT_SELF is the caster - if(nClass == CLASS_TYPE_SUEL_ARCHANAMACH - && GetLevelByClass(CLASS_TYPE_SUEL_ARCHANAMACH) >= 3) - { - // Check that they cast on themselves - // if (oCaster == PRCGetSpellTargetObject()) - if(oCaster == PRCGetSpellTargetObject(oCaster)) - { - // Add extend to the metamagic feat using bitwise math - nFeat |= METAMAGIC_EXTEND; - } - } - //Code for the Abjurant Champion. Works similar to the Suel Archamamach but - //their extend only works on abjuration spells they cast. - if(GetHasFeat(FEAT_EXTENDED_ABJURATION, oCaster) - && GetLevelByClass(CLASS_TYPE_ABJURANT_CHAMPION) >= 1) - { - int nSpellSchool = GetLocalInt(oCaster, "X2_L_LAST_SPELLSCHOOL_VAR"); - // Check that they cast an abjuration spell - if(nSpellSchool == SPELL_SCHOOL_ABJURATION) - { - // Add extend to the metamagic feat using bitwise math - nFeat |= METAMAGIC_EXTEND; - if (DEBUG) FloatingTextStringOnCreature("Extended Abjuration Applied", oCaster, FALSE); - } - } - // Magical Contraction, Truenaming Utterance - if(GetHasSpellEffect(UTTER_MAGICAL_CONTRACTION_R, oCaster)) - //(GetLocalInt(oCaster, "TrueMagicalContraction")) - { - nFeat |= METAMAGIC_EMPOWER; - } - // Sudden Metamagic - int nSuddenMeta = GetLocalInt(oCaster, "SuddenMeta"); - if(nSuddenMeta) - { - nFeat |= nSuddenMeta; - if(bClearFeatFlags) - DeleteLocalInt(oCaster, "SuddenMeta"); - } - - int nDivMeta = GetLocalInt(oCaster, "DivineMeta"); - if(nDivMeta) - { - if(GetIsDivineClass(nClass, oCaster)) - { - nFeat |= nDivMeta; - if(bClearFeatFlags) - DeleteLocalInt(oCaster, "DivineMeta"); - } - } - - int nSpelldance = GetLocalInt(oCaster, "Spelldance"); - if(nSpelldance) - { - nFeat |= nSpelldance; - if (DEBUG) FloatingTextStringOnCreature("Metamagic Spelldances applied", oCaster, FALSE); - } - - int nSpellLevel = PRCGetSpellLevel(oCaster, PRCGetSpellId()); - if (GetLocalInt(oCaster, "Aradros_Extend")/* && GetIsArcaneClass(nClass, oCaster)*/) - { - if (DEBUG) DoDebug("PRCGetMetaMagicFeat: GetIsArcaneClass is TRUE"); - int nHD = GetHitDice(oCaster); - if (nHD >= 12 && 6 >= nSpellLevel) - { - nFeat |= METAMAGIC_EXTEND; - DeleteLocalInt(oCaster, "Aradros_Extend"); - if (DEBUG) FloatingTextStringOnCreature("Aradros Extend Applied", oCaster, FALSE); - } - else if (3 >= nSpellLevel) - { - nFeat |= METAMAGIC_EXTEND; - DeleteLocalInt(oCaster, "Aradros_Extend"); - if (DEBUG) FloatingTextStringOnCreature("Aradros Extend Applied", oCaster, FALSE); - } - } - - if (DEBUG) DoDebug("PRCGetMetaMagicFeat: nSpellLevel " +IntToString(nSpellLevel)+", PRCGetSpellId " +IntToString(PRCGetSpellId())+", nClass " +IntToString(nClass)); - if (DEBUG) DoDebug("PRCGetMetaMagicFeat: returning " +IntToString(nFeat)); - return nFeat; -} - -//Wrapper for The MaximizeOrEmpower function -int PRCMaximizeOrEmpower(int nDice, int nNumberOfDice, int nMeta, int nBonus = 0) -{ - int i, nDamage; - for (i = 1; i <= nNumberOfDice; i++) - { - nDamage = nDamage + Random(nDice) + 1; - } - - //Resolve metamagic - if(nMeta & METAMAGIC_MAXIMIZE) - nDamage = nDice * nNumberOfDice; - if(nMeta & METAMAGIC_EMPOWER) - nDamage = nDamage + nDamage / 2; - - return nDamage + nBonus; -} - -float PRCGetMetaMagicDuration(float fDuration, int nMeta = -1) -{ - if(nMeta == -1) // no metamagic value was passed, so get it here - nMeta = PRCGetMetaMagicFeat(); - - if(nMeta & METAMAGIC_EXTEND) - fDuration *= 2; - - return fDuration; -} - -int PRCGetMetaMagicDamage(int nDamageType, int nDice, int nDieSize, - int nBonusPerDie = 0, int nBonus = 0, int nMetaMagic = -1) -{ - // If the metamagic argument wasn't given get it. - if (-1 == nMetaMagic) nMetaMagic = PRCGetMetaMagicFeat(); - - // Roll the damage, applying metamagic. - int nDamage = PRCMaximizeOrEmpower(nDieSize, nDice, nMetaMagic, (nBonusPerDie * nDice) + nBonus); - return nDamage; -} - -void PRCSetSchool(int nSchool = SPELL_SCHOOL_GENERAL) -{ - // Remove the last value in case it is there and set the new value if it is NOT general. - if(SPELL_SCHOOL_GENERAL != nSchool) - SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", nSchool); - else - DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR"); -} - -void PRCSignalSpellEvent(object oTarget, int bHostile = TRUE, int nSpellID = -1, object oCaster = OBJECT_SELF) -{ - if (-1 == nSpellID) nSpellID = PRCGetSpellId(); - - //Fire cast spell at event for the specified target - SignalEvent(oTarget, EventSpellCastAt(oCaster, nSpellID, bHostile)); -} -/* -void SPEvilShift(object oPC) -{ - // Check for alignment shift switch being active - if(GetPRCSwitch(PRC_SPELL_ALIGNMENT_SHIFT)) - { - // Amount of adjustment is equal to the square root of your distance from pure evil. - // In other words, the amount of shift is higher the farther you are from pure evil, with the - // extremes being 10 points of shift at pure good and 0 points of shift at pure evil. - AdjustAlignment(oPC, ALIGNMENT_EVIL, FloatToInt(sqrt(IntToFloat(GetGoodEvilValue(oPC)))), FALSE); - } -} - -void SPGoodShift(object oPC) -{ - // Check for alignment shift switch being active - if(GetPRCSwitch(PRC_SPELL_ALIGNMENT_SHIFT)) - { - // Amount of adjustment is equal to the square root of your distance from pure good. - // In other words, the amount of shift is higher the farther you are from pure good, with the - // extremes being 10 points of shift at pure evil and 0 points of shift at pure good. - AdjustAlignment(oPC, ALIGNMENT_GOOD, FloatToInt(sqrt(IntToFloat(100 - GetGoodEvilValue(oPC)))), FALSE); - } -}*/ - -void DoCorruptionCost(object oPC, int nAbility, int nCost, int bDrain) -{ - // Undead redirect all damage & drain to Charisma, sez http://www.wizards.com/dnd/files/BookVileFAQ12102002.zip - if(MyPRCGetRacialType(oPC) == RACIAL_TYPE_UNDEAD) - nAbility = ABILITY_CHARISMA; - - //Exalted Raiment - if(GetHasSpellEffect(SPELL_EXALTED_RAIMENT, GetItemInSlot(INVENTORY_SLOT_CHEST, oPC))) - { - nCost -= 1; - - if(nCost < 1) - nCost = 1; - } - - if (GetHasFeat(FEAT_FAVORED_ZULKIRS, oPC)) nCost -= 1; - - // Is it ability drain? - if(bDrain) - ApplyAbilityDamage(oPC, nAbility, nCost, DURATION_TYPE_PERMANENT, TRUE); - // Or damage - else - ApplyAbilityDamage(oPC, nAbility, nCost, DURATION_TYPE_TEMPORARY, TRUE, -1.0f); -} - -void MultisummonPreSummon(object oPC = OBJECT_SELF, int bOverride = FALSE) -{ - if(!GetPRCSwitch(PRC_MULTISUMMON) && !bOverride) - return; - int i=1; - int nCount = GetPRCSwitch(PRC_MULTISUMMON); - if(bOverride) - nCount = bOverride; - if(nCount < 0 - || nCount == 1) - nCount = 99; - if(nCount > 99) - nCount = 99; - object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - while(GetIsObjectValid(oSummon) && !GetLocalInt(oSummon, "RFSummonedElemental") && i < nCount) - { - AssignCommand(oSummon, SetIsDestroyable(FALSE, FALSE, FALSE)); - AssignCommand(oSummon, DelayCommand(0.3, SetIsDestroyable(TRUE, FALSE, FALSE))); - i++; - oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - } -} - - -//This function returns 1 only if the object oTarget is the object -//the weapon hit when it channeled the spell sSpell or if there is no -//channeling at all -int ChannelChecker(string sSpell, object oTarget) -{ - int nSpell = GetLocalInt(GetAreaOfEffectCreator(), sSpell+"channeled"); - int nTarget = GetLocalInt(oTarget, sSpell+"target"); - if(nSpell == 1 && nTarget == 1) - { - return 1; - } - else if(nSpell != 1 && nTarget != 1) - { - return 1; - } - else - { - return 0; - } -} - -//If a spell is being channeled, we store its target and its name -void StoreSpellVariables(string sString,int nDuration) -{ - object oCaster = OBJECT_SELF; - object oTarget = GetSpellTargetObject(); //using prc version could cause problems - - if(GetLocalInt(oCaster,"spellswd_aoe") == 1) - { - SetLocalInt(oCaster, sString+"channeled",1); - SetLocalInt(oTarget, sString+"target",1); - } - DelayCommand(RoundsToSeconds(nDuration),DeleteLocalInt(oTarget, sString+"target")); - DelayCommand(RoundsToSeconds(nDuration),DeleteLocalInt(oCaster, sString+"channeled")); -} - -effect ChannelingVisual() -{ - return EffectVisualEffect(VFX_DUR_SPELLTURNING); -} - -////////////////End Spellsword////////////////// - - -int GetHasMettle(object oTarget, int nSavingThrow = SAVING_THROW_WILL) -{ - if(GetLevelByClass(CLASS_TYPE_HEXBLADE, oTarget) > 2) return TRUE; - if(GetLevelByClass(CLASS_TYPE_SOHEI, oTarget) > 8) return TRUE; - if(GetLevelByClass(CLASS_TYPE_CRUSADER, oTarget) > 12) return TRUE; - if(GetLocalInt(oTarget, "FactotumMettle")) return TRUE; - - if(nSavingThrow = SAVING_THROW_WILL) - { - // Iron Mind's ability only functions in Heavy Armour - if(GetLevelByClass(CLASS_TYPE_IRONMIND, oTarget) > 4 - && GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget)) > 5) - return TRUE; - // Fill out the line below to add another class with Will mettle - // if (GetLevelByClass(CLASS_TYPE_X, oTarget) >= X) return TRUE; - } - /*else if(nSavingThrow = SAVING_THROW_FORT) - { - // Add Classes with Fort mettle here - // if (GetLevelByClass(CLASS_TYPE_X, oTarget) >= X) return TRUE; - }*/ - - return FALSE; -} - -void DoCommandSpell(object oCaster, object oTarget, int nSpellId, int nDuration, int nCaster) -{ - if(DEBUG) DoDebug("DoCommandSpell: SpellId: " + IntToString(nSpellId)); - if(DEBUG) DoDebug("Command Spell: Begin"); - if(nSpellId == SPELL_COMMAND_APPROACH - || nSpellId == SPELL_GREATER_COMMAND_APPROACH - || nSpellId == 18359 //MYST_VOICE_SHADOW_APPROACH - || nSpellId == SPELL_DOA_COMMAND_APPROACH - || nSpellId == SPELL_DOA_GREATER_COMMAND_APPROACH) - { - // Force the target to approach the caster - if(DEBUG) DoDebug("Command Spell: Approach"); - AssignCommand(oTarget, ClearAllActions(TRUE)); - AssignCommand(oTarget, ActionForceMoveToObject(oCaster, TRUE)); - } - // Creatures that can't be disarmed ignore this - else if(nSpellId == SPELL_COMMAND_DROP - || nSpellId == SPELL_GREATER_COMMAND_DROP - || nSpellId == 18360 //MYST_VOICE_SHADOW_DROP - || nSpellId == SPELL_DOA_COMMAND_DROP - || nSpellId == SPELL_DOA_GREATER_COMMAND_DROP) - { - if(GetIsCreatureDisarmable(oTarget) && !GetPRCSwitch(PRC_PNP_DISARM)) - { - // Force the target to drop what its holding - if(DEBUG) DoDebug("Command Spell: Drop"); - AssignCommand(oTarget, ClearAllActions(TRUE)); - object oTargetWep = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); - SetDroppableFlag(oTargetWep, TRUE); - SetStolenFlag(oTargetWep, FALSE); - AssignCommand(oTarget, ActionPutDownItem(oTargetWep)); - /*oTargetWep = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); - SetDroppableFlag(oTargetWep, TRUE); - SetStolenFlag(oTargetWep, FALSE); - AssignCommand(oTarget, ActionPutDownItem(oTargetWep)); */ - } - else - { - FloatingTextStringOnCreature(GetName(oTarget) + " is not disarmable.", oCaster, FALSE); - } - } - else if(nSpellId == SPELL_COMMAND_FALL - || nSpellId == SPELL_GREATER_COMMAND_FALL - || nSpellId == 18361 //MYST_VOICE_SHADOW_FALL - || nSpellId == SPELL_DOA_COMMAND_FALL - || nSpellId == SPELL_DOA_GREATER_COMMAND_FALL) - { - // Force the target to fall down - if(DEBUG) DoDebug("Command Spell: Fall"); - AssignCommand(oTarget, ClearAllActions(TRUE)); - SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oTarget, RoundsToSeconds(nDuration),TRUE,-1,nCaster); - } - else if(nSpellId == SPELL_COMMAND_FLEE - || nSpellId == SPELL_GREATER_COMMAND_FLEE - || nSpellId == 18362 //MYST_VOICE_SHADOW_FLEE - || nSpellId == SPELL_DOA_COMMAND_FLEE - || nSpellId == SPELL_DOA_GREATER_COMMAND_FLEE) - { - // Force the target to flee the caster - if(DEBUG) DoDebug("Command Spell: Flee"); - AssignCommand(oTarget, ClearAllActions(TRUE)); - AssignCommand(oTarget, ActionMoveAwayFromObject(oCaster, TRUE)); - } - else if(nSpellId == SPELL_COMMAND_HALT - || nSpellId == SPELL_GREATER_COMMAND_HALT - || nSpellId == 18363 //MYST_VOICE_SHADOW_HALT - || nSpellId == SPELL_DOA_COMMAND_HALT - || nSpellId == SPELL_DOA_GREATER_COMMAND_HALT) - { - // Force the target to stand still - if(DEBUG) DoDebug("Command Spell: Stand"); - AssignCommand(oTarget, ClearAllActions(TRUE)); - SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectCutsceneParalyze(), oTarget, RoundsToSeconds(nDuration),TRUE,-1,nCaster); - } - else // Catch errors here - { - FloatingTextStringOnCreature("sp_command/sp_greatcommand: Error, Unknown SpellId", oCaster, FALSE); - } - if(DEBUG) DoDebug("Command Spell: End"); -} - -void SetIncorporeal(object oTarget, float fDuration, int nSuperOrEx, int nPermanent = FALSE) -{ - if (!GetIsObjectValid(oTarget)) - return; //No point working - - // Immune to non-magical weapons, ignore physical objects - effect eIncorporeal = EffectLinkEffects(EffectDamageReduction(100, DAMAGE_POWER_PLUS_ONE, 0), EffectCutsceneGhost()); - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, 50)); // 50% chance of magical weapons not working. Done as 50% Damage Immunity - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, 50)); - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, 50)); - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectMissChance(50, MISS_CHANCE_TYPE_VS_MELEE)); // 50% melee miss chance to hit non-incorporeal targets. That's going to be everything - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectSkillIncrease(SKILL_MOVE_SILENTLY, 99)); // Cannot be heard - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectVisualEffect(VFX_DUR_ETHEREAL_VISAGE)); // Visual effect - - // No Strength Score, use Dex for melee attacks too - int nStr = GetAbilityScore(oTarget, ABILITY_STRENGTH); - int nDex = GetAbilityModifier(ABILITY_DEXTERITY, oTarget); - int nPen; - - if (nStr>10) - { - nPen = nStr - 10; - eIncorporeal = EffectLinkEffects(eIncorporeal, EffectAbilityDecrease(ABILITY_STRENGTH, nPen)); // Reduce Strength to 10 - - object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); - if (GetIsObjectValid(oWeapon) && IPGetIsMeleeWeapon(oWeapon)) - { - IPSafeAddItemProperty(oWeapon, ItemPropertyAttackBonus(nDex), fDuration); //Dex has to be done as a melee weapon bonus - } - oWeapon = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); - if (GetIsObjectValid(oWeapon) && IPGetIsMeleeWeapon(oWeapon)) - { - IPSafeAddItemProperty(oWeapon, ItemPropertyAttackBonus(nDex), fDuration); //Dex has to be done as a melee weapon bonus - } - oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oTarget); - if (GetIsObjectValid(oWeapon)) // We know these are melee weapons - { - IPSafeAddItemProperty(oWeapon, ItemPropertyAttackBonus(nDex), fDuration); //Dex has to be done as a melee weapon bonus - } - oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oTarget); - if (GetIsObjectValid(oWeapon)) // We know these are melee weapons - { - IPSafeAddItemProperty(oWeapon, ItemPropertyAttackBonus(nDex), fDuration); //Dex has to be done as a melee weapon bonus - } - oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oTarget); - if (GetIsObjectValid(oWeapon)) // We know these are melee weapons - { - IPSafeAddItemProperty(oWeapon, ItemPropertyAttackBonus(nDex), fDuration); //Dex has to be done as a melee weapon bonus - } - } - - SetLocalInt(oTarget, "Incorporeal", TRUE); - if (!nPermanent) DelayCommand(fDuration, DeleteLocalInt(oTarget, "Incorporeal")); - - if (nSuperOrEx == 1) - eIncorporeal = SupernaturalEffect(eIncorporeal); - else if (nSuperOrEx == 2) - eIncorporeal = ExtraordinaryEffect(eIncorporeal); - - if (nPermanent) - SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eIncorporeal, oTarget); - else - SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eIncorporeal, oTarget, fDuration, FALSE, -1, -1); -} - -int GetIsIncorporeal(object oTarget) -{ - //Check for local int - if(GetPersistantLocalInt(oTarget, "Is_Incorporeal")) - return TRUE; - - //Check for local int - if(GetLocalInt(oTarget, "Incorporeal")) - return TRUE; - - //check for feat - if(GetHasFeat(FEAT_INCORPOREAL, oTarget)) - return TRUE; - - //base it on appearance - int nAppear = GetAppearanceType(oTarget); - if(nAppear == APPEARANCE_TYPE_ALLIP - || nAppear == APPEARANCE_TYPE_SHADOW - || nAppear == APPEARANCE_TYPE_SHADOW_FIEND - || nAppear == APPEARANCE_TYPE_SPECTRE - || nAppear == APPEARANCE_TYPE_WRAITH) - return TRUE; - - //Return value - return FALSE; -} - -int GetIsEthereal(object oTarget) -{ - return GetPersistantLocalInt(oTarget, "Is_Ethereal") - || GetHasFeat(FEAT_ETHEREAL, oTarget); -} - -int PRCGetIsAliveCreature(object oTarget) -{ - int bAlive = TRUE; - // non-creatures aren't alive - if (GetObjectType(oTarget) != OBJECT_TYPE_CREATURE) - return FALSE; // night of the living waypoints :p - - int nType = MyPRCGetRacialType(oTarget); - - //Non-living races, excluding warforged - if(nType == RACIAL_TYPE_UNDEAD || - (nType == RACIAL_TYPE_CONSTRUCT && !GetIsWarforged(oTarget))) bAlive = FALSE; - - //If they're dead :P - if(GetIsDead(oTarget)) bAlive = FALSE; - - //return - return bAlive; -} - -int GetControlledUndeadTotalHD(object oPC = OBJECT_SELF) -{ - int nTotalHD; - int i = 1; - object oSummonTest = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - while(GetIsObjectValid(oSummonTest)) - { - if(MyPRCGetRacialType(oSummonTest) == RACIAL_TYPE_UNDEAD) - nTotalHD += GetHitDice(oSummonTest); - if(DEBUG)FloatingTextStringOnCreature(GetName(oSummonTest)+" is summon number "+IntToString(i), oPC); - i++; - oSummonTest = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - } - return nTotalHD; -} - - -int GetControlledFiendTotalHD(object oPC = OBJECT_SELF) -{ - int nTotalHD; - int i = 1; - object oSummonTest = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - while(GetIsObjectValid(oSummonTest)) - { - if(MyPRCGetRacialType(oSummonTest) == RACIAL_TYPE_OUTSIDER - && GetAlignmentGoodEvil(oSummonTest) == ALIGNMENT_EVIL) - nTotalHD += GetHitDice(oSummonTest); - if(DEBUG)FloatingTextStringOnCreature(GetName(oSummonTest)+" is summon number "+IntToString(i), oPC); - i++; - oSummonTest = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - } - return nTotalHD; -} - -int GetControlledCelestialTotalHD(object oPC = OBJECT_SELF) -{ - int nTotalHD; - int i = 1; - object oSummonTest = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - while(GetIsObjectValid(oSummonTest)) - { - if(MyPRCGetRacialType(oSummonTest) == RACIAL_TYPE_OUTSIDER - && GetAlignmentGoodEvil(oSummonTest) == ALIGNMENT_GOOD) - nTotalHD += GetHitDice(oSummonTest); - if(DEBUG)FloatingTextStringOnCreature(GetName(oSummonTest)+" is summon number "+IntToString(i), oPC); - i++; - oSummonTest = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, i); - } - return nTotalHD; -} - - - -// wrapper for DecrementRemainingSpellUses, works for newspellbook 'fake' spells too -// should also find and decrement metamagics for newspellbooks -void PRCDecrementRemainingSpellUses(object oCreature, int nSpell) -{ - if (!UseNewSpellBook(oCreature) && GetHasSpell(nSpell, oCreature)) - { - DecrementRemainingSpellUses(oCreature, nSpell); - return; - } - - 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, nSpell); - nMeta = RealSpellToSpellbookIDCount(nClass, nSpell); - 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; - } - nSpellLevel = StringToInt(Get2DACache(sFile, "Level", j)); - - if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) - { - nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), j); - if(DEBUG) DoDebug("PRCDecrementRemainingSpellUses: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount)); - if(nCount > 0) - { - persistant_array_set_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), j, nCount - 1); - return; - } - } - else if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) - { - nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel); - if(DEBUG) DoDebug("PRCDecrementRemainingSpellUses: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount)); - if(nCount > 0) - { - persistant_array_set_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel, nCount - 1); - return; - } - } - } - } - } - if(DEBUG) DoDebug("PRCDecrementRemainingSpellUses: Spell " + IntToString(nSpell) + " not found"); -} - -// -// This function determines if spell damage is elemental -// -int IsSpellDamageElemental(int nDamageType) -{ - return nDamageType & 2480;// 2480 = (DAMAGE_TYPE_ACID | DAMAGE_TYPE_COLD | DAMAGE_TYPE_ELECTRICAL | DAMAGE_TYPE_FIRE | DAMAGE_TYPE_SONIC) -} - -// -// This function converts spell damage into the correct type -// TODO: Change the name to consistent (large churn project). -// -int ChangedElementalDamage(object oCaster, int nDamageType) -{ - - // None of the stuff here works when items are involved - if (GetIsObjectValid(PRCGetSpellCastItem())) return nDamageType; - - int nNewType; - - //eldritch spellweave - if(GetIsObjectValid(GetLocalObject(oCaster, "SPELLWEAVE_TARGET"))) - { - int nEssence = GetLocalInt(oCaster, "BlastEssence"); - - if(nEssence == INVOKE_BRIMSTONE_BLAST) - nNewType = DAMAGE_TYPE_FIRE; - - else if(nEssence == INVOKE_HELLRIME_BLAST) - nNewType = DAMAGE_TYPE_COLD; - - else if(nEssence == INVOKE_UTTERDARK_BLAST) - nNewType = DAMAGE_TYPE_NEGATIVE; - - else if(nEssence == INVOKE_VITRIOLIC_BLAST) - nNewType = DAMAGE_TYPE_ACID; - - //save new type for other functions - if(nNewType) - SetLocalInt(oCaster, "archmage_mastery_elements", nNewType); - } - else - // Check if an override is set - nNewType = GetLocalInt(oCaster, "archmage_mastery_elements"); - - // If so, check if the spell qualifies for a change - if (!nNewType || !IsSpellDamageElemental(nDamageType)) - nNewType = nDamageType; - - return nNewType; -} - -//used in scripts after ChangedElementalDamage() to determine saving throw type -int ChangedSaveType(int nDamageType) -{ - switch(nDamageType) - { - case DAMAGE_TYPE_ACID: return SAVING_THROW_TYPE_ACID; - case DAMAGE_TYPE_COLD: return SAVING_THROW_TYPE_COLD; - case DAMAGE_TYPE_ELECTRICAL: return SAVING_THROW_TYPE_ELECTRICITY; - case DAMAGE_TYPE_FIRE: return SAVING_THROW_TYPE_FIRE; - case DAMAGE_TYPE_SONIC: return SAVING_THROW_TYPE_SONIC; - case DAMAGE_TYPE_DIVINE: return SAVING_THROW_TYPE_DIVINE; - case DAMAGE_TYPE_NEGATIVE: return SAVING_THROW_TYPE_NEGATIVE; - case DAMAGE_TYPE_POSITIVE: return SAVING_THROW_TYPE_POSITIVE; - } - return SAVING_THROW_TYPE_NONE;//if it ever gets here, than the function was used incorrectly -} - -// this is possibly used in variations elsewhere -int PRCGetElementalDamageType(int nDamageType, object oCaster = OBJECT_SELF) -{ - switch(nDamageType) - { - case DAMAGE_TYPE_ACID: - case DAMAGE_TYPE_COLD: - case DAMAGE_TYPE_ELECTRICAL: - case DAMAGE_TYPE_FIRE: - case DAMAGE_TYPE_SONIC: - nDamageType = ChangedElementalDamage(oCaster, nDamageType); - } - return nDamageType; -} - -int GetHasBaneMagic(int nRace) -{ - switch(nRace) - { - case RACIAL_TYPE_ABERRATION: return GetHasFeat(FEAT_BANE_MAGIC_ABERRATION); - case RACIAL_TYPE_ANIMAL: return GetHasFeat(FEAT_BANE_MAGIC_ANIMAL); - case RACIAL_TYPE_BEAST: return GetHasFeat(FEAT_BANE_MAGIC_BEAST); - case RACIAL_TYPE_CONSTRUCT: return GetHasFeat(FEAT_BANE_MAGIC_CONSTRUCT); - case RACIAL_TYPE_DRAGON: return GetHasFeat(FEAT_BANE_MAGIC_DRAGON); - case RACIAL_TYPE_DWARF: return GetHasFeat(FEAT_BANE_MAGIC_DWARF); - case RACIAL_TYPE_ELEMENTAL: return GetHasFeat(FEAT_BANE_MAGIC_ELEMENTAL); - case RACIAL_TYPE_ELF: return GetHasFeat(FEAT_BANE_MAGIC_ELF); - case RACIAL_TYPE_FEY: return GetHasFeat(FEAT_BANE_MAGIC_FEY); - case RACIAL_TYPE_GIANT: return GetHasFeat(FEAT_BANE_MAGIC_GIANT); - case RACIAL_TYPE_GNOME: return GetHasFeat(FEAT_BANE_MAGIC_GNOME); - case RACIAL_TYPE_HALFELF: return GetHasFeat(FEAT_BANE_MAGIC_HALFELF); - case RACIAL_TYPE_HALFLING: return GetHasFeat(FEAT_BANE_MAGIC_HALFLING); - case RACIAL_TYPE_HALFORC: return GetHasFeat(FEAT_BANE_MAGIC_HALFORC); - case RACIAL_TYPE_HUMAN: return GetHasFeat(FEAT_BANE_MAGIC_HUMAN); - case RACIAL_TYPE_HUMANOID_GOBLINOID: return GetHasFeat(FEAT_BANE_MAGIC_HUMANOID_GOBLINOID); - case RACIAL_TYPE_HUMANOID_MONSTROUS: return GetHasFeat(FEAT_BANE_MAGIC_HUMANOID_MONSTROUS); - case RACIAL_TYPE_HUMANOID_ORC: return GetHasFeat(FEAT_BANE_MAGIC_HUMANOID_ORC); - case RACIAL_TYPE_HUMANOID_REPTILIAN: return GetHasFeat(FEAT_BANE_MAGIC_HUMANOID_REPTILIAN); - case RACIAL_TYPE_MAGICAL_BEAST: return GetHasFeat(FEAT_BANE_MAGIC_MAGICAL_BEAST); - case RACIAL_TYPE_OUTSIDER: return GetHasFeat(FEAT_BANE_MAGIC_OUTSIDER); - case RACIAL_TYPE_SHAPECHANGER: return GetHasFeat(FEAT_BANE_MAGIC_SHAPECHANGER); - case RACIAL_TYPE_UNDEAD: return GetHasFeat(FEAT_BANE_MAGIC_UNDEAD); - case RACIAL_TYPE_VERMIN: return GetHasFeat(FEAT_BANE_MAGIC_VERMIN); - } - return FALSE; -} - -void DoPiercingCold(object oCaster, object oTarget, int nDamageAmount, int nCurrentHP) -{ - // Get change in HP from spell damage being applied - int nTest = nCurrentHP - GetCurrentHitPoints(oTarget); - // If there's no damage resistance, nTest and nDamageAmount should be equal - if (nDamageAmount > nTest) - { - // Apply the difference to ignore resist - effect eDam = EffectDamage(nDamageAmount - nTest, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY); - ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget); - effect eVis = EffectVisualEffect(VFX_IMP_FROST_L); - ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); - //FloatingTextStringOnCreature("Piercing Cold Triggered", oCaster, FALSE); - } -} - -void BreakDR(object oCaster, object oTarget, int nDamageAmount, int nCurrentHP) -{ - // Get change in HP from spell damage being applied - int nTest = nCurrentHP - GetCurrentHitPoints(oTarget); - // If there's no damage resistance, nTest and nDamageAmount should be equal - if (nDamageAmount > nTest) - { - // Apply the difference to ignore resist - effect eDam = EffectDamage(nDamageAmount - nTest, DAMAGE_TYPE_POSITIVE, DAMAGE_POWER_ENERGY); - ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget); - } -} - -effect PRCEffectDamage(object oTarget, int nDamageAmount, int nDamageType=DAMAGE_TYPE_MAGICAL, int nDamagePower=DAMAGE_POWER_NORMAL, int nMetaMagic=METAMAGIC_NONE) -{ - object oCaster = OBJECT_SELF; - - // Incorporeal creatures have a 50% chance of not being hurt by damage other than Magical/Divine/Negative - if (GetLocalInt(oTarget, "Incorporeal") && nDamageType != DAMAGE_TYPE_MAGICAL && nDamageType != DAMAGE_TYPE_NEGATIVE && nDamageType != DAMAGE_TYPE_DIVINE) - { - if (d2() == 1) // 50% chance - { - if (GetIsPC(oTarget)) - FloatingTextStringOnCreature("Spell missed due to Incorporeality", oTarget, FALSE); - effect eEffect; - return eEffect; // Null return - } - } - - // None of the stuff here works when items are involved - if (!GetIsObjectValid(PRCGetSpellCastItem())) - { - if(PRCGetLastSpellCastClass(oCaster) == CLASS_TYPE_WARMAGE && !GetLocalInt(oTarget, "WarmageEdgeDelay")) - { - // Warmage Edge - nDamageAmount += GetAbilityModifier(ABILITY_INTELLIGENCE); - if(GetHasFeat(FEAT_TYPE_EXTRA_EDGE)) - { - // Extra Edge feat. - nDamageAmount += (GetLevelByClass(CLASS_TYPE_WARMAGE) / 4) + 1; - } - SetLocalInt(oTarget, "WarmageEdgeDelay", TRUE); - DelayCommand(0.25, DeleteLocalInt(oTarget, "WarmageEdgeDelay")); - } - - if(GetHasSpellEffect(MELD_ARCANE_FOCUS, oCaster) && !GetLocalInt(oTarget, "ArcaneFocusDelay")) - { - nDamageAmount += 1 + GetEssentiaInvested(oCaster, MELD_ARCANE_FOCUS); - SetLocalInt(oTarget, "ArcaneFocusDelay", TRUE); - DelayCommand(0.25, DeleteLocalInt(oTarget, "ArcaneFocusDelay")); - if (DEBUG) DoDebug("ArcaneFocus Damage Applied"); - } - - // Thrall of Grazzt damage - nDamageAmount += SpellBetrayalDamage(oTarget, oCaster); - - int nRace = MyPRCGetRacialType(oTarget); - - //Bane Magic - if(GetHasBaneMagic(nRace)) - nDamageAmount += d6(2); - - //Eldritch Spellweave - if(oTarget == GetLocalObject(oCaster, "SPELLWEAVE_TARGET")) - { - //Bane blast essence is active ;) - if(nRace == ((GetLocalInt(oCaster, "EssenceData") >>> 16) & 0xFF) - 1) - { - DeleteLocalObject(oCaster, "SPELLWEAVE_TARGET"); - nDamageAmount += d6(2); - } - } - - // Piercing Evocation - if(GetHasFeat(FEAT_PIERCING_EVOCATION) && GetLocalInt(oCaster, "X2_L_LAST_SPELLSCHOOL_VAR") == SPELL_SCHOOL_EVOCATION) - { - // Elemental damage only - if(IsSpellDamageElemental(nDamageType)) - { - // Damage magical, max 10 to magical - if(nDamageAmount > 10) - { - nDamageAmount -= 10; - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(10), oTarget); - } - else - { - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamageAmount), oTarget); - effect eEffect; - return eEffect; // Null return - } - } - } - - // This is done here so it affects all spells - if(GetLocalInt(oCaster, "Diabolism")) - { - //FloatingTextStringOnCreature("Diabolism is active", oCaster, FALSE); - int iDiabolistLevel = GetLevelByClass(CLASS_TYPE_DIABOLIST, oCaster); - DelayCommand(3.0, DeleteLocalInt(oCaster, "Diabolism")); - - if(iDiabolistLevel) - { - int nDice = (iDiabolistLevel + 5) / 5; - int nDamage = d6(nDice); - int nDamageType = DAMAGE_TYPE_DIVINE; - - if(GetLocalInt(oCaster, "VileDiabolism")) - { - //FloatingTextStringOnCreature("Vile Diabolism is active", oCaster, FALSE); - nDamage /= 2; - nDamageType = DAMAGE_TYPE_POSITIVE; - DeleteLocalInt(oCaster, "VileDiabolism"); - } - - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, nDamageType), oTarget); - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_LOS_EVIL_10), oTarget); - } - } - - // Piercing Cold for the Frost Mage - if (GetLevelByClass(CLASS_TYPE_FROST_MAGE, oCaster) >= 4 && nDamageType == DAMAGE_TYPE_COLD) - { - int nCurrentHP = GetCurrentHitPoints(oTarget); - DelayCommand(0.1, DoPiercingCold(oCaster, oTarget, nDamageAmount, nCurrentHP)); - } - - // Die DR die - if (GetLocalInt(oCaster, "MoveIgnoreDR")) - { - int nCurrentHP = GetCurrentHitPoints(oTarget); - DelayCommand(0.1, BreakDR(oCaster, oTarget, nDamageAmount, nCurrentHP)); - } - } - - // Frostrager heals on cold damage when raging. 1 heal for every 2 cold damage. - if (GetLocalInt(oTarget, "Frostrage") && nDamageType == DAMAGE_TYPE_COLD) - { - nDamageAmount /= 2; - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nDamageAmount), oTarget); - ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FROST_L), oTarget); - - FloatingTextStringOnCreature("Absorb Cold healed " + IntToString(nDamageAmount), oTarget, FALSE); - effect eEffect; - return eEffect; //Doesn't hurt him - } - // Phoenix Belt gains fast healing when hit by fire damage - if (GetHasSpellEffect(MELD_PHOENIX_BELT, oTarget) && nDamageType == DAMAGE_TYPE_FIRE) - { - int nEssentia = GetEssentiaInvested(oTarget, MELD_PHOENIX_BELT); - int nResist = nEssentia * 5; - int nDur; - if (nDamageAmount >= nResist) nDur = nResist; - else nDur = nDamageAmount; - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectRegenerate(1, 6.0), oTarget, RoundsToSeconds(nDur+1)); - } - - return EffectDamage(nDamageAmount, nDamageType, nDamagePower); -} - -// * Kovi. removes any effects from this type of spell -// * i.e., used in Mage Armor to remove any previous -// * mage armors -void PRCRemoveEffectsFromSpell(object oTarget, int SpellID) -{ - effect eLook = GetFirstEffect(oTarget); - while(GetIsEffectValid(eLook)) - { - if(GetEffectSpellId(eLook) == SpellID) - RemoveEffect(oTarget, eLook); - - eLook = GetNextEffect(oTarget); - } -} - -void PRCRemoveSpecificEffect(int nEffectTypeID, object oTarget) -{ - //Search through the valid effects on the target. - effect eAOE = GetFirstEffect(oTarget); - while (GetIsEffectValid(eAOE)) - { - if (GetEffectType(eAOE) == nEffectTypeID) - { - //If the effect was created by the spell then remove it - RemoveEffect(oTarget, eAOE); - } - //Get next effect on the target - eAOE = GetNextEffect(oTarget); - } -} - -effect PRCGetScaledEffect(effect eStandard, object oTarget) -{ - int nDiff = GetGameDifficulty(); - int nEffType = GetEffectType(eStandard); - - if(GetIsPC(oTarget) || GetIsPC(GetMaster(oTarget))) - { - if(nEffType == EFFECT_TYPE_FRIGHTENED) - { - if(nDiff == GAME_DIFFICULTY_VERY_EASY) - { - return EffectAttackDecrease(-2); - } - else if(nDiff == GAME_DIFFICULTY_EASY) - { - return EffectAttackDecrease(-4); - } - } - if(nDiff == GAME_DIFFICULTY_VERY_EASY && - (nEffType == EFFECT_TYPE_PARALYZE || - nEffType == EFFECT_TYPE_STUNNED || - nEffType == EFFECT_TYPE_CONFUSED)) - { - return EffectDazed(); - } - if(nEffType == EFFECT_TYPE_CHARMED - || nEffType == EFFECT_TYPE_DOMINATED) - { - return EffectDazed(); - } - } - return eStandard; -} - -int PRCAmIAHumanoid(object oTarget) -{ - int nRacial = MyPRCGetRacialType(oTarget); - if(nRacial == RACIAL_TYPE_DWARF - || nRacial == RACIAL_TYPE_HALFELF - || nRacial == RACIAL_TYPE_HALFORC - || nRacial == RACIAL_TYPE_ELF - || nRacial == RACIAL_TYPE_GNOME - || nRacial == RACIAL_TYPE_HUMANOID_GOBLINOID - || nRacial == RACIAL_TYPE_HALFLING - || nRacial == RACIAL_TYPE_HUMAN - || nRacial == RACIAL_TYPE_HUMANOID_MONSTROUS - || nRacial == RACIAL_TYPE_HUMANOID_ORC - || nRacial == RACIAL_TYPE_HUMANOID_REPTILIAN) - { - return TRUE; - } - return FALSE; -} - -int PRCGetScaledDuration(int nActualDuration, object oTarget) -{ - int nDiff = GetGameDifficulty(); - int nNew = nActualDuration; - if(GetIsPC(oTarget) && nActualDuration > 3) - { - if(nDiff == GAME_DIFFICULTY_VERY_EASY - || nDiff == GAME_DIFFICULTY_EASY) - { - nNew = nActualDuration / 4; - } - else if(nDiff == GAME_DIFFICULTY_NORMAL) - { - nNew = nActualDuration / 2; - } - if(nNew == 0) - { - nNew = 1; - } - } - return nNew; -} - -effect PRCCreateProtectionFromAlignmentLink(int nAlignment, int nPower = 1) -{ - int nFinal = nPower * 2; - int nAlignmentLC; - int nAlignmentGE; - effect eDur; - - switch(nAlignment) - { - case ALIGNMENT_LAWFUL:{ - nAlignmentLC = ALIGNMENT_LAWFUL; - nAlignmentGE = ALIGNMENT_ALL; - eDur = EffectVisualEffect(VFX_DUR_PROTECTION_EVIL_MINOR); - break;} - case ALIGNMENT_CHAOTIC:{ - nAlignmentLC = ALIGNMENT_CHAOTIC; - nAlignmentGE = ALIGNMENT_ALL; - eDur = EffectVisualEffect(VFX_DUR_PROTECTION_GOOD_MINOR); - break;} - case ALIGNMENT_GOOD:{ - nAlignmentLC = ALIGNMENT_ALL; - nAlignmentGE = ALIGNMENT_GOOD; - eDur = EffectVisualEffect(VFX_DUR_PROTECTION_EVIL_MINOR); - break;} - case ALIGNMENT_EVIL:{ - nAlignmentLC = ALIGNMENT_ALL; - nAlignmentGE = ALIGNMENT_EVIL; - eDur = EffectVisualEffect(VFX_DUR_PROTECTION_GOOD_MINOR); - break;} - } - - //construct final effect - effect eLink = EffectACIncrease(nFinal, AC_DEFLECTION_BONUS); - eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_ALL, nFinal)); - eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_MIND_SPELLS)); - //make it vs alignment - eLink = VersusAlignmentEffect(eLink, nAlignmentLC, nAlignmentGE); - //add duration vfx - eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE)); - eLink = EffectLinkEffects(eLink, eDur); - - return eLink; -} - -float PRCGetSpellEffectDelay(location SpellTargetLocation, object oTarget) -{ - float fDelay = GetDistanceBetweenLocations(SpellTargetLocation, GetLocation(oTarget))/20; - return fDelay; -} - -// * returns true if the creature has flesh -int PRCIsImmuneToPetrification(object oCreature) -{ - int nAppearance = GetAppearanceType(oCreature); - int bImmune = FALSE; - - if (GetHasSpellEffect(VESTIGE_HAAGENTI, oCreature) && GetLocalInt(oCreature, "ExploitVestige") != VESTIGE_HAAGENTI_IMMUNE_TRANS) bImmune = TRUE; - - switch (nAppearance) - { - case APPEARANCE_TYPE_BASILISK: - case APPEARANCE_TYPE_COCKATRICE: - case APPEARANCE_TYPE_MEDUSA: - case APPEARANCE_TYPE_ALLIP: - case APPEARANCE_TYPE_ELEMENTAL_AIR: - case APPEARANCE_TYPE_ELEMENTAL_AIR_ELDER: - case APPEARANCE_TYPE_ELEMENTAL_EARTH: - case APPEARANCE_TYPE_ELEMENTAL_EARTH_ELDER: - case APPEARANCE_TYPE_ELEMENTAL_FIRE: - case APPEARANCE_TYPE_ELEMENTAL_FIRE_ELDER: - case APPEARANCE_TYPE_ELEMENTAL_WATER: - case APPEARANCE_TYPE_ELEMENTAL_WATER_ELDER: - case APPEARANCE_TYPE_GOLEM_STONE: - case APPEARANCE_TYPE_GOLEM_IRON: - case APPEARANCE_TYPE_GOLEM_CLAY: - case APPEARANCE_TYPE_GOLEM_BONE: - case APPEARANCE_TYPE_GORGON: - case APPEARANCE_TYPE_HEURODIS_LICH: - case APPEARANCE_TYPE_LANTERN_ARCHON: - case APPEARANCE_TYPE_SHADOW: - case APPEARANCE_TYPE_SHADOW_FIEND: - case APPEARANCE_TYPE_SHIELD_GUARDIAN: - case APPEARANCE_TYPE_SKELETAL_DEVOURER: - case APPEARANCE_TYPE_SKELETON_CHIEFTAIN: - case APPEARANCE_TYPE_SKELETON_COMMON: - case APPEARANCE_TYPE_SKELETON_MAGE: - case APPEARANCE_TYPE_SKELETON_PRIEST: - case APPEARANCE_TYPE_SKELETON_WARRIOR: - case APPEARANCE_TYPE_SKELETON_WARRIOR_1: - case APPEARANCE_TYPE_SPECTRE: - case APPEARANCE_TYPE_WILL_O_WISP: - case APPEARANCE_TYPE_WRAITH: - case APPEARANCE_TYPE_BAT_HORROR: - case 405: // Dracolich: - case 415: // Alhoon - case 418: // shadow dragon - case 420: // mithral golem - case 421: // admantium golem - case 430: // Demi Lich - case 469: // animated chest - case 474: // golems - case 475: // golems - bImmune = TRUE; - } - - int nRacialType = MyPRCGetRacialType(oCreature); - switch(nRacialType) - { - case RACIAL_TYPE_ELEMENTAL: - case RACIAL_TYPE_CONSTRUCT: - case RACIAL_TYPE_OOZE: - case RACIAL_TYPE_UNDEAD: - bImmune = TRUE; - } - - // 01/08/07 Racial feat for petrification immunity - if(GetHasFeat(FEAT_IMMUNE_PETRIFICATION)) bImmune = TRUE; - - // 03/07/2005 CraigW - Petrification immunity can also be granted as an item property. - if ( ResistSpell(OBJECT_SELF,oCreature) == 2 ) - { - bImmune = TRUE; - } - - // * GZ: Sept 2003 - Prevent people from petrifying DM, resulting in GUI even when - // effect is not successful. - if (!GetPlotFlag(oCreature) && GetIsDM(oCreature)) - { - bImmune = FALSE; - } - return bImmune; -} - -// * This is a wrapper for how Petrify will work in Expansion Pack 1 -// * Scripts affected: flesh to stone, breath petrification, gaze petrification, touch petrification -// * nPower : This is the Hit Dice of a Monster using Gaze, Breath or Touch OR it is the Caster Spell of -// * a spellcaster -// * nFortSaveDC: pass in this number from the spell script -void PRCDoPetrification(int nPower, object oSource, object oTarget, int nSpellID, int nFortSaveDC) -{ - - if(!GetIsReactionTypeFriendly(oTarget)) - { - // * exit if creature is immune to petrification - if(PRCIsImmuneToPetrification(oTarget)) - return; - - float fDifficulty = 0.0; - int bIsPC = GetIsPC(oTarget); - int bShowPopup = FALSE; - - // * calculate Duration based on difficulty settings - int nGameDiff = GetGameDifficulty(); - switch (nGameDiff) - { - case GAME_DIFFICULTY_VERY_EASY: - case GAME_DIFFICULTY_EASY: - case GAME_DIFFICULTY_NORMAL: - fDifficulty = RoundsToSeconds(nPower); // One Round per hit-die or caster level - break; - case GAME_DIFFICULTY_CORE_RULES: - case GAME_DIFFICULTY_DIFFICULT: - bShowPopup = TRUE; - break; - } - - int nSaveDC = nFortSaveDC; - effect ePetrify = EffectPetrify(); - - effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE); - - effect eLink = EffectLinkEffects(eDur, ePetrify); - - // Let target know the negative spell has been cast - SignalEvent(oTarget, - EventSpellCastAt(OBJECT_SELF, nSpellID)); - //SpeakString(IntToString(nSpellID)); - - // Do a fortitude save check - if (!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nSaveDC)) - { - // Save failed; apply paralyze effect and VFX impact - - /// * The duration is permanent against NPCs but only temporary against PCs - if (bIsPC == TRUE) - { - if (bShowPopup == TRUE) - { - // * under hardcore rules or higher, this is an instant death - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget); - //only pop up death panel if switch is not set - if(!GetPRCSwitch(PRC_NO_PETRIFY_GUI)) - DelayCommand(2.75, PopUpDeathGUIPanel(oTarget, FALSE , TRUE, 40579)); - //run the PRC Ondeath code - //no way to run the normal module ondeath code too - //so a execute script has been added for builders to take advantage of - DelayCommand(2.75, ExecuteScript("prc_ondeath", oTarget)); - DelayCommand(2.75, ExecuteScript("prc_pw_petrific", oTarget)); - // if in hardcore, treat the player as an NPC - bIsPC = FALSE; - //fDifficulty = TurnsToSeconds(nPower); // One turn per hit-die - } - else - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDifficulty); - } - else - { - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget); - } - // April 2003: Clearing actions to kick them out of conversation when petrified - AssignCommand(oTarget, ClearAllActions(TRUE)); - } - } - -} - -//------------------------------------------------------------------------------ -// GZ: 2003-Oct-15 -// A different approach for timing these spells that has the positive side -// effects of making the spell dispellable as well. -// I am using the VFX applied by the spell to track the remaining duration -// instead of adding the remaining runtime on the stack -// -// This function returns FALSE if a delayed Spell effect from nSpell_ID has -// expired. See x2_s0_bigby4.nss for details -//------------------------------------------------------------------------------ -int PRCGetDelayedSpellEffectsExpired(int nSpell_ID, object oTarget, object oCaster) -{ - - if (!GetHasSpellEffect(nSpell_ID,oTarget) ) - { - DeleteLocalInt(oTarget,"XP2_L_SPELL_SAVE_DC_" + IntToString (nSpell_ID)); - return TRUE; - } - - //-------------------------------------------------------------------------- - // GZ: 2003-Oct-15 - // If the caster is dead or no longer there, cancel the spell, as it is - // directed - //-------------------------------------------------------------------------- - if( !GetIsObjectValid(oCaster)) - { - GZPRCRemoveSpellEffects(nSpell_ID, oTarget); - DeleteLocalInt(oTarget,"XP2_L_SPELL_SAVE_DC_" + IntToString (nSpell_ID)); - return TRUE; - } - - if (GetIsDead(oCaster)) - { - DeleteLocalInt(oTarget,"XP2_L_SPELL_SAVE_DC_" + IntToString (nSpell_ID)); - GZPRCRemoveSpellEffects(nSpell_ID, oTarget); - return TRUE; - } - - return FALSE; - -} - -// Much similar to PRCGetHasSpell, but used for JPM to get spells left not counting metamagic -int PRCGetSpellUsesLeft(int nRealSpellID, object oCreature = OBJECT_SELF) -{ - if(!PRCGetIsRealSpellKnown(nRealSpellID, oCreature)) - return 0; - int nUses = GetHasSpell(nRealSpellID, oCreature); - - int nClass, nSpellbookID, nCount, 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); - if (nSpellbookID != -1) - { //non-spellbook classes should return -1 - 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("PRCGetHasSpell(Prepared Caster): 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("PRCGetHasSpell(Spontaneous Caster): NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount)); - if(nCount > 0) - { - nUses += nCount; - } - } - } - } - - if(DEBUG) DoDebug("PRCGetHasSpell: RealSpellID = " + IntToString(nRealSpellID) + ", Uses = " + IntToString(nUses)); - return nUses; -} - -// * Applies the effects of FEAT_AUGMENT_SUMMON to summoned creatures. -void AugmentSummonedCreature(string sResRef) -{ - if(GetHasFeat(FEAT_AUGMENT_SUMMON)) - { - int i = 1; - object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF); - while(GetIsObjectValid(oSummon)) - { - if(GetResRef(oSummon) == sResRef && !GetLocalInt(oSummon, "Augmented")) - { - effect eLink = EffectAbilityIncrease(ABILITY_STRENGTH, 4); - eLink = EffectLinkEffects(eLink, EffectAbilityIncrease(ABILITY_CONSTITUTION, 4)); - eLink = SupernaturalEffect(eLink); - - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oSummon); - SetLocalInt(oSummon, "Augmented", TRUE); - } - i++; - oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF, i); - } - } - if(sResRef == "prc_sum_treant") - { - int i = 1; - object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF); - while(GetIsObjectValid(oSummon)) - { - if(GetResRef(oSummon) == sResRef) - { - ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_PROT_BARKSKIN), oSummon); - } - i++; - oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF, i); - } - } - if(GetHasFeat(FEAT_BECKON_THE_FROZEN)) - { - int i = 1; - object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF); - while(GetIsObjectValid(oSummon)) - { - if(GetResRef(oSummon) == sResRef && !GetLocalInt(oSummon, "BeckonTheFrozen")) - { - effect eLink = EffectVisualEffect(VFX_DUR_ELEMENTAL_SHIELD); - eLink = EffectLinkEffects(eLink, EffectDamageImmunityDecrease(DAMAGE_TYPE_FIRE, 50)); - eLink = EffectLinkEffects(eLink, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 100)); - eLink = SupernaturalEffect(eLink); - - ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oSummon); - SetLocalInt(oSummon, "BeckonTheFrozen", TRUE); - } - i++; - oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF, i); - } - } -} - -object GetAreaOfEffectObject(location lTarget, string sTag, object oCaster = OBJECT_SELF) -{ - object oAoE = GetFirstObjectInShape(SHAPE_SPHERE, 1.0f, lTarget, FALSE, OBJECT_TYPE_AREA_OF_EFFECT); - while(GetIsObjectValid(oAoE)) - { - if((GetAreaOfEffectCreator(oAoE) == oCaster) //was created by oCaster - && GetTag(oAoE) == sTag //has required tag - && !GetLocalInt(oAoE, "X2_AoE_BaseSaveDC")) //and wasn't setup before - { - return oAoE; - } - oAoE = GetNextObjectInShape(SHAPE_SPHERE, 1.0f, lTarget, FALSE, OBJECT_TYPE_AREA_OF_EFFECT); - } - return OBJECT_INVALID; -} - -string GetAreaOfEffectTag(int nAoE) -{ - return Get2DACache("vfx_persistent", "LABEL", nAoE); -} - -int CheckTurnUndeadUses(object oPC, int nUses) -{ - int i; - while(i < nUses) - { - if(GetHasFeat(FEAT_TURN_UNDEAD, oPC)) - { - DecrementRemainingFeatUses(oPC, FEAT_TURN_UNDEAD); - i++; - } - else - break; - } - if(i < nUses) - { - while(i) - { - IncrementRemainingFeatUses(oPC, FEAT_TURN_UNDEAD); - i--; - } - return FALSE; - } - return TRUE; -} - -// this will execute the prespellcastcode, whose full functionality is incoded in X2PreSpellCastCode2(), -// as a script, to save loading time for spells scripts and reduce memory usage of NWN -// the prespellcode takes up roughly 250 kByte compiled code, meaning that every spell script that -// calls it directly as a function (e.g.: X2PreSpellCastCode2) will be between 100 kByte to 250 kByte -// larger, than a spell script calling the prespellcode via ExecuteScript (e.g. X2PreSpellCastCode) -// Although ExecuteScript is slightly slower than a direct function call, quite likely overall performance is -// increased, because for every new spell 100-250 kByte less code need to be loaded into memory -// and NWN has more free memory available to keep more spells scripts (and other crucial scripts) -//in RAM - -int X2PreSpellCastCode() -{ - object oCaster = OBJECT_SELF; - - // SetLocalInt(oCaster, "PSCC_Ret", 0); - ExecuteScript("prc_prespell", oCaster); - - int nReturn = GetLocalInt(oCaster, "PSCC_Ret"); - // DeleteLocalInt(oCaster, "PSCC_Ret"); - - return nReturn; -} - -//:: Test Void -//void main (){} \ No newline at end of file diff --git a/trunk/include/prc_shifter_info.nss b/trunk/include/prc_shifter_info.nss deleted file mode 100644 index e5f715d3..00000000 --- a/trunk/include/prc_shifter_info.nss +++ /dev/null @@ -1,1436 +0,0 @@ - -//:: Updated for .35 by Jaysyn 2023/03/10 - -#include "prc_inc_function" -#include "inc_nwnx_funcs" - -//:: Test Void -//void main (){} - - -const int DEBUG_NATURAL_AC_CALCULATION = FALSE; -int MAX_BONUS = GetPRCSwitch(PRC_PNP_SHIFTER_BONUS); -const int MAX_PENALTY = 10; -int NWNX_STR_LIMIT = 100 - MAX_BONUS; - -struct _prc_inc_ability_info_struct{ - int nTemplateSTR; - int nTemplateDEX; - int nTemplateCON; - - int nShifterSTR; - int nShifterDEX; - int nShifterCON; - - int nDeltaSTR; - int nDeltaDEX; - int nDeltaCON; - - int nItemSTR; - int nItemDEX; - int nItemCON; - - int nExtraSTR; - int nExtraDEX; - int nExtraCON; - - int nItemDeltaSTR; - int nItemDeltaDEX; - int nItemDeltaCON; -}; - -//TODO: also count item penalties? -struct _prc_inc_ability_info_struct _prc_inc_CountItemAbilities(object oCreature) -{ - struct _prc_inc_ability_info_struct rInfoStruct; - rInfoStruct.nItemSTR = 0; - rInfoStruct.nItemDEX = 0; - rInfoStruct.nItemCON = 0; - - object oItem; - itemproperty iProperty; - int nSlot; - for(nSlot = 0; nSlot < NUM_INVENTORY_SLOTS; nSlot++) - { - switch (nSlot) - { - case INVENTORY_SLOT_CARMOUR: - case INVENTORY_SLOT_CWEAPON_R: - case INVENTORY_SLOT_CWEAPON_L: - case INVENTORY_SLOT_CWEAPON_B: - break; - - default: - { - oItem = GetItemInSlot(nSlot, oCreature); - if (GetIsObjectValid(oItem)) - { - iProperty = GetFirstItemProperty(oItem); - while (GetIsItemPropertyValid(iProperty)) - { - if (GetItemPropertyType(iProperty) == ITEM_PROPERTY_ABILITY_BONUS && - GetItemPropertyDurationType(iProperty) == DURATION_TYPE_PERMANENT - ) - { - int nSubType = GetItemPropertySubType(iProperty); - int nCostTableValue = GetItemPropertyCostTableValue(iProperty); - if (nSubType == IP_CONST_ABILITY_STR) - rInfoStruct.nItemSTR += nCostTableValue; - else if (nSubType == IP_CONST_ABILITY_DEX) - rInfoStruct.nItemDEX += nCostTableValue; - else if (nSubType == IP_CONST_ABILITY_CON) - rInfoStruct.nItemCON += nCostTableValue; - } - // Next item property. - iProperty = GetNextItemProperty(oItem); - } - } - } - } - } - return rInfoStruct; -} - -struct _prc_inc_ability_info_struct _prc_inc_shifter_GetAbilityInfo(object oTemplate, object oShifter) -{ - int bFuncs = GetPRCSwitch(PRC_NWNX_FUNCS); - - //Initialize with item ability bonuses - - struct _prc_inc_ability_info_struct rInfoStruct = _prc_inc_CountItemAbilities(oShifter); - - //Get template creature abilities - - rInfoStruct.nTemplateSTR = GetAbilityScore(oTemplate, ABILITY_STRENGTH, TRUE); - rInfoStruct.nTemplateDEX = GetAbilityScore(oTemplate, ABILITY_DEXTERITY, TRUE); - rInfoStruct.nTemplateCON = GetAbilityScore(oTemplate, ABILITY_CONSTITUTION, TRUE); - //TODO: merge in "Ability Bonus: Strength" from item property from template hide here (not too important, as not many templates use this) - //TODO: merge in "Ability Bonus: Dexterity" from item property from template hide here (not too important, as not many templates use this) - //TODO: merge in "Ability Bonus: Constitution" from item property from template hide here (not too important, as not many templates use this) - - //Calculate how they compare to the shifter's abilities - - rInfoStruct.nShifterSTR = GetAbilityScore(oShifter, ABILITY_STRENGTH, TRUE); - rInfoStruct.nShifterDEX = GetAbilityScore(oShifter, ABILITY_DEXTERITY, TRUE); - rInfoStruct.nShifterCON = GetAbilityScore(oShifter, ABILITY_CONSTITUTION, TRUE); - - rInfoStruct.nDeltaSTR = rInfoStruct.nTemplateSTR - rInfoStruct.nShifterSTR; - rInfoStruct.nDeltaDEX = rInfoStruct.nTemplateDEX - rInfoStruct.nShifterDEX; - rInfoStruct.nDeltaCON = rInfoStruct.nTemplateCON - rInfoStruct.nShifterCON; - - //Handle stat boosting items - if (rInfoStruct.nItemSTR > MAX_BONUS) - rInfoStruct.nItemSTR = MAX_BONUS; - else if (rInfoStruct.nItemSTR < -MAX_PENALTY) - rInfoStruct.nItemSTR = -MAX_PENALTY; - - if (rInfoStruct.nItemDEX > MAX_BONUS) - rInfoStruct.nItemDEX = MAX_BONUS; - else if (rInfoStruct.nItemDEX < -MAX_PENALTY) - rInfoStruct.nItemDEX = -MAX_PENALTY; - - if (rInfoStruct.nItemCON > MAX_BONUS) - rInfoStruct.nItemCON = MAX_BONUS; - else if (rInfoStruct.nItemCON < -MAX_PENALTY) - rInfoStruct.nItemCON = -MAX_PENALTY; - - //Handle changes that exceed bonus or penalty caps - - rInfoStruct.nItemDeltaSTR = rInfoStruct.nDeltaSTR + rInfoStruct.nItemSTR; - if (bFuncs) - { - //NWNX boosts aren't capped, so we don't need to handle caps, generally speaking. - rInfoStruct.nExtraSTR = 0; - - //However, due to a Bioware issue, if STR, including bonuses, goes greater than 100, - //the amount of weight the PC can carry drops to 0. So, cap STR to make sure this doesn't happen. - - if (rInfoStruct.nTemplateSTR > NWNX_STR_LIMIT) - { - rInfoStruct.nExtraSTR = rInfoStruct.nTemplateSTR - NWNX_STR_LIMIT; - rInfoStruct.nTemplateSTR = NWNX_STR_LIMIT; - rInfoStruct.nDeltaSTR = rInfoStruct.nTemplateSTR - rInfoStruct.nShifterSTR; - } - } - else if (rInfoStruct.nItemDeltaSTR > MAX_BONUS) - rInfoStruct.nExtraSTR = rInfoStruct.nItemDeltaSTR - MAX_BONUS; - else if(rInfoStruct.nItemDeltaSTR < -MAX_PENALTY) - rInfoStruct.nExtraSTR = rInfoStruct.nItemDeltaSTR + MAX_PENALTY; - - rInfoStruct.nItemDeltaDEX = rInfoStruct.nDeltaDEX + rInfoStruct.nItemDEX; - if (bFuncs) - rInfoStruct.nExtraDEX = 0; //NWNX boosts aren't capped, so we don't need to handle caps - else if (rInfoStruct.nItemDeltaDEX > MAX_BONUS) - rInfoStruct.nExtraDEX = rInfoStruct.nItemDeltaDEX - MAX_BONUS; - else if(rInfoStruct.nItemDeltaDEX < -MAX_PENALTY) - rInfoStruct.nExtraDEX = rInfoStruct.nItemDeltaDEX + MAX_PENALTY; - - rInfoStruct.nItemDeltaCON = rInfoStruct.nDeltaCON + rInfoStruct.nItemCON; - if (bFuncs) - rInfoStruct.nExtraCON = 0; //NWNX boosts aren't capped, so we don't need to handle caps - else if (rInfoStruct.nItemDeltaCON > MAX_BONUS) - rInfoStruct.nExtraCON = rInfoStruct.nItemDeltaCON - MAX_BONUS; - else if(rInfoStruct.nItemDeltaCON < -MAX_PENALTY) - rInfoStruct.nExtraCON = rInfoStruct.nItemDeltaCON + MAX_PENALTY; - - return rInfoStruct; -} - -int _prc_inc_GetItemACBonus(object oItem) -{ - int nArmorBonus = 0; - itemproperty iProp = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(iProp)) - { - if(GetItemPropertyType(iProp) == ITEM_PROPERTY_AC_BONUS && GetItemPropertyDurationType(iProp) == DURATION_TYPE_PERMANENT) - nArmorBonus = max(nArmorBonus, GetItemPropertyCostTableValue(iProp)); //TODO: pick the biggest? the first? stack them? - iProp = GetNextItemProperty(oItem); - } - return nArmorBonus; -} - -int _prc_inc_GetArmorMaxDEXBonus(object oArmor, int nMaxDexACBonus = 100) -{ - if (GetIsObjectValid(oArmor)) - { - int nArmorAC = GetItemACValue(oArmor) - _prc_inc_GetItemACBonus(oArmor); //Exclude magical AC bonus to figure out armor type - switch(nArmorAC) - { - //TODO: CAN THESE BE LOOKED UP IN A 2DA OR SOMEWHERE? - case 8: case 7: case 6: - nMaxDexACBonus = 1; break; - case 5: - nMaxDexACBonus = 2; break; - case 4: case 3: - nMaxDexACBonus = 4; break; - case 2: - nMaxDexACBonus = 6; break; - case 1: - nMaxDexACBonus = 8; break; - } - } - return nMaxDexACBonus; -} - -struct _prc_inc_ac_info_struct{ - int nArmorBase; - int nArmorBonus; - - int nShieldBase; - int nShieldBonus; - - int nDodgeBonus; - int nNaturalBonus; - int nDeflectionBonus; - - int nDEXBonus; -}; - -struct _prc_inc_ac_info_struct _prc_inc_ACInfo(object oTemplate) -{ - struct _prc_inc_ac_info_struct ac_info; - - object oArmorItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oTemplate); - ac_info.nArmorBonus = _prc_inc_GetItemACBonus(oArmorItem); - ac_info.nArmorBase = GetItemACValue(oArmorItem) - ac_info.nArmorBonus; - - ac_info.nDodgeBonus = GetItemACValue(GetItemInSlot(INVENTORY_SLOT_BOOTS, oTemplate)); - ac_info.nNaturalBonus = GetItemACValue(GetItemInSlot(INVENTORY_SLOT_NECK, oTemplate)); - - ac_info.nDeflectionBonus = GetItemACValue(GetItemInSlot(INVENTORY_SLOT_HEAD, oTemplate)); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_CLOAK, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_BELT, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_ARROWS, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_BULLETS, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_BOLTS, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oTemplate))); - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTemplate))); - - object oOffHandItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTemplate); - ac_info.nShieldBase = 0; - ac_info.nShieldBonus = 0; - switch (GetBaseItemType(oOffHandItem)) - { - case BASE_ITEM_SMALLSHIELD: - ac_info.nShieldBase = 1; - ac_info.nShieldBonus = GetItemACValue(oOffHandItem) - ac_info.nShieldBase; - break; - case BASE_ITEM_LARGESHIELD: - ac_info.nShieldBase = 2; - ac_info.nShieldBonus = GetItemACValue(oOffHandItem) - ac_info.nShieldBase; - break; - case BASE_ITEM_TOWERSHIELD: - ac_info.nShieldBase = 3; - ac_info.nShieldBonus = GetItemACValue(oOffHandItem) - ac_info.nShieldBase; - break; - default: //A weapon - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(oOffHandItem)); - break; - } - - object oArmsItem = GetItemInSlot(INVENTORY_SLOT_ARMS, oTemplate); - switch (GetBaseItemType(oArmsItem)) - { - case BASE_ITEM_BRACER: - ac_info.nShieldBonus = max(ac_info.nShieldBonus, GetItemACValue(oArmsItem)); - break; - case BASE_ITEM_GLOVES: - default: - ac_info.nDeflectionBonus = max(ac_info.nDeflectionBonus, GetItemACValue(oArmsItem)); - break; - } - - if (ac_info.nArmorBonus > 20) - ac_info.nArmorBonus = 20; - if (ac_info.nDodgeBonus > 20) - ac_info.nDodgeBonus = 20; - if (ac_info.nNaturalBonus > 20) - ac_info.nNaturalBonus = 20; - if (ac_info.nDeflectionBonus > 20) - ac_info.nDeflectionBonus = 20; - if (ac_info.nShieldBonus > 20) - ac_info.nShieldBonus = 20; - - ac_info.nDEXBonus = min(GetAbilityModifier(ABILITY_DEXTERITY, oTemplate), _prc_inc_GetArmorMaxDEXBonus(oArmorItem)); - //TODO: make sure this isn't < 0? - - return ac_info; -} - -//Estimate natural AC of the creature oTemplate -int _prc_inc_CreatureNaturalAC(object oTemplate) -{ - struct _prc_inc_ac_info_struct ac_info = _prc_inc_ACInfo(oTemplate); - - //TODO: GetAC(oTemplate) often returns an AC different (usually higher) than the combat debugging log indicates it should be. - //Note that combat debugging doesn't report DEX bonus, Monk WIS bonus, etc.; where does this come in? - int nNaturalAC = GetAC(oTemplate) - - 10 // Adjust for base AC - - ac_info.nDEXBonus // And Dex bonus - - ac_info.nArmorBase // Etc... - - ac_info.nArmorBonus - - ac_info.nDodgeBonus - - ac_info.nNaturalBonus - - ac_info.nDeflectionBonus - - ac_info.nShieldBase - - ac_info.nShieldBonus; - - //TODO: - //Subtract +4 Dodge bonus if template has Haste? - //Subtract +1 AC / each 5 points of the Tumble skill? - //Subtract Monk AC from level progression? - //Subtract WIS AC if Monk/Ninja, etc.? - //Make sure nNaturalAC is not < 0 (it was for me once using the old method of calculation, which is why I created this new one) - - if (DEBUG_NATURAL_AC_CALCULATION || DEBUG) - { - DoDebug("_prc_inc_CreatureNaturalAC: total ac: " + IntToString(GetAC(oTemplate))); - DoDebug("_prc_inc_CreatureNaturalAC: base ac: " + IntToString(10)); - DoDebug("_prc_inc_CreatureNaturalAC: armor base ac: " + IntToString(ac_info.nArmorBase)); - DoDebug("_prc_inc_CreatureNaturalAC: armor bonus ac: " + IntToString(ac_info.nArmorBonus)); - DoDebug("_prc_inc_CreatureNaturalAC: shield base ac: " + IntToString(ac_info.nShieldBase)); - DoDebug("_prc_inc_CreatureNaturalAC: shield bonus ac: " + IntToString(ac_info.nShieldBonus)); - DoDebug("_prc_inc_CreatureNaturalAC: dodge bonus ac: " + IntToString(ac_info.nDodgeBonus)); - DoDebug("_prc_inc_CreatureNaturalAC: natural bonus ac: " + IntToString(ac_info.nNaturalBonus)); - DoDebug("_prc_inc_CreatureNaturalAC: deflection bonus ac: " + IntToString(ac_info.nDeflectionBonus)); - DoDebug("_prc_inc_CreatureNaturalAC: dex ac: " + IntToString(ac_info.nDEXBonus)); - DoDebug("_prc_inc_CreatureNaturalAC: calculated natural ac: " + IntToString(nNaturalAC)); - } - - //TODO: combat debugging shows actual natural AC (as well as other type); compare with that to debug. - - return nNaturalAC; -} - -int _prc_inc_GetFeatDeathAttackLevel(int nFeat) -{ - switch(nFeat) - { - case FEAT_PRESTIGE_DEATH_ATTACK_1: return 1; - case FEAT_PRESTIGE_DEATH_ATTACK_2: return 2; - case FEAT_PRESTIGE_DEATH_ATTACK_3: return 3; - case FEAT_PRESTIGE_DEATH_ATTACK_4: return 4; - case FEAT_PRESTIGE_DEATH_ATTACK_5: return 5; - case FEAT_PRESTIGE_DEATH_ATTACK_6: return 6; - case FEAT_PRESTIGE_DEATH_ATTACK_7: return 7; - case FEAT_PRESTIGE_DEATH_ATTACK_8: return 8; - case FEAT_PRESTIGE_DEATH_ATTACK_9: return 9; - case FEAT_PRESTIGE_DEATH_ATTACK_10: return 10; - case FEAT_PRESTIGE_DEATH_ATTACK_11: return 11; - case FEAT_PRESTIGE_DEATH_ATTACK_12: return 12; - case FEAT_PRESTIGE_DEATH_ATTACK_13: return 13; - case FEAT_PRESTIGE_DEATH_ATTACK_14: return 14; - case FEAT_PRESTIGE_DEATH_ATTACK_15: return 15; - case FEAT_PRESTIGE_DEATH_ATTACK_16: return 16; - case FEAT_PRESTIGE_DEATH_ATTACK_17: return 17; - case FEAT_PRESTIGE_DEATH_ATTACK_18: return 18; - case FEAT_PRESTIGE_DEATH_ATTACK_19: return 19; - case FEAT_PRESTIGE_DEATH_ATTACK_20: return 20; - } - return 0; -} - -int _prc_inc_GetHasFeat(object oTemplate, int nFeat) -{ - //If oTemplate has the feat FEAT_SNEAK_ATTACK_10, GetHasFeat() always says - //it has FEAT_PRESTIGE_DEATH_ATTACK_1 through FEAT_PRESTIGE_DEATH_ATTACK_20, - //whether it actually does or not. Work around this as follows: - int nSuppress=0; - int FEAT_SNEAK_ATTACK_10 = 353; - if(GetHasFeat(FEAT_SNEAK_ATTACK_10, oTemplate)) - { - int nFeatDeathAttackLevel = _prc_inc_GetFeatDeathAttackLevel(nFeat); - if(nFeatDeathAttackLevel) - { - int nActualDeathAttackLevel = 0; - nActualDeathAttackLevel += (GetLevelByClass(CLASS_TYPE_ASSASSIN, oTemplate) + 1) / 2; - //TODO: Add other classes here? OR use GetTotalSneakAttackDice(), etc. from prc_inc_sneak instead? - if(nFeatDeathAttackLevel > nActualDeathAttackLevel) - nSuppress = 1; - } - } - - return GetHasFeat(nFeat, oTemplate) && !nSuppress; -} - -int _prc_inc_shifting_GetIsCreatureHarmless(object oTemplate) -{ - return GetChallengeRating(oTemplate) < 1.0; -} - -int _prc_inc_shifting_CharacterLevelRequirement(object oTemplate) -{ - return GetPRCSwitch(PNP_SHFT_USECR) ? FloatToInt(GetChallengeRating(oTemplate)) : GetHitDice(oTemplate); -} - -int _prc_inc_shifting_ShifterLevelRequirement(object oTemplate) -{ - int nRacialType = MyPRCGetRacialType(oTemplate); - int nSize = PRCGetCreatureSize(oTemplate); - int nLevelRequired = 0; - - // Size tests - if(nSize >= CREATURE_SIZE_HUGE) - nLevelRequired = max(nLevelRequired, 7); - if(nSize == CREATURE_SIZE_LARGE) - nLevelRequired = max(nLevelRequired, 3); - if(nSize == CREATURE_SIZE_MEDIUM) - nLevelRequired = max(nLevelRequired, 1); - if(nSize == CREATURE_SIZE_SMALL) - nLevelRequired = max(nLevelRequired, 1); - if(nSize <= CREATURE_SIZE_TINY) - nLevelRequired = max(nLevelRequired, 3); - - // Type tests - if(nRacialType == RACIAL_TYPE_OUTSIDER) - nLevelRequired = max(nLevelRequired, 9); - if(nRacialType == RACIAL_TYPE_ELEMENTAL) - nLevelRequired = max(nLevelRequired, 9); - if(nRacialType == RACIAL_TYPE_CONSTRUCT) - nLevelRequired = max(nLevelRequired, 8); - if(nRacialType == RACIAL_TYPE_UNDEAD) - nLevelRequired = max(nLevelRequired, 8); - if(nRacialType == RACIAL_TYPE_DRAGON) - nLevelRequired = max(nLevelRequired, 7); - if(nRacialType == RACIAL_TYPE_ABERRATION) - nLevelRequired = max(nLevelRequired, 6); - if(nRacialType == RACIAL_TYPE_OOZE) - nLevelRequired = max(nLevelRequired, 6); - if(nRacialType == RACIAL_TYPE_MAGICAL_BEAST) - nLevelRequired = max(nLevelRequired, 5); - if(nRacialType == RACIAL_TYPE_GIANT) - nLevelRequired = max(nLevelRequired, 4); - if(nRacialType == RACIAL_TYPE_VERMIN) - nLevelRequired = max(nLevelRequired, 4); - if(nRacialType == RACIAL_TYPE_BEAST) - nLevelRequired = max(nLevelRequired, 3); - if(nRacialType == RACIAL_TYPE_ANIMAL) - nLevelRequired = max(nLevelRequired, 2); - if(nRacialType == RACIAL_TYPE_HUMANOID_MONSTROUS) - nLevelRequired = max(nLevelRequired, 2); - if(nRacialType == RACIAL_TYPE_DWARF || - nRacialType == RACIAL_TYPE_ELF || - nRacialType == RACIAL_TYPE_GNOME || - nRacialType == RACIAL_TYPE_HUMAN || - nRacialType == RACIAL_TYPE_HALFORC || - nRacialType == RACIAL_TYPE_HALFELF || - nRacialType == RACIAL_TYPE_HALFLING || - nRacialType == RACIAL_TYPE_HUMANOID_ORC || - nRacialType == RACIAL_TYPE_HUMANOID_REPTILIAN - ) - nLevelRequired = max(nLevelRequired, 1); - - return nLevelRequired; -} - -int _prc_inc_shifting_GetCanFormCast(object oTemplate) -{ - int nRacialType = MyPRCGetRacialType(oTemplate); - - // Need to have hands, and the ability to speak - - switch (nRacialType) - { - case RACIAL_TYPE_ABERRATION: - case RACIAL_TYPE_ANIMAL: - case RACIAL_TYPE_BEAST: - case RACIAL_TYPE_MAGICAL_BEAST: - case RACIAL_TYPE_VERMIN: - case RACIAL_TYPE_OOZE: -// case RACIAL_TYPE_PLANT: - // These forms can't cast spells - return FALSE; - case RACIAL_TYPE_DWARF: - case RACIAL_TYPE_ELF: - case RACIAL_TYPE_GNOME: - case RACIAL_TYPE_HALFLING: - case RACIAL_TYPE_HALFELF: - case RACIAL_TYPE_HALFORC: - case RACIAL_TYPE_HUMAN: - case RACIAL_TYPE_CONSTRUCT: - case RACIAL_TYPE_DRAGON: - case RACIAL_TYPE_HUMANOID_GOBLINOID: - case RACIAL_TYPE_HUMANOID_MONSTROUS: - case RACIAL_TYPE_HUMANOID_ORC: - case RACIAL_TYPE_HUMANOID_REPTILIAN: - case RACIAL_TYPE_ELEMENTAL: - case RACIAL_TYPE_FEY: - case RACIAL_TYPE_GIANT: - case RACIAL_TYPE_OUTSIDER: - case RACIAL_TYPE_SHAPECHANGER: - case RACIAL_TYPE_UNDEAD: - // Break and go return TRUE at the end of the function - break; - - default:{ - if(DEBUG) DoDebug("prc_inc_shifting: _GetCanFormCast(): Unknown racial type: " + IntToString(nRacialType)); - } - } - - return TRUE; -} - -string _prc_inc_AbilityTypeString(int nAbilityType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_abilities", "Name", nAbilityType))); -} - -string _prc_inc_AlignmentGroupString(int nAlignmentGroup) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_aligngrp", "Name", nAlignmentGroup))); -} - -string _prc_inc_BonusFeatTypeString(int nBonusFeatType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_feats", "Name", nBonusFeatType))); -} - -string _prc_inc_ClassTypeString(int nClassType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", nClassType))); -} - -string _prc_inc_CostTableEntryString(int nCostTable, int nCostTableValue) -{ - string sCostTableName = Get2DACache("iprp_costtable", "Name", nCostTable); - if(sCostTableName == "" || sCostTableName == "****") - return "??? (" + IntToString(nCostTable) + " / " + IntToString(nCostTableValue) + ")"; - string sCostTableEntry = Get2DACache(sCostTableName, "Name", nCostTableValue); - if(sCostTableEntry == "" || sCostTableEntry == "****") - return "??? (" + sCostTableName + " / " + IntToString(nCostTableValue) + ")"; - return GetStringByStrRef(StringToInt(sCostTableEntry)); -} - -string _prc_inc_DamageTypeString(int nDamageType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_damagetype", "Name", nDamageType))); -} - -string _prc_inc_ImmunityTypeString(int nImmunityType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_immunity", "Name", nImmunityType))); -} - -string _prc_inc_OnHitSpellTypeString(int nOnHitSpellType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_onhitspell", "Name", nOnHitSpellType))); -} - -string _prc_inc_OnHitTypeString(int nOnHitSpellType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_onhit", "Name", nOnHitSpellType))); -} - -string _prc_inc_OnMonsterHitTypeString(int nOnMonsterHitType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_monsterhit", "Name", nOnMonsterHitType))); -} - -string _prc_inc_SavingThrowElementTypeString(int nSavingThrowType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_saveelement", "Name", nSavingThrowType))); -} - -string _prc_inc_SavingThrowTypeString(int nSavingThrowType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_savingthrow", "Name", nSavingThrowType))); -} - -string _prc_inc_SkillTypeString(int nSkillType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("skills", "Name", nSkillType))); -} - -string _prc_inc_SpecialWalkTypeString(int nWalkType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_walk", "Name", nWalkType))); -} - -string _prc_inc_SpellSchoolTypeString(int nSpellSchoolType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_spellshl", "Name", nSpellSchoolType))); -} - -string _prc_inc_SpellTypeString(int nOnHitSpellType) -{ - return GetStringByStrRef(StringToInt(Get2DACache("iprp_spells", "Name", nOnHitSpellType))); -} - -string _prc_inc_VisualEffectString(int nVisualEffect) -{ - //TODO: Look up in 2da (which one?) - switch(nVisualEffect) - { - case ITEM_VISUAL_ACID: - return "Acid"; - case ITEM_VISUAL_COLD: - return "Cold"; - case ITEM_VISUAL_ELECTRICAL: - return "Electrical"; - case ITEM_VISUAL_FIRE: - return "Fire"; - case ITEM_VISUAL_SONIC: - return "Sonic"; - case ITEM_VISUAL_HOLY: - return "Holy"; - case ITEM_VISUAL_EVIL: - return "Evil"; - } - return "???"; -} - -string _prc_inc_ItemPropertyString(itemproperty iprop) -{ - int nType = GetItemPropertyType(iprop); - int nSubType = GetItemPropertySubType(iprop); - int nDurationType = GetItemPropertyDurationType(iprop); - int nParam1 = GetItemPropertyParam1(iprop); - int nParam1Value = GetItemPropertyParam1Value(iprop); - int nCostTable = GetItemPropertyCostTable(iprop); - int nCostTableValue = GetItemPropertyCostTableValue(iprop); - string sType = IntToString(nType); - string sSubType = IntToString(nSubType); - string sDurationType = IntToString(nDurationType); - string sParam1 = IntToString(nParam1); - string sParam1Value = IntToString(nParam1Value); - string sCostTable = IntToString(nCostTable); - string sCostTableValue = IntToString(nCostTableValue); - string sResult = - "Typ: " + sType + "; " - + "SubTyp: " + sSubType + "; " - + "DurTyp: " + sDurationType + "; " - + "Parm: " + sParam1 + "; " - + "ParmVal: " + sParam1Value + "; " - + "CTab: " + sCostTable + "; " - + "CVal: " + sCostTableValue; - string sTypeName = GetStringByStrRef(StringToInt(Get2DACache("itempropdef", "Name", nType))); - switch (nType) - { - //TODO: these are all the possible cases; need to handle more of them. - //DONE case ITEM_PROPERTY_ABILITY_BONUS: - //DONE case ITEM_PROPERTY_AC_BONUS: - // case ITEM_PROPERTY_AC_BONUS_VS_ALIGNMENT_GROUP: - // case ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE: - // case ITEM_PROPERTY_AC_BONUS_VS_RACIAL_GROUP: - // case ITEM_PROPERTY_AC_BONUS_VS_SPECIFIC_ALIGNMENT: - //DONE case ITEM_PROPERTY_ENHANCEMENT_BONUS: - //DONE case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP: - // case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP: - // case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_SPECIFIC_ALIGNEMENT: - // case ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER - //DONE case ITEM_PROPERTY_BASE_ITEM_WEIGHT_REDUCTION - //DONE case ITEM_PROPERTY_BONUS_FEAT: - // case ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N: - //DONE case ITEM_PROPERTY_CAST_SPELL: - //DONE case ITEM_PROPERTY_DAMAGE_BONUS: - //DONE case ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP: - //case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP: - //case ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT: - //DONE case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE: - // case ITEM_PROPERTY_DECREASED_DAMAGE: - //DONE case ITEM_PROPERTY_DAMAGE_REDUCTION: - //DONE case ITEM_PROPERTY_DAMAGE_RESISTANCE: - //DONE case ITEM_PROPERTY_DAMAGE_VULNERABILITY: - //DONE case ITEM_PROPERTY_DARKVISION: - //DONE case ITEM_PROPERTY_DECREASED_ABILITY_SCORE: - // case ITEM_PROPERTY_DECREASED_AC: - // case ITEM_PROPERTY_DECREASED_SKILL_MODIFIER: //TODO: e.g. S1-Tomb of Horrors: DesertDragon - // case ITEM_PROPERTY_ENHANCED_CONTAINER_REDUCED_WEIGHT: - //DONE case ITEM_PROPERTY_EXTRA_MELEE_DAMAGE_TYPE: - // case ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE: - //DONE case ITEM_PROPERTY_HASTE: - // case ITEM_PROPERTY_HOLY_AVENGER: - //DONE case ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS: - //DONE case ITEM_PROPERTY_IMPROVED_EVASION: - //DONE case ITEM_PROPERTY_SPELL_RESISTANCE: - //DONE case ITEM_PROPERTY_SAVING_THROW_BONUS: - //DONE case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC: - //DONE case ITEM_PROPERTY_KEEN: - //DONE case ITEM_PROPERTY_LIGHT: - // case ITEM_PROPERTY_MIGHTY: - // case ITEM_PROPERTY_MIND_BLANK: - // case ITEM_PROPERTY_NO_DAMAGE: - //DONE case ITEM_PROPERTY_ON_HIT_PROPERTIES: - //DONE case ITEM_PROPERTY_DECREASED_SAVING_THROWS: - //DONE case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC: - //DONE case ITEM_PROPERTY_REGENERATION: - //DONE case ITEM_PROPERTY_SKILL_BONUS: - //DONE case ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL: - //DONE case ITEM_PROPERTY_IMMUNITY_SPELL_SCHOOL: - // case ITEM_PROPERTY_THIEVES_TOOLS: - //DONE case ITEM_PROPERTY_ATTACK_BONUS: - //DONE case ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP: - // case ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP: - // case ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT: - // case ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER: - // case ITEM_PROPERTY_UNLIMITED_AMMUNITION: - // case ITEM_PROPERTY_USE_LIMITATION_ALIGNMENT_GROUP: - // case ITEM_PROPERTY_USE_LIMITATION_CLASS: - // case ITEM_PROPERTY_USE_LIMITATION_RACIAL_TYPE: - // case ITEM_PROPERTY_USE_LIMITATION_SPECIFIC_ALIGNMENT: - // case ITEM_PROPERTY_USE_LIMITATION_TILESET: - //DONE case ITEM_PROPERTY_REGENERATION_VAMPIRIC: - // case ITEM_PROPERTY_TRAP: - //DONE case ITEM_PROPERTY_TRUE_SEEING: - //DONE case ITEM_PROPERTY_ON_MONSTER_HIT: - //DONE case ITEM_PROPERTY_TURN_RESISTANCE: - //DONE case ITEM_PROPERTY_MASSIVE_CRITICALS: - //DONE case ITEM_PROPERTY_FREEDOM_OF_MOVEMENT: - //DONE case ITEM_PROPERTY_MONSTER_DAMAGE: - //DONE case ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL: - //DONE case ITEM_PROPERTY_SPECIAL_WALK: - // case ITEM_PROPERTY_HEALERS_KIT: - // case ITEM_PROPERTY_WEIGHT_INCREASE: - //DONE case ITEM_PROPERTY_ONHITCASTSPELL: - //DONE case ITEM_PROPERTY_VISUALEFFECT: - // case ITEM_PROPERTY_ARCANE_SPELL_FAILURE: - - //Completely ignore - case ITEM_PROPERTY_BASE_ITEM_WEIGHT_REDUCTION: - return ""; - - //Property name only - case ITEM_PROPERTY_DARKVISION: - case ITEM_PROPERTY_FREEDOM_OF_MOVEMENT: - case ITEM_PROPERTY_HASTE: - case ITEM_PROPERTY_IMPROVED_EVASION: - case ITEM_PROPERTY_KEEN: - case ITEM_PROPERTY_TRUE_SEEING: - return sTypeName; - - //Interpret cost table information - case ITEM_PROPERTY_AC_BONUS: - case ITEM_PROPERTY_ATTACK_BONUS: - case ITEM_PROPERTY_ENHANCEMENT_BONUS: - case ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL: - case ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL: - case ITEM_PROPERTY_LIGHT: - case ITEM_PROPERTY_MASSIVE_CRITICALS: - case ITEM_PROPERTY_MONSTER_DAMAGE: - case ITEM_PROPERTY_REGENERATION: - case ITEM_PROPERTY_SPELL_RESISTANCE: - case ITEM_PROPERTY_TURN_RESISTANCE: - return sTypeName + ": " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - - //Interpret cost table information; interpret subtype as damage type - case ITEM_PROPERTY_DAMAGE_BONUS: - case ITEM_PROPERTY_DAMAGE_RESISTANCE: - case ITEM_PROPERTY_DAMAGE_VULNERABILITY: - case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE: - return sTypeName + ": " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue) + " " + _prc_inc_DamageTypeString(nSubType); - - //Interpret cost table information; interpret subtype as racial group - case ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP: - case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP: - return sTypeName + ": " + _prc_inc_AlignmentGroupString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - - //Special handling - case ITEM_PROPERTY_ABILITY_BONUS: - case ITEM_PROPERTY_DECREASED_ABILITY_SCORE: - return sTypeName + ": " + _prc_inc_AbilityTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - case ITEM_PROPERTY_BONUS_FEAT: - return sTypeName + ": " + _prc_inc_BonusFeatTypeString(nSubType); - case ITEM_PROPERTY_CAST_SPELL: - return sTypeName + ": " + _prc_inc_SpellTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - case ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP: - return sTypeName + ": " + _prc_inc_AlignmentGroupString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue) + " " + _prc_inc_DamageTypeString(nParam1Value); - case ITEM_PROPERTY_DAMAGE_REDUCTION: - return sTypeName + ": " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue) + " / " + IntToString(StringToInt(sSubType)+1); - case ITEM_PROPERTY_EXTRA_MELEE_DAMAGE_TYPE: - case ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE: - return sTypeName + ": " + _prc_inc_DamageTypeString(nSubType); - case ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS: - return sTypeName + ": " + _prc_inc_ImmunityTypeString(nSubType); - case ITEM_PROPERTY_IMMUNITY_SPELL_SCHOOL: - return sTypeName + ": " + _prc_inc_SpellSchoolTypeString(nSubType); - case ITEM_PROPERTY_ON_HIT_PROPERTIES: - return sTypeName + ": " + _prc_inc_OnHitTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - case ITEM_PROPERTY_ONHITCASTSPELL: - return sTypeName + ": " + _prc_inc_OnHitSpellTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - case ITEM_PROPERTY_ON_MONSTER_HIT: - return sTypeName + ": " + _prc_inc_OnMonsterHitTypeString(nSubType) + " " + IntToString(nCostTableValue+1); - case ITEM_PROPERTY_SKILL_BONUS: - return sTypeName + ": " + _prc_inc_SkillTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - case ITEM_PROPERTY_SPECIAL_WALK: - return sTypeName + ": " + _prc_inc_SpecialWalkTypeString(nSubType); - case ITEM_PROPERTY_REGENERATION_VAMPIRIC: - return sTypeName + ": " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - case ITEM_PROPERTY_VISUALEFFECT: - return sTypeName + ": " + _prc_inc_VisualEffectString(nSubType); - - case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC: - case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC: - return sTypeName + ": " + _prc_inc_SavingThrowTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - - case ITEM_PROPERTY_DECREASED_SAVING_THROWS: - case ITEM_PROPERTY_SAVING_THROW_BONUS: - return sTypeName + ": " + _prc_inc_SavingThrowElementTypeString(nSubType) + " " + _prc_inc_CostTableEntryString(nCostTable, nCostTableValue); - } - return sTypeName + " (" + sResult + ")"; -} - -string _prc_inc_EffectString(effect eEffect) -{ - int nType = GetEffectType(eEffect); - int nSubType = GetEffectSubType(eEffect); - int nDurationType = GetEffectDurationType(eEffect); - int nSpellId = GetEffectSpellId(eEffect); - string sType = IntToString(nType); - string sSubType = IntToString(nSubType); - string sDurationType = IntToString(nDurationType); - string sSpellId = IntToString(nSpellId); - - //Decode type if possible - //TODO: look up in 2da (which one?) instead of having a big switch statement - switch (nType) - { - case EFFECT_TYPE_INVALIDEFFECT : sType = "EFFECT_TYPE_INVALIDEFFECT"; break; - case EFFECT_TYPE_DAMAGE_RESISTANCE : sType = "EFFECT_TYPE_DAMAGE_RESISTANCE"; break; - //case EFFECT_TYPE_ABILITY_BONUS : sType = "EFFECT_TYPE_ABILITY_BONUS"; break; - case EFFECT_TYPE_REGENERATE : sType = "EFFECT_TYPE_REGENERATE"; break; - //case EFFECT_TYPE_SAVING_THROW_BONUS : sType = "EFFECT_TYPE_SAVING_THROW_BONUS"; break; - //case EFFECT_TYPE_MODIFY_AC : sType = "EFFECT_TYPE_MODIFY_AC"; break; - //case EFFECT_TYPE_ATTACK_BONUS : sType = "EFFECT_TYPE_ATTACK_BONUS"; break; - case EFFECT_TYPE_DAMAGE_REDUCTION : sType = "EFFECT_TYPE_DAMAGE_REDUCTION"; break; - //case EFFECT_TYPE_DAMAGE_BONUS : sType = "EFFECT_TYPE_DAMAGE_BONUS"; break; - case EFFECT_TYPE_TEMPORARY_HITPOINTS : sType = "EFFECT_TYPE_TEMPORARY_HITPOINTS"; break; - //case EFFECT_TYPE_DAMAGE_IMMUNITY : sType = "EFFECT_TYPE_DAMAGE_IMMUNITY"; break; - case EFFECT_TYPE_ENTANGLE : sType = "EFFECT_TYPE_ENTANGLE"; break; - case EFFECT_TYPE_INVULNERABLE : sType = "EFFECT_TYPE_INVULNERABLE"; break; - case EFFECT_TYPE_DEAF : sType = "EFFECT_TYPE_DEAF"; break; - case EFFECT_TYPE_RESURRECTION : sType = "EFFECT_TYPE_RESURRECTION"; break; - case EFFECT_TYPE_IMMUNITY : sType = "EFFECT_TYPE_IMMUNITY"; break; - //case EFFECT_TYPE_BLIND : sType = "EFFECT_TYPE_BLIND"; break; - case EFFECT_TYPE_ENEMY_ATTACK_BONUS : sType = "EFFECT_TYPE_ENEMY_ATTACK_BONUS"; break; - case EFFECT_TYPE_ARCANE_SPELL_FAILURE : sType = "EFFECT_TYPE_ARCANE_SPELL_FAILURE"; break; - //case EFFECT_TYPE_MOVEMENT_SPEED : sType = "EFFECT_TYPE_MOVEMENT_SPEED"; break; - case EFFECT_TYPE_AREA_OF_EFFECT : sType = "EFFECT_TYPE_AREA_OF_EFFECT"; break; - case EFFECT_TYPE_BEAM : sType = "EFFECT_TYPE_BEAM"; break; - //case EFFECT_TYPE_SPELL_RESISTANCE : sType = "EFFECT_TYPE_SPELL_RESISTANCE"; break; - case EFFECT_TYPE_CHARMED : sType = "EFFECT_TYPE_CHARMED"; break; - case EFFECT_TYPE_CONFUSED : sType = "EFFECT_TYPE_CONFUSED"; break; - case EFFECT_TYPE_FRIGHTENED : sType = "EFFECT_TYPE_FRIGHTENED"; break; - case EFFECT_TYPE_DOMINATED : sType = "EFFECT_TYPE_DOMINATED"; break; - case EFFECT_TYPE_PARALYZE : sType = "EFFECT_TYPE_PARALYZE"; break; - case EFFECT_TYPE_DAZED : sType = "EFFECT_TYPE_DAZED"; break; - case EFFECT_TYPE_STUNNED : sType = "EFFECT_TYPE_STUNNED"; break; - case EFFECT_TYPE_SLEEP : sType = "EFFECT_TYPE_SLEEP"; break; - case EFFECT_TYPE_POISON : sType = "EFFECT_TYPE_POISON"; break; - case EFFECT_TYPE_DISEASE : sType = "EFFECT_TYPE_DISEASE"; break; - case EFFECT_TYPE_CURSE : sType = "EFFECT_TYPE_CURSE"; break; - case EFFECT_TYPE_SILENCE : sType = "EFFECT_TYPE_SILENCE"; break; - case EFFECT_TYPE_TURNED : sType = "EFFECT_TYPE_TURNED"; break; - case EFFECT_TYPE_HASTE : sType = "EFFECT_TYPE_HASTE"; break; - case EFFECT_TYPE_SLOW : sType = "EFFECT_TYPE_SLOW"; break; - case EFFECT_TYPE_ABILITY_INCREASE : sType = "EFFECT_TYPE_ABILITY_INCREASE"; break; - case EFFECT_TYPE_ABILITY_DECREASE : sType = "EFFECT_TYPE_ABILITY_DECREASE"; break; - case EFFECT_TYPE_ATTACK_INCREASE : sType = "EFFECT_TYPE_ATTACK_INCREASE"; break; - case EFFECT_TYPE_ATTACK_DECREASE : sType = "EFFECT_TYPE_ATTACK_DECREASE"; break; - case EFFECT_TYPE_DAMAGE_INCREASE : sType = "EFFECT_TYPE_DAMAGE_INCREASE"; break; - case EFFECT_TYPE_DAMAGE_DECREASE : sType = "EFFECT_TYPE_DAMAGE_DECREASE"; break; - case EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE : sType = "EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE"; break; - case EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE : sType = "EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE"; break; - case EFFECT_TYPE_AC_INCREASE : sType = "EFFECT_TYPE_AC_INCREASE"; break; - case EFFECT_TYPE_AC_DECREASE : sType = "EFFECT_TYPE_AC_DECREASE"; break; - case EFFECT_TYPE_MOVEMENT_SPEED_INCREASE : sType = "EFFECT_TYPE_MOVEMENT_SPEED_INCREASE"; break; - case EFFECT_TYPE_MOVEMENT_SPEED_DECREASE : sType = "EFFECT_TYPE_MOVEMENT_SPEED_DECREASE"; break; - case EFFECT_TYPE_SAVING_THROW_INCREASE : sType = "EFFECT_TYPE_SAVING_THROW_INCREASE"; break; - case EFFECT_TYPE_SAVING_THROW_DECREASE : sType = "EFFECT_TYPE_SAVING_THROW_DECREASE"; break; - case EFFECT_TYPE_SPELL_RESISTANCE_INCREASE : sType = "EFFECT_TYPE_SPELL_RESISTANCE_INCREASE"; break; - case EFFECT_TYPE_SPELL_RESISTANCE_DECREASE : sType = "EFFECT_TYPE_SPELL_RESISTANCE_DECREASE"; break; - case EFFECT_TYPE_SKILL_INCREASE : sType = "EFFECT_TYPE_SKILL_INCREASE"; break; - case EFFECT_TYPE_SKILL_DECREASE : sType = "EFFECT_TYPE_SKILL_DECREASE"; break; - case EFFECT_TYPE_INVISIBILITY : sType = "EFFECT_TYPE_INVISIBILITY"; break; - case EFFECT_TYPE_IMPROVEDINVISIBILITY : sType = "EFFECT_TYPE_IMPROVEDINVISIBILITY"; break; - case EFFECT_TYPE_DARKNESS : sType = "EFFECT_TYPE_DARKNESS"; break; - case EFFECT_TYPE_DISPELMAGICALL : sType = "EFFECT_TYPE_DISPELMAGICALL"; break; - case EFFECT_TYPE_ELEMENTALSHIELD : sType = "EFFECT_TYPE_ELEMENTALSHIELD"; break; - case EFFECT_TYPE_NEGATIVELEVEL : sType = "EFFECT_TYPE_NEGATIVELEVEL"; break; - case EFFECT_TYPE_POLYMORPH : sType = "EFFECT_TYPE_POLYMORPH"; break; - case EFFECT_TYPE_SANCTUARY : sType = "EFFECT_TYPE_SANCTUARY"; break; - case EFFECT_TYPE_TRUESEEING : sType = "EFFECT_TYPE_TRUESEEING"; break; - case EFFECT_TYPE_SEEINVISIBLE : sType = "EFFECT_TYPE_SEEINVISIBLE"; break; - case EFFECT_TYPE_TIMESTOP : sType = "EFFECT_TYPE_TIMESTOP"; break; - case EFFECT_TYPE_BLINDNESS : sType = "EFFECT_TYPE_BLINDNESS"; break; - case EFFECT_TYPE_SPELLLEVELABSORPTION : sType = "EFFECT_TYPE_SPELLLEVELABSORPTION"; break; - case EFFECT_TYPE_DISPELMAGICBEST : sType = "EFFECT_TYPE_DISPELMAGICBEST"; break; - case EFFECT_TYPE_ULTRAVISION : sType = "EFFECT_TYPE_ULTRAVISION"; break; - case EFFECT_TYPE_MISS_CHANCE : sType = "EFFECT_TYPE_MISS_CHANCE"; break; - case EFFECT_TYPE_CONCEALMENT : sType = "EFFECT_TYPE_CONCEALMENT"; break; - case EFFECT_TYPE_SPELL_IMMUNITY : sType = "EFFECT_TYPE_SPELL_IMMUNITY"; break; - case EFFECT_TYPE_VISUALEFFECT : sType = "EFFECT_TYPE_VISUALEFFECT"; break; - case EFFECT_TYPE_DISAPPEARAPPEAR : sType = "EFFECT_TYPE_DISAPPEARAPPEAR"; break; - case EFFECT_TYPE_SWARM : sType = "EFFECT_TYPE_SWARM"; break; - case EFFECT_TYPE_TURN_RESISTANCE_DECREASE : sType = "EFFECT_TYPE_TURN_RESISTANCE_DECREASE"; break; - case EFFECT_TYPE_TURN_RESISTANCE_INCREASE : sType = "EFFECT_TYPE_TURN_RESISTANCE_INCREASE"; break; - case EFFECT_TYPE_PETRIFY : sType = "EFFECT_TYPE_PETRIFY"; break; - case EFFECT_TYPE_CUTSCENE_PARALYZE : sType = "EFFECT_TYPE_CUTSCENE_PARALYZE"; break; - case EFFECT_TYPE_ETHEREAL : sType = "EFFECT_TYPE_ETHEREAL"; break; - case EFFECT_TYPE_SPELL_FAILURE : sType = "EFFECT_TYPE_SPELL_FAILURE"; break; - case EFFECT_TYPE_CUTSCENEGHOST : sType = "EFFECT_TYPE_CUTSCENEGHOST"; break; - case EFFECT_TYPE_CUTSCENEIMMOBILIZE : sType = "EFFECT_TYPE_CUTSCENEIMMOBILIZE"; break; - } - - //Decode subtype if possible - //TODO: look up in 2da (which one?) instead of having a switch statement - switch (nSubType) - { - case SUBTYPE_MAGICAL : sSubType = "SUBTYPE_MAGICAL"; break; - case SUBTYPE_SUPERNATURAL : sSubType = "SUBTYPE_SUPERNATURAL"; break; - case SUBTYPE_EXTRAORDINARY : sSubType = "SUBTYPE_EXTRAORDINARY"; break; - } - - //Decode duration type if possible - //TODO: look up in 2da (which one?) instead of having a switch statement - switch (nDurationType) - { - case DURATION_TYPE_INSTANT : sDurationType = "DURATION_TYPE_INSTANT"; break; - case DURATION_TYPE_TEMPORARY : sDurationType = "DURATION_TYPE_TEMPORARY"; break; - case DURATION_TYPE_PERMANENT : sDurationType = "DURATION_TYPE_PERMANENT"; break; - } - - string sResult = - "EFFECT Type: " + sType + "; " - + "SubType: " + sSubType + "; " - + "DurationType: " + sDurationType + "; " - + "SpellId: " + sSpellId; - - return sResult; -} - -void _prc_inc_PrintShapeInfo(object oPC, string sMessage) -{ - if(!GetLocalInt(oPC, "PRC_SuppressChatPrint")) - SendMessageToPC(oPC, sMessage); //Send to chat window in game - if(GetLocalInt(oPC, "PRC_EnableLogPrint")) - PrintString(sMessage); //Write to log file for reference -} - -void _prc_inc_PrintClassInfo(string sPrefix, object oPC, object oTemplate, int nClassType) -{ - if (nClassType != CLASS_TYPE_INVALID) - { - int nLevel = GetLevelByClass(nClassType, oTemplate); - string sClassName = _prc_inc_ClassTypeString(nClassType); - _prc_inc_PrintShapeInfo(oPC, sPrefix + sClassName + " (" + IntToString(nLevel) + ")"); - } -} - -void _prc_inc_PrintItemProperty(string sPrefix, object oPC, itemproperty iProp, int bIncludeTemp = FALSE) -{ - int nDurationType = GetItemPropertyDurationType(iProp); - if(nDurationType == DURATION_TYPE_PERMANENT || (bIncludeTemp && nDurationType == DURATION_TYPE_TEMPORARY)) - { - string sPropString = _prc_inc_ItemPropertyString(iProp); - if(sPropString != "") - { - if (nDurationType == DURATION_TYPE_TEMPORARY) - sPropString = GetStringByStrRef(57473+0x01000000) + sPropString; //"TEMPORARY: " - _prc_inc_PrintShapeInfo(oPC, sPrefix + sPropString); - } - } -} - -void _prc_inc_PrintAllItemProperties(string sPrefix, object oPC, object oItem, int bIncludeTemp = FALSE) -{ - itemproperty iProp = GetFirstItemProperty(oItem); - while(GetIsItemPropertyValid(iProp)) - { - _prc_inc_PrintItemProperty(sPrefix, oPC, iProp, bIncludeTemp); - iProp = GetNextItemProperty(oItem); - } -} - -void _prc_inc_PrintEffect(string sPrefix, object oPC, effect eEffect) -{ - if (GetEffectType(eEffect) == EFFECT_TYPE_INVALIDEFFECT) - { - //An effect with type EFFECT_TYPE_INVALID is added for each item property - //They are also added for a couple of other things (Knockdown, summons, etc.) - //Just skip these - } - else - { - string sEffectString = _prc_inc_EffectString(eEffect); - if(sEffectString != "") - _prc_inc_PrintShapeInfo(oPC, sPrefix + sEffectString); - } -} - -void _prc_inc_PrintAllEffects(string sPrefix, object oPC, object oItem) -{ - effect eEffect = GetFirstEffect(oItem); - while(GetIsEffectValid(eEffect)) - { - _prc_inc_PrintEffect(sPrefix, oPC, eEffect); - eEffect = GetNextEffect(oItem); - } -} - -//NOTE: THIS FUNCTION HAS A LOT OF CODE IN COMMON WITH _prc_inc_shifting_CreateShifterActiveAbilitiesItem -//TODO: PUT SOME OF IT IN A SHARED FUNCTION THAT THEY BOTH CALL -void _prc_inc_shifting_PrintShifterActiveAbilities(object oPC, object oTemplate) -{ - string sPrefix = GetStringByStrRef(57437+0x01000000); //"Epic Wildshape Spell-Like Abilities:" - _prc_inc_PrintShapeInfo(oPC, "=== " + sPrefix); - - int bPrinted = FALSE; - - object oTemplateHide = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTemplate); - itemproperty iProp = GetFirstItemProperty(oTemplateHide); - while(GetIsItemPropertyValid(iProp)) - { - if(GetItemPropertyDurationType(iProp) == DURATION_TYPE_PERMANENT && GetItemPropertyType(iProp) == ITEM_PROPERTY_CAST_SPELL) - { - _prc_inc_PrintItemProperty("=== ", oPC, iProp); - bPrinted = TRUE; - } - iProp = GetNextItemProperty(oTemplateHide); - } - - // Loop over shifter_abilitie.2da - string sNumUses; - int nSpell, nNumUses, nProps; - int i = 0; - while(nSpell = StringToInt(Get2DACache("shifter_abilitie", "Spell", i))) - { - // See if the template has this spell - if(GetHasSpell(nSpell, oTemplate)) - { - // Determine the number of uses from the 2da - sNumUses = Get2DACache("shifter_abilitie", "IPCSpellNumUses", i); - if(sNumUses == "1_USE_PER_DAY") - nNumUses = IP_CONST_CASTSPELL_NUMUSES_1_USE_PER_DAY; - else if(sNumUses == "2_USES_PER_DAY") - nNumUses = IP_CONST_CASTSPELL_NUMUSES_2_USES_PER_DAY; - else if(sNumUses == "3_USES_PER_DAY") - nNumUses = IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY; - else if(sNumUses == "4_USES_PER_DAY") - nNumUses = IP_CONST_CASTSPELL_NUMUSES_4_USES_PER_DAY; - else if(sNumUses == "5_USES_PER_DAY") - nNumUses = IP_CONST_CASTSPELL_NUMUSES_5_USES_PER_DAY; - else if(sNumUses == "UNLIMITED_USE") - nNumUses = IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE; - else{ - if(DEBUG) DoDebug("prc_inc_shifting: _prc_inc_shifting_PrintShifterActiveAbilities(): Unknown IPCSpellNumUses in shifter_abilitie.2da line " + IntToString(i) + ": " + sNumUses); - nNumUses = -1; - } - - // Create the itemproperty and print it - iProp = ItemPropertyCastSpell(StringToInt(Get2DACache("shifter_abilitie", "IPSpell", i)), nNumUses); - _prc_inc_PrintItemProperty("=== ", oPC, iProp); - bPrinted = TRUE; - //TODO: DESTROY iProp? - - // Increment property counter - nProps += 1; - } - - // Increment loop counter - i += 1; - } - - if(!bPrinted) - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57481+0x01000000)); //"None" -} - -void _prc_inc_shifting_PrintFeats(object oPC, object oTemplate, int nStartIndex, int nLimitIndex) -{ - //Loop over shifter_feats.2da - string sFeat; - int i = nStartIndex; - while((i < nLimitIndex) && (sFeat = Get2DACache("shifter_feats", "Feat", i)) != "") - { - if (_prc_inc_GetHasFeat(oTemplate, StringToInt(sFeat))) - { - string sFeatName = GetStringByStrRef(StringToInt(Get2DACache("feat", "Feat", StringToInt(sFeat)))); - _prc_inc_PrintShapeInfo(oPC, "=== " + sFeatName); - } - i += 1; - } -} - -void _prc_inc_PrintNaturalAC(object oPC, object oTemplate) -{ - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57435+0x01000000) + " " + IntToString(_prc_inc_CreatureNaturalAC(oTemplate))); //Natural AC of form -} - -//TODO: TLK Entries -void _prc_inc_PrintDebugItem(object oPC, string oItemType, object oItem) -{ - if (GetIsObjectValid(oItem)) - { - _prc_inc_PrintShapeInfo(oPC, "===================================="); - _prc_inc_PrintShapeInfo(oPC, "====== " + oItemType); - _prc_inc_PrintShapeInfo(oPC, "====== NAME: " + GetName(oItem)); - _prc_inc_PrintShapeInfo(oPC, "====== RESREF: " + GetResRef(oItem)); - _prc_inc_PrintShapeInfo(oPC, "====== ITEM PROPERTIES ======"); - _prc_inc_PrintAllItemProperties("=== ", oPC, oItem, TRUE); - _prc_inc_PrintShapeInfo(oPC, "====== EFFECTS ======"); - _prc_inc_PrintAllEffects("=== ", oPC, oItem); - _prc_inc_PrintShapeInfo(oPC, "====== OTHER ======"); - if (GetObjectType(oItem) == OBJECT_TYPE_CREATURE) - { - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(1, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(2, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(3, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(4, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(5, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(6, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(7, oItem)); - _prc_inc_PrintClassInfo("=== ", oPC, oItem, GetClassByPosition(8, oItem)); - - _prc_inc_PrintShapeInfo(oPC, "------"); - - _prc_inc_PrintShapeInfo(oPC, "====== Main hand weapon: " + (GetIsWeaponEffective(oItem, FALSE) ? "Effective" : "Ineffective")); - _prc_inc_PrintShapeInfo(oPC, "====== Off hand weapon: " + (GetIsWeaponEffective(oItem, TRUE) ? "Effective" : "Ineffective")); - _prc_inc_PrintShapeInfo(oPC, "====== Immortal: " + (GetImmortal(oItem) ? "Yes" : "No")); - _prc_inc_PrintShapeInfo(oPC, "------"); - - _prc_inc_PrintShapeInfo(oPC, "====== Level: " + IntToString(GetHitDice(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== CR: " + FloatToString(GetChallengeRating(oItem), 4, 1)); - _prc_inc_PrintShapeInfo(oPC, "====== Caster Level: " + IntToString(GetCasterLevel(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== XP: " + IntToString(GetXP(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== Alignment: " + IntToString(GetLawChaosValue(oItem)) + " / " + IntToString(GetGoodEvilValue(oItem))); - //TODO: - // int GetAlignmentLawChaos(object oCreature); - // int GetAlignmentGoodEvil(object oCreature); - _prc_inc_PrintShapeInfo(oPC, "------"); - - _prc_inc_PrintShapeInfo(oPC, "====== BAB: " + IntToString(GetBaseAttackBonus(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== HP: " + IntToString(GetCurrentHitPoints(oItem)) + " / " + IntToString(GetMaxHitPoints(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== AC: " + IntToString(GetAC(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== SR: " + IntToString(GetSpellResistance(oItem))); - _prc_inc_PrintShapeInfo(oPC, "------"); - - //TODO: look up names in 2da/TLK? - _prc_inc_PrintShapeInfo(oPC, "====== STR: " + IntToString(GetAbilityScore(oItem, ABILITY_STRENGTH)) + " (" + IntToString(GetAbilityModifier(ABILITY_STRENGTH, oItem)) + ")"); - _prc_inc_PrintShapeInfo(oPC, "====== DEX: " + IntToString(GetAbilityScore(oItem, ABILITY_DEXTERITY)) + " (" + IntToString(GetAbilityModifier(ABILITY_DEXTERITY, oItem)) + ")"); - _prc_inc_PrintShapeInfo(oPC, "====== CON: " + IntToString(GetAbilityScore(oItem, ABILITY_CONSTITUTION)) + " (" + IntToString(GetAbilityModifier(ABILITY_CONSTITUTION, oItem)) + ")"); - _prc_inc_PrintShapeInfo(oPC, "====== INT: " + IntToString(GetAbilityScore(oItem, ABILITY_INTELLIGENCE)) + " (" + IntToString(GetAbilityModifier(ABILITY_INTELLIGENCE, oItem)) + ")"); - _prc_inc_PrintShapeInfo(oPC, "====== WIS: " + IntToString(GetAbilityScore(oItem, ABILITY_WISDOM)) + " (" + IntToString(GetAbilityModifier(ABILITY_WISDOM, oItem)) + ")"); - _prc_inc_PrintShapeInfo(oPC, "====== CHA: " + IntToString(GetAbilityScore(oItem, ABILITY_CHARISMA)) + " (" + IntToString(GetAbilityModifier(ABILITY_CHARISMA, oItem)) + ")"); - _prc_inc_PrintShapeInfo(oPC, "------"); - - //TODO: look up names in 2da/TLK? - _prc_inc_PrintShapeInfo(oPC, "====== Fortitude: " + IntToString(GetFortitudeSavingThrow(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== Will: " + IntToString(GetWillSavingThrow(oItem))); - _prc_inc_PrintShapeInfo(oPC, "====== Reflex: " + IntToString(GetReflexSavingThrow(oItem))); - _prc_inc_PrintShapeInfo(oPC, "------"); - - int i = 0; - string sSkillName; - while((sSkillName = Get2DACache("skills", "Name", i)) != "") - { - sSkillName = GetStringByStrRef(StringToInt(sSkillName)); - _prc_inc_PrintShapeInfo(oPC, "====== " + sSkillName + ": " + IntToString(GetSkillRank(i, oItem))); - i += 1; - } - _prc_inc_PrintShapeInfo(oPC, "------"); - - _prc_inc_PrintShapeInfo(oPC, "====== Gender: " + IntToString(GetGender(oItem))); //TODO: look up values in 2da? - _prc_inc_PrintShapeInfo(oPC, "====== Size: " + IntToString(GetCreatureSize(oItem))); //TODO: look up values in 2da? - _prc_inc_PrintShapeInfo(oPC, "====== Race: " + IntToString(GetRacialType(oItem))); //TODO: look up values in 2da? - _prc_inc_PrintShapeInfo(oPC, "====== Speed: " + IntToString(GetMovementRate(oItem))); //TODO: look up values in 2da? - _prc_inc_PrintShapeInfo(oPC, "====== Dead: " + (GetIsDead(oItem) ? "Yes" : "No")); - _prc_inc_PrintShapeInfo(oPC, "====== Tag: " + GetTag(oItem)); - _prc_inc_PrintShapeInfo(oPC, "====== Object Type: " + IntToString(GetObjectType(oItem))); //TODO: look up values in 2da? - - //TODO?: - //int GetGold(object oTarget=OBJECT_SELF); - //location GetLocalLocation(object oObject, string sVarName); - // vector GetPositionFromLocation(location lLocation); - // object GetAreaFromLocation(location lLocation); - // float GetFacingFromLocation(location lLocation); - //int GetCommandable(object oTarget=OBJECT_SELF); - //int GetIsListening(object oObject); - //int GetReputation(object oSource, object oTarget); - //location GetLocation(object oObject); - //int GetIsPC(object oCreature); - // int GetIsEnemy(object oTarget, object oSource=OBJECT_SELF); - // int GetIsFriend(object oTarget, object oSource=OBJECT_SELF); - // int GetIsNeutral(object oTarget, object oSource=OBJECT_SELF); - // int GetStealthMode(object oCreature); - // int GetDetectMode(object oCreature); - // int GetDefensiveCastingMode(object oCreature); - // int GetAppearanceType(object oCreature); - // int GetWeight(object oTarget=OBJECT_SELF); //Gets the weight of an item, or the total carried weight of a creature in tenths of pounds (as per the baseitems.2da). - // int GetAILevel(object oTarget=OBJECT_SELF); - // int GetActionMode(object oCreature, int nMode); - // int GetArcaneSpellFailure(object oCreature); - // int GetLootable( object oCreature ); - // int GetIsCreatureDisarmable(object oCreature); - // string GetDeity(object oCreature); - // string GetSubRace(object oTarget); - // int GetAge(object oCreature); - //int GetPlotFlag(object oTarget=OBJECT_SELF); - } - else - _prc_inc_PrintShapeInfo(oPC, "====== AC: " + IntToString(GetItemACValue(oItem))); - _prc_inc_PrintShapeInfo(oPC, "===================================="); - } -} - -//TODO: TLK Entries -void _prc_inc_ShapePrintDebug(object oPC, object oTarget, int bForceLogPrint) -{ - int nSaveValue = GetLocalInt(oPC, "PRC_EnableLogPrint"); - if (bForceLogPrint) - SetLocalInt(oPC, "PRC_EnableLogPrint", TRUE); - - DelayCommand(0.0, _prc_inc_PrintDebugItem(oPC, "CREATURE", oTarget)); - DelayCommand(0.0, _prc_inc_PrintDebugItem(oPC, "CREATURE SKIN", GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTarget))); - DelayCommand(0.0, _prc_inc_PrintDebugItem(oPC, "RIGHT CREATURE WEAPON", GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oTarget))); - DelayCommand(0.0, _prc_inc_PrintDebugItem(oPC, "LEFT CREATURE WEAPON", GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oTarget))); - DelayCommand(0.0, _prc_inc_PrintDebugItem(oPC, "SPECIAL CREATURE WEAPON", GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oTarget))); - - int nSlot; - for(nSlot = 0; nSlot < NUM_INVENTORY_SLOTS; nSlot++) - { - switch (nSlot) - { - case INVENTORY_SLOT_CARMOUR: - case INVENTORY_SLOT_CWEAPON_R: - case INVENTORY_SLOT_CWEAPON_L: - case INVENTORY_SLOT_CWEAPON_B: - break; - - default: - DelayCommand(0.0, _prc_inc_PrintDebugItem(oPC, "INVENTORY ITEM " + IntToString(nSlot) + ": ", GetItemInSlot(nSlot, oTarget))); - } - } - - if (bForceLogPrint) - DelayCommand(0.1, SetLocalInt(oPC, "PRC_EnableLogPrint", nSaveValue)); -} - -//TODO: Add nShifterType parameter so that only applicable information is printed? -void _prc_inc_PrintShape(object oPC, object oTemplate, int bForceLogPrint) -{ - int nSaveValue = GetLocalInt(oPC, "PRC_EnableLogPrint"); - if (bForceLogPrint) - SetLocalInt(oPC, "PRC_EnableLogPrint", TRUE); - - _prc_inc_PrintShapeInfo(oPC, "================================================="); - - //Basic information - - _prc_inc_PrintShapeInfo(oPC, "=== " + GetName(oTemplate)); - _prc_inc_PrintShapeInfo(oPC, "=== " + GetResRef(oTemplate)); - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef((StringToInt(Get2DACache("racialtypes", "Name", MyPRCGetRacialType(oTemplate)))))); - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57420+0x01000000) + IntToString(_prc_inc_shifting_ShifterLevelRequirement(oTemplate))); //"Required Shifter Level: " - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57421+0x01000000) + IntToString(_prc_inc_shifting_CharacterLevelRequirement(oTemplate))); //"Required Character Level: " - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57436+0x01000000) + FloatToString(GetChallengeRating(oTemplate), 4, 1)); //"Challenge Rating: " - - _prc_inc_PrintShapeInfo(oPC, "=========="); - - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(1, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(2, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(3, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(4, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(5, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(6, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(7, oTemplate)); - _prc_inc_PrintClassInfo("=== ", oPC, oTemplate, GetClassByPosition(8, oTemplate)); - - _prc_inc_PrintShapeInfo(oPC, "=========="); - - //Harmlessly invisible? - - if(_prc_inc_shifting_GetIsCreatureHarmless(oTemplate)) - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57424+0x01000000)); //"Harmlessly Invisible" - - //Able to cast spells without Natural Spell? - - if(!_prc_inc_shifting_GetCanFormCast(oTemplate) && !GetHasFeat(FEAT_PRESTIGE_SHIFTER_NATURALSPELL, oTemplate)) - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57477+0x01000000)); //"Cannot cast spells" - else - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57476+0x01000000)); //"Can cast spells" - - //Natural AC - - _prc_inc_PrintNaturalAC(oPC, oTemplate); - - //STR, DEX, CON - - struct _prc_inc_ability_info_struct rInfoStruct = _prc_inc_shifter_GetAbilityInfo(oTemplate, oPC); - - //Extra information related to STR, DEX, CON - - string sExtra, sBonusOrPenalty = GetStringByStrRef(57427+0x01000000); - sExtra = " (" + sBonusOrPenalty + (rInfoStruct.nDeltaSTR>=0?"+":"") + IntToString(rInfoStruct.nDeltaSTR) + ")"; - _prc_inc_PrintShapeInfo(oPC, "=== " + _prc_inc_AbilityTypeString(0) + " " + IntToString(rInfoStruct.nTemplateSTR) + sExtra); - sExtra = " (" + sBonusOrPenalty + (rInfoStruct.nDeltaDEX>=0?"+":"") + IntToString(rInfoStruct.nDeltaDEX) + ")"; - _prc_inc_PrintShapeInfo(oPC, "=== " + _prc_inc_AbilityTypeString(1) + " " + IntToString(rInfoStruct.nTemplateDEX) + sExtra); - sExtra = " (" + sBonusOrPenalty + (rInfoStruct.nDeltaCON>=0?"+":"") + IntToString(rInfoStruct.nDeltaCON) + ")"; - _prc_inc_PrintShapeInfo(oPC, "=== " + _prc_inc_AbilityTypeString(2) + " " + IntToString(rInfoStruct.nTemplateCON) + sExtra); - - _prc_inc_PrintShapeInfo(oPC, "------"); - - int i = 0; - string sSkillName; - string sSTRBasedSkills, sDEXBasedSkills, sCONBasedSkills; - while((sSkillName = Get2DACache("skills", "Name", i)) != "") - { - sSkillName = GetStringByStrRef(StringToInt(sSkillName)); - string sSkillKeyAbility = Get2DACache("skills", "KeyAbility", i); - if (sSkillKeyAbility == "STR") - sSTRBasedSkills += sSkillName + ", "; - else if (sSkillKeyAbility == "DEX") - sDEXBasedSkills += sSkillName + ", "; - else if (sSkillKeyAbility == "CON") - sCONBasedSkills += sSkillName + ", "; - i += 1; - } - if (GetStringLength(sSTRBasedSkills)) - sSTRBasedSkills = GetStringLeft(sSTRBasedSkills, GetStringLength(sSTRBasedSkills) - 2); //Remove the final ", " - if (GetStringLength(sDEXBasedSkills)) - sDEXBasedSkills = GetStringLeft(sDEXBasedSkills, GetStringLength(sDEXBasedSkills) - 2); //Remove the final ", " - if (GetStringLength(sCONBasedSkills)) - sCONBasedSkills = GetStringLeft(sCONBasedSkills, GetStringLength(sCONBasedSkills) - 2); //Remove the final ", " - - int nSTRBonus = rInfoStruct.nExtraSTR / 2; - if (nSTRBonus > 0) - { - //TODO: cap AB bonus - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60544+0x01000000) + " +" + IntToString(nSTRBonus)); //Attack increase from STR increase - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60546+0x01000000) + " +" + IntToString(nSTRBonus)); //Damage increase from STR increase - _prc_inc_PrintShapeInfo(oPC, "=== " + ReplaceString(GetStringByStrRef(60528+0x01000000), "%(SKILLS)", sSTRBasedSkills) + " +" + IntToString(nSTRBonus)); //Skill bonus from STR increase - } - else if (nSTRBonus < 0) - { - //TODO: cap AB penalty--at what? - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60545+0x01000000) + " " + IntToString(nSTRBonus)); //Attack decrease from STR decrease - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60547+0x01000000) + " " + IntToString(nSTRBonus)); //Damage decrease from STR decrease - _prc_inc_PrintShapeInfo(oPC, "=== " + ReplaceString(GetStringByStrRef(60529+0x01000000), "%(SKILLS)", sSTRBasedSkills) + " " + IntToString(nSTRBonus)); //Skill penalty from STR decrease - } - - int nDEXBonus = rInfoStruct.nExtraDEX / 2; - if (nDEXBonus > 0) - { - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60548+0x01000000) + " +" + IntToString(nDEXBonus)); //AC increase from DEX increase - _prc_inc_PrintShapeInfo(oPC, "=== " + ReplaceString(GetStringByStrRef(60530+0x01000000), "%(SKILLS)", sDEXBasedSkills) + " +" + IntToString(nDEXBonus)); //Skill bonus from DEX increase - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60531+0x01000000) + " +" + IntToString(nDEXBonus)); //Saving throw bonus from DEX increase - } - else if (nDEXBonus < 0) - { - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60549+0x01000000) + " " + IntToString(nDEXBonus)); //AC decrease from DEX increase - _prc_inc_PrintShapeInfo(oPC, "=== " + ReplaceString(GetStringByStrRef(60532+0x01000000), "%(SKILLS)", sDEXBasedSkills) + " " + IntToString(nDEXBonus)); //Skill penalty from DEX decrease - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60533+0x01000000) + " " + IntToString(nDEXBonus)); //Saving throw penalty from DEX decrease - } - - int nCONBonus = rInfoStruct.nExtraCON / 2; - if (nCONBonus > 0) - { - _prc_inc_PrintShapeInfo(oPC, "=== " + ReplaceString(GetStringByStrRef(60534+0x01000000), "%(SKILLS)", sCONBasedSkills) + " +" + IntToString(nCONBonus)); //Skill bonus from CON increase - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60535+0x01000000) + " +" + IntToString(nCONBonus)); //Saving throw bonus from CON increase - int tempHP = rInfoStruct.nExtraCON * GetHitDice(oPC); - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(57431+0x01000000) + " " + IntToString(tempHP)); //Temporary HP from CON increase - } - else if (nCONBonus < 0) - { - _prc_inc_PrintShapeInfo(oPC, "=== " + ReplaceString(GetStringByStrRef(60536+0x01000000), "%(SKILLS)", sCONBasedSkills) + " " + IntToString(nCONBonus)); //Skill penalty from CON decrease - _prc_inc_PrintShapeInfo(oPC, "=== " + GetStringByStrRef(60537+0x01000000) + " " + IntToString(nCONBonus)); //Saving throw penalty from CON decrease - } - - _prc_inc_PrintShapeInfo(oPC, "=========="); - - //Hide and creature weapon properties - - object oTemplateCWpR = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oTemplate); - object oTemplateCWpL = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oTemplate); - object oTemplateCWpB = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oTemplate); - object oTemplateHide = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTemplate); - - if(GetIsObjectValid(oTemplateCWpR)) - { - string sPrefix = GetStringByStrRef(57432+0x01000000); //"Right Creature Weapon:" - _prc_inc_PrintShapeInfo(oPC, "=== " + sPrefix); - _prc_inc_PrintAllItemProperties("=== ", oPC, oTemplateCWpR); - } - - if(GetIsObjectValid(oTemplateCWpL)) - { - string sPrefix = GetStringByStrRef(57433+0x01000000); //"Left Creature Weapon:" - _prc_inc_PrintShapeInfo(oPC, "=== " + sPrefix); - _prc_inc_PrintAllItemProperties("=== ", oPC, oTemplateCWpL); - } - - if(GetIsObjectValid(oTemplateCWpB)) - { - string sPrefix = GetStringByStrRef(57434+0x01000000); //"Special Attack Creature Weapon:" - _prc_inc_PrintShapeInfo(oPC, "=== " + sPrefix); - _prc_inc_PrintAllItemProperties("=== ", oPC, oTemplateCWpB); - } - - if(GetIsObjectValid(oTemplateHide)) - _prc_inc_PrintAllItemProperties("=== ", oPC, oTemplateHide); - - //Spell-like abilities - - _prc_inc_shifting_PrintShifterActiveAbilities(oPC, oTemplate); - - //Feats - - i = 0; - string sFeat; - int CHUNK_SIZE = 25; //50 was too big, so use 25 - - while((sFeat = Get2DACache("shifter_feats", "Feat", i)) != "") - { - DelayCommand(0.0f, _prc_inc_shifting_PrintFeats(oPC, oTemplate, i, i+CHUNK_SIZE)); - i += CHUNK_SIZE; - } - DelayCommand(0.0f, _prc_inc_PrintShapeInfo(oPC, "=================================================")); - - if (bForceLogPrint) - DelayCommand(0.1, SetLocalInt(oPC, "PRC_EnableLogPrint", nSaveValue)); - - if (GetLocalInt(oPC, "prc_shifter_debug")) - DelayCommand(0.2f, _prc_inc_ShapePrintDebug(oPC, oTemplate, bForceLogPrint)); -} diff --git a/trunk/include/psi_inc_core.nss b/trunk/include/psi_inc_core.nss deleted file mode 100644 index ff94e44f..00000000 --- a/trunk/include/psi_inc_core.nss +++ /dev/null @@ -1,1312 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Psionics include: Psionic Core Files -//:: psi_inc_core -//:://///////////////////////////////////////////// -/** @file - Core functions removed from - - psi_inc_psifunc - psi_inc_focus (depreciated) - - as they are required by many of the other psi groups - - @author Ornedan/ElgarL - @date Created - 2005.11.10/23.07.2010 - */ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/10 - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -// Included here to provide the values for the constants below -#include "prc_class_const" - -const int POWER_LIST_PSION = CLASS_TYPE_PSION; -const int POWER_LIST_WILDER = CLASS_TYPE_WILDER; -const int POWER_LIST_PSYWAR = CLASS_TYPE_PSYWAR; -const int POWER_LIST_PSYROG = CLASS_TYPE_PSYCHIC_ROGUE; -const int POWER_LIST_FIST_OF_ZUOKEN = CLASS_TYPE_FIST_OF_ZUOKEN; -const int POWER_LIST_WARMIND = CLASS_TYPE_WARMIND; - -#include "psi_inc_const" - -//:: Test Main -//void main (){} - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Attempts to use psionic focus. If the creature was focused, it - * loses the focus. If it has Epic Psionic Focus feats, it will - * be able to use the focus for a number of times equal to the - * number of those feats it has during the next 0.5s - * - * @param oUser Creature expending it's psionic focus - * @return TRUE if the creature was psionically focus or had - * Epic Psionic Focus uses remaining. FALSE otherwise. - */ -int UsePsionicFocus(object oUser = OBJECT_SELF); - -/** - * Sets psionic focus active and triggers feats dependant - * on it. - * - * Feats currently keyed to activity of psionic focus: - * Psionic Dodge - * Speed of Thought - * - * @param oGainee Creature gaining psionic focus. - */ -void GainPsionicFocus(object oGainee = OBJECT_SELF); - -/** - * Gets the number of psionic focus uses the creature has available - * to it at this moment. If the creature is psionically focused, - * the number equal to GetPsionicFocusUsesPerExpenditure(), otherwise - * it is however many focus uses the creature still has remaining of - * that number. - * - * @param oCreature Creaute whose psionic focus use count to evaluate - * @return The total number of times UsePsionicFocus() will - * return TRUE if called at this moment. - */ -int GetPsionicFocusesAvailable(object oCreature = OBJECT_SELF); - -/** - * Calculates the number of times a creature may use it's psionic focus when expending it. - * Base is 1. - * In addition, 1 more use for each Epic Psionic Focus feat the creature has. - * - * @param oCreature Creaute whose psionic focus use count to evaluate - * @return The total number of times UsePsionicFocus() will return - * TRUE for a single expending of psionic focus. - */ -int GetPsionicFocusUsesPerExpenditure(object oCreature = OBJECT_SELF); - -/** - * Sets the given creature's psionic focus off and deactivates all feats keyed to it. - * - * @param oLoser Creature losing it's psionic focus - */ -void LosePsionicFocus(object oLoser = OBJECT_SELF); - -/** - * Checks whether the given creature is psionically focused. - * - * @param oCreature Creature whose psionic focus's state to examine - * @return TRUE if the creature is psionically focused, FALSE - * otherwise. - */ -int GetIsPsionicallyFocused(object oCreature = OBJECT_SELF); - -/** - * Determines the number of feats that would use psionic focus - * when triggered the given creature has active. - * - * Currently accounts for: - * Talented - * Power Specialization - * Power Penetration - * Psionic Endowment - * Chain Power - * Empower Power - * Extend Power - * Maximize Power - * Split Psionic Ray - * Twin Power - * Widen Power - * Quicken Power - * - * @param oCreature Creature whose feats to examine - * @return How many of the listed feats are active - */ -int GetPsionicFocusUsingFeatsActive(object oCreature = OBJECT_SELF); - -/** - * Calculates the DC of the power being currently manifested. - * Base value is 10 + power level + ability modifier in manifesting stat - * - * WARNING: Return value is not defined when a power is not being manifested. - * - */ -int GetManifesterDC(object oManifester = OBJECT_SELF); - -/** - * Determines the spell school matching a discipline according to the - * standard transparency rules. - * Disciplines which have no matching spell school are matched with - * SPELL_SCHOOL_GENERAL. - * - * @param nDiscipline Discipline to find matching spell school for - * @return SPELL_SCHOOL_* of the match - */ -int DisciplineToSpellSchool(int nDiscipline); - -/** - * Determines the discipline matching a spell school according to the - * standard transparency rules. - * Spell schools that have no matching disciplines are matched with - * DISCIPLINE_NONE. - * - * @param nSpellSchool Spell schools to find matching discipline for - * @return DISCIPLINE_* of the match - */ -int SpellSchoolToDiscipline(int nSpellSchool); - -/** - * Determines the discipline of a power, using the School column of spells.2da. - * - * @param nSpellID The spellID of the power to determine the discipline of - * @return DISCIPLINE_* constant. DISCIPLINE_NONE if the power's - * School designation does not match any of the discipline's. - */ -int GetPowerDiscipline(int nSpellID); - -/** - * Determines whether a given power is a power of the Telepahty discipline. - * - * @param nSpellID The spells.2da row of the power. If left to default, - * PRCGetSpellId() is used. - * @return TRUE if the power's discipline is Telepathy, FALSE otherwise - */ -int GetIsTelepathyPower(int nSpellID = -1); - -/** - * Checks whether the PC possesses the feats the given feat has as it's - * prerequisites. Possession of a feat is checked using GetHasFeat(). - * - * - * @param nFeat The feat for which determine the possession of prerequisites - * @param oPC The creature whose feats to check - * @return TRUE if the PC possesses the prerequisite feats AND does not - * already posses nFeat, FALSE otherwise. - */ -int CheckPowerPrereqs(int nFeat, object oPC); - -/** - * Determines the manifester's level in regards to manifester checks to overcome - * spell resistance. - * - * WARNING: Return value is not defined when a power is not being manifested. - * - * @param oManifester A creature manifesting a power at the moment - * @return The creature's manifester level, adjusted to account for - * modifiers that affect spell resistance checks. - */ -int GetPsiPenetration(object oManifester = OBJECT_SELF); - -/** - * Determines whether a given creature possesses the Psionic subtype. - * Ways of possessing the subtype: - * - Being of a naturally psionic race - * - Having class levels in a psionic class - * - Possessing the Wild Talent feat - * - * @param oCreature Creature to test - * @return TRUE if the creature is psionic, FALSE otherwise. - */ -int GetIsPsionicCharacter(object oCreature); - -/** - * Creates the creature weapon for powers like Bite of the Wolf and Claws of the - * Beast. If a creature weapon of the correct type is already present, it is - * used instead of a new one. - * - * Preserving existing weapons may cause problems, if so, make the function instead delete the old object - Ornedan - * - * @param oCreature Creatue whose creature weapons to mess with. - * @param sResRef Resref of the creature weapon. Assumed to be one of the - * PRC creature weapons, so this considered to is also be - * the tag. - * @param nIventorySlot Inventory slot where the creature weapon is to be equipped. - * @param fDuration If a new weapon is created, it will be destroyed after - * this duration. - * - * @return The newly created creature weapon. Or an existing weapon, - * if there was one. - */ -object GetPsionicCreatureWeapon(object oCreature, string sResRef, int nInventorySlot, float fDuration); - -/** - * Applies modifications to a power's damage that depend on some property - * of the target. - * Currently accounts for: - * - Mental Resistance - * - Greater Power Specialization - * - Intellect Fortress - * - * @param oTarget A creature being dealt damage by a power - * @param oManifester The creature manifesting the damaging power - * @param nDamage The amount of damage the creature would be dealt - * - * @param bIsHitPointDamage Is the damage HP damage or something else? - * @param bIsEnergyDamage Is the damage caused by energy or something else? Only relevant if the damage is HP damage. - * - * @return The amount of damage, modified by oTarget's abilities - */ -int GetTargetSpecificChangesToDamage(object oTarget, object oManifester, int nDamage, - int bIsHitPointDamage = TRUE, int bIsEnergyDamage = FALSE); - -/** - * Gets the manifester level adjustment from the Practiced Manifester feats. - * - * @param oManifester The creature to check - * @param iManifestingClass The CLASS_TYPE* that the power was cast by. - * @param iManifestingLevels The manifester level for the power calculated so far - * ie. BEFORE Practiced Manifester. - */ -int PracticedManifesting(object oManifester, int iManifestingClass, int iManifestingLevels); - -/** - * Determines the given creature's manifester level. If a class is specified, - * then returns the manifester level for that class. Otherwise, returns - * the manifester level for the currently active manifestation. - * - * @param oManifester The creature whose manifester level to determine - * @param nSpecificClass The class to determine the creature's manifester - * level in. - * DEFAULT: CLASS_TYPE_INVALID, which means the creature's - * manifester level in regards to an ongoing manifestation - * is determined instead. - * @param nMaxPowerLevel For learning powers. Practiced Manifester is breaking things otherwise. - * @return The manifester level - */ -int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVALID, int nMaxPowerLevel = FALSE); - -/** - * Determines the given creature's highest undmodified manifester level among it's - * manifesting classes. - * - * @param oCreature Creature whose highest manifester level to determine - * @return The highest unmodified manifester level the creature can have - */ -int GetHighestManifesterLevel(object oCreature); - -/** - * Gets the level of the power being currently manifested. - * WARNING: Return value is not defined when a power is not being manifested. - * - * @param oManifester The creature currently manifesting a power - * @return The level of the power being manifested - */ -int GetPowerLevel(object oManifester); - -/** - * Determines a creature's ability score in the manifesting ability of a given - * class. - * - * @param oManifester Creature whose ability score to get - * @param nClass CLASS_TYPE_* constant of a manifesting class - */ -int GetAbilityScoreOfClass(object oManifester, int nClass); - -/** - * Determines from what class's power list the currently being manifested - * power is manifested from. - * - * @param oManifester A creature manifesting a power at this moment - * @return CLASS_TYPE_* constant of the class - */ -int GetManifestingClass(object oManifester = OBJECT_SELF); - -/** - * Determines the manifesting ability of a class. - * - * @param nClass CLASS_TYPE_* constant of the class to determine the manifesting stat of - * @return ABILITY_* of the manifesting stat. ABILITY_CHARISMA for non-manifester - * classes. - */ -int GetAbilityOfClass(int nClass); - -/** - * Determines which of the character's classes is their highest or first psionic - * manifesting class, if any. This is the one which gains manifester level raise - * benefits from prestige classes. - * - * @param oCreature Creature whose classes to test - * @return CLASS_TYPE_* of the first psionic manifesting class, - * CLASS_TYPE_INVALID if the creature does not posses any. - */ -int GetPrimaryPsionicClass(object oCreature = OBJECT_SELF); - -/** - * Calculates how many manifester levels are gained by a given creature from - * it's levels in prestige classes. - * - * @param oCreature Creature to calculate added manifester levels for - * @return The number of manifester levels gained - */ -int GetPsionicPRCLevels(object oCreature); - -/** - * Determines the position of a creature's first psionic manifesting class, if any. - * - * @param oCreature Creature whose classes to test - * @return The position of the first psionic class {1, 2, 3} or 0 if - * the creature possesses no levels in psionic classes. - */ -int GetFirstPsionicClassPosition(object oCreature = OBJECT_SELF); - -/** - * Determines whether a given class is a psionic class or not. A psionic - * class is defined as one that gives base manifesting. - * - * @param nClass CLASS_TYPE_* of the class to test - * @return TRUE if the class is a psionic class, FALSE otherwise - */ -int GetIsPsionicClass(int nClass); - -/** - * Gets the amount of manifester levels the given creature is Wild Surging by. - * - * @param oManifester The creature to test - * @return The number of manifester levels added by Wild Surge. 0 if - * Wild Surge is not active. - */ -int GetWildSurge(object oManifester); - -/** - * Gets the highest power level the creature should know - * - * @param oManifester The creature to test - * @return Power level. - */ -int GetMaxPowerLevel(object oManifester); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "prc_inc_unarmed" - -////////////////////////////////////////////////// -/* Global Structures */ -////////////////////////////////////////////////// - -// These are used in psi_inc_psifunc and psi_inc_augment - -/** - * A structure that contains common data used during power manifestation. - */ -struct manifestation{ - /* Generic stuff */ - /// The creature manifesting the power - object oManifester; - /// Whether the manifestation is successfull or not - int bCanManifest; - /// How much Power Points the manifestation costs - int nPPCost; - /// How many psionic focus uses the manifester would have remaining at a particular point in the manifestation - int nPsiFocUsesRemain; - /// The creature's manifester level in regards to this power - int nManifesterLevel; - /// The power's spell ID - int nSpellID; - - /* Augmentation */ - /// How many times the first augmentation option of the power is used - int nTimesAugOptUsed_1; - /// How many times the second augmentation option of the power is used - int nTimesAugOptUsed_2; - /// How many times the third augmentation option of the power is used - int nTimesAugOptUsed_3; - /// How many times the fourth augmentation option of the power is used - int nTimesAugOptUsed_4; - /// How many times the fifth augmentation option of the power is used - int nTimesAugOptUsed_5; - /// How many times the PP used for augmentation triggered the generic augmentation of the power - int nTimesGenericAugUsed; - - /* Metapsionics */ - /// Whether Chain Power was used with this manifestation - int bChain; - /// Whether Empower Power was used with this manifestation - int bEmpower; - /// Whether Extend Power was used with this manifestation - int bExtend; - /// Whether Maximize Power was used with this manifestation - int bMaximize; - /// Whether Split Psionic Ray was used with this manifestation - int bSplit; - /// Whether Twin Power was used with this manifestation - int bTwin; - /// Whether Widen Power was used with this manifestation - int bWiden; - /// Whether Quicken Power was used with this manifestation - int bQuicken; -}; - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - - - -/* Begin PSI FOCUS */ -////////////////////////////////////////////////////// - -int UsePsionicFocus(object oUser = OBJECT_SELF) -{ - int bToReturn = FALSE; - // This does not expend your psionic focus, but rather the item's - if (GetLocalInt(oUser, "SimpleBow_Focus")) - { - DeleteLocalInt(oUser, "SimpleBow_Focus"); - return TRUE; - } - // Next, check if we have focus on - else if(GetLocalInt(oUser, PSIONIC_FOCUS)) - { - SetLocalInt(oUser, "PsionicFocusUses", GetPsionicFocusUsesPerExpenditure(oUser) - 1); - DelayCommand(0.5f, DeleteLocalInt(oUser, "PsionicFocusUses")); - SendMessageToPCByStrRef(oUser, 16826414); // "You have used your Psionic Focus" - - bToReturn = TRUE; - } - // We don't. Check if there are uses remaining - else if(GetLocalInt(oUser, "PsionicFocusUses")) - { - SetLocalInt(oUser, "PsionicFocusUses", GetLocalInt(oUser, "PsionicFocusUses") - 1); - - bToReturn = TRUE; - } - - // Lose focus if it was used - if(bToReturn) LosePsionicFocus(oUser); - - return bToReturn; -} - -void GainPsionicFocus(object oGainee = OBJECT_SELF) -{ - SetLocalInt(oGainee, PSIONIC_FOCUS, TRUE); - - // Speed Of Thought - if(GetHasFeat(FEAT_SPEED_OF_THOUGHT, oGainee)) - { - // Check for heavy armor before adding the bonus now - if(GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oGainee)) < 6) - AssignCommand(oGainee, ActionCastSpellAtObject(SPELL_FEAT_SPEED_OF_THOUGHT_BONUS, oGainee, METAMAGIC_NONE, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE)); - - // Schedule a script to remove the bonus should they equip heavy armor - AddEventScript(oGainee, EVENT_ONPLAYEREQUIPITEM, "psi_spdfthgt_oeq", TRUE, FALSE); - // Schedule another script to add the bonus back if the unequip the armor - AddEventScript(oGainee, EVENT_ONPLAYERUNEQUIPITEM, "psi_spdfthgt_ueq", TRUE, FALSE); - } - // Psionic Dodge - if(GetHasFeat(FEAT_PSIONIC_DODGE, oGainee)) - SetCompositeBonus(GetPCSkin(oGainee), "PsionicDodge", 1, ITEM_PROPERTY_AC_BONUS); - - //Strength of Two - Kalashtar racial feat - if(GetHasFeat(FEAT_STRENGTH_OF_TWO, oGainee)) - { - SetCompositeBonus(GetPCSkin(oGainee), "StrengthOfTwo", 1, ITEM_PROPERTY_SAVING_THROW_BONUS, SAVING_THROW_WILL); - } - // Danger Sense abilities for Psychic Rogue - if(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oGainee) >= 5) - ExecuteScript("psi_psyrog_dngr", oGainee); - if(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oGainee) >= 7) // Uncanny Dodge - IPSafeAddItemProperty(GetPCSkin(oGainee), PRCItemPropertyBonusFeat(IP_CONST_FEAT_UNCANNY_DODGE1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - if(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oGainee) >= 9) // Improved Uncanny Dodge - IPSafeAddItemProperty(GetPCSkin(oGainee), PRCItemPropertyBonusFeat(IP_CONST_FEAT_UNCANNY_DODGE2), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_1d6, oGainee)) - { - int nPsySneak = 1; - if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_2d6, oGainee)) - nPsySneak += 2; - if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_3d6, oGainee)) - nPsySneak += 3; - - SetLocalInt(oGainee, "PsyRogueSneak",nPsySneak); - DelayCommand(0.1, ExecuteScript("prc_sneak_att", oGainee)); - } -} - -int GetPsionicFocusesAvailable(object oCreature = OBJECT_SELF) -{ - // If the creature has a psionic focus active, return the maximum - if(GetLocalInt(oCreature, PSIONIC_FOCUS)) - return GetPsionicFocusUsesPerExpenditure(oCreature); - // Otherwise, return the amount currently remaining - else - return GetLocalInt(oCreature, "PsionicFocusUses"); -} - -int GetPsionicFocusUsesPerExpenditure(object oCreature = OBJECT_SELF) -{ - int nFocusUses = 1; - int i; - for(i = FEAT_EPIC_PSIONIC_FOCUS_1; i <= FEAT_EPIC_PSIONIC_FOCUS_10; i++) - if(GetHasFeat(i, oCreature)) nFocusUses++; - - return nFocusUses; -} - -void LosePsionicFocus(object oLoser = OBJECT_SELF) -{ - // Only remove focus if it's present - if(GetLocalInt(oLoser, PSIONIC_FOCUS)) - { - SetLocalInt(oLoser, PSIONIC_FOCUS, FALSE); - - // Loss of Speed of Thought effects - PRCRemoveSpellEffects(SPELL_FEAT_SPEED_OF_THOUGHT_BONUS, oLoser, oLoser); - RemoveEventScript(oLoser, EVENT_ONPLAYEREQUIPITEM, "psi_spdfthgt_oeq", TRUE); - RemoveEventScript(oLoser, EVENT_ONPLAYERUNEQUIPITEM, "psi_spdfthgt_ueq", TRUE); - // Loss of Psionic Dodge effects - SetCompositeBonus(GetPCSkin(oLoser), "PsionicDodge", 0, ITEM_PROPERTY_AC_BONUS); - // Loss of Strength of Two effects - SetCompositeBonus(GetPCSkin(oLoser), "StrengthOfTwo", 0, ITEM_PROPERTY_SAVING_THROW_BONUS, SAVING_THROW_WILL); - - if(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oLoser) >= 5) - PRCRemoveSpellEffects(POWER_DANGERSENSE, oLoser, oLoser); - if(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oLoser) >= 7) - RemoveItemProperty(GetPCSkin(oLoser), ItemPropertyBonusFeat(IP_CONST_FEAT_UNCANNY_DODGE1)); - if(GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oLoser) >= 9) - RemoveItemProperty(GetPCSkin(oLoser), ItemPropertyBonusFeat(IP_CONST_FEAT_UNCANNY_DODGE2)); - - // Inform oLoser about the event - FloatingTextStrRefOnCreature(16826415, oLoser, FALSE); // "You have lost your Psionic Focus" - if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_1d6, oLoser)) - { - DeleteLocalInt(oLoser, "PsyRogueSneak"); - DelayCommand(0.1, ExecuteScript("prc_sneak_att", oLoser)); - } - } -} - -int GetIsPsionicallyFocused(object oCreature = OBJECT_SELF) -{ - return GetLocalInt(oCreature, PSIONIC_FOCUS); -} - -int GetPsionicFocusUsingFeatsActive(object oCreature = OBJECT_SELF) -{ - int nFeats; - - if(GetLocalInt(oCreature, "TalentedActive")) nFeats++; - if(GetLocalInt(oCreature, "PowerSpecializationActive")) nFeats++; - if(GetLocalInt(oCreature, "PowerPenetrationActive")) nFeats++; - if(GetLocalInt(oCreature, "PsionicEndowmentActive")) nFeats++; - - if(GetLocalInt(oCreature, METAPSIONIC_CHAIN_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_EMPOWER_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_EXTEND_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_MAXIMIZE_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_SPLIT_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_TWIN_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_WIDEN_VAR)) nFeats++; - if(GetLocalInt(oCreature, METAPSIONIC_QUICKEN_VAR)) nFeats++; - - return nFeats; -} - -////////////////////////////////////////////////////// -/* END PSI FOCUS */ -////////////////////////////////////////////////////// - -int GetManifesterDC(object oManifester = OBJECT_SELF) -{ - int nClass = GetManifestingClass(oManifester); - int nDC = 10; - nDC += GetPowerLevel(oManifester); - nDC += GetAbilityModifier(GetAbilityOfClass(nClass), oManifester); - - // Stuff that applies only to powers, not psi-like abilities goes inside - if(!GetLocalInt(oManifester, PRC_IS_PSILIKE)) - { - if (GetLocalInt(oManifester, "PsionicEndowmentActive") == TRUE && UsePsionicFocus(oManifester)) - { - nDC += GetHasFeat(FEAT_GREATER_PSIONIC_ENDOWMENT, oManifester) ? 4 : 2; - } - } - - // Needed to do some adjustments here. - object oTarget = PRCGetSpellTargetObject(); - int nPower = PRCGetSpellId(); - - // Other DC adjustments - // Soul Manifester - nDC += Soulcaster(oManifester, PRCGetSpellId()); - // Charming Veil meld - if(GetHasSpellEffect(MELD_CHARMING_VEIL, oManifester) && (GetIsOfSubschool(nPower, SUBSCHOOL_CHARM) || GetIsOfSubschool(nPower, SUBSCHOOL_COMPULSION))) nDC += GetEssentiaInvested(oManifester, MELD_CHARMING_VEIL)+1; - // Soul Eater - nDC += (GetLocalInt(oManifester, "PRC_SoulEater_HasDrained") && GetLevelByClass(CLASS_TYPE_SOUL_EATER, oManifester) >= 10) ? 2 : 0; - // Closed Mind - if(GetHasFeat(FEAT_CLOSED_MIND, oTarget)) nDC -= 2; - // Strong Mind - if(GetHasFeat(FEAT_STRONG_MIND, oTarget)) nDC -= 3; - // Fist of Dal Quor - if(GetLevelByClass(CLASS_TYPE_FIST_DAL_QUOR, oTarget) >= 4) nDC -= 2; - - return nDC; -} - -int DisciplineToSpellSchool(int nDiscipline) -{ - int nSpellSchool = SPELL_SCHOOL_GENERAL; - - switch(nDiscipline) - { - case DISCIPLINE_CLAIRSENTIENCE: nSpellSchool = SPELL_SCHOOL_DIVINATION; break; - case DISCIPLINE_METACREATIVITY: nSpellSchool = SPELL_SCHOOL_CONJURATION; break; - case DISCIPLINE_PSYCHOKINESIS: nSpellSchool = SPELL_SCHOOL_EVOCATION; break; - case DISCIPLINE_PSYCHOMETABOLISM: nSpellSchool = SPELL_SCHOOL_TRANSMUTATION; break; - case DISCIPLINE_TELEPATHY: nSpellSchool = SPELL_SCHOOL_ENCHANTMENT; break; - - default: nSpellSchool = SPELL_SCHOOL_GENERAL; break; - } - - return nSpellSchool; -} - -int SpellSchoolToDiscipline(int nSpellSchool) -{ - int nDiscipline = DISCIPLINE_NONE; - - switch(nSpellSchool) - { - case SPELL_SCHOOL_GENERAL: nDiscipline = DISCIPLINE_NONE; break; - case SPELL_SCHOOL_ABJURATION: nDiscipline = DISCIPLINE_NONE; break; - case SPELL_SCHOOL_CONJURATION: nDiscipline = DISCIPLINE_METACREATIVITY; break; - case SPELL_SCHOOL_DIVINATION: nDiscipline = DISCIPLINE_CLAIRSENTIENCE; break; - case SPELL_SCHOOL_ENCHANTMENT: nDiscipline = DISCIPLINE_TELEPATHY; break; - case SPELL_SCHOOL_EVOCATION: nDiscipline = DISCIPLINE_PSYCHOKINESIS; break; - case SPELL_SCHOOL_ILLUSION: nDiscipline = DISCIPLINE_NONE; break; - case SPELL_SCHOOL_NECROMANCY: nDiscipline = DISCIPLINE_NONE; break; - case SPELL_SCHOOL_TRANSMUTATION: nDiscipline = DISCIPLINE_PSYCHOMETABOLISM; break; - - default: nDiscipline = DISCIPLINE_NONE; - } - - return nDiscipline; -} - -int GetPowerDiscipline(int nSpellID) -{ - string sSpellSchool = Get2DACache("spells", "School", nSpellID);//lookup_spell_school(nSpellID); - int nDiscipline; - - if (sSpellSchool == "A") nDiscipline = DISCIPLINE_NONE; - else if (sSpellSchool == "C") nDiscipline = DISCIPLINE_METACREATIVITY; - else if (sSpellSchool == "D") nDiscipline = DISCIPLINE_CLAIRSENTIENCE; - else if (sSpellSchool == "E") nDiscipline = DISCIPLINE_TELEPATHY; - else if (sSpellSchool == "V") nDiscipline = DISCIPLINE_PSYCHOKINESIS; - else if (sSpellSchool == "I") nDiscipline = DISCIPLINE_NONE; - else if (sSpellSchool == "N") nDiscipline = DISCIPLINE_NONE; - else if (sSpellSchool == "T") nDiscipline = DISCIPLINE_PSYCHOMETABOLISM; - else if (sSpellSchool == "G") nDiscipline = DISCIPLINE_PSYCHOPORTATION; - - return nDiscipline; -} - -int GetIsTelepathyPower(int nSpellID = -1) -{ - if(nSpellID == -1) nSpellID = PRCGetSpellId(); - - return GetPowerDiscipline(nSpellID) == DISCIPLINE_TELEPATHY; -} - -int CheckPowerPrereqs(int nFeat, object oPC) -{ - // Having the power already automatically disqualifies one from taking it again - if(GetHasFeat(nFeat, oPC)) - return FALSE; - // We assume that the 2da is correctly formatted, and as such, a prereq slot only contains - // data if the previous slots in order also contains data. - // ie, no PREREQFEAT2 if PREREQFEAT1 is empty - if(Get2DACache("feat", "PREREQFEAT1", nFeat) != "") - { - if(!GetHasFeat(StringToInt(Get2DACache("feat", "PREREQFEAT1", nFeat)), oPC)) - return FALSE; - if(Get2DACache("feat", "PREREQFEAT2", nFeat) != "" - && !GetHasFeat(StringToInt(Get2DACache("feat", "PREREQFEAT2", nFeat)), oPC)) - return FALSE; - } - - if(Get2DACache("feat", "OrReqFeat0", nFeat) != "") - { - if(!GetHasFeat(StringToInt(Get2DACache("feat", "OrReqFeat0", nFeat)), oPC)) - return FALSE; - if(Get2DACache("feat", "OrReqFeat1", nFeat) != "") - { - if(!GetHasFeat(StringToInt(Get2DACache("feat", "OrReqFeat1", nFeat)), oPC)) - return FALSE; - if(Get2DACache("feat", "OrReqFeat2", nFeat) != "") - { - if(!GetHasFeat(StringToInt(Get2DACache("feat", "OrReqFeat2", nFeat)), oPC)) - return FALSE; - if(Get2DACache("feat", "OrReqFeat3", nFeat) != "") - { - if(!GetHasFeat(StringToInt(Get2DACache("feat", "OrReqFeat3", nFeat)), oPC)) - return FALSE; - if(Get2DACache("feat", "OrReqFeat4", nFeat) != "") - { - if(!GetHasFeat(StringToInt(Get2DACache("feat", "OrReqFeat4", nFeat)), oPC)) - return FALSE; - } } } } } - - //if youve reached this far then return TRUE - return TRUE; -} - -int GetPsiPenetration(object oManifester = OBJECT_SELF) -{ - int nPen = GetManifesterLevel(oManifester); - - // The stuff inside applies only to normal manifestation, not psi-like abilities - if(!GetLocalInt(oManifester, PRC_IS_PSILIKE)) - { - // Check for Power Pen feats being used - if(GetLocalInt(oManifester, "PowerPenetrationActive") == TRUE && UsePsionicFocus(oManifester)) - { - nPen += GetHasFeat(FEAT_GREATER_POWER_PENETRATION, oManifester) ? 8 : 4; - } - } - - return nPen; -} - -int GetIsPsionicCharacter(object oCreature) -{ - return !!(GetLevelByClass(CLASS_TYPE_PSION, oCreature) || - GetLevelByClass(CLASS_TYPE_PSYWAR, oCreature) || - GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oCreature) || - GetLevelByClass(CLASS_TYPE_WILDER, oCreature) || - GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oCreature) || - GetLevelByClass(CLASS_TYPE_WARMIND, oCreature) || - GetHasFeat(FEAT_WILD_TALENT, oCreature) || - GetHasFeat(FEAT_KALASHTAR_PP, oCreature) || - GetHasFeat(FEAT_NATPSIONIC_1, oCreature) || - GetHasFeat(FEAT_NATPSIONIC_2, oCreature) || - GetHasFeat(FEAT_NATPSIONIC_3, oCreature) - // Racial psionicity signifying feats go here - ); -} - -void LocalCleanExtraFists(object oCreature) -{ - int iIsCWeap, iIsEquip; - - object oClean = GetFirstItemInInventory(oCreature); - - while (GetIsObjectValid(oClean)) - { - iIsCWeap = GetIsPRCCreatureWeapon(oClean); - - iIsEquip = oClean == GetItemInSlot(INVENTORY_SLOT_CWEAPON_L) || - oClean == GetItemInSlot(INVENTORY_SLOT_CWEAPON_R) || - oClean == GetItemInSlot(INVENTORY_SLOT_CWEAPON_B); - - if (iIsCWeap && !iIsEquip) - { - DestroyObject(oClean); - } - - oClean = GetNextItemInInventory(oCreature); - } -} -object GetPsionicCreatureWeapon(object oCreature, string sResRef, int nInventorySlot, float fDuration) -{ - int bCreatedWeapon = FALSE; - object oCWeapon = GetItemInSlot(nInventorySlot, oCreature); - - RemoveUnarmedAttackEffects(oCreature); - // Make sure they can actually equip them - UnarmedFeats(oCreature); - - // Determine if a creature weapon of the proper type already exists in the slot - if(!GetIsObjectValid(oCWeapon) || - GetStringUpperCase(GetTag(oCWeapon)) != GetStringUpperCase(sResRef) // Hack: The resref's and tags of the PRC creature weapons are the same - ) - { - if (GetHasItem(oCreature, sResRef)) - { - oCWeapon = GetItemPossessedBy(oCreature, sResRef); - SetIdentified(oCWeapon, TRUE); - //AssignCommand(oCreature, ActionEquipItem(oCWeapon, INVENTORY_SLOT_CWEAPON_L)); - ForceEquip(oCreature, oCWeapon, nInventorySlot); - } - else - { - oCWeapon = CreateItemOnObject(sResRef, oCreature); - SetIdentified(oCWeapon, TRUE); - //AssignCommand(oCreature, ActionEquipItem(oCWeapon, INVENTORY_SLOT_CWEAPON_L)); - ForceEquip(oCreature, oCWeapon, nInventorySlot); - bCreatedWeapon = TRUE; - } - } - - - // Clean up the mess of extra fists made on taking first level. - DelayCommand(6.0f, LocalCleanExtraFists(oCreature)); - - // Weapon finesse or intuitive attack? - SetLocalInt(oCreature, "UsingCreature", TRUE); - ExecuteScript("prc_intuiatk", oCreature); - DelayCommand(1.0f, DeleteLocalInt(oCreature, "UsingCreature")); - - // Add OnHitCast: Unique if necessary - if(GetHasFeat(FEAT_REND, oCreature)) - IPSafeAddItemProperty(oCWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - - // This adds creature weapon finesse - ApplyUnarmedAttackEffects(oCreature); - - // Destroy the weapon if it was created by this function - if(bCreatedWeapon) - DestroyObject(oCWeapon, (fDuration + 6.0)); - - return oCWeapon; -} - -int GetTargetSpecificChangesToDamage(object oTarget, object oManifester, int nDamage, - int bIsHitPointDamage = TRUE, int bIsEnergyDamage = FALSE) -{ - // Greater Power Specialization - +2 damage on all HP-damaging powers when target is within 30ft - if(bIsHitPointDamage && - GetHasFeat(FEAT_GREATER_POWER_SPECIALIZATION, oManifester) && - GetDistanceBetween(oTarget, oManifester) <= FeetToMeters(30.0f) - ) - nDamage += 2; - // Intellect Fortress - Halve damage dealt by powers that allow PR. Goes before DR (-like) reductions - if(GetLocalInt(oTarget, "PRC_Power_IntellectFortress_Active") && - Get2DACache("spells", "ItemImmunity", PRCGetSpellId()) == "1" - ) - nDamage /= 2; - // Mental Resistance - 3 damage less for all non-energy damage and ability damage - if(GetHasFeat(FEAT_MENTAL_RESISTANCE, oTarget) && !bIsEnergyDamage) - nDamage -= 3; - - // Reasonable return values only - if(nDamage < 0) nDamage = 0; - - if (GetIsMeldBound(oManifester, MELD_PSYCHIC_FOCUS) == CHAKRA_THROAT && nDamage > 0 && !GetLocalInt(oManifester, "PsychicFocusMeld") && bIsHitPointDamage) - { - SetLocalInt(oManifester, "PsychicFocusMeld", TRUE); - DelayCommand(6.0, DeleteLocalInt(oManifester, "PsychicFocusMeld")); - int nClass = GetMeldShapedClass(oManifester, MELD_PSYCHIC_FOCUS); - int nDC = GetMeldshaperDC(oManifester, nClass, MELD_PSYCHIC_FOCUS); - if(PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_NONE)) - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDazed(), oTarget, 6.0); - } - - return nDamage; -} - -int PracticedManifesting(object oManifester, int iManifestingClass, int iManifestingLevels) -{ - int nFeat; - int iAdjustment = GetHitDice(oManifester) - iManifestingLevels; - iAdjustment = iAdjustment > 4 ? 4 : iAdjustment < 0 ? 0 : iAdjustment; - - switch(iManifestingClass) - { - case CLASS_TYPE_PSION: nFeat = FEAT_PRACTICED_MANIFESTER_PSION; break; - case CLASS_TYPE_PSYWAR: nFeat = FEAT_PRACTICED_MANIFESTER_PSYWAR; break; - case CLASS_TYPE_PSYCHIC_ROGUE: nFeat = FEAT_PRACTICED_MANIFESTER_PSYROG; break; - case CLASS_TYPE_WILDER: nFeat = FEAT_PRACTICED_MANIFESTER_WILDER; break; - case CLASS_TYPE_WARMIND: nFeat = FEAT_PRACTICED_MANIFESTER_WARMIND; break; - case CLASS_TYPE_FIST_OF_ZUOKEN: nFeat = FEAT_PRACTICED_MANIFESTER_FIST_OF_ZUOKEN; break; - default: nFeat = -1; - } - - if(GetHasFeat(nFeat, oManifester)) - return iAdjustment; - - return 0; -} - -int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVALID, int nMaxPowerLevel = FALSE) -{ - int nLevel; - int nAdjust = GetLocalInt(oManifester, PRC_CASTERLEVEL_ADJUSTMENT); - nAdjust -= GetLocalInt(oManifester, "WoLManifPenalty"); - - // The function user needs to know the character's manifester level in a specific class - // instead of whatever the character last manifested a power as - if(nSpecificClass != CLASS_TYPE_INVALID) - { - if(GetIsPsionicClass(nSpecificClass)) - { - nLevel = GetLevelByClass(nSpecificClass, oManifester); - // Add levels from +ML PrCs only for the first manifesting class - if(nSpecificClass == GetPrimaryPsionicClass(oManifester)) - nLevel += GetPsionicPRCLevels(oManifester); - - // Psionic vestiges are tucked in here to override things. - // This assumes that there will never be a psion with this spell effect manifesting things - if (nSpecificClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_ARETE, oManifester) && !nMaxPowerLevel) - { - nLevel = GetLocalInt(oManifester, "AretePsion"); - nMaxPowerLevel = TRUE; - } - if (nSpecificClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_THETRIAD, oManifester) && !nMaxPowerLevel) - { - nLevel = GetLocalInt(oManifester, "TheTriadPsion"); - nMaxPowerLevel = TRUE; - } - if (nSpecificClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_ABYSM, oManifester) && !nMaxPowerLevel) - { - nLevel = GetLocalInt(oManifester, "AbysmPsion"); - nMaxPowerLevel = TRUE; - } - - // This is for learning powers, we need to ignore some adjustments - if (nMaxPowerLevel) return nLevel; - - nLevel += PracticedManifesting(oManifester, nSpecificClass, nLevel); //gotta be the last one - - return nLevel + nAdjust; - } - // A character's manifester level gained from non-manifesting classes is always a nice, round zero - else - return 0; - } - - // Item Spells - if(GetItemPossessor(GetSpellCastItem()) == oManifester) - { - if(DEBUG) SendMessageToPC(oManifester, "Item casting at level " + IntToString(GetCasterLevel(oManifester))); - - return GetCasterLevel(oManifester) + nAdjust; - } - - // For when you want to assign the caster level. - else if(GetLocalInt(oManifester, PRC_CASTERLEVEL_OVERRIDE) != 0) - { - if(DEBUG) SendMessageToPC(oManifester, "Forced-level manifesting at level " + IntToString(GetCasterLevel(oManifester))); - - DelayCommand(1.0, DeleteLocalInt(oManifester, PRC_CASTERLEVEL_OVERRIDE)); - nLevel = GetLocalInt(oManifester, PRC_CASTERLEVEL_OVERRIDE); - } - else if(GetManifestingClass(oManifester) != CLASS_TYPE_INVALID) - { - //Gets the manifesting class - int nManifestingClass = GetManifestingClass(oManifester); -// if(DEBUG) DoDebug("Manifesting class: " + IntToString(nManifestingClass), oManifester); - nLevel = GetLevelByClass(nManifestingClass, oManifester); - // Add levels from +ML PrCs only for the first manifesting class - nLevel += nManifestingClass == GetPrimaryPsionicClass(oManifester) ? GetPsionicPRCLevels(oManifester) : 0; - - // Psionic vestiges are tucked in here to override things. - // This assumes that there will never be a psion with this spell effect manifesting things - if (nManifestingClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_ARETE, oManifester) && !nMaxPowerLevel) - { - nLevel = GetLocalInt(oManifester, "AretePsion"); - nMaxPowerLevel = TRUE; - } - if (nManifestingClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_THETRIAD, oManifester) && !nMaxPowerLevel) - { - nLevel = GetLocalInt(oManifester, "TheTriadPsion"); - nMaxPowerLevel = TRUE; - } - if (nManifestingClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_ABYSM, oManifester) && !nMaxPowerLevel) - { - nLevel = GetLocalInt(oManifester, "AbysmPsion"); - nMaxPowerLevel = TRUE; - } - - // This is for learning powers, we need to ignore some adjustments - if (nMaxPowerLevel) return nLevel; - - nLevel += PracticedManifesting(oManifester, nManifestingClass, nLevel); //gotta be the last one -// if(DEBUG) DoDebug("Level gotten via GetLevelByClass: " + IntToString(nLevel), oManifester); - } - - // If you have a primary psionic class and no manifester level yet, get levels based on that - if (GetPrimaryPsionicClass(oManifester) && nLevel == 0) - { - int nClass = GetPrimaryPsionicClass(oManifester); - nLevel = GetLevelByClass(nClass, oManifester); - nLevel += GetPsionicPRCLevels(oManifester); - nLevel += PracticedManifesting(oManifester, nClass, nLevel); //gotta be the last one - } - - // If everything else fails, you are not a manifester - if(nLevel == 0) - { - if(DEBUG) DoDebug("Failed to get manifester level for creature " + DebugObject2Str(oManifester) + ", using first class slot"); - //else WriteTimestampedLogEntry("Failed to get manifester level for creature " + DebugObject2Str(oManifester) + ", using first class slot"); - - return 0; - } - - - // The bonuses inside only apply to normal manifestation - if(!GetLocalInt(oManifester, PRC_IS_PSILIKE)) - { - //Adding wild surge - int nSurge = GetWildSurge(oManifester); - if (nSurge > 0) nLevel += nSurge; - - // Adding overchannel - int nOverchannel = GetLocalInt(oManifester, PRC_OVERCHANNEL); - if(nOverchannel > 0) nLevel += nOverchannel; - - // Adding Soul Manifester - nLevel += Soulcaster(oManifester, PRCGetSpellId()); - } - - nLevel += nAdjust; - - // This spam is technically no longer necessary once the manifester level getting mechanism has been confirmed to work -// if(DEBUG) FloatingTextStringOnCreature("Manifester Level: " + IntToString(nLevel), oManifester, FALSE); - - return nLevel; -} - -int GetHighestManifesterLevel(object oCreature) -{ - int n = 0; - int nHighest; - int nTemp; - - while(n <= 8) - { - if(GetClassByPosition(n, oCreature) != CLASS_TYPE_INVALID) - { - nTemp = GetManifesterLevel(oCreature, GetClassByPosition(n, oCreature)); - - if(nTemp > nHighest) - nHighest = nTemp; - } - n++; - - } - - return nHighest; -} - -/* int GetHighestManifesterLevel(object oCreature) -{ - return max(max(GetClassByPosition(1, oCreature) != CLASS_TYPE_INVALID ? GetManifesterLevel(oCreature, GetClassByPosition(1, oCreature)) : 0, - GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID ? GetManifesterLevel(oCreature, GetClassByPosition(2, oCreature)) : 0 - ), - GetClassByPosition(3, oCreature) != CLASS_TYPE_INVALID ? GetManifesterLevel(oCreature, GetClassByPosition(3, oCreature)) : 0 - ); -} */ - -int GetPowerLevel(object oManifester) -{ - return GetLocalInt(oManifester, PRC_POWER_LEVEL); -} - -int GetAbilityScoreOfClass(object oManifester, int nClass) -{ - return GetAbilityScore(oManifester, GetAbilityOfClass(nClass)); -} - -int GetManifestingClass(object oManifester = OBJECT_SELF) -{ - return GetLocalInt(oManifester, PRC_MANIFESTING_CLASS) - 1; -} - -int GetAbilityOfClass(int nClass) -{ - switch(nClass) - { - case CLASS_TYPE_DIAMOND_DRAGON: - case CLASS_TYPE_PSION: - case CLASS_TYPE_PSYCHIC_ROGUE: - return ABILITY_INTELLIGENCE; - case CLASS_TYPE_PSYWAR: - case CLASS_TYPE_FIST_OF_ZUOKEN: - case CLASS_TYPE_WARMIND: - return ABILITY_WISDOM; - case CLASS_TYPE_WILDER: - return ABILITY_CHARISMA; - } - - // If there's no class, it's racial. Use Charisma - return ABILITY_CHARISMA; -} - -int GetPrimaryPsionicClass(object oCreature = OBJECT_SELF) -{ - int nClass; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) - { - int iPsionicPos = GetFirstPsionicClassPosition(oCreature); - if (!iPsionicPos) return CLASS_TYPE_INVALID; // no Psionic casting class - - nClass = GetClassByPosition(iPsionicPos, oCreature); - } - else - { - int nClassLvl; - int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8; - int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl; - - nClass1 = GetClassByPosition(1, oCreature); - nClass2 = GetClassByPosition(2, oCreature); - nClass3 = GetClassByPosition(3, oCreature); - nClass4 = GetClassByPosition(4, oCreature); - nClass5 = GetClassByPosition(5, oCreature); - nClass6 = GetClassByPosition(6, oCreature); - nClass7 = GetClassByPosition(7, oCreature); - nClass8 = GetClassByPosition(8, oCreature); - - if(GetIsPsionicClass(nClass1)) nClass1Lvl = GetLevelByClass(nClass1, oCreature); - if(GetIsPsionicClass(nClass2)) nClass2Lvl = GetLevelByClass(nClass2, oCreature); - if(GetIsPsionicClass(nClass3)) nClass3Lvl = GetLevelByClass(nClass3, oCreature); - if(GetIsPsionicClass(nClass4)) nClass4Lvl = GetLevelByClass(nClass4, oCreature); - if(GetIsPsionicClass(nClass5)) nClass5Lvl = GetLevelByClass(nClass5, oCreature); - if(GetIsPsionicClass(nClass6)) nClass6Lvl = GetLevelByClass(nClass6, oCreature); - if(GetIsPsionicClass(nClass7)) nClass7Lvl = GetLevelByClass(nClass7, oCreature); - if(GetIsPsionicClass(nClass8)) nClass8Lvl = GetLevelByClass(nClass8, oCreature); - - - nClass = nClass1; - nClassLvl = nClass1Lvl; - - if(nClass2Lvl > nClassLvl) - { - nClass = nClass2; - nClassLvl = nClass2Lvl; - } - if(nClass3Lvl > nClassLvl) - { - nClass = nClass3; - nClassLvl = nClass3Lvl; - } - if(nClass4Lvl > nClassLvl) - { - nClass = nClass4; - nClassLvl = nClass4Lvl; - } - if(nClass5Lvl > nClassLvl) - { - nClass = nClass5; - nClassLvl = nClass5Lvl; - } - if(nClass6Lvl > nClassLvl) - { - nClass = nClass6; - nClassLvl = nClass6Lvl; - } - if(nClass7Lvl > nClassLvl) - { - nClass = nClass7; - nClassLvl = nClass7Lvl; - } - if(nClass8Lvl > nClassLvl) - { - nClass = nClass8; - nClassLvl = nClass8Lvl; - } - - if(nClassLvl == 0) - nClass = CLASS_TYPE_INVALID; - } - - return nClass; -} - -int GetPsionicPRCLevels(object oCreature) -{ - int nLevel = 0; - - // Cerebremancer and Psychic Theurge add manifester levels on each level - nLevel += GetLevelByClass(CLASS_TYPE_CEREBREMANCER, oCreature); - nLevel += GetLevelByClass(CLASS_TYPE_PSYCHIC_THEURGE, oCreature); - if (GetFirstPsionicClassPosition(oCreature)) nLevel += GetLevelByClass(CLASS_TYPE_SOULCASTER, oCreature); - - // No manifester level boost at level 1 and 10 for Thrallherd - if(GetLevelByClass(CLASS_TYPE_THRALLHERD, oCreature)) - { - nLevel += GetLevelByClass(CLASS_TYPE_THRALLHERD, oCreature) - 1; - if(GetLevelByClass(CLASS_TYPE_THRALLHERD, oCreature) >= 10) nLevel -= 1; - } - // No manifester level boost at levels 2, 5 and 8 for Shadow Mind - if(GetLevelByClass(CLASS_TYPE_SHADOWMIND, oCreature)) - { - nLevel += GetLevelByClass(CLASS_TYPE_SHADOWMIND, oCreature); - if(GetLevelByClass(CLASS_TYPE_SHADOWMIND, oCreature) >= 2) nLevel -= 1; - if(GetLevelByClass(CLASS_TYPE_SHADOWMIND, oCreature) >= 5) nLevel -= 1; - if(GetLevelByClass(CLASS_TYPE_SHADOWMIND, oCreature) >= 8) nLevel -= 1; - } - // No manifester level boost at level 1 and 6 for Iron Mind - if(GetLevelByClass(CLASS_TYPE_IRONMIND, oCreature)) - { - nLevel += GetLevelByClass(CLASS_TYPE_IRONMIND, oCreature) - 1; - if(GetLevelByClass(CLASS_TYPE_IRONMIND, oCreature) >= 6) nLevel -= 1; - } - // No manifester level boost at level 1 and 6 for Diamond Dragon - if(GetLevelByClass(CLASS_TYPE_DIAMOND_DRAGON, oCreature)) - { - nLevel += GetLevelByClass(CLASS_TYPE_DIAMOND_DRAGON, oCreature) - 1; - if(GetLevelByClass(CLASS_TYPE_DIAMOND_DRAGON, oCreature) >= 6) nLevel -= 1; - } - // No manifester level boost at level 1 for Sanctified Mind - if(GetLevelByClass(CLASS_TYPE_SANCTIFIED_MIND, oCreature)) - { - nLevel += GetLevelByClass(CLASS_TYPE_SANCTIFIED_MIND, oCreature) - 1; - } - - return nLevel; -} - -int GetFirstPsionicClassPosition(object oCreature = OBJECT_SELF) -{ - if (GetIsPsionicClass(GetClassByPosition(1, oCreature))) - return 1; - if (GetIsPsionicClass(GetClassByPosition(2, oCreature))) - return 2; - if (GetIsPsionicClass(GetClassByPosition(3, oCreature))) - return 3; - if (GetIsPsionicClass(GetClassByPosition(4, oCreature))) - return 4; - if (GetIsPsionicClass(GetClassByPosition(5, oCreature))) - return 5; - if (GetIsPsionicClass(GetClassByPosition(6, oCreature))) - return 6; - if (GetIsPsionicClass(GetClassByPosition(7, oCreature))) - return 7; - if (GetIsPsionicClass(GetClassByPosition(8, oCreature))) - return 8; - - return 0; -} - -int GetIsPsionicClass(int nClass) -{ - return (nClass==CLASS_TYPE_PSION - || nClass==CLASS_TYPE_PSYWAR - || nClass==CLASS_TYPE_PSYCHIC_ROGUE - || nClass==CLASS_TYPE_WILDER - || nClass==CLASS_TYPE_FIST_OF_ZUOKEN - || nClass==CLASS_TYPE_WARMIND - ); -} - -int GetWildSurge(object oManifester) -{ - int nWildSurge = GetLocalInt(oManifester, PRC_IS_PSILIKE) ? - 0 : // Wild Surge does not apply to psi-like abilities - GetLocalInt(oManifester, PRC_WILD_SURGE); - - if(DEBUG) DoDebug("GetWildSurge():\n" - + "oManifester = " + DebugObject2Str(oManifester) + "\n" - + "nWildSurge = " + IntToString(nWildSurge) + "\n" - ); - - return nWildSurge; -} - -int GetMaxPowerLevel(object oManifester) -{ - int nClass = GetPrimaryPsionicClass(oManifester); - string sFile = GetAMSKnownFileName(nClass); - int nLevel = GetHighestManifesterLevel(oManifester); - int nMax = StringToInt(Get2DACache(sFile, "MaxPowerLevel", nLevel)); - if (DEBUG) DoDebug("GetMaxPowerLevel is "+IntToString(nMax)); - return nMax; -} \ No newline at end of file diff --git a/trunk/include/shd_inc_shdfunc.nss b/trunk/include/shd_inc_shdfunc.nss deleted file mode 100644 index ce4d0590..00000000 --- a/trunk/include/shd_inc_shdfunc.nss +++ /dev/null @@ -1,669 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Shadowcasting main include: Miscellaneous -//:: shd_inc_shdfunc -//:://///////////////////////////////////////////// -/** @file - Defines various functions and other stuff that - do something related to Shadowcasting. - - Also acts as inclusion nexus for the general - shadowcasting includes. In other words, don't include - them directly in your scripts, instead include this. - - @author Stratovarius - @date Created - 2019.02.08 -*/ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/10 - -//:: Test Void -// void main (){} - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Determines from what class's mystery list the currently being shadowcast - * mystery is shadowcast from. - * - * @param oShadow A creature shadowcasting a mystery at this moment - * @return CLASS_TYPE_* constant of the class - */ -int GetShadowcastingClass(object oShadow = OBJECT_SELF); - -/** - * Determines the given creature's Shadowcaster level. If a class is specified, - * then returns the Shadowcaster level for that class. Otherwise, returns - * the Shadowcaster level for the currently active mystery. - * - * @param oShadow The creature whose Shadowcaster level to determine - * @param nSpecificClass The class to determine the creature's Shadowcaster - * level in. - * DEFAULT: CLASS_TYPE_INVALID, which means the creature's - * Shadowcaster level in regards to an ongoing mystery - * is determined instead. - * @return The Shadowcaster level - */ -int GetShadowcasterLevel(object oShadow = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID); - -/** - * Determines whether a given creature uses ShadowMagic. - * Requires either levels in a ShadowMagic-related class or - * natural ShadowMagic ability based on race. - * - * @param oCreature Creature to test - * @return TRUE if the creature can use ShadowMagics, FALSE otherwise. - */ -int GetIsShadowMagicUser(object oCreature); - -/** - * Determines the given creature's highest unmodified Shadowcaster level among its - * shadowcasting classes. - * - * @param oCreature Creature whose highest Shadowcaster level to determine - * @return The highest unmodified Shadowcaster level the creature can have - */ -int GetHighestShadowcasterLevel(object oCreature); - -/** - * Determines whether a given class is a ShadowMagic-related class or not. - * - * @param nClass CLASS_TYPE_* of the class to test - * @return TRUE if the class is a ShadowMagic-related class, FALSE otherwise - */ -int GetIsShadowMagicClass(int nClass); - -/** - * Gets the level of the mystery being currently shadowcast or the level - * of the mystery ID passed to it. - * - * @param oShadow The creature currently shadowcasting a mystery - * @return The level of the mystery being shadowcast - */ -int GetMysteryLevel(object oShadow, int nMystId = 0); - -/** - * Returns the name of the Path - * - * @param nPath PATH_* to name - */ -string GetPathName(int nPath); - -/** - * Returns the Path the mystery is in - * @param nMystId Mystery to check - * - * @return PATH_* - */ -int GetPathByMystery(int nMystId); - -/** - * Returns true or false if the character has Path - * focus in the chosen path - * @param oShadow Person to check - * @param nPath Path to check - * - * @return TRUE or FALSE - */ -int GetHasPathFocus(object oShadow, int nPath); - -/** - * Calculates how many shadowcaster levels are gained by a given creature from - * it's levels in prestige classes. - * - * @param oCreature Creature to calculate added shadowcaster levels for - * @return The number of shadowcaster levels gained - */ -int GetShadowMagicPRCLevels(object oShadow); - -/** - * Determines which of the character's classes is their highest or first - * shadowcasting class, if any. This is the one which gains shadowcaster - * level raise benefits from prestige classes. - * - * @param oCreature Creature whose classes to test - * @return CLASS_TYPE_* of the first shadowcasting class, - * CLASS_TYPE_INVALID if the creature does not possess any. - */ -int GetPrimaryShadowMagicClass(object oCreature = OBJECT_SELF); - -/** - * Determines the position of a creature's first shadowcasting class, if any. - * - * @param oCreature Creature whose classes to test - * @return The position of the first shadowcasting class {1, 2, 3} or 0 if - * the creature possesses no levels in shadowcasting classes. - */ -int GetFirstShadowMagicClassPosition(object oCreature = OBJECT_SELF); - -/** - * Returns ability score needed to Shadowcast - * Type 1 is score to cast, Type 2 is score for DC - * - * @param nClass The class to check - * @return ABILITY_* - */ -int GetShadowAbilityOfClass(int nClass, int nType); - -/** - * Calculates the DC of the Mystery being currently shadowcast. - * - * WARNING: Return value is not defined when a mystery isn't being shadowcast. - * - */ -int GetShadowcasterDC(object oShadow = OBJECT_SELF); - -/** - * Calculates the SpellPen of the Mystery being currently shadowcast. - * Whether a Mystery is supernatural or not is checked in EvaluateMystery - * - * Currently just a placeholder returning GetShadowcasterLevel - */ -int ShadowSRPen(object oShadow, int nShadowcasterLevel); - -/** - * Stores a mystery 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 myst The mystery structure to store - */ -void SetLocalMystery(object oObject, string sName, struct mystery myst); - -/** - * Retrieves a previously stored mystery 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 mystery GetLocalMystery(object oObject, string sName); - -/** - * Returns the boost to caster level from feats - * - * @param oShadow The caster - * @param nMyst The mystery being cast - * @return Total bonus to caster level - */ -int ShadowcastingFeats(object oShadow, int nMyst); - -/** - * Returns the boost to DC from nocturnal caster - * - * @param oShadow The caster - * @param nPath The path to check for - * @return Total bonus to caster level - */ -int GetHasNocturnal(object oShadow, int nPath); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "prc_alterations" -#include "shd_inc_myst" -#include "shd_inc_mystknwn" - -////////////////////////////////////////////////// -/* Internal functions */ -////////////////////////////////////////////////// - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetShadowcastingClass(object oShadow = OBJECT_SELF) -{ - int nReturn = GetLocalInt(oShadow, PRC_SHADOWCASTING_CLASS) - 1; - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcastingClass: GetShadowcastingClass value is "+IntToString(nReturn), oShadow); - return nReturn; -} - -int GetShadowcasterLevel(object oShadow = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID) -{ - int nAdjust = GetLocalInt(oShadow, PRC_CASTERLEVEL_ADJUSTMENT); - int nLevel = GetLocalInt(oShadow, PRC_CASTERLEVEL_OVERRIDE); - int nMyst = PRCGetSpellId(); // The fact that this will return 0 sometimes is relied upon - if (GetIsFundamental(nMyst)) nSpecificClass = CLASS_TYPE_SHADOWCASTER; - - // For when you want to assign the caster level. - if(nLevel) - { - if(DEBUG) SendMessageToPC(oShadow, "GetShadowcasterLevel(): Forced-level shadowcasting at level " + IntToString(nLevel)); - //DelayCommand(1.0, DeleteLocalInt(oShadow, PRC_CASTERLEVEL_OVERRIDE)); - return nLevel + nAdjust; - } - - if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: "+GetName(oShadow)+" is a "+IntToString(nSpecificClass), oShadow); - // The function user needs to know the character's Shadowcaster level in a specific class - // instead of whatever the character last shadowcast a mystery as - if(nSpecificClass != CLASS_TYPE_INVALID) - { - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: Class is Valid", oShadow); - if(GetIsShadowMagicClass(nSpecificClass)) - { - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: Class is Shadow Magic Class", oShadow); - // Shadowcaster level is class level + prestige - nLevel = GetLevelByClass(nSpecificClass, oShadow); - if(nLevel) - { - nLevel += GetShadowMagicPRCLevels(oShadow); - nLevel += ShadowcastingFeats(oShadow, nMyst); - if (GetLocalInt(oShadow, "CaptureMagic")) - { - nLevel += GetLocalInt(oShadow, "CaptureMagic"); - DeleteLocalInt(oShadow, "CaptureMagic"); - } - if (GetLocalInt(oShadow, "EldritchDisrupt")) - nLevel -= 4; - if (GetLocalInt(oShadow, "EldritchVortex")) - nLevel -= 4; - } - } - } - else if(GetShadowcastingClass(oShadow) != -1) - { - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: GetShadowcastingClass", oShadow); - nLevel = GetLevelByClass(GetShadowcastingClass(oShadow), oShadow); - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: GetShadowcastingClass level "+IntToString(nLevel), oShadow); - nLevel += GetShadowMagicPRCLevels(oShadow); - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: GetShadowcastingClass prestige level "+IntToString(nLevel), oShadow); - nLevel += ShadowcastingFeats(oShadow, nMyst); - //if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: GetShadowcastingClass feat level "+IntToString(nLevel), oShadow); - if (GetLocalInt(oShadow, "CaptureMagic")) - { - nLevel += GetLocalInt(oShadow, "CaptureMagic"); - DeleteLocalInt(oShadow, "CaptureMagic"); - } - if (GetLocalInt(oShadow, "EldritchDisrupt")) - nLevel -= 4; - if (GetLocalInt(oShadow, "EldritchVortex")) - nLevel -= 4; - } - - if(DEBUG) FloatingTextStringOnCreature("Shadowcaster Level: " + IntToString(nLevel), oShadow, FALSE); - - return nLevel + nAdjust; -} - -int GetIsShadowMagicUser(object oCreature) -{ - return !!(GetLevelByClass(CLASS_TYPE_SHADOWCASTER, oCreature) - || GetLevelByClass(CLASS_TYPE_SHADOWSMITH, oCreature)); -} - -int GetHighestShadowcasterLevel(object oCreature) -{ - int n = 0; - int nHighest; - int nTemp; - - while(n <= 8) - { - if(GetClassByPosition(n, oCreature) != CLASS_TYPE_INVALID) - { - nTemp = GetShadowcasterLevel(oCreature, GetClassByPosition(n, oCreature)); - - if(nTemp > nHighest) - nHighest = nTemp; - } - n++; - - } - - return nHighest; -} - -/* int GetHighestShadowcasterLevel(object oCreature) -{ - return max(max(GetClassByPosition(1, oCreature) != CLASS_TYPE_INVALID ? GetShadowcasterLevel(oCreature, GetClassByPosition(1, oCreature)) : 0, - GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID ? GetShadowcasterLevel(oCreature, GetClassByPosition(2, oCreature)) : 0 - ), - GetClassByPosition(3, oCreature) != CLASS_TYPE_INVALID ? GetShadowcasterLevel(oCreature, GetClassByPosition(3, oCreature)) : 0 - ); -} */ - -int GetIsShadowMagicClass(int nClass) -{ - return nClass == CLASS_TYPE_SHADOWCASTER - || nClass == CLASS_TYPE_SHADOWSMITH; -} - -int GetMysteryLevel(object oShadow, int nMystId = 0) -{ - if (nMystId > 0) return StringToInt(lookup_spell_innate(nMystId)); - int nLevel = GetLocalInt(oShadow, PRC_MYSTERY_LEVEL); - if (nLevel > 0) return nLevel; - - return 0; -} - -string GetPathName(int nPath) -{ - int nStrRef; - switch(nPath) - { - /* case PATH_DESERT_WIND: nStrRef = 16829714; break; - case PATH_DEVOTED_SPIRIT: nStrRef = 16829715; break; - case PATH_DIAMOND_MIND: nStrRef = 16829716; break; - case PATH_IRON_HEART: nStrRef = 16829717; break; - case PATH_SETTING_SUN: nStrRef = 16829718; break; - case PATH_SHADOW_HAND: nStrRef = 16829719; break; - case PATH_STONE_DRAGON: nStrRef = 16829720; break; - case PATH_TIGER_CLAW: nStrRef = 16829721; break; - case PATH_WHITE_RAVEN: nStrRef = 16829722; break;*/ - } - return GetStringByStrRef(nStrRef); -} - -int GetPathByMystery(int nMystId) -{ - // Shadowcaster has every mystery ever, so this is just the easy way out. - int i = GetPowerfileIndexFromRealSpellID(nMystId); - string sClass = GetAMSDefinitionFileName(CLASS_TYPE_SHADOWCASTER); - int nReturn = StringToInt(Get2DACache(sClass, "Path", i)); - /*if (DEBUG) DoDebug("GetPathByMystery() i "+IntToString(i)); - if (DEBUG) DoDebug("GetPathByMystery() sClass "+sClass); - if (DEBUG) DoDebug("GetPathByMystery() nReturn "+IntToString(nReturn)); */ - - return nReturn; -} - -int GetShadowMagicPRCLevels(object oShadow) -{ - int nLevel = GetLevelByClass(CLASS_TYPE_NOCTUMANCER, oShadow); - - // These two don't add at 1st level - if (GetLevelByClass(CLASS_TYPE_CHILD_OF_NIGHT, oShadow)) - nLevel += GetLevelByClass(CLASS_TYPE_CHILD_OF_NIGHT, oShadow) - 1; - if (GetLevelByClass(CLASS_TYPE_MASTER_OF_SHADOW, oShadow)) - nLevel += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHADOW, oShadow) - 1; - - return nLevel; -} - -int GetPrimaryShadowMagicClass(object oCreature = OBJECT_SELF) -{ - int nClass = CLASS_TYPE_INVALID; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) - { - int nShadowMagicPos = GetFirstShadowMagicClassPosition(oCreature); - if (!nShadowMagicPos) return CLASS_TYPE_INVALID; // no Blade Magic shadowcasting class - - nClass = GetClassByPosition(nShadowMagicPos, oCreature); - } - else - { - int nClassLvl; - int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8; - int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl; - - nClass1 = GetClassByPosition(1, oCreature); - nClass2 = GetClassByPosition(2, oCreature); - nClass3 = GetClassByPosition(3, oCreature); - nClass4 = GetClassByPosition(4, oCreature); - nClass5 = GetClassByPosition(5, oCreature); - nClass6 = GetClassByPosition(6, oCreature); - nClass7 = GetClassByPosition(7, oCreature); - nClass8 = GetClassByPosition(8, oCreature); - - if(GetIsShadowMagicClass(nClass1)) nClass1Lvl = GetLevelByClass(nClass1, oCreature); - if(GetIsShadowMagicClass(nClass2)) nClass2Lvl = GetLevelByClass(nClass2, oCreature); - if(GetIsShadowMagicClass(nClass3)) nClass3Lvl = GetLevelByClass(nClass3, oCreature); - if(GetIsShadowMagicClass(nClass4)) nClass4Lvl = GetLevelByClass(nClass4, oCreature); - if(GetIsShadowMagicClass(nClass5)) nClass5Lvl = GetLevelByClass(nClass5, oCreature); - if(GetIsShadowMagicClass(nClass6)) nClass6Lvl = GetLevelByClass(nClass6, oCreature); - if(GetIsShadowMagicClass(nClass7)) nClass7Lvl = GetLevelByClass(nClass7, oCreature); - if(GetIsShadowMagicClass(nClass8)) nClass8Lvl = GetLevelByClass(nClass8, oCreature); - - nClass = nClass1; - nClassLvl = nClass1Lvl; - - if(nClass2Lvl > nClassLvl) - { - nClass = nClass2; - nClassLvl = nClass2Lvl; - } - if(nClass3Lvl > nClassLvl) - { - nClass = nClass3; - nClassLvl = nClass3Lvl; - } - if(nClass4Lvl > nClassLvl) - { - nClass = nClass4; - nClassLvl = nClass4Lvl; - } - if(nClass5Lvl > nClassLvl) - { - nClass = nClass5; - nClassLvl = nClass5Lvl; - } - if(nClass6Lvl > nClassLvl) - { - nClass = nClass6; - nClassLvl = nClass6Lvl; - } - if(nClass7Lvl > nClassLvl) - { - nClass = nClass7; - nClassLvl = nClass7Lvl; - } - if(nClass8Lvl > nClassLvl) - { - nClass = nClass8; - nClassLvl = nClass8Lvl; - } - - if(nClassLvl == 0) - nClass = CLASS_TYPE_INVALID; - } - - return nClass; -} - -int GetFirstShadowMagicClassPosition(object oCreature = OBJECT_SELF) -{ - if (GetIsShadowMagicClass(GetClassByPosition(1, oCreature))) - return 1; - if (GetIsShadowMagicClass(GetClassByPosition(2, oCreature))) - return 2; - if (GetIsShadowMagicClass(GetClassByPosition(3, oCreature))) - return 3; - if (GetIsShadowMagicClass(GetClassByPosition(4, oCreature))) - return 4; - if (GetIsShadowMagicClass(GetClassByPosition(5, oCreature))) - return 5; - if (GetIsShadowMagicClass(GetClassByPosition(6, oCreature))) - return 6; - if (GetIsShadowMagicClass(GetClassByPosition(7, oCreature))) - return 7; - if (GetIsShadowMagicClass(GetClassByPosition(8, oCreature))) - return 8; - - return 0; -} - -int GetHasPathFocus(object oShadow, int nPath) -{ - //if (DEBUG) DoDebug("GetHasPathFocus() nPath "+IntToString(nPath)); - int nFocus, nGRFocus, nReturn; - switch(nPath) - { - case PATH_CLOAK_SHADOWS: nFocus = FEAT_PATH_FOCUS_CLOAK_SHADOWS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_CLOAK_SHADOWS ; break; - case PATH_DARK_TERRAIN: nFocus = FEAT_PATH_FOCUS_DARK_TERRAIN ; nGRFocus = FEAT_GREATER_PATH_FOCUS_DARK_TERRAIN ; break; - case PATH_EBON_WHISPERS: nFocus = FEAT_PATH_FOCUS_EBON_WHISPERS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_EBON_WHISPERS ; break; - case PATH_EYES_DARKNESS: nFocus = FEAT_PATH_FOCUS_EYES_DARKNESS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_EYES_DARKNESS ; break; - case PATH_SHUTTERS_CLOUDS: nFocus = FEAT_PATH_FOCUS_SHUTTERS_CLOUDS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_SHUTTERS_CLOUDS ; break; - case PATH_TOUCH_TWILIGHT: nFocus = FEAT_PATH_FOCUS_TOUCH_TWILIGHT ; nGRFocus = FEAT_GREATER_PATH_FOCUS_TOUCH_TWILIGHT ; break; - case PATH_UMBRAL_MIND: nFocus = FEAT_PATH_FOCUS_UMBRAL_MIND ; nGRFocus = FEAT_GREATER_PATH_FOCUS_UMBRAL_MIND ; break; - case PATH_BLACK_MAGIC: nFocus = FEAT_PATH_FOCUS_BLACK_MAGIC ; nGRFocus = FEAT_GREATER_PATH_FOCUS_BLACK_MAGIC ; break; - case PATH_BODY_SOUL: nFocus = FEAT_PATH_FOCUS_BODY_SOUL ; nGRFocus = FEAT_GREATER_PATH_FOCUS_BODY_SOUL ; break; - case PATH_DARK_REFLECTIONS: nFocus = FEAT_PATH_FOCUS_DARK_REFLECTIONS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_DARK_REFLECTIONS ; break; - case PATH_EBON_ROADS: nFocus = FEAT_PATH_FOCUS_EBON_ROADS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_EBON_ROADS ; break; - case PATH_ELEMENTAL_SHADOWS: nFocus = FEAT_PATH_FOCUS_ELEMENTAL_SHADOWS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_ELEMENTAL_SHADOWS ; break; - case PATH_UNBINDING_SHADE: nFocus = FEAT_PATH_FOCUS_UNBINDING_SHADE ; nGRFocus = FEAT_GREATER_PATH_FOCUS_UNBINDING_SHADE ; break; - case PATH_VEIL_SHADOWS: nFocus = FEAT_PATH_FOCUS_VEIL_SHADOWS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_VEIL_SHADOWS ; break; - case PATH_BREATH_TWILIGHT: nFocus = FEAT_PATH_FOCUS_BREATH_TWILIGHT ; nGRFocus = FEAT_GREATER_PATH_FOCUS_BREATH_TWILIGHT ; break; - case PATH_DARK_METAMORPHOSIS: nFocus = FEAT_PATH_FOCUS_DARK_METAMORPHOSIS; nGRFocus = FEAT_GREATER_PATH_FOCUS_DARK_METAMORPHOSIS; break; - case PATH_EBON_WALLS: nFocus = FEAT_PATH_FOCUS_EBON_WALLS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_EBON_WALLS ; break; - case PATH_EYES_NIGHT_SKY: nFocus = FEAT_PATH_FOCUS_EYES_NIGHT_SKY ; nGRFocus = FEAT_GREATER_PATH_FOCUS_EYES_NIGHT_SKY ; break; - case PATH_HEART_SOUL: nFocus = FEAT_PATH_FOCUS_HEART_SOUL ; nGRFocus = FEAT_GREATER_PATH_FOCUS_HEART_SOUL ; break; - case PATH_SHADOW_CALLING: nFocus = FEAT_PATH_FOCUS_SHADOW_CALLING ; nGRFocus = FEAT_GREATER_PATH_FOCUS_SHADOW_CALLING ; break; - case PATH_NIGHTS_LONG_FINGERS: nFocus = FEAT_PATH_FOCUS_NIGHTS_LONG_FINGERS; nGRFocus = FEAT_GREATER_PATH_FOCUS_NIGHTS_LONG_FINGERS; break; - case PATH_DARKENED_ALLEYS: nFocus = FEAT_PATH_FOCUS_DARKENED_ALLEYS ; nGRFocus = FEAT_GREATER_PATH_FOCUS_DARKENED_ALLEYS ; break; - case PATH_SHADOWSCAPE: nFocus = FEAT_PATH_FOCUS_SHADOWSCAPE ; nGRFocus = FEAT_GREATER_PATH_FOCUS_SHADOWSCAPE ; break; - } - if(GetHasFeat(nFocus, oShadow)) - nReturn = 1; - if(GetHasFeat(nGRFocus, oShadow)) - nReturn = 2; - - //if (DEBUG) DoDebug("GetHasPathFocus() nReturn "+IntToString(nReturn)); - - // If none of those trigger. - return nReturn; -} - -int GetShadowAbilityOfClass(int nClass, int nType) -{ - if (nClass == CLASS_TYPE_SHADOWSMITH) return ABILITY_INTELLIGENCE; - // Intelligence for max mystery known - if (nClass == CLASS_TYPE_SHADOWCASTER && nType == 1) return ABILITY_INTELLIGENCE; - // Charisma for DC - if (nClass == CLASS_TYPE_SHADOWCASTER && nType == 2) return ABILITY_CHARISMA; - - // Technically, never gets here but the compiler does not realise that - return -1; -} - -int GetShadowcasterDC(object oShadow = OBJECT_SELF) -{ - // Things we need for DC Checks - int nMystId = PRCGetSpellId(); - int nShadEvo = GetLocalInt(oShadow, "ShadowEvoking"); - if (nShadEvo > 0) - nMystId = nShadEvo; // This is used to get the proper DC for Shadow Evocation mysteries - - int nLevel = GetMysteryLevel(oShadow, nMystId); - int nClass = GetShadowcastingClass(oShadow); - int nShadow = GetShadowcasterLevel(oShadow); - int nAbi = GetAbilityModifier(GetShadowAbilityOfClass(nClass, 2), oShadow); - int nPath = GetPathByMystery(nMystId); - int nPFocus = GetHasPathFocus(oShadow, nPath); - int nNoct = GetHasNocturnal(oShadow, nPath); - nShadow -= nPFocus; // These don't count here - - // DC is 10 + Mystery level + ability - int nDC = 10 + nLevel + nAbi; - - // If total Shadowcaster level is >= 13, change the DC for level 3 and under mysteries - // DC is 10 + 1/2 Shadowcaster level + ability - if (GetIsMysterySupernatural(oShadow, nMystId, nClass)) - nDC = 10 + nShadow/2 + nAbi; - - nDC += nPFocus; - nDC += nNoct;// It's a 0 if it doesn't exist - - return nDC; -} - -int ShadowSRPen(object oShadow, int nShadowcasterLevel) -{ - return nShadowcasterLevel; -} - -void SetLocalMystery(object oObject, string sName, struct mystery myst) -{ - //SetLocal (oObject, sName + "_", ); - SetLocalObject(oObject, sName + "_oShadow", myst.oShadow); - - SetLocalInt(oObject, sName + "_bCanMyst", myst.bCanMyst); - SetLocalInt(oObject, sName + "_nShadowcasterLevel", myst.nShadowcasterLevel); - SetLocalInt(oObject, sName + "_nMystId", myst.nMystId); - SetLocalInt(oObject, sName + "_nPen", myst.nPen); - SetLocalInt(oObject, sName + "_bIgnoreSR", myst.bIgnoreSR); - - SetLocalInt(oObject, sName + "_bEmpower", myst.bEmpower); - SetLocalInt(oObject, sName + "_bExtend", myst.bExtend); - SetLocalInt(oObject, sName + "_bMaximize", myst.bMaximize); - SetLocalInt(oObject, sName + "_bQuicken", myst.bQuicken); - - SetLocalInt(oObject, sName + "_nSaveDC", myst.nSaveDC); - SetLocalFloat(oObject, sName + "_fDur", myst.fDur); -} - -struct mystery GetLocalMystery(object oObject, string sName) -{ - struct mystery myst; - myst.oShadow = GetLocalObject(oObject, sName + "_oShadow"); - - myst.bCanMyst = GetLocalInt(oObject, sName + "_bCanMyst"); - myst.nShadowcasterLevel = GetLocalInt(oObject, sName + "_nShadowcasterLevel"); - myst.nMystId = GetLocalInt(oObject, sName + "_nMystId"); - myst.nPen = GetLocalInt(oObject, sName + "_nPen"); - myst.bIgnoreSR = GetLocalInt(oObject, sName + "_bIgnoreSR"); - - myst.bEmpower = GetLocalInt(oObject, sName + "_bEmpower"); - myst.bExtend = GetLocalInt(oObject, sName + "_bExtend"); - myst.bMaximize = GetLocalInt(oObject, sName + "_bMaximize"); - myst.bQuicken = GetLocalInt(oObject, sName + "_bQuicken"); - - myst.nSaveDC = GetLocalInt(oObject, sName + "_nSaveDC"); - myst.fDur = GetLocalFloat(oObject, sName + "_fDur"); - - return myst; -} - -int ShadowcastingFeats(object oShadow, int nMyst) -{ - int nReturn = 0; - int nPath = GetPathByMystery(nMyst); - nReturn += GetHasPathFocus(oShadow, nPath); - - return nReturn; -} - -int GetHasNocturnal(object oShadow, int nPath) -{ - int nNocturnal, nReturn; - switch(nPath) - { - case PATH_CLOAK_SHADOWS: nNocturnal = FEAT_NOCTURNAL_CASTER_CLOAK_SHADOWS ; break; - case PATH_DARK_TERRAIN: nNocturnal = FEAT_NOCTURNAL_CASTER_DARK_TERRAIN ; break; - case PATH_EBON_WHISPERS: nNocturnal = FEAT_NOCTURNAL_CASTER_EBON_WHISPERS ; break; - case PATH_EYES_DARKNESS: nNocturnal = FEAT_NOCTURNAL_CASTER_EYES_DARKNESS ; break; - case PATH_SHUTTERS_CLOUDS: nNocturnal = FEAT_NOCTURNAL_CASTER_SHUTTERS_CLOUDS ; break; - case PATH_TOUCH_TWILIGHT: nNocturnal = FEAT_NOCTURNAL_CASTER_TOUCH_TWILIGHT ; break; - case PATH_UMBRAL_MIND: nNocturnal = FEAT_NOCTURNAL_CASTER_UMBRAL_MIND ; break; - case PATH_BLACK_MAGIC: nNocturnal = FEAT_NOCTURNAL_CASTER_BLACK_MAGIC ; break; - case PATH_BODY_SOUL: nNocturnal = FEAT_NOCTURNAL_CASTER_BODY_SOUL ; break; - case PATH_DARK_REFLECTIONS: nNocturnal = FEAT_NOCTURNAL_CASTER_DARK_REFLECTIONS ; break; - case PATH_EBON_ROADS: nNocturnal = FEAT_NOCTURNAL_CASTER_EBON_ROADS ; break; - case PATH_ELEMENTAL_SHADOWS: nNocturnal = FEAT_NOCTURNAL_CASTER_ELEMENTAL_SHADOWS ; break; - case PATH_UNBINDING_SHADE: nNocturnal = FEAT_NOCTURNAL_CASTER_UNBINDING_SHADE ; break; - case PATH_VEIL_SHADOWS: nNocturnal = FEAT_NOCTURNAL_CASTER_VEIL_SHADOWS ; break; - case PATH_BREATH_TWILIGHT: nNocturnal = FEAT_NOCTURNAL_CASTER_BREATH_TWILIGHT ; break; - case PATH_DARK_METAMORPHOSIS: nNocturnal = FEAT_NOCTURNAL_CASTER_DARK_METAMORPHOSIS; break; - case PATH_EBON_WALLS: nNocturnal = FEAT_NOCTURNAL_CASTER_EBON_WALLS ; break; - case PATH_EYES_NIGHT_SKY: nNocturnal = FEAT_NOCTURNAL_CASTER_EYES_NIGHT_SKY ; break; - case PATH_HEART_SOUL: nNocturnal = FEAT_NOCTURNAL_CASTER_HEART_SOUL ; break; - case PATH_SHADOW_CALLING: nNocturnal = FEAT_NOCTURNAL_CASTER_SHADOW_CALLING ; break; - case PATH_NIGHTS_LONG_FINGERS:nNocturnal = FEAT_NOCTURNAL_CASTER_NIGHTS_LONG_FINGERS; break; - case PATH_DARKENED_ALLEYS: nNocturnal = FEAT_NOCTURNAL_CASTER_DARKENED_ALLEYS ; break; - case PATH_SHADOWSCAPE: nNocturnal = FEAT_NOCTURNAL_CASTER_SHADOWSCAPE ; break; - } - if(GetHasFeat(nNocturnal, oShadow) && GetIsNight()) - nReturn = 1; - - // If none of those trigger. - return nReturn; -} \ No newline at end of file diff --git a/trunk/include/tob_inc_recovery.nss b/trunk/include/tob_inc_recovery.nss deleted file mode 100644 index 9517730f..00000000 --- a/trunk/include/tob_inc_recovery.nss +++ /dev/null @@ -1,652 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Tome of Battle include: Maneuver Recovery -//:: tob_inc_martlore -//:://///////////////////////////////////////////// -/** @file - Defines various functions and other stuff that - do something related to recovery and readying maneuvers - See page #28 of Tome of Battle - - Functions below are called by the initiator as - he makes a maneuver, or when recovering or readying - - @author Stratovarius - @date Created - 2007.3.25 -*/ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/10 - -//:: Test Void -//void main (){} - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -const int MANEUVER_READIED = 1; -const int MANEUVER_RECOVERED = 2; -const int MANEUVER_GRANTED = 3; -const int MANEVUER_WITHHELD = 4; - -const string _MANEUVER_LIST_RDYMODIFIER = "_ReadyModifier"; - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Gets the number of Maneuvers a character has readied - * - * @param oPC The creature whose Maneuvers to check - * @param nList The list to check. One of MANEUVER_LIST_* - * @return The number of Maneuvers readied - */ -int GetReadiedCount(object oPC, int nList); - -/** - * Gets the maximum number of Maneuvers a character may ready. - * - * @param oPC Character to determine maximum Maneuvers readied - * @param nList MANEUVER_LIST_* of the list to determine maximum Maneuvers for - * @return Maximum number of Maneuvers that oPC may ready - */ -int GetMaxReadiedCount(object oPC, int nList); - -/** - * Gets the value of the Maneuvers readied modifier, which is a value that is added - * to the 2da-specified maximum Maneuvers readied to determine the actual maximum. - * - * @param oCreature The creature whose modifier to get - * @param nList The list the maximum Maneuvers readied from which the modifier - * modifies. One of MANEUVER_LIST_* - */ -int GetReadiedManeuversModifier(object oCreature, int nList); - -/** - * Sets the value of the Maneuvers readied modifier, which is a value that is added - * to the 2da-specified maximum Maneuvers readied to determine the actual maximum. - * - * @param oCreature The creature whose modifier to set - * @param nList The list the maximum Maneuvers readied from which the modifier - * modifies. One of MANEUVER_LIST_* - */ -void SetReadiedManeuversModifier(object oCreature, int nList, int nNewValue); - -/** - * Readies the chosen Maneuver. Also checks to see if there are any slots left - * - * @param oPC Character readying maneuver - * @param nList MANEUVER_LIST_* of the list to ready - * @param nMoveId Maneuver to ready - */ -void ReadyManeuver(object oPC, int nList, int nMoveId); - -/** - * Returns whether maneuver is readied or not - * - * @param oPC Character to check - * @param nList MANEUVER_LIST_* - * @param nMoveId Maneuver to check - * @return TRUE or FALSE - */ -int GetIsManeuverReadied(object oPC, int nList, int nMoveId); - -/** - * Returns whether maneuver is expended or not - * - * @param oPC Character to check - * @param nList MANEUVER_LIST_* - * @param nMoveId Maneuver to check - * @return TRUE or FALSE - */ -int GetIsManeuverExpended(object oPC, int nList, int nMoveId); - -/** - * Expends the chosen Maneuver. - * - * @param oPC Character to check - * @param nList MANEUVER_LIST_* - * @param nMoveId Maneuver to expend - */ -void ExpendManeuver(object oPC, int nList, int nMoveId); - -/** - * Clears all local ints marking maneuvers as expended - * - * @param oPC Character to clear - * @param nList MANEUVER_LIST_* - */ -void RecoverExpendedManeuvers(object oPC, int nList); - -/** - * Recovers the chosen Maneuver. - * - * @param oPC Character to check - * @param nList MANEUVER_LIST_* - * @param nMoveId Maneuver to recover - */ -void RecoverManeuver(object oPC, int nList, int nMoveId); - -/** - * Checks to see if the PC is in a Warblade recovery round - * This prevents all use of maneuvers or stances during that round. - * - * @param oPC Character to clear - * @return TRUE or FALSE - */ -int GetIsWarbladeRecoveryRound(object oPC); - -/** - * Marks maneuvers as granted or withheld. - * - * @param oPC Character to grant maneuvers to - * @param nList MANEUVER_LIST_* - */ -void GrantManeuvers(object oPC, int nList); - -/** - * Clears all local ints marking maneuvers as readied - * - * @param oPC Character to clear - * @param nList MANEUVER_LIST_* - */ -void ClearReadiedManeuvers(object oPC, int nList); - -/** - * Grants a withheld maneuver - * Only works on Crusaders - * - * @param oPC Character to grant maneuvers to - * @param nList MANEUVER_LIST_* - * @param nMoveId Maneuver to grant - */ -void GrantWithheldManeuver(object oPC, int nList, int nMoveId = -1); - -/** - * Returns whether maneuver is granted or not - * Only works on Crusaders - * - * @param oPC Character to check - * @param nMoveId Maneuver to check - * @return TRUE or FALSE - */ -int GetIsManeuverGranted(object oPC, int nMoveId); - -/** - * Clears all local ints marking maneuvers as granted or withheld - * Only works on Crusaders - * - * @param oPC Character to clear - */ -void ClearGrantedWithheldManeuvers(object oPC); - -/** - * Starting function for Crusader recovery, calls DoCrusaderGranting - * Only works on Crusaders - * - * @param oPC Crusader - */ -void BeginCrusaderGranting(object oPC); - -/** - * Recursive function granting maneuvers each round in combat - * Will end when combat ends - * Only works on Crusaders - * - * @param oPC Crusader - * @param nTrip Round of combat. Takes values from 1 to 5, always starts with 1. - */ -void DoCrusaderGranting(object oPC, int nTrip); - - -/** - * Returns TRUE if a maneuver was expended, FALSE otherwise - * @param oPC Character to check - * @param nList MANEUVER_LIST_* - * @param nDiscipline DISCIPLINE_* the maneuver has to be from - * - * @return TRUE or FALSE - */ -int ExpendRandomManeuver(object oPC, int nList, int nDiscipline = -1); - -/** - * Clears all local ints marking maneuvers as expended - * - * @param oPC Character to clear - * @param nPRC Specific PRC to recover, else all. - */ -void RecoverPrCAbilities(object oPC); - -/** - * Heals 3 + 1 point per character level ones per minute - * - * @param oPC Character to heal - */ -void VitalRecovery(object oPC); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "inc_lookups" -#include "tob_inc_tobfunc" - -////////////////////////////////////////////////// -/* Internal functions */ -////////////////////////////////////////////////// - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetReadiedCount(object oPC, int nList) -{ - return GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList)); -} - -int GetMaxReadiedCount(object oPC, int nList) -{ - int nLevel = GetLevelByClass(nList, oPC); - // 2das start at Row 0 - int nMaxReadied = StringToInt(Get2DACache(GetAMSKnownFileName(nList), "ManeuversReadied", nLevel-1)); - // Add in the custom modifier - nMaxReadied += GetReadiedManeuversModifier(oPC, nList); - if(nList == MANEUVER_LIST_SWORDSAGE) - nMaxReadied += GetHasFeat(FEAT_EXTRA_GRANTED_MANEUVER, oPC); - - if(DEBUG) DoDebug("tob_inc_recovery: MaxManeuvers Readied: " +IntToString(nMaxReadied)); - return nMaxReadied; -} - -int GetReadiedManeuversModifier(object oCreature, int nList) -{ - return GetPersistantLocalInt(oCreature, _MANEUVER_LIST_NAME_BASE + IntToString(nList) + _MANEUVER_LIST_RDYMODIFIER); -} - -void SetReadiedManeuversModifier(object oCreature, int nList, int nNewValue) -{ - SetPersistantLocalInt(oCreature, _MANEUVER_LIST_NAME_BASE + IntToString(nList) + _MANEUVER_LIST_RDYMODIFIER, nNewValue); -} - -void ReadyManeuver(object oPC, int nList, int nMoveId) -{ - int nCount = GetReadiedCount(oPC, nList); - int nMaxCount = GetMaxReadiedCount(oPC, nList); - - // If the PC can ready a maneuver and hasn't filled them all up - if(nMaxCount > nCount) - { - nCount++; - SetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(nCount), nMoveId); - SetLocalInt(oPC, "ManeuverReadied" + IntToString(nList), nCount); - if(DEBUG) DoDebug("tob_inc_recovery: ReadyManeuver: " +IntToString(nMoveId)); - } - else - FloatingTextStringOnCreature("All maneuvers are readied", oPC, FALSE); -} - -int GetIsManeuverReadied(object oPC, int nList, int nMoveId) -{ - // Counting through the local ints to determine if this one is readied - int i, nMax = GetReadiedCount(oPC, nList); - for(i = 1; i <= nMax; i++) - { - // If the value is valid, return true - if(GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i)) == nMoveId) - { - if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverReadied: " + IntToString(nMoveId)); - return TRUE; - } - } - return FALSE; -} - -int GetIsManeuverExpended(object oPC, int nList, int nMoveId) -{ - // Counting through the local ints to determine if this one is expended - int i, nMax = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList)); - for(i = 1; i <= nMax; i++) - { - // returns if the maneuver is expended - if(GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i)) == nMoveId) - { - if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverExpended: " +IntToString(nMoveId)); - return TRUE; - } - } - return FALSE; -} - -void ExpendManeuver(object oPC, int nList, int nMoveId) -{ - int nCount = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList)) + 1; - - // This will mark the Maneuver Expended - SetLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(nCount), nMoveId); - SetLocalInt(oPC, "ManeuverExpended" + IntToString(nList), nCount); - if(DEBUG) DoDebug("tob_inc_recovery: Expending Maneuver: " + IntToString(nMoveId)); -} - -void RecoverExpendedManeuvers(object oPC, int nList) -{ - if(DEBUG) DoDebug("tob_inc_recovery: Clearing expended maneuvers"); - // Counting through the local ints to clear them all - int i, nMax = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList)); - DeleteLocalInt(oPC, "ManeuverExpended" + IntToString(nList)); - for(i = 1; i <= nMax; i++) - { - // Clear them all - DeleteLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i)); - } - // Do Grant/Withheld Maneuvers whenever this is called on a Crusader - if (nList == MANEUVER_LIST_CRUSADER) - { - // Make sure to clear them all first - ClearGrantedWithheldManeuvers(oPC); - // Then re-grant/withhold them - GrantManeuvers(oPC, nList); - } - if (GetHasFeat(FEAT_VITAL_RECOVERY, oPC)) VitalRecovery(oPC); -} - -void RecoverManeuver(object oPC, int nList, int nMoveId) -{ - // Counting through the local ints to determine if this one is expended - int i, nMax = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList)); - for(i = 1; i <= nMax; i++) - { - // If it has been expended, clear that - if(GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i)) == nMoveId) - { - DeleteLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i)); - if(DEBUG) DoDebug("tob_inc_recovery: Recovering Maneuver: " + IntToString(nMoveId)); - } - } - if (GetHasFeat(FEAT_VITAL_RECOVERY, oPC)) VitalRecovery(oPC); -} - -int GetIsWarbladeRecoveryRound(object oPC) -{ - if(DEBUG) DoDebug("tob_inc_recovery: Warblade recovery check"); - return GetLocalInt(oPC, "WarbladeRecoveryRound"); -} - -void GrantRandomManeuver(object oPC, int nList = MANEUVER_LIST_CRUSADER) -{ - int nMax = GetLocalInt(oPC, "GrantRand#"); - if(!nMax) return;//nothing to grant - - SetLocalInt(oPC, "GrantRand#", nMax - 1); - int x = Random(nMax)+1; - int nMoveId = GetLocalInt(oPC, "GrantRand#" + IntToString(x)); - if(x != nMax) - SetLocalInt(oPC, "GrantRand#" + IntToString(x), GetLocalInt(oPC, "GrantRand#" + IntToString(nMax))); - DeleteLocalInt(oPC, "GrantRand#" + IntToString(nMax)); - - //GrantWithheldManeuver(oPC, MANEUVER_LIST_CRUSADER, MoveId); - // No point in granting an expended maneuver - if(GetIsManeuverExpended(oPC, nList, nMoveId)) - RecoverManeuver(oPC, nList, nMoveId); - - int i = 1; - while(i) - { - // If it hits a non-valid, break - if(!GetLocalInt(oPC, "ManeuverGranted" + IntToString(i))) break; - i++; - } - SetLocalInt(oPC, "ManeuverGranted" + IntToString(i), nMoveId); -} - -void ListGrantedManeuvers(object oPC) -{ - int i; - for(i = 1; i <= 4; i++) - { - int nMoveId = GetLocalInt(oPC, "ManeuverGranted" + IntToString(i)); - int nExpended = GetIsManeuverExpended(oPC, MANEUVER_LIST_CRUSADER, nMoveId); - if (nMoveId > 0 && !nExpended) FloatingTextStringOnCreature(GetManeuverName(nMoveId) + " is granted", oPC, FALSE); - } -} - -void GrantManeuvers(object oPC, int nList = MANEUVER_LIST_CRUSADER) -{ - // Only crusader level matters for this - int nLevel = GetLevelByClass(CLASS_TYPE_CRUSADER, oPC); - // 2das start at Row 0 - int nGranted = StringToInt(Get2DACache(GetAMSKnownFileName(nList), "ManeuversGranted", nLevel-1)); - nGranted += GetReadiedManeuversModifier(oPC, nList); - nGranted += GetHasFeat(FEAT_EXTRA_GRANTED_MANEUVER, oPC); - - // Counting through the local ints to determine how many are readied - int i, nMaxReadied = GetReadiedCount(oPC, nList); - SetLocalInt(oPC, "GrantRand#", nMaxReadied); - for(i = 1; i <= nMaxReadied; i++) - { - // build temporary array for GrantRandomManeuver() function - int nMoveId = GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i)); - if(nMoveId) - SetLocalInt(oPC, "GrantRand#" + IntToString(i), nMoveId); - } - for(i = 1; i <= nGranted; i++) - { - GrantRandomManeuver(oPC); - } - ListGrantedManeuvers(oPC); -} - -void ClearReadiedManeuvers(object oPC, int nList) -{ - if(DEBUG) DoDebug("tob_inc_recovery: Clearing readied maneuvers"); - // Counting through the local ints to clear them all - int i, nMax = GetReadiedCount(oPC, nList); - DeleteLocalInt(oPC, "ManeuverReadied" + IntToString(nList)); - for(i = 1; i <= nMax; i++) - { - // Clear them all - DeleteLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i)); - } -} - -/*void GrantWithheldManeuver(object oPC, int nList, int nMoveId = -1) -{ - int i; - string sPsiFile = GetAMSKnownFileName(nList); - // 2das start at Row 0 - int nLevel = GetInitiatorLevel(oPC, nList); - int nGranted = StringToInt(Get2DACache(sPsiFile, "ManeuversGranted", nLevel-1)); - int nReadied = StringToInt(Get2DACache(sPsiFile, "ManeuversReadied", nLevel-1)); - if(DEBUG) DoDebug("tob_inc_recovery: Maneuvers Granted: " + IntToString(nGranted)); - if(DEBUG) DoDebug("tob_inc_recovery: Maneuvers Readied: " + IntToString(nReadied)); - - // If someone input a maneuver - if (nMoveId > 0) - { - // No point in granting an expended maneuver - if (GetIsManeuverExpended(oPC, nList, nMoveId)) - RecoverManeuver(oPC, nList, nMoveId); - - // 3 is always the number withheld - for(i = nGranted; i < nReadied; i++) - { - // Making sure it gets marked properly - int nGrantId = GetLocalInt(oPC, "ManeuverWithheld" + IntToString(i)); - // If it exists, mark it as ready and break out - if (nMoveId == nGrantId) - { - if(DEBUG) DoDebug("tob_inc_recovery: Withheld Maneuver Granted: " + IntToString(nMoveId)); - DeleteLocalInt(oPC, "ManeuverWithheld" + IntToString(i)); - FloatingTextStringOnCreature(GetManeuverName(nMoveId) + " is granted", oPC, FALSE); - SetLocalInt(oPC, "ManeuverGranted" + IntToString(i), nMoveId); - break; - } - } - } - else - { - // 3 is always the number withheld - for(i = nGranted; i < nReadied; i++) - { - nMoveId = GetLocalInt(oPC, "ManeuverWithheld" + IntToString(i)); - // If it exists, mark it as ready and break out - if (nMoveId > 0) - { - if(DEBUG) DoDebug("tob_inc_recovery: Withheld Maneuver Granted: " + IntToString(nMoveId)); - DeleteLocalInt(oPC, "ManeuverWithheld" + IntToString(i)); - FloatingTextStringOnCreature(GetManeuverName(nMoveId) + " is granted", oPC, FALSE); - SetLocalInt(oPC, "ManeuverGranted" + IntToString(i), nMoveId); - break; - } - } - } -}*/ - -int GetIsManeuverGranted(object oPC, int nMoveId) -{ - if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverGranted Start"); - // Counting through the local ints to determine if this one is expended - int i, nMax = GetReadiedCount(oPC, MANEUVER_LIST_CRUSADER); - for(i = 1; i <= nMax; i++) - { - // returns if the maneuver is expended - if(GetLocalInt(oPC, "ManeuverGranted" + IntToString(i)) == nMoveId) - { - if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverGranted: " + IntToString(nMoveId)); - return TRUE; - } - } - return FALSE; -} - -void ClearGrantedWithheldManeuvers(object oPC) -{ - if(DEBUG) DoDebug("tob_inc_recovery: Clearing Granted and Withheld Maneuvers"); - // Counting through the local ints to clear them all - int i, nMax = GetReadiedCount(oPC, MANEUVER_LIST_CRUSADER); - for(i = 1; i <= nMax; i++) - { - // Clear them all - DeleteLocalInt(oPC, "ManeuverGranted" + IntToString(i)); - } -} - -void BeginCrusaderGranting(object oPC) -{ - if(DEBUG) DoDebug("BeginCrusaderGranting(): Entered Function"); - // Stops it from being called more than once. - if(GetLocalInt(oPC, "CrusaderGrantLoop")) return; - SetLocalInt(oPC, "CrusaderGrantLoop", TRUE); - - // Starts the granting process - if(DEBUG) DoDebug("BeginCrusaderGranting(): DoCrusaderGranting called"); - DoCrusaderGranting(oPC, 1); -} - -void DoCrusaderGranting(object oPC, int nTrip) -{ - if(DEBUG) DoDebug("DoCrusaderGranting(): Entered Function on Round #" + IntToString(nTrip)); - // First round of combat, no granting. - // Last round of the 5, clear and recover/grant maneuvers - if (nTrip >= 5) // Granted maneuvers empty, restart - { - if(DEBUG) DoDebug("DoCrusaderGranting(): RecoverExpendedManeuvers"); - RecoverExpendedManeuvers(oPC, MANEUVER_LIST_CRUSADER); - nTrip = 1; - } - else if (nTrip > 1) - { - // Rounds 2-4, grant a single maneuver - if(DEBUG) DoDebug("DoCrusaderGranting(): GrantWithheldManeuver"); - //GrantWithheldManeuver(oPC, MANEUVER_LIST_CRUSADER); - GrantRandomManeuver(oPC); - ListGrantedManeuvers(oPC); - } - - if(DEBUG) DoDebug("DoCrusaderGranting(): Above Recursive"); - // If in combat, keep the loop going - if (GetIsInCombat(oPC)) - { - if(DEBUG) DoDebug("DoCrusaderGranting(): In Combat"); - DelayCommand(6.0, DoCrusaderGranting(oPC, ++nTrip)); // Increment counter - } - else // Recover and stop loop otherwise. - { - if(DEBUG) DoDebug("DoCrusaderGranting(): Out of Combat Maneuver Recovery"); - RecoverExpendedManeuvers(oPC, MANEUVER_LIST_CRUSADER); - // Resent Int for next time out - DeleteLocalInt(oPC, "CrusaderGrantLoop"); - } - if(DEBUG) DoDebug("DoCrusaderGranting(): Ending"); -} - -int ExpendRandomManeuver(object oPC, int nList, int nDiscipline = -1) -{ - // Counting through the local ints to determine if maneuver can be expended - int i, nMax = GetReadiedCount(oPC, nList); - for(i = 1; i <= nMax; i++) - { - // If the value is valid, next step - int nMoveId = GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i)); - if(nMoveId > 0) - { - // Make sure the disciplines match - if(nDiscipline == -1 || GetDisciplineByManeuver(nMoveId) == nDiscipline) - { - // If not expended - if(!GetIsManeuverExpended(oPC, nList, nMoveId)) - { - // Expend the damn thing and go home - ExpendManeuver(oPC, nList, nMoveId); - return TRUE; - } - } - } - } - - // If we're here, failed. - return FALSE; -} - -void RecoverPrCAbilities(object oPC) -{ - int i; - for(i = 2; i <= 8; i++) // PrC abilities: check last seven slots - { - int nClass = GetClassByPosition(i, oPC); - if(DEBUG) DoDebug("RecoverPrCAbilities" + IntToString(nClass)); - switch(nClass) - { - case CLASS_TYPE_INVALID: - if(DEBUG) DoDebug("RecoverPrCAbilities: no class to recover"); - break; - case CLASS_TYPE_JADE_PHOENIX_MAGE: - DeleteLocalInt(oPC, "JPM_Empowering_Strike_Expended"); - DeleteLocalInt(oPC, "JPM_Quickening_Strike_Expended"); - break; - case CLASS_TYPE_DEEPSTONE_SENTINEL: - DeleteLocalInt(oPC, "DPST_Awaken_Stone_Dragon_Expended"); - break; - case CLASS_TYPE_ETERNAL_BLADE: - DeleteLocalInt(oPC, "ETBL_Eternal_Training_Expended"); - DeleteLocalInt(oPC, "ETBL_Island_In_Time_Expended"); - // Remove bonus to racial type from eternal training - PRCRemoveEffectsFromSpell(oPC, ETBL_RACIAL_TYPE); - break; - } - } -} - -void VitalRecovery(object oPC) -{ - if (GetLocalInt(oPC, "VitalRecovery")) return; //Once a minute - int nHD = GetHitDice(oPC); - effect eHeal = EffectHeal(nHD+3); // That's it - effect eVis = EffectVisualEffect(VFX_IMP_HEALING_M); - ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC); - ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC); - - SetLocalInt(oPC, "VitalRecovery", TRUE); - DelayCommand(60.0, DeleteLocalInt(oPC, "VitalRecovery")); -} \ No newline at end of file diff --git a/trunk/include/tob_inc_tobfunc.nss b/trunk/include/tob_inc_tobfunc.nss deleted file mode 100644 index 04230160..00000000 --- a/trunk/include/tob_inc_tobfunc.nss +++ /dev/null @@ -1,1261 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Tome of Battle include: Miscellaneous -//:: tob_inc_tobfunc -//:://///////////////////////////////////////////// -/** @file - Defines various functions and other stuff that - do something related to the Tome of Battle implementation. - - Also acts as inclusion nexus for the general - tome of battle includes. In other words, don't include - them directly in your scripts, instead include this. - - @author Stratovarius - @date Created - 2007.3.19 -*/ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/11 - -//:: Test Void -//void main (){} - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - -const int DISCIPLINE_DESERT_WIND = 1; -const int DISCIPLINE_DEVOTED_SPIRIT = 2; -const int DISCIPLINE_DIAMOND_MIND = 4; -const int DISCIPLINE_IRON_HEART = 8; -const int DISCIPLINE_SETTING_SUN = 16; -const int DISCIPLINE_SHADOW_HAND = 32; -const int DISCIPLINE_STONE_DRAGON = 64; -const int DISCIPLINE_TIGER_CLAW = 128; -const int DISCIPLINE_WHITE_RAVEN = 256; - -const string PRC_INITIATING_CLASS = "PRC_CurrentManeuver_InitiatingClass"; -const string PRC_MANEUVER_LEVEL = "PRC_CurrentManeuver_Level"; - -const int MANEUVER_TYPE_STANCE = 1; -const int MANEUVER_TYPE_STRIKE = 2; -const int MANEUVER_TYPE_COUNTER = 3; -const int MANEUVER_TYPE_BOOST = 4; -//global constant (strike & counter & boost) -const int MANEUVER_TYPE_MANEUVER = 5; - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Determines from what class's maneuver list the currently being initiated - * maneuver is initiated from. - * - * @param oInitiator A creature initiating a maneuver at this moment - * @return CLASS_TYPE_* constant of the class - */ -int GetInitiatingClass(object oInitiator = OBJECT_SELF); - -/** - * Determines the given creature's Initiator level. If a class is specified, - * then returns the Initiator level for that class. Otherwise, returns - * the Initiator level for the currently active maneuver. - * - * @param oInitiator The creature whose Initiator level to determine - * @param nSpecificClass The class to determine the creature's Initiator - * level in. - * DEFAULT: CLASS_TYPE_INVALID, which means the creature's - * Initiator level in regards to an ongoing maneuver - * is determined instead. - * @return The Initiator level - */ -int GetInitiatorLevel(object oInitiator = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID); - -/** - * Determines whether a given creature uses BladeMagic. - * Requires either levels in a BladeMagic-related class or - * natural BladeMagic ability based on race. - * - * @param oCreature Creature to test - * @return TRUE if the creature can use BladeMagics, FALSE otherwise. - */ -int GetIsBladeMagicUser(object oCreature); - -/** - * Determines the given creature's highest undmodified Initiator level among it's - * initiating classes. - * - * @param oCreature Creature whose highest Initiator level to determine - * @return The highest unmodified Initiator level the creature can have - */ -int GetHighestInitiatorLevel(object oCreature); - -/** - * Determines whether a given class is a BladeMagic-related class or not. - * - * @param nClass CLASS_TYPE_* of the class to test - * @return TRUE if the class is a BladeMagic-related class, FALSE otherwise - */ -int GetIsBladeMagicClass(int nClass); - -/** - * Gets the level of the maneuver being currently initiated or the level - * of the maneuver ID passed to it. - * - * @param oInitiator The creature currently initiating a maneuver - * @return The level of the maneuver being initiated - */ -int GetManeuverLevel(object oInitiator, int nMoveId = 0); - -/** - * Returns the type of the maneuver - * - * @param nSpellId SpellId of the maneuver - */ -int GetManeuverType(int nSpellId); - -/** - * Returns the name of the maneuver - * - * @param nSpellId SpellId of the maneuver - */ -string GetManeuverName(int nSpellId); - -/** - * Returns the name of the Discipline - * - * @param nDiscipline DISCIPLINE_* to name - */ -string GetDisciplineName(int nDiscipline); - -/** - * Returns the Discipline the maneuver is in - * @param nMoveId maneuver to check - * - * @return DISCIPLINE_* - */ -int GetDisciplineByManeuver(int nMoveId); - -/** - * Returns true or false if the initiator has the Discipline - * @param oInitiator Person to check - * @param nDiscipline Discipline to check - * - * @return TRUE or FALSE - */ -int TOBGetHasDiscipline(object oInitiator, int nDiscipline); - -/** - * Returns true or false if the swordsage has Discipline - * focus in the chosen discipline - * @param oInitiator Person to check - * @param nDiscipline Discipline to check - * - * @return TRUE or FALSE - */ -int TOBGetHasDisciplineFocus(object oInitiator, int nDiscipline); - -/** - * Calculates how many initiator levels are gained by a given creature from - * it's levels in prestige classes. - * - * @param oCreature Creature to calculate added initiator levels for - * @return The number of initiator levels gained - */ -int GetBladeMagicPRCLevels(object oInitiator); - -/** - * Determines which of the character's classes is their highest or first blade magic - * initiating class, if any. This is the one which gains initiator level raise benefits - * from prestige classes. - * - * @param oCreature Creature whose classes to test - * @return CLASS_TYPE_* of the first blade magic initiating class, - * CLASS_TYPE_INVALID if the creature does not possess any. - */ -int GetPrimaryBladeMagicClass(object oCreature = OBJECT_SELF); - -/** - * Determines the position of a creature's first blade magic initiating class, if any. - * - * @param oCreature Creature whose classes to test - * @return The position of the first blade magic class {1, 2, 3} or 0 if - * the creature possesses no levels in blade magic classes. - */ -int GetFirstBladeMagicClassPosition(object oCreature = OBJECT_SELF); - -/** - * Checks whether the PC has the prereqs for the maneuver - * - * @param nClass The class that is trying to learn the feat - * @param nFeat The maneuver's FeatId - * @param oPC The creature whose feats to check - * @return TRUE if the PC possesses the prerequisite feats AND does not - * already posses nFeat, FALSE otherwise. - */ -int CheckManeuverPrereqs(int nClass, int nPrereqs, int nDiscipline, object oPC); - -/** - * Checks whether the maneuver is supernatural or not - * Mainly used to check for AMF areas. - * Mostly from Swordsage maneuvers - * - * @param nMoveId The Maneuver to Check - * @return TRUE if Maneuver is (Su), else FALSE - */ -int GetIsManeuverSupernatural(int nMoveId); - -/** - * Checks whether the initiator has an active stance - * - * @param oInitiator The Initiator - * @return The SpellId or FALSE - */ -int GetHasActiveStance(object oInitiator); - -/** - * Clears spell effects for Stances - * Will NOT clear nDontClearMove - * - * @param oInitiator The Initiator - * @param nDontClearMove A single Stance not to clear - */ -void ClearStances(object oInitiator, int nDontClearMove); - -/** - * Marks a stance active via local ints - * - * @param oInitiator The Initiator - * @param nStance The stance to mark active - */ -void MarkStanceActive(object oInitiator, int nStance); - -/** - * This will take an effect that is supposed to be based on size - * And use vs racial effects to approximate it - * - * @param oInitiator The Initiator - * @param eEffect The effect to scale - * @param nSize 0 affects creature one size or more smaller. - * 1 affects creatures one size or more larger - */ -effect VersusSizeEffect(object oInitiator, effect eEffect, int nSize); - -/** - * Checks every 6 seconds whether an adept has moved too far for a stance - * Or whether the adept has moved far enough to get a bonus from a stance - * - * @param oPC The Initiator - * @param nMoveId The stance - * @param fFeet The distance to check - */ -void InitiatorMovementCheck(object oPC, int nMoveId, float fFeet = 10.0); - -/** - * Checks whether the maneuver is a stance - * - * @param nMoveId The Maneuver - * @return TRUE or FALSE - */ -int GetIsStance(int nMoveId); - -/** - * Sets up everything for the Damage boosts (xd6 + IL fire damage) - * That the Desert Wind discipline has. - * - * @param oPC The PC - */ -void DoDesertWindBoost(object oPC); - -/** - * Determines which PC in the area is weakest, and - * returns that PC. - * - * @param oPC The PC - * @param fDistance The distance to check in feet - * @return The Target - */ -object GetCrusaderHealTarget(object oPC, float fDistance); - -/** - * Returns true or false if the swordsage has Insightful Strike in the chosen discipline - * @param oInitiator Person to check - * - * @return TRUE or FALSE - */ -int GetHasInsightfulStrike(object oInitiator); - -/** - * Returns true or false if the swordsage has Defensive Stance - * ONLY CALL THIS FROM WITHIN STANCES - * @param oInitiator Person to check - * @param nDiscipline DISCIPLINE_ constant of the school of the maneuver. - * - * @return TRUE or FALSE - */ -int GetHasDefensiveStance(object oInitiator, int nDiscipline); - -/** - * Returns true if it is a weapon of the appropriate discipline - * @param oWeapon Weapon to check - * @param nDiscipline DISCIPLINE_ constant of the school of the maneuver. - * - * @return TRUE or FALSE - */ -int GetIsDisciplineWeapon(object oWeapon, int nDiscipline); - -/** - * Returns a numerical bonus to attacks for use in strikes - * @param oInitiator Person to check - * @param nDiscipline DISCIPLINE_ constant of the school of the maneuver. - * @param nClass CLASS_TYPE_ constant - * - * @return Bonus total - */ -int TOBSituationalAttackBonuses(object oInitiator, int nDiscipline, int nClass = CLASS_TYPE_INVALID); - -/** - * Returns the skill for the named discipline - * @param nDiscipline DISCIPLINE_ constant - * - * @return Discipline skill - */ -int GetDisciplineSkill(int nDiscipline); - -/** - * Returns the discipline for the Blade Meditation feat - * @param oInitiator Person to check - * - * @return DISCIPLINE_ constant - */ -int BladeMeditationFeat(object oInitiator); - -/** - * Returns 1 if feat and maneuver match - * @param oInitiator Person to check - * @param nMoveId Maneuver to check - * - * @return 1 or -1 - */ -int BladeMeditationDamage(object oInitiator, int nMoveId); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "tob_move_const" -#include "prc_alterations" -#include "tob_inc_moveknwn" - -////////////////////////////////////////////////// -/* Internal functions */ -////////////////////////////////////////////////// - - -int _CheckPrereqsByDiscipline(object oPC, int nDiscipline, int nCount = 1) -{ - int nPrereqCount = GetManeuverCountByDiscipline(oPC, nDiscipline, MANEUVER_TYPE_MANEUVER) - + GetManeuverCountByDiscipline(oPC, nDiscipline, MANEUVER_TYPE_STANCE); - - if(nPrereqCount >= nCount) - return nPrereqCount; - - return 0; -} - -void _RecursiveStanceCheck(object oPC, object oTestWP, int nMoveId, float fFeet = 10.0) -{ - // Seeing if this works better - string sWPTag = "PRC_BMWP_" + GetName(oPC) + IntToString(nMoveId); - oTestWP = GetWaypointByTag(sWPTag); - // Distance moved in the last round - float fDist = FeetToMeters(GetDistanceBetween(oPC, oTestWP)); - // Giving them a little extra distance because of NWN's dance of death - float fCheck = FeetToMeters(fFeet); - if(DEBUG) DoDebug("_RecursiveStanceCheck: fDist: " + FloatToString(fDist)); - if(DEBUG) DoDebug("_RecursiveStanceCheck: fCheck: " + FloatToString(fCheck)); - if(DEBUG) DoDebug("_RecursiveStanceCheck: nMoveId: " + IntToString(nMoveId)); - - - // Moved the distance - if (fDist >= fCheck) - { - if(DEBUG) DoDebug("_RecursiveStanceCheck: fDist > fCheck"); - // Stances that clean up - if (nMoveId == MOVE_SD_STONEFOOT_STANCE) - { - PRCRemoveEffectsFromSpell(oPC, nMoveId); - if(DEBUG) DoDebug("_RecursiveStanceCheck: Moved too far, cancelling stances."); - // Clean up the test WP as well - DestroyObject(oTestWP); - } - // Stances that clean up - else if (nMoveId == MOVE_MOUNTAIN_FORTRESS) - { - PRCRemoveEffectsFromSpell(oPC, nMoveId); - if(DEBUG) DoDebug("_RecursiveStanceCheck: Moved too far, cancelling stances."); - // Clean up the test WP as well - DestroyObject(oTestWP); - } - // Stances that clean up - else if (nMoveId == MOVE_SD_ROOT_MOUNTAIN) - { - PRCRemoveEffectsFromSpell(oPC, nMoveId); - if(DEBUG) DoDebug("_RecursiveStanceCheck: Moved too far, cancelling stances."); - // Clean up the test WP as well - DestroyObject(oTestWP); - } - else if (nMoveId == MOVE_SH_CHILD_SHADOW) - { - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectConcealment(20)), oPC, 6.0); - if(DEBUG) DoDebug("_RecursiveStanceCheck: Applying bonuses."); - // Clean up the test WP - DestroyObject(oTestWP); - // Create waypoint for the movement for next round - CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oPC), FALSE, sWPTag); - } - else if (nMoveId == MOVE_IH_ABSOLUTE_STEEL) - { - ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectACIncrease(2)), oPC, 6.0); - if(DEBUG) DoDebug("_RecursiveStanceCheck: Applying bonuses."); - // Clean up the test WP - DestroyObject(oTestWP); - // Create waypoint for the movement for next round - CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oPC), FALSE, sWPTag); - } - - else if (nMoveId == MOVE_SD_GIANTS_STANCE) - { - DeleteLocalInt(oPC, "DWGiantsStance"); - DeleteLocalInt(oPC, "PRC_Power_Expansion_SizeIncrease"); - PRCRemoveEffectsFromSpell(oPC, nMoveId); - DestroyObject(oTestWP); - } - - else if (nMoveId == MOVE_IH_DANCING_BLADE_FORM) - { - DeleteLocalInt(oPC, "DWDancingBladeForm"); - DestroyObject(oTestWP); - } - - } - // If they still have the spell, keep going - if (GetHasSpellEffect(nMoveId, oPC)) - { - DelayCommand(6.0, _RecursiveStanceCheck(oPC, oTestWP, nMoveId)); - if(DEBUG) DoDebug("_RecursiveStanceCheck: DelayCommand(6.0, _RecursiveStanceCheck(oPC, oTestWP, nMoveId))."); - } - - if(DEBUG) DoDebug("_RecursiveStanceCheck: Exiting"); -} - -int _AllowedDiscipline(object oInitiator, int nClass, int nDiscipline) -{ - //maneuver choice for prestige classes is restricted only to those disciplines - int nOverride = GetPersistantLocalInt(oInitiator, "AllowedDisciplines"); - if(nOverride == 0) - { - switch(nClass) - { - case CLASS_TYPE_CRUSADER: nOverride = 322; break;//DISCIPLINE_DEVOTED_SPIRIT + DISCIPLINE_STONE_DRAGON + DISCIPLINE_WHITE_RAVEN - case CLASS_TYPE_SWORDSAGE: nOverride = 245; break;//DISCIPLINE_DESERT_WIND + DISCIPLINE_DIAMOND_MIND + DISCIPLINE_SETTING_SUN + DISCIPLINE_SHADOW_HAND + DISCIPLINE_STONE_DRAGON + DISCIPLINE_TIGER_CLAW - case CLASS_TYPE_WARBLADE: nOverride = 460; break;//DISCIPLINE_DIAMOND_MIND + DISCIPLINE_IRON_HEART + DISCIPLINE_STONE_DRAGON + DISCIPLINE_TIGER_CLAW + DISCIPLINE_WHITE_RAVEN - } - } - return nOverride & nDiscipline; -} - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetInitiatingClass(object oInitiator = OBJECT_SELF) -{ - return GetLocalInt(oInitiator, PRC_INITIATING_CLASS) - 1; -} - -int GetInitiatorLevel(object oInitiator = OBJECT_SELF, int nSpecificClass = CLASS_TYPE_INVALID) -{ - int nAdjust = GetLocalInt(oInitiator, PRC_CASTERLEVEL_ADJUSTMENT); - int nLevel = GetLocalInt(oInitiator, PRC_CASTERLEVEL_OVERRIDE); - - // For when you want to assign the caster level. - if(nLevel) - { - if(DEBUG) SendMessageToPC(oInitiator, "GetInitiatorLevel(): Forced-level initiating at level " + IntToString(nLevel)); - //DelayCommand(1.0, DeleteLocalInt(oInitiator, PRC_CASTERLEVEL_OVERRIDE)); - return nLevel + nAdjust; - } - - int nTotalHD = GetHitDice(oInitiator); - - // The function user needs to know the character's Initiator level in a specific class - // instead of whatever the character last initiated a maneuver as - if(nSpecificClass != CLASS_TYPE_INVALID) - { - if(GetIsBladeMagicClass(nSpecificClass)) - { - // Initiator level is class level + 1/2 levels in all other classes - // See ToB p39 - // Max level is therefor the level plus 1/2 of remaining levels - // Prestige classes are stuck in here - int nClassLevel = GetLevelByClass(nSpecificClass, oInitiator); - if(nClassLevel) - { - nClassLevel += GetBladeMagicPRCLevels(oInitiator); - nLevel = nClassLevel + ((nTotalHD - nClassLevel)/2); - } - } - } - else if(GetInitiatingClass(oInitiator) != -1) - { - int nClassLevel = GetLevelByClass(GetInitiatingClass(oInitiator), oInitiator); - nClassLevel += GetBladeMagicPRCLevels(oInitiator); - nLevel = nClassLevel + ((nTotalHD - nClassLevel)/2); - } - - // A character with no initiator levels has an init level of 1/2 HD (min 1) - if(!nLevel) - nLevel = max(1, nTotalHD/2); - - // This spam is technically no longer necessary once the Initiator level getting mechanism has been confirmed to work -// if(DEBUG) FloatingTextStringOnCreature("Initiator Level: " + IntToString(nLevel), oInitiator, FALSE); - - return nLevel + nAdjust; -} - -int GetIsBladeMagicUser(object oCreature) -{ - return !!(GetLevelByClass(CLASS_TYPE_CRUSADER, oCreature) - || GetLevelByClass(CLASS_TYPE_SWORDSAGE, oCreature) - || GetLevelByClass(CLASS_TYPE_WARBLADE, oCreature)); -} - -int GetHighestInitiatorLevel(object oCreature) -{ - int n = 0; - int nHighest; - int nTemp; - - while(n <= 8) - { - if(GetClassByPosition(n, oCreature) != CLASS_TYPE_INVALID) - { - nTemp = GetInitiatorLevel(oCreature, GetClassByPosition(n, oCreature)); - - if(nTemp > nHighest) - nHighest = nTemp; - } - n++; - - } - - return nHighest; -} - -/* int GetHighestInitiatorLevel(object oCreature) -{ - return max(max(GetClassByPosition(1, oCreature) != CLASS_TYPE_INVALID ? GetInitiatorLevel(oCreature, GetClassByPosition(1, oCreature)) : 0, - GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID ? GetInitiatorLevel(oCreature, GetClassByPosition(2, oCreature)) : 0 - ), - GetClassByPosition(3, oCreature) != CLASS_TYPE_INVALID ? GetInitiatorLevel(oCreature, GetClassByPosition(3, oCreature)) : 0 - ); -} */ - -int GetIsBladeMagicClass(int nClass) -{ - return nClass == CLASS_TYPE_CRUSADER - || nClass == CLASS_TYPE_SWORDSAGE - || nClass == CLASS_TYPE_WARBLADE; -} - -int GetManeuverLevel(object oInitiator, int nMoveId = 0) -{ - int nLevel = GetLocalInt(oInitiator, PRC_MANEUVER_LEVEL); - if (nLevel > 0) return nLevel; - else if (nMoveId > 0) return StringToInt(lookup_spell_innate(nMoveId)); - - return 0; -} - -string GetManeuverName(int nSpellId) -{ - return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellId))); -} - -int GetManeuverType(int nSpellId) -{ - return StringToInt(GetStringRight(Get2DACache("spells", "MetaMagic", nSpellId), 1)); -} - -int GetIsStance(int nMoveId) -{ - return GetManeuverType(nMoveId) == MANEUVER_TYPE_STANCE; -} - -string GetDisciplineName(int nDiscipline) -{ - int nStrRef; - switch(nDiscipline) - { - case DISCIPLINE_DESERT_WIND: nStrRef = 16829714; break; - case DISCIPLINE_DEVOTED_SPIRIT: nStrRef = 16829715; break; - case DISCIPLINE_DIAMOND_MIND: nStrRef = 16829716; break; - case DISCIPLINE_IRON_HEART: nStrRef = 16829717; break; - case DISCIPLINE_SETTING_SUN: nStrRef = 16829718; break; - case DISCIPLINE_SHADOW_HAND: nStrRef = 16829719; break; - case DISCIPLINE_STONE_DRAGON: nStrRef = 16829720; break; - case DISCIPLINE_TIGER_CLAW: nStrRef = 16829721; break; - case DISCIPLINE_WHITE_RAVEN: nStrRef = 16829722; break; - } - return GetStringByStrRef(nStrRef); -} - -int GetDisciplineByManeuver(int nMoveId) -{ - string sSpellSchool = Get2DACache("spells", "School", nMoveId); - int nDiscipline; - - if (sSpellSchool == "A") nDiscipline = DISCIPLINE_DEVOTED_SPIRIT; - else if (sSpellSchool == "C") nDiscipline = DISCIPLINE_SETTING_SUN; - else if (sSpellSchool == "D") nDiscipline = DISCIPLINE_IRON_HEART; - else if (sSpellSchool == "E") nDiscipline = DISCIPLINE_DIAMOND_MIND; - else if (sSpellSchool == "V") nDiscipline = DISCIPLINE_DESERT_WIND; - else if (sSpellSchool == "I") nDiscipline = DISCIPLINE_SHADOW_HAND; - else if (sSpellSchool == "N") nDiscipline = DISCIPLINE_WHITE_RAVEN; - else if (sSpellSchool == "T") nDiscipline = DISCIPLINE_TIGER_CLAW; - else if (sSpellSchool == "G") nDiscipline = DISCIPLINE_STONE_DRAGON; - - return nDiscipline; -} - -int GetBladeMagicPRCLevels(object oInitiator) -{ - int nLevel = GetLevelByClass(CLASS_TYPE_DEEPSTONE_SENTINEL, oInitiator) - + GetLevelByClass(CLASS_TYPE_BLOODCLAW_MASTER, oInitiator) - + GetLevelByClass(CLASS_TYPE_RUBY_VINDICATOR, oInitiator) - + GetLevelByClass(CLASS_TYPE_JADE_PHOENIX_MAGE, oInitiator) - + GetLevelByClass(CLASS_TYPE_MASTER_OF_NINE, oInitiator) - + GetLevelByClass(CLASS_TYPE_ETERNAL_BLADE, oInitiator) - + GetLevelByClass(CLASS_TYPE_SHADOW_SUN_NINJA, oInitiator); - - return nLevel; -} - -int GetPrimaryBladeMagicClass(object oCreature = OBJECT_SELF) -{ - int nClass = CLASS_TYPE_INVALID; - - if(GetPRCSwitch(PRC_CASTERLEVEL_FIRST_CLASS_RULE)) - { - int nBladeMagicPos = GetFirstBladeMagicClassPosition(oCreature); - if (!nBladeMagicPos) return CLASS_TYPE_INVALID; // no Blade Magic initiating class - - nClass = GetClassByPosition(nBladeMagicPos, oCreature); - } - else - { - /*int i, nLevel, nTest, nTestLevel; - for(i = 1; i < 4; i++) - { - nTest = GetClassByPosition(i, oCreature); - if(GetIsBladeMagicClass(nTest)) - { - nTestLevel = GetLevelByClass(nTest, oCreature); - if(nTestLevel > nLevel) - { - nClass = nTest; - nLevel = nTestLevel; - } - } - }*/ - - int nClassLvl; - int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8; - int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl; - - nClass1 = GetClassByPosition(1, oCreature); - nClass2 = GetClassByPosition(2, oCreature); - nClass3 = GetClassByPosition(3, oCreature); - nClass4 = GetClassByPosition(4, oCreature); - nClass5 = GetClassByPosition(5, oCreature); - nClass6 = GetClassByPosition(6, oCreature); - nClass7 = GetClassByPosition(7, oCreature); - nClass8 = GetClassByPosition(8, oCreature); - - if(GetIsBladeMagicClass(nClass1)) nClass1Lvl = GetLevelByClass(nClass1, oCreature); - if(GetIsBladeMagicClass(nClass2)) nClass2Lvl = GetLevelByClass(nClass2, oCreature); - if(GetIsBladeMagicClass(nClass3)) nClass3Lvl = GetLevelByClass(nClass3, oCreature); - if(GetIsBladeMagicClass(nClass4)) nClass4Lvl = GetLevelByClass(nClass4, oCreature); - if(GetIsBladeMagicClass(nClass5)) nClass5Lvl = GetLevelByClass(nClass5, oCreature); - if(GetIsBladeMagicClass(nClass6)) nClass6Lvl = GetLevelByClass(nClass6, oCreature); - if(GetIsBladeMagicClass(nClass7)) nClass7Lvl = GetLevelByClass(nClass7, oCreature); - if(GetIsBladeMagicClass(nClass8)) nClass8Lvl = GetLevelByClass(nClass8, oCreature); - - nClass = nClass1; - nClassLvl = nClass1Lvl; - - if(nClass2Lvl > nClassLvl) - { - nClass = nClass2; - nClassLvl = nClass2Lvl; - } - if(nClass3Lvl > nClassLvl) - { - nClass = nClass3; - nClassLvl = nClass3Lvl; - } - if(nClass4Lvl > nClassLvl) - { - nClass = nClass4; - nClassLvl = nClass4Lvl; - } - if(nClass5Lvl > nClassLvl) - { - nClass = nClass5; - nClassLvl = nClass5Lvl; - } - if(nClass6Lvl > nClassLvl) - { - nClass = nClass6; - nClassLvl = nClass6Lvl; - } - if(nClass7Lvl > nClassLvl) - { - nClass = nClass7; - nClassLvl = nClass7Lvl; - } - if(nClass8Lvl > nClassLvl) - { - nClass = nClass8; - nClassLvl = nClass8Lvl; - } - - if(nClassLvl == 0) - nClass = CLASS_TYPE_INVALID; - } - - return nClass; -} - -int GetFirstBladeMagicClassPosition(object oCreature = OBJECT_SELF) -{ - if (GetIsBladeMagicClass(GetClassByPosition(1, oCreature))) - return 1; - if (GetIsBladeMagicClass(GetClassByPosition(2, oCreature))) - return 2; - if (GetIsBladeMagicClass(GetClassByPosition(3, oCreature))) - return 3; - if (GetIsBladeMagicClass(GetClassByPosition(4, oCreature))) - return 4; - if (GetIsBladeMagicClass(GetClassByPosition(5, oCreature))) - return 5; - if (GetIsBladeMagicClass(GetClassByPosition(6, oCreature))) - return 6; - if (GetIsBladeMagicClass(GetClassByPosition(7, oCreature))) - return 7; - if (GetIsBladeMagicClass(GetClassByPosition(8, oCreature))) - return 8; - - return 0; -} - -int CheckManeuverPrereqs(int nClass, int nPrereqs, int nDiscipline, object oPC) -{ - // Checking to see what the name of the feat is, and the row number - /*if (DEBUG) - { - DoDebug("CheckManeuverPrereqs: nFeat: " + IntToString(nFeat)); - string sFeatName = GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))); - DoDebug("CheckManeuverPrereqs: sFeatName: " + sFeatName); - }*/ - - // Prestige classes can only access certain disciplines - if(!_AllowedDiscipline(oPC, nClass, nDiscipline)) - return FALSE; - - // If this maneuver has a prereq, check for it - if(nPrereqs) - // if it returns false, exit, otherwise they can take the maneuver - return _CheckPrereqsByDiscipline(oPC, nDiscipline, nPrereqs); - - // if you've reached this far then return TRUE - return TRUE; -} - -int GetIsManeuverSupernatural(int nMoveId) -{ - if(nMoveId == MOVE_DW_BLISTERING_FLOURISH - || nMoveId == MOVE_DW_BURNING_BLADE - || nMoveId == MOVE_DW_BURNING_BRAND - || nMoveId == MOVE_DW_DEATH_MARK - || nMoveId == MOVE_DW_DISTRACTING_EMBER - || nMoveId == MOVE_DW_DRAGONS_FLAME - || nMoveId == MOVE_DW_FAN_FLAMES - || nMoveId == MOVE_DW_FIERY_ASSAULT - || nMoveId == MOVE_DW_FIRE_RIPOSTE - || nMoveId == MOVE_DW_FIRESNAKE - || nMoveId == MOVE_DW_FLAMES_BLESSING - || nMoveId == MOVE_DW_HATCHLINGS_FLAME - || nMoveId == MOVE_DW_HOLOCAUST_CLOAK - || nMoveId == MOVE_DW_INFERNO_BLADE - || nMoveId == MOVE_DW_INFERNO_BLAST - || nMoveId == MOVE_DW_LEAPING_FLAME - || nMoveId == MOVE_DW_LINGERING_INFERNO - || nMoveId == MOVE_DW_RING_FIRE - || nMoveId == MOVE_DW_RISING_PHOENIX - || nMoveId == MOVE_DW_SALAMANDER_CHARGE - || nMoveId == MOVE_DW_SEARING_BLADE - || nMoveId == MOVE_DW_SEARING_CHARGE - || nMoveId == MOVE_DW_WYRMS_FLAME - || nMoveId == MOVE_SH_BALANCE_SKY - || nMoveId == MOVE_SH_CHILD_SHADOW - || nMoveId == MOVE_SH_CLINGING_SHADOW - || nMoveId == MOVE_SH_CLOAK_DECEPTION - || nMoveId == MOVE_SH_ENERVATING_SHADOW - || nMoveId == MOVE_SH_FIVE_SHADOW_CREEPING - || nMoveId == MOVE_SH_GHOST_BLADE - || nMoveId == MOVE_SH_OBSCURING_SHADOW_VEIL - || nMoveId == MOVE_SH_SHADOW_BLADE_TECH - || nMoveId == MOVE_SH_SHADOW_GARROTTE - || nMoveId == MOVE_SH_SHADOW_NOOSE - || nMoveId == MOVE_SH_STRENGTH_DRAINING) - return TRUE; - - // If nothing returns TRUE, fail - return FALSE; -} - -int GetHasActiveStance(object oInitiator) -{ - int nStance = GetLocalInt(oInitiator, "TOBStanceOne"); - if(GetHasSpellEffect(nStance, oInitiator)) - return nStance; - - nStance = GetLocalInt(oInitiator, "TOBStanceTwo"); - if(GetHasSpellEffect(nStance, oInitiator)) - return nStance; - - return FALSE; -} - -void RemoveStance(object oInitiator, int nStance) -{ - PRCRemoveEffectsFromSpell(oInitiator, nStance); - - //stances with special handling goes here - if(nStance == MOVE_DS_AURA_CHAOS) - DeleteLocalInt(oInitiator, "DSChaos"); - else if(nStance == MOVE_DS_PERFECT_ORDER) - DeleteLocalInt(oInitiator, "DSPerfectOrder"); - else if(nStance == MOVE_DW_RISING_PHOENIX) - RemoveItemProperty(GetPCSkin(oInitiator), ItemPropertyBonusFeat(IP_CONST_FEAT_RISING_PHOENIX)); - else if(nStance == MOVE_SH_ASSASSINS_STANCE) - { - DelayCommand(0.1, ExecuteScript("prc_sneak_att", oInitiator)); - if (DEBUG) DoDebug("Cleaning assassin's stance"); - } - else if(nStance == MOVE_MYSTIC_PHOENIX || nStance == MOVE_MYSTIC_PHOENIX_AUG) - { - if(DEBUG) DoDebug("Removing Mystic Phoenix Stance"); - DeleteLocalInt(oInitiator, "ToB_JPM_MystP"); - } - else if(nStance == MOVE_FIREBIRD_STANCE || nStance == MOVE_FIREBIRD_STANCE_AUG) - { - if(DEBUG) DoDebug("Removing Firebird Stance"); - DeleteLocalInt(oInitiator, "ToB_JPM_FireB"); - } - else if(nStance == MOVE_CHILD_SL_STANCE) - { - DeleteLocalInt(oInitiator, "SSN_CHILDSL_SETP"); - RemoveEventScript(oInitiator, EVENT_ONHEARTBEAT, "tob_ssn_childsl", TRUE, FALSE); - } -} - -void ClearStances(object oInitiator, int nDontClearMove) -{ - // Clears spell effects, will not clear DontClearMove - // This is used to allow Warblades to have two stances. - int nStance = GetLocalInt(oInitiator, "TOBStanceOne"); - if(GetHasSpellEffect(nStance, oInitiator) && nStance != nDontClearMove) - { - RemoveStance(oInitiator, nStance); - DeleteLocalInt(oInitiator, "TOBStanceOne"); - } - - nStance = GetLocalInt(oInitiator, "TOBStanceTwo"); - if(GetHasSpellEffect(nStance, oInitiator) && nStance != nDontClearMove) - { - RemoveStance(oInitiator, nStance); - DeleteLocalInt(oInitiator, "TOBStanceTwo"); - } -} - -void MarkStanceActive(object oInitiator, int nStance) -{ - // If the first stance is active, use second - // This should only be called with the first active when it is legal to have two stances - if(GetLocalInt(oInitiator, "TOBStanceOne") > 0) SetLocalInt(oInitiator, "TOBStanceTwo", nStance); - else SetLocalInt(oInitiator, "TOBStanceOne", nStance); -} - -effect VersusSizeEffect(object oInitiator, effect eEffect, int nSize) -{ - // Right now this only deals with medium and small PCs - int nPCSize = PRCGetCreatureSize(oInitiator); - effect eLink; - // Creatures larger than PC - if (nSize == 1) - { - eLink = VersusRacialTypeEffect(eEffect, RACIAL_TYPE_ABERRATION); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_CONSTRUCT)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_DRAGON)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_ELEMENTAL)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_GIANT)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_OUTSIDER)); - if (nPCSize == CREATURE_SIZE_SMALL) - { - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_ANIMAL)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_BEAST)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_DWARF)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_ELF)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HALFELF)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HALFORC)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HUMAN)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HUMANOID_GOBLINOID)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HUMANOID_MONSTROUS)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HUMANOID_ORC)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HUMANOID_REPTILIAN)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_MAGICAL_BEAST)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_OOZE)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_SHAPECHANGER)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_UNDEAD)); - } - }// Smaller - if (nSize == 0) - { - eLink = VersusRacialTypeEffect(eEffect, RACIAL_TYPE_FEY); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_VERMIN)); - if (nPCSize == CREATURE_SIZE_MEDIUM) - { - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_GNOME)); - eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(eEffect, RACIAL_TYPE_HALFLING)); - } - } - - return eLink; -} - -void InitiatorMovementCheck(object oPC, int nMoveId, float fFeet = 10.0) -{ - // Check to see if the WP is valid - string sWPTag = "PRC_BMWP_" + GetName(oPC) + IntToString(nMoveId); - object oTestWP = GetWaypointByTag(sWPTag); - if (!GetIsObjectValid(oTestWP)) - { - // Create waypoint for the movement - CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oPC), FALSE, sWPTag); - if(DEBUG) DoDebug("InitiatorMovementCheck: WP for " + DebugObject2Str(oPC) + " didn't exist, creating. Tag: " + sWPTag); - } - // Start the recursive HB check for movement - // Seeing if this solves some of the issues with it - DelayCommand(2.0, _RecursiveStanceCheck(oPC, oTestWP, nMoveId, fFeet)); -} - -void DoDesertWindBoost(object oPC) -{ - if(DEBUG) DoDebug("DoDesertWindBoost running"); - - object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC); - if (IPGetIsMeleeWeapon(oItem)) - { - effect eVis = EffectLinkEffects(EffectVisualEffect(VFX_IMP_FLAME_M), EffectVisualEffect(VFX_IMP_PULSE_FIRE)); - SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC); - // Add eventhook to the item - AddEventScript(oItem, EVENT_ITEM_ONHIT, "tob_dw_onhit", TRUE, FALSE); - DelayCommand(6.0, RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "tob_dw_onhit", TRUE, FALSE)); - // Add the OnHit and vfx - IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - IPSafeAddItemProperty(oItem, ItemPropertyVisualEffect(ITEM_VISUAL_FIRE), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - SetLocalInt(oPC, "DesertWindBoost", PRCGetSpellId()); - DelayCommand(6.0, DeleteLocalInt(oPC, "DesertWindBoost")); - } - oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC); - if (IPGetIsMeleeWeapon(oItem)) - { - // Add eventhook to the item - AddEventScript(oItem, EVENT_ITEM_ONHIT, "tob_dw_onhit", TRUE, FALSE); - DelayCommand(6.0, RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "tob_dw_onhit", TRUE, FALSE)); - // Add the OnHit and vfx - IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - IPSafeAddItemProperty(oItem, ItemPropertyVisualEffect(ITEM_VISUAL_FIRE), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } -} - -object GetCrusaderHealTarget(object oPC, float fDistance) -{ - object oReturn; - int nTest, nCurrentMin = 100; - location lTarget = GetLocation(oPC); - object oTest = MyFirstObjectInShape(SHAPE_SPHERE, fDistance, lTarget); - while(GetIsObjectValid(oTest)) - { - if(GetIsFriend(oTest, oPC)) - { - nTest = (GetCurrentHitPoints(oTest) * 100) / GetMaxHitPoints(oTest); - // Check HP vs current biggest loss - if(nTest < nCurrentMin && GetCurrentHitPoints(oTest) > 0 && !GetIsDead(oTest)) - { - nCurrentMin = nTest; - oReturn = oTest; - } - } - //Get the next target in the specified area around the caster - oTest = MyNextObjectInShape(SHAPE_SPHERE, fDistance, lTarget); - } - if(DEBUG) DoDebug("GetCrusaderHealTarget: oReturn " + GetName(oReturn)); - return oReturn; -} - -int GetHasInsightfulStrike(object oInitiator) -{ - int nDiscToCheck = GetDisciplineByManeuver(PRCGetSpellId()); - int nFeat; - switch(nDiscToCheck) - { - case DISCIPLINE_DESERT_WIND: nFeat = FEAT_SS_DF_IS_DW; break; - case DISCIPLINE_DIAMOND_MIND: nFeat = FEAT_SS_DF_IS_DM; break; - case DISCIPLINE_SETTING_SUN: nFeat = FEAT_SS_DF_IS_SS; break; - case DISCIPLINE_SHADOW_HAND: nFeat = FEAT_SS_DF_IS_SH; break; - case DISCIPLINE_STONE_DRAGON: nFeat = FEAT_SS_DF_IS_SD; break; - case DISCIPLINE_TIGER_CLAW: nFeat = FEAT_SS_DF_IS_TC; break; - } - if(GetHasFeat(nFeat, oInitiator)) - return TRUE; - - return FALSE; -} - -int GetHasDefensiveStance(object oInitiator, int nDiscipline) -{ - // Because this is only called from inside the proper stances - // Its just a check to see if they should link in the save boost. - int nFeat; - switch(nDiscipline) - { - case DISCIPLINE_DESERT_WIND: nFeat = FEAT_SS_DF_DS_DW; break; - case DISCIPLINE_DIAMOND_MIND: nFeat = FEAT_SS_DF_DS_DM; break; - case DISCIPLINE_SETTING_SUN: nFeat = FEAT_SS_DF_DS_SS; break; - case DISCIPLINE_SHADOW_HAND: nFeat = FEAT_SS_DF_DS_SH; break; - case DISCIPLINE_STONE_DRAGON: nFeat = FEAT_SS_DF_DS_SD; break; - case DISCIPLINE_TIGER_CLAW: nFeat = FEAT_SS_DF_DS_TC; break; - } - if(GetHasFeat(nFeat, oInitiator)) - return TRUE; - - return FALSE; -} - -int TOBGetHasDiscipline(object oInitiator, int nDiscipline) -{ - switch(nDiscipline) - { - case DISCIPLINE_DEVOTED_SPIRIT: return GetLevelByClass(CLASS_TYPE_CRUSADER, oInitiator); - case DISCIPLINE_DESERT_WIND: - case DISCIPLINE_SETTING_SUN: - case DISCIPLINE_SHADOW_HAND: return GetLevelByClass(CLASS_TYPE_SWORDSAGE, oInitiator); - case DISCIPLINE_IRON_HEART: return GetLevelByClass(CLASS_TYPE_WARBLADE, oInitiator); - case DISCIPLINE_DIAMOND_MIND: - case DISCIPLINE_TIGER_CLAW: return GetLevelByClass(CLASS_TYPE_SWORDSAGE, oInitiator) || GetLevelByClass(CLASS_TYPE_WARBLADE, oInitiator); - case DISCIPLINE_WHITE_RAVEN: return GetLevelByClass(CLASS_TYPE_CRUSADER, oInitiator) || GetLevelByClass(CLASS_TYPE_WARBLADE, oInitiator); - case DISCIPLINE_STONE_DRAGON: return GetLevelByClass(CLASS_TYPE_CRUSADER, oInitiator) || GetLevelByClass(CLASS_TYPE_SWORDSAGE, oInitiator) || GetLevelByClass(CLASS_TYPE_WARBLADE, oInitiator); - } - return FALSE; -} - -int TOBGetHasDisciplineFocus(object oInitiator, int nDiscipline) -{ - int nFeat1, nFeat2, nFeat3; - switch(nDiscipline) - { - case DISCIPLINE_DESERT_WIND: nFeat1 = FEAT_SS_DF_DS_DW; nFeat2 = FEAT_SS_DF_IS_DW; nFeat3 = FEAT_SS_DF_WF_DW; break; - case DISCIPLINE_DIAMOND_MIND: nFeat1 = FEAT_SS_DF_DS_DM; nFeat2 = FEAT_SS_DF_IS_DM; nFeat3 = FEAT_SS_DF_WF_DM; break; - case DISCIPLINE_SETTING_SUN: nFeat1 = FEAT_SS_DF_DS_SS; nFeat2 = FEAT_SS_DF_IS_SS; nFeat3 = FEAT_SS_DF_WF_SS; break; - case DISCIPLINE_SHADOW_HAND: nFeat1 = FEAT_SS_DF_DS_SH; nFeat2 = FEAT_SS_DF_IS_SH; nFeat3 = FEAT_SS_DF_WF_SH; break; - case DISCIPLINE_STONE_DRAGON: nFeat1 = FEAT_SS_DF_DS_SD; nFeat2 = FEAT_SS_DF_IS_SD; nFeat3 = FEAT_SS_DF_WF_SD; break; - case DISCIPLINE_TIGER_CLAW: nFeat1 = FEAT_SS_DF_DS_TC; nFeat2 = FEAT_SS_DF_IS_TC; nFeat3 = FEAT_SS_DF_WF_TC; break; - } - if(GetHasFeat(nFeat1, oInitiator) || GetHasFeat(nFeat2, oInitiator) || GetHasFeat(nFeat3, oInitiator)) - return TRUE; - - // If none of those trigger. - return FALSE; -} - -int GetIsDisciplineWeapon(object oWeapon, int nDiscipline) -{ - int nType = GetBaseItemType(oWeapon); - if(nDiscipline == DISCIPLINE_DESERT_WIND) - { - if(nType == BASE_ITEM_SCIMITAR - || nType == BASE_ITEM_LIGHTMACE - || nType == BASE_ITEM_SHORTSPEAR - || nType == BASE_ITEM_LIGHT_PICK - || nType == BASE_ITEM_FALCHION) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_DEVOTED_SPIRIT) - { - if(nType == BASE_ITEM_LONGSWORD - || nType == BASE_ITEM_HEAVYFLAIL - || nType == BASE_ITEM_MAUL - || nType == BASE_ITEM_FALCHION) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_DIAMOND_MIND) - { - if(nType == BASE_ITEM_BASTARDSWORD - || nType == BASE_ITEM_KATANA - || nType == BASE_ITEM_SHORTSPEAR - || nType == BASE_ITEM_RAPIER) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_IRON_HEART) - { - if(nType == BASE_ITEM_BASTARDSWORD - || nType == BASE_ITEM_KATANA - || nType == BASE_ITEM_LONGSWORD - || nType == BASE_ITEM_TWOBLADEDSWORD - || nType == BASE_ITEM_DWARVENWARAXE) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_SETTING_SUN) - { - // Invalid is empty handed / Unarmed strike - if(nType == BASE_ITEM_INVALID - || nType == BASE_ITEM_QUARTERSTAFF - || nType == BASE_ITEM_SHORTSWORD - || nType == BASE_ITEM_NUNCHAKU) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_SHADOW_HAND) - { - // Invalid is empty handed / Unarmed strike - if(nType == BASE_ITEM_DAGGER - || nType == BASE_ITEM_INVALID - || nType == BASE_ITEM_SHORTSWORD - || nType == BASE_ITEM_SAI) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_STONE_DRAGON) - { - // Invalid is empty handed / Unarmed strike - if(nType == BASE_ITEM_GREATAXE - || nType == BASE_ITEM_INVALID - || nType == BASE_ITEM_GREATSWORD - || nType == BASE_ITEM_HEAVY_MACE) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_TIGER_CLAW) - { - // Invalid is empty handed / Unarmed strike - if(nType == BASE_ITEM_KUKRI - || nType == BASE_ITEM_KAMA - || nType == BASE_ITEM_HANDAXE - || nType == BASE_ITEM_GREATAXE - || nType == BASE_ITEM_INVALID) - return TRUE; - } - else if(nDiscipline == DISCIPLINE_WHITE_RAVEN) - { - if(nType == BASE_ITEM_BATTLEAXE - || nType == BASE_ITEM_LONGSWORD - || nType == BASE_ITEM_HALBERD - || nType == BASE_ITEM_WARHAMMER - || nType == BASE_ITEM_GREATSWORD) - return TRUE; - } - - // If none of those trigger. - return FALSE; -} - -int TOBSituationalAttackBonuses(object oInitiator, int nDiscipline, int nClass = CLASS_TYPE_INVALID) -{ - int nBonus = 0; - if(GetLevelByClass(CLASS_TYPE_BLOODCLAW_MASTER, oInitiator) >= 4 - && nDiscipline == DISCIPLINE_TIGER_CLAW) - nBonus += 1; - - return nBonus; -} - -int GetDisciplineSkill(int nDiscipline) -{ - if(nDiscipline == DISCIPLINE_DESERT_WIND) - { - return SKILL_TUMBLE; - } - else if(nDiscipline == DISCIPLINE_DEVOTED_SPIRIT) - { - return SKILL_INTIMIDATE; - } - else if(nDiscipline == DISCIPLINE_DIAMOND_MIND) - { - return SKILL_CONCENTRATION; - } - else if(nDiscipline == DISCIPLINE_IRON_HEART) - { - return SKILL_BALANCE; - } - else if(nDiscipline == DISCIPLINE_SETTING_SUN) - { - return SKILL_SENSE_MOTIVE; - } - else if(nDiscipline == DISCIPLINE_SHADOW_HAND) - { - return SKILL_HIDE; - } - else if(nDiscipline == DISCIPLINE_STONE_DRAGON) - { - return SKILL_BALANCE; - } - else if(nDiscipline == DISCIPLINE_TIGER_CLAW) - { - return SKILL_JUMP; - } - else if(nDiscipline == DISCIPLINE_WHITE_RAVEN) - { - return SKILL_PERSUADE; - } - - // If none of those trigger. - return -1; -} - -int BladeMeditationFeat(object oInitiator) -{ - if(GetHasFeat(FEAT_BLADE_MEDITATION_DESERT_WIND , oInitiator)) return DISCIPLINE_DESERT_WIND ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_DEVOTED_SPIRIT, oInitiator)) return DISCIPLINE_DEVOTED_SPIRIT; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_DIAMOND_MIND , oInitiator)) return DISCIPLINE_DIAMOND_MIND ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_IRON_HEART , oInitiator)) return DISCIPLINE_IRON_HEART ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_SETTING_SUN , oInitiator)) return DISCIPLINE_SETTING_SUN ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_SHADOW_HAND , oInitiator)) return DISCIPLINE_SHADOW_HAND ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_STONE_DRAGON , oInitiator)) return DISCIPLINE_STONE_DRAGON ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_TIGER_CLAW , oInitiator)) return DISCIPLINE_TIGER_CLAW ; - else if(GetHasFeat(FEAT_BLADE_MEDITATION_WHITE_RAVEN , oInitiator)) return DISCIPLINE_WHITE_RAVEN ; - - return -1; -} - -int BladeMeditationDamage(object oInitiator, int nMoveId) -{ - int nDisc = BladeMeditationFeat(oInitiator); - object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oInitiator); - if (nDisc == GetDisciplineByManeuver(nMoveId) && GetIsDisciplineWeapon(oWeapon, nDisc)) - return 1; - - return -1; -} \ No newline at end of file diff --git a/trunk/include/true_inc_trufunc.nss b/trunk/include/true_inc_trufunc.nss deleted file mode 100644 index f60ee313..00000000 --- a/trunk/include/true_inc_trufunc.nss +++ /dev/null @@ -1,839 +0,0 @@ -//:://///////////////////////////////////////////// -//:: Truenaming include: Misceallenous -//:: true_inc_trufunc -//:://///////////////////////////////////////////// -/** @file - Defines various functions and other stuff that - do something related to the truenaming implementation. - - Also acts as inclusion nexus for the general - truenaming includes. In other words, don't include - them directly in your scripts, instead include this. - - @author Stratovarius - @date Created - 2006.7.18 -*/ -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// - -//:: Updated for .35 by Jaysyn 2023/03/11 - -//:: Test Void -//void main (){} - -////////////////////////////////////////////////// -/* Constants */ -////////////////////////////////////////////////// - - -////////////////////////////////////////////////// -/* Function prototypes */ -////////////////////////////////////////////////// - -/** - * Determines from what class's Utterance list the currently being truespoken - * Utterance is truespoken from. - * - * @param oTrueSpeaker A creature uttering a Utterance at this moment - * @return CLASS_TYPE_* constant of the class - */ -int GetTruespeakingClass(object oTrueSpeaker = OBJECT_SELF); - -/** - * Determines the given creature's truespeaker level. If a class is specified, - * then returns the truespeaker level for that class. Otherwise, returns - * the truespeaker level for the currently active utterance. - * - * @param oTrueSpeaker The creature whose truespeaker level to determine - * @param nSpecificClass The class to determine the creature's truespeaker - * level in. - * @param nUseHD If this is set, it returns the Character Level of the calling creature. - * DEFAULT: CLASS_TYPE_INVALID, which means the creature's - * truespeaker level in regards to an ongoing utterance - * is determined instead. - * @return The truespeaker level - */ -int GetTruespeakerLevel(object oTrueSpeaker, int nSpecificClass = CLASS_TYPE_INVALID, int nUseHD = FALSE); - -/** - * Determines whether a given creature uses truenaming. - * Requires either levels in a truenaming-related class or - * natural truenaming ability based on race. - * - * @param oCreature Creature to test - * @return TRUE if the creature can use truenames, FALSE otherwise. - */ -int GetIsTruenamingUser(object oCreature); - -/** - * Determines the given creature's highest undmodified truespeaker level among it's - * uttering classes. - * - * @param oCreature Creature whose highest truespeaker level to determine - * @return The highest unmodified truespeaker level the creature can have - */ -int GetHighestTrueSpeakerLevel(object oCreature); - -/** - * Determines whether a given class is a truenaming-related class or not. - * - * @param nClass CLASS_TYPE_* of the class to test - * @return TRUE if the class is a truenaming-related class, FALSE otherwise - */ -int GetIsTruenamingClass(int nClass); - -/** - * Gets the level of the Utterance being currently truespoken. - * WARNING: Return value is not defined when a Utterance is not being truespoken. - * - * @param oTrueSpeaker The creature currently uttering a utterance - * @return The level of the Utterance being truespoken - */ -int GetUtteranceLevel(object oTrueSpeaker); - -/** - * Determines a creature's ability score in the uttering ability of a given - * class. - * - * @param oTrueSpeaker Creature whose ability score to get - * @param nClass CLASS_TYPE_* constant of a uttering class - */ -int GetTruenameAbilityScoreOfClass(object oTrueSpeaker, int nClass); - -/** - * Determines the uttering ability of a class. - * - * @param nClass CLASS_TYPE_* constant of the class to determine the uttering stat of - * @return ABILITY_* of the uttering stat. ABILITY_CHARISMA for non-TrueSpeaker - * classes. - */ -int GetTruenameAbilityOfClass(int nClass); - -/** - * Calculates the DC of the Utterance being currently truespoken. - * Base value is 10 + Utterance level + ability modifier in uttering stat - * - * WARNING: Return value is not defined when a Utterance is not being truespoken. - * - */ -int GetTrueSpeakerDC(object oTrueSpeaker = OBJECT_SELF); - -/** - * Determines the truespeaker's level in regards to truespeaker checks to overcome - * spell resistance. - * - * WARNING: Return value is not defined when a Utterance is not being truespoken. - * - * @param oTrueSpeaker A creature uttering a Utterance at the moment - * @return The creature's truespeaker level, adjusted to account for - * modifiers that affect spell resistance checks. - */ -int GetTrueSpeakPenetration(object oTrueSpeaker = OBJECT_SELF); - -/** - * Marks an utterance as active for the Law of Sequence. - * Called from the Utterance - * - * @param oTrueSpeaker Caster of the Utterance - * @param nSpellId SpellId of the Utterance - * @param fDur Duration of the Utterance - */ -void DoLawOfSequence(object oTrueSpeaker, int nSpellId, float fDur); - -/** - * Checks to see whether the law of sequence is active - * Utterance fails if it is. - * - * @param oTrueSpeaker Caster of the Utterance - * @param nSpellId SpellId of the Utterance - * - * @return True if the Utterance is active, False if it is not. - */ -int CheckLawOfSequence(object oTrueSpeaker, int nSpellId); - -/** - * Returns the name of the Utterance - * - * @param nSpellId SpellId of the Utterance - */ -string GetUtteranceName(int nSpellId); - -/** - * Returns the name of the Lexicon - * - * @param nLexicon LEXICON_* to name - */ -string GetLexiconName(int nLexicon); - -/** - * Returns the Lexicon the Utterance is in - * @param nSpellId Utterance to check - * - * @return LEXICON_* - */ -int GetLexiconByUtterance(int nSpellId); - -/** - * Affects all of the creatures with Speak Unto the Masses - * - * @param oTrueSpeaker Caster of the Utterance - * @param oTarget Original Target of Utterance - * @param utter The utterance structure returned by EvaluateUtterance - */ -void DoSpeakUntoTheMasses(object oTrueSpeaker, object oTarget, struct utterance utter); - -/** - * Affects all of the creatures with Speak Unto the Masses - * - * @param oTrueSpeaker Caster of the Utterance - * @param oTarget Original Target of Utterance - * @param utter The utterance structure returned by EvaluateUtterance - */ -void DoWordOfNurturingReverse(object oTrueSpeaker, object oTarget, struct utterance utter); - -/** - * Affects all of the creatures with Speak Unto the Masses - * - * @param oTrueSpeaker Caster of the Utterance - * @param oTarget Original Target of Utterance - * @param utter The utterance structure returned by EvaluateUtterance - * @param nBeats Number of rounds to fire this utterance - * @param nDamageType DAMAGE_TYPE_* - */ -void DoEnergyNegation(object oTrueSpeaker, object oTarget, struct utterance utter, int nBeats, int nDamageType); - -/** - * Checks to see if the chosen target of the Crafted Tool utterance is valid. - * If it is not valid, it will search through all slots, starting with right hand weapon - * to try and find a valid target. - * - * @param oTrueSpeaker Caster of the Utterance - * @param oTarget Target of the utterance - * - * @return Item in slot, or, if there are no valid objects on the creature, OBJECT_INVALID. - * If the target is an item, it returns the item. - */ -object CraftedToolTarget(object oTrueSpeaker, object oTarget); - -/** - * Enforces the cross class cap on the Truespeech skill - * - * @param oTrueSpeaker The PC whose feats to check. - * @return TRUE if needed to relevel, FALSE otherwise. - */ -int CheckTrueSpeechSkill(object oTrueSpeaker); - -/** - * Applies modifications to a utterance's damage that depend on some property - * of the target. - * Currently accounts for: - * - Mental Resistance - * - Greater Utterance Specialization - * - Intellect Fortress - * - * @param oTarget A creature being dealt damage by a utterance - * @param oTrueSpeaker The creature uttering the damaging utterance - * @param nDamage The amount of damage the creature would be dealt - * - * @param bIsHitPointDamage Is the damage HP damage or something else? - * @param bIsEnergyDamage Is the damage caused by energy or something else? Only relevant if the damage is HP damage. - * - * @return The amount of damage, modified by oTarget's abilities - */ -/*int GetTargetSpecificChangesToDamage(object oTarget, object oTrueSpeaker, int nDamage, - int bIsHitPointDamage = TRUE, int bIsEnergyDamage = FALSE); - -*/ - -/** - * Returns how many Cadence feats an Acolyte of the Ego has - * - * @param oTrueSpeaker The PC whose feats to check. - * @return The count of feats - */ -int GetCadenceCount(object oTrueSpeaker); - -////////////////////////////////////////////////// -/* Includes */ -////////////////////////////////////////////////// - -#include "prc_alterations" -#include "true_inc_utter" -#include "true_inc_truknwn" - -////////////////////////////////////////////////// -/* Function definitions */ -////////////////////////////////////////////////// - -int GetTruespeakingClass(object oTrueSpeaker = OBJECT_SELF) -{ - return GetLocalInt(oTrueSpeaker, PRC_TRUESPEAKING_CLASS) - 1; -} - -int GetTruespeakerLevel(object oTrueSpeaker, int nSpecificClass = CLASS_TYPE_INVALID, int nUseHD = FALSE) -{ - int nLevel; - int nAdjust = GetLocalInt(oTrueSpeaker, PRC_CASTERLEVEL_ADJUSTMENT); - // Bereft's speak syllables and use their character level. - if (GetIsSyllable(PRCGetSpellId())) nUseHD = TRUE; - - // If this is set, return the user's HD - if (nUseHD) return GetHitDice(oTrueSpeaker); - - // The function user needs to know the character's truespeaker level in a specific class - // instead of whatever the character last truespoken a Utterance as - if(nSpecificClass != CLASS_TYPE_INVALID) - { - if(GetIsTruenamingClass(nSpecificClass)) - { - int nClassLevel = GetLevelByClass(nSpecificClass, oTrueSpeaker); - if (nClassLevel > 0) - { - nLevel = nClassLevel; - } - } - // A character's truespeaker level gained from non-uttering classes is always a nice, round zero - else - return 0; - } - - // Item Spells - if(GetItemPossessor(GetSpellCastItem()) == oTrueSpeaker) - { - if(DEBUG) SendMessageToPC(oTrueSpeaker, "Item casting at level " + IntToString(GetCasterLevel(oTrueSpeaker))); - - return GetCasterLevel(oTrueSpeaker) + nAdjust; - } - - // For when you want to assign the caster level. - else if(GetLocalInt(oTrueSpeaker, PRC_CASTERLEVEL_OVERRIDE) != 0) - { - if(DEBUG) SendMessageToPC(oTrueSpeaker, "Forced-level uttering at level " + IntToString(GetCasterLevel(oTrueSpeaker))); - - DelayCommand(1.0, DeleteLocalInt(oTrueSpeaker, PRC_CASTERLEVEL_OVERRIDE)); - nLevel = GetLocalInt(oTrueSpeaker, PRC_CASTERLEVEL_OVERRIDE); - } - else if(GetTruespeakingClass(oTrueSpeaker) != CLASS_TYPE_INVALID) - { - //Gets the level of the uttering class - int nUtteringClass = GetTruespeakingClass(oTrueSpeaker); - nLevel = GetLevelByClass(nUtteringClass, oTrueSpeaker); - } - - // If everything else fails, use the character's first class position - if(nLevel == 0) - { - if(DEBUG) DoDebug("Failed to get truespeaker level for creature " + DebugObject2Str(oTrueSpeaker) + ", using first class slot"); - else WriteTimestampedLogEntry("Failed to get truespeaker level for creature " + DebugObject2Str(oTrueSpeaker) + ", using first class slot"); - - nLevel = GetLevelByPosition(1, oTrueSpeaker); - } - - nLevel += nAdjust; - - // This spam is technically no longer necessary once the truespeaker level getting mechanism has been confirmed to work -// if(DEBUG) FloatingTextStringOnCreature("TrueSpeaker Level: " + IntToString(nLevel), oTrueSpeaker, FALSE); - - return nLevel; -} - -int GetIsTruenamingUser(object oCreature) -{ - return !!(GetLevelByClass(CLASS_TYPE_TRUENAMER, oCreature) || - GetLevelByClass(CLASS_TYPE_BEREFT, oCreature) - ); -} - -int GetHighestTrueSpeakerLevel(object oCreature) -{ - int n = 0; - int nHighest; - int nTemp; - - while(n <= 8) - { - if(GetClassByPosition(n, oCreature) != CLASS_TYPE_INVALID) - { - nTemp = GetTruespeakerLevel(oCreature, GetClassByPosition(n, oCreature)); - - if(nTemp > nHighest) - nHighest = nTemp; - } - n++; - - } - - return nHighest; -} - -/* int GetHighestTrueSpeakerLevel(object oCreature) -{ - return max(max(GetClassByPosition(1, oCreature) != CLASS_TYPE_INVALID ? GetTruespeakerLevel(oCreature, GetClassByPosition(1, oCreature)) : 0, - GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID ? GetTruespeakerLevel(oCreature, GetClassByPosition(2, oCreature)) : 0 - ), - GetClassByPosition(3, oCreature) != CLASS_TYPE_INVALID ? GetTruespeakerLevel(oCreature, GetClassByPosition(3, oCreature)) : 0 - ); -} */ - -int GetIsTruenamingClass(int nClass) -{ - return (nClass == CLASS_TYPE_TRUENAMER || - nClass == CLASS_TYPE_BEREFT - ); -} - -int GetUtteranceLevel(object oTrueSpeaker) -{ - return GetLocalInt(oTrueSpeaker, PRC_UTTERANCE_LEVEL); -} - -int GetTruenameAbilityScoreOfClass(object oTrueSpeaker, int nClass) -{ - return GetAbilityScore(oTrueSpeaker, GetTruenameAbilityOfClass(nClass)); -} - -int GetTruenameAbilityOfClass(int nClass){ - switch(nClass) - { - case CLASS_TYPE_TRUENAMER: - return ABILITY_CHARISMA; - default: - return ABILITY_CHARISMA; - } - - // Technically, never gets here but the compiler does not realise that - return -1; -} - -int GetTrueSpeakerDC(object oTrueSpeaker = OBJECT_SELF) -{ - // Things we need for DC Checks - int nSpellId = PRCGetSpellId(); - object oTarget = PRCGetSpellTargetObject(); - int nRace = MyPRCGetRacialType(oTarget); - // DC is 10 + 1/2 Truenamer level + Ability (Charisma) - int nClass = GetTruespeakingClass(oTrueSpeaker); - int nDC = 10; - nDC += GetLevelByClass(nClass, oTrueSpeaker) / 2; - nDC += GetAbilityModifier(GetTruenameAbilityOfClass(nClass), oTrueSpeaker); - int nFeat = -1; - - // Focused Lexicon. Bonus vs chosen racial type //:: [PRC .35] Needs update for new racialtypes - switch(nRace) - { - case RACIAL_TYPE_ABERRATION: nFeat = FEAT_FOCUSED_LEXICON_ABERRATION; break; - case RACIAL_TYPE_ANIMAL: nFeat = FEAT_FOCUSED_LEXICON_ANIMAL; break; - case RACIAL_TYPE_BEAST: nFeat = FEAT_FOCUSED_LEXICON_BEAST; break; - case RACIAL_TYPE_CONSTRUCT: nFeat = FEAT_FOCUSED_LEXICON_CONSTRUCT; break; - case RACIAL_TYPE_DRAGON: nFeat = FEAT_FOCUSED_LEXICON_DRAGON; break; - case RACIAL_TYPE_DWARF: nFeat = FEAT_FOCUSED_LEXICON_DWARF; break; - case RACIAL_TYPE_ELEMENTAL: nFeat = FEAT_FOCUSED_LEXICON_ELEMENTAL; break; - case RACIAL_TYPE_ELF: nFeat = FEAT_FOCUSED_LEXICON_ELF; break; - case RACIAL_TYPE_FEY: nFeat = FEAT_FOCUSED_LEXICON_FEY; break; - case RACIAL_TYPE_GIANT: nFeat = FEAT_FOCUSED_LEXICON_GIANT; break; - case RACIAL_TYPE_GNOME: nFeat = FEAT_FOCUSED_LEXICON_GNOME; break; - case RACIAL_TYPE_HALFELF: nFeat = FEAT_FOCUSED_LEXICON_HALFELF; break; - case RACIAL_TYPE_HALFLING: nFeat = FEAT_FOCUSED_LEXICON_HALFLING; break; - case RACIAL_TYPE_HALFORC: nFeat = FEAT_FOCUSED_LEXICON_HALFORC; break; - case RACIAL_TYPE_HUMAN: nFeat = FEAT_FOCUSED_LEXICON_HUMAN; break; - case RACIAL_TYPE_HUMANOID_GOBLINOID: nFeat = FEAT_FOCUSED_LEXICON_GOBLINOID; break; - case RACIAL_TYPE_HUMANOID_MONSTROUS: nFeat = FEAT_FOCUSED_LEXICON_MONSTROUS; break; - case RACIAL_TYPE_HUMANOID_ORC: nFeat = FEAT_FOCUSED_LEXICON_ORC; break; - case RACIAL_TYPE_HUMANOID_REPTILIAN: nFeat = FEAT_FOCUSED_LEXICON_REPTILIAN; break; - case RACIAL_TYPE_MAGICAL_BEAST: nFeat = FEAT_FOCUSED_LEXICON_MAGICALBEAST; break; - case RACIAL_TYPE_OOZE: nFeat = FEAT_FOCUSED_LEXICON_OOZE; break; - case RACIAL_TYPE_OUTSIDER: nFeat = FEAT_FOCUSED_LEXICON_OUTSIDER; break; - case RACIAL_TYPE_SHAPECHANGER: nFeat = FEAT_FOCUSED_LEXICON_SHAPECHANGER; break; - case RACIAL_TYPE_UNDEAD: nFeat = FEAT_FOCUSED_LEXICON_UNDEAD; break; - case RACIAL_TYPE_VERMIN: nFeat = FEAT_FOCUSED_LEXICON_VERMIN; break; - } - if(nFeat > -1 && GetHasFeat(nFeat, oTrueSpeaker)) - { - nDC += 1; - nFeat = -1; - } - - // Utterance Focus. DC Bonus for a chosen utterance - switch(nSpellId) - { - case UTTER_BREATH_CLEANSING_R: nFeat = FEAT_UTTERANCE_FOCUS_BREATH_CLEANSING; break; - case UTTER_BREATH_RECOVERY_R: nFeat = FEAT_UTTERANCE_FOCUS_BREATH_RECOVERY; break; - case UTTER_ELDRITCH_ATTRACTION: nFeat = FEAT_UTTERANCE_FOCUS_ELDRITCH_ATTRACTION; break; - case UTTER_ELDRITCH_ATTRACTION_R: nFeat = FEAT_UTTERANCE_FOCUS_ELDRITCH_ATTRACTION; break; - case UTTER_MORALE_BOOST_R: nFeat = FEAT_UTTERANCE_FOCUS_MORALE_BOOST; break; - case UTTER_PRETERNATURAL_CLARITY_R: nFeat = FEAT_UTTERANCE_FOCUS_PRETERNATURAL_CLARITY; break; - case UTTER_SENSORY_FOCUS_R: nFeat = FEAT_UTTERANCE_FOCUS_SENSORY_FOCUS; break; - case UTTER_SILENT_CASTER_R: nFeat = FEAT_UTTERANCE_FOCUS_SILENT_CASTER; break; - case UTTER_SINGULAR_MIND_R: nFeat = FEAT_UTTERANCE_FOCUS_SINGULAR_MIND; break; - case UTTER_TEMPORAL_SPIRAL_R: nFeat = FEAT_UTTERANCE_FOCUS_TEMPORAL_SPIRAL; break; - case UTTER_TEMPORAL_TWIST_R: nFeat = FEAT_UTTERANCE_FOCUS_TEMPORAL_TWIST; break; - case UTTER_WARD_PEACE_R: nFeat = FEAT_UTTERANCE_FOCUS_WARD_PEACE; break; - case UTTER_SHOCKWAVE: nFeat = FEAT_UTTERANCE_FOCUS_SHOCKWAVE; break; - } - if(nFeat > -1 && GetHasFeat(nFeat, oTrueSpeaker)) - nDC += 1; - - return nDC; -} - -int GetTrueSpeakPenetration(object oTrueSpeaker = OBJECT_SELF) -{ - int nPen = GetTruespeakerLevel(oTrueSpeaker); - - // According to Page 232 of Tome of Magic, Spell Pen as a feat counts, so here it is. - if(GetHasFeat(FEAT_EPIC_SPELL_PENETRATION, oTrueSpeaker)) nPen += 6; - else if(GetHasFeat(FEAT_GREATER_SPELL_PENETRATION, oTrueSpeaker)) nPen += 4; - else if(GetHasFeat(FEAT_SPELL_PENETRATION, oTrueSpeaker)) nPen += 2; - - // Blow away SR totally, just add 9000 - // Does not work on Syllables, only utterances - if (GetLocalInt(oTrueSpeaker, TRUE_IGNORE_SR) && !GetIsSyllable(PRCGetSpellId())) nPen += 9000; - - if(DEBUG) DoDebug("GetTrueSpeakPenetration(" + GetName(oTrueSpeaker) + "): " + IntToString(nPen)); - - return nPen; -} - -void DoLawOfSequence(object oTrueSpeaker, int nSpellId, float fDur) -{ - // This makes sure everything is stored using the Normal, and not the reverse - string sSpellId = GetNormalUtterSpellId(nSpellId); - SetLocalInt(oTrueSpeaker, LAW_OF_SEQUENCE_VARNAME + sSpellId, TRUE); - DelayCommand(fDur, DeleteLocalInt(oTrueSpeaker, LAW_OF_SEQUENCE_VARNAME + sSpellId)); -} - -int CheckLawOfSequence(object oTrueSpeaker, int nSpellId) -{ - // Turns this off - if (GetPRCSwitch(PRC_LAW_OF_SEQUENCE)) return FALSE; - // This makes sure everything is stored using the Normal, and not the reverse - return GetLocalInt(oTrueSpeaker, LAW_OF_SEQUENCE_VARNAME + GetNormalUtterSpellId(nSpellId)); -} - -string GetUtteranceName(int nSpellId) -{ - return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellId))); -} - -string GetLexiconName(int nLexicon) -{ - int nStrRef; - switch(nLexicon) - { - case LEXICON_EVOLVING_MIND: nStrRef = 16828478; break; - case LEXICON_CRAFTED_TOOL: nStrRef = 16828479; break; - case LEXICON_PERFECTED_MAP: nStrRef = 16828480; break; - } - - return GetStringByStrRef(nStrRef); -} - -int GetLexiconByUtterance(int nSpellId) -{ - int i, nUtter; - for(i = 0; i < GetPRCSwitch(FILE_END_CLASS_POWER) ; i++) - { - nUtter = StringToInt(Get2DACache("cls_true_utter", "SpellID", i)); - if(nUtter == nSpellId) - { - return StringToInt(Get2DACache("cls_true_utter", "Lexicon", i)); - } - } - // This should never happen - return -1; -} - -void DoSpeakUntoTheMasses(object oTrueSpeaker, object oTarget, struct utterance utter) -{ - // Check for Speak Unto the Masses, exit function if not set - if (!GetLocalInt(oTrueSpeaker, TRUE_SPEAK_UNTO_MASSES)) return; - - // Speak to the Masses affects all creatures of the same race in the AoE - int nRacial = MyPRCGetRacialType(oTarget); - object oSkin; - - // Loop over targets - object oAreaTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), GetLocation(oTarget), TRUE, OBJECT_TYPE_CREATURE); - while(GetIsObjectValid(oAreaTarget)) - { - if(DEBUG) DoDebug("Speak Unto the Masses: While entered"); - // Skip the original target/truespeaker, its already been hit - if (oAreaTarget != oTarget && oAreaTarget != oTrueSpeaker) - { - if(DEBUG) DoDebug("Speak Unto the Masses: Target check"); - // Targeting limitations - if(MyPRCGetRacialType(oAreaTarget) == nRacial) - { - if(DEBUG) DoDebug("Speak Unto the Masses: Racial Check"); - // Only affect friends or ignore it - if (GetIsFriend(oAreaTarget, oTrueSpeaker) || !utter.bFriend) - { - if(DEBUG) DoDebug("Speak Unto the Masses: Friend Check"); - // Do SR, or ignore if its a friendly utterance. - if (!PRCDoResistSpell(utter.oTrueSpeaker, oAreaTarget, utter.nPen) || utter.bIgnoreSR) - { - if(DEBUG) DoDebug("Speak Unto the Masses: SR Check"); - // Saving throw, ignore it if there is no DC to check - if(!PRCMySavingThrow(utter.nSaveThrow, oAreaTarget, utter.nSaveDC, utter.nSaveType, OBJECT_SELF) || - utter.nSaveDC == 0) - { - if(DEBUG) DoDebug("Speak Unto the Masses: Saving Throw"); - // Itemproperty, if there is one - oSkin = GetPCSkin(oAreaTarget); - if (GetIsItemPropertyValid(utter.ipIProp1)) - { - if(DEBUG) DoDebug("Speak Unto the Masses: IProp1"); - IPSafeAddItemProperty(oSkin, utter.ipIProp1, utter.fDur, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } - // Itemproperty, if there is one - if (GetIsItemPropertyValid(utter.ipIProp2)) - { - if(DEBUG) DoDebug("Speak Unto the Masses: IProp2"); - IPSafeAddItemProperty(oSkin, utter.ipIProp2, utter.fDur, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } - // Itemproperty, if there is one - if (GetIsItemPropertyValid(utter.ipIProp3)) - { - if(DEBUG) DoDebug("Speak Unto the Masses: IProp3"); - IPSafeAddItemProperty(oSkin, utter.ipIProp3, utter.fDur, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); - } - // Duration Effects - SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, utter.eLink, oAreaTarget, utter.fDur, TRUE, utter.nSpellId, utter.nTruespeakerLevel); - if(DEBUG) DoDebug("Speak Unto the Masses: Duration"); - // Impact Effects - SPApplyEffectToObject(DURATION_TYPE_INSTANT, utter.eLink2, oAreaTarget); - if(DEBUG) DoDebug("Speak Unto the Masses: Instant"); - // Utterance Specific code down here - DoWordOfNurturingReverse(oTrueSpeaker, oAreaTarget, utter); - if(DEBUG) DoDebug("Speak Unto the Masses: Word of Nurturing Reverse"); - if (utter.nSpellId == UTTER_ENERGY_NEGATION_R) - DoEnergyNegation(oTrueSpeaker, oTarget, utter, FloatToInt(utter.fDur / 6.0), GetLocalInt(oTrueSpeaker, "TrueEnergyNegation")); - } // end if - Saving Throw - } // end if - Spell Resistance - } // end if - Friend Check - }// end if - Targeting check - } - - // Get next target - oAreaTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), GetLocation(oTarget), TRUE, OBJECT_TYPE_CREATURE); - }// end while - Target loop -} - -void DoWordOfNurturingReverse(object oTrueSpeaker, object oTarget, struct utterance utter) -{ - // Returns TRUE upon concentration failure - if (GetBreakConcentrationCheck(oTrueSpeaker)) return; - - int nDamage; - // First, find out what utterance we're using - if (utter.nSpellId == UTTER_WORD_NURTURING_MINOR_R) nDamage = d6(); - else if (utter.nSpellId == UTTER_WORD_NURTURING_LESSER_R) nDamage = d6(2); - else if (utter.nSpellId == UTTER_WORD_NURTURING_MODERATE_R) nDamage = d6(4); - else if (utter.nSpellId == UTTER_WORD_NURTURING_POTENT_R) nDamage = d6(6); - else if (utter.nSpellId == UTTER_WORD_NURTURING_CRITICAL_R) nDamage = d6(8); - else if (utter.nSpellId == UTTER_WORD_NURTURING_GREATER_R) nDamage = d6(10); - // Empower it - if(utter.bEmpower) nDamage += (nDamage/2); - // If we're using this, target has already failed SR and Saves - effect eImp = EffectLinkEffects(EffectVisualEffect(VFX_IMP_MAGLAW), EffectDamage(nDamage)); - SPApplyEffectToObject(DURATION_TYPE_INSTANT, eImp, oTarget); -} - -void DoEnergyNegation(object oTrueSpeaker, object oTarget, struct utterance utter, int nBeats, int nDamageType) -{ - int nDamage = d6(2); - // Empower it - if(utter.bEmpower) nDamage += (nDamage/2); - // Impact VFX - utter.eLink2 = EffectLinkEffects(EffectVisualEffect(VFX_IMP_MAGVIO), EffectDamage(nDamage, nDamageType)); - // Impact Effects - SPApplyEffectToObject(DURATION_TYPE_INSTANT, utter.eLink2, oTarget); - - nBeats -= 1; - if (nBeats > 0) - DelayCommand(6.0, DoEnergyNegation(oTrueSpeaker, oTarget, utter, nBeats, nDamageType)); -} - -object CraftedToolTarget(object oTrueSpeaker, object oTarget) -{ - // Check to see if its a weapon or item of some sort - // Return it if its a valid base item type - if (GetBaseItemType(oTarget) != BASE_ITEM_INVALID) return oTarget; - - object oItem = OBJECT_INVALID; - - // These are utterances that only target weapons - if (PRCGetSpellId() == UTTER_KEEN_WEAPON || PRCGetSpellId() == UTTER_SUPPRESS_WEAPON || PRCGetSpellId() == UTTER_TRANSMUTE_WEAPON) - { - // By the time we're here, it should only be creatures, not items as targets - oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); - // Only do this for Keen - if (PRCGetSpellId() == UTTER_KEEN_WEAPON) - { - // Put the bonus on the ammo rather than the bow if its ranged - if( GetBaseItemType(oItem) == BASE_ITEM_LONGBOW || GetBaseItemType(oItem) == BASE_ITEM_SHORTBOW ) - { - oItem = GetItemInSlot(INVENTORY_SLOT_ARROWS, oTarget); - } - else if(GetBaseItemType(oItem) == BASE_ITEM_LIGHTCROSSBOW || GetBaseItemType(oItem) == BASE_ITEM_HEAVYCROSSBOW) - { - oItem = GetItemInSlot(INVENTORY_SLOT_BOLTS, oTarget); - } - else if(GetBaseItemType(oItem) == BASE_ITEM_SLING) - { - oItem = GetItemInSlot(INVENTORY_SLOT_BULLETS, oTarget); - } - } - // If its a valid weapon, return it - if (GetBaseItemType(oItem) != BASE_ITEM_INVALID) return oItem; - // Check the spare hand, and make sure its not a shield - oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); - // If its a valid weapon and not a shield, return it - if (GetBaseItemType(oItem) != BASE_ITEM_INVALID && - GetBaseItemType(oItem) != BASE_ITEM_LARGESHIELD && - GetBaseItemType(oItem) != BASE_ITEM_SMALLSHIELD && - GetBaseItemType(oItem) != BASE_ITEM_TOWERSHIELD) return oItem; - }// These ones target only armour - else if (PRCGetSpellId() == UTTER_FORTIFY_ARMOUR_SNEAK || PRCGetSpellId() == UTTER_FORTIFY_ARMOUR_CRIT) - { - return GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); - }// This one targets scrolls and potions - else if (PRCGetSpellId() == UTTER_METAMAGIC_CATALYST_EMP || PRCGetSpellId() == UTTER_METAMAGIC_CATALYST_EXT || - PRCGetSpellId() == UTTER_METAMAGIC_CATALYST_MAX) - { - oItem = GetFirstItemInInventory(oTarget); - while(GetIsObjectValid(oItem)) - { - if (GetBaseItemType(oItem) == BASE_ITEM_SCROLL || GetBaseItemType(oItem) == BASE_ITEM_POTIONS) - { - return oItem; - } - oItem = GetNextItemInInventory(oTarget); - } - } - else // For the rest of the utterances, any item is a valid target. - { - // Get the PC's chosen inventory slot - int nSlot = GetLocalInt(oTrueSpeaker, "TrueCraftedToolTargetSlot"); - oItem = GetItemInSlot(nSlot, oTarget); - // If the chosen item isn't valid, we go into the choice progession - // Yes, its a long chain - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_HEAD, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_LEFTRING, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_NECK, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_CLOAK, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_ARMS, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_BOOTS, oTarget); - if (!GetIsObjectValid(oItem)) - { - oItem = GetItemInSlot(INVENTORY_SLOT_BELT, oTarget); - } - } - } - } - } - } - } - } - } - } - } - } - return oItem; -} - -int CheckTrueSpeechSkill(object oTrueSpeaker) -{ - // The max for a class skill is 3 + 1 per level. We just divide this in half for Cross Class - int nMax = GetHitDice(oTrueSpeaker) + 3; - nMax /= 2; - // We want base ranks only - int nRanks = GetSkillRank(SKILL_TRUESPEAK, oTrueSpeaker, TRUE); - - // The Truenamer class has Truespeech as a class skill, so no relevel - if (GetLevelByClass(CLASS_TYPE_TRUENAMER, oTrueSpeaker) > 0) return FALSE; - // Same for this class - else if (GetLevelByClass(CLASS_TYPE_BEREFT, oTrueSpeaker) > 0) return FALSE; - // And this one - else if (GetLevelByClass(CLASS_TYPE_BRIMSTONE_SPEAKER, oTrueSpeaker) > 0) return FALSE; - // If they have the feat, no relevel - else if(GetHasFeat(FEAT_TRUENAME_TRAINING, oTrueSpeaker)) return FALSE; - // Now we check the values. If they have too many ranks, relevel. - else if (nRanks > nMax) - { - // Relevel - FloatingTextStringOnCreature("You cannot have more than " + IntToString(nMax) + " in TrueSpeech.", oTrueSpeaker, FALSE); - return TRUE; - } - - // No relevel normally - return FALSE; -} - -/* -int GetTargetSpecificChangesToDamage(object oTarget, object oTrueSpeaker, int nDamage, - int bIsHitPointDamage = TRUE, int bIsEnergyDamage = FALSE) -{ - // Greater Utterance Specialization - +2 damage on all HP-damaging utterances when target is within 30ft - if(bIsHitPointDamage && - GetHasFeat(FEAT_GREATER_Utterance_SPECIALIZATION, oTrueSpeaker) && - GetDistanceBetween(oTarget, oTrueSpeaker) <= FeetToMeters(30.0f) - ) - nDamage += 2; - // Intellect Fortress - Halve damage dealt by utterances that allow PR. Goes before DR (-like) reductions - if(GetLocalInt(oTarget, "PRC_Utterance_IntellectFortress_Active") && - Get2DACache("spells", "ItemImmunity", PRCGetSpellId()) == "1" - ) - nDamage /= 2; - // Mental Resistance - 3 damage less for all non-energy damage and ability damage - if(GetHasFeat(FEAT_MENTAL_RESISTANCE, oTarget) && !bIsEnergyDamage) - nDamage -= 3; - - // Reasonable return values only - if(nDamage < 0) nDamage = 0; - - return nDamage; -} -*/ -// Test main -//void main(){} - -int GetCadenceCount(object oTrueSpeaker) -{ - int nClass = GetLevelByClass(CLASS_TYPE_ACOLYTE_EGO, oTrueSpeaker); - if (GetLocalInt(oTrueSpeaker, "ResonantVoice") == TRUE) - { - nClass += 3; //Adds 3 to class level - } - - int nCount = nClass/2; //Get a cadence feat at 2, 4, 6, 8, 10 levels. - - if (nCount > 6) nCount = 6; //Can't go above 6 with Resonant Voice active - - // Return total - return nCount; -} \ No newline at end of file