As a recap: the Spellhook script fires before the bulk of the spell script; if the Spellhook script returns false in the X2PreSpellCastCode function, then the origional script will not fire. In this way, you can 'intercept' a spell, do something else with it, and tell the original spell not to fire.
You have to define what script (what name your script will have) to fire for spellhooking, that is where setting the module variable via SetModuleOverrideSpellscript(string sScriptName) comes in. Pick a name like "my_spell_hook" and then use that name when you create your spellhook script. I don't remember off hand if the PRC has a default value set for a spellhooking script name that you can just use without the need to set anything.
I think you know this, and that you just need helm with how the spellhook sript works. If that's not it, then let me know.
Here is an example from my own spellhook script; however, my script compiles the PRC items in it using the NWNTX Loader.exe updated toolset you can find on the NWN vault. Without that you wont' be able to use any PRC includes or functions.
Here is a partial spellhook file example for simply disabling the Continual Flame spell:
//::///////////////////////////////////////////////
//:: Name: Spellhook script
//:://////////////////////////////////////////////
/*
Description:
This script handles all the spellhooking for various spells
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "x2_inc_switches"
// allows the use of:
// SetModuleOverrideSpellScriptFinished();
// which will kill the origional spell, if we need it not to run
// Include file for PCR Spell constants
#include "prc_spell_const"
// Include file for PCR Psionic Power constants
#include "psi_power_const"
//:://////////////////////////////////////////////
//:: Functions
//:://////////////////////////////////////////////
void main()
{
// Gather all useful info about the spell
object oCaster = OBJECT_SELF; // The caster of the spell is OBJECT_SELF
object oMagicItem = GetSpellCastItem(); // if an item cast the spell, this function gets that item
object oTarget = GetSpellTargetObject(); // returns the targeted object of the spell, if valid
location locTarget = GetSpellTargetLocation(); // returns the targeted location of the spell, if valid
int iCasterClass = GetLastSpellCastClass(); // gets the class the PC cast the spell as
int iCastLevel = GetCasterLevel(OBJECT_SELF); // gets the level the PC cast the spell as
int iSpellDC = GetSpellSaveDC(); // gets the DC required to save against the effects of the spell
int iCasterAlignment = GetAlignmentGoodEvil(OBJECT_SELF); // Returns the good/neutral/evil constant for the caster
int iSpell = GetSpellId(); // returns the SPELL_* constant of the spell cast
switch (iSpell)
{
//:://////////////////////////////////////////////
//:: Spells Section
//:://////////////////////////////////////////////
case SPELL_CONTINUAL_FLAME:
FloatingTextStringOnCreature(ColorString(C_RED, "The Continual Flame spell is currently disabled."), oCaster, FALSE);
SetModuleOverrideSpellScriptFinished();
break;
Basically, in the spellhook file you want to
1) Identify the spell via spell ID (GetSpellId())
2) Do something with the spell (script your own spell, call another script, whatever); in my example I play some floating text in the caster.
3) Tell the original spell NOT to fire (via SetModuleOverrideSpellScriptFinished() call)
My example just ends the spell, and doesn't do #2, but for a different fireball you could do this:
case SPELL_FIREBALL:
ExecuteScript("my_cust_fireball", OBJECT_SELF);
SetModuleOverrideSpellScriptFinished();
break;
And then you can write up your own fireball script in the "my_cust_fireball" scritp file.