Initial upload.
Adding base PRC 4.19a files to repository.
This commit is contained in:
244
trunk/psionics/psi_pow_emptrnh.nss
Normal file
244
trunk/psionics/psi_pow_emptrnh.nss
Normal file
@@ -0,0 +1,244 @@
|
||||
/** @file psi_pow_emptrnh
|
||||
|
||||
Empathic Transfer, Hostile
|
||||
|
||||
Telepathy [Mind-Affecting]
|
||||
Level: Telepath 3, psychic warrior 3
|
||||
Manifesting Time: 1 standard action
|
||||
Range: Touch
|
||||
Target: Creature touched
|
||||
Duration: Instantaneous
|
||||
Saving Throw: Will half
|
||||
Power Resistance: Yes
|
||||
Power Points: 5
|
||||
Metapsionics: Twin, Widen
|
||||
|
||||
You transfer your hurt to another. When you manifest this power and then
|
||||
make a successful touch attack, you can transfer 50 points of damage (or
|
||||
less, if you choose) from yourself to the touched creature. You immediately
|
||||
regain hit points equal to the amount of damage you transfer.
|
||||
|
||||
You cannot use this power to gain hit points in excess of your full normal
|
||||
total. The transferred damage is empathic in nature, so powers and abilities
|
||||
the subject may have such as damage reduction and regeneration do not lessen
|
||||
or change this damage.
|
||||
|
||||
The damage transferred by this power has no type, so even if the subject has
|
||||
immunity to the type of damage you originally took, the transfer occurs
|
||||
normally and deals hit point damage to the subject.
|
||||
|
||||
Augment: You can augment this power in one or both of the following ways.
|
||||
1. For every additional power point you spend, you can transfer an additional
|
||||
10 points of damage (maximum 90 points per manifestation).
|
||||
2. If you spend 6 additional power points, this power affects all creatures
|
||||
in a 20-foot-radius spread centered on you. The amount of damage
|
||||
transferred is divided evenly among all hostile creatures in the area.
|
||||
|
||||
@author Stratovarius
|
||||
@date Created: Apr 19, 2005
|
||||
@date Modified: Jul 3, 2006
|
||||
*/
|
||||
|
||||
#include "psi_inc_psifunc"
|
||||
#include "psi_inc_pwresist"
|
||||
#include "psi_spellhook"
|
||||
#include "prc_sp_func"
|
||||
#include "prc_inc_sp_tch"
|
||||
|
||||
void AvoidDR(object oTarget, int nDamage)
|
||||
{
|
||||
int nCurHP = GetCurrentHitPoints(oTarget);
|
||||
int nTargetHP = nCurHP - nDamage;
|
||||
int nDamageToApply = nDamage;
|
||||
effect eDamage;
|
||||
|
||||
// Try magical damage
|
||||
eDamage = EffectDamage(nDamageToApply, DAMAGE_TYPE_MAGICAL);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
|
||||
// Check if the target's HP dropped enough. Skip if the target died on the way
|
||||
if(GetCurrentHitPoints(oTarget) > nTargetHP && !GetIsDead(oTarget))
|
||||
{
|
||||
// Didn't, try again, this time with Divine damage
|
||||
nDamageToApply = GetCurrentHitPoints(oTarget) - nTargetHP;
|
||||
|
||||
eDamage = EffectDamage(nDamageToApply, DAMAGE_TYPE_DIVINE);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
|
||||
// Check if the target's HP dropped enough. Skip if the target died on the way
|
||||
if(GetCurrentHitPoints(oTarget) > nTargetHP && !GetIsDead(oTarget))
|
||||
{
|
||||
// Didn't, try again, this time with Positive damage
|
||||
nDamageToApply = GetCurrentHitPoints(oTarget) - nTargetHP;
|
||||
|
||||
eDamage = EffectDamage(nDamageToApply, DAMAGE_TYPE_POSITIVE);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
|
||||
// If it still didn't work, just give up. The blighter probably has immunities to everything else, too, anyway
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DoPower(object oManifester, object oTarget, struct manifestation manif)
|
||||
{
|
||||
int nDC = GetManifesterDC(oManifester);
|
||||
int nPen = GetPsiPenetration(oManifester);
|
||||
int nMaxTran = min(50 + (10 * manif.nTimesAugOptUsed_1), // Maximum transferrable is 50 + 10* augmentation
|
||||
GetMaxHitPoints(oManifester) - GetCurrentHitPoints(oManifester) // Limited to the amount of damage the manifester has actually suffered
|
||||
);
|
||||
if (DEBUG) DoDebug("Transfer Cap: " + IntToString(nMaxTran));
|
||||
float fRadius = EvaluateWidenPower(manif, FeetToMeters(20.0f));
|
||||
location lTarget = PRCGetSpellTargetLocation();
|
||||
|
||||
int bHit = 0;
|
||||
|
||||
PRCSignalSpellEvent(oTarget, TRUE, manif.nSpellID, oManifester);
|
||||
|
||||
int nRepeats = manif.bTwin ? 2 : 1;
|
||||
for(; nRepeats > 0; nRepeats--)
|
||||
{
|
||||
// Touch or burst
|
||||
if(manif.nTimesAugOptUsed_2 != 1)
|
||||
{
|
||||
// Let the AI know
|
||||
PRCSignalSpellEvent(oTarget, TRUE, manif.nSpellID, oManifester);
|
||||
|
||||
// Try to touch the single target
|
||||
if(PRCDoMeleeTouchAttack(oTarget) > 0) // No need to store the result, critical hits nor precision-based damage work with this power
|
||||
{
|
||||
bHit = 1;
|
||||
// Mind-affecting immunity
|
||||
if(!GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS))
|
||||
{
|
||||
if(PRCMyResistPower(oManifester, oTarget, nPen))
|
||||
{
|
||||
// Save for half
|
||||
if(PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))
|
||||
{
|
||||
nMaxTran /= 2;
|
||||
|
||||
if (GetHasMettle(oTarget, SAVING_THROW_WILL)) // Ignores partial effects
|
||||
{
|
||||
nMaxTran = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the healing
|
||||
effect eHeal = EffectHeal(nMaxTran);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oManifester);
|
||||
|
||||
// Use some trickery to attempt passing damage resistance / immunity
|
||||
AvoidDR(oTarget, nMaxTran);
|
||||
}// end if - SR check
|
||||
}// end if - Mind-affecting immunity check
|
||||
}// end if - Hit with a touch attack
|
||||
}// end if - Single target
|
||||
else
|
||||
{
|
||||
bHit = 1;
|
||||
// Delete the array if one exists already
|
||||
if(array_exists(oManifester, "PRC_Power_EmpTranHostile_Targets"))
|
||||
array_delete(oManifester, "PRC_Power_EmpTranHostile_Targets");
|
||||
// Create array
|
||||
array_create(oManifester, "PRC_Power_EmpTranHostile_Targets");
|
||||
|
||||
// Determine eligible targets
|
||||
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, fRadius, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||
while(GetIsObjectValid(oTarget))
|
||||
{
|
||||
if(oTarget != oManifester && // Only hurt other people
|
||||
//!GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS) && // Mind-affecting immunity check
|
||||
spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, oManifester) // User can select targets
|
||||
)
|
||||
{
|
||||
// Add target to list
|
||||
array_set_object(oManifester, "PRC_Power_EmpTranHostile_Targets",
|
||||
array_get_size(oManifester, "PRC_Power_EmpTranHostile_Targets"),
|
||||
oTarget
|
||||
);
|
||||
}// end if - Is this something to target?
|
||||
}// end while - Target getting loop
|
||||
|
||||
// Calculate damage per target
|
||||
int nDamagePerTarget = nMaxTran / array_get_size(oManifester, "PRC_Power_EmpTranHostile_Targets");
|
||||
// Calculate the remainder. This will be applied only to the first target
|
||||
int nRemainder = nMaxTran - (nDamagePerTarget * array_get_size(oManifester, "PRC_Power_EmpTranHostile_Targets"));
|
||||
int nDamage;
|
||||
|
||||
// Loop over targets and apply damage
|
||||
int i;
|
||||
for(i = 0; i < array_get_size(oManifester, "PRC_Power_EmpTranHostile_Targets"); i++)
|
||||
{
|
||||
// Let the AI know
|
||||
PRCSignalSpellEvent(oTarget, TRUE, manif.nSpellID, oManifester);
|
||||
|
||||
// Mind-affecting immunity
|
||||
if(!GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS))
|
||||
{
|
||||
if(PRCMyResistPower(oManifester, oTarget, nPen))
|
||||
{
|
||||
// Set the initial damage
|
||||
nDamage = nDamagePerTarget;
|
||||
if(i == 0) nDamage += nRemainder; // First target may get extra
|
||||
|
||||
// Save for half
|
||||
if(PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))
|
||||
{
|
||||
nDamage /= 2;
|
||||
}
|
||||
|
||||
// Apply the healing
|
||||
effect eHeal = EffectHeal(nDamage);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oManifester);
|
||||
|
||||
// Use some trickery to attempt passing damage resistance / immunity
|
||||
AvoidDR(oTarget, nDamage);
|
||||
}// end if - SR check
|
||||
}// end if - Mind-affecting immunity check
|
||||
}// end for - Target affecting loop
|
||||
}// end else - Augmented to affect an area
|
||||
}
|
||||
|
||||
return bHit; //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(PRC_NO_GENERIC_AUGMENTS,
|
||||
1, 4,
|
||||
6, 1
|
||||
),
|
||||
METAPSIONIC_TWIN | METAPSIONIC_WIDEN
|
||||
);
|
||||
|
||||
if(manif.bCanManifest)
|
||||
{
|
||||
if(GetLocalInt(oManifester, PRC_SPELL_HOLD) && oManifester == oTarget && manif.nTimesAugOptUsed_2 != 1)
|
||||
{ //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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user