forked from Jaysyn/PRC8
Updated Vow of Poverty. Added Sanctify Ki Strike, Holy Strike, Fist of Heavens, Vow of Abstinence, Vow of Chastity & Gift of Faith. (@fenac). Turned off the Taunt & Parry skills. Re-disabled AC & save bonuses from Tumble & Spellcraft. Updated min() & max() to PRCmin() & PRCmax() to not conflict with similarly named NUI adjacent functions. Set Point Blank Shot to 30' per PnP. Added icon for Chosen of Evil. Started work on Hidden Talent. Created Psionics function cheatsheet. Updated release archive.
236 lines
11 KiB
Plaintext
236 lines
11 KiB
Plaintext
/*
|
||
----------------
|
||
Strength of my Enemy
|
||
|
||
psi_pow_strnmy
|
||
----------------
|
||
|
||
14/12/05 by Stratovarius
|
||
*/ /** @file
|
||
|
||
Strength of My Enemy
|
||
|
||
Psychometabolism
|
||
Level: Psychic warrior 2
|
||
Manifesting Time: 1 standard action
|
||
Range: Personal
|
||
Target: You
|
||
Duration: 1 round/level
|
||
Power Points: 3
|
||
Metapsionics: Extend
|
||
|
||
You gain the ability to siphon away your enemy’s strength for your own use.
|
||
One of your natural or manufactured weapons becomes the instrument of your
|
||
desire, and deals 1 point of Strength damage on each successful hit. You
|
||
gain that point of Strength as an enhancement bonus to your Strength score.
|
||
Strength you siphon from different foes is tracked separately - the total
|
||
siphoned from each individual foe is considered a separate enhancement bonus
|
||
to your Strength (maximum +8), and you gain only the highest total.
|
||
|
||
Augment: For every 3 additional power points you spend, the maximum
|
||
enhancement bonus you can add to your Strength increases by 2.
|
||
*/
|
||
|
||
#include "prc_inc_spells"
|
||
#include "psi_inc_onhit"
|
||
#include "psi_inc_psifunc"
|
||
#include "psi_spellhook"
|
||
|
||
const string STRNMY_ARRAY = "PRC_Power_StrengthOfMyEnemy_Array";
|
||
|
||
void DispelMonitor(object oManifester, object oTarget, object oWeapon, int nSpellID);
|
||
void CleanUpArray(object oCreature);
|
||
|
||
void main()
|
||
{
|
||
// Determine whether this script call is about manifesting the power or an OnHit
|
||
if(GetRunningEvent() != EVENT_ONHIT)
|
||
{
|
||
// Spellhook
|
||
if (!PsiPrePowerCastCode()){ return; }
|
||
|
||
object oManifester = OBJECT_SELF;
|
||
object oTarget = PRCGetSpellTargetObject();
|
||
struct manifestation manif =
|
||
EvaluateManifestation(oManifester, oTarget,
|
||
PowerAugmentationProfile(PRC_NO_GENERIC_AUGMENTS,
|
||
3, PRC_UNLIMITED_AUGMENTATION
|
||
),
|
||
METAPSIONIC_EXTEND
|
||
);
|
||
|
||
if(manif.bCanManifest)
|
||
{
|
||
int nMaxBonus = 8 + (2* manif.nTimesAugOptUsed_1);
|
||
int nDuration = manif.nManifesterLevel;
|
||
if(manif.bExtend) nDuration *= 2;
|
||
effect eVis = EffectVisualEffect(VFX_COM_HIT_NEGATIVE);
|
||
eVis = EffectLinkEffects(eVis, EffectVisualEffect(VFX_IMP_PULSE_NEGATIVE));
|
||
effect eDur = EffectVisualEffect(VFX_DUR_PROTECTION_EVIL_MINOR);
|
||
float fDuration = 6.0f * nDuration;
|
||
object oWeapon;
|
||
|
||
// Target checks
|
||
if(!IPGetIsMeleeWeapon(oTarget))
|
||
{
|
||
// If the target was the manifester, get either their primary hand weapon or first creature weapon
|
||
if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
|
||
{
|
||
object oTemp = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
|
||
if(IPGetIsMeleeWeapon(oTemp))
|
||
oWeapon = oTemp;
|
||
else if(GetIsObjectValid(oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oTarget)))
|
||
oWeapon = oTemp;
|
||
else if(GetIsObjectValid(oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oTarget)))
|
||
oWeapon = oTemp;
|
||
else if(GetIsObjectValid(oTemp = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oTarget)))
|
||
oWeapon = oTemp;
|
||
// No creature weapon, either
|
||
else
|
||
oWeapon = OBJECT_INVALID;
|
||
}
|
||
else
|
||
oWeapon = OBJECT_INVALID;
|
||
}
|
||
// Target was a weapon
|
||
else
|
||
{
|
||
oWeapon = oTarget;
|
||
oTarget = GetItemPossessor(oWeapon);
|
||
}
|
||
|
||
// At this point, the target should be either the weapon, or an invalid object
|
||
if(!GetIsObjectValid(oWeapon))
|
||
{
|
||
// "Target is not valid for Strength of my Enemy!"
|
||
FloatingTextStrRefOnCreature(16826668, oManifester, FALSE);
|
||
return;
|
||
}
|
||
|
||
// Concurrent instances of the power not allowed
|
||
if(!GetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_Duration"))
|
||
{
|
||
// Add onhit itemproperty to the weapon
|
||
IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1),
|
||
fDuration, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE
|
||
);
|
||
|
||
// Add a marker local to the weapon
|
||
SetLocalInt(oWeapon, "PRC_Power_StrengthOfMyEnemy_Active", TRUE);
|
||
|
||
// Add eventscript
|
||
AddEventScript(oTarget, EVENT_ONHIT, "psi_pow_strnmy", TRUE, FALSE);
|
||
|
||
// Store manifestation data in local vars
|
||
SetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_Duration", nDuration);
|
||
SetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_MaxBonus", nMaxBonus);
|
||
SetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_ManifLvl", manif.nManifesterLevel);
|
||
|
||
// Initialise highest strength bonus granted tracker
|
||
// First, if, for some reason, the array exists already, perform cleanup
|
||
if(array_exists(oTarget, STRNMY_ARRAY))
|
||
CleanUpArray(oTarget);
|
||
// Create the array
|
||
array_create(oTarget, STRNMY_ARRAY);
|
||
// Init the current bonus tracking variable to 0
|
||
SetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_CurBonus", 0);
|
||
|
||
// Apply VFX
|
||
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, oTarget, fDuration, TRUE, manif.nSpellID, manif.nManifesterLevel);
|
||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||
|
||
// Start dispelling monitor
|
||
DelayCommand(6.0f, DispelMonitor(oManifester, oTarget, oWeapon, manif.nSpellID));
|
||
}
|
||
}// end if - Successfull manifestation
|
||
}// end if - Manifesting the power
|
||
else
|
||
{
|
||
object oManifester = OBJECT_SELF;
|
||
object oWeapon = GetSpellCastItem();
|
||
object oTarget = PRCGetSpellTargetObject();
|
||
|
||
// Make sure the item triggering OnHit was the Strength of my Enemy weapon
|
||
if(GetLocalInt(oWeapon, "PRC_Power_StrengthOfMyEnemy_Active"))
|
||
{
|
||
// No point in doing any of this if the target is immune
|
||
if(GetIsImmune(oTarget, IMMUNITY_TYPE_ABILITY_DECREASE))
|
||
return;
|
||
|
||
// Get data
|
||
int nMaxBonus = GetLocalInt(oManifester, "PRC_Power_StrengthOfMyEnemy_MaxBonus");
|
||
int nManifesterLevel = GetLocalInt(oManifester, "PRC_Power_StrengthOfMyEnemy_ManifLvl");
|
||
int nCurrentBonus = GetLocalInt(oManifester, "PRC_Power_StrengthOfMyEnemy_CurBonus");
|
||
int nGainedFromCurrent = GetLocalInt(oManifester, "PRC_Power_SomE_STRGainedFrom_" + ObjectToString(oTarget));
|
||
|
||
// Make an array entry in the tracking array for the current target if it doesn't have one already
|
||
if(nGainedFromCurrent == 0)
|
||
array_set_object(oManifester, STRNMY_ARRAY, array_get_size(oManifester, STRNMY_ARRAY), oTarget);
|
||
|
||
// Apply the damage
|
||
ApplyAbilityDamage(oTarget, ABILITY_STRENGTH, 1, DURATION_TYPE_TEMPORARY, TRUE, -1.0f);
|
||
|
||
// Keep track of how many times we've drained the person, which is one more than previous
|
||
nGainedFromCurrent = PRCMin(nGainedFromCurrent + 1, nMaxBonus); // Do not allow the value to exceed the max bonus. It probably doesn't matter, but it's ugly :P
|
||
SetLocalInt(oManifester, "PRC_Power_SomE_STRGainedFrom_" + ObjectToString(oTarget), nGainedFromCurrent);
|
||
|
||
// Check ff the amount gained from current target is greater than the current bonus, but not higher than the maximum
|
||
if(nGainedFromCurrent > nCurrentBonus &&
|
||
nGainedFromCurrent <= nMaxBonus
|
||
)
|
||
{
|
||
// Apply Strength bonus for a duration equal to the remaining duration of this power, with accuracy of +-6s
|
||
float fDuration = 6.0f * GetLocalInt(oManifester, "PRC_Power_StrengthOfMyEnemy_Duration");
|
||
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, nGainedFromCurrent);
|
||
effect eVis = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE);
|
||
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eStr, oManifester, fDuration, TRUE, POWER_STRENGTH_OF_MY_ENEMY, nManifesterLevel);
|
||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oManifester);
|
||
|
||
// Update the highest bonus tracker
|
||
SetLocalInt(oManifester, "PRC_Power_StrengthOfMyEnemy_CurBonus", nGainedFromCurrent);
|
||
}// end if - We need to increase the STR bonus in effect
|
||
}// end if - OnHit triggered by the corrent item
|
||
}// end else - Running OnHit
|
||
}
|
||
|
||
void DispelMonitor(object oManifester, object oTarget, object oWeapon, int nSpellID)
|
||
{
|
||
int nRoundsRemain = GetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_Duration");
|
||
|
||
if(PRCGetDelayedSpellEffectsExpired(nSpellID, oTarget, oManifester) || // Has the power expired somehow since last check
|
||
nRoundsRemain <= 0 // Or is it running out of duration now
|
||
)
|
||
{
|
||
if(DEBUG) DoDebug("psi_pow_strnmy: Power expired, clearing");
|
||
|
||
// Remove effects
|
||
PRCRemoveSpellEffects(nSpellID, oManifester, oTarget);
|
||
|
||
// Unhook event
|
||
RemoveEventScript(oTarget, EVENT_ONHIT, "psi_pow_strnmy", TRUE, FALSE);
|
||
|
||
// Clear locals
|
||
DeleteLocalInt(oWeapon, "PRC_Power_StrengthOfMyEnemy_Active");
|
||
DeleteLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_Duration");
|
||
DeleteLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_MaxBonus");
|
||
DeleteLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_ManifLvl");
|
||
DeleteLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_CurBonus");
|
||
CleanUpArray(oTarget);
|
||
}
|
||
else
|
||
{
|
||
// Decrement rounds remaining and schedule next HB
|
||
SetLocalInt(oTarget, "PRC_Power_StrengthOfMyEnemy_Duration", nRoundsRemain - 1);
|
||
DelayCommand(6.0f, DispelMonitor(oManifester, oTarget, oWeapon, nSpellID));
|
||
}
|
||
}
|
||
|
||
void CleanUpArray(object oCreature)
|
||
{
|
||
int i, max = array_get_size(oCreature, STRNMY_ARRAY);
|
||
for(i = 0; i < max; i++)
|
||
DeleteLocalInt(oCreature, "PRC_Power_SomE_STRGainedFrom_" + ObjectToString(array_get_object(oCreature, STRNMY_ARRAY, i)));
|
||
|
||
array_delete(oCreature, STRNMY_ARRAY);
|
||
}
|