DelayCommand(2.6, MakeLookupLoop(CLASS_TYPE_BLACKGUARD, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(2.7, MakeLookupLoop(CLASS_TYPE_ANTI_PALADIN, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(2.8, MakeLookupLoop(CLASS_TYPE_SOLDIER_OF_LIGHT, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(2.9, MakeLookupLoop(CLASS_TYPE_KNIGHT_MIDDLECIRCLE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.0, MakeLookupLoop(CLASS_TYPE_KNIGHT_CHALICE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.1, MakeLookupLoop(CLASS_TYPE_VIGILANT, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.2, MakeLookupLoop(CLASS_TYPE_VASSAL, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.3, MakeLookupLoop(CLASS_TYPE_OCULAR, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.4, MakeLookupLoop(CLASS_TYPE_ASSASSIN, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.5, MakeLookupLoop(CLASS_TYPE_SUEL_ARCHANAMACH, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(4.0, MakeLookupLoop(CLASS_TYPE_SHADOWLORD, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(4.0, MakeLookupLoop(CLASS_TYPE_BARD, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(4.0, MakeLookupLoop(CLASS_TYPE_SORCERER, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(4.2, MakeLookupLoop(CLASS_TYPE_FAVOURED_SOUL, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(7.9, MakeLookupLoop(CLASS_TYPE_HEXBLADE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(7.9, MakeLookupLoop(CLASS_TYPE_SOHEI, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(8.9, MakeLookupLoop(CLASS_TYPE_SLAYER_OF_DOMIEL, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(9.5, MakeLookupLoop(CLASS_TYPE_DUSKBLADE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(10.2, MakeLookupLoop(CLASS_TYPE_HEALER, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(11.4, MakeLookupLoop(CLASS_TYPE_WARMAGE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "SpellID", "", "GetRowFromSpellID")); DelayCommand(3.0, MakeSpellIDLevelLoop(CLASS_TYPE_BLACKGUARD, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.1, MakeSpellIDLevelLoop(CLASS_TYPE_ANTI_PALADIN, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.2, MakeSpellIDLevelLoop(CLASS_TYPE_SOLDIER_OF_LIGHT, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.3, MakeSpellIDLevelLoop(CLASS_TYPE_KNIGHT_MIDDLECIRCLE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.4, MakeSpellIDLevelLoop(CLASS_TYPE_KNIGHT_CHALICE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.5, MakeSpellIDLevelLoop(CLASS_TYPE_VIGILANT, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.6, MakeSpellIDLevelLoop(CLASS_TYPE_VASSAL, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.7, MakeSpellIDLevelLoop(CLASS_TYPE_OCULAR, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.8, MakeSpellIDLevelLoop(CLASS_TYPE_ASSASSIN, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(3.9, MakeSpellIDLevelLoop(CLASS_TYPE_SUEL_ARCHANAMACH, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.0, MakeSpellIDLevelLoop(CLASS_TYPE_SHADOWLORD, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.1, MakeSpellIDLevelLoop(CLASS_TYPE_BARD, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.2, MakeSpellIDLevelLoop(CLASS_TYPE_SORCERER, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.3, MakeSpellIDLevelLoop(CLASS_TYPE_FAVOURED_SOUL, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.4, MakeSpellIDLevelLoop(CLASS_TYPE_HEXBLADE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.5, MakeSpellIDLevelLoop(CLASS_TYPE_SOHEI, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.6, MakeSpellIDLevelLoop(CLASS_TYPE_SLAYER_OF_DOMIEL, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.7, MakeSpellIDLevelLoop(CLASS_TYPE_DUSKBLADE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.8, MakeSpellIDLevelLoop(CLASS_TYPE_HEALER, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); DelayCommand(4.9, MakeSpellIDLevelLoop(CLASS_TYPE_WARMAGE, 0, GetPRCSwitch(FILE_END_CLASS_SPELLBOOK) , "RealSpellID", "GetRowFromRealSpellID")); void MakeSpellIDLevelLoop(int nClass, int nMin, int nMax, string sRealColumn, string sVarNameBase, int nLoopSize = 100, string sTag = "") { if(DEBUG) DoDebug("MakeLookupLoop(" +IntToString(nClass)+", " +IntToString(nMin)+", " +IntToString(nMax)+", " +sRealColumn+", " +sVarNameBase+", " +IntToString(nLoopSize)+", " +") : sTag = "+sTag); string sFile; // Stuff handled in GetAMSDefinitionFileName() if(nClass == CLASS_TYPE_PSION || nClass == CLASS_TYPE_PSYWAR || nClass == CLASS_TYPE_WILDER || nClass == CLASS_TYPE_FIST_OF_ZUOKEN || nClass == CLASS_TYPE_WARMIND || // Add new psionic classes here // Tome of Battle nClass == CLASS_TYPE_CRUSADER || nClass == CLASS_TYPE_SWORDSAGE || nClass == CLASS_TYPE_WARBLADE || // Other new caster types nClass == CLASS_TYPE_TRUENAMER ) sFile = GetAMSDefinitionFileName(nClass); // New spellbook class else { sFile = Get2DACache("classes", "FeatsTable", nClass); //sFile = GetStringLeft(sFile, 4)+"spell"+GetStringRight(sFile, GetStringLength(sFile)-8); sFile = "cls_spell" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061210 } // If on the first iteration, generate the storage token tag if(sTag == "") sTag = "PRC_" + sVarNameBase; // Get the token to store the lookup table on. The token is piggybacked in the 2da cache creature's inventory object oToken = _inc_lookups_GetCacheObject(sTag); // Failed to obtain a valid token - nothing to store on if(!GetIsObjectValid(oToken)) return; // Starting a new run and the data is present already. Assume the whole thing is present and abort if(nMin == 0 && GetLocalInt(oToken, IntToString(StringToInt(Get2DACache(sFile, sRealColumn, nMin + 1)))))//+1 cos 0 is always null { DoDebug("MakeSpellIDLevelLoop("+sTag+") restored from database"); return; } int i; int nSource, nDest; int nTemp = 0; int nCount = 0; for(i = nMin; i < nMin + nLoopSize; i++) { // None of the relevant 2da files have blank Label entries on rows other than 0. We can assume i is greater than 0 at this point if(i > 0 && Get2DAString(sFile, "Label", i) == "") // Using Get2DAString() instead of Get2DACache() to avoid caching extra return; nSource = StringToInt(Get2DACache(sFile, sRealColumn, i)); if(i != 0) { if(nSource == nTemp) { nCount += 1; continue; } else { nDest = i; SetLocalInt(oToken, IntToString(nTemp) + "_Count", i); nCount = 0; SetLocalInt(oToken, IntToString(nSource) + "_Start", i); //; } } } // And delay continuation to avoid TMI if(i < nMax) DelayCommand(0.0, MakeSpellIDLevelLoop(nClass, i, nMax, sRealColumn, sVarNameBase, nLoopSize, sTag)); } void MakeLookupLoop(int nClass, int nMin, int nMax, string sSourceColumn, string sDestColumn, string sVarNameBase, int nLoopSize = 100, string sTag = "") void MakeSpellbookLevelLoop(int nClass, int nMin, int nMax, string sVarNameBase, string sColumnName, string sColumnValue, int nLoopSize = 100, string sTag = "") { if(DEBUG) DoDebug("MakeSpellbookLevelLoop(" +IntToString(nClass)+", " +IntToString(nMin)+", " +IntToString(nMax)+", " +sVarNameBase+", " +sColumnName+", " +sColumnValue+", " +IntToString(nLoopSize)+", " +") : sTag = "+sTag); /// Determine the 2da to use int bNewSpellbook = FALSE; string sFile; // Stuff handled in GetAMSDefinitionFileName() if(nClass == CLASS_TYPE_PSION || nClass == CLASS_TYPE_PSYWAR || nClass == CLASS_TYPE_WILDER || nClass == CLASS_TYPE_FIST_OF_ZUOKEN || nClass == CLASS_TYPE_WARMIND || // Add new psionic classes here // Tome of Battle nClass == CLASS_TYPE_CRUSADER || nClass == CLASS_TYPE_SWORDSAGE || nClass == CLASS_TYPE_WARBLADE || // Other new caster types nClass == CLASS_TYPE_TRUENAMER ) sFile = GetAMSDefinitionFileName(nClass); // New spellbook class else { sFile = Get2DACache("classes", "FeatsTable", nClass); //sFile = GetStringLeft(sFile, 4)+"spell"+GetStringRight(sFile, GetStringLength(sFile)-8); sFile = "cls_spell" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061210 bNewSpellbook = TRUE; } // If on the first iteration, generate the storage token tag if(sTag == "") sTag = sVarNameBase + "_" + IntToString(nClass) + "_" + sColumnName + "_" + sColumnValue; // Get the token to store the lookup table on. The token is piggybacked in the 2da cache creature's inventory object oToken = _inc_lookups_GetCacheObject(sTag); // Failed to obtain a valid token - nothing to store on if(!GetIsObjectValid(oToken)) return; // Starting a new run and the array exists already. Assume the whole thing is present and abort if(nMin == 0 && array_exists(oToken, "Lkup")) { DoDebug("MakeSpellbookLevelLoop("+sTag+") restored from database"); return; } // New run, create the array if(nMin == 0) array_create(oToken, "Lkup"); // Cache loopsize rows int i; for(i = nMin; i < nMin + nLoopSize; i++) { // None of the relevant 2da files have blank Label entries on rows other than 0. We can assume i is greater than 0 at this point if(i > 0 && Get2DAString(sFile, "Label", i) == "") // Using Get2DAString() instead of Get2DACache() to avoid caching useless data return; if(Get2DACache(sFile, sColumnName, i) == sColumnValue && (!bNewSpellbook ||Get2DACache(sFile, "ReqFeat", i) == "") // Only new spellbooks have the ReqFeat column. No sense in caching it for other stuff ) { array_set_int(oToken, "Lkup", array_get_size(oToken, "Lkup"), i); } } // And delay continuation to avoid TMI if(i < nMax) DelayCommand(0.0, MakeSpellbookLevelLoop(nClass, i, nMax, sVarNameBase, sColumnName, sColumnValue, nLoopSize, sTag)); } void MakeLookupLoop(int nClass, int nMin, int nMax, string sSourceColumn, string sDestColumn, string sVarNameBase, int nLoopSize = 100, string sTag = "") { if(DEBUG) DoDebug("MakeLookupLoop(" +IntToString(nClass)+", " +IntToString(nMin)+", " +IntToString(nMax)+", " +sSourceColumn+", " +sDestColumn+", " +sVarNameBase+", " +IntToString(nLoopSize)+", " +") : sTag = "+sTag); string sFile; // Stuff handled in GetAMSDefinitionFileName() if(nClass == CLASS_TYPE_PSION || nClass == CLASS_TYPE_PSYWAR || nClass == CLASS_TYPE_WILDER || nClass == CLASS_TYPE_FIST_OF_ZUOKEN || nClass == CLASS_TYPE_WARMIND || // Add new psionic classes here // Tome of Battle nClass == CLASS_TYPE_CRUSADER || nClass == CLASS_TYPE_SWORDSAGE || nClass == CLASS_TYPE_WARBLADE || // Other new caster types nClass == CLASS_TYPE_TRUENAMER ) sFile = GetAMSDefinitionFileName(nClass); // New spellbook class else { sFile = Get2DACache("classes", "FeatsTable", nClass); //sFile = GetStringLeft(sFile, 4)+"spell"+GetStringRight(sFile, GetStringLength(sFile)-8); sFile = "cls_spell" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061210 } // If on the first iteration, generate the storage token tag if(sTag == "") sTag = "PRC_" + sVarNameBase; // Get the token to store the lookup table on. The token is piggybacked in the 2da cache creature's inventory object oToken = _inc_lookups_GetCacheObject(sTag); // Failed to obtain a valid token - nothing to store on if(!GetIsObjectValid(oToken)) return; // Starting a new run and the data is present already. Assume the whole thing is present and abort if(nMin == 0 && GetLocalInt(oToken, /*sTag + "_" + */IntToString(StringToInt(Get2DACache(sFile, sSourceColumn, nMin + 1)))))//+1 cos 0 is always null { DoDebug("MakeLookupLoop("+sTag+") restored from database"); return; } int i; int nSource, nDest; for(i = nMin; i < nMin + nLoopSize; i++) { // None of the relevant 2da files have blank Label entries on rows other than 0. We can assume i is greater than 0 at this point if(i > 0 && Get2DAString(sFile, "Label", i) == "") // Using Get2DAString() instead of Get2DACache() to avoid caching extra return; // In case of blank source or destination column, use current row index // Otherwise, read the relevant data from the 2da and convert it to an integer - we assume that the 2da data is numeral if(sSourceColumn == "") nSource = i; else nSource = StringToInt(Get2DACache(sFile, sSourceColumn, i)); if(sDestColumn == "") nDest = i; else nDest = StringToInt(Get2DACache(sFile, sDestColumn, i)); // Skip storing invalid values. The source column value should always be non-zero in valid cases. // The destination column value might be zero in some cases. However, due to non-presence = 0, it works out OK. if(nSource != 0 && nDest != 0) { if(DEBUG) Assert(!GetLocalInt(oToken, IntToString(nSource)) || (GetLocalInt(oToken, IntToString(nSource)) == nDest), "!GetLocalInt(" + DebugObject2Str(oToken) + ", IntToString(" + IntToString(nSource) + ")) || GetLocalInt(" + DebugObject2Str(oToken) + ", IntToString(" + IntToString(nSource) + ")) == " + IntToString(nDest) + ")\n" + " = !" + IntToString(GetLocalInt(oToken, IntToString(nSource))) + " || " + IntToString(GetLocalInt(oToken, IntToString(nSource))) + " == " + IntToString(nDest) , "sFile = " + sFile + "\n" + "i = " + IntToString(i) + "sSourceColumn = " + sSourceColumn + "\n" + "sDestColumn = " + sDestColumn , "inc_lookups", "MakeLookupLoop"); SetLocalInt(oToken, /*sTag + "_" + */IntToString(nSource), nDest); } } // And delay continuation to avoid TMI if(i < nMax) DelayCommand(0.0, MakeLookupLoop(nClass, i, nMax, sSourceColumn, sDestColumn, sVarNameBase, nLoopSize, sTag)); }