From 234e095efea8fa44ef8a777c09c407977dab4089 Mon Sep 17 00:00:00 2001 From: ineed bots Date: Wed, 20 Apr 2022 12:59:21 -0600 Subject: [PATCH] Prep for bot chatter --- README.md | 4 +- raw/maps/mp/bots/_bot.gsc | 64 ++++++++++++++++++++++++++++-- raw/maps/mp/bots/_bot_internal.gsc | 41 ++++++++++--------- raw/maps/mp/bots/_bot_script.gsc | 34 ++++++++++++++-- raw/maps/mp/bots/_bot_utility.gsc | 27 +++++++------ 5 files changed, 130 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 9fc3101..239249e 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar | 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 | @@ -116,7 +118,7 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar ## Credits - Plutonium Team - https://plutonium.pw/ - CoD4x Team - https://github.com/callofduty4x/CoD4x_Server -- INeedGames(me) - http://www.moddb.com/mods/bot-warfare +- INeedGames - http://www.moddb.com/mods/bot-warfare - tinkie101 - https://web.archive.org/web/20120326060712/http://alteriw.net/viewtopic.php?f=72&t=4869 - PeZBot team - http://www.moddb.com/mods/pezbot - apdonato - http://rsebots.blogspot.ca/ diff --git a/raw/maps/mp/bots/_bot.gsc b/raw/maps/mp/bots/_bot.gsc index 8078127..4135c83 100644 --- a/raw/maps/mp/bots/_bot.gsc +++ b/raw/maps/mp/bots/_bot.gsc @@ -80,6 +80,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 ); @@ -606,9 +612,6 @@ addNotifyOnAirdrops_loop() { airdrop = dropCrates[i]; - if ( !isDefined( airdrop.owner ) ) - continue; - if ( isDefined( airdrop.doingPhysics ) ) continue; @@ -638,7 +641,26 @@ doNotifyOnAirdrop() self waittill( "physics_finished" ); self.doingPhysics = false; - self.owner notify( "crate_physics_done" ); + + if ( isDefined( self.owner ) ) + self.owner notify( "crate_physics_done" ); + + self thread onCarepackageCaptured(); +} + +/* + Waits to be captured +*/ +onCarepackageCaptured() +{ + self endon( "death" ); + + self waittill( "captured", player ); + + if ( isDefined( self.owner ) && self.owner is_bot() ) + { + self.owner BotNotifyBotEvent( "crate_cap", "captured", self, player ); + } } /* @@ -702,6 +724,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" ) ) + { + PrintLn( "Bot Warfare debug: " + self.name + ": " + str ); + } + } } /* @@ -806,6 +848,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/raw/maps/mp/bots/_bot_internal.gsc b/raw/maps/mp/bots/_bot_internal.gsc index 75c5b8a..3e4047e 100644 --- a/raw/maps/mp/bots/_bot_internal.gsc +++ b/raw/maps/mp/bots/_bot_internal.gsc @@ -2193,6 +2193,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 @@ -2290,6 +2291,8 @@ movetowards( goal ) randomDir = self getRandomLargestStafe( stucks ); + self BotNotifyBotEvent( "stuck" ); + self botMoveTo( randomDir ); wait stucks; self stand(); @@ -2314,7 +2317,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; } @@ -2789,29 +2792,31 @@ bot_lookat( pos, time, vel, doAimPredict ) 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/raw/maps/mp/bots/_bot_script.gsc b/raw/maps/mp/bots/_bot_script.gsc index 23e7ce0..1a4d71c 100644 --- a/raw/maps/mp/bots/_bot_script.gsc +++ b/raw/maps/mp/bots/_bot_script.gsc @@ -2142,6 +2142,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" ) @@ -2150,8 +2154,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 ); } /* @@ -2277,8 +2285,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 ); } /* @@ -4127,6 +4141,8 @@ bot_crate_think_loop( data ) if ( !isDefined( crate ) ) return; + self BotNotifyBotEvent( "crate_cap", "go", crate ); + self.bot_lock_goal = true; radius = GetDvarFloat( "player_useRadius" ) - 16; @@ -4142,9 +4158,16 @@ bot_crate_think_loop( data ) self ClearScriptGoal(); if ( path != "goal" || !isDefined( crate ) || DistanceSquared( self.origin, crate.origin ) > radius * radius ) + { + if ( isDefined( crate ) && path == "bad_path" ) + self BotNotifyBotEvent( "crate_cap", "unreachable", crate ); + return; + } } + self BotNotifyBotEvent( "crate_cap", "start", crate ); + self BotRandomStance(); self BotFreezeControls( true ); @@ -4152,13 +4175,16 @@ bot_crate_think_loop( data ) waitTime = 3.25; - if ( isDefined( crate.owner ) && crate.owner == self ) + if ( !isDefined( crate.owner ) || crate.owner == self ) waitTime = 0.75; self thread BotPressUse( waitTime ); wait waitTime; self BotFreezeControls( false ); + + // check if actually captured it? + self BotNotifyBotEvent( "crate_cap", "stop", crate ); } /* @@ -7638,7 +7664,7 @@ bot_vip_loop() if ( !isReallyAlive( player ) ) continue; - if ( isDefined( self.isVip ) && self.isVip ) + if ( isDefined( player.isVip ) && player.isVip ) vip = player; } diff --git a/raw/maps/mp/bots/_bot_utility.gsc b/raw/maps/mp/bots/_bot_utility.gsc index 61b8604..e8c8c6e 100644 --- a/raw/maps/mp/bots/_bot_utility.gsc +++ b/raw/maps/mp/bots/_bot_utility.gsc @@ -230,6 +230,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) @@ -766,19 +774,6 @@ Round( x ) return y; } -/* - Rounds up the given value. -*/ -RoundUp( floatVal ) -{ - i = int( floatVal ); - - if ( i != floatVal ) - return i + 1; - else - return i; -} - /* converts a string into a float */ @@ -2493,6 +2488,12 @@ botGiveLoadout( team, class, allowCopycat, setPrimarySpawnWeapon ) // setPrimary if ( loadoutStreakType == "streaktype_support" ) loadoutStreakType = "streaktype_assault"; + + if ( loadoutPrimary == "riotshield" ) + loadoutPrimary = "iw5_m4"; + + if ( loadoutSecondary == "riotshield" ) + loadoutSecondary = "iw5_m4"; } self maps\mp\gametypes\_class::loadoutFakePerks( loadoutStreakType );