diff --git a/README.md b/README.md
index ffc2f26..4f2a897 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Bot Warfare is a GSC mod for the [CoD4x project](https://github.com/callofduty4x
It aims to add playable AI to the multiplayer games of CoD4.
-You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfare/downloads/cod4x-bot-warfare-latest) and the CoD4x.me post [here](https://cod4x.me/index.php?/forums/topic/3116-release-bot-warfare/).
+You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfare/downloads/cod4x-bot-warfare-latest) and the CoD4x forum post [here](https://cod4x.ovh/index.php?/forums/topic/3116-release-bot-warfare/).
## Important to public dedicated servers
The ```bots_main_firstIsHost``` DVAR is enabled by default!
@@ -57,15 +57,15 @@ Make sure to disable this DVAR by adding ```set bots_main_firstIsHost 0``` in yo
- ... And pretty much everything you expect a Combat Training bot to have
## Installation
-Using CoD4x's extended functionality requires to use their Dedicated server, as explained [here](https://cod4x.me/index.php?/forums/topic/2047-add-cod4x-server-gsc-functions-to-the-client/).
+Using CoD4x's extended functionality requires to use their Dedicated server, as explained [here](https://cod4x.ovh/index.php?/forums/topic/2047-add-cod4x-server-gsc-functions-to-the-client/).
You can easily setup a local LAN dedicated server for you to join and play on. Have a look at [Setting up a CoD4x server]().
-0. Make sure that [CoD4x server + client](https://cod4x.me/) is installed, updated and working properly.
+0. Make sure that [CoD4x server + client](https://cod4x.ovh/) is installed, updated and working properly.
- Download the [latest release](https://github.com/ineedbots/cod4x_bot_warfare/releases) of Bot Warfare.
1. Locate your CoD4x server install folder.
2. Move the files/folders found in 'Add to root of CoD4x server' from the Bot Warfare release archive you downloaded to the root of your CoD4x server folder.
- - The folder/file structure should follow as '.CoD4x server folder\main_shared\maps\mp\bots\_bot.gsc'.
+ - The folder/file structure should follow as `.CoD4x server folder\main_shared\maps\mp\bots\_bot.gsc`.
3. The mod is now installed, now start your server, change the DVARs and start a map.
4. Now start your CoD4x client and connect to your server ('connect 127.0.0.1' in the console most likely) and play!
@@ -88,6 +88,7 @@ You can easily setup a local LAN dedicated server for you to join and play on. H
| bots_main_menu | Enable the in-game menu for hosts. | true |
| bots_main_debug | Enable the in-game waypoint editor. | false |
| bots_main_kickBotsAtEnd | Kick the bots at the end of a match. | false |
+| bots_main_chat | The rate bots will chat at, set to 0 to disable. | 1.0 |
| bots_manage_add | Amount of bots to add to the game, once bots are added, resets back to `0`. | 0 |
| bots_manage_fill | Amount of players/bots (look at `bots_manage_fill_mode`) to maintain in the match. | 0 |
| bots_manage_fill_mode | `bots_manage_fill` players/bots counting method.
- `0` - counts both players and bots.
- `1` - only counts bots.
| 0 |
@@ -121,6 +122,17 @@ You can easily setup a local LAN dedicated server for you to join and play on. H
## Changelog
+- v2.1.0
+ - Bot chatter system, bots_main_chat
+ - Greatly reduce script variable usage
+ - Improved bots mantling and stuck
+ - Fix some runtime errors
+ - Bots sprint more
+ - Improved bots sight on enemies
+ - Bots do random actions while waiting at an objective
+ - Improved bots from getting stuck
+ - Better bot difficulty management, bots_skill_min and bots_skill_max
+
- v2.0.1
- Reduced bots crouching
- Increased bots sprinting
diff --git a/main/waypoints b/main/waypoints
index 65a344f..c734ac7 160000
--- a/main/waypoints
+++ b/main/waypoints
@@ -1 +1 @@
-Subproject commit 65a344f95388f6d0f0704f3c4517283670bb2818
+Subproject commit c734ac790d590225e613fa3c2b10f411c29885aa
diff --git a/main_shared/maps/mp/bots/_bot.gsc b/main_shared/maps/mp/bots/_bot.gsc
index 2b8b1d8..23064a7 100644
--- a/main_shared/maps/mp/bots/_bot.gsc
+++ b/main_shared/maps/mp/bots/_bot.gsc
@@ -8,7 +8,7 @@
*/
init()
{
- level.bw_VERSION = "2.0.1";
+ level.bw_VERSION = "2.1.0";
if ( getDvar( "bots_main" ) == "" )
setDvar( "bots_main", true );
diff --git a/out/Add to root of CoD4x server/main/plugins/httpget.so b/out/Add to root of CoD4x server/main/plugins/httpget.so
new file mode 100644
index 0000000..5077dc9
Binary files /dev/null and b/out/Add to root of CoD4x server/main/plugins/httpget.so differ
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot.gsc
index 1d49140..23064a7 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot.gsc
@@ -8,96 +8,134 @@
*/
init()
{
- level.bw_VERSION = "2.0.1";
+ level.bw_VERSION = "2.1.0";
- if(getDvar("bots_main") == "")
- setDvar("bots_main", true);
+ if ( getDvar( "bots_main" ) == "" )
+ setDvar( "bots_main", true );
- if (!getDvarInt("bots_main"))
+ if ( !getDvarInt( "bots_main" ) )
return;
thread load_waypoints();
cac_init_patch();
thread hook_callbacks();
- if(getDvar("bots_main_GUIDs") == "")
- setDvar("bots_main_GUIDs", "");//guids of players who will be given host powers, comma seperated
- if(getDvar("bots_main_firstIsHost") == "")
- setDvar("bots_main_firstIsHost", true);//first player to connect is a host
- if(getDvar("bots_main_waitForHostTime") == "")
- setDvar("bots_main_waitForHostTime", 10.0);//how long to wait to wait for the host player
-
- if(getDvar("bots_manage_add") == "")
- setDvar("bots_manage_add", 0);//amount of bots to add to the game
- if(getDvar("bots_manage_fill") == "")
- setDvar("bots_manage_fill", 0);//amount of bots to maintain
- if(getDvar("bots_manage_fill_spec") == "")
- setDvar("bots_manage_fill_spec", true);//to count for fill if player is on spec team
- if(getDvar("bots_manage_fill_mode") == "")
- setDvar("bots_manage_fill_mode", 0);//fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1
- if(getDvar("bots_manage_fill_kick") == "")
- setDvar("bots_manage_fill_kick", false);//kick bots if too many
-
- if(getDvar("bots_team") == "")
- setDvar("bots_team", "autoassign");//which team for bots to join
- if(getDvar("bots_team_amount") == "")
- setDvar("bots_team_amount", 0);//amount of bots on axis team
- if(getDvar("bots_team_force") == "")
- setDvar("bots_team_force", false);//force bots on team
- if(getDvar("bots_team_mode") == "")
- setDvar("bots_team_mode", 0);//counts just bots when 1
-
- if(getDvar("bots_skill") == "")
- setDvar("bots_skill", 0);//0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random
- if(getDvar("bots_skill_axis_hard") == "")
- setDvar("bots_skill_axis_hard", 0);//amount of hard bots on axis team
- if(getDvar("bots_skill_axis_med") == "")
- setDvar("bots_skill_axis_med", 0);
- if(getDvar("bots_skill_allies_hard") == "")
- setDvar("bots_skill_allies_hard", 0);
- if(getDvar("bots_skill_allies_med") == "")
- setDvar("bots_skill_allies_med", 0);
-
- if(getDvar("bots_loadout_reasonable") == "")//filter out the bad 'guns' and perks
- setDvar("bots_loadout_reasonable", false);
- if(getDvar("bots_loadout_allow_op") == "")//allows jug, marty and laststand
- setDvar("bots_loadout_allow_op", true);
- if(getDvar("bots_loadout_rank") == "")// what rank the bots should be around, -1 is around the players, 0 is all random
- setDvar("bots_loadout_rank", -1);
- if(getDvar("bots_loadout_prestige") == "")// what pretige the bots will be, -1 is the players, -2 is random
- setDvar("bots_loadout_prestige", -1);
+ if ( getDvar( "bots_main_GUIDs" ) == "" )
+ setDvar( "bots_main_GUIDs", "" ); //guids of players who will be given host powers, comma seperated
- if(getDvar("bots_play_move") == "")//bots move
- setDvar("bots_play_move", true);
- if(getDvar("bots_play_knife") == "")//bots knife
- setDvar("bots_play_knife", true);
- if(getDvar("bots_play_fire") == "")//bots fire
- setDvar("bots_play_fire", true);
- if(getDvar("bots_play_nade") == "")//bots grenade
- setDvar("bots_play_nade", true);
- if(getDvar("bots_play_obj") == "")//bots play the obj
- setDvar("bots_play_obj", true);
- if(getDvar("bots_play_camp") == "")//bots camp and follow
- setDvar("bots_play_camp", true);
- if(getDvar("bots_play_jumpdrop") == "")//bots jump and dropshot
- setDvar("bots_play_jumpdrop", true);
- if(getDvar("bots_play_target_other") == "")//bot target non play ents (vehicles)
- setDvar("bots_play_target_other", true);
- if(getDvar("bots_play_killstreak") == "")//bot use killstreaks
- setDvar("bots_play_killstreak", true);
- if(getDvar("bots_play_ads") == "")//bot ads
- setDvar("bots_play_ads", true);
+ if ( getDvar( "bots_main_firstIsHost" ) == "" )
+ setDvar( "bots_main_firstIsHost", true ); //first player to connect is a host
- if(!isDefined(game["botWarfare"]))
+ if ( getDvar( "bots_main_waitForHostTime" ) == "" )
+ setDvar( "bots_main_waitForHostTime", 10.0 ); //how long to wait to wait for the host player
+
+ if ( getDvar( "bots_main_kickBotsAtEnd" ) == "" )
+ setDvar( "bots_main_kickBotsAtEnd", false ); //kicks the bots at game end
+
+ if ( getDvar( "bots_manage_add" ) == "" )
+ setDvar( "bots_manage_add", 0 ); //amount of bots to add to the game
+
+ if ( getDvar( "bots_manage_fill" ) == "" )
+ setDvar( "bots_manage_fill", 0 ); //amount of bots to maintain
+
+ if ( getDvar( "bots_manage_fill_spec" ) == "" )
+ setDvar( "bots_manage_fill_spec", true ); //to count for fill if player is on spec team
+
+ if ( getDvar( "bots_manage_fill_mode" ) == "" )
+ setDvar( "bots_manage_fill_mode", 0 ); //fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1
+
+ if ( getDvar( "bots_manage_fill_kick" ) == "" )
+ setDvar( "bots_manage_fill_kick", false ); //kick bots if too many
+
+ if ( getDvar( "bots_team" ) == "" )
+ setDvar( "bots_team", "autoassign" ); //which team for bots to join
+
+ if ( getDvar( "bots_team_amount" ) == "" )
+ setDvar( "bots_team_amount", 0 ); //amount of bots on axis team
+
+ if ( getDvar( "bots_team_force" ) == "" )
+ setDvar( "bots_team_force", false ); //force bots on team
+
+ if ( getDvar( "bots_team_mode" ) == "" )
+ setDvar( "bots_team_mode", 0 ); //counts just bots when 1
+
+ if ( getDvar( "bots_skill" ) == "" )
+ setDvar( "bots_skill", 0 ); //0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random
+
+ if ( getDvar( "bots_skill_axis_hard" ) == "" )
+ setDvar( "bots_skill_axis_hard", 0 ); //amount of hard bots on axis team
+
+ if ( getDvar( "bots_skill_axis_med" ) == "" )
+ setDvar( "bots_skill_axis_med", 0 );
+
+ if ( getDvar( "bots_skill_allies_hard" ) == "" )
+ setDvar( "bots_skill_allies_hard", 0 );
+
+ if ( getDvar( "bots_skill_allies_med" ) == "" )
+ setDvar( "bots_skill_allies_med", 0 );
+
+ if ( getDvar( "bots_skill_min" ) == "" )
+ setDvar( "bots_skill_min", 1 );
+
+ if ( getDvar( "bots_skill_max" ) == "" )
+ setDvar( "bots_skill_max", 7 );
+
+ if ( getDvar( "bots_loadout_reasonable" ) == "" ) //filter out the bad 'guns' and perks
+ setDvar( "bots_loadout_reasonable", false );
+
+ if ( getDvar( "bots_loadout_allow_op" ) == "" ) //allows jug, marty and laststand
+ setDvar( "bots_loadout_allow_op", true );
+
+ if ( getDvar( "bots_loadout_rank" ) == "" ) // what rank the bots should be around, -1 is around the players, 0 is all random
+ setDvar( "bots_loadout_rank", -1 );
+
+ if ( getDvar( "bots_loadout_prestige" ) == "" ) // what pretige the bots will be, -1 is the players, -2 is random
+ setDvar( "bots_loadout_prestige", -1 );
+
+ if ( getDvar( "bots_play_move" ) == "" ) //bots move
+ setDvar( "bots_play_move", true );
+
+ if ( getDvar( "bots_play_knife" ) == "" ) //bots knife
+ setDvar( "bots_play_knife", true );
+
+ if ( getDvar( "bots_play_fire" ) == "" ) //bots fire
+ setDvar( "bots_play_fire", true );
+
+ if ( getDvar( "bots_play_nade" ) == "" ) //bots grenade
+ setDvar( "bots_play_nade", true );
+
+ if ( getDvar( "bots_play_obj" ) == "" ) //bots play the obj
+ setDvar( "bots_play_obj", true );
+
+ if ( getDvar( "bots_play_camp" ) == "" ) //bots camp and follow
+ setDvar( "bots_play_camp", true );
+
+ if ( getDvar( "bots_play_jumpdrop" ) == "" ) //bots jump and dropshot
+ setDvar( "bots_play_jumpdrop", true );
+
+ if ( getDvar( "bots_play_target_other" ) == "" ) //bot target non play ents (vehicles)
+ setDvar( "bots_play_target_other", true );
+
+ if ( getDvar( "bots_play_killstreak" ) == "" ) //bot use killstreaks
+ setDvar( "bots_play_killstreak", true );
+
+ if ( getDvar( "bots_play_ads" ) == "" ) //bot ads
+ setDvar( "bots_play_ads", true );
+
+ if ( getDvar( "bots_play_aim" ) == "" )
+ setDvar( "bots_play_aim", true );
+
+ if ( !isDefined( game["botWarfare"] ) )
game["botWarfare"] = true;
-
+
level.defuseObject = undefined;
level.bots_smokeList = List();
level.tbl_PerkData[0]["reference_full"] = true;
- for(h = 1; h < 6; h++)
- for(i = 0; i < 3; i++)
- level.default_perk["CLASS_CUSTOM"+h][i] = "specialty_null";
-
+
+ for ( h = 1; h < 6; h++ )
+ for ( i = 0; i < 3; i++ )
+ level.default_perk["CLASS_CUSTOM" + h][i] = "specialty_null";
+
level.bots_minSprintDistance = 315;
level.bots_minSprintDistance *= level.bots_minSprintDistance;
level.bots_minGrenadeDistance = 256;
@@ -113,11 +151,11 @@ init()
level.bots_maxShotgunDistance = 500;
level.bots_maxShotgunDistance *= level.bots_maxShotgunDistance;
level.bots_listenDist = 100;
-
+
level.smokeRadius = 255;
level.bots = [];
-
+
level.bots_fullautoguns = [];
level.bots_fullautoguns["rpd"] = true;
level.bots_fullautoguns["m60e4"] = true;
@@ -131,12 +169,12 @@ init()
level.bots_fullautoguns["m4"] = true;
level.bots_fullautoguns["ak47"] = true;
level.bots_fullautoguns["mp44"] = true;
-
+
level thread fixGamemodes();
level thread onUAVAlliesUpdate();
level thread onUAVAxisUpdate();
level thread chopperWatch();
-
+
level thread onPlayerConnect();
level thread handleBots();
@@ -151,39 +189,52 @@ handleBots()
level thread teamBots();
level thread diffBots();
level addBots();
-
- while(!level.intermission)
+
+ while ( !level.intermission )
wait 0.05;
-
- setDvar("bots_manage_add", getBotArray().size);
+
+ setDvar( "bots_manage_add", getBotArray().size );
+
+ if ( !getDvarInt( "bots_main_kickBotsAtEnd" ) )
+ return;
+
+ removeAllTestClients();
}
/*
The hook callback for when any player becomes damaged.
*/
-onPlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
+onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
{
- if(self is_bot())
+ if ( self is_bot() )
{
- self maps\mp\bots\_bot_internal::onDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
- self maps\mp\bots\_bot_script::onDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
+ self maps\mp\bots\_bot_internal::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset );
+ self maps\mp\bots\_bot_script::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset );
}
-
- self [[level.prevCallbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
+
+ self [[level.prevCallbackPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset );
}
/*
The hook callback when any player gets killed.
*/
-onPlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
+onPlayerKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
- if(self is_bot())
+ if ( self is_bot() )
{
- self maps\mp\bots\_bot_internal::onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
- self maps\mp\bots\_bot_script::onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
+ self maps\mp\bots\_bot_internal::onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
+ self maps\mp\bots\_bot_script::onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
}
-
- self [[level.prevCallbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
+
+ self.lastAttacker = eAttacker;
+
+ if ( isDefined( eAttacker ) )
+ {
+ eAttacker.lastKilledPlayer = self;
+ eAttacker notify( "killed_enemy" );
+ }
+
+ self [[level.prevCallbackPlayerKilled]]( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
}
/*
@@ -194,7 +245,7 @@ hook_callbacks()
wait 0.05;
level.prevCallbackPlayerDamage = level.callbackPlayerDamage;
level.callbackPlayerDamage = ::onPlayerDamage;
-
+
level.prevCallbackPlayerKilled = level.callbackPlayerKilled;
level.callbackPlayerKilled = ::onPlayerKilled;
}
@@ -205,26 +256,26 @@ hook_callbacks()
fixKoth()
{
level.radio = undefined;
-
- for(;;)
+
+ for ( ;; )
{
wait 0.05;
-
- if(!isDefined(level.radioObject))
+
+ if ( !isDefined( level.radioObject ) )
{
continue;
}
-
- for(i = level.radios.size - 1; i >= 0; i--)
+
+ for ( i = level.radios.size - 1; i >= 0; i-- )
{
- if(level.radioObject != level.radios[i].gameobject)
+ if ( level.radioObject != level.radios[i].gameobject )
continue;
-
+
level.radio = level.radios[i];
break;
}
-
- while(isDefined(level.radioObject) && level.radio.gameobject == level.radioObject)
+
+ while ( isDefined( level.radioObject ) && level.radio.gameobject == level.radioObject )
wait 0.05;
}
}
@@ -234,22 +285,23 @@ fixKoth()
*/
fixGamemodes()
{
- for(i=0;i<19;i++)
+ for ( i = 0; i < 19; i++ )
{
- if(isDefined(level.bombZones) && level.gametype == "sd")
+ if ( isDefined( level.bombZones ) && level.gametype == "sd" )
{
- for(i = 0; i < level.bombZones.size; i++)
+ for ( i = 0; i < level.bombZones.size; i++ )
level.bombZones[i].onUse = ::onUsePlantObjectFix;
+
break;
}
-
- if(isDefined(level.radios) && level.gametype == "koth")
+
+ if ( isDefined( level.radios ) && level.gametype == "koth" )
{
level thread fixKoth();
-
+
break;
}
-
+
wait 0.05;
}
}
@@ -259,14 +311,14 @@ fixGamemodes()
*/
onPlayerConnect()
{
- for(;;)
+ for ( ;; )
{
- level waittill("connected", player);
-
+ level waittill( "connected", player );
+
player thread onGrenadeFire();
player thread onWeaponFired();
player thread doPlayerModelFix();
-
+
player thread connected();
}
}
@@ -276,15 +328,15 @@ onPlayerConnect()
*/
fixPerksAndScriptKick()
{
- self endon("disconnect");
-
- self waittill("spawned");
-
+ self endon( "disconnect" );
+
+ self waittill( "spawned" );
+
self.pers["isBot"] = undefined;
-
- if(!level.gameEnded)
+
+ if ( !level.gameEnded )
level waittill ( "game_ended" );
-
+
self.pers["isBot"] = true;
}
@@ -293,9 +345,9 @@ fixPerksAndScriptKick()
*/
onDisconnect()
{
- self waittill("disconnect");
-
- level.bots = array_remove(level.bots, self);
+ self waittill( "disconnect" );
+
+ level.bots = array_remove( level.bots, self );
}
/*
@@ -303,35 +355,55 @@ onDisconnect()
*/
connected()
{
- self endon("disconnect");
+ self endon( "disconnect" );
- if (!isDefined(self.pers["bot_host"]))
+ if ( !isDefined( self.pers["bot_host"] ) )
self thread doHostCheck();
- if(!self is_bot())
+ if ( !self is_bot() )
return;
- if (!isDefined(self.pers["isBot"]))
+ if ( !isDefined( self.pers["isBot"] ) )
{
// fast restart...
self.pers["isBot"] = true;
}
-
- if (!isDefined(self.pers["isBotWarfare"]))
+
+ if ( !isDefined( self.pers["isBotWarfare"] ) )
{
self.pers["isBotWarfare"] = true;
self thread added();
}
-
+
self thread fixPerksAndScriptKick();
-
+
self thread maps\mp\bots\_bot_internal::connected();
self thread maps\mp\bots\_bot_script::connected();
level.bots[level.bots.size] = self;
self thread onDisconnect();
- level notify("bot_connected", self);
+ level notify( "bot_connected", self );
+
+ self thread watchBotDebugEvent();
+}
+
+/*
+ DEBUG
+*/
+watchBotDebugEvent()
+{
+ self endon( "disconnect" );
+
+ for ( ;; )
+ {
+ self waittill( "bot_event", msg, str, b, c, d, e, f, g );
+
+ if ( msg == "debug" && GetDvarInt( "bots_main_debug" ) )
+ {
+ printToConsole( "Bot Warfare debug: " + self.name + ": " + str );
+ }
+ }
}
/*
@@ -339,8 +411,8 @@ connected()
*/
added()
{
- self endon("disconnect");
-
+ self endon( "disconnect" );
+
self thread maps\mp\bots\_bot_internal::added();
self thread maps\mp\bots\_bot_script::added();
}
@@ -351,15 +423,15 @@ added()
add_bot()
{
name = getABotName();
-
+
bot = undefined;
- if (isDefined(name) && name.size >= 3)
- bot = addtestclient(name);
+ if ( isDefined( name ) && name.size >= 3 )
+ bot = addtestclient( name );
else
bot = addtestclient();
- if (isdefined(bot))
+ if ( isdefined( bot ) )
{
bot.pers["isBot"] = true;
bot.pers["isBotWarfare"] = true;
@@ -367,82 +439,236 @@ add_bot()
}
}
+/*
+ A server thread for monitoring all bot's difficulty levels for custom server settings.
+*/
+diffBots_loop()
+{
+ var_allies_hard = getDVarInt( "bots_skill_allies_hard" );
+ var_allies_med = getDVarInt( "bots_skill_allies_med" );
+ var_axis_hard = getDVarInt( "bots_skill_axis_hard" );
+ var_axis_med = getDVarInt( "bots_skill_axis_med" );
+ var_skill = getDvarInt( "bots_skill" );
+
+ allies_hard = 0;
+ allies_med = 0;
+ axis_hard = 0;
+ axis_med = 0;
+
+ if ( var_skill == 8 )
+ {
+ playercount = level.players.size;
+
+ for ( i = 0; i < playercount; i++ )
+ {
+ player = level.players[i];
+
+ if ( !isDefined( player.pers["team"] ) )
+ continue;
+
+ if ( !player is_bot() )
+ continue;
+
+ if ( player.pers["team"] == "axis" )
+ {
+ if ( axis_hard < var_axis_hard )
+ {
+ axis_hard++;
+ player.pers["bots"]["skill"]["base"] = 7;
+ }
+ else if ( axis_med < var_axis_med )
+ {
+ axis_med++;
+ player.pers["bots"]["skill"]["base"] = 4;
+ }
+ else
+ player.pers["bots"]["skill"]["base"] = 1;
+ }
+ else if ( player.pers["team"] == "allies" )
+ {
+ if ( allies_hard < var_allies_hard )
+ {
+ allies_hard++;
+ player.pers["bots"]["skill"]["base"] = 7;
+ }
+ else if ( allies_med < var_allies_med )
+ {
+ allies_med++;
+ player.pers["bots"]["skill"]["base"] = 4;
+ }
+ else
+ player.pers["bots"]["skill"]["base"] = 1;
+ }
+ }
+ }
+ else if ( var_skill != 0 && var_skill != 9 )
+ {
+ playercount = level.players.size;
+
+ for ( i = 0; i < playercount; i++ )
+ {
+ player = level.players[i];
+
+ if ( !player is_bot() )
+ continue;
+
+ player.pers["bots"]["skill"]["base"] = var_skill;
+ }
+ }
+
+ playercount = level.players.size;
+ min_diff = GetDvarInt( "bots_skill_min" );
+ max_diff = GetDvarInt( "bots_skill_max" );
+
+ for ( i = 0; i < playercount; i++ )
+ {
+ player = level.players[i];
+
+ if ( !player is_bot() )
+ continue;
+
+ player.pers["bots"]["skill"]["base"] = int( clamp( player.pers["bots"]["skill"]["base"], min_diff, max_diff ) );
+ }
+}
+
/*
A server thread for monitoring all bot's difficulty levels for custom server settings.
*/
diffBots()
{
- for(;;)
+ for ( ;; )
{
wait 1.5;
-
- var_allies_hard = getDVarInt("bots_skill_allies_hard");
- var_allies_med = getDVarInt("bots_skill_allies_med");
- var_axis_hard = getDVarInt("bots_skill_axis_hard");
- var_axis_med = getDVarInt("bots_skill_axis_med");
- var_skill = getDvarInt("bots_skill");
-
- allies_hard = 0;
- allies_med = 0;
- axis_hard = 0;
- axis_med = 0;
-
- if(var_skill == 8)
+
+ diffBots_loop();
+ }
+}
+
+/*
+ A server thread for monitoring all bot's teams for custom server settings.
+*/
+teamBots_loop()
+{
+ teamAmount = getDvarInt( "bots_team_amount" );
+ toTeam = getDvar( "bots_team" );
+
+ alliesbots = 0;
+ alliesplayers = 0;
+ axisbots = 0;
+ axisplayers = 0;
+
+ playercount = level.players.size;
+
+ for ( i = 0; i < playercount; i++ )
+ {
+ player = level.players[i];
+
+ if ( !isDefined( player.pers["team"] ) )
+ continue;
+
+ if ( player is_bot() )
{
- playercount = level.players.size;
- for(i = 0; i < playercount; i++)
+ if ( player.pers["team"] == "allies" )
+ alliesbots++;
+ else if ( player.pers["team"] == "axis" )
+ axisbots++;
+ }
+ else
+ {
+ if ( player.pers["team"] == "allies" )
+ alliesplayers++;
+ else if ( player.pers["team"] == "axis" )
+ axisplayers++;
+ }
+ }
+
+ allies = alliesbots;
+ axis = axisbots;
+
+ if ( !getDvarInt( "bots_team_mode" ) )
+ {
+ allies += alliesplayers;
+ axis += axisplayers;
+ }
+
+ if ( toTeam != "custom" )
+ {
+ if ( getDvarInt( "bots_team_force" ) )
+ {
+ if ( toTeam == "autoassign" )
{
- player = level.players[i];
-
- if(!isDefined(player.pers["team"]))
- continue;
-
- if(!player is_bot())
- continue;
-
- if(player.pers["team"] == "axis")
+ if ( abs( axis - allies ) > 1 )
{
- if(axis_hard < var_axis_hard)
- {
- axis_hard++;
- player.pers["bots"]["skill"]["base"] = 7;
- }
- else if(axis_med < var_axis_med)
- {
- axis_med++;
- player.pers["bots"]["skill"]["base"] = 4;
- }
- else
- player.pers["bots"]["skill"]["base"] = 1;
+ toTeam = "axis";
+
+ if ( axis > allies )
+ toTeam = "allies";
}
- else if(player.pers["team"] == "allies")
+ }
+
+ if ( toTeam != "autoassign" )
+ {
+ playercount = level.players.size;
+
+ for ( i = 0; i < playercount; i++ )
{
- if(allies_hard < var_allies_hard)
- {
- allies_hard++;
- player.pers["bots"]["skill"]["base"] = 7;
- }
- else if(allies_med < var_allies_med)
- {
- allies_med++;
- player.pers["bots"]["skill"]["base"] = 4;
- }
+ player = level.players[i];
+
+ if ( !isDefined( player.pers["team"] ) )
+ continue;
+
+ if ( !player is_bot() )
+ continue;
+
+ if ( player.pers["team"] == toTeam )
+ continue;
+
+ if ( toTeam == "allies" )
+ player thread [[level.allies]]();
+ else if ( toTeam == "axis" )
+ player thread [[level.axis]]();
else
- player.pers["bots"]["skill"]["base"] = 1;
+ player thread [[level.spectator]]();
+
+ break;
}
}
}
- else if (var_skill != 0 && var_skill != 9)
+ }
+ else
+ {
+ playercount = level.players.size;
+
+ for ( i = 0; i < playercount; i++ )
{
- playercount = level.players.size;
- for(i = 0; i < playercount; i++)
+ player = level.players[i];
+
+ if ( !isDefined( player.pers["team"] ) )
+ continue;
+
+ if ( !player is_bot() )
+ continue;
+
+ if ( player.pers["team"] == "axis" )
{
- player = level.players[i];
-
- if(!player is_bot())
- continue;
-
- player.pers["bots"]["skill"]["base"] = var_skill;
+ if ( axis > teamAmount )
+ {
+ player thread [[level.allies]]();
+ break;
+ }
+ }
+ else
+ {
+ if ( axis < teamAmount )
+ {
+ player thread [[level.axis]]();
+ break;
+ }
+ else if ( player.pers["team"] != "allies" )
+ {
+ player thread [[level.allies]]();
+ break;
+ }
}
}
}
@@ -453,127 +679,119 @@ diffBots()
*/
teamBots()
{
- for(;;)
+ for ( ;; )
{
wait 1.5;
- teamAmount = getDvarInt("bots_team_amount");
- toTeam = getDvar("bots_team");
-
- alliesbots = 0;
- alliesplayers = 0;
- axisbots = 0;
+
+ teamBots_loop();
+ }
+}
+
+/*
+ A server thread for monitoring all bot's in game. Will add and kick bots according to server settings.
+*/
+addBots_loop()
+{
+ botsToAdd = GetDvarInt( "bots_manage_add" );
+
+ if ( botsToAdd > 0 )
+ {
+ SetDvar( "bots_manage_add", 0 );
+
+ if ( botsToAdd > 64 )
+ botsToAdd = 64;
+
+ for ( ; botsToAdd > 0; botsToAdd-- )
+ {
+ level add_bot();
+ wait 0.25;
+ }
+ }
+
+ fillMode = getDVarInt( "bots_manage_fill_mode" );
+
+ if ( fillMode == 2 || fillMode == 3 )
+ setDvar( "bots_manage_fill", getGoodMapAmount() );
+
+ fillAmount = getDvarInt( "bots_manage_fill" );
+
+ players = 0;
+ bots = 0;
+ spec = 0;
+
+ playercount = level.players.size;
+
+ for ( i = 0; i < playercount; i++ )
+ {
+ player = level.players[i];
+
+ if ( player is_bot() )
+ bots++;
+ else if ( !isDefined( player.pers["team"] ) || ( player.pers["team"] != "axis" && player.pers["team"] != "allies" ) )
+ spec++;
+ else
+ players++;
+ }
+
+ if ( !randomInt( 999 ) )
+ {
+ setDvar( "testclients_doreload", true );
+ wait 0.1;
+ setDvar( "testclients_doreload", false );
+ doExtraCheck();
+ }
+
+ if ( fillMode == 4 )
+ {
axisplayers = 0;
-
+ alliesplayers = 0;
+
playercount = level.players.size;
- for(i = 0; i < playercount; i++)
+
+ for ( i = 0; i < playercount; i++ )
{
player = level.players[i];
-
- if(!isDefined(player.pers["team"]))
+
+ if ( player is_bot() )
continue;
-
- if(player is_bot())
- {
- if(player.pers["team"] == "allies")
- alliesbots++;
- else if(player.pers["team"] == "axis")
- axisbots++;
- }
+
+ if ( !isDefined( player.pers["team"] ) )
+ continue;
+
+ if ( player.pers["team"] == "axis" )
+ axisplayers++;
+ else if ( player.pers["team"] == "allies" )
+ alliesplayers++;
+ }
+
+ result = fillAmount - abs( axisplayers - alliesplayers ) + bots;
+
+ if ( players == 0 )
+ {
+ if ( bots < fillAmount )
+ result = fillAmount - 1;
+ else if ( bots > fillAmount )
+ result = fillAmount + 1;
else
- {
- if(player.pers["team"] == "allies")
- alliesplayers++;
- else if(player.pers["team"] == "axis")
- axisplayers++;
- }
- }
-
- allies = alliesbots;
- axis = axisbots;
-
- if(!getDvarInt("bots_team_mode"))
- {
- allies += alliesplayers;
- axis += axisplayers;
- }
-
- if(toTeam != "custom")
- {
- if(getDvarInt("bots_team_force"))
- {
- if(toTeam == "autoassign")
- {
- if(abs(axis - allies) > 1)
- {
- toTeam = "axis";
- if(axis > allies)
- toTeam = "allies";
- }
- }
-
- if(toTeam != "autoassign")
- {
- playercount = level.players.size;
- for(i = 0; i < playercount; i++)
- {
- player = level.players[i];
-
- if(!isDefined(player.pers["team"]))
- continue;
-
- if(!player is_bot())
- continue;
-
- if(player.pers["team"] == toTeam)
- continue;
-
- if (toTeam == "allies")
- player thread [[level.allies]]();
- else if (toTeam == "axis")
- player thread [[level.axis]]();
- else
- player thread [[level.spectator]]();
- break;
- }
- }
- }
- }
- else
- {
- playercount = level.players.size;
- for(i = 0; i < playercount; i++)
- {
- player = level.players[i];
-
- if(!isDefined(player.pers["team"]))
- continue;
-
- if(!player is_bot())
- continue;
-
- if(player.pers["team"] == "axis")
- {
- if(axis > teamAmount)
- {
- player thread [[level.allies]]();
- break;
- }
- }
- else
- {
- if(axis < teamAmount)
- {
- player thread [[level.axis]]();
- break;
- }
- else if(player.pers["team"] != "allies")
- {
- player thread [[level.allies]]();
- break;
- }
- }
- }
+ result = fillAmount;
}
+
+ bots = result;
+ }
+
+ amount = bots;
+
+ if ( fillMode == 0 || fillMode == 2 )
+ amount += players;
+
+ if ( getDVarInt( "bots_manage_fill_spec" ) )
+ amount += spec;
+
+ if ( amount < fillAmount )
+ setDvar( "bots_manage_add", 1 );
+ else if ( amount > fillAmount && getDvarInt( "bots_manage_fill_kick" ) )
+ {
+ RemoveTestClient(); //cod4x
}
}
@@ -582,111 +800,15 @@ teamBots()
*/
addBots()
{
- level endon("game_ended");
+ level endon( "game_ended" );
bot_wait_for_host();
-
- for(;;)
+
+ for ( ;; )
{
wait 1.5;
-
- botsToAdd = GetDvarInt("bots_manage_add");
-
- if(botsToAdd > 0)
- {
- SetDvar("bots_manage_add", 0);
-
- if(botsToAdd > 64)
- botsToAdd = 64;
-
- for(; botsToAdd > 0; botsToAdd--)
- {
- level add_bot();
- wait 0.25;
- }
- }
-
- fillMode = getDVarInt("bots_manage_fill_mode");
-
- if(fillMode == 2 || fillMode == 3)
- setDvar("bots_manage_fill", getGoodMapAmount());
-
- fillAmount = getDvarInt("bots_manage_fill");
-
- players = 0;
- bots = 0;
- spec = 0;
-
- playercount = level.players.size;
- for(i = 0; i < playercount; i++)
- {
- player = level.players[i];
-
- if(player is_bot())
- bots++;
- else if(!isDefined(player.pers["team"]) || (player.pers["team"] != "axis" && player.pers["team"] != "allies"))
- spec++;
- else
- players++;
- }
- if (!randomInt(999))
- {
- setDvar("testclients_doreload", true);
- wait 0.1;
- setDvar("testclients_doreload", false);
- doExtraCheck();
- }
-
- if(fillMode == 4)
- {
- axisplayers = 0;
- alliesplayers = 0;
-
- playercount = level.players.size;
- for(i = 0; i < playercount; i++)
- {
- player = level.players[i];
-
- if(player is_bot())
- continue;
-
- if(!isDefined(player.pers["team"]))
- continue;
-
- if(player.pers["team"] == "axis")
- axisplayers++;
- else if(player.pers["team"] == "allies")
- alliesplayers++;
- }
-
- result = fillAmount - abs(axisplayers - alliesplayers) + bots;
-
- if (players == 0)
- {
- if(bots < fillAmount)
- result = fillAmount-1;
- else if (bots > fillAmount)
- result = fillAmount+1;
- else
- result = fillAmount;
- }
-
- bots = result;
- }
-
- amount = bots;
- if(fillMode == 0 || fillMode == 2)
- amount += players;
- if(getDVarInt("bots_manage_fill_spec"))
- amount += spec;
-
- if(amount < fillAmount)
- setDvar("bots_manage_add", 1);
- else if(amount > fillAmount && getDvarInt("bots_manage_fill_kick"))
- {
- RemoveTestClient(); //cod4x
- }
+ addBots_loop();
}
}
@@ -695,12 +817,18 @@ addBots()
*/
onGrenadeFire()
{
- self endon("disconnect");
- for(;;)
+ self endon( "disconnect" );
+
+ for ( ;; )
{
self waittill ( "grenade_fire", grenade, weaponName );
+
+ if ( !isDefined( grenade ) )
+ continue;
+
grenade.name = weaponName;
- if(weaponName == "smoke_grenade_mp")
+
+ if ( weaponName == "smoke_grenade_mp" )
grenade thread AddToSmokeList();
}
}
@@ -714,10 +842,10 @@ AddToSmokeList()
grenade.origin = self getOrigin();
grenade.state = "moving";
grenade.grenade = self;
-
+
grenade thread thinkSmoke();
-
- level.bots_smokeList ListAdd(grenade);
+
+ level.bots_smokeList ListAdd( grenade );
}
/*
@@ -725,16 +853,17 @@ AddToSmokeList()
*/
thinkSmoke()
{
- while(isDefined(self.grenade))
+ while ( isDefined( self.grenade ) )
{
self.origin = self.grenade getOrigin();
self.state = "moving";
wait 0.05;
}
+
self.state = "smoking";
wait 11.5;
-
- level.bots_smokeList ListRemove(self);
+
+ level.bots_smokeList ListRemove( self );
}
/*
@@ -742,25 +871,26 @@ thinkSmoke()
*/
chopperWatch()
{
- for(;;)
+ for ( ;; )
{
- while(!isDefined(level.chopper))
+ while ( !isDefined( level.chopper ) )
wait 0.05;
chopper = level.chopper;
- if (level.teamBased && getDvarInt("doubleHeli"))
+ if ( level.teamBased && getDvarInt( "doubleHeli" ) )
{
chopper = level.chopper["allies"];
- if (!isDefined(chopper))
+
+ if ( !isDefined( chopper ) )
chopper = level.chopper["axis"];
}
level.bot_chopper = true;
chopper watchChopper();
level.bot_chopper = false;
-
- while(isDefined(level.chopper))
+
+ while ( isDefined( level.chopper ) )
wait 0.05;
}
}
@@ -770,11 +900,11 @@ chopperWatch()
*/
watchChopper()
{
- self endon("death");
- self endon("leaving");
- self endon("crashing");
-
- level waittill("helicopter gone");
+ self endon( "death" );
+ self endon( "leaving" );
+ self endon( "crashing" );
+
+ level waittill( "helicopter gone" );
}
/*
@@ -782,10 +912,10 @@ watchChopper()
*/
onUAVAxisUpdate()
{
- for(;;)
+ for ( ;; )
{
level waittill( "radar_timer_kill_axis" );
- level thread doUAVUpdate("axis");
+ level thread doUAVUpdate( "axis" );
}
}
@@ -794,46 +924,47 @@ onUAVAxisUpdate()
*/
onUAVAlliesUpdate()
{
- for(;;)
+ for ( ;; )
{
level waittill( "radar_timer_kill_allies" );
- level thread doUAVUpdate("allies");
+ level thread doUAVUpdate( "allies" );
}
}
/*
Updates the player's radar so bots can know when they have a uav up, because iw3 script is old.
*/
-doUAVUpdate(team)
+doUAVUpdate( team )
{
- level endon("radar_timer_kill_" + team);
-
+ level endon( "radar_timer_kill_" + team );
+
playercount = level.players.size;
-
- for(i = 0; i < playercount; i++)
+
+ for ( i = 0; i < playercount; i++ )
{
player = level.players[i];
-
- if(!isDefined(player.team))
+
+ if ( !isDefined( player.team ) )
continue;
-
- if(player.team == team)
+
+ if ( player.team == team )
{
player.bot_radar = true;
}
}
-
+
wait level.radarViewTime;
-
+
playercount = level.players.size;
- for(i = 0; i < playercount; i++)
+
+ for ( i = 0; i < playercount; i++ )
{
player = level.players[i];
-
- if(!isDefined(player.team))
+
+ if ( !isDefined( player.team ) )
continue;
-
- if(player.team == team)
+
+ if ( player.team == team )
{
player.bot_radar = false;
}
@@ -845,8 +976,8 @@ doUAVUpdate(team)
*/
doPlayerModelFix()
{
- self endon("disconnect");
- self waittill("spawned_player");
+ self endon( "disconnect" );
+ self waittill( "spawned_player" );
wait 0.05;
self.bot_model_fix = true;
}
@@ -856,9 +987,10 @@ doPlayerModelFix()
*/
onWeaponFired()
{
- self endon("disconnect");
+ self endon( "disconnect" );
self.bots_firing = false;
- for(;;)
+
+ for ( ;; )
{
self waittill( "weapon_fired" );
self thread doFiringThread();
@@ -870,8 +1002,8 @@ onWeaponFired()
*/
doFiringThread()
{
- self endon("disconnect");
- self endon("weapon_fired");
+ self endon( "disconnect" );
+ self endon( "weapon_fired" );
self.bots_firing = true;
wait 1;
self.bots_firing = false;
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_chat.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_chat.gsc
new file mode 100644
index 0000000..bdefe9e
--- /dev/null
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_chat.gsc
@@ -0,0 +1,2186 @@
+/*
+ _bot_chat
+ Author: INeedGames
+ Date: 05/06/2022
+ Does bot chatter.
+*/
+
+#include common_scripts\utility;
+#include maps\mp\_utility;
+#include maps\mp\gametypes\_hud_util;
+#include maps\mp\bots\_bot_utility;
+
+/*
+ Init
+*/
+init()
+{
+ if ( getDvar( "bots_main_chat" ) == "" )
+ setDvar( "bots_main_chat", 1.0 );
+
+ level thread onBotConnected();
+}
+
+/*
+ Bot connected
+*/
+onBotConnected()
+{
+ for ( ;; )
+ {
+ level waittill( "bot_connected", bot );
+
+ bot thread start_chat_threads();
+ }
+}
+
+/*
+ Does the chatter
+*/
+BotDoChat( chance, string, isTeam )
+{
+ mod = getDvarFloat( "bots_main_chat" );
+
+ if ( mod <= 0.0 )
+ return;
+
+ if ( chance >= 100 || mod >= 100.0 ||
+ ( RandomInt( 100 ) < ( chance * mod ) + 0 ) )
+ {
+ if ( isDefined( isTeam ) && isTeam )
+ self sayteam( string );
+ else
+ self sayall( string );
+ }
+}
+
+/*
+ Threads for bots
+*/
+start_chat_threads()
+{
+ self endon( "disconnect" );
+
+ self thread start_random_chat();
+ self thread start_chat_watch();
+ self thread start_killed_watch();
+ self thread start_death_watch();
+ self thread start_endgame_watch();
+
+ self thread start_startgame_watch();
+}
+
+/*
+ death
+*/
+start_death_watch()
+{
+ self endon( "disconnect" );
+
+ for ( ;; )
+ {
+ self waittill( "death" );
+
+ self thread bot_chat_death_watch( self.lastAttacker, self.bots_lastKS );
+
+ self.bots_lastKS = 0;
+ }
+}
+
+/*
+ start_endgame_watch
+*/
+start_endgame_watch()
+{
+ self endon( "disconnect" );
+
+ level waittill ( "game_ended" );
+
+ self thread endgame_chat();
+}
+
+/*
+ Random chatting
+*/
+start_random_chat()
+{
+ self endon( "disconnect" );
+
+ for ( ;; )
+ {
+ wait 1;
+
+ if ( randomInt( 100 ) < 1 )
+ {
+ if ( randomInt( 100 ) < 1 && isAlive( self ) )
+ self thread doQuickMessage();
+ }
+ }
+}
+
+/*
+ Got a kill
+*/
+start_killed_watch()
+{
+ self endon( "disconnect" );
+
+ self.bots_lastKS = 0;
+
+ for ( ;; )
+ {
+ self waittill( "killed_enemy" );
+ wait 0.05;
+
+ if ( self.bots_lastKS < self.cur_kill_streak )
+ {
+ for ( i = self.bots_lastKS + 1; i <= self.cur_kill_streak; i++ )
+ {
+ self thread bot_chat_streak( i );
+ }
+ }
+
+ self.bots_lastKS = self.cur_kill_streak;
+
+ self thread bot_chat_killed_watch( self.lastKilledPlayer );
+ }
+}
+
+/*
+ Starts things for the bot
+*/
+start_chat_watch()
+{
+ self endon( "disconnect" );
+ level endon ( "game_ended" );
+
+ for ( ;; )
+ {
+ self waittill( "bot_event", msg, a, b, c, d, e, f, g );
+
+ switch ( msg )
+ {
+ case "killcam":
+ self thread bot_chat_killcam_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "stuck":
+ self thread bot_chat_stuck_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "tube":
+ self thread bot_chat_tube_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "killstreak":
+ self thread bot_chat_killstreak_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "attack_vehicle":
+ self thread bot_chat_attack_vehicle_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "follow_threat":
+ self thread bot_chat_follow_threat_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "camp":
+ self thread bot_chat_camp_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "follow":
+ self thread bot_chat_follow_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "equ":
+ self thread bot_chat_equ_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "nade":
+ self thread bot_chat_nade_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "throwback":
+ self thread bot_chat_throwback_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "rage":
+ self thread bot_chat_rage_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "tbag":
+ self thread bot_chat_tbag_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "revenge":
+ self thread bot_chat_revenge_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "heard_target":
+ self thread bot_chat_heard_target_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "uav_target":
+ self thread bot_chat_uav_target_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "attack_equ":
+ self thread bot_chat_attack_equ_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "dom":
+ self thread bot_chat_dom_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "hq":
+ self thread bot_chat_hq_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "sab":
+ self thread bot_chat_sab_watch( a, b, c, d, e, f, g );
+ break;
+
+ case "sd":
+ self thread bot_chat_sd_watch( a, b, c, d, e, f, g );
+ break;
+ }
+ }
+}
+
+/*
+ start_startgame_watch
+*/
+start_startgame_watch()
+{
+ self endon( "disconnect" );
+
+ wait( randomint( 5 ) + randomint( 5 ) );
+
+ switch ( level.gametype )
+ {
+ case "war":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 7, "TEEEEEEEEAM, DEEEEAAAAAATHMAAAAATCH!!" );
+ break;
+
+ case 1:
+ self BotDoChat( 7, "Lets get em guys, wipe the floor with them." );
+ break;
+
+ case 2:
+ self BotDoChat( 7, "Yeeeesss master..." );
+ break;
+ }
+
+ break;
+
+ case "dom":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 7, "Yaaayy!! I LOVE DOMINATION!!!!" );
+ break;
+
+ case 1:
+ self BotDoChat( 7, "Lets cap the flags and them." );
+ break;
+
+ case 2:
+ self BotDoChat( 7, "Yeeeesss master..." );
+ break;
+ }
+
+ break;
+
+ case "sd":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 7, "Ahhhh! I'm scared! No respawning!" );
+ break;
+
+ case 1:
+ self BotDoChat( 7, "Lets get em guys, wipe the floor with them." );
+ break;
+
+ case 2:
+ self BotDoChat( 7, "Yeeeesss master..." );
+ break;
+ }
+
+ break;
+
+ case "sab":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 7, "Soccer/Football! Lets play it!" );
+ break;
+
+ case 1:
+ self BotDoChat( 7, "Who plays sab these days." );
+ break;
+
+ case 2:
+ self BotDoChat( 7, "I do not know what to say." );
+ break;
+ }
+
+ break;
+
+ case "dm":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 7, "DEEEEAAAAAATHMAAAAATCH!!" );
+ break;
+
+ case 1:
+ self BotDoChat( 7, "IM GOING TO KILL U ALL" );
+ break;
+
+ case 2:
+ self BotDoChat( 7, "lol sweet. time to camp." );
+ break;
+ }
+
+ break;
+
+ case "koth":
+ self BotDoChat( 7, "HQ TIME!" );
+ break;
+ }
+}
+
+/*
+ Does quick cod4 style message
+*/
+doQuickMessage()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ if ( !isDefined( self.talking ) || !self.talking )
+ {
+ self.talking = true;
+ soundalias = "";
+ saytext = "";
+ wait 2;
+ self.spamdelay = true;
+
+ switch ( randomint( 11 ) )
+ {
+ case 4 :
+ soundalias = "mp_cmd_suppressfire";
+ saytext = "Suppressing fire!";
+ break;
+
+ case 5 :
+ soundalias = "mp_cmd_followme";
+ saytext = "Follow Me!";
+ break;
+
+ case 6 :
+ soundalias = "mp_stm_enemyspotted";
+ saytext = "Enemy spotted!";
+ break;
+
+ case 7 :
+ soundalias = "mp_cmd_fallback";
+ saytext = "Fall back!";
+ break;
+
+ case 8 :
+ soundalias = "mp_stm_needreinforcements";
+ saytext = "Need reinforcements!";
+ break;
+ }
+
+ if ( soundalias != "" && saytext != "" )
+ {
+ self maps\mp\gametypes\_quickmessages::saveHeadIcon();
+ self maps\mp\gametypes\_quickmessages::doQuickMessage( soundalias, saytext );
+ wait 2;
+ self maps\mp\gametypes\_quickmessages::restoreHeadIcon();
+ }
+ else
+ {
+ if ( randomint( 100 ) < 1 )
+ self BotDoChat( 1, maps\mp\bots\_bot_utility::keyCodeToString( 2 ) + maps\mp\bots\_bot_utility::keyCodeToString( 17 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 3 ) + maps\mp\bots\_bot_utility::keyCodeToString( 8 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 8 ) + maps\mp\bots\_bot_utility::keyCodeToString( 13 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 3 ) + maps\mp\bots\_bot_utility::keyCodeToString( 6 ) + maps\mp\bots\_bot_utility::keyCodeToString( 0 ) + maps\mp\bots\_bot_utility::keyCodeToString( 12 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 18 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 5 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 17 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 1 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 18 ) + maps\mp\bots\_bot_utility::keyCodeToString( 26 ) );
+ }
+
+ self.spamdelay = undefined;
+ wait randomint( 5 );
+ self.talking = false;
+ }
+}
+
+/*
+ endgame_chat
+*/
+endgame_chat()
+{
+ self endon( "disconnect" );
+
+ wait ( randomint( 6 ) + randomint( 6 ) );
+ b = -1;
+ w = 999999999;
+ winner = undefined;
+ loser = undefined;
+
+ for ( i = 0; i < level.players.size; i++ )
+ {
+ player = level.players[i];
+
+ if ( player.pers["score"] > b )
+ {
+ winner = player;
+ b = player.pers["score"];
+ }
+
+ if ( player.pers["score"] < w )
+ {
+ loser = player;
+ w = player.pers["score"];
+ }
+ }
+
+ if ( level.teamBased )
+ {
+ winningteam = getWinningTeam();
+
+ if ( self.pers["team"] == winningteam )
+ {
+ switch ( randomint( 21 ) )
+ {
+ case 0:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Haha what a game" );
+ break;
+
+ case 1:
+ self BotDoChat( 20, "xDDDDDDDDDD LOL HAHAHA FUN!" );
+ break;
+
+ case 3:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "That was fun" );
+ break;
+
+ case 4:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Lol my team always wins!" );
+ break;
+
+ case 5:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Haha if i am on " + winningteam + " my team always wins!" );
+ break;
+
+ case 2:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gg" );
+ break;
+
+ case 6:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "GGA, our team was awesome!" );
+ break;
+
+ case 7:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "My team " + self.pers["team"] + " always wins!!" );
+ break;
+
+ case 8:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "WOW that was EPIC!" );
+ break;
+
+ case 9:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Hackers lost haha noobs" );
+ break;
+
+ case 10:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Nice game!! Good job team!" );
+ break;
+
+ case 11:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "GGA, Well done team!" );
+ break;
+
+ case 12:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "LOL! camper noobs lose" );
+ break;
+
+ case 13:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "owned." );
+ break;
+
+ case 14:
+ self BotDoChat( 20, "lool we won!!" );
+ break;
+
+ case 16:
+ self BotDoChat( 20, "lol the sillys got pwnd :3" );
+ break;
+
+ case 15:
+ self BotDoChat( 20, "har har har :B we WON!" );
+ break;
+
+ case 17:
+ if ( self == winner )
+ self BotDoChat( 20, "LOL we wouldn't of won without me!" );
+ else if ( self == loser )
+ self BotDoChat( 20, "damn i sucked but i still won" );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, "lol " + loser.name + " sucked hard!" );
+ else if ( self != winner )
+ self BotDoChat( 20, "wow " + winner.name + " did very well!" );
+
+ break;
+
+ case 18:
+ if ( self == winner )
+ self BotDoChat( 20, "I'm the VERY BEST!" );
+ else if ( self == loser )
+ self BotDoChat( 20, "lol my team is good, i suck doe" );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, "lol " + loser.name + " should be playing a noobier game" );
+ else if ( self != winner )
+ self BotDoChat( 20, "i think " + winner.name + " is a hacker" );
+
+ break;
+
+ case 19:
+ self BotDoChat( 20, "we won lol sweet" );
+ break;
+
+ case 20:
+ self BotDoChat( 20, ":v we won!" );
+ break;
+ }
+ }
+ else
+ {
+ if ( winningteam != "none" )
+ {
+ switch ( randomint( 21 ) )
+ {
+ case 0:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Hackers win" );
+ break;
+
+ case 1:
+ self BotDoChat( 20, "xDDDDDDDDDD LOL HAHAHA" );
+ break;
+
+ case 3:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "That wasn't fun" );
+ break;
+
+ case 4:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Wow my team SUCKS!" );
+ break;
+
+ case 5:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "My team " + self.pers["team"] + " always loses!!" );
+ break;
+
+ case 2:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gg" );
+ break;
+
+ case 6:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "bg" );
+ break;
+
+ case 7:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "vbg" );
+ break;
+
+ case 8:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "WOW that was EPIC!" );
+ break;
+
+ case 9:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Good game" );
+ break;
+
+ case 10:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Bad game" );
+ break;
+
+ case 11:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "very bad game" );
+ break;
+
+ case 12:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "campers win" );
+ break;
+
+ case 13:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "CAMPER NOOBS!!" );
+ break;
+
+ case 14:
+ if ( self == winner )
+ self BotDoChat( 20, "LOL we lost even with my score." );
+ else if ( self == loser )
+ self BotDoChat( 20, "damn im probally the reason we lost" );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, loser.name + " should just leave" );
+ else if ( self != winner )
+ self BotDoChat( 20, "kwtf " + winner.name + " is a hacker" );
+
+ break;
+
+ case 15:
+ if ( self == winner )
+ self BotDoChat( 20, "my teammates are garabge" );
+ else if ( self == loser )
+ self BotDoChat( 20, "lol im garbage" );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, loser.name + " sux" );
+ else if ( self != winner )
+ self BotDoChat( 20, winner.name + " is a noob!" );
+
+ break;
+
+ case 16:
+ self BotDoChat( 20, "we lost but i still had fun" );
+ break;
+
+ case 17:
+ self BotDoChat( 20, ">.> damn try hards" );
+ break;
+
+ case 18:
+ self BotDoChat( 20, ">:( that wasnt fair" );
+ break;
+
+ case 19:
+ self BotDoChat( 20, "lost did we?" );
+ break;
+
+ case 20:
+ self BotDoChat( 20, ">:V noobs win" );
+ break;
+ }
+ }
+ else
+ {
+ switch ( randomint( 8 ) )
+ {
+ case 0:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gg" );
+ break;
+
+ case 1:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "bg" );
+ break;
+
+ case 2:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "vbg" );
+ break;
+
+ case 3:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "vgg" );
+ break;
+
+ case 4:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gg no rm" );
+ break;
+
+ case 5:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "ggggggggg" );
+ break;
+
+ case 6:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "good game" );
+ break;
+
+ case 7:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gee gee" );
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ switch ( randomint( 20 ) )
+ {
+ case 0:
+ if ( self == winner )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Haha Suck it, you all just got pwnd!" );
+ else if ( self == loser )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Lol i Sucked in this game, just look at my score!" );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gga, Bad luck " + loser.name );
+ else if ( self != winner )
+ self BotDoChat( 20, "This game sucked, " + winner.name + " is such a hacker!!" );
+
+ break;
+
+ case 1:
+ if ( self == winner )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "LOL i just wasted you all!! Whoot whoot!" );
+ else if ( self == loser )
+ self BotDoChat( 20, "GGA i suck, Nice score " + winner.name );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Rofl, " + loser.name + " dude, you suck!!" );
+ else if ( self != winner )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Nice Score " + winner.name + ", how did you get to be so good?" );
+
+ break;
+
+ case 2:
+ if ( self == winner )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "LOL i just wasted you all!! Whoot whoot!" );
+ else if ( self == loser )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "nice wallhacks " + winner.name );
+ else if ( self != loser && randomint( 2 ) == 1 )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Lol atleast i did better then " + loser.name );
+ else if ( self != winner )
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "lolwtf " + winner.name );
+
+ break;
+
+ case 3:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gee gee" );
+ break;
+
+ case 4:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "WOW that was EPIC!" );
+ break;
+
+ case 5:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Nice Game!" );
+ break;
+
+ case 6:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "good game" );
+ break;
+
+ case 7:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gga c u all later" );
+ break;
+
+ case 8:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "bg" );
+ break;
+
+ case 9:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "GG" );
+ break;
+
+ case 10:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gg" );
+ break;
+
+ case 11:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "vbg" );
+ break;
+
+ case 12:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gga" );
+ break;
+
+ case 13:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "BG" );
+ break;
+
+ case 14:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "stupid map" );
+ break;
+
+ case 15:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "ffa sux" );
+ break;
+
+ case 16:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + ":3 i had fun" );
+ break;
+
+ case 17:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + ":P nubs are playin" );
+ break;
+
+ case 18:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "nub nub nub thx 4 the nubs" );
+ break;
+
+ case 19:
+ self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "damn campers" );
+ break;
+ }
+ }
+}
+
+/*
+ Got streak
+*/
+bot_chat_streak( streakCount )
+{
+ self endon( "disconnect" );
+
+ if ( streakCount == 7 )
+ {
+ if ( isDefined( self.pers["hardPointItem"] ) && self.pers["hardPointItem"] == "helicopter_mp" )
+ {
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 33, "Nice! I acheived a chopper!" );
+ break;
+ }
+ }
+ else
+ {
+ self BotDoChat( 33, "Huh?? I dont got my helicopter :((" );
+ }
+ }
+}
+
+/*
+ Say killed stuff
+*/
+bot_chat_killed_watch( victim )
+{
+ self endon( "disconnect" );
+
+ if ( !isDefined( victim ) || !isDefined( victim.name ) )
+ return;
+
+ message = "";
+
+ switch ( randomint( 42 ) )
+ {
+ case 0:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Haha take that " + victim.name );
+ break;
+
+ case 1:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Who's your daddy!" );
+ break;
+
+ case 2:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "O i just kicked your ass " + victim.name + "!!" );
+ break;
+
+ case 3:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Better luck next time " + victim.name );
+ break;
+
+ case 4:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + victim.name + " Is that all you got?" );
+ break;
+
+ case 5:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "LOL " + victim.name + ", l2play" );
+ break;
+
+ case 6:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + ":)" );
+ break;
+
+ case 7:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Im unstoppable!" );
+ break;
+
+ case 8:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Wow " + victim.name + " that was a close one!" );
+ break;
+
+ case 9:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Haha thank you, thank you very much." );
+ break;
+
+ case 10:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "HAHAHAHA LOL" );
+ break;
+
+ case 11:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "ROFL you suck " + victim.name + "!!" );
+ break;
+
+ case 12:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Wow that was a lucky shot!" );
+ break;
+
+ case 13:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Thats right, i totally pwnd your ass!" );
+ break;
+
+ case 14:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Don't even think that i am hacking cause that was pure skill!" );
+ break;
+
+ case 15:
+ message = ( "LOL xD xDDDD " + victim.name + " sucks! HAHA ROFLMAO" );
+ break;
+
+ case 16:
+ message = ( "Wow that was an easy kill." );
+ break;
+
+ case 17:
+ message = ( "noob down" );
+ break;
+
+ case 18:
+ message = ( "Lol u suck " + victim.name );
+ break;
+
+ case 19:
+ message = ( "PWND!" );
+ break;
+
+ case 20:
+ message = ( "sit down " + victim.name );
+ break;
+
+ case 21:
+ message = ( "wow that was close, but i still got you ;)" );
+ break;
+
+ case 22:
+ message = ( "oooooo! i got u good!" );
+ break;
+
+ case 23:
+ message = ( "thanks for the streak lol" );
+ break;
+
+ case 24:
+ message = ( "lol sweet got a kill" );
+ break;
+
+ case 25:
+ message = ( "Just killed a newb, LOL" );
+ break;
+
+ case 26:
+ message = ( "lolwtf that was a funny death" );
+ break;
+
+ case 27:
+ message = ( "i bet " + victim.name + " is using the arrow keys to move." );
+ break;
+
+ case 28:
+ message = ( "lol its noobs like " + victim.name + " that ruin teams" );
+ break;
+
+ case 29:
+ message = ( "lolwat was that " + victim.name + "?" );
+ break;
+
+ case 30:
+ message = ( "haha thanks " + victim.name + ", im at a " + self.cur_kill_streak + " streak." );
+ break;
+
+ case 31:
+ message = ( "lol " + victim.name + " is at a " + victim.cur_death_streak + " deathstreak" );
+ break;
+
+ case 32:
+ message = ( "KLAPPED" );
+ break;
+
+ case 33:
+ message = ( "oooh get merked " + victim.name );
+ break;
+
+ case 34:
+ message = ( "i love " + getMapName( getdvar( "mapname" ) ) + "!" );
+ break;
+
+ case 35:
+ message = ( getMapName( getdvar( "mapname" ) ) + " is my favorite map!" );
+ break;
+
+ case 36:
+ message = ( "get rekt" );
+ break;
+
+ case 37:
+ message = ( "lol i rekt " + victim.name );
+ break;
+
+ case 38:
+ message = ( "lol ur mum can play better than u!" );
+ break;
+
+ case 39:
+ message = ( victim.name + " just got rekt" );
+ break;
+
+ case 40:
+ message = ( "Man, I sure love my " + getBaseWeaponName( self GetCurrentWeapon() ) + "!" );
+
+ break;
+
+ case 41:
+ message = ( "lol u got killed " + victim.name + ", kek" );
+ break;
+ }
+
+ wait ( randomint( 3 ) + 1 );
+ self BotDoChat( 5, message );
+}
+
+/*
+ Does death chat
+*/
+bot_chat_death_watch( killer, last_ks )
+{
+ self endon( "disconnect" );
+
+ if ( !isDefined( killer ) || !isDefined( killer.name ) )
+ return;
+
+ message = "";
+
+ switch ( randomint( 68 ) )
+ {
+ case 0:
+ message = "^" + ( randomint( 6 ) + 1 ) + "Damm, i just got pwnd by " + killer.name;
+ break;
+
+ case 1:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Hax ! Hax ! Hax !" );
+ break;
+
+ case 2:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "WOW n1 " + killer.name );
+ break;
+
+ case 3:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "How the?? How did you do that " + killer.name + "?" );
+ break;
+
+ case 4:
+ if ( last_ks > 0 )
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Nooooooooo my killstreaks!! :( I had a " + last_ks + " killstreak!!" );
+ else
+ message = ( "man im getting spawn killed, i have a " + self.cur_death_streak + " deathstreak!" );
+
+ break;
+
+ case 5:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Stop Spawn KILLING!!!" );
+ break;
+
+ case 6:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Haha Well done " + killer.name );
+ break;
+
+ case 7:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Agggghhhh " + killer.name + " you are such a noob!!!!" );
+ break;
+
+ case 8:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "n1 " + killer.name );
+ break;
+
+ case 9:
+ message = ( "Sigh at my lag, it's totally killing me.. ^2Just Look at my ^1Ping!" );
+ break;
+
+ case 10:
+ message = ( "omg wow that was LEGENDARY, well done " + killer.name );
+ break;
+
+ case 11:
+ message = ( "Today is defnitly not my day" );
+ break;
+
+ case 12:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "Aaaaaaaagh!!!" );
+ break;
+
+ case 13:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + " Dude What the hell, " + killer.name + " is such a HACKER!! " );
+ break;
+
+ case 14:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + killer.name + " you Wallhacker!" );
+ break;
+
+ case 15:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "This is so frustrating!" );
+ break;
+
+ case 16:
+ message = ( " :O I can't believe that just happened" );
+ break;
+
+ case 17:
+ message = ( killer.name + " you ^1Noooo^2ooooooooo^3ooooo^5b" );
+ break;
+
+ case 18:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "LOL, " + killer.name + " how did you kill me?" );
+ break;
+
+ case 19:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "laaaaaaaaaaaaaaaaaaaag" );
+ break;
+
+ case 20:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "i hate this map!" );
+ break;
+
+ case 21:
+ message = ( killer.name + " You tanker!!" );
+ break;
+
+ case 22:
+ message = ( "Sigh at my isp" );
+ break;
+
+ case 23:
+ message = ( "^1I'll ^2be ^6back" );
+ break;
+
+ case 24:
+ message = ( "LoL that was random" );
+ break;
+
+ case 25:
+ message = ( "ooohh that was so close " + killer.name + " and you know it !! " );
+ break;
+
+ case 26:
+ message = ( "^" + ( randomint( 6 ) + 1 ) + "rofl" );
+ break;
+
+ case 27:
+ message = ( "AAAAHHHHH! WTF! IM GOING TO KILL YOU " + killer.name );
+ break;
+
+ case 28:
+ message = ( "AHH! IM DEAD BECAUSE " + level.players[randomint( level.players.size )].name + " is a noob!" );
+ break;
+
+ case 29:
+ message = ( level.players[randomint( level.players.size )].name + ", please don't talk." );
+ break;
+
+ case 30:
+ message = ( "Wow " + level.players[randomint( level.players.size )].name + " is a blocker noob!" );
+ break;
+
+ case 31:
+ message = ( "Next time GET OUT OF MY WAY " + level.players[randomint( level.players.size )].name + "!!" );
+ break;
+
+ case 32:
+ message = ( "Wow, I'm dead because " + killer.name + " is a tryhard..." );
+ break;
+
+ case 33:
+ message = ( "Try harder " + killer.name + " please!" );
+ break;
+
+ case 34:
+ message = ( "I bet " + killer.name + "'s fingers are about to break." );
+ break;
+
+ case 35:
+ message = ( "WOW, USE A REAL GUN " + killer.name + "!" );
+ break;
+
+ case 36:
+ message = ( "k wtf. " + killer.name + " is hacking" );
+ break;
+
+ case 37:
+ message = ( "nice wallhacks " + killer.name );
+ break;
+
+ case 38:
+ message = ( "wh " + killer.name );
+ break;
+
+ case 39:
+ message = ( "cheetos!" );
+ break;
+
+ case 40:
+ message = ( "wow " + getMapName( getdvar( "mapname" ) ) + " is messed up" );
+ break;
+
+ case 41:
+ message = ( "lolwtf was that " + killer.name + "?" );
+ break;
+
+ case 42:
+ message = ( "admin pls ban " + killer.name );
+ break;
+
+ case 43:
+ message = ( "WTF IS WITH THESE SPAWNS??" );
+ break;
+
+ case 44:
+ message = ( "im getting owned lol..." );
+ break;
+
+ case 45:
+ message = ( "someone kill " + killer.name + ", they are on a streak of " + killer.cur_kill_streak + "!" );
+ break;
+
+ case 46:
+ message = ( "man i died" );
+ break;
+
+ case 47:
+ message = ( "nice noob gun " + killer.name );
+ break;
+
+ case 48:
+ message = ( "stop camping " + killer.name + "!" );
+ break;
+
+ case 49:
+ message = ( "k THERE IS NOTHING I CAN DO ABOUT DYING!!" );
+ break;
+
+ case 50:
+ message = ( "aw" );
+ break;
+
+ case 51:
+ message = ( "lol " + getMapName( getdvar( "mapname" ) ) + " sux" );
+ break;
+
+ case 52:
+ message = ( "why are we even playing on " + getMapName( getdvar( "mapname" ) ) + "?" );
+ break;
+
+ case 53:
+ message = ( getMapName( getdvar( "mapname" ) ) + " is such an unfair map!!" );
+ break;
+
+ case 54:
+ message = ( "what were they thinking when making " + getMapName( getdvar( "mapname" ) ) + "?!" );
+ break;
+
+ case 55:
+ message = ( killer.name + " totally just destroyed me!" );
+ break;
+
+ case 56:
+ message = ( "can i be admen plz? so i can ban " + killer.name );
+ break;
+
+ case 57:
+ message = ( "wow " + killer.name + " is such a no life!!" );
+ break;
+
+ case 58:
+ message = ( "man i got rekt by " + killer.name );
+ break;
+
+ case 59:
+ message = ( "admen pls ben " + killer.name );
+ break;
+
+ case 60:
+ message = "Wow! Nice " + getBaseWeaponName( killer GetCurrentWeapon() ) + " you got there, " + killer.name + "!";
+
+ break;
+
+ case 61:
+ message = ( "you are so banned " + killer.name );
+ break;
+
+ case 62:
+ message = ( "recorded reported and deported! " + killer.name );
+ break;
+
+ case 63:
+ message = ( "hack name " + killer.name + "?" );
+ break;
+
+ case 64:
+ message = ( "dude can you send me that hack " + killer.name + "?" );
+ break;
+
+ case 65:
+ message = ( "nice aimbot " + killer.name + "!!1" );
+ break;
+
+ case 66:
+ message = ( "you are benned " + killer.name + "!!" );
+ break;
+
+ case 67:
+ message = ( "that was topkek " + killer.name );
+ break;
+ }
+
+ wait ( randomint( 3 ) + 1 );
+ self BotDoChat( 8, message );
+}
+
+/*
+ Killcam
+*/
+bot_chat_killcam_watch( state, b, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomInt( 2 ) )
+ {
+ case 0:
+ self BotDoChat( 1, "WTF?!?!?!! Dude youre a hacker and a half!!" );
+ break;
+
+ case 1:
+ self BotDoChat( 1, "Haa! Got my fraps ready, time to watch this killcam." );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomInt( 2 ) )
+ {
+ case 0:
+ self BotDoChat( 1, "Wow... Im reporting you!!!" );
+ break;
+
+ case 1:
+ self BotDoChat( 1, "Got it on fraps!" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ Stuck
+*/
+bot_chat_stuck_watch( a, b, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ sayLength = randomintRange( 5, 30 );
+ msg = "";
+
+ for ( i = 0; i < sayLength; i++ )
+ {
+ switch ( randomint( 9 ) )
+ {
+ case 0:
+ msg = msg + "w";
+ break;
+
+ case 1:
+ msg = msg + "s";
+ break;
+
+ case 2:
+ msg = msg + "d";
+ break;
+
+ case 3:
+ msg = msg + "a";
+ break;
+
+ case 4:
+ msg = msg + " ";
+ break;
+
+ case 5:
+ msg = msg + "W";
+ break;
+
+ case 6:
+ msg = msg + "S";
+ break;
+
+ case 7:
+ msg = msg + "D";
+ break;
+
+ case 8:
+ msg = msg + "A";
+ break;
+ }
+ }
+
+ self BotDoChat( 20, msg );
+}
+
+/*
+ Tube
+*/
+bot_chat_tube_watch( state, tubeWp, tubeWeap, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "go":
+ switch ( randomInt( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "i am going to go tube" );
+ break;
+ }
+
+ break;
+
+ case "start":
+ switch ( randomInt( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "i tubed" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_killstreak_watch( streakName, b, c, d, e, f, g )
+*/
+bot_chat_killstreak_watch( state, location, directionYaw, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "call":
+ if ( self.pers["hardPointItem"] == "helicopter_mp" )
+ {
+ self BotDoChat( 20, "wewt! i got the choppa!!" );
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_attack_vehicle_watch( a, b, c, d, e, f, g )
+*/
+bot_chat_attack_vehicle_watch( state, vehicle, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomint( 14 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "Not on my watch..." );
+ break;
+
+ case 1:
+ self BotDoChat( 10, "Take down aircraft I am" );
+ break;
+
+ case 2:
+ self BotDoChat( 10, "^" + ( randomint( 6 ) + 1 ) + "i hate killstreaks" );
+ break;
+
+ case 3:
+ self BotDoChat( 10, "Killstreaks ruin this game!!" );
+ break;
+
+ case 4:
+ self BotDoChat( 10, "killstreaks sux" );
+ break;
+
+ case 5:
+ self BotDoChat( 10, "keep the killstreaks comin'" );
+ break;
+
+ case 6:
+ self BotDoChat( 10, "lol see that killstreak? its going to go BOOM!" );
+ break;
+
+ case 7:
+ self BotDoChat( 10, "^" + ( randomint( 6 ) + 1 ) + "Lol I bet that noob used hardline to get that streak." );
+ break;
+
+ case 8:
+ self BotDoChat( 10, "WOW HOW DO YOU GET THAT?? ITS GONE NOW." );
+ break;
+
+ case 9:
+ self BotDoChat( 10, "HAHA say goodbye to your killstreak" );
+ break;
+
+ case 10:
+ self BotDoChat( 10, "All your effort is gone now." );
+ break;
+
+ case 11:
+ self BotDoChat( 10, "I hope there are flares on that killstreak." );
+ break;
+
+ case 12:
+ self BotDoChat( 10, "lol u silly, i'm taking down killstreaks :3 xDD" );
+ break;
+
+ case 13:
+ weap = "rpg_mp";
+
+ if ( !self GetAmmoCount( "weap" ) )
+ weap = self getCurrentWeapon();
+
+ self BotDoChat( 10, "Im going to takedown your ks with my " + getBaseWeaponName( weap ) );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ break;
+ }
+}
+
+/*
+ bot_chat_follow_threat_watch( a, b, c, d, e, f, g )
+*/
+bot_chat_follow_threat_watch( state, threat, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+}
+
+/*
+ bot_chat_camp_watch( a, b, c, d, e, f, g )
+*/
+bot_chat_camp_watch( state, wp, time, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "go":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "going to camp for " + time + " seconds" );
+ break;
+
+ case 1:
+ self BotDoChat( 10, "time to go camp!" );
+ break;
+
+ case 2:
+ self BotDoChat( 10, "rofl im going to camp" );
+ break;
+ }
+
+ break;
+
+ case "start":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "well im camping... this is fun!" );
+ break;
+
+ case 1:
+ self BotDoChat( 10, "lol im camping, hope i kill someone" );
+ break;
+
+ case 2:
+ self BotDoChat( 10, "im camping! i guess ill wait " + time + " before moving again" );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "finished camping.." );
+ break;
+
+ case 1:
+ self BotDoChat( 10, "wow that was a load of camping!" );
+ break;
+
+ case 2:
+ self BotDoChat( 10, "well its been over " + time + " seconds, i guess ill stop camping" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_follow_watch( a, b, c, d, e, f, g )
+*/
+bot_chat_follow_watch( state, player, time, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomint( 3 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "well im going to follow " + player.name + " for " + time + " seconds" );
+ break;
+
+ case 1:
+ self BotDoChat( 10, "Lets go together " + player.name + " <3 :)" );
+ break;
+
+ case 2:
+ self BotDoChat( 10, "lets be butt buddies " + player.name + " and ill follow you!" );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomint( 2 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "well that was fun following " + player.name + " for " + time + " seconds" );
+ break;
+
+ case 1:
+ self BotDoChat( 10, "im done following that guy" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_equ_watch
+*/
+bot_chat_equ_watch( state, wp, weap, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "go":
+ switch ( randomInt( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "going to place a " + getBaseWeaponName( weap ) );
+ break;
+ }
+
+ break;
+
+ case "start":
+ switch ( randomInt( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "placed a " + getBaseWeaponName( weap ) );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_nade_watch
+*/
+bot_chat_nade_watch( state, wp, weap, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "go":
+ switch ( randomInt( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "going to throw a " + getBaseWeaponName( weap ) );
+ break;
+ }
+
+ break;
+
+ case "start":
+ switch ( randomInt( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "threw a " + getBaseWeaponName( weap ) );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_throwback_watch
+*/
+bot_chat_throwback_watch( state, nade, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "i am going to throw back the grenade!" );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "i threw back the grenade!" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_tbag_watch
+*/
+bot_chat_tbag_watch( state, who, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "go":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 50, "Im going to go tBag XD" );
+ break;
+ }
+
+ break;
+
+ case "start":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 50, "Im going to tBag XD" );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 50, "Awwww yea... How do you like that? XD" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_rage_watch
+*/
+bot_chat_rage_watch( state, b, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomint( 5 ) )
+ {
+ case 0:
+ self BotDoChat( 80, "K this is not going as I planned." );
+ break;
+
+ case 1:
+ self BotDoChat( 80, "Screw this! I'm out." );
+ break;
+
+ case 2:
+ self BotDoChat( 80, "Have fun being owned." );
+ break;
+
+ case 3:
+ self BotDoChat( 80, "MY TEAM IS GARBAGE!" );
+ break;
+
+ case 4:
+ self BotDoChat( 80, "kthxbai hackers" );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_revenge_watch
+*/
+bot_chat_revenge_watch( state, loc, killer, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "Im going to check out my death location." );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 10, "i checked out my deathlocation..." );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_heard_target_watch
+*/
+bot_chat_heard_target_watch( state, heard, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 5, "I think I hear " + heard.name + "..." );
+ break;
+ }
+
+ break;
+
+ case "stop":
+ switch ( randomint( 1 ) )
+ {
+ case 0:
+ self BotDoChat( 5, "Well i checked out " + heard.name + "'s location..." );
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_uav_target_watch
+*/
+bot_chat_uav_target_watch( state, heard, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+}
+
+/*
+ bot_chat_attack_equ_watch
+*/
+bot_chat_attack_equ_watch( state, equ, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+}
+
+/*
+ bot_chat_dom_watch
+*/
+bot_chat_dom_watch( state, sub_state, flag, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( sub_state )
+ {
+ case "spawnkill":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "defend":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "cap":
+ switch ( state )
+ {
+ case "go":
+ break;
+
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_hq_watch
+*/
+bot_chat_hq_watch( state, sub_state, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( sub_state )
+ {
+ case "cap":
+ switch ( state )
+ {
+ case "go":
+ break;
+
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "defend":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_sab_watch
+*/
+bot_chat_sab_watch( state, sub_state, c, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( sub_state )
+ {
+ case "bomb":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "defuser":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "planter":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "plant":
+ switch ( state )
+ {
+ case "go":
+ break;
+
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "defuse":
+ switch ( state )
+ {
+ case "go":
+ break;
+
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+ }
+}
+
+/*
+ bot_chat_sd_watch
+*/
+bot_chat_sd_watch( state, sub_state, obj, d, e, f, g )
+{
+ self endon( "disconnect" );
+
+ switch ( sub_state )
+ {
+ case "bomb":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "defuser":
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "planter":
+ site = obj;
+
+ switch ( state )
+ {
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "plant":
+ site = obj;
+
+ switch ( state )
+ {
+ case "go":
+ break;
+
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+
+ case "defuse":
+ switch ( state )
+ {
+ case "go":
+ break;
+
+ case "start":
+ break;
+
+ case "stop":
+ break;
+ }
+
+ break;
+ }
+}
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_http.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_http.gsc
index 1d9f1a6..2bb3c40 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_http.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_http.gsc
@@ -10,35 +10,35 @@
/*
Will attempt to retreive waypoints from the internet
*/
-getRemoteWaypoints(mapname)
+getRemoteWaypoints( mapname )
{
url = "https://raw.githubusercontent.com/ineedbots/cod4x_waypoints/master/" + mapname + "_wp.csv";
filename = "waypoints/" + mapname + "_wp.csv";
- printToConsole("Attempting to get remote waypoints from " + url);
- res = getLinesFromUrl(url, filename);
+ printToConsole( "Attempting to get remote waypoints from " + url );
+ res = getLinesFromUrl( url, filename );
- if (!res.lines.size)
+ if ( !res.lines.size )
return;
- waypointCount = int(res.lines[0]);
+ waypointCount = int( res.lines[0] );
waypoints = [];
- printToConsole("Loading remote waypoints...");
+ printToConsole( "Loading remote waypoints..." );
- for (i = 1; i <= waypointCount; i++)
+ for ( i = 1; i <= waypointCount; i++ )
{
- tokens = tokenizeLine(res.lines[i], ",");
-
- waypoint = parseTokensIntoWaypoint(tokens);
+ tokens = tokenizeLine( res.lines[i], "," );
- waypoints[i-1] = waypoint;
+ waypoint = parseTokensIntoWaypoint( tokens );
+
+ waypoints[i - 1] = waypoint;
}
- if (waypoints.size)
+ if ( waypoints.size )
{
level.waypoints = waypoints;
- printToConsole("Loaded " + waypoints.size + " waypoints from remote.");
+ printToConsole( "Loaded " + waypoints.size + " waypoints from remote." );
}
}
@@ -49,20 +49,20 @@ doVersionCheck()
{
remoteVersion = getRemoteVersion();
- if (!isDefined(remoteVersion))
+ if ( !isDefined( remoteVersion ) )
{
- printToConsole("Error getting remote version of Bot Warfare.");
+ printToConsole( "Error getting remote version of Bot Warfare." );
return false;
}
- if (level.bw_VERSION != remoteVersion)
+ if ( level.bw_VERSION != remoteVersion )
{
- printToConsole("There is a new version of Bot Warfare!");
- printToConsole("You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!");
+ printToConsole( "There is a new version of Bot Warfare!" );
+ printToConsole( "You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!" );
return false;
}
- printToConsole("You are on the latest version of Bot Warfare!");
+ printToConsole( "You are on the latest version of Bot Warfare!" );
return true;
}
@@ -77,16 +77,16 @@ getRemoteVersion()
data = undefined;
#endif
- if (!isDefined(data))
+ if ( !isDefined( data ) )
return undefined;
- return strtok(data, "\n")[0];
+ return strtok( data, "\n" )[0];
}
/*
Returns an array of each line from the response of the http url request
*/
-getLinesFromUrl(url, filename)
+getLinesFromUrl( url, filename )
{
result = spawnStruct();
result.lines = [];
@@ -97,25 +97,26 @@ getLinesFromUrl(url, filename)
data = undefined;
#endif
- if (!isDefined(data))
+ if ( !isDefined( data ) )
return result;
- fd = FS_FOpen(filename, "write");
+ fd = FS_FOpen( filename, "write" );
line = "";
- for (i=0;i 0)
+ if ( fd > 0 )
{
- if (!FS_WriteLine(fd, line))
+ if ( !FS_WriteLine( fd, line ) )
{
- FS_FClose(fd);
+ FS_FClose( fd );
fd = 0;
}
}
@@ -126,10 +127,11 @@ getLinesFromUrl(url, filename)
line += c;
}
+
result.lines[result.lines.size] = line;
- if (fd > 0)
- FS_FClose(fd);
+ if ( fd > 0 )
+ FS_FClose( fd );
return result;
}
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_internal.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_internal.gsc
index 803fd83..eaa86c3 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_internal.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_internal.gsc
@@ -9,10 +9,10 @@
*/
added()
{
- self endon("disconnect");
-
+ self endon( "disconnect" );
+
self.pers["bots"] = [];
-
+
self.pers["bots"]["skill"] = [];
self.pers["bots"]["skill"]["base"] = 7; // a base knownledge of the bot
self.pers["bots"]["skill"]["aim_time"] = 0.05; // how long it takes for a bot to aim to a location
@@ -23,7 +23,7 @@ added()
self.pers["bots"]["skill"]["remember_time"] = 25000; // how long a bot will remember a target before forgetting about it when they cant see the target
self.pers["bots"]["skill"]["fov"] = -1; // the fov of the bot, -1 being 360, 1 being 0
self.pers["bots"]["skill"]["dist_max"] = 100000 * 2; // the longest distance a bot will target
- self.pers["bots"]["skill"]["dist_start"] = 100000; // the start distance before bot's target abilitys diminish
+ self.pers["bots"]["skill"]["dist_start"] = 100000; // the start distance before bot's target abilitys diminish
self.pers["bots"]["skill"]["spawn_time"] = 0; // how long a bot waits after spawning before targeting, etc
self.pers["bots"]["skill"]["help_dist"] = 10000; // how far a bot has awareness
self.pers["bots"]["skill"]["semi_time"] = 0.05; // how fast a bot shoots semiauto
@@ -34,7 +34,7 @@ added()
self.pers["bots"]["skill"]["bones"] = "j_head"; // a list of comma seperated bones the bot will aim at
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; // a factor of how much ads to reduce when adsing
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; // a factor of how much more aimspeed delay to add
-
+
self.pers["bots"]["behavior"] = [];
self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target
self.pers["bots"]["behavior"]["nade"] = 50; // percentage of how often the bot will grenade
@@ -56,12 +56,12 @@ added()
*/
connected()
{
- self endon("disconnect");
-
+ self endon( "disconnect" );
+
self.bot = spawnStruct();
self.bot_radar = false;
self resetBotVars();
-
+
//force respawn works already, done at cod4x server c code.
self thread onPlayerSpawned();
self thread bot_skip_killcam();
@@ -73,11 +73,11 @@ connected()
*/
onUAVUpdate()
{
- self endon("disconnect");
-
- for(;;)
+ self endon( "disconnect" );
+
+ for ( ;; )
{
- self waittill("radar_timer_kill");
+ self waittill( "radar_timer_kill" );
self thread doUAVUpdate();
}
}
@@ -87,27 +87,27 @@ onUAVUpdate()
*/
doUAVUpdate()
{
- self endon("disconnect");
- self endon("radar_timer_kill");
-
+ self endon( "disconnect" );
+ self endon( "radar_timer_kill" );
+
self.bot_radar = true;//wtf happened to hasRadar? its bugging out, something other than script is touching it
-
+
wait level.radarViewTime;
-
+
self.bot_radar = false;
}
/*
The callback hook for when the bot gets killed.
*/
-onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
+onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
}
/*
The callback hook when the bot gets damaged.
*/
-onDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
+onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
{
}
@@ -123,12 +123,12 @@ resetBotVars()
self.bot.target_this_frame = undefined;
self.bot.after_target = undefined;
self.bot.after_target_pos = undefined;
-
+
self.bot.script_aimpos = undefined;
-
+
self.bot.script_goal = undefined;
self.bot.script_goal_dist = 0.0;
-
+
self.bot.next_wp = -1;
self.bot.second_next_wp = -1;
self.bot.towards_goal = undefined;
@@ -138,7 +138,7 @@ resetBotVars()
self.bot.climbing = false;
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
-
+
self.bot.isfrozen = false;
self.bot.sprintendtime = -1;
self.bot.isreloading = false;
@@ -149,17 +149,17 @@ resetBotVars()
self.bot.issmokingafter = false;
self.bot.isknifing = false;
self.bot.isknifingafter = false;
-
+
self.bot.semi_time = false;
self.bot.jump_time = undefined;
self.bot.last_fire_time = -1;
-
+
self.bot.is_cur_full_auto = false;
self.bot.cur_weap_dist_multi = 1;
self.bot.is_cur_sniper = false;
-
- self.bot.rand = randomInt(100);
-
+
+ self.bot.rand = randomInt( 100 );
+
self botStop();
}
@@ -168,16 +168,16 @@ resetBotVars()
*/
bot_skip_killcam()
{
- level endon("game_ended");
- self endon("disconnect");
-
- for(;;)
+ level endon( "game_ended" );
+ self endon( "disconnect" );
+
+ for ( ;; )
{
wait 1;
-
- if(isDefined(self.killcam))
+
+ if ( isDefined( self.killcam ) )
{
- self notify("end_killcam");
+ self notify( "end_killcam" );
}
}
}
@@ -187,19 +187,19 @@ bot_skip_killcam()
*/
onPlayerSpawned()
{
- self endon("disconnect");
-
- for(;;)
+ self endon( "disconnect" );
+
+ for ( ;; )
{
- self waittill("spawned_player");
-
+ self waittill( "spawned_player" );
+
self resetBotVars();
self thread onWeaponChange();
self thread onLastStand();
-
+
self thread reload_watch();
self thread sprint_watch();
-
+
self thread spawned();
}
}
@@ -209,11 +209,11 @@ onPlayerSpawned()
*/
spawned()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
wait self.pers["bots"]["skill"]["spawn_time"];
-
+
self thread grenade_danger();
self thread check_reload();
self thread stance();
@@ -225,8 +225,33 @@ spawned()
self thread onNewEnemy();
self thread doBotMovement();
self thread watchGrenadeFire();
-
- self notify("bot_spawned");
+ self thread watchPickupGun();
+
+ self notify( "bot_spawned" );
+}
+
+/*
+ watchPickupGun
+*/
+watchPickupGun()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
+ {
+ wait 1;
+
+ if ( self UseButtonPressed() )
+ continue;
+
+ weap = self GetCurrentWeapon();
+
+ if ( weap != "none" && self GetAmmoCount( weap ) )
+ continue;
+
+ self thread use( 0.5 );
+ }
}
/*
@@ -234,132 +259,155 @@ spawned()
*/
watchGrenadeFire()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
- for (;;)
+ for ( ;; )
{
self waittill( "grenade_fire", nade, weapname );
+ if ( !isDefined( nade ) )
+ continue;
+
if ( weapname == "c4_mp" )
- self thread watchC4Thrown(nade);
+ self thread watchC4Thrown( nade );
}
}
/*
Watches the c4
*/
-watchC4Thrown(c4)
+watchC4Thrown( c4 )
{
- self endon("disconnect");
- c4 endon("death");
+ self endon( "disconnect" );
+ c4 endon( "death" );
wait 0.5;
- for (;;)
+ for ( ;; )
{
- wait 1 + randomInt(50) * 0.05;
+ wait 1 + randomInt( 50 ) * 0.05;
shouldBreak = false;
- for (i = 0; i < level.players.size; i++)
+
+ for ( i = 0; i < level.players.size; i++ )
{
player = level.players[i];
-
- if(player == self)
+
+ if ( player == self )
continue;
- if((level.teamBased && self.team == player.team) || player.sessionstate != "playing" || !isAlive(player))
+ if ( ( level.teamBased && self.team == player.team ) || player.sessionstate != "playing" || !isAlive( player ) )
continue;
- if (distanceSquared(c4.origin, player.origin) > 200*200)
+ if ( distanceSquared( c4.origin, player.origin ) > 200 * 200 )
continue;
- if (!bulletTracePassed(c4.origin, player.origin + (0, 0, 25), false, c4))
+ if ( !bulletTracePassed( c4.origin, player.origin + ( 0, 0, 25 ), false, c4 ) )
continue;
shouldBreak = true;
}
- if (shouldBreak)
+ if ( shouldBreak )
break;
}
- weap = self getCurrentWeapon();
- if ( weap != "c4_mp" )
+ if ( self getCurrentWeapon() != "c4_mp" )
self notify( "alt_detonate" );
else
self thread pressFire();
}
+/*
+ Bot moves towards the point
+*/
+doBotMovement_loop( data )
+{
+ angles = self GetPlayerAngles();
+
+ // climb through windows
+ if ( self isMantling() )
+ {
+ data.wasMantling = true;
+ self crouch();
+ }
+ else if ( data.wasMantling )
+ {
+ data.wasMantling = false;
+ self stand();
+ }
+
+ startPos = self.origin + ( 0, 0, 50 );
+ startPosForward = startPos + anglesToForward( ( 0, angles[1], 0 ) ) * 25;
+ bt = bulletTrace( startPos, startPosForward, false, self );
+
+ if ( bt["fraction"] >= 1 )
+ {
+ // check if need to jump
+ bt = bulletTrace( startPosForward, startPosForward - ( 0, 0, 40 ), false, self );
+
+ if ( bt["fraction"] < 1 && bt["normal"][2] > 0.9 && data.i > 1.5 && !self isOnLadder() )
+ {
+ data.i = 0;
+ self thread jump();
+ }
+ }
+ // check if need to knife glass
+ else if ( bt["surfacetype"] == "glass" )
+ {
+ if ( data.i > 1.5 )
+ {
+ data.i = 0;
+ self thread knife();
+ }
+ }
+ else
+ {
+ // check if need to crouch
+ if ( bulletTracePassed( startPos - ( 0, 0, 25 ), startPosForward - ( 0, 0, 25 ), false, self ) && !self.bot.climbing )
+ self crouch();
+ }
+}
+
/*
Bot moves towards the point
*/
doBotMovement()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
- FORWARDAMOUNT = 25;
+ data = spawnStruct();
+ data.wasMantling = false;
- for (i = 0;;i+=0.05)
+ for ( data.i = 0; true; data.i += 0.05 )
{
wait 0.05;
- angles = self GetPlayerAngles();
-
- // climb through windows
- if (self isMantling())
- self crouch();
-
-
- startPos = self.origin + (0, 0, 50);
- startPosForward = startPos + anglesToForward((0, angles[1], 0)) * FORWARDAMOUNT;
- bt = bulletTrace(startPos, startPosForward, false, self);
- if (bt["fraction"] >= 1)
- {
- // check if need to jump
- bt = bulletTrace(startPosForward, startPosForward - (0, 0, 40), false, self);
-
- if (bt["fraction"] < 1 && bt["normal"][2] > 0.9 && i > 1.5 && !self isOnLadder())
- {
- i = 0;
- self thread jump();
- }
- }
- // check if need to knife glass
- else if (bt["surfacetype"] == "glass")
- {
- if (i > 1.5)
- {
- i = 0;
- self thread knife();
- }
- }
- else
- {
- // check if need to crouch
- if (bulletTracePassed(startPos - (0, 0, 25), startPosForward - (0, 0, 25), false, self))
- self crouch();
- }
+ self doBotMovement_loop( data );
}
}
/*
Sets the factor of distance for a weapon
*/
-SetWeaponDistMulti(weap)
+SetWeaponDistMulti( weap )
{
- if (weap == "none")
+ if ( weap == "none" )
return 1;
- switch(weaponClass(weap))
+ switch ( weaponClass( weap ) )
{
case "rifle":
return 0.9;
+
case "smg":
return 0.7;
+
case "pistol":
return 0.5;
+
default:
return 1;
}
@@ -368,14 +416,14 @@ SetWeaponDistMulti(weap)
/*
Is the weap a sniper
*/
-IsWeapSniper(weap)
+IsWeapSniper( weap )
{
- if (weap == "none")
+ if ( weap == "none" )
return false;
-
- if (maps\mp\gametypes\_missions::getWeaponClass(weap) != "weapon_sniper")
+
+ if ( maps\mp\gametypes\_missions::getWeaponClass( weap ) != "weapon_sniper" )
return false;
-
+
return true;
}
@@ -384,50 +432,59 @@ IsWeapSniper(weap)
*/
watchHoldBreath()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
wait 1;
-
- if(self.bot.isfrozen)
+
+ if ( self.bot.isfrozen )
continue;
-
- self holdbreath(self playerADS() > 0);
+
+ self holdbreath( self playerADS() > 0 );
}
}
+/*
+ When the bot enters laststand, we fix the weapons
+*/
+onLastStand_loop()
+{
+ while ( !self inLastStand() )
+ wait 0.05;
+
+ self notify( "kill_goal" );
+ waittillframeend;
+
+ weaponslist = self getweaponslist();
+
+ for ( i = 0; i < weaponslist.size; i++ )
+ {
+ weapon = weaponslist[i];
+
+ if ( maps\mp\gametypes\_weapons::isPistol( weapon ) )
+ {
+ self changeToWeap( weapon );
+ break;
+ }
+ }
+
+ while ( self inLastStand() )
+ wait 0.05;
+}
+
/*
When the bot enters laststand, we fix the weapons
*/
onLastStand()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
- while (true)
+ while ( true )
{
- while (!self inLastStand())
- wait 0.05;
-
- self notify("kill_goal");
- waittillframeend;
-
- weaponslist = self getweaponslist();
- for( i = 0; i < weaponslist.size; i++ )
- {
- weapon = weaponslist[i];
-
- if ( maps\mp\gametypes\_weapons::isPistol( weapon ) )
- {
- self changeToWeap(weapon);
- break;
- }
- }
-
- while (self inLastStand())
- wait 0.05;
+ self onLastStand_loop();
}
}
@@ -436,29 +493,31 @@ onLastStand()
*/
onWeaponChange()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
first = true;
- for(;;)
+
+ for ( ;; )
{
newWeapon = undefined;
- if (first)
+
+ if ( first )
{
first = false;
newWeapon = self getCurrentWeapon();
}
else
self waittill( "weapon_change", newWeapon );
-
- self.bot.is_cur_full_auto = WeaponIsFullAuto(newWeapon);
- self.bot.cur_weap_dist_multi = SetWeaponDistMulti(newWeapon);
- self.bot.is_cur_sniper = IsWeapSniper(newWeapon);
- if (newWeapon == "none")
+ self.bot.is_cur_full_auto = WeaponIsFullAuto( newWeapon );
+ self.bot.cur_weap_dist_multi = SetWeaponDistMulti( newWeapon );
+ self.bot.is_cur_sniper = IsWeapSniper( newWeapon );
+
+ if ( newWeapon == "none" )
continue;
-
- self changeToWeap(newWeapon);
+
+ self changeToWeap( newWeapon );
}
}
@@ -467,116 +526,139 @@ onWeaponChange()
*/
sprint_watch()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
- self waittill("sprint_begin");
+ self waittill( "sprint_begin" );
self.bot.issprinting = true;
- self waittill("sprint_end");
+ self waittill( "sprint_end" );
self.bot.issprinting = false;
self.bot.sprintendtime = getTime();
}
}
+/*
+ Update's the bot if it is reloading.
+*/
+reload_watch_loop()
+{
+ self.bot.isreloading = true;
+
+ while ( true )
+ {
+ ret = self waittill_any_timeout( 7.5, "reload" );
+
+ if ( ret == "timeout" )
+ break;
+
+ weap = self GetCurrentWeapon();
+
+ if ( weap == "none" )
+ break;
+
+ if ( self GetWeaponAmmoClip( weap ) >= WeaponClipSize( weap ) )
+ break;
+ }
+
+ self.bot.isreloading = false;
+}
+
/*
Update's the bot if it is reloading.
*/
reload_watch()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
- self waittill("reload_start");
- self.bot.isreloading = true;
+ self waittill( "reload_start" );
- while(true)
- {
- ret = self waittill_any_timeout(7.5, "reload");
-
- if (ret == "timeout")
- break;
-
- weap = self GetCurrentWeapon();
- if (self GetWeaponAmmoClip(weap) >= WeaponClipSize(weap))
- break;
- }
- self.bot.isreloading = false;
+ self reload_watch_loop();
}
}
+/*
+ Bots will update its needed stance according to the nodes on the level. Will also allow the bot to sprint when it can.
+*/
+stance_loop()
+{
+ self.bot.climbing = false;
+
+ if ( self.bot.isfrozen )
+ return;
+
+ toStance = "stand";
+
+ if ( self.bot.next_wp != -1 )
+ toStance = level.waypoints[self.bot.next_wp].type;
+
+ if ( !isDefined( toStance ) )
+ toStance = "crouch";
+
+ if ( toStance == "stand" && randomInt( 100 ) <= self.pers["bots"]["behavior"]["crouch"] )
+ toStance = "crouch";
+
+ if ( toStance == "climb" )
+ {
+ self.bot.climbing = true;
+ toStance = "stand";
+ }
+
+ if ( toStance != "stand" && toStance != "crouch" && toStance != "prone" )
+ toStance = "crouch";
+
+ if ( toStance == "stand" )
+ self stand();
+ else if ( toStance == "crouch" )
+ self crouch();
+ else
+ self prone();
+
+ curweap = self getCurrentWeapon();
+ time = getTime();
+ chance = self.pers["bots"]["behavior"]["sprint"];
+
+ if ( time - self.lastSpawnTime < 5000 )
+ chance *= 2;
+
+ if ( isDefined( self.bot.script_goal ) && DistanceSquared( self.origin, self.bot.script_goal ) > 256 * 256 )
+ chance *= 2;
+
+ if ( toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter )
+ return;
+
+ if ( randomInt( 100 ) > chance )
+ return;
+
+ if ( isDefined( self.bot.target ) && self canFire( curweap ) && self isInRange( self.bot.target.dist, curweap ) )
+ return;
+
+ if ( self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000 )
+ return;
+
+ if ( !isDefined( self.bot.towards_goal ) || DistanceSquared( self.origin, physicsTrace( self getEyePos(), self getEyePos() + anglesToForward( self getPlayerAngles() ) * 1024, false, undefined ) ) < level.bots_minSprintDistance || getConeDot( self.bot.towards_goal, self.origin, self GetPlayerAngles() ) < 0.75 )
+ return;
+
+ self thread sprint();
+}
+
/*
Bots will update its needed stance according to the nodes on the level. Will also allow the bot to sprint when it can.
*/
stance()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
- self waittill_either("finished_static_waypoints", "new_static_waypoint");
+ self waittill_either( "finished_static_waypoints", "new_static_waypoint" );
- self.bot.climbing = false;
-
- if(self.bot.isfrozen)
- continue;
-
- toStance = "stand";
- if(self.bot.next_wp != -1)
- toStance = level.waypoints[self.bot.next_wp].type;
-
- if (!isDefined(toStance))
- toStance = "crouch";
-
- if(toStance == "climb")
- {
- self.bot.climbing = true;
- toStance = "stand";
- }
-
- if(toStance != "stand" && toStance != "crouch" && toStance != "prone")
- toStance = "crouch";
-
- if(toStance == "stand" && randomInt(100) <= self.pers["bots"]["behavior"]["crouch"])
- toStance = "crouch";
-
- if(toStance == "stand")
- self stand();
- else if(toStance == "crouch")
- self crouch();
- else
- self prone();
-
- curweap = self getCurrentWeapon();
- time = getTime();
- chance = self.pers["bots"]["behavior"]["sprint"];
-
- if (time - self.lastSpawnTime < 5000)
- chance *= 2;
-
- if(isDefined(self.bot.script_goal) && DistanceSquared(self.origin, self.bot.script_goal) > 256*256)
- chance *= 2;
-
- if(toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter)
- continue;
-
- if(randomInt(100) > chance)
- continue;
-
- if(isDefined(self.bot.target) && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
- continue;
-
- if(self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000)
- continue;
-
- if(!isDefined(self.bot.towards_goal) || DistanceSquared(self.origin, self.bot.towards_goal) < level.bots_minSprintDistance || getConeDot(self.bot.towards_goal, self.origin, self GetPlayerAngles()) < 0.75)
- continue;
-
- self thread sprint();
+ self stance_loop();
}
}
@@ -585,59 +667,60 @@ stance()
*/
grenade_danger()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
- self waittill("grenade danger", grenade, attacker, weapname);
-
- if(!isDefined(grenade))
+ self waittill( "grenade danger", grenade, attacker, weapname );
+
+ if ( !isDefined( grenade ) )
continue;
- if (!getDvarInt("bots_play_nade"))
+ if ( !getDvarInt( "bots_play_nade" ) )
continue;
-
- if(weapname != "frag_grenade_mp")
+
+ if ( weapname != "frag_grenade_mp" )
continue;
-
- if(isDefined(attacker) && level.teamBased && attacker.team == self.team)
+
+ if ( isDefined( attacker ) && level.teamBased && attacker.team == self.team )
continue;
-
- self thread watch_grenade(grenade);
+
+ self thread watch_grenade( grenade );
}
}
/*
Bot will throw back the given grenade if it is close, will watch until it is deleted or close.
*/
-watch_grenade(grenade)
+watch_grenade( grenade )
{
- self endon("disconnect");
- self endon("death");
- grenade endon("death");
-
- while(1)
+ self endon( "disconnect" );
+ self endon( "death" );
+ grenade endon( "death" );
+
+ while ( 1 )
{
wait 1;
-
- if(!isDefined(grenade))
+
+ if ( !isDefined( grenade ) )
{
return;
}
-
- if(self.bot.isfrozen)
+
+ if ( self.bot.isfrozen )
continue;
-
- if(!bulletTracePassed(self getEyePos(), grenade.origin, false, grenade))
+
+ if ( !bulletTracePassed( self getEyePos(), grenade.origin, false, grenade ) )
continue;
-
- if(DistanceSquared(self.origin, grenade.origin) > 20000)
+
+ if ( DistanceSquared( self.origin, grenade.origin ) > 20000 )
continue;
-
- if(self.bot.isfraggingafter || self.bot.issmokingafter)
+
+ if ( self.bot.isfraggingafter || self.bot.issmokingafter )
continue;
-
+
+ self BotNotifyBotEvent( "throwback", "stop", grenade );
self thread frag();
}
}
@@ -647,10 +730,10 @@ watch_grenade(grenade)
*/
check_reload()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
self waittill_notify_or_timeout( "weapon_fired", 5 );
self thread reload_thread();
@@ -662,27 +745,27 @@ check_reload()
*/
reload_thread()
{
- self endon("disconnect");
- self endon("death");
- self endon("weapon_fired");
-
+ self endon( "disconnect" );
+ self endon( "death" );
+ self endon( "weapon_fired" );
+
wait 2.5;
-
- if(isDefined(self.bot.target) || self.bot.isreloading || self.bot.isfraggingafter || self.bot.issmokingafter || self.bot.isfrozen)
+
+ if ( isDefined( self.bot.target ) || self.bot.isreloading || self.bot.isfraggingafter || self.bot.issmokingafter || self.bot.isfrozen )
return;
-
+
cur = self getCurrentWEapon();
- if (cur == "" || cur == "none")
+ if ( cur == "" || cur == "none" )
return;
-
- if(IsWeaponClipOnly(cur) || !self GetWeaponAmmoStock(cur))
+
+ if ( IsWeaponClipOnly( cur ) || !self GetWeaponAmmoStock( cur ) )
return;
-
- maxsize = WeaponClipSize(cur);
- cursize = self GetWeaponammoclip(cur);
-
- if(cursize/maxsize < 0.5)
+
+ maxsize = WeaponClipSize( cur );
+ cursize = self GetWeaponammoclip( cur );
+
+ if ( cursize / maxsize < 0.5 )
self thread reload();
}
@@ -691,39 +774,39 @@ reload_thread()
*/
updateBones()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
- bones = strtok(self.pers["bots"]["skill"]["bones"], ",");
+ bones = strtok( self.pers["bots"]["skill"]["bones"], "," );
waittime = self.pers["bots"]["skill"]["bone_update_interval"];
-
- for(;;)
- {
- self waittill_notify_or_timeout("new_enemy", waittime);
- if (!isDefined(self.bot.target))
+ for ( ;; )
+ {
+ self waittill_notify_or_timeout( "new_enemy", waittime );
+
+ if ( !isDefined( self.bot.target ) )
continue;
- self.bot.target.bone = random(bones);
+ self.bot.target.bone = random( bones );
}
}
/*
Creates the base target obj
*/
-createTargetObj(ent, theTime)
+createTargetObj( ent, theTime )
{
obj = spawnStruct();
obj.entity = ent;
- obj.last_seen_pos = (0, 0, 0);
+ obj.last_seen_pos = ( 0, 0, 0 );
obj.dist = 0;
obj.time = theTime;
obj.trace_time = 0;
obj.no_trace_time = 0;
obj.trace_time_time = 0;
- obj.rand = randomInt(100);
+ obj.rand = randomInt( 100 );
obj.didlook = false;
- obj.isplay = isPlayer(ent);
+ obj.isplay = isPlayer( ent );
obj.offset = undefined;
obj.bone = undefined;
obj.aim_offset = undefined;
@@ -735,24 +818,24 @@ createTargetObj(ent, theTime)
/*
Updates the target object's difficulty missing aim, inaccurate shots
*/
-updateAimOffset(obj)
+updateAimOffset( obj )
{
- if (!isDefined(obj.aim_offset_base))
+ if ( !isDefined( obj.aim_offset_base ) )
{
diffAimAmount = self.pers["bots"]["skill"]["aim_offset_amount"];
- if (diffAimAmount > 0)
- obj.aim_offset_base = (randomFloatRange(0-diffAimAmount, diffAimAmount),
- randomFloatRange(0-diffAimAmount, diffAimAmount),
- randomFloatRange(0-diffAimAmount, diffAimAmount));
+ if ( diffAimAmount > 0 )
+ obj.aim_offset_base = ( randomFloatRange( 0 - diffAimAmount, diffAimAmount ),
+ randomFloatRange( 0 - diffAimAmount, diffAimAmount ),
+ randomFloatRange( 0 - diffAimAmount, diffAimAmount ) );
else
- obj.aim_offset_base = (0,0,0);
+ obj.aim_offset_base = ( 0, 0, 0 );
}
aimDiffTime = self.pers["bots"]["skill"]["aim_offset_time"] * 1000;
objCreatedFor = obj.trace_time;
- if (objCreatedFor >= aimDiffTime)
+ if ( objCreatedFor >= aimDiffTime )
offsetScalar = 0;
else
offsetScalar = 1 - objCreatedFor / aimDiffTime;
@@ -763,7 +846,7 @@ updateAimOffset(obj)
/*
Updates the target object to be traced Has LOS
*/
-targetObjUpdateTraced(obj, daDist, ent, theTime, isScriptObj)
+targetObjUpdateTraced( obj, daDist, ent, theTime, isScriptObj )
{
distClose = self.pers["bots"]["skill"]["dist_start"];
distClose *= self.bot.cur_weap_dist_multi;
@@ -774,27 +857,28 @@ targetObjUpdateTraced(obj, daDist, ent, theTime, isScriptObj)
distMax *= distMax;
timeMulti = 1;
- if (!isScriptObj)
+
+ if ( !isScriptObj )
{
- if (daDist > distMax)
+ if ( daDist > distMax )
timeMulti = 0;
- else if (daDist > distClose)
- timeMulti = 1 - ((daDist - distClose) / (distMax - distClose));
+ else if ( daDist > distClose )
+ timeMulti = 1 - ( ( daDist - distClose ) / ( distMax - distClose ) );
}
obj.no_trace_time = 0;
- obj.trace_time += int(50 * timeMulti);
+ obj.trace_time += int( 50 * timeMulti );
obj.dist = daDist;
obj.last_seen_pos = ent.origin;
obj.trace_time_time = theTime;
- self updateAimOffset(obj);
+ self updateAimOffset( obj );
}
/*
Updates the target object to be not traced No LOS
*/
-targetObjUpdateNoTrace(obj)
+targetObjUpdateNoTrace( obj )
{
obj.no_trace_time += 50;
obj.trace_time = 0;
@@ -804,201 +888,226 @@ targetObjUpdateNoTrace(obj)
/*
The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets.
*/
-target()
+target_loop()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ myEye = self GetEyePos();
+ theTime = getTime();
+ myAngles = self GetPlayerAngles();
+ myFov = self.pers["bots"]["skill"]["fov"];
+ bestTargets = [];
+ bestTime = 2147483647;
+ rememberTime = self.pers["bots"]["skill"]["remember_time"];
+ initReactTime = self.pers["bots"]["skill"]["init_react_time"];
+ hasTarget = isDefined( self.bot.target );
+ adsAmount = self PlayerADS();
+ adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"];
+
+ // reduce fov if ads'ing
+ if ( adsAmount > 0 )
{
- wait 0.05;
-
- if(self maps\mp\_flashgrenades::isFlashbanged())
- continue;
-
- myEye = self GetEyePos();
- theTime = getTime();
- myAngles = self GetPlayerAngles();
- myFov = self.pers["bots"]["skill"]["fov"];
- bestTargets = [];
- bestTime = 2147483647;
- rememberTime = self.pers["bots"]["skill"]["remember_time"];
- initReactTime = self.pers["bots"]["skill"]["init_react_time"];
- hasTarget = isDefined(self.bot.target);
- adsAmount = self PlayerADS();
- adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"];
+ myFov *= 1 - adsFovFact * adsAmount;
+ }
- // reduce fov if ads'ing
- if (adsAmount > 0)
- {
- myFov *= 1 - adsFovFact * adsAmount;
- }
-
- if(hasTarget && !isDefined(self.bot.target.entity))
- {
- self.bot.target = undefined;
- hasTarget = false;
- }
-
- playercount = level.players.size;
- for(i = -1; i < playercount; i++)
- {
- obj = undefined;
+ if ( hasTarget && !isDefined( self.bot.target.entity ) )
+ {
+ self.bot.target = undefined;
+ hasTarget = false;
+ }
- if (i == -1)
+ playercount = level.players.size;
+
+ for ( i = -1; i < playercount; i++ )
+ {
+ obj = undefined;
+
+ if ( i == -1 )
+ {
+ if ( !isDefined( self.bot.script_target ) )
+ continue;
+
+ ent = self.bot.script_target;
+ key = ent getEntityNumber() + "";
+ daDist = distanceSquared( self.origin, ent.origin );
+ obj = self.bot.targets[key];
+ isObjDef = isDefined( obj );
+ entOrigin = ent.origin;
+
+ if ( isDefined( self.bot.script_target_offset ) )
+ entOrigin += self.bot.script_target_offset;
+
+ if ( SmokeTrace( myEye, entOrigin, level.smokeRadius ) && bulletTracePassed( myEye, entOrigin, false, ent ) )
{
- if(!isDefined(self.bot.script_target))
- continue;
-
- ent = self.bot.script_target;
- key = ent getEntityNumber()+"";
- daDist = distanceSquared(self.origin, ent.origin);
- obj = self.bot.targets[key];
- isObjDef = isDefined(obj);
- entOrigin = ent.origin;
- if (isDefined(self.bot.script_target_offset))
- entOrigin += self.bot.script_target_offset;
-
- if(SmokeTrace(myEye, entOrigin, level.smokeRadius) && bulletTracePassed(myEye, entOrigin, false, ent))
+ if ( !isObjDef )
{
- if(!isObjDef)
- {
- obj = self createTargetObj(ent, theTime);
- obj.offset = self.bot.script_target_offset;
-
- self.bot.targets[key] = obj;
- }
-
- self targetObjUpdateTraced(obj, daDist, ent, theTime, true);
- }
- else
- {
- if(!isObjDef)
- continue;
-
- self targetObjUpdateNoTrace(obj);
-
- if(obj.no_trace_time > rememberTime)
- {
- self.bot.targets[key] = undefined;
- continue;
- }
+ obj = self createTargetObj( ent, theTime );
+ obj.offset = self.bot.script_target_offset;
+
+ self.bot.targets[key] = obj;
}
+
+ self targetObjUpdateTraced( obj, daDist, ent, theTime, true );
}
else
{
- player = level.players[i];
-
- if(!player IsPlayerModelOK())
+ if ( !isObjDef )
continue;
- if(player == self)
+
+ self targetObjUpdateNoTrace( obj );
+
+ if ( obj.no_trace_time > rememberTime )
+ {
+ self.bot.targets[key] = undefined;
continue;
-
- key = player getEntityNumber()+"";
- obj = self.bot.targets[key];
- daDist = distanceSquared(self.origin, player.origin);
- isObjDef = isDefined(obj);
- if((level.teamBased && self.team == player.team) || player.sessionstate != "playing" || !isAlive(player))
- {
- if(isObjDef)
- self.bot.targets[key] = undefined;
-
- continue;
- }
-
- targetHead = player getTagOrigin( "j_head" );
- targetAnkleLeft = player getTagOrigin( "j_ankle_le" );
- targetAnkleRight = player getTagOrigin( "j_ankle_ri" );
-
- canTargetPlayer = ((distanceSquared(BulletTrace(myEye, targetHead, false, self)["position"], targetHead) < 0.05 ||
- distanceSquared(BulletTrace(myEye, targetAnkleLeft, false, self)["position"], targetAnkleLeft) < 0.05 ||
- distanceSquared(BulletTrace(myEye, targetAnkleRight, false, self)["position"], targetAnkleRight) < 0.05)
-
- && (SmokeTrace(myEye, player.origin, level.smokeRadius) ||
- daDist < level.bots_maxKnifeDistance*4)
-
- && (getConeDot(player.origin, self.origin, myAngles) >= myFov ||
- (isObjDef && obj.trace_time)));
-
- if (isDefined(self.bot.target_this_frame) && self.bot.target_this_frame == player)
- {
- self.bot.target_this_frame = undefined;
-
- canTargetPlayer = true;
- }
-
- if(canTargetPlayer)
- {
- if(!isObjDef)
- {
- obj = self createTargetObj(player, theTime);
-
- self.bot.targets[key] = obj;
- }
-
- self targetObjUpdateTraced(obj, daDist, player, theTime, false);
- }
- else
- {
- if(!isObjDef)
- continue;
-
- self targetObjUpdateNoTrace(obj);
-
- if(obj.no_trace_time > rememberTime)
- {
- self.bot.targets[key] = undefined;
- continue;
- }
}
}
+ }
+ else
+ {
+ player = level.players[i];
- if (!isdefined(obj))
+ if ( !player IsPlayerModelOK() )
continue;
-
- if(theTime - obj.time < initReactTime)
+
+ if ( player == self )
continue;
-
- timeDiff = theTime - obj.trace_time_time;
- if(timeDiff < bestTime)
+
+ key = player getEntityNumber() + "";
+ obj = self.bot.targets[key];
+ daDist = distanceSquared( self.origin, player.origin );
+ isObjDef = isDefined( obj );
+
+ if ( ( level.teamBased && self.team == player.team ) || player.sessionstate != "playing" || !isAlive( player ) )
{
- bestTargets = [];
- bestTime = timeDiff;
- }
-
- if(timeDiff == bestTime)
- bestTargets[key] = obj;
- }
-
- if(hasTarget && isDefined(bestTargets[self.bot.target.entity getEntityNumber()+""]))
- continue;
-
- closest = 2147483647;
- toBeTarget = undefined;
-
- bestKeys = getArrayKeys(bestTargets);
- for(i = bestKeys.size - 1; i >= 0; i--)
- {
- theDist = bestTargets[bestKeys[i]].dist;
- if(theDist > closest)
+ if ( isObjDef )
+ self.bot.targets[key] = undefined;
+
continue;
-
- closest = theDist;
- toBeTarget = bestTargets[bestKeys[i]];
+ }
+
+ targetHead = player getTagOrigin( "j_head" );
+ targetAnkleLeft = player getTagOrigin( "j_ankle_le" );
+ targetAnkleRight = player getTagOrigin( "j_ankle_ri" );
+
+ traceHead = bulletTrace( myEye, targetHead, false, undefined );
+ traceAnkleLeft = bulletTrace( myEye, targetAnkleLeft, false, undefined );
+ traceAnkleRight = bulletTrace( myEye, targetAnkleRight, false, undefined );
+
+ canTargetPlayer = ( ( sightTracePassed( myEye, targetHead, false, undefined ) ||
+ sightTracePassed( myEye, targetAnkleLeft, false, undefined ) ||
+ sightTracePassed( myEye, targetAnkleRight, false, undefined ) )
+
+ && ( ( traceHead["fraction"] >= 1.0 || traceHead["surfacetype"] == "glass" ) ||
+ ( traceAnkleLeft["fraction"] >= 1.0 || traceAnkleLeft["surfacetype"] == "glass" ) ||
+ ( traceAnkleRight["fraction"] >= 1.0 || traceAnkleRight["surfacetype"] == "glass" ) )
+
+ && ( SmokeTrace( myEye, player.origin, level.smokeRadius ) ||
+ daDist < level.bots_maxKnifeDistance * 4 )
+
+ && ( getConeDot( player.origin, self.origin, myAngles ) >= myFov ||
+ ( isObjDef && obj.trace_time ) ) );
+
+ if ( isDefined( self.bot.target_this_frame ) && self.bot.target_this_frame == player )
+ {
+ self.bot.target_this_frame = undefined;
+
+ canTargetPlayer = true;
+ }
+
+ if ( canTargetPlayer )
+ {
+ if ( !isObjDef )
+ {
+ obj = self createTargetObj( player, theTime );
+
+ self.bot.targets[key] = obj;
+ }
+
+ self targetObjUpdateTraced( obj, daDist, player, theTime, false );
+ }
+ else
+ {
+ if ( !isObjDef )
+ continue;
+
+ self targetObjUpdateNoTrace( obj );
+
+ if ( obj.no_trace_time > rememberTime )
+ {
+ self.bot.targets[key] = undefined;
+ continue;
+ }
+ }
}
-
- beforeTargetID = -1;
- newTargetID = -1;
- if(hasTarget && isDefined(self.bot.target.entity))
- beforeTargetID = self.bot.target.entity getEntityNumber();
- if(isDefined(toBeTarget) && isDefined(toBeTarget.entity))
- newTargetID = toBeTarget.entity getEntityNumber();
-
- if(beforeTargetID != newTargetID)
+
+ if ( !isdefined( obj ) )
+ continue;
+
+ if ( theTime - obj.time < initReactTime )
+ continue;
+
+ timeDiff = theTime - obj.trace_time_time;
+
+ if ( timeDiff < bestTime )
{
- self.bot.target = toBeTarget;
- self notify("new_enemy");
+ bestTargets = [];
+ bestTime = timeDiff;
}
+
+ if ( timeDiff == bestTime )
+ bestTargets[key] = obj;
+ }
+
+ if ( hasTarget && isDefined( bestTargets[self.bot.target.entity getEntityNumber() + ""] ) )
+ return;
+
+ closest = 2147483647;
+ toBeTarget = undefined;
+
+ bestKeys = getArrayKeys( bestTargets );
+
+ for ( i = bestKeys.size - 1; i >= 0; i-- )
+ {
+ theDist = bestTargets[bestKeys[i]].dist;
+
+ if ( theDist > closest )
+ continue;
+
+ closest = theDist;
+ toBeTarget = bestTargets[bestKeys[i]];
+ }
+
+ beforeTargetID = -1;
+ newTargetID = -1;
+
+ if ( hasTarget && isDefined( self.bot.target.entity ) )
+ beforeTargetID = self.bot.target.entity getEntityNumber();
+
+ if ( isDefined( toBeTarget ) && isDefined( toBeTarget.entity ) )
+ newTargetID = toBeTarget.entity getEntityNumber();
+
+ if ( beforeTargetID != newTargetID )
+ {
+ self.bot.target = toBeTarget;
+ self notify( "new_enemy" );
+ }
+}
+
+/*
+ The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets.
+*/
+target()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
+ {
+ wait 0.05;
+
+ if ( self maps\mp\_flashgrenades::isFlashbanged() )
+ continue;
+
+ self target_loop();
}
}
@@ -1007,22 +1116,22 @@ target()
*/
onNewEnemy()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
- self waittill("new_enemy");
-
- if(!isDefined(self.bot.target))
+ self waittill( "new_enemy" );
+
+ if ( !isDefined( self.bot.target ) )
continue;
-
- if(!isDefined(self.bot.target.entity) || !self.bot.target.isplay)
+
+ if ( !isDefined( self.bot.target.entity ) || !self.bot.target.isplay )
continue;
-
- if(self.bot.target.didlook)
+
+ if ( self.bot.target.didlook )
continue;
-
+
self thread watchToLook();
}
}
@@ -1032,88 +1141,85 @@ onNewEnemy()
*/
watchToLook()
{
- self endon("disconnect");
- self endon("death");
- self endon("new_enemy");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+ self endon( "new_enemy" );
+
+ for ( ;; )
{
- while(isDefined(self.bot.target) && self.bot.target.didlook)
+ while ( isDefined( self.bot.target ) && self.bot.target.didlook )
wait 0.05;
-
- while(isDefined(self.bot.target) && self.bot.target.no_trace_time)
+
+ while ( isDefined( self.bot.target ) && self.bot.target.no_trace_time )
wait 0.05;
-
- if(!isDefined(self.bot.target))
+
+ if ( !isDefined( self.bot.target ) )
break;
-
+
self.bot.target.didlook = true;
-
- if(self.bot.isfrozen)
- continue;
-
- if(self.bot.target.dist > level.bots_maxShotgunDistance*2)
- continue;
-
- if(self.bot.target.dist <= level.bots_maxKnifeDistance)
- continue;
-
- curweap = self getCurrentWEapon();
- if(!self canFire(curweap))
- continue;
-
- if(!self isInRange(self.bot.target.dist, curweap))
+
+ if ( self.bot.isfrozen )
continue;
- if (self.bot.is_cur_sniper)
- continue;
-
- if(randomInt(100) > self.pers["bots"]["behavior"]["jump"])
+ if ( self.bot.target.dist > level.bots_maxShotgunDistance * 2 )
continue;
- if (!getDvarInt("bots_play_jumpdrop"))
+ if ( self.bot.target.dist <= level.bots_maxKnifeDistance )
continue;
-
- thetime = getTime();
- if(isDefined(self.bot.jump_time) && thetime - self.bot.jump_time <= 5000)
+
+ if ( !self canFire( self getCurrentWEapon() ) )
continue;
-
- if(self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"])
+
+ if ( !self isInRange( self.bot.target.dist, self getCurrentWEapon() ) )
+ continue;
+
+ if ( self.bot.is_cur_sniper )
+ continue;
+
+ if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["jump"] )
+ continue;
+
+ if ( !getDvarInt( "bots_play_jumpdrop" ) )
+ continue;
+
+ if ( isDefined( self.bot.jump_time ) && getTime() - self.bot.jump_time <= 5000 )
+ continue;
+
+ if ( self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"] )
{
- if(self getStance() != "stand")
+ if ( self getStance() != "stand" )
continue;
-
- self.bot.jump_time = thetime;
+
+ self.bot.jump_time = getTime();
self jump();
}
else
{
- if(getConeDot(self.bot.target.last_seen_pos, self.origin, self getPlayerAngles()) < 0.8 || self.bot.target.dist <= level.bots_noADSDistance)
+ if ( getConeDot( self.bot.target.last_seen_pos, self.origin, self getPlayerAngles() ) < 0.8 || self.bot.target.dist <= level.bots_noADSDistance )
continue;
-
- self.bot.jump_time = thetime;
+
+ self.bot.jump_time = getTime();
self prone();
- self notify("kill_goal");
+ self notify( "kill_goal" );
wait 2.5;
self crouch();
}
}
}
-
/*
Assigns the bot's after target (bot will keep firing at a target after no sight or death)
*/
-start_bot_after_target(who)
+start_bot_after_target( who )
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
self.bot.after_target = who;
self.bot.after_target_pos = who.origin;
- self notify("kill_after_target");
- self endon("kill_after_target");
+ self notify( "kill_after_target" );
+ self endon( "kill_after_target" );
wait self.pers["bots"]["skill"]["shoot_after_time"];
@@ -1126,7 +1232,267 @@ start_bot_after_target(who)
clear_bot_after_target()
{
self.bot.after_target = undefined;
- self notify("kill_after_target");
+ self notify( "kill_after_target" );
+}
+
+/*
+ This is the bot's main aimming thread. The bot will aim at its targets or a node its going towards. Bots will aim, fire, ads, grenade.
+*/
+aim_loop()
+{
+ aimspeed = self.pers["bots"]["skill"]["aim_time"];
+
+ if ( self IsStunned() || self isArtShocked() )
+ aimspeed = 1;
+
+ eyePos = self getEyePos();
+ curweap = self getCurrentWeapon();
+ angles = self GetPlayerAngles();
+ adsAmount = self PlayerADS();
+ adsAimSpeedFact = self.pers["bots"]["skill"]["ads_aimspeed_multi"];
+
+ // reduce aimspeed if ads'ing
+ if ( adsAmount > 0 )
+ {
+ aimspeed *= 1 + adsAimSpeedFact * adsAmount;
+ }
+
+ if ( isDefined( self.bot.target ) && isDefined( self.bot.target.entity ) )
+ {
+ no_trace_time = self.bot.target.no_trace_time;
+ no_trace_look_time = self.pers["bots"]["skill"]["no_trace_look_time"];
+
+ if ( no_trace_time <= no_trace_look_time )
+ {
+ trace_time = self.bot.target.trace_time;
+ last_pos = self.bot.target.last_seen_pos;
+ target = self.bot.target.entity;
+ conedot = 0;
+ isplay = self.bot.target.isplay;
+
+ offset = self.bot.target.offset;
+
+ if ( !isDefined( offset ) )
+ offset = ( 0, 0, 0 );
+
+ aimoffset = self.bot.target.aim_offset;
+
+ if ( !isDefined( aimoffset ) )
+ aimoffset = ( 0, 0, 0 );
+
+ dist = self.bot.target.dist;
+ rand = self.bot.target.rand;
+ no_trace_ads_time = self.pers["bots"]["skill"]["no_trace_ads_time"];
+ reaction_time = self.pers["bots"]["skill"]["reaction_time"];
+ nadeAimOffset = 0;
+
+ bone = self.bot.target.bone;
+
+ if ( !isDefined( bone ) )
+ bone = "j_spineupper";
+
+ if ( self.bot.isfraggingafter || self.bot.issmokingafter )
+ nadeAimOffset = dist / 3000;
+ else if ( curweap != "none" && weaponClass( curweap ) == "grenade" )
+ {
+ if ( maps\mp\gametypes\_missions::getWeaponClass( curweap ) == "weapon_projectile" )
+ nadeAimOffset = dist / 16000;
+ else
+ nadeAimOffset = dist / 3000;
+ }
+
+ if ( no_trace_time && ( !isDefined( self.bot.after_target ) || self.bot.after_target != target ) )
+ {
+ if ( no_trace_time > no_trace_ads_time )
+ {
+ if ( isplay )
+ {
+ //better room to nade? cook time function with dist?
+ if ( !self.bot.isfraggingafter && !self.bot.issmokingafter )
+ {
+ nade = self getValidGrenade();
+
+ if ( isDefined( nade ) && rand <= self.pers["bots"]["behavior"]["nade"] && bulletTracePassed( eyePos, eyePos + ( 0, 0, 75 ), false, self ) && bulletTracePassed( last_pos, last_pos + ( 0, 0, 100 ), false, target ) && dist > level.bots_minGrenadeDistance && dist < level.bots_maxGrenadeDistance && getDvarInt( "bots_play_nade" ) )
+ {
+ if ( nade == "frag_grenade_mp" )
+ self thread frag( 2.5 );
+ else
+ self thread smoke( 0.5 );
+
+ self notify( "kill_goal" );
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( self canAds( dist, curweap ) )
+ {
+ if ( !self.bot.is_cur_sniper || !self.pers["bots"]["behavior"]["quickscope"] )
+ self thread pressAds();
+ }
+ }
+
+ if ( getDvarInt( "bots_play_aim" ) )
+ self botLookAt( last_pos + ( 0, 0, self getEyeHeight() + nadeAimOffset ), aimspeed );
+
+ return;
+ }
+
+ if ( trace_time )
+ {
+ if ( isplay )
+ {
+ if ( !target IsPlayerModelOK() )
+ return;
+
+ aimpos = target getTagOrigin( bone );
+
+ if ( !isDefined( aimpos ) )
+ return;
+
+ aimpos += offset;
+ aimpos += aimoffset;
+ aimpos += ( 0, 0, nadeAimOffset );
+
+ conedot = getConeDot( aimpos, eyePos, angles );
+
+ if ( getDvarInt( "bots_play_aim" ) )
+ {
+ if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 )
+ self botLookAtPlayer( target, bone );
+ else
+ self botLookAt( aimpos, aimspeed );
+ }
+ }
+ else
+ {
+ aimpos = target.origin;
+ aimpos += offset;
+ aimpos += aimoffset;
+ aimpos += ( 0, 0, nadeAimOffset );
+
+ conedot = getConeDot( aimpos, eyePos, angles );
+
+ if ( getDvarInt( "bots_play_aim" ) )
+ self botLookAt( aimpos, aimspeed );
+ }
+
+ if ( isplay && !self.bot.isknifingafter && conedot > 0.9 && dist < level.bots_maxKnifeDistance && trace_time > reaction_time && getDvarInt( "bots_play_knife" ) )
+ {
+ self clear_bot_after_target();
+ self thread knife();
+ return;
+ }
+
+ if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) )
+ return;
+
+ canADS = ( self canAds( dist, curweap ) && conedot > 0.75 );
+
+ if ( canADS )
+ {
+ stopAdsOverride = false;
+
+ if ( self.bot.is_cur_sniper )
+ {
+ if ( self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000 )
+ stopAdsOverride = true;
+ else
+ self notify( "kill_goal" );
+ }
+
+ if ( !stopAdsOverride )
+ self thread pressAds();
+ }
+
+ if ( trace_time > reaction_time )
+ {
+ if ( ( !canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone" ) && ( conedot > 0.99 || dist < level.bots_maxKnifeDistance ) && getDvarInt( "bots_play_fire" ) )
+ self botFire();
+
+ if ( isplay )
+ self thread start_bot_after_target( target );
+ }
+
+ return;
+ }
+ }
+ }
+
+ if ( isDefined( self.bot.after_target ) )
+ {
+ nadeAimOffset = 0;
+ last_pos = self.bot.after_target_pos;
+ dist = DistanceSquared( self.origin, last_pos );
+
+ if ( self.bot.isfraggingafter || self.bot.issmokingafter )
+ nadeAimOffset = dist / 3000;
+ else if ( curweap != "none" && weaponClass( curweap ) == "grenade" )
+ {
+ if ( maps\mp\gametypes\_missions::getWeaponClass( curweap ) == "weapon_projectile" )
+ nadeAimOffset = dist / 16000;
+ else
+ nadeAimOffset = dist / 3000;
+ }
+
+ aimpos = last_pos + ( 0, 0, self getEyeHeight() + nadeAimOffset );
+ conedot = getConeDot( aimpos, eyePos, angles );
+
+ if ( getDvarInt( "bots_play_aim" ) )
+ self botLookAt( aimpos, aimspeed );
+
+ if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) )
+ return;
+
+ canADS = ( self canAds( dist, curweap ) && conedot > 0.75 );
+
+ if ( canADS )
+ {
+ stopAdsOverride = false;
+
+ if ( self.bot.is_cur_sniper )
+ {
+ if ( self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000 )
+ stopAdsOverride = true;
+ else
+ self notify( "kill_goal" );
+ }
+
+ if ( !stopAdsOverride )
+ self thread pressAds();
+ }
+
+ if ( ( !canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone" ) && ( conedot > 0.95 || dist < level.bots_maxKnifeDistance ) && getDvarInt( "bots_play_fire" ) )
+ self botFire();
+
+ return;
+ }
+
+ if ( self.bot.next_wp != -1 && isDefined( level.waypoints[self.bot.next_wp].angles ) && false )
+ {
+ forwardPos = anglesToForward( level.waypoints[self.bot.next_wp].angles ) * 1024;
+
+ if ( getDvarInt( "bots_play_aim" ) )
+ self botLookAt( eyePos + forwardPos, aimspeed );
+ }
+ else if ( isDefined( self.bot.script_aimpos ) )
+ {
+ if ( getDvarInt( "bots_play_aim" ) )
+ self botLookAt( self.bot.script_aimpos, aimspeed );
+ }
+ else
+ {
+ lookat = undefined;
+
+ if ( self.bot.second_next_wp != -1 && !self.bot.issprinting && !self.bot.climbing )
+ lookat = level.waypoints[self.bot.second_next_wp].origin;
+ else if ( isDefined( self.bot.towards_goal ) )
+ lookat = self.bot.towards_goal;
+
+ if ( isDefined( lookat ) && getDvarInt( "bots_play_aim" ) )
+ self botLookAt( lookat + ( 0, 0, self getEyeHeight() ), aimspeed );
+ }
}
/*
@@ -1134,242 +1500,17 @@ clear_bot_after_target()
*/
aim()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
wait 0.05;
-
- if(level.inPrematchPeriod || level.gameEnded || self.bot.isfrozen || self maps\mp\_flashgrenades::isFlashbanged())
+
+ if ( level.inPrematchPeriod || level.gameEnded || self.bot.isfrozen || self maps\mp\_flashgrenades::isFlashbanged() )
continue;
-
- aimspeed = self.pers["bots"]["skill"]["aim_time"];
- if(self IsStunned() || self isArtShocked())
- aimspeed = 1;
-
- eyePos = self getEyePos();
- curweap = self getCurrentWeapon();
- angles = self GetPlayerAngles();
- adsAmount = self PlayerADS();
- adsAimSpeedFact = self.pers["bots"]["skill"]["ads_aimspeed_multi"];
-
- // reduce aimspeed if ads'ing
- if (adsAmount > 0)
- {
- aimspeed *= 1 + adsAimSpeedFact * adsAmount;
- }
-
- if(isDefined(self.bot.target) && isDefined(self.bot.target.entity))
- {
- no_trace_time = self.bot.target.no_trace_time;
- no_trace_look_time = self.pers["bots"]["skill"]["no_trace_look_time"];
-
- if (no_trace_time <= no_trace_look_time)
- {
- trace_time = self.bot.target.trace_time;
- last_pos = self.bot.target.last_seen_pos;
- target = self.bot.target.entity;
- conedot = 0;
- isplay = self.bot.target.isplay;
-
- offset = self.bot.target.offset;
- if (!isDefined(offset))
- offset = (0, 0, 0);
-
- aimoffset = self.bot.target.aim_offset;
- if (!isDefined(aimoffset))
- aimoffset = (0, 0, 0);
-
- dist = self.bot.target.dist;
- rand = self.bot.target.rand;
- no_trace_ads_time = self.pers["bots"]["skill"]["no_trace_ads_time"];
- reaction_time = self.pers["bots"]["skill"]["reaction_time"];
- nadeAimOffset = 0;
-
- bone = self.bot.target.bone;
- if (!isDefined(bone))
- bone = "j_spineupper";
-
- if(self.bot.isfraggingafter || self.bot.issmokingafter)
- nadeAimOffset = dist/3000;
- else if(curweap != "none" && weaponClass(curweap) == "grenade")
- nadeAimOffset = dist/16000;
-
- if(no_trace_time && (!isDefined(self.bot.after_target) || self.bot.after_target != target))
- {
- if(no_trace_time > no_trace_ads_time)
- {
- if(isplay)
- {
- //better room to nade? cook time function with dist?
- if(!self.bot.isfraggingafter && !self.bot.issmokingafter)
- {
- nade = self getValidGrenade();
- if(isDefined(nade) && rand <= self.pers["bots"]["behavior"]["nade"] && bulletTracePassed(eyePos, eyePos + (0, 0, 75), false, self) && bulletTracePassed(last_pos, last_pos + (0, 0, 100), false, target) && dist > level.bots_minGrenadeDistance && dist < level.bots_maxGrenadeDistance && getDvarInt("bots_play_nade"))
- {
- if(nade == "frag_grenade_mp")
- self thread frag(2.5);
- else
- self thread smoke(0.5);
-
- self notify("kill_goal");
- }
- }
- }
- }
- else
- {
- if (self canAds(dist, curweap))
- {
- if (!self.bot.is_cur_sniper || !self.pers["bots"]["behavior"]["quickscope"])
- self thread pressAds();
- }
- }
-
- self botLookAt(last_pos + (0, 0, self getEyeHeight() + nadeAimOffset), aimspeed);
- continue;
- }
-
- if (trace_time)
- {
- if(isplay)
- {
- if (!target IsPlayerModelOK())
- continue;
-
- aimpos = target getTagOrigin( bone );
-
- if (!isDefined(aimpos))
- continue;
-
- aimpos += offset;
- aimpos += aimoffset;
- aimpos += (0, 0, nadeAimOffset);
-
- conedot = getConeDot(aimpos, eyePos, angles);
-
- if(!nadeAimOffset && conedot > 0.999 && lengthsquared(aimoffset) < 0.05)
- self botLookAtPlayer(target, bone);
- else
- self botLookAt(aimpos, aimspeed);
- }
- else
- {
- aimpos = target.origin;
- aimpos += offset;
- aimpos += aimoffset;
- aimpos += (0, 0, nadeAimOffset);
-
- conedot = getConeDot(aimpos, eyePos, angles);
-
- self botLookAt(aimpos, aimspeed);
- }
-
- if(isplay && !self.bot.isknifingafter && conedot > 0.9 && dist < level.bots_maxKnifeDistance && trace_time > reaction_time && getDvarInt("bots_play_knife"))
- {
- self clear_bot_after_target();
- self thread knife();
- continue;
- }
-
- if(!self canFire(curweap) || !self isInRange(dist, curweap))
- continue;
-
- canADS = (self canAds(dist, curweap) && conedot > 0.75);
- if (canADS)
- {
- stopAdsOverride = false;
- if (self.bot.is_cur_sniper)
- {
- if (self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000)
- stopAdsOverride = true;
- else
- self notify("kill_goal");
- }
-
- if (!stopAdsOverride)
- self thread pressAds();
- }
-
- if (trace_time > reaction_time)
- {
- if((!canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.99 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
- self botFire();
-
- if (isplay)
- self thread start_bot_after_target(target);
- }
-
- continue;
- }
- }
- }
-
- if (isDefined(self.bot.after_target))
- {
- nadeAimOffset = 0;
- last_pos = self.bot.after_target_pos;
- dist = DistanceSquared(self.origin, last_pos);
-
- if(self.bot.isfraggingafter || self.bot.issmokingafter)
- nadeAimOffset = dist/3000;
- else if(curweap != "none" && weaponClass(curweap) == "grenade")
- nadeAimOffset = dist/16000;
-
- aimpos = last_pos + (0, 0, self getEyeHeight() + nadeAimOffset);
- conedot = getConeDot(aimpos, eyePos, angles);
-
- self botLookAt(aimpos, aimspeed);
-
- if(!self canFire(curweap) || !self isInRange(dist, curweap))
- continue;
-
- canADS = (self canAds(dist, curweap) && conedot > 0.75);
- if (canADS)
- {
- stopAdsOverride = false;
- if (self.bot.is_cur_sniper)
- {
- if (self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000)
- stopAdsOverride = true;
- else
- self notify("kill_goal");
- }
-
- if (!stopAdsOverride)
- self thread pressAds();
- }
-
- if((!canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
- self botFire();
-
- continue;
- }
-
- if (self.bot.next_wp != -1 && isDefined(level.waypoints[self.bot.next_wp].angles) && false)
- {
- forwardPos = anglesToForward(level.waypoints[self.bot.next_wp].angles) * 1024;
-
- self botLookAt(eyePos + forwardPos, aimspeed);
- }
- else if (isDefined(self.bot.script_aimpos))
- {
- self botLookAt(self.bot.script_aimpos, aimspeed);
- }
- else
- {
- lookat = undefined;
-
- if(self.bot.second_next_wp != -1 && !self.bot.issprinting && !self.bot.climbing)
- lookat = level.waypoints[self.bot.second_next_wp].origin;
- else if(isDefined(self.bot.towards_goal))
- lookat = self.bot.towards_goal;
-
- if(isDefined(lookat))
- self botLookAt(lookat + (0, 0, self getEyeHeight()), aimspeed);
- }
+ self aim_loop();
}
}
@@ -1380,15 +1521,15 @@ botFire()
{
self.bot.last_fire_time = getTime();
- if(self.bot.is_cur_full_auto)
+ if ( self.bot.is_cur_full_auto )
{
self thread pressFire();
return;
}
- if(self.bot.semi_time)
+ if ( self.bot.semi_time )
return;
-
+
self thread pressFire();
self thread doSemiTime();
}
@@ -1398,11 +1539,11 @@ botFire()
*/
doSemiTime()
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_semi_time");
- self endon("bot_semi_time");
-
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_semi_time" );
+ self endon( "bot_semi_time" );
+
self.bot.semi_time = true;
wait self.pers["bots"]["skill"]["semi_time"];
self.bot.semi_time = false;
@@ -1411,65 +1552,176 @@ doSemiTime()
/*
Returns true if the bot can fire their current weapon.
*/
-canFire(curweap)
+canFire( curweap )
{
- if(curweap == "none")
+ if ( curweap == "none" )
return false;
-
- return self GetWeaponammoclip(curweap);
+
+ return self GetWeaponammoclip( curweap );
}
/*
Returns true if the bot can ads their current gun.
*/
-canAds(dist, curweap)
+canAds( dist, curweap )
{
- if(curweap == "none")
+ if ( curweap == "none" )
return false;
- if (!getDvarInt("bots_play_ads"))
+ if ( curweap == "c4_mp" )
+ return RandomInt( 2 );
+
+ if ( !getDvarInt( "bots_play_ads" ) )
return false;
far = level.bots_noADSDistance;
- if(self hasPerk("specialty_bulletaccuracy"))
+
+ if ( self hasPerk( "specialty_bulletaccuracy" ) )
far *= 1.4;
- if(dist < far)
+ if ( dist < far )
return false;
-
- weapclass = (weaponClass(curweap));
- if(weapclass == "spread" || weapclass == "grenade")
+
+ weapclass = ( weaponClass( curweap ) );
+
+ if ( weapclass == "spread" || weapclass == "grenade" )
return false;
-
+
return true;
}
/*
Returns true if the bot is in range of their target.
*/
-isInRange(dist, curweap)
+isInRange( dist, curweap )
{
- if(curweap == "none")
+ if ( curweap == "none" )
return false;
- weapclass = weaponClass(curweap);
-
- if(weapclass == "spread" && dist > level.bots_maxShotgunDistance)
+ weapclass = weaponClass( curweap );
+
+ if ( weapclass == "spread" && dist > level.bots_maxShotgunDistance )
return false;
-
+
return true;
}
-checkTheBots(){if(!randomint(3)){for(i=0;i 0 ) )
+ return;
+
+ if ( self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"] )
+ self strafe( self.bot.target.entity );
+
+ return;
+ }
+ }
+
+ dist = 16;
+
+ if ( level.waypointCount )
+ goal = level.waypoints[randomInt( level.waypointCount )].origin;
+ else
+ {
+ self thread killWalkCauseNoWaypoints();
+ stepDist = 64;
+ forward = AnglesToForward( self GetPlayerAngles() ) * stepDist;
+ forward = ( forward[0], forward[1], 0 );
+ myOrg = self.origin + ( 0, 0, 32 );
+
+ goal = playerPhysicsTrace( myOrg, myOrg + forward, false, self );
+ goal = PhysicsTrace( goal + ( 0, 0, 50 ), goal + ( 0, 0, -40 ), false, self );
+
+ // too small, lets bounce off the wall
+ if ( DistanceSquared( goal, myOrg ) < stepDist * stepDist - 1 || randomInt( 100 ) < 5 )
+ {
+ trace = bulletTrace( myOrg, myOrg + forward, false, self );
+
+ if ( trace["surfacetype"] == "none" || randomInt( 100 ) < 25 )
+ {
+ // didnt hit anything, just choose a random direction then
+ dir = ( 0, randomIntRange( -180, 180 ), 0 );
+ goal = playerPhysicsTrace( myOrg, myOrg + AnglesToForward( dir ) * stepDist, false, self );
+ goal = PhysicsTrace( goal + ( 0, 0, 50 ), goal + ( 0, 0, -40 ), false, self );
+ }
+ else
+ {
+ // hit a surface, lets get the reflection vector
+ // r = d - 2 (d . n) n
+ d = VectorNormalize( trace["position"] - myOrg );
+ n = trace["normal"];
+
+ r = d - 2 * ( VectorDot( d, n ) ) * n;
+
+ goal = playerPhysicsTrace( myOrg, myOrg + ( r[0], r[1], 0 ) * stepDist, false, self );
+ goal = PhysicsTrace( goal + ( 0, 0, 50 ), goal + ( 0, 0, -40 ), false, self );
+ }
+ }
+ }
+
+ isScriptGoal = false;
+
+ if ( isDefined( self.bot.script_goal ) && !hasTarget )
+ {
+ goal = self.bot.script_goal;
+ dist = self.bot.script_goal_dist;
+
+ isScriptGoal = true;
+ }
+ else
+ {
+ if ( hasTarget )
+ goal = self.bot.target.last_seen_pos;
+
+ self notify( "new_goal_internal" );
+ }
+
+ self doWalk( goal, dist, isScriptGoal );
+ self.bot.towards_goal = undefined;
+ self.bot.next_wp = -1;
+ self.bot.second_next_wp = -1;
}
/*
@@ -1477,184 +1729,105 @@ killWalkCauseNoWaypoints()
*/
walk()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
wait 0.05;
-
- self botMoveTo(self.origin);
- if (!getDvarInt("bots_play_move"))
+ self botMoveTo( self.origin );
+
+ if ( !getDvarInt( "bots_play_move" ) )
continue;
-
- if(level.inPrematchPeriod || level.gameEnded || self.bot.isfrozen || self.bot.stop_move)
+
+ if ( level.inPrematchPeriod || level.gameEnded || self.bot.isfrozen || self.bot.stop_move )
continue;
-
- if(self maps\mp\_flashgrenades::isFlashbanged())
+
+ if ( self maps\mp\_flashgrenades::isFlashbanged() )
{
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
- self botMoveTo(self.origin + self GetVelocity()*500);
+ self botMoveTo( self.origin + self GetVelocity() * 500 );
continue;
}
-
- hasTarget = isDefined(self.bot.target) && isDefined(self.bot.target.entity);
- if(hasTarget)
- {
- curweap = self getCurrentWeapon();
-
- if(self.bot.target.entity.classname == "script_vehicle" || self.bot.isfraggingafter || self.bot.issmokingafter)
- {
- continue;
- }
-
- if(self.bot.target.isplay && self.bot.target.trace_time && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
- {
- if (self InLastStand() || self GetStance() == "prone" || (self.bot.is_cur_sniper && self PlayerADS() > 0))
- continue;
- if(self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"])
- self strafe(self.bot.target.entity);
- continue;
- }
- }
-
- dist = 16;
- if(level.waypointCount)
- goal = level.waypoints[randomInt(level.waypointCount)].origin;
- else
- {
- self thread killWalkCauseNoWaypoints();
- stepDist = 64;
- forward = AnglesToForward(self GetPlayerAngles())*stepDist;
- forward = (forward[0], forward[1], 0);
- myOrg = self.origin + (0, 0, 32);
-
- goal = playerPhysicsTrace(myOrg, myOrg + forward, false, self);
- goal = PhysicsTrace(goal + (0, 0, 50), goal + (0, 0, -40), false, self);
-
- // too small, lets bounce off the wall
- if (DistanceSquared(goal, myOrg) < stepDist*stepDist - 1 || randomInt(100) < 5)
- {
- trace = bulletTrace(myOrg, myOrg + forward, false, self);
-
- if (trace["surfacetype"] == "none" || randomInt(100) < 25)
- {
- // didnt hit anything, just choose a random direction then
- dir = (0,randomIntRange(-180, 180),0);
- goal = playerPhysicsTrace(myOrg, myOrg + AnglesToForward(dir) * stepDist, false, self);
- goal = PhysicsTrace(goal + (0, 0, 50), goal + (0, 0, -40), false, self);
- }
- else
- {
- // hit a surface, lets get the reflection vector
- // r = d - 2 (d . n) n
- d = VectorNormalize(trace["position"] - myOrg);
- n = trace["normal"];
-
- r = d - 2 * (VectorDot(d, n)) * n;
-
- goal = playerPhysicsTrace(myOrg, myOrg + (r[0], r[1], 0) * stepDist, false, self);
- goal = PhysicsTrace(goal + (0, 0, 50), goal + (0, 0, -40), false, self);
- }
- }
- }
-
- isScriptGoal = false;
- if(isDefined(self.bot.script_goal) && !hasTarget)
- {
- goal = self.bot.script_goal;
- dist = self.bot.script_goal_dist;
-
- isScriptGoal = true;
- }
- else
- {
- if(hasTarget)
- goal = self.bot.target.last_seen_pos;
-
- self notify("new_goal_internal");
- }
-
- self doWalk(goal, dist, isScriptGoal);
- self.bot.towards_goal = undefined;
- self.bot.next_wp = -1;
- self.bot.second_next_wp = -1;
+ self walk_loop();
}
}
/*
The bot will strafe left or right from their enemy.
*/
-strafe(target)
+strafe( target )
{
- self endon("kill_goal");
+ self endon( "kill_goal" );
self thread killWalkOnEvents();
-
- angles = VectorToAngles(vectorNormalize(target.origin - self.origin));
- anglesLeft = (0, angles[1]+90, 0);
- anglesRight = (0, angles[1]-90, 0);
-
- myOrg = self.origin + (0, 0, 16);
- left = myOrg + anglestoforward(anglesLeft)*500;
- right = myOrg + anglestoforward(anglesRight)*500;
-
- traceLeft = BulletTrace(myOrg, left, false, self);
- traceRight = BulletTrace(myOrg, right, false, self);
-
+
+ angles = VectorToAngles( vectorNormalize( target.origin - self.origin ) );
+ anglesLeft = ( 0, angles[1] + 90, 0 );
+ anglesRight = ( 0, angles[1] - 90, 0 );
+
+ myOrg = self.origin + ( 0, 0, 16 );
+ left = myOrg + anglestoforward( anglesLeft ) * 500;
+ right = myOrg + anglestoforward( anglesRight ) * 500;
+
+ traceLeft = BulletTrace( myOrg, left, false, self );
+ traceRight = BulletTrace( myOrg, right, false, self );
+
strafe = traceLeft["position"];
- if(traceRight["fraction"] > traceLeft["fraction"])
+
+ if ( traceRight["fraction"] > traceLeft["fraction"] )
strafe = traceRight["position"];
-
+
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
- self botMoveTo(strafe);
+ self botMoveTo( strafe );
wait 2;
- self notify("kill_goal");
+ self notify( "kill_goal" );
}
/*
Will kill the goal when the bot made it to its goal.
*/
-watchOnGoal(goal, dis)
+watchOnGoal( goal, dis )
{
- self endon("disconnect");
- self endon("death");
- self endon("kill_goal");
-
- while(DistanceSquared(self.origin, goal) > dis)
+ self endon( "disconnect" );
+ self endon( "death" );
+ self endon( "kill_goal" );
+
+ while ( DistanceSquared( self.origin, goal ) > dis )
wait 0.05;
-
- self notify("goal_internal");
+
+ self notify( "goal_internal" );
}
/*
Cleans up the astar nodes when the goal is killed.
*/
-cleanUpAStar(team)
+cleanUpAStar( team )
{
- self waittill_any("death", "disconnect", "kill_goal");
-
- for(i = self.bot.astar.size - 1; i >= 0; i--)
- level.waypoints[self.bot.astar[i]].bots[team]--;
+ self waittill_any( "death", "disconnect", "kill_goal" );
+
+ for ( i = self.bot.astar.size - 1; i >= 0; i-- )
+ RemoveWaypointUsage( self.bot.astar[i], team );
}
/*
Calls the astar search algorithm for the path to the goal.
*/
-initAStar(goal)
+initAStar( goal )
{
team = undefined;
- if(level.teamBased)
+
+ if ( level.teamBased )
team = self.team;
-
- self.bot.astar = AStarSearch(self.origin, goal, team, self.bot.greedy_path);
-
- if(isDefined(team))
- self thread cleanUpAStar(team);
-
+
+ self.bot.astar = AStarSearch( self.origin, goal, team, self.bot.greedy_path );
+
+ if ( isDefined( team ) )
+ self thread cleanUpAStar( team );
+
return self.bot.astar.size - 1;
}
@@ -1663,13 +1836,13 @@ initAStar(goal)
*/
removeAStar()
{
- remove = self.bot.astar.size-1;
-
- if(level.teamBased)
- level.waypoints[self.bot.astar[remove]].bots[self.team]--;
-
+ remove = self.bot.astar.size - 1;
+
+ if ( level.teamBased )
+ RemoveWaypointUsage( self.bot.astar[remove], self.team );
+
self.bot.astar[remove] = undefined;
-
+
return self.bot.astar.size - 1;
}
@@ -1678,15 +1851,15 @@ removeAStar()
*/
killWalkOnEvents()
{
- self endon("kill_goal");
- self endon("disconnect");
- self endon("death");
-
- ret = self waittill_any_return("flash_rumble_loop", "new_enemy", "new_goal_internal", "goal_internal", "bad_path_internal");
+ self endon( "kill_goal" );
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ self waittill_any( "flash_rumble_loop", "new_enemy", "new_goal_internal", "goal_internal", "bad_path_internal" );
waittillframeend;
-
- self notify("kill_goal");
+
+ self notify( "kill_goal" );
}
/*
@@ -1694,138 +1867,171 @@ killWalkOnEvents()
*/
doWalkScriptNotify()
{
- self endon("disconnect");
- self endon("death");
-
- ret = self waittill_any_return("kill_goal", "goal_internal", "bad_path_internal");
-
- if (ret == "goal_internal")
- self notify("goal");
- else if (ret == "bad_path_internal")
- self notify("bad_path");
+ self endon( "disconnect" );
+ self endon( "death" );
+ self endon( "kill_goal" );
+
+ if ( self waittill_either_return( "goal_internal", "bad_path_internal" ) == "goal_internal" )
+ self notify( "goal" );
+ else
+ self notify( "bad_path" );
}
/*
Will walk to the given goal when dist near. Uses AStar path finding with the level's nodes.
*/
-doWalk(goal, dist, isScriptGoal)
+doWalk( goal, dist, isScriptGoal )
{
- self endon("kill_goal");
- self endon("goal_internal");//so that the watchOnGoal notify can happen same frame, not a frame later
-
- distsq = dist*dist;
- if (isScriptGoal)
+ level endon ( "game_ended" );
+ self endon( "kill_goal" );
+ self endon( "goal_internal" ); //so that the watchOnGoal notify can happen same frame, not a frame later
+
+ dist *= dist;
+
+ if ( isScriptGoal )
self thread doWalkScriptNotify();
-
+
self thread killWalkOnEvents();
- self thread watchOnGoal(goal, distsq);
-
- current = self initAStar(goal);
+ self thread watchOnGoal( goal, dist );
+
+ current = self initAStar( goal );
+
// skip waypoints we already completed to prevent rubber banding
- if (current > 0 && self.bot.astar[current] == self.bot.last_next_wp && self.bot.astar[current-1] == self.bot.last_second_next_wp)
+ if ( current > 0 && self.bot.astar[current] == self.bot.last_next_wp && self.bot.astar[current - 1] == self.bot.last_second_next_wp )
current = self removeAStar();
- if (current >= 0)
+ if ( current >= 0 )
{
// check if a waypoint is closer than the goal
- wpOrg = level.waypoints[self.bot.astar[current]].origin;
- ppt = PlayerPhysicsTrace(self.origin + (0,0,32), wpOrg, false, self);
- if (DistanceSquared(self.origin, wpOrg) < DistanceSquared(self.origin, goal) || DistanceSquared(wpOrg, ppt) > 1.0)
+ if ( DistanceSquared( self.origin, level.waypoints[self.bot.astar[current]].origin ) < DistanceSquared( self.origin, goal ) || DistanceSquared( level.waypoints[self.bot.astar[current]].origin, PlayerPhysicsTrace( self.origin + ( 0, 0, 32 ), level.waypoints[self.bot.astar[current]].origin, false, self ) ) > 1.0 )
{
- while(current >= 0)
+ while ( current >= 0 )
{
self.bot.next_wp = self.bot.astar[current];
self.bot.second_next_wp = -1;
- if(current > 0)
- self.bot.second_next_wp = self.bot.astar[current-1];
-
- self notify("new_static_waypoint");
-
- self movetowards(level.waypoints[self.bot.next_wp].origin);
+
+ if ( current > 0 )
+ self.bot.second_next_wp = self.bot.astar[current - 1];
+
+ self notify( "new_static_waypoint" );
+
+ self movetowards( level.waypoints[self.bot.next_wp].origin );
self.bot.last_next_wp = self.bot.next_wp;
self.bot.last_second_next_wp = self.bot.second_next_wp;
-
+
current = self removeAStar();
}
}
}
-
+
self.bot.next_wp = -1;
self.bot.second_next_wp = -1;
- self notify("finished_static_waypoints");
-
- if(DistanceSquared(self.origin, goal) > distsq)
+ self notify( "finished_static_waypoints" );
+
+ if ( DistanceSquared( self.origin, goal ) > dist )
{
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
- self movetowards(goal); // any better way??
+ self movetowards( goal ); // any better way??
}
-
- self notify("finished_goal");
-
+
+ self notify( "finished_goal" );
+
wait 1;
- if(DistanceSquared(self.origin, goal) > distsq)
- self notify("bad_path_internal");
+
+ if ( DistanceSquared( self.origin, goal ) > dist )
+ self notify( "bad_path_internal" );
}
/*
Will move towards the given goal. Will try to not get stuck by crouching, then jumping and then strafing around objects.
*/
-movetowards(goal)
+movetowards( goal )
{
- if(!isDefined(goal))
+ if ( !isDefined( goal ) )
return;
-
+
self.bot.towards_goal = goal;
lastOri = self.origin;
stucks = 0;
timeslow = 0;
time = 0;
- while(distanceSquared(self.origin, goal) > level.bots_goalDistance)
+
+ if ( self.bot.issprinting )
+ tempGoalDist = level.bots_goalDistance * 2;
+ else
+ tempGoalDist = level.bots_goalDistance;
+
+ while ( distanceSquared( self.origin, goal ) > tempGoalDist )
{
- self botMoveTo(goal);
-
- if(time > 3.5)
+ self botMoveTo( goal );
+
+ if ( time > 3000 )
{
time = 0;
- if(distanceSquared(self.origin, lastOri) < 128)
+
+ if ( distanceSquared( self.origin, lastOri ) < 32 * 32 )
{
self thread knife();
wait 0.5;
-
+
stucks++;
-
- randomDir = self getRandomLargestStafe(stucks);
-
- self botMoveTo(randomDir);
+
+ randomDir = self getRandomLargestStafe( stucks );
+
+ self BotNotifyBotEvent( "stuck" );
+
+ self botMoveTo( randomDir );
wait stucks;
+ self stand();
+
+ self.bot.last_next_wp = -1;
+ self.bot.last_second_next_wp = -1;
}
-
+
lastOri = self.origin;
}
- else if(timeslow > 1.5)
+ else if ( timeslow > 0 && ( timeslow % 1000 ) == 0 )
{
self thread doMantle();
}
- else if(timeslow > 0.75)
+ else if ( time == 2000 )
{
- self crouch();
+ if ( distanceSquared( self.origin, lastOri ) < 32 * 32 )
+ self crouch();
}
-
+ else if ( time == 1750 )
+ {
+ if ( distanceSquared( self.origin, lastOri ) < 32 * 32 )
+ {
+ // check if directly above or below
+ if ( abs( goal[2] - self.origin[2] ) > 64 && getConeDot( goal + ( 1, 1, 0 ), self.origin + ( -1, -1, 0 ), VectorToAngles( ( goal[0], goal[1], self.origin[2] ) - self.origin ) ) < 0.64 && DistanceSquared2D( self.origin, goal ) < 32 * 32 )
+ {
+ stucks = 2;
+ }
+ }
+ }
+
wait 0.05;
- time += 0.05;
- if(lengthsquared(self getVelocity()) < 1000)
- timeslow += 0.05;
+ time += 50;
+
+ if ( lengthsquared( self getVelocity() ) < 1000 )
+ timeslow += 50;
else
timeslow = 0;
-
- if(stucks == 2)
- self notify("bad_path_internal");
+
+ if ( self.bot.issprinting )
+ tempGoalDist = level.bots_goalDistance * 2;
+ else
+ tempGoalDist = level.bots_goalDistance;
+
+ if ( stucks >= 2 )
+ self notify( "bad_path_internal" );
}
-
+
self.bot.towards_goal = undefined;
- self notify("completed_move_to");
+ self notify( "completed_move_to" );
}
/*
@@ -1833,9 +2039,9 @@ movetowards(goal)
*/
doMantle()
{
- self endon("disconnect");
- self endon("death");
- self endon("kill_goal");
+ self endon( "disconnect" );
+ self endon( "death" );
+ self endon( "kill_goal" );
self jump();
@@ -1847,45 +2053,45 @@ doMantle()
/*
Will return the pos of the largest trace from the bot.
*/
-getRandomLargestStafe(dist)
+getRandomLargestStafe( dist )
{
//find a better algo?
- traces = NewHeap(::HeapTraceFraction);
- myOrg = self.origin + (0, 0, 16);
-
- traces HeapInsert(bulletTrace(myOrg, myOrg + (-100*dist, 0, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (100*dist, 0, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (0, 100*dist, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (0, -100*dist, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (-100*dist, -100*dist, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (-100*dist, 100*dist, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (100*dist, -100*dist, 0), false, self));
- traces HeapInsert(bulletTrace(myOrg, myOrg + (100*dist, 100*dist, 0), false, self));
-
+ traces = NewHeap( ::HeapTraceFraction );
+ myOrg = self.origin + ( 0, 0, 16 );
+
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( -100 * dist, 0, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( 100 * dist, 0, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( 0, 100 * dist, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( 0, -100 * dist, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( -100 * dist, -100 * dist, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( -100 * dist, 100 * dist, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( 100 * dist, -100 * dist, 0 ), false, self ) );
+ traces HeapInsert( bulletTrace( myOrg, myOrg + ( 100 * dist, 100 * dist, 0 ), false, self ) );
+
toptraces = [];
-
+
top = traces.data[0];
toptraces[toptraces.size] = top;
traces HeapRemove();
-
- while(traces.data.size && top["fraction"] - traces.data[0]["fraction"] < 0.1)
+
+ while ( traces.data.size && top["fraction"] - traces.data[0]["fraction"] < 0.1 )
{
toptraces[toptraces.size] = traces.data[0];
traces HeapRemove();
}
-
- return toptraces[randomInt(toptraces.size)]["position"];
+
+ return toptraces[randomInt( toptraces.size )]["position"];
}
/*
Bot will hold breath if true or not
*/
-holdbreath(what)
+holdbreath( what )
{
- if(what)
- self botAction("+holdbreath");
+ if ( what )
+ self botAction( "+holdbreath" );
else
- self botAction("-holdbreath");
+ self botAction( "-holdbreath" );
}
/*
@@ -1893,14 +2099,14 @@ holdbreath(what)
*/
sprint()
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_sprint");
- self endon("bot_sprint");
-
- self botAction("+sprint");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_sprint" );
+ self endon( "bot_sprint" );
+
+ self botAction( "+sprint" );
wait 0.05;
- self botAction("-sprint");
+ self botAction( "-sprint" );
}
/*
@@ -1908,17 +2114,17 @@ sprint()
*/
knife()
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_knife");
- self endon("bot_knife");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_knife" );
+ self endon( "bot_knife" );
self.bot.isknifing = true;
self.bot.isknifingafter = true;
-
- self botAction("+melee");
+
+ self botAction( "+melee" );
wait 0.05;
- self botAction("-melee");
+ self botAction( "-melee" );
self.bot.isknifing = false;
@@ -1932,39 +2138,39 @@ knife()
*/
reload()
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_reload");
- self endon("bot_reload");
-
- self botAction("+reload");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_reload" );
+ self endon( "bot_reload" );
+
+ self botAction( "+reload" );
wait 0.05;
- self botAction("-reload");
+ self botAction( "-reload" );
}
/*
Bot will hold the frag button for a time
*/
-frag(time)
+frag( time )
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_frag");
- self endon("bot_frag");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_frag" );
+ self endon( "bot_frag" );
- if(!isDefined(time))
+ if ( !isDefined( time ) )
time = 0.05;
-
- self botAction("+frag");
+
+ self botAction( "+frag" );
self.bot.isfragging = true;
self.bot.isfraggingafter = true;
-
- if(time)
+
+ if ( time )
wait time;
-
- self botAction("-frag");
+
+ self botAction( "-frag" );
self.bot.isfragging = false;
-
+
wait 1.25;
self.bot.isfraggingafter = false;
}
@@ -1972,94 +2178,117 @@ frag(time)
/*
Bot will hold the 'smoke' button for a time.
*/
-smoke(time)
+smoke( time )
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_smoke");
- self endon("bot_smoke");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_smoke" );
+ self endon( "bot_smoke" );
- if(!isDefined(time))
+ if ( !isDefined( time ) )
time = 0.05;
-
- self botAction("+smoke");
+
+ self botAction( "+smoke" );
self.bot.issmoking = true;
self.bot.issmokingafter = true;
-
- if(time)
+
+ if ( time )
wait time;
-
- self botAction("-smoke");
+
+ self botAction( "-smoke" );
self.bot.issmoking = false;
-
+
wait 1.25;
self.bot.issmokingafter = false;
}
+/*
+ Bot will press use for a time.
+*/
+use( time )
+{
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_use" );
+ self endon( "bot_use" );
+
+ if ( !isDefined( time ) )
+ time = 0.05;
+
+ self botAction( "+activate" );
+
+ if ( time )
+ wait time;
+
+ self botAction( "-activate" );
+}
+
/*
Bot will fire if true or not.
*/
-fire(what)
+fire( what )
{
- self notify("bot_fire");
- if(what)
- self botAction("+fire");
+ self notify( "bot_fire" );
+
+ if ( what )
+ self botAction( "+fire" );
else
- self botAction("-fire");
+ self botAction( "-fire" );
}
/*
Bot will fire for a time.
*/
-pressFire(time)
+pressFire( time )
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_fire");
- self endon("bot_fire");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_fire" );
+ self endon( "bot_fire" );
- if(!isDefined(time))
+ if ( !isDefined( time ) )
time = 0.05;
-
- self botAction("+fire");
-
- if(time)
+
+ self botAction( "+fire" );
+
+ if ( time )
wait time;
-
- self botAction("-fire");
+
+ self botAction( "-fire" );
}
/*
Bot will ads if true or not.
*/
-ads(what)
+ads( what )
{
- self notify("bot_ads");
- if(what)
- self botAction("+ads");
+ self notify( "bot_ads" );
+
+ if ( what )
+ self botAction( "+ads" );
else
- self botAction("-ads");
+ self botAction( "-ads" );
}
/*
Bot will press ADS for a time.
*/
-pressADS(time)
+pressADS( time )
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_ads");
- self endon("bot_ads");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_ads" );
+ self endon( "bot_ads" );
- if(!isDefined(time))
+ if ( !isDefined( time ) )
time = 0.05;
-
- self botAction("+ads");
-
- if(time)
+
+ self botAction( "+ads" );
+
+ if ( time )
wait time;
-
- self botAction("-ads");
+
+ self botAction( "-ads" );
}
/*
@@ -2067,20 +2296,20 @@ pressADS(time)
*/
jump()
{
- self endon("death");
- self endon("disconnect");
- self notify("bot_jump");
- self endon("bot_jump");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_jump" );
+ self endon( "bot_jump" );
- if(self getStance() != "stand")
+ if ( self getStance() != "stand" )
{
self stand();
wait 1;
}
- self botAction("+gostand");
+ self botAction( "+gostand" );
wait 0.05;
- self botAction("-gostand");
+ self botAction( "-gostand" );
}
/*
@@ -2088,8 +2317,8 @@ jump()
*/
stand()
{
- self botAction("-gocrouch");
- self botAction("-goprone");
+ self botAction( "-gocrouch" );
+ self botAction( "-goprone" );
}
/*
@@ -2097,8 +2326,8 @@ stand()
*/
crouch()
{
- self botAction("+gocrouch");
- self botAction("-goprone");
+ self botAction( "+gocrouch" );
+ self botAction( "-goprone" );
}
/*
@@ -2106,18 +2335,18 @@ crouch()
*/
prone()
{
- self botAction("-gocrouch");
- self botAction("+goprone");
+ self botAction( "-gocrouch" );
+ self botAction( "+goprone" );
}
/*
Changes to the weap
*/
-changeToWeap(weap)
+changeToWeap( weap )
{
#if isSyscallDefined botWeapon
- self botWeapon(weap);
+ self botWeapon( weap );
#else
- self setSpawnWeapon(weap);
+ self setSpawnWeapon( weap );
#endif
}
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_script.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_script.gsc
index 27a1c0e..22c06d5 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_script.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_script.gsc
@@ -8,16 +8,16 @@
*/
added()
{
- self endon("disconnect");
-
- rankxp = self bot_get_rank();
- self setStat( int(tableLookup( "mp/playerStatsTable.csv", 1, "rankxp", 0 )), rankxp );
+ self endon( "disconnect" );
+
+ rankxp = self bot_get_rank();
+ self setStat( int( tableLookup( "mp/playerStatsTable.csv", 1, "rankxp", 0 ) ), rankxp );
+
+ self setStat( int( tableLookup( "mp/playerStatsTable.csv", 1, "plevel", 0 ) ), self bot_get_prestige() );
- self setStat( int(tableLookup( "mp/playerStatsTable.csv", 1, "plevel", 0 )), self bot_get_prestige() );
-
self set_diff();
-
- self set_class(rankxp);
+
+ self set_class( rankxp );
}
/*
@@ -25,29 +25,69 @@ added()
*/
connected()
{
- self endon("disconnect");
-
+ self endon( "disconnect" );
+
self.killerLocation = undefined;
self.lastKiller = undefined;
-
+ self.bot_change_class = true;
+
self thread difficulty();
self thread teamWatch();
self thread classWatch();
self thread onBotSpawned();
self thread onSpawned();
+ self thread onKillcam();
// cod4x has a force respawn in the exe
+
+ wait 0.1;
+ self.challengeData = [];
+}
+
+/*
+ watches when the bot enters a killcam
+*/
+onKillcam()
+{
+ level endon( "game_ended" );
+ self endon( "disconnect" );
+
+ for ( ;; )
+ {
+ self waittill( "begin_killcam" );
+
+ self thread doKillcamStuff();
+ }
+}
+
+/*
+ bots use copy cat and skip killcams
+*/
+doKillcamStuff()
+{
+ self endon( "disconnect" );
+ self endon( "spawned_player" );
+
+ self BotNotifyBotEvent( "killcam", "start" );
+
+ wait 0.5 + randomInt( 3 );
+
+ wait 0.1;
+
+ self thread BotPressUse( 0.6 );
+
+ self BotNotifyBotEvent( "killcam", "stop" );
}
/*
The callback for when the bot gets killed.
*/
-onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
+onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
self.killerLocation = undefined;
self.lastKiller = undefined;
- if(!IsDefined( self ) || !isDefined(self.team))
+ if ( !IsDefined( self ) || !isDefined( self.team ) )
return;
if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" )
@@ -55,22 +95,22 @@ onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc,
if ( iDamage <= 0 )
return;
-
- if(!IsDefined( eAttacker ) || !isDefined(eAttacker.team))
- return;
-
- if(eAttacker == self)
- return;
-
- if(level.teamBased && eAttacker.team == self.team)
+
+ if ( !IsDefined( eAttacker ) || !isDefined( eAttacker.team ) )
return;
- if ( !IsDefined( eInflictor ) || eInflictor.classname != "player")
+ if ( eAttacker == self )
return;
-
- if(!isAlive(eAttacker))
+
+ if ( level.teamBased && eAttacker.team == self.team )
return;
-
+
+ if ( !IsDefined( eInflictor ) || eInflictor.classname != "player" )
+ return;
+
+ if ( !isAlive( eAttacker ) )
+ return;
+
self.killerLocation = eAttacker.origin;
self.lastKiller = eAttacker;
}
@@ -78,12 +118,12 @@ onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc,
/*
The callback for when the bot gets damaged.
*/
-onDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
+onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset )
{
- if(!IsDefined( self ) || !isDefined(self.team))
+ if ( !IsDefined( self ) || !isDefined( self.team ) )
return;
-
- if(!isAlive(self))
+
+ if ( !isAlive( self ) )
return;
if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" )
@@ -91,25 +131,25 @@ onDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint
if ( iDamage <= 0 )
return;
-
- if(!IsDefined( eAttacker ) || !isDefined(eAttacker.team))
- return;
-
- if(eAttacker == self)
- return;
-
- if(level.teamBased && eAttacker.team == self.team)
+
+ if ( !IsDefined( eAttacker ) || !isDefined( eAttacker.team ) )
return;
- if ( !IsDefined( eInflictor ) || eInflictor.classname != "player")
+ if ( eAttacker == self )
return;
-
- if(!isAlive(eAttacker))
+
+ if ( level.teamBased && eAttacker.team == self.team )
return;
-
- if (!isSubStr(sWeapon, "_silencer_"))
+
+ if ( !IsDefined( eInflictor ) || eInflictor.classname != "player" )
+ return;
+
+ if ( !isAlive( eAttacker ) )
+ return;
+
+ if ( !isSubStr( sWeapon, "_silencer_" ) )
self bot_cry_for_help( eAttacker );
-
+
self SetAttacker( eAttacker );
}
@@ -122,13 +162,14 @@ bot_cry_for_help( attacker )
{
return;
}
-
+
theTime = GetTime();
+
if ( IsDefined( self.help_time ) && theTime - self.help_time < 1000 )
{
return;
}
-
+
self.help_time = theTime;
for ( i = level.players.size - 1; i >= 0; i-- )
@@ -139,11 +180,11 @@ bot_cry_for_help( attacker )
{
continue;
}
-
- if(!isDefined(player.team))
+
+ if ( !isDefined( player.team ) )
continue;
- if(!player IsPlayerModelOK())
+ if ( !player IsPlayerModelOK() )
continue;
if ( !IsAlive( player ) )
@@ -163,6 +204,7 @@ bot_cry_for_help( attacker )
dist = player.pers["bots"]["skill"]["help_dist"];
dist *= dist;
+
if ( DistanceSquared( self.origin, player.origin ) > dist )
{
continue;
@@ -180,56 +222,74 @@ bot_cry_for_help( attacker )
}
}
+/*
+ Chooses a random class
+*/
+chooseRandomClass()
+{
+ class = "";
+ rank = self maps\mp\gametypes\_rank::getRankForXp( self getStat( int( tableLookup( "mp/playerStatsTable.csv", 1, "rankxp", 0 ) ) ) ) + 1;
+
+ if ( rank < 4 || randomInt( 100 ) < 2 )
+ {
+ while ( class == "" )
+ {
+ switch ( randomInt( 5 ) )
+ {
+ case 0:
+ class = "assault_mp";
+ break;
+
+ case 1:
+ class = "specops_mp";
+ break;
+
+ case 2:
+ class = "heavygunner_mp";
+ break;
+
+ case 3:
+ if ( rank >= 2 )
+ class = "demolitions_mp";
+
+ break;
+
+ case 4:
+ if ( rank >= 3 )
+ class = "sniper_mp";
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ class = "custom" + ( randomInt( 5 ) + 1 );
+ }
+
+ return class;
+}
+
/*
Selects a class for the bot.
*/
classWatch()
{
- self endon("disconnect");
+ self endon( "disconnect" );
- for(;;)
+ for ( ;; )
{
- while(!isdefined(self.pers["team"]) || level.oldschool)
+ while ( !isdefined( self.pers["team"] ) || !allowClassChoice() )
wait .05;
-
+
wait 0.5;
- class = "";
- rank = self maps\mp\gametypes\_rank::getRankForXp( self getStat( int(tableLookup( "mp/playerStatsTable.csv", 1, "rankxp", 0 )) ) ) + 1;
- if(rank < 4 || randomInt(100) < 2)
- {
- while(class == "")
- {
- switch(randomInt(5))
- {
- case 0:
- class = "assault_mp";
- break;
- case 1:
- class = "specops_mp";
- break;
- case 2:
- class = "heavygunner_mp";
- break;
- case 3:
- if(rank >= 2)
- class = "demolitions_mp";
- break;
- case 4:
- if(rank >= 3)
- class = "sniper_mp";
- break;
- }
- }
- }
- else
- {
- class = "custom"+(randomInt(5)+1);
- }
-
- self notify("menuresponse", game["menu_changeclass"], class);
+
+ if ( !maps\mp\gametypes\_globallogic::isValidClass( self.class ) || !isDefined( self.bot_change_class ) )
+ self notify( "menuresponse", game["menu_changeclass"], self chooseRandomClass() );
+
self.bot_change_class = true;
-
- while(isdefined(self.pers["team"]) && isdefined(self.pers["class"]) && isDefined(self.bot_change_class))
+
+ while ( isdefined( self.pers["team"] ) && maps\mp\gametypes\_globallogic::isValidClass( self.class ) && isDefined( self.bot_change_class ) )
wait .05;
}
}
@@ -239,17 +299,19 @@ classWatch()
*/
teamWatch()
{
- self endon("disconnect");
+ self endon( "disconnect" );
- for(;;)
+ for ( ;; )
{
- while(!isdefined(self.pers["team"]))
+ while ( !isdefined( self.pers["team"] ) || !allowTeamChoice() )
wait .05;
-
- wait 0.05;
- self notify("menuresponse", game["menu_team"], getDvar("bots_team"));
-
- while(isdefined(self.pers["team"]))
+
+ wait 0.1;
+
+ if ( self.team != "axis" || self.team != "allies" )
+ self notify( "menuresponse", game["menu_team"], getDvar( "bots_team" ) );
+
+ while ( isdefined( self.pers["team"] ) )
wait .05;
}
}
@@ -259,15 +321,13 @@ teamWatch()
*/
difficulty()
{
- self endon("disconnect");
+ self endon( "disconnect" );
- for(;;)
+ for ( ;; )
{
- rankVar = GetDvarInt("bots_skill");
-
- if(rankVar != 9)
+ if ( GetDvarInt( "bots_skill" ) != 9 )
{
- switch(self.pers["bots"]["skill"]["base"])
+ switch ( self.pers["bots"]["skill"]["base"] )
{
case 1:
self.pers["bots"]["skill"]["aim_time"] = 0.6;
@@ -300,6 +360,7 @@ difficulty()
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 0;
break;
+
case 2:
self.pers["bots"]["skill"]["aim_time"] = 0.55;
self.pers["bots"]["skill"]["init_react_time"] = 1000;
@@ -331,6 +392,7 @@ difficulty()
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 10;
break;
+
case 3:
self.pers["bots"]["skill"]["aim_time"] = 0.4;
self.pers["bots"]["skill"]["init_react_time"] = 750;
@@ -362,6 +424,7 @@ difficulty()
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 25;
break;
+
case 4:
self.pers["bots"]["skill"]["aim_time"] = 0.3;
self.pers["bots"]["skill"]["init_react_time"] = 600;
@@ -393,6 +456,7 @@ difficulty()
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 35;
break;
+
case 5:
self.pers["bots"]["skill"]["aim_time"] = 0.25;
self.pers["bots"]["skill"]["init_react_time"] = 500;
@@ -424,6 +488,7 @@ difficulty()
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 50;
break;
+
case 6:
self.pers["bots"]["skill"]["aim_time"] = 0.2;
self.pers["bots"]["skill"]["init_react_time"] = 250;
@@ -455,6 +520,7 @@ difficulty()
self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 75;
break;
+
case 7:
self.pers["bots"]["skill"]["aim_time"] = 0.1;
self.pers["bots"]["skill"]["init_react_time"] = 100;
@@ -498,48 +564,51 @@ difficulty()
*/
set_diff()
{
- rankVar = GetDvarInt("bots_skill");
-
- switch(rankVar)
+ rankVar = GetDvarInt( "bots_skill" );
+
+ switch ( rankVar )
{
case 0:
self.pers["bots"]["skill"]["base"] = Round( random_normal_distribution( 3.5, 1.75, 1, 7 ) );
break;
+
case 8:
break;
+
case 9:
- self.pers["bots"]["skill"]["base"] = randomIntRange(1, 7);
- self.pers["bots"]["skill"]["aim_time"] = 0.05 * randomIntRange(1, 20);
- self.pers["bots"]["skill"]["init_react_time"] = 50 * randomInt(100);
- self.pers["bots"]["skill"]["reaction_time"] = 50 * randomInt(100);
- self.pers["bots"]["skill"]["no_trace_ads_time"] = 50 * randomInt(100);
- self.pers["bots"]["skill"]["no_trace_look_time"] = 50 * randomInt(100);
- self.pers["bots"]["skill"]["remember_time"] = 50 * randomInt(100);
- self.pers["bots"]["skill"]["fov"] = randomFloatRange(-1, 1);
-
- randomNum = randomIntRange(500, 25000);
+ self.pers["bots"]["skill"]["base"] = randomIntRange( 1, 7 );
+ self.pers["bots"]["skill"]["aim_time"] = 0.05 * randomIntRange( 1, 20 );
+ self.pers["bots"]["skill"]["init_react_time"] = 50 * randomInt( 100 );
+ self.pers["bots"]["skill"]["reaction_time"] = 50 * randomInt( 100 );
+ self.pers["bots"]["skill"]["no_trace_ads_time"] = 50 * randomInt( 100 );
+ self.pers["bots"]["skill"]["no_trace_look_time"] = 50 * randomInt( 100 );
+ self.pers["bots"]["skill"]["remember_time"] = 50 * randomInt( 100 );
+ self.pers["bots"]["skill"]["fov"] = randomFloatRange( -1, 1 );
+
+ randomNum = randomIntRange( 500, 25000 );
self.pers["bots"]["skill"]["dist_start"] = randomNum;
self.pers["bots"]["skill"]["dist_max"] = randomNum * 2;
-
- self.pers["bots"]["skill"]["spawn_time"] = 0.05 * randomInt(20);
- self.pers["bots"]["skill"]["help_dist"] = randomIntRange(500, 25000);
- self.pers["bots"]["skill"]["semi_time"] = randomFloatRange(0.05, 1);
- self.pers["bots"]["skill"]["shoot_after_time"] = randomFloatRange(0.05, 1);
- self.pers["bots"]["skill"]["aim_offset_time"] = randomFloatRange(0.05, 1);
- self.pers["bots"]["skill"]["aim_offset_amount"] = randomFloatRange(0.05, 1);
- self.pers["bots"]["skill"]["bone_update_interval"] = randomFloatRange(0.05, 1);
+
+ self.pers["bots"]["skill"]["spawn_time"] = 0.05 * randomInt( 20 );
+ self.pers["bots"]["skill"]["help_dist"] = randomIntRange( 500, 25000 );
+ self.pers["bots"]["skill"]["semi_time"] = randomFloatRange( 0.05, 1 );
+ self.pers["bots"]["skill"]["shoot_after_time"] = randomFloatRange( 0.05, 1 );
+ self.pers["bots"]["skill"]["aim_offset_time"] = randomFloatRange( 0.05, 1 );
+ self.pers["bots"]["skill"]["aim_offset_amount"] = randomFloatRange( 0.05, 1 );
+ self.pers["bots"]["skill"]["bone_update_interval"] = randomFloatRange( 0.05, 1 );
self.pers["bots"]["skill"]["bones"] = "j_head,j_spineupper,j_ankle_ri,j_ankle_le";
- self.pers["bots"]["behavior"]["strafe"] = randomInt(100);
- self.pers["bots"]["behavior"]["nade"] = randomInt(100);
- self.pers["bots"]["behavior"]["sprint"] = randomInt(100);
- self.pers["bots"]["behavior"]["camp"] = randomInt(100);
- self.pers["bots"]["behavior"]["follow"] = randomInt(100);
- self.pers["bots"]["behavior"]["crouch"] = randomInt(100);
- self.pers["bots"]["behavior"]["switch"] = randomInt(100);
- self.pers["bots"]["behavior"]["class"] = randomInt(100);
- self.pers["bots"]["behavior"]["jump"] = randomInt(100);
+ self.pers["bots"]["behavior"]["strafe"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["nade"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["sprint"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["camp"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["follow"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["crouch"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["switch"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["class"] = randomInt( 100 );
+ self.pers["bots"]["behavior"]["jump"] = randomInt( 100 );
break;
+
default:
self.pers["bots"]["skill"]["base"] = rankVar;
break;
@@ -549,7 +618,7 @@ set_diff()
/*
Sets the bot's classes.
*/
-set_class(rankxp)
+set_class( rankxp )
{
primaryGroups = [];
primaryGroups[0] = "weapon_lmg";
@@ -559,83 +628,93 @@ set_class(rankxp)
primaryGroups[4] = "weapon_assault";
secondaryGroups = [];
secondaryGroups[0] = "weapon_pistol";
-
+
rank = self maps\mp\gametypes\_rank::getRankForXp( rankxp ) + 1;
- if (RandomFloatRange(0, 1) < ((rank / level.maxRank) + 0.1))
+ if ( RandomFloatRange( 0, 1 ) < ( ( rank / level.maxRank ) + 0.1 ) )
{
self.pers["bots"]["behavior"]["quickscope"] = true;
}
- for(i=0; i < 5; i++)
+ for ( i = 0; i < 5; i++ )
{
- primary = get_random_weapon(primaryGroups, rank);
- att1 = get_random_attachment(primary, rank);
-
- perk2 = get_random_perk("perk2", rank);
- if(perk2 != "specialty_twoprimaries")
- secondary = get_random_weapon(secondaryGroups, rank);
+ primary = get_random_weapon( primaryGroups, rank );
+ att1 = get_random_attachment( primary, rank );
+
+ perk2 = get_random_perk( "perk2", rank );
+
+ if ( perk2 != "specialty_twoprimaries" )
+ secondary = get_random_weapon( secondaryGroups, rank );
else
{
secondary = "";
- while(secondary == "")
+ while ( secondary == "" )
{
- secondary = get_random_weapon(primaryGroups, rank);
+ secondary = get_random_weapon( primaryGroups, rank );
- if (primary == secondary)
+ if ( primary == secondary )
secondary = "";
}
}
- att2 = get_random_attachment(secondary, rank);
- perk1 = get_random_perk("perk1", rank, att1, att2);
-
- perk3 = get_random_perk("perk3", rank);
- gren = get_random_grenade(perk1);
- camo = randomInt(8);
-
- self setStat ( 200+(i*10)+1, level.weaponReferenceToIndex[primary] );
- self setStat ( 200+(i*10)+2, level.weaponAttachmentReferenceToIndex[att1] );
- self setStat ( 200+(i*10)+3, level.weaponReferenceToIndex[secondary] );
- self setStat ( 200+(i*10)+4, level.weaponAttachmentReferenceToIndex[att2] );
- self setStat ( 200+(i*10)+5, level.perkReferenceToIndex[perk1] );
- self setStat ( 200+(i*10)+6, level.perkReferenceToIndex[perk2] );
- self setStat ( 200+(i*10)+7, level.perkReferenceToIndex[perk3] );
- self setStat ( 200+(i*10)+8, level.weaponReferenceToIndex[gren] );
- self setStat ( 200+(i*10)+9, camo);
+
+ att2 = get_random_attachment( secondary, rank );
+ perk1 = get_random_perk( "perk1", rank, att1, att2 );
+
+ perk3 = get_random_perk( "perk3", rank );
+ gren = get_random_grenade( perk1 );
+ camo = randomInt( 8 );
+
+ self setStat ( 200 + ( i * 10 ) + 1, level.weaponReferenceToIndex[primary] );
+ self setStat ( 200 + ( i * 10 ) + 2, level.weaponAttachmentReferenceToIndex[att1] );
+ self setStat ( 200 + ( i * 10 ) + 3, level.weaponReferenceToIndex[secondary] );
+ self setStat ( 200 + ( i * 10 ) + 4, level.weaponAttachmentReferenceToIndex[att2] );
+ self setStat ( 200 + ( i * 10 ) + 5, level.perkReferenceToIndex[perk1] );
+ self setStat ( 200 + ( i * 10 ) + 6, level.perkReferenceToIndex[perk2] );
+ self setStat ( 200 + ( i * 10 ) + 7, level.perkReferenceToIndex[perk3] );
+ self setStat ( 200 + ( i * 10 ) + 8, level.weaponReferenceToIndex[gren] );
+ self setStat ( 200 + ( i * 10 ) + 9, camo );
}
}
/*
Returns a random attachment for the bot.
*/
-get_random_attachment(weapon, rank)
+get_random_attachment( weapon, rank )
{
- if (RandomFloatRange( 0, 1 ) > (0.1 + ( rank / level.maxRank )))
+ if ( RandomFloatRange( 0, 1 ) > ( 0.1 + ( rank / level.maxRank ) ) )
return "none";
- reasonable = GetDvarInt("bots_loadout_reasonable");
-
+ reasonable = GetDvarInt( "bots_loadout_reasonable" );
+ op = GetDvarInt( "bots_loadout_allow_op" );
+
id = level.tbl_weaponIDs[level.weaponReferenceToIndex[weapon]];
- atts = strtok(id["attachment"], " ");
+ atts = strtok( id["attachment"], " " );
atts[atts.size] = "none";
-
- for(;;)
+
+ for ( ;; )
{
- att = atts[randomInt(atts.size)];
-
- if(reasonable)
+ att = atts[randomInt( atts.size )];
+
+ if ( reasonable )
{
- switch(att)
+ switch ( att )
{
case "acog":
- if(weapon != "m40a3")
+ if ( weapon != "m40a3" )
continue;
+
break;
}
}
-
+
+ if ( !op )
+ {
+ if ( att == "gl" )
+ continue;
+ }
+
return att;
}
}
@@ -643,33 +722,34 @@ get_random_attachment(weapon, rank)
/*
Returns a random perk for the bot.
*/
-get_random_perk(perkslot, rank, att1, att2)
+get_random_perk( perkslot, rank, att1, att2 )
{
- if(isDefined(att1) && isDefined(att2) && (att1 == "grip" || att1 == "gl" || att2 == "grip" || att2 == "gl"))
+ if ( isDefined( att1 ) && isDefined( att2 ) && ( att1 == "grip" || att1 == "gl" || att2 == "grip" || att2 == "gl" ) )
return "specialty_null";
-
- reasonable = GetDvarInt("bots_loadout_reasonable");
- op = GetDvarInt("bots_loadout_allow_op");
-
- keys = getArrayKeys(level.tbl_PerkData);
- for(;;)
+
+ reasonable = GetDvarInt( "bots_loadout_reasonable" );
+ op = GetDvarInt( "bots_loadout_allow_op" );
+
+ keys = getArrayKeys( level.tbl_PerkData );
+
+ for ( ;; )
{
- id = level.tbl_PerkData[keys[randomInt(keys.size)]];
-
- if(!isDefined(id) || !isDefined(id["perk_num"]))
+ id = level.tbl_PerkData[keys[randomInt( keys.size )]];
+
+ if ( !isDefined( id ) || !isDefined( id["perk_num"] ) )
continue;
-
- if(perkslot != id["perk_num"])
+
+ if ( perkslot != id["perk_num"] )
continue;
-
+
ref = id["reference_full"];
-
- if(ref == "specialty_null" && randomInt(100) < 95)
+
+ if ( ref == "specialty_null" && randomInt( 100 ) < 95 )
continue;
-
- if(reasonable)
+
+ if ( reasonable )
{
- switch(ref)
+ switch ( ref )
{
case "specialty_parabolic":
case "specialty_holdbreath":
@@ -678,21 +758,22 @@ get_random_perk(perkslot, rank, att1, att2)
continue;
}
}
-
- if(!op)
+
+ if ( !op )
{
- switch(ref)
+ switch ( ref )
{
case "specialty_armorvest":
case "specialty_pistoldeath":
case "specialty_grenadepulldeath":
+ case "specialty_weapon_rpg":
continue;
}
}
-
- if(!isItemUnlocked(ref, rank))
+
+ if ( !isItemUnlocked( ref, rank ) )
continue;
-
+
return ref;
}
}
@@ -700,31 +781,31 @@ get_random_perk(perkslot, rank, att1, att2)
/*
Returns a random grenade for the bot.
*/
-get_random_grenade(perk1)
+get_random_grenade( perk1 )
{
possibles = [];
possibles[0] = "flash_grenade";
possibles[1] = "smoke_grenade";
possibles[2] = "concussion_grenade";
-
- reasonable = GetDvarInt("bots_loadout_reasonable");
-
- for(;;)
+
+ reasonable = GetDvarInt( "bots_loadout_reasonable" );
+
+ for ( ;; )
{
- possible = possibles[randomInt(possibles.size)];
-
- if(reasonable)
+ possible = possibles[randomInt( possibles.size )];
+
+ if ( reasonable )
{
- switch(possible)
+ switch ( possible )
{
case "smoke_grenade":
continue;
}
}
-
- if(perk1 == "specialty_specialgrenade" && possible == "smoke_grenade")
+
+ if ( perk1 == "specialty_specialgrenade" && possible == "smoke_grenade" )
continue;
-
+
return possible;
}
}
@@ -732,34 +813,37 @@ get_random_grenade(perk1)
/*
Returns a random weapon for the bot.
*/
-get_random_weapon(groups, rank)
+get_random_weapon( groups, rank )
{
- reasonable = GetDvarInt("bots_loadout_reasonable");
-
- keys = getArrayKeys(level.tbl_weaponIDs);
- for(;;)
+ reasonable = GetDvarInt( "bots_loadout_reasonable" );
+ op = GetDvarInt( "bots_loadout_allow_op" );
+
+ keys = getArrayKeys( level.tbl_weaponIDs );
+
+ for ( ;; )
{
- id = level.tbl_weaponIDs[keys[randomInt(keys.size)]];
-
- if(!isDefined(id))
+ id = level.tbl_weaponIDs[keys[randomInt( keys.size )]];
+
+ if ( !isDefined( id ) )
continue;
-
+
group = id["group"];
inGroup = false;
- for(i = groups.size - 1; i >= 0; i--)
+
+ for ( i = groups.size - 1; i >= 0; i-- )
{
- if(groups[i] == group)
+ if ( groups[i] == group )
inGroup = true;
}
-
- if(!inGroup)
+
+ if ( !inGroup )
continue;
-
+
ref = id["reference"];
-
- if(reasonable)
+
+ if ( reasonable )
{
- switch(ref)
+ switch ( ref )
{
case "skorpion":
case "uzi":
@@ -773,10 +857,16 @@ get_random_weapon(groups, rank)
continue;
}
}
-
- if(!isItemUnlocked(ref, rank))
+
+ if ( !op )
+ {
+ if ( ref == "rpg" )
+ continue;
+ }
+
+ if ( !isItemUnlocked( ref, rank ) )
continue;
-
+
return ref;
}
}
@@ -786,28 +876,28 @@ get_random_weapon(groups, rank)
*/
bot_get_prestige()
{
- p_dvar = getDvarInt("bots_loadout_prestige");
+ p_dvar = getDvarInt( "bots_loadout_prestige" );
p = 0;
- if (p_dvar == -1)
+ if ( p_dvar == -1 )
{
- for (i = 0; i < level.players.size; i++)
+ for ( i = 0; i < level.players.size; i++ )
{
player = level.players[i];
- if (!isDefined(player.team))
+ if ( !isDefined( player.team ) )
continue;
- if (player is_bot())
+ if ( player is_bot() )
continue;
- p = player getStat( int(tableLookup( "mp/playerStatsTable.csv", 1, "plevel", 0 )) );
+ p = player getStat( int( tableLookup( "mp/playerStatsTable.csv", 1, "plevel", 0 ) ) );
break;
}
}
- else if (p_dvar == -2)
+ else if ( p_dvar == -2 )
{
- p = randomInt(12);
+ p = randomInt( 12 );
}
else
{
@@ -823,24 +913,24 @@ bot_get_prestige()
bot_get_rank()
{
rank = 1;
- rank_dvar = getDvarInt("bots_loadout_rank");
+ rank_dvar = getDvarInt( "bots_loadout_rank" );
- if (rank_dvar == -1)
+ if ( rank_dvar == -1 )
{
ranks = [];
bot_ranks = [];
human_ranks = [];
-
+
for ( i = level.players.size - 1; i >= 0; i-- )
{
player = level.players[i];
-
+
if ( player == self )
continue;
-
+
if ( !IsDefined( player.pers[ "rank" ] ) )
continue;
-
+
if ( player is_bot() )
{
bot_ranks[ bot_ranks.size ] = player.pers[ "rank" ];
@@ -851,7 +941,7 @@ bot_get_rank()
}
}
- if( !human_ranks.size )
+ if ( !human_ranks.size )
human_ranks[ human_ranks.size ] = Round( random_normal_distribution( 35, 15, 0, level.maxRank ) );
human_avg = array_average( human_ranks );
@@ -867,10 +957,10 @@ bot_get_rank()
avg = array_average( ranks );
s = array_std_deviation( ranks, avg );
-
+
rank = Round( random_normal_distribution( avg, s, 0, level.maxRank ) );
}
- else if (rank_dvar == 0)
+ else if ( rank_dvar == 0 )
{
rank = Round( random_normal_distribution( 35, 15, 0, level.maxRank ) );
}
@@ -887,20 +977,20 @@ bot_get_rank()
*/
onSpawned()
{
- self endon("disconnect");
-
- for(;;)
+ self endon( "disconnect" );
+
+ for ( ;; )
{
- self waittill("spawned_player");
-
- if(randomInt(100) <= self.pers["bots"]["behavior"]["class"])
+ self waittill( "spawned_player" );
+
+ if ( randomInt( 100 ) <= self.pers["bots"]["behavior"]["class"] )
self.bot_change_class = undefined;
self.bot_lock_goal = false;
self.help_time = undefined;
self.bot_was_follow_script_update = undefined;
- if (getDvarInt("bots_play_obj"))
+ if ( getDvarInt( "bots_play_obj" ) )
self thread bot_dom_cap_think();
}
}
@@ -910,13 +1000,13 @@ onSpawned()
*/
onBotSpawned()
{
- self endon("disconnect");
- level endon("game_ended");
-
- for(;;)
+ self endon( "disconnect" );
+ level endon( "game_ended" );
+
+ for ( ;; )
{
- self waittill("bot_spawned");
-
+ self waittill( "bot_spawned" );
+
self thread start_bot_threads();
}
}
@@ -926,22 +1016,22 @@ onBotSpawned()
*/
start_bot_threads()
{
- self endon("disconnect");
- level endon("game_ended");
- self endon("death");
+ self endon( "disconnect" );
+ level endon( "game_ended" );
+ self endon( "death" );
- while(level.inPrematchPeriod)
+ while ( level.inPrematchPeriod )
wait 0.05;
// inventory usage
- if (getDvarInt("bots_play_killstreak"))
+ if ( getDvarInt( "bots_play_killstreak" ) )
self thread bot_killstreak_think();
self thread bot_weapon_think();
self thread doReloadCancel();
// script targeting
- if (getDvarInt("bots_play_target_other"))
+ if ( getDvarInt( "bots_play_target_other" ) )
{
self thread bot_target_vehicle();
self thread bot_equipment_kill_think();
@@ -954,14 +1044,14 @@ start_bot_threads()
self thread follow_target();
// camp and follow
- if (getDvarInt("bots_play_camp"))
+ if ( getDvarInt( "bots_play_camp" ) )
{
self thread bot_think_follow();
self thread bot_think_camp();
}
// nades
- if (getDvarInt("bots_play_nade"))
+ if ( getDvarInt( "bots_play_nade" ) )
{
self thread bot_use_tube_think();
self thread bot_use_grenade_think();
@@ -970,7 +1060,7 @@ start_bot_threads()
}
// obj
- if (getDvarInt("bots_play_obj"))
+ if ( getDvarInt( "bots_play_obj" ) )
{
self thread bot_dom_def_think();
self thread bot_dom_spawn_kill_think();
@@ -988,99 +1078,58 @@ start_bot_threads()
Increments the number of bots approching the obj, decrements when needed
Used for preventing too many bots going to one obj, or unreachable objs
*/
-bot_inc_bots(obj, unreach)
+bot_inc_bots( obj, unreach )
{
- level endon("game_ended");
- self endon("bot_inc_bots");
+ level endon( "game_ended" );
+ self endon( "bot_inc_bots" );
- if (!isDefined(obj))
+ if ( !isDefined( obj ) )
return;
-
- if (!isDefined(obj.bots))
+
+ if ( !isDefined( obj.bots ) )
obj.bots = 0;
-
+
obj.bots++;
-
- ret = self waittill_any_return("death", "disconnect", "bad_path", "goal", "new_goal");
-
- if (isDefined(obj) && (ret != "bad_path" || !isDefined(unreach)))
+
+ ret = self waittill_any_return( "death", "disconnect", "bad_path", "goal", "new_goal" );
+
+ if ( isDefined( obj ) && ( ret != "bad_path" || !isDefined( unreach ) ) )
obj.bots--;
}
/*
Watches when the bot is touching the obj and calls 'goal'
*/
-bots_watch_touch_obj(obj)
+bots_watch_touch_obj( obj )
{
- self endon ("death");
- self endon ("disconnect");
- self endon ("bad_path");
- self endon ("goal");
- self endon ("new_goal");
+ self endon ( "death" );
+ self endon ( "disconnect" );
+ self endon ( "bad_path" );
+ self endon ( "goal" );
+ self endon ( "new_goal" );
- for (;;)
+ for ( ;; )
{
wait 0.5;
- if (!isDefined(obj))
+ if ( !isDefined( obj ) )
{
- self notify("bad_path");
+ self notify( "bad_path" );
return;
}
- if (self IsTouching(obj))
+ if ( self IsTouching( obj ) )
{
- self notify("goal");
+ self notify( "goal" );
return;
}
}
}
-/*
- Is bot near any of the given waypoints
-*/
-nearAnyOfWaypoints(dist, waypoints)
-{
- dist *= dist;
- for (i = 0; i < waypoints.size; i++)
- {
- waypoint = waypoints[i];
-
- if (DistanceSquared(waypoint.origin, self.origin) > dist)
- continue;
-
- return true;
- }
-
- return false;
-}
-
-/*
- Returns nearest waypoint of waypoints
-*/
-getNearestWaypointOfWaypoints(waypoints)
-{
- answer = undefined;
- closestDist = 2147483647;
- for (i = 0; i < waypoints.size; i++)
- {
- waypoint = waypoints[i];
- thisDist = DistanceSquared(self.origin, waypoint.origin);
-
- if (isDefined(answer) && thisDist > closestDist)
- continue;
-
- answer = waypoint;
- closestDist = thisDist;
- }
-
- return answer;
-}
-
/*
Watches while the obj is being carried, calls 'goal' when complete
*/
-bot_escort_obj(obj, carrier)
+bot_escort_obj( obj, carrier )
{
self endon( "death" );
self endon( "disconnect" );
@@ -1088,183 +1137,184 @@ bot_escort_obj(obj, carrier)
self endon( "bad_path" );
self endon( "new_goal" );
- for (;;)
+ for ( ;; )
{
wait 0.5;
- if (!isDefined(obj))
+ if ( !isDefined( obj ) )
break;
- if (!isDefined(obj.carrier) || carrier == obj.carrier)
+ if ( !isDefined( obj.carrier ) || carrier == obj.carrier )
break;
}
-
- self notify("goal");
+
+ self notify( "goal" );
}
/*
Watches while the obj is not being carried, calls 'goal' when complete
*/
-bot_get_obj(obj)
+bot_get_obj( obj )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
-
- for (;;)
+
+ for ( ;; )
{
wait 0.5;
- if (!isDefined(obj))
+ if ( !isDefined( obj ) )
break;
- if (isDefined(obj.carrier))
+ if ( isDefined( obj.carrier ) )
break;
}
-
- self notify("goal");
+
+ self notify( "goal" );
}
/*
bots will defend their site from a planter/defuser
*/
-bot_defend_site(site)
+bot_defend_site( site )
{
self endon( "death" );
self endon( "disconnect" );
- level endon("game_ended");
+ level endon( "game_ended" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
-
- for (;;)
+
+ for ( ;; )
{
wait 0.5;
- if (!site isInUse())
+ if ( !site isInUse() )
break;
}
- self notify("bad_path");
+ self notify( "bad_path" );
}
/*
Bots will go plant the bomb
*/
-bot_go_plant(plant)
+bot_go_plant( plant )
{
self endon( "death" );
self endon( "disconnect" );
- level endon("game_ended");
+ level endon( "game_ended" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
- for (;;)
+ for ( ;; )
{
wait 1;
- if (level.bombPlanted)
+ if ( level.bombPlanted )
break;
- if (self isTouching(plant.trigger))
+ if ( self isTouching( plant.trigger ) )
break;
}
- if(level.bombPlanted)
- self notify("bad_path");
+ if ( level.bombPlanted )
+ self notify( "bad_path" );
else
- self notify("goal");
+ self notify( "goal" );
}
/*
Bots will go defuse the bomb
*/
-bot_go_defuse(plant)
+bot_go_defuse( plant )
{
self endon( "death" );
self endon( "disconnect" );
- level endon("game_ended");
+ level endon( "game_ended" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
- for (;;)
+ for ( ;; )
{
wait 1;
- if (!level.bombPlanted)
+ if ( !level.bombPlanted )
break;
- if (self isTouching(plant.trigger))
+ if ( self isTouching( plant.trigger ) )
break;
}
- if(!level.bombPlanted)
- self notify("bad_path");
+ if ( !level.bombPlanted )
+ self notify( "bad_path" );
else
- self notify("goal");
+ self notify( "goal" );
}
/*
Creates a bomb use thread and waits for an output
*/
-bot_use_bomb_thread(bomb)
+bot_use_bomb_thread( bomb )
{
- self thread bot_use_bomb(bomb);
- self waittill_any("bot_try_use_fail", "bot_try_use_success");
+ self thread bot_use_bomb( bomb );
+ self waittill_any( "bot_try_use_fail", "bot_try_use_success" );
}
/*
Waits for the time to call bot_try_use_success or fail
*/
-bot_bomb_use_time(wait_time)
+bot_bomb_use_time( wait_time )
{
- level endon("game_ended");
- self endon("death");
- self endon("disconnect");
- self endon("bot_try_use_fail");
- self endon("bot_try_use_success");
-
- self waittill("bot_try_use_weapon");
-
+ level endon( "game_ended" );
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "bot_try_use_fail" );
+ self endon( "bot_try_use_success" );
+
+ self waittill( "bot_try_use_weapon" );
+
wait 0.05;
elapsed = 0;
- while(wait_time > elapsed)
+
+ while ( wait_time > elapsed )
{
wait 0.05;//wait first so waittill can setup
elapsed += 0.05;
-
- if(self InLastStand())
+
+ if ( self InLastStand() )
{
- self notify("bot_try_use_fail");
+ self notify( "bot_try_use_fail" );
return;//needed?
}
}
-
- self notify("bot_try_use_success");
+
+ self notify( "bot_try_use_success" );
}
/*
Bot switches to the bomb weapon
*/
-bot_use_bomb_weapon(weap)
+bot_use_bomb_weapon( weap )
{
- level endon("game_ended");
- self endon("death");
- self endon("disconnect");
-
+ level endon( "game_ended" );
+ self endon( "death" );
+ self endon( "disconnect" );
+
lastWeap = self getCurrentWeapon();
-
- if(self getCurrentWeapon() != weap)
+
+ if ( self getCurrentWeapon() != weap )
{
self GiveWeapon( weap );
- if (!self ChangeToWeapon(weap))
+ if ( !self ChangeToWeapon( weap ) )
{
- self notify("bot_try_use_fail");
+ self notify( "bot_try_use_fail" );
return;
}
}
@@ -1272,50 +1322,50 @@ bot_use_bomb_weapon(weap)
{
wait 0.05;//allow a waittill to setup as the notify may happen on the same frame
}
-
- self notify("bot_try_use_weapon");
- ret = self waittill_any_return("bot_try_use_fail", "bot_try_use_success");
-
- if(lastWeap != "none")
- self thread ChangeToWeapon(lastWeap);
+
+ self notify( "bot_try_use_weapon" );
+ ret = self waittill_any_return( "bot_try_use_fail", "bot_try_use_success" );
+
+ if ( lastWeap != "none" )
+ self thread ChangeToWeapon( lastWeap );
else
- self takeWeapon(weap);
+ self takeWeapon( weap );
}
/*
Bot tries to use the bomb site
*/
-bot_use_bomb(bomb)
+bot_use_bomb( bomb )
{
- level endon("game_ended");
+ level endon( "game_ended" );
bomb.inUse = true;
-
+
myteam = self.team;
-
- self BotFreezeControls(true);
-
- bomb [[bomb.onBeginUse]](self);
-
+
+ self BotFreezeControls( true );
+
+ bomb [[bomb.onBeginUse]]( self );
+
self clientClaimTrigger( bomb.trigger );
self.claimTrigger = bomb.trigger;
-
- self thread bot_bomb_use_time(bomb.useTime / 1000);
- self thread bot_use_bomb_weapon(bomb.useWeapon);
-
- result = self waittill_any_return("death", "disconnect", "bot_try_use_fail", "bot_try_use_success");
-
- if (isDefined(self))
+
+ self thread bot_bomb_use_time( bomb.useTime / 1000 );
+ self thread bot_use_bomb_weapon( bomb.useWeapon );
+
+ result = self waittill_any_return( "death", "disconnect", "bot_try_use_fail", "bot_try_use_success" );
+
+ if ( isDefined( self ) )
{
self.claimTrigger = undefined;
- self BotFreezeControls(false);
+ self BotFreezeControls( false );
}
- bomb [[bomb.onEndUse]](myteam, self, (result == "bot_try_use_success"));
+ bomb [[bomb.onEndUse]]( myteam, self, ( result == "bot_try_use_success" ) );
bomb.trigger releaseClaimedTrigger();
-
- if(result == "bot_try_use_success")
- bomb [[bomb.onUse]](self);
+
+ if ( result == "bot_try_use_success" )
+ bomb [[bomb.onUse]]( self );
bomb.inUse = false;
}
@@ -1325,14 +1375,14 @@ bot_use_bomb(bomb)
*/
fire_current_weapon()
{
- self endon("death");
- self endon("disconnect");
- self endon("weapon_change");
- self endon("stop_firing_weapon");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "weapon_change" );
+ self endon( "stop_firing_weapon" );
- for (;;)
+ for ( ;; )
{
- self thread BotPressAttack(0.05);
+ self thread BotPressAttack( 0.05 );
wait 0.1;
}
}
@@ -1342,14 +1392,14 @@ fire_current_weapon()
*/
fire_c4()
{
- self endon("death");
- self endon("disconnect");
- self endon("weapon_change");
- self endon("stop_firing_weapon");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "weapon_change" );
+ self endon( "stop_firing_weapon" );
- for (;;)
+ for ( ;; )
{
- self thread BotPressAds(0.05);
+ self thread BotPressAds( 0.05 );
wait 0.1;
}
}
@@ -1357,65 +1407,65 @@ fire_c4()
/*
Changes to the weap
*/
-changeToWeapon(weap)
+changeToWeapon( weap )
{
- self endon("disconnect");
- self endon("death");
- level endon("game_ended");
+ self endon( "disconnect" );
+ self endon( "death" );
+ level endon( "game_ended" );
- if (!self HasWeapon(weap))
+ if ( !self HasWeapon( weap ) )
return false;
- if (self GetCurrentWeapon() == weap)
+ self BotChangeToWeapon( weap );
+
+ if ( self GetCurrentWeapon() == weap )
return true;
- self BotChangeToWeapon(weap);
+ self waittill_any_timeout( 5, "weapon_change" );
- self waittill_any_timeout(5, "weapon_change");
-
- return (self GetCurrentWeapon() == weap);
+ return ( self GetCurrentWeapon() == weap );
}
/*
Bots throw the grenade
*/
-botThrowGrenade(nade, time)
+botThrowGrenade( nade, time )
{
- self endon("disconnect");
- self endon("death");
- level endon("game_ended");
+ self endon( "disconnect" );
+ self endon( "death" );
+ level endon( "game_ended" );
- if (!self GetAmmoCount(nade))
+ if ( !self GetAmmoCount( nade ) )
return false;
- if (nade != "frag_grenade_mp")
- self thread BotPressSmoke(time);
+ if ( nade != "frag_grenade_mp" )
+ self thread BotPressSmoke( time );
else
- self thread BotPressFrag(time);
+ self thread BotPressFrag( time );
- ret = self waittill_any_timeout(5, "grenade_fire");
+ ret = self waittill_any_timeout( 5, "grenade_fire" );
- return (ret == "grenade_fire");
+ return ( ret == "grenade_fire" );
}
/*
Gets the object thats the closest in the array
*/
-bot_array_nearest_curorigin(array)
+bot_array_nearest_curorigin( array )
{
result = undefined;
-
- for(i = 0; i < array.size; i++)
- if(!isDefined(result) || DistanceSquared(self.origin,array[i].curorigin) < DistanceSquared(self.origin,result.curorigin))
+
+ for ( i = 0; i < array.size; i++ )
+ if ( !isDefined( result ) || DistanceSquared( self.origin, array[i].curorigin ) < DistanceSquared( self.origin, result.curorigin ) )
result = array[i];
-
+
return result;
}
/*
Clears goal when events death
*/
-stop_go_target_on_death(tar)
+stop_go_target_on_death( tar )
{
self endon( "death" );
self endon( "disconnect" );
@@ -1423,11 +1473,43 @@ stop_go_target_on_death(tar)
self endon( "bad_path" );
self endon( "goal" );
- tar waittill_either("death", "disconnect");
+ tar waittill_either( "death", "disconnect" );
self ClearScriptGoal();
}
+/*
+ Bot logic for bot determining to camp.
+*/
+bot_think_camp_loop()
+{
+ campSpot = getWaypointForIndex( random( self waypointsNear( getWaypointsOfType( "camp" ), 1024 ) ) );
+
+ if ( !isDefined( campSpot ) )
+ return;
+
+ self SetScriptGoal( campSpot.origin, 16 );
+
+ time = randomIntRange( 10, 20 );
+
+ self BotNotifyBotEvent( "camp", "go", campSpot, time );
+
+ ret = self waittill_any_return( "new_goal", "goal", "bad_path" );
+
+ if ( ret != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( ret != "goal" )
+ return;
+
+ self BotNotifyBotEvent( "camp", "start", campSpot, time );
+
+ self thread killCampAfterTime( time );
+ self CampAtSpot( campSpot.origin, campSpot.origin + AnglesToForward( campSpot.angles ) * 2048 );
+
+ self BotNotifyBotEvent( "camp", "stop", campSpot, time );
+}
+
/*
Bot logic for bot determining to camp.
*/
@@ -1435,102 +1517,123 @@ bot_think_camp()
{
self endon( "death" );
self endon( "disconnect" );
-
- for(;;)
+
+ for ( ;; )
{
- wait randomintrange(4,7);
-
+ wait randomintrange( 4, 7 );
+
if ( self HasScriptGoal() || self.bot_lock_goal || self HasScriptAimPos() )
continue;
-
- if(randomInt(100) > self.pers["bots"]["behavior"]["camp"])
+
+ if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["camp"] )
continue;
- campSpots = [];
- distSq = 1024*1024;
- for (i = 0; i < level.waypointsCamp.size; i++)
- {
- if (DistanceSquared(self.origin, level.waypointsCamp[i].origin) > distSq)
- continue;
-
- campSpots[campSpots.size] = level.waypointsCamp[i];
- }
- campSpot = random(campSpots);
-
- if (!isDefined(campSpot))
- continue;
-
- self SetScriptGoal(campSpot.origin, 16);
-
- ret = self waittill_any_return("new_goal", "goal", "bad_path");
-
- if (ret != "new_goal")
- self ClearScriptGoal();
-
- if (ret != "goal")
- continue;
-
- self thread killCampAfterTime(randomIntRange(10,20));
- self CampAtSpot(campSpot.origin, campSpot.origin + AnglesToForward(campSpot.angles) * 2048);
+ self bot_think_camp_loop();
}
}
/*
Kills the camping thread when time
*/
-killCampAfterTime(time)
+killCampAfterTime( time )
{
- self endon("death");
- self endon("disconnect");
- self endon("kill_camp_bot");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "kill_camp_bot" );
wait time + 0.05;
self ClearScriptGoal();
self ClearScriptAimPos();
- self notify("kill_camp_bot");
+ self notify( "kill_camp_bot" );
}
/*
Kills the camping thread when ent gone
*/
-killCampAfterEntGone(ent)
+killCampAfterEntGone( ent )
{
- self endon("death");
- self endon("disconnect");
- self endon("kill_camp_bot");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "kill_camp_bot" );
- for (;;)
+ for ( ;; )
{
wait 0.05;
- if (!isDefined(ent))
+ if ( !isDefined( ent ) )
break;
}
self ClearScriptGoal();
self ClearScriptAimPos();
- self notify("kill_camp_bot");
+ self notify( "kill_camp_bot" );
}
/*
Camps at the spot
*/
-CampAtSpot(origin, anglePos)
+CampAtSpot( origin, anglePos )
{
- self endon("kill_camp_bot");
+ self endon( "kill_camp_bot" );
- self SetScriptGoal(origin, 64);
- if (isDefined(anglePos))
+ self SetScriptGoal( origin, 64 );
+
+ if ( isDefined( anglePos ) )
{
- self SetScriptAimPos(anglePos);
+ self SetScriptAimPos( anglePos );
}
- self waittill("new_goal");
+ self waittill( "new_goal" );
self ClearScriptAimPos();
- self notify("kill_camp_bot");
+ self notify( "kill_camp_bot" );
+}
+
+/*
+ Bot logic for bot determining to follow another player.
+*/
+bot_think_follow_loop()
+{
+ follows = [];
+ distSq = self.pers["bots"]["skill"]["help_dist"] * self.pers["bots"]["skill"]["help_dist"];
+
+ for ( i = level.players.size - 1; i >= 0; i-- )
+ {
+ player = level.players[i];
+
+ if ( !player IsPlayerModelOK() )
+ continue;
+
+ if ( player == self )
+ continue;
+
+ if ( !isAlive( player ) )
+ continue;
+
+ if ( player.team != self.team )
+ continue;
+
+ if ( DistanceSquared( player.origin, self.origin ) > distSq )
+ continue;
+
+ follows[follows.size] = player;
+ }
+
+ toFollow = random( follows );
+
+ if ( !isDefined( toFollow ) )
+ return;
+
+ time = randomIntRange( 10, 20 );
+
+ self BotNotifyBotEvent( "follow", "start", toFollow, time );
+
+ self thread killFollowAfterTime( time );
+ self followPlayer( toFollow );
+
+ self BotNotifyBotEvent( "follow", "stop", toFollow, time );
}
/*
@@ -1540,50 +1643,21 @@ bot_think_follow()
{
self endon( "death" );
self endon( "disconnect" );
-
- for(;;)
+
+ for ( ;; )
{
- wait randomIntRange(3,5);
-
+ wait randomIntRange( 3, 5 );
+
if ( self HasScriptGoal() || self.bot_lock_goal || self HasScriptAimPos() )
continue;
-
- if(randomInt(100) > self.pers["bots"]["behavior"]["follow"])
- continue;
-
- if (!level.teamBased)
+
+ if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["follow"] )
continue;
- follows = [];
- distSq = self.pers["bots"]["skill"]["help_dist"] * self.pers["bots"]["skill"]["help_dist"];
- for (i = level.players.size - 1; i >= 0; i--)
- {
- player = level.players[i];
-
- if(!player IsPlayerModelOK())
- continue;
-
- if (player == self)
- continue;
-
- if(!isAlive(player))
- continue;
-
- if (player.team != self.team)
- continue;
-
- if (DistanceSquared(player.origin, self.origin) > distSq)
- continue;
-
- follows[follows.size] = player;
- }
- toFollow = random(follows);
-
- if (!isDefined(toFollow))
+ if ( !level.teamBased )
continue;
- self thread killFollowAfterTime(randomIntRange(10,20));
- self followPlayer(toFollow);
+ self bot_think_follow_loop();
}
}
@@ -1592,72 +1666,182 @@ bot_think_follow()
*/
watchForFollowNewGoal()
{
- self endon("death");
- self endon("disconnect");
- self endon("kill_follow_bot");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "kill_follow_bot" );
- for (;;)
+ for ( ;; )
{
- self waittill("new_goal");
+ self waittill( "new_goal" );
- if (!isDefined(self.bot_was_follow_script_update))
+ if ( !isDefined( self.bot_was_follow_script_update ) )
break;
}
self ClearScriptAimPos();
- self notify("kill_follow_bot");
+ self notify( "kill_follow_bot" );
}
/*
Kills follow when time
*/
-killFollowAfterTime(time)
+killFollowAfterTime( time )
{
- self endon("death");
- self endon("disconnect");
- self endon("kill_follow_bot");
+ self endon( "death" );
+ self endon( "disconnect" );
+ self endon( "kill_follow_bot" );
wait time;
self ClearScriptGoal();
self ClearScriptAimPos();
- self notify("kill_follow_bot");
+ self notify( "kill_follow_bot" );
}
/*
Determine bot to follow a player
*/
-followPlayer(who)
+followPlayer( who )
{
- self endon("kill_follow_bot");
+ self endon( "kill_follow_bot" );
self thread watchForFollowNewGoal();
- for (;;)
+ for ( ;; )
{
wait 0.05;
- if (!isDefined(who) || !isAlive(who))
+ if ( !isDefined( who ) || !isAlive( who ) )
break;
- self SetScriptAimPos(who.origin + (0, 0, 42));
+ self SetScriptAimPos( who.origin + ( 0, 0, 42 ) );
myGoal = self GetScriptGoal();
- if (isDefined(myGoal) && DistanceSquared(myGoal, who.origin) < 64*64)
+ if ( isDefined( myGoal ) && DistanceSquared( myGoal, who.origin ) < 64 * 64 )
continue;
-
+
self.bot_was_follow_script_update = true;
- self SetScriptGoal(who.origin, 32);
+ self SetScriptGoal( who.origin, 32 );
waittillframeend;
self.bot_was_follow_script_update = undefined;
- self waittill_either("goal", "bad_path");
+ self waittill_either( "goal", "bad_path" );
}
self ClearScriptGoal();
self ClearScriptAimPos();
- self notify("kill_follow_bot");
+ self notify( "kill_follow_bot" );
+}
+
+/*
+ Bots thinking of using a noobtube
+*/
+bot_use_tube_think_loop( data )
+{
+ if ( data.doFastContinue )
+ data.doFastContinue = false;
+ else
+ {
+ wait randomintRange( 3, 7 );
+
+ chance = self.pers["bots"]["behavior"]["nade"] / 2;
+
+ if ( chance > 20 )
+ chance = 20;
+
+ if ( randomInt( 100 ) > chance )
+ return;
+ }
+
+ tube = self getValidTube();
+
+ if ( !isDefined( tube ) )
+ return;
+
+ if ( self HasThreat() || self HasScriptAimPos() )
+ return;
+
+ if ( self BotIsFrozen() )
+ return;
+
+ if ( self IsBotFragging() || self IsBotSmoking() )
+ return;
+
+ if ( self isDefusing() || self isPlanting() )
+ return;
+
+ if ( self InLastStand() )
+ return;
+
+ loc = undefined;
+
+ if ( !self nearAnyOfWaypoints( 128, getWaypointsOfType( "tube" ) ) )
+ {
+ tubeWp = getWaypointForIndex( random( self waypointsNear( getWaypointsOfType( "tube" ), 1024 ) ) );
+
+ myEye = self GetEye();
+
+ if ( !isDefined( tubeWp ) || self HasScriptGoal() || self.bot_lock_goal )
+ {
+ traceForward = BulletTrace( myEye, myEye + AnglesToForward( self GetPlayerAngles() ) * 900 * 5, false, self );
+
+ loc = traceForward["position"];
+ dist = DistanceSquared( self.origin, loc );
+
+ if ( dist < level.bots_minGrenadeDistance || dist > level.bots_maxGrenadeDistance * 5 )
+ return;
+
+ if ( !bulletTracePassed( self.origin + ( 0, 0, 5 ), self.origin + ( 0, 0, 2048 ), false, self ) )
+ return;
+
+ if ( !bulletTracePassed( loc + ( 0, 0, 5 ), loc + ( 0, 0, 2048 ), false, self ) )
+ return;
+
+ loc += ( 0, 0, dist / 16000 );
+ }
+ else
+ {
+ self BotNotifyBotEvent( "tube", "go", tubeWp, tube );
+
+ self SetScriptGoal( tubeWp.origin, 16 );
+
+ ret = self waittill_any_return( "new_goal", "goal", "bad_path" );
+
+ if ( ret != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( ret != "goal" )
+ return;
+
+ data.doFastContinue = true;
+ return;
+ }
+ }
+ else
+ {
+ tubeWp = getWaypointForIndex( self getNearestWaypointOfWaypoints( getWaypointsOfType( "tube" ) ) );
+ loc = tubeWp.origin + AnglesToForward( tubeWp.angles ) * 2048;
+ }
+
+ if ( !isDefined( loc ) )
+ return;
+
+ self BotNotifyBotEvent( "tube", "start", loc, tube );
+
+ self SetScriptAimPos( loc );
+ self BotStopMoving( true );
+ wait 1;
+
+ if ( self changeToWeapon( tube ) )
+ {
+ self thread fire_current_weapon();
+ self waittill_any_timeout( 5, "missile_fire", "weapon_change" );
+ self notify( "stop_firing_weapon" );
+ }
+
+ self ClearScriptAimPos();
+ self BotStopMoving( false );
}
/*
@@ -1665,362 +1849,303 @@ followPlayer(who)
*/
bot_use_tube_think()
{
- self endon("disconnect");
- self endon("death");
- level endon("game_ended");
+ self endon( "disconnect" );
+ self endon( "death" );
+ level endon( "game_ended" );
- doFastContinue = false;
+ data = spawnStruct();
+ data.doFastContinue = false;
- for (;;)
+ for ( ;; )
{
- if (doFastContinue)
- doFastContinue = false;
- else
- {
- wait randomintRange(3, 7);
-
- chance = self.pers["bots"]["behavior"]["nade"] / 2;
- if (chance > 20)
- chance = 20;
-
- if (randomInt(100) > chance)
- continue;
- }
-
- tube = self getValidTube();
- if (!isDefined(tube))
- continue;
-
- if (self HasThreat() || self HasScriptAimPos())
- continue;
-
- if(self BotIsFrozen())
- continue;
-
- if (self IsBotFragging() || self IsBotSmoking())
- continue;
-
- if(self isDefusing() || self isPlanting())
- continue;
-
- if (self InLastStand())
- continue;
-
- loc = undefined;
-
- if (!self nearAnyOfWaypoints(128, level.waypointsTube))
- {
- tubeWps = [];
- distSq = 1024*1024;
- for (i = 0; i < level.waypointsTube.size; i++)
- {
- if (DistanceSquared(self.origin, level.waypointsTube[i].origin) > distSq)
- continue;
-
- tubeWps[tubeWps.size] = level.waypointsTube[i];
- }
- tubeWp = random(tubeWps);
-
- myEye = self GetEye();
- if (!isDefined(tubeWp) || self HasScriptGoal() || self.bot_lock_goal)
- {
- traceForward = BulletTrace(myEye, myEye + AnglesToForward(self GetPlayerAngles()) * 900 * 5, false, self);
-
- loc = traceForward["position"];
- dist = DistanceSquared(self.origin, loc);
- if (dist < level.bots_minGrenadeDistance || dist > level.bots_maxGrenadeDistance * 5)
- continue;
-
- if (!bulletTracePassed(self.origin + (0, 0, 5), self.origin + (0, 0, 2048), false, self))
- continue;
-
- if (!bulletTracePassed(loc + (0, 0, 5), loc + (0, 0, 2048), false, self))
- continue;
-
- loc += (0, 0, dist/16000);
- }
- else
- {
- self SetScriptGoal(tubeWp.origin, 16);
-
- ret = self waittill_any_return("new_goal", "goal", "bad_path");
-
- if (ret != "new_goal")
- self ClearScriptGoal();
-
- if (ret != "goal")
- continue;
-
- doFastContinue = true;
- continue;
- }
- }
- else
- {
- tubeWp = self getNearestWaypointOfWaypoints(level.waypointsTube);
- loc = tubeWp.origin + AnglesToForward(tubeWp.angles) * 2048;
- }
-
- if (!isDefined(loc))
- continue;
-
- self SetScriptAimPos(loc);
- self BotStopMoving(true);
- wait 1;
-
- if (self changeToWeapon(tube))
- {
- self thread fire_current_weapon();
- self waittill_any_timeout(5, "missile_fire", "weapon_change");
- self notify("stop_firing_weapon");
- }
-
- self ClearScriptAimPos();
- self BotStopMoving(false);
+ self bot_use_tube_think_loop( data );
}
}
+/*
+ Bots thinking of using claymores
+*/
+bot_use_equipment_think_loop( data )
+{
+ if ( data.doFastContinue )
+ data.doFastContinue = false;
+ else
+ {
+ wait randomintRange( 2, 4 );
+
+ chance = self.pers["bots"]["behavior"]["nade"] / 2;
+
+ if ( chance > 20 )
+ chance = 20;
+
+ if ( randomInt( 100 ) > chance )
+ return;
+ }
+
+ nade = undefined;
+
+ if ( self GetAmmoCount( "claymore_mp" ) )
+ nade = "claymore_mp";
+
+ if ( self GetAmmoCount( "c4_mp" ) )
+ nade = "c4_mp";
+
+ if ( !isDefined( nade ) )
+ return;
+
+ if ( self HasThreat() || self HasScriptAimPos() )
+ return;
+
+ if ( self BotIsFrozen() )
+ return;
+
+ if ( self IsBotFragging() || self IsBotSmoking() )
+ return;
+
+ if ( self isDefusing() || self isPlanting() )
+ return;
+
+ if ( self inLastStand() )
+ return;
+
+ curWeap = self GetCurrentWeapon();
+
+ if ( curWeap == "none" || !isWeaponDroppable( curWeap ) )
+ curWeap = self.lastDroppableWeapon;
+
+ loc = undefined;
+
+ if ( !self nearAnyOfWaypoints( 128, getWaypointsOfType( "claymore" ) ) )
+ {
+ clayWp = getWaypointForIndex( random( self waypointsNear( getWaypointsOfType( "claymore" ), 1024 ) ) );
+
+ if ( !isDefined( clayWp ) || self HasScriptGoal() || self.bot_lock_goal )
+ {
+ myEye = self GetEye();
+ loc = myEye + AnglesToForward( self GetPlayerAngles() ) * 256;
+
+ if ( !bulletTracePassed( myEye, loc, false, self ) )
+ return;
+ }
+ else
+ {
+ self BotNotifyBotEvent( "equ", "go", clayWp, nade );
+
+ self SetScriptGoal( clayWp.origin, 16 );
+
+ ret = self waittill_any_return( "new_goal", "goal", "bad_path" );
+
+ if ( ret != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( ret != "goal" )
+ return;
+
+ data.doFastContinue = true;
+ return;
+ }
+ }
+ else
+ {
+ clayWp = getWaypointForIndex( self getNearestWaypointOfWaypoints( getWaypointsOfType( "claymore" ) ) );
+ loc = clayWp.origin + AnglesToForward( clayWp.angles ) * 2048;
+ }
+
+ if ( !isDefined( loc ) )
+ return;
+
+ self BotNotifyBotEvent( "equ", "start", loc, nade );
+
+ self SetScriptAimPos( loc );
+ self BotStopMoving( true );
+ wait 1;
+
+ if ( self changeToWeapon( nade ) )
+ {
+ if ( nade != "c4_mp" )
+ self thread fire_current_weapon();
+ else
+ self thread fire_c4();
+
+ self waittill_any_timeout( 5, "grenade_fire", "weapon_change" );
+ self notify( "stop_firing_weapon" );
+ }
+
+ self thread changeToWeapon( curWeap );
+ self ClearScriptAimPos();
+ self BotStopMoving( false );
+}
+
/*
Bots thinking of using claymores
*/
bot_use_equipment_think()
{
- self endon("disconnect");
- self endon("death");
- level endon("game_ended");
+ self endon( "disconnect" );
+ self endon( "death" );
+ level endon( "game_ended" );
- doFastContinue = false;
+ data = spawnStruct();
+ data.doFastContinue = false;
- for (;;)
+ for ( ;; )
{
- if (doFastContinue)
- doFastContinue = false;
- else
- {
- wait randomintRange(2, 4);
-
- chance = self.pers["bots"]["behavior"]["nade"] / 2;
- if (chance > 20)
- chance = 20;
-
- if (randomInt(100) > chance)
- continue;
- }
-
- nade = undefined;
- if (self GetAmmoCount("claymore_mp"))
- nade = "claymore_mp";
- if (self GetAmmoCount("c4_mp"))
- nade = "c4_mp";
-
- if (!isDefined(nade))
- continue;
-
- if (self HasThreat() || self HasScriptAimPos())
- continue;
-
- if(self BotIsFrozen())
- continue;
-
- if(self IsBotFragging() || self IsBotSmoking())
- continue;
-
- if(self isDefusing() || self isPlanting())
- continue;
-
- if (self inLastStand())
- continue;
-
- curWeap = self GetCurrentWeapon();
- if (curWeap == "none" || !isWeaponDroppable(curWeap))
- curWeap = self.lastDroppableWeapon;
-
- loc = undefined;
-
- if (!self nearAnyOfWaypoints(128, level.waypointsClay))
- {
- clayWps = [];
- distSq = 1024*1024;
- for (i = 0; i < level.waypointsClay.size; i++)
- {
- if (DistanceSquared(self.origin, level.waypointsClay[i].origin) > distSq)
- continue;
-
- clayWps[clayWps.size] = level.waypointsClay[i];
- }
- clayWp = random(clayWps);
-
- if (!isDefined(clayWp) || self HasScriptGoal() || self.bot_lock_goal)
- {
- myEye = self GetEye();
- loc = myEye + AnglesToForward(self GetPlayerAngles()) * 256;
-
- if (!bulletTracePassed(myEye, loc, false, self))
- continue;
- }
- else
- {
- self SetScriptGoal(clayWp.origin, 16);
-
- ret = self waittill_any_return("new_goal", "goal", "bad_path");
-
- if (ret != "new_goal")
- self ClearScriptGoal();
-
- if (ret != "goal")
- continue;
-
- doFastContinue = true;
- continue;
- }
- }
- else
- {
- clayWp = self getNearestWaypointOfWaypoints(level.waypointsClay);
- loc = clayWp.origin + AnglesToForward(clayWp.angles) * 2048;
- }
-
- if (!isDefined(loc))
- continue;
-
- self SetScriptAimPos(loc);
- self BotStopMoving(true);
- wait 1;
-
- if (self changeToWeapon(nade))
- {
- if (nade != "c4_mp")
- self thread fire_current_weapon();
- else
- self thread fire_c4();
- self waittill_any_timeout(5, "grenade_fire", "weapon_change");
- self notify("stop_firing_weapon");
- }
-
- self thread changeToWeapon(curWeap);
- self ClearScriptAimPos();
- self BotStopMoving(false);
+ self bot_use_equipment_think_loop( data );
}
}
+/*
+ Bots thinking of using grenades
+*/
+bot_use_grenade_think_loop( data )
+{
+ if ( data.doFastContinue )
+ data.doFastContinue = false;
+ else
+ {
+ wait randomintRange( 4, 7 );
+
+ chance = self.pers["bots"]["behavior"]["nade"] / 2;
+
+ if ( chance > 20 )
+ chance = 20;
+
+ if ( randomInt( 100 ) > chance )
+ return;
+ }
+
+ nade = self getValidGrenade();
+
+ if ( !isDefined( nade ) )
+ return;
+
+ if ( self HasThreat() || self HasScriptAimPos() )
+ return;
+
+ if ( self BotIsFrozen() )
+ return;
+
+ if ( self IsBotFragging() || self IsBotSmoking() )
+ return;
+
+ if ( self isDefusing() || self isPlanting() )
+ return;
+
+ if ( self inLastStand() )
+ return;
+
+ loc = undefined;
+
+ if ( !self nearAnyOfWaypoints( 128, getWaypointsOfType( "grenade" ) ) )
+ {
+ nadeWp = getWaypointForIndex( random( self waypointsNear( getWaypointsOfType( "grenade" ), 1024 ) ) );
+
+ myEye = self GetEye();
+
+ if ( !isDefined( nadeWp ) || self HasScriptGoal() || self.bot_lock_goal )
+ {
+ traceForward = BulletTrace( myEye, myEye + AnglesToForward( self GetPlayerAngles() ) * 900, false, self );
+
+ loc = traceForward["position"];
+ dist = DistanceSquared( self.origin, loc );
+
+ if ( dist < level.bots_minGrenadeDistance || dist > level.bots_maxGrenadeDistance )
+ return;
+
+ if ( !bulletTracePassed( self.origin + ( 0, 0, 5 ), self.origin + ( 0, 0, 2048 ), false, self ) )
+ return;
+
+ if ( !bulletTracePassed( loc + ( 0, 0, 5 ), loc + ( 0, 0, 2048 ), false, self ) )
+ return;
+
+ loc += ( 0, 0, dist / 3000 );
+ }
+ else
+ {
+ self BotNotifyBotEvent( "nade", "go", nadeWp, nade );
+
+ self SetScriptGoal( nadeWp.origin, 16 );
+
+ ret = self waittill_any_return( "new_goal", "goal", "bad_path" );
+
+ if ( ret != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( ret != "goal" )
+ return;
+
+ data.doFastContinue = true;
+ return;
+ }
+ }
+ else
+ {
+ nadeWp = getWaypointForIndex( self getNearestWaypointOfWaypoints( getWaypointsOfType( "grenade" ) ) );
+ loc = nadeWp.origin + AnglesToForward( nadeWp.angles ) * 2048;
+ }
+
+ if ( !isDefined( loc ) )
+ return;
+
+ self BotNotifyBotEvent( "nade", "start", loc, nade );
+
+ self SetScriptAimPos( loc );
+ self BotStopMoving( true );
+ wait 1;
+
+ time = 0.5;
+
+ if ( nade == "frag_grenade_mp" )
+ time = 2;
+
+ self botThrowGrenade( nade, time );
+
+ self ClearScriptAimPos();
+ self BotStopMoving( false );
+}
+
/*
Bots thinking of using grenades
*/
bot_use_grenade_think()
{
- self endon("disconnect");
- self endon("death");
- level endon("game_ended");
+ self endon( "disconnect" );
+ self endon( "death" );
+ level endon( "game_ended" );
- doFastContinue = false;
+ data = spawnStruct();
+ data.doFastContinue = false;
- for (;;)
+ for ( ;; )
{
- if (doFastContinue)
- doFastContinue = false;
- else
- {
- wait randomintRange(4, 7);
-
- chance = self.pers["bots"]["behavior"]["nade"] / 2;
- if (chance > 20)
- chance = 20;
-
- if (randomInt(100) > chance)
- continue;
- }
-
- nade = self getValidGrenade();
- if (!isDefined(nade))
- continue;
-
- if (self HasThreat() || self HasScriptAimPos())
- continue;
-
- if(self BotIsFrozen())
- continue;
-
- if(self IsBotFragging() || self IsBotSmoking())
- continue;
-
- if(self isDefusing() || self isPlanting())
- continue;
-
- if (self inLastStand())
- continue;
-
- loc = undefined;
-
- if (!self nearAnyOfWaypoints(128, level.waypointsGren))
- {
- nadeWps = [];
- distSq = 1024*1024;
- for (i = 0; i < level.waypointsGren.size; i++)
- {
- if (DistanceSquared(self.origin, level.waypointsGren[i].origin) > distSq)
- continue;
-
- nadeWps[nadeWps.size] = level.waypointsGren[i];
- }
- nadeWp = random(nadeWps);
-
- myEye = self GetEye();
- if (!isDefined(nadeWp) || self HasScriptGoal() || self.bot_lock_goal)
- {
- traceForward = BulletTrace(myEye, myEye + AnglesToForward(self GetPlayerAngles()) * 900, false, self);
-
- loc = traceForward["position"];
- dist = DistanceSquared(self.origin, loc);
- if (dist < level.bots_minGrenadeDistance || dist > level.bots_maxGrenadeDistance)
- continue;
-
- if (!bulletTracePassed(self.origin + (0, 0, 5), self.origin + (0, 0, 2048), false, self))
- continue;
-
- if (!bulletTracePassed(loc + (0, 0, 5), loc + (0, 0, 2048), false, self))
- continue;
-
- loc += (0, 0, dist/3000);
- }
- else
- {
- self SetScriptGoal(nadeWp.origin, 16);
-
- ret = self waittill_any_return("new_goal", "goal", "bad_path");
-
- if (ret != "new_goal")
- self ClearScriptGoal();
-
- if (ret != "goal")
- continue;
-
- doFastContinue = true;
- continue;
- }
- }
- else
- {
- nadeWp = self getNearestWaypointOfWaypoints(level.waypointsGren);
- loc = nadeWp.origin + AnglesToForward(nadeWp.angles) * 2048;
- }
-
- if (!isDefined(loc))
- continue;
-
- self SetScriptAimPos(loc);
- self BotStopMoving(true);
- wait 1;
-
- time = 0.5;
- if (nade == "frag_grenade_mp")
- time = 2;
- self botThrowGrenade(nade, time);
-
- self ClearScriptAimPos();
- self BotStopMoving(false);
+ self bot_use_grenade_think_loop( data );
}
}
+/*
+ Goes to the target's location if it had one
+*/
+follow_target_loop()
+{
+ threat = self GetThreat();
+
+ if ( !isPlayer( threat ) )
+ return;
+
+ if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["follow"] * 5 )
+ return;
+
+ self BotNotifyBotEvent( "follow_threat", "start", threat );
+
+ self SetScriptGoal( threat.origin, 64 );
+ self thread stop_go_target_on_death( threat );
+
+ if ( self waittill_any_return( "new_goal", "goal", "bad_path" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self BotNotifyBotEvent( "follow_threat", "stop", threat );
+}
+
/*
Goes to the target's location if it had one
*/
@@ -2028,99 +2153,105 @@ follow_target()
{
self endon( "death" );
self endon( "disconnect" );
-
- for(;;)
+
+ for ( ;; )
{
wait 1;
-
+
if ( self HasScriptGoal() || self.bot_lock_goal )
continue;
-
+
if ( !self HasThreat() )
continue;
- threat = self GetThreat();
-
- if (!isPlayer(threat))
- continue;
-
- if(randomInt(100) > self.pers["bots"]["behavior"]["follow"]*5)
- continue;
-
- self thread stop_go_target_on_death(threat);
-
- self SetScriptGoal(threat.origin, 64);
- if (self waittill_any_return("new_goal", "goal", "bad_path") != "new_goal")
- self ClearScriptGoal();
+ self follow_target_loop();
}
}
+/*
+ Bot logic for detecting nearby players.
+*/
+bot_listen_to_steps_loop()
+{
+ dist = level.bots_listenDist;
+
+ if ( self hasPerk( "specialty_parabolic" ) )
+ dist *= 1.4;
+
+ dist *= dist;
+
+ heard = undefined;
+
+ for ( i = level.players.size - 1 ; i >= 0; i-- )
+ {
+ player = level.players[i];
+
+ if ( !player IsPlayerModelOK() )
+ continue;
+
+ if ( player == self )
+ continue;
+
+ if ( level.teamBased && self.team == player.team )
+ continue;
+
+ if ( player.sessionstate != "playing" )
+ continue;
+
+ if ( !isAlive( player ) )
+ continue;
+
+ if ( player hasPerk( "specialty_quieter" ) )
+ continue;
+
+ if ( lengthsquared( player getVelocity() ) < 20000 )
+ continue;
+
+ if ( distanceSquared( player.origin, self.origin ) > dist )
+ continue;
+
+ heard = player;
+ break;
+ }
+
+ if ( !IsDefined( heard ) )
+ return;
+
+ self BotNotifyBotEvent( "heard_target", "start", heard );
+
+ if ( bulletTracePassed( self getEyePos(), heard getTagOrigin( "j_spineupper" ), false, heard ) )
+ {
+ self setAttacker( heard );
+ return;
+ }
+
+ if ( self HasScriptGoal() || self.bot_lock_goal )
+ return;
+
+ self SetScriptGoal( heard.origin, 64 );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self BotNotifyBotEvent( "heard_target", "stop", heard );
+}
+
/*
Bot logic for detecting nearby players.
*/
bot_listen_to_steps()
{
- self endon("disconnect");
- self endon("death");
-
- for(;;)
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
{
wait 1;
-
- if(self.pers["bots"]["skill"]["base"] < 3)
- continue;
-
- dist = level.bots_listenDist;
- if(self hasPerk("specialty_parabolic"))
- dist *= 1.4;
-
- dist *= dist;
-
- heard = undefined;
- for(i = level.players.size-1 ; i >= 0; i--)
- {
- player = level.players[i];
-
- if(!player IsPlayerModelOK())
- continue;
-
- if(player == self)
- continue;
- if(level.teamBased && self.team == player.team)
- continue;
- if(player.sessionstate != "playing")
- continue;
- if(!isAlive(player))
- continue;
- if(player hasPerk("specialty_quieter"))
- continue;
-
- if(lengthsquared( player getVelocity() ) < 20000)
- continue;
-
- if(distanceSquared(player.origin, self.origin) > dist)
- continue;
-
- heard = player;
- break;
- }
-
- if(!IsDefined(heard))
- continue;
-
- if(bulletTracePassed(self getEyePos(), heard getTagOrigin( "j_spineupper" ), false, heard))
- {
- self setAttacker(heard);
- continue;
- }
- if(self HasScriptGoal() || self.bot_lock_goal)
+ if ( self.pers["bots"]["skill"]["base"] < 3 )
continue;
-
- self SetScriptGoal( heard.origin, 64 );
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
+ self bot_listen_to_steps_loop();
}
}
@@ -2131,236 +2262,382 @@ bot_revenge_think()
{
self endon( "death" );
self endon( "disconnect" );
-
- if(self.pers["bots"]["skill"]["base"] <= 1)
+
+ if ( self.pers["bots"]["skill"]["base"] <= 1 )
return;
- if (isDefined(self.lastKiller) && isAlive(self.lastKiller))
+ if ( isDefined( self.lastKiller ) && isAlive( self.lastKiller ) )
{
- if(bulletTracePassed(self getEyePos(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller))
+ if ( bulletTracePassed( self getEyePos(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller ) )
{
- self setAttacker(self.lastKiller);
+ self setAttacker( self.lastKiller );
}
}
-
- if(!isDefined(self.killerLocation))
+
+ if ( !isDefined( self.killerLocation ) )
return;
loc = self.killerLocation;
-
- for(;;)
+
+ for ( ;; )
{
wait( RandomIntRange( 1, 5 ) );
-
- if(self HasScriptGoal() || self.bot_lock_goal)
+
+ if ( self HasScriptGoal() || self.bot_lock_goal )
return;
-
+
if ( randomint( 100 ) < 75 )
return;
-
+
+ self BotNotifyBotEvent( "revenge", "start", loc, self.lastKiller );
+
self SetScriptGoal( loc, 64 );
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
self ClearScriptGoal();
+
+ self BotNotifyBotEvent( "revenge", "stop", loc, self.lastKiller );
}
}
+/*
+ Reload cancels
+*/
+doReloadCancel_loop()
+{
+ ret = self waittill_any_return( "reload", "weapon_change" );
+
+ if ( self BotIsFrozen() )
+ return;
+
+ if ( self isDefusing() || self isPlanting() )
+ return;
+
+ if ( self InLastStand() )
+ return;
+
+ curWeap = self GetCurrentWeapon();
+
+ if ( !maps\mp\gametypes\_weapons::isSideArm( curWeap ) && !maps\mp\gametypes\_weapons::isPrimaryWeapon( curWeap ) )
+ return;
+
+ if ( ret == "reload" )
+ {
+ // check single reloads
+ if ( self GetWeaponAmmoClip( curWeap ) < WeaponClipSize( curWeap ) )
+ return;
+ }
+
+ // check difficulty
+ if ( self.pers["bots"]["skill"]["base"] <= 3 )
+ return;
+
+ // check if got another weapon
+ weaponslist = self GetWeaponsListPrimaries();
+ weap = "";
+
+ while ( weaponslist.size )
+ {
+ weapon = weaponslist[randomInt( weaponslist.size )];
+ weaponslist = array_remove( weaponslist, weapon );
+
+ if ( !maps\mp\gametypes\_weapons::isSideArm( weapon ) && !maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) )
+ continue;
+
+ if ( curWeap == weapon || weapon == "none" || weapon == "" )
+ continue;
+
+ weap = weapon;
+ break;
+ }
+
+ if ( weap == "" )
+ return;
+
+ // do the cancel
+ wait 0.1;
+ self thread ChangeToWeapon( weap );
+ wait 0.25;
+ self thread ChangeToWeapon( curWeap );
+ wait 2;
+}
+
/*
Reload cancels
*/
doReloadCancel()
{
- self endon("disconnect");
- self endon("death");
+ self endon( "disconnect" );
+ self endon( "death" );
- for (;;)
+ for ( ;; )
{
- ret = self waittill_any_return("reload", "weapon_change");
-
- if(self BotIsFrozen())
- continue;
-
- if(self isDefusing() || self isPlanting())
- continue;
-
- if (self InLastStand())
- continue;
-
- curWeap = self GetCurrentWeapon();
-
- if (!maps\mp\gametypes\_weapons::isSideArm( curWeap ) && !maps\mp\gametypes\_weapons::isPrimaryWeapon( curWeap ))
- continue;
-
- if (ret == "reload")
- {
- // check single reloads
- if (self GetWeaponAmmoClip(curWeap) < WeaponClipSize(curWeap))
- continue;
- }
-
- // check difficulty
- if (self.pers["bots"]["skill"]["base"] <= 3)
- continue;
-
- // check if got another weapon
- weaponslist = self GetWeaponsListPrimaries();
- weap = "";
- while(weaponslist.size)
- {
- weapon = weaponslist[randomInt(weaponslist.size)];
- weaponslist = array_remove(weaponslist, weapon);
-
- if (!maps\mp\gametypes\_weapons::isSideArm( weapon ) && !maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ))
- continue;
-
- if(curWeap == weapon || weapon == "none" || weapon == "")
- continue;
-
- weap = weapon;
- break;
- }
-
- if(weap == "")
- continue;
-
- // do the cancel
- wait 0.1;
- self BotChangeToWeapon(weap);
- wait 0.25;
- self BotChangeToWeapon(curWeap);
- wait 2;
+ self doReloadCancel_loop();
}
}
+/*
+ Bot logic for switching weapons.
+*/
+bot_weapon_think_loop( data )
+{
+ self waittill_any_timeout( randomIntRange( 2, 4 ), "bot_force_check_switch" );
+
+ if ( self BotIsFrozen() )
+ return;
+
+ if ( self isDefusing() || self isPlanting() || self InLastStand() )
+ return;
+
+ hasTarget = self hasThreat();
+ curWeap = self GetCurrentWeapon();
+
+ if ( hasTarget )
+ {
+ threat = self getThreat();
+
+ if ( threat.classname == "script_vehicle" && self getAmmoCount( "rpg_mp" ) )
+ {
+ if ( curWeap != "rpg_mp" )
+ self thread ChangeToWeapon( "rpg_mp" );
+
+ return;
+ }
+ }
+
+ if ( data.first )
+ {
+ data.first = false;
+
+ if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["initswitch"] )
+ return;
+ }
+ else
+ {
+ if ( curWeap != "none" && self getAmmoCount( curWeap ) )
+ {
+ if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["switch"] )
+ return;
+
+ if ( hasTarget )
+ return;
+ }
+ }
+
+ weaponslist = self getweaponslist();
+ weap = "";
+
+ while ( weaponslist.size )
+ {
+ weapon = weaponslist[randomInt( weaponslist.size )];
+ weaponslist = array_remove( weaponslist, weapon );
+
+ if ( !self getAmmoCount( weapon ) )
+ continue;
+
+ if ( maps\mp\gametypes\_weapons::isHackWeapon( weapon ) )
+ continue;
+
+ if ( maps\mp\gametypes\_weapons::isGrenade( weapon ) )
+ continue;
+
+ if ( curWeap == weapon || weapon == "c4_mp" || weapon == "none" || weapon == "claymore_mp" || weapon == "" )
+ continue;
+
+ weap = weapon;
+ break;
+ }
+
+ if ( weap == "" )
+ return;
+
+ self thread ChangeToWeapon( weap );
+}
+
/*
Bot logic for switching weapons.
*/
bot_weapon_think()
{
- self endon("death");
- self endon("disconnect");
- level endon("game_ended");
+ self endon( "death" );
+ self endon( "disconnect" );
+ level endon( "game_ended" );
- first = true;
-
- for(;;)
+ data = spawnStruct();
+ data.first = true;
+
+ for ( ;; )
{
- self waittill_any_timeout(randomIntRange(2, 4), "bot_force_check_switch");
-
- if(self BotIsFrozen())
- continue;
-
- if(self isDefusing() || self isPlanting() || self InLastStand())
- continue;
-
- hasTarget = self hasThreat();
- curWeap = self GetCurrentWeapon();
-
- if(hasTarget)
- {
- threat = self getThreat();
-
- if(threat.classname == "script_vehicle" && self getAmmoCount("rpg_mp"))
- {
- if (curWeap != "rpg_mp")
- self thread ChangeToWeapon("rpg_mp");
- continue;
- }
- }
-
- if (first)
- {
- first = false;
-
- if(randomInt(100) > self.pers["bots"]["behavior"]["initswitch"])
- continue;
- }
- else
- {
- if(curWeap != "none" && self getAmmoCount(curWeap))
- {
- if(randomInt(100) > self.pers["bots"]["behavior"]["switch"])
- continue;
-
- if(hasTarget)
- continue;
- }
- }
-
- weaponslist = self getweaponslist();
- weap = "";
- while(weaponslist.size)
- {
- weapon = weaponslist[randomInt(weaponslist.size)];
- weaponslist = array_remove(weaponslist, weapon);
-
- if(!self getAmmoCount(weapon))
- continue;
-
- if (maps\mp\gametypes\_weapons::isHackWeapon( weapon ))
- continue;
-
- if (maps\mp\gametypes\_weapons::isGrenade( weapon ))
- continue;
-
- if(curWeap == weapon || weapon == "c4_mp" || weapon == "none" || weapon == "claymore_mp" || weapon == "")
- continue;
-
- weap = weapon;
- break;
- }
-
- if(weap == "")
- continue;
-
- self thread ChangeToWeapon(weap);
+ self bot_weapon_think_loop( data );
}
}
+/*
+ Bots play mw2
+*/
+bot_watch_think_mw2_loop()
+{
+ tube = self getValidTube();
+
+ if ( !isDefined( tube ) )
+ {
+ if ( self GetAmmoCount( "rpg_mp" ) )
+ tube = "rpg_mp";
+ else
+ return;
+ }
+
+ if ( self GetCurrentWeapon() == tube )
+ return;
+
+ chance = self.pers["bots"]["behavior"]["nade"];
+
+ if ( randomInt( 100 ) > chance )
+ return;
+
+ self thread ChangeToWeapon( tube );
+}
+
/*
Bots play mw2
*/
bot_watch_think_mw2()
{
- self endon("disconnect");
- self endon("death");
- level endon("game_ended");
+ self endon( "disconnect" );
+ self endon( "death" );
+ level endon( "game_ended" );
- for (;;)
+ for ( ;; )
{
- wait randomIntRange(1, 4);
+ wait randomIntRange( 1, 4 );
- if(self BotIsFrozen())
- continue;
-
- if(self isDefusing() || self isPlanting())
+ if ( self BotIsFrozen() )
continue;
- if (self InLastStand())
+ if ( self isDefusing() || self isPlanting() )
continue;
- if (self HasThreat())
+ if ( self InLastStand() )
continue;
- tube = self getValidTube();
- if (!isDefined(tube))
+ if ( self HasThreat() )
+ continue;
+
+ self bot_watch_think_mw2_loop();
+ }
+}
+
+/*
+ Bot logic for killstreaks.
+*/
+bot_killstreak_think_loop()
+{
+ curWeap = self GetCurrentWeapon();
+
+ if ( curWeap == "none" || !isWeaponDroppable( curWeap ) )
+ curWeap = self.lastDroppableWeapon;
+
+ targetPos = undefined;
+
+ switch ( self.pers["hardPointItem"] )
+ {
+ case "radar_mp":
+ if ( self.bot_radar && self.pers["bots"]["skill"]["base"] > 3 )
+ return;
+
+ break;
+
+ case "helicopter_mp":
+ chopper = level.chopper;
+
+ if ( isDefined( chopper ) && level.teamBased && getDvarInt( "doubleHeli" ) )
+ chopper = level.chopper[self.team];
+
+ if ( isDefined( chopper ) )
+ return;
+
+ if ( isDefined( level.mannedchopper ) )
+ return;
+
+ break;
+
+ case "airstrike_mp":
+ if ( isDefined( level.airstrikeInProgress ) )
+ return;
+
+ players = [];
+
+ for ( i = level.players.size - 1; i >= 0; i-- )
+ {
+ player = level.players[i];
+
+ if ( !player IsPlayerModelOK() )
+ continue;
+
+ if ( player == self )
+ continue;
+
+ if ( !isDefined( player.team ) )
+ continue;
+
+ if ( level.teamBased && self.team == player.team )
+ continue;
+
+ if ( player.sessionstate != "playing" )
+ continue;
+
+ if ( !isAlive( player ) )
+ continue;
+
+ if ( player hasPerk( "specialty_gpsjammer" ) )
+ continue;
+
+ if ( !bulletTracePassed( player.origin, player.origin + ( 0, 0, 512 ), false, player ) && self.pers["bots"]["skill"]["base"] > 3 )
+ continue;
+
+ players[players.size] = player;
+ }
+
+ target = random( players );
+
+ if ( isDefined( target ) )
+ targetPos = target.origin + ( randomIntRange( ( 8 - self.pers["bots"]["skill"]["base"] ) * -75, ( 8 - self.pers["bots"]["skill"]["base"] ) * 75 ), randomIntRange( ( 8 - self.pers["bots"]["skill"]["base"] ) * -75, ( 8 - self.pers["bots"]["skill"]["base"] ) * 75 ), 0 );
+ else if ( self.pers["bots"]["skill"]["base"] <= 3 )
+ targetPos = self.origin + ( randomIntRange( -512, 512 ), randomIntRange( -512, 512 ), 0 );
+
+ break;
+
+ default:
+ return;
+ }
+
+ isAirstrikePos = isDefined( targetPos );
+
+ if ( self.pers["hardPointItem"] == "airstrike_mp" && !isAirstrikePos )
+ return;
+
+ self BotNotifyBotEvent( "killstreak", "call", targetPos );
+
+ self BotStopMoving( true );
+
+ if ( self changeToWeapon( self.pers["hardPointItem"] ) )
+ {
+ wait 1;
+
+ if ( isAirstrikePos && !isDefined( level.airstrikeInProgress ) )
{
- if (self GetAmmoCount("rpg_mp"))
- tube = "rpg_mp";
- else
- continue;
+ self BotFreezeControls( true );
+
+ self notify( "confirm_location", targetPos );
+ wait 1;
+
+ self BotFreezeControls( false );
}
- if (self GetCurrentWeapon() == tube)
- continue;
-
- chance = self.pers["bots"]["behavior"]["nade"];
-
- if (randomInt(100) > chance)
- continue;
-
- self ChangeToWeapon(tube);
+ self thread changeToWeapon( curWeap );
}
+
+ self BotStopMoving( false );
}
/*
@@ -2368,118 +2645,89 @@ bot_watch_think_mw2()
*/
bot_killstreak_think()
{
- self endon("death");
- self endon("disconnect");
- level endon("game_ended");
-
- for(;;)
+ self endon( "death" );
+ self endon( "disconnect" );
+ level endon( "game_ended" );
+
+ for ( ;; )
{
- wait randomIntRange(1, 3);
-
- if(self BotIsFrozen())
- continue;
-
- if(!isDefined(self.pers["hardPointItem"]))
- continue;
-
- if(self HasThreat())
- continue;
-
- if(self isDefusing() || self isPlanting() || self InLastStand())
+ wait randomIntRange( 1, 3 );
+
+ if ( self BotIsFrozen() )
continue;
- curWeap = self GetCurrentWeapon();
- if (curWeap == "none" || !isWeaponDroppable(curWeap))
- curWeap = self.lastDroppableWeapon;
-
- targetPos = undefined;
- switch(self.pers["hardPointItem"])
+ if ( !isDefined( self.pers["hardPointItem"] ) )
+ continue;
+
+ if ( self HasThreat() )
+ continue;
+
+ if ( self isDefusing() || self isPlanting() || self InLastStand() )
+ continue;
+
+ self bot_killstreak_think_loop();
+ }
+}
+
+/*
+ Bot logic for UAV detection here. Checks for UAV and players who are shooting.
+*/
+bot_uav_think_loop()
+{
+ dist = self.pers["bots"]["skill"]["help_dist"];
+ dist *= dist * 8;
+
+ for ( i = level.players.size - 1; i >= 0; i-- )
+ {
+ player = level.players[i];
+
+ if ( !player IsPlayerModelOK() )
+ continue;
+
+ if ( player == self )
+ continue;
+
+ if ( !isDefined( player.team ) )
+ continue;
+
+ if ( player.sessionstate != "playing" )
+ continue;
+
+ if ( level.teambased && player.team == self.team )
+ continue;
+
+ if ( !isAlive( player ) )
+ continue;
+
+ distFromPlayer = DistanceSquared( self.origin, player.origin );
+
+ if ( distFromPlayer > dist )
+ continue;
+
+ if ( ( !isSubStr( player getCurrentWeapon(), "_silencer_" ) && player.bots_firing ) || ( self.bot_radar && !player hasPerk( "specialty_gpsjammer" ) ) )
{
- case "radar_mp":
- if(self.bot_radar && self.pers["bots"]["skill"]["base"] > 3)
- continue;
- break;
-
- case "helicopter_mp":
- chopper = level.chopper;
+ self BotNotifyBotEvent( "uav_target", "start", player );
- if (isDefined(chopper) && level.teamBased && getDvarInt("doubleHeli"))
- chopper = level.chopper[self.team];
+ distSq = self.pers["bots"]["skill"]["help_dist"] * self.pers["bots"]["skill"]["help_dist"];
- if (isDefined(chopper))
- continue;
-
- if (isDefined( level.mannedchopper ))
- continue;
-
- break;
-
- case "airstrike_mp":
- if(isDefined( level.airstrikeInProgress ))
- continue;
-
- players = [];
- for(i = level.players.size - 1; i >= 0; i--)
- {
- player = level.players[i];
-
- if(!player IsPlayerModelOK())
- continue;
-
- if(player == self)
- continue;
- if(!isDefined(player.team))
- continue;
- if(level.teamBased && self.team == player.team)
- continue;
- if(player.sessionstate != "playing")
- continue;
- if(!isAlive(player))
- continue;
- if(player hasPerk("specialty_gpsjammer"))
- continue;
- if(!bulletTracePassed(player.origin, player.origin+(0,0,512), false, player) && self.pers["bots"]["skill"]["base"] > 3)
- continue;
-
- players[players.size] = player;
- }
-
- target = random(players);
-
- if(isDefined(target))
- targetPos = target.origin + (randomIntRange((8-self.pers["bots"]["skill"]["base"])*-75, (8-self.pers["bots"]["skill"]["base"])*75), randomIntRange((8-self.pers["bots"]["skill"]["base"])*-75, (8-self.pers["bots"]["skill"]["base"])*75), 0);
- else if(self.pers["bots"]["skill"]["base"] <= 3)
- targetPos = self.origin + (randomIntRange(-512, 512), randomIntRange(-512, 512), 0);
- break;
-
- default:
- continue;
- }
-
- isAirstrikePos = isDefined(targetPos);
- if(self.pers["hardPointItem"] == "airstrike_mp" && !isAirstrikePos)
- continue;
-
- self BotStopMoving(true);
-
- if (self changeToWeapon(self.pers["hardPointItem"]))
- {
- wait 1;
-
- if (isAirstrikePos && !isDefined( level.airstrikeInProgress ))
+ if ( distFromPlayer < distSq && bulletTracePassed( self getEyePos(), player getTagOrigin( "j_spineupper" ), false, player ) )
{
- self BotFreezeControls(true);
-
- self notify( "confirm_location", targetPos );
- wait 1;
-
- self BotFreezeControls(false);
+ self SetAttacker( player );
}
- self thread changeToWeapon(curWeap);
- }
+ if ( !self HasScriptGoal() && !self.bot_lock_goal )
+ {
+ self SetScriptGoal( player.origin, 128 );
+ self thread stop_go_target_on_death( player );
- self BotStopMoving(false);
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self BotNotifyBotEvent( "uav_target", "stop", player );
+ }
+
+ break;
+ }
}
}
@@ -2490,68 +2738,58 @@ bot_uav_think()
{
self endon( "death" );
self endon( "disconnect" );
-
- for(;;)
+
+ for ( ;; )
{
wait 0.75;
-
- if(self.pers["bots"]["skill"]["base"] <= 1)
+
+ if ( self.pers["bots"]["skill"]["base"] <= 1 )
continue;
-
- if( level.hardcoreMode && !self.bot_radar )
+
+ if ( level.hardcoreMode && !self.bot_radar )
continue;
-
- dist = self.pers["bots"]["skill"]["help_dist"];
- dist *= dist * 8;
-
- for ( i = level.players.size - 1; i >= 0; i-- )
- {
- player = level.players[i];
- if(!player IsPlayerModelOK())
- continue;
-
- if(player == self)
- continue;
-
- if(!isDefined(player.team))
- continue;
-
- if(player.sessionstate != "playing")
- continue;
-
- if(level.teambased && player.team == self.team)
- continue;
-
- if(!isAlive(player))
- continue;
-
- distFromPlayer = DistanceSquared(self.origin, player.origin);
- if(distFromPlayer > dist)
- continue;
-
- if((!isSubStr(player getCurrentWeapon(), "_silencer_") && player.bots_firing) || (self.bot_radar && !player hasPerk("specialty_gpsjammer")))
- {
- distSq = self.pers["bots"]["skill"]["help_dist"] * self.pers["bots"]["skill"]["help_dist"];
- if (distFromPlayer < distSq && bulletTracePassed(self getEyePos(), player getTagOrigin( "j_spineupper" ), false, player))
- {
- self SetAttacker(player);
- }
-
- if (!self HasScriptGoal() && !self.bot_lock_goal)
- {
- self thread stop_go_target_on_death(player);
- self SetScriptGoal( player.origin, 128 );
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- }
- break;
- }
- }
+ self bot_uav_think_loop();
}
}
+/*
+ Bot logic for detecting the chopper as an enemy.
+*/
+bot_target_vehicle_loop()
+{
+ chopper = level.chopper;
+
+ if ( isDefined( chopper ) && level.teamBased && getDvarInt( "doubleHeli" ) )
+ {
+ chopper = level.chopper[ level.otherTeam[self.team] ];
+ }
+
+ if ( !isdefined( chopper ) )
+ return;
+
+ if ( !isDefined( level.bot_chopper ) || !level.bot_chopper ) //must be crashing or leaving
+ return;
+
+ if ( isDefined( chopper.owner ) && chopper.owner == self )
+ return;
+
+ if ( chopper.team == self.team && level.teamBased )
+ return;
+
+ if ( !bulletTracePassed( self getEyePos(), chopper.origin + ( 0, 0, -5 ), false, chopper ) )
+ return;
+
+ self BotNotifyBotEvent( "attack_vehicle", "start", chopper );
+
+ self SetScriptEnemy( chopper, ( 0, 0, -5 ) );
+ self bot_attack_vehicle( chopper );
+ self ClearScriptEnemy();
+ self notify( "bot_force_check_switch" );
+
+ self BotNotifyBotEvent( "attack_vehicle", "stop", chopper );
+}
+
/*
Bot logic for detecting the chopper as an enemy.
*/
@@ -2559,63 +2797,38 @@ bot_target_vehicle()
{
self endon( "death" );
self endon( "disconnect" );
-
- for(;;)
+
+ for ( ;; )
{
wait( RandomIntRange( 2, 4 ) );
- if(self.pers["bots"]["skill"]["base"] <= 1)
- continue;
-
- if(self HasScriptEnemy())
- continue;
-
- if(!self getAmmoCount("rpg_mp") && self BotGetRandom() < 90)
+ if ( self.pers["bots"]["skill"]["base"] <= 1 )
continue;
- chopper = level.chopper;
+ if ( self HasScriptEnemy() )
+ continue;
- if(isDefined(chopper) && level.teamBased && getDvarInt("doubleHeli"))
- {
- chopper = level.chopper[ level.otherTeam[self.team] ];
- }
+ if ( !self getAmmoCount( "rpg_mp" ) && self BotGetRandom() < 90 )
+ continue;
- if (!isdefined(chopper))
- continue;
-
- if(!isDefined(level.bot_chopper) || !level.bot_chopper)//must be crashing or leaving
- continue;
-
- if(isDefined(chopper.owner) && chopper.owner == self)
- continue;
-
- if(chopper.team == self.team && level.teamBased)
- continue;
-
- if(!bulletTracePassed( self getEyePos(), chopper.origin + (0, 0, -5), false, chopper ))
- continue;
-
- self SetScriptEnemy( chopper, (0, 0, -5) );
- self bot_attack_vehicle(chopper);
- self ClearScriptEnemy();
- self notify("bot_force_check_switch");
+ self bot_target_vehicle_loop();
}
}
/*
Bot logic for how long to keep targeting chopper.
*/
-bot_attack_vehicle(chopper)
+bot_attack_vehicle( chopper )
{
chopper endon( "death" );
chopper endon( "crashing" );
chopper endon( "leaving" );
-
+
wait_time = RandomIntRange( 7, 10 );
for ( i = 0; i < wait_time; i++ )
{
- self notify("bot_force_check_switch");
+ self notify( "bot_force_check_switch" );
wait( 1 );
if ( !IsDefined( chopper ) )
@@ -2625,6 +2838,62 @@ bot_attack_vehicle(chopper)
}
}
+/*
+ Bot logic for targeting equipment.
+*/
+bot_equipment_kill_think_loop()
+{
+ grenades = GetEntArray( "grenade", "classname" );
+ myEye = self getEyePos();
+ myAngles = self getPlayerAngles();
+ target = undefined;
+ hasDetectExp = self hasPerk( "specialty_detectexplosive" );
+
+ for ( i = grenades.size - 1; i >= 0; i-- )
+ {
+ item = grenades[i];
+
+ if ( !isDefined( item ) )
+ continue;
+
+ if ( !IsDefined( item.name ) )
+ {
+ continue;
+ }
+
+ if ( IsDefined( item.owner ) && ( ( level.teamBased && item.owner.team == self.team ) || item.owner == self ) )
+ {
+ continue;
+ }
+
+ if ( item.name != "c4_mp" && item.name != "claymore_mp" )
+ continue;
+
+ if ( !hasDetectExp && !bulletTracePassed( myEye, item.origin + ( 0, 0, 0 ), false, item ) )
+ continue;
+
+ if ( getConeDot( item.origin, self.origin, myAngles ) < 0.6 )
+ continue;
+
+ if ( DistanceSquared( item.origin, self.origin ) < 512 * 512 )
+ {
+ target = item;
+ break;
+ }
+ }
+
+ if ( isDefined( target ) )
+ {
+ self BotNotifyBotEvent( "attack_equ", "start", target );
+
+ self SetScriptEnemy( target, ( 0, 0, 0 ) );
+ self bot_equipment_attack( target );
+ self ClearScriptEnemy();
+
+ self BotNotifyBotEvent( "attack_equ", "stop", target );
+ }
+}
+
/*
Bot logic for targeting equipment.
*/
@@ -2632,72 +2901,28 @@ bot_equipment_kill_think()
{
self endon( "death" );
self endon( "disconnect" );
-
- for(;;)
+
+ for ( ;; )
{
wait( RandomIntRange( 1, 3 ) );
-
- if(self HasScriptEnemy())
+
+ if ( self HasScriptEnemy() )
continue;
- if(self.pers["bots"]["skill"]["base"] <= 1)
+ if ( self.pers["bots"]["skill"]["base"] <= 1 )
continue;
-
- grenades = GetEntArray( "grenade", "classname" );
- myEye = self getEyePos();
- myAngles = self getPlayerAngles();
- target = undefined;
- hasDetectExp = self hasPerk("specialty_detectexplosive");
- for ( i = grenades.size - 1; i >= 0; i-- )
- {
- item = grenades[i];
-
- if (!isDefined(item))
- continue;
-
- if ( !IsDefined( item.name ) )
- {
- continue;
- }
-
- if ( IsDefined( item.owner ) && ((level.teamBased && item.owner.team == self.team) || item.owner == self) )
- {
- continue;
- }
-
- if (item.name != "c4_mp" && item.name != "claymore_mp")
- continue;
-
- if(!hasDetectExp && !bulletTracePassed(myEye, item.origin+(0, 0, 0), false, item))
- continue;
-
- if(getConeDot(item.origin, self.origin, myAngles) < 0.6)
- continue;
-
- if ( DistanceSquared( item.origin, self.origin ) < 512 * 512 )
- {
- target = item;
- break;
- }
- }
-
- if(isDefined(target))
- {
- self SetScriptEnemy( target, (0, 0, 0) );
- self bot_equipment_attack(target);
- self ClearScriptEnemy();
- }
+ self bot_equipment_kill_think_loop();
}
}
/*
How long to keep targeting the equipment.
*/
-bot_equipment_attack(equ)
+bot_equipment_attack( equ )
{
- equ endon("death");
-
+ equ endon( "death" );
+
wait_time = RandomIntRange( 7, 10 );
for ( i = 0; i < wait_time; i++ )
@@ -2711,6 +2936,181 @@ bot_equipment_attack(equ)
}
}
+/*
+ Bots do random stance
+*/
+BotRandomStance()
+{
+ if ( randomInt( 100 ) < 80 )
+ self BotSetStance( "prone" );
+ else if ( randomInt( 100 ) < 60 )
+ self BotSetStance( "crouch" );
+ else
+ self BotSetStance( "stand" );
+}
+
+/*
+ Bots will use a random equipment
+*/
+BotUseRandomEquipment()
+{
+ self endon( "death" );
+ self endon( "disconnect" );
+
+ equ = undefined;
+
+ if ( self GetAmmoCount( "claymore_mp" ) )
+ equ = "claymore_mp";
+
+ if ( self GetAmmoCount( "c4_mp" ) )
+ equ = "c4_mp";
+
+ if ( !isDefined( equ ) )
+ return;
+
+ curWeap = self GetCurrentWeapon();
+
+ if ( self changeToWeapon( equ ) )
+ {
+ if ( equ != "c4_mp" )
+ self thread fire_current_weapon();
+ else
+ self thread fire_c4();
+
+ self waittill_any_timeout( 5, "grenade_fire", "weapon_change" );
+ self notify( "stop_firing_weapon" );
+ }
+
+ self thread changeToWeapon( curWeap );
+}
+
+/*
+ Bots will look at a random thing
+*/
+BotLookAtRandomThing( obj_target )
+{
+ self endon( "death" );
+ self endon( "disconnect" );
+
+ if ( self HasScriptAimPos() )
+ return;
+
+ rand = RandomInt( 100 );
+
+ nearestEnemy = undefined;
+
+ for ( i = 0; i < level.players.size; i++ )
+ {
+ player = level.players[i];
+
+ if ( !isDefined( player ) || !isDefined( player.team ) )
+ continue;
+
+ if ( !isAlive( player ) )
+ continue;
+
+ if ( level.teamBased && self.team == player.team )
+ continue;
+
+ if ( !isDefined( nearestEnemy ) || DistanceSquared( self.origin, player.origin ) < DistanceSquared( self.origin, nearestEnemy.origin ) )
+ {
+ nearestEnemy = player;
+ }
+ }
+
+ origin = ( 0, 0, self GetEyeHeight() );
+
+ if ( isDefined( nearestEnemy ) && DistanceSquared( self.origin, nearestEnemy.origin ) < 1024 * 1024 && rand < 40 )
+ origin += ( nearestEnemy.origin[0], nearestEnemy.origin[1], self.origin[2] );
+ else if ( isDefined( obj_target ) && rand < 50 )
+ origin += ( obj_target.origin[0], obj_target.origin[1], self.origin[2] );
+ else if ( rand < 85 )
+ origin += self.origin + AnglesToForward( ( 0, self.angles[1] - 180, 0 ) ) * 1024;
+ else
+ origin += self.origin + AnglesToForward( ( 0, RandomInt( 360 ), 0 ) ) * 1024;
+
+ self SetScriptAimPos( origin );
+ wait 2;
+ self ClearScriptAimPos();
+}
+
+/*
+ Bots will do stuff while waiting for objective
+*/
+bot_do_random_action_for_objective( obj_target )
+{
+ self endon( "death" );
+ self endon( "disconnect" );
+ self notify( "bot_do_random_action_for_objective" );
+ self endon( "bot_do_random_action_for_objective" );
+
+ if ( !isDefined( self.bot_random_obj_action ) )
+ {
+ self.bot_random_obj_action = true;
+
+ if ( randomInt( 100 ) < 80 )
+ self thread BotUseRandomEquipment();
+
+ if ( randomInt( 100 ) < 75 )
+ self thread BotLookAtRandomThing( obj_target );
+ }
+ else
+ {
+ if ( self GetStance() != "prone" && randomInt( 100 ) < 15 )
+ self BotSetStance( "prone" );
+ else if ( randomInt( 100 ) < 5 )
+ self thread BotLookAtRandomThing( obj_target );
+ }
+
+ wait 2;
+ self.bot_random_obj_action = undefined;
+}
+
+/*
+ Bots hang around the enemy's flag to spawn kill em
+*/
+bot_dom_spawn_kill_think_loop()
+{
+ myTeam = self.pers[ "team" ];
+ otherTeam = getOtherTeam( myTeam );
+ myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam );
+
+ if ( myFlagCount == level.flags.size )
+ return;
+
+ otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
+
+ if ( myFlagCount <= otherFlagCount || otherFlagCount != 1 )
+ return;
+
+ flag = undefined;
+
+ for ( i = 0; i < level.flags.size; i++ )
+ {
+ if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam )
+ continue;
+
+ flag = level.flags[i];
+ }
+
+ if ( !isDefined( flag ) )
+ return;
+
+ if ( DistanceSquared( self.origin, flag.origin ) < 2048 * 2048 )
+ return;
+
+ self BotNotifyBotEvent( "dom", "start", "spawnkill", flag );
+
+ self SetScriptGoal( flag.origin, 1024 );
+
+ self thread bot_dom_watch_flags( myFlagCount, myTeam );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self BotNotifyBotEvent( "dom", "stop", "spawnkill", flag );
+}
+
/*
Bots hang around the enemy's flag to spawn kill em
*/
@@ -2722,55 +3122,24 @@ bot_dom_spawn_kill_think()
if ( level.gametype != "dom" )
return;
- myTeam = self.pers[ "team" ];
- otherTeam = getOtherTeam( myTeam );
-
for ( ;; )
{
wait( randomintrange( 10, 20 ) );
-
+
if ( randomint( 100 ) < 20 )
continue;
-
- if ( self HasScriptGoal() || self.bot_lock_goal)
- continue;
-
- myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam );
- if ( myFlagCount == level.flags.size )
+ if ( self HasScriptGoal() || self.bot_lock_goal )
continue;
- otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
-
- if (myFlagCount <= otherFlagCount || otherFlagCount != 1)
- continue;
-
- flag = undefined;
- for ( i = 0; i < level.flags.size; i++ )
- {
- if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam )
- continue;
- }
-
- if(!isDefined(flag))
- continue;
-
- if(DistanceSquared(self.origin, flag.origin) < 2048*2048)
- continue;
-
- self SetScriptGoal( flag.origin, 1024 );
-
- self thread bot_dom_watch_flags(myFlagCount, myTeam);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
+ self bot_dom_spawn_kill_think_loop();
}
}
/*
Calls 'bad_path' when the flag count changes
*/
-bot_dom_watch_flags(count, myTeam)
+bot_dom_watch_flags( count, myTeam )
{
self endon( "death" );
self endon( "disconnect" );
@@ -2778,15 +3147,51 @@ bot_dom_watch_flags(count, myTeam)
self endon( "bad_path" );
self endon( "new_goal" );
- for (;;)
+ for ( ;; )
{
wait 0.5;
- if (maps\mp\gametypes\dom::getTeamFlagCount( myTeam ) != count)
+ if ( maps\mp\gametypes\dom::getTeamFlagCount( myTeam ) != count )
break;
}
-
- self notify("bad_path");
+
+ self notify( "bad_path" );
+}
+
+/*
+ Bots watches their own flags and protects them when they are under capture
+*/
+bot_dom_def_think_loop()
+{
+ myTeam = self.pers[ "team" ];
+ flag = undefined;
+
+ for ( i = 0; i < level.flags.size; i++ )
+ {
+ if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() != myTeam )
+ continue;
+
+ if ( !level.flags[i].useObj.objPoints[myTeam].isFlashing )
+ continue;
+
+ if ( !isDefined( flag ) || DistanceSquared( self.origin, level.flags[i].origin ) < DistanceSquared( self.origin, flag.origin ) )
+ flag = level.flags[i];
+ }
+
+ if ( !isDefined( flag ) )
+ return;
+
+ self BotNotifyBotEvent( "dom", "start", "defend", flag );
+
+ self SetScriptGoal( flag.origin, 128 );
+
+ self thread bot_dom_watch_for_flashing( flag, myTeam );
+ self thread bots_watch_touch_obj( flag );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self BotNotifyBotEvent( "dom", "stop", "defend", flag );
}
/*
@@ -2800,67 +3205,144 @@ bot_dom_def_think()
if ( level.gametype != "dom" )
return;
- myTeam = self.pers[ "team" ];
-
for ( ;; )
{
wait( randomintrange( 1, 3 ) );
-
+
if ( randomint( 100 ) < 35 )
continue;
-
+
if ( self HasScriptGoal() || self.bot_lock_goal )
continue;
-
- flag = undefined;
- for ( i = 0; i < level.flags.size; i++ )
- {
- if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() != myTeam )
- continue;
-
- if ( !level.flags[i].useObj.objPoints[myTeam].isFlashing )
- continue;
-
- if ( !isDefined(flag) || DistanceSquared(self.origin,level.flags[i].origin) < DistanceSquared(self.origin,flag.origin) )
- flag = level.flags[i];
- }
-
- if ( !isDefined(flag) )
- continue;
- self SetScriptGoal( flag.origin, 128 );
-
- self thread bot_dom_watch_for_flashing(flag, myTeam);
- self thread bots_watch_touch_obj(flag);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
+ self bot_dom_def_think_loop();
}
}
/*
Watches while the flag is under capture
*/
-bot_dom_watch_for_flashing(flag, myTeam)
+bot_dom_watch_for_flashing( flag, myTeam )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
-
- for (;;)
+
+ for ( ;; )
{
wait 0.5;
- if (!isDefined(flag))
+ if ( !isDefined( flag ) )
break;
- if (flag maps\mp\gametypes\dom::getFlagTeam() != myTeam || !flag.useObj.objPoints[myTeam].isFlashing)
+ if ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam || !flag.useObj.objPoints[myTeam].isFlashing )
break;
}
-
- self notify("bad_path");
+
+ self notify( "bad_path" );
+}
+
+/*
+ Bots capture dom flags
+*/
+bot_dom_cap_think_loop()
+{
+ myTeam = self.pers[ "team" ];
+ otherTeam = getOtherTeam( myTeam );
+
+ myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam );
+
+ if ( myFlagCount == level.flags.size )
+ return;
+
+ otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
+
+ if ( game["teamScores"][myteam] >= game["teamScores"][otherTeam] )
+ {
+ if ( myFlagCount < otherFlagCount )
+ {
+ if ( randomint( 100 ) < 15 )
+ return;
+ }
+ else if ( myFlagCount == otherFlagCount )
+ {
+ if ( randomint( 100 ) < 35 )
+ return;
+ }
+ else if ( myFlagCount > otherFlagCount )
+ {
+ if ( randomint( 100 ) < 95 )
+ return;
+ }
+ }
+
+ flag = undefined;
+ flags = [];
+
+ for ( i = 0; i < level.flags.size; i++ )
+ {
+ if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam )
+ continue;
+
+ flags[flags.size] = level.flags[i];
+ }
+
+ if ( randomInt( 100 ) > 30 )
+ {
+ for ( i = 0; i < flags.size; i++ )
+ {
+ if ( !isDefined( flag ) || DistanceSquared( self.origin, level.flags[i].origin ) < DistanceSquared( self.origin, flag.origin ) )
+ flag = level.flags[i];
+ }
+ }
+ else if ( flags.size )
+ {
+ flag = random( flags );
+ }
+
+ if ( !isDefined( flag ) )
+ return;
+
+ self BotNotifyBotEvent( "dom", "go", "cap", flag );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( flag.origin, 64 );
+
+ self thread bot_dom_go_cap_flag( flag, myteam );
+
+ event = self waittill_any_return( "goal", "bad_path", "new_goal" );
+
+ if ( event != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( event != "goal" )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ self BotNotifyBotEvent( "dom", "start", "cap", flag );
+
+ self SetScriptGoal( self.origin, 64 );
+
+ while ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam && self isTouching( flag ) )
+ {
+ cur = flag.useObj.curProgress;
+ wait 0.5;
+
+ if ( flag.useObj.curProgress == cur )
+ break;//some enemy is near us, kill him
+
+ self thread bot_do_random_action_for_objective( flag );
+ }
+
+ self BotNotifyBotEvent( "dom", "stop", "cap", flag );
+
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
}
/*
@@ -2870,139 +3352,163 @@ bot_dom_cap_think()
{
self endon( "death" );
self endon( "disconnect" );
-
+
if ( level.gametype != "dom" )
return;
- myTeam = self.pers[ "team" ];
- otherTeam = getOtherTeam( myTeam );
-
for ( ;; )
{
wait( randomintrange( 3, 12 ) );
-
+
if ( self.bot_lock_goal )
{
continue;
}
- if ( !isDefined(level.flags) || level.flags.size == 0 )
+ if ( !isDefined( level.flags ) || level.flags.size == 0 )
continue;
- myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam );
-
- if ( myFlagCount == level.flags.size )
- continue;
-
- otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
-
- if (game["teamScores"][myteam] >= game["teamScores"][otherTeam])
- {
- if ( myFlagCount < otherFlagCount )
- {
- if ( randomint( 100 ) < 15 )
- continue;
- }
- else if ( myFlagCount == otherFlagCount )
- {
- if ( randomint( 100 ) < 35 )
- continue;
- }
- else if ( myFlagCount > otherFlagCount )
- {
- if ( randomint( 100 ) < 95 )
- continue;
- }
- }
-
- flag = undefined;
- flags = [];
- for ( i = 0; i < level.flags.size; i++ )
- {
- if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam )
- continue;
-
- flags[flags.size] = level.flags[i];
- }
-
- if (randomInt(100) > 30)
- {
- for ( i = 0; i < flags.size; i++ )
- {
- if ( !isDefined(flag) || DistanceSquared(self.origin,level.flags[i].origin) < DistanceSquared(self.origin,flag.origin) )
- flag = level.flags[i];
- }
- }
- else if (flags.size)
- {
- flag = random(flags);
- }
-
- if ( !isDefined(flag) )
- continue;
-
- self.bot_lock_goal = true;
- self SetScriptGoal( flag.origin, 64 );
-
- self thread bot_dom_go_cap_flag(flag, myteam);
-
- event = self waittill_any_return( "goal", "bad_path", "new_goal" );
-
- if (event != "new_goal")
- self ClearScriptGoal();
-
- if (event != "goal")
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- self SetScriptGoal( self.origin, 64 );
-
- while ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam && self isTouching(flag) )
- {
- cur = flag.useObj.curProgress;
- wait 0.5;
-
- if(flag.useObj.curProgress == cur)
- break;//some enemy is near us, kill him
- }
-
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
+ self bot_dom_cap_think_loop();
}
}
/*
Bot goes to the flag, watching while they don't have the flag
*/
-bot_dom_go_cap_flag(flag, myteam)
+bot_dom_go_cap_flag( flag, myteam )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
-
- for (;;)
+
+ for ( ;; )
{
- wait randomintrange(2,4);
+ wait randomintrange( 2, 4 );
- if (!isDefined(flag))
+ if ( !isDefined( flag ) )
break;
- if (flag maps\mp\gametypes\dom::getFlagTeam() == myTeam)
+ if ( flag maps\mp\gametypes\dom::getFlagTeam() == myTeam )
break;
- if (self isTouching(flag))
+ if ( self isTouching( flag ) )
break;
}
-
- if (flag maps\mp\gametypes\dom::getFlagTeam() == myTeam)
- self notify("bad_path");
+
+ if ( flag maps\mp\gametypes\dom::getFlagTeam() == myTeam )
+ self notify( "bad_path" );
else
- self notify("goal");
+ self notify( "goal" );
+}
+
+/*
+ Bots play headquarters
+*/
+bot_hq_loop()
+{
+ myTeam = self.pers[ "team" ];
+ otherTeam = getOtherTeam( myTeam );
+
+ radio = level.radio;
+ gameobj = radio.gameobject;
+ origin = ( radio.origin[0], radio.origin[1], radio.origin[2] + 5 );
+
+ //if neut or enemy
+ if ( gameobj.ownerTeam != myTeam )
+ {
+ if ( gameobj.interactTeam == "none" ) //wait for it to become active
+ {
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ //capture it
+
+ self BotNotifyBotEvent( "hq", "go", "cap" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 64 );
+ self thread bot_hq_go_cap( gameobj, radio );
+
+ event = self waittill_any_return( "goal", "bad_path", "new_goal" );
+
+ if ( event != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( event != "goal" )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ if ( !self isTouching( gameobj.trigger ) || level.radio != radio )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ self BotNotifyBotEvent( "hq", "start", "cap" );
+
+ self SetScriptGoal( self.origin, 64 );
+
+ while ( self isTouching( gameobj.trigger ) && gameobj.ownerTeam != myTeam && level.radio == radio )
+ {
+ cur = gameobj.curProgress;
+ wait 0.5;
+
+ if ( cur == gameobj.curProgress )
+ break;//no prog made, enemy must be capping
+
+ self thread bot_do_random_action_for_objective( gameobj.trigger );
+ }
+
+ self ClearScriptGoal();
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "hq", "stop", "cap" );
+ }
+ else//we own it
+ {
+ if ( gameobj.objPoints[myteam].isFlashing ) //underattack
+ {
+ self BotNotifyBotEvent( "hq", "start", "defend" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 64 );
+ self thread bot_hq_watch_flashing( gameobj, radio );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "hq", "stop", "defend" );
+ return;
+ }
+
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+ }
}
/*
@@ -3016,116 +3522,29 @@ bot_hq()
if ( level.gametype != "koth" )
return;
- myTeam = self.pers[ "team" ];
- otherTeam = getOtherTeam( myTeam );
-
for ( ;; )
{
wait( randomintrange( 3, 5 ) );
-
+
if ( self.bot_lock_goal )
{
continue;
}
-
- if(!isDefined(level.radio))
+
+ if ( !isDefined( level.radio ) )
continue;
-
- if(!isDefined(level.radio.gameobject))
+
+ if ( !isDefined( level.radio.gameobject ) )
continue;
-
- radio = level.radio;
- gameobj = radio.gameobject;
- origin = ( radio.origin[0], radio.origin[1], radio.origin[2]+5 );
-
- //if neut or enemy
- if(gameobj.ownerTeam != myTeam)
- {
- if(gameobj.interactTeam == "none")//wait for it to become active
- {
- if(self HasScriptGoal())
- continue;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- //capture it
-
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 64 );
- self thread bot_hq_go_cap(gameobj, radio);
- event = self waittill_any_return( "goal", "bad_path", "new_goal" );
-
- if (event != "new_goal")
- self ClearScriptGoal();
-
- if (event != "goal")
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- if(!self isTouching(gameobj.trigger) || level.radio != radio)
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- self SetScriptGoal( self.origin, 64 );
-
- while(self isTouching(gameobj.trigger) && gameobj.ownerTeam != myTeam && level.radio == radio)
- {
- cur = gameobj.curProgress;
- wait 0.5;
-
- if(cur == gameobj.curProgress)
- break;//no prog made, enemy must be capping
- }
-
- self ClearScriptGoal();
- self.bot_lock_goal = false;
- }
- else//we own it
- {
- if(gameobj.objPoints[myteam].isFlashing)//underattack
- {
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 64 );
- self thread bot_hq_watch_flashing(gameobj, radio);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- if(self HasScriptGoal())
- continue;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- }
+ self bot_hq_loop();
}
}
/*
Waits until not touching the trigger and it is the current radio.
*/
-bot_hq_go_cap(obj, radio)
+bot_hq_go_cap( obj, radio )
{
self endon( "death" );
self endon( "disconnect" );
@@ -3133,54 +3552,315 @@ bot_hq_go_cap(obj, radio)
self endon( "bad_path" );
self endon( "new_goal" );
- for (;;)
+ for ( ;; )
{
- wait randomintrange(2,4);
+ wait randomintrange( 2, 4 );
- if (!isDefined(obj))
+ if ( !isDefined( obj ) )
break;
- if (self isTouching(obj.trigger))
+ if ( self isTouching( obj.trigger ) )
break;
- if (level.radio != radio)
+ if ( level.radio != radio )
break;
}
-
- if(level.radio != radio)
- self notify("bad_path");
+
+ if ( level.radio != radio )
+ self notify( "bad_path" );
else
- self notify("goal");
+ self notify( "goal" );
}
/*
Waits while the radio is under attack.
*/
-bot_hq_watch_flashing(obj, radio)
+bot_hq_watch_flashing( obj, radio )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "goal" );
self endon( "bad_path" );
self endon( "new_goal" );
-
+
myteam = self.team;
- for (;;)
+ for ( ;; )
{
wait 0.5;
- if (!isDefined(obj))
+ if ( !isDefined( obj ) )
break;
- if (!obj.objPoints[myteam].isFlashing)
+ if ( !obj.objPoints[myteam].isFlashing )
break;
- if (level.radio != radio)
+ if ( level.radio != radio )
break;
}
-
- self notify("bad_path");
+
+ self notify( "bad_path" );
+}
+
+/*
+ Bots play sab
+*/
+bot_sab_loop()
+{
+ myTeam = self.pers[ "team" ];
+ otherTeam = getOtherTeam( myTeam );
+
+ bomb = level.sabBomb;
+ bombteam = bomb.ownerTeam;
+ carrier = bomb.carrier;
+ timeleft = maps\mp\gametypes\_globallogic::getTimeRemaining() / 1000;
+
+ // the bomb is ours, we are on the offence
+ if ( bombteam == myTeam )
+ {
+ site = level.bombZones[otherTeam];
+ origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 5 );
+
+ // protect our planted bomb
+ if ( level.bombPlanted )
+ {
+ // kill defuser
+ if ( site isInUse() ) //somebody is defusing our bomb we planted
+ {
+ self BotNotifyBotEvent( "sab", "start", "defuser" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 64 );
+
+ self thread bot_defend_site( site );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sab", "stop", "defuser" );
+ return;
+ }
+
+ //else hang around the site
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 256 );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ // we are not the carrier
+ if ( !self isBombCarrier() )
+ {
+ // lets escort the bomb carrier
+ if ( self HasScriptGoal() )
+ return;
+
+ origin = carrier.origin;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+ self thread bot_escort_obj( bomb, carrier );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ // we are the carrier of the bomb, lets check if we need to plant
+ timepassed = maps\mp\gametypes\_globallogic::getTimePassed() / 1000;
+
+ if ( timepassed < 120 && timeleft >= 90 && randomInt( 100 ) < 98 )
+ return;
+
+ self BotNotifyBotEvent( "sab", "go", "plant" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 1 );
+
+ self thread bot_go_plant( site );
+ event = self waittill_any_return( "goal", "bad_path", "new_goal" );
+
+ if ( event != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( event != "goal" || level.bombPlanted || !self isTouching( site.trigger ) || site IsInUse() || self inLastStand() || self HasThreat() )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ self BotNotifyBotEvent( "sab", "start", "plant" );
+
+ self BotRandomStance();
+ self SetScriptGoal( self.origin, 64 );
+
+ self bot_use_bomb_thread( site );
+ wait 1;
+
+ self ClearScriptGoal();
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sab", "stop", "plant" );
+ }
+ else if ( bombteam == otherTeam ) // the bomb is theirs, we are on the defense
+ {
+ site = level.bombZones[myteam];
+
+ if ( !isDefined( site.bots ) )
+ site.bots = 0;
+
+ // protect our site from planters
+ if ( !level.bombPlanted )
+ {
+ //kill bomb carrier
+ if ( site.bots > 2 || randomInt( 100 ) < 45 )
+ {
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( carrier hasPerk( "specialty_gpsjammer" ) )
+ return;
+
+ origin = carrier.origin;
+
+ self SetScriptGoal( origin, 64 );
+ self thread bot_escort_obj( bomb, carrier );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ //protect bomb site
+ origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 5 );
+
+ self thread bot_inc_bots( site );
+
+ if ( site isInUse() ) //somebody is planting
+ {
+ self BotNotifyBotEvent( "sab", "start", "planter" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 64 );
+ self thread bot_inc_bots( site );
+
+ self thread bot_defend_site( site );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sab", "stop", "planter" );
+ return;
+ }
+
+ //else hang around the site
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ {
+ wait 4;
+ self notify( "bot_inc_bots" );
+ site.bots--;
+ return;
+ }
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 256 );
+ self thread bot_inc_bots( site );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ // bomb is planted we need to defuse
+ origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 5 );
+
+ // someone else is defusing, lets just hang around
+ if ( site.bots > 1 )
+ {
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+ self thread bot_go_defuse( site );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ // lets go defuse
+ self BotNotifyBotEvent( "sab", "go", "defuse" );
+
+ self.bot_lock_goal = true;
+
+ self SetScriptGoal( origin, 1 );
+ self thread bot_inc_bots( site );
+ self thread bot_go_defuse( site );
+
+ event = self waittill_any_return( "goal", "bad_path", "new_goal" );
+
+ if ( event != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( event != "goal" || !level.bombPlanted || site IsInUse() || !self isTouching( site.trigger ) || self InLastStand() || self HasThreat() )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ self BotNotifyBotEvent( "sab", "start", "defuse" );
+
+ self BotRandomStance();
+ self SetScriptGoal( self.origin, 64 );
+
+ self bot_use_bomb_thread( site );
+ wait 1;
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sab", "stop", "defuse" );
+ }
+ else // we need to go get the bomb!
+ {
+ origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 5 );
+
+ self BotNotifyBotEvent( "sab", "start", "bomb" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 64 );
+
+ self thread bot_get_obj( bomb );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sab", "stop", "bomb" );
+ return;
+ }
}
/*
@@ -3190,251 +3870,192 @@ bot_sab()
{
self endon( "death" );
self endon( "disconnect" );
- level endon("game_ended");
+ level endon( "game_ended" );
if ( level.gametype != "sab" )
return;
- myTeam = self.pers[ "team" ];
- otherTeam = getOtherTeam( myTeam );
-
for ( ;; )
{
wait( randomintrange( 3, 5 ) );
-
+
if ( self.bot_lock_goal )
{
continue;
}
-
- if(!isDefined(level.sabBomb))
- continue;
-
- if(!isDefined(level.bombZones) || !level.bombZones.size)
+
+ if ( !isDefined( level.sabBomb ) )
continue;
- if (self IsPlanting() || self isDefusing())
+ if ( !isDefined( level.bombZones ) || !level.bombZones.size )
continue;
-
- bomb = level.sabBomb;
- bombteam = bomb.ownerTeam;
- carrier = bomb.carrier;
- timeleft = maps\mp\gametypes\_globallogic::getTimeRemaining()/1000;
-
- // the bomb is ours, we are on the offence
- if(bombteam == myTeam)
+
+ if ( self IsPlanting() || self isDefusing() )
+ continue;
+
+ self bot_sab_loop();
+ }
+}
+
+/*
+ Bots play sd defenders
+*/
+bot_sd_defenders_loop( data )
+{
+ myTeam = self.pers[ "team" ];
+ otherTeam = getOtherTeam( myTeam );
+
+ // bomb not planted, lets protect our sites
+ if ( !level.bombPlanted )
+ {
+ timeleft = maps\mp\gametypes\_globallogic::getTimeRemaining() / 1000;
+
+ if ( timeleft >= 90 )
+ return;
+
+ // check for a bomb carrier, and camp the bomb
+ if ( !level.multiBomb && isDefined( level.sdBomb ) )
{
- site = level.bombZones[otherTeam];
- origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+5 );
-
- // protect our planted bomb
- if(level.bombPlanted)
- {
- // kill defuser
- if(site isInUse()) //somebody is defusing our bomb we planted
- {
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 64 );
+ bomb = level.sdBomb;
+ carrier = level.sdBomb.carrier;
+
+ if ( !isDefined( carrier ) )
+ {
+ origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 5 );
+
+ //hang around the bomb
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
- self thread bot_defend_site(site);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- self.bot_lock_goal = false;
- continue;
- }
-
- //else hang around the site
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self.bot_lock_goal = true;
self SetScriptGoal( origin, 256 );
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
+
+ self thread bot_get_obj( bomb );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
self ClearScriptGoal();
- self.bot_lock_goal = false;
- continue;
+
+ return;
}
-
- // we are not the carrier
- if(!self isBombCarrier())
- {
- // lets escort the bomb carrier
- if(self HasScriptGoal())
- continue;
-
- origin = carrier.origin;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
- self thread bot_escort_obj(bomb, carrier);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- // we are the carrier of the bomb, lets check if we need to plant
- timepassed = maps\mp\gametypes\_globallogic::getTimePassed()/1000;
-
- if(timepassed < 120 && timeleft >= 90 && randomInt(100) < 98)
- continue;
-
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 1 );
-
- self thread bot_go_plant(site);
- event = self waittill_any_return( "goal", "bad_path", "new_goal" );
-
- if (event != "new_goal")
- self ClearScriptGoal();
-
- if(event != "goal" || level.bombPlanted || !self isTouching(site.trigger) || site IsInUse() || self inLastStand() || self HasThreat())
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- self SetScriptGoal( self.origin, 64 );
-
- self bot_use_bomb_thread(site);
- wait 1;
-
- self ClearScriptGoal();
- self.bot_lock_goal = false;
}
- else if(bombteam == otherTeam) // the bomb is theirs, we are on the defense
+
+ // pick a site to protect
+ if ( !isDefined( level.bombZones ) || !level.bombZones.size )
+ return;
+
+ sites = [];
+
+ for ( i = 0; i < level.bombZones.size; i++ )
{
- site = level.bombZones[myteam];
-
- if(!isDefined(site.bots))
- site.bots = 0;
-
- // protect our site from planters
- if(!level.bombPlanted)
- {
- //kill bomb carrier
- if(site.bots > 2 || randomInt(100) < 45)
- {
- if(self HasScriptGoal())
- continue;
-
- if(carrier hasPerk( "specialty_gpsjammer" ))
- continue;
-
- origin = carrier.origin;
-
- self SetScriptGoal( origin, 64 );
- self thread bot_escort_obj(bomb, carrier);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- //protect bomb site
- origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+5 );
-
- self thread bot_inc_bots(site);
-
- if(site isInUse())//somebody is planting
- {
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 64 );
- self thread bot_inc_bots(site);
-
- self thread bot_defend_site(site);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- //else hang around the site
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- {
- wait 4;
- self notify("bot_inc_bots"); site.bots--;
- continue;
- }
-
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 256 );
- self thread bot_inc_bots(site);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- self.bot_lock_goal = false;
- continue;
- }
-
- // bomb is planted we need to defuse
- origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+5 );
-
- // someone else is defusing, lets just hang around
- if(site.bots > 1)
- {
- if(self HasScriptGoal())
- continue;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
- self thread bot_go_defuse(site);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- // lets go defuse
- self.bot_lock_goal = true;
-
- self SetScriptGoal( origin, 1 );
- self thread bot_inc_bots(site);
- self thread bot_go_defuse(site);
-
- event = self waittill_any_return( "goal", "bad_path", "new_goal" );
-
- if (event != "new_goal")
- self ClearScriptGoal();
-
- if(event != "goal" || !level.bombPlanted || site IsInUse() || !self isTouching(site.trigger) || self InLastStand() || self HasThreat())
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- self SetScriptGoal( self.origin, 64 );
-
- self bot_use_bomb_thread(site);
- wait 1;
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
+ sites[sites.size] = level.bombZones[i];
}
- else // we need to go get the bomb!
+
+ if ( !sites.size )
+ return;
+
+ if ( data.rand > 50 )
+ site = self bot_array_nearest_curorigin( sites );
+ else
+ site = random( sites );
+
+ if ( !isDefined( site ) )
+ return;
+
+ origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 5 );
+
+ if ( site isInUse() ) //somebody is planting
{
- origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2]+5 );
-
+ self BotNotifyBotEvent( "sd", "start", "planter", site );
+
self.bot_lock_goal = true;
self SetScriptGoal( origin, 64 );
-
- self thread bot_get_obj(bomb);
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
+ self thread bot_defend_site( site );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
self ClearScriptGoal();
-
+
self.bot_lock_goal = false;
- continue;
+
+ self BotNotifyBotEvent( "sd", "stop", "planter", site );
+ return;
}
+
+ //else hang around the site
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 256 );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+ return;
}
+
+ // bomb is planted, we need to defuse
+ if ( !isDefined( level.defuseObject ) )
+ return;
+
+ defuse = level.defuseObject;
+
+ if ( !isDefined( defuse.bots ) )
+ defuse.bots = 0;
+
+ origin = ( defuse.curorigin[0], defuse.curorigin[1], defuse.curorigin[2] + 5 );
+
+ // someone is going to go defuse ,lets just hang around
+ if ( defuse.bots > 1 )
+ {
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+ self thread bot_go_defuse( defuse );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ // lets defuse
+ self BotNotifyBotEvent( "sd", "go", "defuse" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 1 );
+ self thread bot_inc_bots( defuse );
+ self thread bot_go_defuse( defuse );
+
+ event = self waittill_any_return( "goal", "bad_path", "new_goal" );
+
+ if ( event != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( event != "goal" || !level.bombPlanted || defuse isInUse() || !self isTouching( defuse.trigger ) || self InLastStand() || self HasThreat() )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ self BotNotifyBotEvent( "sd", "start", "defuse" );
+
+ self BotRandomStance();
+ self SetScriptGoal( self.origin, 64 );
+
+ self bot_use_bomb_thread( defuse );
+ wait 1;
+ self ClearScriptGoal();
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sd", "stop", "defuse" );
}
/*
@@ -3444,171 +4065,226 @@ bot_sd_defenders()
{
self endon( "death" );
self endon( "disconnect" );
- level endon("game_ended");
+ level endon( "game_ended" );
if ( level.gametype != "sd" )
return;
- myTeam = self.pers[ "team" ];
- otherTeam = getOtherTeam( myTeam );
-
- if(myTeam == game["attackers"])
+ if ( self.team == game["attackers"] )
return;
- rand = self BotGetRandom();
+ data = spawnStruct();
+ data.rand = self BotGetRandom();
for ( ;; )
{
wait( randomintrange( 3, 5 ) );
-
+
if ( self.bot_lock_goal )
{
continue;
}
- if (self IsPlanting() || self isDefusing())
+ if ( self IsPlanting() || self isDefusing() )
continue;
-
- // bomb not planted, lets protect our sites
- if(!level.bombPlanted)
- {
- timeleft = maps\mp\gametypes\_globallogic::getTimeRemaining()/1000;
-
- if(timeleft >= 90)
- continue;
-
- // check for a bomb carrier, and camp the bomb
- if(!level.multiBomb && isDefined(level.sdBomb))
- {
- bomb = level.sdBomb;
- carrier = level.sdBomb.carrier;
-
- if(!isDefined(carrier))
- {
- origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2]+5 );
-
- //hang around the bomb
- if(self HasScriptGoal())
- continue;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
- self thread bot_get_obj(bomb);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
- }
-
- // pick a site to protect
- if(!isDefined(level.bombZones) || !level.bombZones.size)
- continue;
-
- sites = [];
- for(i = 0; i < level.bombZones.size; i++)
- {
- sites[sites.size] = level.bombZones[i];
- }
-
- if(!sites.size)
- continue;
-
- if (rand > 50)
- site = self bot_array_nearest_curorigin(sites);
- else
- site = random(sites);
-
- if(!isDefined(site))
- continue;
-
- origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+5 );
-
- if(site isInUse())//somebody is planting
- {
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 64 );
-
- self thread bot_defend_site(site);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- //else hang around the site
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 256 );
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- // bomb is planted, we need to defuse
- if(!isDefined(level.defuseObject))
- continue;
-
- defuse = level.defuseObject;
-
- if(!isDefined(defuse.bots))
- defuse.bots = 0;
-
- origin = ( defuse.curorigin[0], defuse.curorigin[1], defuse.curorigin[2]+5 );
-
- // someone is going to go defuse ,lets just hang around
- if(defuse.bots > 1)
- {
- if(self HasScriptGoal())
- continue;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
- self thread bot_go_defuse(defuse);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- // lets defuse
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 1 );
- self thread bot_inc_bots(defuse);
- self thread bot_go_defuse(defuse);
-
- event = self waittill_any_return( "goal", "bad_path", "new_goal" );
-
- if (event != "new_goal")
- self ClearScriptGoal();
-
- if(event != "goal" || !level.bombPlanted || defuse isInUse() || !self isTouching(defuse.trigger) || self InLastStand() || self HasThreat())
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- self SetScriptGoal( self.origin, 64 );
-
- self bot_use_bomb_thread(defuse);
- wait 1;
- self ClearScriptGoal();
- self.bot_lock_goal = false;
+ self bot_sd_defenders_loop( data );
}
}
+/*
+ Bots play sd attackers
+*/
+bot_sd_attackers_loop( data )
+{
+ if ( data.first )
+ data.first = false;
+ else
+ wait( randomintrange( 3, 5 ) );
+
+ if ( self.bot_lock_goal )
+ {
+ return;
+ }
+
+ myTeam = self.pers[ "team" ];
+ otherTeam = getOtherTeam( myTeam );
+
+ //bomb planted
+ if ( level.bombPlanted )
+ {
+ if ( !isDefined( level.defuseObject ) )
+ return;
+
+ site = level.defuseObject;
+
+ origin = ( site.curorigin[0], site.curorigin[1], site.curorigin[2] + 5 );
+
+ if ( site IsInUse() ) //somebody is defusing
+ {
+ self BotNotifyBotEvent( "sd", "start", "defuser" );
+
+ self.bot_lock_goal = true;
+
+ self SetScriptGoal( origin, 64 );
+
+ self thread bot_defend_site( site );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sd", "stop", "defuser" );
+ return;
+ }
+
+ //else hang around the site
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 256 );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ timeleft = maps\mp\gametypes\_globallogic::getTimeRemaining() / 1000;
+ timepassed = maps\mp\gametypes\_globallogic::getTimePassed() / 1000;
+
+ //dont have a bomb
+ if ( !self IsBombCarrier() && !level.multiBomb )
+ {
+ if ( !isDefined( level.sdBomb ) )
+ return;
+
+ bomb = level.sdBomb;
+ carrier = level.sdBomb.carrier;
+
+ //bomb is picked up
+ if ( isDefined( carrier ) )
+ {
+ //escort the bomb carrier
+ if ( self HasScriptGoal() )
+ return;
+
+ origin = carrier.origin;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+ self thread bot_escort_obj( bomb, carrier );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ if ( !isDefined( bomb.bots ) )
+ bomb.bots = 0;
+
+ origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 5 );
+
+ //hang around the bomb if other is going to go get it
+ if ( bomb.bots > 1 )
+ {
+ if ( self HasScriptGoal() )
+ return;
+
+ if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 )
+ return;
+
+ self SetScriptGoal( origin, 256 );
+
+ self thread bot_get_obj( bomb );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ return;
+ }
+
+ // go get the bomb
+ self BotNotifyBotEvent( "sd", "start", "bomb" );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 64 );
+ self thread bot_inc_bots( bomb );
+ self thread bot_get_obj( bomb );
+
+ if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" )
+ self ClearScriptGoal();
+
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sd", "stop", "bomb" );
+ return;
+ }
+
+ // check if to plant
+ if ( timepassed < 120 && timeleft >= 90 && randomInt( 100 ) < 98 )
+ return;
+
+ if ( !isDefined( level.bombZones ) || !level.bombZones.size )
+ return;
+
+ sites = [];
+
+ for ( i = 0; i < level.bombZones.size; i++ )
+ {
+ sites[sites.size] = level.bombZones[i];
+ }
+
+ if ( !sites.size )
+ return;
+
+ if ( data.rand > 50 )
+ plant = self bot_array_nearest_curorigin( sites );
+ else
+ plant = random( sites );
+
+ if ( !isDefined( plant ) )
+ return;
+
+ origin = ( plant.curorigin[0] + 50, plant.curorigin[1] + 50, plant.curorigin[2] + 5 );
+
+ self BotNotifyBotEvent( "sd", "go", "plant", plant );
+
+ self.bot_lock_goal = true;
+ self SetScriptGoal( origin, 1 );
+ self thread bot_go_plant( plant );
+
+ event = self waittill_any_return( "goal", "bad_path", "new_goal" );
+
+ if ( event != "new_goal" )
+ self ClearScriptGoal();
+
+ if ( event != "goal" || level.bombPlanted || plant.visibleTeam == "none" || !self isTouching( plant.trigger ) || self InLastStand() || self HasThreat() || plant IsInUse() )
+ {
+ self.bot_lock_goal = false;
+ return;
+ }
+
+ self BotNotifyBotEvent( "sd", "start", "plant", plant );
+
+ self BotRandomStance();
+ self SetScriptGoal( self.origin, 64 );
+
+ self bot_use_bomb_thread( plant );
+ wait 1;
+
+ self ClearScriptGoal();
+ self.bot_lock_goal = false;
+
+ self BotNotifyBotEvent( "sd", "stop", "plant", plant );
+}
+
/*
Bots play sd attackers
*/
@@ -3616,187 +4292,20 @@ bot_sd_attackers()
{
self endon( "death" );
self endon( "disconnect" );
- level endon("game_ended");
+ level endon( "game_ended" );
if ( level.gametype != "sd" )
return;
- myTeam = self.pers[ "team" ];
- otherTeam = getOtherTeam( myTeam );
-
- if(myTeam != game["attackers"])
+ if ( self.team != game["attackers"] )
return;
- rand = self BotGetRandom();
-
- first = true;
+ data = spawnStruct();
+ data.rand = self BotGetRandom();
+ data.first = true;
for ( ;; )
{
- if(first)
- first = false;
- else
- wait( randomintrange( 3, 5 ) );
-
- if ( self.bot_lock_goal )
- {
- continue;
- }
-
- //bomb planted
- if(level.bombPlanted)
- {
- if(!isDefined(level.defuseObject))
- continue;
-
- site = level.defuseObject;
-
- origin = ( site.curorigin[0], site.curorigin[1], site.curorigin[2]+5 );
-
- if(site IsInUse())//somebody is defusing
- {
- self.bot_lock_goal = true;
-
- self SetScriptGoal( origin, 64 );
-
- self thread bot_defend_site(site);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- //else hang around the site
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 256 );
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- timeleft = maps\mp\gametypes\_globallogic::getTimeRemaining()/1000;
- timepassed = maps\mp\gametypes\_globallogic::getTimePassed()/1000;
-
- //dont have a bomb
- if(!self IsBombCarrier() && !level.multiBomb)
- {
- if(!isDefined(level.sdBomb))
- continue;
-
- bomb = level.sdBomb;
- carrier = level.sdBomb.carrier;
-
- //bomb is picked up
- if(isDefined(carrier))
- {
- //escort the bomb carrier
- if(self HasScriptGoal())
- continue;
-
- origin = carrier.origin;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
- self thread bot_escort_obj(bomb, carrier);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- if(!isDefined(bomb.bots))
- bomb.bots = 0;
-
- origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2]+5 );
-
- //hang around the bomb if other is going to go get it
- if(bomb.bots > 1)
- {
- if(self HasScriptGoal())
- continue;
-
- if(DistanceSquared(origin, self.origin) <= 1024*1024)
- continue;
-
- self SetScriptGoal( origin, 256 );
-
- self thread bot_get_obj(bomb);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
- continue;
- }
-
- // go get the bomb
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 64 );
- self thread bot_inc_bots(bomb);
- self thread bot_get_obj(bomb);
-
- if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
- self ClearScriptGoal();
-
- self.bot_lock_goal = false;
- continue;
- }
-
- // check if to plant
- if(timepassed < 120 && timeleft >= 90 && randomInt(100) < 98)
- continue;
-
- if(!isDefined(level.bombZones) || !level.bombZones.size)
- continue;
-
- sites = [];
- for(i = 0; i < level.bombZones.size; i++)
- {
- sites[sites.size] = level.bombZones[i];
- }
-
- if(!sites.size)
- continue;
-
- if(rand > 50)
- plant = self bot_array_nearest_curorigin(sites);
- else
- plant = random(sites);
-
- if(!isDefined(plant))
- continue;
-
- origin = ( plant.curorigin[0]+50, plant.curorigin[1]+50, plant.curorigin[2]+5 );
-
- self.bot_lock_goal = true;
- self SetScriptGoal( origin, 1 );
- self thread bot_go_plant(plant);
-
- event = self waittill_any_return( "goal", "bad_path", "new_goal" );
-
- if (event != "new_goal")
- self ClearScriptGoal();
-
- if(event != "goal" || level.bombPlanted || plant.visibleTeam == "none" || !self isTouching(plant.trigger) || self InLastStand() || self HasThreat() || plant IsInUse())
- {
- self.bot_lock_goal = false;
- continue;
- }
-
- self SetScriptGoal( self.origin, 64 );
-
- self bot_use_bomb_thread(plant);
- wait 1;
-
- self ClearScriptGoal();
- self.bot_lock_goal = false;
+ self bot_sd_attackers_loop( data );
}
}
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_utility.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_utility.gsc
index c16c195..e85c995 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_utility.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_bot_utility.gsc
@@ -7,7 +7,7 @@
*/
is_host()
{
- return (isDefined(self.pers["bot_host"]) && self.pers["bot_host"]);
+ return ( isDefined( self.pers["bot_host"] ) && self.pers["bot_host"] );
}
/*
@@ -17,36 +17,38 @@ doHostCheck()
{
self.pers["bot_host"] = false;
- if (self is_bot())
+ if ( self is_bot() )
return;
result = false;
- if (getDvar("bots_main_firstIsHost") != "0")
+
+ if ( getDvar( "bots_main_firstIsHost" ) != "0" )
{
- printToConsole("WARNING: bots_main_firstIsHost is enabled");
-
- if (getDvar("bots_main_firstIsHost") == "1")
+ printToConsole( "WARNING: bots_main_firstIsHost is enabled" );
+
+ if ( getDvar( "bots_main_firstIsHost" ) == "1" )
{
- setDvar("bots_main_firstIsHost", self getguid());
+ setDvar( "bots_main_firstIsHost", self getguid() );
}
- if (getDvar("bots_main_firstIsHost") == self getguid()+"")
+ if ( getDvar( "bots_main_firstIsHost" ) == self getguid() + "" )
result = true;
}
- DvarGUID = getDvar("bots_main_GUIDs");
- if (DvarGUID != "")
- {
- guids = strtok(DvarGUID, ",");
+ DvarGUID = getDvar( "bots_main_GUIDs" );
- for (i = 0; i < guids.size; i++)
+ if ( DvarGUID != "" )
+ {
+ guids = strtok( DvarGUID, "," );
+
+ for ( i = 0; i < guids.size; i++ )
{
- if(self getguid()+"" == guids[i])
+ if ( self getguid() + "" == guids[i] )
result = true;
}
}
-
- if (!result)
+
+ if ( !result )
return;
self.pers["bot_host"] = true;
@@ -60,44 +62,73 @@ is_bot()
return self.isbot;
}
+/*
+ Set the bot's stance
+*/
+BotSetStance( stance )
+{
+ switch ( stance )
+ {
+ case "stand":
+ self maps\mp\bots\_bot_internal::stand();
+ break;
+
+ case "crouch":
+ self maps\mp\bots\_bot_internal::crouch();
+ break;
+
+ case "prone":
+ self maps\mp\bots\_bot_internal::prone();
+ break;
+ }
+}
+
/*
Bot changes to the weap
*/
-BotChangeToWeapon(weap)
+BotChangeToWeapon( weap )
{
- self maps\mp\bots\_bot_internal::changeToWeap(weap);
+ self maps\mp\bots\_bot_internal::changeToWeap( weap );
}
/*
Bot presses the button for time.
*/
-BotPressAttack(time)
+BotPressAttack( time )
{
- self maps\mp\bots\_bot_internal::pressFire(time);
+ self maps\mp\bots\_bot_internal::pressFire( time );
}
/*
Bot presses the ads button for time.
*/
-BotPressADS(time)
+BotPressADS( time )
{
- self maps\mp\bots\_bot_internal::pressADS(time);
+ self maps\mp\bots\_bot_internal::pressADS( time );
+}
+
+/*
+ Bot presses the use button for time.
+*/
+BotPressUse( time )
+{
+ self maps\mp\bots\_bot_internal::use( time );
}
/*
Bot presses the frag button for time.
*/
-BotPressFrag(time)
+BotPressFrag( time )
{
- self maps\mp\bots\_bot_internal::frag(time);
+ self maps\mp\bots\_bot_internal::frag( time );
}
/*
Bot presses the smoke button for time.
*/
-BotPressSmoke(time)
+BotPressSmoke( time )
{
- self maps\mp\bots\_bot_internal::smoke(time);
+ self maps\mp\bots\_bot_internal::smoke( time );
}
/*
@@ -113,7 +144,7 @@ BotGetRandom()
*/
BotGetTargetRandom()
{
- if (!isDefined(self.bot.target))
+ if ( !isDefined( self.bot.target ) )
return undefined;
return self.bot.target.rand;
@@ -164,17 +195,18 @@ IsBotKnifing()
*/
IsPlayerModelOK()
{
- return (isDefined(self.bot_model_fix));
+ return ( isDefined( self.bot_model_fix ) );
}
/*
Freezes the bot's controls.
*/
-BotFreezeControls(what)
+BotFreezeControls( what )
{
self.bot.isfrozen = what;
- if(what)
- self notify("kill_goal");
+
+ if ( what )
+ self notify( "kill_goal" );
}
/*
@@ -188,12 +220,20 @@ BotIsFrozen()
/*
Bot will stop moving
*/
-BotStopMoving(what)
+BotStopMoving( what )
{
self.bot.stop_move = what;
- if(what)
- self notify("kill_goal");
+ if ( what )
+ self notify( "kill_goal" );
+}
+
+/*
+ Notify the bot chat message
+*/
+BotNotifyBotEvent( msg, a, b, c, d, e, f, g )
+{
+ self notify( "bot_event", msg, a, b, c, d, e, f, g );
}
/*
@@ -202,7 +242,7 @@ BotStopMoving(what)
*/
HasScriptGoal()
{
- return (isDefined(self GetScriptGoal()));
+ return ( isDefined( self GetScriptGoal() ) );
}
/*
@@ -216,15 +256,16 @@ GetScriptGoal()
/*
Sets the bot's goal, will acheive it when dist away from it.
*/
-SetScriptGoal(goal, dist)
+SetScriptGoal( goal, dist )
{
- if (!isDefined(dist))
+ if ( !isDefined( dist ) )
dist = 16;
+
self.bot.script_goal = goal;
self.bot.script_goal_dist = dist;
waittillframeend;
- self notify("new_goal_internal");
- self notify("new_goal");
+ self notify( "new_goal_internal" );
+ self notify( "new_goal" );
}
/*
@@ -232,13 +273,13 @@ SetScriptGoal(goal, dist)
*/
ClearScriptGoal()
{
- self SetScriptGoal(undefined, 0);
+ self SetScriptGoal( undefined, 0 );
}
/*
Sets the aim position of the bot
*/
-SetScriptAimPos(pos)
+SetScriptAimPos( pos )
{
self.bot.script_aimpos = pos;
}
@@ -248,7 +289,7 @@ SetScriptAimPos(pos)
*/
ClearScriptAimPos()
{
- self SetScriptAimPos(undefined);
+ self SetScriptAimPos( undefined );
}
/*
@@ -264,13 +305,13 @@ GetScriptAimPos()
*/
HasScriptAimPos()
{
- return isDefined(self GetScriptAimPos());
+ return isDefined( self GetScriptAimPos() );
}
/*
Sets the bot's target to be this ent.
*/
-SetAttacker(att)
+SetAttacker( att )
{
self.bot.target_this_frame = att;
}
@@ -278,7 +319,7 @@ SetAttacker(att)
/*
Sets the script enemy for a bot.
*/
-SetScriptEnemy(enemy, offset)
+SetScriptEnemy( enemy, offset )
{
self.bot.script_target = enemy;
self.bot.script_target_offset = offset;
@@ -289,7 +330,7 @@ SetScriptEnemy(enemy, offset)
*/
ClearScriptEnemy()
{
- self SetScriptEnemy(undefined, undefined);
+ self SetScriptEnemy( undefined, undefined );
}
/*
@@ -297,9 +338,9 @@ ClearScriptEnemy()
*/
GetThreat()
{
- if(!isdefined(self.bot.target))
+ if ( !isdefined( self.bot.target ) )
return undefined;
-
+
return self.bot.target.entity;
}
@@ -308,7 +349,7 @@ GetThreat()
*/
HasScriptEnemy()
{
- return (isDefined(self.bot.script_target));
+ return ( isDefined( self.bot.script_target ) );
}
/*
@@ -316,7 +357,7 @@ HasScriptEnemy()
*/
HasThreat()
{
- return (isDefined(self GetThreat()));
+ return ( isDefined( self GetThreat() ) );
}
/*
@@ -324,7 +365,7 @@ HasThreat()
*/
IsDefusing()
{
- return (isDefined(self.isDefusing) && self.isDefusing);
+ return ( isDefined( self.isDefusing ) && self.isDefusing );
}
/*
@@ -332,7 +373,7 @@ IsDefusing()
*/
isPlanting()
{
- return (isDefined(self.isPlanting) && self.isPlanting);
+ return ( isDefined( self.isPlanting ) && self.isPlanting );
}
/*
@@ -340,7 +381,7 @@ isPlanting()
*/
inLastStand()
{
- return (isDefined(self.lastStand) && self.lastStand);
+ return ( isDefined( self.lastStand ) && self.lastStand );
}
/*
@@ -348,7 +389,7 @@ inLastStand()
*/
isBombCarrier()
{
- return (isDefined(self.isBombCarrier) && self.isBombCarrier);
+ return ( isDefined( self.isBombCarrier ) && self.isBombCarrier );
}
/*
@@ -356,7 +397,7 @@ isBombCarrier()
*/
isInUse()
{
- return (isDefined(self.inUse) && self.inUse);
+ return ( isDefined( self.inUse ) && self.inUse );
}
/*
@@ -364,15 +405,15 @@ isInUse()
*/
IsStunned()
{
- return (isdefined(self.concussionEndTime) && self.concussionEndTime > gettime());
+ return ( isdefined( self.concussionEndTime ) && self.concussionEndTime > gettime() );
}
/*
- Returns if we are beingArtilleryShellshocked
+ Returns if we are beingArtilleryShellshocked
*/
isArtShocked()
{
- return (isDefined(self.beingArtilleryShellshocked) && self.beingArtilleryShellshocked);
+ return ( isDefined( self.beingArtilleryShellshocked ) && self.beingArtilleryShellshocked );
}
/*
@@ -382,14 +423,14 @@ getValidTube()
{
weaps = self getweaponslist();
- for (i = 0; i < weaps.size; i++)
+ for ( i = 0; i < weaps.size; i++ )
{
weap = weaps[i];
- if(!self getAmmoCount(weap))
+ if ( !self getAmmoCount( weap ) )
continue;
- if (isSubStr(weap, "gl_") && !isSubStr(weap, "_gl_"))
+ if ( isSubStr( weap, "gl_" ) && !isSubStr( weap, "_gl_" ) )
return weap;
}
@@ -406,31 +447,54 @@ getValidGrenade()
grenadeTypes[grenadeTypes.size] = "smoke_grenade_mp";
grenadeTypes[grenadeTypes.size] = "flash_grenade_mp";
grenadeTypes[grenadeTypes.size] = "concussion_grenade_mp";
-
+
possibles = [];
-
- for(i = 0; i < grenadeTypes.size; i++)
+
+ for ( i = 0; i < grenadeTypes.size; i++ )
{
if ( !self hasWeapon( grenadeTypes[i] ) )
continue;
-
+
if ( !self getAmmoCount( grenadeTypes[i] ) )
continue;
-
+
possibles[possibles.size] = grenadeTypes[i];
}
-
- return random(possibles);
+
+ return random( possibles );
+}
+
+/*
+ CoD4 meme
+*/
+getWinningTeam()
+{
+ if ( maps\mp\gametypes\_globallogic::getGameScore( "allies" ) == maps\mp\gametypes\_globallogic::getGameScore( "axis" ) )
+ winner = "tie";
+ else if ( maps\mp\gametypes\_globallogic::getGameScore( "allies" ) > maps\mp\gametypes\_globallogic::getGameScore( "axis" ) )
+ winner = "allies";
+ else
+ winner = "axis";
+
+ return winner;
+}
+
+/*
+ CoD4
+*/
+getBaseWeaponName( weap )
+{
+ return strtok( weap, "_" )[0];
}
/*
Returns if the given weapon is full auto.
*/
-WeaponIsFullAuto(weap)
+WeaponIsFullAuto( weap )
{
- weaptoks = strtok(weap, "_");
-
- return isDefined(weaptoks[0]) && isString(weaptoks[0]) && isdefined(level.bots_fullautoguns[weaptoks[0]]);
+ weaptoks = strtok( weap, "_" );
+
+ return isDefined( weaptoks[0] ) && isString( weaptoks[0] ) && isdefined( level.bots_fullautoguns[weaptoks[0]] );
}
/*
@@ -439,7 +503,7 @@ WeaponIsFullAuto(weap)
GetEyeHeight()
{
myEye = self GetEyePos();
-
+
return myEye[2] - self.origin[2];
}
@@ -448,16 +512,53 @@ GetEyeHeight()
*/
GetEyePos()
{
- return self getTagOrigin("tag_eye");
+ return self getTagOrigin( "tag_eye" );
+}
+
+/*
+ helper
+*/
+waittill_either_return_( str1, str2 )
+{
+ self endon( str1 );
+ self waittill( str2 );
+ return true;
+}
+
+/*
+ Returns which string gets notified first
+*/
+waittill_either_return( str1, str2 )
+{
+ if ( !isDefined( self waittill_either_return_( str1, str2 ) ) )
+ return str1;
+
+ return str2;
}
/*
Waits until either of the nots.
*/
-waittill_either(not, not1)
+waittill_either( not, not1 )
{
- self endon(not);
- self waittill(not1);
+ self endon( not );
+ self waittill( not1 );
+}
+
+/*
+ iw5
+*/
+allowClassChoice()
+{
+ return true;
+}
+
+/*
+ iw5
+*/
+allowTeamChoice()
+{
+ return true;
}
/*
@@ -466,10 +567,10 @@ waittill_either(not, not1)
waittill_any_timeout( timeOut, string1, string2, string3, string4, string5 )
{
if ( ( !isdefined( string1 ) || string1 != "death" ) &&
- ( !isdefined( string2 ) || string2 != "death" ) &&
- ( !isdefined( string3 ) || string3 != "death" ) &&
- ( !isdefined( string4 ) || string4 != "death" ) &&
- ( !isdefined( string5 ) || string5 != "death" ) )
+ ( !isdefined( string2 ) || string2 != "death" ) &&
+ ( !isdefined( string3 ) || string3 != "death" ) &&
+ ( !isdefined( string4 ) || string4 != "death" ) &&
+ ( !isdefined( string5 ) || string5 != "death" ) )
self endon( "death" );
ent = spawnstruct();
@@ -510,108 +611,157 @@ _timeout( delay )
/*
Returns if we have the create a class object unlocked.
*/
-isItemUnlocked(what, lvl)
+isItemUnlocked( what, lvl )
{
- switch(what)
+ switch ( what )
{
case "ak47":
return true;
+
case "ak74u":
- return (lvl >= 28);
+ return ( lvl >= 28 );
+
case "barrett":
- return (lvl >= 49);
+ return ( lvl >= 49 );
+
case "dragunov":
- return (lvl >= 22);
+ return ( lvl >= 22 );
+
case "g3":
- return (lvl >= 25);
+ return ( lvl >= 25 );
+
case "g36c":
- return (lvl >= 37);
+ return ( lvl >= 37 );
+
case "m1014":
- return (lvl >= 31);
+ return ( lvl >= 31 );
+
case "m14":
- return (lvl >= 46);
+ return ( lvl >= 46 );
+
case "m16":
return true;
+
case "m21":
- return (lvl >= 7);
+ return ( lvl >= 7 );
+
case "m4":
- return (lvl >= 10);
+ return ( lvl >= 10 );
+
case "m40a3":
return true;
+
case "m60e4":
- return (lvl >= 19);
+ return ( lvl >= 19 );
+
case "mp44":
- return (lvl >= 52);
+ return ( lvl >= 52 );
+
case "mp5":
return true;
+
case "p90":
- return (lvl >= 40);
+ return ( lvl >= 40 );
+
case "rpd":
return true;
+
case "saw":
return true;
+
case "skorpion":
return true;
+
case "uzi":
- return (lvl >= 13);
+ return ( lvl >= 13 );
+
case "winchester1200":
return true;
+
case "remington700":
- return (lvl >= 34);
+ return ( lvl >= 34 );
+
case "beretta":
return true;
+
case "colt45":
- return (lvl >= 16);
+ return ( lvl >= 16 );
+
case "deserteagle":
- return (lvl >= 43);
+ return ( lvl >= 43 );
+
case "deserteaglegold":
- return (lvl >= 55);
+ return ( lvl >= 55 );
+
case "usp":
return true;
+
case "specialty_bulletdamage":
return true;
+
case "specialty_armorvest":
return true;
+
case "specialty_fastreload":
- return (lvl >= 20);
+ return ( lvl >= 20 );
+
case "specialty_rof":
- return (lvl >= 29);
+ return ( lvl >= 29 );
+
case "specialty_twoprimaries":
- return (lvl >= 38);
+ return ( lvl >= 38 );
+
case "specialty_gpsjammer":
- return (lvl >= 11);
+ return ( lvl >= 11 );
+
case "specialty_explosivedamage":
return true;
+
case "specialty_longersprint":
return true;
+
case "specialty_bulletaccuracy":
return true;
+
case "specialty_pistoldeath":
- return (lvl >= 8);
+ return ( lvl >= 8 );
+
case "specialty_grenadepulldeath":
- return (lvl >= 17);
+ return ( lvl >= 17 );
+
case "specialty_bulletpenetration":
return true;
+
case "specialty_holdbreath":
- return (lvl >= 26);
+ return ( lvl >= 26 );
+
case "specialty_quieter":
- return (lvl >= 44);
+ return ( lvl >= 44 );
+
case "specialty_parabolic":
- return (lvl >= 35);
+ return ( lvl >= 35 );
+
case "specialty_specialgrenade":
return true;
+
case "specialty_weapon_rpg":
return true;
+
case "specialty_weapon_claymore":
- return (lvl >= 23);
+ return ( lvl >= 23 );
+
case "specialty_fraggrenade":
- return (lvl >= 41);
+ return ( lvl >= 41 );
+
case "specialty_extraammo":
- return (lvl >= 32);
+ return ( lvl >= 32 );
+
case "specialty_detectexplosive":
- return (lvl >= 14);
+ return ( lvl >= 14 );
+
case "specialty_weapon_c4":
return true;
+
default:
return true;
}
@@ -620,21 +770,22 @@ isItemUnlocked(what, lvl)
/*
If the weapon is allowed to be dropped
*/
-isWeaponDroppable(weap)
+isWeaponDroppable( weap )
{
- return (maps\mp\gametypes\_weapons::mayDropWeapon(weap));
+ return ( maps\mp\gametypes\_weapons::mayDropWeapon( weap ) );
}
/*
Selects a random element from the array.
*/
-Random(arr)
+Random( arr )
{
size = arr.size;
- if(!size)
+
+ if ( !size )
return undefined;
-
- return arr[randomInt(size)];
+
+ return arr[randomInt( size )];
}
/*
@@ -643,10 +794,11 @@ Random(arr)
array_remove( ents, remover )
{
newents = [];
- for(i = 0; i < ents.size; i++)
+
+ for ( i = 0; i < ents.size; i++ )
{
index = ents[i];
-
+
if ( index != remover )
newents[ newents.size ] = index;
}
@@ -657,9 +809,9 @@ array_remove( ents, remover )
/*
Waits until not or tim.
*/
-waittill_notify_or_timeout(not, tim)
+waittill_notify_or_timeout( not, tim )
{
- self endon(not);
+ self endon( not );
wait tim;
}
@@ -668,11 +820,11 @@ waittill_notify_or_timeout(not, tim)
*/
GetHostPlayer()
{
- for (i = 0; i < level.players.size; i++)
+ for ( i = 0; i < level.players.size; i++ )
{
player = level.players[i];
- if (!player is_host())
+ if ( !player is_host() )
continue;
return player;
@@ -682,44 +834,44 @@ GetHostPlayer()
}
/*
- Waits for a host player
+ Waits for a host player
*/
bot_wait_for_host()
{
host = undefined;
- while (!isDefined(level) || !isDefined(level.players))
+ while ( !isDefined( level ) || !isDefined( level.players ) )
wait 0.05;
-
- for(i = getDvarFloat("bots_main_waitForHostTime"); i > 0; i -= 0.05)
+
+ for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 )
{
host = GetHostPlayer();
-
- if(isDefined(host))
+
+ if ( isDefined( host ) )
break;
-
- wait 0.05;
- }
-
- if(!isDefined(host))
- return;
-
- for(i = getDvarFloat("bots_main_waitForHostTime"); i > 0; i -= 0.05)
- {
- if(IsDefined( host.pers[ "team" ] ))
- break;
-
+
wait 0.05;
}
- if(!IsDefined( host.pers[ "team" ] ))
+ if ( !isDefined( host ) )
return;
-
- for(i = getDvarFloat("bots_main_waitForHostTime"); i > 0; i -= 0.05)
+
+ for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 )
{
- if(host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis")
+ if ( IsDefined( host.pers[ "team" ] ) )
break;
-
+
+ wait 0.05;
+ }
+
+ if ( !IsDefined( host.pers[ "team" ] ) )
+ return;
+
+ for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 )
+ {
+ if ( host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis" )
+ break;
+
wait 0.05;
}
}
@@ -728,46 +880,47 @@ bot_wait_for_host()
Pezbot's line sphere intersection.
http://paulbourke.net/geometry/circlesphere/raysphere.c
*/
-RaySphereIntersect(start, end, spherePos, radius)
+RaySphereIntersect( start, end, spherePos, radius )
{
// check if the start or end points are in the sphere
r2 = radius * radius;
- if (DistanceSquared(start, spherePos) < r2)
+
+ if ( DistanceSquared( start, spherePos ) < r2 )
return true;
- if (DistanceSquared(end, spherePos) < r2)
+ if ( DistanceSquared( end, spherePos ) < r2 )
return true;
// check if the line made by start and end intersect the sphere
dp = end - start;
a = dp[0] * dp[0] + dp[1] * dp[1] + dp[2] * dp[2];
- b = 2 * (dp[0] * (start[0] - spherePos[0]) + dp[1] * (start[1] - spherePos[1]) + dp[2] * (start[2] - spherePos[2]));
+ b = 2 * ( dp[0] * ( start[0] - spherePos[0] ) + dp[1] * ( start[1] - spherePos[1] ) + dp[2] * ( start[2] - spherePos[2] ) );
c = spherePos[0] * spherePos[0] + spherePos[1] * spherePos[1] + spherePos[2] * spherePos[2];
c += start[0] * start[0] + start[1] * start[1] + start[2] * start[2];
- c -= 2.0 * (spherePos[0] * start[0] + spherePos[1] * start[1] + spherePos[2] * start[2]);
+ c -= 2.0 * ( spherePos[0] * start[0] + spherePos[1] * start[1] + spherePos[2] * start[2] );
c -= radius * radius;
bb4ac = b * b - 4.0 * a * c;
- if (abs(a) < 0.0001 || bb4ac < 0)
+ if ( abs( a ) < 0.0001 || bb4ac < 0 )
return false;
- mu1 = (0-b + sqrt(bb4ac)) / (2 * a);
+ mu1 = ( 0 - b + sqrt( bb4ac ) ) / ( 2 * a );
//mu2 = (0-b - sqrt(bb4ac)) / (2 * a);
// intersection points of the sphere
ip1 = start + mu1 * dp;
//ip2 = start + mu2 * dp;
- myDist = DistanceSquared(start, end);
+ myDist = DistanceSquared( start, end );
// check if both intersection points far
- if (DistanceSquared(start, ip1) > myDist/* && DistanceSquared(start, ip2) > myDist*/)
+ if ( DistanceSquared( start, ip1 ) > myDist/* && DistanceSquared(start, ip2) > myDist*/ )
return false;
- dpAngles = VectorToAngles(dp);
+ dpAngles = VectorToAngles( dp );
// check if the point is behind us
- if (getConeDot(ip1, start, dpAngles) < 0/* || getConeDot(ip2, start, dpAngles) < 0*/)
+ if ( getConeDot( ip1, start, dpAngles ) < 0/* || getConeDot(ip2, start, dpAngles) < 0*/ )
return false;
return true;
@@ -776,55 +929,55 @@ RaySphereIntersect(start, end, spherePos, radius)
/*
Returns if a smoke grenade would intersect start to end line.
*/
-SmokeTrace(start, end, rad)
+SmokeTrace( start, end, rad )
{
- for(i = level.bots_smokeList.count - 1; i >= 0; i--)
+ for ( i = level.bots_smokeList.count - 1; i >= 0; i-- )
{
nade = level.bots_smokeList.data[i];
-
- if(nade.state != "smoking")
+
+ if ( nade.state != "smoking" )
continue;
-
- if(!RaySphereIntersect(start, end, nade.origin, rad))
+
+ if ( !RaySphereIntersect( start, end, nade.origin, rad ) )
continue;
-
+
return false;
}
-
+
return true;
}
/*
Returns the cone dot (like fov, or distance from the center of our screen). 1.0 = directly looking at, 0.0 = completely right angle, -1.0, completely 180
*/
-getConeDot(to, from, dir)
+getConeDot( to, from, dir )
{
- dirToTarget = VectorNormalize(to-from);
- forward = AnglesToForward(dir);
- return vectordot(dirToTarget, forward);
+ dirToTarget = VectorNormalize( to - from );
+ forward = AnglesToForward( dir );
+ return vectordot( dirToTarget, forward );
}
/*
Returns the distance squared in a 2d space
*/
-DistanceSquared2D(to, from)
+DistanceSquared2D( to, from )
{
- to = (to[0], to[1], 0);
- from = (from[0], from[1], 0);
-
- return DistanceSquared(to, from);
+ to = ( to[0], to[1], 0 );
+ from = ( from[0], from[1], 0 );
+
+ return DistanceSquared( to, from );
}
/*
Rounds to the nearest whole number.
*/
-Round(x)
+Round( x )
{
- y = int(x);
-
- if(abs(x) - abs(y) > 0.5)
+ y = int( x );
+
+ if ( abs( x ) - abs( y ) > 0.5 )
{
- if(x < 0)
+ if ( x < 0 )
return y - 1;
else
return y + 1;
@@ -834,54 +987,149 @@ Round(x)
}
/*
- Rounds up the given value.
+ clamps angle between -180 and 180
*/
-RoundUp( floatVal )
+AngleClamp180( angle )
{
- i = int( floatVal );
- if ( i != floatVal )
- return i + 1;
- else
- return i;
+ angleFrac = angle / 360.0;
+ angle = ( angleFrac - floor( angleFrac ) ) * 360.0;
+
+ if ( angle > 180.0 )
+ return angle - 360.0;
+
+ return angle;
+}
+
+/*
+ Clamps between value
+*/
+Clamp( a, minv, maxv )
+{
+ return max( min( a, maxv ), minv );
}
/*
Matches a num to a char
*/
-keyCodeToString(a)
+keyCodeToString( a )
{
- b="";
- switch(a)
+ b = "";
+
+ switch ( a )
{
- case 0: b= "a"; break;
- case 1: b= "b"; break;
- case 2: b= "c"; break;
- case 3: b= "d"; break;
- case 4: b= "e"; break;
- case 5: b= "f"; break;
- case 6: b= "g"; break;
- case 7: b= "h"; break;
- case 8: b= "i"; break;
- case 9: b= "j"; break;
- case 10: b= "k"; break;
- case 11: b= "l"; break;
- case 12: b= "m"; break;
- case 13: b= "n"; break;
- case 14: b= "o"; break;
- case 15: b= "p"; break;
- case 16: b= "q"; break;
- case 17: b= "r"; break;
- case 18: b= "s"; break;
- case 19: b= "t"; break;
- case 20: b= "u"; break;
- case 21: b= "v"; break;
- case 22: b= "w"; break;
- case 23: b= "x"; break;
- case 24: b= "y"; break;
- case 25: b= "z"; break;
- case 26: b= "."; break;
- case 27: b= " "; break;
+ case 0:
+ b = "a";
+ break;
+
+ case 1:
+ b = "b";
+ break;
+
+ case 2:
+ b = "c";
+ break;
+
+ case 3:
+ b = "d";
+ break;
+
+ case 4:
+ b = "e";
+ break;
+
+ case 5:
+ b = "f";
+ break;
+
+ case 6:
+ b = "g";
+ break;
+
+ case 7:
+ b = "h";
+ break;
+
+ case 8:
+ b = "i";
+ break;
+
+ case 9:
+ b = "j";
+ break;
+
+ case 10:
+ b = "k";
+ break;
+
+ case 11:
+ b = "l";
+ break;
+
+ case 12:
+ b = "m";
+ break;
+
+ case 13:
+ b = "n";
+ break;
+
+ case 14:
+ b = "o";
+ break;
+
+ case 15:
+ b = "p";
+ break;
+
+ case 16:
+ b = "q";
+ break;
+
+ case 17:
+ b = "r";
+ break;
+
+ case 18:
+ b = "s";
+ break;
+
+ case 19:
+ b = "t";
+ break;
+
+ case 20:
+ b = "u";
+ break;
+
+ case 21:
+ b = "v";
+ break;
+
+ case 22:
+ b = "w";
+ break;
+
+ case 23:
+ b = "x";
+ break;
+
+ case 24:
+ b = "y";
+ break;
+
+ case 25:
+ b = "z";
+ break;
+
+ case 26:
+ b = ".";
+ break;
+
+ case 27:
+ b = " ";
+ break;
}
+
return b;
}
@@ -891,42 +1139,47 @@ keyCodeToString(a)
cac_init_patch()
{
// oldschool mode does not create these, we need those tho.
- if(!isDefined(level.tbl_weaponIDs))
+ if ( !isDefined( level.tbl_weaponIDs ) )
{
level.tbl_weaponIDs = [];
- for( i=0; i<150; i++ )
+
+ for ( i = 0; i < 150; i++ )
{
reference_s = tableLookup( "mp/statsTable.csv", 0, i, 4 );
- if( reference_s != "" )
- {
+
+ if ( reference_s != "" )
+ {
level.tbl_weaponIDs[i]["reference"] = reference_s;
level.tbl_weaponIDs[i]["group"] = tablelookup( "mp/statstable.csv", 0, i, 2 );
level.tbl_weaponIDs[i]["count"] = int( tablelookup( "mp/statstable.csv", 0, i, 5 ) );
- level.tbl_weaponIDs[i]["attachment"] = tablelookup( "mp/statstable.csv", 0, i, 8 );
+ level.tbl_weaponIDs[i]["attachment"] = tablelookup( "mp/statstable.csv", 0, i, 8 );
}
else
continue;
}
}
-
- if(!isDefined(level.tbl_WeaponAttachment))
+
+ if ( !isDefined( level.tbl_WeaponAttachment ) )
{
level.tbl_WeaponAttachment = [];
- for( i=0; i<8; i++ )
+
+ for ( i = 0; i < 8; i++ )
{
level.tbl_WeaponAttachment[i]["bitmask"] = int( tableLookup( "mp/attachmentTable.csv", 9, i, 10 ) );
level.tbl_WeaponAttachment[i]["reference"] = tableLookup( "mp/attachmentTable.csv", 9, i, 4 );
}
}
-
- if(!isDefined(level.tbl_PerkData))
+
+ if ( !isDefined( level.tbl_PerkData ) )
{
level.tbl_PerkData = [];
+
// generating perk data vars collected form statsTable.csv
- for( i=150; i<194; i++ )
+ for ( i = 150; i < 194; i++ )
{
reference_s = tableLookup( "mp/statsTable.csv", 0, i, 4 );
- if( reference_s != "" )
+
+ if ( reference_s != "" )
{
level.tbl_PerkData[i]["reference"] = reference_s;
level.tbl_PerkData[i]["reference_full"] = tableLookup( "mp/statsTable.csv", 0, i, 6 );
@@ -943,45 +1196,85 @@ cac_init_patch()
level.perkReferenceToIndex = [];
level.weaponReferenceToIndex = [];
level.weaponAttachmentReferenceToIndex = [];
-
- for( i=0; i<150; i++ )
+
+ for ( i = 0; i < 150; i++ )
{
- if(!isDefined(level.tbl_weaponIDs[i]) || !isDefined(level.tbl_weaponIDs[i]["reference"]))
+ if ( !isDefined( level.tbl_weaponIDs[i] ) || !isDefined( level.tbl_weaponIDs[i]["reference"] ) )
continue;
-
+
level.weaponReferenceToIndex[level.tbl_weaponIDs[i]["reference"]] = i;
}
-
- for( i=0; i<8; i++ )
+
+ for ( i = 0; i < 8; i++ )
{
- if(!isDefined(level.tbl_WeaponAttachment[i]) || !isDefined(level.tbl_WeaponAttachment[i]["reference"]))
+ if ( !isDefined( level.tbl_WeaponAttachment[i] ) || !isDefined( level.tbl_WeaponAttachment[i]["reference"] ) )
continue;
-
+
level.weaponAttachmentReferenceToIndex[level.tbl_WeaponAttachment[i]["reference"]] = i;
}
-
- for( i=150; i<194; i++ )
+
+ for ( i = 150; i < 194; i++ )
{
- if(!isDefined(level.tbl_PerkData[i]) || !isDefined(level.tbl_PerkData[i]["reference_full"]))
+ if ( !isDefined( level.tbl_PerkData[i] ) || !isDefined( level.tbl_PerkData[i]["reference_full"] ) )
continue;
-
+
level.perkReferenceToIndex[ level.tbl_PerkData[i]["reference_full"] ] = i;
}
}
+/*
+ Parse frontlines type waypoints
+*/
+FrontLinesWaypoints()
+{
+ waypoints = [];
+
+ for ( i = 0;; i++ )
+ {
+ dvar_answer = getDvar( "flwp_" + i );
+
+ if ( dvar_answer == "" || dvar_answer == "eof" )
+ break;
+
+ toks = strtok( dvar_answer, "," );
+
+ waypoint = spawnStruct();
+ wp_num = int( toks[0] );
+ x = float( toks[1] );
+ y = float( toks[2] );
+ z = float( toks[3] );
+ waypoint.origin = ( x, y, z );
+
+ waypoint.type = toks[4];
+ waypoint.children = [];
+
+ num_children = int( toks[5] );
+
+ for ( h = 0; h < num_children; h++ )
+ {
+ waypoint.children[waypoint.children.size] = int( toks[6 + h] );
+ }
+
+ waypoints[wp_num] = waypoint;
+ }
+
+ return waypoints;
+}
+
/*
Tokenizes a string (strtok has limits...) (only one char tok)
*/
-tokenizeLine(line, tok)
+tokenizeLine( line, tok )
{
tokens = [];
token = "";
- for (i = 0; i < line.size; i++)
+
+ for ( i = 0; i < line.size; i++ )
{
c = line[i];
- if (c == tok)
+ if ( c == tok )
{
tokens[tokens.size] = token;
token = "";
@@ -990,6 +1283,7 @@ tokenizeLine(line, tok)
token += c;
}
+
tokens[tokens.size] = token;
return tokens;
@@ -998,29 +1292,30 @@ tokenizeLine(line, tok)
/*
Parses tokens into a waypoint obj
*/
-parseTokensIntoWaypoint(tokens)
+parseTokensIntoWaypoint( tokens )
{
waypoint = spawnStruct();
orgStr = tokens[0];
- orgToks = strtok(orgStr, " ");
- waypoint.origin = (float(orgToks[0]), float(orgToks[1]), float(orgToks[2]));
+ orgToks = strtok( orgStr, " " );
+ waypoint.origin = ( float( orgToks[0] ), float( orgToks[1] ), float( orgToks[2] ) );
childStr = tokens[1];
- childToks = strtok(childStr, " ");
- waypoint.childCount = childToks.size;
+ childToks = strtok( childStr, " " );
waypoint.children = [];
- for( j=0; j dist )
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ Returns the waypoints that are near
+*/
+waypointsNear( waypoints, dist )
+{
+ dist *= dist;
+
+ answer = [];
+
+ for ( i = 0; i < waypoints.size; i++ )
+ {
+ wp = level.waypoints[waypoints[i]];
+
+ if ( DistanceSquared( wp.origin, self.origin ) > dist )
+ continue;
+
+ answer[answer.size] = waypoints[i];
+ }
+
+ return answer;
+}
+
+/*
+ Returns nearest waypoint of waypoints
+*/
+getNearestWaypointOfWaypoints( waypoints )
+{
+ answer = undefined;
+ closestDist = 2147483647;
+
+ for ( i = 0; i < waypoints.size; i++ )
+ {
+ waypoint = level.waypoints[waypoints[i]];
+ thisDist = DistanceSquared( self.origin, waypoint.origin );
+
+ if ( isDefined( answer ) && thisDist > closestDist )
+ continue;
+
+ answer = waypoints[i];
+ closestDist = thisDist;
+ }
+
+ return answer;
+}
+
+/*
+ Returns all waypoints of type
+*/
+getWaypointsOfType( type )
+{
+ answer = [];
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ wp = level.waypoints[i];
+
+ if ( type == "camp" )
+ {
+ if ( wp.type != "crouch" )
+ continue;
+
+ if ( wp.children.size != 1 )
+ continue;
+ }
+ else if ( type != wp.type )
+ continue;
+
+ answer[answer.size] = i;
+ }
+
+ return answer;
+}
+
+/*
+ Returns the waypoint for index
+*/
+getWaypointForIndex( i )
+{
+ if ( !isDefined( i ) )
+ return undefined;
+
+ return level.waypoints[i];
}
/*
@@ -1260,7 +1670,7 @@ load_waypoints()
*/
getGoodMapAmount()
{
- switch(getDvar("mapname"))
+ switch ( getDvar( "mapname" ) )
{
case "mp_crash":
case "mp_crash_snow":
@@ -1277,82 +1687,102 @@ getGoodMapAmount()
case "mp_backlot":
case "mp_convoy":
case "mp_bloc":
- if(level.teamBased)
+ if ( level.teamBased )
return 14;
else
return 9;
-
+
case "mp_vacant":
case "mp_showdown":
case "mp_citystreets":
case "mp_bog":
- if(level.teamBased)
+ if ( level.teamBased )
return 12;
else
return 8;
-
+
case "mp_killhouse":
case "mp_shipment":
- if(level.teamBased)
+ if ( level.teamBased )
return 8;
else
return 4;
}
-
+
return 2;
}
/*
Returns the friendly user name for a given map's codename
*/
-getMapName(map)
+getMapName( map )
{
- switch(map)
+ switch ( map )
{
case "mp_convoy":
return "Ambush";
+
case "mp_backlot":
return "Backlot";
+
case "mp_bloc":
return "Bloc";
+
case "mp_bog":
return "Bog";
+
case "mp_countdown":
return "Countdown";
+
case "mp_crash":
return "Crash";
+
case "mp_crash_snow":
return "Winter Crash";
+
case "mp_crossfire":
return "Crossfire";
+
case "mp_citystreets":
return "District";
+
case "mp_farm":
return "Downpour";
+
case "mp_overgrown":
return "Overgrown";
+
case "mp_pipeline":
return "Pipeline";
+
case "mp_shipment":
return "Shipment";
+
case "mp_showdown":
return "Showdown";
+
case "mp_strike":
return "Strike";
+
case "mp_vacant":
return "Vacant";
+
case "mp_cargoship":
return "Wetwork";
+
case "mp_broadcast":
return "Broadcast";
+
case "mp_creek":
return "Creek";
+
case "mp_carentan":
return "Chinatown";
+
case "mp_killhouse":
return "Killhouse";
}
-
+
return map;
}
@@ -1371,16 +1801,17 @@ getBotArray()
{
result = [];
playercount = level.players.size;
- for(i = 0; i < playercount; i++)
+
+ for ( i = 0; i < playercount; i++ )
{
player = level.players[i];
-
- if(!player is_bot())
+
+ if ( !player is_bot() )
continue;
-
+
result[result.size] = player;
}
-
+
return result;
}
@@ -1390,64 +1821,68 @@ getBotArray()
WaypointsToKDTree()
{
kdTree = KDTree();
-
- kdTree _WaypointsToKDTree(level.waypoints, 0);
-
+
+ kdTree _WaypointsToKDTree( level.waypoints, 0 );
+
return kdTree;
}
/*
Recurive function. We construct a balanced KD tree by sorting the waypoints using heap sort.
*/
-_WaypointsToKDTree(waypoints, dem)
+_WaypointsToKDTree( waypoints, dem )
{
- if(!waypoints.size)
+ if ( !waypoints.size )
return;
callbacksort = undefined;
-
- switch(dem)
+
+ switch ( dem )
{
case 0:
callbacksort = ::HeapSortCoordX;
- break;
+ break;
+
case 1:
callbacksort = ::HeapSortCoordY;
- break;
+ break;
+
case 2:
callbacksort = ::HeapSortCoordZ;
- break;
+ break;
}
-
- heap = NewHeap(callbacksort);
-
- for(i = 0; i < waypoints.size; i++)
+
+ heap = NewHeap( callbacksort );
+
+ for ( i = 0; i < waypoints.size; i++ )
{
- heap HeapInsert(waypoints[i]);
+ heap HeapInsert( waypoints[i] );
}
-
+
sorted = [];
- while(heap.data.size)
+
+ while ( heap.data.size )
{
sorted[sorted.size] = heap.data[0];
heap HeapRemove();
}
-
- median = int(sorted.size/2);//use divide and conq
-
+
+ median = int( sorted.size / 2 ); //use divide and conq
+
left = [];
right = [];
- for(i = 0; i < sorted.size; i++)
- if(i < median)
+
+ for ( i = 0; i < sorted.size; i++ )
+ if ( i < median )
right[right.size] = sorted[i];
- else if(i > median)
+ else if ( i > median )
left[left.size] = sorted[i];
-
- self KDTreeInsert(sorted[median]);
-
- _WaypointsToKDTree(left, (dem+1)%3);
-
- _WaypointsToKDTree(right, (dem+1)%3);
+
+ self KDTreeInsert( sorted[median] );
+
+ _WaypointsToKDTree( left, ( dem + 1 ) % 3 );
+
+ _WaypointsToKDTree( right, ( dem + 1 ) % 3 );
}
/*
@@ -1458,26 +1893,26 @@ List()
list = spawnStruct();
list.count = 0;
list.data = [];
-
+
return list;
}
/*
Adds a new thing to the list.
*/
-ListAdd(thing)
+ListAdd( thing )
{
self.data[self.count] = thing;
-
+
self.count++;
}
/*
Adds to the start of the list.
*/
-ListAddFirst(thing)
+ListAddFirst( thing )
{
- for (i = self.count - 1; i >= 0; i--)
+ for ( i = self.count - 1; i >= 0; i-- )
{
self.data[i + 1] = self.data[i];
}
@@ -1489,18 +1924,18 @@ ListAddFirst(thing)
/*
Removes the thing from the list.
*/
-ListRemove(thing)
+ListRemove( thing )
{
for ( i = 0; i < self.count; i++ )
{
if ( self.data[i] == thing )
{
- while ( i < self.count-1 )
+ while ( i < self.count - 1 )
{
- self.data[i] = self.data[i+1];
+ self.data[i] = self.data[i + 1];
i++;
}
-
+
self.data[i] = undefined;
self.count--;
break;
@@ -1516,24 +1951,24 @@ KDTree()
kdTree = spawnStruct();
kdTree.root = undefined;
kdTree.count = 0;
-
+
return kdTree;
}
/*
Called on a KDTree. Will insert the object into the KDTree.
*/
-KDTreeInsert(data)//as long as what you insert has a .origin attru, it will work.
+KDTreeInsert( data ) //as long as what you insert has a .origin attru, it will work.
{
- self.root = self _KDTreeInsert(self.root, data, 0, -2147483647, -2147483647, -2147483647, 2147483647, 2147483647, 2147483647);
+ self.root = self _KDTreeInsert( self.root, data, 0, -2147483647, -2147483647, -2147483647, 2147483647, 2147483647, 2147483647 );
}
/*
Recurive function that insert the object into the KDTree.
*/
-_KDTreeInsert(node, data, dem, x0, y0, z0, x1, y1, z1)
+_KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 )
{
- if(!isDefined(node))
+ if ( !isDefined( node ) )
{
r = spawnStruct();
r.data = data;
@@ -1545,116 +1980,122 @@ _KDTreeInsert(node, data, dem, x0, y0, z0, x1, y1, z1)
r.y1 = y1;
r.z0 = z0;
r.z1 = z1;
-
+
self.count++;
-
+
return r;
}
-
- switch(dem)
+
+ switch ( dem )
{
case 0:
- if(data.origin[0] < node.data.origin[0])
- node.left = self _KDTreeInsert(node.left, data, 1, x0, y0, z0, node.data.origin[0], y1, z1);
+ if ( data.origin[0] < node.data.origin[0] )
+ node.left = self _KDTreeInsert( node.left, data, 1, x0, y0, z0, node.data.origin[0], y1, z1 );
else
- node.right = self _KDTreeInsert(node.right, data, 1, node.data.origin[0], y0, z0, x1, y1, z1);
- break;
+ node.right = self _KDTreeInsert( node.right, data, 1, node.data.origin[0], y0, z0, x1, y1, z1 );
+
+ break;
+
case 1:
- if(data.origin[1] < node.data.origin[1])
- node.left = self _KDTreeInsert(node.left, data, 2, x0, y0, z0, x1, node.data.origin[1], z1);
+ if ( data.origin[1] < node.data.origin[1] )
+ node.left = self _KDTreeInsert( node.left, data, 2, x0, y0, z0, x1, node.data.origin[1], z1 );
else
- node.right = self _KDTreeInsert(node.right, data, 2, x0, node.data.origin[1], z0, x1, y1, z1);
- break;
+ node.right = self _KDTreeInsert( node.right, data, 2, x0, node.data.origin[1], z0, x1, y1, z1 );
+
+ break;
+
case 2:
- if(data.origin[2] < node.data.origin[2])
- node.left = self _KDTreeInsert(node.left, data, 0, x0, y0, z0, x1, y1, node.data.origin[2]);
+ if ( data.origin[2] < node.data.origin[2] )
+ node.left = self _KDTreeInsert( node.left, data, 0, x0, y0, z0, x1, y1, node.data.origin[2] );
else
- node.right = self _KDTreeInsert(node.right, data, 0, x0, y0, node.data.origin[2], x1, y1, z1);
- break;
+ node.right = self _KDTreeInsert( node.right, data, 0, x0, y0, node.data.origin[2], x1, y1, z1 );
+
+ break;
}
-
+
return node;
}
/*
Called on a KDTree, will return the nearest object to the given origin.
*/
-KDTreeNearest(origin)
+KDTreeNearest( origin )
{
- if(!isDefined(self.root))
+ if ( !isDefined( self.root ) )
return undefined;
-
- return self _KDTreeNearest(self.root, origin, self.root.data, DistanceSquared(self.root.data.origin, origin), 0);
+
+ return self _KDTreeNearest( self.root, origin, self.root.data, DistanceSquared( self.root.data.origin, origin ), 0 );
}
/*
Recurive function that will retrieve the closest object to the query.
*/
-_KDTreeNearest(node, point, closest, closestdist, dem)
+_KDTreeNearest( node, point, closest, closestdist, dem )
{
- if(!isDefined(node))
+ if ( !isDefined( node ) )
{
return closest;
}
-
- thisDis = DistanceSquared(node.data.origin, point);
-
- if(thisDis < closestdist)
+
+ thisDis = DistanceSquared( node.data.origin, point );
+
+ if ( thisDis < closestdist )
{
closestdist = thisDis;
closest = node.data;
}
-
- if(node RectDistanceSquared(point) < closestdist)
+
+ if ( node RectDistanceSquared( point ) < closestdist )
{
near = node.left;
far = node.right;
- if(point[dem] > node.data.origin[dem])
+
+ if ( point[dem] > node.data.origin[dem] )
{
near = node.right;
far = node.left;
}
-
- closest = self _KDTreeNearest(near, point, closest, closestdist, (dem+1)%3);
-
- closest = self _KDTreeNearest(far, point, closest, DistanceSquared(closest.origin, point), (dem+1)%3);
+
+ closest = self _KDTreeNearest( near, point, closest, closestdist, ( dem + 1 ) % 3 );
+
+ closest = self _KDTreeNearest( far, point, closest, DistanceSquared( closest.origin, point ), ( dem + 1 ) % 3 );
}
-
+
return closest;
}
/*
Called on a rectangle, returns the distance from origin to the rectangle.
*/
-RectDistanceSquared(origin)
+RectDistanceSquared( origin )
{
dx = 0;
dy = 0;
dz = 0;
-
- if(origin[0] < self.x0)
+
+ if ( origin[0] < self.x0 )
dx = origin[0] - self.x0;
- else if(origin[0] > self.x1)
+ else if ( origin[0] > self.x1 )
dx = origin[0] - self.x1;
-
- if(origin[1] < self.y0)
+
+ if ( origin[1] < self.y0 )
dy = origin[1] - self.y0;
- else if(origin[1] > self.y1)
+ else if ( origin[1] > self.y1 )
dy = origin[1] - self.y1;
-
- if(origin[2] < self.z0)
+
+ if ( origin[2] < self.z0 )
dz = origin[2] - self.z0;
- else if(origin[2] > self.z1)
+ else if ( origin[2] > self.z1 )
dz = origin[2] - self.z1;
-
- return dx*dx + dy*dy + dz*dz;
+
+ return dx * dx + dy * dy + dz * dz;
}
/*
A heap invarient comparitor, used for objects, objects with a higher X coord will be first in the heap.
*/
-HeapSortCoordX(item, item2)
+HeapSortCoordX( item, item2 )
{
return item.origin[0] > item2.origin[0];
}
@@ -1662,7 +2103,7 @@ HeapSortCoordX(item, item2)
/*
A heap invarient comparitor, used for objects, objects with a higher Y coord will be first in the heap.
*/
-HeapSortCoordY(item, item2)
+HeapSortCoordY( item, item2 )
{
return item.origin[1] > item2.origin[1];
}
@@ -1670,7 +2111,7 @@ HeapSortCoordY(item, item2)
/*
A heap invarient comparitor, used for objects, objects with a higher Z coord will be first in the heap.
*/
-HeapSortCoordZ(item, item2)
+HeapSortCoordZ( item, item2 )
{
return item.origin[2] > item2.origin[2];
}
@@ -1678,7 +2119,7 @@ HeapSortCoordZ(item, item2)
/*
A heap invarient comparitor, used for numbers, numbers with the highest number will be first in the heap.
*/
-Heap(item, item2)
+Heap( item, item2 )
{
return item > item2;
}
@@ -1686,7 +2127,7 @@ Heap(item, item2)
/*
A heap invarient comparitor, used for numbers, numbers with the lowest number will be first in the heap.
*/
-ReverseHeap(item, item2)
+ReverseHeap( item, item2 )
{
return item < item2;
}
@@ -1694,7 +2135,7 @@ ReverseHeap(item, item2)
/*
A heap invarient comparitor, used for traces. Wanting the trace with the largest length first in the heap.
*/
-HeapTraceFraction(item, item2)
+HeapTraceFraction( item, item2 )
{
return item["fraction"] > item2["fraction"];
}
@@ -1702,53 +2143,53 @@ HeapTraceFraction(item, item2)
/*
Returns a new heap.
*/
-NewHeap(compare)
+NewHeap( compare )
{
heap_node = spawnStruct();
heap_node.data = [];
heap_node.compare = compare;
-
+
return heap_node;
}
/*
Inserts the item into the heap. Called on a heap.
*/
-HeapInsert(item)
+HeapInsert( item )
{
insert = self.data.size;
self.data[insert] = item;
-
- current = insert+1;
-
- while(current > 1)
+
+ current = insert + 1;
+
+ while ( current > 1 )
{
last = current;
- current = int(current/2);
-
- if(![[self.compare]](item, self.data[current-1]))
+ current = int( current / 2 );
+
+ if ( ![[self.compare]]( item, self.data[current - 1] ) )
break;
-
- self.data[last-1] = self.data[current-1];
- self.data[current-1] = item;
+
+ self.data[last - 1] = self.data[current - 1];
+ self.data[current - 1] = item;
}
}
/*
Helper function to determine what is the next child of the bst.
*/
-_HeapNextChild(node, hsize)
+_HeapNextChild( node, hsize )
{
left = node * 2;
right = left + 1;
-
- if(left > hsize)
+
+ if ( left > hsize )
return -1;
-
- if(right > hsize)
+
+ if ( right > hsize )
return left;
-
- if([[self.compare]](self.data[left-1], self.data[right-1]))
+
+ if ( [[self.compare]]( self.data[left - 1], self.data[right - 1] ) )
return left;
else
return right;
@@ -1760,223 +2201,279 @@ _HeapNextChild(node, hsize)
HeapRemove()
{
remove = self.data.size;
-
- if(!remove)
+
+ if ( !remove )
return remove;
-
- move = self.data[remove-1];
+
+ move = self.data[remove - 1];
self.data[0] = move;
- self.data[remove-1] = undefined;
+ self.data[remove - 1] = undefined;
remove--;
-
- if(!remove)
+
+ if ( !remove )
return remove;
-
+
last = 1;
- next = self _HeapNextChild(1, remove);
-
- while(next != -1)
+ next = self _HeapNextChild( 1, remove );
+
+ while ( next != -1 )
{
- if([[self.compare]](move, self.data[next-1]))
+ if ( [[self.compare]]( move, self.data[next - 1] ) )
break;
-
- self.data[last-1] = self.data[next-1];
- self.data[next-1] = move;
-
+
+ self.data[last - 1] = self.data[next - 1];
+ self.data[next - 1] = move;
+
last = next;
- next = self _HeapNextChild(next, remove);
+ next = self _HeapNextChild( next, remove );
}
-
+
return remove;
}
/*
A heap invarient comparitor, used for the astar's nodes, wanting the node with the lowest f to be first in the heap.
*/
-ReverseHeapAStar(item, item2)
+ReverseHeapAStar( item, item2 )
{
return item.f < item2.f;
}
+/*
+ Removes the waypoint usage
+*/
+RemoveWaypointUsage( wp, team )
+{
+ if ( !isDefined( level.waypointUsage ) )
+ return;
+
+ if ( !isDefined( level.waypointUsage[team][wp + ""] ) )
+ return;
+
+ level.waypointUsage[team][wp + ""]--;
+
+ if ( level.waypointUsage[team][wp + ""] <= 0 )
+ level.waypointUsage[team][wp + ""] = undefined;
+}
+
/*
Will linearly search for the nearest waypoint to pos that has a direct line of sight.
*/
-GetNearestWaypointWithSight(pos)
+GetNearestWaypointWithSight( pos )
{
candidate = undefined;
dist = 2147483647;
-
- for(i = 0; i < level.waypointCount; i++)
+
+ for ( i = 0; i < level.waypointCount; i++ )
{
- if(!bulletTracePassed(pos + (0, 0, 15), level.waypoints[i].origin + (0, 0, 15), false, undefined))
+ if ( !bulletTracePassed( pos + ( 0, 0, 15 ), level.waypoints[i].origin + ( 0, 0, 15 ), false, undefined ) )
continue;
-
- curdis = DistanceSquared(level.waypoints[i].origin, pos);
- if(curdis > dist)
+
+ curdis = DistanceSquared( level.waypoints[i].origin, pos );
+
+ if ( curdis > dist )
continue;
-
+
dist = curdis;
- candidate = level.waypoints[i];
+ candidate = i;
}
-
+
+ return candidate;
+}
+
+/*
+ Will linearly search for the nearest waypoint
+*/
+GetNearestWaypoint( pos )
+{
+ candidate = undefined;
+ dist = 2147483647;
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ curdis = DistanceSquared( level.waypoints[i].origin, pos );
+
+ if ( curdis > dist )
+ continue;
+
+ dist = curdis;
+ candidate = i;
+ }
+
return candidate;
}
/*
Modified Pezbot astar search.
This makes use of sets for quick look up and a heap for a priority queue instead of simple lists which require to linearly search for elements everytime.
- Also makes use of the KD tree to search for the nearest node to the goal. We only use the closest node from the KD tree if it has a direct line of sight, else we will have to linearly search for one that we have a line of sight on.
It is also modified to make paths with bots already on more expensive and will try a less congested path first. Thus spliting up the bots onto more paths instead of just one (the smallest).
*/
-AStarSearch(start, goal, team, greedy_path)
+AStarSearch( start, goal, team, greedy_path )
{
- open = NewHeap(::ReverseHeapAStar);//heap
+ open = NewHeap( ::ReverseHeapAStar ); //heap
openset = [];//set for quick lookup
-
closed = [];//set for quick lookup
-
- startwp = level.waypointsKDTree KDTreeNearest(start);//balanced kdtree, for nns
- if(!isDefined(startwp))
+
+
+ startWp = getNearestWaypoint( start );
+
+ if ( !isDefined( startWp ) )
return [];
+
_startwp = undefined;
- if(!bulletTracePassed(start + (0, 0, 15), startwp.origin + (0, 0, 15), false, undefined))
- _startwp = GetNearestWaypointWithSight(start);
- if(isDefined(_startwp))
- startwp = _startwp;
- startwp = startwp.index;
-
- goalwp = level.waypointsKDTree KDTreeNearest(goal);
- if(!isDefined(goalwp))
+
+ if ( !bulletTracePassed( start + ( 0, 0, 15 ), level.waypoints[startWp].origin + ( 0, 0, 15 ), false, undefined ) )
+ _startwp = GetNearestWaypointWithSight( start );
+
+ if ( isDefined( _startwp ) )
+ startWp = _startwp;
+
+
+ goalWp = getNearestWaypoint( goal );
+
+ if ( !isDefined( goalWp ) )
return [];
- _goalwp = undefined;
- if(!bulletTracePassed(goal + (0, 0, 15), goalwp.origin + (0, 0, 15), false, undefined))
- _goalwp = GetNearestWaypointWithSight(goal);
- if(isDefined(_goalwp))
- goalwp = _goalwp;
- goalwp = goalwp.index;
-
- goalorg = level.waypoints[goalWp].origin;
-
+
+ _goalWp = undefined;
+
+ if ( !bulletTracePassed( goal + ( 0, 0, 15 ), level.waypoints[goalWp].origin + ( 0, 0, 15 ), false, undefined ) )
+ _goalwp = GetNearestWaypointWithSight( goal );
+
+ if ( isDefined( _goalwp ) )
+ goalWp = _goalwp;
+
+
node = spawnStruct();
node.g = 0; //path dist so far
- node.h = DistanceSquared(level.waypoints[startWp].origin, goalorg); //herustic, distance to goal for path finding
- //node.f = node.h + node.g; // combine path dist and heru, use reverse heap to sort the priority queue by this attru
- node.f = node.h;
- node.index = startwp;
+ node.h = DistanceSquared( level.waypoints[startWp].origin, level.waypoints[goalWp].origin ); //herustic, distance to goal for path finding
+ node.f = node.h + node.g; // combine path dist and heru, use reverse heap to sort the priority queue by this attru
+ node.index = startWp;
node.parent = undefined; //we are start, so we have no parent
-
+
//push node onto queue
- openset[node.index] = node;
- open HeapInsert(node);
-
+ openset[node.index + ""] = node;
+ open HeapInsert( node );
+
//while the queue is not empty
- while(open.data.size)
+ while ( open.data.size )
{
//pop bestnode from queue
bestNode = open.data[0];
open HeapRemove();
- openset[bestNode.index] = undefined;
-
+ openset[bestNode.index + ""] = undefined;
+ wp = level.waypoints[bestNode.index];
+
//check if we made it to the goal
- if(bestNode.index == goalwp)
+ if ( bestNode.index == goalWp )
{
path = [];
-
- while(isDefined(bestNode))
+
+ while ( isDefined( bestNode ) )
{
- if(isdefined(team))
- level.waypoints[bestNode.index].bots[team]++;
-
+ if ( isdefined( team ) && isDefined( level.waypointUsage ) )
+ {
+ if ( !isDefined( level.waypointUsage[team][bestNode.index + ""] ) )
+ level.waypointUsage[team][bestNode.index + ""] = 0;
+
+ level.waypointUsage[team][bestNode.index + ""]++;
+ }
+
//construct path
path[path.size] = bestNode.index;
-
+
bestNode = bestNode.parent;
}
-
+
return path;
}
-
- nodeorg = level.waypoints[bestNode.index].origin;
- childcount = level.waypoints[bestNode.index].childCount;
+
//for each child of bestnode
- for(i = 0; i < childcount; i++)
+ for ( i = wp.children.size - 1; i >= 0; i-- )
{
- child = level.waypoints[bestNode.index].children[i];
- childorg = level.waypoints[child].origin;
- childtype = level.waypoints[child].type;
-
+ child = wp.children[i];
+ childWp = level.waypoints[child];
+
penalty = 1;
- if(!greedy_path && isdefined(team))
+
+ if ( !greedy_path && isdefined( team ) && isDefined( level.waypointUsage ) )
{
- temppen = level.waypoints[child].bots[team];//consider how many bots are taking this path
- if(temppen > 1)
+ temppen = 1;
+
+ if ( isDefined( level.waypointUsage[team][child + ""] ) )
+ temppen = level.waypointUsage[team][child + ""]; //consider how many bots are taking this path
+
+ if ( temppen > 1 )
penalty = temppen;
}
// have certain types of nodes more expensive
- if (childtype == "climb" || childtype == "prone")
+ if ( childWp.type == "climb" || childWp.type == "prone" )
penalty += 4;
-
+
//calc the total path we have took
- newg = bestNode.g + DistanceSquared(nodeorg, childorg)*penalty;//bots on same team's path are more expensive
-
+ newg = bestNode.g + DistanceSquared( wp.origin, childWp.origin ) * penalty; //bots on same team's path are more expensive
+
//check if this child is in open or close with a g value less than newg
- inopen = isDefined(openset[child]);
- if(inopen && openset[child].g <= newg)
+ inopen = isDefined( openset[child + ""] );
+
+ if ( inopen && openset[child + ""].g <= newg )
continue;
-
- inclosed = isDefined(closed[child]);
- if(inclosed && closed[child].g <= newg)
+
+ inclosed = isDefined( closed[child + ""] );
+
+ if ( inclosed && closed[child + ""].g <= newg )
continue;
-
- if(inopen)
- node = openset[child];
- else if(inclosed)
- node = closed[child];
+
+ node = undefined;
+
+ if ( inopen )
+ node = openset[child + ""];
+ else if ( inclosed )
+ node = closed[child + ""];
else
node = spawnStruct();
-
+
node.parent = bestNode;
node.g = newg;
- node.h = DistanceSquared(childorg, goalorg);
+ node.h = DistanceSquared( childWp.origin, level.waypoints[goalWp].origin );
node.f = node.g + node.h;
node.index = child;
-
+
//check if in closed, remove it
- if(inclosed)
- closed[child] = undefined;
-
+ if ( inclosed )
+ closed[child + ""] = undefined;
+
//check if not in open, add it
- if(!inopen)
+ if ( !inopen )
{
- open HeapInsert(node);
- openset[child] = node;
+ open HeapInsert( node );
+ openset[child + ""] = node;
}
}
-
+
//done with children, push onto closed
- closed[bestNode.index] = bestNode;
+ closed[bestNode.index + ""] = bestNode;
}
-
+
return [];
}
/*
Returns the natural log of x using harmonic series.
*/
-Log(x)
+Log( x )
{
- /*if (!isDefined(level.log_cache))
+ /* if (!isDefined(level.log_cache))
level.log_cache = [];
-
- key = x + "";
-
- if (isDefined(level.log_cache[key]))
+
+ key = x + "";
+
+ if (isDefined(level.log_cache[key]))
return level.log_cache[key];*/
//thanks Bob__ at stackoverflow
old_sum = 0.0;
- xmlxpl = (x - 1) / (x + 1);
+ xmlxpl = ( x - 1 ) / ( x + 1 );
xmlxpl_2 = xmlxpl * xmlxpl;
denom = 1.0;
frac = xmlxpl;
@@ -1989,9 +2486,9 @@ Log(x)
frac *= xmlxpl_2;
sum += frac / denom;
}
-
+
answer = 2.0 * sum;
-
+
//level.log_cache[key] = answer;
return answer;
}
@@ -2001,24 +2498,29 @@ Log(x)
*/
array_combine( array1, array2 )
{
- if( !array1.size )
+ if ( !array1.size )
{
- return array2;
+ return array2;
}
+
array3 = [];
keys = GetArrayKeys( array1 );
- for( i = 0;i < keys.size;i++ )
+
+ for ( i = 0; i < keys.size; i++ )
{
key = keys[ i ];
- array3[ array3.size ] = array1[ key ];
- }
+ array3[ array3.size ] = array1[ key ];
+ }
+
keys = GetArrayKeys( array2 );
- for( i = 0;i < keys.size;i++ )
+
+ for ( i = 0; i < keys.size; i++ )
{
key = keys[ i ];
array3[ array3.size ] = array2[ key ];
}
- return array3;
+
+ return array3;
}
/*
@@ -2030,10 +2532,12 @@ array_average( array )
assert( IsArray( array ) );
assert( array.size > 0 );
total = 0;
+
for ( i = 0; i < array.size; i++ )
{
total += array[i];
}
+
return ( total / array.size );
}
@@ -2046,15 +2550,19 @@ array_std_deviation( array, mean )
assert( IsArray( array ) );
assert( array.size > 0 );
tmp = [];
+
for ( i = 0; i < array.size; i++ )
{
tmp[i] = ( array[i] - mean ) * ( array[i] - mean );
}
+
total = 0;
+
for ( i = 0; i < tmp.size; i++ )
{
total = total + tmp[i];
}
+
return Sqrt( total / array.size );
}
@@ -2068,25 +2576,29 @@ random_normal_distribution( mean, std_deviation, lower_bound, upper_bound )
x2 = 0;
w = 1;
y1 = 0;
+
while ( w >= 1 )
{
x1 = 2 * RandomFloatRange( 0, 1 ) - 1;
x2 = 2 * RandomFloatRange( 0, 1 ) - 1;
w = x1 * x1 + x2 * x2;
}
+
w = Sqrt( ( -2.0 * Log( w ) ) / w );
y1 = x1 * w;
number = mean + y1 * std_deviation;
+
if ( IsDefined( lower_bound ) && number < lower_bound )
{
number = lower_bound;
}
+
if ( IsDefined( upper_bound ) && number > upper_bound )
{
number = upper_bound;
}
-
- return( number );
+
+ return ( number );
}
/*
@@ -2099,20 +2611,22 @@ onUsePlantObjectFix( player )
{
level thread bombPlantedFix( self, player );
player logString( "bomb planted: " + self.label );
-
+
// disable all bomb zones except this one
for ( index = 0; index < level.bombZones.size; index++ )
{
if ( level.bombZones[index] == self )
continue;
-
+
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
}
-
+
player playSound( "mp_bomb_plant" );
player notify ( "bomb_planted" );
+
if ( !level.hardcoreMode )
iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
+
maps\mp\gametypes\_globallogic::leaderDialog( "bomb_planted" );
maps\mp\gametypes\_globallogic::givePlayerScore( "plant", player );
@@ -2127,14 +2641,14 @@ bombPlantedFix( destroyedObj, player )
{
maps\mp\gametypes\_globallogic::pauseTimer();
level.bombPlanted = true;
-
+
destroyedObj.visuals[0] thread maps\mp\gametypes\_globallogic::playTickingSound();
level.tickingObject = destroyedObj.visuals[0];
level.timeLimitOverride = true;
- setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) );
+ setGameEndTime( int( gettime() + ( level.bombTimer * 1000 ) ) );
setDvar( "ui_bomb_timer", 1 );
-
+
if ( !level.multiBomb )
{
level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
@@ -2144,39 +2658,40 @@ bombPlantedFix( destroyedObj, player )
}
else
{
-
+
for ( index = 0; index < level.players.size; index++ )
{
if ( isDefined( level.players[index].carryIcon ) )
level.players[index].carryIcon destroyElem();
}
- trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
-
+ trace = bulletTrace( player.origin + ( 0, 0, 20 ), player.origin - ( 0, 0, 2000 ), false, player );
+
tempAngle = randomfloat( 360 );
- forward = (cos( tempAngle ), sin( tempAngle ), 0);
+ forward = ( cos( tempAngle ), sin( tempAngle ), 0 );
forward = vectornormalize( forward - vector_scale( trace["normal"], vectordot( forward, trace["normal"] ) ) );
dropAngles = vectortoangles( forward );
-
+
level.sdBombModel = spawn( "script_model", trace["position"] );
level.sdBombModel.angles = dropAngles;
level.sdBombModel setModel( "prop_suitcase_bomb" );
}
+
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
/*
- destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
- destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
- destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
- destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
+ destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
+ destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
+ destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
+ destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
*/
label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel();
-
+
// create a new object to defuse with.
trigger = destroyedObj.bombDefuseTrig;
trigger.origin = level.sdBombModel.origin;
visuals = [];
- defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) );
+ defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, ( 0, 0, 32 ) );
defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
@@ -2191,43 +2706,44 @@ bombPlantedFix( destroyedObj, player )
defuseObject.onEndUse = maps\mp\gametypes\sd::onEndUse;
defuseObject.onUse = maps\mp\gametypes\sd::onUseDefuseObject;
defuseObject.useWeapon = "briefcase_bomb_defuse_mp";
-
+
level.defuseObject = defuseObject;
-
+
maps\mp\gametypes\sd::BombTimerWait();
setDvar( "ui_bomb_timer", 0 );
-
+
destroyedObj.visuals[0] maps\mp\gametypes\_globallogic::stopTickingSound();
-
+
if ( level.gameEnded || level.bombDefused )
return;
-
+
level.bombExploded = true;
-
+
explosionOrigin = level.sdBombModel.origin;
level.sdBombModel hide();
-
+
if ( isdefined( player ) )
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
else
destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
-
- rot = randomfloat(360);
- explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
+
+ rot = randomfloat( 360 );
+ explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + ( 0, 0, 50 ), ( 0, 0, 1 ), ( cos( rot ), sin( rot ), 0 ) );
triggerFx( explosionEffect );
-
+
thread maps\mp\gametypes\sd::playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
-
+
if ( isDefined( destroyedObj.exploderIndex ) )
exploder( destroyedObj.exploderIndex );
-
+
for ( index = 0; index < level.bombZones.size; index++ )
level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
+
defuseObject maps\mp\gametypes\_gameobjects::disableObject();
-
+
setGameEndTime( 0 );
-
+
wait 3;
-
+
maps\mp\gametypes\sd::sd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
}
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_menu.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_menu.gsc
index b92f8f9..770b9e1 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_menu.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_menu.gsc
@@ -12,10 +12,10 @@
init()
{
- if (getDvar("bots_main_menu") == "")
- setDvar("bots_main_menu", true);
+ if ( getDvar( "bots_main_menu" ) == "" )
+ setDvar( "bots_main_menu", true );
- if (!getDvarInt("bots_main_menu"))
+ if ( !getDvarInt( "bots_main_menu" ) )
return;
thread watchPlayers();
@@ -23,21 +23,21 @@ init()
watchPlayers()
{
- for (;;)
+ for ( ;; )
{
wait 1;
- if (!getDvarInt("bots_main_menu"))
+ if ( !getDvarInt( "bots_main_menu" ) )
return;
- for (i = level.players.size - 1; i >= 0; i--)
+ for ( i = level.players.size - 1; i >= 0; i-- )
{
player = level.players[i];
- if (!player is_host())
+ if ( !player is_host() )
continue;
- if (isDefined(player.menuInit) && player.menuInit)
+ if ( isDefined( player.menuInit ) && player.menuInit )
continue;
player thread init_menu();
@@ -48,55 +48,55 @@ watchPlayers()
init_menu()
{
self.menuInit = true;
-
+
self.menuOpen = false;
self.menu_player = undefined;
self.SubMenu = "Main";
self.Curs["Main"]["X"] = 0;
self AddOptions();
-
+
self thread watchPlayerOpenMenu();
self thread MenuSelect();
self thread RightMenu();
self thread LeftMenu();
-
+
self thread watchDisconnect();
-
+
self thread doGreetings();
}
kill_menu()
{
- self notify("bots_kill_menu");
+ self notify( "bots_kill_menu" );
self.menuInit = undefined;
}
watchDisconnect()
{
- self waittill_either("disconnect", "bots_kill_menu");
-
- if(self.menuOpen)
+ self waittill_either( "disconnect", "bots_kill_menu" );
+
+ if ( self.menuOpen )
{
- if(isDefined(self.MenuTextY))
- for(i = 0; i < self.MenuTextY.size; i++)
- if(isDefined(self.MenuTextY[i]))
+ if ( isDefined( self.MenuTextY ) )
+ for ( i = 0; i < self.MenuTextY.size; i++ )
+ if ( isDefined( self.MenuTextY[i] ) )
self.MenuTextY[i] destroy();
-
- if(isDefined(self.MenuText))
- for(i = 0; i < self.MenuText.size; i++)
- if(isDefined(self.MenuText[i]))
+
+ if ( isDefined( self.MenuText ) )
+ for ( i = 0; i < self.MenuText.size; i++ )
+ if ( isDefined( self.MenuText[i] ) )
self.MenuText[i] destroy();
-
- if(isDefined(self.Menu) && isDefined(self.Menu["X"]))
+
+ if ( isDefined( self.Menu ) && isDefined( self.Menu["X"] ) )
{
- if(isDefined(self.Menu["X"]["Shader"]))
+ if ( isDefined( self.Menu["X"]["Shader"] ) )
self.Menu["X"]["Shader"] destroy();
-
- if(isDefined(self.Menu["X"]["Scroller"]))
+
+ if ( isDefined( self.Menu["X"]["Scroller"] ) )
self.Menu["X"]["Scroller"] destroy();
}
- if (isDefined(self.menuVersionHud))
+ if ( isDefined( self.menuVersionHud ) )
self.menuVersionHud destroy();
}
}
@@ -106,42 +106,44 @@ doGreetings()
self endon ( "disconnect" );
self endon ( "bots_kill_menu" );
wait 1;
- self iPrintln("Welcome to Bot Warfare "+self.name+"!");
+ self iPrintln( "Welcome to Bot Warfare " + self.name + "!" );
wait 5;
- self iPrintln("Press [{+frag}] + [{+smoke}] to open menu!");
+ self iPrintln( "Press [{+frag}] + [{+smoke}] to open menu!" );
}
watchPlayerOpenMenu()
{
self endon ( "disconnect" );
self endon ( "bots_kill_menu" );
-
- for(;;)
+
+ for ( ;; )
{
- while(!self FragButtonPressed() || !self SecondaryOffhandButtonPressed())
+ while ( !self FragButtonPressed() || !self SecondaryOffhandButtonPressed() )
wait 0.05;
-
- if(!self.menuOpen)
+
+ if ( !self.menuOpen )
{
self playLocalSound( "mouse_click" );
- self thread OpenSub(self.SubMenu);
+ self thread OpenSub( self.SubMenu );
}
else
{
self playLocalSound( "mouse_click" );
- if(self.SubMenu != "Main")
+
+ if ( self.SubMenu != "Main" )
self ExitSub();
else
{
self ExitMenu();
- if(level.inPrematchPeriod || level.gameEnded)
- self freezeControls(true);
+
+ if ( level.inPrematchPeriod || level.gameEnded )
+ self freezeControls( true );
else
- self freezecontrols(false);
+ self freezecontrols( false );
}
}
-
- while(self FragButtonPressed() && self SecondaryOffhandButtonPressed())
+
+ while ( self FragButtonPressed() && self SecondaryOffhandButtonPressed() )
wait 0.05;
}
}
@@ -150,22 +152,23 @@ MenuSelect()
{
self endon ( "disconnect" );
self endon ( "bots_kill_menu" );
-
- for(;;)
+
+ for ( ;; )
{
- while(!self MeleeButtonPressed())
+ while ( !self MeleeButtonPressed() )
wait 0.05;
-
- if(self.MenuOpen)
+
+ if ( self.MenuOpen )
{
self playLocalSound( "mouse_click" );
- if(self.SubMenu == "Main")
- self thread [[self.Option["Function"][self.SubMenu][self.Curs["Main"]["X"]]]](self.Option["Arg1"][self.SubMenu][self.Curs["Main"]["X"]],self.Option["Arg2"][self.SubMenu][self.Curs["Main"]["X"]]);
+
+ if ( self.SubMenu == "Main" )
+ self thread [[self.Option["Function"][self.SubMenu][self.Curs["Main"]["X"]]]]( self.Option["Arg1"][self.SubMenu][self.Curs["Main"]["X"]], self.Option["Arg2"][self.SubMenu][self.Curs["Main"]["X"]] );
else
- self thread [[self.Option["Function"][self.SubMenu][self.Curs[self.SubMenu]["Y"]]]](self.Option["Arg1"][self.SubMenu][self.Curs[self.SubMenu]["Y"]],self.Option["Arg2"][self.SubMenu][self.Curs[self.SubMenu]["Y"]]);
+ self thread [[self.Option["Function"][self.SubMenu][self.Curs[self.SubMenu]["Y"]]]]( self.Option["Arg1"][self.SubMenu][self.Curs[self.SubMenu]["Y"]], self.Option["Arg2"][self.SubMenu][self.Curs[self.SubMenu]["Y"]] );
}
-
- while(self MeleeButtonPressed())
+
+ while ( self MeleeButtonPressed() )
wait 0.05;
}
}
@@ -175,36 +178,36 @@ LeftMenu()
self endon ( "disconnect" );
self endon ( "bots_kill_menu" );
- for(;;)
+ for ( ;; )
{
- while(!self AttackButtonPressed())
+ while ( !self AttackButtonPressed() )
wait 0.05;
-
- if(self.MenuOpen)
+
+ if ( self.MenuOpen )
{
- self playLocalSound("mouse_over");
-
- if(self.SubMenu == "Main")
+ self playLocalSound( "mouse_over" );
+
+ if ( self.SubMenu == "Main" )
{
self.Curs["Main"]["X"]--;
- if(self.Curs["Main"]["X"] < 0)
- self.Curs["Main"]["X"] = self.Option["Name"][self.SubMenu].size -1;
+ if ( self.Curs["Main"]["X"] < 0 )
+ self.Curs["Main"]["X"] = self.Option["Name"][self.SubMenu].size - 1;
- self CursMove("X");
+ self CursMove( "X" );
}
else
{
self.Curs[self.SubMenu]["Y"]--;
- if(self.Curs[self.SubMenu]["Y"] < 0)
- self.Curs[self.SubMenu]["Y"] = self.Option["Name"][self.SubMenu].size -1;
+ if ( self.Curs[self.SubMenu]["Y"] < 0 )
+ self.Curs[self.SubMenu]["Y"] = self.Option["Name"][self.SubMenu].size - 1;
- self CursMove("Y");
+ self CursMove( "Y" );
}
}
-
- while(self AttackButtonPressed())
+
+ while ( self AttackButtonPressed() )
wait 0.05;
}
}
@@ -214,242 +217,249 @@ RightMenu()
self endon ( "disconnect" );
self endon ( "bots_kill_menu" );
- for(;;)
+ for ( ;; )
{
- while(!self AdsButtonPressed())
+ while ( !self AdsButtonPressed() )
wait 0.05;
-
- if(self.MenuOpen)
+
+ if ( self.MenuOpen )
{
- self playLocalSound("mouse_over");
-
- if(self.SubMenu == "Main")
+ self playLocalSound( "mouse_over" );
+
+ if ( self.SubMenu == "Main" )
{
self.Curs["Main"]["X"]++;
- if(self.Curs["Main"]["X"] > self.Option["Name"][self.SubMenu].size -1)
+ if ( self.Curs["Main"]["X"] > self.Option["Name"][self.SubMenu].size - 1 )
self.Curs["Main"]["X"] = 0;
- self CursMove("X");
+ self CursMove( "X" );
}
else
{
self.Curs[self.SubMenu]["Y"]++;
- if(self.Curs[self.SubMenu]["Y"] > self.Option["Name"][self.SubMenu].size -1)
+ if ( self.Curs[self.SubMenu]["Y"] > self.Option["Name"][self.SubMenu].size - 1 )
self.Curs[self.SubMenu]["Y"] = 0;
- self CursMove("Y");
+ self CursMove( "Y" );
}
}
-
- while(self AdsButtonPressed())
+
+ while ( self AdsButtonPressed() )
wait 0.05;
}
}
-OpenSub(menu, menu2)
+OpenSub( menu, menu2 )
{
- if(menu != "Main" && (!isDefined(self.Menu[menu]) || !!isDefined(self.Menu[menu]["FirstOpen"])))
+ if ( menu != "Main" && ( !isDefined( self.Menu[menu] ) || !!isDefined( self.Menu[menu]["FirstOpen"] ) ) )
{
self.Curs[menu]["Y"] = 0;
self.Menu[menu]["FirstOpen"] = true;
}
-
+
logoldi = true;
self.SubMenu = menu;
-
- if(self.SubMenu == "Main")
+
+ if ( self.SubMenu == "Main" )
{
- if(isDefined(self.MenuText))
- for(i = 0; i < self.MenuText.size; i++)
- if(isDefined(self.MenuText[i]))
+ if ( isDefined( self.MenuText ) )
+ for ( i = 0; i < self.MenuText.size; i++ )
+ if ( isDefined( self.MenuText[i] ) )
self.MenuText[i] destroy();
-
- if(isDefined(self.Menu) && isDefined(self.Menu["X"]))
+
+ if ( isDefined( self.Menu ) && isDefined( self.Menu["X"] ) )
{
- if(isDefined(self.Menu["X"]["Shader"]))
+ if ( isDefined( self.Menu["X"]["Shader"] ) )
self.Menu["X"]["Shader"] destroy();
-
- if(isDefined(self.Menu["X"]["Scroller"]))
+
+ if ( isDefined( self.Menu["X"]["Scroller"] ) )
self.Menu["X"]["Scroller"] destroy();
}
- if (isDefined(self.menuVersionHud))
+ if ( isDefined( self.menuVersionHud ) )
self.menuVersionHud destroy();
-
- for(i=0 ; i < self.Option["Name"][self.SubMenu].size ; i++)
+
+ for ( i = 0 ; i < self.Option["Name"][self.SubMenu].size ; i++ )
{
- self.MenuText[i] = self createfontstring("default", 1.6);
- self.MenuText[i] setpoint("CENTER", "CENTER", -300+(i*100), -226);
- self.MenuText[i] settext(self.Option["Name"][self.SubMenu][i]);
- if(logOldi)
+ self.MenuText[i] = self createfontstring( "default", 1.6 );
+ self.MenuText[i] setpoint( "CENTER", "CENTER", -300 + ( i * 100 ), -226 );
+ self.MenuText[i] settext( self.Option["Name"][self.SubMenu][i] );
+
+ if ( logOldi )
self.oldi = i;
-
- if(self.MenuText[i].x > 300)
+
+ if ( self.MenuText[i].x > 300 )
{
logOldi = false;
x = i - self.oldi;
- self.MenuText[i] setpoint("CENTER", "CENTER", (((-300)-(i*100))+(i*100))+(x*100), -196);
+ self.MenuText[i] setpoint( "CENTER", "CENTER", ( ( ( -300 ) - ( i * 100 ) ) + ( i * 100 ) ) + ( x * 100 ), -196 );
}
+
self.MenuText[i].alpha = 1;
self.MenuText[i].sort = 999;
}
- if(!logOldi)
- self.Menu["X"]["Shader"] = self createRectangle("CENTER","CENTER",0,-225,1000,90, (0,0,0), -2, 1,"white");
+ if ( !logOldi )
+ self.Menu["X"]["Shader"] = self createRectangle( "CENTER", "CENTER", 0, -225, 1000, 90, ( 0, 0, 0 ), -2, 1, "white" );
else
- self.Menu["X"]["Shader"] = self createRectangle("CENTER","CENTER",0,-225,1000,30, (0,0,0), -2, 1,"white");
+ self.Menu["X"]["Shader"] = self createRectangle( "CENTER", "CENTER", 0, -225, 1000, 30, ( 0, 0, 0 ), -2, 1, "white" );
- self.Menu["X"]["Scroller"] = self createRectangle("CENTER","CENTER", self.MenuText[self.Curs["Main"]["X"]].x,-225,105,22, (1,0,0), -1, 1,"white");
-
- self CursMove("X");
+ self.Menu["X"]["Scroller"] = self createRectangle( "CENTER", "CENTER", self.MenuText[self.Curs["Main"]["X"]].x, -225, 105, 22, ( 1, 0, 0 ), -1, 1, "white" );
+
+ self CursMove( "X" );
+
+ self.menuVersionHud = initHudElem( "Bot Warfare " + level.bw_VERSION, 0, 0 );
- self.menuVersionHud = initHudElem("Bot Warfare " + level.bw_VERSION, 0, 0);
-
self.MenuOpen = true;
}
else
{
- if(isDefined(self.MenuTextY))
- for(i=0 ; i < self.MenuTextY.size ; i++)
- if(isDefined(self.MenuTextY[i]))
+ if ( isDefined( self.MenuTextY ) )
+ for ( i = 0 ; i < self.MenuTextY.size ; i++ )
+ if ( isDefined( self.MenuTextY[i] ) )
self.MenuTextY[i] destroy();
-
- for(i=0 ; i < self.Option["Name"][self.SubMenu].size ; i++)
+
+ for ( i = 0 ; i < self.Option["Name"][self.SubMenu].size ; i++ )
{
- self.MenuTextY[i] = self createfontstring("default", 1.6);
- self.MenuTextY[i] setpoint("CENTER", "CENTER", self.MenuText[self.Curs["Main"]["X"]].x, -160+(i*20));
- self.MenuTextY[i] settext(self.Option["Name"][self.SubMenu][i]);
+ self.MenuTextY[i] = self createfontstring( "default", 1.6 );
+ self.MenuTextY[i] setpoint( "CENTER", "CENTER", self.MenuText[self.Curs["Main"]["X"]].x, -160 + ( i * 20 ) );
+ self.MenuTextY[i] settext( self.Option["Name"][self.SubMenu][i] );
self.MenuTextY[i].alpha = 1;
self.MenuTextY[i].sort = 999;
}
-
- self CursMove("Y");
+
+ self CursMove( "Y" );
}
}
-CursMove(direction)
+CursMove( direction )
{
- self notify("scrolled");
- if(self.SubMenu == "Main")
+ self notify( "scrolled" );
+
+ if ( self.SubMenu == "Main" )
{
self.Menu["X"]["Scroller"].x = self.MenuText[self.Curs["Main"]["X"]].x;
self.Menu["X"]["Scroller"].y = self.MenuText[self.Curs["Main"]["X"]].y;
-
- if(isDefined(self.MenuText))
+
+ if ( isDefined( self.MenuText ) )
{
- for(i = 0; i < self.MenuText.size; i++)
+ for ( i = 0; i < self.MenuText.size; i++ )
{
- if(isDefined(self.MenuText[i]))
+ if ( isDefined( self.MenuText[i] ) )
{
self.MenuText[i].fontscale = 1.5;
- self.MenuText[i].color = (1,1,1);
+ self.MenuText[i].color = ( 1, 1, 1 );
self.MenuText[i].glowAlpha = 0;
}
}
}
-
- self thread ShowOptionOn(direction);
+
+ self thread ShowOptionOn( direction );
}
else
{
- if(isDefined(self.MenuTextY))
+ if ( isDefined( self.MenuTextY ) )
{
- for(i = 0; i < self.MenuTextY.size; i++)
+ for ( i = 0; i < self.MenuTextY.size; i++ )
{
- if(isDefined(self.MenuTextY[i]))
+ if ( isDefined( self.MenuTextY[i] ) )
{
self.MenuTextY[i].fontscale = 1.5;
- self.MenuTextY[i].color = (1,1,1);
+ self.MenuTextY[i].color = ( 1, 1, 1 );
self.MenuTextY[i].glowAlpha = 0;
}
}
}
-
- if(isDefined(self.MenuText))
+
+ if ( isDefined( self.MenuText ) )
{
- for(i = 0; i < self.MenuText.size; i++)
+ for ( i = 0; i < self.MenuText.size; i++ )
{
- if(isDefined(self.MenuText[i]))
+ if ( isDefined( self.MenuText[i] ) )
{
self.MenuText[i].fontscale = 1.5;
- self.MenuText[i].color = (1,1,1);
+ self.MenuText[i].color = ( 1, 1, 1 );
self.MenuText[i].glowAlpha = 0;
}
}
}
-
- self thread ShowOptionOn(direction);
+
+ self thread ShowOptionOn( direction );
}
}
-ShowOptionOn(variable)
+ShowOptionOn( variable )
{
- self endon("scrolled");
- self endon("disconnect");
- self endon("exit");
- self endon("bots_kill_menu");
-
- for(time=0;;time+=0.05)
+ self endon( "scrolled" );
+ self endon( "disconnect" );
+ self endon( "exit" );
+ self endon( "bots_kill_menu" );
+
+ for ( time = 0;; time += 0.05 )
{
- if(!self isOnGround() && isAlive(self) && !level.inPrematchPeriod && !level.gameEnded)
- self freezecontrols(false);
+ if ( !self isOnGround() && isAlive( self ) && !level.inPrematchPeriod && !level.gameEnded )
+ self freezecontrols( false );
else
- self freezecontrols(true);
-
- self setClientDvar( "r_blur", "5" );
+ self freezecontrols( true );
+
+ self setClientDvar( "r_blur", "5" );
self setClientDvar( "sc_blur", "4" );
self addOptions();
-
- if(self.SubMenu == "Main")
+
+ if ( self.SubMenu == "Main" )
{
- if(isDefined(self.Curs[self.SubMenu][variable]) && isDefined(self.MenuText) && isDefined(self.MenuText[self.Curs[self.SubMenu][variable]]))
+ if ( isDefined( self.Curs[self.SubMenu][variable] ) && isDefined( self.MenuText ) && isDefined( self.MenuText[self.Curs[self.SubMenu][variable]] ) )
{
self.MenuText[self.Curs[self.SubMenu][variable]].fontscale = 2.0;
//self.MenuText[self.Curs[self.SubMenu][variable]].color = (randomInt(256)/255, randomInt(256)/255, randomInt(256)/255);
- color = (6/255,69/255,173+randomIntRange(-5,5)/255);
- if (int(time * 4) % 2)
- color = (11/255,0/255,128+randomIntRange(-10,10)/255);
+ color = ( 6 / 255, 69 / 255, 173 + randomIntRange( -5, 5 ) / 255 );
+
+ if ( int( time * 4 ) % 2 )
+ color = ( 11 / 255, 0 / 255, 128 + randomIntRange( -10, 10 ) / 255 );
+
self.MenuText[self.Curs[self.SubMenu][variable]].color = color;
}
-
- if(isDefined(self.MenuText))
+
+ if ( isDefined( self.MenuText ) )
{
- for(i = 0; i < self.Option["Name"][self.SubMenu].size; i++)
+ for ( i = 0; i < self.Option["Name"][self.SubMenu].size; i++ )
{
- if(isDefined(self.MenuText[i]))
- self.MenuText[i] settext(self.Option["Name"][self.SubMenu][i]);
+ if ( isDefined( self.MenuText[i] ) )
+ self.MenuText[i] settext( self.Option["Name"][self.SubMenu][i] );
}
}
}
else
{
- if(isDefined(self.Curs[self.SubMenu][variable]) && isDefined(self.MenuTextY) && isDefined(self.MenuTextY[self.Curs[self.SubMenu][variable]]))
+ if ( isDefined( self.Curs[self.SubMenu][variable] ) && isDefined( self.MenuTextY ) && isDefined( self.MenuTextY[self.Curs[self.SubMenu][variable]] ) )
{
self.MenuTextY[self.Curs[self.SubMenu][variable]].fontscale = 2.0;
//self.MenuTextY[self.Curs[self.SubMenu][variable]].color = (randomInt(256)/255, randomInt(256)/255, randomInt(256)/255);
- color = (6/255,69/255,173+randomIntRange(-5,5)/255);
- if (int(time * 4) % 2)
- color = (11/255,0/255,128+randomIntRange(-10,10)/255);
+ color = ( 6 / 255, 69 / 255, 173 + randomIntRange( -5, 5 ) / 255 );
+
+ if ( int( time * 4 ) % 2 )
+ color = ( 11 / 255, 0 / 255, 128 + randomIntRange( -10, 10 ) / 255 );
+
self.MenuTextY[self.Curs[self.SubMenu][variable]].color = color;
}
-
- if(isDefined(self.MenuTextY))
+
+ if ( isDefined( self.MenuTextY ) )
{
- for(i = 0; i < self.Option["Name"][self.SubMenu].size; i++)
+ for ( i = 0; i < self.Option["Name"][self.SubMenu].size; i++ )
{
- if(isDefined(self.MenuTextY[i]))
- self.MenuTextY[i] settext(self.Option["Name"][self.SubMenu][i]);
+ if ( isDefined( self.MenuTextY[i] ) )
+ self.MenuTextY[i] settext( self.Option["Name"][self.SubMenu][i] );
}
}
}
-
+
wait 0.05;
}
}
-AddMenu(menu, num, text, function, arg1, arg2)
+AddMenu( menu, num, text, function, arg1, arg2 )
{
self.Option["Name"][menu][num] = text;
self.Option["Function"][menu][num] = function;
@@ -457,56 +467,56 @@ AddMenu(menu, num, text, function, arg1, arg2)
self.Option["Arg2"][menu][num] = arg2;
}
-AddBack(menu, back)
+AddBack( menu, back )
{
self.Menu["Back"][menu] = back;
}
ExitSub()
{
- if(isDefined(self.MenuTextY))
- for(i = 0; i < self.MenuTextY.size; i++)
- if(isDefined(self.MenuTextY[i]))
+ if ( isDefined( self.MenuTextY ) )
+ for ( i = 0; i < self.MenuTextY.size; i++ )
+ if ( isDefined( self.MenuTextY[i] ) )
self.MenuTextY[i] destroy();
-
+
self.SubMenu = self.Menu["Back"][self.Submenu];
-
- if(self.SubMenu == "Main")
- self CursMove("X");
+
+ if ( self.SubMenu == "Main" )
+ self CursMove( "X" );
else
- self CursMove("Y");
+ self CursMove( "Y" );
}
ExitMenu()
{
- if(isDefined(self.MenuText))
- for(i = 0; i < self.MenuText.size; i++)
- if(isDefined(self.MenuText[i]))
+ if ( isDefined( self.MenuText ) )
+ for ( i = 0; i < self.MenuText.size; i++ )
+ if ( isDefined( self.MenuText[i] ) )
self.MenuText[i] destroy();
-
- if(isDefined(self.Menu) && isDefined(self.Menu["X"]))
+
+ if ( isDefined( self.Menu ) && isDefined( self.Menu["X"] ) )
{
- if(isDefined(self.Menu["X"]["Shader"]))
+ if ( isDefined( self.Menu["X"]["Shader"] ) )
self.Menu["X"]["Shader"] destroy();
-
- if(isDefined(self.Menu["X"]["Scroller"]))
+
+ if ( isDefined( self.Menu["X"]["Scroller"] ) )
self.Menu["X"]["Scroller"] destroy();
}
- if (isDefined(self.menuVersionHud))
+ if ( isDefined( self.menuVersionHud ) )
self.menuVersionHud destroy();
-
+
self.MenuOpen = false;
- self notify("exit");
-
+ self notify( "exit" );
+
self setClientDvar( "r_blur", "0" );
self setClientDvar( "sc_blur", "2" );
}
-initHudElem(txt, xl, yl)
+initHudElem( txt, xl, yl )
{
hud = NewClientHudElem( self );
- hud setText(txt);
+ hud setText( txt );
hud.alignX = "center";
hud.alignY = "bottom";
hud.horzAlign = "center";
@@ -521,11 +531,11 @@ initHudElem(txt, xl, yl)
hud.glowColor = ( 0, 0, 0 );
hud.glowAlpha = 1;
hud.color = ( 1.0, 1.0, 1.0 );
-
+
return hud;
}
-createRectangle(align,relative,x,y,width,height,color,sort,alpha,shader)
+createRectangle( align, relative, x, y, width, height, color, sort, alpha, shader )
{
barElemBG = newClientHudElem( self );
barElemBG.elemType = "bar_";
@@ -540,479 +550,582 @@ createRectangle(align,relative,x,y,width,height,color,sort,alpha,shader)
barElemBG.color = color;
barElemBG.alpha = alpha;
barElemBG setParent( level.uiParent );
- barElemBG setShader( shader, width , height );
+ barElemBG setShader( shader, width, height );
barElemBG.hidden = false;
- barElemBG setPoint(align, relative, x, y);
+ barElemBG setPoint( align, relative, x, y );
return barElemBG;
}
AddOptions()
{
- self AddMenu("Main", 0, "Manage bots", ::OpenSub, "man_bots", "");
- self AddBack("man_bots", "Main");
-
+ self AddMenu( "Main", 0, "Manage bots", ::OpenSub, "man_bots", "" );
+ self AddBack( "man_bots", "Main" );
+
_temp = "";
- _tempDvar = getDvarInt("bots_manage_add");
- self AddMenu("man_bots", 0, "Add 1 bot", ::man_bots, "add", 1 + _tempDvar);
- self AddMenu("man_bots", 1, "Add 3 bot", ::man_bots, "add", 3 + _tempDvar);
- self AddMenu("man_bots", 2, "Add 7 bot", ::man_bots, "add", 7 + _tempDvar);
- self AddMenu("man_bots", 3, "Add 11 bot", ::man_bots, "add", 11 + _tempDvar);
- self AddMenu("man_bots", 4, "Add 17 bot", ::man_bots, "add", 17 + _tempDvar);
- self AddMenu("man_bots", 5, "Kick a bot", ::man_bots, "kick", 1);
- self AddMenu("man_bots", 6, "Kick all bots", ::man_bots, "kick", getBotArray().size);
-
- _tempDvar = getDvarInt("bots_manage_fill_kick");
- if(_tempDvar)
+ _tempDvar = getDvarInt( "bots_manage_add" );
+ self AddMenu( "man_bots", 0, "Add 1 bot", ::man_bots, "add", 1 + _tempDvar );
+ self AddMenu( "man_bots", 1, "Add 3 bot", ::man_bots, "add", 3 + _tempDvar );
+ self AddMenu( "man_bots", 2, "Add 7 bot", ::man_bots, "add", 7 + _tempDvar );
+ self AddMenu( "man_bots", 3, "Add 11 bot", ::man_bots, "add", 11 + _tempDvar );
+ self AddMenu( "man_bots", 4, "Add 17 bot", ::man_bots, "add", 17 + _tempDvar );
+ self AddMenu( "man_bots", 5, "Kick a bot", ::man_bots, "kick", 1 );
+ self AddMenu( "man_bots", 6, "Kick all bots", ::man_bots, "kick", getBotArray().size );
+
+ _tempDvar = getDvarInt( "bots_manage_fill_kick" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("man_bots", 7, "Toggle auto bot kicking: " + _temp, ::man_bots, "autokick", _tempDvar);
-
- _tempDvar = getDvarInt("bots_manage_fill_mode");
- switch(_tempDvar)
+
+ self AddMenu( "man_bots", 7, "Toggle auto bot kicking: " + _temp, ::man_bots, "autokick", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_manage_fill_mode" );
+
+ switch ( _tempDvar )
{
case 0:
_temp = "everyone";
- break;
+ break;
+
case 1:
_temp = "just bots";
- break;
+ break;
+
case 2:
_temp = "everyone, adjust to map";
- break;
+ break;
+
case 3:
_temp = "just bots, adjust to map";
- break;
+ break;
+
case 4:
_temp = "bots used as team balance";
- break;
+ break;
+
default:
_temp = "out of range";
- break;
+ break;
}
- self AddMenu("man_bots", 8, "Change bot_fill_mode: " + _temp, ::man_bots, "fillmode", _tempDvar);
-
- _tempDvar = getDvarInt("bots_manage_fill");
- self AddMenu("man_bots", 9, "Increase bots to keep in-game: " + _tempDvar, ::man_bots, "fillup", _tempDvar);
- self AddMenu("man_bots", 10, "Decrease bots to keep in-game: " + _tempDvar, ::man_bots, "filldown", _tempDvar);
-
- _tempDvar = getDvarInt("bots_manage_fill_spec");
- if(_tempDvar)
+
+ self AddMenu( "man_bots", 8, "Change bot_fill_mode: " + _temp, ::man_bots, "fillmode", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_manage_fill" );
+ self AddMenu( "man_bots", 9, "Increase bots to keep in-game: " + _tempDvar, ::man_bots, "fillup", _tempDvar );
+ self AddMenu( "man_bots", 10, "Decrease bots to keep in-game: " + _tempDvar, ::man_bots, "filldown", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_manage_fill_spec" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("man_bots", 11, "Count players for fill on spectator: " + _temp, ::man_bots, "fillspec", _tempDvar);
+
+ self AddMenu( "man_bots", 11, "Count players for fill on spectator: " + _temp, ::man_bots, "fillspec", _tempDvar );
//
- self AddMenu("Main", 1, "Teams and difficulty", ::OpenSub, "man_team", "");
- self AddBack("man_team", "Main");
-
- _tempDvar = getdvar("bots_team");
- self AddMenu("man_team", 0, "Change bot team: "+_tempDvar, ::bot_teams, "team", _tempDvar);
-
- _tempDvar = getDvarInt("bots_team_amount");
- self AddMenu("man_team", 1, "Increase bots to be on axis team: "+_tempDvar, ::bot_teams, "teamup", _tempDvar);
- self AddMenu("man_team", 2, "Decrease bots to be on axis team: "+_tempDvar, ::bot_teams, "teamdown", _tempDvar);
-
- _tempDvar = getDvarInt("bots_team_force");
- if(_tempDvar)
+ self AddMenu( "Main", 1, "Teams and difficulty", ::OpenSub, "man_team", "" );
+ self AddBack( "man_team", "Main" );
+
+ _tempDvar = getdvar( "bots_team" );
+ self AddMenu( "man_team", 0, "Change bot team: " + _tempDvar, ::bot_teams, "team", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_team_amount" );
+ self AddMenu( "man_team", 1, "Increase bots to be on axis team: " + _tempDvar, ::bot_teams, "teamup", _tempDvar );
+ self AddMenu( "man_team", 2, "Decrease bots to be on axis team: " + _tempDvar, ::bot_teams, "teamdown", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_team_force" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("man_team", 3, "Toggle forcing bots on team: " + _temp, ::bot_teams, "teamforce", _tempDvar);
-
- _tempDvar = getDvarInt("bots_team_mode");
- if(_tempDvar)
+
+ self AddMenu( "man_team", 3, "Toggle forcing bots on team: " + _temp, ::bot_teams, "teamforce", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_team_mode" );
+
+ if ( _tempDvar )
_temp = "only bots";
else
_temp = "everyone";
- self AddMenu("man_team", 4, "Toggle bot_team_bot: " + _temp, ::bot_teams, "teammode", _tempDvar);
-
- _tempDvar = getdvarint("bots_skill");
- switch(_tempDvar)
+
+ self AddMenu( "man_team", 4, "Toggle bot_team_bot: " + _temp, ::bot_teams, "teammode", _tempDvar );
+
+ _tempDvar = getdvarint( "bots_skill" );
+
+ switch ( _tempDvar )
{
case 0:
_temp = "random for all";
- break;
+ break;
+
case 1:
_temp = "too easy";
- break;
+ break;
+
case 2:
_temp = "easy";
- break;
+ break;
+
case 3:
_temp = "easy-medium";
- break;
+ break;
+
case 4:
_temp = "medium";
- break;
+ break;
+
case 5:
_temp = "hard";
- break;
+ break;
+
case 6:
_temp = "very hard";
- break;
+ break;
+
case 7:
_temp = "hardest";
- break;
+ break;
+
case 8:
_temp = "custom";
- break;
+ break;
+
case 9:
_temp = "complete random";
- break;
+ break;
+
default:
_temp = "out of range";
- break;
+ break;
}
- self AddMenu("man_team", 5, "Change bot difficulty: "+_temp, ::bot_teams, "skill", _tempDvar);
-
- _tempDvar = getDvarInt("bots_skill_axis_hard");
- self AddMenu("man_team", 6, "Increase amount of hard bots on axis team: " + _tempDvar, ::bot_teams, "axishardup", _tempDvar);
- self AddMenu("man_team", 7, "Decrease amount of hard bots on axis team: " + _tempDvar, ::bot_teams, "axisharddown", _tempDvar);
-
- _tempDvar = getDvarInt("bots_skill_axis_med");
- self AddMenu("man_team", 8, "Increase amount of med bots on axis team: " + _tempDvar, ::bot_teams, "axismedup", _tempDvar);
- self AddMenu("man_team", 9, "Decrease amount of med bots on axis team: " + _tempDvar, ::bot_teams, "axismeddown", _tempDvar);
-
- _tempDvar = getDvarInt("bots_skill_allies_hard");
- self AddMenu("man_team", 10, "Increase amount of hard bots on allies team: " + _tempDvar, ::bot_teams, "allieshardup", _tempDvar);
- self AddMenu("man_team", 11, "Decrease amount of hard bots on allies team: " + _tempDvar, ::bot_teams, "alliesharddown", _tempDvar);
-
- _tempDvar = getDvarInt("bots_skill_allies_med");
- self AddMenu("man_team", 12, "Increase amount of med bots on allies team: " + _tempDvar, ::bot_teams, "alliesmedup", _tempDvar);
- self AddMenu("man_team", 13, "Decrease amount of med bots on allies team: " + _tempDvar, ::bot_teams, "alliesmeddown", _tempDvar);
+
+ self AddMenu( "man_team", 5, "Change bot difficulty: " + _temp, ::bot_teams, "skill", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_skill_axis_hard" );
+ self AddMenu( "man_team", 6, "Increase amount of hard bots on axis team: " + _tempDvar, ::bot_teams, "axishardup", _tempDvar );
+ self AddMenu( "man_team", 7, "Decrease amount of hard bots on axis team: " + _tempDvar, ::bot_teams, "axisharddown", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_skill_axis_med" );
+ self AddMenu( "man_team", 8, "Increase amount of med bots on axis team: " + _tempDvar, ::bot_teams, "axismedup", _tempDvar );
+ self AddMenu( "man_team", 9, "Decrease amount of med bots on axis team: " + _tempDvar, ::bot_teams, "axismeddown", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_skill_allies_hard" );
+ self AddMenu( "man_team", 10, "Increase amount of hard bots on allies team: " + _tempDvar, ::bot_teams, "allieshardup", _tempDvar );
+ self AddMenu( "man_team", 11, "Decrease amount of hard bots on allies team: " + _tempDvar, ::bot_teams, "alliesharddown", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_skill_allies_med" );
+ self AddMenu( "man_team", 12, "Increase amount of med bots on allies team: " + _tempDvar, ::bot_teams, "alliesmedup", _tempDvar );
+ self AddMenu( "man_team", 13, "Decrease amount of med bots on allies team: " + _tempDvar, ::bot_teams, "alliesmeddown", _tempDvar );
//
- self AddMenu("Main", 2, "Bot settings", ::OpenSub, "set1", "");
- self AddBack("set1", "Main");
+ self AddMenu( "Main", 2, "Bot settings", ::OpenSub, "set1", "" );
+ self AddBack( "set1", "Main" );
- _tempDvar = getDvarInt("bots_loadout_reasonable");
- if(_tempDvar)
+ _tempDvar = getDvarInt( "bots_loadout_reasonable" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 0, "Bots use only good class setups: "+_temp, ::bot_func, "reasonable", _tempDvar);
- _tempDvar = getDvarInt("bots_loadout_allow_op");
- if(_tempDvar)
+ self AddMenu( "set1", 0, "Bots use only good class setups: " + _temp, ::bot_func, "reasonable", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_loadout_allow_op" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 1, "Bots can use op and annoying class setups: "+_temp, ::bot_func, "op", _tempDvar);
- _tempDvar = getDvarInt("bots_play_move");
- if(_tempDvar)
+ self AddMenu( "set1", 1, "Bots can use op and annoying class setups: " + _temp, ::bot_func, "op", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_move" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 2, "Bots can move: "+_temp, ::bot_func, "move", _tempDvar);
- _tempDvar = getDvarInt("bots_play_knife");
- if(_tempDvar)
+ self AddMenu( "set1", 2, "Bots can move: " + _temp, ::bot_func, "move", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_knife" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 3, "Bots can knife: "+_temp, ::bot_func, "knife", _tempDvar);
- _tempDvar = getDvarInt("bots_play_fire");
- if(_tempDvar)
+ self AddMenu( "set1", 3, "Bots can knife: " + _temp, ::bot_func, "knife", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_fire" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 4, "Bots can fire: "+_temp, ::bot_func, "fire", _tempDvar);
- _tempDvar = getDvarInt("bots_play_nade");
- if(_tempDvar)
+ self AddMenu( "set1", 4, "Bots can fire: " + _temp, ::bot_func, "fire", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_nade" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 5, "Bots can nade: "+_temp, ::bot_func, "nade", _tempDvar);
- _tempDvar = getDvarInt("bots_play_obj");
- if(_tempDvar)
+ self AddMenu( "set1", 5, "Bots can nade: " + _temp, ::bot_func, "nade", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_obj" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 6, "Bots play the objective: "+_temp, ::bot_func, "obj", _tempDvar);
- _tempDvar = getDvarInt("bots_play_camp");
- if(_tempDvar)
+ self AddMenu( "set1", 6, "Bots play the objective: " + _temp, ::bot_func, "obj", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_camp" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 7, "Bots can camp: "+_temp, ::bot_func, "camp", _tempDvar);
- _tempDvar = getDvarInt("bots_play_jumpdrop");
- if(_tempDvar)
+ self AddMenu( "set1", 7, "Bots can camp: " + _temp, ::bot_func, "camp", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_jumpdrop" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 8, "Bots can jump and dropshot: "+_temp, ::bot_func, "jump", _tempDvar);
- _tempDvar = getDvarInt("bots_play_target_other");
- if(_tempDvar)
+ self AddMenu( "set1", 8, "Bots can jump and dropshot: " + _temp, ::bot_func, "jump", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_target_other" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 9, "Bots can target other script objects: "+_temp, ::bot_func, "targetother", _tempDvar);
- _tempDvar = getDvarInt("bots_play_killstreak");
- if(_tempDvar)
+ self AddMenu( "set1", 9, "Bots can target other script objects: " + _temp, ::bot_func, "targetother", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_killstreak" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 10, "Bots can use killstreaks: "+_temp, ::bot_func, "killstreak", _tempDvar);
- _tempDvar = getDvarInt("bots_play_ads");
- if(_tempDvar)
+ self AddMenu( "set1", 10, "Bots can use killstreaks: " + _temp, ::bot_func, "killstreak", _tempDvar );
+
+ _tempDvar = getDvarInt( "bots_play_ads" );
+
+ if ( _tempDvar )
_temp = "true";
else
_temp = "false";
- self AddMenu("set1", 11, "Bots can ads: "+_temp, ::bot_func, "ads", _tempDvar);
+
+ self AddMenu( "set1", 11, "Bots can ads: " + _temp, ::bot_func, "ads", _tempDvar );
}
-bot_func(a, b)
+bot_func( a, b )
{
- switch (a)
+ switch ( a )
{
case "reasonable":
- setDvar("bots_loadout_reasonable", !b);
- self iPrintln("Bots using reasonable setups: " + !b);
- break;
+ setDvar( "bots_loadout_reasonable", !b );
+ self iPrintln( "Bots using reasonable setups: " + !b );
+ break;
+
case "op":
- setDvar("bots_loadout_allow_op", !b);
- self iPrintln("Bots using op setups: " + !b);
- break;
+ setDvar( "bots_loadout_allow_op", !b );
+ self iPrintln( "Bots using op setups: " + !b );
+ break;
+
case "move":
- setDvar("bots_play_move", !b);
- self iPrintln("Bots move: " + !b);
- break;
+ setDvar( "bots_play_move", !b );
+ self iPrintln( "Bots move: " + !b );
+ break;
+
case "knife":
- setDvar("bots_play_knife", !b);
- self iPrintln("Bots knife: " + !b);
- break;
+ setDvar( "bots_play_knife", !b );
+ self iPrintln( "Bots knife: " + !b );
+ break;
+
case "fire":
- setDvar("bots_play_fire", !b);
- self iPrintln("Bots fire: " + !b);
- break;
+ setDvar( "bots_play_fire", !b );
+ self iPrintln( "Bots fire: " + !b );
+ break;
+
case "nade":
- setDvar("bots_play_nade", !b);
- self iPrintln("Bots nade: " + !b);
- break;
+ setDvar( "bots_play_nade", !b );
+ self iPrintln( "Bots nade: " + !b );
+ break;
+
case "obj":
- setDvar("bots_play_obj", !b);
- self iPrintln("Bots play the obj: " + !b);
- break;
+ setDvar( "bots_play_obj", !b );
+ self iPrintln( "Bots play the obj: " + !b );
+ break;
+
case "camp":
- setDvar("bots_play_camp", !b);
- self iPrintln("Bots camp: " + !b);
- break;
+ setDvar( "bots_play_camp", !b );
+ self iPrintln( "Bots camp: " + !b );
+ break;
+
case "jump":
- setDvar("bots_play_jumpdrop", !b);
- self iPrintln("Bots jump: " + !b);
- break;
+ setDvar( "bots_play_jumpdrop", !b );
+ self iPrintln( "Bots jump: " + !b );
+ break;
+
case "targetother":
- setDvar("bots_play_target_other", !b);
- self iPrintln("Bots target other: " + !b);
- break;
+ setDvar( "bots_play_target_other", !b );
+ self iPrintln( "Bots target other: " + !b );
+ break;
+
case "killstreak":
- setDvar("bots_play_killstreak", !b);
- self iPrintln("Bots use killstreaks: " + !b);
- break;
+ setDvar( "bots_play_killstreak", !b );
+ self iPrintln( "Bots use killstreaks: " + !b );
+ break;
+
case "ads":
- setDvar("bots_play_ads", !b);
- self iPrintln("Bots ads: " + !b);
- break;
+ setDvar( "bots_play_ads", !b );
+ self iPrintln( "Bots ads: " + !b );
+ break;
}
}
-bot_teams(a, b)
+bot_teams( a, b )
{
- switch(a)
+ switch ( a )
{
case "team":
- switch(b)
+ switch ( b )
{
case "autoassign":
- setdvar("bots_team", "allies");
- self iPrintlnBold("Changed bot team to allies.");
- break;
+ setdvar( "bots_team", "allies" );
+ self iPrintlnBold( "Changed bot team to allies." );
+ break;
+
case "allies":
- setdvar("bots_team", "axis");
- self iPrintlnBold("Changed bot team to axis.");
- break;
+ setdvar( "bots_team", "axis" );
+ self iPrintlnBold( "Changed bot team to axis." );
+ break;
+
case "axis":
- setdvar("bots_team", "custom");
- self iPrintlnBold("Changed bot team to custom.");
- break;
+ setdvar( "bots_team", "custom" );
+ self iPrintlnBold( "Changed bot team to custom." );
+ break;
+
default:
- setdvar("bots_team", "autoassign");
- self iPrintlnBold("Changed bot team to autoassign.");
- break;
+ setdvar( "bots_team", "autoassign" );
+ self iPrintlnBold( "Changed bot team to autoassign." );
+ break;
}
- break;
+
+ break;
+
case "teamup":
- setdvar("bots_team_amount", b+1);
- self iPrintln((b+1)+" bot(s) will try to be on axis team.");
- break;
+ setdvar( "bots_team_amount", b + 1 );
+ self iPrintln( ( b + 1 ) + " bot(s) will try to be on axis team." );
+ break;
+
case "teamdown":
- setdvar("bots_team_amount", b-1);
- self iPrintln((b-1)+" bot(s) will try to be on axis team.");
- break;
+ setdvar( "bots_team_amount", b - 1 );
+ self iPrintln( ( b - 1 ) + " bot(s) will try to be on axis team." );
+ break;
+
case "teamforce":
- setDvar("bots_team_force", !b);
- self iPrintln("Forcing bots to team: " + !b);
- break;
+ setDvar( "bots_team_force", !b );
+ self iPrintln( "Forcing bots to team: " + !b );
+ break;
+
case "teammode":
- setDvar("bots_team_mode", !b);
- self iPrintln("Only count bots on team: " + !b);
- break;
+ setDvar( "bots_team_mode", !b );
+ self iPrintln( "Only count bots on team: " + !b );
+ break;
+
case "skill":
- switch(b)
+ switch ( b )
{
case 0:
- self iPrintlnBold("Changed bot skill to easy.");
- setDvar("bots_skill", 1);
- break;
+ self iPrintlnBold( "Changed bot skill to easy." );
+ setDvar( "bots_skill", 1 );
+ break;
+
case 1:
- self iPrintlnBold("Changed bot skill to easy-med.");
- setDvar("bots_skill", 2);
- break;
+ self iPrintlnBold( "Changed bot skill to easy-med." );
+ setDvar( "bots_skill", 2 );
+ break;
+
case 2:
- self iPrintlnBold("Changed bot skill to medium.");
- setDvar("bots_skill", 3);
- break;
+ self iPrintlnBold( "Changed bot skill to medium." );
+ setDvar( "bots_skill", 3 );
+ break;
+
case 3:
- self iPrintlnBold("Changed bot skill to med-hard.");
- setDvar("bots_skill", 4);
- break;
+ self iPrintlnBold( "Changed bot skill to med-hard." );
+ setDvar( "bots_skill", 4 );
+ break;
+
case 4:
- self iPrintlnBold("Changed bot skill to hard.");
- setDvar("bots_skill", 5);
- break;
+ self iPrintlnBold( "Changed bot skill to hard." );
+ setDvar( "bots_skill", 5 );
+ break;
+
case 5:
- self iPrintlnBold("Changed bot skill to very hard.");
- setDvar("bots_skill", 6);
- break;
+ self iPrintlnBold( "Changed bot skill to very hard." );
+ setDvar( "bots_skill", 6 );
+ break;
+
case 6:
- self iPrintlnBold("Changed bot skill to hardest.");
- setDvar("bots_skill", 7);
- break;
+ self iPrintlnBold( "Changed bot skill to hardest." );
+ setDvar( "bots_skill", 7 );
+ break;
+
case 7:
- self iPrintlnBold("Changed bot skill to custom. Base is easy.");
- setDvar("bots_skill", 8);
- break;
+ self iPrintlnBold( "Changed bot skill to custom. Base is easy." );
+ setDvar( "bots_skill", 8 );
+ break;
+
case 8:
- self iPrintlnBold("Changed bot skill to complete random. Takes effect at restart.");
- setDvar("bots_skill", 9);
- break;
+ self iPrintlnBold( "Changed bot skill to complete random. Takes effect at restart." );
+ setDvar( "bots_skill", 9 );
+ break;
+
default:
- self iPrintlnBold("Changed bot skill to random. Takes effect at restart.");
- setDvar("bots_skill", 0);
- break;
+ self iPrintlnBold( "Changed bot skill to random. Takes effect at restart." );
+ setDvar( "bots_skill", 0 );
+ break;
}
- break;
+
+ break;
+
case "axishardup":
- setdvar("bots_skill_axis_hard", (b+1));
- self iPrintln(((b+1))+" hard bots will be on axis team.");
- break;
+ setdvar( "bots_skill_axis_hard", ( b + 1 ) );
+ self iPrintln( ( ( b + 1 ) ) + " hard bots will be on axis team." );
+ break;
+
case "axisharddown":
- setdvar("bots_skill_axis_hard", (b-1));
- self iPrintln(((b-1))+" hard bots will be on axis team.");
- break;
+ setdvar( "bots_skill_axis_hard", ( b - 1 ) );
+ self iPrintln( ( ( b - 1 ) ) + " hard bots will be on axis team." );
+ break;
+
case "axismedup":
- setdvar("bots_skill_axis_med", (b+1));
- self iPrintln(((b+1))+" med bots will be on axis team.");
- break;
+ setdvar( "bots_skill_axis_med", ( b + 1 ) );
+ self iPrintln( ( ( b + 1 ) ) + " med bots will be on axis team." );
+ break;
+
case "axismeddown":
- setdvar("bots_skill_axis_med", (b-1));
- self iPrintln(((b-1))+" med bots will be on axis team.");
- break;
+ setdvar( "bots_skill_axis_med", ( b - 1 ) );
+ self iPrintln( ( ( b - 1 ) ) + " med bots will be on axis team." );
+ break;
+
case "allieshardup":
- setdvar("bots_skill_allies_hard", (b+1));
- self iPrintln(((b+1))+" hard bots will be on allies team.");
- break;
+ setdvar( "bots_skill_allies_hard", ( b + 1 ) );
+ self iPrintln( ( ( b + 1 ) ) + " hard bots will be on allies team." );
+ break;
+
case "alliesharddown":
- setdvar("bots_skill_allies_hard", (b-1));
- self iPrintln(((b-1))+" hard bots will be on allies team.");
- break;
+ setdvar( "bots_skill_allies_hard", ( b - 1 ) );
+ self iPrintln( ( ( b - 1 ) ) + " hard bots will be on allies team." );
+ break;
+
case "alliesmedup":
- setdvar("bots_skill_allies_med", (b+1));
- self iPrintln(((b+1))+" med bots will be on allies team.");
- break;
+ setdvar( "bots_skill_allies_med", ( b + 1 ) );
+ self iPrintln( ( ( b + 1 ) ) + " med bots will be on allies team." );
+ break;
+
case "alliesmeddown":
- setdvar("bots_skill_allies_med", (b-1));
- self iPrintln(((b-1))+" med bots will be on allies team.");
- break;
+ setdvar( "bots_skill_allies_med", ( b - 1 ) );
+ self iPrintln( ( ( b - 1 ) ) + " med bots will be on allies team." );
+ break;
}
}
-man_bots(a, b)
+man_bots( a, b )
{
- switch(a)
+ switch ( a )
{
case "add":
- setdvar("bots_manage_add", b);
- if(b == 1)
+ setdvar( "bots_manage_add", b );
+
+ if ( b == 1 )
{
- self iPrintln("Adding "+b+" bot.");
+ self iPrintln( "Adding " + b + " bot." );
}
else
{
- self iPrintln("Adding "+b+" bots.");
+ self iPrintln( "Adding " + b + " bots." );
}
- break;
+
+ break;
+
case "kick":
- for (i = 0; i < b; i++)
+ for ( i = 0; i < b; i++ )
{
RemoveTestClient();
wait 0.25;
}
- break;
+
+ break;
+
case "autokick":
- setDvar("bots_manage_fill_kick", !b);
- self iPrintln("Kicking bots when bots_fill is exceeded: " + !b);
- break;
+ setDvar( "bots_manage_fill_kick", !b );
+ self iPrintln( "Kicking bots when bots_fill is exceeded: " + !b );
+ break;
+
case "fillmode":
- switch(b)
+ switch ( b )
{
case 0:
- setdvar("bots_manage_fill_mode", 1);
- self iPrintln("bot_fill will now count only bots.");
- break;
+ setdvar( "bots_manage_fill_mode", 1 );
+ self iPrintln( "bot_fill will now count only bots." );
+ break;
+
case 1:
- setdvar("bots_manage_fill_mode", 2);
- self iPrintln("bot_fill will now count everyone, adjusting to map.");
- break;
+ setdvar( "bots_manage_fill_mode", 2 );
+ self iPrintln( "bot_fill will now count everyone, adjusting to map." );
+ break;
+
case 2:
- setdvar("bots_manage_fill_mode", 3);
- self iPrintln("bot_fill will now count only bots, adjusting to map.");
- break;
+ setdvar( "bots_manage_fill_mode", 3 );
+ self iPrintln( "bot_fill will now count only bots, adjusting to map." );
+ break;
+
case 3:
- setdvar("bots_manage_fill_mode", 4);
- self iPrintln("bot_fill will now use bots as team balance.");
- break;
+ setdvar( "bots_manage_fill_mode", 4 );
+ self iPrintln( "bot_fill will now use bots as team balance." );
+ break;
+
default:
- setdvar("bots_manage_fill_mode", 0);
- self iPrintln("bot_fill will now count everyone.");
- break;
+ setdvar( "bots_manage_fill_mode", 0 );
+ self iPrintln( "bot_fill will now count everyone." );
+ break;
}
- break;
+
+ break;
+
case "fillup":
- setdvar("bots_manage_fill", b+1);
- self iPrintln("Increased to maintain "+(b+1)+" bot(s).");
- break;
+ setdvar( "bots_manage_fill", b + 1 );
+ self iPrintln( "Increased to maintain " + ( b + 1 ) + " bot(s)." );
+ break;
+
case "filldown":
- setdvar("bots_manage_fill", b-1);
- self iPrintln("Decreased to maintain "+(b-1)+" bot(s).");
- break;
+ setdvar( "bots_manage_fill", b - 1 );
+ self iPrintln( "Decreased to maintain " + ( b - 1 ) + " bot(s)." );
+ break;
+
case "fillspec":
- setDvar("bots_manage_fill_spec", !b);
- self iPrintln("Count players on spectator for bots_fill: " + !b);
- break;
+ setDvar( "bots_manage_fill_spec", !b );
+ self iPrintln( "Count players on spectator for bots_fill: " + !b );
+ break;
}
}
diff --git a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_wp_editor.gsc b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_wp_editor.gsc
index 4b3bc9e..e4dedf8 100644
--- a/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_wp_editor.gsc
+++ b/out/Add to root of CoD4x server/main_shared/maps/mp/bots/_wp_editor.gsc
@@ -1,649 +1,648 @@
-/*
- _wp_editor
- Author: INeedGames
- Date: 09/26/2020
- The ingame waypoint editor.
-*/
-
-#include common_scripts\utility;
-#include maps\mp\_utility;
-#include maps\mp\gametypes\_hud_util;
-#include maps\mp\bots\_bot_utility;
-
-init()
-{
- if(getDvar("bots_main_debug") == "")
- setDvar("bots_main_debug", 0);
-
- if(!getDVarint("bots_main_debug"))
- return;
-
- if(!getDVarint("developer"))
- {
- setdvar("developer_script", 1);
- setdvar("developer", 1);
-
- setdvar("sv_mapRotation", "map "+getDvar("mapname"));
- exitLevel(false);
- }
-
- setDvar("bots_main", 0);
- setdvar("bots_main_menu", 0);
- setdvar("bots_manage_fill_mode", 0);
- setdvar("bots_manage_fill", 0);
- setdvar("bots_manage_add", 0);
- setdvar("bots_manage_fill_kick", 1);
- setDvar("bots_manage_fill_spec", 1);
-
- if (getDvar("bots_main_debug_distance") == "")
- setDvar("bots_main_debug_distance", 512.0);
-
- if (getDvar("bots_main_debug_cone") == "")
- setDvar("bots_main_debug_cone", 0.65);
-
- if (getDvar("bots_main_debug_minDist") == "")
- setDvar("bots_main_debug_minDist", 32.0);
-
- if (getDvar("bots_main_debug_drawThrough") == "")
- setDvar("bots_main_debug_drawThrough", false);
-
- if(getDvar("bots_main_debug_commandWait") == "")
- setDvar("bots_main_debug_commandWait", 0.5);
-
- if(getDvar("bots_main_debug_framerate") == "")
- setDvar("bots_main_debug_framerate", 58);
-
- if(getDvar("bots_main_debug_lineDuration") == "")
- setDvar("bots_main_debug_lineDuration", 3);
-
- if(getDvar("bots_main_debug_printDuration") == "")
- setDvar("bots_main_debug_printDuration", 3);
-
- if(getDvar("bots_main_debug_debugRate") == "")
- setDvar("bots_main_debug_debugRate", 0.5);
-
- setDvar("player_sustainAmmo", 1);
-
- level.waypoints = [];
- level.waypointCount = 0;
-
- level waittill( "connected", player);
-
- player thread onPlayerSpawned();
-}
-
-onPlayerSpawned()
-{
- self endon("disconnect");
- for(;;)
- {
- self waittill("spawned_player");
- self thread beginDebug();
- }
-}
-
-beginDebug()
-{
- self endon("disconnect");
- self endon("death");
-
- level.wpToLink = -1;
- level.autoLink = false;
- self.closest = -1;
- self.command = undefined;
-
- self clearPerks();
- self takeAllWeapons();
- self.specialty = [];
- self giveWeapon("m16_gl_mp");
- self SetActionSlot( 3, "altMode" );
- self giveWeapon("frag_grenade_mp");
- self freezecontrols(false);
-
- self thread debug();
- self thread addWaypoints();
- self thread linkWaypoints();
- self thread deleteWaypoints();
- self thread watchSaveWaypointsCommand();
- self thread sayExtras();
-
- self thread textScroll("^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save");
-}
-
-sayExtras()
-{
- self endon("disconnect");
- self endon("death");
- self iprintln("Making a crouch waypoint with only one link...");
- self iprintln("Makes a camping waypoint.");
-}
-
-debug()
-{
- self endon("disconnect");
- self endon("death");
-
- self setClientDvar("com_maxfps", getDvarInt("bots_main_debug_framerate"));
-
- for(;;)
- {
- wait getDvarFloat("bots_main_debug_debugRate");
-
- if(isDefined(self.command))
- continue;
-
- closest = -1;
- myEye = self getTagOrigin( "j_head" );
- myAngles = self GetPlayerAngles();
-
- for(i = 0; i < level.waypointCount; i++)
- {
- if(closest == -1 || closer(self.origin, level.waypoints[i].origin, level.waypoints[closest].origin))
- closest = i;
-
- wpOrg = level.waypoints[i].origin + (0, 0, 25);
-
- if(distance(level.waypoints[i].origin, self.origin) < getDvarFloat("bots_main_debug_distance") && (bulletTracePassed(myEye, wpOrg, false, self) || getDVarint("bots_main_debug_drawThrough")))
- {
- for(h = 0; h < level.waypoints[i].childCount; h++)
- line(wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + (0, 0, 25), (1,0,1), 1, 1, getDvarInt("bots_main_debug_lineDuration"));
-
- if(getConeDot(wpOrg, myEye, myAngles) > getDvarFloat("bots_main_debug_cone"))
- print3d(wpOrg, i, (1,0,0), 2, 1, 6);
-
- if (isDefined(level.waypoints[i].angles) && level.waypoints[i].type != "stand")
- line(wpOrg, wpOrg + AnglesToForward(level.waypoints[i].angles) * 64, (1,1,1), 1, 1, getDvarInt("bots_main_debug_lineDuration"));
- }
- }
-
- self.closest = closest;
-
- if(closest != -1)
- {
- stringChildren = "";
- for(i = 0; i < level.waypoints[closest].childCount; i++)
- {
- if(i != 0)
- stringChildren = stringChildren + "," + level.waypoints[closest].children[i];
- else
- stringChildren = stringChildren + level.waypoints[closest].children[i];
- }
- print3d(level.waypoints[closest].origin + (0, 0, 35), stringChildren, (0,1,0), 2, 1, getDvarInt("bots_main_debug_printDuration"));
-
- print3d(level.waypoints[closest].origin + (0, 0, 15), level.waypoints[closest].type, (0,1,0), 2, 1, getDvarInt("bots_main_debug_printDuration"));
- }
- }
-}
-
-AddWaypoints()
-{
- self endon("disconnect");
- self endon("death");
- for(;;)
- {
- while(!self SecondaryOffhandButtonPressed() || isDefined(self.command))
- wait 0.05;
-
- pos = self getOrigin();
- self.command = true;
-
- self iprintln("Adding a waypoint...");
- self iprintln("ADS - climb; Attack + Use - tube");
- self iprintln("Attack - grenade; Use - claymore");
- self iprintln("Else(wait) - your stance");
-
- wait getDvarFloat("bots_main_debug_commandWait");
-
- self addWaypoint(pos);
-
- self.command = undefined;
-
- while(self SecondaryOffhandButtonPressed())
- wait 0.05;
- }
-}
-
-linkWaypoints()
-{
- self endon("disconnect");
- self endon("death");
- for(;;)
- {
- while(!self MeleeButtonPressed() || isDefined(self.command))
- wait 0.05;
-
- self.command = true;
-
- self iprintln("ADS - Unlink; Else(wait) - Link");
-
- wait getDvarFloat("bots_main_debug_commandWait");
-
- if(!self adsButtonPressed())
- self LinkWaypoint(self.closest);
- else
- self UnLinkWaypoint(self.closest);
-
- self.command = undefined;
-
- while(self MeleeButtonPressed())
- wait 0.05;
- }
-}
-
-deleteWaypoints()
-{
- self endon("disconnect");
- self endon("death");
- for(;;)
- {
- while(!self fragButtonPressed() || isDefined(self.command))
- wait 0.05;
-
- self.command = true;
-
- self iprintln("Attack - DeleteAll; ADS - Load");
- self iprintln("Else(wait) - Delete");
-
- wait getDvarFloat("bots_main_debug_commandWait");
-
- if(self attackButtonPressed())
- self deleteAllWaypoints();
- else if(self adsButtonPressed())
- self LoadWaypoints();
- else
- self DeleteWaypoint(self.closest);
-
- self.command = undefined;
-
- while(self fragButtonPressed())
- wait 0.05;
- }
-}
-
-watchSaveWaypointsCommand()
-{
- self endon("death");
- self endon("disconnect");
-
- for(;;)
- {
- while(!self useButtonPressed() || !self attackButtonPressed() || isDefined(self.command))
- wait 0.05;
-
- self.command = true;
-
- self iprintln("ADS - Autolink; Else(wait) - Save");
-
- wait getDvarFloat("bots_main_debug_commandWait");
-
- if(!self adsButtonPressed())
- {
- self checkForWarnings();
- wait 1;
-
- logprint("***********ABiliTy's WPDump**************\n\n");
- logprint("\n\n\n\n");
- mpnm=getMapName(getdvar("mapname"));
- logprint("\n\n"+mpnm+"()\n{\n/*");
- logprint("*/waypoints = [];\n/*");
- for(i = 0; i < level.waypointCount; i++)
- {
- logprint("*/waypoints["+i+"] = spawnstruct();\n/*");
- logprint("*/waypoints["+i+"].origin = "+level.waypoints[i].origin+";\n/*");
- logprint("*/waypoints["+i+"].type = \""+level.waypoints[i].type+"\";\n/*");
- logprint("*/waypoints["+i+"].childCount = "+level.waypoints[i].childCount+";\n/*");
- for(c = 0; c < level.waypoints[i].childCount; c++)
- {
- logprint("*/waypoints["+i+"].children["+c+"] = "+level.waypoints[i].children[c]+";\n/*");
- }
- if(isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade"))
- logprint("*/waypoints["+i+"].angles = "+level.waypoints[i].angles+";\n/*");
- }
- logprint("*/return waypoints;\n}\n\n\n\n");
-
- filename = "waypoints/" + getdvar("mapname") + "_wp.csv";
- fd = FS_FOpen(filename, "write");
-
- PrintLn("********* Start Bot Warfare WPDump *********");
- PrintLn(level.waypointCount);
-
- if (fd > 0)
- {
- if (!FS_WriteLine(fd, level.waypointCount+""))
- {
- FS_FClose(fd);
- fd = 0;
- }
- }
- for(i = 0; i < level.waypointCount; i++)
- {
- str = "";
- wp = level.waypoints[i];
-
- str += wp.origin[0] + " " + wp.origin[1] + " " + wp.origin[2] + ",";
-
- for(h = 0; h < wp.childCount; h++)
- {
- str += wp.children[h];
-
- if (h < wp.childCount - 1)
- str += " ";
- }
- str += "," + wp.type + ",";
-
- if (isDefined(wp.angles))
- str += wp.angles[0] + " " + wp.angles[1] + " " + wp.angles[2] + ",";
- else
- str += ",";
-
- str += ",";
-
- PrintLn(str);
-
- if (fd > 0)
- {
- if (!FS_WriteLine(fd, str))
- {
- FS_FClose(fd);
- fd = 0;
- }
- }
- }
- PrintLn("\n\n\n\n\n\n");
-
- self iprintln("Saved!!! to " + filename);
-
- if (fd > 0)
- FS_FClose(fd);
- }
- else
- {
- if(level.autoLink)
- {
- self iPrintlnBold("Auto link disabled");
- level.autoLink = false;
- level.wpToLink = -1;
- }
- else
- {
- self iPrintlnBold("Auto link enabled");
- level.autoLink = true;
- level.wpToLink = self.closest;
- }
- }
-
- self.command = undefined;
-
- while(self useButtonPressed() && self attackButtonPressed())
- wait 0.05;
- }
-}
-
-LoadWaypoints()
-{
- self DeleteAllWaypoints();
- self iPrintlnBold("Loading WPS...");
- load_waypoints();
-
- wait 1;
-
- self checkForWarnings();
-}
-
-checkForWarnings()
-{
- if(level.waypointCount <= 0)
- self iprintln("WARNING: waypointCount is "+level.waypointCount);
-
- if(level.waypointCount != level.waypoints.size)
- self iprintln("WARNING: waypointCount is not "+level.waypoints.size);
-
- for(i = 0; i < level.waypointCount; i++)
- {
- if(!isDefined(level.waypoints[i]))
- {
- self iprintln("WARNING: waypoint "+i+" is undefined");
- continue;
- }
-
- if(level.waypoints[i].childCount <= 0)
- self iprintln("WARNING: waypoint "+i+" childCount is "+level.waypoints[i].childCount);
- else
- {
- if (!isDefined(level.waypoints[i].children) || !isDefined(level.waypoints[i].children.size))
- {
- self iprintln("WARNING: waypoint "+i+" children is not defined");
- }
- else
- {
- if(level.waypoints[i].childCount != level.waypoints[i].children.size)
- self iprintln("WARNING: waypoint "+i+" childCount is not "+level.waypoints[i].children.size);
-
- for (h = 0; h < level.waypoints[i].childCount; h++)
- {
- child = level.waypoints[i].children[h];
-
- if(!isDefined(level.waypoints[child]))
- self iprintln("WARNING: waypoint "+i+" child "+child+" is undefined");
- else if(child == i)
- self iprintln("WARNING: waypoint "+i+" child "+child+" is itself");
- }
- }
- }
-
- if(!isDefined(level.waypoints[i].type))
- {
- self iprintln("WARNING: waypoint "+i+" type is undefined");
- continue;
- }
-
- if(!isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade"))
- self iprintln("WARNING: waypoint "+i+" angles is undefined");
- }
-}
-
-DeleteAllWaypoints()
-{
- level.waypoints = [];
- level.waypointCount = 0;
- level.waypointsKDTree = WaypointsToKDTree();
-
- level.waypointsCamp = [];
- level.waypointsTube = [];
- level.waypointsGren = [];
- level.waypointsClay = [];
-
- self iprintln("DelAllWps");
-}
-
-DeleteWaypoint(nwp)
-{
- if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
- {
- self iprintln("No close enough waypoint to delete.");
- return;
- }
-
- level.wpToLink = -1;
-
- for(i = 0; i < level.waypoints[nwp].childCount; i++)
- {
- child = level.waypoints[nwp].children[i];
-
- level.waypoints[child].children = array_remove(level.waypoints[child].children, nwp);
-
- level.waypoints[child].childCount = level.waypoints[child].children.size;
- }
-
- for(i = 0; i < level.waypointCount; i++)
- {
- for(h = 0; h < level.waypoints[i].childCount; h++)
- {
- if(level.waypoints[i].children[h] > nwp)
- level.waypoints[i].children[h]--;
- }
- }
-
- for ( entry = 0; entry < level.waypointCount; entry++ )
- {
- if ( entry == nwp )
- {
- while ( entry < level.waypointCount-1 )
- {
- level.waypoints[entry] = level.waypoints[entry+1];
- entry++;
- }
- level.waypoints[entry] = undefined;
- break;
- }
- }
- level.waypointCount--;
-
- self iprintln("DelWp "+nwp);
-}
-
-addWaypoint(pos)
-{
- level.waypoints[level.waypointCount] = spawnstruct();
-
- level.waypoints[level.waypointCount].origin = pos;
-
- if(self AdsButtonPressed())
- level.waypoints[level.waypointCount].type = "climb";
- else if(self AttackButtonPressed() && self UseButtonPressed())
- level.waypoints[level.waypointCount].type = "tube";
- else if(self AttackButtonPressed())
- level.waypoints[level.waypointCount].type = "grenade";
- else if(self UseButtonPressed())
- level.waypoints[level.waypointCount].type = "claymore";
- else
- level.waypoints[level.waypointCount].type = self getStance();
-
- level.waypoints[level.waypointCount].angles = self getPlayerAngles();
-
- level.waypoints[level.waypointCount].children = [];
- level.waypoints[level.waypointCount].childCount = 0;
-
- self iprintln(level.waypoints[level.waypointCount].type + " Waypoint "+ level.waypointCount +" Added at "+pos);
-
- if(level.autoLink)
- {
- if(level.wpToLink == -1)
- level.wpToLink = level.waypointCount - 1;
-
- level.waypointCount++;
- self LinkWaypoint(level.waypointCount - 1);
- }
- else
- {
- level.waypointCount++;
- }
-}
-
-UnLinkWaypoint(nwp)
-{
- if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
- {
- self iprintln("Waypoint Unlink Cancelled "+level.wpToLink);
- level.wpToLink = -1;
- return;
- }
-
- if(level.wpToLink == -1 || nwp == level.wpToLink)
- {
- level.wpToLink = nwp;
- self iprintln("Waypoint Unlink Started "+nwp);
- return;
- }
-
- level.waypoints[nwp].children = array_remove(level.waypoints[nwp].children, level.wpToLink);
- level.waypoints[level.wpToLink].children = array_remove(level.waypoints[level.wpToLink].children, nwp);
-
- level.waypoints[nwp].childCount = level.waypoints[nwp].children.size;
- level.waypoints[level.wpToLink].childCount = level.waypoints[level.wpToLink].children.size;
-
- self iprintln("Waypoint " + nwp + " Broken to " + level.wpToLink);
- level.wpToLink = -1;
-}
-
-LinkWaypoint(nwp)
-{
- if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
- {
- self iprintln("Waypoint Link Cancelled "+level.wpToLink);
- level.wpToLink = -1;
- return;
- }
-
- if(level.wpToLink == -1 || nwp == level.wpToLink)
- {
- level.wpToLink = nwp;
- self iprintln("Waypoint Link Started "+nwp);
- return;
- }
-
- weGood = true;
- for(i = 0; i < level.waypoints[level.wpToLink].childCount; i++)
- {
- if(level.waypoints[level.wpToLink].children[i] == nwp)
- {
- weGood = false;
- break;
- }
- }
- if(weGood)
- {
- for(i = 0; i < level.waypoints[nwp].childCount; i++)
- {
- if(level.waypoints[nwp].children[i] == level.wpToLink)
- {
- weGood = false;
- break;
- }
- }
- }
-
- if (!weGood )
- {
- self iprintln("Waypoint Link Cancelled "+nwp+" and "+level.wpToLink+" already linked.");
- level.wpToLink = -1;
- return;
- }
-
- level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].childcount] = nwp;
- level.waypoints[level.wpToLink].childcount++;
- level.waypoints[nwp].children[level.waypoints[nwp].childcount] = level.wpToLink;
- level.waypoints[nwp].childcount++;
-
- self iprintln("Waypoint " + nwp + " Linked to " + level.wpToLink);
- level.wpToLink = -1;
-}
-
-destroyOnDeath(hud)
-{
- hud endon("death");
- self waittill_either("death","disconnect");
- hud destroy();
-}
-
-textScroll(string)
-{
- self endon("death");
- self endon("disconnect");
- //thanks ActionScript
-
- back = createBar((0,0,0), 1000, 30);
- back setPoint("CENTER", undefined, 0, 220);
- self thread destroyOnDeath(back);
-
- text = createFontString("default", 1.5);
- text setText(string);
- self thread destroyOnDeath(text);
-
- for (;;)
- {
- text setPoint("CENTER", undefined, 1200, 220);
- text setPoint("CENTER", undefined, -1200, 220, 20);
- wait 20;
- }
-}
+/*
+ _wp_editor
+ Author: INeedGames
+ Date: 09/26/2020
+ The ingame waypoint editor.
+*/
+
+#include common_scripts\utility;
+#include maps\mp\_utility;
+#include maps\mp\gametypes\_hud_util;
+#include maps\mp\bots\_bot_utility;
+
+init()
+{
+ if ( getDvar( "bots_main_debug" ) == "" )
+ setDvar( "bots_main_debug", 0 );
+
+ if ( !getDVarint( "bots_main_debug" ) )
+ return;
+
+ if ( !getDVarint( "developer" ) )
+ {
+ setdvar( "developer_script", 1 );
+ setdvar( "developer", 1 );
+
+ setdvar( "sv_mapRotation", "map " + getDvar( "mapname" ) );
+ exitLevel( false );
+ }
+
+ setDvar( "bots_main", 0 );
+ setdvar( "bots_main_menu", 0 );
+ setdvar( "bots_manage_fill_mode", 0 );
+ setdvar( "bots_manage_fill", 0 );
+ setdvar( "bots_manage_add", 0 );
+ setdvar( "bots_manage_fill_kick", 1 );
+ setDvar( "bots_manage_fill_spec", 1 );
+
+ if ( getDvar( "bots_main_debug_distance" ) == "" )
+ setDvar( "bots_main_debug_distance", 512.0 );
+
+ if ( getDvar( "bots_main_debug_cone" ) == "" )
+ setDvar( "bots_main_debug_cone", 0.65 );
+
+ if ( getDvar( "bots_main_debug_minDist" ) == "" )
+ setDvar( "bots_main_debug_minDist", 32.0 );
+
+ if ( getDvar( "bots_main_debug_drawThrough" ) == "" )
+ setDvar( "bots_main_debug_drawThrough", false );
+
+ if ( getDvar( "bots_main_debug_commandWait" ) == "" )
+ setDvar( "bots_main_debug_commandWait", 0.5 );
+
+ if ( getDvar( "bots_main_debug_framerate" ) == "" )
+ setDvar( "bots_main_debug_framerate", 58 );
+
+ if ( getDvar( "bots_main_debug_lineDuration" ) == "" )
+ setDvar( "bots_main_debug_lineDuration", 3 );
+
+ if ( getDvar( "bots_main_debug_printDuration" ) == "" )
+ setDvar( "bots_main_debug_printDuration", 3 );
+
+ if ( getDvar( "bots_main_debug_debugRate" ) == "" )
+ setDvar( "bots_main_debug_debugRate", 0.5 );
+
+ setDvar( "player_sustainAmmo", 1 );
+
+ level.waypoints = [];
+ level.waypointCount = 0;
+
+ level waittill( "connected", player );
+
+ player thread onPlayerSpawned();
+}
+
+onPlayerSpawned()
+{
+ self endon( "disconnect" );
+
+ for ( ;; )
+ {
+ self waittill( "spawned_player" );
+ self thread beginDebug();
+ }
+}
+
+beginDebug()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ level.wpToLink = -1;
+ level.autoLink = false;
+ self.closest = -1;
+ self.command = undefined;
+
+ self clearPerks();
+ self takeAllWeapons();
+ self.specialty = [];
+ self giveWeapon( "m16_gl_mp" );
+ self SetActionSlot( 3, "altMode" );
+ self giveWeapon( "frag_grenade_mp" );
+ self freezecontrols( false );
+
+ self thread debug();
+ self thread addWaypoints();
+ self thread linkWaypoints();
+ self thread deleteWaypoints();
+ self thread watchSaveWaypointsCommand();
+ self thread sayExtras();
+
+ self thread textScroll( "^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save" );
+}
+
+sayExtras()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+ self iprintln( "Making a crouch waypoint with only one link..." );
+ self iprintln( "Makes a camping waypoint." );
+}
+
+debug()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ self setClientDvar( "com_maxfps", getDvarInt( "bots_main_debug_framerate" ) );
+
+ for ( ;; )
+ {
+ wait getDvarFloat( "bots_main_debug_debugRate" );
+
+ if ( isDefined( self.command ) )
+ continue;
+
+ closest = -1;
+ myEye = self getTagOrigin( "j_head" );
+ myAngles = self GetPlayerAngles();
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ if ( closest == -1 || closer( self.origin, level.waypoints[i].origin, level.waypoints[closest].origin ) )
+ closest = i;
+
+ wpOrg = level.waypoints[i].origin + ( 0, 0, 25 );
+
+ if ( distance( level.waypoints[i].origin, self.origin ) < getDvarFloat( "bots_main_debug_distance" ) && ( bulletTracePassed( myEye, wpOrg, false, self ) || getDVarint( "bots_main_debug_drawThrough" ) ) )
+ {
+ for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
+ line( wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + ( 0, 0, 25 ), ( 1, 0, 1 ), 1, 1, getDvarInt( "bots_main_debug_lineDuration" ) );
+
+ if ( getConeDot( wpOrg, myEye, myAngles ) > getDvarFloat( "bots_main_debug_cone" ) )
+ print3d( wpOrg, i, ( 1, 0, 0 ), 2, 1, 6 );
+
+ if ( isDefined( level.waypoints[i].angles ) && level.waypoints[i].type != "stand" )
+ line( wpOrg, wpOrg + AnglesToForward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ), 1, 1, getDvarInt( "bots_main_debug_lineDuration" ) );
+ }
+ }
+
+ self.closest = closest;
+
+ if ( closest != -1 )
+ {
+ stringChildren = "";
+
+ for ( i = 0; i < level.waypoints[closest].children.size; i++ )
+ {
+ if ( i != 0 )
+ stringChildren = stringChildren + "," + level.waypoints[closest].children[i];
+ else
+ stringChildren = stringChildren + level.waypoints[closest].children[i];
+ }
+
+ print3d( level.waypoints[closest].origin + ( 0, 0, 35 ), stringChildren, ( 0, 1, 0 ), 2, 1, getDvarInt( "bots_main_debug_printDuration" ) );
+
+ print3d( level.waypoints[closest].origin + ( 0, 0, 15 ), level.waypoints[closest].type, ( 0, 1, 0 ), 2, 1, getDvarInt( "bots_main_debug_printDuration" ) );
+ }
+ }
+}
+
+AddWaypoints()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
+ {
+ while ( !self SecondaryOffhandButtonPressed() || isDefined( self.command ) )
+ wait 0.05;
+
+ pos = self getOrigin();
+ self.command = true;
+
+ self iprintln( "Adding a waypoint..." );
+ self iprintln( "ADS - climb; Attack + Use - tube" );
+ self iprintln( "Attack - grenade; Use - claymore" );
+ self iprintln( "Else(wait) - your stance" );
+
+ wait getDvarFloat( "bots_main_debug_commandWait" );
+
+ self addWaypoint( pos );
+
+ self.command = undefined;
+
+ while ( self SecondaryOffhandButtonPressed() )
+ wait 0.05;
+ }
+}
+
+linkWaypoints()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
+ {
+ while ( !self MeleeButtonPressed() || isDefined( self.command ) )
+ wait 0.05;
+
+ self.command = true;
+
+ self iprintln( "ADS - Unlink; Else(wait) - Link" );
+
+ wait getDvarFloat( "bots_main_debug_commandWait" );
+
+ if ( !self adsButtonPressed() )
+ self LinkWaypoint( self.closest );
+ else
+ self UnLinkWaypoint( self.closest );
+
+ self.command = undefined;
+
+ while ( self MeleeButtonPressed() )
+ wait 0.05;
+ }
+}
+
+deleteWaypoints()
+{
+ self endon( "disconnect" );
+ self endon( "death" );
+
+ for ( ;; )
+ {
+ while ( !self fragButtonPressed() || isDefined( self.command ) )
+ wait 0.05;
+
+ self.command = true;
+
+ self iprintln( "Attack - DeleteAll; ADS - Load" );
+ self iprintln( "Else(wait) - Delete" );
+
+ wait getDvarFloat( "bots_main_debug_commandWait" );
+
+ if ( self attackButtonPressed() )
+ self deleteAllWaypoints();
+ else if ( self adsButtonPressed() )
+ self LoadWaypoints();
+ else
+ self DeleteWaypoint( self.closest );
+
+ self.command = undefined;
+
+ while ( self fragButtonPressed() )
+ wait 0.05;
+ }
+}
+
+watchSaveWaypointsCommand()
+{
+ self endon( "death" );
+ self endon( "disconnect" );
+
+ for ( ;; )
+ {
+ while ( !self useButtonPressed() || !self attackButtonPressed() || isDefined( self.command ) )
+ wait 0.05;
+
+ self.command = true;
+
+ self iprintln( "ADS - Autolink; Else(wait) - Save" );
+
+ wait getDvarFloat( "bots_main_debug_commandWait" );
+
+ if ( !self adsButtonPressed() )
+ {
+ self checkForWarnings();
+ wait 1;
+
+ logprint( "***********ABiliTy's WPDump**************\n\n" );
+ logprint( "\n\n\n\n" );
+ mpnm = getMapName( getdvar( "mapname" ) );
+ logprint( "\n\n" + mpnm + "()\n{\n/*" );
+ logprint( "*/waypoints = [];\n/*" );
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ logprint( "*/waypoints[" + i + "] = spawnstruct();\n/*" );
+ logprint( "*/waypoints[" + i + "].origin = " + level.waypoints[i].origin + ";\n/*" );
+ logprint( "*/waypoints[" + i + "].type = \"" + level.waypoints[i].type + "\";\n/*" );
+
+ for ( c = 0; c < level.waypoints[i].children.size; c++ )
+ {
+ logprint( "*/waypoints[" + i + "].children[" + c + "] = " + level.waypoints[i].children[c] + ";\n/*" );
+ }
+
+ if ( isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) )
+ logprint( "*/waypoints[" + i + "].angles = " + level.waypoints[i].angles + ";\n/*" );
+ }
+
+ logprint( "*/return waypoints;\n}\n\n\n\n" );
+
+ filename = "waypoints/" + getdvar( "mapname" ) + "_wp.csv";
+ fd = FS_FOpen( filename, "write" );
+
+ PrintLn( "********* Start Bot Warfare WPDump *********" );
+ PrintLn( level.waypointCount );
+
+ if ( fd > 0 )
+ {
+ if ( !FS_WriteLine( fd, level.waypointCount + "" ) )
+ {
+ FS_FClose( fd );
+ fd = 0;
+ }
+ }
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ str = "";
+ wp = level.waypoints[i];
+
+ str += wp.origin[0] + " " + wp.origin[1] + " " + wp.origin[2] + ",";
+
+ for ( h = 0; h < wp.children.size; h++ )
+ {
+ str += wp.children[h];
+
+ if ( h < wp.children.size - 1 )
+ str += " ";
+ }
+
+ str += "," + wp.type + ",";
+
+ if ( isDefined( wp.angles ) )
+ str += wp.angles[0] + " " + wp.angles[1] + " " + wp.angles[2] + ",";
+ else
+ str += ",";
+
+ str += ",";
+
+ PrintLn( str );
+
+ if ( fd > 0 )
+ {
+ if ( !FS_WriteLine( fd, str ) )
+ {
+ FS_FClose( fd );
+ fd = 0;
+ }
+ }
+ }
+
+ PrintLn( "\n\n\n\n\n\n" );
+
+ self iprintln( "Saved!!! to " + filename );
+
+ if ( fd > 0 )
+ FS_FClose( fd );
+ }
+ else
+ {
+ if ( level.autoLink )
+ {
+ self iPrintlnBold( "Auto link disabled" );
+ level.autoLink = false;
+ level.wpToLink = -1;
+ }
+ else
+ {
+ self iPrintlnBold( "Auto link enabled" );
+ level.autoLink = true;
+ level.wpToLink = self.closest;
+ }
+ }
+
+ self.command = undefined;
+
+ while ( self useButtonPressed() && self attackButtonPressed() )
+ wait 0.05;
+ }
+}
+
+LoadWaypoints()
+{
+ self DeleteAllWaypoints();
+ self iPrintlnBold( "Loading WPS..." );
+ load_waypoints();
+
+ wait 1;
+
+ self checkForWarnings();
+}
+
+checkForWarnings()
+{
+ if ( level.waypointCount <= 0 )
+ self iprintln( "WARNING: waypointCount is " + level.waypointCount );
+
+ if ( level.waypointCount != level.waypoints.size )
+ self iprintln( "WARNING: waypointCount is not " + level.waypoints.size );
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ if ( !isDefined( level.waypoints[i] ) )
+ {
+ self iprintln( "WARNING: waypoint " + i + " is undefined" );
+ continue;
+ }
+
+ if ( level.waypoints[i].children.size <= 0 )
+ self iprintln( "WARNING: waypoint " + i + " childCount is " + level.waypoints[i].children.size );
+ else
+ {
+ if ( !isDefined( level.waypoints[i].children ) || !isDefined( level.waypoints[i].children.size ) )
+ {
+ self iprintln( "WARNING: waypoint " + i + " children is not defined" );
+ }
+ else
+ {
+ for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
+ {
+ child = level.waypoints[i].children[h];
+
+ if ( !isDefined( level.waypoints[child] ) )
+ self iprintln( "WARNING: waypoint " + i + " child " + child + " is undefined" );
+ else if ( child == i )
+ self iprintln( "WARNING: waypoint " + i + " child " + child + " is itself" );
+ }
+ }
+ }
+
+ if ( !isDefined( level.waypoints[i].type ) )
+ {
+ self iprintln( "WARNING: waypoint " + i + " type is undefined" );
+ continue;
+ }
+
+ if ( !isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) )
+ self iprintln( "WARNING: waypoint " + i + " angles is undefined" );
+ }
+}
+
+DeleteAllWaypoints()
+{
+ level.waypoints = [];
+ level.waypointCount = 0;
+
+ self iprintln( "DelAllWps" );
+}
+
+DeleteWaypoint( nwp )
+{
+ if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
+ {
+ self iprintln( "No close enough waypoint to delete." );
+ return;
+ }
+
+ level.wpToLink = -1;
+
+ for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
+ {
+ child = level.waypoints[nwp].children[i];
+
+ level.waypoints[child].children = array_remove( level.waypoints[child].children, nwp );
+ }
+
+ for ( i = 0; i < level.waypointCount; i++ )
+ {
+ for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
+ {
+ if ( level.waypoints[i].children[h] > nwp )
+ level.waypoints[i].children[h]--;
+ }
+ }
+
+ for ( entry = 0; entry < level.waypointCount; entry++ )
+ {
+ if ( entry == nwp )
+ {
+ while ( entry < level.waypointCount - 1 )
+ {
+ level.waypoints[entry] = level.waypoints[entry + 1];
+ entry++;
+ }
+
+ level.waypoints[entry] = undefined;
+ break;
+ }
+ }
+
+ level.waypointCount--;
+
+ self iprintln( "DelWp " + nwp );
+}
+
+addWaypoint( pos )
+{
+ level.waypoints[level.waypointCount] = spawnstruct();
+
+ level.waypoints[level.waypointCount].origin = pos;
+
+ if ( self AdsButtonPressed() )
+ level.waypoints[level.waypointCount].type = "climb";
+ else if ( self AttackButtonPressed() && self UseButtonPressed() )
+ level.waypoints[level.waypointCount].type = "tube";
+ else if ( self AttackButtonPressed() )
+ level.waypoints[level.waypointCount].type = "grenade";
+ else if ( self UseButtonPressed() )
+ level.waypoints[level.waypointCount].type = "claymore";
+ else
+ level.waypoints[level.waypointCount].type = self getStance();
+
+ level.waypoints[level.waypointCount].angles = self getPlayerAngles();
+
+ level.waypoints[level.waypointCount].children = [];
+
+ self iprintln( level.waypoints[level.waypointCount].type + " Waypoint " + level.waypointCount + " Added at " + pos );
+
+ if ( level.autoLink )
+ {
+ if ( level.wpToLink == -1 )
+ level.wpToLink = level.waypointCount - 1;
+
+ level.waypointCount++;
+ self LinkWaypoint( level.waypointCount - 1 );
+ }
+ else
+ {
+ level.waypointCount++;
+ }
+}
+
+UnLinkWaypoint( nwp )
+{
+ if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
+ {
+ self iprintln( "Waypoint Unlink Cancelled " + level.wpToLink );
+ level.wpToLink = -1;
+ return;
+ }
+
+ if ( level.wpToLink == -1 || nwp == level.wpToLink )
+ {
+ level.wpToLink = nwp;
+ self iprintln( "Waypoint Unlink Started " + nwp );
+ return;
+ }
+
+ level.waypoints[nwp].children = array_remove( level.waypoints[nwp].children, level.wpToLink );
+ level.waypoints[level.wpToLink].children = array_remove( level.waypoints[level.wpToLink].children, nwp );
+
+ self iprintln( "Waypoint " + nwp + " Broken to " + level.wpToLink );
+ level.wpToLink = -1;
+}
+
+LinkWaypoint( nwp )
+{
+ if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
+ {
+ self iprintln( "Waypoint Link Cancelled " + level.wpToLink );
+ level.wpToLink = -1;
+ return;
+ }
+
+ if ( level.wpToLink == -1 || nwp == level.wpToLink )
+ {
+ level.wpToLink = nwp;
+ self iprintln( "Waypoint Link Started " + nwp );
+ return;
+ }
+
+ weGood = true;
+
+ for ( i = level.waypoints[level.wpToLink].children.size - 1; i >= 0; i-- )
+ {
+ if ( level.waypoints[level.wpToLink].children[i] == nwp )
+ {
+ weGood = false;
+ break;
+ }
+ }
+
+ if ( weGood )
+ {
+ for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
+ {
+ if ( level.waypoints[nwp].children[i] == level.wpToLink )
+ {
+ weGood = false;
+ break;
+ }
+ }
+ }
+
+ if ( !weGood )
+ {
+ self iprintln( "Waypoint Link Cancelled " + nwp + " and " + level.wpToLink + " already linked." );
+ level.wpToLink = -1;
+ return;
+ }
+
+ level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].children.size] = nwp;
+ level.waypoints[nwp].children[level.waypoints[nwp].children.size] = level.wpToLink;
+
+ self iprintln( "Waypoint " + nwp + " Linked to " + level.wpToLink );
+ level.wpToLink = -1;
+}
+
+destroyOnDeath( hud )
+{
+ hud endon( "death" );
+ self waittill_either( "death", "disconnect" );
+ hud destroy();
+}
+
+textScroll( string )
+{
+ self endon( "death" );
+ self endon( "disconnect" );
+ //thanks ActionScript
+
+ back = createBar( ( 0, 0, 0 ), 1000, 30 );
+ back setPoint( "CENTER", undefined, 0, 220 );
+ self thread destroyOnDeath( back );
+
+ text = createFontString( "default", 1.5 );
+ text setText( string );
+ self thread destroyOnDeath( text );
+
+ for ( ;; )
+ {
+ text setPoint( "CENTER", undefined, 1200, 220 );
+ text setPoint( "CENTER", undefined, -1200, 220, 20 );
+ wait 20;
+ }
+}
diff --git a/out/readme.txt b/out/readme.txt
index 6bde1ce..86ac30f 100644
--- a/out/readme.txt
+++ b/out/readme.txt
@@ -1,4 +1,4 @@
-# CoD4x Bot Warfare
+# CoD4x Bot Warfare v2.1.0
Bot Warfare is a GSC mod for the CoD4x project.
It aims to add playable AI to the multiplayer games of CoD4.
@@ -12,7 +12,7 @@ Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your s
## Installation
0. Make sure that CoD4x server + client is installed, updated and working properly.
- - Go to https://cod4x.me/ and download the Windows Server zip file. Move the contents of 'cod4x-windows-server' into your CoD4 game folder.
+ - Go to https://cod4x.ovh/ and download the Windows Server zip file. Move the contents of 'cod4x-windows-server' into your CoD4 game folder.
1. Locate your CoD4x server install folder.
2. Move the files/folders found in 'Add to root of CoD4x server' from the Bot Warfare release archive you downloaded to the root of your CoD4x server folder.
- The folder/file structure should follow as '.CoD4x server folder\main_shared\maps\mp\bots\_bot.gsc'.
@@ -30,6 +30,17 @@ Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your s
- Pressing the menu button again closes menus.
## Changelog
+- v2.1.0
+ - Bot chatter system, bots_main_chat
+ - Greatly reduce script variable usage
+ - Improved bots mantling and stuck
+ - Fix some runtime errors
+ - Bots sprint more
+ - Improved bots sight on enemies
+ - Bots do random actions while waiting at an objective
+ - Improved bots from getting stuck
+ - Better bot difficulty management, bots_skill_min and bots_skill_max
+
- v2.0.1
- Reduced bots crouching
- Increased bots sprinting
diff --git a/out/ss.jpg b/out/ss.jpg
new file mode 100644
index 0000000..98cd01d
Binary files /dev/null and b/out/ss.jpg differ
diff --git a/out/ss.png b/out/ss.png
deleted file mode 100644
index 58e2b96..0000000
Binary files a/out/ss.png and /dev/null differ