Further file organization
Further file organization
This commit is contained in:
268
nwn/nwnprc/trunk/smp/phs_spellhook.nss
Normal file
268
nwn/nwnprc/trunk/smp/phs_spellhook.nss
Normal file
@@ -0,0 +1,268 @@
|
||||
/*:://////////////////////////////////////////////
|
||||
//:: Name Spell Hook file
|
||||
//:: FileName SMP_SpellHook
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Notes
|
||||
//:://////////////////////////////////////////////
|
||||
Spell hook file.
|
||||
|
||||
This is executed on any PC casters who cast a spell with SMP_SpellHookCheck()
|
||||
at the beginning.
|
||||
|
||||
This has all the things like Domain spells and stuff and everything.
|
||||
|
||||
Affects PCs only.
|
||||
|
||||
Its sets the local variable "SMP_SPELLHOOK_RETURN" to TRUE if the spellhook interrupts
|
||||
the spell.
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Jasperre
|
||||
//::////////////////////////////////////////////*/
|
||||
|
||||
#include "SMP_INC_SPLLHOOK"
|
||||
#include "SMP_INC_CRAFT"
|
||||
|
||||
// This returns bResult
|
||||
// * FALSE and stops the rest of the spell firing.
|
||||
// * TRUE and the rest of the spell fires normally.
|
||||
void ReturnResult(int bResult);
|
||||
|
||||
void main()
|
||||
{
|
||||
// Declare things we may, or may not use.
|
||||
object oCaster = OBJECT_SELF;
|
||||
object oTarget = GetSpellTargetObject();
|
||||
object oSpellItem = GetSpellCastItem();
|
||||
object oArea = GetArea(oCaster);
|
||||
int nCasterClass = GetLastSpellCastClass();
|
||||
int nSpellSaveDC = SMP_GetSpellSaveDC();
|
||||
int nRoll;
|
||||
string sMessage;
|
||||
|
||||
// Check nSpellID
|
||||
int nSpellId = GetSpellId();
|
||||
// Note: Get master as appropriate too.
|
||||
// * Is this needed?
|
||||
// int nMasterSpell = GetMaster(nSpellId);
|
||||
|
||||
// Get info from nSpellId
|
||||
string sName = SMP_ArrayGetSpellName(nSpellId);
|
||||
int nSpellLevel = SMP_ArrayGetSpellLevel(nSpellId, nCasterClass);
|
||||
|
||||
// DEBUG MESSAGE
|
||||
SpeakString("Cast: " + sName + ". ID (Input): " + IntToString(nSpellId) + ". Target: " + GetName(oTarget) + ". Class: " + IntToString(nCasterClass));
|
||||
|
||||
// We MUST set the caster level for this spell onto the caster, using nSpellID.
|
||||
int nCasterLevel = SMP_GetCasterLevel();
|
||||
SetLocalInt(oCaster, "SMP_SPELL_CAST_BY_LEVEL_" + IntToString(nSpellId), nCasterLevel);
|
||||
// We also must set the level of the spell cast
|
||||
SetLocalInt(oCaster, "SMP_SPELL_CAST_SPELL_LEVEL" + IntToString(nSpellId), nSpellLevel);
|
||||
// We also set the DC used, if we need it later.
|
||||
SetLocalInt(oCaster, "SMP_SPELL_CAST_SPELL_SAVEDC" + IntToString(nSpellId), nSpellSaveDC);
|
||||
// We also set the Metamagic used, if we need it later.
|
||||
int nMetaMagic = GetMetaMagicFeat();
|
||||
SetLocalInt(oCaster, "SMP_SPELL_CAST_SPELL_METAMAGIC" + IntToString(nSpellId), nMetaMagic);
|
||||
|
||||
/*:://////////////////////////////////////////////
|
||||
Section 1: Anything that should happen whenever a spell is attempted.
|
||||
----------
|
||||
Basically, things which do not stop the spell from being cast, but
|
||||
will be activated even if the spell fails - it is the mear action of attempting
|
||||
to cast the spell (even if it is unsucessful) which this section uses.
|
||||
//::////////////////////////////////////////////*/
|
||||
|
||||
// Concentration for spells such as Black Blade of Disaster
|
||||
SMP_SpecialConcentrationChecks(oCaster);
|
||||
|
||||
// Check for damage via. Spell Curse and Greater Spell curse.
|
||||
SMP_SpellCurseCheck(nSpellLevel, nCasterClass, oSpellItem, oCaster);
|
||||
|
||||
|
||||
// We may turn of Expertise. Bioware setting.
|
||||
if(SMP_SettingGetGlobal(SMP_SETTING_BIO_STOP_EXPERTISE_ABUSE) == TRUE)
|
||||
{
|
||||
SetActionMode(oCaster, ACTION_MODE_EXPERTISE, FALSE);
|
||||
SetActionMode(oCaster, ACTION_MODE_IMPROVED_EXPERTISE, FALSE);
|
||||
}
|
||||
|
||||
/*:://////////////////////////////////////////////
|
||||
Section 2: Stop if the spell hook catches something
|
||||
----------
|
||||
If there is something that would stop the spell, such as, for example,
|
||||
wild magic, an invalid target, or a fail at a blink check, it is done here.
|
||||
|
||||
The order is basically the "Damaging" parts first, and later, the checks
|
||||
for things like "Blink" and "Divine Focus".
|
||||
|
||||
Uses, in each case, ReturnResult(FALSE); if it wants to stop the spell script
|
||||
from firing.
|
||||
//::////////////////////////////////////////////*/
|
||||
|
||||
// You can NOT cast a spell on another person or thing if you are in
|
||||
// "Meld into Stone"
|
||||
if(GetHasSpellEffect(SMP_SPELL_MELD_INTO_STONE, oCaster))
|
||||
{
|
||||
// Check the target
|
||||
if(oTarget != oCaster)
|
||||
{
|
||||
// Stop the casting
|
||||
FloatingTextStringOnCreature("*You cannot cast a spell onto anything but yourself if you are Melded into Stone*", oCaster, FALSE);
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot cast hostile spells (any) while in timestop.
|
||||
if(GetHasSpellEffect(SMP_SPELL_TIME_STOP, oCaster))
|
||||
{
|
||||
// Is it hositle?
|
||||
if(SMP_ArrayGetIsHostile(nSpellId))
|
||||
{
|
||||
// Stop the casting
|
||||
FloatingTextStringOnCreature("*You are unable to affect with hostile spells in timestop*", oCaster, FALSE);
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Note:
|
||||
// - We automatically exit for all NPC's, only doing wild magic checks
|
||||
if(!GetIsPC(oCaster))
|
||||
{
|
||||
ReturnResult(SMP_WildMagicAreaSurge(oArea, oCaster));
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a check for explosive runes
|
||||
if(SMP_ExplosiveRunes())
|
||||
{
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Making sure they are not in time stop and casting spells against a target.
|
||||
if(GetIsObjectValid(oTarget) && oTarget != oCaster)
|
||||
{
|
||||
if(GetHasSpellEffect(SMP_SPELL_TIME_STOP, oCaster))
|
||||
{
|
||||
FloatingTextStringOnCreature("*You cannot cast spells against objects other then yourself under the effects of Time Stop*", oCaster, FALSE);
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Divine Focus check
|
||||
// * Must have the correct alignment-orientated relic to power spells
|
||||
if(!SMP_DivineFocusCheck(sName))
|
||||
{
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Scroll casting
|
||||
if(!SMP_SpellScrollCastingCheck(nSpellId, nSpellLevel, oSpellItem, nCasterClass, oCaster))
|
||||
{
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clerical divine domain spell Check
|
||||
// * Make sure a cleric isn't trying to cast 2 domain spells for one level.
|
||||
if(!SMP_DomainSpellCheck(nSpellId, oSpellItem, nCasterClass, oCaster))
|
||||
{
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check use magical device
|
||||
// * Check UMD, if an item is being used to cast the spell with.
|
||||
if(!SMP_UMDCheck(sName, nSpellLevel, nSpellId))
|
||||
{
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check breaking concentration incase normal hardcoded things where overriden
|
||||
// * Concentration from other sources:
|
||||
// - Entanglement
|
||||
if(!SMP_BreakConcentrationCheck(nSpellLevel, oCaster))
|
||||
{
|
||||
// Failed: We do a special VFX to show it was concentration failure
|
||||
SMP_ApplyVFX(oCaster, EffectVisualEffect(SMP_VFX_FNF_SPELL_FAIL_HAND));
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// We cannot have a sorceror or bard casting a quickened spell - we did
|
||||
// warn them its against the rules.
|
||||
if((nCasterClass == CLASS_TYPE_BARD ||
|
||||
nCasterClass == CLASS_TYPE_SORCERER) &&
|
||||
GetMetaMagicFeat() == METAMAGIC_QUICKEN)
|
||||
{
|
||||
SendMessageToPC(oCaster, "You cannot use the quicken metamagic feat with a bard or sorceror spell");
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wild magic area + Effects.
|
||||
if(!SMP_WildMagicAreaSurge(oArea, oCaster))
|
||||
{
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Crafting checks
|
||||
if(SMP_CraftASpellOntoSomething(oCaster, nSpellId, nSpellLevel, nCasterClass, nCasterLevel, oTarget))
|
||||
{
|
||||
// Crafting checks are sucessful, stop the spell
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Spell components check.
|
||||
if(!SMP_SpellComponentsHookCheck(oCaster, nSpellId))
|
||||
{
|
||||
// Return FALSE, it failed as we do not have the components.
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure Blink doesn't stop the spell from working (if it is a
|
||||
// single target spell!)
|
||||
if(GetIsObjectValid(oTarget) && GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
|
||||
{
|
||||
// Blink check
|
||||
if(!SMP_BlinkCheck(oTarget, oCaster))
|
||||
{
|
||||
// Stop if the roll fails.
|
||||
ReturnResult(FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// NEED:
|
||||
// - Check for SEQUENCER ROBES!
|
||||
|
||||
// Can this be cast on an item? Bioware for now...
|
||||
// if(Get2DAString("crafting 2da need this string completeing", "CastOnItems", GetSpellId()) != "1")
|
||||
// {
|
||||
// FloatingTextStrRefOnCreature(83453, OBJECT_SELF); // not cast spell on item
|
||||
// ReturnResult(FALSE);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Return TRUE if we can cast the spell
|
||||
ReturnResult(TRUE);
|
||||
}
|
||||
|
||||
// This returns bResult
|
||||
// * FALSE and stops the rest of the spell firing.
|
||||
// * TRUE and the rest of the spell fires normally.
|
||||
void ReturnResult(int bResult)
|
||||
{
|
||||
SMP_Debug("HOOK RESULT:" + IntToString(bResult));
|
||||
// Return value
|
||||
// FALSE - stops the spell
|
||||
// TRUE - fires the spell normally
|
||||
SetLocalInt(OBJECT_SELF, "SMP_SPELLHOOK_RETURN", bResult);
|
||||
}
|
Reference in New Issue
Block a user