PRC8/nwn/nwnprc/trunk/psionics/psi_pow_shrpain.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

130 lines
5.0 KiB
Plaintext

/** @file psi_pow_shrpain
Share Pain
Psychometabolism
Level: Psion/wilder 2
Manifesting Time: 1 standard action
Range: Touch
Targets: You and one willing creature
Duration: 1 hour/level
Power Points: 3
Metapsionics: Extend
This power creates a psychometabolic connection between you and a willing
subject so that some of your wounds are transferred to the subject. You take
half damage from all attacks that deal hit point damage to you, and the
subject takes the remainder. The amount of damage not taken by you is taken
by the subject. If your hit points are reduced by a lowered Constitution
score, that reduction is not shared with the subject because it is not a
form of hit point damage. When this power ends, subsequent damage is no
longer divided between the subject and you, but damage already shared is not
reassigned.
If you and the subject move farther away from each other than close range,
the power ends.
Implementation notes:
You may not have more than one Share Pain or Share Pain, Forced active at
any one time. Any subsequent uses override the previous.
We're lazy bastards :P
@author Stratovarius
@date Created: Feb 19, 2004
@date Modified: Jul 3, 2006
*/
#include "psi_inc_psifunc"
#include "psi_inc_pwresist"
#include "psi_spellhook"
#include "prc_sp_func"
void DispelMonitor(object oManifester, object oTarget, int nSpellID, int nManifesterLevel, int nBeatsRemaining)
{
// Has the power ended since the last beat, or does the duration run out now
if((--nBeatsRemaining == 0) ||
GetIsDead(oTarget) ||
PRCGetDelayedSpellEffectsExpired(nSpellID, oTarget, oManifester) ||
PRCGetDelayedSpellEffectsExpired(nSpellID, oManifester, oManifester) /*||
GetDistanceBetween(oManifester, oTarget) > FeetToMeters(25.0f + (5.0f * (nManifesterLevel / 2))) This does not work in NWN */
)
{
if(DEBUG) DoDebug("psi_pow_shrpain: Effect expired, clearing");
// Clear the target local
DeleteLocalObject(oManifester, "PRC_Power_SharePain_Target");
// Remove the eventscript
RemoveEventScript(oManifester, EVENT_ONHIT, "psi_pow_shrpnaux", TRUE, FALSE);
// Remove remaining effects
PRCRemoveSpellEffects(nSpellID, oManifester, oTarget);
PRCRemoveSpellEffects(nSpellID, oManifester, oManifester);
}
else
DelayCommand(6.0f, DispelMonitor(oManifester, oTarget, nSpellID, nManifesterLevel, nBeatsRemaining));
}
int DoPower(object oManifester, object oTarget, struct manifestation manif)
{
effect eDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_POSITIVE);
float fDuration = HoursToSeconds(manif.nManifesterLevel);
if(manif.bExtend) fDuration *= 2;
// Let the AI know
PRCSignalSpellEvent(oTarget, FALSE, manif.nSpellID, oManifester);
// Get the OnHitCast: Unique on the manifester's armor / hide
ExecuteScript("prc_keep_onhit_a", oManifester);
// Hook eventscript
AddEventScript(oManifester, EVENT_ONHIT, "psi_pow_shrpnaux", TRUE, FALSE);
// Store the target for use in the damage script
SetLocalObject(oManifester, "PRC_Power_SharePain_Target", oTarget);
// Do VFX for the monitor to look for
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, oTarget, fDuration, TRUE, manif.nSpellID, manif.nManifesterLevel);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, oManifester, fDuration, TRUE, manif.nSpellID, manif.nManifesterLevel);
// Start effect end monitor
DelayCommand(6.0f, DispelMonitor(oManifester, oTarget, manif.nSpellID, manif.nManifesterLevel, FloatToInt(fDuration) / 6));
return TRUE; //Held charge is used if at least 1 touch from twinned power hits
}
void main()
{
if(!PsiPrePowerCastCode()) return;
object oManifester = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
struct manifestation manif;
int nEvent = GetLocalInt(oManifester, PRC_SPELL_EVENT); //use bitwise & to extract flags
if(!nEvent) //normal cast
{
manif =
EvaluateManifestation(oManifester, oTarget,
PowerAugmentationProfile(),
METAPSIONIC_EXTEND
);
if(manif.bCanManifest)
{
if(GetLocalInt(oManifester, PRC_SPELL_HOLD) && oManifester == oTarget)
{ //holding the charge, manifesting power on self
SetLocalSpellVariables(oManifester, 1); //change 1 to number of charges
SetLocalManifestation(oManifester, PRC_POWER_HOLD_MANIFESTATION, manif);
return;
}
DoPower(oManifester, oTarget, manif);
}
}
else
{
if(nEvent & PRC_SPELL_EVENT_ATTACK)
{
manif = GetLocalManifestation(oManifester, PRC_POWER_HOLD_MANIFESTATION);
if(DoPower(oManifester, oTarget, manif))
DecrementSpellCharges(oManifester);
}
}
}