Updated AMS marker feats. Removed arcane & divine marker feats. Updated Dread Necromancer for epic progression. Updated weapon baseitem models. Updated new weapons for crafting & npc equip. Updated prefix. Updated release archive.
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(){}
|