/*////////////////////////////////////////////////////////////////////////////// // Script Name: 0e_id_events //////////////////////////////////////////////////////////////////////////////// Infinite Dungeons monster event handler. */////////////////////////////////////////////////////////////////////////////// #include "0i_actions" #include "x0_i0_assoc" // Followers special heartbeat script. void ai_hen_id1_heart(object oCreature); // Followers special conversation script. void ai_hen_id1_convo(object oCreature, int nMatch); // Followers special perception script. void ai_hen_id1_percept(object oCreature); // Followers special end of round script. void ai_hen_id1_endcombat(object oCreature, int bFollower); // Followers special castat script. void ai_hen_id1_castat(object oCreature); void main() { object oCreature = OBJECT_SELF; int nEvent = GetCurrentlyRunningEvent(); int bFollower = GetLocalInt(oCreature, "bFollower"); //WriteTimestampedLogEntry("0e_id_events [24] " + GetName(oCreature) + " nEvent: " + IntToString(nEvent) + // " bFollower: " + IntToString(bFollower)); switch (nEvent) { case EVENT_SCRIPT_CREATURE_ON_HEARTBEAT: { if(bFollower) ai_hen_id1_heart(oCreature); else ExecuteScript("nw_c2_default1", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_NOTICE: { if(bFollower) ai_hen_id1_percept(oCreature); else ExecuteScript("nw_c2_default2", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_DIALOGUE: { int nMatch = GetListenPatternNumber(); if(nMatch == -1) { if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature) || GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return; ai_ClearCreatureActions(); string sConversation = GetLocalString(oCreature, "sConversation"); if(sConversation != "") BeginConversation(sConversation); else BeginConversation(); } if(bFollower) ai_hen_id1_convo(oCreature, nMatch); else ExecuteScript("nw_c2_default4", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED: { if(bFollower) ExecuteScript("nw_ch_ac5", oCreature); else ExecuteScript("nw_c2_default5", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_DAMAGED: { if(bFollower) ExecuteScript("nw_ch_ac6", oCreature); else ExecuteScript("nw_c2_default6", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT: { if(bFollower) ai_hen_id1_castat(oCreature); else ExecuteScript("nw_c2_defaultb", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND: { ai_hen_id1_endcombat(oCreature, bFollower); break; } case EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR: { if(bFollower) ExecuteScript("nw_ch_ace", oCreature); else ExecuteScript("nw_c2_defaulte", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_RESTED: { if(bFollower) ExecuteScript("nw_ch_aca", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_DISTURBED: { if(bFollower) ExecuteScript("nw_ch_ac8", oCreature); else ExecuteScript("nw_c2_default8", oCreature); break; } case EVENT_SCRIPT_CREATURE_ON_DEATH: { if(bFollower) ExecuteScript("nw_ch_ac7", oCreature); else { ExecuteScript("nw_c2_default7", oCreature); } break; } } } void ai_hen_id1_heart(object oCreature) { // Sometimes they slip out of this mode! if(GetAssociateState(NW_ASC_MODE_DYING, oCreature) && GetCommandable()) { ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 65.0); SetCommandable(FALSE); } ExecuteScript("nw_ch_ac1", oCreature); } void ai_hen_id1_convo(object oCreature, int nMatch) { if(nMatch == ASSOCIATE_COMMAND_INVENTORY) { // * cannot modify disabled equipment if(!GetLocalInt(OBJECT_SELF, "X2_JUST_A_DISABLEEQUIP")) { OpenInventory(oCreature, GetLastSpeaker()); } // * feedback as to why else SendMessageToPCByStrRef(GetMaster(), 100895); return; } else if(nMatch == ASSOCIATE_COMMAND_LEAVEPARTY) { object oMaster = GetMaster(); string sTag = GetTag(GetArea(oMaster)); // * henchman cannot be kicked out in the reaper realm // * Followers can never be kicked out if (sTag == "GatesofCania" || GetIsFollower(oCreature)) return; if(GetIsObjectValid(oMaster)) { ai_ClearCreatureActions(); if(GetAssociateType(oCreature) == ASSOCIATE_TYPE_HENCHMAN) { string sConversation = GetLocalString(oCreature, "sConversation"); if (sConversation == "id1_plotgiver") { string sVariable = GetLocalString(oCreature, "sVariable"); object oDungeon = GetLocalObject(GetModule(), "oCurrentDungeon"); SetLocalInt(oDungeon, "b" + sVariable + "Gone", FALSE); } RemoveHenchman(oMaster); DestroyObject(oCreature); } } return; } ExecuteScript("nw_ch_ac4", oCreature); } void ai_hen_id1_percept(object oCreature) { // If henchman is dying and Player disappears then force a respawn of the henchman if (GetIsHenchmanDying(oCreature)) { // The henchman must be removed otherwise their corpse will follow the player object oOldMaster = GetMaster(); object oPC = GetLastPerceived(); int bVanish = GetLastPerceptionVanished(); if(GetIsObjectValid(oPC) && bVanish) { if (oPC == oOldMaster) { RemoveHenchman(oPC, oCreature); // Only in chapter 1 if(GetTag(GetModule()) == "x0_module1") { SetCommandable(TRUE); DoRespawn(oPC, oCreature); // Should teleport henchman back } } } } ExecuteScript("nw_ch_ac2", oCreature); } void ai_hen_id1_endcombat(object oCreature, int bFollower) { if (ai_GetIsInCombat(oCreature)) { int nNum; int nLine; string sString; int nCreature; int bIntelligent; int nRandom = d100(); // chance of a oneliner int nOnelinerPercentage = GetLocalInt(GetModule(), "nFlagCombatOneLinerFrequencyValue"); if(nRandom <= nOnelinerPercentage) { string sCreature = GetLocalString(oCreature, "sVariable"); // if the current creature is hostile towards PCs if(sCreature != "") { object oDungeon = GetLocalObject(GetModule(), "oCurrentDungeon"); if(GetIsReactionTypeHostile(GetFirstPC())) { nCreature = GetLocalInt(oDungeon, "n" + sCreature); bIntelligent = GetLocalInt(oDungeon, "bListCreature" + IntToString(nCreature) + "Intelligent"); if(bIntelligent) { nNum = GetLocalInt(GetModule(), "nLinesHostileNum"); nLine = Random(nNum) + 1; if(nLine > 0) { sString = GetLocalString(GetModule(), "sLinesHostile" + IntToString(nLine)); SpeakString(sString, TALKVOLUME_SHOUT); } } } else { nCreature = GetLocalInt(oDungeon, "n" + sCreature); bIntelligent = GetLocalInt(oDungeon, "bListCreature" + IntToString(nCreature) + "Intelligent"); if(bIntelligent) { nNum = GetLocalInt(GetModule(), "nLinesAlliesNum"); nLine = Random(nNum) + 1; if (nLine > 0) { sString = GetLocalString(GetModule(), "sLinesAllies" + IntToString(nLine)); SpeakString(sString, TALKVOLUME_SHOUT); } } } } } } if(bFollower) ExecuteScript("nw_ch_ac3", oCreature); else ExecuteScript("nw_c2_default3", oCreature); } void ai_hen_id1_castat(object oCreature) { if(!GetLastSpellHarmful()) { int nSpell = GetLastSpell(); if(nSpell == SPELL_RAISE_DEAD || nSpell == SPELL_RESURRECTION) { object oCaster = GetLastSpellCaster(); // Restore faction to neutral SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 100, oCaster); SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 100, oCaster); SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 100, oCaster); ClearPersonalReputation(oCaster, oCreature); AssignCommand(oCreature, SurrenderToEnemies()); AssignCommand(oCreature, ai_ClearCreatureActions(TRUE)); // Reset henchmen attack state - Oct 28 (BK) ai_SetAIMode(oCreature, AI_MODE_DEFEND_MASTER, FALSE); ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE); ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); // Oct 30 - If player previously hired this hench // then just have them rejoin automatically if(GetPlayerHasHired(oCaster, oCreature)) { // Feb 11, 2004 - Jon: Don't fire the HireHenchman function if the // henchman is already oCaster's associate. Fixes a silly little problem // that occured when you try to raise a henchman who wasn't actually dead. if(GetMaster(oCreature)!= oCaster) HireHenchman(oCaster, oCreature, TRUE); } else { string sFile = GetDialogFileToUse(oCaster); AssignCommand(oCaster, ActionStartConversation(oCreature, sFile)); } } } ExecuteScript("nw_ch_acb", oCreature); }