From c86a6645b01d8adbc7d058f332fe07da73da447c Mon Sep 17 00:00:00 2001 From: Jaysyn904 <68194417+Jaysyn904@users.noreply.github.com> Date: Sat, 23 Aug 2025 00:55:04 -0400 Subject: [PATCH] 2025/08/23 Early update. A few more tweaks for Create Infusion. Ooze isn't a player race. --- nwn/nwnprc/trunk/2das/classes.2da | 2 +- nwn/nwnprc/trunk/gfx/iit_herb_254.tga | Bin 0 -> 4635 bytes nwn/nwnprc/trunk/gfx/iit_infusion_000.tga | Bin 0 -> 4635 bytes nwn/nwnprc/trunk/include/inc_newspellbook.nss | 134 +++++++++++++++--- nwn/nwnprc/trunk/include/prc_inc_spells.nss | 6 +- nwn/nwnprc/trunk/include/prc_x2_craft.nss | 8 +- 6 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 nwn/nwnprc/trunk/gfx/iit_herb_254.tga create mode 100644 nwn/nwnprc/trunk/gfx/iit_infusion_000.tga diff --git a/nwn/nwnprc/trunk/2das/classes.2da b/nwn/nwnprc/trunk/2das/classes.2da index f6a9cc0a..4af84abc 100644 --- a/nwn/nwnprc/trunk/2das/classes.2da +++ b/nwn/nwnprc/trunk/2das/classes.2da @@ -39,7 +39,7 @@ 35 Shifter 112222 9026 9027 9028 9029 IR_SHIFTR 8 CLS_ATK_2 CLS_FEAT_SHIFTR CLS_SAVTHR_WILD CLS_SKILL_SHIFTR CLS_BFEAT_SHIFTR 4 **** **** 1 0 12 16 14 8 14 12 WIS 0X00 0X0 0 CLASS_TYPE_SHIFTER 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_SHIFTR 40 0 0 0 10 108 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 36 Dwarven_Defender 112223 76418 76419 76420 76422 IR_DWDEF 12 CLS_ATK_1 CLS_FEAT_DWDEF CLS_SAVTHR_CLER CLS_SKILL_DWDEF CLS_BFEAT_DWDEF 2 **** **** 1 0 16 8 15 14 10 12 STR 0X05 0X1 0 CLASS_TYPE_DWARVEN_DEFENDER 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_DWDEF 40 0 0 0 10 89 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 37 Dragon_Disciple 112224 16832127 16832128 16832129 16832130 IR_DRAGOND 6 CLS_ATK_2 CLS_FEAT_DRADIS CLS_SAVTHR_CLER CLS_SKILL_DRADIS CLS_BFEAT_DRADIS 2 **** **** 1 0 14 8 14 16 10 14 STR 0X00 0X0 0 CLASS_TYPE_DRAGON_DISCIPLE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_DRADIS 40 0 0 0 10 111 0 cls_stat_dradis **** **** **** **** **** **** **** **** **** **** **** **** **** **** -38 Ooze 112225 84438 84438 84437 8154 IR_CLERIC 10 CLS_ATK_2 CLS_FEAT_CLER CLS_SAVTHR_CLER CLS_SKILL_CLER CLS_BFEAT_CLER 0 **** **** 1 0 14 8 14 16 10 14 STR 0X00 0X0 0 CLASS_TYPE_OOZE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_OOZE 0 0 0 0 -1 75 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** +38 Ooze 112225 84438 84438 84437 8154 IR_CLERIC 10 CLS_ATK_2 CLS_FEAT_CLER CLS_SAVTHR_CLER CLS_SKILL_CLER CLS_BFEAT_CLER 0 **** **** 0 0 14 8 14 16 10 14 STR 0X00 0X0 0 CLASS_TYPE_OOZE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_OOZE 0 0 0 0 -1 75 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 39 Eye_of_Gruumsh 16790665 16824294 16824295 16824296 16824297 IR_GRUUMSH 12 CLS_ATK_1 CLS_FEAT_EOG CLS_SAVTHR_BARB CLS_SKILL_EOG CLS_BFEAT_EOG 2 **** **** 1 0 16 14 14 14 10 8 STR 0X0A 0X3 0 CLASS_TYPE_PRC_EYE_OF_GRUUMSH 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_EOG 40 0 0 0 10 17 0 cls_stat_eog **** **** **** **** **** **** **** **** **** **** **** **** **** **** 40 Shou_Disciple 16790649 16823346 16823347 16823348 16823349 IR_SHOUDISC 10 CLS_ATK_1 CLS_FEAT_SHOU CLS_SAVTHR_WILD CLS_SKILL_SHOU CLS_BFEAT_SHOU 2 **** **** 1 0 12 16 14 8 14 12 DEX 0X00 0X0 0 CLASS_TYPE_SHOU 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_SHOU 5 0 0 0 5 4 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 41 Purple_Dragon_Knight 112226 111710 111711 111712 111713 IR_PDK 10 CLS_ATK_1 CLS_FEAT_PDK CLS_SAVTHR_FIGHT CLS_SKILL_PDK CLS_BFEAT_PDK 2 **** **** 1 0 12 16 14 8 14 12 STR 0X14 0X3 0 CLASS_TYPE_PDK 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CLS_PRES_PDK 5 0 0 0 5 131 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** diff --git a/nwn/nwnprc/trunk/gfx/iit_herb_254.tga b/nwn/nwnprc/trunk/gfx/iit_herb_254.tga new file mode 100644 index 0000000000000000000000000000000000000000..796a6323b263ce4d5100c63cdd6d4eec7ecaf734 GIT binary patch literal 4635 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 literal 0 HcmV?d00001 diff --git a/nwn/nwnprc/trunk/gfx/iit_infusion_000.tga b/nwn/nwnprc/trunk/gfx/iit_infusion_000.tga new file mode 100644 index 0000000000000000000000000000000000000000..796a6323b263ce4d5100c63cdd6d4eec7ecaf734 GIT binary patch literal 4635 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 literal 0 HcmV?d00001 diff --git a/nwn/nwnprc/trunk/include/inc_newspellbook.nss b/nwn/nwnprc/trunk/include/inc_newspellbook.nss index 12655813..542e2d50 100644 --- a/nwn/nwnprc/trunk/include/inc_newspellbook.nss +++ b/nwn/nwnprc/trunk/include/inc_newspellbook.nss @@ -8,7 +8,7 @@ Make cls_spcr_*.2da Make blank cls_spell_*.2da Add cls_spgn_*.2da to classes.2da Add class entry in prc_classes.2da -Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level +Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level (not needed for NWN:EE) Add class to PRCGetSpellSaveDC() in prc_add_spell_dc Add class to GetSpellbookTypeForClass() below Add class to GetAbilityScoreForClass() below @@ -580,7 +580,79 @@ int bKnowsAllClassSpells(int nClass) return TRUE; } + int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC) +{ + // If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either + if(!GetSlotCount(nLevel, nSpellLevel, GetAbilityScoreForClass(nClass, oPC), nClass)) + { + if(DEBUG) DoDebug("GetSpellKnownMaxCount: No slots available for " + IntToString(nClass) + " level " + IntToString(nLevel) + " circle " + IntToString(nSpellLevel)); + return 0; + } + + int nKnown; + string sFile = Get2DACache("classes", "SpellKnownTable", nClass); + string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1); + + if(DEBUG) + { + DoDebug("GetSpellKnownMaxCount Details:"); + DoDebug("- Class: " + IntToString(nClass)); + DoDebug("- Passed Level: " + IntToString(nLevel)); + DoDebug("- Base Class Level: " + IntToString(GetLevelByClass(nClass, oPC))); + DoDebug("- Effective Level: " + IntToString(GetSpellslotLevel(nClass, oPC))); + DoDebug("- Spell Level: " + IntToString(nSpellLevel)); + DoDebug("- SpellKnownTable: " + sFile); + DoDebug("- MaxKnown from 2DA: " + sKnown); + } + + if(sKnown == "") + { + nKnown = -1; + if(DEBUG) DoDebug("GetSpellKnownMaxCount: Problem getting known numbers"); + } + else + nKnown = StringToInt(sKnown); + + if(nKnown == -1) + return 0; + + // COMPLETELY REWROTE THIS SECTION + // Bard and Sorcerer logic for prestige class advancement + if(nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_BARD) + { + int baseClassLevel = GetLevelByClass(nClass, oPC); + int effectiveLevel = GetSpellslotLevel(nClass, oPC); + + // Debug the values we're checking + if(DEBUG) + { + DoDebug("Spont caster check - Base level: " + IntToString(baseClassLevel) + + ", Effective level: " + IntToString(effectiveLevel)); + } + + // If they have prestige class advancement OR special feats, they should get spells + if(effectiveLevel > baseClassLevel || + GetHasFeat(FEAT_DRACONIC_GRACE, oPC) || + GetHasFeat(FEAT_DRACONIC_BREATH, oPC)) + { + // Allow them to get spells - do nothing here, return nKnown at the end + if(DEBUG) DoDebug("Spontaneous caster eligible for new spells"); + } + else + { + // No advancement, no special feats - no new spells + if(DEBUG) DoDebug("Spontaneous caster NOT eligible for new spells"); + return 0; + } + } + + if(DEBUG) DoDebug("Final spell known count: " + IntToString(nKnown)); + return nKnown; +} + + +/* int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC) { // If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either // @todo Check rules. There might be cases where this doesn't hold @@ -588,22 +660,9 @@ int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC) return 0; int nKnown; string sFile; - // Bioware casters use their classes.2da-specified tables - /*if( nClass == CLASS_TYPE_WIZARD - || nClass == CLASS_TYPE_SORCERER - || nClass == CLASS_TYPE_BARD - || nClass == CLASS_TYPE_CLERIC - || nClass == CLASS_TYPE_DRUID - || nClass == CLASS_TYPE_PALADIN - || nClass == CLASS_TYPE_RANGER) - {*/ - sFile = Get2DACache("classes", "SpellKnownTable", nClass); - /*} - else - { - sFile = Get2DACache("classes", "FeatsTable", nClass); - sFile = "cls_spkn" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061231 - }*/ + + sFile = Get2DACache("classes", "SpellKnownTable", nClass); + string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1); if(DEBUG) DoDebug("GetSpellKnownMaxCount(" + IntToString(nLevel) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ", " + GetName(oPC) + ") = " + sKnown); @@ -626,6 +685,7 @@ int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC) } return nKnown; } + */ int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass) { @@ -693,6 +753,44 @@ int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass) } int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass) +{ + // Get the lookup token created by MakeSpellbookLevelLoop() + string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel); + object oCache = GetObjectByTag(sTag); + if(!GetIsObjectValid(oCache)) + { + if(DEBUG) DoDebug("GetSpellUnknownCurrentCount: " + sTag + " is not valid"); + + // Add code to create the missing lookup object + if(DEBUG) DoDebug("Attempting to create missing spell lookup token"); + ExecuteScript("prc_create_spellb", oPC); + + // Try again after creating it + oCache = GetObjectByTag(sTag); + if(!GetIsObjectValid(oCache)) + { + if(DEBUG) DoDebug("Still couldn't create spell lookup token"); + return 0; + } + else + { + if(DEBUG) DoDebug("Successfully created spell lookup token"); + } + } + + // Read the total number of spells on the given level and determine how many are already known + int nTotal = array_get_size(oCache, "Lkup"); + int nKnown = GetSpellKnownCurrentCount(oPC, nSpellLevel, nClass); + int nUnknown = nTotal - nKnown; + + if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown)); + if(DEBUG) DoDebug(" Total spells in lookup: " + IntToString(nTotal) + ", Known spells: " + IntToString(nKnown)); + + return nUnknown; +} + + +/* int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass) { // Get the lookup token created by MakeSpellbookLevelLoop() string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel); @@ -709,7 +807,7 @@ int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass) if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown)); return nUnknown; -} +} */ void AddSpellUse(object oPC, int nSpellbookID, int nClass, string sFile, string sArrayName, int nSpellbookType, object oSkin, int nFeatID, int nIPFeatID, string sIDX = "") { diff --git a/nwn/nwnprc/trunk/include/prc_inc_spells.nss b/nwn/nwnprc/trunk/include/prc_inc_spells.nss index 72930a28..18c0efae 100644 --- a/nwn/nwnprc/trunk/include/prc_inc_spells.nss +++ b/nwn/nwnprc/trunk/include/prc_inc_spells.nss @@ -385,10 +385,10 @@ const int TYPE_DIVINE = -2; // Returns TRUE if nSpellID is a subradial spell, FALSE otherwise int GetIsSubradialSpell(int nSpellID) { - string sMaster = Get2DAString("spells", "Master", nSpellID); + string sMaster = Get2DACache("spells", "Master", nSpellID); - // A subradial will have a numeric master ID here, not **** - if (sMaster != "****") + // If the Master column is numeric, this spell is a subradial of that master + if (sMaster != "" && sMaster != "****") { return TRUE; } diff --git a/nwn/nwnprc/trunk/include/prc_x2_craft.nss b/nwn/nwnprc/trunk/include/prc_x2_craft.nss index cdeb1ff2..ac1d795a 100644 --- a/nwn/nwnprc/trunk/include/prc_x2_craft.nss +++ b/nwn/nwnprc/trunk/include/prc_x2_craft.nss @@ -3309,21 +3309,23 @@ object CICreateInfusion(object oCreator, int nSpellID) // Keep the original spell id the engine gave us (may be a subradial) int nSpellOriginal = nSpellID; + if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: nSpellOriginal is "+IntToString(nSpellOriginal)+"."); - // Compute the master (one-step) if this is a subradial. Keep original intact. - int nSpellMaster = nSpellOriginal; + // Compute the master if this is a subradial. Keep original intact. + int nSpellMaster = nSpellOriginal; if (GetIsSubradialSpell(nSpellOriginal)) { nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal); if (DEBUG) DoDebug("CICreateInfusion: detected subradial " + IntToString(nSpellOriginal) + " master -> " + IntToString(nSpellMaster)); } + if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: nSpellMaster is "+IntToString(nSpellMaster)+"."); // Try to find an iprp_spells row for the original subradial first (preferred). int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal); int nSpellUsedForIP = nSpellOriginal; // If not found for original, fall back to the master/base spell. - if (nPropID < 0) + if (nPropID < 0) { if (DEBUG) DoDebug("CICreateInfusion: no iprp row for original " + IntToString(nSpellOriginal) + ", trying master " + IntToString(nSpellMaster)); nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster);