///:://///////////////////////////////////////////// //:: Spell Hook Include File //:: x2_inc_spellhook //:: Copyright (c) 2003 Bioware Corp. //::////////////////////////////////////////////// /* This file acts as a hub for all code that is hooked into the nwn spellscripts' If you want to implement material components into spells or add restrictions to certain spells, this is the place to do it. */ //::////////////////////////////////////////////// //:: Created By: Georg Zoeller //:: Created On: 2003-06-04 //:: Updated On: 2003-10-25 //::////////////////////////////////////////////// //#include "x2_inc_itemprop" - Inherited from x2_inc_craft #include "x2_inc_craft" #include "jw_nun_wild" const int X2_EVENT_CONCENTRATION_BROKEN = 12400; // added by PALMER. Check Druid Spell failure int PalmerCheckDruidSpellFailure(); // Use Magic Device Check. // Returns TRUE if the Spell is allowed to be cast, either because the // character is allowed to cast it or he has won the required UMD check // Only active on spell scroll int X2UseMagicDeviceCheck(); // This function holds all functions that are supposed to run before the actual // spellscript gets run. If this functions returns FALSE, the spell is aborted // and the spellscript will not run int X2PreSpellCastCode(); // check if the spell is prohibited from being cast on items // returns FALSE if the spell was cast on an item but is prevented // from being cast there by its corresponding entry in des_crft_spells // oItem - pass GetSpellTargetObject in here int X2CastOnItemWasAllowed(object oItem); // Sequencer Item Property Handling // Returns TRUE (and charges the sequencer item) if the spell // ... was cast on an item AND // ... the item has the sequencer property // ... the spell was non hostile // ... the spell was not cast from an item // in any other case, FALSE is returned an the normal spellscript will be run // oItem - pass GetSpellTargetObject in here int X2GetSpellCastOnSequencerItem(object oItem); int X2RunUserDefinedSpellScript(); //------------------------------------------------------------------------------ // PALMER Execute the wild magic script. //------------------------------------------------------------------------------ int X2RunWildMagicScript(); int X2UseMagicDeviceCheck() { int nRet = ExecuteScriptAndReturnInt("x2_pc_umdcheck",OBJECT_SELF); return nRet; } //------------------------------------------------------------------------------ // GZ: This is a filter I added to prevent spells from firing their original spell // script when they were cast on items and do not have special coding for that // case. If you add spells that can be cast on items you need to put them into // des_crft_spells.2da //------------------------------------------------------------------------------ int X2CastOnItemWasAllowed(object oItem) { int bAllow = (Get2DAString(X2_CI_CRAFTING_SP_2DA,"CastOnItems",GetSpellId()) == "1"); if (!bAllow) { FloatingTextStrRefOnCreature(83453, OBJECT_SELF); // not cast spell on item } return bAllow; } //------------------------------------------------------------------------------ // Execute a user overridden spell script. //------------------------------------------------------------------------------ int X2RunUserDefinedSpellScript() { // See x2_inc_switches for details on this code string sScript = GetModuleOverrideSpellscript(); if (sScript != "") { ExecuteScript(sScript,OBJECT_SELF); if (GetModuleOverrideSpellScriptFinished() == TRUE) { return FALSE; } } return TRUE; } //------------------------------------------------------------------------------ // PALMER Execute the wild magic script. //------------------------------------------------------------------------------ int X2RunWildMagicScript() { // Remember returning FALSE will prevent the spell from being cast // So if we DO use wild magic, we return FALSE here if (jw_check_wildmagic()) { //SpeakString("Debug - Spellhook got a TRUE response to wild magic"); return FALSE; } else { // SpeakString("Debug - Spellhook got a FALSE response to wild magic"); return TRUE; } } //------------------------------------------------------------------------------ // Created Brent Knowles, Georg Zoeller 2003-07-31 // Returns TRUE (and charges the sequencer item) if the spell // ... was cast on an item AND // ... the item has the sequencer property // ... the spell was non hostile // ... the spell was not cast from an item // in any other case, FALSE is returned an the normal spellscript will be run //------------------------------------------------------------------------------ int X2GetSpellCastOnSequencerItem(object oItem) { if (!GetIsObjectValid(oItem)) { return FALSE; } int nMaxSeqSpells = IPGetItemSequencerProperty(oItem); // get number of maximum spells that can be stored if (nMaxSeqSpells <1) { return FALSE; } if (GetIsObjectValid(GetSpellCastItem())) // spell cast from item? { // we allow scrolls int nBt = GetBaseItemType(GetSpellCastItem()); if ( nBt !=BASE_ITEM_SPELLSCROLL && nBt != 105) { FloatingTextStrRefOnCreature(83373, OBJECT_SELF); return TRUE; // wasted! } } // Check if the spell is marked as hostile in spells.2da int nHostile = StringToInt(Get2DAString("spells","HostileSetting",GetSpellId())); if(nHostile ==1) { FloatingTextStrRefOnCreature(83885,OBJECT_SELF); return TRUE; // no hostile spells on sequencers, sorry ya munchkins :) } int nNumberOfTriggers = GetLocalInt(oItem, "X2_L_NUMTRIGGERS"); // is there still space left on the sequencer? if (nNumberOfTriggers < nMaxSeqSpells) { // success visual and store spell-id on item. effect eVisual = EffectVisualEffect(VFX_IMP_BREACH); nNumberOfTriggers++; //NOTE: I add +1 to the SpellId to spell 0 can be used to trap failure int nSID = GetSpellId()+1; SetLocalInt(oItem, "X2_L_SPELLTRIGGER" + IntToString(nNumberOfTriggers), nSID); SetLocalInt(oItem, "X2_L_NUMTRIGGERS", nNumberOfTriggers); ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, OBJECT_SELF); FloatingTextStrRefOnCreature(83884, OBJECT_SELF); } else { FloatingTextStrRefOnCreature(83859,OBJECT_SELF); } return TRUE; // in any case, spell is used up from here, so do not fire regular spellscript } //------------------------------------------------------------------------------ // * This is our little concentration system for black blade of disaster // * if the mage tries to cast any kind of spell, the blade is signaled an event to die //------------------------------------------------------------------------------ void X2BreakConcentrationSpells() { // * At the moment we got only one concentration spell, black blade of disaster object oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED); if (GetIsObjectValid(oAssoc) && GetIsPC(OBJECT_SELF)) // only applies to PCS { if(GetTag(oAssoc) == "x2_s_bblade") // black blade of disaster { if (GetLocalInt(OBJECT_SELF,"X2_L_CREATURE_NEEDS_CONCENTRATION")) { SignalEvent(oAssoc,EventUserDefined(X2_EVENT_CONCENTRATION_BROKEN)); } } } } //------------------------------------------------------------------------------ // being hit by any kind of negative effect affecting the caster's ability to concentrate // will cause a break condition for concentration spells //------------------------------------------------------------------------------ int X2GetBreakConcentrationCondition(object oPlayer) { effect e1 = GetFirstEffect(oPlayer); int nType; int bRet = FALSE; while (GetIsEffectValid(e1) && !bRet) { nType = GetEffectType(e1); if (nType == EFFECT_TYPE_STUNNED || nType == EFFECT_TYPE_PARALYZE || nType == EFFECT_TYPE_SLEEP || nType == EFFECT_TYPE_FRIGHTENED || nType == EFFECT_TYPE_PETRIFY || nType == EFFECT_TYPE_CONFUSED || nType == EFFECT_TYPE_DOMINATED || nType == EFFECT_TYPE_POLYMORPH) { bRet = TRUE; } e1 = GetNextEffect(oPlayer); } return bRet; } void X2DoBreakConcentrationCheck() { object oMaster = GetMaster(); if (GetLocalInt(OBJECT_SELF,"X2_L_CREATURE_NEEDS_CONCENTRATION")) { if (GetIsObjectValid(oMaster)) { int nAction = GetCurrentAction(oMaster); // master doing anything that requires attention and breaks concentration if (nAction == ACTION_DISABLETRAP || nAction == ACTION_TAUNT || nAction == ACTION_PICKPOCKET || nAction ==ACTION_ATTACKOBJECT || nAction == ACTION_COUNTERSPELL || nAction == ACTION_FLAGTRAP || nAction == ACTION_CASTSPELL || nAction == ACTION_ITEMCASTSPELL) { SignalEvent(OBJECT_SELF,EventUserDefined(X2_EVENT_CONCENTRATION_BROKEN)); } else if (X2GetBreakConcentrationCondition(oMaster)) { SignalEvent(OBJECT_SELF,EventUserDefined(X2_EVENT_CONCENTRATION_BROKEN)); } } } } // ADDED BY PALMER int PalmerCheckDruidSpellFailure() { int nReturn=TRUE; object oCaster=OBJECT_SELF; int nClass=GetLastSpellCastClass(); if (nClass==CLASS_TYPE_DRUID) { int nFailure=GetArcaneSpellFailure(oCaster); int nShield=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oCaster)); if (nShield==BASE_ITEM_TOWERSHIELD) { nFailure=nFailure-50; } if (nShield==BASE_ITEM_LARGESHIELD) { nFailure=nFailure-15; } if (nShield==BASE_ITEM_SMALLSHIELD) { nFailure=nFailure-5; } if ((nFailure>20)&&(d100()