forked from Jaysyn/PRC8
Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
115 lines
3.9 KiB
Plaintext
115 lines
3.9 KiB
Plaintext
//:://////////////////////////////////////////////
|
|
//:: Telflammar Shadowlord: Shadow Jump
|
|
//:: tfshad_jump
|
|
//:://////////////////////////////////////////////
|
|
/** @file
|
|
Shadow Jump (Su):
|
|
A Telflammar Shadowlord can travel between
|
|
shadows as if by means of a Dimension Door spell.
|
|
The limitation is that the magical transport
|
|
must begin and end in an area with at least some
|
|
shadow or darkness. The shadowlord can jump up
|
|
to a total of 20 feet per class level per day
|
|
in this way. This amount can be split up among
|
|
many jumps, but each jump, no matter how small,
|
|
counts as a 10-foot increment.
|
|
|
|
|
|
The shadow requirement is waived, since it's not
|
|
possible to detect without builder intervention.
|
|
This script also contains an implementation of
|
|
Shadow Pounce.
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:://////////////////////////////////////////////
|
|
|
|
|
|
#include "prc_inc_combat"
|
|
#include "prc_inc_sneak"
|
|
#include "prc_inc_teleport"
|
|
|
|
void main()
|
|
{
|
|
// Declare major variables
|
|
object oCaster = OBJECT_SELF;
|
|
location lTarget = PRCGetSpellTargetLocation();
|
|
location lCaster = GetLocation(oCaster);
|
|
effect eVis = EffectVisualEffect(VFX_DUR_PROT_SHADOW_ARMOR);
|
|
float fDistance = GetDistanceBetweenLocations(lCaster,lTarget);
|
|
int iLevel = GetLevelByClass(CLASS_TYPE_SHADOWLORD, oCaster);
|
|
|
|
// Get the feat ID
|
|
int iFeat = FEAT_SHADOWJUMP - 1 + GetLevelByClass(CLASS_TYPE_SHADOWLORD, oCaster);
|
|
|
|
// Check if we're targeting some creature instead of just a spot on the floor
|
|
object oTarget = PRCGetSpellTargetObject();
|
|
if(GetIsObjectValid(oTarget))
|
|
lTarget = GetLocation(oTarget);
|
|
|
|
// Check if teleportation is possible
|
|
if(!GetCanTeleport(oCaster, lTarget, TRUE, TRUE))
|
|
{
|
|
IncrementRemainingFeatUses(oCaster, iFeat);
|
|
return;
|
|
}
|
|
|
|
vector vOrigin = GetPositionFromLocation(GetLocation(oCaster));
|
|
vector vDest = GetPositionFromLocation(lTarget);
|
|
|
|
// Calculate the amount of jump range remaining
|
|
int iLeftUse = 1; // Init to 1 to account for the use taken by the engine when activating the feat
|
|
while(GetHasFeat(iFeat, oCaster))
|
|
{
|
|
DecrementRemainingFeatUses(oCaster, iFeat);
|
|
iLeftUse++;
|
|
}
|
|
|
|
// Return the feat uses for now.
|
|
/// @TODO This is inefficient, make it so that the uses are only returned after calculating how many will be left after the jump.
|
|
int nCount = iLeftUse;
|
|
while(nCount)
|
|
{
|
|
IncrementRemainingFeatUses(oCaster, iFeat);
|
|
nCount--;
|
|
}
|
|
|
|
// Calculate the maximum distance jumpable
|
|
float fMaxDis = FeetToMeters(iLeftUse * 20.0);
|
|
|
|
// If the target is too far, abort
|
|
if(fDistance > fMaxDis)
|
|
{// "Your target is too far!"
|
|
FloatingTextStrRefOnCreature(16825300, oCaster);
|
|
return;
|
|
}
|
|
|
|
// Reduce feat uses based on the distance teleported
|
|
nCount = FloatToInt(fDistance / FeetToMeters(10.0));
|
|
// The minimum of 10 feet
|
|
if(!nCount) nCount = 1;
|
|
// Take away the required number of uses.
|
|
while(nCount)
|
|
{
|
|
DecrementRemainingFeatUses(oCaster, iFeat);
|
|
nCount--;
|
|
}
|
|
|
|
// Calculate the locations to apply the VFX at
|
|
vOrigin = Vector(vOrigin.x + 2.0, vOrigin.y - 0.2, vOrigin.z);
|
|
vDest = Vector(vDest.x + 2.0, vDest.y - 0.2, vDest.z);
|
|
|
|
// Do VFX
|
|
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, Location(GetArea(oCaster), vOrigin, 0.0), 0.8);
|
|
DelayCommand(0.1, ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, Location(GetArea(oCaster), vDest, 0.0), 0.7));
|
|
|
|
// Schedule the jump itself
|
|
DelayCommand(0.8, AssignCommand(oCaster, JumpToLocation(lTarget)));
|
|
|
|
// Class level 4 gives the Shadow Pounce ability, which gives one a full attack at the end of a jump
|
|
if(iLevel >= 4)
|
|
{
|
|
DelayCommand(1.0f, PerformAttackRound(oTarget, oCaster, EffectVisualEffect(-1), 0.0, 0, 0, 0, FALSE, "", "", FALSE, FALSE, TRUE));
|
|
}
|
|
}
|
|
|