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

704 lines
29 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Psionics include: Augmentation
//:: psi_inc_augment
//::///////////////////////////////////////////////
/** @file
Defines structs and functions for handling
psionic power augmentation.
@author Ornedan
@date Created - 2005.11.04
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//////////////////////////////////////////////////
/* Constants */
//////////////////////////////////////////////////
// Constants are provided via psi_inc_core
/// Prefix of the local variable names used for storing an user's profiles
const string PRC_AUGMENT_PROFILE = "PRC_Augment_Profile_";
/// Index of the currently used profile.
const string PRC_CURRENT_AUGMENT_PROFILE = "PRC_Current_Augment_Profile_Index";
/// Name of local variable where override is stored
const string PRC_AUGMENT_OVERRIDE = "PRC_Augment_Override";
/// Name of local variable where the value of maximal augmentation switch is stored
const string PRC_AUGMENT_MAXAUGMENT = "PRC_Augment_MaxAugment";
/// The lowest valid value of PRC_CURRENT_AUGMENT_PROFILE
const int PRC_AUGMENT_PROFILE_INDEX_MIN = 1;
/// The highest valid value of PRC_CURRENT_AUGMENT_PROFILE
const int PRC_AUGMENT_PROFILE_INDEX_MAX = 49;
/// Prefix of the local variable names used for storing quickselections
const string PRC_AUGMENT_QUICKSELECTION = "PRC_Augment_Quickselection_";
/// The lowest value the quickslot index can have
const int PRC_AUGMENT_QUICKSELECTION_MIN = 1;
/// The highest value the quickslot index can have
const int PRC_AUGMENT_QUICKSELECTION_MAX = 7;
/// An index that should never contain a profile
const int PRC_AUGMENT_PROFILE_NONE = 0;
/// The value of an empty profile. Also known as zero
const int PRC_AUGMENT_NULL_PROFILE = 0x00000000;
/// The special value for nGenericAugCost in power augmentation profile that means the power has no generic augmentation.
const int PRC_NO_GENERIC_AUGMENTS = -1;
/// The special value for nMaxAugs_* that means there is no limit to the times that option may be used.
const int PRC_UNLIMITED_AUGMENTATION = -1;
//////////////////////////////////////////////////
/* Structures */
//////////////////////////////////////////////////
/**
* A structure used for defining how a particular power may be augmented.
* Use PowerAugmentationProfile() to create.
*/
struct power_augment_profile{
/**
* Many powers specify several augmentation options and in addition a
* "for each N PP spent augmenting this power, something happens".
* This value is that N.
*/
int nGenericAugCost;
/**
* How many PP the first augmentation option of the power will cost per
* times used.
*/
int nAugCost_1;
/**
* How many times, at most, can the first augmentation option be used.
*/
int nMaxAugs_1;
/**
* How many PP the second augmentation option of the power will cost per
* times used.
*/
int nAugCost_2;
/**
* How many times, at most, can the second augmentation option be used.
*/
int nMaxAugs_2;
/**
* How many PP the third augmentation option of the power will cost per
* times used.
*/
int nAugCost_3;
/**
* How many times, at most, can the third augmentation option be used.
*/
int nMaxAugs_3;
/**
* How many PP the fourth augmentation option of the power will cost per
* times used.
*/
int nAugCost_4;
/**
* How many times, at most, can the fourth augmentation option be used.
*/
int nMaxAugs_4;
/**
* How many PP the fifth augmentation option of the power will cost per
* times used.
*/
int nAugCost_5;
/**
* How many times, at most, can the fifth augmentation option be used.
*/
int nMaxAugs_5;
};
/**
* Users define how much PP they want to use for each augmentation option or
* how many times they want to use each option. This structure is for transferring
* that data.
*/
struct user_augment_profile{
int nOption_1;
int nOption_2;
int nOption_3;
int nOption_4;
int nOption_5;
/// Whether the values in this structure are to be interpreted as augmentation levels
/// or as amounts of PP.
int bValueIsPP;
};
//////////////////////////////////////////////////
/* Function prototypes */
//////////////////////////////////////////////////
/**
* Constructs an augmentation profile for a power.
* The default values for each parameter specify that the power in question
* does not have that augmentation feature.
*
* @param nGenericAugCost Many powers have an augmentation clause saying "for
* each N power points used to augment this power,
* X happens". This parameter is used to define the
* value N.
* Valid values: {x = -1 OR x > 0}
* Default: -1, which means that there is no generic
* augmentation for this power.
*
* @param nAugCost_1 Cost to use the first augmentation option of this
* power.
* Valid values: {x >= 0}
* Default: 0
* @param nMaxAugs_1 Number of times the first augmentation option may at
* most be used. Value of -1 means the option may be used
* an unlimited number of times.
* Valid values: {x >= -1}
* Default: 0
*
* @param nAugCost_2 Cost to use the second augmentation option of this
* power.
* Valid values: {x >= 0}
* Default: 0
* @param nMaxAugs_2 Number of times the second augmentation option may at
* most be used. Value of -1 means the option may be used
* an unlimited number of times.
* Valid values: {x >= -1}
* Default: 0 *
*
* @param nAugCost_3 Cost to use the third augmentation option of this
* power.
* Valid values: {x >= 0}
* Default: 0
* @param nMaxAugs_3 Number of times the third augmentation option may at
* most be used. Value of -1 means the option may be used
* an unlimited number of times.
* Valid values: {x >= -1}
* Default: 0
*
* @param nAugCost_4 Cost to use the fourth augmentation option of this
* power.
* Valid values: {x >= 0}
* Default: 0
* @param nMaxAugs_4 Number of times the fourth augmentation option may at
* most be used. Value of -1 means the option may be used
* an unlimited number of times.
* Valid values: {x >= -1}
* Default: 0
*
* @param nAugCost_5 Cost to use the fifth augmentation option of this
* power.
* Valid values: {x >= 0}
* Default: 0
* @param nMaxAugs_5 Number of times the fifth augmentation option may at
* most be used. Value of -1 means the option may be used
* an unlimited number of times.
* Valid values: {x >= -1}
* Default: 0
*
* @return The parameters compiled into a power_augment_profile
* structure.
*/
struct power_augment_profile PowerAugmentationProfile(int nGenericAugCost = PRC_NO_GENERIC_AUGMENTS,
int nAugCost_1 = 0, int nMaxAugs_1 = 0,
int nAugCost_2 = 0, int nMaxAugs_2 = 0,
int nAugCost_3 = 0, int nMaxAugs_3 = 0,
int nAugCost_4 = 0, int nMaxAugs_4 = 0,
int nAugCost_5 = 0, int nMaxAugs_5 = 0
);
/**
* Reads an augmentation profile from a user and compiles it into
* a structure.
*
* @param oUser A creature that has power augmentation profiles set up.
* @param nIndex The number of the profile to retrieve.
* @param bQuickSelection Whether the index is a quickselection or a normal profile.
* @return The retrieved profile, compiled into a structure
*/
struct user_augment_profile GetUserAugmentationProfile(object oUser, int nIndex, int bQuickSelection = FALSE);
/**
* Gets the user's current augmentation profile.
*
* @param oUser A creature that has power augmentation profiles set up.
* @return The retrieved profile, compiled into a structure
*/
struct user_augment_profile GetCurrentUserAugmentationProfile(object oUser);
/**
* Stores a user-specified augmentation profile.
*
* @param oUser The user for whose use to store the profile for.
* @param nIndex The index number to store the profile under.
* @param bQuickSelection Whether the index is a quickselection or a normal profile.
* @param uap A structure containing the profile to store.
*/
void StoreUserAugmentationProfile(object oUser, int nIndex, struct user_augment_profile uap, int bQuickSelection = FALSE);
/**
* Converts the given augmentation profile into a string.
*
* @param uap The augmentation profile to convert to a string.
* @return A string of format:
* Option 1: N [times|PP], Option 2: N [times|PP], Option 2: N [times|PP], Option 4: N [times|PP], Option 5: N [times|PP]
*/
string UserAugmentationProfileToString(struct user_augment_profile uap);
/**
* Calculates how many times each augmentation option of a power is used and
* the increased PP cost caused by augmentation.
* In addition to basic augmentation, currently accounts for:
* - Wild Surge
*
*
* @param manif The manifestation data related to an ongoing manifestation attempt.
* @param pap The power's augmentation profile.
* @return The manifestation data with augmentation's effects added in.
*/
struct manifestation EvaluateAugmentation(struct manifestation manif, struct power_augment_profile pap);
/**
* Overrides the given creature's augmentation settings during it's next
* manifestation with the given settings.
*
* NOTE: These values are assumed to be augmentation levels.
*
* @param oCreature Creature whose augmentation to override
* @param uap The profile to use as override
*/
void SetAugmentationOverride(object oCreature, struct user_augment_profile uap);
//////////////////////////////////////////////////
/* Includes */
//////////////////////////////////////////////////
#include "psi_inc_core"
//////////////////////////////////////////////////
/* Internal functions */
//////////////////////////////////////////////////
/** Internal function.
* @param nToDecode Integer from which to extract an user augmentation profile
* @return An user augmentation profile created based on nToDecode
*/
struct user_augment_profile _DecodeProfile(int nToDecode)
{
struct user_augment_profile uap;
// The augmentation profile is stored in one integer, with 6 bits per option.
// MSB -> [xx555555444444333333222222111111] <- LSB
int nMask = 0x3F; // 6 LSB
uap.nOption_1 = nToDecode & nMask;
uap.nOption_2 = (nToDecode >>> 6) & nMask;
uap.nOption_3 = (nToDecode >>> 12) & nMask;
uap.nOption_4 = (nToDecode >>> 18) & nMask;
uap.nOption_5 = (nToDecode >>> 24) & nMask;
return uap;
}
/** Internal function.
* @param uapToEncode An user augmentation profile to encode into a single integer
* @return Integer built from values in uapToEncode
*/
int _EncodeProfile(struct user_augment_profile uapToEncode)
{
// The augmentation profile is stored in one integer, with 6 bits per option.
// MSB -> [xx555555444444333333222222111111] <- LSB
int nProfile = PRC_AUGMENT_NULL_PROFILE;
int nMask = 0x3F; // 6 LSB
nProfile |= (uapToEncode.nOption_1 & nMask);
nProfile |= (uapToEncode.nOption_2 & nMask) << 6;
nProfile |= (uapToEncode.nOption_3 & nMask) << 12;
nProfile |= (uapToEncode.nOption_4 & nMask) << 18;
nProfile |= (uapToEncode.nOption_5 & nMask) << 24;
return nProfile;
}
//////////////////////////////////////////////////
/* Function definitions */
//////////////////////////////////////////////////
struct power_augment_profile PowerAugmentationProfile(int nGenericAugCost = PRC_NO_GENERIC_AUGMENTS,
int nAugCost_1 = 0, int nMaxAugs_1 = 0,
int nAugCost_2 = 0, int nMaxAugs_2 = 0,
int nAugCost_3 = 0, int nMaxAugs_3 = 0,
int nAugCost_4 = 0, int nMaxAugs_4 = 0,
int nAugCost_5 = 0, int nMaxAugs_5 = 0
)
{
struct power_augment_profile pap;
pap.nGenericAugCost = nGenericAugCost;
pap.nAugCost_1 = nAugCost_1;
pap.nMaxAugs_1 = nMaxAugs_1;
pap.nAugCost_2 = nAugCost_2;
pap.nMaxAugs_2 = nMaxAugs_2;
pap.nAugCost_3 = nAugCost_3;
pap.nMaxAugs_3 = nMaxAugs_3;
pap.nAugCost_4 = nAugCost_4;
pap.nMaxAugs_4 = nMaxAugs_4;
pap.nAugCost_5 = nAugCost_5;
pap.nMaxAugs_5 = nMaxAugs_5;
return pap;
}
struct user_augment_profile GetUserAugmentationProfile(object oUser, int nIndex, int bQuickSelection = FALSE)
{
int nProfile = GetPersistantLocalInt(oUser, (bQuickSelection ? PRC_AUGMENT_QUICKSELECTION : PRC_AUGMENT_PROFILE) + IntToString(nIndex));
struct user_augment_profile uap = _DecodeProfile(nProfile);
// Get the augmentation levels / PP switch
uap.bValueIsPP = GetPersistantLocalInt(oUser, PRC_PLAYER_SWITCH_AUGMENT_IS_PP);
// Validity check on the index
if(bQuickSelection ?
(nIndex < PRC_AUGMENT_QUICKSELECTION_MIN ||
nIndex > PRC_AUGMENT_QUICKSELECTION_MAX
):
(nIndex < PRC_AUGMENT_PROFILE_INDEX_MIN ||
nIndex > PRC_AUGMENT_PROFILE_INDEX_MAX
)
)
{
// Null the profile, just in case
uap.nOption_1 = 0;
uap.nOption_2 = 0;
uap.nOption_3 = 0;
uap.nOption_4 = 0;
uap.nOption_5 = 0;
}
return uap;
}
/**
* Gets the user's current augmentation profile.
*
* @param oUser A creature that has power augmentation profiles set up.
* @return The retrieved profile, compiled into a structure
*/
struct user_augment_profile GetCurrentUserAugmentationProfile(object oUser)
{
struct user_augment_profile uap_ret;
// Is augmentation override in effect?
if(GetLocalInt(oUser, PRC_AUGMENT_OVERRIDE))
{
uap_ret = _DecodeProfile(GetLocalInt(oUser, PRC_AUGMENT_OVERRIDE) - 1);
uap_ret.bValueIsPP = FALSE; // Override is always considered to be augmentation levels
}
// It wasn't, so get normally
else
{
int nIndex = GetLocalInt(oUser, PRC_CURRENT_AUGMENT_PROFILE);
int bQuick = nIndex < 0 ? TRUE : FALSE;
if(bQuick) nIndex = -nIndex;
uap_ret = GetUserAugmentationProfile(oUser, nIndex, bQuick);
}
return uap_ret;
}
void StoreUserAugmentationProfile(object oUser, int nIndex, struct user_augment_profile uap, int bQuickSelection = FALSE)
{
// Validity check on the index
if(bQuickSelection ?
(nIndex < PRC_AUGMENT_QUICKSELECTION_MIN ||
nIndex > PRC_AUGMENT_QUICKSELECTION_MAX
):
(nIndex < PRC_AUGMENT_PROFILE_INDEX_MIN ||
nIndex > PRC_AUGMENT_PROFILE_INDEX_MAX
)
)
{
if(DEBUG) DoDebug("StoreUserAugmentationProfile(): Attempt to store outside valid range: " + IntToString(nIndex));
return;
}
SetPersistantLocalInt(oUser, (bQuickSelection ? PRC_AUGMENT_QUICKSELECTION : PRC_AUGMENT_PROFILE) + IntToString(nIndex), _EncodeProfile(uap));
}
string UserAugmentationProfileToString(struct user_augment_profile uap)
{
string sBegin = GetStringByStrRef(16823498) + " "; // "Option"
string sEnd = " " + (uap.bValueIsPP ? "PP" : GetStringByStrRef(16823499)); // "times"
return sBegin + "1: " + IntToString(uap.nOption_1) + sEnd + "; "
+ sBegin + "2: " + IntToString(uap.nOption_2) + sEnd + "; "
+ sBegin + "3: " + IntToString(uap.nOption_3) + sEnd + "; "
+ sBegin + "4: " + IntToString(uap.nOption_4) + sEnd + "; "
+ sBegin + "5: " + IntToString(uap.nOption_5) + sEnd;
}
struct manifestation EvaluateAugmentation(struct manifestation manif, struct power_augment_profile pap)
{
// Get the user's augmentation profile - will be all zeroes if no profile is active
struct user_augment_profile uap = GetCurrentUserAugmentationProfile(manif.oManifester);
int nSurge = GetWildSurge(manif.oManifester);
int nAugPPCost = 0;
int nAugPPCostReductions = 0;
int bMaxAugment = GetLocalInt(manif.oManifester, PRC_AUGMENT_MAXAUGMENT) &&
!GetLocalInt(manif.oManifester, PRC_AUGMENT_OVERRIDE); // Override profile also overrides max augment
// Initialise the augmentation data in the manifestation structure to zero
/* Probably unnecessary due to auto-init
manif.nTimesAugOptUsed_1 = 0;
manif.nTimesAugOptUsed_2 = 0;
manif.nTimesAugOptUsed_3 = 0;
manif.nTimesAugOptUsed_4 = 0;
manif.nTimesAugOptUsed_5 = 0;
manif.nTimesGenericAugUsed = 0;
*/
/* Bloody duplication follows. Real arrays would be nice */
// Make sure the option is available for use and the user wants to do something with it
if(pap.nMaxAugs_1 && uap.nOption_1)
{
// Determine how many times the augmentation option has been used
manif.nTimesAugOptUsed_1 = uap.bValueIsPP ? // The user can determine whether their settings are interpreted
uap.nOption_1 / pap.nAugCost_1 : // as static PP costs
uap.nOption_1; // or as number of times to use
// Make sure the number of times the option is used does not exceed the maximum
if(pap.nMaxAugs_1 != PRC_UNLIMITED_AUGMENTATION && manif.nTimesAugOptUsed_1 > pap.nMaxAugs_1)
manif.nTimesAugOptUsed_1 = pap.nMaxAugs_1;
// Calculate the amount of PP the augmentation will cost
nAugPPCost += manif.nTimesAugOptUsed_1 * pap.nAugCost_1;
}
// Make sure the option is available for use and the user wants to do something with it
if(pap.nMaxAugs_2 && uap.nOption_2)
{
// Determine how many times the augmentation option has been used
manif.nTimesAugOptUsed_2 = uap.bValueIsPP ? // The user can determine whether their settings are interpreted
uap.nOption_2 / pap.nAugCost_2 : // as static PP costs
uap.nOption_2; // or as number of times to use
// Make sure the number of times the option is used does not exceed the maximum
if(pap.nMaxAugs_2 != PRC_UNLIMITED_AUGMENTATION && manif.nTimesAugOptUsed_2 > pap.nMaxAugs_2)
manif.nTimesAugOptUsed_2 = pap.nMaxAugs_2;
// Calculate the amount of PP the augmentation will cost
nAugPPCost += manif.nTimesAugOptUsed_2 * pap.nAugCost_2;
}
// Make sure the option is available for use and the user wants to do something with it
if(pap.nMaxAugs_3 && uap.nOption_3)
{
// Determine how many times the augmentation option has been used
manif.nTimesAugOptUsed_3 = uap.bValueIsPP ? // The user can determine whether their settings are interpreted
uap.nOption_3 / pap.nAugCost_3 : // as static PP costs
uap.nOption_3; // or as number of times to use
// Make sure the number of times the option is used does not exceed the maximum
if(pap.nMaxAugs_3 != PRC_UNLIMITED_AUGMENTATION && manif.nTimesAugOptUsed_3 > pap.nMaxAugs_3)
manif.nTimesAugOptUsed_3 = pap.nMaxAugs_3;
// Calculate the amount of PP the augmentation will cost
nAugPPCost += manif.nTimesAugOptUsed_3 * pap.nAugCost_3;
}
// Make sure the option is available for use and the user wants to do something with it
if(pap.nMaxAugs_4 && uap.nOption_4)
{
// Determine how many times the augmentation option has been used
manif.nTimesAugOptUsed_4 = uap.bValueIsPP ? // The user can determine whether their settings are interpreted
uap.nOption_4 / pap.nAugCost_4 : // as static PP costs
uap.nOption_4; // or as number of times to use
// Make sure the number of times the option is used does not exceed the maximum
if(pap.nMaxAugs_4 != PRC_UNLIMITED_AUGMENTATION && manif.nTimesAugOptUsed_4 > pap.nMaxAugs_4)
manif.nTimesAugOptUsed_4 = pap.nMaxAugs_4;
// Calculate the amount of PP the augmentation will cost
nAugPPCost += manif.nTimesAugOptUsed_4 * pap.nAugCost_4;
}
// Make sure the option is available for use and the user wants to do something with it
if(pap.nMaxAugs_5 && uap.nOption_5)
{
// Determine how many times the augmentation option has been used
manif.nTimesAugOptUsed_5 = uap.bValueIsPP ? // The user can determine whether their settings are interpreted
uap.nOption_5 / pap.nAugCost_5 : // as static PP costs
uap.nOption_5; // or as number of times to use
// Make sure the number of times the option is used does not exceed the maximum
if(pap.nMaxAugs_5 != PRC_UNLIMITED_AUGMENTATION && manif.nTimesAugOptUsed_5 > pap.nMaxAugs_5)
manif.nTimesAugOptUsed_5 = pap.nMaxAugs_5;
// Calculate the amount of PP the augmentation will cost
nAugPPCost += manif.nTimesAugOptUsed_5 * pap.nAugCost_5;
}
// Calculate number of times a generic augmentation happens with this number of PP
if(pap.nGenericAugCost != PRC_NO_GENERIC_AUGMENTS)
manif.nTimesGenericAugUsed = nAugPPCost / pap.nGenericAugCost;
/*/ Various effects modifying the augmentation go below /*/
// Account for wild surge
nAugPPCostReductions += nSurge;
// Midnight Augmentation feat from incarnum
if (GetHasFeat(FEAT_MIDNIGHT_AUGMENTATION, manif.oManifester))
{
// Make sure the power is the correct one, and that you can expend your psionic focus
if (manif.nSpellID == GetLocalInt(manif.oManifester, "MidnightAugPower") && UsePsionicFocus(manif.oManifester))
nAugPPCostReductions += GetEssentiaInvestedFeat(manif.oManifester, FEAT_MIDNIGHT_AUGMENTATION);
}
/*/ Various effects modifying the augmentation go above /*/
// Auto-distribution, if modifying effects provided more PP than has been used so far or
// the maximal augmentation switch is active
if((nAugPPCost - nAugPPCostReductions) < 0 || bMaxAugment)
{
int nToAutodistribute = 0, nAutodistributed;
// Calculate autodistribution amount
if(bMaxAugment)
{
// Maximal augmentation ignores PP cost reductions here. They are instead handled at the end
if(((manif.nManifesterLevel - manif.nPPCost) - nAugPPCost) > 0)
nToAutodistribute = manif.nManifesterLevel // Maximum usable
- manif.nPPCost // Reduced by what's already been used for other things
- nAugPPCost; // Reduced by what's already been used for augmentation
}
// No maximal augmentation, instead more PP cost reduction provided than PP has been used
else if((nAugPPCost - nAugPPCostReductions) < 0)
nToAutodistribute = -(nAugPPCost - nAugPPCostReductions); // The amount of PP cost reduction that's in excess of what's already been used for augmentation
// Store the value for use in cost calculations
nAutodistributed = nToAutodistribute;
// Start the distribution
int nTimesCanAug;
int nTimesAugd;
if(nToAutodistribute > 0 && pap.nMaxAugs_1)
{
// Determine how many times this option could be used
if(pap.nMaxAugs_1 == PRC_UNLIMITED_AUGMENTATION)
nTimesCanAug = PRC_UNLIMITED_AUGMENTATION;
else
nTimesCanAug = pap.nMaxAugs_1 - manif.nTimesAugOptUsed_1;
if(nTimesCanAug)
{
// Determine how many times it can be used and how much it costs
nTimesAugd = nTimesCanAug == PRC_UNLIMITED_AUGMENTATION ?
nToAutodistribute / pap.nAugCost_1 :
min(nToAutodistribute / pap.nAugCost_1, nTimesCanAug);
nToAutodistribute -= nTimesAugd * pap.nAugCost_1;
manif.nTimesAugOptUsed_1 += nTimesAugd;
}
}
if(nToAutodistribute > 0 && pap.nMaxAugs_2)
{
// Determine how many times this option can be used
if(pap.nMaxAugs_2 == PRC_UNLIMITED_AUGMENTATION)
nTimesCanAug = PRC_UNLIMITED_AUGMENTATION;
else
nTimesCanAug = pap.nMaxAugs_2 - manif.nTimesAugOptUsed_2;
if(nTimesCanAug)
{
// Determine how many times it can be used and how much it costs
nTimesAugd = nTimesCanAug == PRC_UNLIMITED_AUGMENTATION ?
nToAutodistribute / pap.nAugCost_2 :
min(nToAutodistribute / pap.nAugCost_2, nTimesCanAug);
nToAutodistribute -= nTimesAugd * pap.nAugCost_2;
manif.nTimesAugOptUsed_2 += nTimesAugd;
}
}
if(nToAutodistribute > 0 && pap.nMaxAugs_3)
{
// Determine how many times this option can be used
if(pap.nMaxAugs_3 == PRC_UNLIMITED_AUGMENTATION)
nTimesCanAug = PRC_UNLIMITED_AUGMENTATION;
else
nTimesCanAug = pap.nMaxAugs_3 - manif.nTimesAugOptUsed_3;
if(nTimesCanAug)
{
// Determine how many times it can be used and how much it costs
nTimesAugd = nTimesCanAug == PRC_UNLIMITED_AUGMENTATION ?
nToAutodistribute / pap.nAugCost_3 :
min(nToAutodistribute / pap.nAugCost_3, nTimesCanAug);
nToAutodistribute -= nTimesAugd * pap.nAugCost_3;
manif.nTimesAugOptUsed_3 += nTimesAugd;
}
}
if(nToAutodistribute > 0 && pap.nMaxAugs_4)
{
// Determine how many times this option can be used
if(pap.nMaxAugs_4 == PRC_UNLIMITED_AUGMENTATION)
nTimesCanAug = PRC_UNLIMITED_AUGMENTATION;
else
nTimesCanAug = pap.nMaxAugs_4 - manif.nTimesAugOptUsed_4;
if(nTimesCanAug)
{
// Determine how many times it can be used and how much it costs
nTimesAugd = nTimesCanAug == PRC_UNLIMITED_AUGMENTATION ?
nToAutodistribute / pap.nAugCost_4 :
min(nToAutodistribute / pap.nAugCost_4, nTimesCanAug);
nToAutodistribute -= nTimesAugd * pap.nAugCost_4;
manif.nTimesAugOptUsed_4 += nTimesAugd;
}
}
if(nToAutodistribute > 0 && pap.nMaxAugs_5)
{
// Determine how many times this option can be used
if(pap.nMaxAugs_5 == PRC_UNLIMITED_AUGMENTATION)
nTimesCanAug = PRC_UNLIMITED_AUGMENTATION;
else
nTimesCanAug = pap.nMaxAugs_5 - manif.nTimesAugOptUsed_5;
if(nTimesCanAug)
{
// Determine how many times it can be used and how much it costs
nTimesAugd = nTimesCanAug == PRC_UNLIMITED_AUGMENTATION ?
nToAutodistribute / pap.nAugCost_5 :
min(nToAutodistribute / pap.nAugCost_5, nTimesCanAug);
nToAutodistribute -= nTimesAugd * pap.nAugCost_5;
manif.nTimesAugOptUsed_5 += nTimesAugd;
}
}
// Calculate amount actually autodistributed. nToAutoDistribute now contains the amount of PP that could not be auto-distributed
nAutodistributed = (nAutodistributed - nToAutodistribute);
// Calculate increase to generic augmentation
if(pap.nGenericAugCost != PRC_NO_GENERIC_AUGMENTS)
manif.nTimesGenericAugUsed += nAutodistributed / pap.nGenericAugCost;
// Determine new augmentation PP cost
nAugPPCost += nAutodistributed;
}
// Add in cost reduction
nAugPPCost = max(0, nAugPPCost - nAugPPCostReductions);
// Store the PP cost increase
manif.nPPCost += nAugPPCost;
return manif;
}
void SetAugmentationOverride(object oCreature, struct user_augment_profile uap)
{
SetLocalInt(oCreature, PRC_AUGMENT_OVERRIDE, _EncodeProfile(uap) + 1);
}
// Test main
//void main(){}