diff --git a/README.md b/README.md
index af10d57..884fc9a 100644
--- a/README.md
+++ b/README.md
@@ -106,6 +106,8 @@ Also make sure that PunkBuster is disabled!
| bots_skill_axis_med | When `bots_skill` is set to `8`, the amount of medium difficulty bots to set on the axis team. The remaining bots on the team will be set to easy difficulty. | 0 |
| bots_skill_allies_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the allies team. | 0 |
| bots_skill_allies_med | When `bots_skill` is set to `8`, the amount of medium difficulty bots to set on the allies team. The remaining bots on the team will be set to easy difficulty. | 0 |
+| bots_skill_min | The minimum difficulty level for the bots. | 1 |
+| bots_skill_max | The maximum difficulty level for the bots. | 7 |
| bots_loadout_reasonable | If the bots should filter bad performing create-a-class selections. | false |
| bots_loadout_allow_op | If the bots should be able to use overpowered and annoying create-a-class selections. | true |
| bots_loadout_rank | What rank to set the bots.
- `-1` - Average of all players in the match.
- `0` - All random.
- `1` or higher - Sets the bots' rank to this.
| -1 |
@@ -144,7 +146,7 @@ Also make sure that PunkBuster is disabled!
## Credits
- iAmThatMichael - https://github.com/iAmThatMichael/T4M
-- INeedGames(me) - http://www.moddb.com/mods/bot-warfare
+- INeedGames - http://www.moddb.com/mods/bot-warfare
- PeZBot team - http://www.moddb.com/mods/pezbot
- Ability
- Salvation
diff --git a/main_shared/maps/mp/bots/_bot.gsc b/main_shared/maps/mp/bots/_bot.gsc
index 65182f9..cc820d5 100644
--- a/main_shared/maps/mp/bots/_bot.gsc
+++ b/main_shared/maps/mp/bots/_bot.gsc
@@ -74,6 +74,12 @@ init()
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 );
@@ -377,6 +383,26 @@ connected()
self thread onDisconnect();
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" ) )
+ {
+ PrintConsole( "Bot Warfare debug: " + self.name + ": " + str + "\n" );
+ }
+ }
}
/*
@@ -481,6 +507,20 @@ diffBots_loop()
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 ) );
+ }
}
/*
diff --git a/main_shared/maps/mp/bots/_bot_internal.gsc b/main_shared/maps/mp/bots/_bot_internal.gsc
index 8e212dd..a413d22 100644
--- a/main_shared/maps/mp/bots/_bot_internal.gsc
+++ b/main_shared/maps/mp/bots/_bot_internal.gsc
@@ -1899,6 +1899,7 @@ doWalkScriptNotify()
*/
doWalk( goal, dist, 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
@@ -1996,6 +1997,8 @@ movetowards( goal )
randomDir = self getRandomLargestStafe( stucks );
+ self BotNotifyBotEvent( "stuck" );
+
self botMoveTo( randomDir );
wait stucks;
self stand();
@@ -2020,7 +2023,7 @@ movetowards( goal )
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 )
+ 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;
}
@@ -2413,29 +2416,31 @@ bot_lookat( pos, time, vel, doAimPredict )
myAngle = self getPlayerAngles();
angles = VectorToAngles( ( pos - myEye ) - anglesToForward( myAngle ) );
- X = ( angles[0] - myAngle[0] );
-
- while ( X > 170.0 )
- X = X - 360.0;
-
- while ( X < -170.0 )
- X = X + 360.0;
-
+ X = AngleClamp180( angles[0] - myAngle[0] );
X = X / steps;
- Y = ( angles[1] - myAngle[1] );
-
- while ( Y > 180.0 )
- Y = Y - 360.0;
-
- while ( Y < -180.0 )
- Y = Y + 360.0;
-
+ Y = AngleClamp180( angles[1] - myAngle[1] );
Y = Y / steps;
for ( i = 0; i < steps; i++ )
{
- myAngle = ( myAngle[0] + X, myAngle[1] + Y, 0 );
+ newX = myAngle[0] + X;
+
+ while ( newX < 0 )
+ newX += 360.0;
+
+ while ( newX >= 360.0 )
+ newX -= 360.0;
+
+ newY = myAngle[1] + Y;
+
+ while ( newY < 0 )
+ newY += 360.0;
+
+ while ( newY >= 360.0 )
+ newY -= 360.0;
+
+ myAngle = ( newX, newY, 0 );
self setPlayerAngles( myAngle );
wait 0.05;
}
diff --git a/main_shared/maps/mp/bots/_bot_script.gsc b/main_shared/maps/mp/bots/_bot_script.gsc
index 35f95dc..b6dcdc3 100644
--- a/main_shared/maps/mp/bots/_bot_script.gsc
+++ b/main_shared/maps/mp/bots/_bot_script.gsc
@@ -1724,6 +1724,10 @@ bot_think_camp_loop()
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" )
@@ -1732,8 +1736,12 @@ bot_think_camp_loop()
if ( ret != "goal" )
return;
- self thread killCampAfterTime( randomIntRange( 10, 20 ) );
+ 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 );
}
/*
@@ -1852,8 +1860,14 @@ bot_think_follow_loop()
if ( !isDefined( toFollow ) )
return;
- self thread killFollowAfterTime( randomIntRange( 10, 20 ) );
+ time = randomIntRange( 10, 20 );
+
+ self BotNotifyBotEvent( "follow", "start", toFollow, time );
+
+ self thread killFollowAfterTime( time );
self followPlayer( toFollow );
+
+ self BotNotifyBotEvent( "follow", "stop", toFollow, time );
}
/*
diff --git a/main_shared/maps/mp/bots/_bot_utility.gsc b/main_shared/maps/mp/bots/_bot_utility.gsc
index 220e88e..ab48aac 100644
--- a/main_shared/maps/mp/bots/_bot_utility.gsc
+++ b/main_shared/maps/mp/bots/_bot_utility.gsc
@@ -228,6 +228,14 @@ BotStopMoving( 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 );
+}
+
/*
Returns if the bot has a script goal.
(like t5 gsc bot)
@@ -1096,6 +1104,28 @@ cac_init_patch()
}
}
+/*
+ clamps angle between -180 and 180
+*/
+AngleClamp180( angle )
+{
+ 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 );
+}
+
/*
converts a string into a float
*/