Version 2.1.0

This commit is contained in:
ineed bots 2022-05-08 17:46:25 -06:00
parent 9c20cf621b
commit a64a0cc810
15 changed files with 9340 additions and 5631 deletions

View File

@ -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/).
## <span style="color:red">Important to public dedicated servers</span>
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.<ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots.</li></ul> | 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

@ -1 +1 @@
Subproject commit 65a344f95388f6d0f0704f3c4517283670bb2818
Subproject commit c734ac790d590225e613fa3c2b10f411c29885aa

View File

@ -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 );

File diff suppressed because it is too large Load Diff

View File

@ -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], ",");
tokens = tokenizeLine( res.lines[i], "," );
waypoint = parseTokensIntoWaypoint(tokens);
waypoint = parseTokensIntoWaypoint( tokens );
waypoints[i-1] = waypoint;
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<data.size;i++)
for ( i = 0; i < data.size; i++ )
{
c = data[i];
if (c == "\n")
if ( c == "\n" )
{
result.lines[result.lines.size] = line;
if (fd > 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;
}

View File

@ -12,80 +12,81 @@
init()
{
if(getDvar("bots_main_debug") == "")
setDvar("bots_main_debug", 0);
if ( getDvar( "bots_main_debug" ) == "" )
setDvar( "bots_main_debug", 0 );
if(!getDVarint("bots_main_debug"))
if ( !getDVarint( "bots_main_debug" ) )
return;
if(!getDVarint("developer"))
if ( !getDVarint( "developer" ) )
{
setdvar("developer_script", 1);
setdvar("developer", 1);
setdvar( "developer_script", 1 );
setdvar( "developer", 1 );
setdvar("sv_mapRotation", "map "+getDvar("mapname"));
exitLevel(false);
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);
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_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_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_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_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_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_framerate" ) == "" )
setDvar( "bots_main_debug_framerate", 58 );
if(getDvar("bots_main_debug_lineDuration") == "")
setDvar("bots_main_debug_lineDuration", 3);
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_printDuration" ) == "" )
setDvar( "bots_main_debug_printDuration", 3 );
if(getDvar("bots_main_debug_debugRate") == "")
setDvar("bots_main_debug_debugRate", 0.5);
if ( getDvar( "bots_main_debug_debugRate" ) == "" )
setDvar( "bots_main_debug_debugRate", 0.5 );
setDvar("player_sustainAmmo", 1);
setDvar( "player_sustainAmmo", 1 );
level.waypoints = [];
level.waypointCount = 0;
level waittill( "connected", player);
level waittill( "connected", player );
player thread onPlayerSpawned();
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
self endon( "disconnect" );
for ( ;; )
{
self waittill("spawned_player");
self waittill( "spawned_player" );
self thread beginDebug();
}
}
beginDebug()
{
self endon("disconnect");
self endon("death");
self endon( "disconnect" );
self endon( "death" );
level.wpToLink = -1;
level.autoLink = false;
@ -95,10 +96,10 @@ beginDebug()
self clearPerks();
self takeAllWeapons();
self.specialty = [];
self giveWeapon("m16_gl_mp");
self giveWeapon( "m16_gl_mp" );
self SetActionSlot( 3, "altMode" );
self giveWeapon("frag_grenade_mp");
self freezecontrols(false);
self giveWeapon( "frag_grenade_mp" );
self freezecontrols( false );
self thread debug();
self thread addWaypoints();
@ -107,266 +108,277 @@ beginDebug()
self thread watchSaveWaypointsCommand();
self thread sayExtras();
self thread textScroll("^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save");
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.");
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 endon( "disconnect" );
self endon( "death" );
self setClientDvar("com_maxfps", getDvarInt("bots_main_debug_framerate"));
self setClientDvar( "com_maxfps", getDvarInt( "bots_main_debug_framerate" ) );
for(;;)
for ( ;; )
{
wait getDvarFloat("bots_main_debug_debugRate");
wait getDvarFloat( "bots_main_debug_debugRate" );
if(isDefined(self.command))
if ( isDefined( self.command ) )
continue;
closest = -1;
myEye = self getTagOrigin( "j_head" );
myAngles = self GetPlayerAngles();
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
if(closest == -1 || closer(self.origin, level.waypoints[i].origin, level.waypoints[closest].origin))
if ( closest == -1 || closer( self.origin, level.waypoints[i].origin, level.waypoints[closest].origin ) )
closest = i;
wpOrg = level.waypoints[i].origin + (0, 0, 25);
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")))
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"));
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 ( 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"));
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)
if ( closest != -1 )
{
stringChildren = "";
for(i = 0; i < level.waypoints[closest].childCount; i++)
for ( i = 0; i < level.waypoints[closest].children.size; i++ )
{
if(i != 0)
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"));
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(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self SecondaryOffhandButtonPressed() || isDefined(self.command))
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");
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");
wait getDvarFloat( "bots_main_debug_commandWait" );
self addWaypoint(pos);
self addWaypoint( pos );
self.command = undefined;
while(self SecondaryOffhandButtonPressed())
while ( self SecondaryOffhandButtonPressed() )
wait 0.05;
}
}
linkWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self MeleeButtonPressed() || isDefined(self.command))
while ( !self MeleeButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("ADS - Unlink; Else(wait) - Link");
self iprintln( "ADS - Unlink; Else(wait) - Link" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(!self adsButtonPressed())
self LinkWaypoint(self.closest);
if ( !self adsButtonPressed() )
self LinkWaypoint( self.closest );
else
self UnLinkWaypoint(self.closest);
self UnLinkWaypoint( self.closest );
self.command = undefined;
while(self MeleeButtonPressed())
while ( self MeleeButtonPressed() )
wait 0.05;
}
}
deleteWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self fragButtonPressed() || isDefined(self.command))
while ( !self fragButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("Attack - DeleteAll; ADS - Load");
self iprintln("Else(wait) - Delete");
self iprintln( "Attack - DeleteAll; ADS - Load" );
self iprintln( "Else(wait) - Delete" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(self attackButtonPressed())
if ( self attackButtonPressed() )
self deleteAllWaypoints();
else if(self adsButtonPressed())
else if ( self adsButtonPressed() )
self LoadWaypoints();
else
self DeleteWaypoint(self.closest);
self DeleteWaypoint( self.closest );
self.command = undefined;
while(self fragButtonPressed())
while ( self fragButtonPressed() )
wait 0.05;
}
}
watchSaveWaypointsCommand()
{
self endon("death");
self endon("disconnect");
self endon( "death" );
self endon( "disconnect" );
for(;;)
for ( ;; )
{
while(!self useButtonPressed() || !self attackButtonPressed() || isDefined(self.command))
while ( !self useButtonPressed() || !self attackButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("ADS - Autolink; Else(wait) - Save");
self iprintln( "ADS - Autolink; Else(wait) - Save" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(!self adsButtonPressed())
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( "***********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 + "] = 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/*");
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/*");
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");
logprint( "*/return waypoints;\n}\n\n\n\n" );
PrintLn("********* Start Bot Warfare WPDump *********");
PrintLn(level.waypointCount);
filename = "waypoints/" + getdvar( "mapname" ) + "_wp.csv";
fd = FS_FOpen( filename, "write" );
if (fd > 0)
PrintLn( "********* Start Bot Warfare WPDump *********" );
PrintLn( level.waypointCount );
if ( fd > 0 )
{
if (!FS_WriteLine(fd, level.waypointCount+""))
if ( !FS_WriteLine( fd, level.waypointCount + "" ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
for(i = 0; i < level.waypointCount; i++)
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++)
for ( h = 0; h < wp.children.size; h++ )
{
str += wp.children[h];
if (h < wp.childCount - 1)
if ( h < wp.children.size - 1 )
str += " ";
}
str += "," + wp.type + ",";
if (isDefined(wp.angles))
if ( isDefined( wp.angles ) )
str += wp.angles[0] + " " + wp.angles[1] + " " + wp.angles[2] + ",";
else
str += ",";
str += ",";
PrintLn(str);
PrintLn( str );
if (fd > 0)
if ( fd > 0 )
{
if (!FS_WriteLine(fd, str))
if ( !FS_WriteLine( fd, str ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
}
PrintLn("\n\n\n\n\n\n");
self iprintln("Saved!!! to " + filename);
PrintLn( "\n\n\n\n\n\n" );
if (fd > 0)
FS_FClose(fd);
self iprintln( "Saved!!! to " + filename );
if ( fd > 0 )
FS_FClose( fd );
}
else
{
if(level.autoLink)
if ( level.autoLink )
{
self iPrintlnBold("Auto link disabled");
self iPrintlnBold( "Auto link disabled" );
level.autoLink = false;
level.wpToLink = -1;
}
else
{
self iPrintlnBold("Auto link enabled");
self iPrintlnBold( "Auto link enabled" );
level.autoLink = true;
level.wpToLink = self.closest;
}
@ -374,7 +386,7 @@ watchSaveWaypointsCommand()
self.command = undefined;
while(self useButtonPressed() && self attackButtonPressed())
while ( self useButtonPressed() && self attackButtonPressed() )
wait 0.05;
}
}
@ -382,7 +394,7 @@ watchSaveWaypointsCommand()
LoadWaypoints()
{
self DeleteAllWaypoints();
self iPrintlnBold("Loading WPS...");
self iPrintlnBold( "Loading WPS..." );
load_waypoints();
wait 1;
@ -392,53 +404,50 @@ LoadWaypoints()
checkForWarnings()
{
if(level.waypointCount <= 0)
self iprintln("WARNING: waypointCount is "+level.waypointCount);
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);
if ( level.waypointCount != level.waypoints.size )
self iprintln( "WARNING: waypointCount is not " + level.waypoints.size );
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
if(!isDefined(level.waypoints[i]))
if ( !isDefined( level.waypoints[i] ) )
{
self iprintln("WARNING: waypoint "+i+" is undefined");
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);
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))
if ( !isDefined( level.waypoints[i].children ) || !isDefined( level.waypoints[i].children.size ) )
{
self iprintln("WARNING: waypoint "+i+" children is not defined");
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++)
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[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))
if ( !isDefined( level.waypoints[i].type ) )
{
self iprintln("WARNING: waypoint "+i+" type is undefined");
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");
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" );
}
}
@ -446,40 +455,32 @@ DeleteAllWaypoints()
{
level.waypoints = [];
level.waypointCount = 0;
level.waypointsKDTree = WaypointsToKDTree();
level.waypointsCamp = [];
level.waypointsTube = [];
level.waypointsGren = [];
level.waypointsClay = [];
self iprintln("DelAllWps");
self iprintln( "DelAllWps" );
}
DeleteWaypoint(nwp)
DeleteWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("No close enough waypoint to delete.");
self iprintln( "No close enough waypoint to delete." );
return;
}
level.wpToLink = -1;
for(i = 0; i < level.waypoints[nwp].childCount; i++)
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);
level.waypoints[child].childCount = level.waypoints[child].children.size;
level.waypoints[child].children = array_remove( level.waypoints[child].children, nwp );
}
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
for(h = 0; h < level.waypoints[i].childCount; h++)
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
{
if(level.waypoints[i].children[h] > nwp)
if ( level.waypoints[i].children[h] > nwp )
level.waypoints[i].children[h]--;
}
}
@ -488,33 +489,35 @@ DeleteWaypoint(nwp)
{
if ( entry == nwp )
{
while ( entry < level.waypointCount-1 )
while ( entry < level.waypointCount - 1 )
{
level.waypoints[entry] = level.waypoints[entry+1];
level.waypoints[entry] = level.waypoints[entry + 1];
entry++;
}
level.waypoints[entry] = undefined;
break;
}
}
level.waypointCount--;
self iprintln("DelWp "+nwp);
self iprintln( "DelWp " + nwp );
}
addWaypoint(pos)
addWaypoint( pos )
{
level.waypoints[level.waypointCount] = spawnstruct();
level.waypoints[level.waypointCount].origin = pos;
if(self AdsButtonPressed())
if ( self AdsButtonPressed() )
level.waypoints[level.waypointCount].type = "climb";
else if(self AttackButtonPressed() && self UseButtonPressed())
else if ( self AttackButtonPressed() && self UseButtonPressed() )
level.waypoints[level.waypointCount].type = "tube";
else if(self AttackButtonPressed())
else if ( self AttackButtonPressed() )
level.waypoints[level.waypointCount].type = "grenade";
else if(self UseButtonPressed())
else if ( self UseButtonPressed() )
level.waypoints[level.waypointCount].type = "claymore";
else
level.waypoints[level.waypointCount].type = self getStance();
@ -522,17 +525,16 @@ addWaypoint(pos)
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);
self iprintln( level.waypoints[level.waypointCount].type + " Waypoint " + level.waypointCount + " Added at " + pos );
if(level.autoLink)
if ( level.autoLink )
{
if(level.wpToLink == -1)
if ( level.wpToLink == -1 )
level.wpToLink = level.waypointCount - 1;
level.waypointCount++;
self LinkWaypoint(level.waypointCount - 1);
self LinkWaypoint( level.waypointCount - 1 );
}
else
{
@ -540,62 +542,61 @@ addWaypoint(pos)
}
}
UnLinkWaypoint(nwp)
UnLinkWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("Waypoint Unlink Cancelled "+level.wpToLink);
self iprintln( "Waypoint Unlink Cancelled " + level.wpToLink );
level.wpToLink = -1;
return;
}
if(level.wpToLink == -1 || nwp == level.wpToLink)
if ( level.wpToLink == -1 || nwp == level.wpToLink )
{
level.wpToLink = nwp;
self iprintln("Waypoint Unlink Started "+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].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);
self iprintln( "Waypoint " + nwp + " Broken to " + level.wpToLink );
level.wpToLink = -1;
}
LinkWaypoint(nwp)
LinkWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("Waypoint Link Cancelled "+level.wpToLink);
self iprintln( "Waypoint Link Cancelled " + level.wpToLink );
level.wpToLink = -1;
return;
}
if(level.wpToLink == -1 || nwp == level.wpToLink)
if ( level.wpToLink == -1 || nwp == level.wpToLink )
{
level.wpToLink = nwp;
self iprintln("Waypoint Link Started "+nwp);
self iprintln( "Waypoint Link Started " + nwp );
return;
}
weGood = true;
for(i = 0; i < level.waypoints[level.wpToLink].childCount; i++)
for ( i = level.waypoints[level.wpToLink].children.size - 1; i >= 0; i-- )
{
if(level.waypoints[level.wpToLink].children[i] == nwp)
if ( level.waypoints[level.wpToLink].children[i] == nwp )
{
weGood = false;
break;
}
}
if(weGood)
if ( weGood )
{
for(i = 0; i < level.waypoints[nwp].childCount; i++)
for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
{
if(level.waypoints[nwp].children[i] == level.wpToLink)
if ( level.waypoints[nwp].children[i] == level.wpToLink )
{
weGood = false;
break;
@ -603,47 +604,45 @@ LinkWaypoint(nwp)
}
}
if (!weGood )
if ( !weGood )
{
self iprintln("Waypoint Link Cancelled "+nwp+" and "+level.wpToLink+" already linked.");
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++;
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);
self iprintln( "Waypoint " + nwp + " Linked to " + level.wpToLink );
level.wpToLink = -1;
}
destroyOnDeath(hud)
destroyOnDeath( hud )
{
hud endon("death");
self waittill_either("death","disconnect");
hud endon( "death" );
self waittill_either( "death", "disconnect" );
hud destroy();
}
textScroll(string)
textScroll( string )
{
self endon("death");
self endon("disconnect");
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);
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);
text = createFontString( "default", 1.5 );
text setText( string );
self thread destroyOnDeath( text );
for (;;)
for ( ;; )
{
text setPoint("CENTER", undefined, 1200, 220);
text setPoint("CENTER", undefined, -1200, 220, 20);
text setPoint( "CENTER", undefined, 1200, 220 );
text setPoint( "CENTER", undefined, -1200, 220, 20 );
wait 20;
}
}

View File

@ -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

BIN
out/ss.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 MiB