mirror of
https://github.com/JezuzLizard/t4sp_bot_warfare.git
synced 2025-04-19 21:22:54 +00:00
cleanup
This commit is contained in:
parent
65ad154eb6
commit
81e65a3adb
@ -1,7 +1,5 @@
|
||||
# T4ZM-Zombie-Bots
|
||||
Bots for T4ZM.
|
||||
# T4SP-Bots
|
||||
Bots for T4SP.
|
||||
|
||||
Coby basted code from https://github.com/ineedbots/t4m_bot_warfare
|
||||
Credit to ineedbots for his bot warfare mods for various games.
|
||||
|
||||
Requires https://github.com/JezuzLizard/T4ZM-Script-Overhaul
|
@ -155,6 +155,11 @@ handleBots()
|
||||
*/
|
||||
onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
|
||||
{
|
||||
if ( self isBot() && getDvarInt( "bots_t8_mode" ) )
|
||||
{
|
||||
iDamage = int( iDamage * 0.1 );
|
||||
}
|
||||
|
||||
if ( self is_bot() )
|
||||
{
|
||||
self maps\bots\_bot_internal::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
|
||||
@ -164,6 +169,16 @@ onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon,
|
||||
self [[level.prevCallbackPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
|
||||
}
|
||||
|
||||
onActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset )
|
||||
{
|
||||
if ( isDefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker isBot() && getDvarInt( "bots_t8_mode" ) )
|
||||
{
|
||||
iDamage += int( self.maxhealth * randomFloatRange( 0.25, 1.25 ) );
|
||||
}
|
||||
|
||||
self [[level.prevCallbackActorDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset );
|
||||
}
|
||||
|
||||
/*
|
||||
Starts the callbacks.
|
||||
*/
|
||||
@ -172,6 +187,9 @@ hook_callbacks()
|
||||
wait 0.05;
|
||||
level.prevCallbackPlayerDamage = level.callbackPlayerDamage;
|
||||
level.callbackPlayerDamage = ::onPlayerDamage;
|
||||
|
||||
level.prevCallbackActorDamage = level.callbackActorDamage;
|
||||
level.callbackActorDamage = ::onActorDamage;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -764,6 +764,7 @@ load_waypoints()
|
||||
level.waypoints = GetAllNodes();
|
||||
level.waypointCount = level.waypoints.size;
|
||||
|
||||
level.waypointsInPlayableArea = [];
|
||||
level.waypointsInPlayableArea = get_nodes_in_playable_area();
|
||||
}
|
||||
|
||||
@ -1040,7 +1041,16 @@ random_normal_distribution( mean, std_deviation, lower_bound, upper_bound )
|
||||
*/
|
||||
inLastStand()
|
||||
{
|
||||
return self maps\_laststand::player_is_in_laststand();
|
||||
func = GetFunction( "maps/_laststand", "player_is_in_laststand" );
|
||||
|
||||
return self [[func]]();
|
||||
}
|
||||
|
||||
isReviving( revivee )
|
||||
{
|
||||
func = GetFunction( "maps/_laststand", "is_reviving" );
|
||||
|
||||
return self [[func]]( revivee );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1048,6 +1058,11 @@ inLastStand()
|
||||
*/
|
||||
getRandomGoal()
|
||||
{
|
||||
if ( !level.waypointsInPlayableArea.size )
|
||||
{
|
||||
return self.origin;
|
||||
}
|
||||
|
||||
return PickRandom( level.waypointsInPlayableArea ).origin;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ init()
|
||||
level.bot_objectives = [];
|
||||
level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "revive", maps\bots\objectives\_revive::Finder, maps\bots\objectives\_revive::Executer, 1000 );
|
||||
level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "powerup", maps\bots\objectives\_powerup::Finder, maps\bots\objectives\_powerup::Executer, 2500 );
|
||||
level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "wallweapon", maps\bots\objectives\_wallweapon::Finder, maps\bots\objectives\_wallweapon::Executer, 7500 );
|
||||
}
|
||||
|
||||
connected()
|
||||
|
@ -10,7 +10,7 @@ Finder( eObj )
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return Answer;
|
||||
return answer;
|
||||
}
|
||||
|
||||
for ( i = 0; i < ents.size; i++ )
|
||||
@ -40,7 +40,7 @@ Priority( eObj, eEnt )
|
||||
{
|
||||
// TODO: check powerup type
|
||||
base_priority = 0;
|
||||
base_priority += ClampLerp( Distance( self.origin, eEnt.origin ), 300, 700, 2, -2 );
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 300, 700, 2, -2 );
|
||||
|
||||
if ( self HasBotObjective() )
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ Finder( eObj )
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
base_priority = 3;
|
||||
base_priority += ClampLerp( Distance( self.origin, eEnt.origin ), 500, 1200, 2, -2 );
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 500, 1200, 2, -2 );
|
||||
|
||||
if ( self HasBotObjective() )
|
||||
{
|
||||
@ -114,9 +114,9 @@ WatchForCancelRevive( revivee )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( revivee.revivetrigger.beingrevived && !self maps\_laststand::is_reviving( revivee ) )
|
||||
if ( revivee.revivetrigger.beingrevived && !self isReviving( revivee ) )
|
||||
{
|
||||
self CancelObjective( "revivee.revivetrigger.beingrevived && !self maps\_laststand::is_reviving( revivee )" );
|
||||
self CancelObjective( "revivee.revivetrigger.beingrevived && !self isReviving( revivee )" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ ClampLerp( dist, min_dist, max_dist, max_bonus, min_bonus )
|
||||
{
|
||||
answer += max_bonus;
|
||||
}
|
||||
else if ( dist <= max_dist )
|
||||
else if ( dist >= max_dist )
|
||||
{
|
||||
answer += min_bonus;
|
||||
}
|
||||
@ -172,9 +172,23 @@ get_angle_offset_node( forward_size, angle_offset, offset )
|
||||
angles += angle_offset;
|
||||
node = self.origin + ( AnglesToForward( angles ) * forward_size ) + offset;
|
||||
node = clamp_to_ground( node );
|
||||
|
||||
self thread debug_offset_line( node );
|
||||
return node;
|
||||
}
|
||||
|
||||
debug_offset_line( node )
|
||||
{
|
||||
self notify( "debug_offset_line" );
|
||||
self endon( "debug_offset_line" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
line( self.origin, node );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
clamp_to_ground( org )
|
||||
{
|
||||
trace = playerPhysicsTrace( org + ( 0, 0, 20 ), org - ( 0, 0, 2000 ) );
|
||||
|
214
maps/bots/objectives/_wallweapon.gsc
Normal file
214
maps/bots/objectives/_wallweapon.gsc
Normal file
@ -0,0 +1,214 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
Finder( eObj )
|
||||
{
|
||||
answer = [];
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" );
|
||||
|
||||
if ( !isDefined( weapon_spawns ) || weapon_spawns.size <= 0 )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
weapons = self GetWeaponsList();
|
||||
|
||||
// TODO check if need a new weapon, rate weapons too is better then current etc
|
||||
|
||||
for ( i = 0; i < weapon_spawns.size; i++ )
|
||||
{
|
||||
player_has_weapon = false;
|
||||
|
||||
if ( !isDefined( weapon_spawns[i].zombie_weapon_upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( h = 0; h < weapons.size; h++ )
|
||||
{
|
||||
if ( weapons[h] == weapon_spawns[i].zombie_weapon_upgrade )
|
||||
{
|
||||
player_has_weapon = true;
|
||||
}
|
||||
}
|
||||
|
||||
is_grenade = ( WeaponType( weapon_spawns[i].zombie_weapon_upgrade ) == "grenade" );
|
||||
|
||||
if ( !player_has_weapon || is_grenade )
|
||||
{
|
||||
func = GetFunction( "maps/_zombiemode_weapons", "get_weapon_cost" );
|
||||
|
||||
if ( self.score < [[func]]( weapon_spawns[i].zombie_weapon_upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
func = GetFunction( "maps/_zombiemode_weapons", "get_ammo_cost" );
|
||||
|
||||
if ( self.score < [[func]]( weapon_spawns[i].zombie_weapon_upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
model = getEnt( weapon_spawns[ i ].target, "targetname" );
|
||||
|
||||
if ( !isDefined( model ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
org = self getOffset( model );
|
||||
|
||||
if ( GetPathIsInaccessible( self.origin, org ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
answer[answer.size] = self CreateFinderObjective( eObj, eObj.sName + "_" + weapon_spawns[i] GetEntityNumber(), weapon_spawns[i], self Priority( eObj, weapon_spawns[i] ) );
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
getOffset( model )
|
||||
{
|
||||
// some weapons have 90 offset... how to handle this??
|
||||
angle_off = -90;
|
||||
|
||||
org = model get_angle_offset_node( 40, ( 0, angle_off, 0 ), ( 0, 0, 1 ) );
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
// TODO: check weallweapon type
|
||||
|
||||
base_priority = 0;
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 0, 800, 2, -2 );
|
||||
|
||||
if ( self HasBotObjective() )
|
||||
{
|
||||
base_priority -= 1;
|
||||
}
|
||||
|
||||
if ( eEnt.zombie_weapon_upgrade == "zombie_kar98k" )
|
||||
{
|
||||
base_priority -= 99;
|
||||
}
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
|
||||
Executer( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
weapon = eObj.eEnt;
|
||||
|
||||
self thread WatchForCancel( weapon );
|
||||
|
||||
self GoDoWallweapon( eObj );
|
||||
|
||||
self WatchForCancelCleanup();
|
||||
self ClearScriptAimPos();
|
||||
self ClearScriptGoal();
|
||||
self CompletedObjective( eObj.bWasSuccessful, eObj.sReason );
|
||||
}
|
||||
|
||||
WatchForCancelCleanup()
|
||||
{
|
||||
self notify( "WatchForCancelWallweapon" );
|
||||
}
|
||||
|
||||
WatchForCancel( weapon )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "WatchForCancelWallweapon" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
self CancelObjective( "self inLastStand()" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchToGoToWeapon( weapon )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "goal" );
|
||||
self endon( "bad_path" );
|
||||
self endon( "new_goal" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self IsTouching( weapon ) )
|
||||
{
|
||||
self notify( "goal" );
|
||||
break; // is this needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GoDoWallweapon( eObj )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
|
||||
weapon = eObj.eEnt;
|
||||
model = getEnt( weapon.target, "targetname" );
|
||||
org = self getOffset( model );
|
||||
|
||||
// go to weapon
|
||||
self thread WatchToGoToWeapon( weapon );
|
||||
self SetScriptGoal( org, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sReason = "didn't go to weapon";
|
||||
return;
|
||||
}
|
||||
|
||||
// istouching use triggers doesnt work well
|
||||
if ( !self IsTouching( weapon ) && false )
|
||||
{
|
||||
eObj.sReason = "not touching weapon";
|
||||
return;
|
||||
}
|
||||
|
||||
// ok we are touching weapon, lets look at it
|
||||
self SetScriptAimPos( weapon.origin );
|
||||
|
||||
// wait to look at it
|
||||
wait 1;
|
||||
|
||||
// press use
|
||||
self thread BotPressUse( 0.15 );
|
||||
wait 0.1;
|
||||
|
||||
eObj.sReason = "completed";
|
||||
eObj.bWasSuccessful = true;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,635 +0,0 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\script_objectives\_obj_utility;
|
||||
|
||||
register_bot_objective( objective_group )
|
||||
{
|
||||
if ( !isDefined( level.zbot_objective_glob ) )
|
||||
{
|
||||
level.zbot_objective_glob = [];
|
||||
}
|
||||
if ( !isDefined( level.zbot_objective_glob[ objective_group ] ) )
|
||||
{
|
||||
level.zbot_objective_glob[ objective_group ] = spawnStruct();
|
||||
level.zbot_objective_glob[ objective_group ].active_objectives = [];
|
||||
}
|
||||
}
|
||||
|
||||
add_possible_bot_objective( objective_group, target_ent, is_global_shared )
|
||||
{
|
||||
if ( !isDefined( target_ent ) )
|
||||
{
|
||||
objective_assert( objective_group, undefined, "add_possible_bot_objective", "[ent was undefined]" );
|
||||
return;
|
||||
}
|
||||
|
||||
id = target_ent getEntityNumber();
|
||||
|
||||
if ( !isDefined( level.zbot_objective_glob ) )
|
||||
{
|
||||
objective_assert( objective_group, id, "add_possible_bot_objective", "Trying to add objective before calling register_bot_objective for objective group " + objective_group );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isDefined( level.zbot_objective_glob[ objective_group ] ) )
|
||||
{
|
||||
objective_assert( objective_group, id, "add_possible_bot_objective", "Trying to add objective to group " + objective_group + " before calling register_bot_objective" );
|
||||
return;
|
||||
}
|
||||
|
||||
objective_struct = spawnStruct();
|
||||
objective_struct.group = objective_group;
|
||||
objective_struct.is_global_shared = is_global_shared;
|
||||
objective_struct.target_ent = target_ent;
|
||||
objective_struct.owner = undefined;
|
||||
objective_struct.is_objective = true;
|
||||
objective_struct.bad = false;
|
||||
objective_struct.id = id;
|
||||
|
||||
level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ] = objective_struct;
|
||||
|
||||
return level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ];
|
||||
}
|
||||
|
||||
get_objective( objective_group, ent, id )
|
||||
{
|
||||
return get_objective_safe( objective_group, ent, id, "get_objective_by_entity_ref" );
|
||||
}
|
||||
|
||||
get_all_objectives_for_group( objective_group )
|
||||
{
|
||||
return level.zbot_objective_glob[ objective_group ].active_objectives;
|
||||
}
|
||||
|
||||
bot_get_objective()
|
||||
{
|
||||
return self.zbot_current_objective;
|
||||
}
|
||||
|
||||
bot_has_objective()
|
||||
{
|
||||
return isDefined( self.zbot_current_objective );
|
||||
}
|
||||
|
||||
bot_set_objective( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "bot_set_objective" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new_obj_history = spawnStruct();
|
||||
new_obj_history.id = ent getEntityNumber();
|
||||
new_obj_history.group = objective_group;
|
||||
new_obj_history.ent_start_pos = ent.origin;
|
||||
new_obj_history.ent_end_pos = ent.origin;
|
||||
new_obj_history.bot_start_pos = self.origin;
|
||||
new_obj_history.bot_end_pos = self.origin;
|
||||
new_obj_history.start_time = getTime();
|
||||
new_obj_history.end_time = getTime();
|
||||
new_obj_history.time_spent = 0;
|
||||
|
||||
self.bot_obj_history_prev_index = self.bot_obj_history_index;
|
||||
if ( self.bot_obj_history_index >= self.bot_obj_history_max_entries )
|
||||
{
|
||||
self.bot_obj_history_index = 0;
|
||||
}
|
||||
|
||||
self.obj_history[ self.bot_obj_history_index ] = new_obj_history;
|
||||
self.zbot_current_objective = objective;
|
||||
}
|
||||
|
||||
bot_clear_objective()
|
||||
{
|
||||
objective = self.zbot_current_objective;
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self bot_clear_objective_owner( objective.group, objective.target_ent );
|
||||
self.zbot_current_objective = undefined;
|
||||
}
|
||||
|
||||
objective_has_owner( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "objective_has_owner" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !isDefined( id ) )
|
||||
{
|
||||
id = ent getEntityNumber();
|
||||
}
|
||||
|
||||
if ( !objective.is_global_shared )
|
||||
{
|
||||
objective_assert( objective_group, id, "objective_has_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group );
|
||||
return false;
|
||||
}
|
||||
|
||||
return isDefined( objective.owner );
|
||||
}
|
||||
|
||||
bot_is_objective_owner( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "bot_is_objective_owner" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !isDefined( id ) )
|
||||
{
|
||||
id = ent getEntityNumber();
|
||||
}
|
||||
|
||||
if ( !objective.is_global_shared )
|
||||
{
|
||||
objective_assert( objective_group, id, "bot_is_objective_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group );
|
||||
return false;
|
||||
}
|
||||
|
||||
return isDefined( objective.owner ) && objective.owner == self;
|
||||
}
|
||||
|
||||
bot_set_objective_owner( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "bot_set_objective_owner" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isDefined( id ) )
|
||||
{
|
||||
id = ent getEntityNumber();
|
||||
}
|
||||
|
||||
if ( !objective.is_global_shared )
|
||||
{
|
||||
objective_assert( objective_group, id, "bot_set_objective_owner", "Objective with " + id + " id number cannot be set to have an owner because is_global_shared field is false in group " + objective_group );
|
||||
return;
|
||||
}
|
||||
|
||||
objective.owner = self;
|
||||
}
|
||||
|
||||
bot_clear_objective_owner( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "clear_objective_owner" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isDefined( objective.owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( objective.owner != self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
objective.owner = undefined;
|
||||
}
|
||||
|
||||
mark_objective_bad( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "mark_objective_bad" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
objective.bad = true;
|
||||
}
|
||||
|
||||
free_bot_objective( objective_group, ent, id )
|
||||
{
|
||||
objective = get_objective_safe( objective_group, ent, id, "free_bot_objective" );
|
||||
if ( !isDefined( objective ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isDefined( ent ) )
|
||||
{
|
||||
id = ent getEntityNumber();
|
||||
}
|
||||
players = getPlayers();
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[ i ] is_bot() )
|
||||
{
|
||||
if ( isDefined( players[ i ].zbot_current_objective ) && players[ i ].zbot_current_objective == objective )
|
||||
{
|
||||
players[ i ].zbot_current_objective = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level.zbot_objective_glob[ objective_group ].active_objectives[ "obj_id_" + id ] = undefined;
|
||||
}
|
||||
|
||||
get_objective_safe( objective_group, ent, id, function_name )
|
||||
{
|
||||
if ( !isDefined( ent ) && !isDefined( id ) )
|
||||
{
|
||||
objective_assert( objective_group, id, function_name, "[ent and id were undefined]" );
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if ( isDefined( ent ) )
|
||||
{
|
||||
id = ent getEntityNumber();
|
||||
}
|
||||
|
||||
if ( !isDefined( level.zbot_objective_glob[ objective_group ] ) )
|
||||
{
|
||||
objective_assert( objective_group, id, function_name, "[obj group is invalid]" );
|
||||
return undefined;
|
||||
}
|
||||
|
||||
active_objectives = level.zbot_objective_glob[ objective_group ].active_objectives;
|
||||
|
||||
objective = active_objectives[ "obj_id_" + id ];
|
||||
|
||||
objective_exists = isDefined( objective );
|
||||
if ( !objective_exists )
|
||||
{
|
||||
objective_assert( objective_group, id, function_name, "[obj was undefined]" );
|
||||
return undefined;
|
||||
}
|
||||
return objective;
|
||||
}
|
||||
|
||||
bot_objective_print( objective_group, id, message, function_name )
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) != 0 || getDvarInt( "bot_obj_debug_" + objective_group ) != 0 )
|
||||
{
|
||||
self objective_info_print( objective_group, id, function_name, message );
|
||||
}
|
||||
}
|
||||
|
||||
objective_assert( objective_group, id, function_name, message )
|
||||
{
|
||||
assertMsg( message );
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) != 0 || getDvarInt( "bot_obj_debug_" + objective_group ) != 0 )
|
||||
{
|
||||
if ( !isDefined( id ) )
|
||||
{
|
||||
error_message = "BOT_OBJ_ERROR: Time <" + getTime() + "> " + function_name + "() Obj <" + objective_group + "> " + message;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_message = "BOT_OBJ_ERROR: Time <" + getTime() + "> " + function_name + "() Obj <" + objective_group + "> Ent <" + id + "> " + message;
|
||||
}
|
||||
logprint( error_message + "\n" );
|
||||
printConsole( error_message );
|
||||
}
|
||||
}
|
||||
|
||||
objective_info_print( objective_group, id, function_name, message )
|
||||
{
|
||||
message = "BOT_OBJ_INFO: Time <" + getTime() + "> " + function_name + "() Obj <" + objective_group + "> ent <" + id + "> " + message;
|
||||
logprint( message + "\n" );
|
||||
printConsole( message );
|
||||
}
|
||||
|
||||
bot_objective_history_get_oldest()
|
||||
{
|
||||
oldest = self.obj_history[ 0 ];
|
||||
for ( i = 1; i < self.obj_history.size; i++ )
|
||||
{
|
||||
if ( oldest.end_time < self.obj_history[ i ] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
oldest = self.obj_history[ i ];
|
||||
}
|
||||
return oldest;
|
||||
}
|
||||
|
||||
bot_objective_history_get_current()
|
||||
{
|
||||
return self.obj_history[ self.bot_obj_history_index ];
|
||||
}
|
||||
|
||||
bot_objective_history_get_previous()
|
||||
{
|
||||
return self.obj_history[ self.bot_obj_history_prev_index ];
|
||||
}
|
||||
|
||||
/**********Action Section**********/
|
||||
|
||||
register_bot_action( action_name, action_func, init_func, post_think_func, should_do_func, check_if_complete_func, should_cancel_func, priority_func )
|
||||
{
|
||||
if ( !isDefined( level.zbots_actions ) )
|
||||
{
|
||||
level.zbots_actions = [];
|
||||
}
|
||||
if ( !isDefined( level.zbots_actions[ action_name ] ) )
|
||||
{
|
||||
level.zbots_actions[ action_name ] = spawnStruct();
|
||||
}
|
||||
level.zbots_actions[ action_name ].action = action_func;
|
||||
level.zbots_actions[ action_name ].init_func = init_func;
|
||||
level.zbots_actions[ action_name ].post_think_func = post_think_func;
|
||||
level.zbots_actions[ action_name ].should_do_func = should_do_func;
|
||||
level.zbots_actions[ action_name ].check_if_complete_func = check_if_complete_func;
|
||||
level.zbots_actions[ action_name ].should_cancel_func = should_cancel_func;
|
||||
level.zbots_actions[ action_name ].priority_func = priority_func;
|
||||
}
|
||||
|
||||
bot_process_action()
|
||||
{
|
||||
self endon( "stop_action_think" );
|
||||
|
||||
action_name = self.bot_action.action_name;
|
||||
|
||||
self [[ level.zbots_actions[ action_name ].init_func ]]();
|
||||
|
||||
self thread [[ level.zbots_actions[ action_name ].action ]]( self.bot_action.obj );
|
||||
|
||||
self.running_action = true;
|
||||
self wait_for_action_completion( action_name );
|
||||
}
|
||||
|
||||
wait_for_action_completion( action_name )
|
||||
{
|
||||
action_complete_name = action_name + "_complete";
|
||||
action_cancel_name = action_name + "_cancel";
|
||||
|
||||
result = self waittill_any_return( action_complete_name, action_cancel_name );
|
||||
|
||||
end_state = undefined;
|
||||
|
||||
if ( ( result == action_complete_name ) )
|
||||
{
|
||||
end_state = "completed";
|
||||
}
|
||||
else if ( result == action_cancel_name )
|
||||
{
|
||||
end_state = "canceled";
|
||||
}
|
||||
|
||||
self notify( action_name + "_end_think" );
|
||||
|
||||
self [[ level.zbots_actions[ action_name ].post_think_func ]]( end_state );
|
||||
|
||||
self.bot_action = undefined;
|
||||
|
||||
self.obj_history[ self.bot_obj_history_index ].end_time = getTime();
|
||||
end_time = self.obj_history[ self.bot_obj_history_index ].end_time;
|
||||
start_time = self.obj_history[ self.bot_obj_history_index ].start_time;
|
||||
self.obj_history[ self.bot_obj_history_index ].time_spent = end_time - start_time;
|
||||
self.obj_history[ self.bot_obj_history_index ].bot_end_pos = self.origin;
|
||||
self.bot_obj_history_index++;
|
||||
self.running_action = false;
|
||||
}
|
||||
|
||||
bot_pick_action()
|
||||
{
|
||||
action_keys = getArrayKeys( level.zbots_actions );
|
||||
|
||||
possible_actions = NewHeap( ::HeapPriority );
|
||||
for ( i = 0; i < action_keys.size; i++ )
|
||||
{
|
||||
struct = spawnStruct();
|
||||
struct.possible_objs = [];
|
||||
if ( self [[ level.zbots_actions[ action_keys[ i ] ].should_do_func ]]( struct ) )
|
||||
{
|
||||
available_objs = struct.possible_objs;
|
||||
for ( j = 0; j < available_objs.size; j++ )
|
||||
{
|
||||
possible_action = spawnStruct();
|
||||
possible_action.action_name = action_keys[ i ];
|
||||
possible_action.priority = self [[ level.zbots_actions[ action_keys[ i ] ].priority_func ]]( available_objs[ j ] );
|
||||
possible_action.obj = available_objs[ j ];
|
||||
possible_actions HeapInsert( possible_action );
|
||||
printConsole( self.playername + " Adding obj " + action_keys[ i ] + " id " + available_objs[ j ].id + " to queue of size: " + possible_actions.data.size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forced_action = getDvar( "bots_debug_forced_action" );
|
||||
|
||||
if ( ( !isDefined( possible_actions.data ) || possible_actions.data.size <= 0 ) && forced_action == "" )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( forced_action != "" )
|
||||
{
|
||||
entnum_and_forced_action = strTok( forced_action, " " );
|
||||
if ( entnum_and_forced_action.size != 2 )
|
||||
{
|
||||
setDvar( "bots_debug_forced_action", "" );
|
||||
}
|
||||
else if ( int( entnum_and_forced_action[ 0 ] ) == self getEntityNumber() && isDefined( level.zbots_actions[ entnum_and_forced_action[ 1 ] ] ) )
|
||||
{
|
||||
possible_action = spawnStruct();
|
||||
possible_action.action_name = entnum_and_forced_action[ 1 ];
|
||||
possible_action.priority = 999;
|
||||
self.bot_action = possible_action;
|
||||
setDvar( "bots_debug_forced_action", "" );
|
||||
printConsole( self.playername + " Picking forced action " + self.bot_action.action_name + " Priority " + self.bot_action.priority );
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
self.bot_action = possible_actions.data[ 0 ];
|
||||
printConsole( self.playername + " Picking action " + self.bot_action.action_name + " Priority " + self.bot_action.priority );
|
||||
return true;
|
||||
}
|
||||
|
||||
bot_check_action_complete( action_name )
|
||||
{
|
||||
assert( isDefined( level.zbots_actions[ action_name ].check_if_complete_func ) );
|
||||
|
||||
is_complete = self [[ level.zbots_actions[ action_name ].check_if_complete_func ]]();
|
||||
|
||||
if ( is_complete )
|
||||
{
|
||||
self notify( action_name + "_complete" );
|
||||
self notify( "goal" );
|
||||
}
|
||||
return is_complete;
|
||||
}
|
||||
|
||||
bot_check_if_action_should_be_canceled_in_group( action_name )
|
||||
{
|
||||
should_cancel = self [[ level.zbots_actions[ action_name ].should_cancel_func ]]();
|
||||
if ( should_cancel )
|
||||
{
|
||||
self notify( action_name + "_cancel" );
|
||||
self notify( "goal" );
|
||||
}
|
||||
|
||||
return should_cancel;
|
||||
}
|
||||
|
||||
bot_check_if_action_should_be_canceled_globally( action_name )
|
||||
{
|
||||
should_cancel = self action_should_be_canceled_global( action_name );
|
||||
if ( should_cancel )
|
||||
{
|
||||
self notify( action_name + "_cancel" );
|
||||
self notify( "goal" );
|
||||
}
|
||||
return should_cancel;
|
||||
}
|
||||
|
||||
bot_action_think()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
level endon( "end_game" );
|
||||
|
||||
self thread bot_action_pump();
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) != 0 )
|
||||
{
|
||||
wait 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
wait 1;
|
||||
}
|
||||
//Wait until the end of the frame so any variables set by _bot_internal in the current frame will have up to date values
|
||||
waittillframeend;
|
||||
|
||||
self.bot_action = undefined;
|
||||
if ( !self bot_pick_action() )
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) != 0 )
|
||||
{
|
||||
printConsole( "BOT_ACTION_THINK: " + self.playername + " does not have an action selected" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
self bot_process_action();
|
||||
|
||||
while ( !maps\so\zm_common\_zm_utility::is_player_valid( self ) )
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) != 0 )
|
||||
{
|
||||
printConsole( "BOT_ACTION_THINK: " + self.playername + " is not in a valid state" );
|
||||
}
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_action_pump()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
level endon( "end_game" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.05;
|
||||
if ( !isDefined( self.bot_action ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
action_name = self.bot_action.action_name;
|
||||
if ( self bot_check_action_complete( action_name ) )
|
||||
{
|
||||
}
|
||||
else if ( self bot_check_if_action_should_be_canceled_globally( action_name ) )
|
||||
{
|
||||
}
|
||||
else if ( self bot_check_if_action_should_be_canceled_in_group( action_name ) )
|
||||
{
|
||||
}
|
||||
|
||||
while ( !maps\so\zm_common\_zm_utility::is_player_valid( self ) )
|
||||
{
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action_should_be_postponed_global( action_name )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
action_should_be_canceled_global( action_name )
|
||||
{
|
||||
obj = self bot_get_objective();
|
||||
|
||||
goal_canceled = false;
|
||||
if ( !isDefined( obj ) )
|
||||
{
|
||||
self.obj_cancel_reason = "Obj didn't exist";
|
||||
goal_canceled = true;
|
||||
}
|
||||
else if ( !isDefined( obj.target_ent ) )
|
||||
{
|
||||
self.obj_cancel_reason = "Obj entity doesn't exist";
|
||||
canceled_goal = true;
|
||||
}
|
||||
else if ( isDefined( obj.target_ent.player_visibility ) && !obj.target_ent.player_visibility[ self getEntityNumber() + "" ] )
|
||||
{
|
||||
self.obj_cancel_reason = "Trigger wasn't visible";
|
||||
goal_canceled = true;
|
||||
}
|
||||
else if ( !isDefined( obj.target_ent.bot_use_node ) && self GetPathIsInaccessible( obj.target_ent.origin ) )
|
||||
{
|
||||
self.obj_cancel_reason = "Path to ent was inaccessible";
|
||||
goal_canceled = true;
|
||||
}
|
||||
else if ( isDefined( obj.target_ent.bot_use_node ) && self GetPathIsInaccessible( obj.target_ent.bot_use_node ) )
|
||||
{
|
||||
self.obj_cancel_reason = "Path to use node was inaccessible";
|
||||
goal_canceled = true;
|
||||
}
|
||||
else if ( obj.bad )
|
||||
{
|
||||
self.obj_cancel_reason = "Obj was bad";
|
||||
goal_canceled = true;
|
||||
}
|
||||
else if ( !maps\so\zm_common\_zm_utility::is_player_valid( self ) )
|
||||
{
|
||||
self.obj_cancel_reason = "In invalid state";
|
||||
goal_canceled = true;
|
||||
}
|
||||
return goal_canceled;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\script_objectives\_obj_utility;
|
||||
#include maps\bots\script_objectives\_obj_common;
|
||||
#include maps\bots\script_objectives\_obj_actions;
|
||||
#include maps\bots\script_objectives\_obj_trackers;
|
||||
|
||||
init()
|
||||
{
|
||||
register_bot_action( "powerup",
|
||||
::bot_grab_powerup,
|
||||
::bot_powerup_init,
|
||||
::bot_powerup_post_think,
|
||||
::bot_should_grab_powerup,
|
||||
::bot_check_complete_grab_powerup,
|
||||
::bot_powerup_should_cancel,
|
||||
::bot_powerup_priority );
|
||||
|
||||
register_bot_action( "revive",
|
||||
::bot_revive_player,
|
||||
::bot_revive_player_init,
|
||||
::bot_revive_player_post_think,
|
||||
::bot_should_revive_player,
|
||||
::bot_check_complete_revive_player,
|
||||
::bot_revive_player_should_cancel,
|
||||
::bot_revive_player_priority );
|
||||
|
||||
register_bot_action( "magicbox",
|
||||
::bot_magicbox_purchase,
|
||||
::bot_magicbox_purchase_init,
|
||||
::bot_magicbox_purchase_post_think,
|
||||
::bot_should_purchase_magicbox,
|
||||
::bot_check_complete_purchase_magicbox,
|
||||
::bot_magicbox_purchase_should_cancel,
|
||||
::bot_magicbox_purchase_priority );
|
||||
|
||||
register_bot_action( "perk",
|
||||
::bot_perk_purchase,
|
||||
::bot_perk_purchase_init,
|
||||
::bot_perk_purchase_post_think,
|
||||
::bot_should_purchase_perk,
|
||||
::bot_check_complete_perk_purchase,
|
||||
::bot_perk_purchase_should_cancel,
|
||||
::bot_perk_purchase_priority );
|
||||
|
||||
register_bot_action( "door",
|
||||
::bot_door_purchase,
|
||||
::bot_door_purchase_init,
|
||||
::bot_door_purchase_post_think,
|
||||
::bot_should_purchase_door,
|
||||
::bot_check_complete_door_purchase,
|
||||
::bot_door_purchase_should_cancel,
|
||||
::bot_door_purchase_priority );
|
||||
|
||||
register_bot_action( "debris",
|
||||
::bot_debris_purchase,
|
||||
::bot_debris_purchase_init,
|
||||
::bot_debris_purchase_post_think,
|
||||
::bot_should_purchase_debris,
|
||||
::bot_check_complete_debris_purchase,
|
||||
::bot_debris_purchase_should_cancel,
|
||||
::bot_debris_purchase_priority );
|
||||
|
||||
register_bot_action( "wallbuy",
|
||||
::bot_wallbuy_purchase,
|
||||
::bot_wallbuy_purchase_init,
|
||||
::bot_wallbuy_purchase_post_think,
|
||||
::bot_should_purchase_wallbuy,
|
||||
::bot_check_complete_wallbuy_purchase,
|
||||
::bot_wallbuy_purchase_should_cancel,
|
||||
::bot_wallbuy_purchase_priority );
|
||||
|
||||
register_bot_action( "wallbuyammo",
|
||||
::bot_wallbuy_ammo_purchase,
|
||||
::bot_wallbuy_ammo_purchase_init,
|
||||
::bot_wallbuy_ammo_purchase_post_think,
|
||||
::bot_should_purchase_wallbuy_ammo,
|
||||
::bot_check_complete_wallbuy_ammo_purchase,
|
||||
::bot_wallbuy_ammo_purchase_should_cancel,
|
||||
::bot_wallbuy_ammo_purchase_priority );
|
||||
|
||||
register_bot_action( "packapunch",
|
||||
::bot_packapunch_purchase,
|
||||
::bot_packapunch_purchase_init,
|
||||
::bot_packapunch_purchase_post_think,
|
||||
::bot_should_purchase_packapunch,
|
||||
::bot_check_complete_packapunch_purchase,
|
||||
::bot_packapunch_purchase_should_cancel,
|
||||
::bot_packapunch_purchase_priority );
|
||||
|
||||
register_bot_action( "power",
|
||||
::bot_power_activate,
|
||||
::bot_power_activate_init,
|
||||
::bot_power_activate_post_think,
|
||||
::bot_should_activate_power,
|
||||
::bot_check_complete_power_activate,
|
||||
::bot_power_activate_should_cancel,
|
||||
::bot_power_activate_priority );
|
||||
|
||||
register_bot_objective( "magicbox" );
|
||||
register_bot_objective( "wallbuy" );
|
||||
register_bot_objective( "wallbuyammo" );
|
||||
register_bot_objective( "perk" );
|
||||
register_bot_objective( "door" );
|
||||
register_bot_objective( "debris" );
|
||||
register_bot_objective( "trap" );
|
||||
register_bot_objective( "packapunch" );
|
||||
register_bot_objective( "power" );
|
||||
register_bot_objective( "revive" );
|
||||
//register_bot_objective( "grabbuildable" );
|
||||
//register_bot_objective( "buildbuildable" );
|
||||
//register_bot_objective( "part" );
|
||||
register_bot_objective( "powerup" );
|
||||
|
||||
if ( getDvar( "bots_obj_buy_blockers" ) == "" )
|
||||
{
|
||||
setDvar( "bots_obj_buy_blockers", true );
|
||||
}
|
||||
|
||||
create_static_objectives();
|
||||
}
|
||||
|
||||
connected()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self.on_powerup_grab_func = ::bot_on_powerup_grab;
|
||||
self.on_revive_success_func = ::bot_on_revive_success;
|
||||
self.on_magicbox_weapon_grab_func = ::bot_on_magicbox_weapon_grab;
|
||||
self.on_perk_purchase_func = ::bot_on_perk_purchase;
|
||||
self.on_door_purchase_func = ::bot_on_door_purchase_func;
|
||||
self.on_debris_purchase_func = ::bot_on_debris_purchase_func;
|
||||
self.on_wallbuy_purchase_func = ::bot_on_wallbuy_purchase_func;
|
||||
self.on_wallbuy_ammo_purchase_func = ::bot_on_wallbuy_ammo_purchase_func;
|
||||
|
||||
self.obj_cancel_reason = "";
|
||||
|
||||
self.obj_history = [];
|
||||
self.bot_obj_history_max_entries = 20;
|
||||
self.bot_obj_history_index = 0;
|
||||
self.bot_obj_history_prev_index = 0;
|
||||
}
|
||||
|
||||
spawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
|
||||
self thread bot_action_think();
|
||||
//self thread cleanup_on_disconnect();
|
||||
}
|
||||
|
||||
start_bot_threads()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
}
|
||||
|
||||
//TODO: Add ability to pause an action so the bot won't be doing it while its paused but when its unpaused they can resume the action with the same settings
|
||||
//Similar to postpone except instead of selecting a new action the current action is preserved
|
||||
action_should_be_paused_global( primary_group_name, action_name )
|
||||
{
|
||||
return false;
|
||||
}
|
@ -1,397 +0,0 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\script_objectives\_obj_common;
|
||||
#include maps\bots\script_objectives\_obj_utility;
|
||||
|
||||
create_static_objectives()
|
||||
{
|
||||
if ( getDvar( "magicbox_node_forward_size" ) == "" )
|
||||
{
|
||||
setDvar( "magicbox_node_forward_size", 55 );
|
||||
}
|
||||
if ( getDvar( "magicbox_node_vertical_offset" ) == "" )
|
||||
{
|
||||
setDvar( "magicbox_node_vertical_offset", 10 );
|
||||
}
|
||||
if ( getDvar( "magicbox_node_angle" ) == "" )
|
||||
{
|
||||
setDvar( "magicbox_node_angle", 90 );
|
||||
}
|
||||
if ( getDvar( "perk_node_forward_size" ) == "" )
|
||||
{
|
||||
setDvar( "perk_node_forward_size", 55 );
|
||||
}
|
||||
if ( getDvar( "perk_node_vertical_offset" ) == "" )
|
||||
{
|
||||
setDvar( "perk_node_vertical_offset", 1 );
|
||||
}
|
||||
if ( getDvar( "perk_node_angle" ) == "" )
|
||||
{
|
||||
setDvar( "perk_node_angle", -90 );
|
||||
}
|
||||
if ( getDvar( "wallbuy_node_forward_size" ) == "" )
|
||||
{
|
||||
setDvar( "wallbuy_node_forward_size", 40 );
|
||||
}
|
||||
if ( getDvar( "wallbuy_node_vertical_offset" ) == "" )
|
||||
{
|
||||
setDvar( "wallbuy_node_vertical_offset", 1 );
|
||||
}
|
||||
if ( getDvar( "wallbuy_node_angle" ) == "" )
|
||||
{
|
||||
setDvar( "wallbuy_node_angle", -90 );
|
||||
}
|
||||
if ( getDvar( "packapunch_node_forward_size" ) == "" )
|
||||
{
|
||||
setDvar( "packapunch_node_forward_size", 55 );
|
||||
}
|
||||
if ( getDvar( "packapunch_node_vertical_offset" ) == "" )
|
||||
{
|
||||
setDvar( "packapunch_node_vertical_offset", 1 );
|
||||
}
|
||||
if ( getDvar( "packapunch_node_angle" ) == "" )
|
||||
{
|
||||
setDvar( "packapunch_node_angle", -90 );
|
||||
}
|
||||
if ( getDvar( "power_node_forward_size" ) == "" )
|
||||
{
|
||||
setDvar( "power_node_forward_size", 55 );
|
||||
}
|
||||
if ( getDvar( "power_node_vertical_offset" ) == "" )
|
||||
{
|
||||
setDvar( "power_node_vertical_offset", 1 );
|
||||
}
|
||||
if ( getDvar( "power_node_angle" ) == "" )
|
||||
{
|
||||
setDvar( "power_node_angle", -90 );
|
||||
}
|
||||
weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" );
|
||||
|
||||
if ( isDefined( weapon_spawns ) && weapon_spawns.size > 0 )
|
||||
{
|
||||
for( i = 0; i < weapon_spawns.size; i++ )
|
||||
{
|
||||
obj = add_possible_bot_objective( "wallbuy", weapon_spawns[ i ], false );
|
||||
obj = add_possible_bot_objective( "wallbuyammo", weapon_spawns[ i ], false );
|
||||
model = getEnt( weapon_spawns[ i ].target, "targetname" );
|
||||
weapon_spawns[ i ].bot_use_node = model get_angle_offset_node( getDvarInt( "wallbuy_node_forward_size" ), ( 0, getDvarInt( "wallbuy_node_angle" ), 0 ), ( 0, 0, getDvarInt( "wallbuy_node_vertical_offset" ) ) );
|
||||
model thread wallbuy_debug();
|
||||
}
|
||||
}
|
||||
|
||||
vending_triggers = GetEntArray( "zombie_vending", "targetname" );
|
||||
|
||||
if ( isDefined( vending_triggers ) && vending_triggers.size > 0 )
|
||||
{
|
||||
for ( i = 0; i < vending_triggers.size; i++ )
|
||||
{
|
||||
obj = add_possible_bot_objective( "perk", vending_triggers[ i ], false );
|
||||
model = getEnt( vending_triggers[ i ].target, "targetname" );
|
||||
vending_triggers[ i ].bot_use_node = model get_angle_offset_node( getDvarInt( "perk_node_forward_size" ), ( 0, getDvarInt( "perk_node_angle" ), 0 ), ( 0, 0, getDvarInt( "perk_node_vertical_offset" ) ) );
|
||||
model thread perk_debug();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: See if its possible to automatically detect if a door is blocking an objective
|
||||
zombie_doors = GetEntArray( "zombie_door", "targetname" );
|
||||
|
||||
if ( isDefined( zombie_doors ) && zombie_doors.size > 0 )
|
||||
{
|
||||
for ( i = 0; i < zombie_doors.size; i++ )
|
||||
{
|
||||
if ( isDefined( zombie_doors[ i ].script_noteworthy ) && zombie_doors[ i ].script_noteworthy == "electric_door" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
obj = add_possible_bot_objective( "door", zombie_doors[ i ], true );
|
||||
}
|
||||
level thread watch_door_objectives( zombie_doors );
|
||||
}
|
||||
|
||||
zombie_debris = GetEntArray( "zombie_debris", "targetname" );
|
||||
|
||||
if ( isDefined( zombie_debris ) && zombie_debris.size > 0 )
|
||||
{
|
||||
for ( i = 0; i < zombie_debris.size; i++ )
|
||||
{
|
||||
obj = add_possible_bot_objective( "debris", zombie_debris[ i ], true );
|
||||
}
|
||||
level thread watch_debris_objectives( zombie_debris );
|
||||
}
|
||||
|
||||
vending_upgrade_trigger = GetEntArray("zombie_vending_upgrade", "targetname");
|
||||
|
||||
if ( isDefined( vending_upgrade_trigger ) && vending_upgrade_trigger.size > 0 )
|
||||
{
|
||||
for ( i = 0; i < vending_upgrade_trigger.size; i++ )
|
||||
{
|
||||
obj = add_possible_bot_objective( "packapunch", vending_upgrade_trigger[ i ], false );
|
||||
model = getEnt( vending_triggers[ i ].target, "targetname" );
|
||||
vending_upgrade_trigger[ i ].bot_use_node = model get_angle_offset_node( getDvarInt( "packapunch_node_forward_size" ), ( 0, getDvarInt( "packapunch_node_angle" ), 0 ), ( 0, 0, getDvarInt( "packapunch_node_vertical_offset" ) ) );
|
||||
model thread packapunch_debug();
|
||||
}
|
||||
}
|
||||
|
||||
master_switch = getent("power_switch","targetname");
|
||||
if ( !isDefined( master_switch ) )
|
||||
{
|
||||
master_switch = getent("master_switch","targetname");
|
||||
}
|
||||
if ( isDefined( master_switch ) )
|
||||
{
|
||||
obj = add_possible_bot_objective( "power", master_switch, false );
|
||||
master_switch.bot_use_node = master_switch get_angle_offset_node( getDvarInt( "power_node_forward_size" ), ( 0, getDvarInt( "power_node_angle" ), 0 ), ( 0, 0, getDvarInt( "power_node_vertical_offset" ) ) );
|
||||
//model thread power_debug();
|
||||
}
|
||||
|
||||
if ( isDefined( level.chests ) && level.chests.size > 0 )
|
||||
{
|
||||
level thread watch_magicbox_objectives();
|
||||
}
|
||||
|
||||
//maps\bots\script_objectives\_obj_trackers;
|
||||
level thread store_powerups_dropped();
|
||||
level thread watch_for_downed_players();
|
||||
}
|
||||
|
||||
watch_power_objective( power_switch )
|
||||
{
|
||||
while ( !isDefined( level.flag ) && !isDefined( level.flag[ "power_on" ] ) )
|
||||
{
|
||||
wait 0.05;
|
||||
}
|
||||
players = getPlayers();
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[ i ];
|
||||
if ( player bot_get_objective() == "power" )
|
||||
{
|
||||
player.sucessfully_activated_power = true;
|
||||
}
|
||||
}
|
||||
waittillframeend;
|
||||
free_bot_objective( "power", power_switch );
|
||||
}
|
||||
|
||||
watch_door_objectives( zombie_doors )
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
for ( doors_opened_count = 0; doors_opened_count < zombie_doors.size; doors_opened_count++ )
|
||||
{
|
||||
level waittill( "door_opened", door, player );
|
||||
free_bot_objective( "door", door );
|
||||
}
|
||||
}
|
||||
|
||||
watch_debris_objectives( zombie_debris )
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
for ( debris_opened_count = 0; debris_opened_count < zombie_debris.size; debris_opened_count++ )
|
||||
{
|
||||
level waittill( "debris_opened", debris, player );
|
||||
free_bot_objective( "debris", debris );
|
||||
}
|
||||
}
|
||||
|
||||
store_powerups_dropped()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
level thread free_powerups_dropped();
|
||||
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "powerup_dropped", powerup );
|
||||
waittillframeend;
|
||||
if ( !isDefined( powerup ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
obj = add_possible_bot_objective( "powerup", powerup, true );
|
||||
}
|
||||
}
|
||||
|
||||
free_powerups_dropped()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "powerup_freed", powerup );
|
||||
id = powerup getEntityNumber();
|
||||
waittillframeend;
|
||||
free_bot_objective( "powerup", powerup, id );
|
||||
}
|
||||
}
|
||||
|
||||
watch_for_downed_players()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "player_entered_laststand", player );
|
||||
if ( !isDefined( player ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
obj = add_possible_bot_objective( "revive", player, true );
|
||||
obj.accessible = true;
|
||||
player thread free_revive_objective_when_needed();
|
||||
}
|
||||
}
|
||||
|
||||
free_revive_objective_when_needed()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
id = self getEntityNumber();
|
||||
self waittill_any( "disconnect", "zombified", "player_revived" );
|
||||
|
||||
waittillframeend;
|
||||
|
||||
free_bot_objective( "revive", self, id );
|
||||
}
|
||||
|
||||
watch_magicbox_objectives()
|
||||
{
|
||||
level endon( "end_game" );
|
||||
|
||||
level waittill( "connected", player );
|
||||
|
||||
cur_magicbox = maps\so\zm_common\_zm_magicbox::get_active_magicbox();
|
||||
add_possible_bot_objective( "magicbox", cur_magicbox, true );
|
||||
lid = cur_magicbox maps\so\zm_common\_zm_magicbox::get_chest_pieces()[ 1 ];
|
||||
cur_magicbox.bot_use_node = lid get_angle_offset_node( getDvarInt( "magicbox_node_forward_size" ), ( 0, getDvarInt( "magicbox_node_angle" ), 0 ), ( 0, 0, getDvarInt( "magicbox_node_vertical_offset" ) ) );
|
||||
|
||||
cur_magicbox thread magicbox_debug();
|
||||
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "magicbox_teddy_bear", old_magicbox );
|
||||
waittillframeend;
|
||||
free_bot_objective( "magicbox", old_magicbox );
|
||||
level waittill( "new_magicbox", new_magicbox );
|
||||
add_possible_bot_objective( "magicbox", new_magicbox, true );
|
||||
lid = new_magicbox maps\so\zm_common\_zm_magicbox::get_chest_pieces()[ 1 ];
|
||||
new_magicbox.bot_use_node = lid get_angle_offset_node( getDvarInt( "magicbox_node_forward_size" ), ( 0, getDvarInt( "magicbox_node_angle" ), 0 ), ( 0, 0, getDvarInt( "magicbox_node_vertical_offset" ) ) );
|
||||
new_magicbox thread magicbox_debug();
|
||||
}
|
||||
}
|
||||
|
||||
magicbox_debug()
|
||||
{
|
||||
self notify( "magicbox_debug" );
|
||||
self endon( "magicbox_debug");
|
||||
level endon( "magicbox_teddy_bear" );
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) == 0 && getDvarInt( "bot_obj_debug_perk" ) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( true )
|
||||
{
|
||||
lid = self maps\so\zm_common\_zm_magicbox::get_chest_pieces()[ 1 ];
|
||||
node = lid get_angle_offset_node( getDvarInt( "magicbox_node_forward_size" ), ( 0, getDvarInt( "magicbox_node_angle" ), 0 ), ( 0, 0, getDvarInt( "magicbox_node_vertical_offset" ) ) );
|
||||
self.bot_use_node = node;
|
||||
line( self.origin, node, ( 1.0, 1.0, 1.0 ) );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
perk_debug()
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) == 0 && getDvarInt( "bot_obj_debug_perk" ) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( true )
|
||||
{
|
||||
node = self get_angle_offset_node( getDvarInt( "perk_node_forward_size" ), ( 0, getDvarInt( "perk_node_angle" ), 0 ), ( 0, 0, getDvarInt( "perk_node_vertical_offset" ) ) );
|
||||
self.bot_use_node = node;
|
||||
line( self.origin, node, ( 1.0, 1.0, 1.0 ) );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
wallbuy_debug()
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) == 0 && getDvarInt( "bot_obj_debug_wallbuy" ) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( true )
|
||||
{
|
||||
node = self get_angle_offset_node( getDvarInt( "wallbuy_node_forward_size" ), ( 0, getDvarInt( "wallbuy_node_angle" ), 0 ), ( 0, 0, getDvarInt( "wallbuy_node_vertical_offset" ) ) );
|
||||
self.bot_use_node = node;
|
||||
line( self.origin, node, ( 1.0, 1.0, 1.0 ) );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
packapunch_debug()
|
||||
{
|
||||
if ( getDvarInt( "bot_obj_debug_all" ) == 0 && getDvarInt( "bot_obj_debug_packapunch" ) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( true )
|
||||
{
|
||||
node = self get_angle_offset_node( getDvarInt( "packapunch_node_forward_size" ), ( 0, getDvarInt( "packapunch_node_angle" ), 0 ), ( 0, 0, getDvarInt( "packapunch_node_vertical_offset" ) ) );
|
||||
self.bot_use_node = node;
|
||||
line( self.origin, node, ( 1.0, 1.0, 1.0 ) );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
bot_on_powerup_grab( powerup )
|
||||
{
|
||||
self bot_objective_print( "powerup", powerup getEntityNumber(), "bot_on_powerup_grab", "Bot <" + self.playername + "> grabbed powerup" );
|
||||
self.successfully_grabbed_powerup = true;
|
||||
}
|
||||
|
||||
bot_on_revive_success( revivee )
|
||||
{
|
||||
self bot_objective_print( "revive", revivee getEntityNumber(), "bot_on_revive_success", "Bot <" + self.playername + "> revived <" + revivee.playername + ">" );
|
||||
self.successfully_revived_player = true;
|
||||
}
|
||||
|
||||
bot_on_magicbox_weapon_grab( magicbox, weapon )
|
||||
{
|
||||
self bot_objective_print( "magicbox", magicbox getEntityNumber(), "bot_on_magicbox_weapon_grab", "Bot <" + self.playername + "> grabbed <" + weapon + "> from the box" );
|
||||
self.successfully_grabbed_magicbox_weapon = true;
|
||||
self.last_magicbox_purchase_time = getTime();
|
||||
}
|
||||
|
||||
bot_on_perk_purchase( trigger, perk )
|
||||
{
|
||||
self bot_objective_print( "perk", trigger getEntityNumber(), "bot_on_perk_purchase", "Bot <" + self.playername + "> purchased <" + perk + ">" );
|
||||
self.successfully_bought_perk = true;
|
||||
}
|
||||
|
||||
bot_on_door_purchase_func( door )
|
||||
{
|
||||
self bot_objective_print( "door", door getEntityNumber(), "bot_on_door_purchase_func", "Bot <" + self.playername + "> purchased door" );
|
||||
self.successfully_bought_door = true;
|
||||
}
|
||||
|
||||
bot_on_debris_purchase_func( debris )
|
||||
{
|
||||
self bot_objective_print( "debris", debris getEntityNumber(), "bot_on_debris_purchase_func", "Bot <" + self.playername + "> purchased debris" );
|
||||
self.successfully_bought_debris = true;
|
||||
}
|
||||
|
||||
bot_on_wallbuy_purchase_func( trigger, weapon )
|
||||
{
|
||||
self bot_objective_print( "wallbuy", trigger getEntityNumber(), "bot_on_wallbuy_purchase_func", "Bot <" + self.playername + "> purchased wallbuy <" + weapon + ">" );
|
||||
self.successfully_bought_wallbuy = true;
|
||||
self.last_wallbuy_purchase_time = getTime();
|
||||
}
|
||||
|
||||
bot_on_wallbuy_ammo_purchase_func( trigger, weapon )
|
||||
{
|
||||
self bot_objective_print( "wallbuyammo", trigger getEntityNumber(), "bot_on_wallbuy_ammo_purchase_func", "Bot <" + self.playername + "> purchased wallbuy ammo <" + weapon + ">" );
|
||||
self.successfully_bought_wallbuy_ammo = true;
|
||||
}
|
@ -1,234 +0,0 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
|
||||
/*
|
||||
Checks whether the path generated by the ASTAR path finding is inaccessible
|
||||
*/
|
||||
GetPathIsInaccessible( to, best_effort )
|
||||
{
|
||||
if ( isDefined( best_effort ) )
|
||||
{
|
||||
path = generatePath( self.origin, to, self.team, level.bot_allowed_negotiation_links, best_effort );
|
||||
}
|
||||
else
|
||||
{
|
||||
path = generatePath( self.origin, to, self.team, level.bot_allowed_negotiation_links );
|
||||
}
|
||||
return !isDefined( path ) || ( path.size <= 0) ;
|
||||
}
|
||||
|
||||
swap_array_index( array, index1, index2 )
|
||||
{
|
||||
temp = array[ index1 ];
|
||||
array[ index1 ] = array[ index2 ];
|
||||
array[ index2 ] = temp;
|
||||
return array;
|
||||
}
|
||||
|
||||
quickSort(array, compare_func, compare_func_arg1)
|
||||
{
|
||||
return quickSortMid( array, 0, array.size - 1, compare_func, compare_func_arg1 );
|
||||
}
|
||||
|
||||
/*
|
||||
Quicksort algorithm copied from T7 modified for T4
|
||||
*/
|
||||
quickSortMid( array, start, end, compare_func, compare_func_arg1 )
|
||||
{
|
||||
i = start;
|
||||
k = end;
|
||||
|
||||
if(!IsDefined(compare_func))
|
||||
compare_func = ::quicksort_compare;
|
||||
|
||||
if (end - start >= 1)
|
||||
{
|
||||
pivot = array[start];
|
||||
|
||||
while (k > i)
|
||||
{
|
||||
while ( [[ compare_func ]](array[i], pivot, compare_func_arg1) && i <= end && k > i)
|
||||
i++;
|
||||
while ( ![[ compare_func ]](array[k], pivot, compare_func_arg1) && k >= start && k >= i)
|
||||
k--;
|
||||
if (k > i)
|
||||
array = swap_array_index(array, i, k);
|
||||
}
|
||||
array = swap_array_index(array, start, k);
|
||||
array = quickSortMid(array, start, k - 1, compare_func);
|
||||
array = quickSortMid(array, k + 1, end, compare_func);
|
||||
}
|
||||
else
|
||||
return array;
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
quicksort_compare(left, right, compare_func_arg1)
|
||||
{
|
||||
return left <= right;
|
||||
}
|
||||
|
||||
quicksort_compare_priority_field(left, right, compare_func_arg1)
|
||||
{
|
||||
return left.priority <= right.priority;
|
||||
}
|
||||
|
||||
quicksort_compare_pers_value_highest_to_lowest( left, right, compare_func_arg1 )
|
||||
{
|
||||
return left.pers[ compare_func_arg1 ] <= right.pers[ compare_func_arg1 ];
|
||||
}
|
||||
|
||||
quicksort_compare_pers_value_lowest_to_highest( left, right, compare_func_arg1 )
|
||||
{
|
||||
return left.pers[ compare_func_arg1 ] >= right.pers[ compare_func_arg1 ];
|
||||
}
|
||||
|
||||
assign_priority_to_powerup( powerup )
|
||||
{
|
||||
if ( !isDefined( powerup ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
priority = 0;
|
||||
powerup_is_max_ammo = false;
|
||||
switch ( powerup.powerup_name )
|
||||
{
|
||||
case "zombie_blood":
|
||||
case "insta_kill":
|
||||
case "nuke":
|
||||
priority += 2;
|
||||
break;
|
||||
case "full_ammo":
|
||||
powerup_is_max_ammo = true;
|
||||
priority += 1;
|
||||
break;
|
||||
case "double_points":
|
||||
case "fire_sale":
|
||||
case "carpenter":
|
||||
case "free_perk":
|
||||
priority += 1;
|
||||
break;
|
||||
default:
|
||||
priority += 0;
|
||||
break;
|
||||
}
|
||||
if ( powerup_is_max_ammo )
|
||||
{
|
||||
LOW_AMMO_THRESHOLD = 0.3;
|
||||
|
||||
players = getPlayers();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
weapons = players[ i ] getWeaponsListPrimaries();
|
||||
for ( j = 0; j < weapons.size; j++ )
|
||||
{
|
||||
if ( players[ i ] getWeaponAmmoStock( weapons[ j ] ) <= int( weaponmaxammo( weapons[ j ] ) * LOW_AMMO_THRESHOLD ) )
|
||||
{
|
||||
priority += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( priority > 3 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( maps\_laststand::player_any_player_in_laststand() )
|
||||
{
|
||||
switch ( powerup.powerup_name )
|
||||
{
|
||||
case "zombie_blood":
|
||||
case "insta_kill":
|
||||
case "nuke":
|
||||
priority += 1;
|
||||
break;
|
||||
case "full_ammo":
|
||||
priority += 0;
|
||||
break;
|
||||
case "double_points":
|
||||
case "fire_sale":
|
||||
case "carpenter":
|
||||
case "free_perk":
|
||||
priority -= 1;
|
||||
break;
|
||||
default:
|
||||
priority += 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( powerup.time_left_until_timeout < 10.0 )
|
||||
{
|
||||
priority += 1;
|
||||
}
|
||||
if ( priority < 0 )
|
||||
{
|
||||
priority = 0;
|
||||
}
|
||||
powerup.priority = priority;
|
||||
}
|
||||
|
||||
sort_array_by_priority_field( array, item )
|
||||
{
|
||||
if ( isDefined( item ) )
|
||||
{
|
||||
array[ array.size ] = item;
|
||||
}
|
||||
|
||||
array = quickSort( array, ::quicksort_compare_priority_field, undefined );
|
||||
return array;
|
||||
}
|
||||
|
||||
get_players_sorted_by_highest_pers_value( pers_name )
|
||||
{
|
||||
players = getPlayers();
|
||||
|
||||
if ( !isDefined( players[ 0 ].pers[ pers_name ] ) )
|
||||
{
|
||||
assertMsg( "Uninitialized pers value: " + pers_name );
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return quickSort( players, ::quicksort_compare_pers_value_highest_to_lowest, pers_name );
|
||||
}
|
||||
|
||||
get_players_sorted_by_lowest_pers_value( pers_name )
|
||||
{
|
||||
players = getPlayers();
|
||||
|
||||
if ( !isDefined( players[ 0 ].pers[ pers_name ] ) )
|
||||
{
|
||||
assertMsg( "Uninitialized pers value: " + pers_name );
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return quickSort( players, ::quicksort_compare_pers_value_lowest_to_highest, pers_name );
|
||||
}
|
||||
|
||||
get_path_dist( start, end )
|
||||
{
|
||||
path = generatePath( start, end, self.team, level.bot_allowed_negotiation_links, 192.0 );
|
||||
if ( !isDefined( path ) || path.size <= 0 )
|
||||
{
|
||||
return 9999999;
|
||||
}
|
||||
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;
|
||||
}
|
@ -5,57 +5,4 @@
|
||||
init()
|
||||
{
|
||||
level thread maps\bots\_bot::init();
|
||||
|
||||
if ( getDvar( "player_debug_bots" ) == "" )
|
||||
setDvar( "player_debug_bots", 1 );
|
||||
|
||||
thread test_bot_pathing();
|
||||
}
|
||||
|
||||
test_bot_pathing()
|
||||
{
|
||||
if ( !getDvarInt( "player_debug_bots" ) )
|
||||
return;
|
||||
|
||||
player = undefined;
|
||||
|
||||
while ( !isDefined( player ) || player is_bot() )
|
||||
level waittill( "connected", player );
|
||||
|
||||
PrintConsole( "player has CMDS! " + player.playername );
|
||||
player endon( "disconnect" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( !player UseButtonPressed() )
|
||||
continue;
|
||||
|
||||
bots = getBotArray();
|
||||
|
||||
if ( player AttackButtonPressed() )
|
||||
{
|
||||
player iprintln( "Telling bots to go to you" );
|
||||
|
||||
for ( i = 0; i < bots.size; i++ )
|
||||
{
|
||||
bots[i] SetScriptGoal( player.origin );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player AdsButtonPressed() )
|
||||
{
|
||||
player iprintln( "Telling bots to ROAM" );
|
||||
|
||||
for ( i = 0; i < bots.size; i++ )
|
||||
{
|
||||
bots[i] ClearScriptGoal();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,395 +0,0 @@
|
||||
#include maps\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
main()
|
||||
{
|
||||
replaceFunc( GetFunction( "maps/_utility", "wait_network_frame" ), ::wait_network_frame_func );
|
||||
}
|
||||
|
||||
wait_network_frame_func()
|
||||
{
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
level thread print_new_rounds();
|
||||
level thread onPlayerConnect();
|
||||
level thread spitOutTime();
|
||||
|
||||
if ( getDvar( "killtest_bot_debug" ) == "" )
|
||||
setDvar( "killtest_bot_debug", 0 );
|
||||
|
||||
level thread addBot();
|
||||
|
||||
level thread setupcallbacks();
|
||||
}
|
||||
|
||||
setupcallbacks()
|
||||
{
|
||||
wait 1;
|
||||
|
||||
level.killtestoldoverrideplayerdamage = level.callbackPlayerDamage;
|
||||
level.callbackPlayerDamage = ::killtestoverrideplayerdamage;
|
||||
|
||||
level.killtestoldoverrideactordamage = level.callbackActorDamage;
|
||||
level.callbackActorDamage = ::killtestoverrideactordamage;
|
||||
}
|
||||
|
||||
killtestoverrideactordamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset )
|
||||
{
|
||||
setDvar( "aa_player_damage_dealt", 0 );
|
||||
|
||||
if ( isPlayer( eAttacker ) && eAttacker isBot() && getDvarInt( "bots_t8_mode" ) )
|
||||
{
|
||||
iDamage += int( self.maxhealth * randomFloatRange( 0.25, 1.25 ) );
|
||||
}
|
||||
|
||||
self [[level.killtestoldoverrideactordamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset );
|
||||
}
|
||||
|
||||
killtestoverrideplayerdamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
|
||||
{
|
||||
if ( self isBot() && getDvarInt( "bots_t8_mode" ) )
|
||||
{
|
||||
iDamage = int( iDamage * 0.1 );
|
||||
}
|
||||
|
||||
//PrintConsole( self GetPlayerName() + " took " + iDamage );
|
||||
|
||||
self [[level.killtestoldoverrideplayerdamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
|
||||
}
|
||||
|
||||
print_new_rounds()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
level waittill( "new_zombie_round", round_num );
|
||||
|
||||
PrintConsole( "New zombie round!: " + round_num );
|
||||
}
|
||||
}
|
||||
|
||||
spitOutTime()
|
||||
{
|
||||
startTime = GetTime();
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 60;
|
||||
PrintConsole( "TIME: " + ( GetTime() - startTime ) );
|
||||
}
|
||||
}
|
||||
|
||||
botMoveTo( to )
|
||||
{
|
||||
self.moveTo = to;
|
||||
}
|
||||
|
||||
walk_to_player()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
bot_allowed_negotiation_links = [];
|
||||
bot_allowed_negotiation_links[ bot_allowed_negotiation_links.size ] = "zombie_jump_down_72";
|
||||
bot_allowed_negotiation_links[ bot_allowed_negotiation_links.size ] = "zombie_jump_down_96";
|
||||
bot_allowed_negotiation_links[ bot_allowed_negotiation_links.size ] = "zombie_jump_down_120";
|
||||
bot_allowed_negotiation_links[ bot_allowed_negotiation_links.size ] = "zombie_jump_down_127";
|
||||
bot_allowed_negotiation_links[ bot_allowed_negotiation_links.size ] = "zombie_jump_down_184";
|
||||
bot_allowed_negotiation_links[ bot_allowed_negotiation_links.size ] = "zombie_jump_down_190";
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
// stop bot moving
|
||||
self botMoveTo( self.origin );
|
||||
|
||||
// get a player
|
||||
non_bot_player = undefined;
|
||||
players = getPlayers();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( player isBot() )
|
||||
continue;
|
||||
|
||||
non_bot_player = player;
|
||||
}
|
||||
|
||||
goal = ( 0, 0, 50 );
|
||||
|
||||
if ( isdefined( non_bot_player ) )
|
||||
{
|
||||
goal = non_bot_player.origin;
|
||||
}
|
||||
|
||||
// generate a path to the player
|
||||
path = generatePath( self.origin, goal, self.team, bot_allowed_negotiation_links );
|
||||
|
||||
if ( !isdefined( path ) || !path.size )
|
||||
continue;
|
||||
|
||||
// traverse each node in the path
|
||||
for ( i = 0; i < path.size; i++ )
|
||||
{
|
||||
path_node = path[i];
|
||||
|
||||
while ( distance2d( self.origin, path_node.origin ) >= 7 )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
self botMoveTo( path_node.origin );
|
||||
}
|
||||
}
|
||||
|
||||
// blindly go to player after traversing each path node
|
||||
while ( distance2d( self.origin, goal ) >= 10 )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
self botMoveTo( goal );
|
||||
}
|
||||
|
||||
// done
|
||||
}
|
||||
}
|
||||
|
||||
do_move()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
waittillframeend;
|
||||
|
||||
move_To = self.moveTo;
|
||||
angles = self GetPlayerAngles();
|
||||
dir = ( 0, 0, 0 );
|
||||
|
||||
if ( DistanceSquared( self.origin, move_To ) >= 49 )
|
||||
{
|
||||
cosa = cos( 0 - angles[1] );
|
||||
sina = sin( 0 - angles[1] );
|
||||
|
||||
// get the direction
|
||||
dir = move_To - self.origin;
|
||||
|
||||
// rotate our direction according to our angles
|
||||
dir = ( dir[0] * cosa - dir[1] * sina,
|
||||
dir[0] * sina + dir[1] * cosa,
|
||||
0 );
|
||||
|
||||
// make the length 127
|
||||
dir = VectorNormalize( dir ) * 127;
|
||||
|
||||
// invert the second component as the engine requires this
|
||||
dir = ( dir[0], 0 - dir[1], 0 );
|
||||
}
|
||||
|
||||
self botMovement( int( dir[0] ), int( dir[1] ) );
|
||||
}
|
||||
}
|
||||
|
||||
addBot()
|
||||
{
|
||||
if ( !getDvarInt( "killtest_bot_debug" ) )
|
||||
return;
|
||||
|
||||
// level waittill("connected", player);
|
||||
wait 5;
|
||||
|
||||
guy = addTestClient();
|
||||
|
||||
if ( !isDefined( guy ) )
|
||||
return;
|
||||
|
||||
guy endon( "disconnect" );
|
||||
|
||||
guy botStop();
|
||||
|
||||
wait 5;
|
||||
|
||||
if ( !isDefined( guy ) )
|
||||
return;
|
||||
|
||||
guy.killingAll = true;
|
||||
weapon = "ray_gun";
|
||||
guy giveWeapon( weapon ); // ptrs41_zombie zombie_doublebarrel
|
||||
guy switchToWeapon( weapon ); // colt_dirty_harry
|
||||
|
||||
guy thread walk_to_player();
|
||||
guy thread do_move();
|
||||
|
||||
while ( isDefined( guy ) )
|
||||
{
|
||||
if ( isDefined( level.isPlayerDead ) && [[level.isPlayerDead]]( guy ) )
|
||||
{
|
||||
wait 2.5;
|
||||
guy removeTestClient();
|
||||
break;
|
||||
}
|
||||
|
||||
guy giveMaxAmmo( weapon );
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread onSpawned();
|
||||
}
|
||||
}
|
||||
|
||||
onSpawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self.killingAll = false;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self thread killAllZombsWithBullets();
|
||||
self thread watchKillAllButton();
|
||||
|
||||
if ( !self isBot() )
|
||||
self thread moveBot();
|
||||
}
|
||||
}
|
||||
|
||||
EyeTraceForward()
|
||||
{
|
||||
origin = self getTagOrigin( "tag_eye" );
|
||||
angles = self GetPlayerAngles();
|
||||
forward = AnglesToForward( angles );
|
||||
endpoint = origin + forward * 15000;
|
||||
|
||||
res = BulletTrace( origin, endpoint, false, undefined );
|
||||
|
||||
return res["position"];
|
||||
}
|
||||
|
||||
moveBot()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self MeleeButtonPressed() && self AdsButtonPressed() )
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( !player isBot() )
|
||||
continue;
|
||||
|
||||
if ( self AttackButtonPressed() && isDefined( player.bot.moveTo ) )
|
||||
player SetOrigin( player.bot.moveTo );
|
||||
else
|
||||
player SetOrigin( self EyeTraceForward() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchKillAllButton()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
wait 5;
|
||||
|
||||
self notifyOnPlayerCommand( "+smoke", "toggle_killall" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "toggle_killall" );
|
||||
|
||||
self.killingAll = !self.killingAll;
|
||||
self iPrintLn( "Killing all: " + self.killingAll );
|
||||
}
|
||||
}
|
||||
|
||||
do_magic_bullets()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
myeye = self getTagOrigin( "tag_eye" );
|
||||
|
||||
if ( !isDefined( myeye ) )
|
||||
return;
|
||||
|
||||
zombies = GetAiSpeciesArray( "axis", "all" );
|
||||
weap = self GetCurrentWeapon();
|
||||
|
||||
for ( i = 0; i < zombies.size; i++ )
|
||||
{
|
||||
zombie = zombies[i];
|
||||
|
||||
if ( isDefined( zombie ) )
|
||||
{
|
||||
if ( getDvarInt( "killtest_overflow_health_test" ) )
|
||||
{
|
||||
if ( zombie.maxhealth != 2147483647 )
|
||||
{
|
||||
zombie.maxhealth = 2147483647;
|
||||
zombie.health = zombie.maxhealth;
|
||||
}
|
||||
else
|
||||
{
|
||||
zombie DoDamage( zombie.health + 666, zombie.origin, self, 0, "headshot" );
|
||||
}
|
||||
}
|
||||
|
||||
hit_loc = undefined;
|
||||
|
||||
if ( randomint( 2 ) )
|
||||
hit_loc = zombie getTagOrigin( "j_head" );
|
||||
else
|
||||
hit_loc = zombie getTagOrigin( "j_spine4" );
|
||||
|
||||
if ( isDefined( hit_loc ) )
|
||||
{
|
||||
if ( sighttracepassed( myeye, hit_loc, false, self ) )
|
||||
{
|
||||
magicbullet( weap, myeye, hit_loc, self );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
killAllZombsWithBullets()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( !self.killingAll )
|
||||
continue;
|
||||
|
||||
self thread do_magic_bullets();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user