Files
dsrc/sku.0/sys.server/compiled/game/script/ai/ai_template.script
T

415 lines
10 KiB
Plaintext

include library.ai_lib;
include library.factions;
include ai.ai_combat;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
const string ACTION_ALERT = "alert";
const string ACTION_THREATEN = "threaten";
const float CORPSE_CLEANUP_DELAY = 30.0f;
trigger OnAttach()
{
// To ensure that you don't do anything with the NPC until he has been
// instantiated and setup, use a callback:
//CHANGE THE NAME OF THIS HANDLER TO ONE SPECIFIC TO THIS AI SCRIPT!
messageTo( self, "handleSetupNPC", null, 5, isObjectPersisted( self ) );
//mever do anything here.
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
//mever do anything here.
return SCRIPT_CONTINUE;
}
//CHANGE THE NAME OF THIS HANDLER TO ONE SPECIFIC TO THIS AI SCRIPT!
messageHandler handleSetupNPC()
{
//if setup isn't complete yet, then wait 5 seconds and try again:
if ( !hasObjVar( self, "ai.setupComplete" ))
{
//CHANGE THE NAME OF THIS HANDLER TO ONE SPECIFIC TO THIS AI SCRIPT!
messageTo( self, "handleSetupNPC", null, 5, isObjectPersisted( self ) );
return SCRIPT_CONTINUE;
}
/* -----------------9/11/2002 11:30AM----------------
* Your setup code goes here.
* --------------------------------------------------*/
return SCRIPT_CONTINUE;
}
messageHandler resumeDefaultCalmBehavior()
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
if ( hasObjVar( self, "ai.conversing") )
{
//the npc is conversing. Want to do something special?
// return SCRIPT_OVERRIDE;
// otherwise
return SCRIPT_CONTINUE;
}
//if you don't want a calm NPC to resume his default calm behavior,
// then
//
// YOUR CODE GOES HERE
//
// return SCRIPT_OVERRIDE;
// else
return SCRIPT_CONTINUE;
}
trigger OnMovePathComplete()
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
return SCRIPT_CONTINUE;
}
trigger OnMovePathNotFound()
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
// return SCRIPT_OVERRIDE; if you do NOT want the NPC to
// resume patrolling (if he was patrolling) or to
// resume his default behavior (if he's calm)
// otherwise:
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
//ignore gm's
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
//ignore yourself and dead things
if ( breacher == self || ai_lib.isAiDead( breacher ) )
return SCRIPT_CONTINUE;
if ( volumeName == ALERT_VOLUME_NAME )
{
//the alert trigger has been breached! Wand to prevent default
// reactions from taking place?
// return SCRIPT_OVERRIDE;
// otherwise:
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
if ( volumeName == ALERT_VOLUME_NAME )
{
//want to prevent herding behaviors and the like?
// if you return SCRIPT_OVERRIDE here, make sure
// to call this function first!
//ignoreCreatureMovement(self, breacher);
// return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
trigger OnLoiterWaiting(modifiable_float time)
{
int herding = dataTableGetInt("datatables/ai/species.iff", ai_lib.aiGetSpecies( self ), "Herd");
if ( herding != 1 )
{
//you can do anything you want to here, and
// return SCRIPT_OVERRIDE;
}
//you can do anything you want to here,
// but if you return SCRIPT_OVERRIDE then
// herding animals won't herd!
// Unless you also call:
// ai_lib.maintainHerding( self );
// return SCRIPT_OVERRIDE;
return SCRIPT_CONTINUE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( ai_lib.isAiDead( self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;//you probably don't want to do anything if you are in combat
//don't put code in this trigger. Put it in doCalmerBehavior or doAgitated behavior
// this is hard enough to read already:
if ( newBehavior <= oldBehavior )
{
if ( doCalmerBehavior( self, newBehavior, oldBehavior ) == SCRIPT_CONTINUE)
return SCRIPT_CONTINUE;
else
return SCRIPT_OVERRIDE;
}
else
{
if ( doAgitatedBehavior( self, newBehavior, oldBehavior) == SCRIPT_CONTINUE )
return SCRIPT_CONTINUE;
else
return SCRIPT_OVERRIDE;
}
}
int doCalmerBehavior( obj_id npc, int newBehavior, int oldBehavior )
{
//You are now calming down.
// return SCRIPT_OVERRIDE to stomp on default behaviors:
switch ( newBehavior )
{
case BEHAVIOR_CALM:
//going from More Agitated to Calm
// Your code goes here.
break;
case BEHAVIOR_ALERT:
//going from More Agitated to Alert
// Your code goes here.
break;
case BEHAVIOR_THREATEN:
//going from More Agitated to Threaten
// Your code goes here.
break;
case BEHAVIOR_FLEE:
//going from More Agitated to Flee
// Your code goes here.
break;
case BEHAVIOR_PANIC:
//going from More Agitated to Panic
// Your code goes here.
break;
case BEHAVIOR_ATTACK:
//Going from More Agitated to Attack
// Your code goes here.
break;
case BEHAVIOR_FRENZY:
//This is impossible.
break;
default :
// This is an error
break;
}
return SCRIPT_CONTINUE;
}
int doAgitatedBehavior( obj_id npc, int newBehavior, int oldBehavior )
{
//You are becoming more Fearful or more Angry
// return SCRIPT_OVERRIDE to stomp on default behaviors:
switch ( newBehavior )
{
case BEHAVIOR_CALM:
//this is impossible
break;
case BEHAVIOR_ALERT:
//going from Calmer to Alert
// Your code goes here.
break;
case BEHAVIOR_THREATEN:
//going from Calmer to Threaten
// Your code goes here.
break;
case BEHAVIOR_FLEE:
//going from Calmer to Flee
// Your code goes here.
break;
case BEHAVIOR_PANIC:
//Going from Calmer to Panic
// Your code goes here.
break;
case BEHAVIOR_ATTACK:
//Going from Calmer to Attack
// Your code goes here.
break;
case BEHAVIOR_FRENZY:
//going from Calmer to Frenzy
break;
default :
// This is an error
break;
}
return SCRIPT_CONTINUE;
}
/* -----------------8/1/2002 9:42PM------------------
* COMBAT:
* --------------------------------------------------*/
trigger OnEnteredCombat()
{
//you probably dont want to do anything here
return SCRIPT_CONTINUE;
}
trigger OnDefenderCombatAction( obj_id attacker, obj_id weapon, int combatResult )
{
//bet you shouldn't do anything here, either.
return SCRIPT_CONTINUE;
}
messageHandler lairThreatened()
{
if ( ai_lib.isAiDead( self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self) )
return SCRIPT_CONTINUE;
if ( !hasObjVar( self, "poi.baseObject" ))
return SCRIPT_CONTINUE;
obj_id myLair = getObjIdObjVar( self, "poi.baseObject" );
obj_id lair = params.getObjId( "lairId" );
if ( lair == null || lair == obj_id.NULL_ID )
return SCRIPT_CONTINUE;
if ( lair == myLair )
{
//your code goes here.
// return SCRIPT_OVERRIDE;
// to stomp default behavior.
}
return SCRIPT_CONTINUE;
}
//--------------- DEATH -----------------------//
trigger OnIncapacitated( obj_id attacker )
{
//you probably don't ever want to use
// return SCRIPT_OVERRIDE here
// if you do, it'll prevent the body from
// decaying (Ever!), etc.
return SCRIPT_CONTINUE;
}
messageHandler corpseCleanup()
{
//want to do something special when the corpse
// is deleted? Better hurry!
// If you
// return SCRIPT_OVERRIDE
// then you'd better
//destroyObject( self );
// or the corpse will never go away.
return SCRIPT_CONTINUE;
}
//---------------DEATH -----------------------//
trigger OnStartNpcConversation (obj_id speaker)
{
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( speaker ) )
return SCRIPT_CONTINUE;
//if you return SCRIPT_OVERRIDE in this trigger,
// then do all this stuff FIRST!
/*
ai_lib.setMood( self, ai_lib.MOOD_CALM );
stop( self );
faceTo( self, speaker );
setObjVar( self, "ai.conversing", false );
messageTo( self, "handleAbortConversation", null, 30, true );
*/
return SCRIPT_CONTINUE;
}
trigger OnNpcConversationResponse(string convo, obj_id player, string_id response)
{
//if you return SCRIPT_OVERRIDE from this trigger, then do
// this stuff FIRST!
/*
if ( hasObjVar( self, "ai.conversing" ) )
setObjVar( self, "ai.conversing", true);
*/
return SCRIPT_CONTINUE;
}
trigger OnEndNpcConversation(obj_id speaker )
{
//if you return SCRIPT_OVERRIDE from this trigger, then do
// this stuff FIRST!
/*
removeObjVar( self, "ai.conversing");
if ( getBehavior(self) == BEHAVIOR_CALM )
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
*/
return SCRIPT_CONTINUE;
}
trigger OnFleeTargetLost(obj_id oldTarget)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//if you don't want the NPC to resume default calm behavior (if calm)
//return SCRIPT_OVERRIDE;
//else:
return SCRIPT_CONTINUE;
}
trigger OnFleePathNotFound(obj_id oldTarget)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//if you don't want the NPC to resume default calm behavior (if calm)
//return SCRIPT_OVERRIDE;
//else:
return SCRIPT_CONTINUE;
}
trigger OnFollowTargetLost(obj_id oldTarget)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//note: if the npc is not in combat, and you fail
// to return SCRIPT_CONTINUE -and- you don't call
// ai_lib.stopFollowing(), then this NPC will
// think he's following someone, but won't be moving!
// That's BAD.
return SCRIPT_CONTINUE;
}
trigger OnFollowPathNotFound(obj_id target)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//note: if the npc is not in combat, and you fail
// to return SCRIPT_CONTINUE -and- you don't call
// ai_lib.stopFollowing(), then this NPC will
// think he's following someone, but won't be moving!
// That's BAD.
return SCRIPT_CONTINUE;
}