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.
96 lines
3.3 KiB
Plaintext
96 lines
3.3 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: Name Sonic Shield: OnEnter
|
|
//:: FileName sp_sonic_shldA.nss
|
|
//:://////////////////////////////////////////////
|
|
/**@file Sonic Shield
|
|
Evocation
|
|
Level: Bard 3, duskblade 5, sorcerer/wizard 5
|
|
Components: V,S
|
|
Casting Time: 1 standard action
|
|
Range: Personal
|
|
Target: You
|
|
Duration: 1 round/level
|
|
|
|
This spell grants you a +4 deflection bonus to AC.
|
|
In addition, anyone who successfully hits you with
|
|
a melee attack takes 1d8 points of sonic damage
|
|
and must make a Fortitude saving throw or be
|
|
knocked 5 feet away from you into an unoccupied
|
|
space of your choice. If no space of sufficient
|
|
size is available for it to enter, it instead
|
|
takes an extra 1d8 points of sonic damage.
|
|
**/
|
|
|
|
#include "prc_inc_spells"
|
|
#include "prc_add_spell_dc"
|
|
|
|
void DoPush(object oTarget, object oPC, int nReverse = FALSE);
|
|
|
|
void main()
|
|
{
|
|
object oPC = OBJECT_SELF;
|
|
object oTarget = PRCGetSpellTargetObject();
|
|
int nDC = PRCGetSaveDC(oTarget, oPC);
|
|
|
|
if(GetHasSpellEffect(SPELL_SONIC_SHIELD, oPC))
|
|
{
|
|
// Make Save
|
|
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_SPELL))
|
|
{
|
|
//Fire cast spell at event for the target
|
|
SignalEvent(oTarget, EventSpellCastAt(oPC, SPELL_SONIC_SHIELD));
|
|
|
|
// Punt them out of the area
|
|
DoPush(oTarget, oPC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RemoveEventScript(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC), EVENT_ITEM_ONHIT, "prc_evnt_snshld", TRUE, FALSE);
|
|
RemoveEventScript(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC), EVENT_ITEM_ONHIT, "prc_evnt_snshld", TRUE, FALSE);
|
|
}
|
|
}
|
|
|
|
void DoPush(object oTarget, object oPC, int nReverse = FALSE)
|
|
{
|
|
// Calculate how far the creature gets pushed
|
|
float fDistance = FeetToMeters(5.0f);
|
|
// Determine if they hit a wall on the way
|
|
location lCreator = GetLocation(oPC);
|
|
location lTargetOrigin = GetLocation(oTarget);
|
|
vector vAngle = AngleToVector(GetRelativeAngleBetweenLocations(lCreator, lTargetOrigin));
|
|
vector vTargetOrigin = GetPosition(oTarget);
|
|
vector vTarget = vTargetOrigin + (vAngle * fDistance);
|
|
|
|
if(!LineOfSightVector(vTargetOrigin, vTarget))
|
|
{
|
|
// Hit a wall, binary search for the wall
|
|
float fEpsilon = 1.0f; // Search precision
|
|
float fLowerBound = 0.0f; // The lower search bound, initialise to 0
|
|
float fUpperBound = fDistance; // The upper search bound, initialise to the initial distance
|
|
fDistance = fDistance / 2; // The search position, set to middle of the range
|
|
|
|
do
|
|
{
|
|
// Create test vector for this iteration
|
|
vTarget = vTargetOrigin + (vAngle * fDistance);
|
|
// Determine which bound to move.
|
|
if(LineOfSightVector(vTargetOrigin, vTarget))
|
|
fLowerBound = fDistance;
|
|
else
|
|
fUpperBound = fDistance;
|
|
|
|
// Get the new middle point
|
|
fDistance = (fUpperBound + fLowerBound) / 2;
|
|
}
|
|
while(fabs(fUpperBound - fLowerBound) > fEpsilon);
|
|
}
|
|
// Create the final target vector
|
|
vTarget = vTargetOrigin + (vAngle * fDistance);
|
|
|
|
// Move the target
|
|
location lTargetDestination = Location(GetArea(oTarget), vTarget, GetFacing(oTarget));
|
|
AssignCommand(oTarget, ClearAllActions(TRUE));
|
|
AssignCommand(oTarget, JumpToLocation(lTargetDestination));
|
|
}
|