343 lines
10 KiB
Plaintext
343 lines
10 KiB
Plaintext
|
#include common_scripts\utility;
|
||
|
#include maps\_utility;
|
||
|
#include maps\_anim;
|
||
|
#include maps\_stealth_utility;
|
||
|
#include maps\_stealth_shared_utilities;
|
||
|
|
||
|
stealth_smartstance_friendly_main()
|
||
|
{
|
||
|
self friendly_init();
|
||
|
|
||
|
self thread friendly_stance_handler();
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************/
|
||
|
/* FRIENDLY LOGIC */
|
||
|
/************************************************************************************************************/
|
||
|
friendly_stance_handler()
|
||
|
{
|
||
|
self endon( "death" );
|
||
|
self endon( "pain_death" );
|
||
|
|
||
|
self.old_fixednode = self.fixednode;
|
||
|
self.old_fixednodesaferadius = self.fixednodesaferadius;
|
||
|
|
||
|
while ( 1 )
|
||
|
{
|
||
|
self ent_flag_wait( "_stealth_stance_handler" );
|
||
|
flag_waitopen( "_stealth_spotted" );
|
||
|
|
||
|
self.fixednode = 1;
|
||
|
self.fixednodesaferadius = 10;
|
||
|
|
||
|
while ( self ent_flag( "_stealth_stance_handler" ) && !flag( "_stealth_spotted" ) )
|
||
|
{
|
||
|
self friendly_stance_handler_set_stance_up();
|
||
|
stances = [];
|
||
|
stances = friendly_stance_handler_check_mightbeseen( stances );
|
||
|
|
||
|
// this means we're currently visible we need to drop a stance or stay still
|
||
|
if ( stances[ self._stealth.logic.stance ] )
|
||
|
self thread friendly_stance_handler_change_stance_down();
|
||
|
// ok coast is clear - we can go again if we were staying still
|
||
|
else if ( self ent_flag( "_stealth_stay_still" ) )
|
||
|
self thread friendly_stance_handler_resume_path();
|
||
|
// this means we can actually go one stance up
|
||
|
else if ( ! stances[ self._stealth.behavior.stance_up ] && self._stealth.behavior.stance_up != self._stealth.logic.stance )
|
||
|
self thread friendly_stance_handler_change_stance_up();
|
||
|
// so - we're not stancing up, we're not stancing down, or staying still...lets notify
|
||
|
// ourselves that we should stay in the same stance( just in case we're about to stance up )
|
||
|
else if ( self ent_flag( "_stealth_stance_change" ) )
|
||
|
self notify( "_stealth_stance_dont_change" );
|
||
|
|
||
|
wait .05;
|
||
|
}
|
||
|
|
||
|
self.fixednode = self.old_fixednode;
|
||
|
self.fixednodesaferadius = self.old_fixednodesaferadius;
|
||
|
|
||
|
self.moveplaybackrate = 1;
|
||
|
self allowedstances( "stand", "crouch", "prone" );
|
||
|
|
||
|
if ( self ent_flag( "_stealth_stay_still" ) )
|
||
|
self thread friendly_stance_handler_resume_path( 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_set_stance_up()
|
||
|
{
|
||
|
// figure out what the next stance up is
|
||
|
switch( self._stealth.logic.stance )
|
||
|
{
|
||
|
case "prone":
|
||
|
self._stealth.behavior.stance_up = "crouch";
|
||
|
break;
|
||
|
case "crouch":
|
||
|
self._stealth.behavior.stance_up = "stand";
|
||
|
break;
|
||
|
case "stand":
|
||
|
self._stealth.behavior.stance_up = "stand";// can't leave it as undefined
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_check_mightbeseen( stances )
|
||
|
{
|
||
|
// not using species because we dont care about dogs...
|
||
|
// when they're awake - we're already not in stealth mode anymore
|
||
|
ai = getaispeciesarray( "bad_guys", "all" );
|
||
|
|
||
|
stances[ self._stealth.logic.stance ] = 0;
|
||
|
stances[ self._stealth.behavior.stance_up ] = 0;
|
||
|
|
||
|
foreach ( key, actor in ai )
|
||
|
{
|
||
|
//can the ai even see us?
|
||
|
// if( !( actor cansee( self ) ) )
|
||
|
// continue;
|
||
|
|
||
|
// this is how much to add based on a fast sight trace
|
||
|
dist_add_curr = self friendly_stance_handler_return_ai_sight( actor, self._stealth.logic.stance );
|
||
|
dist_add_up = self friendly_stance_handler_return_ai_sight( actor, self._stealth.behavior.stance_up );
|
||
|
|
||
|
// this is the score for both the current stance and the next one up
|
||
|
score_current = ( self maps\_stealth_visibility_friendly::friendly_compute_score() ) + dist_add_curr;
|
||
|
score_up = ( self maps\_stealth_visibility_friendly::friendly_compute_score( self._stealth.behavior.stance_up ) ) + dist_add_up;
|
||
|
|
||
|
dist = distance( actor.origin, self.origin );
|
||
|
|
||
|
if ( dist < score_current )
|
||
|
{
|
||
|
stances[ self._stealth.logic.stance ] = score_current;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( dist < score_up )
|
||
|
stances[ self._stealth.behavior.stance_up ] = score_up;
|
||
|
}
|
||
|
|
||
|
// if( ai.size > 0 )
|
||
|
// {
|
||
|
// println("score_current " + stances[ self._stealth.logic.stance ] );
|
||
|
// println("score_up " + stances[ self._stealth.behavior.stance_up ] );
|
||
|
// guy = getclosest( self.origin, ai );
|
||
|
// println("dist " + distance( guy.origin, self.origin ) );
|
||
|
// }
|
||
|
|
||
|
return stances;
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_return_ai_sight( ai, stance )
|
||
|
{
|
||
|
// check to see where the ai is facing
|
||
|
vec1 = anglestoforward( ai.angles );// this is the direction the ai is facing
|
||
|
vec2 = vectornormalize( self.origin - ai.origin );// this is the direction from him to us
|
||
|
|
||
|
// comparing the dotproduct of the 2 will tell us if he's facing us and how much so..
|
||
|
// 0 will mean his direction is exactly perpendicular to us,
|
||
|
// 1 will mean he's facing directly at us
|
||
|
// - 1 will mean he's facing directly away from us
|
||
|
vecdot = vectordot( vec1, vec2 );
|
||
|
|
||
|
// is the ai facing us?
|
||
|
if ( vecdot > .3 )
|
||
|
return self._stealth.behavior.stance_handler[ "looking_towards" ][ stance ];
|
||
|
// is the ai facing away from us
|
||
|
else if ( vecdot < - .7 )
|
||
|
return self._stealth.behavior.stance_handler[ "looking_away" ][ stance ];
|
||
|
// the ai is kinda not facing us or away
|
||
|
else
|
||
|
return self._stealth.behavior.stance_handler[ "neutral" ][ stance ];
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_change_stance_down()
|
||
|
{
|
||
|
self.moveplaybackrate = 1;
|
||
|
|
||
|
self notify( "_stealth_stance_down" );
|
||
|
|
||
|
switch( self._stealth.logic.stance )
|
||
|
{
|
||
|
case "stand":
|
||
|
self.moveplaybackrate = .7;
|
||
|
self allowedstances( "crouch" );
|
||
|
break;
|
||
|
case "crouch":
|
||
|
if( self._stealth.behavior.no_prone )
|
||
|
friendly_stance_handler_stay_still();
|
||
|
else
|
||
|
self allowedstances( "prone" );
|
||
|
break;
|
||
|
case "prone":
|
||
|
friendly_stance_handler_stay_still();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_change_stance_up()
|
||
|
{
|
||
|
self endon( "_stealth_stance_down" );
|
||
|
self endon( "_stealth_stance_dont_change" );
|
||
|
self endon( "_stealth_stance_handler" );
|
||
|
|
||
|
if ( self ent_flag( "_stealth_stance_change" ) )
|
||
|
return;
|
||
|
|
||
|
time = 4;
|
||
|
|
||
|
// we wait a sec before deciding to actually stand up - just like a real player
|
||
|
self ent_flag_set( "_stealth_stance_change" );
|
||
|
self add_wait( ::_wait, time );
|
||
|
self add_wait( ::waittill_msg, "_stealth_stance_down" );
|
||
|
self add_wait( ::waittill_msg, "_stealth_stance_dont_change" );
|
||
|
self add_wait( ::waittill_msg, "_stealth_stance_handler" );
|
||
|
self add_func( ::ent_flag_clear, "_stealth_stance_change" );
|
||
|
thread do_wait_any();
|
||
|
|
||
|
wait time;
|
||
|
|
||
|
self.moveplaybackrate = 1;
|
||
|
|
||
|
switch( self._stealth.logic.stance )
|
||
|
{
|
||
|
case "prone":
|
||
|
self allowedstances( "crouch" );
|
||
|
break;
|
||
|
case "crouch":
|
||
|
self allowedstances( "stand" );
|
||
|
break;
|
||
|
case "stand":
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_stay_still()
|
||
|
{
|
||
|
self notify( "friendly_stance_handler_stay_still" );
|
||
|
|
||
|
if ( self ent_flag( "_stealth_stay_still" ) )
|
||
|
return;
|
||
|
self ent_flag_set( "_stealth_stay_still" );
|
||
|
|
||
|
badplace_cylinder( "_stealth_" + self.unique_id + "_prone", 0, self.origin, 30, 90, "bad_guys" );
|
||
|
|
||
|
//we're going to use fixed node to make him stay still
|
||
|
self.fixednodesaferadius = 5000; //arbitrarily large number - maybe in the future we should actually set this to be a little larger than his current smart stance safe distance
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_resume_path( time )
|
||
|
{
|
||
|
self endon( "friendly_stance_handler_stay_still" );
|
||
|
|
||
|
if( !isdefined( time ) )
|
||
|
time = self._stealth.behavior.wait_resume_path;
|
||
|
|
||
|
wait( time );
|
||
|
|
||
|
if( !self ent_flag( "_stealth_stay_still" ) )
|
||
|
return;
|
||
|
self ent_flag_clear( "_stealth_stay_still" );
|
||
|
|
||
|
badplace_delete( "_stealth_" + self.unique_id + "_prone" );
|
||
|
|
||
|
self.fixednodesaferadius = 10;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
friendly_stance_handler_stay_still()
|
||
|
{
|
||
|
//need this in here because we could start resuming the path before we actually hit the line
|
||
|
//near the bottom to loop the prone anim...when that happens - the system thinks we're not
|
||
|
//staying still even though we're playing a looping animation
|
||
|
self endon( "friendly_stance_handler_resume_path" );
|
||
|
|
||
|
if ( self ent_flag( "_stealth_stay_still" ) )
|
||
|
return;
|
||
|
self ent_flag_set( "_stealth_stay_still" );
|
||
|
|
||
|
badplace_cylinder( "_stealth_" + self.unique_id + "_prone", 0, self.origin, 30, 90, "bad_guys" );
|
||
|
|
||
|
//MIGHT NEED THIS IN THE FUTURE
|
||
|
//self ent_flag_set( "_stealth_custom_anim" ); --> this is for dynamic run speed
|
||
|
|
||
|
self notify( "stop_loop" );
|
||
|
self anim_generic_custom_animmode( self, "gravity", "_stealth_prone_stop" );
|
||
|
self thread anim_generic_custom_animmode_loop( self, "gravity", "_stealth_prone_idle" );
|
||
|
}
|
||
|
|
||
|
friendly_stance_handler_resume_path()
|
||
|
{
|
||
|
self notify( "friendly_stance_handler_resume_path" );
|
||
|
|
||
|
self ent_flag_clear( "_stealth_stay_still" );
|
||
|
|
||
|
badplace_delete( "_stealth_" + self.unique_id + "_prone" );
|
||
|
|
||
|
self notify( "stop_loop" );
|
||
|
self anim_generic_custom_animmode( self, "gravity", "_stealth_prone_start" );
|
||
|
//MIGHT NEED THIS IN THE FUTURE
|
||
|
//self ent_flag_clear( "_stealth_custom_anim" ); --> this is for dynamic run speed
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
/************************************************************************************************************/
|
||
|
/* SETUP */
|
||
|
/************************************************************************************************************/
|
||
|
friendly_init()
|
||
|
{
|
||
|
self ent_flag_init( "_stealth_stance_handler" );
|
||
|
self ent_flag_init( "_stealth_stay_still" );
|
||
|
self ent_flag_init( "_stealth_stance_change" );
|
||
|
|
||
|
self._stealth.behavior.stance_up = undefined;
|
||
|
self._stealth.behavior.stance_handler = [];
|
||
|
self friendly_default_stance_handler_distances();
|
||
|
|
||
|
self._stealth.behavior.no_prone = false;
|
||
|
self._stealth.behavior.wait_resume_path = 2;
|
||
|
|
||
|
self._stealth.plugins.smartstance = true;
|
||
|
}
|
||
|
|
||
|
friendly_default_stance_handler_distances()
|
||
|
{
|
||
|
// i do this because the player doesn't look as bad sneaking up on the enemies
|
||
|
// friendlies however don't look as good getting so close
|
||
|
looking_away = [];
|
||
|
looking_away[ "stand" ] = 500;
|
||
|
looking_away[ "crouch" ] = -400;
|
||
|
looking_away[ "prone" ] = 0;
|
||
|
|
||
|
neutral = [];
|
||
|
neutral[ "stand" ] = 500;
|
||
|
neutral[ "crouch" ] = 200;
|
||
|
neutral[ "prone" ] = 50;
|
||
|
|
||
|
looking_towards = [];
|
||
|
looking_towards[ "stand" ] = 800;
|
||
|
looking_towards[ "crouch" ] = 400;
|
||
|
looking_towards[ "prone" ] = 100;
|
||
|
|
||
|
friendly_set_stance_handler_distances( looking_away, neutral, looking_towards );
|
||
|
}
|
||
|
|
||
|
friendly_set_stance_handler_distances( looking_away, neutral, looking_towards )
|
||
|
{
|
||
|
if ( isdefined( looking_away ) )
|
||
|
{
|
||
|
foreach ( key, value in looking_away )
|
||
|
self._stealth.behavior.stance_handler[ "looking_away" ][ key ] = value;
|
||
|
}
|
||
|
|
||
|
if ( isdefined( neutral ) )
|
||
|
{
|
||
|
foreach ( key, value in neutral )
|
||
|
self._stealth.behavior.stance_handler[ "neutral" ][ key ] = value;
|
||
|
}
|
||
|
|
||
|
if ( isdefined( looking_towards ) )
|
||
|
{
|
||
|
foreach ( key, value in looking_towards )
|
||
|
self._stealth.behavior.stance_handler[ "looking_towards" ][ key ] = value;
|
||
|
}
|
||
|
}
|