Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
530 lines
24 KiB
Plaintext
530 lines
24 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: Invocation include: Invocations Known
|
|
//:: inv_inc_invknown
|
|
//::///////////////////////////////////////////////
|
|
/** @file
|
|
Defines functions for adding & removing
|
|
Invocations known.
|
|
|
|
Data stored:
|
|
|
|
- For each Class list
|
|
-- Total number of Invocations known
|
|
-- A modifier value to maximum Invocations known on this list to account for feats and classes that add Invocations
|
|
-- An array related to Invocations the knowledge of which is not dependent on character level
|
|
--- Each array entry specifies the spells.2da row of the known Invocations's class-specific entry
|
|
-- For each character level on which Invocations have been gained from this list
|
|
--- An array of Invocations gained on this level
|
|
---- Each array entry specifies the spells.2da row of the known Invocations's class-specific entry
|
|
|
|
@author Fox
|
|
@date Created - 2008.01.25
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:://////////////////////////////////////////////
|
|
|
|
// Included here to provide the values for the constants below
|
|
#include "prc_class_const"
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Constants */
|
|
//////////////////////////////////////////////////
|
|
|
|
const int INVOCATION_LIST_DRAGONFIRE_ADEPT = CLASS_TYPE_DRAGONFIRE_ADEPT;
|
|
const int INVOCATION_LIST_WARLOCK = CLASS_TYPE_WARLOCK;
|
|
const int INVOCATION_LIST_DRAGON_SHAMAN = CLASS_TYPE_DRAGON_SHAMAN;
|
|
|
|
/// Special Maneuver list. Maneuvers gained via Extra Invocation or other sources.
|
|
const int INVOCATION_LIST_EXTRA = CLASS_TYPE_INVALID;//-1;
|
|
const int INVOCATION_LIST_EXTRA_EPIC = /*CLASS_TYPE_INVALID - 1;*/-2; //needs a constant in there to compile properly
|
|
|
|
const string _INVOCATION_LIST_NAME_BASE = "PRC_InvocationList_";
|
|
const string _INVOCATION_LIST_TOTAL_KNOWN = "_TotalKnown";
|
|
const string _INVOCATION_LIST_MODIFIER = "_KnownModifier";
|
|
const string _INVOCATION_LIST_EXTRA_ARRAY = "_InvocationsKnownExtraArray";
|
|
const string _INVOCATION_LIST_EXTRA_EPIC_ARRAY = "_InvocationsKnownExtraEpicArray";
|
|
const string _INVOCATION_LIST_LEVEL_ARRAY = "_InvocationsKnownLevelArray_";
|
|
const string _INVOCATION_LIST_GENERAL_ARRAY = "_InvocationsKnownGeneralArray";
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function prototypes */
|
|
//////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Gives the creature the control feats for the given Invocation and marks the Invocation
|
|
* in a Invocations known array.
|
|
* If the Invocation's data is already stored in one of the Invocations known arrays for
|
|
* the list or adding the Invocation's data to the array fails, the function aborts.
|
|
*
|
|
* @param oCreature The creature to gain the Invocation
|
|
* @param nList The list the Invocation comes from. One of INVOCATION_LIST_*
|
|
* @param n2daRow The 2da row in the lists's 2da file that specifies the Invocation.
|
|
* @param bLevelDependent If this is TRUE, the Invocation is tied to a certain level and can
|
|
* be lost via level loss. If FALSE, the Invocation is not dependent
|
|
* of a level and cannot be lost via level loss.
|
|
* @param nLevelToTieTo If bLevelDependent is TRUE, this specifies the level the Invocation
|
|
* is gained on. Otherwise, it's ignored.
|
|
* The default value (-1) means that the current level of oCreature
|
|
* will be used.
|
|
*
|
|
* @return TRUE if the Invocation was successfully stored and control feats added.
|
|
* FALSE otherwise.
|
|
*/
|
|
int AddInvocationKnown(object oCreature, int nList, int n2daRow, int bLevelDependent = FALSE, int nLevelToTieTo = -1);
|
|
|
|
/**
|
|
* Removes all Invocations gained from each list on the given level.
|
|
*
|
|
* @param oCreature The creature whose Invocations to remove
|
|
* @param nLevel The level to clear
|
|
*/
|
|
void RemoveInvocationsKnownOnLevel(object oCreature, int nLevel);
|
|
|
|
/**
|
|
* Gets the value of the Invocations known modifier, which is a value that is added
|
|
* to the 2da-specified maximum Invocations known to determine the actual maximum.
|
|
*
|
|
* @param oCreature The creature whose modifier to get
|
|
* @param nList The list the maximum Invocations known from which the modifier
|
|
* modifies. One of INVOCATION_LIST_*
|
|
*/
|
|
int GetKnownInvocationsModifier(object oCreature, int nList);
|
|
|
|
/**
|
|
* Sets the value of the Invocations known modifier, which is a value that is added
|
|
* to the 2da-specified maximum Invocations known to determine the actual maximum.
|
|
*
|
|
* @param oCreature The creature whose modifier to set
|
|
* @param nList The list the maximum Invocations known from which the modifier
|
|
* modifies. One of INVOCATION_LIST_*
|
|
*/
|
|
void SetKnownInvocationsModifier(object oCreature, int nList, int nNewValue);
|
|
|
|
/**
|
|
* Gets the number of Invocations a character character possesses from a
|
|
* specific list and lexicon
|
|
*
|
|
* @param oCreature The creature whose Invocations to check
|
|
* @param nList The list to check. One of INVOCATION_LIST_*
|
|
* @return The number of Invocations known oCreature has from nList
|
|
*/
|
|
int GetInvocationCount(object oCreature, int nList);
|
|
|
|
/**
|
|
* Gets the maximum number of Invocations a character may posses from a given list
|
|
* at this time. Calculated based on class levels, feats and a misceallenous
|
|
* modifier. There are three Types of Invocations, so it checks each seperately.
|
|
*
|
|
* @param oCreature Character to determine maximum Invocations for
|
|
* @param nList INVOCATION_LIST_* of the list to determine maximum Invocations for
|
|
* @return Maximum number of Invocations that oCreature may know from the given list.
|
|
*/
|
|
int GetMaxInvocationCount(object oCreature, int nList);
|
|
|
|
/**
|
|
* Determines whether a character has a given Invocation, gained via some Invocation list.
|
|
*
|
|
* @param nInvocation INVOKE_* of the Invocation to test
|
|
* @param oCreature Character to test for the possession of the Invocation
|
|
* @return TRUE if the character has the Invocation, FALSE otherwise
|
|
*/
|
|
int GetHasInvocation(int nInvocation, object oCreature = OBJECT_SELF);
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Includes */
|
|
//////////////////////////////////////////////////
|
|
|
|
#include "inc_item_props"
|
|
#include "prc_x2_itemprop"
|
|
#include "inc_lookups"
|
|
#include "prc_inc_nwscript"
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Internal functions */
|
|
//////////////////////////////////////////////////
|
|
|
|
void _InvocationRecurseRemoveArray(object oCreature, string sArrayName, string sInvocFile, int nArraySize, int nCurIndex)
|
|
{
|
|
if(DEBUG) DoDebug("_InvocationRecurseRemoveArray():\n"
|
|
+ "oCreature = " + DebugObject2Str(oCreature) + "\n"
|
|
+ "sArrayName = '" + sArrayName + "'\n"
|
|
+ "sInvocFile = '" + sInvocFile + "'\n"
|
|
+ "nArraySize = " + IntToString(nArraySize) + "\n"
|
|
+ "nCurIndex = " + IntToString(nCurIndex) + "\n"
|
|
);
|
|
|
|
// Determine whether we've already parsed the whole array or not
|
|
if(nCurIndex >= nArraySize)
|
|
{
|
|
if(DEBUG) DoDebug("_InvocationRecurseRemoveArray(): Running itemproperty removal loop.");
|
|
// Loop over itemproperties on the skin and remove each match
|
|
object oSkin = GetPCSkin(oCreature);
|
|
itemproperty ipTest = GetFirstItemProperty(oSkin);
|
|
while(GetIsItemPropertyValid(ipTest))
|
|
{
|
|
// Check if the itemproperty is a bonus feat that has been marked for removal
|
|
if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_BONUS_FEAT &&
|
|
GetLocalInt(oCreature, "PRC_InvocFeatRemovalMarker_" + IntToString(GetItemPropertySubType(ipTest)))
|
|
)
|
|
{
|
|
if(DEBUG) DoDebug("_InvocationRecurseRemoveArray(): Removing bonus feat itemproperty:\n" + DebugIProp2Str(ipTest));
|
|
// If so, remove it
|
|
RemoveItemProperty(oSkin, ipTest);
|
|
}
|
|
|
|
ipTest = GetNextItemProperty(oSkin);
|
|
}
|
|
}
|
|
// Still parsing the array
|
|
else
|
|
{
|
|
// Set the marker
|
|
string sName = "PRC_InvocFeatRemovalMarker_" + Get2DACache(sInvocFile, "IPFeatID",
|
|
GetPowerfileIndexFromSpellID(persistant_array_get_int(oCreature, sArrayName, nCurIndex))
|
|
);
|
|
if(DEBUG) DoDebug("_InvocationRecurseRemoveArray(): Recursing through array, marker set:\n" + sName);
|
|
|
|
SetLocalInt(oCreature, sName, TRUE);
|
|
// Recurse to next array index
|
|
_InvocationRecurseRemoveArray(oCreature, sArrayName, sInvocFile, nArraySize, nCurIndex + 1);
|
|
// After returning, delete the local
|
|
DeleteLocalInt(oCreature, sName);
|
|
}
|
|
}
|
|
|
|
void _RemoveInvocationArray(object oCreature, int nList, int nLevel)
|
|
{
|
|
if(DEBUG) DoDebug("_RemoveInvocationArray():\n"
|
|
+ "oCreature = " + DebugObject2Str(oCreature) + "\n"
|
|
+ "nList = " + IntToString(nList) + "\n"
|
|
);
|
|
|
|
string sBase = _INVOCATION_LIST_NAME_BASE + IntToString(nList);
|
|
string sArray = sBase + _INVOCATION_LIST_LEVEL_ARRAY + IntToString(nLevel);
|
|
int nSize = persistant_array_get_size(oCreature, sArray);
|
|
|
|
// Reduce the total by the array size
|
|
SetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN,
|
|
GetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN) - nSize
|
|
);
|
|
|
|
// Remove each Invocation in the array
|
|
_InvocationRecurseRemoveArray(oCreature, sArray, GetAMSDefinitionFileName(nList), nSize, 0);
|
|
|
|
// Remove the array itself
|
|
persistant_array_delete(oCreature, sArray);
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function definitions */
|
|
//////////////////////////////////////////////////
|
|
|
|
int AddInvocationKnown(object oCreature, int nList, int n2daRow, int bLevelDependent = FALSE, int nLevelToTieTo = -1)
|
|
{
|
|
string sBase = _INVOCATION_LIST_NAME_BASE + IntToString(nList);
|
|
string sArray = sBase;
|
|
string sPowerFile = GetAMSDefinitionFileName(/*PowerListToClassType(*/nList/*)*/);
|
|
if(nList == -2 || nList == CLASS_TYPE_INVALID)
|
|
{
|
|
sPowerFile = GetAMSDefinitionFileName(GetPrimaryInvocationClass(oCreature));
|
|
}
|
|
string sTestArray;
|
|
int i, j, nSize, bReturn;
|
|
|
|
// Get the spells.2da row corresponding to the cls_psipw_*.2da row
|
|
int nSpells2daRow = StringToInt(Get2DACache(sPowerFile, "SpellID", n2daRow));
|
|
|
|
// Determine the array name.
|
|
if(bLevelDependent)
|
|
{
|
|
// If no level is specified, default to the creature's current level
|
|
if(nLevelToTieTo == -1)
|
|
nLevelToTieTo = GetHitDice(oCreature);
|
|
|
|
sArray += _INVOCATION_LIST_LEVEL_ARRAY + IntToString(nLevelToTieTo);
|
|
}
|
|
else
|
|
{
|
|
sArray += _INVOCATION_LIST_GENERAL_ARRAY;
|
|
}
|
|
|
|
// Make sure the power isn't already in an array. If it is, abort and return FALSE
|
|
// Loop over each level array and check that it isn't there.
|
|
if(DEBUG) DoDebug("inv_inc_invknown: Checking first array set for duplicates.");
|
|
for(i = 1; i <= GetHitDice(oCreature); i++)
|
|
{
|
|
sTestArray = sBase + _INVOCATION_LIST_LEVEL_ARRAY + IntToString(i);
|
|
if(persistant_array_exists(oCreature, sTestArray))
|
|
{
|
|
nSize = persistant_array_get_size(oCreature, sTestArray);
|
|
for(j = 0; j < nSize; j++)
|
|
if(persistant_array_get_int(oCreature, sArray, j) == nSpells2daRow)
|
|
return FALSE;
|
|
}
|
|
}
|
|
// Check the non-level-dependent array
|
|
if(DEBUG) DoDebug("inv_inc_invknown: Checking second array set for duplicates.");
|
|
sTestArray = sBase + _INVOCATION_LIST_GENERAL_ARRAY;
|
|
if(persistant_array_exists(oCreature, sTestArray))
|
|
{
|
|
nSize = persistant_array_get_size(oCreature, sTestArray);
|
|
for(j = 0; j < nSize; j++)
|
|
if(persistant_array_get_int(oCreature, sArray, j) == nSpells2daRow)
|
|
return FALSE;
|
|
}
|
|
|
|
// All checks are made, now start adding the new power
|
|
// Create the array if it doesn't exist yet
|
|
if(!persistant_array_exists(oCreature, sArray))
|
|
persistant_array_create(oCreature, sArray);
|
|
|
|
// Store the power in the array
|
|
if(DEBUG) DoDebug("inv_inc_invknown: Adding to invocation array.");
|
|
if(persistant_array_set_int(oCreature, sArray, persistant_array_get_size(oCreature, sArray), nSpells2daRow) != SDL_SUCCESS)
|
|
{
|
|
if(DEBUG) DoDebug("inv_inc_invknown: AddPowerKnown(): ERROR: Unable to add power to known array\n"
|
|
+ "oCreature = " + DebugObject2Str(oCreature) + "\n"
|
|
+ "nList = " + IntToString(nList) + "\n"
|
|
+ "n2daRow = " + IntToString(n2daRow) + "\n"
|
|
+ "bLevelDependent = " + DebugBool2String(bLevelDependent) + "\n"
|
|
+ "nLevelToTieTo = " + IntToString(nLevelToTieTo) + "\n"
|
|
+ "nSpells2daRow = " + IntToString(nSpells2daRow) + "\n"
|
|
);
|
|
return FALSE;
|
|
}
|
|
|
|
// Increment Invocations known total
|
|
SetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN,
|
|
GetPersistantLocalInt(oCreature, sBase + _INVOCATION_LIST_TOTAL_KNOWN) + 1
|
|
);
|
|
|
|
// Give the power's control feats
|
|
object oSkin = GetPCSkin(oCreature);
|
|
string sPowerFeatIP = Get2DACache(sPowerFile, "IPFeatID", n2daRow);
|
|
itemproperty ipFeat = PRCItemPropertyBonusFeat(StringToInt(sPowerFeatIP));
|
|
IPSafeAddItemProperty(oSkin, ipFeat, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
// Second power feat, if any
|
|
sPowerFeatIP = Get2DACache(sPowerFile, "IPFeatID2", n2daRow);
|
|
if(sPowerFeatIP != "")
|
|
{
|
|
ipFeat = PRCItemPropertyBonusFeat(StringToInt(sPowerFeatIP));
|
|
IPSafeAddItemProperty(oSkin, ipFeat, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void RemoveInvocationsKnownOnLevel(object oCreature, int nLevel)
|
|
{
|
|
if(DEBUG) DoDebug("inv_inc_invknown: RemoveInvocationKnownOnLevel():\n"
|
|
+ "oCreature = " + DebugObject2Str(oCreature) + "\n"
|
|
+ "nLevel = " + IntToString(nLevel) + "\n"
|
|
);
|
|
|
|
string sPostFix = _INVOCATION_LIST_LEVEL_ARRAY + IntToString(nLevel);
|
|
// For each Invocation list, determine if an array exists for this level.
|
|
if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_DRAGONFIRE_ADEPT) + sPostFix))
|
|
// If one does exist, clear it
|
|
_RemoveInvocationArray(oCreature, INVOCATION_LIST_DRAGONFIRE_ADEPT, nLevel);
|
|
|
|
if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_WARLOCK) + sPostFix))
|
|
_RemoveInvocationArray(oCreature, INVOCATION_LIST_WARLOCK, nLevel);
|
|
|
|
if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_DRAGON_SHAMAN) + sPostFix))
|
|
_RemoveInvocationArray(oCreature, INVOCATION_LIST_DRAGON_SHAMAN, nLevel);
|
|
|
|
if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_EXTRA) + sPostFix))
|
|
_RemoveInvocationArray(oCreature, INVOCATION_LIST_EXTRA, nLevel);
|
|
|
|
if(persistant_array_exists(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(INVOCATION_LIST_EXTRA_EPIC) + sPostFix))
|
|
_RemoveInvocationArray(oCreature, INVOCATION_LIST_EXTRA_EPIC, nLevel);
|
|
}
|
|
|
|
int GetKnownInvocationsModifier(object oCreature, int nList)
|
|
{
|
|
return GetPersistantLocalInt(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(nList) + _INVOCATION_LIST_MODIFIER);
|
|
}
|
|
|
|
void SetKnownInvocationsModifier(object oCreature, int nList, int nNewValue)
|
|
{
|
|
SetPersistantLocalInt(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(nList) + _INVOCATION_LIST_MODIFIER, nNewValue);
|
|
}
|
|
|
|
int GetInvocationCount(object oCreature, int nList)
|
|
{
|
|
return GetPersistantLocalInt(oCreature, _INVOCATION_LIST_NAME_BASE + IntToString(nList) + _INVOCATION_LIST_TOTAL_KNOWN);
|
|
}
|
|
|
|
int GetMaxInvocationCount(object oCreature, int nList)
|
|
{
|
|
int nMaxInvocations = 0;
|
|
|
|
switch(nList)
|
|
{
|
|
case INVOCATION_LIST_DRAGONFIRE_ADEPT:{
|
|
// Determine base Invocations known
|
|
int nLevel = GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oCreature);
|
|
nLevel += GetPrimaryInvocationClass(oCreature) == CLASS_TYPE_DRAGONFIRE_ADEPT ? GetInvocationPRCLevels(oCreature) : 0;
|
|
if(nLevel == 0)
|
|
break;
|
|
nMaxInvocations = StringToInt(Get2DACache(GetAMSKnownFileName(CLASS_TYPE_DRAGONFIRE_ADEPT), "InvocationKnown", nLevel - 1));
|
|
|
|
// Calculate feats
|
|
|
|
// Add in the custom modifier
|
|
nMaxInvocations += GetKnownInvocationsModifier(oCreature, nList);
|
|
break;
|
|
}
|
|
|
|
case INVOCATION_LIST_WARLOCK:{
|
|
// Determine base Invocations known
|
|
int nLevel = GetLevelByClass(CLASS_TYPE_WARLOCK, oCreature);
|
|
nLevel += GetPrimaryInvocationClass(oCreature) == CLASS_TYPE_WARLOCK ? GetInvocationPRCLevels(oCreature) : 0;
|
|
if(nLevel == 0)
|
|
break;
|
|
nMaxInvocations = StringToInt(Get2DACache(GetAMSKnownFileName(CLASS_TYPE_WARLOCK), "InvocationKnown", nLevel - 1));
|
|
|
|
// Calculate feats
|
|
|
|
// Add in the custom modifier
|
|
nMaxInvocations += GetKnownInvocationsModifier(oCreature, nList);
|
|
break;
|
|
}
|
|
|
|
case INVOCATION_LIST_DRAGON_SHAMAN:{
|
|
// Determine base Invocations known
|
|
int nLevel = GetLevelByClass(CLASS_TYPE_DRAGON_SHAMAN, oCreature);
|
|
nLevel += GetPrimaryInvocationClass(oCreature) == CLASS_TYPE_DRAGON_SHAMAN ? GetInvocationPRCLevels(oCreature) : 0;
|
|
if(nLevel == 0)
|
|
break;
|
|
nMaxInvocations = StringToInt(Get2DACache(GetAMSKnownFileName(CLASS_TYPE_DRAGON_SHAMAN), "InvocationKnown", nLevel - 1));
|
|
|
|
// Calculate feats
|
|
|
|
// Add in the custom modifier
|
|
nMaxInvocations += GetKnownInvocationsModifier(oCreature, nList);
|
|
break;
|
|
}
|
|
|
|
case INVOCATION_LIST_EXTRA:
|
|
nMaxInvocations = GetHasFeat(FEAT_EXTRA_INVOCATION_I, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_II, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_III, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_IV, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_V, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_VI, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_VII, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_VIII, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_IX, oCreature) +
|
|
GetHasFeat(FEAT_EXTRA_INVOCATION_X, oCreature);
|
|
break;
|
|
|
|
case INVOCATION_LIST_EXTRA_EPIC:
|
|
nMaxInvocations = GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_I, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_II, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_III, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_IV, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_V, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_VI, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_VII, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_VIII, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_IX, oCreature) +
|
|
GetHasFeat(FEAT_EPIC_EXTRA_INVOCATION_X, oCreature);
|
|
break;
|
|
|
|
default:{
|
|
string sErr = "GetMaxInvocationCount(): ERROR: Unknown power list value: " + IntToString(nList);
|
|
if(DEBUG) DoDebug(sErr);
|
|
else WriteTimestampedLogEntry(sErr);
|
|
}
|
|
}
|
|
|
|
return nMaxInvocations;
|
|
}
|
|
|
|
int GetHasInvocation(int nInvocation, object oCreature = OBJECT_SELF)
|
|
{
|
|
if((GetLevelByClass(CLASS_TYPE_DRAGONFIRE_ADEPT, oCreature)
|
|
&& GetHasFeat(GetClassFeatFromPower(nInvocation, CLASS_TYPE_DRAGONFIRE_ADEPT), oCreature)
|
|
) ||
|
|
(GetLevelByClass(CLASS_TYPE_WARLOCK, oCreature)
|
|
&& GetHasFeat(GetClassFeatFromPower(nInvocation, CLASS_TYPE_WARLOCK), oCreature)
|
|
) ||
|
|
(GetLevelByClass(CLASS_TYPE_DRAGON_SHAMAN, oCreature)
|
|
&& GetHasFeat(GetClassFeatFromPower(nInvocation, CLASS_TYPE_DRAGON_SHAMAN), oCreature)
|
|
)
|
|
// add new Invocation classes here
|
|
)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
string DebugListKnownInvocations(object oCreature)
|
|
{
|
|
string sReturn = "Invocations known by " + DebugObject2Str(oCreature) + ":\n";
|
|
int i, j, k, numPowerLists = 6;
|
|
int nPowerList, nSize;
|
|
string sTemp, sArray, sArrayBase, sPowerFile;
|
|
// Loop over all power lists
|
|
for(i = 1; i <= numPowerLists; i++)
|
|
{
|
|
// Some padding
|
|
sReturn += " ";
|
|
// Get the power list for this loop
|
|
switch(i)
|
|
{
|
|
case 1: nPowerList = INVOCATION_LIST_DRAGONFIRE_ADEPT; sReturn += "Dragonfire Adept"; break;
|
|
|
|
case 2: nPowerList = INVOCATION_LIST_WARLOCK; sReturn += "Warlock"; break;
|
|
case 3: nPowerList = INVOCATION_LIST_DRAGON_SHAMAN; sReturn += "Dragon Shaman"; break;
|
|
|
|
// This should always be last
|
|
case 5: nPowerList = INVOCATION_LIST_EXTRA; sReturn += "Extra"; break;
|
|
case 6: nPowerList = INVOCATION_LIST_EXTRA_EPIC; sReturn += "Epic Extra"; break;
|
|
}
|
|
sReturn += " Invocations known:\n";
|
|
|
|
// Determine if the character has any Invocations from this list
|
|
sPowerFile = GetAMSDefinitionFileName(nPowerList);
|
|
sArrayBase = _INVOCATION_LIST_NAME_BASE + IntToString(nPowerList);
|
|
|
|
// Loop over levels
|
|
for(j = 1; j <= GetHitDice(oCreature); j++)
|
|
{
|
|
sArray = sArrayBase + _INVOCATION_LIST_LEVEL_ARRAY + IntToString(j);
|
|
if(persistant_array_exists(oCreature, sArray))
|
|
{
|
|
sReturn += " Gained on level " + IntToString(j) + ":\n";
|
|
nSize = persistant_array_get_size(oCreature, sArray);
|
|
for(k = 0; k < nSize; k++)
|
|
sReturn += " " + GetStringByStrRef(StringToInt(Get2DACache(sPowerFile, "Name",
|
|
GetPowerfileIndexFromSpellID(persistant_array_get_int(oCreature, sArray, k))
|
|
)
|
|
)
|
|
)
|
|
+ "\n";
|
|
}
|
|
}
|
|
|
|
// Non-leveldependent Invocations
|
|
sArray = sArrayBase + _INVOCATION_LIST_GENERAL_ARRAY;
|
|
if(persistant_array_exists(oCreature, sArray))
|
|
{
|
|
sReturn += " Non-leveldependent:\n";
|
|
nSize = persistant_array_get_size(oCreature, sArray);
|
|
for(k = 0; k < nSize; k++)
|
|
sReturn += " " + GetStringByStrRef(StringToInt(Get2DACache(sPowerFile, "Name",
|
|
GetPowerfileIndexFromSpellID(persistant_array_get_int(oCreature, sArray, k))
|
|
)
|
|
)
|
|
)
|
|
+ "\n";
|
|
}
|
|
}
|
|
|
|
return sReturn;
|
|
}
|
|
// Test main
|
|
//void main(){}
|