PRC8/nwn/nwnprc/trunk/include/shd_inc_mystknwn.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
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.
2024-02-11 14:01:05 -05:00

801 lines
42 KiB
Plaintext
Raw Blame History

//::///////////////////////////////////////////////
//:: 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;
}