/************************ [On Percieve] **************************************** Filename: j_ai_onpercieve or nw_c2_default2 ************************* [On Percieve] **************************************** If the target is an enemy, attack Will determine combat round on that person, is an enemy, basically. Includes shouting for a big radius - if the spawn in condition is set to this. NOTE: Debug strings in this file will be uncommented for speed by default. - It is one of the most intensive scripts as it runs so often. - Attempted to optimise as much as possible. ************************* [History] ******************************************** 1.3 - We include j_inc_other_ai to initiate combat (or go into combat again) - j_inc_other_ai holds all other needed functions/integers ETC. - Turn off hide things. - Added "Only attack if attacked" - Removed special conversation things. Almost no one uses them, and the taunt system is easier. - Should now search around if they move to a dead body, and only once they get there. ************************* [Workings] ******************************************* It fires: - When a creature enters it perception range (Set in creature properties) and is seen or heard. - When a creature uses invisiblity/leaves the area in the creatures perception range - When a creature appears suddenly, already in the perception range (not the other way round, normally) - When a creature moves out of the creatures perception range, and therefore becomes unseen. ************************* [Arguments] ****************************************** Arguments: GetLastPerceived, GetLastPerceptionSeen, GetLastPerceptionHeard, GetLastPerceptionVanished, GetLastPerceptionInaudible. ************************* [On Percieve] ***************************************/ #include "j_inc_other_ai" void main() { // Percieve pre event. if(FireUserEvent(AI_FLAG_UDE_PERCIEVE_PRE_EVENT, EVENT_PERCIEVE_PRE_EVENT)) // We may exit if it fires if(ExitFromUDE(EVENT_PERCIEVE_PRE_EVENT)) return; // AI status check. Is the AI on? if(GetAIOff()) return; ExecuteScript("prc_npc_percep", OBJECT_SELF); if (GetLevelByClass(CLASS_TYPE_COMMONER) > 0) { ExecuteScript("oai_default2", OBJECT_SELF); return; } // Declare main things. // - We declare OUTSIDE if's JUST IN CASE! object oPerceived = GetLastPerceived(); object oAttackTarget = GetAttackTarget(); int bSeen = GetLastPerceptionSeen(); int bHeard = GetLastPerceptionHeard(); // Need to be valid and not ignorable. if(GetIsObjectValid(oPerceived) && !GetIsDM(oPerceived) && !GetIgnore(oPerceived)) { // First, easy enemy checks. if(GetIsEnemy(oPerceived) && !GetFactionEqual(oPerceived)) { // Turn of hiding, a timer to activate Hiding in the main file. This is // done in each of the events, with the opposition checking seen/heard. TurnOffHiding(oPerceived); // Well, are we both inaudible and vanished? // * the GetLastPerception should only say what specific event has fired! if(GetLastPerceptionInaudible() || GetLastPerceptionVanished()) { // If they just became invisible because of the spell // invisiblity, or improved invisiblity...we set a local object. // - Beta: Added in ethereal as well. if(GetHasEffect(EFFECT_TYPE_INVISIBILITY, oPerceived) || GetHasEffect(EFFECT_TYPE_ETHEREAL, oPerceived) || GetStealthMode(oPerceived) == STEALTH_MODE_ACTIVATED) { // Set object, AND the location they went invisible! SetAIObject(AI_LAST_TO_GO_INVISIBLE, oPerceived); // We also set thier location for AOE dispelling - same name SetLocalLocation(OBJECT_SELF, AI_LAST_TO_GO_INVISIBLE, GetLocation(oPerceived)); } // If they were our target, follow! >:-D // - Optional, on spawn option, for following through areas. if(oAttackTarget == oPerceived) { // This means they have exited the area! follow! if(GetArea(oPerceived) != GetArea(OBJECT_SELF)) { ClearAllActions(); // 51: "[Perception] Our Enemy Target changed areas. Stopping, moving too...and attack... [Percieved] " + GetName(oPerceived) DebugActionSpeakByInt(51, oPerceived); // Call to stop silly moving to enemies if we are fleeing ActionMoveToEnemy(oPerceived); } // - Added check for not casting a spell. If we are, we finnish // (EG: AOE spell) and automatically carry on. else if(GetCurrentAction() != ACTION_CASTSPELL) { ClearAllActions(); // 52: "[Perception] Enemy Vanished (Same area) Retargeting/Searching [Percieved] " + GetName(oPerceived) DebugActionSpeakByInt(52, oPerceived); DetermineCombatRound(oPerceived); } } }// End if just gone out of perception // ELSE they have been SEEN or HEARD. We don't check specifics. else //if(bSeen || bHeard) { // If they have been made seen, and they are our attack target, // we must re-do combat round - unless we are casting a spell. if(bSeen && GetCurrentAction() != ACTION_CASTSPELL && (oAttackTarget == oPerceived || !GetObjectSeen(oAttackTarget))) { AISpeakString(I_WAS_ATTACKED); // 53: "[Perception] Enemy seen, and was old enemy/cannot see current. Re-evaluating (no spell) [Percieved] " + GetName(oPerceived) DebugActionSpeakByInt(53, oPerceived); DetermineCombatRound(oPerceived); } // Else We check if we are already attacking. else if(!CannotPerformCombatRound() && !GetSpawnInCondition(AI_FLAG_OTHER_ONLY_ATTACK_IF_ATTACKED, AI_OTHER_MASTER)) { // Special shout, d1000 though! SpeakArrayString(AI_TALK_ON_PERCIEVE_ENEMY, TRUE); // Stop stuff because of facing point - New enemy HideOrClear(); // Face the person (this helps stops sneak attacks if we then // cast something on ourselves, ETC). SetFacingPoint(GetPosition(oPerceived)); // Get all allies in 60M to come to thier aid. Talkvolume silent // shout does not seem to work well. // - void function. Checks for the spawn int. in it. // - Turns it off in it too // - Variable range On Spawn ShoutBossShout(oPerceived); // Warn others AISpeakString(I_WAS_ATTACKED); // 54: "[Perception] Enemy Seen. Not in combat, attacking. [Percieved] " + GetName(oPerceived) DebugActionSpeakByInt(54, oPerceived); // Note: added ActionDoCommand, so that SetFacingPoint is not // interrupted. ActionDoCommand(DetermineCombatRound(oPerceived)); } } } // Else, they are an equal faction, or not an enemy (or both) else { // If they are dead, say we saw something on waypoints, we charge in // to investigate. // * Higher intelligence will buff somewhat as well! if(GetIsDead(oPerceived) && (bSeen || bHeard)) { // Warn others AISpeakString(I_WAS_ATTACKED); // Check if we can attack if(!CannotPerformCombatRound()) { // Hide or clear actions HideOrClear(); // 55: "[Perception] Percieved Dead Friend! Moving and Searching [Percieved] " + GetName(oPerceived) DebugActionSpeakByInt(55, oPerceived); ActionMoveToLocation(GetLocation(oPerceived), TRUE); ActionDoCommand(DetermineCombatRound()); } } else if(GetIsInCombat(oPerceived) && (bSeen || bHeard)) { // Warn others AISpeakString(I_WAS_ATTACKED); // Only if we can attack. if(!CannotPerformCombatRound()) { // Hide or clear actions HideOrClear(); // 56: "[Perception] Percieved Alive Fighting Friend! Moving to and attacking. [Percieved] " + GetName(oPerceived) DebugActionSpeakByInt(56, oPerceived); ActionMoveToLocation(GetLocation(oPerceived), TRUE); ActionDoCommand(DetermineCombatRound()); } } } } // Fire End of Percieve event FireUserEvent(AI_FLAG_UDE_PERCIEVE_EVENT, EVENT_PERCIEVE_EVENT); }