mirror of
https://github.com/JezuzLizard/t4sp_bot_warfare.git
synced 2025-04-22 22:45:43 +00:00
new objective system
This commit is contained in:
parent
2f5a21fd8c
commit
7c9f6fca11
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
bot_script_init()
|
bot_script_init()
|
||||||
{
|
{
|
||||||
level thread maps\bots\script_objectives\_obj_init::init();
|
level thread maps\bots\objectives\_manager::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,7 +31,7 @@ connected()
|
|||||||
self thread onBotSpawned();
|
self thread onBotSpawned();
|
||||||
self thread onSpawned();
|
self thread onSpawned();
|
||||||
|
|
||||||
self thread maps\bots\script_objectives\_obj_init::connected();
|
self thread maps\bots\objectives\_manager::connected();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -389,10 +389,7 @@ onSpawned()
|
|||||||
{
|
{
|
||||||
self waittill( "spawned_player" );
|
self waittill( "spawned_player" );
|
||||||
|
|
||||||
self.bot_lock_goal = false;
|
self thread maps\bots\objectives\_manager::spawned();
|
||||||
self.bot_was_follow_script_update = undefined;
|
|
||||||
|
|
||||||
self thread maps\bots\script_objectives\_obj_init::spawned();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +404,7 @@ start_bot_threads()
|
|||||||
|
|
||||||
self thread doReloadCancel();
|
self thread doReloadCancel();
|
||||||
|
|
||||||
self thread maps\bots\script_objectives\_obj_init::start_bot_threads();
|
self thread maps\bots\objectives\_manager::start_bot_threads();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -822,7 +822,7 @@ ReverseHeap( item, item2 )
|
|||||||
|
|
||||||
HeapPriority( item, item2 )
|
HeapPriority( item, item2 )
|
||||||
{
|
{
|
||||||
return item.priority > item2.priority;
|
return item.fPriority > item2.fPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
146
maps/bots/objectives/_manager.gsc
Normal file
146
maps/bots/objectives/_manager.gsc
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include common_scripts\utility;
|
||||||
|
#include maps\_utility;
|
||||||
|
#include maps\bots\_bot_utility;
|
||||||
|
#include maps\bots\objectives\_utility;
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
level.bot_objectives = [];
|
||||||
|
level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "revive", maps\bots\objectives\_revive::Finder, maps\bots\objectives\_revive::Executer, maps\bots\objectives\_revive::Priority );
|
||||||
|
level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "powerup", maps\bots\objectives\_powerup::Finder, maps\bots\objectives\_powerup::Executer, maps\bots\objectives\_powerup::Priority );
|
||||||
|
}
|
||||||
|
|
||||||
|
connected()
|
||||||
|
{
|
||||||
|
self.bot_current_objective = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
spawned()
|
||||||
|
{
|
||||||
|
self.bot_current_objective = undefined;
|
||||||
|
|
||||||
|
self thread clean_objective_on_completion();
|
||||||
|
self thread watch_for_objective_canceled();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_for_objective_canceled()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
level endon( "intermission" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
self waittill( "cancel_bot_objective", reason );
|
||||||
|
|
||||||
|
obj_name = "undefined";
|
||||||
|
|
||||||
|
if ( isDefined( self.bot_current_objective ) )
|
||||||
|
{
|
||||||
|
obj_name = self.bot_current_objective.sName;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintConsole( "watch_for_objective_canceled: " + self.playername + ": " + obj_name + ": " + reason );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_objective_on_completion()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
level endon( "intermission" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
self waittill( "completed_bot_objective", successful, reason );
|
||||||
|
|
||||||
|
obj_name = "undefined";
|
||||||
|
|
||||||
|
if ( isDefined( self.bot_current_objective ) )
|
||||||
|
{
|
||||||
|
obj_name = self.bot_current_objective.sName;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintConsole( "clean_objective_on_completion: " + self.playername + ": " + obj_name + ": " + successful + ": " + reason );
|
||||||
|
|
||||||
|
waittillframeend;
|
||||||
|
self.bot_current_objective = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start_bot_threads()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
level endon( "intermission" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
self thread bot_objective_think();
|
||||||
|
}
|
||||||
|
|
||||||
|
bot_objective_think()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
level endon( "intermission" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
wait 1;
|
||||||
|
|
||||||
|
// find all avail objectives
|
||||||
|
objectives = [];
|
||||||
|
|
||||||
|
for ( i = 0; i < level.bot_objectives.size; i++ )
|
||||||
|
{
|
||||||
|
objective = level.bot_objectives[i];
|
||||||
|
|
||||||
|
objectives = array_merge( objectives, self [[objective.fpFinder]]( objective ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( objectives.size <= 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort according to priority
|
||||||
|
heap = NewHeap( ::HeapPriority );
|
||||||
|
|
||||||
|
for ( i = 0; i < objectives.size; i++ )
|
||||||
|
{
|
||||||
|
heap HeapInsert( objectives[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pop the top!
|
||||||
|
best_prio = heap.data[0];
|
||||||
|
|
||||||
|
if ( !isDefined( best_prio ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// already on a better obj
|
||||||
|
if ( self HasBotObjective() && ( best_prio.GUID == self.bot_current_objective.GUID || best_prio.fPriority < self.bot_current_objective.fPriority ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DO THE OBJ
|
||||||
|
// cancel the old obj
|
||||||
|
if ( self HasBotObjective() )
|
||||||
|
{
|
||||||
|
// cancel it
|
||||||
|
self CancelObjective( "new obj: " + best_prio.sName );
|
||||||
|
|
||||||
|
// wait for it to clean up
|
||||||
|
self waittill( "completed_bot_objective" );
|
||||||
|
|
||||||
|
// redo the loop, should do the obj next iteration
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready to execute
|
||||||
|
PrintConsole( "bot_objective_think: " + self.playername + ": " + best_prio.sName );
|
||||||
|
self.bot_current_objective = best_prio;
|
||||||
|
self thread [[best_prio.eParentObj.fpExecuter]]( best_prio );
|
||||||
|
}
|
||||||
|
}
|
126
maps/bots/objectives/_powerup.gsc
Normal file
126
maps/bots/objectives/_powerup.gsc
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include common_scripts\utility;
|
||||||
|
#include maps\_utility;
|
||||||
|
#include maps\bots\_bot_utility;
|
||||||
|
#include maps\bots\objectives\_utility;
|
||||||
|
|
||||||
|
Finder( eObj )
|
||||||
|
{
|
||||||
|
answer = [];
|
||||||
|
ents = getentarray( "script_model", "classname" );
|
||||||
|
|
||||||
|
if ( self inLastStand() )
|
||||||
|
{
|
||||||
|
return Answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < ents.size; i++ )
|
||||||
|
{
|
||||||
|
if ( !isDefined( ents[i].powerup_name ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( GetPathIsInaccessible( self.origin, ents[i].origin ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( self GetBotsAmountForEntity( ents[i] ) >= 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
answer[answer.size] = self CreateFinderObjective( eObj, eObj.sName + "_" + ents[i] GetEntityNumber(), ents[i], self [[eObj.fpPriority]]( eObj, ents[i] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Priority( eObj, eEnt )
|
||||||
|
{
|
||||||
|
// TODO: check powerup type
|
||||||
|
base_priority = 0;
|
||||||
|
base_priority += ClampLerp( Distance( self.origin, eEnt.origin ), 300, 700, 2, -2 );
|
||||||
|
|
||||||
|
if ( self HasBotObjective() )
|
||||||
|
{
|
||||||
|
base_priority -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
Executer( eObj )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
powerup = eObj.eEnt;
|
||||||
|
|
||||||
|
self thread IncrementBotsForEntity( powerup );
|
||||||
|
self thread WatchForCancel( powerup );
|
||||||
|
|
||||||
|
self GoDoPowerup( eObj );
|
||||||
|
|
||||||
|
self WatchForCancelCleanup();
|
||||||
|
self DecrementBotsForEntity( powerup );
|
||||||
|
self ClearScriptGoal();
|
||||||
|
|
||||||
|
self CompletedObjective( eObj.bWasSuccessful, eObj.sReason );
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchForCancelCleanup()
|
||||||
|
{
|
||||||
|
self notify( "WatchForCancelPowerup" );
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchForCancel( powerup )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
self endon( "WatchForCancelPowerup" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
|
||||||
|
if ( self inLastStand() )
|
||||||
|
{
|
||||||
|
self CancelObjective( "self inLastStand()" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isdefined( powerup ) )
|
||||||
|
{
|
||||||
|
self CancelObjective( "!isdefined( powerup )" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GoDoPowerup( eObj )
|
||||||
|
{
|
||||||
|
self endon( "cancel_bot_objective" );
|
||||||
|
|
||||||
|
powerup = eObj.eEnt;
|
||||||
|
|
||||||
|
// go to it
|
||||||
|
self SetScriptGoal( powerup.origin, 32 );
|
||||||
|
|
||||||
|
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||||
|
|
||||||
|
if ( result != "goal" )
|
||||||
|
{
|
||||||
|
eObj.sReason = "didn't go to powerup";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( distance( powerup.origin, self.origin ) > 64 )
|
||||||
|
{
|
||||||
|
eObj.sReason = "not touching it";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eObj.sReason = "completed";
|
||||||
|
eObj.bWasSuccessful = true;
|
||||||
|
}
|
201
maps/bots/objectives/_revive.gsc
Normal file
201
maps/bots/objectives/_revive.gsc
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
#include common_scripts\utility;
|
||||||
|
#include maps\_utility;
|
||||||
|
#include maps\bots\_bot_utility;
|
||||||
|
#include maps\bots\objectives\_utility;
|
||||||
|
|
||||||
|
Finder( eObj )
|
||||||
|
{
|
||||||
|
Players = get_players();
|
||||||
|
Answer = [];
|
||||||
|
|
||||||
|
if ( self inLastStand() )
|
||||||
|
{
|
||||||
|
return Answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < Players.size; i++ )
|
||||||
|
{
|
||||||
|
Player = Players[i];
|
||||||
|
|
||||||
|
if ( !IsDefined( Player ) || !IsDefined( Player.team ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Player == self )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Player.sessionstate != "playing" )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !Player inLastStand() || Player.revivetrigger.beingrevived )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( GetPathIsInaccessible( self.origin, Player.origin ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( self GetBotsAmountForEntity( Player ) >= 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Answer[Answer.size] = self CreateFinderObjective( eObj, eObj.sName + "_" + Player GetEntityNumber(), Player, self [[eObj.fpPriority]]( eObj, Player ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return Answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Priority( eObj, eEnt )
|
||||||
|
{
|
||||||
|
base_priority = 3;
|
||||||
|
base_priority += ClampLerp( Distance( self.origin, eEnt.origin ), 500, 1200, 2, -2 );
|
||||||
|
|
||||||
|
if ( self HasBotObjective() )
|
||||||
|
{
|
||||||
|
base_priority -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
Executer( eObj )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
revivee = eObj.eEnt;
|
||||||
|
|
||||||
|
self thread IncrementBotsForEntity( revivee );
|
||||||
|
self thread WatchForCancelRevive( revivee );
|
||||||
|
|
||||||
|
self GoDoRevive( eObj );
|
||||||
|
|
||||||
|
self WatchForCancelReviveCleanup();
|
||||||
|
self DecrementBotsForEntity( revivee );
|
||||||
|
self ClearScriptAimPos();
|
||||||
|
self ClearScriptGoal();
|
||||||
|
self ClearPriorityObjective();
|
||||||
|
|
||||||
|
self CompletedObjective( eObj.bWasSuccessful, eObj.sReason );
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchForCancelReviveCleanup()
|
||||||
|
{
|
||||||
|
self notify( "WatchForCancelRevive" );
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchForCancelRevive( revivee )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
self endon( "WatchForCancelRevive" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
|
||||||
|
if ( self inLastStand() )
|
||||||
|
{
|
||||||
|
self CancelObjective( "self inLastStand()" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isdefined( revivee ) || !revivee inLastStand() )
|
||||||
|
{
|
||||||
|
self CancelObjective( "!isdefined( revivee ) || !revivee inLastStand()" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( revivee.revivetrigger.beingrevived && !self maps\_laststand::is_reviving( revivee ) )
|
||||||
|
{
|
||||||
|
self CancelObjective( "revivee.revivetrigger.beingrevived && !self maps\_laststand::is_reviving( revivee )" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchToGoToGuy( revivee )
|
||||||
|
{
|
||||||
|
self endon( "cancel_bot_objective" );
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
self endon( "goal" );
|
||||||
|
self endon( "bad_path" );
|
||||||
|
self endon( "new_goal" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
wait 1;
|
||||||
|
|
||||||
|
if ( self IsTouching( revivee.revivetrigger ) )
|
||||||
|
{
|
||||||
|
self notify( "goal" );
|
||||||
|
break; // is this needed?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchForSuccessRevive( eObj )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "zombified" );
|
||||||
|
|
||||||
|
revivee = eObj.eEnt;
|
||||||
|
|
||||||
|
ret = self waittill_either_return( "cancel_bot_objective", "completed_bot_objective" );
|
||||||
|
|
||||||
|
if ( ret == "cancel_bot_objective" && isDefined( revivee ) && !revivee inLastStand() )
|
||||||
|
{
|
||||||
|
eObj.bWasSuccessful = true;
|
||||||
|
eObj.sReason = "revived him!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GoDoRevive( eObj )
|
||||||
|
{
|
||||||
|
self endon( "cancel_bot_objective" );
|
||||||
|
|
||||||
|
revivee = eObj.eEnt;
|
||||||
|
|
||||||
|
// go to guy
|
||||||
|
self thread WatchToGoToGuy( revivee );
|
||||||
|
self SetPriorityObjective();
|
||||||
|
self SetScriptGoal( revivee.origin, 32 );
|
||||||
|
|
||||||
|
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||||
|
|
||||||
|
if ( result != "goal" )
|
||||||
|
{
|
||||||
|
eObj.sReason = "didn't go to guy";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !self IsTouching( revivee.revivetrigger ) )
|
||||||
|
{
|
||||||
|
eObj.sReason = "not touching guy";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok we are touching guy, lets look at him
|
||||||
|
self SetScriptAimPos( revivee.origin );
|
||||||
|
|
||||||
|
// now lets hold use until he is up or otherwise
|
||||||
|
self thread WatchForSuccessRevive( eObj );
|
||||||
|
|
||||||
|
while ( self IsTouching( revivee.revivetrigger ) )
|
||||||
|
{
|
||||||
|
self thread BotPressUse( 0.15 );
|
||||||
|
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eObj.sReason = "not touching guy";
|
||||||
|
}
|
191
maps/bots/objectives/_utility.gsc
Normal file
191
maps/bots/objectives/_utility.gsc
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
#include common_scripts\utility;
|
||||||
|
#include maps\_utility;
|
||||||
|
#include maps\bots\_bot_utility;
|
||||||
|
|
||||||
|
CreateObjectiveForManger( sName, fpFinder, fpExecuter, fpPriority )
|
||||||
|
{
|
||||||
|
Answer = SpawnStruct();
|
||||||
|
|
||||||
|
Answer.sName = sName;
|
||||||
|
Answer.fpFinder = fpFinder;
|
||||||
|
Answer.fpExecuter = fpExecuter;
|
||||||
|
|
||||||
|
if ( !IsDefined( fpPriority ) )
|
||||||
|
{
|
||||||
|
Answer.fpPriority = ::DefaultPriority;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Answer.fpPriority = fpPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateFinderObjective( eObj, sName, eEnt, fPriority )
|
||||||
|
{
|
||||||
|
Answer = SpawnStruct();
|
||||||
|
|
||||||
|
Answer.eParentObj = eObj;
|
||||||
|
Answer.sName = sName;
|
||||||
|
Answer.eEnt = eEnt;
|
||||||
|
Answer.fPriority = fPriority;
|
||||||
|
Answer.GUID = eEnt GetEntityNumber();
|
||||||
|
|
||||||
|
Answer.bWasSuccessful = false;
|
||||||
|
Answer.sReason = "canceled";
|
||||||
|
|
||||||
|
return Answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultPriority( eObj, eEnt )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Checks whether the path generated by the ASTAR path finding is inaccessible
|
||||||
|
*/
|
||||||
|
GetPathIsInaccessible( from, to, team, best_effort )
|
||||||
|
{
|
||||||
|
if ( isDefined( best_effort ) )
|
||||||
|
{
|
||||||
|
path = generatePath( from, to, team, level.bot_allowed_negotiation_links, best_effort );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = generatePath( from, to, team, level.bot_allowed_negotiation_links );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( !isDefined( path ) || ( path.size <= 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
get_path_dist( start, end, team )
|
||||||
|
{
|
||||||
|
path = generatePath( start, end, team, level.bot_allowed_negotiation_links, 192.0 );
|
||||||
|
|
||||||
|
if ( !isDefined( path ) || path.size <= 0 )
|
||||||
|
{
|
||||||
|
return 999999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = 0;
|
||||||
|
prev_node = undefined;
|
||||||
|
|
||||||
|
for ( i = 0; i < path.size; i++ )
|
||||||
|
{
|
||||||
|
if ( i == 0 )
|
||||||
|
{
|
||||||
|
prev_node = path[ i ];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist += distance( prev_node.origin, path[ i ].origin );
|
||||||
|
prev_node = path[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClampLerp( dist, min_dist, max_dist, max_bonus, min_bonus )
|
||||||
|
{
|
||||||
|
answer = 0;
|
||||||
|
|
||||||
|
if ( dist <= min_dist )
|
||||||
|
{
|
||||||
|
answer += max_bonus;
|
||||||
|
}
|
||||||
|
else if ( dist <= max_dist )
|
||||||
|
{
|
||||||
|
answer += min_bonus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dist_multi = 1 - ( ( dist - min_dist ) / ( max_dist - min_dist ) );
|
||||||
|
answer += min_bonus + ( ( max_bonus - min_bonus ) * dist_multi );
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBotsAmountForEntity( eEnt )
|
||||||
|
{
|
||||||
|
if ( !isDefined( eEnt.bots ) )
|
||||||
|
{
|
||||||
|
eEnt.bots = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eEnt.bots;
|
||||||
|
}
|
||||||
|
|
||||||
|
IncrementBotsForEntity( eEnt )
|
||||||
|
{
|
||||||
|
self endon( "bots_for_entity_cleanup" );
|
||||||
|
|
||||||
|
eEnt.bots++;
|
||||||
|
|
||||||
|
self waittill_either( "disconnect", "zombified" );
|
||||||
|
|
||||||
|
if ( isDefined( eEnt ) )
|
||||||
|
{
|
||||||
|
eEnt.bots--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DecrementBotsForEntity( eEnt )
|
||||||
|
{
|
||||||
|
self notify( "bots_for_entity_cleanup" );
|
||||||
|
|
||||||
|
if ( isDefined( eEnt ) )
|
||||||
|
{
|
||||||
|
eEnt.bots--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CleanupBotsForEntity( eEnt )
|
||||||
|
{
|
||||||
|
self notify( "bots_for_entity_cleanup" );
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelObjective( reason )
|
||||||
|
{
|
||||||
|
self notify( "cancel_bot_objective", reason );
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletedObjective( successful, reason )
|
||||||
|
{
|
||||||
|
self notify( "completed_bot_objective", successful, reason );
|
||||||
|
}
|
||||||
|
|
||||||
|
HasBotObjective()
|
||||||
|
{
|
||||||
|
return isDefined( self.bot_current_objective );
|
||||||
|
}
|
||||||
|
|
||||||
|
get_angle_offset_node( forward_size, angle_offset, offset )
|
||||||
|
{
|
||||||
|
if ( !isDefined( forward_size ) )
|
||||||
|
{
|
||||||
|
forward_size = 40;
|
||||||
|
}
|
||||||
|
if ( !isDefined( angle_offset ) )
|
||||||
|
{
|
||||||
|
angle_offset = ( 0, 0, 0 );
|
||||||
|
}
|
||||||
|
if ( !isDefined( offset ) )
|
||||||
|
{
|
||||||
|
offset = ( 0, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
angles = ( 0, self.angles[ 1 ], 0 );
|
||||||
|
angles += angle_offset;
|
||||||
|
node = self.origin + ( AnglesToForward( angles ) * forward_size ) + offset;
|
||||||
|
node = clamp_to_ground( node );
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
clamp_to_ground( org )
|
||||||
|
{
|
||||||
|
trace = playerPhysicsTrace( org + ( 0, 0, 20 ), org - ( 0, 0, 2000 ) );
|
||||||
|
return trace;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user