forked from Jaysyn/PRC8
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.
801 lines
42 KiB
Plaintext
801 lines
42 KiB
Plaintext
//::///////////////////////////////////////////////
|
||
//:: Shadowcasting include: Mysteries Known
|
||
//:: shd_inc_mystknwn
|
||
//::///////////////////////////////////////////////
|
||
/** @file
|
||
Defines functions for adding & removing
|
||
Mysteries known.
|
||
|
||
Data stored:
|
||
|
||
- For each Path list
|
||
-- Total number of Mysteries known
|
||
-- A modifier value to maximum Mysteries known on this list to account for feats and classes that add Mysteries
|
||
-- An array related to Mysteries the knowledge of which is not dependent on character level
|
||
--- Each array entry specifies the spells.2da row of the known Mysteries's class-specific entry
|
||
-- For each character level on which Mysteries have been gained from this list
|
||
--- An array of Mysteries gained on this level
|
||
---- Each array entry specifies the spells.2da row of the known Mysteries's class-specific entry
|
||
|
||
@author Stratovarius
|
||
@date Created - 2019.02.06
|
||
*/
|
||
//:://////////////////////////////////////////////
|
||
//:://////////////////////////////////////////////
|
||
|
||
//////////////////////////////////////////////////
|
||
/* Constants */
|
||
//////////////////////////////////////////////////
|
||
|
||
const int MYSTERY_LIST_SHADOWCASTER = 136;
|
||
const int MYSTERY_LIST_SHADOWSMITH = 98;
|
||
|
||
/// Special Mystery list. Mysteries gained via other sources.
|
||
const int MYSTERY_LIST_MISC = CLASS_TYPE_INVALID;//-1;
|
||
|
||
const string _MYSTERY_LIST_NAME_BASE = "PRC_MysteryList_";
|
||
const string _MYSTERY_LIST_PATH = "PRC_PathTotal_";
|
||
const string _MYSTERY_LIST_TOTAL_KNOWN = "_TotalKnown";
|
||
const string _MYSTERY_LIST_MODIFIER = "_KnownModifier";
|
||
const string _MYSTERY_LIST_MISC_ARRAY = "_MysteriesKnownMiscArray";
|
||
const string _MYSTERY_LIST_LEVEL_ARRAY = "_MysteriesKnownLevelArray_";
|
||
const string _MYSTERY_LIST_GENERAL_ARRAY = "_MysteriesKnownGeneralArray";
|
||
|
||
|
||
//////////////////////////////////////////////////
|
||
/* Function prototypes */
|
||
//////////////////////////////////////////////////
|
||
|
||
/**
|
||
* Gives the creature the control feats for the given Mystery and marks the Mystery
|
||
* in a Mysteries known array.
|
||
* If the Mystery's data is already stored in one of the Mysteries known arrays for
|
||
* the list or adding the Mystery's data to the array fails, the function aborts.
|
||
*
|
||
* @param oShadow The creature to gain the Mystery
|
||
* @param nList The list the Mystery comes from. One of MYSTERY_LIST_*
|
||
* @param n2daRow The 2da row in the lists's 2da file that specifies the Mystery.
|
||
* @param bLevelDependent If this is TRUE, the Mystery is tied to a certain level and can
|
||
* be lost via level loss. If FALSE, the Mystery is not dependent
|
||
* of a level and cannot be lost via level loss.
|
||
* @param nLevelToTieTo If bLevelDependent is TRUE, this specifies the level the Mystery
|
||
* is gained on. Otherwise, it's ignored.
|
||
* The default value (-1) means that the current level of oShadow
|
||
* will be used.
|
||
*
|
||
* @return TRUE if the Mystery was successfully stored and control feats added.
|
||
* FALSE otherwise.
|
||
*/
|
||
int AddMysteryKnown(object oShadow, int nList, int n2daRow, int bLevelDependent = FALSE, int nLevelToTieTo = -1);
|
||
|
||
/**
|
||
* Removes all Mysteries gained from each list on the given level.
|
||
*
|
||
* @param oShadow The creature whose Mysteries to remove
|
||
* @param nLevel The level to clear
|
||
*/
|
||
void RemoveMysteriesKnownOnLevel(object oShadow, int nLevel);
|
||
|
||
/**
|
||
* Gets the value of the Mysteries known modifier, which is a value that is added
|
||
* to the 2da-specified maximum Mysteries known to determine the actual maximum.
|
||
*
|
||
* @param oShadow The creature whose modifier to get
|
||
* @param nList The list the maximum Mysteries known from which the modifier
|
||
* modifies. One of MYSTERY_LIST_*
|
||
*/
|
||
int GetKnownMysteriesModifier(object oShadow, int nList);
|
||
|
||
/**
|
||
* Sets the value of the Mysteries known modifier, which is a value that is added
|
||
* to the 2da-specified maximum Mysteries known to determine the actual maximum.
|
||
*
|
||
* @param oShadow The creature whose modifier to set
|
||
* @param nList The list the maximum Mysteries known from which the modifier
|
||
* modifies. One of MYSTERY_LIST_*
|
||
*/
|
||
void SetKnownMysteriesModifier(object oShadow, int nList, int nNewValue);
|
||
|
||
/**
|
||
* Gets the number of Mysteries a character possesses
|
||
*
|
||
* @param oShadow The creature whose Mysteries to check
|
||
* @param nList The list to check. One of MYSTERY_LIST_*
|
||
*
|
||
* @return The number of Mysteries known oShadow has from nList
|
||
*/
|
||
int GetMysteryCount(object oShadow, int nList);
|
||
|
||
/**
|
||
* Gets the number of Mysteries a character character possesses from a
|
||
* specific path
|
||
*
|
||
* @param oShadow The creature whose Mysteries to check
|
||
* @param nPath The path to check. One of PATH_*
|
||
*
|
||
* @return The number of Mysteries known oShadow has from nPath
|
||
*/
|
||
int GetMysteryCountByPath(object oShadow, int nPath);
|
||
|
||
/**
|
||
* Gets the maximum number of Mysteries a character may possess from a given list
|
||
* at this time. Calculated based on class levels, feats and a misceallenous
|
||
* modifier.
|
||
*
|
||
* @param oShadow Character to determine maximum Mysteries for
|
||
* @param nList MYSTERY_LIST_* of the list to determine maximum Mysteries for
|
||
*
|
||
* @return Maximum number of Mysteries that oShadow may know from the given list.
|
||
*/
|
||
int GetMaxMysteryCount(object oShadow, int nList);
|
||
|
||
/**
|
||
* Determines whether a character has a given Mystery, gained via some Mystery list.
|
||
*
|
||
* @param nMystery Mystery_* of the Mystery to test
|
||
* @param oShadow Character to test for the possession of the Mystery
|
||
* @return TRUE if the character has the Mystery, FALSE otherwise
|
||
*/
|
||
int GetHasMystery(int nMystery, object oShadow = OBJECT_SELF);
|
||
|
||
/**
|
||
* Gets the highest Mystery level a character may learn at this time.
|
||
*
|
||
* @param oShadow Character to determine maximum Mystery level for
|
||
* @param nClass Class to check against
|
||
* @param nType 1 = apprentice, 2 = initiate, 3 = master
|
||
*
|
||
* @return Maxmimum mystery level
|
||
*/
|
||
int GetMaxMysteryLevelLearnable(object oShadow, int nClass, int nType);
|
||
|
||
/**
|
||
* Gets the total number of completed paths for the character
|
||
*
|
||
* @param oShadow Character to check
|
||
*/
|
||
int GetCompletedPaths(object oShadow);
|
||
|
||
/**
|
||
* Adds the feat as a bonus feat gained from having completed a path. Aborts if the feat
|
||
* was one the character already had
|
||
*
|
||
* @param oShadow Character to check
|
||
* @param nFeat Feat to add
|
||
*/
|
||
void AddPathBonusFeat(object oShadow, int nFeat);
|
||
|
||
/**
|
||
* Returns how many Path Bonus feats the character has
|
||
*
|
||
* @param oShadow Character to check
|
||
*/
|
||
int GetPathBonusFeats(object oShadow);
|
||
|
||
/**
|
||
* Reapplies any missing Path Bonus feats the character has chosen and doesn't have
|
||
*
|
||
* @param oShadow Character to check
|
||
*/
|
||
void ReapplyPathBonusFeat(object oShadow);
|
||
|
||
/**
|
||
* Returns the IP_CONST version of the feat.
|
||
* Only works on Bonus Path feats
|
||
*
|
||
* @param nFeat Feat to itemproperty
|
||
*/
|
||
int PathFeatToIPFeat(int nFeat);
|
||
|
||
//////////////////////////////////////////////////
|
||
/* Includes */
|
||
//////////////////////////////////////////////////
|
||
|
||
|
||
|
||
//////////////////////////////////////////////////
|
||
/* Internal functions */
|
||
//////////////////////////////////////////////////
|
||
|
||
void _MysteryRecurseRemoveArray(object oShadow, string sArrayName, string sMystFile, int nArraySize, int nCurIndex)
|
||
{
|
||
if(DEBUG) DoDebug("_MysteryRecurseRemoveArray():\n"
|
||
+ "oShadow = " + DebugObject2Str(oShadow) + "\n"
|
||
+ "sArrayName = '" + sArrayName + "'\n"
|
||
+ "sMystFile = '" + sMystFile + "'\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("_MysteryRecurseRemoveArray(): Running itemproperty removal loop.");
|
||
// Loop over itemproperties on the skin and remove each match
|
||
object oSkin = GetPCSkin(oShadow);
|
||
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(oShadow, "PRC_MystFeatRemovalMarker_" + IntToString(GetItemPropertySubType(ipTest)))
|
||
)
|
||
{
|
||
if(DEBUG) DoDebug("_MysteryRecurseRemoveArray(): Removing bonus feat itemproperty:\n" + DebugIProp2Str(ipTest));
|
||
// If so, remove it
|
||
RemoveItemProperty(oSkin, ipTest);
|
||
DeleteLocalInt(oShadow, "PRC_MystFeatRemovalMarker_" + IntToString(GetItemPropertySubType(ipTest)));
|
||
}
|
||
|
||
ipTest = GetNextItemProperty(oSkin);
|
||
}
|
||
}
|
||
// Still parsing the array
|
||
else
|
||
{
|
||
int nMystID = GetPowerfileIndexFromSpellID(persistant_array_get_int(oShadow, sArrayName, nCurIndex));
|
||
// Set the marker
|
||
string sName = "PRC_MystFeatRemovalMarker_" + Get2DACache(sMystFile, "IPFeatID", nMystID);
|
||
if(DEBUG) DoDebug("_MysteryRecurseRemoveArray(): Recursing through array, marker set:\n" + sName);
|
||
SetLocalInt(oShadow, sName, TRUE);
|
||
|
||
string sPathArray = _MYSTERY_LIST_PATH + "_" + Get2DACache(sMystFile, "Path", nMystID);
|
||
SetPersistantLocalInt(oShadow, sPathArray,
|
||
GetPersistantLocalInt(oShadow, sPathArray) - 1);
|
||
|
||
// Recurse to next array index
|
||
_MysteryRecurseRemoveArray(oShadow, sArrayName, sMystFile, nArraySize, nCurIndex + 1);
|
||
}
|
||
}
|
||
|
||
void _RemoveMysteryArray(object oShadow, int nList, int nLevel)
|
||
{
|
||
if(DEBUG) DoDebug("_RemoveMysteryArray():\n"
|
||
+ "oShadow = " + DebugObject2Str(oShadow) + "\n"
|
||
+ "nList = " + IntToString(nList) + "\n"
|
||
);
|
||
|
||
string sBase = _MYSTERY_LIST_NAME_BASE + IntToString(nList);
|
||
string sArray = sBase + _MYSTERY_LIST_LEVEL_ARRAY + IntToString(nLevel);
|
||
int nSize = persistant_array_get_size(oShadow, sArray);
|
||
|
||
// Reduce the total by the array size
|
||
SetPersistantLocalInt(oShadow, sBase + _MYSTERY_LIST_TOTAL_KNOWN,
|
||
GetPersistantLocalInt(oShadow, sBase + _MYSTERY_LIST_TOTAL_KNOWN) - nSize
|
||
);
|
||
|
||
// Remove each Mystery in the array
|
||
_MysteryRecurseRemoveArray(oShadow, sArray, GetAMSDefinitionFileName(nList), nSize, 0);
|
||
|
||
// Remove the array itself
|
||
persistant_array_delete(oShadow, sArray);
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////
|
||
/* Function definitions */
|
||
//////////////////////////////////////////////////
|
||
|
||
int AddMysteryKnown(object oShadow, int nList, int n2daRow, int bLevelDependent = FALSE, int nLevelToTieTo = -1)
|
||
{
|
||
string sBase = _MYSTERY_LIST_NAME_BASE + IntToString(nList);
|
||
string sArray = sBase;
|
||
string sPowerFile = GetAMSDefinitionFileName(/*PowerListToClassType(*/nList/*)*/);
|
||
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(oShadow);
|
||
|
||
sArray += _MYSTERY_LIST_LEVEL_ARRAY + IntToString(nLevelToTieTo);
|
||
}
|
||
else
|
||
{
|
||
sArray += _MYSTERY_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.
|
||
for(i = 1; i <= GetHitDice(oShadow); i++)
|
||
{
|
||
sTestArray = sBase + _MYSTERY_LIST_LEVEL_ARRAY + IntToString(i);
|
||
if(persistant_array_exists(oShadow, sTestArray))
|
||
{
|
||
nSize = persistant_array_get_size(oShadow, sTestArray);
|
||
for(j = 0; j < nSize; j++)
|
||
if(persistant_array_get_int(oShadow, sArray, j) == nSpells2daRow)
|
||
return FALSE;
|
||
}
|
||
}
|
||
// Check the non-level-dependent array
|
||
sTestArray = sBase + _MYSTERY_LIST_GENERAL_ARRAY;
|
||
if(persistant_array_exists(oShadow, sTestArray))
|
||
{
|
||
nSize = persistant_array_get_size(oShadow, sTestArray);
|
||
for(j = 0; j < nSize; j++)
|
||
if(persistant_array_get_int(oShadow, 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(oShadow, sArray))
|
||
persistant_array_create(oShadow, sArray);
|
||
|
||
// Store the power in the array
|
||
if(persistant_array_set_int(oShadow, sArray, persistant_array_get_size(oShadow, sArray), nSpells2daRow) != SDL_SUCCESS)
|
||
{
|
||
if(DEBUG) DoDebug("shd_inc_mystknwn: AddPowerKnown(): ERROR: Unable to add power to known array\n"
|
||
+ "oShadow = " + DebugObject2Str(oShadow) + "\n"
|
||
+ "nList = " + IntToString(nList) + "\n"
|
||
+ "n2daRow = " + IntToString(n2daRow) + "\n"
|
||
+ "bLevelDependent = " + DebugBool2String(bLevelDependent) + "\n"
|
||
+ "nLevelToTieTo = " + IntToString(nLevelToTieTo) + "\n"
|
||
+ "nSpells2daRow = " + IntToString(nSpells2daRow) + "\n"
|
||
);
|
||
return FALSE;
|
||
}
|
||
|
||
// Increment Mysteries known total
|
||
SetPersistantLocalInt(oShadow, sBase + _MYSTERY_LIST_TOTAL_KNOWN,
|
||
GetPersistantLocalInt(oShadow, sBase + _MYSTERY_LIST_TOTAL_KNOWN) + 1
|
||
);
|
||
|
||
// Increment Mysteries known by path
|
||
string sPathArray = _MYSTERY_LIST_PATH + "_" + Get2DACache(sPowerFile, "Path", n2daRow);
|
||
SetPersistantLocalInt(oShadow, sPathArray,
|
||
GetPersistantLocalInt(oShadow, sPathArray) + 1);
|
||
|
||
// Give the power's control feats
|
||
object oSkin = GetPCSkin(oShadow);
|
||
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 RemoveMysteriesKnownOnLevel(object oShadow, int nLevel)
|
||
{
|
||
if(DEBUG) DoDebug("shd_inc_mystknwn: RemoveMysteryKnownOnLevel():\n"
|
||
+ "oShadow = " + DebugObject2Str(oShadow) + "\n"
|
||
+ "nLevel = " + IntToString(nLevel) + "\n"
|
||
);
|
||
|
||
string sPostFix = _MYSTERY_LIST_LEVEL_ARRAY + IntToString(nLevel);
|
||
// For each Mystery list, determine if an array exists for this level.
|
||
if(persistant_array_exists(oShadow, _MYSTERY_LIST_NAME_BASE + IntToString(MYSTERY_LIST_SHADOWCASTER) + sPostFix))
|
||
// If one does exist, clear it
|
||
_RemoveMysteryArray(oShadow, MYSTERY_LIST_SHADOWCASTER, nLevel);
|
||
|
||
if(persistant_array_exists(oShadow, _MYSTERY_LIST_NAME_BASE + IntToString(MYSTERY_LIST_SHADOWSMITH) + sPostFix))
|
||
_RemoveMysteryArray(oShadow, MYSTERY_LIST_SHADOWSMITH, nLevel);
|
||
|
||
if(persistant_array_exists(oShadow, _MYSTERY_LIST_NAME_BASE + IntToString(MYSTERY_LIST_MISC) + sPostFix))
|
||
_RemoveMysteryArray(oShadow, MYSTERY_LIST_MISC, nLevel);
|
||
|
||
}
|
||
|
||
int GetKnownMysteriesModifier(object oShadow, int nList)
|
||
{
|
||
return GetPersistantLocalInt(oShadow, _MYSTERY_LIST_NAME_BASE + IntToString(nList) + _MYSTERY_LIST_MODIFIER);
|
||
}
|
||
|
||
void SetKnownMysteriesModifier(object oShadow, int nList, int nNewValue)
|
||
{
|
||
SetPersistantLocalInt(oShadow, _MYSTERY_LIST_NAME_BASE + IntToString(nList) + _MYSTERY_LIST_MODIFIER, nNewValue);
|
||
}
|
||
|
||
int GetMysteryCount(object oShadow, int nList)
|
||
{
|
||
return GetPersistantLocalInt(oShadow, _MYSTERY_LIST_NAME_BASE + IntToString(nList) + _MYSTERY_LIST_TOTAL_KNOWN);
|
||
}
|
||
|
||
int GetMysteryCountByPath(object oShadow, int nPath)
|
||
{
|
||
return GetPersistantLocalInt(oShadow, _MYSTERY_LIST_PATH + "_" + IntToString(nPath));
|
||
}
|
||
|
||
int GetMaxMysteryCount(object oShadow, int nList)
|
||
{
|
||
int nMaxMysteries = 0;
|
||
|
||
if(nList == MYSTERY_LIST_MISC)
|
||
{
|
||
if(DEBUG) DoDebug("GetMaxMysteryCount(): ERROR: Using unfinished power list!");
|
||
}
|
||
else
|
||
{
|
||
int nLevel = GetLevelByClass(nList, oShadow);
|
||
if (nList == GetPrimaryShadowMagicClass(oShadow))
|
||
nLevel += GetShadowMagicPRCLevels(oShadow);
|
||
string sFile = GetAMSKnownFileName(nList);
|
||
nMaxMysteries = StringToInt(Get2DACache(sFile, "Mysteries", nLevel - 1));
|
||
|
||
// Calculate feats
|
||
|
||
// Add in the custom modifier
|
||
nMaxMysteries += GetKnownMysteriesModifier(oShadow, nList);
|
||
if(DEBUG) DoDebug("GetMaxMysteryCount(): " + IntToString(nList) + " Mysteries: " + IntToString(nMaxMysteries));
|
||
}
|
||
|
||
return nMaxMysteries;
|
||
}
|
||
|
||
int GetHasMystery(int nMystery, object oShadow = OBJECT_SELF)
|
||
{
|
||
if((GetLevelByClass(CLASS_TYPE_SHADOWCASTER, oShadow)
|
||
&& GetHasFeat(GetClassFeatFromPower(nMystery, CLASS_TYPE_SHADOWCASTER), oShadow)
|
||
) ||
|
||
(GetLevelByClass(CLASS_TYPE_SHADOWSMITH, oShadow)
|
||
&& GetHasFeat(GetClassFeatFromPower(nMystery, CLASS_TYPE_SHADOWSMITH), oShadow)
|
||
)
|
||
// add new classes here
|
||
)
|
||
return TRUE;
|
||
return FALSE;
|
||
}
|
||
|
||
string DebugListKnownMysteries(object oShadow)
|
||
{
|
||
string sReturn = "Mysteries known by " + DebugObject2Str(oShadow) + ":\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 = MYSTERY_LIST_SHADOWCASTER; sReturn += "SHADOWCASTER"; break;
|
||
case 2: nPowerList = MYSTERY_LIST_SHADOWSMITH; sReturn += "SHADOWSMITH"; break;
|
||
|
||
// This should always be last
|
||
case 6: nPowerList = MYSTERY_LIST_MISC; sReturn += "Misceallenous"; break;
|
||
}
|
||
sReturn += " Mysteries known:\n";
|
||
|
||
// Determine if the character has any Mysteries from this list
|
||
sPowerFile = GetAMSDefinitionFileName(nPowerList);
|
||
sArrayBase = _MYSTERY_LIST_NAME_BASE + IntToString(nPowerList);
|
||
|
||
// Loop over levels
|
||
for(j = 1; j <= GetHitDice(oShadow); j++)
|
||
{
|
||
sArray = sArrayBase + _MYSTERY_LIST_LEVEL_ARRAY + IntToString(j);
|
||
if(persistant_array_exists(oShadow, sArray))
|
||
{
|
||
sReturn += " Gained on level " + IntToString(j) + ":\n";
|
||
nSize = persistant_array_get_size(oShadow, sArray);
|
||
for(k = 0; k < nSize; k++)
|
||
sReturn += " " + GetStringByStrRef(StringToInt(Get2DACache(sPowerFile, "Name",
|
||
GetPowerfileIndexFromSpellID(persistant_array_get_int(oShadow, sArray, k))
|
||
)
|
||
)
|
||
)
|
||
+ "\n";
|
||
}
|
||
}
|
||
|
||
// Non-leveldependent Mysteries
|
||
sArray = sArrayBase + _MYSTERY_LIST_GENERAL_ARRAY;
|
||
if(persistant_array_exists(oShadow, sArray))
|
||
{
|
||
sReturn += " Non-leveldependent:\n";
|
||
nSize = persistant_array_get_size(oShadow, sArray);
|
||
for(k = 0; k < nSize; k++)
|
||
sReturn += " " + GetStringByStrRef(StringToInt(Get2DACache(sPowerFile, "Name",
|
||
GetPowerfileIndexFromSpellID(persistant_array_get_int(oShadow, sArray, k))
|
||
)
|
||
)
|
||
)
|
||
+ "\n";
|
||
}
|
||
}
|
||
|
||
return sReturn;
|
||
}
|
||
|
||
int GetMaxMysteryLevelLearnable(object oShadow, int nClass, int nType)
|
||
{
|
||
if(DEBUG) DoDebug("GetMaxMysteryLevelLearnable nType: " + IntToString(nType));
|
||
|
||
// Rules Quote:
|
||
// Within a category<72>Apprentice, Initiate, Master<65>you must have at least two mysteries of any given level
|
||
// before you can take any mysteries of the next higher level. For instance, you must have two 1st-level
|
||
// mysteries before you can take any 2nds, and at least two 2nds before you can take any 3rds.
|
||
int nMaxLrn, i, nMystLevel, nCount1, nCount2;
|
||
string sFeatID;
|
||
int nLevel = GetLevelByClass(nClass, oShadow);
|
||
if (nClass == GetPrimaryShadowMagicClass(oShadow))
|
||
nLevel += GetShadowMagicPRCLevels(oShadow);
|
||
if(DEBUG) DoDebug("GetMaxMysteryLevelLearnable nClass: " + IntToString(nClass));
|
||
string sPowerFile = GetAMSDefinitionFileName(nClass);
|
||
if(DEBUG) DoDebug("GetMaxMysteryLevelLearnable sPowerFile: " + sPowerFile);
|
||
|
||
if (nType == 3 && nLevel >= 13 && nClass == CLASS_TYPE_SHADOWCASTER) // Master mysteries, must be minimum 13th level
|
||
{
|
||
for(i = 0; i < GetPRCSwitch(FILE_END_CLASS_POWER) ; i++)
|
||
{
|
||
sFeatID = Get2DACache(sPowerFile, "FeatID", i);
|
||
if(sFeatID != "" && GetHasFeat(StringToInt(sFeatID), oShadow)) // Make sure it's not a blank mystery and that the PC has it
|
||
{
|
||
nMystLevel = StringToInt(Get2DACache(sPowerFile, "Level", i));
|
||
if (nMystLevel == 7) nCount1++;
|
||
else if (nMystLevel == 8) nCount2++; // Don't need to check for 9th because 10th don't exist
|
||
}
|
||
}
|
||
//DoDebug("GetMaxMysteryLevelLearnable nCount1: " + IntToString(nCount1));
|
||
//DoDebug("GetMaxMysteryLevelLearnable nCount2: " + IntToString(nCount2));
|
||
if (nCount2 > 1) // Need to know at least two
|
||
nMaxLrn = 9;
|
||
else if (nCount1 > 1) // Need to know at least two
|
||
nMaxLrn = 8;
|
||
else // At 13th level you get access to 7ths regardless
|
||
nMaxLrn = 7;
|
||
}
|
||
else if (nType == 2 && nLevel >= 7 && nClass == CLASS_TYPE_SHADOWCASTER) // Initiate mysteries
|
||
{
|
||
for(i = 0; i < GetPRCSwitch(FILE_END_CLASS_POWER) ; i++)
|
||
{
|
||
sFeatID = Get2DACache(sPowerFile, "FeatID", i);
|
||
if(sFeatID != "" && GetHasFeat(StringToInt(sFeatID), oShadow)) // Make sure it's not a blank mystery and that the PC has it
|
||
{
|
||
nMystLevel = StringToInt(Get2DACache(sPowerFile, "Level", i));
|
||
if (nMystLevel == 4) nCount1++;
|
||
else if (nMystLevel == 5) nCount2++; // Don't need to check for 6th because 7th is triggered by level
|
||
}
|
||
}
|
||
//DoDebug("GetMaxMysteryLevelLearnable nCount1: " + IntToString(nCount1));
|
||
//DoDebug("GetMaxMysteryLevelLearnable nCount2: " + IntToString(nCount2));
|
||
if (nCount2 > 1) // Need to know at least two
|
||
nMaxLrn = 6;
|
||
else if (nCount1 > 1) // Need to know at least two
|
||
nMaxLrn = 5;
|
||
else // At 7th level you get access to 4ths regardless
|
||
nMaxLrn = 4;
|
||
}
|
||
else // Apprentice mysteries
|
||
{
|
||
for(i = 0; i < GetPRCSwitch(FILE_END_CLASS_POWER) ; i++)
|
||
{
|
||
sFeatID = Get2DACache(sPowerFile, "FeatID", i);
|
||
if(sFeatID != "" && GetHasFeat(StringToInt(sFeatID), oShadow)) // Make sure it's not a blank mystery and that the PC has it
|
||
{
|
||
nMystLevel = StringToInt(Get2DACache(sPowerFile, "Level", i));
|
||
if (nMystLevel == 1) nCount1++;
|
||
else if (nMystLevel == 2) nCount2++; // Don't need to check for 3rd because 4th is triggered by level
|
||
}
|
||
}
|
||
//DoDebug("GetMaxMysteryLevelLearnable nCount1: " + IntToString(nCount1));
|
||
//DoDebug("GetMaxMysteryLevelLearnable nCount2: " + IntToString(nCount2));
|
||
if (nCount2 > 1) // Need to know at least two
|
||
nMaxLrn = 3;
|
||
else if (nCount1 > 1) // Need to know at least two
|
||
nMaxLrn = 2;
|
||
else // At 1st level you get access to 1st regardless
|
||
nMaxLrn = 1;
|
||
}
|
||
|
||
//DoDebug("GetMaxMysteryLevelLearnable nMaxLrn: " + IntToString(nMaxLrn));
|
||
|
||
return nMaxLrn;
|
||
}
|
||
|
||
int GetCompletedPaths(object oShadow)
|
||
{
|
||
int i, nReturn, nPath;
|
||
for(i = 0; i < 24; i++)
|
||
{
|
||
//if(DEBUG) DoDebug("GetCompletedPaths(): i " + IntToString(i));
|
||
nPath = GetMysteryCountByPath(oShadow, i);
|
||
//if(DEBUG) DoDebug("GetCompletedPaths(): nPath " + IntToString(nPath));
|
||
if(nPath == 3) // Completed Path
|
||
nReturn++; //Number of completed paths
|
||
}
|
||
|
||
//if(DEBUG) DoDebug("GetCompletedPaths(): nReturn " + IntToString(nReturn));
|
||
// Return the total
|
||
return nReturn;
|
||
}
|
||
|
||
void AddPathBonusFeat(object oShadow, int nFeat)
|
||
{
|
||
if (GetHasFeat(nFeat, oShadow)) return; // No point adding something they've got
|
||
|
||
int nCount, i;
|
||
for(i = 1; i < 7 ; i++)
|
||
{
|
||
if (GetPersistantLocalInt(oShadow, "PathBonus"+IntToString(i)) > 0) // Make sure to only fill empty ones
|
||
nCount++;
|
||
}
|
||
|
||
SetPersistantLocalInt(oShadow, "PathBonus"+IntToString(nCount + 1), nFeat);
|
||
|
||
// Give the power's control feats
|
||
object oSkin = GetPCSkin(oShadow);
|
||
int nIPFeat = PathFeatToIPFeat(nFeat);
|
||
itemproperty ipFeat = PRCItemPropertyBonusFeat(nIPFeat);
|
||
IPSafeAddItemProperty(oSkin, ipFeat, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||
}
|
||
|
||
int GetPathBonusFeats(object oShadow)
|
||
{
|
||
int nCount, i;
|
||
for(i = 1; i < 7 ; i++)
|
||
{
|
||
if (GetPersistantLocalInt(oShadow, "PathBonus"+IntToString(i)) > 0) // Count filled ones
|
||
nCount++;
|
||
}
|
||
|
||
return nCount;
|
||
}
|
||
|
||
void ReapplyPathBonusFeat(object oShadow)
|
||
{
|
||
int nFeat, i;
|
||
object oSkin = GetPCSkin(oShadow);
|
||
for(i = 1; i < 7 ; i++)
|
||
{
|
||
nFeat = GetPersistantLocalInt(oShadow, "PathBonus"+IntToString(i));
|
||
if (nFeat > 0 && !GetHasFeat(nFeat, oShadow))// Only apply if it's a valid feat they don't have
|
||
{
|
||
int nIPFeat = PathFeatToIPFeat(nFeat);
|
||
itemproperty ipFeat = PRCItemPropertyBonusFeat(nIPFeat);
|
||
IPSafeAddItemProperty(oSkin, ipFeat, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||
}
|
||
}
|
||
}
|
||
|
||
int PathFeatToIPFeat(int nFeat)
|
||
{
|
||
int nIPFeat = -1;
|
||
switch(nFeat)
|
||
{
|
||
case FEAT_PATH_FOCUS_CLOAK_SHADOWS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_CLOAK_SHADOWS ; break;
|
||
case FEAT_PATH_FOCUS_DARK_TERRAIN : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_DARK_TERRAIN ; break;
|
||
case FEAT_PATH_FOCUS_EBON_WHISPERS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_EBON_WHISPERS ; break;
|
||
case FEAT_PATH_FOCUS_EYES_DARKNESS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_EYES_DARKNESS ; break;
|
||
case FEAT_PATH_FOCUS_SHUTTERS_CLOUDS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_SHUTTERS_CLOUDS ; break;
|
||
case FEAT_PATH_FOCUS_TOUCH_TWILIGHT : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_TOUCH_TWILIGHT ; break;
|
||
case FEAT_PATH_FOCUS_UMBRAL_MIND : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_UMBRAL_MIND ; break;
|
||
case FEAT_PATH_FOCUS_BLACK_MAGIC : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_BLACK_MAGIC ; break;
|
||
case FEAT_PATH_FOCUS_BODY_SOUL : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_BODY_SOUL ; break;
|
||
case FEAT_PATH_FOCUS_DARK_REFLECTIONS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_DARK_REFLECTIONS ; break;
|
||
case FEAT_PATH_FOCUS_EBON_ROADS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_EBON_ROADS ; break;
|
||
case FEAT_PATH_FOCUS_ELEMENTAL_SHADOWS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_ELEMENTAL_SHADOWS ; break;
|
||
case FEAT_PATH_FOCUS_UNBINDING_SHADE : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_UNBINDING_SHADE ; break;
|
||
case FEAT_PATH_FOCUS_VEIL_SHADOWS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_VEIL_SHADOWS ; break;
|
||
case FEAT_PATH_FOCUS_BREATH_TWILIGHT : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_BREATH_TWILIGHT ; break;
|
||
case FEAT_PATH_FOCUS_DARK_METAMORPHOSIS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_DARK_METAMORPHOSIS ; break;
|
||
case FEAT_PATH_FOCUS_EBON_WALLS : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_EBON_WALLS ; break;
|
||
case FEAT_PATH_FOCUS_EYES_NIGHT_SKY : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_EYES_NIGHT_SKY ; break;
|
||
case FEAT_PATH_FOCUS_HEART_SOUL : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_HEART_SOUL ; break;
|
||
case FEAT_PATH_FOCUS_SHADOW_CALLING : nIPFeat = IP_CONST_FEAT_PATH_FOCUS_SHADOW_CALLING ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_CLOAK_SHADOWS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_CLOAK_SHADOWS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_DARK_TERRAIN : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_DARK_TERRAIN ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_EBON_WHISPERS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_EBON_WHISPERS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_EYES_DARKNESS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_EYES_DARKNESS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_SHUTTERS_CLOUDS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_SHUTTERS_CLOUDS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_TOUCH_TWILIGHT : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_TOUCH_TWILIGHT ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_UMBRAL_MIND : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_UMBRAL_MIND ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_BLACK_MAGIC : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_BLACK_MAGIC ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_BODY_SOUL : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_BODY_SOUL ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_DARK_REFLECTIONS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_DARK_REFLECTIONS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_EBON_ROADS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_EBON_ROADS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_ELEMENTAL_SHADOWS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_ELEMENTAL_SHADOWS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_UNBINDING_SHADE : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_UNBINDING_SHADE ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_VEIL_SHADOWS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_VEIL_SHADOWS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_BREATH_TWILIGHT : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_BREATH_TWILIGHT ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_DARK_METAMORPHOSIS: nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_DARK_METAMORPHOSIS; break;
|
||
case FEAT_GREATER_PATH_FOCUS_EBON_WALLS : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_EBON_WALLS ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_EYES_NIGHT_SKY : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_EYES_NIGHT_SKY ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_HEART_SOUL : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_HEART_SOUL ; break;
|
||
case FEAT_GREATER_PATH_FOCUS_SHADOW_CALLING : nIPFeat = IP_CONST_FEAT_GREATER_PATH_FOCUS_SHADOW_CALLING ; break;
|
||
case FEAT_NOCTURNAL_CASTER_CLOAK_SHADOWS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_CLOAK_SHADOWS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_DARK_TERRAIN : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_DARK_TERRAIN ; break;
|
||
case FEAT_NOCTURNAL_CASTER_EBON_WHISPERS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_EBON_WHISPERS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_EYES_DARKNESS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_EYES_DARKNESS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_SHUTTERS_CLOUDS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_SHUTTERS_CLOUDS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_TOUCH_TWILIGHT : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_TOUCH_TWILIGHT ; break;
|
||
case FEAT_NOCTURNAL_CASTER_UMBRAL_MIND : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_UMBRAL_MIND ; break;
|
||
case FEAT_NOCTURNAL_CASTER_BLACK_MAGIC : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_BLACK_MAGIC ; break;
|
||
case FEAT_NOCTURNAL_CASTER_BODY_SOUL : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_BODY_SOUL ; break;
|
||
case FEAT_NOCTURNAL_CASTER_DARK_REFLECTIONS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_DARK_REFLECTIONS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_EBON_ROADS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_EBON_ROADS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_ELEMENTAL_SHADOWS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_ELEMENTAL_SHADOWS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_UNBINDING_SHADE : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_UNBINDING_SHADE ; break;
|
||
case FEAT_NOCTURNAL_CASTER_VEIL_SHADOWS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_VEIL_SHADOWS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_BREATH_TWILIGHT : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_BREATH_TWILIGHT ; break;
|
||
case FEAT_NOCTURNAL_CASTER_DARK_METAMORPHOSIS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_DARK_METAMORPHOSIS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_EBON_WALLS : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_EBON_WALLS ; break;
|
||
case FEAT_NOCTURNAL_CASTER_EYES_NIGHT_SKY : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_EYES_NIGHT_SKY ; break;
|
||
case FEAT_NOCTURNAL_CASTER_HEART_SOUL : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_HEART_SOUL ; break;
|
||
case FEAT_NOCTURNAL_CASTER_SHADOW_CALLING : nIPFeat = IP_CONST_FEAT_NOCTURNAL_CASTER_SHADOW_CALLING ; break;
|
||
case FEAT_FAV_MYST_BENDPERSPECTIVE : nIPFeat = IP_CONST_FEAT_FAV_MYST_BENDPERSPECTIVE ; break;
|
||
case FEAT_FAV_MYST_CARPETSHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_CARPETSHADOW ; break;
|
||
case FEAT_FAV_MYST_DUSKANDDAWN : nIPFeat = IP_CONST_FEAT_FAV_MYST_DUSKANDDAWN ; break;
|
||
case FEAT_FAV_MYST_LIFEFADES : nIPFeat = IP_CONST_FEAT_FAV_MYST_LIFEFADES ; break;
|
||
case FEAT_FAV_MYST_MESMERIZINGSHADE : nIPFeat = IP_CONST_FEAT_FAV_MYST_MESMERIZINGSHADE ; break;
|
||
case FEAT_FAV_MYST_STEELSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_STEELSHADOWS ; break;
|
||
case FEAT_FAV_MYST_VOICEOFSHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_VOICEOFSHADOW ; break;
|
||
case FEAT_FAV_MYST_BLACKFIRE : nIPFeat = IP_CONST_FEAT_FAV_MYST_BLACKFIRE ; break;
|
||
case FEAT_FAV_MYST_CONGRESSSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_CONGRESSSHADOWS ; break;
|
||
case FEAT_FAV_MYST_FLESHFAILS : nIPFeat = IP_CONST_FEAT_FAV_MYST_FLESHFAILS ; break;
|
||
case FEAT_FAV_MYST_PIERCINGSIGHT : nIPFeat = IP_CONST_FEAT_FAV_MYST_PIERCINGSIGHT ; break;
|
||
case FEAT_FAV_MYST_SHADOWSKIN : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWSKIN ; break;
|
||
case FEAT_FAV_MYST_SIGHTECLIPSED : nIPFeat = IP_CONST_FEAT_FAV_MYST_SIGHTECLIPSED ; break;
|
||
case FEAT_FAV_MYST_THOUGHTSSHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_THOUGHTSSHADOW ; break;
|
||
case FEAT_FAV_MYST_AFRAIDOFTHEDARK : nIPFeat = IP_CONST_FEAT_FAV_MYST_AFRAIDOFTHEDARK ; break;
|
||
case FEAT_FAV_MYST_CLINGINGDARKNESS : nIPFeat = IP_CONST_FEAT_FAV_MYST_CLINGINGDARKNESS ; break;
|
||
case FEAT_FAV_MYST_DANCINGSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_DANCINGSHADOWS ; break;
|
||
case FEAT_FAV_MYST_FLICKER : nIPFeat = IP_CONST_FEAT_FAV_MYST_FLICKER ; break;
|
||
case FEAT_FAV_MYST_KILLINGSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_KILLINGSHADOWS ; break;
|
||
case FEAT_FAV_MYST_SHARPSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHARPSHADOWS ; break;
|
||
case FEAT_FAV_MYST_UMBRALTOUCH : nIPFeat = IP_CONST_FEAT_FAV_MYST_UMBRALTOUCH ; break;
|
||
case FEAT_FAV_MYST_AURAOFSHADE : nIPFeat = IP_CONST_FEAT_FAV_MYST_AURAOFSHADE ; break;
|
||
case FEAT_FAV_MYST_BOLSTER : nIPFeat = IP_CONST_FEAT_FAV_MYST_BOLSTER ; break;
|
||
case FEAT_FAV_MYST_SHADOWEVOCATION : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWEVOCATION ; break;
|
||
case FEAT_FAV_MYST_SHADOWVISION : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWVISION ; break;
|
||
case FEAT_FAV_MYST_SHADOWSFADE : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWSFADE ; break;
|
||
case FEAT_FAV_MYST_STEPINTOSHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_STEPINTOSHADOW ; break;
|
||
case FEAT_FAV_MYST_WARPSPELL : nIPFeat = IP_CONST_FEAT_FAV_MYST_WARPSPELL ; break;
|
||
case FEAT_FAV_MYST_CURTAINSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_CURTAINSHADOWS ; break;
|
||
case FEAT_FAV_MYST_DARKAIR : nIPFeat = IP_CONST_FEAT_FAV_MYST_DARKAIR ; break;
|
||
case FEAT_FAV_MYST_ECHOSPELL : nIPFeat = IP_CONST_FEAT_FAV_MYST_ECHOSPELL ; break;
|
||
case FEAT_FAV_MYST_FEIGNLIFE : nIPFeat = IP_CONST_FEAT_FAV_MYST_FEIGNLIFE ; break;
|
||
case FEAT_FAV_MYST_LANGUOR : nIPFeat = IP_CONST_FEAT_FAV_MYST_LANGUOR ; break;
|
||
case FEAT_FAV_MYST_PASSINTOSHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_PASSINTOSHADOW ; break;
|
||
case FEAT_FAV_MYST_UNRAVELDWEOMER : nIPFeat = IP_CONST_FEAT_FAV_MYST_UNRAVELDWEOMER ; break;
|
||
case FEAT_FAV_MYST_FLOODSHADOWS : nIPFeat = IP_CONST_FEAT_FAV_MYST_FLOODSHADOWS ; break;
|
||
case FEAT_FAV_MYST_GREATERSHADOWEVOCATION : nIPFeat = IP_CONST_FEAT_FAV_MYST_GREATERSHADOWEVOCATION ; break;
|
||
case FEAT_FAV_MYST_SHADOWINVESTITURE : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWINVESTITURE ; break;
|
||
case FEAT_FAV_MYST_SHADOWSTORM : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWSTORM ; break;
|
||
case FEAT_FAV_MYST_SHADOWSFADE_GREATER : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWSFADE_GREATER ; break;
|
||
case FEAT_FAV_MYST_UNVEIL : nIPFeat = IP_CONST_FEAT_FAV_MYST_UNVEIL ; break;
|
||
case FEAT_FAV_MYST_VOYAGESHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_VOYAGESHADOW ; break;
|
||
case FEAT_FAV_MYST_DARKSOUL : nIPFeat = IP_CONST_FEAT_FAV_MYST_DARKSOUL ; break;
|
||
case FEAT_FAV_MYST_EPHEMERALIMAGE : nIPFeat = IP_CONST_FEAT_FAV_MYST_EPHEMERALIMAGE ; break;
|
||
case FEAT_FAV_MYST_LIFEFADESGREATER : nIPFeat = IP_CONST_FEAT_FAV_MYST_LIFEFADESGREATER ; break;
|
||
case FEAT_FAV_MYST_PRISONNIGHT : nIPFeat = IP_CONST_FEAT_FAV_MYST_PRISONNIGHT ; break;
|
||
case FEAT_FAV_MYST_UMBRALSERVANT : nIPFeat = IP_CONST_FEAT_FAV_MYST_UMBRALSERVANT ; break;
|
||
case FEAT_FAV_MYST_TRUTHREVEALED : nIPFeat = IP_CONST_FEAT_FAV_MYST_TRUTHREVEALED ; break;
|
||
case FEAT_FAV_MYST_FARSIGHT : nIPFeat = IP_CONST_FEAT_FAV_MYST_FARSIGHT ; break;
|
||
case FEAT_FAV_MYST_GRFLESHFAILS : nIPFeat = IP_CONST_FEAT_FAV_MYST_GRFLESHFAILS ; break;
|
||
case FEAT_FAV_MYST_SHADOWPLAGUE : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWPLAGUE ; break;
|
||
case FEAT_FAV_MYST_SOULPUPPET : nIPFeat = IP_CONST_FEAT_FAV_MYST_SOULPUPPET ; break;
|
||
case FEAT_FAV_MYST_TOMBNIGHT : nIPFeat = IP_CONST_FEAT_FAV_MYST_TOMBNIGHT ; break;
|
||
case FEAT_FAV_MYST_UMBRALBODY : nIPFeat = IP_CONST_FEAT_FAV_MYST_UMBRALBODY ; break;
|
||
case FEAT_FAV_MYST_ARMYSHADOW : nIPFeat = IP_CONST_FEAT_FAV_MYST_ARMYSHADOW ; break;
|
||
case FEAT_FAV_MYST_CONSUMEESSENCE : nIPFeat = IP_CONST_FEAT_FAV_MYST_CONSUMEESSENCE ; break;
|
||
case FEAT_FAV_MYST_EPHEMERALSTORM : nIPFeat = IP_CONST_FEAT_FAV_MYST_EPHEMERALSTORM ; break;
|
||
case FEAT_FAV_MYST_REFLECTIONS : nIPFeat = IP_CONST_FEAT_FAV_MYST_REFLECTIONS ; break;
|
||
case FEAT_FAV_MYST_SHADOWSURGE : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWSURGE ; break;
|
||
case FEAT_FAV_MYST_SHADOWTIME : nIPFeat = IP_CONST_FEAT_FAV_MYST_SHADOWTIME ; break;
|
||
case FEAT_SHADOW_CAST : nIPFeat = IP_CONST_FEAT_SHADOW_CAST ; break;
|
||
case FEAT_EMPOWER_MYSTERY : nIPFeat = IP_CONST_FEAT_EMPOWER_MYSTERY ; break;
|
||
case FEAT_EXTEND_MYSTERY : nIPFeat = IP_CONST_FEAT_EXTEND_MYSTERY ; break;
|
||
case FEAT_MAXIMIZE_MYSTERY : nIPFeat = IP_CONST_FEAT_MAXIMIZE_MYSTERY ; break;
|
||
case FEAT_QUICKEN_MYSTERY : nIPFeat = IP_CONST_FEAT_QUICKEN_MYSTERY ; break;
|
||
case FEAT_STILL_MYSTERY : nIPFeat = IP_CONST_FEAT_STILL_MYSTERY ; break;
|
||
}
|
||
|
||
return nIPFeat;
|
||
} |