mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-31 00:15:54 -04:00
389 lines
9.8 KiB
Plaintext
389 lines
9.8 KiB
Plaintext
include library.ai_lib;
|
|
include ai.ai_combat;
|
|
include library.factions;
|
|
include library.chat;
|
|
include library.attrib;
|
|
include library.utils;
|
|
|
|
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
|
|
|
|
const string SOCIAL_VOLUME = "npc_socialization";
|
|
const float SOCIAL_RANGE = 15f;
|
|
|
|
const string ACTION_ALERT = "alert";
|
|
const string ACTION_THREATEN = "threaten";
|
|
|
|
const int CONVO_LENGTH = 300;
|
|
|
|
const string CREATURE_TABLE = "datatables/mob/creatures.iff";
|
|
|
|
trigger OnAttach()
|
|
{
|
|
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
|
|
createTriggerVolume( SOCIAL_VOLUME, SOCIAL_RANGE, false );
|
|
|
|
//set diction:
|
|
string diction = "townperson";
|
|
switch ( rand( 1, 3 ))
|
|
{
|
|
case 1 :
|
|
diction = "townperson_fancy";
|
|
break;
|
|
case 2 :
|
|
diction = "townperson_slang";
|
|
break;
|
|
case 3 :
|
|
diction = "townperson";
|
|
break;
|
|
}
|
|
setObjVar( self, "ai.diction", diction );
|
|
|
|
//set faction:
|
|
factions.setFaction( self, "townperson" );
|
|
switch ( rand( 1,5) )
|
|
{
|
|
case 1 :
|
|
factions.setFaction( self, "ImperialCitizen" );
|
|
break;
|
|
case 2 :
|
|
factions.setFaction( self, "RebelCitizen" );
|
|
break;
|
|
}
|
|
|
|
attachScript( self, "theme_park.tatooine.city_convo" );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnAddedToWorld()
|
|
{
|
|
utils.removeScriptVar( self, "ai.speaking" );
|
|
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
|
|
createTriggerVolume( SOCIAL_VOLUME, SOCIAL_RANGE, false );
|
|
|
|
setAttributeAttained(self, attrib.TOWNSPERSON );
|
|
setAttributeInterested(self, attrib.TOWNSPERSON );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
|
|
{
|
|
if ( hasObjVar( breacher, "gm") )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//debugSpeakMsg( self, volumeName + " breached by " + breacher );
|
|
if ( breacher == self )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
if ( isIncapacitated(self) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//debugSpeakMsg( self, volumeName + " breached by " + breacher );
|
|
if ( volumeName == ALERT_VOLUME_NAME )
|
|
{
|
|
if ( hasScript( breacher, "ai.townperson") )
|
|
{
|
|
//debugSpeakMsg( self, "adding " + breacher + " to " + SOCIAL_VOLUME );
|
|
addTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
if ( volumeName == SOCIAL_VOLUME )
|
|
{
|
|
if ( !isPlayer( breacher) )
|
|
initiateDialog( self, breacher );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
|
|
{
|
|
//debugSpeakMsg( self, volumeName + " breached by " + breacher );
|
|
if ( volumeName == ALERT_VOLUME_NAME )
|
|
{
|
|
if ( hasScript( breacher, "ai.townperson") )
|
|
{
|
|
//debugSpeakMsg( self, "removing " + breacher + " from " + SOCIAL_VOLUME );
|
|
removeTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler cancelFacing()
|
|
{
|
|
utils.removeScriptVar( self, "ai.speaking" );
|
|
if ( getBehavior( self ) == BEHAVIOR_CALM )
|
|
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void initiateDialog( obj_id talker, obj_id listener )
|
|
{
|
|
if ( ai_lib.isInCombat( talker ) || ai_lib.isInCombat( listener ) )
|
|
return;
|
|
|
|
if ( ai_lib.isFollowing(talker) || ai_lib.isFollowing(listener) )
|
|
return;
|
|
|
|
aiUnEquipWeapons(talker);
|
|
aiUnEquipWeapons(listener);
|
|
|
|
if ( utils.hasScriptVar( talker, "ai.speaking") || utils.hasScriptVar( listener, "ai.speaking" ))
|
|
return;
|
|
|
|
if ( getBehavior( talker ) >= BEHAVIOR_THREATEN || getBehavior( listener ) >= BEHAVIOR_THREATEN )
|
|
return;
|
|
|
|
if ( getIntObjVar( listener, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL ||
|
|
getIntObjVar( talker, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL )
|
|
return;
|
|
|
|
utils.setScriptVar( talker, "ai.speaking", listener );
|
|
utils.setScriptVar( listener, "ai.speaking", talker );
|
|
stop( talker );
|
|
stop( listener );
|
|
faceTo( listener, talker );
|
|
utils.setScriptVar( talker, "ai.pathingToSocialize", listener );
|
|
utils.setScriptVar( listener, "ai.pathingToSocialize", talker );
|
|
location pathToLoc = new location( getLocation( listener ) );
|
|
location myLoc = getLocation( talker );
|
|
if ( pathToLoc.x < myLoc.x )
|
|
pathToLoc.x += 1.5f;
|
|
else
|
|
pathToLoc.x -= 1.5f;
|
|
|
|
if ( pathToLoc.z < myLoc.z )
|
|
pathToLoc.z += 1.5f;
|
|
else
|
|
pathToLoc.z -= 1.5f;
|
|
pathTo( talker, pathToLoc );
|
|
}
|
|
|
|
trigger OnMovePathComplete()
|
|
{
|
|
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
|
|
if ( exists(listener) )
|
|
{
|
|
faceTo( self, listener);
|
|
faceTo( listener, self );
|
|
|
|
ai_lib.greet( self, listener);
|
|
|
|
ai_lib.doAction( self, "conversation_"+getGender(self) );
|
|
ai_lib.doAction( listener, "conversation_"+getGender(listener) );
|
|
}
|
|
messageTo( self, "handleEndSocializing", null, CONVO_LENGTH, isObjectPersisted( self ) );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler handleEndSocializing()
|
|
{
|
|
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
|
|
endSocializing( self, listener );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnMovePathNotFound()
|
|
{
|
|
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
|
|
endSocializing( self, listener );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void endSocializing( obj_id talker, obj_id listener )
|
|
{
|
|
if ( getBehavior( talker ) == BEHAVIOR_CALM )
|
|
{
|
|
ai_lib.setMood( talker, ai_lib.MOOD_CALM );
|
|
ai_lib.dismiss( talker, listener );
|
|
messageTo( talker, "resumeDefaultCalmBehavior", null, 5, false );
|
|
}
|
|
|
|
if ( getBehavior( listener ) == BEHAVIOR_CALM )
|
|
{
|
|
ai_lib.setMood( listener, ai_lib.MOOD_CALM );
|
|
ai_lib.doAction( listener, "wave"+rand(1,2) );
|
|
messageTo( listener, "resumeDefaultCalmBehavior", null, 8, false );
|
|
}
|
|
|
|
utils.removeScriptVar( talker, "ai.pathingToSocialize" );
|
|
utils.removeScriptVar( listener, "ai.pathingToSocialize" );
|
|
utils.removeScriptVar( talker, "ai.speaking" );
|
|
utils.removeScriptVar( listener, "ai.speaking");
|
|
}
|
|
|
|
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
|
|
{
|
|
if ( isIncapacitated(self) )
|
|
return SCRIPT_CONTINUE;
|
|
|
|
//debugSpeakMsg( self, "newbehavior: " + newBehavior );
|
|
|
|
if ( newBehavior > oldBehavior )
|
|
{
|
|
if ( utils.hasScriptVar( self, "ai.pathingToSocialize") )
|
|
{
|
|
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
|
|
endSocializing( self, listener );
|
|
}
|
|
if ( newBehavior >= BEHAVIOR_ALERT && newBehavior < BEHAVIOR_ATTACK )
|
|
{
|
|
doAgitateBehavior( self, newBehavior );
|
|
return SCRIPT_OVERRIDE;//don't do the default AI thing
|
|
}
|
|
else
|
|
{
|
|
//debugSpeakMsg( self, newBehavior + " is not between " + BEHAVIOR_ALERT + " and " + BEHAVIOR_ATTACK );
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
else if ( newBehavior == BEHAVIOR_CALM )
|
|
{
|
|
//debugSpeakMsg( self, "now I am calm again" );
|
|
if ( utils.hasScriptVar( self, "ai.speaking"))
|
|
{
|
|
ai_lib.setMood( self, ai_lib.MOOD_CALM );
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
if ( oldBehavior != BEHAVIOR_CALM )
|
|
{
|
|
chat.setNeutralMood( self );
|
|
ai_lib.barkString( self, "calm" );//newly calm and not conversing
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void doAgitateBehavior( obj_id npc, int behavior )
|
|
{
|
|
if ( isInvulnerable( npc ) )
|
|
return;
|
|
|
|
//debugSpeakMsg( npc, "doing custom thing" );
|
|
//obj_id threat = ai_lib.getBehaviorTarget( npc, behavior );
|
|
//if ( threat == null )
|
|
return;
|
|
//else
|
|
// setObjVar( npc, "ai.threat", threat );
|
|
//
|
|
//switch ( behavior )
|
|
//{
|
|
// case BEHAVIOR_ALERT:
|
|
// if (!hasObjVar(npc, "ai.pathingAwayFrom" ))
|
|
// stop( npc );
|
|
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
|
|
// break;
|
|
// case BEHAVIOR_THREATEN:
|
|
// faceTo( npc, threat );
|
|
// ai_lib.doAction( npc, ACTION_THREATEN );
|
|
// ai_lib.setMood( npc, ai_lib.MOOD_THREATEN );
|
|
// break;
|
|
// case BEHAVIOR_FLEE:
|
|
// chat.setBadMood( npc );
|
|
// ai_lib.barkString( npc, "flee" );
|
|
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
|
|
// setMovementRun( npc );
|
|
// flee( npc, threat, 5f, 10f );
|
|
// break;
|
|
// case BEHAVIOR_PANIC:
|
|
// chat.setAngryMood( npc );
|
|
// ai_lib.barkString( npc, "flee" );
|
|
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
|
|
// setMovementRun( npc );
|
|
// flee( npc, threat, 5f, 10f );
|
|
// break;
|
|
// default :
|
|
// //debugSpeakMsg( npc, "default: " + behavior );
|
|
// break;
|
|
//}
|
|
}
|
|
|
|
trigger OnTargeted(obj_id attacker )
|
|
{
|
|
if ( isInvulnerable( self ) )
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
addToMentalStateToward(self, attacker, FEAR, 100f );
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
trigger OnEnteredCombat()
|
|
{
|
|
if ( isInvulnerable( self ) )
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
trigger OnStartNpcConversation (obj_id speaker)
|
|
{
|
|
if ( utils.hasScriptVar( self, "ai.speaking") )
|
|
{
|
|
obj_id listener = utils.getObjIdScriptVar( self, "ai.speaking" );
|
|
if ( listener != speaker )
|
|
endSocializing( self, listener );
|
|
}
|
|
utils.setScriptVar( self, "ai.speaking", speaker );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnEndNpcConversation(obj_id speaker )
|
|
{
|
|
utils.removeScriptVar( self, "ai.speaking" );
|
|
if ( getBehavior(self) == BEHAVIOR_CALM )
|
|
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler resumeDefaultCalmBehavior()
|
|
{
|
|
if ( utils.hasScriptVar( self, "ai.speaking" ))
|
|
return SCRIPT_OVERRIDE;
|
|
|
|
if ( getBehavior(self) == BEHAVIOR_CALM )
|
|
{
|
|
aiUnEquipWeapons(self);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
trigger OnSawAttack(obj_id defender, obj_id[] attackers)
|
|
{
|
|
if ( getConfigSetting("GameServer", "disableAICombat")!=null )
|
|
{
|
|
setWantSawAttackTriggers(self, false);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
if ( ai_lib.isAiDead( self ) || isInvulnerable( self ) )
|
|
{
|
|
setWantSawAttackTriggers(self, false);
|
|
return SCRIPT_OVERRIDE;
|
|
}
|
|
|
|
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
|
|
return SCRIPT_CONTINUE;
|
|
|
|
setAnimationMood( self, "nervous" );
|
|
|
|
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
|
|
endSocializing( self, listener );
|
|
return SCRIPT_CONTINUE;
|
|
}
|