PRC8/nwn/nwnprc/trunk/include/tob_inc_recovery.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

650 lines
22 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Tome of Battle include: Maneuver Recovery
//:: tob_inc_martlore
//::///////////////////////////////////////////////
/** @file
Defines various functions and other stuff that
do something related to recovery and readying maneuvers
See page #28 of Tome of Battle
Functions below are called by the initiator as
he makes a maneuver, or when recovering or readying
@author Stratovarius
@date Created - 2007.3.25
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Test Void
//void main (){}
//////////////////////////////////////////////////
/* Constants */
//////////////////////////////////////////////////
const int MANEUVER_READIED = 1;
const int MANEUVER_RECOVERED = 2;
const int MANEUVER_GRANTED = 3;
const int MANEVUER_WITHHELD = 4;
const string _MANEUVER_LIST_RDYMODIFIER = "_ReadyModifier";
//////////////////////////////////////////////////
/* Function prototypes */
//////////////////////////////////////////////////
/**
* Gets the number of Maneuvers a character has readied
*
* @param oPC The creature whose Maneuvers to check
* @param nList The list to check. One of MANEUVER_LIST_*
* @return The number of Maneuvers readied
*/
int GetReadiedCount(object oPC, int nList);
/**
* Gets the maximum number of Maneuvers a character may ready.
*
* @param oPC Character to determine maximum Maneuvers readied
* @param nList MANEUVER_LIST_* of the list to determine maximum Maneuvers for
* @return Maximum number of Maneuvers that oPC may ready
*/
int GetMaxReadiedCount(object oPC, int nList);
/**
* Gets the value of the Maneuvers readied modifier, which is a value that is added
* to the 2da-specified maximum Maneuvers readied to determine the actual maximum.
*
* @param oCreature The creature whose modifier to get
* @param nList The list the maximum Maneuvers readied from which the modifier
* modifies. One of MANEUVER_LIST_*
*/
int GetReadiedManeuversModifier(object oCreature, int nList);
/**
* Sets the value of the Maneuvers readied modifier, which is a value that is added
* to the 2da-specified maximum Maneuvers readied to determine the actual maximum.
*
* @param oCreature The creature whose modifier to set
* @param nList The list the maximum Maneuvers readied from which the modifier
* modifies. One of MANEUVER_LIST_*
*/
void SetReadiedManeuversModifier(object oCreature, int nList, int nNewValue);
/**
* Readies the chosen Maneuver. Also checks to see if there are any slots left
*
* @param oPC Character readying maneuver
* @param nList MANEUVER_LIST_* of the list to ready
* @param nMoveId Maneuver to ready
*/
void ReadyManeuver(object oPC, int nList, int nMoveId);
/**
* Returns whether maneuver is readied or not
*
* @param oPC Character to check
* @param nList MANEUVER_LIST_*
* @param nMoveId Maneuver to check
* @return TRUE or FALSE
*/
int GetIsManeuverReadied(object oPC, int nList, int nMoveId);
/**
* Returns whether maneuver is expended or not
*
* @param oPC Character to check
* @param nList MANEUVER_LIST_*
* @param nMoveId Maneuver to check
* @return TRUE or FALSE
*/
int GetIsManeuverExpended(object oPC, int nList, int nMoveId);
/**
* Expends the chosen Maneuver.
*
* @param oPC Character to check
* @param nList MANEUVER_LIST_*
* @param nMoveId Maneuver to expend
*/
void ExpendManeuver(object oPC, int nList, int nMoveId);
/**
* Clears all local ints marking maneuvers as expended
*
* @param oPC Character to clear
* @param nList MANEUVER_LIST_*
*/
void RecoverExpendedManeuvers(object oPC, int nList);
/**
* Recovers the chosen Maneuver.
*
* @param oPC Character to check
* @param nList MANEUVER_LIST_*
* @param nMoveId Maneuver to recover
*/
void RecoverManeuver(object oPC, int nList, int nMoveId);
/**
* Checks to see if the PC is in a Warblade recovery round
* This prevents all use of maneuvers or stances during that round.
*
* @param oPC Character to clear
* @return TRUE or FALSE
*/
int GetIsWarbladeRecoveryRound(object oPC);
/**
* Marks maneuvers as granted or withheld.
*
* @param oPC Character to grant maneuvers to
* @param nList MANEUVER_LIST_*
*/
void GrantManeuvers(object oPC, int nList);
/**
* Clears all local ints marking maneuvers as readied
*
* @param oPC Character to clear
* @param nList MANEUVER_LIST_*
*/
void ClearReadiedManeuvers(object oPC, int nList);
/**
* Grants a withheld maneuver
* Only works on Crusaders
*
* @param oPC Character to grant maneuvers to
* @param nList MANEUVER_LIST_*
* @param nMoveId Maneuver to grant
*/
void GrantWithheldManeuver(object oPC, int nList, int nMoveId = -1);
/**
* Returns whether maneuver is granted or not
* Only works on Crusaders
*
* @param oPC Character to check
* @param nMoveId Maneuver to check
* @return TRUE or FALSE
*/
int GetIsManeuverGranted(object oPC, int nMoveId);
/**
* Clears all local ints marking maneuvers as granted or withheld
* Only works on Crusaders
*
* @param oPC Character to clear
*/
void ClearGrantedWithheldManeuvers(object oPC);
/**
* Starting function for Crusader recovery, calls DoCrusaderGranting
* Only works on Crusaders
*
* @param oPC Crusader
*/
void BeginCrusaderGranting(object oPC);
/**
* Recursive function granting maneuvers each round in combat
* Will end when combat ends
* Only works on Crusaders
*
* @param oPC Crusader
* @param nTrip Round of combat. Takes values from 1 to 5, always starts with 1.
*/
void DoCrusaderGranting(object oPC, int nTrip);
/**
* Returns TRUE if a maneuver was expended, FALSE otherwise
* @param oPC Character to check
* @param nList MANEUVER_LIST_*
* @param nDiscipline DISCIPLINE_* the maneuver has to be from
*
* @return TRUE or FALSE
*/
int ExpendRandomManeuver(object oPC, int nList, int nDiscipline = -1);
/**
* Clears all local ints marking maneuvers as expended
*
* @param oPC Character to clear
* @param nPRC Specific PRC to recover, else all.
*/
void RecoverPrCAbilities(object oPC);
/**
* Heals 3 + 1 point per character level ones per minute
*
* @param oPC Character to heal
*/
void VitalRecovery(object oPC);
//////////////////////////////////////////////////
/* Includes */
//////////////////////////////////////////////////
#include "inc_lookups"
#include "tob_inc_tobfunc"
//////////////////////////////////////////////////
/* Internal functions */
//////////////////////////////////////////////////
//////////////////////////////////////////////////
/* Function definitions */
//////////////////////////////////////////////////
int GetReadiedCount(object oPC, int nList)
{
return GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList));
}
int GetMaxReadiedCount(object oPC, int nList)
{
int nLevel = GetLevelByClass(nList, oPC);
// 2das start at Row 0
int nMaxReadied = StringToInt(Get2DACache(GetAMSKnownFileName(nList), "ManeuversReadied", nLevel-1));
// Add in the custom modifier
nMaxReadied += GetReadiedManeuversModifier(oPC, nList);
if(nList == MANEUVER_LIST_SWORDSAGE)
nMaxReadied += GetHasFeat(FEAT_EXTRA_GRANTED_MANEUVER, oPC);
if(DEBUG) DoDebug("tob_inc_recovery: MaxManeuvers Readied: " +IntToString(nMaxReadied));
return nMaxReadied;
}
int GetReadiedManeuversModifier(object oCreature, int nList)
{
return GetPersistantLocalInt(oCreature, _MANEUVER_LIST_NAME_BASE + IntToString(nList) + _MANEUVER_LIST_RDYMODIFIER);
}
void SetReadiedManeuversModifier(object oCreature, int nList, int nNewValue)
{
SetPersistantLocalInt(oCreature, _MANEUVER_LIST_NAME_BASE + IntToString(nList) + _MANEUVER_LIST_RDYMODIFIER, nNewValue);
}
void ReadyManeuver(object oPC, int nList, int nMoveId)
{
int nCount = GetReadiedCount(oPC, nList);
int nMaxCount = GetMaxReadiedCount(oPC, nList);
// If the PC can ready a maneuver and hasn't filled them all up
if(nMaxCount > nCount)
{
nCount++;
SetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(nCount), nMoveId);
SetLocalInt(oPC, "ManeuverReadied" + IntToString(nList), nCount);
if(DEBUG) DoDebug("tob_inc_recovery: ReadyManeuver: " +IntToString(nMoveId));
}
else
FloatingTextStringOnCreature("All maneuvers are readied", oPC, FALSE);
}
int GetIsManeuverReadied(object oPC, int nList, int nMoveId)
{
// Counting through the local ints to determine if this one is readied
int i, nMax = GetReadiedCount(oPC, nList);
for(i = 1; i <= nMax; i++)
{
// If the value is valid, return true
if(GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i)) == nMoveId)
{
if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverReadied: " + IntToString(nMoveId));
return TRUE;
}
}
return FALSE;
}
int GetIsManeuverExpended(object oPC, int nList, int nMoveId)
{
// Counting through the local ints to determine if this one is expended
int i, nMax = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList));
for(i = 1; i <= nMax; i++)
{
// returns if the maneuver is expended
if(GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i)) == nMoveId)
{
if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverExpended: " +IntToString(nMoveId));
return TRUE;
}
}
return FALSE;
}
void ExpendManeuver(object oPC, int nList, int nMoveId)
{
int nCount = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList)) + 1;
// This will mark the Maneuver Expended
SetLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(nCount), nMoveId);
SetLocalInt(oPC, "ManeuverExpended" + IntToString(nList), nCount);
if(DEBUG) DoDebug("tob_inc_recovery: Expending Maneuver: " + IntToString(nMoveId));
}
void RecoverExpendedManeuvers(object oPC, int nList)
{
if(DEBUG) DoDebug("tob_inc_recovery: Clearing expended maneuvers");
// Counting through the local ints to clear them all
int i, nMax = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList));
DeleteLocalInt(oPC, "ManeuverExpended" + IntToString(nList));
for(i = 1; i <= nMax; i++)
{
// Clear them all
DeleteLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i));
}
// Do Grant/Withheld Maneuvers whenever this is called on a Crusader
if (nList == MANEUVER_LIST_CRUSADER)
{
// Make sure to clear them all first
ClearGrantedWithheldManeuvers(oPC);
// Then re-grant/withhold them
GrantManeuvers(oPC, nList);
}
if (GetHasFeat(FEAT_VITAL_RECOVERY, oPC)) VitalRecovery(oPC);
}
void RecoverManeuver(object oPC, int nList, int nMoveId)
{
// Counting through the local ints to determine if this one is expended
int i, nMax = GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList));
for(i = 1; i <= nMax; i++)
{
// If it has been expended, clear that
if(GetLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i)) == nMoveId)
{
DeleteLocalInt(oPC, "ManeuverExpended" + IntToString(nList) + IntToString(i));
if(DEBUG) DoDebug("tob_inc_recovery: Recovering Maneuver: " + IntToString(nMoveId));
}
}
if (GetHasFeat(FEAT_VITAL_RECOVERY, oPC)) VitalRecovery(oPC);
}
int GetIsWarbladeRecoveryRound(object oPC)
{
if(DEBUG) DoDebug("tob_inc_recovery: Warblade recovery check");
return GetLocalInt(oPC, "WarbladeRecoveryRound");
}
void GrantRandomManeuver(object oPC, int nList = MANEUVER_LIST_CRUSADER)
{
int nMax = GetLocalInt(oPC, "GrantRand#");
if(!nMax) return;//nothing to grant
SetLocalInt(oPC, "GrantRand#", nMax - 1);
int x = Random(nMax)+1;
int nMoveId = GetLocalInt(oPC, "GrantRand#" + IntToString(x));
if(x != nMax)
SetLocalInt(oPC, "GrantRand#" + IntToString(x), GetLocalInt(oPC, "GrantRand#" + IntToString(nMax)));
DeleteLocalInt(oPC, "GrantRand#" + IntToString(nMax));
//GrantWithheldManeuver(oPC, MANEUVER_LIST_CRUSADER, MoveId);
// No point in granting an expended maneuver
if(GetIsManeuverExpended(oPC, nList, nMoveId))
RecoverManeuver(oPC, nList, nMoveId);
int i = 1;
while(i)
{
// If it hits a non-valid, break
if(!GetLocalInt(oPC, "ManeuverGranted" + IntToString(i))) break;
i++;
}
SetLocalInt(oPC, "ManeuverGranted" + IntToString(i), nMoveId);
}
void ListGrantedManeuvers(object oPC)
{
int i;
for(i = 1; i <= 4; i++)
{
int nMoveId = GetLocalInt(oPC, "ManeuverGranted" + IntToString(i));
int nExpended = GetIsManeuverExpended(oPC, MANEUVER_LIST_CRUSADER, nMoveId);
if (nMoveId > 0 && !nExpended) FloatingTextStringOnCreature(GetManeuverName(nMoveId) + " is granted", oPC, FALSE);
}
}
void GrantManeuvers(object oPC, int nList = MANEUVER_LIST_CRUSADER)
{
// Only crusader level matters for this
int nLevel = GetLevelByClass(CLASS_TYPE_CRUSADER, oPC);
// 2das start at Row 0
int nGranted = StringToInt(Get2DACache(GetAMSKnownFileName(nList), "ManeuversGranted", nLevel-1));
nGranted += GetReadiedManeuversModifier(oPC, nList);
nGranted += GetHasFeat(FEAT_EXTRA_GRANTED_MANEUVER, oPC);
// Counting through the local ints to determine how many are readied
int i, nMaxReadied = GetReadiedCount(oPC, nList);
SetLocalInt(oPC, "GrantRand#", nMaxReadied);
for(i = 1; i <= nMaxReadied; i++)
{
// build temporary array for GrantRandomManeuver() function
int nMoveId = GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i));
if(nMoveId)
SetLocalInt(oPC, "GrantRand#" + IntToString(i), nMoveId);
}
for(i = 1; i <= nGranted; i++)
{
GrantRandomManeuver(oPC);
}
ListGrantedManeuvers(oPC);
}
void ClearReadiedManeuvers(object oPC, int nList)
{
if(DEBUG) DoDebug("tob_inc_recovery: Clearing readied maneuvers");
// Counting through the local ints to clear them all
int i, nMax = GetReadiedCount(oPC, nList);
DeleteLocalInt(oPC, "ManeuverReadied" + IntToString(nList));
for(i = 1; i <= nMax; i++)
{
// Clear them all
DeleteLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i));
}
}
/*void GrantWithheldManeuver(object oPC, int nList, int nMoveId = -1)
{
int i;
string sPsiFile = GetAMSKnownFileName(nList);
// 2das start at Row 0
int nLevel = GetInitiatorLevel(oPC, nList);
int nGranted = StringToInt(Get2DACache(sPsiFile, "ManeuversGranted", nLevel-1));
int nReadied = StringToInt(Get2DACache(sPsiFile, "ManeuversReadied", nLevel-1));
if(DEBUG) DoDebug("tob_inc_recovery: Maneuvers Granted: " + IntToString(nGranted));
if(DEBUG) DoDebug("tob_inc_recovery: Maneuvers Readied: " + IntToString(nReadied));
// If someone input a maneuver
if (nMoveId > 0)
{
// No point in granting an expended maneuver
if (GetIsManeuverExpended(oPC, nList, nMoveId))
RecoverManeuver(oPC, nList, nMoveId);
// 3 is always the number withheld
for(i = nGranted; i < nReadied; i++)
{
// Making sure it gets marked properly
int nGrantId = GetLocalInt(oPC, "ManeuverWithheld" + IntToString(i));
// If it exists, mark it as ready and break out
if (nMoveId == nGrantId)
{
if(DEBUG) DoDebug("tob_inc_recovery: Withheld Maneuver Granted: " + IntToString(nMoveId));
DeleteLocalInt(oPC, "ManeuverWithheld" + IntToString(i));
FloatingTextStringOnCreature(GetManeuverName(nMoveId) + " is granted", oPC, FALSE);
SetLocalInt(oPC, "ManeuverGranted" + IntToString(i), nMoveId);
break;
}
}
}
else
{
// 3 is always the number withheld
for(i = nGranted; i < nReadied; i++)
{
nMoveId = GetLocalInt(oPC, "ManeuverWithheld" + IntToString(i));
// If it exists, mark it as ready and break out
if (nMoveId > 0)
{
if(DEBUG) DoDebug("tob_inc_recovery: Withheld Maneuver Granted: " + IntToString(nMoveId));
DeleteLocalInt(oPC, "ManeuverWithheld" + IntToString(i));
FloatingTextStringOnCreature(GetManeuverName(nMoveId) + " is granted", oPC, FALSE);
SetLocalInt(oPC, "ManeuverGranted" + IntToString(i), nMoveId);
break;
}
}
}
}*/
int GetIsManeuverGranted(object oPC, int nMoveId)
{
if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverGranted Start");
// Counting through the local ints to determine if this one is expended
int i, nMax = GetReadiedCount(oPC, MANEUVER_LIST_CRUSADER);
for(i = 1; i <= nMax; i++)
{
// returns if the maneuver is expended
if(GetLocalInt(oPC, "ManeuverGranted" + IntToString(i)) == nMoveId)
{
if(DEBUG) DoDebug("tob_inc_recovery: GetIsManeuverGranted: " + IntToString(nMoveId));
return TRUE;
}
}
return FALSE;
}
void ClearGrantedWithheldManeuvers(object oPC)
{
if(DEBUG) DoDebug("tob_inc_recovery: Clearing Granted and Withheld Maneuvers");
// Counting through the local ints to clear them all
int i, nMax = GetReadiedCount(oPC, MANEUVER_LIST_CRUSADER);
for(i = 1; i <= nMax; i++)
{
// Clear them all
DeleteLocalInt(oPC, "ManeuverGranted" + IntToString(i));
}
}
void BeginCrusaderGranting(object oPC)
{
if(DEBUG) DoDebug("BeginCrusaderGranting(): Entered Function");
// Stops it from being called more than once.
if(GetLocalInt(oPC, "CrusaderGrantLoop")) return;
SetLocalInt(oPC, "CrusaderGrantLoop", TRUE);
// Starts the granting process
if(DEBUG) DoDebug("BeginCrusaderGranting(): DoCrusaderGranting called");
DoCrusaderGranting(oPC, 1);
}
void DoCrusaderGranting(object oPC, int nTrip)
{
if(DEBUG) DoDebug("DoCrusaderGranting(): Entered Function on Round #" + IntToString(nTrip));
// First round of combat, no granting.
// Last round of the 5, clear and recover/grant maneuvers
if (nTrip >= 5) // Granted maneuvers empty, restart
{
if(DEBUG) DoDebug("DoCrusaderGranting(): RecoverExpendedManeuvers");
RecoverExpendedManeuvers(oPC, MANEUVER_LIST_CRUSADER);
nTrip = 1;
}
else if (nTrip > 1)
{
// Rounds 2-4, grant a single maneuver
if(DEBUG) DoDebug("DoCrusaderGranting(): GrantWithheldManeuver");
//GrantWithheldManeuver(oPC, MANEUVER_LIST_CRUSADER);
GrantRandomManeuver(oPC);
ListGrantedManeuvers(oPC);
}
if(DEBUG) DoDebug("DoCrusaderGranting(): Above Recursive");
// If in combat, keep the loop going
if (GetIsInCombat(oPC))
{
if(DEBUG) DoDebug("DoCrusaderGranting(): In Combat");
DelayCommand(6.0, DoCrusaderGranting(oPC, ++nTrip)); // Increment counter
}
else // Recover and stop loop otherwise.
{
if(DEBUG) DoDebug("DoCrusaderGranting(): Out of Combat Maneuver Recovery");
RecoverExpendedManeuvers(oPC, MANEUVER_LIST_CRUSADER);
// Resent Int for next time out
DeleteLocalInt(oPC, "CrusaderGrantLoop");
}
if(DEBUG) DoDebug("DoCrusaderGranting(): Ending");
}
int ExpendRandomManeuver(object oPC, int nList, int nDiscipline = -1)
{
// Counting through the local ints to determine if maneuver can be expended
int i, nMax = GetReadiedCount(oPC, nList);
for(i = 1; i <= nMax; i++)
{
// If the value is valid, next step
int nMoveId = GetLocalInt(oPC, "ManeuverReadied" + IntToString(nList) + IntToString(i));
if(nMoveId > 0)
{
// Make sure the disciplines match
if(nDiscipline == -1 || GetDisciplineByManeuver(nMoveId) == nDiscipline)
{
// If not expended
if(!GetIsManeuverExpended(oPC, nList, nMoveId))
{
// Expend the damn thing and go home
ExpendManeuver(oPC, nList, nMoveId);
return TRUE;
}
}
}
}
// If we're here, failed.
return FALSE;
}
void RecoverPrCAbilities(object oPC)
{
int i;
for(i = 2; i <= 8; i++) // PrC abilities: check last seven slots
{
int nClass = GetClassByPosition(i, oPC);
if(DEBUG) DoDebug("RecoverPrCAbilities" + IntToString(nClass));
switch(nClass)
{
case CLASS_TYPE_INVALID:
if(DEBUG) DoDebug("RecoverPrCAbilities: no class to recover");
break;
case CLASS_TYPE_JADE_PHOENIX_MAGE:
DeleteLocalInt(oPC, "JPM_Empowering_Strike_Expended");
DeleteLocalInt(oPC, "JPM_Quickening_Strike_Expended");
break;
case CLASS_TYPE_DEEPSTONE_SENTINEL:
DeleteLocalInt(oPC, "DPST_Awaken_Stone_Dragon_Expended");
break;
case CLASS_TYPE_ETERNAL_BLADE:
DeleteLocalInt(oPC, "ETBL_Eternal_Training_Expended");
DeleteLocalInt(oPC, "ETBL_Island_In_Time_Expended");
// Remove bonus to racial type from eternal training
PRCRemoveEffectsFromSpell(oPC, ETBL_RACIAL_TYPE);
break;
}
}
}
void VitalRecovery(object oPC)
{
if (GetLocalInt(oPC, "VitalRecovery")) return; //Once a minute
int nHD = GetHitDice(oPC);
effect eHeal = EffectHeal(nHD+3); // That's it
effect eVis = EffectVisualEffect(VFX_IMP_HEALING_M);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
SetLocalInt(oPC, "VitalRecovery", TRUE);
DelayCommand(60.0, DeleteLocalInt(oPC, "VitalRecovery"));
}