diff --git a/README.md b/README.md index 153e4f1..8806429 100644 --- a/README.md +++ b/README.md @@ -123,19 +123,7 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar - Fixed bots aim in third person - Bots sprint more - Improved bots sight on enemies - - - Still TODOs (some required in-engine) - - A variable leak in _menu - - Recoil for bots - - Improve/speed up unreachable spot detection - - Use proper activate button for bombs, carepackages, etc - - Proper weapon swaps, including altmode - - Complete cut/unfinished gamemodes and features - - Pick up weapons from ground - - Use static turrets in maps - - Proper use of pred missile - - Improve bot revenge system - - Have bots do random actions while waiting at an objective + - Bots play hidden gamemodes like one-flag and arena - v2.0.1 - Reduced bots crouching @@ -160,6 +148,21 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar - v2.0.0 - Initial reboot release + +- Still TODOs (some required in-engine) + - A variable leak in _menu + - Recoil for bots + - Improve/speed up unreachable spot detection + - Use proper activate button for bombs, carepackages, etc + - Proper weapon swaps, including altmode + - Pick up weapons from ground + - Use static turrets in maps + - Proper use of pred missile + - Improve bot revenge system + - Have bots do random actions while waiting at an objective + - Better bot difficulty management + - Setup a bot chatter system + ## Credits - IW4x Team - https://github.com/XLabsProject/iw4x-client - CoD4x Team - https://github.com/callofduty4x/CoD4x_Server diff --git a/userraw/maps/mp/bots/_bot_script.gsc b/userraw/maps/mp/bots/_bot_script.gsc index 2a324ac..add4377 100644 --- a/userraw/maps/mp/bots/_bot_script.gsc +++ b/userraw/maps/mp/bots/_bot_script.gsc @@ -6915,6 +6915,86 @@ bot_arena() } } +/* + bot_vip_loop + + For those wondering why i call a function for these loops like this + its because, the variables created in this function will be free'd once the function exits, + if it was in the infinite loop, the function never exits, thus the variables are never free'd + + This isnt leaking variables, but freeing variables that will no longer be used, an optimization of sorts +*/ +bot_vip_loop() +{ + vip = undefined; + + for ( i = 0; i < level.players.size; i++ ) + { + player = level.players[i]; + + if ( !isReallyAlive( player ) ) + continue; + + if ( isDefined( self.isVip ) && self.isVip ) + vip = player; + } + + if ( self.team == game["defenders"] ) + { + if ( isDefined( self.isVip ) && self.isVip ) + { + if ( isDefined( level.extractionZone ) && !isDefined( level.extractionTime ) ) + { + // go to extraction zone + self.bot_lock_goal = true; + self SetScriptGoal( level.extractionZone.trigger.origin, 32 ); + + evt = self waittill_any_return( "goal", "bad_path", "new_goal" ); + + wait 1; + + if ( evt != "new_goal" ) + self ClearScriptGoal(); + + self.bot_lock_goal = false; + } + } + else if ( isDefined( vip ) ) + { + // protect the vip + if ( DistanceSquared( vip.origin, self.origin ) <= 1024 * 1024 ) + return; + + self SetScriptGoal( vip.origin, 256 ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + self ClearScriptGoal(); + } + } + else + { + if ( isDefined( level.extractionZone ) && !isDefined( level.extractionTime ) && self BotGetRandom() < 65 ) + { + // camp the extraction zone + if ( DistanceSquared( level.extractionZone.trigger.origin, self.origin ) <= 1024 * 1024 ) + return; + + self SetScriptGoal( level.extractionZone.trigger.origin, 256 ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + self ClearScriptGoal(); + } + else if ( isDefined( vip ) ) + { + // kill the vip + self SetScriptGoal( vip.origin, 32 ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + self ClearScriptGoal(); + } + } +} + /* Bots play arena */ @@ -6936,121 +7016,6 @@ bot_vip() continue; } - /* case "vip"://maybe used at gaming events. (ya right, this is not even finished) - if(isDefined(level.extractionZone)) - { - if(self.team == game["defenders"]) - { - if(isDefined(self.isVip) && self.isVip) - { - if(!isDefined(level.extractionTime)) - { - self.bots_objDoing = "vip"; - self thread bots\talk::bots_vip_extract(); - self bots_goToLoc(level.extractionZone.trigger.origin, ::bots_nullFunc, 0, 0, 0); - if(distance(level.extractionZone.trigger.origin, self.origin) <= level.bots_useNear) - level.extractionZone [[level.extractionZone.onUse]](self); - - self thread bots\talk::bots_vip_extractDone(); - self.bots_objDoing = "none"; - } - else - { - wps = bots_getWaypointsNear(level.bots_goalPoint.origin, level.bots_goalRad); - wp = undefined; - if(wps.size > 0) - { - wp = wps[randomint(wps.size)]; - } - if(isDefined(wp) && self.bots_traitRandom != 3) - { - self bots_goToLoc(level.waypoints[wp].origin, ::bots_nullFunc, 0, 0, 0); - } - else - { - self bots_goToLoc(level.waypoints[randomint(level.waypointCount)].origin, ::bots_nullFunc, 0, 0, 0); - } - } - } - else - { - if(self.bots_traitRandom) - { - tarPlay = undefined; - foreach(player in level.players) - { - if(!isDefined(player.isVip) || !player.isVip) - continue; - - if(!bots_isReallyAlive(player)) - continue; - - tarPlay = player; - break; - } - - self thread bots\talk::bots_vip_protect(tarPlay); - self bots_goFollow(tarPlay, 30, false); - } - else - { - wps = bots_getWaypointsNear(level.bots_goalPoint.origin, level.bots_goalRad); - wp = undefined; - if(wps.size > 0) - { - wp = wps[randomint(wps.size)]; - } - if(isDefined(wp) && self.bots_traitRandom != 3) - { - self bots_goToLoc(level.waypoints[wp].origin, ::bots_nullFunc, 0, 0, 0); - } - else - { - self bots_goToLoc(level.waypoints[randomint(level.waypointCount)].origin, ::bots_nullFunc, 0, 0, 0); - } - } - } - } - else - { - tarPlay = undefined; - foreach(player in level.players) - { - if(!isDefined(player.isVip) || !player.isVip) - continue; - - if(!bots_isReallyAlive(player)) - continue; - - tarPlay = player; - break; - } - - if((!isDefined(level.extractionTime) || self.bots_traitRandom < 2) && isDefined(tarPlay)) - { - self thread bots\talk::bots_vip_kill(tarPlay); - self bots_goFollow(tarPlay, 30, false); - } - else - { - wps = bots_getWaypointsNear(level.extractionZone.trigger.origin, randomFloatRange(100,1000)); - wp = undefined; - if(wps.size > 0) - { - wp = wps[randomint(wps.size)]; - } - if(isDefined(wp) && self.bots_traitRandom != 3) - { - self thread bots\talk::bots_vip_hangaround(); - self bots_goToLoc(level.waypoints[wp].origin, ::bots_nullFunc, 0, 0, 0); - } - else - { - self bots_goToLoc(level.waypoints[randomint(level.waypointCount)].origin, ::bots_nullFunc, 0, 0, 0); - } - } - } - } - break;*/ + self bot_vip_loop(); } }