From 1409bd7a97a8ab1b6f926745541d8d98c3eea9fe Mon Sep 17 00:00:00 2001 From: Jaysyn904 <68194417+Jaysyn904@users.noreply.github.com> Date: Tue, 24 Aug 2021 21:02:02 -0400 Subject: [PATCH] Added nwnds_scripts hakfile Added nwnds_scripts hakfile for PRC scripts that need to be overridden. --- hakbuilder.json | 7 +- nwnds_scripts/inv_et_grblst.ncs | Bin 0 -> 16543 bytes nwnds_scripts/inv_et_grblst.nss | 313 ++++++ nwnds_scripts/inv_et_spellblst.ncs | Bin 0 -> 15779 bytes nwnds_scripts/inv_et_spellblst.nss | 247 +++++ nwnds_scripts/nw_s2_familiar.ncs | Bin 0 -> 59001 bytes nwnds_scripts/nw_s2_familiar.nss | 343 +++++++ nwnds_scripts/prc_amagsys_gain.ncs | Bin 0 -> 49568 bytes nwnds_scripts/prc_amagsys_gain.nss | 556 +++++++++++ nwnds_scripts/prc_cbtmed_spnhl.ncs | Bin 0 -> 47843 bytes nwnds_scripts/prc_cbtmed_spnhl.nss | 116 +++ nwnds_scripts/prc_ccc_make_pc.ncs | Bin 0 -> 22369 bytes nwnds_scripts/prc_ccc_make_pc.nss | 252 +++++ nwnds_scripts/prc_ef_spell.ncs | Bin 0 -> 17386 bytes nwnds_scripts/prc_ef_spell.nss | 331 +++++++ nwnds_scripts/prc_nwnx_funcs.ncs | Bin 0 -> 15089 bytes nwnds_scripts/prc_nwnx_funcs.nss | 445 +++++++++ nwnds_scripts/prc_onaquire.ncs | Bin 0 -> 41375 bytes nwnds_scripts/prc_onaquire.nss | 342 +++++++ nwnds_scripts/prc_prereq.ncs | Bin 0 -> 99941 bytes nwnds_scripts/prc_prereq.nss | 1426 ++++++++++++++++++++++++++++ nwnds_scripts/prc_rest.ncs | Bin 0 -> 135275 bytes nwnds_scripts/prc_rest.nss | 395 ++++++++ nwnds_scripts/tob_jpm_spellcon.ncs | Bin 0 -> 15153 bytes nwnds_scripts/tob_jpm_spellcon.nss | 305 ++++++ nwnds_scripts/x2_pc_umdcheck.ncs | Bin 0 -> 5289 bytes nwnds_scripts/x2_pc_umdcheck.nss | 163 ++++ nwnds_scripts/x2_s0_blckblde.ncs | Bin 0 -> 187404 bytes nwnds_scripts/x2_s0_blckblde.nss | 220 +++++ 29 files changed, 5460 insertions(+), 1 deletion(-) create mode 100644 nwnds_scripts/inv_et_grblst.ncs create mode 100644 nwnds_scripts/inv_et_grblst.nss create mode 100644 nwnds_scripts/inv_et_spellblst.ncs create mode 100644 nwnds_scripts/inv_et_spellblst.nss create mode 100644 nwnds_scripts/nw_s2_familiar.ncs create mode 100644 nwnds_scripts/nw_s2_familiar.nss create mode 100644 nwnds_scripts/prc_amagsys_gain.ncs create mode 100644 nwnds_scripts/prc_amagsys_gain.nss create mode 100644 nwnds_scripts/prc_cbtmed_spnhl.ncs create mode 100644 nwnds_scripts/prc_cbtmed_spnhl.nss create mode 100644 nwnds_scripts/prc_ccc_make_pc.ncs create mode 100644 nwnds_scripts/prc_ccc_make_pc.nss create mode 100644 nwnds_scripts/prc_ef_spell.ncs create mode 100644 nwnds_scripts/prc_ef_spell.nss create mode 100644 nwnds_scripts/prc_nwnx_funcs.ncs create mode 100644 nwnds_scripts/prc_nwnx_funcs.nss create mode 100644 nwnds_scripts/prc_onaquire.ncs create mode 100644 nwnds_scripts/prc_onaquire.nss create mode 100644 nwnds_scripts/prc_prereq.ncs create mode 100644 nwnds_scripts/prc_prereq.nss create mode 100644 nwnds_scripts/prc_rest.ncs create mode 100644 nwnds_scripts/prc_rest.nss create mode 100644 nwnds_scripts/tob_jpm_spellcon.ncs create mode 100644 nwnds_scripts/tob_jpm_spellcon.nss create mode 100644 nwnds_scripts/x2_pc_umdcheck.ncs create mode 100644 nwnds_scripts/x2_pc_umdcheck.nss create mode 100644 nwnds_scripts/x2_s0_blckblde.ncs create mode 100644 nwnds_scripts/x2_s0_blckblde.nss diff --git a/hakbuilder.json b/hakbuilder.json index 63fb85df3..02cb22ea7 100644 --- a/hakbuilder.json +++ b/hakbuilder.json @@ -103,9 +103,14 @@ "CompileModels": false }, { - "Name": tmd19a_deepcave", + "Name": "tmd19a_deepcave", "Path": "./tmd19a_deepcave/", "CompileModels": false + }, + { + "Name": "nwnds_scripts", + "Path": "./nwnds_scripts/", + "CompileModels": false }, ] } \ No newline at end of file diff --git a/nwnds_scripts/inv_et_grblst.ncs b/nwnds_scripts/inv_et_grblst.ncs new file mode 100644 index 0000000000000000000000000000000000000000..2c534313457295b2de761f05d93f4f64ac83de40 GIT binary patch literal 16543 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 literal 0 HcmV?d00001 diff --git a/nwnds_scripts/inv_et_grblst.nss b/nwnds_scripts/inv_et_grblst.nss new file mode 100644 index 000000000..993835319 --- /dev/null +++ b/nwnds_scripts/inv_et_grblst.nss @@ -0,0 +1,313 @@ +//::////////////////////////////////////////////// +//:: prc_et_grblast.nss +//::////////////////////////////////////////////// +/** @file + Spell selection for eldritch theurge's greatreach blast ability + Handles the dynamic convo *and* the quickselects +*/ +//::////////////////////////////////////////////// +//::////////////////////////////////////////////// + +#include "prc_sp_func" +#include "inc_dynconv" +#include "inv_inc_invfunc" +//#include "inc_newspellbook" + +/* Constant defintions */ +const int STAGE_ENTRY = 0; +const int STAGE_SLOT = 1; +const int STAGE_LVL0 = 10; +const int STAGE_LVL9 = 20; + +/* Aid functions */ +void PopulateList(object oPC, int nLevel, int nClass) +{ + int i = 0, MaxValue = 0, nSpellID, nChoice = 1; + if(nClass == CLASS_TYPE_WIZARD + || nClass == CLASS_TYPE_DEFILER //NWN Dark Sun Class + || (nClass == CLASS_TYPE_SORCERER && GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK))) + { + string sFile = "cls_spell_sorc"; + object oToken = GetObjectByTag("SpellLvl_9_Level_" + IntToString(nLevel)); + MaxValue = array_get_size(oToken, "Lkup"); + //DoDebug("ET PopulateList: nClass = "+IntToString(nClass)); + //DoDebug("ET PopulateList: nLevel = "+IntToString(nLevel)); + //DoDebug("ET PopulateList: MaxValue = "+IntToString(MaxValue)); + while(i < MaxValue) + { + nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", array_get_int(oToken, "Lkup", i))); + if(GetHasSpell(nSpellID, oPC)) + { + if(IsTouchSpell(nSpellID)) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice), -1); + nChoice++; + } + } + i++; + } + } + else if(nClass == CLASS_TYPE_BARD && GetPRCSwitch(PRC_BARD_DISALLOW_NEWSPELLBOOK)) + { + string sFile = "cls_spell_bard"; + object oToken = GetObjectByTag("SpellLvl_1_Level_" + IntToString(nLevel)); + MaxValue = array_get_size(oToken, "Lkup"); + //DoDebug("ET PopulateList: MaxValue = "+IntToString(MaxValue)); + while(i < MaxValue) + { + nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", array_get_int(oToken, "Lkup", i))); + if(GetHasSpell(nSpellID, oPC)) + { + if(IsTouchSpell(nSpellID)) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice), -1); + nChoice++; + } + } + i++; + } + } + else + { + string sFile = GetFileForClass(nClass); + string sArray = "NewSpellbookMem_" + IntToString(nClass); + // if we ever add another arcane caster with prepared spellbook + // uncomment all following lines + //int nSpellbookType = GetSpellbookTypeForClass(nClass); + //if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) + { + int nCount = persistant_array_get_int(oPC, sArray, nLevel); + //DoDebug("ET PopulateList: nCount = "+IntToString(nCount)); + if(nCount) + { + MaxValue = persistant_array_get_size(oPC, "Spellbook"+IntToString(nClass)); + while(i < MaxValue) + { + int nNewSpellbookID = persistant_array_get_int(oPC, "Spellbook"+IntToString(nClass), i); + if(nLevel == StringToInt(Get2DACache(sFile, "Level", nNewSpellbookID)) + && GetHasFeat(StringToInt(Get2DACache(sFile, "FeatID", nNewSpellbookID)), oPC)) + { + int nRealSpell = StringToInt(Get2DACache(sFile, "RealSpellID", nNewSpellbookID)); + if(IsTouchSpell(nRealSpell)) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice), nLevel); + SetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice), sArray); + nChoice++; + } + } + i++; + } + } + } + /*else if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) + { + string sArrayIDX = "SpellbookIDX" + IntToString(nLevel) + "_" + IntToString(nClass); + MaxValue = persistant_array_get_size(oPC, sArrayIDX); + while(i < MaxValue) + { + int nNewSpellbookID = persistant_array_get_int(oPC, sArrayIDX, i); + int nCount = persistant_array_get_int(oPC, sArray, nNewSpellbookID); + if(nCount) + { + int nRealSpell = StringToInt(Get2DACache(sFile, "RealSpellID", nNewSpellbookID)); + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "EF_SPELL_CHOICE_" + IntToString(nChoice), nNewSpellbookID); + SetLocalInt(oPC, "EF_REAL_SPELL_CHOICE_" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "EF_CLASS_ARRAY_" + IntToString(nChoice), sArray); + nChoice++; + } + i++; + } + }*/ + } + + SetDefaultTokens(); + DeleteLocalInt(oPC, "DynConv_Waiting"); + FloatingTextStringOnCreature("*Done*", oPC, FALSE); +} + +void main() +{ + object oPC = OBJECT_SELF; + int nID = GetSpellId(); + int nValue = GetLocalInt(GetPCSpeaker(), DYNCONV_VARIABLE); + + //SendMessageToPC(oPC, "inv_et_grblst.nss:" + IntToString(nID) + " nVal:"+ IntToString(nValue)); + if (nValue != 0) { + // do conversation + oPC = GetPCSpeaker(); + /* Get the value of the local variable set by the conversation script calling + * this script. Values: + * DYNCONV_ABORTED Conversation aborted + * DYNCONV_EXITED Conversation exited via the exit node + * DYNCONV_SETUP_STAGE System's reply turn + * 0 Error - something else called the script + * Other The user made a choice + */ + // The stage is used to determine the active conversation node. + // 0 is the entry node. + int nStage = GetStage(oPC); + + if(nValue == DYNCONV_SETUP_STAGE) + { + // Check if this stage is marked as already set up + // This stops list duplication when scrolling + if(!GetIsStageSetUp(nStage, oPC)) + { + // variable named nStage determines the current conversation node + // Function SetHeader to set the text displayed to the PC + // Function AddChoice to add a response option for the PC. The responses are show in order added + if(nStage == STAGE_ENTRY) + { + SetHeader("Select Spell Level:"); + if(!GetLocalInt(oPC, "PRC_ArcSpell1")) AddChoice(GetStringByStrRef(690), 1, oPC);//"Level 1" + if(!GetLocalInt(oPC, "PRC_ArcSpell2")) AddChoice(GetStringByStrRef(725), 2, oPC);//"Level 2" + if(!GetLocalInt(oPC, "PRC_ArcSpell3")) AddChoice(GetStringByStrRef(687), 3, oPC);//"Level 3" + if(!GetLocalInt(oPC, "PRC_ArcSpell4")) AddChoice(GetStringByStrRef(684), 4, oPC);//"Level 4" + if(!GetLocalInt(oPC, "PRC_ArcSpell5")) AddChoice(GetStringByStrRef(1026), 5, oPC);//"Level 5" + if(!GetLocalInt(oPC, "PRC_ArcSpell6")) AddChoice(GetStringByStrRef(1014), 6, oPC);//"Level 6" + if(!GetLocalInt(oPC, "PRC_ArcSpell7")) AddChoice(GetStringByStrRef(2214), 7, oPC);//"Level 7" + if(!GetLocalInt(oPC, "PRC_ArcSpell8")) AddChoice(GetStringByStrRef(2215), 8, oPC);//"Level 8" + if(!GetLocalInt(oPC, "PRC_ArcSpell9")) AddChoice(GetStringByStrRef(2216), 9, oPC);//"Level 9" + MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + else if (nStage >= STAGE_LVL0 && nStage <= STAGE_LVL9) + { + // Set the header + SetHeader("Select Spell:"); + int nLevel = nStage - STAGE_LVL0; + SetLocalInt(oPC, "DynConv_Waiting", TRUE); + + PopulateList(oPC, nLevel, GetETArcaneClass(oPC)); + + MarkStageSetUp(nStage, oPC); + } + else if (nStage = STAGE_SLOT) + { + SetHeader("Select QuickSlot:"); + AddChoice("Slot 1", 1, oPC); + AddChoice("Slot 2", 2, oPC); + AddChoice("Slot 3", 3, oPC); + AddChoice("Slot 4", 4, oPC); + MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + + //add more stages for more nodes with Else If clauses + } + + // Do token setup + SetupTokens(); + } + // End of conversation cleanup + // Abort conversation cleanup. + else if(nValue == DYNCONV_EXITED + || nValue == DYNCONV_ABORTED) + { + int nChoice = 1; + while(GetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice))) + { + DeleteLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice)); + nChoice++; + } + DeleteLocalInt(oPC, "ET_SPELL_ID"); + DeleteLocalInt(oPC, "ET_REAL_SPELL_ID"); + DeleteLocalString(oPC, "ET_CLASS_ARRAY_ID"); + DeleteLocalInt(oPC, "ET_SPELL_LEVEL_CHOICE"); + } + // Handle PC responses + else + { + // variable named nChoice is the value of the player's choice as stored when building the choice list + // variable named nStage determines the current conversation node + int nChoice = GetChoice(oPC); + if(nStage == STAGE_ENTRY) + { + int nLevel = nChoice; + SetLocalInt(oPC, "ET_SPELL_LEVEL_CHOICE", nLevel); + nStage = STAGE_LVL0 + nChoice; + // Move to another stage based on response, for example + //nStage = STAGE_QUUX; + } + else if (nStage >= STAGE_LVL0 && nStage <= STAGE_LVL9) + { + MarkStageNotSetUp(nStage, oPC); + int nSpell = GetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice)); + int nRealSpell = GetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + string sArray = GetLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice)); + + SetLocalInt(oPC, "ET_SPELL_ID", nSpell); + SetLocalInt(oPC, "ET_REAL_SPELL_ID", nRealSpell); + SetLocalString(oPC, "ET_CLASS_ARRAY_ID", sArray); + + nStage = STAGE_SLOT; + } + else if (nStage = STAGE_SLOT) + { + int nSpell = GetLocalInt(oPC, "ET_SPELL_ID"); + int nRealSpell = GetLocalInt(oPC, "ET_REAL_SPELL_ID"); + string sArray = GetLocalString(oPC, "ET_CLASS_ARRAY_ID"); + int nLevel = GetLocalInt(oPC, "ET_SPELL_LEVEL_CHOICE"); + SetLocalInt(oPC, "ET_GR_SPELL_QUICK" + IntToString(nChoice), nSpell); + SetLocalInt(oPC, "ET_GR_REAL_SPELL_QUICK" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "ET_GR_SPELL_QUICK" + IntToString(nChoice), sArray); + SetLocalInt(oPC, "ET_GR_SPELL_QUICK" + IntToString(nChoice) + "LVL", nLevel); + + nStage = STAGE_ENTRY; + } + // Store the stage value. If it has been changed, this clears out the choices + SetStage(nStage, oPC); + } + } + else if(nID == INVOKE_GR_SPELL_SELECT_CONVO) + { + DelayCommand(0.5, StartDynamicConversation("inv_et_grblst", oPC, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, FALSE, oPC)); + } + else + { + string sSlotNo; + switch(nID) + { + case INVOKE_GR_SPELL_SELECT_QUICK1: sSlotNo = "1"; break; + case INVOKE_GR_SPELL_SELECT_QUICK2: sSlotNo = "2"; break; + case INVOKE_GR_SPELL_SELECT_QUICK3: sSlotNo = "3"; break; + case INVOKE_GR_SPELL_SELECT_QUICK4: sSlotNo = "4"; break; + } + + if(sSlotNo == "") + return; + + int nSpell = GetLocalInt(oPC, "ET_GR_SPELL_QUICK"+sSlotNo); + int nLevel = GetLocalInt(oPC, "ET_GR_SPELL_QUICK"+sSlotNo+"LVL"); + int nRealSpell = GetLocalInt(oPC, "ET_GR_REAL_SPELL_QUICK"+sSlotNo); + if(nRealSpell == -1) nRealSpell = nSpell; + string sArray = GetLocalString(oPC, "ET_GR_SPELL_QUICK"+sSlotNo); + int nUses = sArray == "" ? GetHasSpell(nSpell, oPC) : persistant_array_get_int(oPC, sArray, nSpell); + if(nUses) + { + SetLocalInt(oPC, "ET_SPELL_CURRENT", (nSpell+1)); + SetLocalInt(oPC, "ET_SPELL_CURRENT_LVL", nLevel); + SetLocalInt(oPC, "ET_REAL_SPELL_CURRENT", nRealSpell); + SetLocalString(oPC, "ET_SPELL_CURRENT", sArray); + FloatingTextStringOnCreature("*Greatreach Blast: " + GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))) + "*", oPC, FALSE); + FloatingTextStringOnCreature("*You have " + IntToString(nUses) + " uses left*", oPC, FALSE); + } + else + { + FloatingTextStringOnCreature("No uses or preperations left for selected spell!", oPC, FALSE); + } + } +} diff --git a/nwnds_scripts/inv_et_spellblst.ncs b/nwnds_scripts/inv_et_spellblst.ncs new file mode 100644 index 0000000000000000000000000000000000000000..1c1f2b6c4dc1bed1ff8e26ff798af7b0c3899dd6 GIT binary patch literal 15779 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 literal 0 HcmV?d00001 diff --git a/nwnds_scripts/inv_et_spellblst.nss b/nwnds_scripts/inv_et_spellblst.nss new file mode 100644 index 000000000..f8828caef --- /dev/null +++ b/nwnds_scripts/inv_et_spellblst.nss @@ -0,0 +1,247 @@ +//::////////////////////////////////////////////// +//:: inv_et_spellblst.nss +//::////////////////////////////////////////////// +/** @file + Spell selection for eldritch theurge's spellblast ability + Handles the dynamic convo *and* the quickselects +*/ +//::////////////////////////////////////////////// +//::////////////////////////////////////////////// + +#include "inv_invoc_const" +#include "inc_dynconv" +#include "inv_inc_invfunc" + +/* Constant defintions */ +const int STAGE_ENTRY = 0; +const int STAGE_SLOT = 1; + +/* Aid functions */ + +void PopulateList(object oPC, int nClass) +{ + string sFile = "et_spellblast"; + int MaxValue = StringToInt(Get2DACache(sFile, "Label", 0)); + + int i = 1, nSpellID, nChoice = 1; + if(nClass == CLASS_TYPE_WIZARD + || nClass == CLASS_TYPE_DEFILER + || (nClass == CLASS_TYPE_SORCERER && GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK)) + || (nClass == CLASS_TYPE_BARD && GetPRCSwitch(PRC_BARD_DISALLOW_NEWSPELLBOOK))) + { + while(i < MaxValue) + { + nSpellID = StringToInt(Get2DACache(sFile, "SpellID", i)); + if(GetHasSpell(nSpellID, oPC)) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice), -1); + nChoice++; + } + i++; + } + } + else + { + string sClassFile = GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED ? "": + GetFileForClass(nClass); + string sArray = "NewSpellbookMem_" + IntToString(nClass); + int nSpellbookID, nLevel, nCount; + while(i < MaxValue) + { + nSpellID = StringToInt(Get2DACache(sFile, "SpellID", i)); + nSpellbookID = RealSpellToSpellbookID(nClass, nSpellID); +DoDebug(Get2DACache(sFile, "Label", i)+" = "+IntToString(nSpellbookID)); + if(nSpellbookID != -1) + { + /* // if we ever add another arcane caster with prepared spellbook + // uncomment all following lines + if(sClassFile == "") + { + nCount = persistant_array_get_int(oPC, sArray, nSpellbookID); + if(nCount) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice), nSpellbookID); + SetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice), sArray); + nChoice++; + } + } + else*/ + { + if(GetHasFeat(StringToInt(Get2DACache(sClassFile, "FeatID", nSpellbookID)), oPC)) + { + nLevel = StringToInt(Get2DACache(sClassFile, "Level", nSpellbookID)); + nCount = persistant_array_get_int(oPC, sArray, nLevel); + if(nCount) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice), nLevel); + SetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice), sArray); + nChoice++; + } + } + } + } + i++; + } + } + + SetDefaultTokens(); + DeleteLocalInt(oPC, "DynConv_Waiting"); + FloatingTextStringOnCreature("*Done*", oPC, FALSE); +} + +void main() +{ + object oPC = OBJECT_SELF; + int nID = GetSpellId(); + int nValue = GetLocalInt(GetPCSpeaker(), DYNCONV_VARIABLE); + + //SendMessageToPC(oPC, "inv_et_spellblst:" + IntToString(nID) + " nVal:"+ IntToString(nValue)); + if (nValue != 0) { + // do conversation + oPC = GetPCSpeaker(); + /* Get the value of the local variable set by the conversation script calling + * this script. Values: + * DYNCONV_ABORTED Conversation aborted + * DYNCONV_EXITED Conversation exited via the exit node + * DYNCONV_SETUP_STAGE System's reply turn + * 0 Error - something else called the script + * Other The user made a choice + */ + // The stage is used to determine the active conversation node. + // 0 is the entry node. + int nStage = GetStage(oPC); + + if(nValue == DYNCONV_SETUP_STAGE) + { + // Check if this stage is marked as already set up + // This stops list duplication when scrolling + if(!GetIsStageSetUp(nStage, oPC)) + { + // variable named nStage determines the current conversation node + // Function SetHeader to set the text displayed to the PC + // Function AddChoice to add a response option for the PC. The responses are show in order added + if(nStage == STAGE_ENTRY) + { + // Set the header + SetHeader("Select Spell:"); + SetLocalInt(oPC, "DynConv_Waiting", TRUE); + + PopulateList(oPC, GetETArcaneClass(oPC)); + + MarkStageSetUp(nStage, oPC); + } + else if (nStage = STAGE_SLOT) + { + SetHeader("Select QuickSlot:"); + AddChoice("Slot 1", 1, oPC); + AddChoice("Slot 2", 2, oPC); + AddChoice("Slot 3", 3, oPC); + AddChoice("Slot 4", 4, oPC); + MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + + //add more stages for more nodes with Else If clauses + } + + // Do token setup + SetupTokens(); + } + // Abort conversation cleanup. + // NOTE: This section is only run when the conversation is aborted + // while aborting is allowed. When it isn't, the dynconvo infrastructure + // handles restoring the conversation in a transparent manner + else if(nValue == DYNCONV_ABORTED + || nValue == DYNCONV_EXITED) + { + int nChoice = 1; + while(GetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice))) + { + DeleteLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice)); + nChoice++; + } + DeleteLocalInt(oPC, "ET_SPELL_ID"); + DeleteLocalInt(oPC, "ET_REAL_SPELL_ID"); + DeleteLocalString(oPC, "ET_CLASS_ARRAY_ID"); + DeleteLocalInt(oPC, "ET_SPELL_LEVEL_CHOICE"); + } + // Handle PC responses + else + { + // variable named nChoice is the value of the player's choice as stored when building the choice list + // variable named nStage determines the current conversation node + int nChoice = GetChoice(oPC); + if(nStage == STAGE_ENTRY) + { + MarkStageNotSetUp(nStage, oPC); + int nSpell = GetLocalInt(oPC, "ET_SPELL_CHOICE_" + IntToString(nChoice)); + int nRealSpell = GetLocalInt(oPC, "ET_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + string sArray = GetLocalString(oPC, "ET_CLASS_ARRAY_" + IntToString(nChoice)); + + SetLocalInt(oPC, "ET_SPELL_ID", nSpell); + SetLocalInt(oPC, "ET_REAL_SPELL_ID", nRealSpell); + SetLocalString(oPC, "ET_CLASS_ARRAY_ID", sArray); + + nStage = STAGE_SLOT; + } + else if (nStage = STAGE_SLOT) + { + MarkStageNotSetUp(nStage, oPC); + int nSpell = GetLocalInt(oPC, "ET_SPELL_ID"); + int nRealSpell = GetLocalInt(oPC, "ET_REAL_SPELL_ID"); + string sArray = GetLocalString(oPC, "ET_CLASS_ARRAY_ID"); + int nLevel = GetLocalInt(oPC, "ET_SPELL_LEVEL_CHOICE"); + SetLocalInt(oPC, "ET_SPELL_QUICK" + IntToString(nChoice), nSpell); + SetLocalInt(oPC, "ET_REAL_SPELL_QUICK" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "ET_SPELL_QUICK" + IntToString(nChoice), sArray); + SetLocalInt(oPC, "ET_SPELL_QUICK" + IntToString(nChoice) + "LVL", nLevel); + + nStage = STAGE_ENTRY; + } + // Store the stage value. If it has been changed, this clears out the choices + SetStage(nStage, oPC); + } + } + else if(nID == INVOKE_SB_SPELL_SELECT_CONVO) + { + DelayCommand(0.5, StartDynamicConversation("inv_et_spellblst", oPC, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, FALSE, oPC)); + } + else + { + string sSlotNo; + switch(nID) + { + case INVOKE_SB_SPELL_SELECT_QUICK1: sSlotNo = "1"; break; + case INVOKE_SB_SPELL_SELECT_QUICK2: sSlotNo = "2"; break; + case INVOKE_SB_SPELL_SELECT_QUICK3: sSlotNo = "3"; break; + case INVOKE_SB_SPELL_SELECT_QUICK4: sSlotNo = "4"; break; + } + + if(sSlotNo == "") + return; + + int nSpell = GetLocalInt(oPC, "ET_SPELL_QUICK"+sSlotNo); + int nLevel = GetLocalInt(oPC, "ET_SPELL_QUICK"+sSlotNo+"LVL"); + int nRealSpell = GetLocalInt(oPC, "ET_REAL_SPELL_QUICK"+sSlotNo); + if(nRealSpell == -1) nRealSpell = nSpell; + string sArray = GetLocalString(oPC, "ET_SPELL_QUICK"+sSlotNo); + SetLocalInt(oPC, "ET_SPELL_CURRENT", (nSpell+1)); + SetLocalInt(oPC, "ET_SPELL_CURRENT_LVL", nLevel); + SetLocalInt(oPC, "ET_REAL_SPELL_CURRENT", nRealSpell); + SetLocalString(oPC, "ET_SPELL_CURRENT", sArray); + int nUses = sArray == "" ? GetHasSpell(nSpell, oPC) : persistant_array_get_int(oPC, sArray, nSpell); + FloatingTextStringOnCreature("*Spellblast: " + GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))) + "*", oPC, FALSE); + FloatingTextStringOnCreature("*You have " + IntToString(nUses) + " uses left*", oPC, FALSE); + } +} diff --git a/nwnds_scripts/nw_s2_familiar.ncs b/nwnds_scripts/nw_s2_familiar.ncs new file mode 100644 index 0000000000000000000000000000000000000000..63bbd5f89186eac07d68db748354bc60330868e5 GIT binary patch literal 59001 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 SWqf`gWw#%>e3IUWIQhT!R 6) + { + //handles dread necromancer familiar + DreadNecro(oPC); + } + else if(GetLevelByClass(CLASS_TYPE_CELEBRANT_SHARESS, oPC)) + { + //It's a PnP Cat familiar + SummonPnPFamiliar(oPC, 6); + } + else if(GetPRCSwitch(PRC_PNP_FAMILIARS)) + { + //handles summoning of pnp familiar + SummonPnPFamiliar(oPC, -1); + } + else if(GetPRCSwitch(PRC_FAMILIARS)//the switch is set + || (!GetLevelByClass(CLASS_TYPE_WIZARD, oPC) || !GetLevelByClass(CLASS_TYPE_DEFILER, oPC) + && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC)))//or no bio-ware familiar + { + //handles summoning of familiars for PRC classes (witch, hexblade) + SummonPRCFamiliar(oPC); + } + else + //summon bio-ware familiar + SummonFamiliar(); + + object oFam; + int i; + int bDiabol = GetLevelByClass(CLASS_TYPE_DIABOLIST, oPC) >= 2; + int bPseudonat = GetHasFeat(FEAT_PSEUDONATURAL_FAMILIAR, oPC); + for(i = 1; i <= 5; i++) + { + oFam = GetAssociateNPC(ASSOCIATE_TYPE_FAMILIAR, oPC, i); + + if(bDiabol && GetAppearanceType(oFam) != APPEARANCE_TYPE_IMP) + DestroyAssociate(oFam); + + if(bPseudonat) + { + object oFamSkin = GetPCSkin(oFam); + ApplyPseudonatural(oFam, oFamSkin); + } + } +} + +void BondedSummoner(object oPC) +{ + object oFam = GetAssociateNPC(ASSOCIATE_TYPE_FAMILIAR, oPC, NPC_BONDED_FAMILIAR); + + //remove previously summoned familiar + if(GetIsObjectValid(oFam)) + DestroyAssociate(oFam); + + string sResRef, sElem; + int nPackage; + if(GetHasFeat(FEAT_BONDED_AIR, oPC)) + { + sElem = "air"; + nPackage = PACKAGE_ELEMENTAL_DEX; + } + else if(GetHasFeat(FEAT_BONDED_EARTH, oPC)) + { + sElem = "earth"; + nPackage = PACKAGE_ELEMENTAL_STR; + } + else if(GetHasFeat(FEAT_BONDED_FIRE, oPC)) + { + sElem = "fire"; + nPackage = PACKAGE_ELEMENTAL_DEX; + } + else if(GetHasFeat(FEAT_BONDED_WATER, oPC)) + { + sElem = "water"; + nPackage = PACKAGE_ELEMENTAL_STR; + } + + int nLevel = GetLevelByClass(CLASS_TYPE_BONDED_SUMMONNER, oPC); + + switch(nLevel) + { + case 1: + case 2: sResRef = "x1_s_"+sElem+"small"; break;//this is the 4HD version in the SRD, which is medium + case 3: + case 4: sResRef = "prc_s_"+sElem+"large"; break; + case 5: + case 6: sResRef = "nw_s_"+sElem+"huge"; break; + case 7: + case 8: sResRef = "nw_s_"+sElem+"great"; break; + case 9: + case 10: sResRef = "nw_s_"+sElem+"elder"; break; + } + + oFam = CreateLocalNPC(oPC, ASSOCIATE_TYPE_FAMILIAR, sResRef, PRCGetSpellTargetLocation(), NPC_BONDED_FAMILIAR); + AddAssociate(oPC, oFam); + + //set its name + string sName = GetFamiliarName(oPC); + if(sName == "") + sName = GetName(oPC)+ "'s Familiar"; + SetName(oFam, sName); + //apply bonus based on level + int nArcaneLevel = GetPrCAdjustedCasterLevelByType(TYPE_ARCANE) + nLevel/2; + object oSkin = GetPCSkin(oFam); + //in all cases + IPSafeAddItemProperty(oSkin, PRCItemPropertyBonusFeat(ITEM_PROPERTY_IMPROVED_EVASION)); + //9+ levels + if(nArcaneLevel >= 9) + IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nArcaneLevel+5))); + //11+ levels + if(nArcaneLevel >= 11) + ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectMovementSpeedIncrease(30)), oFam); + //add their ondeath special + AddEventScript(oFam, EVENT_NPC_ONDEATH, "prc_bond_death"); + + /*int nAdjustLevel = nArcaneLevel - GetHitDice(oFam); + int n; + for(n = 1; nAdjustLevel >= n; n++) + LevelUpHenchman(oFam, CLASS_TYPE_INVALID, TRUE, nPackage);*/ + + //set it so the spell-share detects it + SetLocalObject(oPC, "Familiar", oFam); +} + +void DreadNecro(object oPC) +{ + object oFam = GetAssociateNPC(ASSOCIATE_TYPE_FAMILIAR, oPC, NPC_DN_FAMILIAR); + + //remove previously summoned familiar + if(GetIsObjectValid(oFam)) + DestroyAssociate(oFam); + + int bPnP = GetPRCSwitch(PRC_PNP_FAMILIARS); + int nAlign = GetAlignmentLawChaos(oPC); + string sResRef; + if(bPnP) + { + sResRef = nAlign == ALIGNMENT_LAWFUL ? "prc_pnpfam_imp" : nAlign == ALIGNMENT_CHAOTIC ? "prc_pnpfam_qust" : "prc_pnpfam_varg"; + } + else + { + int nDNLevel = GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oPC); + string sTemp = nDNLevel < 10 ? "0"+IntToString(nDNLevel) : IntToString(nDNLevel); + sResRef = nAlign == ALIGNMENT_LAWFUL ? "NW_FM_IMP"+sTemp : nAlign == ALIGNMENT_CHAOTIC ? "NW_FM_QUAS"+sTemp : "X2_FM_EYE0"+sTemp; + } + + oFam = CreateLocalNPC(oPC, ASSOCIATE_TYPE_FAMILIAR, sResRef, PRCGetSpellTargetLocation(), NPC_DN_FAMILIAR); + + //add the familiar as a henchman + AddAssociate(oPC, oFam); + + //set its name + string sName = GetFamiliarName(oPC); + if(sName == "") + sName = GetName(oPC)+ "'s Familiar"; + SetName(oFam, sName); + + if(bPnP) ApplyPnPFamiliarProperties(oPC, oFam); +} + +void SummonPnPFamiliar(object oPC, int nType) +{ + IncrementRemainingFeatUses(oPC, FEAT_SUMMON_FAMILIAR); + + //check if already has a familiar + object oFam = GetAssociateNPC(ASSOCIATE_TYPE_FAMILIAR, oPC, NPC_PNP_FAMILIAR); + object oFamToken = GetItemPossessedBy(oPC, "prc_pnp_familiar"); + + int nFamiliarType; + + if (nType > 0) + nFamiliarType = nType; + else + nFamiliarType = GetPersistantLocalInt(oPC, "PnPFamiliarType"); + if(!nFamiliarType) + { + StartDynamicConversation("prc_pnp_fam_conv", oPC, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, TRUE, oPC); + return; + } + + if(GetIsObjectValid(oFam)) + { + //reapply familiar bonuses + PRCRemoveEffectsFromSpell(oFam, 318);//318 = summon familiar + } + else + { + if(GetIsObjectValid(oFamToken)) + { + DestroyObject(oFamToken, 0.1f); + } + //spawn the familiar + string sResRef = Get2DACache("prc_familiar", "BASERESREF", nFamiliarType); + oFam = CreateLocalNPC(oPC, ASSOCIATE_TYPE_FAMILIAR, sResRef, PRCGetSpellTargetLocation(), NPC_PNP_FAMILIAR); + + //set its name + string sName = GetFamiliarName(oPC); + if(sName == "") + sName = GetName(oPC)+ "'s Familiar"; + SetName(oFam, sName); + + //add the familiar as a henchman + AddAssociate(oPC, oFam); + } + + //this is the masters bonus + effect eBonus = GetMasterBonus(nFamiliarType); + eBonus = SupernaturalEffect(eBonus); + if(!GetHasFeatEffect(FEAT_SUMMON_FAMILIAR, oPC)) + { + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonus, oPC); + CheckIsValidFamiliar(oPC, eBonus); + } + + ApplyPnPFamiliarProperties(oPC, oFam); + if (GetHasFeat(FEAT_SHADOW_FAMILIAR, oPC)) ApplyTemplateToObject(TEMPLATE_DARK, oFam); +} + +void SummonPRCFamiliar(object oPC) +{ + object oFam = GetAssociateNPC(ASSOCIATE_TYPE_FAMILIAR, oPC, NPC_HENCHMAN_COMPANION); + + //remove previously summoned familiar + if(GetIsObjectValid(oFam)) + DestroyAssociate(oFam); + + int nFamiliarType = GetPersistantLocalInt(oPC, "FamiliarType"); + if(!nFamiliarType) + { + StartDynamicConversation("prc_pnp_fam_conv", oPC, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, TRUE, oPC); + IncrementRemainingFeatUses(oPC, FEAT_SUMMON_FAMILIAR); + return; + } + else + nFamiliarType--; + + int nFamLevel = GetLevelByClass(CLASS_TYPE_WIZARD); + nFamLevel = max(nFamLevel, GetLevelByClass(CLASS_TYPE_DEFILER)); // NWN Dark Sun class + nFamLevel = max(nFamLevel, GetLevelByClass(CLASS_TYPE_SORCERER)); + nFamLevel = max(nFamLevel, GetLevelByClass(CLASS_TYPE_WITCH)); + nFamLevel = max(nFamLevel, GetLevelByClass(CLASS_TYPE_HEXBLADE)); + nFamLevel += GetLevelByClass(CLASS_TYPE_ALIENIST); + if (GetHasFeat(FEAT_SHADOW_FAMILIAR, oPC)) nFamLevel = GetLevelByTypeArcane(oPC) + GetShadowcasterLevel(oPC); // For the purpose of determining familiar abilities that depend on your arcane caster level, your levels in all classes that allow you to cast mysteries or arcane spells stack + + string sTemp = Get2DACache("hen_familiar", "BASERESREF", nFamiliarType); + string sResRef = nFamLevel < 10 ? sTemp+"0"+IntToString(nFamLevel) : sTemp+IntToString(nFamLevel); + + //spawn the familiar + oFam = CreateLocalNPC(oPC, ASSOCIATE_TYPE_FAMILIAR, sResRef, PRCGetSpellTargetLocation(), NPC_HENCHMAN_COMPANION); + AddAssociate(oPC, oFam); + + if (GetHasFeat(FEAT_SHADOW_FAMILIAR, oPC)) ApplyTemplateToObject(TEMPLATE_DARK, oFam); + + //set its name + string sName = GetFamiliarName(oPC); + if(sName == "") + sName = GetName(oPC)+ "'s Familiar"; + SetName(oFam, sName); +} + +void MasterShadow(object oPC) +{ + object oFam = GetAssociateNPC(ASSOCIATE_TYPE_FAMILIAR, oPC, NPC_MS_ELEMENTAL); + + //remove previously summoned familiar + if(GetIsObjectValid(oFam)) + DestroyAssociate(oFam); + + int nLevel = GetLevelByClass(CLASS_TYPE_MASTER_OF_SHADOW, oPC); + string sShadow = "shd_shdelem_med"; + if (nLevel >= 10) + sShadow = "shd_shdelem_med4"; + else if (nLevel >= 7) + sShadow = "shd_shdelem_med3"; + else if (nLevel >= 4) + sShadow = "shd_shdelem_med2"; + + oFam = CreateLocalNPC(oPC, ASSOCIATE_TYPE_FAMILIAR, sShadow, PRCGetSpellTargetLocation(), NPC_MS_ELEMENTAL); + AddAssociate(oPC, oFam); + //set its name + string sName = GetFamiliarName(oPC); + if(sName == "") + sName = GetName(oPC)+ "'s Shadow Elemental"; + SetName(oFam, sName); + + itemproperty ipIP; + object oSkin = GetPCSkin(oFam); + if (nLevel >= 10) + ipIP =ItemPropertyDamageImmunity(IP_CONST_DAMAGETYPE_COLD,IP_CONST_DAMAGEIMMUNITY_100_PERCENT); + else if (nLevel >= 6) + ipIP =ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGERESIST_20); + else if (nLevel >= 4) + ipIP =ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGERESIST_10); + else if (nLevel >= 2) + ipIP =ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGERESIST_5); + + IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE); + + if (nLevel >= 3) // Grow to size large + SetCreatureAppearanceType(oFam, APPEARANCE_TYPE_SHADOW_FIEND); +} \ No newline at end of file diff --git a/nwnds_scripts/prc_amagsys_gain.ncs b/nwnds_scripts/prc_amagsys_gain.ncs new file mode 100644 index 0000000000000000000000000000000000000000..f91269a67d429dd1d6b567af3f6a862de7a898fb GIT binary patch literal 49568 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 YbAXkt^>@ybvOl4c?B%Aby~XJN0Z5PhjQ{`u literal 0 HcmV?d00001 diff --git a/nwnds_scripts/prc_amagsys_gain.nss b/nwnds_scripts/prc_amagsys_gain.nss new file mode 100644 index 000000000..77b418bdb --- /dev/null +++ b/nwnds_scripts/prc_amagsys_gain.nss @@ -0,0 +1,556 @@ +//::////////////////////////////////////////////// +//:: Alternate magic system gain evaluation script +//:: prc_amagsys_gain +//::////////////////////////////////////////////// +/** @file + This file determines if the given character + has gained new spells / powers / utterances / + whathaveyou since the last time it was run. + If so, it starts the relevant selection + conversations. + + Add new classes to their respective magic + user type block, or if such doesn't exist + yet for the system the class belongs to, + make a new block for them at the end of main(). + + + @author Ornedan + @date Created - 2006.12.14 + */ +//::////////////////////////////////////////////// +//::////////////////////////////////////////////// + +#include "inc_dynconv" +#include "psi_inc_psifunc" +#include "inc_newspellbook" +#include "true_inc_trufunc" +#include "tob_inc_tobfunc" +#include "shd_inc_shdfunc" +#include "inv_inc_invfunc" + +////////////////////////////////////////////////// +/* Function prototypes */ +////////////////////////////////////////////////// + +void CheckSpellbooks(object oPC); +void CheckPsionics(object oPC); +void CheckInvocations(object oPC); +void CheckToB(object oPC); +void CheckShadow(object oPC); +void CheckTruenaming(object oPC); +int CheckMissingPowers(object oPC, int nClass); +int CheckMissingSpells(object oPC, int nClass, int nMinLevel, int nMaxLevel); +int CheckMissingUtterances(object oPC, int nClass, int nLexicon); +int CheckMissingManeuvers(object oPC, int nClass); +int CheckMissingMysteries(object oPC, int nClass); +int CheckMissingInvocations(object oPC, int nClass); +void AMSCompatibilityCheck(object oPC); + +////////////////////////////////////////////////// +/* Function definitions */ +////////////////////////////////////////////////// + +void main() +{ + object oPC = OBJECT_SELF; + + // Sanity checks - Shifted or polymorphed characters may have their hide fucked up, and might be missing access to their hide-feats + // @todo Shifting probably doesn't do this anymore, could be ditchable - Ornedan, 20061214 + if(GetLocalInt(oPC, "nPCShifted")) + return; + effect eTest = GetFirstEffect(oPC); + while(GetIsEffectValid(eTest)) + { + if(GetEffectType(eTest) == EFFECT_TYPE_POLYMORPH) + return; + eTest = GetNextEffect(oPC); + } + + DelayCommand(0.0f, CheckSpellbooks(oPC)); +} + +// Handle new spellbooks +void CheckSpellbooks(object oPC) +{ + if(!GetPRCSwitch(PRC_BARD_DISALLOW_NEWSPELLBOOK) && CheckMissingSpells(oPC, CLASS_TYPE_BARD, 0, 6)) + return; + if(!GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK) && CheckMissingSpells(oPC, CLASS_TYPE_SORCERER, 0, 9)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_SUEL_ARCHANAMACH, 1, 5)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_FAVOURED_SOUL, 0, 9)) + return; +// if(CheckMissingSpells(oPC, CLASS_TYPE_MYSTIC, 0, 9)) +// return; + if(CheckMissingSpells(oPC, CLASS_TYPE_WARMAGE, 0, 9)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_DREAD_NECROMANCER, 1, 9)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_HEXBLADE, 1, 4)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_DUSKBLADE, 0, 5)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_JUSTICEWW, 1, 4)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_KNIGHT_WEAVE, 1, 6)) + return; +// if(CheckMissingSpells(oPC, CLASS_TYPE_WITCH, 0, 9)) +// return; + if(CheckMissingSpells(oPC, CLASS_TYPE_SUBLIME_CHORD, 4, 9)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_ARCHIVIST, 0, 9)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_BEGUILER, 0, 9)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_HARPER, 1, 3)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_TEMPLAR, 0, 9)) +// return; + if(CheckMissingSpells(oPC, CLASS_TYPE_ASSASSIN, 1, 4)) + return; + if(CheckMissingSpells(oPC, CLASS_TYPE_CELEBRANT_SHARESS, 1, 4)) + return; + + DelayCommand(0.0f, CheckPsionics(oPC)); +} + +// Handle psionics +void CheckPsionics(object oPC) +{ + if(CheckMissingPowers(oPC, CLASS_TYPE_PSION)) + return; + if(CheckMissingPowers(oPC, CLASS_TYPE_WILDER)) + return; + if(CheckMissingPowers(oPC, CLASS_TYPE_PSYWAR)) + return; + if(CheckMissingPowers(oPC, CLASS_TYPE_PSYCHIC_ROGUE)) + return; + if(CheckMissingPowers(oPC, CLASS_TYPE_FIST_OF_ZUOKEN)) + return; + if(CheckMissingPowers(oPC, CLASS_TYPE_WARMIND)) + return; + //expanded knowledge + if(CheckMissingPowers(oPC, -1)) + return; + //epic expanded knowledge + if(CheckMissingPowers(oPC, -2)) + return; + + DelayCommand(0.0f, CheckInvocations(oPC)); +} + +// Handle Invocations +void CheckInvocations(object oPC) +{ + if(CheckMissingInvocations(oPC, CLASS_TYPE_DRAGONFIRE_ADEPT)) + return; + if(CheckMissingInvocations(oPC, CLASS_TYPE_WARLOCK)) + return; + if(CheckMissingInvocations(oPC, CLASS_TYPE_DRAGON_SHAMAN)) + return; + //extra invocations + if(CheckMissingInvocations(oPC, CLASS_TYPE_INVALID)) + return; + //epic extra invocations + if(CheckMissingInvocations(oPC, -2)) + return; + + DelayCommand(0.0f, CheckToB(oPC)); +} + +// Handle Tome of Battle +void CheckToB(object oPC) +{ + if(CheckMissingManeuvers(oPC, CLASS_TYPE_CRUSADER)) + return; + if(CheckMissingManeuvers(oPC, CLASS_TYPE_SWORDSAGE)) + return; + if(CheckMissingManeuvers(oPC, CLASS_TYPE_WARBLADE)) + return; + + DelayCommand(0.0f, CheckShadow(oPC)); +} + +// Handle Shadowcasting +void CheckShadow(object oPC) +{ + if(CheckMissingMysteries(oPC, CLASS_TYPE_SHADOWCASTER)) + return; + if(CheckMissingMysteries(oPC, CLASS_TYPE_SHADOWSMITH)) + return; + + DelayCommand(0.0f, CheckTruenaming(oPC)); +} + +// Handle Truenaming - Three different Lexicons to check +void CheckTruenaming(object oPC) +{ + if(CheckMissingUtterances(oPC, CLASS_TYPE_TRUENAMER, LEXICON_EVOLVING_MIND)) + return; + if(CheckMissingUtterances(oPC, CLASS_TYPE_TRUENAMER, LEXICON_CRAFTED_TOOL)) + return; + if(CheckMissingUtterances(oPC, CLASS_TYPE_TRUENAMER, LEXICON_PERFECTED_MAP)) + return; + + if(!GetIsDM(oPC)) + DelayCommand(0.0f, AMSCompatibilityCheck(oPC)); +} + +int CheckMissingPowers(object oPC, int nClass) +{ + int nLevel = GetLevelByClass(nClass, oPC); + if(!nLevel && nClass != -1 && nClass != -2) + return FALSE; + else if(nClass == -1 && !GetHasFeat(FEAT_EXPANDED_KNOWLEDGE_1)) + return FALSE; + else if(nClass == -2 && !GetHasFeat(FEAT_EPIC_EXPANDED_KNOWLEDGE_1)) + return FALSE; + + int nCurrentPowers = GetPowerCount(oPC, nClass); + int nMaxPowers = GetMaxPowerCount(oPC, nClass); + + if(nCurrentPowers < nMaxPowers) + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "nClass", nClass); + StartDynamicConversation("psi_powconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + + return TRUE; + } + return FALSE; +} + +int CheckMissingInvocations(object oPC, int nClass) +{ + int nLevel = GetLevelByClass(nClass, oPC); + if(!nLevel && (nClass == CLASS_TYPE_DRAGONFIRE_ADEPT || nClass == CLASS_TYPE_WARLOCK || nClass == CLASS_TYPE_DRAGON_SHAMAN)) + return FALSE; + else if(nClass == CLASS_TYPE_INVALID && !GetHasFeat(FEAT_EXTRA_INVOCATION_I)) + return FALSE; + else if(nClass == -2 && !GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_I)) + return FALSE; + + int nCurrentInvocations = GetInvocationCount(oPC, nClass); + if(DEBUG) DoDebug("Current Invocations: " + IntToString(nCurrentInvocations)); + int nMaxInvocations = GetMaxInvocationCount(oPC, nClass); + if(DEBUG) DoDebug("Max Invocations: " + IntToString(nMaxInvocations)); + + if(nCurrentInvocations < nMaxInvocations) + { + // Mark the class for which the PC is to gain invocations and start the conversation + SetLocalInt(oPC, "nClass", nClass); + StartDynamicConversation("inv_invokeconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + + return TRUE; + } + return FALSE; +} + +void AddSpellsForLevel(int nClass, int nLevel) +{ + object oPC = OBJECT_SELF; + object oSkin = GetPCSkin(oPC); + object oToken = GetHideToken(oPC); + string sFile = GetFileForClass(nClass); + string sSpellbook; + int nSpellbookType = GetSpellbookTypeForClass(nClass); + if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) + sSpellbook = "Spellbook"+IntToString(nClass); + else + sSpellbook = "Spellbook_Known_"+IntToString(nClass)+"_"+IntToString(nLevel); + + // Create spells known persistant array if it is missing + int nSize = array_get_size(oToken, sSpellbook); + if (nSize < 0) + { + array_create(oToken, sSpellbook); + nSize = 0; + } + + //check for learnable spells + object oToken_Class = GetObjectByTag("SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nLevel)); + int nSpells_Total = array_get_size(oToken_Class, "Lkup"); + int i; + for(i = 0; i < nSpells_Total; i++) + { + int nSpellbookID = array_get_int(oToken_Class, "Lkup", i); + if(Get2DAString(sFile, "AL", nSpellbookID) != "1") + { + array_set_int(oToken, sSpellbook, nSize, nSpellbookID); + nSize++; + if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) + { + int nIPFeatID = StringToInt(Get2DACache(sFile, "IPFeatID", nSpellbookID)); + int nFeatID = StringToInt(Get2DACache(sFile, "FeatID", nSpellbookID)); + AddSpellUse(oPC, nSpellbookID, nClass, sFile, "NewSpellbookMem_" + IntToString(nClass), nSpellbookType, oSkin, nFeatID, nIPFeatID); + } + } + } +} + +int CheckMissingSpells(object oPC, int nClass, int nMinLevel, int nMaxLevel) +{ + int nLevel; + //Raks cast as sorcs + if(nClass == CLASS_TYPE_SORCERER && GetRacialType(oPC) == RACIAL_TYPE_RAKSHASA) + nLevel = GetLevelByClass(CLASS_TYPE_OUTSIDER, oPC); +// else if(nClass == CLASS_TYPE_SORCERER && GetRacialType(oPC) == RACIAL_TYPE_BOZAK) //Bozaks cast as sorcs +// nLevel = GetLevelByClass(CLASS_TYPE_DRAGON, oPC); + else if(nClass == CLASS_TYPE_SORCERER && GetRacialType(oPC) == RACIAL_TYPE_DRIDER) //Driders cast as sorcs + nLevel = GetLevelByClass(CLASS_TYPE_ABERRATION, oPC); + else + nLevel = nClass == CLASS_TYPE_SUBLIME_CHORD ? GetLevelByClass(nClass, oPC) : GetSpellslotLevel(nClass, oPC); + + if (DEBUG) DoDebug("CheckMissingSpells 1 Class: " + IntToString(nClass)); + if (DEBUG) DoDebug("CheckMissingSpells 1 Level: " + IntToString(nLevel)); + + if(!nLevel) + return FALSE; + if(nClass == CLASS_TYPE_BARD || nClass == CLASS_TYPE_SORCERER) + { + if((GetLevelByClass(nClass, oPC) == nLevel) //no PrC + && !(GetHasFeat(FEAT_DRACONIC_GRACE, oPC) || GetHasFeat(FEAT_DRACONIC_BREATH, oPC))) //no Draconic feats that apply + return FALSE; + } + else if(nClass == CLASS_TYPE_ARCHIVIST) + { + int nLastGainLevel = GetPersistantLocalInt(oPC, "LastSpellGainLevel"); + nLevel = GetLevelByClass(CLASS_TYPE_ARCHIVIST, oPC); + + if(nLastGainLevel < nLevel) + { + if(nLevel == 1) + { + //count the number of available at 1st level spells + int nSpellsAvailable = 3 + GetAbilityModifier(ABILITY_INTELLIGENCE, oPC); + SetLocalInt(oPC, "LrnLvlUp", nSpellsAvailable); + } + else if(nLevel > 1) + //add additional 2 spells form cleric list + SetLocalInt(oPC, "LrnLvlUp", 2); + + SetLocalInt(oPC, "SpellGainClass", CLASS_TYPE_ARCHIVIST); + SetLocalInt(oPC, "SpellbookMinSpelllevel", nMinLevel); + StartDynamicConversation("prc_s_spellgain", oPC, DYNCONV_EXIT_NOT_ALLOWED, TRUE, FALSE, oPC); + + return TRUE; + } + //add cleric spells known for level 0 + else if(persistant_array_get_size(oPC, "Spellbook_Known_"+IntToString(CLASS_TYPE_ARCHIVIST)+"_0") < 5) // TODO: replace with GetSpellKnownCurrentCount + { + ActionDoCommand(AddSpellsForLevel(CLASS_TYPE_ARCHIVIST, 0)); + } + else + return FALSE; + } + + if (DEBUG) DoDebug("CheckMissingSpells 2 Class: " + IntToString(nClass)); + if (DEBUG) DoDebug("CheckMissingSpells 2 Level: " + IntToString(nLevel)); + + int i; + for(i = nMinLevel; i <= nMaxLevel; i++) + { + int nMaxSpells = GetSpellKnownMaxCount(nLevel, i, nClass, oPC); + if(nMaxSpells > 0) + { + int nCurrentSpells = GetSpellKnownCurrentCount(oPC, i, nClass); + int nSpellsAvailable = GetSpellUnknownCurrentCount(oPC, i, nClass); + + if(nCurrentSpells < nMaxSpells && nSpellsAvailable > 0) + { + if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS && bKnowsAllClassSpells(nClass)) + { + ActionDoCommand(AddSpellsForLevel(nClass, i)); + } + else + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "SpellGainClass", nClass); + SetLocalInt(oPC, "SpellbookMinSpelllevel", nMinLevel); + SetLocalInt(oPC, "SpellbookMaxSpelllevel", nMaxLevel); + StartDynamicConversation("prc_s_spellgain", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + + return TRUE; + } + } + } + } + //Advanced Learning check + nLevel = GetLevelByClass(nClass, oPC); + int nALSpells = GetPersistantLocalInt(oPC, "AdvancedLearning_"+IntToString(nClass)); + if(nClass == CLASS_TYPE_BEGUILER && nALSpells < (nLevel+1)/4)//one every 4 levels starting at 3. + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "SpellGainClass", CLASS_TYPE_BEGUILER); + SetLocalInt(oPC, "SpellbookMinSpelllevel", nMinLevel); + SetLocalInt(oPC, "AdvancedLearning", 1); + StartDynamicConversation("prc_s_spellgain", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + return TRUE; + } + else if(nClass == CLASS_TYPE_DREAD_NECROMANCER && nALSpells < nLevel/4)//one every 4 levels + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "SpellGainClass", CLASS_TYPE_DREAD_NECROMANCER); + SetLocalInt(oPC, "SpellbookMinSpelllevel", nMinLevel); + SetLocalInt(oPC, "AdvancedLearning", 1); + StartDynamicConversation("prc_s_spellgain", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + return TRUE; + } + else if(nClass == CLASS_TYPE_WARMAGE) + { + if((nLevel >= 40 && nALSpells < 9) ||// :/ + (nLevel >= 36 && nLevel < 40 && nALSpells < 8) || + (nLevel >= 32 && nLevel < 36 && nALSpells < 7) || + (nLevel >= 28 && nLevel < 32 && nALSpells < 6) || + (nLevel >= 24 && nLevel < 28 && nALSpells < 5) || + (nLevel >= 16 && nLevel < 24 && nALSpells < 4) || + (nLevel >= 11 && nLevel < 16 && nALSpells < 3) || + (nLevel >= 6 && nLevel < 11 && nALSpells < 2) || + (nLevel >= 3 && nLevel < 6 && nALSpells < 1)) + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "SpellGainClass", CLASS_TYPE_WARMAGE); + SetLocalInt(oPC, "SpellbookMinSpelllevel", nMinLevel); + SetLocalInt(oPC, "AdvancedLearning", 1); + StartDynamicConversation("prc_s_spellgain", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + return TRUE; + } + } + else if(nClass == CLASS_TYPE_NIGHTSTALKER && nALSpells < (nLevel+1)/6)//one every 6 levels starting at 5th + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "SpellGainClass", CLASS_TYPE_NIGHTSTALKER); + SetLocalInt(oPC, "SpellbookMinSpelllevel", nMinLevel); + SetLocalInt(oPC, "AdvancedLearning", 1); + StartDynamicConversation("prc_s_spellgain", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + return TRUE; + } + + return FALSE; +} + +int CheckMissingUtterances(object oPC, int nClass, int nLexicon) +{ + int nLevel = GetLevelByClass(nClass, oPC); + if(!nLevel) + return FALSE; + + int nCurrentUtterances = GetUtteranceCount(oPC, nClass, nLexicon); + int nMaxUtterances = GetMaxUtteranceCount(oPC, nClass, nLexicon); + if(DEBUG) DoDebug("CheckMissingUtterances(" + IntToString(nClass) + ", " + IntToString(nLexicon) + ", " + GetName(oPC) + ") = " + IntToString(nCurrentUtterances) + ", " + IntToString(nMaxUtterances)); + + if(nCurrentUtterances < nMaxUtterances) + { + // Mark the class for which the PC is to gain Utterances and start the conversation + SetLocalInt(oPC, "nClass", nClass); + StartDynamicConversation("true_utterconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + + return TRUE; + } + return FALSE; +} + +int CheckMissingManeuvers(object oPC, int nClass) +{ + int nLevel = GetLevelByClass(nClass, oPC); + if(!nLevel) + return FALSE; + + int nCurrentManeuvers = GetManeuverCount(oPC, nClass, MANEUVER_TYPE_MANEUVER); + int nMaxManeuvers = GetMaxManeuverCount(oPC, nClass, MANEUVER_TYPE_MANEUVER); + int nCurrentStances = GetManeuverCount(oPC, nClass, MANEUVER_TYPE_STANCE); + int nMaxStances = GetMaxManeuverCount(oPC, nClass, MANEUVER_TYPE_STANCE); + + if(nCurrentManeuvers < nMaxManeuvers || nCurrentStances < nMaxStances) + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "nClass", nClass); + StartDynamicConversation("tob_moveconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + + return TRUE; + } + return FALSE; +} + +int CheckMissingMysteries(object oPC, int nClass) +{ + int nLevel = GetLevelByClass(nClass, oPC); + if(!nLevel) + return FALSE; + + int nCurrentMysteries = GetMysteryCount(oPC, nClass); + int nMaxMysteries = GetMaxMysteryCount(oPC, nClass); + + if(nCurrentMysteries < nMaxMysteries) + { + // Mark the class for which the PC is to gain powers and start the conversation + SetLocalInt(oPC, "nClass", nClass); + StartDynamicConversation("shd_mystconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); + + return TRUE; + } + return FALSE; +} + +//AMS Compatibility functions - xwarren: +void CopyAMSArray(object oHideToken, object oAMSToken, int nClass, string sArray, int nMin, int nMax, int nLoopSize = 100) +{ + string sFile = GetFileForClass(nClass); + int i = nMin; + while(i < nMin + nLoopSize && i < nMax) + { + int nSpellbookID = array_get_int(oHideToken, sArray, i); + int nSpell = StringToInt(Get2DACache(sFile, "RealSpellID", nSpellbookID)); + if(DEBUG) DoDebug("Copying spell "+IntToString(nSpell)); + array_set_int(oAMSToken, sArray, i, nSpell); + i++; + } + if(i < nMax) + DelayCommand(0.0, CopyAMSArray(oHideToken, oAMSToken, nClass, sArray, i, nMax)); +} + +void DoBuckUpAMS(object oPC, int nClass, string sSpellbook, object oHideToken, object oAMSToken) +{ + if(DEBUG) DoDebug("Creating buck-up copy of "+sSpellbook); + if(array_exists(oAMSToken, sSpellbook)) + array_delete(oAMSToken, sSpellbook); + array_create(oAMSToken, sSpellbook); + int nSize = array_get_size(oHideToken, sSpellbook); + DelayCommand(0.0, CopyAMSArray(oHideToken, oAMSToken, nClass, sSpellbook, 0, nSize)); +} + +void AMSCompatibilityCheck(object oPC) +{ + //Get an extra hide token with amagsys info + object oAMSToken = GetHideToken(oPC, TRUE); + object oHideToken = GetHideToken(oPC); + + int i; + for(i = 1; i <= 3; i++) + { + int nClass = GetClassByPosition(i, oPC); + string sSpellbook; + int nSpellbookType = GetSpellbookTypeForClass(nClass); + if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) + { + sSpellbook = "Spellbook"+IntToString(nClass); + int nSize1 = array_get_size(oHideToken, sSpellbook); + int nSize2 = array_get_size(oAMSToken, sSpellbook); + if(nSize1 > nSize2) + DelayCommand(0.1f, DoBuckUpAMS(oPC, nClass, sSpellbook, oHideToken, oAMSToken)); + } + else if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) + { + int j; + for(j = 0; j <= 9; j++) + { + sSpellbook = "Spellbook_Known_"+IntToString(nClass)+"_"+IntToString(j); + int nSize1 = array_get_size(oHideToken, sSpellbook); + int nSize2 = array_get_size(oAMSToken, sSpellbook); + if(nSize1 > nSize2) + DelayCommand(0.1f, DoBuckUpAMS(oPC, nClass, sSpellbook, oHideToken, oAMSToken)); + } + } + } +} \ No newline at end of file diff --git a/nwnds_scripts/prc_cbtmed_spnhl.ncs b/nwnds_scripts/prc_cbtmed_spnhl.ncs new file mode 100644 index 0000000000000000000000000000000000000000..c92fcc877f03d2cf9432678aaf1d612275e97bd2 GIT binary patch literal 47843 zcmd^o36xz`neI9FR#irlA{G#agiAn%5F~^-OsP~=ps+GnRS;01s8lXVkxCU*Re}u7 zLvabu0b5;-imi=PK)V}hn?`WpF*T3XMrCQxv@a^Nh;++CTJtnm@7v%1?{oG(ci&U@ zg1+TiPnLCa|NZapANIfhJ)Uz{we^(FKkjXdmq*bzo}C}ze^X0Qp;#z3G)B|bbhq`j zcPu~eY*P^bLmW>`Oze&t4vg@*2Q0-XS{9kVQ9QMjQ(DL^otj(PoLgGTEnSvddP81m z3_n!2sE}LQkXt%6x3oF8v{X^LFk+*%A04q(9xp{j(@J|Hv|sdUgg?g@Xvb@|-R7A_ zo+)i8f6?Gg4NZoewOHCXT20JXq6Q;t+SQd@Zu#lY`{h<2iIW*6`~6@eu*H6(R{QcB zBCMeZ8zyFyrj*Dv#DFw$CYrn`nk<_hmP8b2J4!w#P42&qltfazf6+%* zUu1kFR{6-32Y<7y*i0>^yiDp-=q{#xphaU8pC?TNb3~0ok%emBs*e+(FoOW`UHsNW zQ7_vX7K~-nXN$ofR2*ZK!{2tdavR1jsDILG!xGTgyWp8)Zp;iWuLqM=|j}(mpb}S`ZqRoCjeW|vp=rH1!~89d9)tWz5N*eYamW1*4d&xzANI5!h$ zD6iUXyXYj-ZkbAHYOQ?i~Nc>$0n3+UHXZr=@LLChXV|Sm%#uEvZA_LLN z%J7cy%LiV~Dkd)WsjPt{#ZQErM(%&A=MZu%vEAi9!Crk8QIhCaKT51LdI4ZmnR^GU zc`;_4q}yAG)T&WK`l7VQupBMJPnElBf*1%;$E9cqvCQihi_%Dlnuq}_**SJQokL2p z2y-n5bXOcl9;6dzhvk}>_~TKO055r(JjZY0PKH*3Q?!$zz40y6$vh4;4LD{eoy_Er z&UQ+*d?H%^no*?oUiL**+(cW_%kESnd)d40p|y`2uNM9&z9r>F`8PE&?axU_4TB4! zm%P)=;9}c{gUp#S=Sez+b!{L`-aJd>?O&W(YVuJ+1DchIOrDXM$6c(8dwN~mM;mTq zb$puVgBEKSy}PgW3dE`DPB*=iy#OI05h%Q*?Y1b8 znFu;x<~CVDHdh%zRak6VG=j1$0^&?m{&JL1BC|^Aq$9N^Qd!hsnea6O#%0 zal2-Ce40A5j#G>beZL>Jl#FkadXH;8e42W5zi!Hjh+)!D4mv+enRj_hW+_2_>#U|4 zvX=GQl)8HPmA02h3n|gYL19192YJ)=5P57X*P@lR;LT};h?dY(t&)-2>1xoFJhf9~1NbmqtJpj|Wj8F@y3qic-ZxK@`}LL0PRR zA&Y=a6x7OUOgidh$`f5I-F{}JkPdFu2CYO2e8*4iPltb_np~|150W2A!mIaQtyiIs z*0YwOCwcYG&FZQAJ5o8OS2w(UL6Nzp#Hf%(V5T)QH6e*L_YTxdw3Han)I?mFn#CUn zYUZ^XeBv#6A%&R`^orQEEt#zYdeu6J3hR4M4(L_uzzZzft~%_b#dAa-{@umDyOUj~ zlG$}?YwhXn=zvU@CxG6l|9{ z-yzk8GI#?5)Gpgkz(o5Vq1{(_0DuR;+5(ACR~x6pey2v(+&x}ZP+8UYns~wYMRuw) zaWsL#zC{GnK`#?yS?a7vHe6n_bv*B_gr-ntN^>=NP9?Sjxy0Cv*7xypg z;@(<2x0#C9&W*l)VeQ;?V=pw=UJ~2GB|uFm$p)#rC~cXzf+ zj%EV48}(=$Nj)}M=-72M7QDMdndT)oQypP;mob@Qe%q?Mo{iB_kbQP}oD1mA^-Hnl z+%mkrG_tikIy#6YDA%Q>!S$sxWH&<;GP{h>yLnM*WOQ)D;Bfztu(TXXRdi#7`E=MB zEHET6XJG?Mr^W81DKXEl;rTEpgF>IC(+BRk{O``Bdw@nA8%{rV;7p@e;V_(e#9NcG zP&_bm0sV1uer+PkV7j&7s|Vo4v1Ir3gvD4n7>$d+(gPcrXUS-t zOg!k(+Z{iQ9}{_=XspAUsixz}Aa1=#Z~4-eIMSNP7ib&rFzhwVHSGSp@iM}#XJF&V z$dLJ$Y~L753tg0!1hZ`gaK)`N4y9tQ6TG=WVM?l2{6lqu={2a_=2ezG6t8mpZ%*Y~ z{mSiLWjVj{D}UIje4$^t!>cT_cE9o(r}9C5<@3GDjb7lgH^*;DD@Q-~D|dR8<@myr z9R0|t{CU6fDzEaCO3BfuoXTata<5l;YM}B(PURzy!Bi5BA4smaX-m|b#~<)Haka8O9K9Bev> zIlY_3%K_!FfziP$#z#iw{1}jW++5K!G(%=`T$H&~;ACCNafOEeK3)3xIaCwW%=}(+ zPoZggi3ZpVAO^HM?U$U#Sg!?ZRJN0>P36o^a>DfX)Nt%*Uokq+XLAEiWfpTtJd)ZZ zZAQ!7X~7<6Ac5b!NR$Zk>c;b3OEmimU*cq!&5Ms)a{LJ=o^J3VLw@Zy9rM}mtPPNnz(SmK_HZKQoYb1JH0*~dAB5jV4a-G_+{DwgNo74IY60m;# zjY)YyQ>$Noj+Dz^@iy&1J3uBA1f}{N-whGjMv!?p5_p45I}pI8RsV2OVDg4CN1ij} znu7#dn(2DfNP}0or=B`;~^i(jr*8P^bKXQ(m+)aL{Bbb>|w zZI@1G?lxVkuYUVWPl`JwwRN*w^ana^70vz$jcbyOUb}B<1Anq^aBa(F)KLeLcpJaL zqijG=|M<+hMR<NUZzcPFbimoQ{BB3sY63#hYwG|^qLXDv775zE&1#J1-QC2 zsJR`xGMXc#W~>+;xu!h4vVX(i02PO->P2+s>ZT;pJeIlqX8px5b%x=Do;~z)W)Fbx_*y^nDpIwKg+{Ru*l5Cd~h3VQ_m`4@z)m>iU{rh94AV=JZQYYA`xe$?*Aq93 z;-nJvd6RtN<=Vl~DJ_s0`=9+Czu8%ozju3%)j*c6qdJJS|Sxk*ci4;@c}mmKg0 zQ>NVhbd$1PJ@@AU(frI{==<1t+`u$b?Z-smUR@V=XIE%AJsla}CBY?gLMQoQfFOUQ+poeeOO+5mRQ2Q_vAq=;tC;Nb zOKU21j>n6TBCn)ID;aAFQV;NWk$6a*?@_VELFxjJid`X65BI1zk|fpN2tv{(HQ5cN zzPJHH>JkqDcPU6c$)h5*kh;{PBAJmYC&$*dWlCM{@#3}!c~^K;-18vyT#t(T1*EP@ zsdA5i)b5muM!-D>QqT9ONLQr3)1!VysnVgWzIP~foyUut97IU=e(1BGD)n-Y7rmUk z{?0LO>X16>@!}Q-sariNhBH#H@u)~%q+ah)G2oE;UXO|)j@0*i)CZLM0gsBImb|xk zRNQeQ^?OO^ymE;A(! z9}kptvCi>d4ZC3ESVoDIfo?&2TItt^Rt%aWr5 zCA(Piu0YAdEcqXSk~>-QV4&m{mOKeJ*!}A=^GY{>Cm~V^q^U<%h4LCKdOT z3pZ1zWcaq}%G=nL<3_A~XejkA=wX;MJ+P(&3#RMdQnJsMPFiBz_o(xp@~^0tU9cf` z0|In?h{+C_!DQC9uO@>4?U!viD8(kd*z6vY{+Do%c}9-!Z8XR|=IyC7v-g;3S9XS- zw~D~LICmDkFSSCO5*hPZT|<}neVQLVPBdVe;B}>(9dq5wu5ungIrhT(+pmqD3y;JS(!kWMRI;qJ*|(6$O!$ z2+BUxrYy*DWcjl_8aFZVq+BW7;VouzAB~%s__2Kqbh~zOd>TJLbzk12aT60y|E>QZ z+{DBS{aMQMNBI=Ym#){%prjcXC)RzK*)z(zNVToku$NE|@~C*sjU8hqy(;S^G-gE% z+Sc>2ZL;#QEj5H~W8FO!x549M+ivY+TWSa!ax3(PPiXJX$sRu|_Nh;+SRX`zM2*WQ zWb3iGzoJyJGl&A4e3SwnsAT^PSp;OFpjK96(orWQSKhC`lhsrCccgMmU;EXuIx#3!kL65FNHR5F z`maFEL`xYsGBpubtohAA&Ae8FPrS#%AcZXrdPVHomdw@xy=omqh4sBB2lT3S;02a# zR~>fJVs~1%i@ISGhuC{02hTnk$$p-k#57@xc(WHAH+qM7%ph44!y?FvPhbMEpdEcx#BbB}BY9MC=F=mxhSX zgoxLX$grw@;(2u~ObcpZs_9ttN3|fe)xvadElmHr7N*^`Fb&nhRO_*5npD_2{lsS4 zK;o6OVN)mbO)J0I0Tw*0R@_I1E=;teb!cJDJjgC?=D`AUdgrS1`^-C`%CZxQWP>Wl z7bG+?`}+P0Ygw9zkV&qfq6_@vQaSX%s6#mO?9N&|yOW$y%C@1^-R8OWpgSqdBK<7L zq6hYtX*-!R#5W8<7vPE4?P>yU_ZwHetlfaOLt+0i^?#A#PmkQp_Cn8T~8 zAaim+Dzt)gsWF<5WzSX2k6x5I>HNsE#_rg!@u>E!#y@|tJNAcpy!LEqmPgg|fx>Q& zswYl`XFRH&I2E>gR6W-z-0M;GT&HlmN7XZxf`9Iyr#*#nk5^Be3jV2#o^KW8Ar;%! zdcIXy;vwj1PeE3zmRC=3^sc6*>IqK#iie=5GVxD5s-7*ykEYc094fvmr6QN;nN|Er zkE*ACv42*h=W+3eJYGFjjJJAJJ*$Z?^{9GY6#M69dNLGCceWPmDP26@L(tQyc&bO$ z)1K&6kBYUnIRlDzdDPD+^)Zi%YX#)J+oMiX>TMqNVx_*%qv~l|H0)9J#3{PKqv{D6 zo_NuBbV}+_+%EP#o*H4ZLf;a}-Y2_fqtX*uN0ugb9p~+?RV`m4^&J%16UkrT$YW1- z{px)3A*W+7Hoqv!Vw4hSn&GaKbkCedX8>X`1hWLG>p3RM9qnaL*)CIH#H?C&RKZUN z;V@lyR2Q201>KEgNG-&jmpaxorBB>}J9#rADxhxi5>410W^2XDUYKVuQcJs zt32eezM)g!!TP>WU>|uvg-E^SZe1=4SBfxK6OzZ)IA9!t+IyRu^Q|j;dPg>u@%GJu zjb*mjK`5GIiq63k;c1z#OX>&0?T=}4`zE8+O^aMnzYeLRpJbqER02i_&%*k1>>G7GXd71@yS^` zNO#JW52&Qi@f}GOk<_RhARQBqp`*kI5r)SQJRA4`+{c{;w@OC$kZ6s=Y!1TbXErLl zdQ^4UqGovN6#QSdL}eNb*N~MuL^l_7jF+!X@&x>u`oJtCGEx&eO*3yqq>P&=f)WRZ zEN#ljJy@b$kmTR!PHjb%EWwTaXmtiZt(G!DTPm-_bN5)SlkKca4r|=rAdd*5H+XMH z_@6N0ppkW#mj}j6csIhDww_Ic!$&G%WKG*qD4%H_?HnA&gDHl zwDtD&Ubv>CudTbIwfDSkc{c=V!@FsBVaOjV5u^bNx6zk-gYnZf1p0I!?zOIetlY;3 zS7DhG1{zF$_JNCmy)b4l9Vx=RM$**RP^4mCz=P7@mu4oP37@P`aA?pZ!m1+|zsxe( zrDL2F9x5c!HIrf|i7qih<63&34IQZGWPUevBvm4l;7YwMnjAJM#JSBx~y>K z9&rk<*rk;|$f(hTj9QT_IV6nX0!o&*@4^v5 zRUNUyQfwU;2Lrq1(5#kL`+$CO7My70Jzyiyg{6p%>=1%%pF}y)DL2F=s!C*&6G3U# z+~4>F=Ogl_YfZTfwU!n+bTJ zz}OmqE7@^gTBNDa&~VlbIs*ntQVIECN?y}I0l+O~%8!@mJV8MJ-EUz(M@TrMqf#}z zf?FrzU$sJkn#^}jN+)H;XS>@NzYr~Yrim{;nD(weCdzo=E#e=5PKz`1j0|TDzLG|= z-XyYp>%JHX&B!B%&eIzjT1!#1pIjwNyql4GxW&tU8jJVbosK=QVTw%47IB2F+S%A^ z;+X}H*SR@^s5+LvmH40!8g%q%gC9L_GL+0YD591K;$>WqXF zXt)ev`xpuBZGF9~dt1AbcXs8%+qjMtepLqkc)}YleIpp)m$&wG)P{~ZE|s6ib&uil z+#@f~tjRswbzEPQ(fdT|ErZa$#w{y5dRtevp556tndX;kYA|(O$A_C%B(P~y39aqt zp4Zd6vSU?muJ3oL?(fX#eir4%@W}$BIp4w7*W22Cc1Let*Xp*`-pDAJ%f2%qF>8-V}rvRS_jO$&m6Pxm2j0_ z^;SylEI0n!KU1;9>gJ7dHmuR>%!Y_bU0=IE(xr#hnPAP&V#%pbiNE8Zfar!U;FJJh zj&jSf#woR9Y__rMVExlK16Uo2atCCU>m3=#`|lDkbTJo9-+$*>x*`EPFblS_Jl>D@ z#0(CoY6x5xO%~}*9@^x7AmY>ky!-nBTT{TfS@nARM>mwmmzJcvIxTA!Fs5bi zzCHlho!EOw7I3wF(O>}iajKdiA127Q55NjtcD9l9giRu%n}oGx=I4XDt06vJEFtqj zZ+cQEB2p5OJw&|qH=vNrd*FSRA`1vG)8)G|-;af~Nk>ddlnEg`KgEi7+9W%CuFr_+%zR%2vH8R3Oe-uIhpTt ztPb75v2}8hW(YNdl^tm7^lo^-om^~oj4Wp?J2&(F77CC z#{fFHU^|-rAS0+Z^WD6+v*wYoir5U~n-eh;9iv(=F@2@Dw`PZIC(X8B?VWP6Y3$h< z18eMeS=ek>TakgSt!rgbv%P5&H{|r5EV7-hW>Y||9V5kCS7n-7RoA@fDT6S@mdT^- zXW7_$BmF9iZM)JZGwoG>*CFzoLNUF=(NETl{JR6)Mo*bKR`j)Yx3#Y7!2A7sdO4!) z=1k!D0ymZ9JZMko0A=?5vaXd;34pWKj9uM5vSCZPy?=Ov-W#eJY{&(}>a~VcgP~D> zTG6N)n~CwH>B-i~o0AWyfOTb%bdC(PKLGQ%6%DLU5tvGcEOUv$QL>wUmUBbu^Vr@0QR#dJ07*WWs=aBa4e&zQpUY`q8kx*#d-*>!*+jSd+aJkuEJ(p-j{Suv{BpQ#b~kn$ zM>e;YFB`(4)ree>^Bns(2;c_OuHIkM(t6%Xry?CgfhS|^PTkHB_=%Jn>J9S#U34F5 z=J4Y)PJh+O^qqQ-3hLN~Ga9cQ99oZeJC!Ad}&ih7uX8TIzMoc>2^B#x+30aIe`cD*i){40B8lJ_MQ zrAK(yVCK04_zhC{iJoS6xTkKie5R*1Z=5ZwSU8IHWZxRlru59u*nR8xXS&I3O7P0+ z6*!aZY&ZW(Ur>9;NATSqVo06^H?4&!RG-gTPJf3OB*E?BPF*{AOnm-uz;(X2bIS(e=K(ZT}jqcbr$Rv3+#QV7B6if)$VV zDo$C`Kh(dT=e~~jw!I@*HDe`uDn_D=w)@$dY{4AQPyMm$c_+DOdq z4V22jh&GwmTsYzoV3iF$RbRoX4PErS&`48!OTM%c&3wA)K`~yTU6H5uH*2poBUhD2 z`?|~P*Nn z?(X9+SoPTOWc2#Ig^!X~X{VhU?|~ZmqILu;rlG_@x{=?Vfkz*zT50Lf*3KIA&N{p$ zzh)gRAQKd%ZUAv3k7;DSE~mmgJG2y|8Ige8QhLJz31Oiygyp_=r`Ff#0B_PZeS(hG zU(-eYp(3dQuuA+wy3J1^1rkmt*Bk!Hf=WU}6#xjE16on+P6Jl>kf^}Fay81Ei&C}S zk`9}WKtf+E$IW)0A%~*ov5h{NB;vxhrlLi%TA@sD;!v0?GIcz$7xuto=1Eh2_%rm~%N%qG)aclF$9bOt7D~)f&Lh-8M@@Q$~ zGJfHD(&%6Wn`;Ro_LFx7#IlvV0VeW($<3((R|UA;dsN9=`pq&2W;MyF7~2VPk^MAr z65Sq-6As+Ce$Ff=4}v>c4A_DDxu8zz6Onp}3Y`UhmD>yHJsHo6YUkXql%mST4#29t zdzuR4GBXukWWE(&3J7}D?KE@ zalXW-@BDa%48m1e(O#J_XQScD4~4>4?rsY2=gHh3CFDS}YEnt>zqGI;$g)tX_y zyRVj-?(vWo@t^)bZz7CKfE4JqU_tYS937< zi=XXBr&xWVJg4PP%51^!#?QI#KvU0JKGZ+3sjGk8)uV&M;~TAW7y}lN4oH_;>t(4` zOh%4PxHyTyFW!h+<~IbQ7s%m#Z&-GFgzT;i{qeqsgYPGX`DYQwMm*AlZE#=NlU-%W z8ej@`Z*MpKsmudRg@*J$+PG849p@9$ejZb?3n}wO{UOHJSOJFw{Cp*vX}_bwkBejl z3iX!ttgD`^GtBTq4OkVxhs4p$Xligkx25o%UcPp8H0s4oEr)nckvGM^rl_bVBjM~r zWKKhwPU-%Bu6G|@va%bh$&MaT+2~EuQXV?$<;X^<%1&xax3?Iy>Tz|u`%d-OC`boa2^)*U8#)VoG z>pqn2ankY`7wP#Lesas#L?_kIo;m@8vDoZ$S$(D3CqKBmBwYJ|ANaMMXh7@MhH>yk zZyw{&FXmye%=&C{-@`*pjSm|COleNn74d@}620G~uQL$KQ!f!=yFqCBo`bMGfUr$M zJcJOtT!YZ~Sc(vx z8$kGM4#GJ^c%OrCP5|Me9E3SUSneRq2_Se+Ci$%ywGtt65Lzn{8g^FKq0np)8Xiay z3ex**Y%-!6Zp}g9xZ7}@gCJ9SAECE8LcEnaEKL#OtpO`^1PsRHJqDq;J4J}@sYEC~ zQC)`uuKWVw-V~uAS<|zkcuRGJ_<16XrwH-$0Uf$>5MCg{5(nXh0K)X@2+@58q3}wI z5ZzaaPYm!oZbS0zHE zH%vl)z+?09L-drRL!fU)_f^*+T1|w{ItZ%+I&95BSV@G79E6nt1b3SU)Pb@3S zSz^OtQn#y`;DrEvjr9&&QMZZl-OR84OZq-^5?IarTKaW)(K&XiyizOR37JVXucK-^ z^SSn3KrSps90PWxb0v8Ut0*VDpp)BfnaVl=deA^f;wQLTN@99(AGOQ41oPVN@|9+y zOEy$9rr!80Au-8u6fl!DOkedeV8g(mU{D(_#;%+ez_H419QIewItHTMXkeu081k$*;)JHKC8#$f zir%S<;=arkZk&6Xej1~$ab(>PWS+u$v3Q702}JnH(SBLOkU^5<;BU@Pe{FRV5sVKqM+R^8?PAx2ndJK}_` z^LXN3xOv*5(s@`wrZJQ{-^9?hf9EKIXkimPs%`lM%iKMO9aPaSchLbUkR1`3(n;>J zNsT2i2oDAn{ljE$+S(zVvau8}8hECC@aow^@g>myQZgB;x>mk$x z`d7Py!5~t=!_o(mAEOW%((^nS(cQibZvfC6w)B(Ay$-+WS#fiW3>c62DY;=@Wp3E1 zw#jDPDXv^E@A}G64(!r!%l51t}B0vu`|6(bH|uU{5dH z>8dXOwxLwf(?^m%gJfnJ?zYe8sGa?JYH3dBMT4hhno}I+>!$N$+h3`dO8(*r3#9kj z%(2Rr8uZ!bea7>WBi2A_!7d)Q*ddPW@@wmIt<&*WK&SZKuD{TGabF07T3^p<{Aus( zY3=G-y|!;v$68)5T)uks+l`+t5^+}7j3+97;Lh)CYf>r8Tf5t`xi!cX0Ac9tfXB|KiSk-`kYAsB02GZ6RbG8dT)74(i}ivXg*H1eui4qB%-kz8r=4?S^r2p^u2z4(1FNa8ZDh+Zbgk7TfKyw%rIMag%C!qf z*Su_V;FnEy{txH;C;Bq&@G$ar>*MblgqPj(pYH|`a(3&ZQ;Fc7|C|~?P+xlU4{OCK zL~zf4PN_u5+pUj2Oa$lrC;D&zA!oNfde|WR%02&iIDpXQj_H}UxSa^@`OobEgq+>_ zc!&tj`AvuV3Wu)?Z5m=lmzSHlRb!ZhiDAA~@$i z(WfdAa(C--stGHc^Pebis+qT2ACDV^7oGE;cs!s(-fsO0BDm*2D*^~_Zns|ZK>R(* za^wGdm9iRga#1`&1ULRi0th*|DE^8;_=OYy@mDGla&ysjL~!F@et^!4y}Xmd=t3em z@gK=$As-JFSzl)C16EPE{fhy1ULTQUx|>Li~gPnPW;DzA3(^4YY{6~R!$je0$GwSnh{0A~>UM`C7FjhS8oPWl5R9cani#mwlo_}@(5b|=- zy$0bq=lnCew-O;Y7tJGrbN-3TfE778FBcUA!8!jdgb?y_(I|CT;H-*A13LUka#3`@ zk@c(_|MyqQ%9~jg_9223|Al=52szm-x`qgD{9hA5$jN3=r$KnejsMO{guHAPf1e0W z{Kwx9Amq)g9w34f|Iq^hguHC_5E0z?e<*;Em(4g1KJCVTU>wZLX3<)s!_#j3udURf zkeAJFB!UzF(TxFwylnQ5L~!H(9|H(EGpp!x2H~lvoF4SKN`$;@7A+!zd;Y&DfRJ|& zVlffi^Z&&GguHC_H6k3~Sn;(=gxqX)mO=RWP6y$v0K$Dav)to}aI1q5_-XqnC!59J RB0_J95PvJ6!yC+I{} nCasterLvl) + nCasterLvl = nTest; + } + + int nClass, nLevel, i; + int nBurnableSpell = -1; + int bBioCastersLoopDone = 0;//will prevent running 'GetBestSpell' loops twice + + for(i = 1; i <= 3; i++) + { + nClass = GetClassByPosition(i, oCaster); + + if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS) + { + for(nLevel = 6; nLevel < 10; nLevel++) + { + nBurnableSpell = persistant_array_get_int(oCaster, "NewSpellbookMem_" + IntToString(nClass), nLevel); + if(nBurnableSpell > 0) + break; + } + + if(nBurnableSpell > 0) + { + SetLocalInt(oCaster, "DomainCast", -1); + SetLocalInt(oCaster, "NSB_Class", nClass); + SetLocalInt(oCaster, "NSB_SpellLevel", nLevel); + ActionCastSpell(SPELL_HEAL, nCasterLvl, 16 + GetAbilityModifier(ABILITY_WISDOM, oCaster), 0, METAMAGIC_NONE, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, FALSE); + return; + } + } + else if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) + { + string sFile = GetFileForClass(nClass); + string sArrayIDX, sArray = "NewSpellbookMem_" + IntToString(nClass); + int nSpellbookID, nSpellLevel, MaxValue; + + for(nLevel = 6; nLevel < 10; nLevel++) + { + sArrayIDX = "SpellbookIDX" + IntToString(nLevel) + "_" + IntToString(nClass); + MaxValue = persistant_array_get_size(oCaster, sArrayIDX); + int j = 0; + while(j < MaxValue) + { + nSpellbookID = persistant_array_get_int(oCaster, sArrayIDX, j); + nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookID)); + if(nSpellLevel > 5) + { + nBurnableSpell = persistant_array_get_int(oCaster, sArray, nSpellbookID); + if(nBurnableSpell > 0)//escape while loop + break; + } + j++; + } + if(nBurnableSpell > 0)//escape for loop + break; + } + + if(nBurnableSpell > 0) + { + SetLocalInt(oCaster, "DomainCast", -1); + SetLocalInt(oCaster, "NSB_Class", nClass); + SetLocalInt(oCaster, "NSB_SpellbookID", nSpellbookID); + ActionCastSpell(SPELL_HEAL, nCasterLvl, 16 + GetAbilityModifier(ABILITY_WISDOM, oCaster), 0, METAMAGIC_NONE, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, FALSE); + return; + } + } + if(((nClass == CLASS_TYPE_BARD || nClass == CLASS_TYPE_SORCERER) && persistant_array_get_size(oCaster, "Spellbook" + IntToString(nClass)) != -1) ||//bard/sorcerer *not* using new spellbooks + nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_DRUID || nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_DEFILER)//other bioware casters with 6+ spell levels + { + nBurnableSpell = bBioCastersLoopDone ? -1: GetSpontaneousHealBurnableSpell(oCaster); + bBioCastersLoopDone = 1; + if(nBurnableSpell != -1) + { + SetLocalInt(oCaster, "DomainCast", -1); + SetLocalInt(oCaster, "Domain_BurnableSpell", nBurnableSpell + 1); + ActionCastSpell(SPELL_HEAL, nCasterLvl, 16 + GetAbilityModifier(ABILITY_WISDOM, oCaster), 0, METAMAGIC_NONE, CLASS_TYPE_INVALID, 0, 0, OBJECT_INVALID, FALSE); + return; + } + } + } + + //if we got here - there's no burnable spells left + FloatingTextStringOnCreature("You have no spells left to trade for a spontaneous heal.", oCaster, FALSE); +} \ No newline at end of file diff --git a/nwnds_scripts/prc_ccc_make_pc.ncs b/nwnds_scripts/prc_ccc_make_pc.ncs new file mode 100644 index 0000000000000000000000000000000000000000..19c876944dd521c2eb89cdba454e5b989e20e1b3 GIT binary patch literal 22369 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 WFC8`@A8jJ!9ZMaddMOVs{{AFAu)}y)$e@& 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 STAGE_LVL0 && nStage <= STAGE_LVL9) + { + // Set the header + SetHeader("Select Spell:"); + int nLevel = nStage - STAGE_LVL0; + SetLocalInt(oPC, "DynConv_Waiting", TRUE); + + PopulateList(oPC, nLevel, 1, 1); + + MarkStageSetUp(nStage, oPC); + } + else if (nStage = STAGE_SLOT) + { + SetHeader("Select QuickSlot:"); + AddChoice("Slot 1", 1, oPC); + AddChoice("Slot 2", 2, oPC); + AddChoice("Slot 3", 3, oPC); + AddChoice("Slot 4", 4, oPC); + MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + + //add more stages for more nodes with Else If clauses + } + + // Do token setup + SetupTokens(); + } + // End of conversation cleanup + else if(nValue == DYNCONV_EXITED) + { + int nChoice = 1; + while(GetLocalInt(oPC, "EF_SPELL_CHOICE_" + IntToString(nChoice))) + { + DeleteLocalInt(oPC, "EF_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalInt(oPC, "EF_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalString(oPC, "EF_CLASS_ARRAY_" + IntToString(nChoice)); + nChoice++; + } + DeleteLocalInt(oPC, "EF_SPELL_ID"); + DeleteLocalInt(oPC, "EF_REAL_SPELL_ID"); + DeleteLocalString(oPC, "EF_CLASS_ARRAY_ID"); + DeleteLocalInt(oPC, "EF_SPELL_LEVEL_CHOICE"); + } + // Abort conversation cleanup. + // NOTE: This section is only run when the conversation is aborted + // while aborting is allowed. When it isn't, the dynconvo infrastructure + // handles restoring the conversation in a transparent manner + else if(nValue == DYNCONV_ABORTED) + { + int nChoice = 1; + while(GetLocalInt(oPC, "EF_SPELL_CHOICE_" + IntToString(nChoice))) + { + DeleteLocalInt(oPC, "EF_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalInt(oPC, "EF_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalString(oPC, "EF_CLASS_ARRAY_" + IntToString(nChoice)); + nChoice++; + } + DeleteLocalInt(oPC, "EF_SPELL_ID"); + DeleteLocalInt(oPC, "EF_REAL_SPELL_ID"); + DeleteLocalString(oPC, "EF_CLASS_ARRAY_ID"); + DeleteLocalInt(oPC, "EF_SPELL_LEVEL_CHOICE"); + } + // Handle PC responses + else + { + // variable named nChoice is the value of the player's choice as stored when building the choice list + // variable named nStage determines the current conversation node + int nChoice = GetChoice(oPC); + if(nStage == STAGE_ENTRY) + { + int nLevel = nChoice; + SetLocalInt(oPC, "EF_SPELL_LEVEL_CHOICE", nLevel); + nStage = STAGE_LVL0 + nChoice; + // Move to another stage based on response, for example + //nStage = STAGE_QUUX; + } + else if (nStage >= STAGE_LVL0 && nStage <= STAGE_LVL9) + { + MarkStageNotSetUp(nStage, oPC); + int nSpell = GetLocalInt(oPC, "EF_SPELL_CHOICE_" + IntToString(nChoice)); + int nRealSpell = GetLocalInt(oPC, "EF_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + string sArray = GetLocalString(oPC, "EF_CLASS_ARRAY_" + IntToString(nChoice)); + + SetLocalInt(oPC, "EF_SPELL_ID", nSpell); + SetLocalInt(oPC, "EF_REAL_SPELL_ID", nRealSpell); + SetLocalString(oPC, "EF_CLASS_ARRAY_ID", sArray); + + nStage = STAGE_SLOT; + } + else if (nStage = STAGE_SLOT) + { + int nSpell = GetLocalInt(oPC, "EF_SPELL_ID"); + int nRealSpell = GetLocalInt(oPC, "EF_REAL_SPELL_ID"); + string sArray = GetLocalString(oPC, "EF_CLASS_ARRAY_ID"); + int nLevel = GetLocalInt(oPC, "EF_SPELL_LEVEL_CHOICE"); + SetLocalInt(oPC, "EF_SPELL_QUICK" + IntToString(nChoice), nSpell); + SetLocalInt(oPC, "EF_REAL_SPELL_QUICK" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "EF_SPELL_QUICK" + IntToString(nChoice), sArray); + SetLocalInt(oPC, "EF_SPELL_QUICK" + IntToString(nChoice) + "LVL", nLevel); + + nStage = STAGE_ENTRY; + } + // Store the stage value. If it has been changed, this clears out the choices + SetStage(nStage, oPC); + } + } + else if (nID == SPELL_EF_SPELL_SELECT_CONVO) + { + DelayCommand(0.5, StartDynamicConversation("prc_ef_spell", oPC, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, FALSE, oPC)); + } + else + { + string sSlotNo; + switch(nID) + { + case SPELL_EF_SPELL_SELECT_QUICK1: sSlotNo = "1"; break; + case SPELL_EF_SPELL_SELECT_QUICK2: sSlotNo = "2"; break; + case SPELL_EF_SPELL_SELECT_QUICK3: sSlotNo = "3"; break; + case SPELL_EF_SPELL_SELECT_QUICK4: sSlotNo = "4"; break; + } + + if(sSlotNo == "") + return; + + int nSpell = GetLocalInt(oPC, "EF_SPELL_QUICK"+sSlotNo); + int nLevel = GetLocalInt(oPC, "EF_SPELL_QUICK"+sSlotNo+"LVL"); + int nRealSpell = GetLocalInt(oPC, "EF_REAL_SPELL_QUICK"+sSlotNo); + if(nRealSpell == -1) nRealSpell = nSpell; + string sArray = GetLocalString(oPC, "EF_SPELL_QUICK"+sSlotNo); + SetLocalInt(oPC, "EF_SPELL_CURRENT", nSpell); + SetLocalInt(oPC, "EF_SPELL_CURRENT_LVL", nLevel); + SetLocalInt(oPC, "EF_REAL_SPELL_CURRENT", nRealSpell); + SetLocalString(oPC, "EF_SPELL_CURRENT", sArray); + int nUses = sArray == "" ? GetHasSpell(nSpell, oPC) : persistant_array_get_int(oPC, sArray, nSpell); + FloatingTextStringOnCreature("*Selected Spell: " + GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))) + "*", oPC, FALSE); + FloatingTextStringOnCreature("*You have " + IntToString(nUses) + " uses left*", oPC, FALSE); + } +} diff --git a/nwnds_scripts/prc_nwnx_funcs.ncs b/nwnds_scripts/prc_nwnx_funcs.ncs new file mode 100644 index 0000000000000000000000000000000000000000..64bb078466cddfb248c8147e1f56213cc6320ff8 GIT binary patch literal 15089 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 GyZ;0Gw4cua literal 0 HcmV?d00001 diff --git a/nwnds_scripts/prc_nwnx_funcs.nss b/nwnds_scripts/prc_nwnx_funcs.nss new file mode 100644 index 000000000..d7a51d2c6 --- /dev/null +++ b/nwnds_scripts/prc_nwnx_funcs.nss @@ -0,0 +1,445 @@ +//:://///////////////////////////////////////////// +//:: Script for nwnx_funcs plugin +//:: prc_nwnx_funcs.nss +//::////////////////////////////////////////////// +//:: This script is executed only if PRC code detects +//:: nwnx_funcs plugin. +//:: +//:: It will apply permanent stat modifications +//:: for PRC classes. +//::////////////////////////////////////////////// +//:: Created By: xwarren +//:: Created On: 12/05/2010 +//::////////////////////////////////////////////// + +#include "prc_inc_template" +#include "inc_nwnx_funcs" + +void main() +{ + object oPC = OBJECT_SELF; + int nBonus, nClassLvl, iTest, nDiff; + + //Warchief + nClassLvl = GetLevelByClass(CLASS_TYPE_WARCHIEF, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_WarchiefCha"); + if(nClassLvl || iTest) + { + if (nClassLvl > 1 && nClassLvl < 6) nBonus = 2; + else if(nClassLvl > 5 && nClassLvl < 10) nBonus = 4; + else if(nClassLvl > 9) nBonus = 6; + + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_WarchiefCha", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + + //Mighty Contender of Kord + nClassLvl = GetLevelByClass(CLASS_TYPE_MIGHTY_CONTENDER_KORD, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_MightyContenderStr"); + if(nClassLvl || iTest) + { + nBonus = 0; + if (nClassLvl >= 9) nBonus = 2; + else if (nClassLvl >= 5) nBonus = 1; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_MightyContenderStr", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_STRENGTH, nDiff); + } + } + + //Heartwarder + nClassLvl = GetLevelByClass(CLASS_TYPE_HEARTWARDER, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_HeartWardCha"); + if(nClassLvl || iTest) + { + nBonus = (nClassLvl + 1) / 2; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_HeartWardCha", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + /*iTest = GetPersistantLocalInt(oPC, "NWNX_HeartWardSkill"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_HEART_PASSION, oPC) ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_HeartWardSkill", nBonus); + PRC_Funcs_ModSkill(oPC, SKILL_ANIMAL_EMPATHY, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_PERFORM, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_PERSUADE, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_TAUNT, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_USE_MAGIC_DEVICE, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_BLUFF, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_INTIMIDATE, nDiff); + } + }*/ + + //Acolyte of the Skin + nClassLvl = GetLevelByClass(CLASS_TYPE_ACOLYTE, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_AcolyteDex"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_WEAR_FIEND, oPC) * 2; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_AcolyteDex", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_DEXTERITY, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_AcolyteInt"); + if(nClassLvl || iTest) + { + nBonus = (GetHasFeat(FEAT_EPIC_INT_1, oPC) + + GetHasFeat(FEAT_EPIC_INT_2, oPC)) * 2; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_AcolyteInt", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_INTELLIGENCE, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_AcolyteCon"); + if(nClassLvl || iTest) + { + nBonus = (GetHasFeat(FEAT_SKIN_ADAPTION, oPC) + + GetHasFeat(FEAT_EPIC_CON_1, oPC) + + GetHasFeat(FEAT_EPIC_CON_2, oPC) + + GetHasFeat(FEAT_EPIC_CON_3, oPC)) * 2; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_AcolyteCon", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, nDiff); + } + } + + //Alienist + nClassLvl = GetLevelByClass(CLASS_TYPE_ALIENIST, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_AlienistWis"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_ALIEN_BLESSING, oPC) ? -2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_AlienistWis", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_WISDOM, nDiff); + } + } + + //Diamond Dragon + nClassLvl = GetLevelByClass(CLASS_TYPE_DIAMOND_DRAGON, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_DiaDragStr"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_DRAGON_AUGMENT_STR_1, oPC) + + GetHasFeat(FEAT_DRAGON_AUGMENT_STR_2, oPC) + + GetHasFeat(FEAT_DRAGON_AUGMENT_STR_3, oPC); + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DiaDragStr", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_STRENGTH, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DiaDragDex"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_DRAGON_AUGMENT_DEX_1, oPC) + + GetHasFeat(FEAT_DRAGON_AUGMENT_DEX_2, oPC) + + GetHasFeat(FEAT_DRAGON_AUGMENT_DEX_3, oPC); + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DiaDragDex", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_DEXTERITY, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DiaDragCon"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_DRAGON_AUGMENT_CON_1, oPC) + + GetHasFeat(FEAT_DRAGON_AUGMENT_CON_2, oPC) + + GetHasFeat(FEAT_DRAGON_AUGMENT_CON_3, oPC); + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DiaDragCon", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, nDiff); + } + } + + //Disciple of Baalzebul + nClassLvl = GetLevelByClass(CLASS_TYPE_DISC_BAALZEBUL, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_KingofLies"); + if(nClassLvl || iTest) + { + nBonus = GetHasFeat(FEAT_KING_LIES, oPC) ? 4 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_KingofLies", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + + //Oozemaster + nClassLvl = GetLevelByClass(CLASS_TYPE_OOZEMASTER, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_OozemasterCha"); + if(nClassLvl || iTest) + { + nBonus = (nClassLvl / 2) * -1; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_OozemasterCha", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + + //Swift Wing + iTest = GetPersistantLocalInt(oPC, "NWNX_DragonicSurgeStr"); + nBonus = GetHasFeat(FEAT_DRACONIC_SURGE_STR, oPC); + if(nBonus || iTest) + { + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DragonicSurgeStr", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_STRENGTH, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DragonicSurgeDex"); + nBonus = GetHasFeat(FEAT_DRACONIC_SURGE_DEX, oPC); + if(nBonus || iTest) + { + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DragonicSurgeDex", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_DEXTERITY, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DragonicSurgeCon"); + nBonus = GetHasFeat(FEAT_DRACONIC_SURGE_CON, oPC); + if(nBonus || iTest) + { + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DragonicSurgeCon", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DragonicSurgeInt"); + nBonus = GetHasFeat(FEAT_DRACONIC_SURGE_INT, oPC); + if(nBonus || iTest) + { + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DragonicSurgeInt", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_INTELLIGENCE, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DragonicSurgeWis"); + nBonus = GetHasFeat(FEAT_DRACONIC_SURGE_WIS, oPC); + if(nBonus || iTest) + { + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DragonicSurgeWis", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_WISDOM, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DragonicSurgeCha"); + nBonus = GetHasFeat(FEAT_DRACONIC_SURGE_CHA, oPC); + if(nBonus || iTest) + { + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DragonicSurgeCha", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + + //Dragon Devotee + nClassLvl = GetLevelByClass(CLASS_TYPE_DRAGON_DEVOTEE, oPC); + int nDragDisc = GetLevelByClass(CLASS_TYPE_DRAGON_DISCIPLE, oPC); + int nHalfDrag = GetHasTemplate(TEMPLATE_HALF_DRAGON); + iTest = GetPersistantLocalInt(oPC, "NWNX_DraDevCha"); + if(nClassLvl || iTest) + { + nBonus = nDragDisc < 10 && !nHalfDrag ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DraDevCha", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DraDevCon"); + if(nClassLvl || iTest) + { + nBonus = nClassLvl > 2 && nDragDisc < 7 && !nHalfDrag ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DraDevCon", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_DraDevStr"); + if(nClassLvl || iTest) + { + nBonus = nClassLvl > 4 && nDragDisc < 2 && !nHalfDrag ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_DraDevStr", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_STRENGTH, nDiff); + } + } + + //Baelnorn + nClassLvl = GetLevelByClass(CLASS_TYPE_BAELNORN, oPC); + iTest = GetPersistantLocalInt(oPC, "NWNX_BaelnornCha"); + if(nClassLvl || iTest) + { + nBonus = nClassLvl >= 4 ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_BaelnornCha", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CHARISMA, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_BaelnornWis"); + if(nClassLvl || iTest) + { + nBonus = nClassLvl >= 3 ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_BaelnornWis", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_WISDOM, nDiff); + } + } + iTest = GetPersistantLocalInt(oPC, "NWNX_BaelnornInt"); + if(nClassLvl || iTest) + { + nBonus = nClassLvl >= 1 ? 2 : 0; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_BaelnornInt", nBonus); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_INTELLIGENCE, nDiff); + } + } + /*iTest = GetPersistantLocalInt(oPC, "NWNX_BaelnornSkill"); + if(nClassLvl || iTest) + { + nBonus = nClassLvl * 2; + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_BaelnornSkill", nBonus); + PRC_Funcs_ModSkill(oPC, SKILL_SPOT, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_HIDE, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_LISTEN, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_MOVE_SILENTLY, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_SEARCH, nDiff); + PRC_Funcs_ModSkill(oPC, SKILL_PERSUADE, nDiff); + } + }*/ + if(GetPersistantLocalInt(oPC, "EpicSpell_TransVital")) + { + if(!GetPersistantLocalInt(oPC, "NWNX_TransVital")) + { + SetPersistantLocalInt(oPC, "NWNX_TransVital", 1); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, 5); + } + } + if(GetAlignmentGoodEvil(oPC) == ALIGNMENT_EVIL) + { + if(GetHasFeat(FEAT_VILE_DEFORM_OBESE, oPC) && !GetHasFeat(FEAT_VILE_DEFORM_GAUNT, oPC)) + { + if(!GetPersistantLocalInt(oPC, "NWNX_DeformObese")) + { + SetPersistantLocalInt(oPC, "NWNX_DeformObese", 1); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, 2); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_DEXTERITY, -2); + } + } + if(GetHasFeat(FEAT_VILE_DEFORM_GAUNT, oPC) && !GetHasFeat(FEAT_VILE_DEFORM_OBESE, oPC)) + { + if(!GetPersistantLocalInt(oPC, "NWNX_DeformGaunt")) + { + SetPersistantLocalInt(oPC, "NWNX_DeformGaunt", 1); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_DEXTERITY, 2); + PRC_Funcs_ModAbilityScore(oPC, ABILITY_CONSTITUTION, -2); + } + } + } + + //Mystics with Sun domain get Turn Undead feat + /*if(GetLevelByClass(CLASS_TYPE_MYSTIC, oPC) && GetHasFeat(FEAT_BONUS_DOMAIN_SUN, oPC)) + { + if(!PRC_Funcs_GetFeatKnown(oPC, FEAT_TURN_UNDEAD)) + PRC_Funcs_AddFeat(oPC, FEAT_TURN_UNDEAD); + }*/ + + //Inherent Bonuses to abilities + if(GetPersistantLocalInt(oPC, "PRC_InherentBonus")) + { + int i; + string sAbi; + for(i = 0; i < 6; i++) + { + sAbi = IntToString(i); + nBonus = GetPersistantLocalInt(oPC, "PRC_InherentBonus_"+sAbi); + iTest = GetPersistantLocalInt(oPC, "NWNX_InherentBonus_"+sAbi); + nDiff = nBonus - iTest; + if(nDiff != 0) + { + SetPersistantLocalInt(oPC, "NWNX_InherentBonus_"+sAbi, nBonus); + PRC_Funcs_ModAbilityScore(oPC, i, nDiff); + } + } + } + + //PRC PnP Spell Schools + if(GetPRCSwitch(PRC_PNP_SPELL_SCHOOLS) + && GetLevelByClass(CLASS_TYPE_WIZARD, oPC) || GetLevelByClass(CLASS_TYPE_DEFILER, oPC)) // NWN Dark Sun class + { + if(GetHasFeat(2274, oPC) + || GetHasFeat(2276, oPC) + || GetHasFeat(2277, oPC) + || GetHasFeat(2278, oPC) + || GetHasFeat(2279, oPC) + || GetHasFeat(2280, oPC) + || GetHasFeat(2281, oPC)) + { + //set school to PnP school + PRC_Funcs_SetWizardSpecialization(oPC, 9); + } + else if(GetHasFeat(2273, oPC)) + { + //set school to generalist + PRC_Funcs_SetWizardSpecialization(oPC, 0); + } + } +} \ No newline at end of file diff --git a/nwnds_scripts/prc_onaquire.ncs b/nwnds_scripts/prc_onaquire.ncs new file mode 100644 index 0000000000000000000000000000000000000000..eac5f7a6625e5ec82647ffd057a4201a93aa5658 GIT binary patch literal 41375 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 Iwo~5!0Yjl2r~m)} literal 0 HcmV?d00001 diff --git a/nwnds_scripts/prc_onaquire.nss b/nwnds_scripts/prc_onaquire.nss new file mode 100644 index 000000000..05384c0b1 --- /dev/null +++ b/nwnds_scripts/prc_onaquire.nss @@ -0,0 +1,342 @@ +//:://///////////////////////////////////////////// +//:: OnAcquireItem eventscript +//:: prc_onaquire +//::////////////////////////////////////////////// +#include "prc_alterations" +#include "prc_craft_inc" +//#include "psi_inc_manifest" + +void AntiMagicFieldCheck(object oItem, object oCreature) +{ + int nIP = array_get_size(oItem, "PRC_NPF_ItemList"); + if(GetHasSpellEffect(SPELL_ANTIMAGIC_FIELD, oCreature) + || GetHasSpellEffect(POWER_NULL_PSIONICS_FIELD, oCreature)) + { + if(nIP) + // itemproperty list already exists - do nothing + return; + + //remove ips + string sIP; + int nIpCount; + persistant_array_create(oCreature, "PRC_NPF_ItemList"); //stores object strings + itemproperty ip = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ip)) + { + if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT) + { //only store the permanent ones as underscore delimited strings + sIP = IntToString(GetItemPropertyType(ip)) + "_" + + IntToString(GetItemPropertySubType(ip)) + "_" + + IntToString(GetItemPropertyCostTableValue(ip)) + "_" + + IntToString(GetItemPropertyParam1Value(ip)); + if(DEBUG) DoDebug("StoreItemprops: " + GetName(oCreature) + ", " + ObjectToString(oItem) + ", " + sIP); + array_set_string(oCreature, "PRC_NPF_ItemList", nIpCount++, sIP); + } + RemoveItemProperty(oItem, ip); + ip = GetNextItemProperty(oItem); + } + } + else + { + if(!nIP) + // itemproperty list not found! + return; + + //restore ips + struct ipstruct iptemp; + itemproperty ip; + string sIP; + int i; + + for(i = 0; i < nIP; i++) + { + sIP = array_get_string(oItem, "PRC_NPF_ItemList", i); + iptemp = GetIpStructFromString(sIP); + ip = ConstructIP(iptemp.type, iptemp.subtype, iptemp.costtablevalue, iptemp.param1value); + IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); + if(DEBUG) DoDebug("RetoreItemprops: " + GetName(GetItemPossessor(oItem)) + ", " + ObjectToString(oItem) + ", " + sIP); + } + array_delete(oItem, "PRC_NPF_ItemList"); + } +} + +void UpdateIPs(object oItem) +{ + // Has lookup finished yet? + if(GetXP(GetObjectByTag("Bioware2DACache")) & 0x01) + { + int bAddRestrictions = FALSE; + int nSpellID; + + //Set the AMS version of last update + SetLocalString(oItem, "sb_ver", AMS_VERSION); + + //remove all class restrictions and mark the spell + itemproperty ipTest = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipTest)) + { + if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_USE_LIMITATION_CLASS) + { + //the scroll/wand had a use limitation + RemoveItemProperty(oItem, ipTest); + bAddRestrictions = TRUE; + } + else if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_CAST_SPELL) + { + nSpellID = StringToInt(Get2DACache("iprp_spells", "SpellIndex", GetItemPropertySubType(ipTest))); + } + ipTest = GetNextItemProperty(oItem); + } + if(bAddRestrictions) + { + int i, nClass, bAdd; + for(i = 0; i < 36; i++) + { + bAdd = FALSE; + switch(i) + { + case 0: nClass = CLASS_TYPE_BARD; break; + case 1: nClass = CLASS_TYPE_CLERIC; break; + case 2: nClass = CLASS_TYPE_DRUID; break; + case 3: nClass = CLASS_TYPE_PALADIN; break; + case 4: nClass = CLASS_TYPE_RANGER; break; + case 5: nClass = CLASS_TYPE_SORCERER; break; + case 6: nClass = CLASS_TYPE_WIZARD; break; + case 7: nClass = CLASS_TYPE_HARPER; break; + case 8: nClass = CLASS_TYPE_ASSASSIN; break; + case 9: nClass = CLASS_TYPE_BLACKGUARD; break; + case 10: nClass = CLASS_TYPE_OCULAR; break; + case 11: nClass = CLASS_TYPE_HEXBLADE; break; + case 12: nClass = CLASS_TYPE_DUSKBLADE; break; + case 13: nClass = CLASS_TYPE_HEALER; break; + case 14: nClass = CLASS_TYPE_BEGUILER; break; + case 15: nClass = CLASS_TYPE_KNIGHT_CHALICE; break; + case 16: nClass = CLASS_TYPE_VIGILANT; break; + case 17: nClass = CLASS_TYPE_VASSAL; break; + case 18: nClass = CLASS_TYPE_SUBLIME_CHORD; break; + case 19: nClass = CLASS_TYPE_ANTI_PALADIN; break; + case 20: nClass = CLASS_TYPE_SOLDIER_OF_LIGHT; break; + case 21: nClass = CLASS_TYPE_SHADOWLORD; break; + case 22: nClass = CLASS_TYPE_JUSTICEWW; break; + case 23: nClass = CLASS_TYPE_KNIGHT_MIDDLECIRCLE; break; + case 24: nClass = CLASS_TYPE_DREAD_NECROMANCER; break; + case 25: nClass = CLASS_TYPE_MYSTIC; break; + case 26: nClass = CLASS_TYPE_ARCHIVIST; break; + case 27: nClass = CLASS_TYPE_WITCH; break; + case 28: nClass = CLASS_TYPE_SHAMAN; break; + case 29: nClass = CLASS_TYPE_SLAYER_OF_DOMIEL; break; + case 30: nClass = CLASS_TYPE_SUEL_ARCHANAMACH; break; + case 31: nClass = CLASS_TYPE_FAVOURED_SOUL; break; + case 32: nClass = CLASS_TYPE_SHUGENJA; break; + case 33: nClass = CLASS_TYPE_SOHEI; break; + case 34: nClass = CLASS_TYPE_WARMAGE; break; + case 35: nClass = CLASS_TYPE_TEMPLAR; break; + case 36: nClass = CLASS_TYPE_DEFILER; break; + } + + if(nClass == CLASS_TYPE_DRUID) + bAdd = Get2DACache("Spells", "Druid", nSpellID) == "" ? FALSE : TRUE; + else if(nClass == CLASS_TYPE_PALADIN) + bAdd = Get2DACache("Spells", "Paladin", nSpellID) == "" ? FALSE : TRUE; + else if(nClass == CLASS_TYPE_RANGER) + bAdd = Get2DACache("Spells", "Ranger", nSpellID) == "" ? FALSE : TRUE; + else if(nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_DEFILER) + bAdd = RealSpellToSpellbookID(CLASS_TYPE_SORCERER, nSpellID) == -1 ? FALSE : TRUE; + else if(nClass == CLASS_TYPE_CLERIC) + bAdd = RealSpellToSpellbookID(CLASS_TYPE_MYSTIC, nSpellID) == -1 ? FALSE : TRUE; + else + bAdd = RealSpellToSpellbookID(nClass, nSpellID) == -1 ? FALSE : TRUE; + + if(bAdd) + AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByClass(nClass), oItem); + } + } + } + else // Nope, try again later + { + DelayCommand(0.2f, UpdateIPs(oItem)); + } +} + +void main() +{ + // Find out the relevant objects + object oCreature = GetModuleItemAcquiredBy(); + object oItem = GetModuleItemAcquired(); + string sTag = GetTag(oItem); + + // Do not run for some of the PRC special items + if(sTag == "PRC_MANIFTOKEN" + || sTag == "HideToken" + || GetResRef(oItem) == "base_prc_skin") + return; + + //if(DEBUG) DoDebug("Running OnAcquireItem, creature = '" + GetName(oCreature) + "' is PC: " + DebugBool2String(GetIsPC(oCreature)) + "; Item = '" + GetName(oItem) + "' - '" + GetTag(oItem) + "'"); + + AntiMagicFieldCheck(oItem, oCreature); + + int nItemType = GetBaseItemType(oItem); + + //fix for all-beige 1.67 -> 1.68 cloaks + //gives them a random color + if(nItemType == BASE_ITEM_CLOAK) + { + if(!GetPRCSwitch(PRC_DYNAMIC_CLOAK_AUTOCOLOUR_DISABLE) && !GetLocalInt(oItem, "CloakDone")) + { + //&& GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0) == 1 + if(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH1) == 0 + && GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH2) == 0 + && GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1) == 0 + && GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER2) == 0 + && GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1) == 0 + && GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL2) == 0) + { + //pre-1.68 boring bland cloak, colorise it :) + //move it to temporary storage first + object oChest = GetObjectByTag("HEARTOFCHAOS"); + DestroyObject(oItem); + oItem = CopyItem(oItem, oChest, TRUE); + //set appearance + //doesnt work yet should do for 1.69 + //DestroyObject(oItem); + //oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, Random(14)+1, TRUE); + //set colors + DestroyObject(oItem); + oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH1, Random(176), TRUE); + DestroyObject(oItem); + oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH2, Random(176), TRUE); + DestroyObject(oItem); + oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1, Random(176), TRUE); + DestroyObject(oItem); + oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER2, Random(176), TRUE); + DestroyObject(oItem); + oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1, Random(176), TRUE); + DestroyObject(oItem); + oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL2, Random(176), TRUE); + //move it back + DestroyObject(oItem); + oItem = CopyItem(oItem, oCreature, TRUE); + //mark it as set just to be sure + SetLocalInt(oItem, "CloakDone", TRUE); + } + } + } + + // This is a resource hog. To work around, we assume that it's not going to cause noticeable issues if + // racial restrictions are only ever expanded when a PC is involved + if(GetIsPC(oCreature) || GetIsPC(GetMaster(oCreature)) || GetPRCSwitch(PRC_NPC_FORCE_RACE_ACQUIRE)) + ExecuteScript("race_ev_aquire", OBJECT_SELF); + + // Creatures not related to PCs skip this block, contents are irrelevant for them + if(GetIsPC(oCreature) || GetIsPC(GetMaster(oCreature))) + { + if(GetPRCSwitch(PRC_AUTO_IDENTIFY_ON_ACQUIRE)) + { + if(!GetIdentified(oItem)) + { + int nLore = GetSkillRank(SKILL_LORE, oCreature); + int nMax = StringToInt(Get2DACache("SkillVsItemCost", "DeviceCostMax", nLore)); + if(nMax == 0) + nMax = 120000000; + // Check for the value of the item first. + SetIdentified(oItem, TRUE); + int nGP = GetGoldPieceValue(oItem); + // If oPC has enough Lore skill to ID the item, then do so. + if(nMax >= nGP) + { + string sName = GetName(oItem); + if(sName != "") + SendMessageToPC(oCreature, GetStringByStrRef(16826224) + " " + sName + " " + GetStringByStrRef(16826225)); + } + else + SetIdentified(oItem, FALSE); + } + } + + if(nItemType == BASE_ITEM_MAGICWAND + || nItemType == BASE_ITEM_ENCHANTED_WAND + || nItemType == BASE_ITEM_SCROLL + || nItemType == BASE_ITEM_SPELLSCROLL + || nItemType == BASE_ITEM_ENCHANTED_SCROLL) + { + if(!GetPRCSwitch(PRC_SCROLL_AUTOUPDATE_RESTR_DISABLE) + && GetLocalString(oItem, "sb_ver") != AMS_VERSION //different Alternate Magic System versions - update IPs + && !GetLocalInt(oItem, "ip_lock")) //IPs of wand/scroll were locked in toolset or by script + { + DelayCommand(1.0f, UpdateIPs(oItem));//delayed to reduce lag and prevent TMIs + } + } + + //rest kits + if(GetPRCSwitch(PRC_SUPPLY_BASED_REST)) + ExecuteScript("sbr_onaquire", OBJECT_SELF); + + //PRC Companion + //DOA visible dyepot items + /*if(GetPRCSwitch(MARKER_PRC_COMPANION)) + { + if(GetBaseItemType(oItem) == BASE_ITEM_MISCSMALL) + { + //x2_it_dyec23 + string sTag = GetTag(oItem); + if(GetStringLeft(sTag, 9) == "x2_it_dye") + { + //get the color + //taken from x2_s3_dyearmour + // GZ@2006/03/26: Added new color palette support. Note: Will only work + // if craig updates the in engine functions as well. + int nColor = 0; + // See if we find a valid int between 0 and 127 in the last three letters + // of the tag, use it as color + int nTest = StringToInt(GetStringRight(sTag,3)); + if (nTest > 0 && + nTest < 175 )//magic number, bad! + nColor = nTest; + else //otherwise, use last two letters, as per legacy HotU + nColor = StringToInt(GetStringRight(sTag,2)); + + //use limbo for crafting in + object oLimbo = GetObjectByTag("HEARTOFCHAOS"); + //create the new one with the same tag as the old + object oDye = CreateItemOnObject("prccompdye", oLimbo, 1, sTag); + //ensure old one is cleaned up + DestroyObject(oItem); + //if its a metalic dye, modify it to use model 2 + if(GetStringRight(GetStringLeft(sTag, 10), 1) == "m") + { + DestroyObject(oDye); + oDye = CopyItemAndModify(oDye, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, 2); + //metal dye color + DestroyObject(oDye); + oDye = CopyItemAndModify(oDye, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1, nColor); + } + else + { + //standard dye + DestroyObject(oDye); + //cloth and leather use same palettee + oDye = CopyItemAndModify(oDye, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1, nColor); + } + //copy the itemprops to cast the dye "spell" + itemproperty ipTest = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipTest)) + { + AddItemProperty(DURATION_TYPE_PERMANENT, ipTest, oDye); + ipTest = GetNextItemProperty(oItem); + } + //move it back to the player + CopyItem(oDye, oCreature); + DestroyObject(oDye); + } + } + }*/ + }// end if - PC or associate of PC + + // Execute scripts hooked to this event for the creature and item triggering it + ExecuteAllScriptsHookedToEvent(oCreature, EVENT_ONACQUIREITEM); + ExecuteAllScriptsHookedToEvent(oItem, EVENT_ITEM_ONACQUIREITEM); + + // Tag-based scripting hook for PRC items + SetUserDefinedItemEventNumber(X2_ITEM_EVENT_ACQUIRE); + ExecuteScript("is_"+sTag, OBJECT_SELF); +} \ No newline at end of file diff --git a/nwnds_scripts/prc_prereq.ncs b/nwnds_scripts/prc_prereq.ncs new file mode 100644 index 0000000000000000000000000000000000000000..dbf241aead1b79345889f95f57be8c7c0a440403 GIT binary patch literal 99941 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 literal 0 HcmV?d00001 diff --git a/nwnds_scripts/prc_prereq.nss b/nwnds_scripts/prc_prereq.nss new file mode 100644 index 000000000..33941485b --- /dev/null +++ b/nwnds_scripts/prc_prereq.nss @@ -0,0 +1,1426 @@ +//:://///////////////////////////////////////////// +//:: PRC Prerequisites +//:: prc_prereq.nss +//::////////////////////////////////////////////// +//:: Check to see what classes a PC is capable of taking. +//::////////////////////////////////////////////// +//:: Created By: Stratovarius. +//:: Created On: July 3rd, 2004 +//::////////////////////////////////////////////// + +#include "inc_epicspells" +#include "prc_inc_sneak" +#include "psi_inc_psifunc" +#include "tob_inc_tobfunc" +#include "shd_inc_shdfunc" +#include "inc_newspellbook" +#include "prc_allow_const" +#include "inv_inc_invfunc" +#include "prc_inc_template" +#include "moi_inc_moifunc" +#include "bnd_inc_bndfunc" + +/* +AlignRestrict flags in classes.2da: +0x01 - no neutral +0x02 - no lawful +0x04 - no chaotic +0x08 - no good +0x10 - no evil + +AlignRstrctType: +0x01 - law/chaos +0x02 - good/evil +*/ +// Some alignment restrictions can't be setup properly in classes.2da +// ie. for Soldier of Light the closest thing to NG requirement is 0x16 0x3 +// which will allow only NG and TN alignments. +// To disable True Neutral Soldiers of Light a Script Var 'PRC_ExAlignTN' +// was added to cls_pres_sol.2da. +void reqAlignment(object oPC) +{ + string sAling = "PRC_ExAlign"; + DeleteLocalInt(oPC, sAling+"LG"); + DeleteLocalInt(oPC, sAling+"LN"); + DeleteLocalInt(oPC, sAling+"LE"); + DeleteLocalInt(oPC, sAling+"NG"); + DeleteLocalInt(oPC, sAling+"TN"); + DeleteLocalInt(oPC, sAling+"NE"); + DeleteLocalInt(oPC, sAling+"CG"); + DeleteLocalInt(oPC, sAling+"CN"); + DeleteLocalInt(oPC, sAling+"CE"); + + int nGoodEvil = GetAlignmentGoodEvil(oPC); + int nLawChaos = GetAlignmentLawChaos(oPC); + + if(nGoodEvil == ALIGNMENT_GOOD) + { + if(nLawChaos == ALIGNMENT_LAWFUL) + SetLocalInt(oPC, sAling+"LG", 1); + else if(nLawChaos == ALIGNMENT_NEUTRAL) + SetLocalInt(oPC, sAling+"NG", 1); + else// if(nLawChaos == ALIGNMENT_CHAOTIC) + SetLocalInt(oPC, sAling+"CG", 1); + } + else if(nGoodEvil == ALIGNMENT_NEUTRAL) + { + if(nLawChaos == ALIGNMENT_LAWFUL) + SetLocalInt(oPC, sAling+"LN", 1); + else if(nLawChaos == ALIGNMENT_NEUTRAL) + SetLocalInt(oPC, sAling+"TN", 1); + else// if(nLawChaos == ALIGNMENT_CHAOTIC) + SetLocalInt(oPC, sAling+"CN", 1); + } + else// if(nGoodEvil == ALIGNMENT_EVIL) + { + if(nLawChaos == ALIGNMENT_LAWFUL) + SetLocalInt(oPC, sAling+"LE", 1); + else if(nLawChaos == ALIGNMENT_NEUTRAL) + SetLocalInt(oPC, sAling+"NE", 1); + else// if(nLawChaos == ALIGNMENT_CHAOTIC) + SetLocalInt(oPC, sAling+"CE", 1); + } +} + +//for requirements that Skirmish or Sneak Attack apply to +void reqSpecialAttack(object oPC) +{ + int iSneak = GetTotalSneakAttackDice(oPC); + int nLevel = GetLevelByClass(CLASS_TYPE_SCOUT, oPC); + int iCount; + string sVariable1, sVariable2; + + //Skirmish + int nDice = (nLevel + 3) / 4; + for (iCount = 1; iCount <= 30; iCount++) + { + sVariable1 = "PRC_SkirmishLevel" + IntToString(iCount); + sVariable2 = "PRC_SplAtkLevel" + IntToString(iCount); + if (nDice >= iCount) + { + SetLocalInt(oPC, sVariable1, 0); + SetLocalInt(oPC, sVariable2, 0); + } + } + //Sneak Attack + for (iCount = 1; iCount <= 30; iCount++) + { + sVariable1 = "PRC_SneakLevel" + IntToString(iCount); + sVariable2 = "PRC_SplAtkLevel" + IntToString(iCount); + if (iSneak >= iCount) + { + SetLocalInt(oPC, sVariable1, 0); + SetLocalInt(oPC, sVariable2, 0); + } + } +} + +void reqGender() +{ + int nGender = GetGender(OBJECT_SELF); + + SetLocalInt(OBJECT_SELF, "PRC_Female", 1); + SetLocalInt(OBJECT_SELF, "PRC_Male", 1); + + if (nGender == GENDER_FEMALE) + DeleteLocalInt(OBJECT_SELF, "PRC_Female"); + else if (nGender == GENDER_MALE) + DeleteLocalInt(OBJECT_SELF, "PRC_Male"); +} + +void Kord(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqKord", 1); + + if (GetFortitudeSavingThrow(oPC) >= 6) + { + SetLocalInt(oPC, "PRC_PrereqKord", 0); + } +} + +void Purifier(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqPurifier", 1); + + if (GetWillSavingThrow(oPC) >= 5) + { + SetLocalInt(oPC, "PRC_PrereqPurifier", 0); + } +} + +void Dragonheart(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqDragonheart", 1); + + int nClassSlot = 1; + while(nClassSlot <= 3) + { + int nClass = GetClassByPosition(nClassSlot, oPC); + nClassSlot += 1; + if(GetIsArcaneClass(nClass) && GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS) + SetLocalInt(oPC, "PRC_PrereqDragonheart", 0); + } +} + +void Cultist(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqCultist", 1); + + // Can't be arcane + if(!GetIsArcaneClass(GetClassByPosition(1, oPC)) && (!GetIsArcaneClass(GetClassByPosition(2, oPC)) || GetClassByPosition(2, oPC) == CLASS_TYPE_CULTIST_SHATTERED_PEAK)) + SetLocalInt(oPC, "PRC_PrereqCultist", 0); +} + +void Shifter(object oPC, int iArcSpell, int iDivSpell) +{ + //This function checks if the Pnp Shifter requirement "You must be able to assume an alternate form" is met. + + SetLocalInt(oPC, "PRC_PrereqShift", 1); + + //This used to check for Cleric class, animal domain, and divine spell level 5. + //I've eliminated the Cleric class check--any class with the animal domain should qualify-- + //and changed it to check for divine spell level 9 instead of 5, since it isn't until level 9 + //that the PRC Animal domain gains the Shapechange spell, which is what qualifies it for PnP Shifter. + //(The Bioware implementation of the Animal domain gives Polymorph Self at spell level 5). + if (GetHasFeat(FEAT_ANIMAL_DOMAIN_POWER) && iDivSpell >= 9) + { + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + + //Sorcerer (if it uses the old spellbook) and Wizard (which always does) need special checks + if ((GetLevelByClass(CLASS_TYPE_SORCERER) && !UseNewSpellBook(oPC)) || GetLevelByClass(CLASS_TYPE_WIZARD) || GetLevelByClass(CLASS_TYPE_DEFILER)) + { + if(GetHasSpell(SPELL_POLYMORPH_SELF, oPC)) + { + // done this way as it's the only way to see if a bioware spellcaster knows the spell + // actually checks if they have at least one use left + SetLocalInt(oPC, "PRC_PrereqShift", 0); + return; + } + } + + //Ranger also needs special check since it also uses the old spellbook. It gains Polymorph Self at spell level 4. + if (GetLevelByClass(CLASS_TYPE_RANGER) && iDivSpell >= 4) + { + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + + //Any class that has Polymorph Self spell qualifies + if (PRCGetIsRealSpellKnown(SPELL_POLYMORPH_SELF, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + + //Warlock doesn't normally qualify for PnP Shifter since it doesn't cast spells, + //but these invocations from Warlock meets the alternate form qualification + //if another class provides the level 3 spells + if(GetHasInvocation(INVOKE_MASK_OF_FLESH, oPC) + || GetHasInvocation(INVOKE_HUMANOID_SHAPE, oPC) + || GetHasInvocation(INVOKE_SPIDER_SHAPE, oPC) + || GetHasInvocation(INVOKE_HELLSPAWNED_GRACE, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + + //These classes have appropriate alternate forms + if (GetLevelByClass(CLASS_TYPE_DRUID) >= 5) + { + //Wild Shape qualifies + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + if (GetLevelByClass(CLASS_TYPE_INITIATE_DRACONIC) >= 10) + { + //Dragon Shape qualifies + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + if (GetLevelByClass(CLASS_TYPE_NINJA_SPY) >= 7) + { + //Thousand Faces qualifies + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + if (GetLevelByClass(CLASS_TYPE_WEREWOLF) >= 1) + { + //Alternate Form, Wolf qualifies + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + if (GetLevelByClass(CLASS_TYPE_BONDED_SUMMONNER) >= 10) + { + //Elemental Form qualifies + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + //This is not strictly necessary because Witch gains Polymorph Self + //at an earlier level, but add it here anyway for completeness: + if (GetLevelByClass(CLASS_TYPE_WITCH) >= 13) + { + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } + + int nRace = GetRacialType(oPC); + //These races have appropriate alternate forms + if(nRace == RACIAL_TYPE_PURE_YUAN + || nRace == RACIAL_TYPE_ABOM_YUAN + || nRace == RACIAL_TYPE_PIXIE + || nRace == RACIAL_TYPE_RAKSHASA + || nRace == RACIAL_TYPE_FEYRI + || nRace == RACIAL_TYPE_HOUND_ARCHON + || nRace == RACIAL_TYPE_IRDA + || nRace == RACIAL_TYPE_ZAKYA_RAKSHASA + || nRace == RACIAL_TYPE_CHANGELING + || nRace == RACIAL_TYPE_SHIFTER + // not counted since it is just "disguise self" and not alter self or shape change + //||nRace == RACIAL_TYPE_DEEP_GNOME + || nRace == RACIAL_TYPE_NAZTHARUNE_RAKSHASA) + { + SetLocalInt(oPC, "PRC_PrereqShift", 0); + } +} + +void Tempest() +{ + SetLocalInt(OBJECT_SELF, "PRC_PrereqTemp", 1); + + if(((GetHasFeat(FEAT_AMBIDEXTERITY) || GetPRCSwitch(PRC_35_TWO_WEAPON_FIGHTING)) && GetHasFeat(FEAT_TWO_WEAPON_FIGHTING)) + || GetHasFeat(FEAT_RANGER_DUAL)) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqTemp"); +} + +void KOTC(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqKOTC", 1); + + // to check if PC can cast protection from evil + if(GetLevelByClass(CLASS_TYPE_CLERIC)) + DeleteLocalInt(oPC, "PRC_PrereqKOTC"); + + if(GetLevelByClass(CLASS_TYPE_PALADIN) > 3) + { + if(GetAbilityScore(oPC, ABILITY_WISDOM) > 11 + || GetLevelByClass(CLASS_TYPE_PALADIN) > 5) + { + DeleteLocalInt(oPC, "PRC_PrereqKOTC"); + return; + } + } + if(PRCGetIsRealSpellKnown(SPELL_PROTECTION_FROM_EVIL, oPC)) + { + DeleteLocalInt(oPC, "PRC_PrereqKOTC"); + } +} + +void Shadowlord(object oPC, int iArcSpell) +{ + SetLocalInt(oPC, "PRC_PrereqTelflam", 1); + + if(iArcSpell > 3 //ability to cast Level 4 Arcane Spells + || GetLevelByClass(CLASS_TYPE_SHADOWDANCER, oPC) //at least 1 lvl of shadowdancer + || GetPersistantLocalInt(oPC, "shadowwalkerstok")) //a token proving a donation of 10,000 gold to the Telflamm Guild + //|| GetHasItem(oPC, "shadowwalkerstok")) + { + SetLocalInt(oPC, "PRC_PrereqTelflam", 0); + } +} + +//taken out of master at arms because i wanted to use the code in Eternal Blade prereq too +int WeaponFocusCount(object oPC) +{ + int iWF; + + // Calculate the total number of Weapon Focus feats the character has + iWF = GetHasFeat(FEAT_WEAPON_FOCUS_BASTARD_SWORD,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_BATTLE_AXE,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_CLUB,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_DART,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_DIRE_MACE,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_DOUBLE_AXE,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_DWAXE,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_AXE,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_SWORD,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_HALBERD,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_FLAIL,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_KAMA,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD,oPC)+GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_KATANA,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_KUKRI,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_FLAIL,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_HAMMER,oPC)+GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR,oPC)+GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_SCYTHE,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_SHURIKEN,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_SLING,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_STAFF,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_THROWING_AXE,oPC)+ + GetHasFeat(FEAT_WEAPON_FOCUS_WAR_HAMMER,oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_MINDBLADE, oPC) +GetHasFeat(FEAT_WEAPON_FOCUS_WHIP,oPC); //why was whip commented out? + + // If they are a soulknife, their WF Mindblade might be counting twice due to how it is implemented, so account for it if necessary + if(GetStringLeft(GetTag(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)), 14) == "prc_sk_mblade_" || + GetStringLeft(GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC)), 14) == "prc_sk_mblade_") + iWF--; + + return iWF; +} + +void DemiLich(object oPC) +{ + DeleteLocalInt(oPC, "PRC_DemiLich"); + + if (!GetIsEpicSpellcaster(oPC) && GetLevelByClass(CLASS_TYPE_LICH) > 3) + SetLocalInt(oPC, "PRC_DemiLich", 1); // Need to be an epic caster to take demilich + + if(GetPRCSwitch(PRC_DISABLE_DEMILICH) && GetLevelByClass(CLASS_TYPE_LICH) > 3) + { + SetLocalInt(oPC, "PRC_DemiLich", 1); // This is here because it'll always turn things off + } +} + +void reqDomains() +{ + //Black Flame Zealot + SetLocalInt(OBJECT_SELF, "PRC_PrereqBFZ", 1); + if(GetHasFeat(FEAT_FIRE_DOMAIN_POWER) + + GetHasFeat(FEAT_DESTRUCTION_DOMAIN_POWER) + + GetHasFeat(FEAT_DOMAIN_POWER_RENEWAL) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqBFZ"); + + //Brimstone Speaker + SetLocalInt(OBJECT_SELF, "PRC_PrereqBrimstone", 1); + if(GetHasFeat(FEAT_FIRE_DOMAIN_POWER) + || GetHasFeat(FEAT_GOOD_DOMAIN_POWER)) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqBrimstone"); + + //Shining Blade of Heironeous + SetLocalInt(OBJECT_SELF, "PRC_PrereqSBHeir", 1); + if (GetHasFeat(FEAT_WAR_DOMAIN_POWER) + && GetHasFeat(FEAT_GOOD_DOMAIN_POWER)) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqSBHeir"); + + //Eye of Gruumsh + SetLocalInt(OBJECT_SELF, "PRC_PrereqEOG", 1); + if(GetHasFeat(FEAT_WAR_DOMAIN_POWER) + + GetHasFeat(FEAT_STRENGTH_DOMAIN_POWER) + + GetHasFeat(FEAT_EVIL_DOMAIN_POWER) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqEOG"); + + //Stormlord + SetLocalInt(OBJECT_SELF, "PRC_PrereqStormL", 1); + if(GetHasFeat(FEAT_FIRE_DOMAIN_POWER) + + GetHasFeat(FEAT_DESTRUCTION_DOMAIN_POWER) + + GetHasFeat(FEAT_EVIL_DOMAIN_POWER) + + GetHasFeat(FEAT_DOMAIN_POWER_STORM) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqStormL"); + + //Battleguard of Tempus + SetLocalInt(OBJECT_SELF, "PRC_PrereqTempus", 1); + if(GetHasFeat(FEAT_PROTECTION_DOMAIN_POWER) + + GetHasFeat(FEAT_STRENGTH_DOMAIN_POWER) >= 1 + && GetHasFeat(FEAT_WAR_DOMAIN_POWER)) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqTempus"); + + //Heartwarder + SetLocalInt(OBJECT_SELF, "PRC_PrereqHeartW", 1); + if(GetHasFeat(FEAT_GOOD_DOMAIN_POWER) + + GetHasFeat(FEAT_PROTECTION_DOMAIN_POWER) + + GetHasFeat(FEAT_DOMAIN_POWER_CHARM) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqHeartW"); + + //Talontar Blightlord + SetLocalInt(OBJECT_SELF, "PRC_PrereqBlightL", 1); + if(GetHasFeat(FEAT_DESTRUCTION_DOMAIN_POWER) + && GetHasFeat(FEAT_EVIL_DOMAIN_POWER)) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqBlightL"); + + //Shadow Adept + SetLocalInt(OBJECT_SELF, "PRC_PrereqShadAd", 1); + if(GetHasFeat(FEAT_EVIL_DOMAIN_POWER) + + GetHasFeat(FEAT_KNOWLEDGE_DOMAIN_POWER) + + GetHasFeat(FEAT_DARKNESS_DOMAIN) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqShadAd"); + + //Thrall of Graz'zt + SetLocalInt(OBJECT_SELF, "PRC_PrereqTOG", 1); + if(GetHasFeat(FEAT_EVIL_DOMAIN_POWER) + && GetHasFeat(FEAT_DARKNESS_DOMAIN)) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqTOG"); + + //Champion of Corellon + SetLocalInt(OBJECT_SELF, "PRC_PrereqCoC", 1); + if(GetHasFeat(FEAT_DOMAIN_POWER_ELF) + //+ GetHasFeat(FEAT_DOMAIN_POWER_CHAOS) //chaos domain not yet implemented + + GetHasFeat(FEAT_GOOD_DOMAIN_POWER) + + GetHasFeat(FEAT_MAGIC_DOMAIN_POWER) + + GetHasFeat(FEAT_PROTECTION_DOMAIN_POWER) + + GetHasFeat(FEAT_WAR_DOMAIN_POWER) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqCoC"); + + //Morninglord of Lathander + SetLocalInt(OBJECT_SELF, "PRC_PrereqMornLord", 1); + if(GetHasFeat(FEAT_GOOD_DOMAIN_POWER) + + GetHasFeat(FEAT_PROTECTION_DOMAIN_POWER) + + GetHasFeat(FEAT_STRENGTH_DOMAIN_POWER) + + GetHasFeat(FEAT_SUN_DOMAIN_POWER) + + GetHasFeat(FEAT_DOMAIN_POWER_NOBILITY) + + GetHasFeat(FEAT_DOMAIN_POWER_RENEWAL) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqMornLord"); + + //Favored of Milil + SetLocalInt(OBJECT_SELF, "PRC_PrereqFoM", 1); + if(GetHasFeat(FEAT_GOOD_DOMAIN_POWER) + + GetHasFeat(FEAT_DOMAIN_POWER_NOBILITY) + + GetHasFeat(FEAT_DOMAIN_POWER_CHARM) + + GetHasFeat(FEAT_KNOWLEDGE_DOMAIN_POWER) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqFoM"); + + //Soldier of Light + SetLocalInt(OBJECT_SELF, "PRC_PrereqSOL", 1); + if(GetHasFeat(FEAT_GOOD_DOMAIN_POWER) + + GetHasFeat(FEAT_HEALING_DOMAIN_POWER) + + GetHasFeat(FEAT_LUCK_DOMAIN_POWER) + + GetHasFeat(FEAT_PROTECTION_DOMAIN_POWER) + + GetHasFeat(FEAT_SUN_DOMAIN_POWER) + + GetHasFeat(FEAT_KNOWLEDGE_DOMAIN_POWER) >= 2) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqSOL"); +} + + +void WWolf(object oPC) +{ + //If not a natural lycanthrope or not already leveled in werewolf, prevent the player from taking the werewolf class + if (!GetHasFeat(FEAT_TRUE_LYCANTHROPE, oPC) || GetLevelByClass(CLASS_TYPE_WEREWOLF, oPC) < 1) + { + SetLocalInt(oPC, "PRC_PrereqWWolf", 1); + } + + if (GetHasFeat(FEAT_TRUE_LYCANTHROPE, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqWWolf", 0); + } +} + +void Maester(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqMaester", 1); + + // Base Ranks Only + if(GetSkillRank(SKILL_CRAFT_ARMOR, oPC, TRUE) > 7 + || GetSkillRank(SKILL_CRAFT_TRAP, oPC, TRUE) > 7 + || GetSkillRank(SKILL_CRAFT_WEAPON, oPC, TRUE) > 7) + { + // At least two crafting feats + if(GetItemCreationFeatCount() > 1) + { + //check for arcane caster levels + if(!GetLocalInt(oPC, "PRC_ArcSpell3") || GetInvokerLevel(oPC) > 4) + SetLocalInt(oPC, "PRC_PrereqMaester", 0); + } + } +} + +void reqCombatMedic(object oPC) +{ + /* The combat medic can only be taken if the player is able to cast Cure Light Wounds. + * Base classes: + * With druids and clerics, that's no problem - they get it at first level. Paladins and + * rangers are a bit more complicated, due to their bonus spells and later spell gains. + */ + + SetLocalInt(oPC, "PRC_PrereqCbtMed", 1); + + //check PRC classes + if(PRCGetIsRealSpellKnown(SPELL_CURE_LIGHT_WOUNDS, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqCbtMed", 0); + return; + } + + //check bioware classes + int iWis = GetLocalInt(GetPCSkin(oPC), "PRC_trueWIS"); + if(iWis > 10) + { + if(GetLevelByClass(CLASS_TYPE_CLERIC) + || GetLevelByClass(CLASS_TYPE_DRUID) + || GetLevelByClass(CLASS_TYPE_PALADIN) >= 6 + || GetLevelByClass(CLASS_TYPE_RANGER) >= 6 + || (iWis > 11 && GetLevelByClass(CLASS_TYPE_PALADIN) >= 4) + || (iWis > 11 && GetLevelByClass(CLASS_TYPE_RANGER) >= 4)) + SetLocalInt(oPC, "PRC_PrereqCbtMed", 0); + } +} + +void RedWizard(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqRedWiz", 1); + + int iFeat; + int iFocus; + + iFocus = GetHasFeat(FEAT_RW_TF_ABJ, oPC) + + GetHasFeat(FEAT_RW_TF_CON, oPC) + + GetHasFeat(FEAT_RW_TF_DIV, oPC) + + GetHasFeat(FEAT_RW_TF_ENC, oPC) + + GetHasFeat(FEAT_RW_TF_EVO, oPC) + + GetHasFeat(FEAT_RW_TF_ILL, oPC) + + GetHasFeat(FEAT_RW_TF_NEC, oPC) + + GetHasFeat(FEAT_RW_TF_TRS, oPC); + // Metamagic or Item Creation feats + iFeat = GetItemCreationFeatCount() + + GetHasFeat(FEAT_EMPOWER_SPELL, oPC) + + GetHasFeat(FEAT_EXTEND_SPELL, oPC) + + GetHasFeat(FEAT_MAXIMIZE_SPELL, oPC) + + GetHasFeat(FEAT_QUICKEN_SPELL, oPC) + + GetHasFeat(FEAT_SILENCE_SPELL, oPC) + + GetHasFeat(FEAT_STILL_SPELL, oPC) + + GetHasFeat(FEAT_SUDDEN_EMPOWER, oPC) + + GetHasFeat(FEAT_SUDDEN_MAXIMIZE, oPC) + + GetHasFeat(FEAT_SUDDEN_EXTEND, oPC) + + GetHasFeat(FEAT_SUDDEN_WIDEN, oPC); + + + // At least two arcane feats, one tattoo focus + if (iFeat > 2 && iFocus == 1) + { + SetLocalInt(oPC, "PRC_PrereqRedWiz", 0); + } +} + +void WildMageReq(object oPC) +{ + SetLocalInt(oPC, "PRC_PresWildMageReq", 1); + + int iFeat = GetHasFeat(FEAT_EMPOWER_SPELL, oPC) + + GetHasFeat(FEAT_EXTEND_SPELL, oPC) + + GetHasFeat(FEAT_MAXIMIZE_SPELL, oPC) + + GetHasFeat(FEAT_QUICKEN_SPELL, oPC) + + GetHasFeat(FEAT_SILENCE_SPELL, oPC) + + GetHasFeat(FEAT_STILL_SPELL, oPC) + + GetHasFeat(FEAT_SUDDEN_EMPOWER, oPC) + + GetHasFeat(FEAT_SUDDEN_MAXIMIZE, oPC) + + GetHasFeat(FEAT_SUDDEN_EXTEND, oPC) + + GetHasFeat(FEAT_SUDDEN_WIDEN, oPC); + + // At least one metamagic feat + if (iFeat) + SetLocalInt(oPC, "PRC_PresWildMageReq", 0); +} + +void DalQuor(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqDalQuor", 1); + + // Psionic feats + if(GetHasFeat(FEAT_COMBAT_MANIFESTATION , oPC) + || GetHasFeat(FEAT_MENTAL_LEAP , oPC) + || GetHasFeat(FEAT_NARROW_MIND , oPC) + || GetHasFeat(FEAT_POWER_PENETRATION , oPC) + || GetHasFeat(FEAT_GREATER_POWER_PENETRATION , oPC) + || GetHasFeat(FEAT_POWER_SPECIALIZATION , oPC) + || GetHasFeat(FEAT_GREATER_POWER_SPECIALIZATION, oPC) + || GetHasFeat(FEAT_PSIONIC_DODGE , oPC) + || GetHasFeat(FEAT_PSIONIC_ENDOWMENT , oPC) + || GetHasFeat(FEAT_GREATER_PSIONIC_ENDOWMENT , oPC) + || GetHasFeat(FEAT_PSIONIC_FIST , oPC) + || GetHasFeat(FEAT_GREATER_PSIONIC_FIST , oPC) + || GetHasFeat(FEAT_PSIONIC_WEAPON , oPC) + || GetHasFeat(FEAT_GREATER_PSIONIC_WEAPON , oPC) + || GetHasFeat(FEAT_PSIONIC_SHOT , oPC) + || GetHasFeat(FEAT_GREATER_PSIONIC_SHOT , oPC) + || GetHasFeat(FEAT_OVERCHANNEL , oPC) + || GetHasFeat(FEAT_PSIONIC_MEDITATION , oPC) + || GetHasFeat(FEAT_RAPID_METABOLISM , oPC) + || GetHasFeat(FEAT_TALENTED , oPC) + || GetHasFeat(FEAT_UNAVOIDABLE_STRIKE , oPC) + || GetHasFeat(FEAT_WILD_TALENT , oPC) + || GetHasFeat(FEAT_WOUNDING_ATTACK , oPC) + || GetHasFeat(FEAT_BOOST_CONSTRUCT , oPC) + || GetHasFeat(FEAT_SPEED_OF_THOUGHT , oPC) + || GetHasFeat(FEAT_PSIONIC_TALENT_1 , oPC) + || GetHasFeat(FEAT_METAMORPHIC_TRANSFER_1 , oPC) + || GetHasFeat(FEAT_DEEP_IMPACT , oPC) + || GetHasFeat(FEAT_FELL_SHOT , oPC) + || GetHasFeat(FEAT_EXPANDED_KNOWLEDGE_1 , oPC) + || GetHasFeat(FEAT_INVEST_ARMOUR , oPC)) + // At least one psionic feat + SetLocalInt(oPC, "PRC_PrereqDalQuor", 0); +} + +void Thrallherd(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqThrallherd", 1); + + // Technically, you must be able to manifest mindlink, and the only class that can do so is a Telepath Psion + // Thus, this restriction. + if(GetHasFeat(FEAT_PSION_DIS_TELEPATH, oPC)) + { + // @todo Replace with some mechanism that is not dependent on power enumeration. Maybe a set of variables that tell how many powers of each discipline a character knows <- requires hooking to power gain / loss + if(GetHasPower(POWER_CHARMPERSON, oPC) + || GetHasPower(POWER_AVERSION, oPC) + || GetHasPower(POWER_BRAINLOCK, oPC) + || GetHasPower(POWER_CRISISBREATH, oPC) + || GetHasPower(POWER_EMPATHICTRANSFERHOSTILE, oPC) + || GetHasPower(POWER_DOMINATE, oPC) + || GetHasPower(POWER_CRISISLIFE, oPC) + || GetHasPower(POWER_PSYCHICCHIR_REPAIR, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqThrallherd", 0); + } + } +} + +void Shadowmind(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqShadowmind", 1); + + if(GetHasPower(POWER_CONCEALAMORPHA, oPC)) + SetLocalInt(oPC, "PRC_PrereqShadowmind", 0); +} + +void SoulEater(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqSoulEater", 1); + + int nRace = MyPRCGetRacialType(oPC); + if(nRace == RACIAL_TYPE_ABERRATION + || nRace == RACIAL_TYPE_ANIMAL + || nRace == RACIAL_TYPE_BEAST + || nRace == RACIAL_TYPE_DRAGON + || nRace == RACIAL_TYPE_HUMANOID_MONSTROUS + || nRace == RACIAL_TYPE_MAGICAL_BEAST + || nRace == RACIAL_TYPE_OUTSIDER + || nRace == RACIAL_TYPE_FEY + || nRace == RACIAL_TYPE_GIANT + || nRace == RACIAL_TYPE_ELEMENTAL) + SetLocalInt(oPC, "PRC_PrereqSoulEater", 0); +} + +void RacialHD(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqAberration", 1); + SetLocalInt(oPC, "PRC_PrereqAnimal", 1); + SetLocalInt(oPC, "PRC_PrereqConstruct", 1); + SetLocalInt(oPC, "PRC_PrereqHumanoid", 1); + SetLocalInt(oPC, "PRC_PrereqMonstrous", 1); + SetLocalInt(oPC, "PRC_PrereqEle", 1); + SetLocalInt(oPC, "PRC_PrereqFey", 1); + SetLocalInt(oPC, "PRC_PrereqDragon", 1); + SetLocalInt(oPC, "PRC_PrereqUndead", 1); + SetLocalInt(oPC, "PRC_PrereqBeast", 1); + SetLocalInt(oPC, "PRC_PrereqGiant", 1); + SetLocalInt(oPC, "PRC_PrereqMagicalBeast", 1); + SetLocalInt(oPC, "PRC_PrereqOutsider", 1); + SetLocalInt(oPC, "PRC_PrereqShapechanger", 1); + SetLocalInt(oPC, "PRC_PrereqVermin", 1); + SetLocalInt(oPC, "PRC_PrereqPlant", 1); + if(GetPRCSwitch(PRC_XP_USE_SIMPLE_RACIAL_HD)) + { + int nRealRace = GetRacialType(oPC); + int nRacialHD = StringToInt(Get2DACache("ECL", "RaceHD", nRealRace)); + int nRacialClass = StringToInt(Get2DACache("ECL", "RaceClass", nRealRace)); + if(nRacialHD && GetLevelByClass(nRacialClass, oPC) < nRacialHD) + { + switch(nRacialClass) + { + case CLASS_TYPE_ABERRATION: SetLocalInt(oPC, "PRC_PrereqAberration", 0); break; + case CLASS_TYPE_ANIMAL: SetLocalInt(oPC, "PRC_PrereqAnmal", 0); break; + case CLASS_TYPE_CONSTRUCT: SetLocalInt(oPC, "PRC_PrereqConstruct", 0); break; + case CLASS_TYPE_HUMANOID: SetLocalInt(oPC, "PRC_PrereqHumanoid", 0); break; + case CLASS_TYPE_MONSTROUS: SetLocalInt(oPC, "PRC_PrereqMonstrous", 0); break; + case CLASS_TYPE_ELEMENTAL: SetLocalInt(oPC, "PRC_PrereqEle", 0); break; + case CLASS_TYPE_FEY: SetLocalInt(oPC, "PRC_PrereqFey", 0); break; + case CLASS_TYPE_DRAGON: SetLocalInt(oPC, "PRC_PrereqDragon", 0); break; + case CLASS_TYPE_UNDEAD: SetLocalInt(oPC, "PRC_PrereqUndead", 0); break; + case CLASS_TYPE_BEAST: SetLocalInt(oPC, "PRC_PrereqBeast", 0); break; + case CLASS_TYPE_GIANT: SetLocalInt(oPC, "PRC_PrereqGiant", 0); break; + case CLASS_TYPE_MAGICAL_BEAST: SetLocalInt(oPC, "PRC_PrereqMagicalBeast", 0); break; + case CLASS_TYPE_OUTSIDER: SetLocalInt(oPC, "PRC_PrereqOutsider", 0); break; + case CLASS_TYPE_SHAPECHANGER: SetLocalInt(oPC, "PRC_PrereqShapechanger", 0); break; + case CLASS_TYPE_VERMIN: SetLocalInt(oPC, "PRC_PrereqVermin", 0); break; + case CLASS_TYPE_PLANT: SetLocalInt(oPC, "PRC_PrereqPlant", 0); break; + default: SetLocalInt(oPC, "NoRace", 0); + } + } + } +} + +void Virtuoso(object oPC) +{ //Needs 6 ranks of Persuade OR 6 ranks of Intimidate + SetLocalInt(oPC, "PRC_PrereqVirtuoso", 1); + if((GetSkillRank(SKILL_PERSUADE, oPC) >= 6) || (GetSkillRank(SKILL_INTIMIDATE, oPC) >= 6)) + SetLocalInt(oPC, "PRC_PrereqVirtuoso", 0); +} + +void FistRaziel(object oPC) +{ + /* The fist of Raziel can only be taken if the player is able to cast Divine Favor. + * Base classes: + * Cleric gets it at level 1. Paladin at level 4 (with wis > 11) to 6 (wis == 11) + */ + + SetLocalInt(oPC, "PRC_PrereqFistRaz", 1); + object oSkin = GetPCSkin(oPC); + int iWis = GetLocalInt(oSkin, "PRC_trueWIS"); + // hard code it to work for Bioware classes + if (GetLevelByClass(CLASS_TYPE_CLERIC)) + { + SetLocalInt(oPC, "PRC_PrereqFistRaz", 0); + return; + } + + if (GetLevelByClass(CLASS_TYPE_PALADIN)) + { + if(iWis > 11 && GetLevelByClass(CLASS_TYPE_PALADIN) >= 4) + { + SetLocalInt(oPC, "PRC_PrereqFistRaz", 0); + return; + } + else if (GetLevelByClass(CLASS_TYPE_PALADIN) >= 6) + { + SetLocalInt(oPC, "PRC_PrereqFistRaz", 0); + return; + } + } + + if (PRCGetIsRealSpellKnown(SPELL_DIVINE_FAVOR, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqFistRaz", 0); + return; + } + +} + +void Pyro(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqPyro", 1); + if(GetIsPsionicCharacter(oPC)) + SetLocalInt(oPC, "PRC_PrereqPyro", 0); +} + +void Suel() +{ + SetLocalInt(OBJECT_SELF, "PRC_PrereqSuelWeap", 1); + + //martial weapon proficiences + int nProf = GetHasFeat(FEAT_WEAPON_PROFICIENCY_SHORTSWORD) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_LONGSWORD) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_BATTLEAXE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_WARHAMMER) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_LONGBOW) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_HALBERD) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_SHORTBOW) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_GREATSWORD) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_GREATAXE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_HANDAXE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_RAPIER) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_SCIMITAR) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_THROWING_AXE); + //exotic weapon proficiences + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_BATTLEAXE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_DIRE_MACE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_KAMA) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_KUKRI) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_KATANA) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_SCYTHE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_SHURIKEN) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_WHIP) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_RAPIER) + + GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE); + + if(nProf > 3) + DeleteLocalInt(OBJECT_SELF, "PRC_PrereqSuelWeap"); +} + +void TomeOfBattle(object oPC = OBJECT_SELF) +{ + // Deepstone Sentinel + SetLocalInt(oPC, "PRC_PrereqDeepSt", 1); + // Needs two Stone Dragon maneuvers + int nMove = GetManeuverCountByDiscipline(oPC, DISCIPLINE_STONE_DRAGON, MANEUVER_TYPE_MANEUVER); + // Needs one Stone Dragon Stance + int nStance = GetManeuverCountByDiscipline(oPC, DISCIPLINE_STONE_DRAGON, MANEUVER_TYPE_STANCE); + if(nMove > 1 && nStance) + SetLocalInt(oPC, "PRC_PrereqDeepSt", 0); + + // Bloodclaw Master + SetLocalInt(oPC, "PRC_PrereqBloodclaw", 1); + // Needs three Tiger Claw maneuvers + if(_CheckPrereqsByDiscipline(oPC, DISCIPLINE_TIGER_CLAW, 3)) + SetLocalInt(oPC, "PRC_PrereqBloodclaw", 0); + + // Ruby Knight Vindicator + SetLocalInt(oPC, "PRC_PrereqRubyKnight", 1); + // Needs one Devoted Spirit maneuver + nMove = GetManeuverCountByDiscipline(oPC, DISCIPLINE_DEVOTED_SPIRIT, MANEUVER_TYPE_MANEUVER); + // Needs one Devoted Spirit stance + nStance = GetManeuverCountByDiscipline(oPC, DISCIPLINE_DEVOTED_SPIRIT, MANEUVER_TYPE_STANCE); + // If it's a cleric, needs to have Death, Law and Magic as domains. + int nDomain = TRUE; + if(GetLevelByClass(CLASS_TYPE_CLERIC, oPC)) + { + nDomain = GetHasFeat(FEAT_DEATH_DOMAIN_POWER, oPC) + + GetHasFeat(FEAT_MAGIC_DOMAIN_POWER, oPC) + //+ GetHasFeat(FEAT_LAW_DOMAIN_POWER, oPC) + > 1; + } + if(nMove && nStance && nDomain) + SetLocalInt(oPC, "PRC_PrereqRubyKnight", 0); + + // Jade Phoenix Mage + SetLocalInt(oPC, "PRC_PrereqJPM", 1); + // Skip the rest of not an arcane caster + if(GetLocalInt(oPC, "PRC_ArcSpell2") == 0) + { + int nUser; + int nMove = 0; + int nStance = 0; + int nType; + + // Only need first blade magic class. Can't take a second and Jade Phoenix and meet requirements. + nUser = GetPrimaryBladeMagicClass(oPC); + + // If inv_inc_moveknwn can be included here, GetManeuverCount() can be used in place of GetPersistantLocalInt() + // the following is pulled from the function + + nType = MANEUVER_TYPE_MANEUVER; + nMove += GetPersistantLocalInt(oPC, "PRC_ManeuverList_" + IntToString(nUser) + IntToString(nType) + "_TotalKnown"); + + nType = MANEUVER_TYPE_STANCE; + nStance += GetPersistantLocalInt(oPC, "PRC_ManeuverList_" + IntToString(nUser) + IntToString(nType) + "_TotalKnown"); + + if (nMove >= 2 && nStance >= 1) + SetLocalInt(oPC, "PRC_PrereqJPM", 0); + } + + //Master of Nine + SetLocalInt(oPC, "PRC_PrereqMoNine", 1); + // Needs 6 maneuvers, so check the persistent locals + int i, nCount, nSkills; + for(i = 1; i <= 256; i <<= 1) + { + // Loop over all disciplines, and total up how many he knows + if(_CheckPrereqsByDiscipline(oPC, i)) + nCount++; + } + + // Base ranks only + if(GetSkillRank(SKILL_TUMBLE, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_INTIMIDATE, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_CONCENTRATION, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_BALANCE, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_SENSE_MOTIVE, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_HIDE, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_JUMP, oPC, TRUE) >= 10) nSkills += 1; + if(GetSkillRank(SKILL_PERSUADE, oPC, TRUE) >= 10) nSkills += 1; + + if(nCount >= 6 && nSkills >= 4) + SetLocalInt(oPC, "PRC_PrereqMoNine", 0); + + //Eternal Blade + SetLocalInt(oPC, "PRC_PrereqETBL", 1); + + int iWF = WeaponFocusCount(oPC); + nCount = _CheckPrereqsByDiscipline(oPC, DISCIPLINE_DEVOTED_SPIRIT) + + _CheckPrereqsByDiscipline(oPC, DISCIPLINE_DIAMOND_MIND); + + if(nCount >= 2 && iWF >= 1) + SetLocalInt(oPC, "PRC_PrereqETBL", 0); + + //Shadow Sun Ninja + SetLocalInt(oPC, "PRC_PrereqSSN", 1); + + int nLv2 = GetPersistantLocalInt(oPC, "ShadowSunNinjaLv2Req"); + int nSS = _CheckPrereqsByDiscipline(oPC, DISCIPLINE_SETTING_SUN); + int nSH = _CheckPrereqsByDiscipline(oPC, DISCIPLINE_SHADOW_HAND); + + // We have at least one 2nd level Shadow Hand or Setting Sun maneuver + // And at least one of each Shadow Hand and Setting Sun maneuvers + if(nLv2 && nSS && nSH && (nSS >= 2 || nSH >= 2)) + SetLocalInt(oPC, "PRC_PrereqSSN", 0); +} + +void AOTS(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqAOTS", 1); + int iArcane = GetLocalInt(oPC, "PRC_ArcSpell3"); + if(iArcane == 0 || GetInvokerLevel(oPC) >= 5) + SetLocalInt(oPC, "PRC_PrereqAOTS", 0); +} + +void EnlF(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqEnlF", 1); + int iArcane = GetLocalInt(oPC, "PRC_ArcSpell2"); + if(iArcane == 0 || GetInvokerLevel(oPC) >= 3) + SetLocalInt(oPC, "PRC_PrereqEnlF", 0); +} + +void LichPrereq(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqLich", 1); + if(PRCAmIAHumanoid(oPC) || GetLevelByClass(CLASS_TYPE_LICH, oPC) >= 4) + SetLocalInt(oPC, "PRC_PrereqLich", 0); +} + +void DragDisciple(object oPC) +{ + int bRace = FALSE; + int bSpells = FALSE; + SetLocalInt(oPC, "PRC_PrereqDrDis", 1); + + //Any nondragon (cannot already be a half-dragon) + int nRace = GetRacialType(oPC); + if(!GetHasTemplate(TEMPLATE_HALF_DRAGON, oPC) + && nRace != RACIAL_TYPE_BAAZ + && nRace != RACIAL_TYPE_BOZAK + && nRace != RACIAL_TYPE_KAPAK) + bRace = TRUE; + + // Ability to cast arcane spells without preparation + // (dragon blooded feat eliminates that requirement) + if(GetHasFeat(DRAGON_BLOODED, oPC)) + bSpells = TRUE; + else if(GetLevelByClass(CLASS_TYPE_ASSASSIN, oPC) + || GetLevelByClass(CLASS_TYPE_BARD, oPC) + || GetLevelByClass(CLASS_TYPE_BEGUILER, oPC) + || GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oPC) + || GetLevelByClass(CLASS_TYPE_DUSKBLADE, oPC) + || GetLevelByClass(CLASS_TYPE_HEXBLADE, oPC) + || GetLevelByClass(CLASS_TYPE_SORCERER, oPC) + || GetLevelByClass(CLASS_TYPE_SUEL_ARCHANAMACH, oPC) + || GetLevelByClass(CLASS_TYPE_WARMAGE, oPC) + || GetLevelByClass(CLASS_TYPE_WITCH, oPC)) + { + if(!GetLocalInt(oPC, "PRC_ArcSpell0") + || !GetLocalInt(oPC, "PRC_ArcSpell1")) + bSpells = TRUE; + } + + if(bRace && bSpells) + SetLocalInt(oPC, "PRC_PrereqDrDis", 0); +} + +void WarlockPrCs(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqHFWar", 1); + SetLocalInt(oPC, "PRC_PrereqEDisc", 1); + SetLocalInt(oPC, "PRC_PrereqETheurg", 1); + + if(GetHasInvocation(INVOKE_BRIMSTONE_BLAST, oPC) + || GetHasInvocation(INVOKE_HELLRIME_BLAST, oPC)) + { + SetLocalInt(oPC, "PRC_PrereqHFWar", 0); + } + + //currently there are only 2 invocation using classes + //all start with least invocations so this should be accurate + if(GetIsInvocationUser(oPC)) + { + SetLocalInt(oPC, "PRC_PrereqEDisc", 0); + + if(GetBlastDamageDices(oPC, GetInvokerLevel(oPC, CLASS_TYPE_WARLOCK)) > 1) + { + SetLocalInt(oPC, "PRC_PrereqETheurg", 0); + } + } +} + +void Shadowbane(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqShadowbane", 1); + if(GetLevelByClass(CLASS_TYPE_CLERIC, oPC) || + GetLevelByClass(CLASS_TYPE_ARCHIVIST, oPC) || + GetLevelByClass(CLASS_TYPE_PALADIN, oPC) || + GetLevelByClass(CLASS_TYPE_KNIGHT_CHALICE, oPC) || + GetLevelByClass(CLASS_TYPE_SOLDIER_OF_LIGHT, oPC) || + GetLevelByClass(CLASS_TYPE_SHAMAN, oPC) || + GetLevelByClass(CLASS_TYPE_SLAYER_OF_DOMIEL, oPC)) + SetLocalInt(oPC, "PRC_PrereqShadowbane", 0); +} + +void KnightWeave(object oPC) +{ + int bSpontCaster = FALSE; + //make sure user is a spontaneous arcane caster + int i; + for(i = 1; i <= 3; i++) + { + int nClass = GetClassByPosition(i, oPC); + if((GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS) && GetMaxSpellLevelForCasterLevel(nClass, GetLevelByTypeArcane(oPC)) >= 3) + bSpontCaster = TRUE; + + //if (DEBUG) DoDebug("Knight of the Weave: Spellbook Type "+IntToString(GetSpellbookTypeForClass(nClass))+", MaxSpellLevel "+IntToString(GetMaxSpellLevelForCasterLevel(nClass, GetLevelByTypeArcane(oPC)))+", BAB "+IntToString(GetBaseAttackBonus(oPC))); + } + + SetLocalInt(oPC, "PRC_PrereqKnightWeave", 1); + if((GetBaseAttackBonus(oPC) >= 5 || bSpontCaster) && !GetHasFeat(FEAT_SHADOWWEAVE, oPC)) // Shadow weave not allowed + SetLocalInt(oPC, "PRC_PrereqKnightWeave", 0); +} + +void Incarnate(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqIncarnate", 1); + if(IncarnateAlignment(oPC) && (PRCGetIsAliveCreature(oPC) || GetHasFeat(FEAT_UNDEAD_MELDSHAPER, oPC))) + SetLocalInt(oPC, "PRC_PrereqIncarnate", 0); +} + +void Spinemeld(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqSpinemeld", 1); + SetLocalInt(oPC, "PRC_PrereqUmbral", 1); + SetLocalInt(oPC, "PRC_PrereqIncandescent", 1); + if(GetTotalEssentia(oPC)) + { + SetLocalInt(oPC, "PRC_PrereqSpinemeld", 0); + SetLocalInt(oPC, "PRC_PrereqUmbral", 0); + SetLocalInt(oPC, "PRC_PrereqIncandescent", 0); + } + //FloatingTextStringOnCreature("PRC_PrereqSpinemeld is "+IntToString(GetLocalInt(oPC, "PRC_PrereqSpinemeld"))+" GetBAB is "+IntToString(GetBaseAttackBonus(oPC))+" GetLawChaos is "+IntToString(GetAlignmentLawChaos(oPC))+" GetRace is "+IntToString(GetRacialType(oPC)), oPC, FALSE); +} + +void SapphireHierarch(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqSapphire", 1); + if(GetTotalEssentia(oPC) >= 3 &&/* GetHasFeat(FEAT_LAW_DOMAIN_POWER, oPC) &&*/ GetTotalSoulmeldCount(oPC) >= 3) + SetLocalInt(oPC, "PRC_PrereqSapphire", 0); +} + +void SoulcasterReq(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqSoulcaster", 1); + if( GetMaxBindCount(oPC, GetPrimaryIncarnumClass(oPC)) >= 1 && GetTotalSoulmeldCount(oPC) >= 3 && + ((!GetLocalInt(oPC, "PRC_PsiPower2") && GetHasFeat(FEAT_AZURE_TALENT, oPC)) || + (!GetLocalInt(oPC, "PRC_ArcSpell2") && GetHasFeat(FEAT_INCARNUM_SPELLSHAPING)))) + SetLocalInt(oPC, "PRC_PrereqSoulcaster", 0); +} + +void Ironsoul(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqIronsoul", 1); + if(GetTotalSoulmeldCount(oPC) >= 1) + SetLocalInt(oPC, "PRC_PrereqIronsoul", 0); +} + +void Necrocarnum(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqNecrocarnum", 1); + if(GetTotalSoulmeldCount(oPC) && GetCanBindChakra(oPC, CHAKRA_CROWN) && GetCanBindChakra(oPC, CHAKRA_FEET) && GetCanBindChakra(oPC, CHAKRA_HANDS)) + SetLocalInt(oPC, "PRC_PrereqNecrocarnum", 0); +} + +void Witchborn(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqWitchborn", 1); + // Can't be arcane at all, Meldshaper level 6th + if(GetPrimaryArcaneClass(oPC) == CLASS_TYPE_INVALID && GetHighestMeldshaperLevel(oPC) >= 6) + SetLocalInt(oPC, "PRC_PrereqWitchborn", 0); +} + +void AbChamp(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqAbjCha", 1); + if(GetHasFeat(FEAT_COMBAT_CASTING, oPC)) + SetLocalInt(oPC, "PRC_PrereqAbjCha", 0); +} + +void AnimaMageReq(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqAnimaMage", 1); + + int iFeat = GetHasFeat(FEAT_EMPOWER_SPELL, oPC) + + GetHasFeat(FEAT_EXTEND_SPELL, oPC) + + GetHasFeat(FEAT_MAXIMIZE_SPELL, oPC) + + GetHasFeat(FEAT_QUICKEN_SPELL, oPC) + + GetHasFeat(FEAT_SILENCE_SPELL, oPC) + + GetHasFeat(FEAT_STILL_SPELL, oPC); + + // At least one metamagic feat, 2nd level vestiges from Binder class + if (iFeat && GetMaxVestigeLevel(oPC) >= 2 && GetLevelByClass(CLASS_TYPE_BINDER, oPC)) + SetLocalInt(oPC, "PRC_PrereqAnimaMage", 0); +} + +void TenebrousReq(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqTenebrous", 1); + int nDomain = FALSE; + if(GetHasFeat(FEAT_DEATH_DOMAIN_POWER) + + GetHasFeat(FEAT_TRICKERY_DOMAIN_POWER) + + GetHasFeat(FEAT_EVIL_DOMAIN_POWER) >= 2) + nDomain = TRUE; + + // Tenebrous grants turn undead, so it actually meets that requirement. + + // 4th level vestiges from Binder class + if ((nDomain || !GetLevelByClass(CLASS_TYPE_CLERIC, oPC)) && GetMaxVestigeLevel(oPC) >= 4 && GetLevelByClass(CLASS_TYPE_BINDER, oPC)) + SetLocalInt(oPC, "PRC_PrereqTenebrous", 0); +} + +void ScionReq(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqScion", 1); + int nCheck = FALSE; + int nRace = MyPRCGetRacialType(oPC); + if(nRace == RACIAL_TYPE_HUMAN + || nRace == RACIAL_TYPE_HALFORC + || nRace == RACIAL_TYPE_HALFELF) + nCheck = TRUE; + + // 5th level vestiges from Binder class + if (nCheck && GetMaxVestigeLevel(oPC) >= 5 && GetLevelByClass(CLASS_TYPE_BINDER, oPC)) + SetLocalInt(oPC, "PRC_PrereqScion", 0); +} + +void DragonDevotee(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqDragonDevotee", 1); + + if(MyPRCGetRacialType(oPC) != RACIAL_TYPE_DRAGON) + SetLocalInt(oPC, "PRC_PrereqDragonDevotee", 0); +} + +void UrPriest(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqUrPriest", 1); + + if (GetWillSavingThrow(oPC) >= 3 && GetFortitudeSavingThrow(oPC) >= 3) + { + SetLocalInt(oPC, "PRC_PrereqUrPriest", 0); + } +} + +void Ocular(object oPC) +{ + SetLocalInt(oPC, "PRC_PrereqOcular", 1); + + if (GetFortitudeSavingThrow(oPC) >= 4) + { + SetLocalInt(oPC, "PRC_PrereqOcular", 0); + } +} + +void main() +{ + //Declare Major Variables + object oPC = OBJECT_SELF; + object oSkin = GetPCSkin(oPC); + + // Initialize all the variables. + string sVariable, sCount; + int iCount; + for (iCount = 0; iCount <= 9; iCount++) + { + sCount = IntToString(iCount); + + sVariable = "PRC_AllSpell" + sCount; + SetLocalInt(oPC, sVariable, 1); + + sVariable = "PRC_ArcSpell" + sCount; + SetLocalInt(oPC, sVariable, 1); + + sVariable = "PRC_DivSpell" + sCount; + SetLocalInt(oPC, sVariable, 1); + + sVariable = "PRC_PsiPower" + sCount; + SetLocalInt(oPC, sVariable, 1); + + sVariable = "PRC_MystLevel" + sCount; + SetLocalInt(oPC, sVariable, 1); + } + + for (iCount = 1; iCount <= 30; iCount++) + { + sCount = IntToString(iCount); + + sVariable = "PRC_SneakLevel" + sCount; + SetLocalInt(oPC, sVariable, 1); + + sVariable = "PRC_SkirmishLevel" + sCount; + SetLocalInt(oPC, sVariable, 1); + + sVariable = "PRC_SplAtkLevel" + sCount; + SetLocalInt(oPC, sVariable, 1); + } + + // Find the spell levels. + int iCha = GetLocalInt(oSkin, "PRC_trueCHA") - 10; + int iWis = GetLocalInt(oSkin, "PRC_trueWIS") - 10; + int iInt = GetLocalInt(oSkin, "PRC_trueINT") - 10; + int nArcHighest; + int nDivHighest; + int nPsiHighest; + int bFirstArcClassFound, bFirstDivClassFound, bFirstPsiClassFound, bFirstShdClassFound; + //for(i=1;i<3;i++) + int nSpellLevel; + int nClassSlot = 1; + while(nClassSlot <= 3) + { + int nClass = GetClassByPosition(nClassSlot, oPC); + nClassSlot += 1; + if(GetIsDivineClass(nClass)) + { + int nLevel = GetLevelByClass(nClass, oPC); + if (!bFirstDivClassFound && + GetPrimaryDivineClass(oPC) == nClass) + { + nLevel += GetDivinePRCLevels(oPC); + bFirstDivClassFound = TRUE; + } + int nAbility = GetAbilityScoreForClass(nClass, oPC); + + for(nSpellLevel = 0; nSpellLevel <= 9; nSpellLevel++) + { + int nSlots = GetSlotCount(nLevel, nSpellLevel, nAbility, nClass); + if(nSlots > 0) + { + SetLocalInt(oPC, "PRC_AllSpell"+IntToString(nSpellLevel), 0); + SetLocalInt(oPC, "PRC_DivSpell"+IntToString(nSpellLevel), 0); + if(nSpellLevel > nDivHighest) + nDivHighest = nSpellLevel; + } + } + } + else if(GetIsArcaneClass(nClass)) + { + int nLevel = GetLevelByClass(nClass, oPC); + if (!bFirstArcClassFound && + GetPrimaryArcaneClass(oPC) == nClass) + { + nLevel += GetArcanePRCLevels(oPC); + bFirstArcClassFound = TRUE; + } + int nAbility = GetAbilityScoreForClass(nClass, oPC); + + for(nSpellLevel = 0; nSpellLevel <= 9; nSpellLevel++) + { + int nSlots = GetSlotCount(nLevel, nSpellLevel, nAbility, nClass); + if(nSlots > 0) + { + SetLocalInt(oPC, "PRC_AllSpell"+IntToString(nSpellLevel), 0); + SetLocalInt(oPC, "PRC_ArcSpell"+IntToString(nSpellLevel), 0); + if(nSpellLevel > nArcHighest) + nArcHighest = nSpellLevel; + } + } + } + else if(GetIsPsionicClass(nClass)) + { + int nLevel = GetLevelByClass(nClass, oPC); + if (!bFirstPsiClassFound && + GetPrimaryPsionicClass(oPC) == nClass) + { + nLevel += GetPsionicPRCLevels(oPC); + bFirstPsiClassFound = TRUE; + } + int nAbility = GetAbilityScoreForClass(nClass, oPC); + string sPsiFile = GetAMSKnownFileName(nClass); + int nMaxLevel = StringToInt(Get2DACache(sPsiFile, "MaxPowerLevel", nLevel)); + + int nPsiHighest = min(nMaxLevel, nAbility - 10); + + for(nSpellLevel = 1; nSpellLevel <= nPsiHighest; nSpellLevel++) + { + SetLocalInt(oPC, "PRC_PsiPower"+IntToString(nSpellLevel), 0); + //if(DEBUG) DoDebug("Psionics power level Prereq Variable " + IntToString(nSpellLevel) +": " + IntToString(GetLocalInt(oPC, "PRC_PsiPower"+IntToString(nSpellLevel))), oPC); + } + } + else if(GetIsShadowMagicClass(nClass)) + { + int nLevel = GetLevelByClass(nClass, oPC); + if (!bFirstShdClassFound && + GetPrimaryShadowMagicClass(oPC) == nClass) + { + nLevel += GetShadowMagicPRCLevels(oPC); + bFirstShdClassFound = TRUE; + } + int nAbility = GetAbilityScoreForClass(nClass, oPC); + string sShdFile = GetAMSKnownFileName(nClass); + + int nShdHighest = max(GetMaxMysteryLevelLearnable(oPC, nClass, 1), GetMaxMysteryLevelLearnable(oPC, nClass, 2)); + nShdHighest = max(nShdHighest, GetMaxMysteryLevelLearnable(oPC, nClass, 3)); + + for(nSpellLevel = 1; nSpellLevel <= nShdHighest; nSpellLevel++) + { + SetLocalInt(oPC, "PRC_MystLevel"+IntToString(nSpellLevel), 0); + //if(DEBUG) DoDebug("Shadowcasting mystery level Prereq Variable " + IntToString(nSpellLevel) +": " + IntToString(GetLocalInt(oPC, "PRC_MystLevel"+IntToString(nSpellLevel))), oPC); + } + } + }// end while - loop over all 3 class slots + + // special alignment requirements + reqAlignment(oPC); + // special gender requirements + reqGender(); + // Find the sneak attack/skirmish capacity. + reqSpecialAttack(oPC); + + // Cleric domain requirements + if(GetLevelByClass(CLASS_TYPE_CLERIC)) + reqDomains(); + + // Special requirements for several classes. + Tempest(); + KOTC(oPC); + RedWizard(oPC); + Shadowlord(oPC, nArcHighest); + Shifter(oPC, nArcHighest, nDivHighest); + DemiLich(oPC); + WWolf(oPC); + Kord(oPC); + Maester(oPC); + reqCombatMedic(oPC); + Thrallherd(oPC); + Shadowmind(oPC); + SoulEater(oPC); + RacialHD(oPC); + Virtuoso(oPC); + LichPrereq(oPC); + DalQuor(oPC); + Pyro(oPC); + Suel(); + TomeOfBattle(oPC); + AOTS(oPC); + EnlF(oPC); + DragDisciple(oPC); + WarlockPrCs(oPC); + Purifier(oPC); + Shadowbane(oPC); + WildMageReq(oPC); + KnightWeave(oPC); + Dragonheart(oPC); + Cultist(oPC); + Incarnate(oPC); + Spinemeld(oPC); + SapphireHierarch(oPC); + SoulcasterReq(oPC); + Ironsoul(oPC); + AbChamp(oPC); + Necrocarnum(oPC); + Witchborn(oPC); + AnimaMageReq(oPC); + TenebrousReq(oPC); + ScionReq(oPC); + DragonDevotee(oPC); + UrPriest(oPC); + Ocular(oPC); + // Truly massive debug message flood if activated. + /* + if (DEBUG) + { + string sPRC_AllSpell; + string sPRC_ArcSpell; + string sPRC_DivSpell; + string sPRC_PsiPower; + string sPRC_ShdMyst; + for (iCount = 1; iCount <= 9; iCount++) + { + sPRC_AllSpell = "PRC_AllSpell" + IntToString(iCount); + sPRC_ArcSpell = "PRC_ArcSpell" + IntToString(iCount); + sPRC_DivSpell = "PRC_DivSpell" + IntToString(iCount); + sPRC_PsiPower = "PRC_PsiPower" + IntToString(iCount); + sPRC_ShdMyst = "PRC_MystLevel" + IntToString(iCount); + SendMessageToPC(oPC, sPRC_AllSpell + " is " + IntToString(GetLocalInt(oPC, sPRC_AllSpell)) + ". " + + sPRC_ArcSpell + " is " + IntToString(GetLocalInt(oPC, sPRC_ArcSpell)) + ". " + + sPRC_DivSpell + " is " + IntToString(GetLocalInt(oPC, sPRC_DivSpell)) + ". " + + sPRC_PsiPower + " is " + IntToString(GetLocalInt(oPC, sPRC_PsiPower)) + ". " + + sPRC_ShdMyst + " is " + IntToString(GetLocalInt(oPC, sPRC_ShdMyst)) + "."); + } + for (iCount = 1; iCount <= 30; iCount++) + { + sVariable = "PRC_SneakLevel" + IntToString(iCount); + SendMessageToPC(oPC, sVariable + " is " + IntToString(GetLocalInt(oPC, sVariable)) + "."); + } + + }*/ +} diff --git a/nwnds_scripts/prc_rest.ncs b/nwnds_scripts/prc_rest.ncs new file mode 100644 index 0000000000000000000000000000000000000000..712bb17990424b8193b932ca14c3aff4bbd48dc8 GIT binary patch literal 135275 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 literal 0 HcmV?d00001 diff --git a/nwnds_scripts/prc_rest.nss b/nwnds_scripts/prc_rest.nss new file mode 100644 index 000000000..2c9224f9e --- /dev/null +++ b/nwnds_scripts/prc_rest.nss @@ -0,0 +1,395 @@ +//:://///////////////////////////////////////////// +//:: OnPlayerRest eventscript +//:: prc_rest +//::////////////////////////////////////////////// +/* + Hooked NPC's into this via prc_npc_rested - 06.03.2004, Ornedan +*/ + +#include "prc_inc_function" +#include "psi_inc_psifunc" +#include "prc_sp_func" +#include "prc_inc_domain" +#include "true_inc_trufunc" +#include "inv_inc_invfunc" +#include "inc_epicspells" +#include "prc_inc_scry" +#include "prc_inc_dragsham" +#include "prc_inc_wpnrest" +#include "inc_dynconv" +#include "prc_inc_util" +#include "shd_inc_myst" +#include "prc_inc_template" + +void PrcFeats(object oPC) +{ + if(DEBUG) DoDebug("prc_rest: Evaluating PC feats for " + DebugObject2Str(oPC)); + + SetLocalInt(oPC,"ONREST",1); + object oSkin = GetPCSkin(oPC); + DelayCommand(0.0, ScrubPCSkin(oPC, oSkin)); + DelayCommand(0.1, FeatSpecialUsePerDay(oPC)); + DelayCommand(0.2, DeletePRCLocalInts(oSkin)); + DelayCommand(0.3, DeletePRCLocalIntsT(oPC)); + DelayCommand(0.4, EvalPRCFeats(oPC)); + DelayCommand(0.4, DoWeaponsEquip(oPC)); + DelayCommand(1.0, DeleteLocalInt(oPC,"ONREST")); +} + +void RestCancelled(object oPC) +{ + if(GetPRCSwitch(PRC_PNP_REST_HEALING)) + { + int nHP = GetLocalInt(oPC, "PnP_Rest_InitialHP"); + //cancelled, dont heal anything + //nHP += GetHitDice(oPC); + int nCurrentHP = GetCurrentHitPoints(oPC); + int nDamage = nCurrentHP-nHP; + //check its a positive number + if(nDamage > 0) + { + //DelayCommand(1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY), oPC)); + SetCurrentHitPoints(oPC, nCurrentHP - nDamage); + } + } + if(DEBUG) DoDebug("prc_rest: Rest cancelled for " + DebugObject2Str(oPC)); + DelayCommand(1.0,PrcFeats(oPC)); + // Execute scripts hooked to this event for the player triggering it + ExecuteAllScriptsHookedToEvent(oPC, EVENT_ONPLAYERREST_CANCELLED); +} + +void RestFinished(object oPC) +{ + int nGeneration = PRC_NextGeneration(GetLocalInt(oPC, PRC_Rest_Generation)); + if (DEBUG > 1) DoDebug("Rest Generation: " + IntToString(nGeneration)); + SetLocalInt(oPC, PRC_Rest_Generation, nGeneration); + + if(DEBUG) DoDebug("prc_rest: Rest finished for for " + DebugObject2Str(oPC)); + //Restore Power Points for Psionics + ExecuteScript("prc_psi_ppoints", oPC); + ExecuteScript("tob_evnt_recover", oPC); + DelayCommand(0.0, BonusDomainRest(oPC)); + DelayCommand(0.0, ClearLawLocalVars(oPC)); + DelayCommand(0.0, ClearMystLocalVars(oPC)); + DelayCommand(0.0, ClearLegacyUses(oPC)); + DelayCommand(0.1, ClearInvocationLocalVars(oPC)); + + // To heal up enslaved creatures... + object oSlave = GetLocalObject(oPC, "EnslavedCreature"); + if (GetIsObjectValid(oSlave) && !GetIsDead(oSlave) && !GetIsInCombat(oSlave)) + AssignCommand(oSlave, ActionRest()); + //ForceRest(oSlave); + + if (GetIsEpicSpellcaster(oPC)) { + FloatingTextStringOnCreature("*You feel refreshed*", oPC, FALSE); + ReplenishSlots(oPC); + } + + if (GetHasFeat(FEAT_SF_CODE,oPC)) + DelayCommand(0.1, RemoveSpecificProperty(GetPCSkin(oPC),ITEM_PROPERTY_BONUS_FEAT,IP_CONST_FEAT_SF_CODE)); + + // begin flurry of swords array + if (GetLevelByClass(CLASS_TYPE_ARCANE_DUELIST, oPC)) + { + DeleteLocalInt(oPC, "FLURRY_TARGET_NUMBER"); + + int i; + for (i = 0 ; i < 10 ; i++) + { + string sName = "FLURRY_TARGET_" + IntToString(i); + SetLocalObject(oPC, sName, OBJECT_INVALID); + } + } + // end flurry or swords array + + //Check for leftover Diamond Dragon appendages + if (GetLevelByClass(CLASS_TYPE_DIAMOND_DRAGON, oPC)) + { + if(GetPersistantLocalInt(oPC, "ChannelingTail")) + { + SetPersistantLocalInt(oPC, "ChannelingTail", FALSE); + SetCreatureTailType(CREATURE_TAIL_TYPE_NONE, oPC); + } + if(GetPersistantLocalInt(oPC, "ChannelingWings")) + { + SetPersistantLocalInt(oPC, "ChannelingWings", FALSE); + SetCreatureWingType(CREATURE_WING_TYPE_NONE, oPC); + } + } + + if(GetPRCSwitch(PRC_PNP_REST_HEALING)) + { + int nHP = GetLocalInt(oPC, "PnP_Rest_InitialHP"); + int nOldMax = GetLocalInt(oPC, "PnP_Rest_InitialMax"); + if(DEBUG) DoDebug("prc_rest: Finished HPs for " + DebugObject2Str(oPC)+"n/n/"+" nCurrent: "+IntToString(nHP)+" nMax: "+IntToString(nOldMax)); + //only heal HP if not undead and not a construct + if(MyPRCGetRacialType(oPC) != RACIAL_TYPE_UNDEAD && MyPRCGetRacialType(oPC) != RACIAL_TYPE_CONSTRUCT) + nHP = GetMaxHitPoints(oPC) - nOldMax + nHP + GetHitDice(oPC); + int nCurrentHP = GetCurrentHitPoints(oPC); + int nDamage = nCurrentHP-nHP; + //check its a positive number + if(nDamage > 0) + { + //DelayCommand(1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY), oPC)); + SetCurrentHitPoints(oPC, nCurrentHP - nDamage); + } + // We've finished rest, clean up + DeleteLocalInt(oPC, "PnP_Rest_InitialHP"); + DeleteLocalInt(oPC, "PnP_Rest_InitialMax"); + } + + int nSpellCount = GetPRCSwitch(PRC_DISABLE_SPELL_COUNT); + int i; + string sMessage; + for(i=1;i 0 || nRest < 0) + { + int nDelay = nRest * GetHitDice(oPC); + if (nRest == -1) nDelay = 24; + else if (nRest == -2) nDelay = 16; + + SetLocalInt(oPC, "RestTimer", TRUE); + DelayCommand(HoursToSeconds(nDelay), DeleteLocalInt(oPC, "RestTimer")); + DelayCommand(HoursToSeconds(nDelay), FloatingTextStringOnCreature("You may now rest again.", oPC, FALSE)); + FloatingTextStringOnCreature("You may rest again in "+IntToString(nDelay)+" hours.", oPC, FALSE); + } + + // Execute scripts hooked to this event for the player triggering it + ExecuteAllScriptsHookedToEvent(oPC, EVENT_ONPLAYERREST_FINISHED); +} + +void RestStarted(object oPC) +{ + if(DEBUG) DoDebug("prc_rest: Rest started for " + DebugObject2Str(oPC)); + + // Scrying cleanup + if (GetIsScrying(oPC)) + { + object oCopy = GetLocalObject(oPC, "Scry_Copy"); + DoScryEnd(oPC, oCopy); + } + + int nRest = GetPRCSwitch(PRC_PNP_REST_LIMIT); + if(nRest > 0 || nRest < 0) + { + int nDelay = nRest * GetHitDice(oPC); + if (nRest == -1) nDelay = 24; + else if (nRest == -2) nDelay = 16; + + if(GetLocalInt(oPC, "RestTimer")) + { + AssignCommand(oPC, ClearAllActions()); + FloatingTextStringOnCreature("You may not rest yet. You may rest once every "+IntToString(nDelay)+" hours.", oPC, FALSE); + } + } + + // Clean up Crown of Might + object oCrown = GetItemPossessedBy(oPC, "prc_crown_might"); + if (GetIsObjectValid(oCrown)) DestroyObject(oCrown); + oCrown = GetItemPossessedBy(oPC, "prc_crown_prot"); + if (GetIsObjectValid(oCrown)) DestroyObject(oCrown); + + if (GetLevelByClass(CLASS_TYPE_DRUNKEN_MASTER, oPC)){ + SetLocalInt(oPC, "DRUNKEN_MASTER_IS_IN_DRUNKEN_RAGE", 0); + SetLocalInt(oPC, "DRUNKEN_MASTER_IS_DRUNK_LIKE_A_DEMON", 0); + } + /* Left here in case the multisummon trick is ever broken. In that case, use this to make Astral Constructs get unsummoned properly + if(GetHasFeat(whatever feat determines if the PC can manifest Astral Construct here)){ + int i = 1; + object oCheck = GetHenchman(oPC, i); + while(oCheck != OBJECT_INVALID){ + if(GetStringLeft(GetTag(oCheck), 14) == "psi_astral_con") + DoDespawn(oCheck); + i++; + oCheck = GetHenchman(oPC, i); + } + } + */ + + if (GetIsPC(oPC)) SetLocalInt(oPC, "PnP_Rest_InitialHP", GetCurrentHitPoints(oPC)); + SetLocalInt(oPC, "PnP_Rest_InitialMax", GetMaxHitPoints(oPC)); + if(DEBUG) DoDebug("prc_rest: HPs for " + DebugObject2Str(oPC)+"n/n/"+" nCurrent: "+IntToString(GetCurrentHitPoints(oPC))+" nMax: "+IntToString(GetMaxHitPoints(oPC))); + // Remove Psionic Focus + if(GetIsPsionicallyFocused(oPC)) + { + LosePsionicFocus(oPC); + } + DeleteLocalInt(oPC, PRC_SPELL_CHARGE_COUNT); + DeleteLocalInt(oPC, PRC_SPELL_CHARGE_SPELLID); + DeleteLocalObject(oPC, PRC_SPELL_CONC_TARGET); + if(GetLocalInt(oPC, PRC_SPELL_HOLD)) FloatingTextStringOnCreature("*Normal Casting*", oPC); + DeleteLocalInt(oPC, PRC_SPELL_HOLD); + DeleteLocalInt(oPC, PRC_SPELL_METAMAGIC); + DeleteLocalManifestation(oPC, PRC_POWER_HOLD_MANIFESTATION); + DeleteLocalMystery(oPC, "MYST_HOLD_MYST"); + // run the prereq check here + ExecuteScript("prc_prereq", oPC); + // Execute scripts hooked to this event for the player triggering it + ExecuteAllScriptsHookedToEvent(oPC, EVENT_ONPLAYERREST_STARTED); +} + +void main() +{ + object oPC = GetLastBeingRested(); + + if(DEBUG) DoDebug("prc_rest: Running for " + DebugObject2Str(oPC)); + if(DEBUG) DoDebug("prc_rest Void Main: HPs for " + DebugObject2Str(oPC) +" nCurrent: "+IntToString(GetCurrentHitPoints(oPC))); + + // return here for DMs as they don't need all this stuff + if(GetIsDM(oPC)) + return; + + //rest kits + if(GetPRCSwitch(PRC_SUPPLY_BASED_REST)) + ExecuteScript("sbr_onrest", OBJECT_SELF); + + // Handle the PRCForceRest() wrapper + if(GetLocalInt(oPC, "PRC_ForceRested")) + { + if(DEBUG) DoDebug("prc_rest: Handling forced rest"); + RestStarted(oPC); + // A minor delay to break the script association and to lessen TMI chances + DelayCommand(0.1f, RestFinished(oPC)); + // Clear the flag + DeleteLocalInt(oPC, "PRC_ForceRested"); + } + else + { + switch(MyGetLastRestEventType()){ + case REST_EVENTTYPE_REST_CANCELLED:{ + RestCancelled(oPC); + break; + } + case REST_EVENTTYPE_REST_STARTED:{ + RestStarted(oPC); + break; + } + case REST_EVENTTYPE_REST_FINISHED:{ + RestFinished(oPC); + break; + } + case REST_EVENTTYPE_REST_INVALID:{ + break; + } + } + } +} diff --git a/nwnds_scripts/tob_jpm_spellcon.ncs b/nwnds_scripts/tob_jpm_spellcon.ncs new file mode 100644 index 0000000000000000000000000000000000000000..5a1ff11836fd435a60d742e6de94e3d2fa958843 GIT binary patch literal 15153 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 literal 0 HcmV?d00001 diff --git a/nwnds_scripts/tob_jpm_spellcon.nss b/nwnds_scripts/tob_jpm_spellcon.nss new file mode 100644 index 000000000..5cc78e1b3 --- /dev/null +++ b/nwnds_scripts/tob_jpm_spellcon.nss @@ -0,0 +1,305 @@ +//::////////////////////////////////////////////// +//:: Spell selection conversation for the Jade Phoenix Mage's abilities +//:: tob_jpm_spellconv.nss +//::////////////////////////////////////////////// +/** @file + Spell selection for Jade Phoenix Mage's abilities + Handles the dynamic convo *and* the quickselects + + @author Stratovaris + @date Created - yyyy.mm.dd +*/ +//::////////////////////////////////////////////// +//::////////////////////////////////////////////// + +#include "prc_spell_const" +#include "inc_dynconv" +#include "inc_newspellbook" +////#include "prc_alterations" + + +#include "prc_inc_castlvl" +/* Constant defintions */ +const int STAGE_ENTRY = 0; +const int STAGE_SLOT = 1; +const int STAGE_LVL0 = 10; +const int STAGE_LVL9 = 20; + +void PopulateList(object oPC, int nLevel, int iClass, int nChoice) +{ + if(!GetLocalInt(oPC, "DynConv_Waiting")) + return; + + //SendMessageToPC(oPC, "*Tick* *" + IntToString(iClass) + "*"); + + int nClass = GetClassByPosition(iClass); + if(GetIsArcaneClass(nClass)) + { + int i = 0, MaxValue = 0, nSpellID; + if(nClass == CLASS_TYPE_WIZARD + || nClass == CLASS_TYPE_DEFILER + || (nClass == CLASS_TYPE_SORCERER && GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK))) + { + string sFile = "cls_spell_sorc"; + object oToken = GetObjectByTag("SpellLvl_9_Level_" + IntToString(nLevel)); + MaxValue = array_get_size(oToken, "Lkup"); + //DoDebug("JPM PopulateList: nClass = "+IntToString(nClass)); + //DoDebug("JPM PopulateList: nLevel = "+IntToString(nLevel)); + //DoDebug("JPM PopulateList: MaxValue = "+IntToString(MaxValue)); + while(i < MaxValue) + { + nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", array_get_int(oToken, "Lkup", i))); + if(GetHasSpell(nSpellID, oPC)) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice), -1); + nChoice++; + } + i++; + } + } + else if(nClass == CLASS_TYPE_BARD && GetPRCSwitch(PRC_BARD_DISALLOW_NEWSPELLBOOK)) + { + string sFile = "cls_spell_bard"; + object oToken = GetObjectByTag("SpellLvl_1_Level_" + IntToString(nLevel)); + MaxValue = array_get_size(oToken, "Lkup"); + //DoDebug("JPM PopulateList: MaxValue = "+IntToString(MaxValue)); + while(i < MaxValue) + { + nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", array_get_int(oToken, "Lkup", i))); + if(GetHasSpell(nSpellID, oPC)) + { + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice), nSpellID); + SetLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice), -1); + nChoice++; + } + i++; + } + } + else + { + string sFile = GetFileForClass(nClass); + string sArray = "NewSpellbookMem_" + IntToString(nClass); + // if we ever add another arcane caster with prepared spellbook + // uncomment all following lines + //int nSpellbookType = GetSpellbookTypeForClass(nClass); + //if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS) + { + int nCount = persistant_array_get_int(oPC, sArray, nLevel); + //DoDebug("JPM PopulateList: nCount = "+IntToString(nCount)); + if(nCount) + { + MaxValue = persistant_array_get_size(oPC, "Spellbook"+IntToString(nClass)); + while(i < MaxValue) + { + int nNewSpellbookID = persistant_array_get_int(oPC, "Spellbook"+IntToString(nClass), i); + if(nLevel == StringToInt(Get2DACache(sFile, "Level", nNewSpellbookID)) + && GetHasFeat(StringToInt(Get2DACache(sFile, "FeatID", nNewSpellbookID)), oPC)) + { + int nRealSpell = StringToInt(Get2DACache(sFile, "SpellID", nNewSpellbookID)); + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice), nLevel); + SetLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "JPM_CLASS_ARRAY_" + IntToString(nChoice), sArray); + nChoice++; + } + i++; + } + } + } + /*else if(nSpellbookType == SPELLBOOK_TYPE_PREPARED) + { + string sArrayIDX = "SpellbookIDX" + IntToString(nLevel) + "_" + IntToString(nClass); + MaxValue = persistant_array_get_size(oPC, sArrayIDX); + while(i < MaxValue) + { + int nNewSpellbookID = persistant_array_get_int(oPC, sArrayIDX, i); + int nCount = persistant_array_get_int(oPC, sArray, nNewSpellbookID); + if(nCount + && GetHasFeat(StringToInt(Get2DACache(sFile, "FeatID", nNewSpellbookID)), oPC)) + { + int nRealSpell = StringToInt(Get2DACache(sFile, "RealSpellID", nNewSpellbookID)); + string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nRealSpell))); + AddChoice(sName, nChoice, oPC); + SetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice), nNewSpellbookID); + SetLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "JPM_CLASS_ARRAY_" + IntToString(nChoice), sArray); + nChoice++; + } + i++; + } + }*/ + } + } + + if(iClass == 3) + { + SetDefaultTokens(); + DeleteLocalInt(oPC, "DynConv_Waiting"); + FloatingTextStringOnCreature("*Done*", oPC, FALSE); + return; + } + + DelayCommand(0.01, PopulateList(oPC, nLevel, iClass + 1, nChoice)); +} + +void main() +{ + object oPC = GetPCSpeaker(); + int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE); + int nStage = GetStage(oPC); + + // Check which of the conversation scripts called the scripts + if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort + return; + + // Check if this stage is marked as already set up + // This stops list duplication when scrolling + //SendMessageToPC(OBJECT_SELF, "prc_jpm_spellconv:" + IntToString(nID) + " nVal:"+ IntToString(nValue)); + /* Get the value of the local variable set by the conversation script calling + * this script. Values: + * DYNCONV_ABORTED Conversation aborted + * DYNCONV_EXITED Conversation exited via the exit node + * DYNCONV_SETUP_STAGE System's reply turn + * 0 Error - something else called the script + * Other The user made a choice + */ + // The stage is used to determine the active conversation node. + // 0 is the entry node. + + + if(nValue == DYNCONV_SETUP_STAGE) + { + // Check if this stage is marked as already set up + // This stops list duplication when scrolling + if(!GetIsStageSetUp(nStage, oPC)) + { + // variable named nStage determines the current conversation node + // Function SetHeader to set the text displayed to the PC + // Function AddChoice to add a response option for the PC. The responses are show in order added + if(nStage == STAGE_ENTRY) + { + SetHeader("Select Spell Level:"); + AddChoice(GetStringByStrRef(690), 1, oPC);//"Level 1" + AddChoice(GetStringByStrRef(725), 2, oPC);//"Level 2" + AddChoice(GetStringByStrRef(687), 3, oPC);//"Level 3" + AddChoice(GetStringByStrRef(684), 4, oPC);//"Level 4" + AddChoice(GetStringByStrRef(1026), 5, oPC);//"Level 5" + AddChoice(GetStringByStrRef(1014), 6, oPC);//"Level 6" + AddChoice(GetStringByStrRef(2214), 7, oPC);//"Level 7" + AddChoice(GetStringByStrRef(2215), 8, oPC);//"Level 8" + AddChoice(GetStringByStrRef(2216), 9, oPC);//"Level 9" + MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + else if (nStage >= STAGE_LVL0 && nStage <= STAGE_LVL9) + { + // Set the header + SetHeader("Select Spell:"); + int nLevel = nStage - STAGE_LVL0; + SetLocalInt(oPC, "DynConv_Waiting", TRUE); + + PopulateList(oPC, nLevel, 1, 1); + + MarkStageSetUp(nStage, oPC); + } + else if (nStage = STAGE_SLOT) + { + SetHeader("Select QuickSlot:"); + AddChoice("Slot 1", 1, oPC); + AddChoice("Slot 2", 2, oPC); + AddChoice("Slot 3", 3, oPC); + AddChoice("Slot 4", 4, oPC); + MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + //add more stages for more nodes with Else If clauses + } + // Do token setup + SetupTokens(); + } + // End of conversation cleanup + else if(nValue == DYNCONV_EXITED) + { + int nChoice = 1; + while(GetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice))) + { + DeleteLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalString(oPC, "JPM_CLASS_ARRAY_" + IntToString(nChoice)); + nChoice++; + } + DeleteLocalInt(oPC, "JPM_SPELL_ID"); + DeleteLocalInt(oPC, "JPM_REAL_SPELL_ID"); + DeleteLocalString(oPC, "JPM_CLASS_ARRAY_ID"); + DeleteLocalInt(oPC, "JPM_SPELL_LEVEL_CHOICE"); + } + // Abort conversation cleanup. + // NOTE: This section is only run when the conversation is aborted + // while aborting is allowed. When it isn't, the dynconvo infrastructure + // handles restoring the conversation in a transparent manner + else if(nValue == DYNCONV_ABORTED) + { + int nChoice = 1; + while (GetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice))) + { + DeleteLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + DeleteLocalString(oPC, "JPM_CLASS_ARRAY_" + IntToString(nChoice)); + nChoice++; + } + DeleteLocalInt(oPC, "JPM_SPELL_ID"); + DeleteLocalInt(oPC, "JPM_REAL_SPELL_ID"); + DeleteLocalString(oPC, "JPM_CLASS_ARRAY_ID"); + DeleteLocalInt(oPC, "JPM_SPELL_LEVEL_CHOICE"); + } + // Handle PC responses + else + { + // variable named nChoice is the value of the player's choice as stored when building the choice list + // variable named nStage determines the current conversation node + int nChoice = GetChoice(oPC); + if(nStage == STAGE_ENTRY) + { + int nLevel = nChoice; + SetLocalInt(oPC, "JPM_SPELL_LEVEL_CHOICE", nLevel); + nStage = STAGE_LVL0 + nLevel; + // Move to another stage based on response, for example + //nStage = STAGE_QUUX; + } + else if (nStage >= STAGE_LVL0 && nStage <= STAGE_LVL9) + { + MarkStageNotSetUp(nStage, oPC); + int nSpell = GetLocalInt(oPC, "JPM_SPELL_CHOICE_" + IntToString(nChoice)); + int nRealSpell = GetLocalInt(oPC, "JPM_REAL_SPELL_CHOICE_" + IntToString(nChoice)); + string sArray = GetLocalString(oPC, "JPM_CLASS_ARRAY_" + IntToString(nChoice)); + + SetLocalInt(oPC, "JPM_SPELL_ID", nSpell); + SetLocalInt(oPC, "JPM_REAL_SPELL_ID", nRealSpell); + SetLocalString(oPC, "JPM_CLASS_ARRAY_ID", sArray); + + nStage = STAGE_SLOT; + } + else if (nStage = STAGE_SLOT) + { + int nSpell = GetLocalInt(oPC, "JPM_SPELL_ID"); + int nRealSpell = GetLocalInt(oPC, "JPM_REAL_SPELL_ID"); + string sArray = GetLocalString(oPC, "JPM_CLASS_ARRAY_ID"); + int nLevel = GetLocalInt(oPC, "JPM_SPELL_LEVEL_CHOICE"); + + if(DEBUG) DoDebug("tob_jpm_spellconv: nSpell value = " + IntToString(nSpell)); + SetLocalInt(oPC, "JPM_SPELL_QUICK" + IntToString(nChoice), nSpell); + SetLocalInt(oPC, "JPM_REAL_SPELL_QUICK" + IntToString(nChoice), nRealSpell); + SetLocalString(oPC, "JPM_SPELL_QUICK" + IntToString(nChoice), sArray); + SetLocalInt(oPC, "JPM_SPELL_QUICK" + IntToString(nChoice) + "LVL", nLevel); + nStage = STAGE_ENTRY; + } + // Store the stage value. If it has been changed, this clears out the choices + SetStage(nStage, oPC); + } +} \ No newline at end of file diff --git a/nwnds_scripts/x2_pc_umdcheck.ncs b/nwnds_scripts/x2_pc_umdcheck.ncs new file mode 100644 index 0000000000000000000000000000000000000000..e508398b5993899cfa6a5438b3cff93b9d836808 GIT binary patch literal 5289 zcmb7IU2Kz882-MmKkI&A1L_ap#>s{X9Ux)?$sB{N?Vwt=rQH}tVpH31v)Z+!?S_z; z5KK(G@B%Nn(F?pV;l{Xlr`{PZy!I#If(wk3kbp>JF~j+s_x(=$owX~Iknd~H`*Ys+ zeV+F{ryC0=#p#z192_x>;FmoH{sn|#c`T3DXS7Zv!l_7fWa@+znAc5nb#-;w@a{D5 zUV)0oFpeAYX_x`gL~1pa2AWE{no31e>G7u0OUac!BR#U0BsWi}3+SODl>ZBoq zK#TMngvt$JcqB?I2JkZ;7W#0G~!3Qs4VauZJSq#}w2(%YD6z?9qwAZ}~Yevc9Y9 zt4NS-$ZX(P)o+;`zv*^dGc`XkDVEneL|tUMgB@-MmWN!RwPa-epP#h7=cZ=uWTodr zJxu6GpDn+wm8u=-eV=!3ZLN#?u0xyqGHp-Ry|3~>8E^9$W{=g&iGY3NsGC%fIH?4n zG7S~KpykF&JsVNlSygHtuchPft48cII%5-wiB$5OozKS#S^Ir-Kxfu2r!u9PN~$cE z%d&3m*JK~H_t8Ed;qyo+6gqQgs%)Q1&*m}_dm)#x#h&SOsgNto?i~=L#rZ;36pG?p zsd&yVRW69RbS3i+gn~DVaQ46&j?bFGJ~YokW{pW0X%#mgxGN4!IR{x%pW%z!3w9nK z8b#iA2mY7X<(ipoY}3g=WdQ{UrMIZIly9h7FFE3^r+6SL9NXLCD`6*j^iL9QNxB{#R2w{2h7@!+<@+a>aL z-Brb_`wgqh>qSP0q51RJCFsc9`S}kjy6Dqu$1YS(^j3VA!}lf^)gU88OL5$$n4aaB zT+h4mAX_KIspfMeItR8nzEsdzd10KNP{x|$faXFvezNkaynnlX|!QZm;@@JeWGMn=4nuf zw{ykw>C%RCq{s)K7k|<%V>R zwTqUGYajn#+QU-2ZVIVc{*Y?(hMQQm(pfeq=o+l6tN;GV{3Yt?Zrms@SKC}(*n`zJ zk3||axN{Y(YjEej(T_e^=24{&mOJjiHTo}9>A%-S|5$dNX3k~N#kI`o{6pMb?*5f3 zl9vbt4|ziN;P=MkA)Q`S9UKqsTy$qN=#8pdH0X49C2IqdkDO+t^LFyC7aZyWxmr@@ z6t@yUqeZ-_eJ`%d4xZi#cag~wQ+~Hc{^U{;eEy&TE!La<%V<2lFR1ep9?9Nn7thOK zcv0;`t0*R|Ue;Fq&g#e7YKyb_skYkYtX|bt`<>Nm1ju&)+#k-{rCf#}anT+TeGaKF zQku_UN+4Zb_#uQX6X|?9n=3RBXQk&vx-e^(8c0VW4NT`Qrjo@{qn%%Pg51w2R5JrP zoqOR)hX$(3xZDupmla7n_~wLl^1*nWRj4BC*KjA%kwW4!8#*EBCTi}$ccY_^GSfZP z)A%8s`+Rf3PdhmlaNH(}=SNG$xrCk0J9kldys_rcuTdJpvnDn*Q^7vU8ce1&IzRlW zWF=jyI3k1#(R%ZRIqS4)uc``VQk_K&npI`V)6<F7S9O5csgB05rlWMZ>|b%_>fTO0V*Xm|5%bD^2~Wph=HB<;^8X>` zm2wI^ocmy4Fe7H5gZm9kJYoO`3hO$^BPa>ySbEOJ+h3NoL6_l}S%jA*6OVg*we-R` z1O}(8C)WBs^AzIpn}Sf)Ph0bK8JD*|T)~7m74+nu zT1=43Q<5_6N2atD6TiAHk5pRMa;RChiiPq45edsmsgP?@bFZ^XZLaQ$Dl2T|lmjc9 pc+_byHuzz3zt*~lyNmwz6vt1KR3bWgdN@J!mB;@P4>Ld*{{e9 literal 0 HcmV?d00001 diff --git a/nwnds_scripts/x2_pc_umdcheck.nss b/nwnds_scripts/x2_pc_umdcheck.nss new file mode 100644 index 000000000..f45bfaf95 --- /dev/null +++ b/nwnds_scripts/x2_pc_umdcheck.nss @@ -0,0 +1,163 @@ +//------------------------------------------------------------------------------ +/* +Use Magic Device Check. +Simple use magic device check to prevent abuse of +the engine level implementation of use magic device +This function is not supposed to mirror the 3E use +magic device mechanics. + +Returns TRUE if the Spell is allowed to be +cast, either because the character is allowed +to cast it or he has won the required UMD check + +returns TRUE if + ... spell not cast by an item + ... item is not a scroll (may be extended) + ... caster has levels in wiz, bard, sorc + ... caster is no rogue and has no UMD skill + ... caster has memorized this spell + ... the property corresponding to the spell does not exist (2da inconsistency) + + ... a UMD check against 25+InnateLevel of the spell is won + +Note: I am not using the effective level of the spell for DC calculation but + instead the lowest possible effective level. This is by design to allow + rogues to use most low level scrolls in the game (i.e. light scrolls have + an effective level 5 but a lowest effective level of 1 and we want low level + rogues to cast these spells..) + + Setting a Local Interger called X2_SWITCH_CLASSIC_UMD (TRUE) on the Module + will result in this function to return TRUE all the time + + User's can change this default implementation by modifing this file +*/ +//------------------------------------------------------------------------------ + +#include "prc_inc_spells" + +int DoCastingClassCheck(object oCaster, int nSpellID, int nClass) +{ + string sClass; + switch(nClass) + { + case CLASS_TYPE_CLERIC: sClass = "Cleric"; break; + case CLASS_TYPE_DRUID: sClass = "Druid"; break; + case CLASS_TYPE_PALADIN: sClass = "Paladin"; break; + case CLASS_TYPE_RANGER: sClass = "Ranger"; break; + case CLASS_TYPE_WIZARD: sClass = "Wiz_Sorc"; break; + case CLASS_TYPE_DEFILER: sClass = "Wiz_Sorc"; break; + } + if(sClass == "") + return RealSpellToSpellbookID(nClass, nSpellID) != -1; + else + return Get2DACache("Spells", sClass, nSpellID) != ""; +} + +int UMD_CheckCastingClass(object oCaster, int nSpellID) +{ + int i; + for(i = 1; i < 4; i++) + { + if(DoCastingClassCheck(oCaster, nSpellID, GetClassByPosition(i, oCaster))) + return TRUE; + } + return FALSE; +} + +int X2_UMD() +{ + if(!GetModuleSwitchValue(MODULE_SWITCH_ENABLE_UMD_SCROLLS)) + return TRUE; + + object oItem = PRCGetSpellCastItem(); + if(!GetIsObjectValid(oItem)) + return TRUE; // Spell not cast by item, UMD not required + + // ------------------------------------------------------------------------- + // Only Scrolls are subject to our default UMD Check + // ------------------------------------------------------------------------- + if(GetBaseItemType(oItem) != BASE_ITEM_SPELLSCROLL) + return TRUE; // spell not cast from a scroll + + // ------------------------------------------------------------------------- + // Ignore scrolls that have no use limitations (i.e. raise dead) + // ------------------------------------------------------------------------- + if(!IPGetHasUseLimitation(oItem)) + return TRUE; + + object oCaster = OBJECT_SELF; + int nSpellID = PRCGetSpellId(); + + // ------------------------------------------------------------------------- + // Check if caster has levels in class that can cast given spell + // ------------------------------------------------------------------------- + if(UMD_CheckCastingClass(oCaster, nSpellID)) + return TRUE; + + // ------------------------------------------------------------------------- + // If the caster used the item and has no UMD Skill and is not a rogue + // thus we assume he must be allowed to use it because the engine + // prevents people that are not capable of using an item from using it.... + // ------------------------------------------------------------------------- + if(!GetHasSkill(SKILL_USE_MAGIC_DEVICE, oCaster) + && !GetLevelByClass(CLASS_TYPE_ROGUE, oCaster) + && !GetLevelByClass(CLASS_TYPE_ASSASSIN, oCaster) + && !GetLevelByClass(CLASS_TYPE_SHADOWDANCER, oCaster)) + { + // --------------------------------------------------------------------- + //SpeakString("I have no UMD, thus I can cast the spell... "); + // --------------------------------------------------------------------- + return TRUE; + } + + if(Get2DACache("des_crft_spells", "IPRP_SpellIndex", nSpellID) == "") + { + WriteTimestampedLogEntry("***X2UseMagicDevice (Warning): Found no property matching SpellID "+ IntToString(nSpellID)); + return TRUE; + } + + // ------------------------------------------------------------------------- + //I am using des_crft_spells.2da Innate Level column here, not (as would be correct) + //the IPPR_Spells.2da InnateLvl column, because some of the scrolls in + //the game (i.e. light) would not be useable (DC 30+) + // ------------------------------------------------------------------------- + int nInnateLevel = StringToInt(Get2DACache("des_crft_spells","Level",nSpellID)); + int nSkill = SKILL_USE_MAGIC_DEVICE; + //int nSkillRanks = GetSkillRank(SKILL_USE_MAGIC_DEVICE, oCaster); + if(GetLevelByClass(CLASS_TYPE_ARTIFICER, oCaster)) + nInnateLevel -= 2; //only scrolls are being checked, and arti gets scribe scroll at level 1, this instead of +2 to skill + + // ------------------------------------------------------------------------- + // Base DC for casting a spell from a scroll is 25+SpellLevel + // We do not have a way to check for misshaps here but GetIsSkillSuccessful + // does not return the required information + // ------------------------------------------------------------------------- + if(GetPRCIsSkillSuccessful(oCaster, nSkill, 25+ nInnateLevel, (GetHasFeat(FEAT_DECEIVE_ITEM, oCaster) || GetHasFeat(FEAT_SKILL_MASTERY_ARTIFICER, oCaster)) ? 10 : -1)) + { + return TRUE; + } + else + { + effect ePuff = EffectVisualEffect(VFX_IMP_MAGIC_RESISTANCE_USE); + ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster); + return FALSE; + } +} + +void main() +{ + //-------------------------------------------------------------------------- + // Reset + //-------------------------------------------------------------------------- + if(GetLocalInt(GetModule(),"X2_L_STOP_EXPERTISE_ABUSE")) + { + SetActionMode(OBJECT_SELF, ACTION_MODE_EXPERTISE, FALSE); + SetActionMode(OBJECT_SELF, ACTION_MODE_IMPROVED_EXPERTISE, FALSE); + } + + //-------------------------------------------------------------------------- + // Do use magic device check + //-------------------------------------------------------------------------- + int nRet = X2_UMD(); + SetExecutedScriptReturnValue(nRet); +} \ No newline at end of file diff --git a/nwnds_scripts/x2_s0_blckblde.ncs b/nwnds_scripts/x2_s0_blckblde.ncs new file mode 100644 index 0000000000000000000000000000000000000000..9a93f01184ff630962dbc092ea1e2cfcc44f4fa2 GIT binary patch literal 187404 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�r{> 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 UqpgV=19) + nAttackResult = 2; + int nDamage = d12(2); + if(nAttackResult == 2) + nDamage *=2; //critical doubles damage + //its magical damage because the description is unclear + AssignCommand(oSummon, ApplyEffectToObject( + DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDamage, + DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE), oTarget)); + } + if(nAttackResult == 2) + { + //critical hit + //cast disintegrate + int nLevel = GetLocalInt(oSummon, "BBoD_Level"); + + SetLocalInt(oSummon, PRC_CASTERLEVEL_OVERRIDE, nLevel); + // Make sure this variable gets deleted as quickly as possible in case it's added in error. + AssignCommand(oSummon, DelayCommand(1.0, DeleteLocalInt(oSummon, PRC_CASTERLEVEL_OVERRIDE))); + + // Make SR check + if (!PRCDoResistSpell(OBJECT_SELF, oTarget)) + { + // Generate the RTA beam. + AssignCommand(oSummon, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, + EffectBeam(VFX_BEAM_DISINTEGRATE, OBJECT_SELF, BODY_NODE_HAND), oTarget, 1.0,FALSE)); + + // Fort save or die time, but we implement death by doing massive damage + // since disintegrate works on constructs, undead, etc. At some point EffectDie() + // should be tested to see if it works on non-living targets, and if it does it should + // be used instead. + // Test done. Result: It does kill them. + int nDamage = 9999; + if (PRCMySavingThrow(SAVING_THROW_FORT, oTarget, PRCGetSaveDC(oTarget,OBJECT_SELF), SAVING_THROW_TYPE_SPELL)) + { + nDamage = PRCGetMetaMagicDamage(DAMAGE_TYPE_MAGICAL, 1 == nAttackResult ? 5 : 10, 6); + } + else + { + // If FB passes saving throw it survives, else it dies + //DeathlessFrenzyCheck(oTarget); + + // For targets with > 9999 HP. Uncomment if you have such in your module and would like Disintegrate + // to be sure to blast them + //DelayCommand(0.30, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oTarget)); + } + + // Apply damage effect and VFX impact, and if the target is dead then apply + // the fancy rune circle too. + if (nDamage >= GetCurrentHitPoints (oTarget)) + DelayCommand(0.25, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_2), oTarget)); + //DelayCommand(0.25, SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_MAGICAL), oTarget)); + DelayCommand(0.25, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MAGBLUE), oTarget)); + ApplyTouchAttackDamage(OBJECT_SELF, oTarget, nAttackResult, nDamage, DAMAGE_TYPE_MAGICAL); + } + + } + } + if(GetIsObjectValid(oSummon)) + DelayCommand(6.0, DoPnPAttack(oSummon)); +} + +//Creates the weapon that the creature will be using. +void spellsCreateItemForSummoned() +{ + //Declare major variables + int nStat; + + // cast from scroll, we just assume +5 ability modifier + if (GetSpellCastItem() != OBJECT_INVALID) + { + nStat = 5; + } + else + { + int nClass = PRCGetLastSpellCastClass(); + int nLevel = GetLevelByClass(nClass); + + int nStat; + + int nCha = GetAbilityModifier(ABILITY_CHARISMA,OBJECT_SELF); + int nInt = GetAbilityModifier(ABILITY_INTELLIGENCE,OBJECT_SELF); + + if (nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_DEFILER) + { + nStat = nInt; + } + else + { + nStat = nCha; + } + + if (nStat >20) + { + nStat =20; + } + + if (nStat <1) + { + nStat = 0; + } + } + int i = 1; + object oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF, i); + while(GetIsObjectValid(oSummon)) + { + oSummon = GetAssociate(ASSOCIATE_TYPE_SUMMONED, OBJECT_SELF, i); + i++; + } + // Make the blade require concentration + SetLocalInt(oSummon,"X2_L_CREATURE_NEEDS_CONCENTRATION",TRUE); + object oWeapon; + //Create item on the creature, epuip it and add properties. + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oSummon); + if (nStat > 0 && !GetPRCSwitch(PRC_PNP_BLACK_BLADE_OF_DISASTER)) + { + IPSetWeaponEnhancementBonus(oWeapon, nStat); + } + SetDroppableFlag(oWeapon, FALSE); + SetPlotFlag (oSummon,TRUE); + + if(GetPRCSwitch(PRC_PNP_BLACK_BLADE_OF_DISASTER)) + { + itemproperty ipTest = GetFirstItemProperty(oWeapon); + while(GetIsItemPropertyValid(ipTest)) + { + ipTest = GetNextItemProperty(oWeapon); + } + itemproperty ipNoDam = ItemPropertyNoDamage(); + AddItemProperty(DURATION_TYPE_PERMANENT, ipNoDam, oWeapon); + itemproperty ipVFX = ItemPropertyVisualEffect(ITEM_VISUAL_ELECTRICAL); + AddItemProperty(DURATION_TYPE_PERMANENT, ipVFX, oWeapon); + //store the level on the summon + SetLocalInt(oSummon, "BBoD_Level", GetLocalInt(OBJECT_SELF, "BBoD_Level")); + DeleteLocalInt(OBJECT_SELF, "BBoD_Level"); + //attacks are handled through a pseudoHB + DoPnPAttack(oSummon); + } +} + +void main() +{ +DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR"); +SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_CONJURATION); +/* + Spellcast Hook Code + Added 2003-07-07 by Georg Zoeller + If you want to make changes to all spells, + check x2_inc_spellhook.nss to find out more + +*/ + + if (!X2PreSpellCastCode()) + { + // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell + return; + } + +// End of Spell Cast Hook + + + //Declare major variables + int nMetaMagic = PRCGetMetaMagicFeat(); + int nDuration = PRCGetCasterLevel(OBJECT_SELF); + effect eSummon = EffectSummonCreature("x2_s_bblade"); + effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); + //Make metamagic check for extend + if ((nMetaMagic & METAMAGIC_EXTEND)) + nDuration = nDuration *2;//Duration is +100% + //Apply the VFX impact and summon effect + MultisummonPreSummon(); + ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, PRCGetSpellTargetLocation()); + + float fDuration = RoundsToSeconds(nDuration); + if(GetPRCSwitch(PRC_SUMMON_ROUND_PER_LEVEL)) + fDuration = RoundsToSeconds(nDuration*GetPRCSwitch(PRC_SUMMON_ROUND_PER_LEVEL)); + ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, PRCGetSpellTargetLocation(), fDuration); + DelayCommand(1.5, spellsCreateItemForSummoned()); + if(GetPRCSwitch(PRC_PNP_BLACK_BLADE_OF_DISASTER)) + { + SetLocalInt(OBJECT_SELF, "BBoD_Level", PRCGetCasterLevel(OBJECT_SELF)); + } + +DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR"); +// Erasing the variable used to store the spell's spell school +}