/////////////////////////////////////////////////////////////////////////////// // Spells out the Wazoo - Command/Suggestion spell // By Deva Bryson Winblood. 12/19/2003 /////////////////////////////////////////////////////////////////////////////// // This script MUST be called by a conversation. The conversation enables the // caster to choose the word they utter. /////////////////////////////////////////////////////////////////////////////// #include "prc_inc_spells" #include "x2_inc_spellhook" /// NOTE: This script is called by a conversation /// The conversation is started when the spell is cast and is handled by /// script wazoo_s0_ctl1 ////////////// // CONSTANTS ////////////// const int SPELL_COMMAND = 864; const int SPELL_SUGGESTION = 865; // put correct # here ///////////// // WORDS: //////////// const int COMMAND_DIE = 0; const int COMMAND_FLEE = 1; const int COMMAND_HALT = 2; const int COMMAND_RUN = 3; const int COMMAND_STOP = 4; const int COMMAND_FALL = 5; const int COMMAND_GO = 6; const int COMMAND_SLEEP = 7; const int COMMAND_SIT = 8; const int COMMAND_SPEAK = 9; const int COMMAND_ATTACK = 10; const int COMMAND_OPEN = 11; const int COMMAND_CLOSE = 12; const int COMMAND_STEAL = 13; const int COMMAND_SEARCH = 14; const int COMMAND_DISARM = 15; const int COMMAND_FORGET = 16; const int COMMAND_HIDE = 17; const int COMMAND_HALLUCINATE = 18; const int COMMAND_WANDER = 19; const int COMMAND_FUMBLE = 20; const int COMMAND_GET = 21; const int COMMAND_DRINK = 22; const int COMMAND_HEAL = 23; const int COMMAND_RELAX = 24; //////////////////////////////// // PROTOTYPES //////////////////////////////// void fnCommandDie(object oTarget,float fDuration=6.0); void fnCommandFlee(object oTarget,float fDuration=6.0); void fnCommandHalt(object oTarget,float fDuration=6.0); void fnCommandRun(object oTarget,float fDuration=6.0); void fnCommandStop(object oTarget,float fDuration=6.0); void fnCommandFall(object oTarget,float fDuration=6.0); void fnCommandGo(object oTarget,float fDuration=6.0); void fnCommandSleep(object oTarget,float fDuration=6.0); void fnCommandSit(object oTarget,float fDuration=6.0); void fnCommandSpeak(object oTarget,float fDuration=6.0); void fnCommandAttack(object oTarget,float fDuration=6.0); void fnCommandOpen(object oTarget,float fDuration=6.0); void fnCommandClose(object oTarget,float fDuration=6.0); void fnCommandSteal(object oTarget,float fDuration=6.0); void fnCommandSearch(object oTarget,float fDuration=6.0); void fnCommandDisarm(object oTarget,float fDuration=6.0); void fnCommandForget(object oTarget,float fDuration=6.0); void fnCommandHide(object oTarget,float fDuration=6.0); void fnCommandHallucinate(object oTarget,float fDuration=6.0); void fnCommandWander(object oTarget,float fDuration=6.0); void fnCommandFumble(object oTarget,float fDuration=6.0); void fnCommandGet(object oTarget,float fDuration=6.0); void fnCommandDrink(object oTarget,float fDuration=6.0); void fnCommandHeal(object oTarget,float fDuration=6.0); void fnCommandRelax(object oTarget,float fDuration=6.0); void fnSpellControl(object oTarget,int nWord,int nSpellID,float fDuration=6.0); /////////////////////////////////////////////////////////[ MAIN ]////////////// void main() { object oCaster=GetPCSpeaker(); object oTarget=GetLocalObject(oCaster,"oSpellTarget"); int nWord=GetLocalInt(oCaster,"nParm"); int nID=GetLocalInt(oCaster,"nSpellID"); int nSaveDC=PRCGetSpellSaveDC(); int bSaved=FALSE; // did the target save? float fDuration; int nMetaMagic = PRCGetMetaMagicFeat(); int nCasterLevel=GetLocalInt(oCaster,"nCasterLevel"); int nL; int nClass; int nT=0; string sSay="DIE!"; int bHostile=FALSE; if (nWord==COMMAND_FLEE) sSay="FLEE!"; else if (nWord==COMMAND_HALT) sSay="HALT!"; else if (nWord==COMMAND_RUN) sSay="RUN!"; else if (nWord==COMMAND_STOP) sSay="STOP!"; else if (nWord==COMMAND_FALL) { sSay="FALL!"; bHostile=TRUE; } else if (nWord==COMMAND_GO) sSay="GO!"; else if (nWord==COMMAND_SLEEP){ sSay="SLEEP!"; bHostile=TRUE; } else if (nWord==COMMAND_SIT) sSay="SIT!"; else if (nWord==COMMAND_SPEAK) sSay="SPEAK!"; else if (nWord==COMMAND_ATTACK) sSay="ATTACK!"; else if (nWord==COMMAND_OPEN) { sSay="OPEN!"; bHostile=TRUE; } else if (nWord==COMMAND_CLOSE) sSay="CLOSE!"; else if (nWord==COMMAND_STEAL) sSay="STEAL!"; else if (nWord==COMMAND_SEARCH) sSay="SEARCH!"; else if (nWord==COMMAND_DISARM) sSay="DISARM!"; else if (nWord==COMMAND_FORGET) { sSay="FORGET!"; bHostile=TRUE; } else if (nWord==COMMAND_HIDE) sSay="HIDE!"; else if (nWord==COMMAND_HALLUCINATE) sSay="HALLUCINATE!"; else if (nWord==COMMAND_WANDER) sSay="WANDER!"; else if (nWord==COMMAND_FUMBLE) { sSay="FUMBLE!"; bHostile=TRUE; } else if (nWord==COMMAND_GET) sSay="GET!"; else if (nWord==COMMAND_DRINK) { sSay="DRINK!"; bHostile=TRUE; } else if (nWord==COMMAND_HEAL) sSay="HEAL!"; else if (nWord==COMMAND_RELAX) sSay="RELAX!"; if (!X2PreSpellCastCode()) { // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell return; } AssignCommand(oCaster,SpeakString(sSay)); if (nID==SPELL_SUGGESTION) { fDuration=HoursToSeconds(nCasterLevel); nL=GetLevelByClass(CLASS_TYPE_SORCERER,oCaster); if (nL==nCasterLevel) { nT=nL; nClass=CLASS_TYPE_SORCERER; } nL=GetLevelByClass(CLASS_TYPE_BARD,oCaster); if (nL==nCasterLevel) { nT=nL; nClass=CLASS_TYPE_BARD; } nL=GetLevelByClass(CLASS_TYPE_WIZARD,oCaster); if (nL==nCasterLevel) { nT=nL; nClass=CLASS_TYPE_WIZARD; } } else { fDuration=6.0; } //// cleanup DeleteLocalObject(oCaster,"oSpellTarget"); DeleteLocalInt(oCaster,"nParm"); DeleteLocalInt(oCaster,"nSpellID"); DeleteLocalInt(oCaster,"nCasterLevel"); //// METAMAGIC if (nMetaMagic == METAMAGIC_EXTEND) { fDuration = fDuration * 2.0; } //// Check for target saving throw nT=WillSave(oTarget,nSaveDC); if (nT!=0) bSaved=TRUE; //// Process spell if (bSaved==FALSE) { // check for resistance nT=ResistSpell(oCaster,oTarget); if (nT>0) bSaved=TRUE; if (nT==2) SendMessageToPC(oCaster,"The target is immune to this spell!"); else if (nT==3) SendMessageToPC(oCaster,"The target absorbed the spell!"); } // check for resistance if (bSaved==FALSE) { // the target did not make their saving throw SendMessageToPC(oCaster,"The command spell was successful."); SetLocalInt(oTarget,"bSPELL"+IntToString(nID),TRUE);// set a variable in case you want to make other spells detect and be able to dispel DelayCommand(fDuration+0.02,DeleteLocalInt(oTarget,"bSPELL"+IntToString(nID))); // remove spell effect flag SetLocalObject(oTarget,"oCASTER",oCaster); DelayCommand(fDuration+0.03,DeleteLocalObject(oTarget,"oCASTER")); fnSpellControl(oTarget,nWord,nID,fDuration); if (bHostile==TRUE) DelayCommand(fDuration+0.01,SetIsTemporaryEnemy(oTarget,oCaster)); } // the target did not make their saving throw else { SendMessageToPC(oCaster,"The target of the spell resisted."); } } /////////////////////////////////////////////////////////[ MAIN ]////////////// void fnSpellControl(object oTarget,int nWord,int nSpellID,float fDuration=6.0) { // handles all the spell modes and recursion if needed int bRecursion=FALSE; int bActive=GetLocalInt(oTarget,"bSPELL"+IntToString(nSpellID)); //SendMessageToPC(GetFirstPC(),"SPELL: WORD:"+IntToString(nWord)+" TARGET:"+GetName(oTarget)+" DURATION:"+FloatToString(fDuration)+" SPELLID:"+IntToString(nSpellID)); if (bActive==TRUE) { // spell not dispelled switch(nWord) { // main word switch case COMMAND_DIE: { // die fnCommandDie(oTarget,fDuration); break; } // die case COMMAND_FLEE: { // flee fnCommandFlee(oTarget); bRecursion=TRUE; break; } // flee case COMMAND_HALT: { // halt fnCommandHalt(oTarget,fDuration); break; } // halt case COMMAND_RUN: { // run fnCommandRun(oTarget,fDuration); break; } // run case COMMAND_STOP: { // stop fnCommandStop(oTarget,fDuration); break; } // stop case COMMAND_FALL: { // fall fnCommandFall(oTarget,fDuration-0.8); bRecursion=TRUE; break; } // fall case COMMAND_GO: { // go fnCommandGo(oTarget); bRecursion=TRUE; break; } // go case COMMAND_SLEEP: { // sleep fnCommandSleep(oTarget,fDuration); break; } // sleep case COMMAND_SIT: { // sit fnCommandSit(oTarget); bRecursion=TRUE; break; } // sit case COMMAND_SPEAK: { // speak fnCommandSpeak(oTarget); bRecursion=TRUE; break; } // speak case COMMAND_ATTACK: { // attack fnCommandAttack(oTarget); bRecursion=TRUE; break; } // attack case COMMAND_OPEN: { // open fnCommandOpen(oTarget); break; } // open case COMMAND_CLOSE: { // close fnCommandClose(oTarget); break; } // close case COMMAND_STEAL: { // steal fnCommandSteal(oTarget); break; } // steal case COMMAND_SEARCH: { // search fnCommandSearch(oTarget); bRecursion=TRUE; break; } // search case COMMAND_DISARM: { // disarm fnCommandDisarm(oTarget); break; } // disarm case COMMAND_FORGET: { // forget fnCommandForget(oTarget); bRecursion=TRUE; break; } // forget case COMMAND_HIDE: { // hide fnCommandHide(oTarget); bRecursion=TRUE; break; } // hide case COMMAND_HALLUCINATE: { // hallucinate fnCommandHallucinate(oTarget); bRecursion=TRUE; break; } // hallucinate case COMMAND_WANDER: { // wander fnCommandWander(oTarget); bRecursion=TRUE; break; } // wander case COMMAND_FUMBLE: { // fumble fnCommandFumble(oTarget); bRecursion=TRUE; break; } // fumble case COMMAND_GET: { // get fnCommandGet(oTarget); bRecursion=TRUE; break; } // get case COMMAND_DRINK: { // drink fnCommandDrink(oTarget); break; } // drink case COMMAND_HEAL: { // heal fnCommandHeal(oTarget); bRecursion=TRUE; break; } // heal case COMMAND_RELAX: { // relax fnCommandRelax(oTarget,fDuration); break; } // relax } // main word switch // end of control if (bRecursion==TRUE&&fDuration>6.0) DelayCommand(6.0,fnSpellControl(oTarget,nWord,nSpellID,fDuration-6.0)); } // spell not dispelled } // fnSpellControl() void fnCommandRelax(object oTarget,float fDuration=6.0) { // applies charm effect effect eCharm=EffectCharmed(); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eCharm,oTarget,fDuration); } // fnCommandRelax() void fnCommandHeal(object oTarget,float fDuration=6.0) { // will heal self then ANY nearby wounded creatures int nCHP=GetCurrentHitPoints(oTarget); int nMHP=GetMaxHitPoints(oTarget); int nC=1; object oC=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oTarget,nC); object oT=OBJECT_INVALID; if (nCHP7) { // mutter nINT=d4(); if (nINT==2) sSay="Did you see that?"; else if (nINT==3) sSay="That sound tastes funny."; else if (nINT==4) sSay="Look at the pretty colors."; AssignCommand(oTarget,SpeakString(sSay)); } // mutter } // fnCommandHallucinate() void fnCommandHide(object oTarget,float fDuration=6.0) { // put target into hide mode int nMode=GetActionMode(oTarget,ACTION_MODE_STEALTH); if (nMode==FALSE) { // put in hide mode SetActionMode(oTarget,ACTION_MODE_STEALTH,TRUE); } // put in hide mode } // fnCommandHide() void fnCommandForget(object oTarget,float fDuration=6.0) { // fire off ClearAllActions(TRUE) AssignCommand(oTarget,ClearAllActions(TRUE)); } // fnCommandForget() void fnCommandDisarm(object oTarget,float fDuration=6.0) { // disarm int nC=1; object oNearD=GetNearestObject(OBJECT_TYPE_DOOR,oTarget,nC); object oNearP=GetNearestObject(OBJECT_TYPE_PLACEABLE,oTarget,nC); object oNearT=GetNearestObject(OBJECT_TYPE_TRIGGER,oTarget,nC); object oT=OBJECT_INVALID; int bDone=FALSE; float fDistC; int nRun=GetLocalInt(oTarget,"nRun"); while(oT==OBJECT_INVALID&&(oNearD!=OBJECT_INVALID||oNearP!=OBJECT_INVALID||oNearT!=OBJECT_INVALID)&&bDone==FALSE) { // look for target fDistC=999.0; if (oNearD!=OBJECT_INVALID&&GetDistanceBetween(oNearD,oTarget)0.0&&fClosest<15.0) { // look for something to open if (oD!=OBJECT_INVALID&&GetIsOpen(oD)==FALSE) oT=oD; else if (oC!=OBJECT_INVALID) { // placeable if (GetHasInventory(oC)==TRUE) { // can be opened if (GetIsOpen(oD)!=TRUE) oT=oC; } // can be opened } // placeable nC++; oD=GetNearestObject(OBJECT_TYPE_DOOR,oTarget,nC); oC=GetNearestObject(OBJECT_TYPE_PLACEABLE,oTarget,nC); fDistD=GetDistanceBetween(oD,oTarget); fDistC=GetDistanceBetween(oC,oTarget); fClosest=fDistD; if (fClosest<0.1) fClosest=999.0; if (fDistC7) { // can speak nINT=d6(); AssignCommand(oTarget,ClearAllActions(TRUE)); if (nINT==1)AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_BATTLECRY1,oTarget)); else if (nINT==2) AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_HELLO,oTarget)); else if (nINT==3) AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_LAUGH,oTarget)); else if (nINT==4) AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_NO,oTarget)); else if (nINT==5) AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_CUSS,oTarget)); else if (nINT==6) AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_GOODBYE,oTarget)); AssignCommand(oTarget,ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL,1.0,fDuration)); SetCommandable(FALSE,oTarget); DelayCommand(fDuration-0.8,SetCommandable(TRUE,oTarget)); } // can speak else { // make noises AssignCommand(oTarget,ClearAllActions(TRUE)); AssignCommand(oTarget,PlayVoiceChat(VOICE_CHAT_BATTLECRY1,oTarget)); DelayCommand(0.5,SetCommandable(FALSE,oTarget)); DelayCommand(fDuration-0.5,SetCommandable(TRUE,oTarget)); } // make noises } // fnCommandSpeak() void fnCommandSit(object oTarget,float fDuration=6.0) { // sit crosslegged AssignCommand(oTarget,ClearAllActions(TRUE)); AssignCommand(oTarget,ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS,1.0,fDuration)); } // fnCommandSit() void fnCommandSleep(object oTarget,float fDuration=6.0) { // cause npc to sleep like sleep spell but, not a sleep spell effect eSleep=EffectSleep(); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSleep,oTarget,fDuration); } // fnCommandSleep() void fnCommandGo(object oTarget,float fDuration=6.0) { // this will cause the target to attempt to get further and further from the caster object oCaster=GetLocalObject(oTarget,"oCASTER"); float fDist=GetDistanceBetween(oCaster,oTarget); int nRun=GetLocalInt(oTarget,"nRun"); fDist=fDist+8.0; AssignCommand(oTarget,ClearAllActions(TRUE)); AssignCommand(oTarget,ActionMoveAwayFromObject(oCaster,nRun,fDist)); } // fnCommandGo() void fnCommandFall(object oTarget,float fDuration=6.0) { // this will keep applying the knockdown effect to the target effect eKnockdown=EffectKnockdown(); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eKnockdown,oTarget,fDuration); } // fnCommandFall() void fnCommandStop(object oTarget,float fDuration=6.0) { // this command will 75% of the time work like halt... 25% it will just // fire a single ClearAllActions(TRUE); int nP=d100(); if (nP<76) fnCommandHalt(oTarget,fDuration); else { AssignCommand(oTarget,ClearAllActions(TRUE)); } } // fnCommandStop() void fnCommandRun(object oTarget,float fDuration=6.0) { // set characters movement type nRun to TRUE // this is only useful for scripts where nRun is a variable TRUE/FALSE // stored on an NPC to determine how it should move from point A to B. int nRun=GetLocalInt(oTarget,"nRun"); AssignCommand(oTarget,ClearAllActions(TRUE)); SetLocalInt(oTarget,"nRun",TRUE); DelayCommand(fDuration,SetLocalInt(oTarget,"nRun",nRun)); } // fnCommandRun() void fnCommandHalt(object oTarget,float fDuration=6.0) { // stop walking/running effect eImmobilize=EffectCutsceneImmobilize(); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eImmobilize,oTarget,fDuration); } // fnCommandHalt() void fnCommandFlee(object oTarget,float fDuration=6.0) { // flee from any enemy object oEnemy=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oTarget,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); float fDist=GetDistanceBetween(oEnemy,oTarget); if (oEnemy!=OBJECT_INVALID) { AssignCommand(oTarget,ClearAllActions(TRUE)); fDist=fDist+15.0; AssignCommand(oTarget,ActionMoveAwayFromObject(oTarget,TRUE,fDist)); } else { AssignCommand(oTarget,ClearAllActions(TRUE)); } DelayCommand(0.5,SetCommandable(FALSE,oTarget)); DelayCommand(fDuration,SetCommandable(TRUE,oTarget)); } // fnCommandFlee() void fnCommandDie(object oTarget,float fDuration=6.0) { // feign death for duration AssignCommand(oTarget,ClearAllActions(TRUE)); AssignCommand(oTarget,ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,fDuration)); DelayCommand(0.5,SetCommandable(FALSE,oTarget)); DelayCommand(fDuration+0.01,SetCommandable(TRUE,oTarget)); } // fnCommandDie()