diff --git a/bw-assets/wpedit.md b/bw-assets/wpedit.md
index dba1da2..17fc4df 100644
--- a/bw-assets/wpedit.md
+++ b/bw-assets/wpedit.md
@@ -13,15 +13,15 @@ Now if you want to modify existing or create new waypoints for PlutoniumIW5 maps
The Bot Warfare mod comes with the Waypoint Editor out of the box, so its just a matter of telling the mod you want to use it. Its a matter of setting the 'bots_main_debug' DVAR to '1'.
Start your game, and load up the Bot Warfare mod. Now open your console with tilde(~).
-
+
In the console, type in ```set bots_main_debug 1```
-
+
Now start a match with the map you want to edit.
## The Editor
-
+
This is the Waypoint Editor. You can view, edit and create the waypoint graph.
- Each death icons you see are waypoints.
- Each line of knives show the links between the waypoints, a link defines that a bot can walk from A to B.
@@ -59,10 +59,10 @@ Pressing any of these buttons will initiate a command to the Waypoint Editor.
Okay, now that you know how to control the Editor, lets now goahead and create some waypoints.
Here I added a waypoint.
-
+
And I added a second waypoint.
-
+
There are several types of waypoints, holding a modifier button before pressing the add waypoint button will create a special type of waypoint.
- Types of waypoints:
@@ -75,7 +75,7 @@ There are several types of waypoints, holding a modifier button before pressing
- javelin - bots will use the javelin and lockon at the target location
Here I linked the two waypoints together.
-
+
Linking waypoints are very important, it tells the bots that they can reach waypoint 1 from waypoint 0, and vice versa.
@@ -84,11 +84,11 @@ Now go and waypoint the whole map out. This may take awhile and can be pretty te
Once you feel like you are done, press the Save button. This will output the waypoints to your `games_mp.log` file.
Your `games_mp.log` can be located at the `C:\Users\\AppData\Plutonium\storage\iw5` folder.
-
+
The editor will generate some GSC code for the waypoints.
-
+
This is the GSC function that will generate the waypoints for the map. If you have trouble beyond this point, simply create an Issue and provide the output from here, I can do the rest from there.
You can create/replace the map's waypoints GSC file with the function in `games_mp.log`.
@@ -105,9 +105,8 @@ main()
```
-
-
+
+
Now Bot Warfare will use your waypoints you've created!
-Create a pull request to have your waypoints included in the mod if you like, any help is greatly appreciated.
diff --git a/maps/mp/bots/_bot.gsc b/maps/mp/bots/_bot.gsc
index 6f83d0b..ad8798f 100644
--- a/maps/mp/bots/_bot.gsc
+++ b/maps/mp/bots/_bot.gsc
@@ -23,6 +23,9 @@ init()
if ( !getDvarInt( "bots_main" ) )
return;
+ if ( !wait_for_builtins() )
+ PrintLn( "FATAL: NO BUILT-INS FOR BOTS" );
+
thread load_waypoints();
thread hook_callbacks();
@@ -202,8 +205,6 @@ init()
level thread auditModels();
level thread handleBots();
-
- //level thread maps\mp\bots\_bot_http::doVersionCheck();
}
/*
@@ -764,11 +765,11 @@ watchBotDebugEvent()
if ( isDefined( g ) && isString( g ) )
big_str += ", " + g;
- PrintLn( big_str );
+ BotBuiltinPrintConsole( big_str );
}
else if ( msg == "debug" && GetDvarInt( "bots_main_debug" ) )
{
- PrintLn( "Bot Warfare debug: " + self.name + ": " + str );
+ BotBuiltinPrintConsole( "Bot Warfare debug: " + self.name + ": " + str );
}
}
}
diff --git a/maps/mp/bots/_bot_internal.gsc b/maps/mp/bots/_bot_internal.gsc
index 5967536..55aa826 100644
--- a/maps/mp/bots/_bot_internal.gsc
+++ b/maps/mp/bots/_bot_internal.gsc
@@ -143,7 +143,7 @@ resetBotVars()
self.bot.rand = randomInt( 100 );
- self botStop();
+ self BotBuiltinBotStop();
}
/*
@@ -373,7 +373,7 @@ watchUsingTurret()
{
if ( self getCurrentWeapon() != "killstreak_remote_turret_remote_mp" )
{
- self changeToWeap( "killstreak_remote_turret_remote_mp" );
+ self switchToWeapon( "killstreak_remote_turret_remote_mp" );
}
if ( isDefined( self.bot.target ) )
@@ -423,7 +423,7 @@ watchUsingTank()
{
if ( self getCurrentWeapon() != "killstreak_remote_tank_remote_mp" )
{
- self changeToWeap( "killstreak_remote_tank_remote_mp" );
+ self switchToWeapon( "killstreak_remote_tank_remote_mp" );
}
if ( isDefined( self.bot.target ) )
@@ -462,7 +462,7 @@ watchUsingUav()
{
if ( self getCurrentWeapon() != "uav_remote_mp" )
{
- self changeToWeap( "uav_remote_mp" );
+ self switchToWeapon( "uav_remote_mp" );
}
if ( isDefined( self.lockedTarget ) )
@@ -483,7 +483,7 @@ watchUsingMortar()
{
if ( self getCurrentWeapon() != "mortar_remote_mp" )
{
- self changeToWeap( "mortar_remote_mp" );
+ self switchToWeapon( "mortar_remote_mp" );
}
if ( isDefined( self.bot.target ) )
@@ -504,7 +504,7 @@ watchUsingMinigun()
{
if ( self getCurrentWeapon() != "heli_remote_mp" )
{
- self changeToWeap( "heli_remote_mp" );
+ self switchToWeapon( "heli_remote_mp" );
}
if ( isDefined( self.bot.target ) )
@@ -528,7 +528,7 @@ watchAc130Weapon()
curWeap = self GetCurrentWeapon();
if ( curWeap != "ac130_105mm_mp" && curWeap != "ac130_40mm_mp" && curWeap != "ac130_25mm_mp" )
- self changeToWeap( "ac130_105mm_mp" );
+ self switchToWeapon( "ac130_105mm_mp" );
if ( isDefined( self.bot.target ) )
self thread pressFire();
@@ -546,11 +546,11 @@ watchUsingAc130()
while ( isDefined( level.ac130Player ) && level.ac130player == self )
{
- self changeToWeap( "ac130_105mm_mp" );
+ self switchToWeapon( "ac130_105mm_mp" );
wait 1 + randomInt( 2 );
- self changeToWeap( "ac130_40mm_mp" );
+ self switchToWeapon( "ac130_40mm_mp" );
wait 2 + randomInt( 2 );
- self changeToWeap( "ac130_25mm_mp" );
+ self switchToWeapon( "ac130_25mm_mp" );
wait 3 + randomInt( 2 );
}
}
@@ -757,7 +757,7 @@ doBotMovement_loop( data )
if ( self.bot.wantsprint && self.bot.issprinting )
dir = ( 127, dir[1], 0 );
- self botMovement( int( dir[0] ), int( dir[1] ) );
+ self BotBuiltinBotMovement( int( dir[0] ), int( dir[1] ) );
if ( isDefined( self.remoteUAV ) )
{
@@ -2439,9 +2439,9 @@ getRandomLargestStafe( dist )
holdbreath( what )
{
if ( what )
- self botAction( "+holdbreath" );
+ self BotBuiltinBotAction( "+holdbreath" );
else
- self botAction( "-holdbreath" );
+ self BotBuiltinBotAction( "-holdbreath" );
}
/*
@@ -2454,9 +2454,9 @@ sprint()
self notify( "bot_sprint" );
self endon( "bot_sprint" );
- self botAction( "+sprint" );
+ self BotBuiltinBotAction( "+sprint" );
wait 0.05;
- self botAction( "-sprint" );
+ self BotBuiltinBotAction( "-sprint" );
}
/*
@@ -2469,9 +2469,9 @@ gostand()
self notify( "bot_gostand" );
self endon( "bot_gostand" );
- self botAction( "+gostand" );
+ self BotBuiltinBotAction( "+gostand" );
wait 0.05;
- self botAction( "-gostand" );
+ self BotBuiltinBotAction( "-gostand" );
}
/*
@@ -2484,9 +2484,9 @@ pressfrag()
self notify( "bot_frag" );
self endon( "bot_frag" );
- self botAction( "+frag" );
+ self BotBuiltinBotAction( "+frag" );
wait 0.05;
- self botAction( "-frag" );
+ self BotBuiltinBotAction( "-frag" );
}
/*
@@ -2502,9 +2502,9 @@ knife()
self.bot.isknifing = true;
self.bot.isknifingafter = true;
- self botAction( "+melee" );
+ self BotBuiltinBotAction( "+melee" );
wait 0.05;
- self botAction( "-melee" );
+ self BotBuiltinBotAction( "-melee" );
self.bot.isknifing = false;
@@ -2523,9 +2523,9 @@ reload()
self notify( "bot_reload" );
self endon( "bot_reload" );
- self botAction( "+reload" );
+ self BotBuiltinBotAction( "+reload" );
wait 0.05;
- self botAction( "-reload" );
+ self BotBuiltinBotAction( "-reload" );
}
/*
@@ -2541,14 +2541,14 @@ frag( time )
if ( !isDefined( time ) )
time = 0.05;
- self botAction( "+frag" );
+ self BotBuiltinBotAction( "+frag" );
self.bot.isfragging = true;
self.bot.isfraggingafter = true;
if ( time )
wait time;
- self botAction( "-frag" );
+ self BotBuiltinBotAction( "-frag" );
self.bot.isfragging = false;
wait 1.25;
@@ -2568,14 +2568,14 @@ smoke( time )
if ( !isDefined( time ) )
time = 0.05;
- self botAction( "+smoke" );
+ self BotBuiltinBotAction( "+smoke" );
self.bot.issmoking = true;
self.bot.issmokingafter = true;
if ( time )
wait time;
- self botAction( "-smoke" );
+ self BotBuiltinBotAction( "-smoke" );
self.bot.issmoking = false;
wait 1.25;
@@ -2590,9 +2590,9 @@ fire( what )
self notify( "bot_fire" );
if ( what )
- self botAction( "+fire" );
+ self BotBuiltinBotAction( "+fire" );
else
- self botAction( "-fire" );
+ self BotBuiltinBotAction( "-fire" );
}
/*
@@ -2608,12 +2608,12 @@ pressFire( time )
if ( !isDefined( time ) )
time = 0.05;
- self botAction( "+fire" );
+ self BotBuiltinBotAction( "+fire" );
if ( time )
wait time;
- self botAction( "-fire" );
+ self BotBuiltinBotAction( "-fire" );
}
/*
@@ -2624,9 +2624,9 @@ ads( what )
self notify( "bot_ads" );
if ( what )
- self botAction( "+ads" );
+ self BotBuiltinBotAction( "+ads" );
else
- self botAction( "-ads" );
+ self BotBuiltinBotAction( "-ads" );
}
/*
@@ -2642,12 +2642,12 @@ pressADS( time )
if ( !isDefined( time ) )
time = 0.05;
- self botAction( "+ads" );
+ self BotBuiltinBotAction( "+ads" );
if ( time )
wait time;
- self botAction( "-ads" );
+ self BotBuiltinBotAction( "-ads" );
}
/*
@@ -2663,12 +2663,12 @@ use( time )
if ( !isDefined( time ) )
time = 0.05;
- self botAction( "+activate" );
+ self BotBuiltinBotAction( "+activate" );
if ( time )
wait time;
- self botAction( "-activate" );
+ self BotBuiltinBotAction( "-activate" );
}
/*
@@ -2690,9 +2690,9 @@ jump()
wait 1;
}
- self botAction( "+gostand" );
+ self BotBuiltinBotAction( "+gostand" );
wait 0.05;
- self botAction( "-gostand" );
+ self BotBuiltinBotAction( "-gostand" );
}
/*
@@ -2703,8 +2703,8 @@ stand()
if ( self IsUsingRemote() )
return;
- self botAction( "-gocrouch" );
- self botAction( "-goprone" );
+ self BotBuiltinBotAction( "-gocrouch" );
+ self BotBuiltinBotAction( "-goprone" );
}
/*
@@ -2715,8 +2715,8 @@ crouch()
if ( self IsUsingRemote() )
return;
- self botAction( "+gocrouch" );
- self botAction( "-goprone" );
+ self BotBuiltinBotAction( "+gocrouch" );
+ self BotBuiltinBotAction( "-goprone" );
}
/*
@@ -2727,16 +2727,8 @@ prone()
if ( self IsUsingRemote() || self.hasRiotShieldEquipped )
return;
- self botAction( "-gocrouch" );
- self botAction( "+goprone" );
-}
-
-/*
- Changes to the weap
-*/
-changeToWeap( weap )
-{
- self botWeapon( weap );
+ self BotBuiltinBotAction( "-gocrouch" );
+ self BotBuiltinBotAction( "+goprone" );
}
/*
@@ -2860,11 +2852,3 @@ bot_lookat( pos, time, vel, doAimPredict )
wait 0.05;
}
}
-
-/*
- Bot change weap
-*/
-botWeapon( weap )
-{
- self switchToWeapon( weap );
-}
diff --git a/maps/mp/bots/_bot_script.gsc b/maps/mp/bots/_bot_script.gsc
index 32aa6e5..9e2657a 100644
--- a/maps/mp/bots/_bot_script.gsc
+++ b/maps/mp/bots/_bot_script.gsc
@@ -2003,7 +2003,7 @@ changeToWeapon( weap )
if ( !self HasWeapon( weap ) )
return false;
- self BotChangeToWeapon( weap );
+ self switchToWeapon( weap );
if ( self GetCurrentWeapon() == weap )
return true;
diff --git a/maps/mp/bots/_bot_utility.gsc b/maps/mp/bots/_bot_utility.gsc
index d077958..335a648 100644
--- a/maps/mp/bots/_bot_utility.gsc
+++ b/maps/mp/bots/_bot_utility.gsc
@@ -9,6 +9,109 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
+/*
+ Waits for the built-ins to be defined
+*/
+wait_for_builtins()
+{
+ for ( i = 0; i < 20; i++ )
+ {
+ if ( isDefined( level.bot_builtins ) )
+ return true;
+
+ if ( i < 18 )
+ waittillframeend;
+ else
+ wait 0.05;
+ }
+
+ return false;
+}
+
+/*
+ Prints to console without dev script on
+*/
+BotBuiltinPrintConsole( s )
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["printconsole"] ) )
+ {
+ [[ level.bot_builtins["printconsole" ]]]( s );
+ }
+}
+
+/*
+ Writes to the file, mode can be "append" or "write"
+*/
+BotBuiltinFileWrite( file, contents, mode )
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["filewrite"] ) )
+ {
+ [[ level.bot_builtins["filewrite" ]]]( file, contents, mode );
+ }
+}
+
+/*
+ Returns the whole file as a string
+*/
+BotBuiltinFileRead( file )
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["fileread"] ) )
+ {
+ return [[ level.bot_builtins["fileread" ]]]( file );
+ }
+
+ return undefined;
+}
+
+/*
+ Test if a file exists
+*/
+BotBuiltinFileExists( file )
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["fileexists"] ) )
+ {
+ return [[ level.bot_builtins["fileexists" ]]]( file );
+ }
+
+ return false;
+}
+
+/*
+ Bot action, does a bot action
+ botAction()
+*/
+BotBuiltinBotAction( action )
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botaction"] ) )
+ {
+ self [[ level.bot_builtins["botaction" ]]]( action );
+ }
+}
+
+/*
+ Clears the bot from movement and actions
+ botStop()
+*/
+BotBuiltinBotStop()
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botstop"] ) )
+ {
+ self [[ level.bot_builtins["botstop" ]]]();
+ }
+}
+
+/*
+ Sets the bot's movement
+ botMovement(, )
+*/
+BotBuiltinBotMovement( left, forward )
+{
+ if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botmovement"] ) )
+ {
+ self [[ level.bot_builtins["botmovement" ]]]( left, forward );
+ }
+}
+
/*
Returns if player is the host
*/
@@ -31,7 +134,7 @@ doHostCheck()
if ( getDvar( "bots_main_firstIsHost" ) != "0" )
{
- printLn( "WARNING: bots_main_firstIsHost is enabled" );
+ BotBuiltinPrintConsole( "WARNING: bots_main_firstIsHost is enabled" );
if ( getDvar( "bots_main_firstIsHost" ) == "1" )
{
@@ -93,14 +196,6 @@ BotSetStance( stance )
}
}
-/*
- Bot changes to the weap
-*/
-BotChangeToWeapon( weap )
-{
- self maps\mp\bots\_bot_internal::changeToWeap( weap );
-}
-
/*
Bot presses the frag button for time.
*/
@@ -855,20 +950,21 @@ parseTokensIntoWaypoint( tokens )
*/
getWaypointLinesFromFile( filename )
{
- /* result = spawnStruct();
- result.lines = [];
+ result = spawnStruct();
+ result.lines = [];
- waypointStr = fileRead(filename);
+ waypointStr = BotBuiltinFileRead( filename );
- if (!isDefined(waypointStr))
+ if ( !isDefined( waypointStr ) )
return result;
- line = "";
- for (i=0;i