16 Commits

Author SHA1 Message Date
93b82d7720 use wrapper 2025-01-23 23:56:31 -06:00
d19be1dd2d fix this var leak 2025-01-23 23:48:35 -06:00
223c6e4664 democlient checks 2025-01-17 23:40:05 -06:00
28bfe5bbda demo records without players 2025-01-16 20:11:03 -06:00
9cbff651ce more funcs 2025-01-15 00:58:51 -06:00
232938dfd7 pt5mp rewrite 2025-01-02 10:12:21 -06:00
2e7cf4fb9c more comments 2024-11-16 12:32:41 -06:00
9604ea1df3 Merge branch 'master' of https://github.com/ineedbots/bo1_bot_warfare 2024-10-22 10:06:04 -06:00
80865977ad wait for notifies 2024-10-22 10:06:02 -06:00
80de21a3a5 Update README.md 2024-08-13 11:36:29 -06:00
2d18695341 added bots_manage_fill_watchplayers 2024-05-16 23:07:33 -06:00
ee26e6b33f note 2024-04-30 13:14:30 -06:00
d95a6491ee small update 2024-04-30 12:56:21 -06:00
82c0c1152d chat event 2024-04-26 13:42:15 -06:00
c4481626a5 playername 2024-04-25 14:51:03 -06:00
65435391bc connection events 2024-04-25 14:25:36 -06:00
7 changed files with 297 additions and 231 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
*.zip *.zip
*.log *.log*
*.stat *.stat
logs/ logs/
demos/ demos/

View File

@ -60,15 +60,17 @@ This mod extends the functionality and features of Combat Training in Black Ops
|----------------------------------|---------------------------------------------------------------------------------------------|--------------:| |----------------------------------|---------------------------------------------------------------------------------------------|--------------:|
| bots_main | Enable this mod. | 1 | | bots_main | Enable this mod. | 1 |
| bots_main_waitForHostTime | How many seconds to wait for the host player to connect before adding bots to the match. | 10 | | bots_main_waitForHostTime | How many seconds to wait for the host player to connect before adding bots to the match. | 10 |
| bots_main_debug | Enable bot event prints. <ul><li>`0` - disable</li><li>`1` - for just debug events</li><li>`2` - for every event</li><ul> | 0 |
| bots_main_kickBotsAtEnd | Kick the bots at the end of a match. | 0 | | bots_main_kickBotsAtEnd | Kick the bots at the end of a match. | 0 |
| bots_manage_add | Amount of bots to add to the game, once bots are added, resets back to `0`. | 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 | 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.<ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots.</li></ul> | 0 | | bots_manage_fill_mode | `bots_manage_fill` players/bots counting method.<ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots.</li><li>`2` - exactly `0` but auto adjusts `bots_manage_fill` to map.</li><li>`3` - exactly `1` but auto adjusts `bots_manage_fill` to map.</li><li>`4` - bots are used for balancing teams.</li><li>`5` - exactly `4` but auto adjusts `bots_manage_fill` to map.</li></ul> | 0 |
| bots_manage_fill_kick | If the amount of players/bots in the match exceeds `bots_manage_fill`, kick bots until no longer exceeds. | 0 | | bots_manage_fill_watchplayers | Bots will not be added until one player is in the game | 0 |
| bots_manage_fill_kick | If the amount of players/bots in the match exceeds `bots_manage_fill`, kick bots until no longer exceeds. | 0 |
| bots_manage_fill_spec | If when counting players for `bots_manage_fill` should include spectators. | 1 | | bots_manage_fill_spec | If when counting players for `bots_manage_fill` should include spectators. | 1 |
| bots_team | One of `autoassign`, `allies`, `axis`, `spectator`, or `custom`. What team the bots should be on. | autoassign | | bots_team | One of `autoassign`, `allies`, `axis`, `spectator`, or `custom`. What team the bots should be on. | autoassign |
| bots_team_amount | When `bots_team` is set to `custom`. The amount of bots to be placed on the axis team. The remainder will be placed on the allies team. | 0 | | bots_team_amount | When `bots_team` is set to `custom`. The amount of bots to be placed on the axis team. The remainder will be placed on the allies team. | 0 |
| bots_team_force | If the server should force bots' teams according to the `bots_team` value. When `bots_team` is `autoassign`, unbalanced teams will be balanced. This dvar is ignored when `bots_team` is `custom`. | 0 | | bots_team_force | If the server should force bots' teams according to the `bots_team` value. When `bots_team` is `autoassign`, unbalanced teams will be balanced. This dvar is ignored when `bots_team` is `custom`. | 0 |
| bots_team_mode | When `bots_team_force` is `1` and `bots_team` is `autoassign`, players/bots counting method. <ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots</li></ul> | 0 | | bots_team_mode | When `bots_team_force` is `1` and `bots_team` is `autoassign`, players/bots counting method. <ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots</li></ul> | 0 |
| bots_loadout_reasonable | If the bots should filter bad performing create-a-class selections. | 0 | | bots_loadout_reasonable | If the bots should filter bad performing create-a-class selections. | 0 |
| bots_loadout_allow_op | If the bots should be able to use overpowered and annoying create-a-class selections. | 1 | | bots_loadout_allow_op | If the bots should be able to use overpowered and annoying create-a-class selections. | 1 |
@ -87,9 +89,11 @@ This mod extends the functionality and features of Combat Training in Black Ops
| bots_play_aim | If the bots can aim. | 1 | | bots_play_aim | If the bots can aim. | 1 |
## Changelog ## Changelog
- v1.2.0 - v1.2.0 (not released yet)
- Bots can now melee lunge - Bots can now melee lunge
- Bots can now jumpshot and dropshot - Bots can now jumpshot and dropshot
- Fixed bots_manage_fill_spec players being counted with bots_manage_fill_mode 1 (bot only)
- Added bots_manage_fill_watchplayers dvar
- Fix some script runtime errors - Fix some script runtime errors
- Improved bots using altmode weapons - Improved bots using altmode weapons
- Improved bots taking spyplanes down - Improved bots taking spyplanes down
@ -129,7 +133,7 @@ This mod extends the functionality and features of Combat Training in Black Ops
## Credits ## Credits
- INeedGames - http://www.moddb.com/mods/bot-warfare - INeedGames - http://www.moddb.com/mods/bot-warfare
- apdonato - http://rsebots.blogspot.ca/ - apdonato - https://web.archive.org/web/20240516065610/http://rsebots.blogspot.com/
Feel free to use code, host on other sites, host on servers, mod it and merge mods with it, just give credit where credit is due! Feel free to use code, host on other sites, host on servers, mod it and merge mods with it, just give credit where credit is due!
-INeedGames/INeedBot(s) @ ineedbots@outlook.com -INeedGames/INeedBot(s) @ ineedbots@outlook.com

View File

@ -216,7 +216,7 @@ bot_get_prestige()
continue; continue;
} }
if ( player is_bot() ) if ( player is_bot() || player isdemoclient() )
{ {
continue; continue;
} }
@ -1246,7 +1246,7 @@ bot_get_cod_points()
for ( i = 0; i < players.size; i++ ) for ( i = 0; i < players.size; i++ )
{ {
if ( players[ i ] is_bot() ) if ( players[ i ] is_bot() || players[ i ] isdemoclient() )
{ {
continue; continue;
} }

View File

@ -166,7 +166,7 @@ bot_on_spawn()
for ( ;; ) for ( ;; )
{ {
self waittill( "spawned_player" ); self waittill( "spawned_player" );
self BotBuiltinClearOverrides( true ); self BotBuiltinClearOverride( false );
self BotBuiltinWeaponOverride( self getcurrentweapon() ); self BotBuiltinWeaponOverride( self getcurrentweapon() );
self.bot_is_doing_some_other_override = false; self.bot_is_doing_some_other_override = false;
@ -405,6 +405,8 @@ bot_spawn()
{ {
self thread bot_use_equipment_think(); self thread bot_use_equipment_think();
self thread bot_watch_think_mw2(); self thread bot_watch_think_mw2();
// self thread bot_use_tube_think();
// self thread bot_use_grenade_think();
} }
if ( getdvarint( "bots_play_target_other" ) ) if ( getdvarint( "bots_play_target_other" ) )
@ -425,7 +427,7 @@ bot_spawn()
self thread bot_uav_think(); self thread bot_uav_think();
self thread bot_weapon_think(); self thread bot_weapon_think();
// todo: reload cancel // self thread doReloadCancel();
self thread bot_listen_to_steps(); self thread bot_listen_to_steps();
self thread bot_revenge_think(); self thread bot_revenge_think();
self thread follow_target(); self thread follow_target();
@ -1260,6 +1262,12 @@ bot_killstreak_think_loop()
return; return;
} }
if ( maps\mp\gametypes\_hardpoints::iskillstreakweapon( curWeap ) && curWeap != "m220_tow_mp" && curWeap != "m202_flash_mp" && curWeap != "minigun_mp" )
{
self thread changeToWeapon( self.lastnonkillstreakweapon );
return;
}
weapon = self maps\mp\gametypes\_hardpoints::gettopkillstreak(); weapon = self maps\mp\gametypes\_hardpoints::gettopkillstreak();
if ( !isdefined( weapon ) || weapon == "none" ) if ( !isdefined( weapon ) || weapon == "none" )
@ -2441,7 +2449,7 @@ do_bot_plane_combat( plane, weap )
self endon( "missile_fire" ); self endon( "missile_fire" );
time = 7; time = 7;
self BotBuiltinAimOverride(); self BotBuiltinAimOverride( true );
while ( time > 0 && isdefined( plane ) && isalive( plane ) && self getcurrentweapon() == weap && !self inLastStand() && !isdefined( self getthreat() ) ) while ( time > 0 && isdefined( plane ) && isalive( plane ) && self getcurrentweapon() == weap && !self inLastStand() && !isdefined( self getthreat() ) )
{ {
@ -2450,7 +2458,7 @@ do_bot_plane_combat( plane, weap )
if ( bullettracepassed( myeye, plane.origin, false, plane ) ) if ( bullettracepassed( myeye, plane.origin, false, plane ) )
{ {
self thread bot_lookat( plane.origin, 0.3 ); self thread bot_lookat( plane.origin, 0.3 );
self BotBuiltinButtonOverride( "ads", "enable" ); self BotBuiltinButtonOverride( "+ads" );
if ( isdefined( self.stingerlockfinalized ) && self.stingerlockfinalized ) if ( isdefined( self.stingerlockfinalized ) && self.stingerlockfinalized )
{ {
@ -2459,7 +2467,7 @@ do_bot_plane_combat( plane, weap )
} }
else else
{ {
self BotBuiltinButtonOverride( "ads", "disable" ); self BotBuiltinButtonOverride( "-ads" );
} }
time -= 0.05; time -= 0.05;
@ -2491,8 +2499,8 @@ bot_plane_attack( plane )
self do_bot_plane_combat( plane, weap ); self do_bot_plane_combat( plane, weap );
self notify( "bots_aim_overlap" ); self notify( "bots_aim_overlap" );
self BotBuiltinClearAimOverride(); self BotBuiltinAimOverride( false );
self BotBuiltinClearButtonOverride( "ads" ); self BotBuiltinButtonOverride( "~ads" );
} }
self.bot_is_doing_some_other_override = false; self.bot_is_doing_some_other_override = false;
@ -6397,8 +6405,8 @@ watch_for_melee_override()
angles = vectortoangles( threat.origin - self.origin ); angles = vectortoangles( threat.origin - self.origin );
self BotBuiltinBotMeleeParams( angles[ 1 ], dist ); self BotBuiltinBotMeleeParams( angles[ 1 ], dist );
self BotBuiltinButtonOverride( "melee", "enable" ); self BotBuiltinButtonOverride( "+melee" );
self BotBuiltinAimOverride(); self BotBuiltinAimOverride( true );
time_left = 1; time_left = 1;
once = false; once = false;
@ -6412,17 +6420,17 @@ watch_for_melee_override()
if ( !once ) if ( !once )
{ {
once = true; once = true;
self BotBuiltinClearButtonOverride( "melee" ); self BotBuiltinButtonOverride( "~melee" );
} }
} }
if ( !once ) if ( !once )
{ {
self BotBuiltinClearButtonOverride( "melee" ); self BotBuiltinButtonOverride( "~melee" );
} }
self BotBuiltinClearMeleeParams(); self BotBuiltinBotMeleeParams( false );
self BotBuiltinClearAimOverride(); self BotBuiltinAimOverride( false );
wait 1; wait 1;
break; break;
@ -6490,7 +6498,7 @@ watch_for_override_stuff()
if ( need_to_clear_mantle_override && ( time - last_jump_time ) > 3000 ) if ( need_to_clear_mantle_override && ( time - last_jump_time ) > 3000 )
{ {
need_to_clear_mantle_override = false; need_to_clear_mantle_override = false;
self BotBuiltinClearMantleOverride(); self BotBuiltinMantleOverride( false );
} }
weapon_is_good = true; weapon_is_good = true;
@ -6512,28 +6520,28 @@ watch_for_override_stuff()
{ {
last_jump_time = time; last_jump_time = time;
need_to_clear_mantle_override = true; need_to_clear_mantle_override = true;
self BotBuiltinMantleOverride(); self BotBuiltinMantleOverride( true );
// drop shot // drop shot
self BotBuiltinMovementOverride( 0, 0 ); self BotBuiltinMovementOverride( 0, 0 );
self BotBuiltinButtonOverride( "prone", "enable" ); self BotBuiltinButtonOverride( "+prone" );
wait 1.5; wait 1.5;
self BotBuiltinClearMovementOverride(); self BotBuiltinMovementOverride( false );
self BotBuiltinClearButtonOverride( "prone" ); self BotBuiltinButtonOverride( "~prone" );
} }
} }
else else
{ {
last_jump_time = time; last_jump_time = time;
need_to_clear_mantle_override = true; need_to_clear_mantle_override = true;
self BotBuiltinMantleOverride(); self BotBuiltinMantleOverride( true );
// jump shot // jump shot
self BotBuiltinButtonOverride( "gostand", "enable" ); self BotBuiltinButtonOverride( "+gostand" );
wait 0.1; wait 0.1;
self BotBuiltinClearButtonOverride( "gostand" ); self BotBuiltinButtonOverride( "~gostand" );
} }
} }

View File

@ -49,6 +49,46 @@ BotBuiltinPrintConsole( s )
} }
} }
/*
*/
BotBuiltinDisableDetourOnce( s )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "disabledetouronce" ] ) )
{
[[ level.bot_builtins[ "disabledetouronce" ] ]]( s );
}
}
/*
*/
BotBuiltinReplaceFunc( s, b )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "replacefunc" ] ) )
{
return [[ level.bot_builtins[ "replacefunc" ] ]]( s, b );
}
}
/*
*/
BotBuiltinGetFunction( s, b )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "getfunction" ] ) )
{
return [[ level.bot_builtins[ "getfunction" ] ]]( s, b );
}
}
/*
*/
BotBuiltinClearOverride( a )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearoverride" ] ) )
{
self [[ level.bot_builtins[ "botclearoverride" ] ]]( a );
}
}
/* /*
*/ */
BotBuiltinMovementOverride( a, b ) BotBuiltinMovementOverride( a, b )
@ -61,71 +101,21 @@ BotBuiltinMovementOverride( a, b )
/* /*
*/ */
BotBuiltinClearMovementOverride() BotBuiltinButtonOverride( a )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearmovementoverride" ] ) )
{
self [[ level.bot_builtins[ "botclearmovementoverride" ] ]]();
}
}
/*
*/
BotBuiltinClearButtonOverride( a )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearbuttonoverride" ] ) )
{
self [[ level.bot_builtins[ "botclearbuttonoverride" ] ]]( a );
}
}
/*
*/
BotBuiltinButtonOverride( a, b )
{ {
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botbuttonoverride" ] ) ) if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botbuttonoverride" ] ) )
{ {
self [[ level.bot_builtins[ "botbuttonoverride" ] ]]( a, b ); self [[ level.bot_builtins[ "botbuttonoverride" ] ]]( a );
} }
} }
/* /*
*/ */
BotBuiltinClearOverrides( a ) BotBuiltinMantleOverride( a )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearoverrides" ] ) )
{
self [[ level.bot_builtins[ "botclearoverrides" ] ]]( a );
}
}
/*
*/
BotBuiltinMantleOverride()
{ {
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botmantleoverride" ] ) ) if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botmantleoverride" ] ) )
{ {
self [[ level.bot_builtins[ "botmantleoverride" ] ]](); self [[ level.bot_builtins[ "botmantleoverride" ] ]]( a );
}
}
/*
*/
BotBuiltinClearMantleOverride()
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearmantleoverride" ] ) )
{
self [[ level.bot_builtins[ "botclearmantleoverride" ] ]]();
}
}
/*
*/
BotBuiltinClearWeaponOverride()
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearweaponoverride" ] ) )
{
self [[ level.bot_builtins[ "botclearweaponoverride" ] ]]();
} }
} }
@ -141,31 +131,11 @@ BotBuiltinWeaponOverride( a )
/* /*
*/ */
BotBuiltinClearButtonOverrides() BotBuiltinAimOverride( a )
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearbuttonoverrides" ] ) )
{
self [[ level.bot_builtins[ "botclearbuttonoverrides" ] ]]();
}
}
/*
*/
BotBuiltinAimOverride()
{ {
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botaimoverride" ] ) ) if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botaimoverride" ] ) )
{ {
self [[ level.bot_builtins[ "botaimoverride" ] ]](); self [[ level.bot_builtins[ "botaimoverride" ] ]]( a );
}
}
/*
*/
BotBuiltinClearAimOverride()
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botclearaimoverride" ] ) )
{
self [[ level.bot_builtins[ "botclearaimoverride" ] ]]();
} }
} }
@ -174,19 +144,9 @@ BotBuiltinClearAimOverride()
*/ */
BotBuiltinBotMeleeParams( yaw, dist ) BotBuiltinBotMeleeParams( yaw, dist )
{ {
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botmeleeparams" ] ) ) if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "botmeleeparamsoverride" ] ) )
{ {
self [[ level.bot_builtins[ "botmeleeparams" ] ]]( yaw, dist ); self [[ level.bot_builtins[ "botmeleeparamsoverride" ] ]]( yaw, dist );
}
}
/*
*/
BotBuiltinClearMeleeParams()
{
if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins[ "clearbotmeleeparams" ] ) )
{
self [[ level.bot_builtins[ "clearbotmeleeparams" ] ]]();
} }
} }

View File

@ -10,6 +10,70 @@
#include maps\mp\gametypes\_hud_util; #include maps\mp\gametypes\_hud_util;
#include maps\mp\bots\_bot_utility; #include maps\mp\bots\_bot_utility;
/*
*/
main()
{
level.bw_version = "1.2.0";
if ( getdvar( "bots_main" ) == "" )
{
setdvar( "bots_main", true );
}
if ( !getdvarint( "bots_main" ) )
{
return;
}
if ( !wait_for_builtins() )
{
println( "FATAL: NO BUILT-INS FOR BOTS" );
}
// fix var leak
BotBuiltinReplaceFunc( BotBuiltinGetFunction( "maps/mp/gametypes/_hud_util", "destroyelem" ), ::destroyElemFixed );
}
/*
Fix leak with menus
*/
removeChildFixed( element )
{
temp = [];
for ( i = 0; i < self.children.size ; i++ )
{
if ( isdefined( self.children[ i ] ) && self.children[ i ] != element )
{
self.children[ i ].index = temp.size;
temp[ temp.size ] = self.children[ i ];
}
}
self.children = temp;
}
/*
Fix leak with menus
*/
destroyElemFixed()
{
if ( !isdefined( self ) )
{
return;
}
if ( isdefined( self.parent ) )
{
self.parent removeChildFixed( self );
}
func = BotBuiltinGetFunction( "maps/mp/gametypes/_hud_util", "destroyelem" );
BotBuiltinDisableDetourOnce( func );
self [[ func ]]();
}
/* /*
Entry point to the bots Entry point to the bots
*/ */
@ -17,8 +81,6 @@ init()
{ {
level.bw_version = "1.2.0"; level.bw_version = "1.2.0";
level.bot_offline = false;
if ( getdvar( "bots_main" ) == "" ) if ( getdvar( "bots_main" ) == "" )
{ {
setdvar( "bots_main", true ); setdvar( "bots_main", true );
@ -69,6 +131,11 @@ init()
setdvar( "bots_manage_fill_kick", false ); // kick bots if too many setdvar( "bots_manage_fill_kick", false ); // kick bots if too many
} }
if ( getdvar( "bots_manage_fill_watchplayers" ) == "" )
{
setdvar( "bots_manage_fill_watchplayers", false ); // add bots when player exists, kick if not
}
if ( getdvar( "bots_skill" ) == "" ) // alias for bot_difficulty if ( getdvar( "bots_skill" ) == "" ) // alias for bot_difficulty
{ {
setdvar( "bots_skill", "" ); setdvar( "bots_skill", "" );
@ -181,8 +248,12 @@ init()
if ( !isdefined( game[ "botWarfare" ] ) ) if ( !isdefined( game[ "botWarfare" ] ) )
{ {
game[ "botWarfare" ] = true; game[ "botWarfare" ] = true;
game[ "botWarfareInitTime" ] = gettime();
} }
level.bot_inittime = gettime();
level.demorecord_minplayers = max( 0, getdvarint( #"scr_demorecord_minplayers" ) );
thread fixGamemodes(); thread fixGamemodes();
thread onPlayerConnect(); thread onPlayerConnect();
thread bot_watch_planes(); thread bot_watch_planes();
@ -190,6 +261,9 @@ init()
thread handleBots(); thread handleBots();
thread doNonDediBots(); thread doNonDediBots();
level thread onPlayerChat();
// todo: _bot_chat
} }
/* /*
@ -236,6 +310,23 @@ handleBots()
} }
} }
/*
When a bot disconnects.
*/
onDisconnectPlayer()
{
name = self.name;
self waittill( "disconnect" );
waittillframeend;
for ( i = 0; i < level.bots.size; i++ )
{
bot = level.bots[ i ];
bot BotNotifyBotEvent( "connection", "disconnected", self, name );
}
}
/* /*
When a bot disconnects. When a bot disconnects.
*/ */
@ -253,19 +344,39 @@ connected()
{ {
self endon( "disconnect" ); self endon( "disconnect" );
for ( i = 0; i < level.bots.size; i++ )
{
bot = level.bots[ i ];
bot BotNotifyBotEvent( "connection", "connected", self, self.name );
}
self thread onDisconnectPlayer();
if ( !self is_bot() ) if ( !self is_bot() )
{ {
return; return;
} }
if ( !isdefined( self.pers[ "isBot" ] ) )
{
// fast restart...
self.pers[ "isBot" ] = true;
}
if ( !isdefined( self.pers[ "isBotWarfare" ] ) )
{
self.pers[ "isBotWarfare" ] = true;
self thread maps\mp\bots\_bot_script::added();
}
self thread maps\mp\bots\_bot_script::connected(); self thread maps\mp\bots\_bot_script::connected();
level.bots[ level.bots.size ] = self; level.bots[ level.bots.size ] = self;
self thread onDisconnect(); self thread onDisconnect();
level notify( "bot_connected", self );
self thread watchBotDebugEvent(); self thread watchBotDebugEvent();
waittillframeend; // wait for waittills to process
level notify( "bot_connected", self );
} }
/* /*
@ -755,7 +866,7 @@ addBots_loop()
fillMode = getdvarint( "bots_manage_fill_mode" ); fillMode = getdvarint( "bots_manage_fill_mode" );
if ( fillMode == 2 || fillMode == 3 ) if ( fillMode == 2 || fillMode == 3 || fillMode == 5 )
{ {
setdvar( "bots_manage_fill", getGoodMapAmount() ); setdvar( "bots_manage_fill", getGoodMapAmount() );
} }
@ -765,6 +876,8 @@ addBots_loop()
players = 0; players = 0;
bots = 0; bots = 0;
spec = 0; spec = 0;
axisplayers = 0;
alliesplayers = 0;
playercount = level.players.size; playercount = level.players.size;
@ -788,29 +901,6 @@ addBots_loop()
else else
{ {
players++; players++;
}
}
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" ) if ( player.pers[ "team" ] == "axis" )
{ {
@ -821,26 +911,11 @@ addBots_loop()
alliesplayers++; alliesplayers++;
} }
} }
}
result = fillAmount - abs( axisplayers - alliesplayers ) + bots; if ( getdvarint( "bots_manage_fill_spec" ) )
{
if ( players == 0 ) players += spec;
{
if ( bots < fillAmount )
{
result = fillAmount - 1;
}
else if ( bots > fillAmount )
{
result = fillAmount + 1;
}
else
{
result = fillAmount;
}
}
bots = result;
} }
if ( !randomint( 999 ) ) if ( !randomint( 999 ) )
@ -858,22 +933,46 @@ addBots_loop()
amount += players; amount += players;
} }
if ( getdvarint( "bots_manage_fill_spec" ) ) // use bots as balance
if ( fillMode == 4 || fillMode == 5 )
{ {
amount += spec; diffPlayers = abs( alliesplayers - axisplayers );
amount = fillAmount - ( diffPlayers - bots );
if ( players + diffPlayers < fillAmount )
{
amount = players + bots;
}
}
if ( players <= 0 && getdvarint( "bots_manage_fill_watchplayers" ) )
{
amount = fillAmount + bots;
} }
if ( amount < fillAmount ) if ( amount < fillAmount )
{ {
setdvar( "bots_manage_add", 1 ); setdvar( "bots_manage_add", fillAmount - amount );
} }
else if ( amount > fillAmount && getdvarint( "bots_manage_fill_kick" ) ) else if ( amount > fillAmount && getdvarint( "bots_manage_fill_kick" ) )
{ {
tempBot = getBotToKick(); botsToKick = amount - fillAmount;
if ( isdefined( tempBot ) ) if ( botsToKick > 64 )
{ {
kick( tempBot getentitynumber(), "EXE_PLAYERKICKED" ); botsToKick = 64;
}
for ( i = 0; i < botsToKick; i++ )
{
tempBot = getBotToKick();
if ( isdefined( tempBot ) )
{
kick( tempBot getentitynumber(), "EXE_PLAYERKICKED" );
wait 0.25;
}
} }
} }
} }
@ -1236,3 +1335,21 @@ fixGamemodes()
wait 0.05; wait 0.05;
} }
} }
/*
When a player chats
*/
onPlayerChat()
{
for ( ;; )
{
level waittill( "say", message, player, is_hidden );
for ( i = 0; i < level.bots.size; i++ )
{
bot = level.bots[ i ];
bot BotNotifyBotEvent( "chat", "chat", message, player, is_hidden );
}
}
}

View File

@ -1,25 +1,37 @@
init() main()
{ {
level.bot_builtins[ "printconsole" ] = ::do_printconsole; level.bot_builtins[ "printconsole" ] = ::do_printconsole;
level.bot_builtins[ "botmovementoverride" ] = ::do_botmovementoverride; level.bot_builtins[ "botmovementoverride" ] = ::do_botmovementoverride;
level.bot_builtins[ "botclearmovementoverride" ] = ::do_botclearmovementoverride;
level.bot_builtins[ "botclearbuttonoverride" ] = ::do_botclearbuttonoverride;
level.bot_builtins[ "botbuttonoverride" ] = ::do_botbuttonoverride; level.bot_builtins[ "botbuttonoverride" ] = ::do_botbuttonoverride;
level.bot_builtins[ "botclearoverrides" ] = ::do_botclearoverrides; level.bot_builtins[ "botclearoverride" ] = ::do_botclearoverride;
level.bot_builtins[ "botmantleoverride" ] = ::do_botmantleoverride; level.bot_builtins[ "botmantleoverride" ] = ::do_botmantleoverride;
level.bot_builtins[ "botclearmantleoverride" ] = ::do_botclearmantleoverride;
level.bot_builtins[ "botclearweaponoverride" ] = ::do_botclearweaponoverride;
level.bot_builtins[ "botweaponoverride" ] = ::do_botweaponoverride; level.bot_builtins[ "botweaponoverride" ] = ::do_botweaponoverride;
level.bot_builtins[ "botclearbuttonoverrides" ] = ::do_botclearbuttonoverrides;
level.bot_builtins[ "botaimoverride" ] = ::do_botaimoverride; level.bot_builtins[ "botaimoverride" ] = ::do_botaimoverride;
level.bot_builtins[ "botclearaimoverride" ] = ::do_botclearaimoverride; level.bot_builtins[ "botmeleeparamsoverride" ] = ::do_botmeleeparamsoverride;
level.bot_builtins[ "botmeleeparams" ] = ::do_botmeleeparams; level.bot_builtins[ "replacefunc" ] = ::do_replacefunc;
level.bot_builtins[ "clearbotmeleeparams" ] = ::do_clearbotmeleeparams; level.bot_builtins[ "getfunction" ] = ::do_getfunction;
level.bot_builtins[ "disabledetouronce" ] = ::do_disabledetouronce;
maps\mp\gametypes\_bot::main();
}
do_replacefunc( a, b )
{
return replacefunc( a, b );
}
do_getfunction( a, b )
{
return getfunction( a, b );
} }
do_printconsole( s ) do_printconsole( s )
{ {
println( s ); printf( s );
}
do_disabledetouronce( s )
{
disabledetouronce( s );
} }
do_botmovementoverride( a, b ) do_botmovementoverride( a, b )
@ -27,39 +39,19 @@ do_botmovementoverride( a, b )
self botmovementoverride( a, b ); self botmovementoverride( a, b );
} }
do_botclearmovementoverride() do_botclearoverride( a )
{ {
self botclearmovementoverride(); self botclearoverride( a );
} }
do_botclearbuttonoverride( a ) do_botbuttonoverride( a )
{ {
self botclearbuttonoverride( a ); self botbuttonoverride( a );
} }
do_botbuttonoverride( a, b ) do_botmantleoverride( a )
{ {
self botbuttonoverride( a, b ); self botmantleoverride( a );
}
do_botclearoverrides( a )
{
self botclearoverrides( a );
}
do_botmantleoverride()
{
self botmantleoverride();
}
do_botclearmantleoverride()
{
self botclearmantleoverride();
}
do_botclearweaponoverride()
{
self botclearweaponoverride();
} }
do_botweaponoverride( a ) do_botweaponoverride( a )
@ -67,27 +59,12 @@ do_botweaponoverride( a )
self botweaponoverride( a ); self botweaponoverride( a );
} }
do_botclearbuttonoverrides() do_botaimoverride( a )
{ {
self botclearbuttonoverrides(); self botaimoverride( a );
} }
do_botaimoverride() do_botmeleeparamsoverride( yaw, dist )
{ {
self botaimoverride(); self botmeleeparamsoverride( yaw, dist );
}
do_botclearaimoverride()
{
self botclearaimoverride();
}
do_botmeleeparams( yaw, dist )
{
self botmeleeparams( yaw, dist );
}
do_clearbotmeleeparams()
{
self botclearmeleeparams();
} }