PRC8/nwn/nwnprc/trunk/smp/phs_s_telekinspa.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

177 lines
6.1 KiB
Plaintext

/*:://////////////////////////////////////////////
//:: Spell Name Telekinetic Sphere: Movement
//:: Spell FileName PHS_S_TelekinSpA
//:://////////////////////////////////////////////
//:: Spell Effects Applied / Notes
//:://////////////////////////////////////////////
This moves the nearest person affected with Telekinetic Sphere from this
caster, to move to the target location (20M range from the caster). The
cutscene immobilis is removed and reset (to permanent) when they get to the
target place.
//:://////////////////////////////////////////////
//:: Created By: Jasperre
//::////////////////////////////////////////////*/
#include "PHS_INC_SPELLS"
// Moves the person to lTarget.
void TeleMove(location lTarget, effect Stop);
// Wrappers Cutscene mode off, and commandable as approprate, into
// one function
void TeleSetOff(object oSelf, int bResetFalse, effect eStop);
void main()
{
// Delcare Major Variables
object oCaster = OBJECT_SELF;
object oTarget;
location lTarget = GetSpellTargetLocation();
// Declare effects
effect eStop = EffectCutsceneImmobilize(); // Applied seperatly.
// Make the "effect eStop = EffectCutsceneImmobilize();" supernatural,
// so it isn't dispelled (will be removed if the spell is though)
eStop = SupernaturalEffect(eStop);
// Get nearest person with the spells effects
int nCnt = 1;
object oCreature = GetNearestObjectToLocation(OBJECT_TYPE_CREATURE, lTarget, nCnt);
while(GetIsObjectValid(oCreature) && !GetIsObjectValid(oTarget))
{
// Distance check
if(GetDistanceToObject(oCreature) <= 20.0)
{
// Check if the effects are from us
if(PHS_GetHasSpellEffectFromCaster(PHS_SPELL_TELEKINETIC_SPHERE, oCreature, oCaster))
{
// Make oTarget oCreature
oTarget = oCreature;
}
}
// Get next nearest creature
nCnt++;
oCreature = GetNearestObjectToLocation(OBJECT_TYPE_CREATURE, lTarget, nCnt);
}
if(GetIsObjectValid(oTarget))
{
// Now, we assign the special movement to oTarget
FloatingTextStringOnCreature("*You telekinetically move " + GetName(oTarget) + " to the specified location*", oCaster, FALSE);
AssignCommand(oTarget, TeleMove(lTarget, eStop));
}
else
{
FloatingTextStringOnCreature("*You can force nothing to move*", oCaster, FALSE);
}
}
// Moves the person to lTarget.
void TeleMove(location lTarget, effect eStop)
{
// Target is self now, we are assigned this action
object oSelf = OBJECT_SELF;
// Remove the immobilis
PHS_RemoveSpecificEffectFromSpell(EFFECT_TYPE_CUTSCENEIMMOBILIZE, PHS_SPELL_TELEKINETIC_SPHERE, oSelf, SUBTYPE_SUPERNATURAL);
PHS_RemoveSpecificEffectFromSpell(EFFECT_TYPE_CUTSCENEIMMOBILIZE, PHS_SPELL_TELEKINETIC_SPHERE_MOVEMENT, oSelf, SUBTYPE_SUPERNATURAL);
// Check plot flag + Some other things.
// * As the cutscene function is used, this captures two attempts at it.
// * Shouldn't break anything much. This move back should take no time at all.
// * Note: Some effects seem to stop moving, dispite the SetCommandable() flag.
if(PHS_GetIsImmuneToRepel(oSelf)) return;
// We need the commandable flag to put it back correctly.
int bCommandable = GetCommandable(oSelf);
// Time taken will be 1/4 of fDisance
float fTime = GetDistanceBetweenLocations(lTarget, GetLocation(oSelf)) / 4;
// Clear all actions - must stop what we are doing to move.
ClearAllActions();
// Set local saying we are moving
SetLocalInt(oSelf, "PHS_REPELLING", TRUE);
// Set it ON
SetCutsceneMode(oSelf, TRUE);
// Set cutscene cameraman movement rate to high
// * Reset after complete automatically
SetCutsceneCameraMoveRate(oSelf, 2.0);
// Move them
int bResetFalse = FALSE;
if(!bCommandable)
{
// Needs to be set commandable
SetCommandable(TRUE, oSelf);
bResetFalse = TRUE;
}
// Application of effects to make the slide look better.
effect eMove = EffectMovementSpeedIncrease(99);
// Apply the effects using Actions, as to not go on before falling dead
ActionDoCommand(PHS_ApplyDuration(oSelf, eMove, fTime));
// Move to point
ActionMoveToLocation(lTarget, TRUE);
ActionDoCommand(TeleSetOff(oSelf, bResetFalse, eStop));
// Make sure to Set Commandable to FALSE, no AOO's, no actions changing
SetCommandable(FALSE, oSelf);
// Delay the cutscene mode OFF, and any commandable things, not an action.
DelayCommand(fTime, TeleSetOff(oSelf, bResetFalse, eStop));
}
// Wrappers Cutscene mode off, and commandable as approprate, into
// one function
void TeleSetOff(object oSelf, int bResetFalse, effect eStop)
{
// Do not remove twice
if(!GetLocalInt(oSelf, "PHS_REPELLING")) return;
// Delete local saying we are moving
DeleteLocalInt(oSelf, "PHS_REPELLING");
// Store current camerea position
StoreCameraFacing();
// Turn of cutscene mode.
SetCutsceneMode(oSelf, FALSE);
// Restore camera position after the reset of cutscene mode changed it
RestoreCameraFacing();
// Remove the effects (movement increase, ETC)
effect eCheck = GetFirstEffect(oSelf);
while(GetIsEffectValid(eCheck))
{
// Check effect type, creator, spell Id, subtype, and duration tpye,
// to only remove the correct ones.
if(GetEffectType(eCheck) == EFFECT_TYPE_MOVEMENT_SPEED_INCREASE &&
GetEffectCreator(eCheck) == oSelf &&
GetEffectSpellId(eCheck) == SPELL_INVALID &&
GetEffectSubType(eCheck) == SUBTYPE_SUPERNATURAL &&
GetEffectDurationType(eCheck) == DURATION_TYPE_TEMPORARY)
{
RemoveEffect(oSelf, eCheck);
}
// Get next effect
eCheck = GetNextEffect(oSelf);
}
// Reset the state of commandable if need be.
if(bResetFalse == FALSE)
{
// Reset commandable state after delay so we can move again
SetCommandable(TRUE, oSelf);
}
// Stop what we are doing too
ClearAllActions();
// Reapply the immobilis
PHS_ApplyPermanent(oSelf, eStop);
}