mirror of
https://github.com/ineedbots/t4_bot_warfare.git
synced 2025-07-09 12:41:55 +00:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
87744ba13a | |||
837bec9c73 | |||
5d9c90cc25 | |||
93ce2ae1b5 | |||
cf40501f60 | |||
979d1135be | |||
5afc002126 | |||
6225ae74fb | |||
ca71fbee4b | |||
4059b373c2 | |||
73dc1c17b1 | |||
f41ab46747 | |||
1d26bbd492 | |||
52f1062793 | |||
9744ff6ccd | |||
3c7e07866f | |||
f0aa54189d | |||
ff413d513b | |||
795ed863f6 | |||
861430e884 | |||
a9ccf1bcbd | |||
9d0bc09dee | |||
e7e13bffc0 | |||
edc183c7e2 | |||
dbe69a395a | |||
1578001094 | |||
1718f7c37a | |||
49597887f3 | |||
ad07563755 | |||
2e775d9fb2 |
21
README.md
21
README.md
@ -59,7 +59,12 @@ Make sure to disable this DVAR by adding ```set bots_main_firstIsHost 0``` in yo
|
||||
## Installation
|
||||
T4M requires an unpacked steamless version of the multiplayer World at War executable (otherwise known as LanFixed). You can use a [Steam Unpacker](https://github.com/atom0s/Steamless) on your multiplayer World at War Steam executable to acquire the required executable.
|
||||
|
||||
Also make sure that PunkBuster is disabled!
|
||||

|
||||
|
||||
0. Make sure that [T4M](https://github.com/ineedbots/T4M) is installed, updated and working properly.
|
||||
- Download the [d3d9.dll](https://github.com/ineedbots/T4M/releases) and place it into the root of your World at War install
|
||||
- Download the [WaW MP LanFixed](https://bit.ly/3803IUC) and place it into the root of your World at War install, you will use this executable to run the game.
|
||||
- Download the [latest release](https://github.com/ineedbots/t4m_bot_warfare/releases) of Bot Warfare.
|
||||
1. Extract all the files from the Bot Warfare release archive you downloaded to anywhere on your computer.
|
||||
2. Run the 'install.bat'. This copies the mod to your WaW mods folder.
|
||||
@ -162,6 +167,22 @@ T4M requires an unpacked steamless version of the multiplayer World at War execu
|
||||
- bots_main_debug - a boolean value (0 or 1), enables or disables the waypoint editor
|
||||
|
||||
## Changelog
|
||||
- v2.0.1
|
||||
- Reduced bots crouching
|
||||
- Increased bots sprinting
|
||||
- Improved bots mantling, crouching and knifing glass when needed
|
||||
- Fixed possible script runtime errors
|
||||
- Improved domination
|
||||
- Bots use explosives more if they have it
|
||||
- Bots aim slower when ads'ing
|
||||
- Fixed bots holding breath
|
||||
- Fixed bots rubberbanding movement when their goal changes
|
||||
- Added bots quickscoping with snipers
|
||||
- Added bots reload canceling and fast swaps
|
||||
- Bots use C4
|
||||
- Improved revenge
|
||||
- Bots can swap weapons on spawn more likely
|
||||
|
||||
- v2.0.0
|
||||
- Initial reboot release
|
||||
|
||||
|
BIN
main_shared/bw-assets/disable_pb.png
Normal file
BIN
main_shared/bw-assets/disable_pb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -8,7 +8,7 @@
|
||||
*/
|
||||
init()
|
||||
{
|
||||
level.bw_VERSION = "2.0.0";
|
||||
level.bw_VERSION = "2.0.1";
|
||||
|
||||
if(getDvar("bots_main") == "")
|
||||
setDvar("bots_main", true);
|
||||
|
@ -12,34 +12,34 @@
|
||||
*/
|
||||
getRemoteWaypoints(mapname)
|
||||
{
|
||||
url = "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/" + mapname + "_wp.csv";
|
||||
url = "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/" + mapname + "_wp.csv";
|
||||
filename = "waypoints/" + mapname + "_wp.csv";
|
||||
|
||||
PrintConsole("Attempting to get remote waypoints from " + url + "\n");
|
||||
res = getLinesFromUrl(url, filename);
|
||||
PrintConsole("Attempting to get remote waypoints from " + url + "\n");
|
||||
res = getLinesFromUrl(url, filename);
|
||||
|
||||
if (!res.lines.size)
|
||||
return;
|
||||
if (!res.lines.size)
|
||||
return;
|
||||
|
||||
waypointCount = int(res.lines[0]);
|
||||
waypointCount = int(res.lines[0]);
|
||||
|
||||
waypoints = [];
|
||||
PrintConsole("Loading remote waypoints...\n");
|
||||
PrintConsole("Loading remote waypoints...\n");
|
||||
|
||||
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)
|
||||
{
|
||||
level.waypoints = waypoints;
|
||||
PrintConsole("Loaded " + waypoints.size + " waypoints from remote.\n");
|
||||
}
|
||||
if (waypoints.size)
|
||||
{
|
||||
level.waypoints = waypoints;
|
||||
PrintConsole("Loaded " + waypoints.size + " waypoints from remote.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -71,12 +71,12 @@ doVersionCheck()
|
||||
*/
|
||||
getRemoteVersion()
|
||||
{
|
||||
data = httpGet( "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/version.txt" );
|
||||
data = httpGet( "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/version.txt" );
|
||||
|
||||
if (!isDefined(data))
|
||||
return undefined;
|
||||
|
||||
return strtok(data, "\n")[0];
|
||||
return strtok(data, "\n")[0];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -84,8 +84,8 @@ getRemoteVersion()
|
||||
*/
|
||||
getLinesFromUrl(url, filename)
|
||||
{
|
||||
result = spawnStruct();
|
||||
result.lines = [];
|
||||
result = spawnStruct();
|
||||
result.lines = [];
|
||||
|
||||
data = HTTPGet(url);
|
||||
|
||||
@ -109,7 +109,7 @@ getLinesFromUrl(url, filename)
|
||||
|
||||
line += c;
|
||||
}
|
||||
result.lines[result.lines.size] = line;
|
||||
result.lines[result.lines.size] = line;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ added()
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 1; // how far a bot's incorrect aim is
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; // how often a bot changes their bone target
|
||||
self.pers["bots"]["skill"]["bones"] = "j_head"; // a list of comma seperated bones the bot will aim at
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; // a factor of how much ads to reduce when adsing
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; // a factor of how much more aimspeed delay to add
|
||||
|
||||
self.pers["bots"]["behavior"] = [];
|
||||
self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target
|
||||
@ -43,6 +45,9 @@ added()
|
||||
self.pers["bots"]["behavior"]["switch"] = 1; // percentage of how often the bot will switch weapons
|
||||
self.pers["bots"]["behavior"]["class"] = 1; // percentage of how often the bot will change classes
|
||||
self.pers["bots"]["behavior"]["jump"] = 100; // percentage of how often the bot will jumpshot and dropshot
|
||||
|
||||
self.pers["bots"]["behavior"]["quickscope"] = false; // is a quickscoper
|
||||
self.pers["bots"]["behavior"]["initswitch"] = 10; // percentage of how often the bot will switch weapons on spawn
|
||||
}
|
||||
|
||||
/*
|
||||
@ -131,6 +136,8 @@ resetBotVars()
|
||||
self.bot.stop_move = false;
|
||||
self.bot.greedy_path = false;
|
||||
self.bot.climbing = false;
|
||||
self.bot.last_next_wp = -1;
|
||||
self.bot.last_second_next_wp = -1;
|
||||
|
||||
self.bot.isfrozen = false;
|
||||
self.bot.sprintendtime = -1;
|
||||
@ -145,8 +152,11 @@ resetBotVars()
|
||||
|
||||
self.bot.semi_time = false;
|
||||
self.bot.jump_time = undefined;
|
||||
self.bot.last_fire_time = -1;
|
||||
|
||||
self.bot.is_cur_full_auto = false;
|
||||
self.bot.cur_weap_dist_multi = 1;
|
||||
self.bot.is_cur_sniper = false;
|
||||
|
||||
self.bot.rand = randomInt(100);
|
||||
|
||||
@ -188,7 +198,6 @@ onPlayerSpawned()
|
||||
self thread onLastStand();
|
||||
|
||||
self thread reload_watch();
|
||||
self thread doBotMovement();
|
||||
self thread sprint_watch();
|
||||
|
||||
self thread spawned();
|
||||
@ -203,7 +212,9 @@ doBotMovement()
|
||||
self endon("disconnect");
|
||||
self endon("death");
|
||||
|
||||
for (;;)
|
||||
FORWARDAMOUNT = 25;
|
||||
|
||||
for (i=0;;i+=0.05)
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
@ -232,9 +243,43 @@ doBotMovement()
|
||||
dir = (dir[0], 0-dir[1], 0);
|
||||
}
|
||||
|
||||
// climb through windows
|
||||
if (self isMantling())
|
||||
self crouch();
|
||||
|
||||
|
||||
startPos = self.origin + (0, 0, 50);
|
||||
startPosForward = startPos + anglesToForward((0, angles[1], 0)) * FORWARDAMOUNT;
|
||||
bt = bulletTrace(startPos, startPosForward, false, self);
|
||||
if (bt["fraction"] >= 1)
|
||||
{
|
||||
// check if need to jump
|
||||
bt = bulletTrace(startPosForward, startPosForward - (0, 0, 40), false, self);
|
||||
|
||||
if (bt["fraction"] < 1 && bt["normal"][2] > 0.9 && i > 1.5 && !self isOnLadder())
|
||||
{
|
||||
i = 0;
|
||||
self thread jump();
|
||||
}
|
||||
}
|
||||
// check if need to knife glass
|
||||
else if (bt["surfacetype"] == "glass")
|
||||
{
|
||||
if (i > 1.5)
|
||||
{
|
||||
i = 0;
|
||||
self thread knife();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if need to crouch
|
||||
if (bulletTracePassed(startPos - (0, 0, 25), startPosForward - (0, 0, 25), false, self))
|
||||
self crouch();
|
||||
}
|
||||
|
||||
// move!
|
||||
self botMovement(int(dir[0]), int(dir[1]));
|
||||
self setPing(randomIntRange(45, 55));
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,6 +293,7 @@ spawned()
|
||||
|
||||
wait self.pers["bots"]["skill"]["spawn_time"];
|
||||
|
||||
self thread doBotMovement();
|
||||
self thread grenade_danger();
|
||||
self thread check_reload();
|
||||
self thread stance();
|
||||
@ -257,10 +303,108 @@ spawned()
|
||||
self thread aim();
|
||||
self thread watchHoldBreath();
|
||||
self thread onNewEnemy();
|
||||
self thread watchGrenadeFire();
|
||||
|
||||
self notify("bot_spawned");
|
||||
}
|
||||
|
||||
/*
|
||||
Watches when the bot fires a grenade
|
||||
*/
|
||||
watchGrenadeFire()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("death");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "grenade_fire", nade, weapname );
|
||||
|
||||
if ( weapname == "satchel_charge_mp" )
|
||||
self thread watchC4Thrown(nade);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Watches the c4
|
||||
*/
|
||||
watchC4Thrown(c4)
|
||||
{
|
||||
self endon("disconnect");
|
||||
c4 endon("death");
|
||||
|
||||
wait 0.5;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait 1 + randomInt(50) * 0.05;
|
||||
|
||||
shouldBreak = false;
|
||||
for (i = 0; i < level.players.size; i++)
|
||||
{
|
||||
player = level.players[i];
|
||||
|
||||
if(player == self)
|
||||
continue;
|
||||
|
||||
if((level.teamBased && self.team == player.team) || player.sessionstate != "playing" || !isAlive(player))
|
||||
continue;
|
||||
|
||||
if (distanceSquared(c4.origin, player.origin) > 200*200)
|
||||
continue;
|
||||
|
||||
if (!bulletTracePassed(c4.origin, player.origin + (0, 0, 25), false, c4))
|
||||
continue;
|
||||
|
||||
shouldBreak = true;
|
||||
}
|
||||
|
||||
if (shouldBreak)
|
||||
break;
|
||||
}
|
||||
|
||||
weap = self getCurrentWeapon();
|
||||
if ( weap != "satchel_charge_mp" )
|
||||
self notify( "alt_detonate" );
|
||||
else
|
||||
self thread pressFire();
|
||||
}
|
||||
|
||||
/*
|
||||
Sets the factor of distance for a weapon
|
||||
*/
|
||||
SetWeaponDistMulti(weap)
|
||||
{
|
||||
if (weap == "none")
|
||||
return 1;
|
||||
|
||||
switch(weaponClass(weap))
|
||||
{
|
||||
case "rifle":
|
||||
return 0.9;
|
||||
case "smg":
|
||||
return 0.7;
|
||||
case "pistol":
|
||||
return 0.5;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Is the weap a sniper
|
||||
*/
|
||||
IsWeapSniper(weap)
|
||||
{
|
||||
if (weap == "none")
|
||||
return false;
|
||||
|
||||
if (maps\mp\gametypes\_missions::getWeaponClass(weap) != "weapon_sniper")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
The hold breath thread.
|
||||
*/
|
||||
@ -276,7 +420,7 @@ watchHoldBreath()
|
||||
if(self.bot.isfrozen)
|
||||
continue;
|
||||
|
||||
self holdbreath((self playerADS() && weaponClass(self getCurrentWEapon()) == "rifle"));
|
||||
self holdbreath(self playerADS() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,21 +469,24 @@ onWeaponChange()
|
||||
self endon("disconnect");
|
||||
self endon("death");
|
||||
|
||||
weap = self GetCurrentWeapon();
|
||||
self.bot.is_cur_full_auto = WeaponIsFullAuto(weap);
|
||||
if (weap != "none")
|
||||
self changeToWeap(weap);
|
||||
|
||||
first = true;
|
||||
for(;;)
|
||||
{
|
||||
self waittill( "weapon_change", newWeapon );
|
||||
newWeapon = undefined;
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
newWeapon = self getCurrentWeapon();
|
||||
}
|
||||
else
|
||||
self waittill( "weapon_change", newWeapon );
|
||||
|
||||
self.bot.is_cur_full_auto = WeaponIsFullAuto(newWeapon);
|
||||
self.bot.cur_weap_dist_multi = SetWeaponDistMulti(newWeapon);
|
||||
self.bot.is_cur_sniper = IsWeapSniper(newWeapon);
|
||||
|
||||
if (newWeapon == "none")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
self changeToWeap(newWeapon);
|
||||
}
|
||||
@ -375,7 +522,18 @@ reload_watch()
|
||||
{
|
||||
self waittill("reload_start");
|
||||
self.bot.isreloading = true;
|
||||
self waittill_notify_or_timeout("reload", 7.5);
|
||||
|
||||
while(true)
|
||||
{
|
||||
ret = self waittill_any_timeout(7.5, "reload");
|
||||
|
||||
if (ret == "timeout")
|
||||
break;
|
||||
|
||||
weap = self GetCurrentWeapon();
|
||||
if (self GetWeaponAmmoClip(weap) >= WeaponClipSize(weap))
|
||||
break;
|
||||
}
|
||||
self.bot.isreloading = false;
|
||||
}
|
||||
}
|
||||
@ -424,17 +582,25 @@ stance()
|
||||
self prone();
|
||||
|
||||
curweap = self getCurrentWeapon();
|
||||
time = getTime();
|
||||
chance = self.pers["bots"]["behavior"]["sprint"];
|
||||
|
||||
if (time - self.lastSpawnTime < 5000)
|
||||
chance *= 2;
|
||||
|
||||
if(isDefined(self.bot.script_goal) && DistanceSquared(self.origin, self.bot.script_goal) > 256*256)
|
||||
chance *= 2;
|
||||
|
||||
if(toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter)
|
||||
continue;
|
||||
|
||||
if(randomInt(100) > self.pers["bots"]["behavior"]["sprint"])
|
||||
if(randomInt(100) > chance)
|
||||
continue;
|
||||
|
||||
if(isDefined(self.bot.target) && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
|
||||
continue;
|
||||
|
||||
if(self.bot.sprintendtime != -1 && getTime() - self.bot.sprintendtime < 2000)
|
||||
if(self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000)
|
||||
continue;
|
||||
|
||||
if(!isDefined(self.bot.towards_goal) || DistanceSquared(self.origin, self.bot.towards_goal) < level.bots_minSprintDistance || getConeDot(self.bot.towards_goal, self.origin, self GetPlayerAngles()) < 0.75)
|
||||
@ -630,9 +796,11 @@ updateAimOffset(obj)
|
||||
targetObjUpdateTraced(obj, daDist, ent, theTime, isScriptObj)
|
||||
{
|
||||
distClose = self.pers["bots"]["skill"]["dist_start"];
|
||||
distClose *= self.bot.cur_weap_dist_multi;
|
||||
distClose *= distClose;
|
||||
|
||||
distMax = self.pers["bots"]["skill"]["dist_max"];
|
||||
distMax *= self.bot.cur_weap_dist_multi;
|
||||
distMax *= distMax;
|
||||
|
||||
timeMulti = 1;
|
||||
@ -683,10 +851,12 @@ target()
|
||||
myAngles = self GetPlayerAngles();
|
||||
myFov = self.pers["bots"]["skill"]["fov"];
|
||||
bestTargets = [];
|
||||
bestTime = 9999999999;
|
||||
bestTime = 2147483647;
|
||||
rememberTime = self.pers["bots"]["skill"]["remember_time"];
|
||||
initReactTime = self.pers["bots"]["skill"]["init_react_time"];
|
||||
hasTarget = isDefined(self.bot.target);
|
||||
adsAmount = self PlayerADS();
|
||||
adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"];
|
||||
|
||||
if(hasTarget && !isDefined(self.bot.target.entity))
|
||||
{
|
||||
@ -695,7 +865,10 @@ target()
|
||||
}
|
||||
|
||||
// reduce fov if ads'ing
|
||||
myFov *= 1 - 0.5 * self PlayerADS();
|
||||
if (adsAmount > 0)
|
||||
{
|
||||
myFov *= 1 - adsFovFact * adsAmount;
|
||||
}
|
||||
|
||||
playercount = level.players.size;
|
||||
for(i = -1; i < playercount; i++)
|
||||
@ -830,7 +1003,7 @@ target()
|
||||
if(hasTarget && isDefined(bestTargets[self.bot.target.entity getEntityNumber()+""]))
|
||||
continue;
|
||||
|
||||
closest = 9999999999;
|
||||
closest = 2147483647;
|
||||
toBeTarget = undefined;
|
||||
|
||||
bestKeys = getArrayKeys(bestTargets);
|
||||
@ -922,6 +1095,9 @@ watchToLook()
|
||||
if(!self isInRange(self.bot.target.dist, curweap))
|
||||
continue;
|
||||
|
||||
if (self.bot.is_cur_sniper)
|
||||
continue;
|
||||
|
||||
if(randomInt(100) > self.pers["bots"]["behavior"]["jump"])
|
||||
continue;
|
||||
|
||||
@ -1006,6 +1182,14 @@ aim()
|
||||
eyePos = self getEyePos();
|
||||
curweap = self getCurrentWeapon();
|
||||
angles = self GetPlayerAngles();
|
||||
adsAmount = self PlayerADS();
|
||||
adsAimSpeedFact = self.pers["bots"]["skill"]["ads_aimspeed_multi"];
|
||||
|
||||
// reduce aimspeed if ads'ing
|
||||
if (adsAmount > 0)
|
||||
{
|
||||
aimspeed *= 1 + adsAimSpeedFact * adsAmount;
|
||||
}
|
||||
|
||||
if(isDefined(self.bot.target) && isDefined(self.bot.target.entity))
|
||||
{
|
||||
@ -1072,7 +1256,10 @@ aim()
|
||||
else
|
||||
{
|
||||
if (self canAds(dist, curweap))
|
||||
self thread pressADS();
|
||||
{
|
||||
if (!self.bot.is_cur_sniper || !self.pers["bots"]["behavior"]["quickscope"])
|
||||
self thread pressAds();
|
||||
}
|
||||
}
|
||||
|
||||
self thread bot_lookat(last_pos + (0, 0, self getEyeHeight() + nadeAimOffset), aimspeed);
|
||||
@ -1083,7 +1270,14 @@ aim()
|
||||
{
|
||||
if(isplay)
|
||||
{
|
||||
if (!target IsPlayerModelOK())
|
||||
continue;
|
||||
|
||||
aimpos = target getTagOrigin( bone );
|
||||
|
||||
if (!isDefined(aimpos))
|
||||
continue;
|
||||
|
||||
aimpos += offset;
|
||||
aimpos += aimoffset;
|
||||
aimpos += (0, 0, nadeAimOffset);
|
||||
@ -1119,13 +1313,25 @@ aim()
|
||||
|
||||
//c4 logic here, but doesnt work anyway
|
||||
|
||||
canADS = self canAds(dist, curweap);
|
||||
canADS = (self canAds(dist, curweap) && conedot > 0.75);
|
||||
if (canADS)
|
||||
self thread pressADS();
|
||||
{
|
||||
stopAdsOverride = false;
|
||||
if (self.bot.is_cur_sniper)
|
||||
{
|
||||
if (self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000)
|
||||
stopAdsOverride = true;
|
||||
else
|
||||
self notify("kill_goal");
|
||||
}
|
||||
|
||||
if (!stopAdsOverride)
|
||||
self thread pressAds();
|
||||
}
|
||||
|
||||
if (trace_time > reaction_time)
|
||||
{
|
||||
if((!canADS || self playerads() == 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
|
||||
if((!canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.99 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
|
||||
self botFire();
|
||||
|
||||
if (isplay)
|
||||
@ -1156,11 +1362,23 @@ aim()
|
||||
if(!self canFire(curweap) || !self isInRange(dist, curweap))
|
||||
continue;
|
||||
|
||||
canADS = self canAds(dist, curweap);
|
||||
canADS = (self canAds(dist, curweap) && conedot > 0.75);
|
||||
if (canADS)
|
||||
self thread pressADS();
|
||||
{
|
||||
stopAdsOverride = false;
|
||||
if (self.bot.is_cur_sniper)
|
||||
{
|
||||
if (self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000)
|
||||
stopAdsOverride = true;
|
||||
else
|
||||
self notify("kill_goal");
|
||||
}
|
||||
|
||||
if((!canADS || self playerads() == 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
|
||||
if (!stopAdsOverride)
|
||||
self thread pressAds();
|
||||
}
|
||||
|
||||
if((!canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
|
||||
self botFire();
|
||||
|
||||
continue;
|
||||
@ -1196,6 +1414,8 @@ aim()
|
||||
*/
|
||||
botFire()
|
||||
{
|
||||
self.bot.last_fire_time = getTime();
|
||||
|
||||
if(self.bot.is_cur_full_auto)
|
||||
{
|
||||
self thread pressFire();
|
||||
@ -1313,6 +1533,8 @@ walk()
|
||||
|
||||
if(self isFlared())
|
||||
{
|
||||
self.bot.last_next_wp = -1;
|
||||
self.bot.last_second_next_wp = -1;
|
||||
self botMoveTo(self.origin + self GetVelocity()*500);
|
||||
continue;
|
||||
}
|
||||
@ -1332,7 +1554,7 @@ walk()
|
||||
|
||||
if(self.bot.target.isplay && self.bot.target.trace_time && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
|
||||
{
|
||||
if (self InLastStand() || self GetStance() == "prone")
|
||||
if (self InLastStand() || self GetStance() == "prone" || (self.bot.is_cur_sniper && self PlayerADS() > 0))
|
||||
continue;
|
||||
|
||||
if(self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"])
|
||||
@ -1428,6 +1650,8 @@ strafe(target)
|
||||
if(traceRight["fraction"] > traceLeft["fraction"])
|
||||
strafe = traceRight["position"];
|
||||
|
||||
self.bot.last_next_wp = -1;
|
||||
self.bot.last_second_next_wp = -1;
|
||||
self botMoveTo(strafe);
|
||||
wait 2;
|
||||
self notify("kill_goal");
|
||||
@ -1539,39 +1763,34 @@ doWalk(goal, dist, isScriptGoal)
|
||||
self thread watchOnGoal(goal, distsq);
|
||||
|
||||
current = self initAStar(goal);
|
||||
// if a waypoint is closer than the goal
|
||||
//if (current >= 0 && DistanceSquared(self.origin, level.waypoints[self.bot.astar[current]].origin) < DistanceSquared(self.origin, goal))
|
||||
//{
|
||||
while(current >= 0)
|
||||
// skip waypoints we already completed to prevent rubber banding
|
||||
if (current > 0 && self.bot.astar[current] == self.bot.last_next_wp && self.bot.astar[current-1] == self.bot.last_second_next_wp)
|
||||
current = self removeAStar();
|
||||
|
||||
if (current >= 0)
|
||||
{
|
||||
// check if a waypoint is closer than the goal
|
||||
wpOrg = level.waypoints[self.bot.astar[current]].origin;
|
||||
ppt = PlayerPhysicsTrace(self.origin + (0,0,32), wpOrg, false, self);
|
||||
if (DistanceSquared(self.origin, wpOrg) < DistanceSquared(self.origin, goal) || DistanceSquared(wpOrg, ppt) > 1.0)
|
||||
{
|
||||
// skip down the line of waypoints and go to the waypoint we have a direct path too
|
||||
/*for (;;)
|
||||
while(current >= 0)
|
||||
{
|
||||
if (current <= 0)
|
||||
break;
|
||||
self.bot.next_wp = self.bot.astar[current];
|
||||
self.bot.second_next_wp = -1;
|
||||
if(current > 0)
|
||||
self.bot.second_next_wp = self.bot.astar[current-1];
|
||||
|
||||
ppt = PlayerPhysicsTrace(self.origin + (0,0,32), level.waypoints[self.bot.astar[current-1]].origin, false, self);
|
||||
if (DistanceSquared(level.waypoints[self.bot.astar[current-1]].origin, ppt) > 1.0)
|
||||
break;
|
||||
self notify("new_static_waypoint");
|
||||
|
||||
if (level.waypoints[self.bot.astar[current-1]].type == "climb" || level.waypoints[self.bot.astar[current]].type == "climb")
|
||||
break;
|
||||
self movetowards(level.waypoints[self.bot.next_wp].origin);
|
||||
self.bot.last_next_wp = self.bot.next_wp;
|
||||
self.bot.last_second_next_wp = self.bot.second_next_wp;
|
||||
|
||||
current = self removeAStar();
|
||||
}*/
|
||||
|
||||
self.bot.next_wp = self.bot.astar[current];
|
||||
self.bot.second_next_wp = -1;
|
||||
if(current != 0)
|
||||
self.bot.second_next_wp = self.bot.astar[current-1];
|
||||
|
||||
self notify("new_static_waypoint");
|
||||
|
||||
self movetowards(level.waypoints[self.bot.next_wp].origin);
|
||||
|
||||
current = self removeAStar();
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
self.bot.next_wp = -1;
|
||||
self.bot.second_next_wp = -1;
|
||||
@ -1579,6 +1798,8 @@ doWalk(goal, dist, isScriptGoal)
|
||||
|
||||
if(DistanceSquared(self.origin, goal) > distsq)
|
||||
{
|
||||
self.bot.last_next_wp = -1;
|
||||
self.bot.last_second_next_wp = -1;
|
||||
self movetowards(goal); // any better way??
|
||||
}
|
||||
|
||||
@ -1607,17 +1828,18 @@ movetowards(goal)
|
||||
{
|
||||
self botMoveTo(goal);
|
||||
|
||||
if(time > 3)
|
||||
if(time > 3.5)
|
||||
{
|
||||
time = 0;
|
||||
if(distanceSquared(self.origin, lastOri) < 128)
|
||||
{
|
||||
self thread knife();
|
||||
wait 0.5;
|
||||
|
||||
stucks++;
|
||||
|
||||
randomDir = self getRandomLargestStafe(stucks);
|
||||
|
||||
self knife(); // knife glass
|
||||
wait 0.25;
|
||||
self botMoveTo(randomDir);
|
||||
wait stucks;
|
||||
}
|
||||
@ -1626,7 +1848,7 @@ movetowards(goal)
|
||||
}
|
||||
else if(timeslow > 1.5)
|
||||
{
|
||||
self thread jump();
|
||||
self thread doMantle();
|
||||
}
|
||||
else if(timeslow > 0.75)
|
||||
{
|
||||
@ -1648,6 +1870,22 @@ movetowards(goal)
|
||||
self notify("completed_move_to");
|
||||
}
|
||||
|
||||
/*
|
||||
Bots do the mantle
|
||||
*/
|
||||
doMantle()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("death");
|
||||
self endon("kill_goal");
|
||||
|
||||
self jump();
|
||||
|
||||
wait 0.35;
|
||||
|
||||
self jump();
|
||||
}
|
||||
|
||||
/*
|
||||
Will return the pos of the largest trace from the bot.
|
||||
*/
|
||||
|
@ -28,6 +28,7 @@ connected()
|
||||
self endon("disconnect");
|
||||
|
||||
self.killerLocation = undefined;
|
||||
self.lastKiller = undefined;
|
||||
|
||||
self thread difficulty();
|
||||
self thread teamWatch();
|
||||
@ -43,6 +44,7 @@ connected()
|
||||
onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
|
||||
{
|
||||
self.killerLocation = undefined;
|
||||
self.lastKiller = undefined;
|
||||
|
||||
if(!IsDefined( self ) || !isDefined(self.team))
|
||||
return;
|
||||
@ -69,6 +71,7 @@ onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc,
|
||||
return;
|
||||
|
||||
self.killerLocation = eAttacker.origin;
|
||||
self.lastKiller = eAttacker;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -275,219 +278,233 @@ difficulty()
|
||||
|
||||
for(;;)
|
||||
{
|
||||
wait 1;
|
||||
|
||||
rankVar = GetDvarInt("bots_skill");
|
||||
|
||||
if(rankVar == 9)
|
||||
continue;
|
||||
|
||||
switch(self.pers["bots"]["skill"]["base"])
|
||||
if(rankVar != 9)
|
||||
{
|
||||
case 1:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.6;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 500;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 600;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 750;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.7;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 2500;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 1000;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 0;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.9;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 1;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 1.5;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 4;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 2;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri";
|
||||
switch(self.pers["bots"]["skill"]["base"])
|
||||
{
|
||||
case 1:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.6;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 500;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 600;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 750;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.7;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 2500;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 1000;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 0;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.9;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 1;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 1.5;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 4;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 2;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 0;
|
||||
self.pers["bots"]["behavior"]["nade"] = 10;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 10;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 70;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 0;
|
||||
break;
|
||||
case 2:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.55;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 800;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 1250;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.65;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 3000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 1500;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.65;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 500;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 1;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 3;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 1.5;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri,j_head";
|
||||
self.pers["bots"]["behavior"]["strafe"] = 0;
|
||||
self.pers["bots"]["behavior"]["nade"] = 10;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 30;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 20;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 0;
|
||||
break;
|
||||
case 2:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.55;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 800;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 1250;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.65;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 3000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 1500;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.65;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 500;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 1;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 3;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 1.5;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri,j_head";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 10;
|
||||
self.pers["bots"]["behavior"]["nade"] = 15;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 15;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 60;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 10;
|
||||
break;
|
||||
case 3:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.4;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 750;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 500;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 2000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.6;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 4000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 2250;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 750;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.65;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.65;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 1;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head";
|
||||
self.pers["bots"]["behavior"]["strafe"] = 10;
|
||||
self.pers["bots"]["behavior"]["nade"] = 15;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 45;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 15;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 10;
|
||||
break;
|
||||
case 3:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.4;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 750;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 500;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 2000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.6;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 4000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 2250;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 750;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.65;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.65;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.75;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 1;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 20;
|
||||
self.pers["bots"]["behavior"]["nade"] = 20;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 20;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 50;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 25;
|
||||
break;
|
||||
case 4:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.3;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 600;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 400;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 3000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.55;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 5000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 3350;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.35;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 1000;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 2;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.75;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head,j_head";
|
||||
self.pers["bots"]["behavior"]["strafe"] = 20;
|
||||
self.pers["bots"]["behavior"]["nade"] = 20;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 50;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 10;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 25;
|
||||
break;
|
||||
case 4:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.3;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 600;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 400;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 3000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.55;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 5000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 3350;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.35;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 1000;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.5;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 2;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.75;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head,j_head";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 30;
|
||||
self.pers["bots"]["behavior"]["nade"] = 25;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 30;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 40;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 35;
|
||||
break;
|
||||
case 5:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 500;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 300;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 2000;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 4000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.5;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 7500;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 5000;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 1500;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.4;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.35;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.35;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 1.5;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.5;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head";
|
||||
self.pers["bots"]["behavior"]["strafe"] = 30;
|
||||
self.pers["bots"]["behavior"]["nade"] = 25;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 55;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 10;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 35;
|
||||
break;
|
||||
case 5:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 500;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 300;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 2000;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 4000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.5;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 7500;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 5000;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 1500;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.4;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.35;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.35;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 1.5;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.5;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 40;
|
||||
self.pers["bots"]["behavior"]["nade"] = 35;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 40;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 30;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 50;
|
||||
break;
|
||||
case 6:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.2;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 250;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 150;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 3000;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 5000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.45;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 10000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 7500;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.2;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 2000;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 1;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.25;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head,j_head";
|
||||
self.pers["bots"]["behavior"]["strafe"] = 40;
|
||||
self.pers["bots"]["behavior"]["nade"] = 35;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 60;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 10;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 50;
|
||||
break;
|
||||
case 6:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.2;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 250;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 150;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 3000;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 5000;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.45;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 10000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 7500;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.2;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 2000;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0.25;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 1;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.25;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head,j_head";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 50;
|
||||
self.pers["bots"]["behavior"]["nade"] = 45;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 50;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 20;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 75;
|
||||
break;
|
||||
case 7:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.1;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 100;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 50;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 4000;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 7500;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.4;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 15000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 10000;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.05;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 3000;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.1;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 0;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.05;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_head";
|
||||
self.pers["bots"]["behavior"]["strafe"] = 50;
|
||||
self.pers["bots"]["behavior"]["nade"] = 45;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 65;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 10;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 75;
|
||||
break;
|
||||
case 7:
|
||||
self.pers["bots"]["skill"]["aim_time"] = 0.1;
|
||||
self.pers["bots"]["skill"]["init_react_time"] = 100;
|
||||
self.pers["bots"]["skill"]["reaction_time"] = 50;
|
||||
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500;
|
||||
self.pers["bots"]["skill"]["no_trace_look_time"] = 4000;
|
||||
self.pers["bots"]["skill"]["remember_time"] = 7500;
|
||||
self.pers["bots"]["skill"]["fov"] = 0.4;
|
||||
self.pers["bots"]["skill"]["dist_max"] = 15000;
|
||||
self.pers["bots"]["skill"]["dist_start"] = 10000;
|
||||
self.pers["bots"]["skill"]["spawn_time"] = 0.05;
|
||||
self.pers["bots"]["skill"]["help_dist"] = 3000;
|
||||
self.pers["bots"]["skill"]["semi_time"] = 0.1;
|
||||
self.pers["bots"]["skill"]["shoot_after_time"] = 0;
|
||||
self.pers["bots"]["skill"]["aim_offset_time"] = 0;
|
||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 0;
|
||||
self.pers["bots"]["skill"]["bone_update_interval"] = 0.05;
|
||||
self.pers["bots"]["skill"]["bones"] = "j_head";
|
||||
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5;
|
||||
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5;
|
||||
|
||||
self.pers["bots"]["behavior"]["strafe"] = 65;
|
||||
self.pers["bots"]["behavior"]["nade"] = 65;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 65;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 5;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 90;
|
||||
break;
|
||||
self.pers["bots"]["behavior"]["strafe"] = 65;
|
||||
self.pers["bots"]["behavior"]["nade"] = 65;
|
||||
self.pers["bots"]["behavior"]["sprint"] = 70;
|
||||
self.pers["bots"]["behavior"]["camp"] = 5;
|
||||
self.pers["bots"]["behavior"]["follow"] = 5;
|
||||
self.pers["bots"]["behavior"]["crouch"] = 5;
|
||||
self.pers["bots"]["behavior"]["switch"] = 2;
|
||||
self.pers["bots"]["behavior"]["class"] = 2;
|
||||
self.pers["bots"]["behavior"]["jump"] = 90;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wait 5;
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,6 +578,11 @@ set_class(rankxp)
|
||||
|
||||
rank = self maps\mp\gametypes\_rank::getRankForXp( rankxp ) + 1;
|
||||
|
||||
if (RandomFloatRange(0, 1) < ((rank / level.maxRank) + 0.1))
|
||||
{
|
||||
self.pers["bots"]["behavior"]["quickscope"] = true;
|
||||
}
|
||||
|
||||
for(i=0; i < 5; i++)
|
||||
{
|
||||
primary = get_random_weapon(primaryGroups, rank);
|
||||
@ -969,6 +991,7 @@ start_bot_threads()
|
||||
self thread bot_killstreak_think();
|
||||
|
||||
self thread bot_weapon_think();
|
||||
self thread doReloadCancel();
|
||||
|
||||
// script targeting
|
||||
if (getDvarInt("bots_play_target_other"))
|
||||
@ -997,6 +1020,7 @@ start_bot_threads()
|
||||
self thread bot_use_tube_think();
|
||||
self thread bot_use_grenade_think();
|
||||
self thread bot_use_equipment_think();
|
||||
self thread bot_watch_think_mw2();
|
||||
}
|
||||
|
||||
// obj
|
||||
@ -1029,6 +1053,9 @@ bot_inc_bots(obj, unreach)
|
||||
level endon("game_ended");
|
||||
self endon("bot_inc_bots");
|
||||
|
||||
if (!isDefined(obj))
|
||||
return;
|
||||
|
||||
if (!isDefined(obj.bots))
|
||||
obj.bots = 0;
|
||||
|
||||
@ -1094,7 +1121,7 @@ nearAnyOfWaypoints(dist, waypoints)
|
||||
getNearestWaypointOfWaypoints(waypoints)
|
||||
{
|
||||
answer = undefined;
|
||||
closestDist = 999999999999;
|
||||
closestDist = 2147483647;
|
||||
for (i = 0; i < waypoints.size; i++)
|
||||
{
|
||||
waypoint = waypoints[i];
|
||||
@ -1370,6 +1397,23 @@ fire_current_weapon()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fires the bots c4
|
||||
*/
|
||||
fire_c4()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("disconnect");
|
||||
self endon("weapon_change");
|
||||
self endon("stop_firing_weapon");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self thread BotPressAds(0.05);
|
||||
wait 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Changes to the weap
|
||||
*/
|
||||
@ -1556,6 +1600,12 @@ bot_revive_think()
|
||||
if ( self HasScriptGoal() || self.bot_lock_goal )
|
||||
continue;
|
||||
|
||||
if(self isDefusing() || self isPlanting())
|
||||
continue;
|
||||
|
||||
if (self inLastStand())
|
||||
continue;
|
||||
|
||||
revivePlayer = undefined;
|
||||
for(i = 0; i < level.players.size; i++)
|
||||
{
|
||||
@ -1599,7 +1649,7 @@ bot_revive_think()
|
||||
if (event != "new_goal")
|
||||
self ClearScriptGoal();
|
||||
|
||||
if(event != "goal" || (isDefined(revivePlayer.currentlyBeingRevived) && revivePlayer.currentlyBeingRevived) || !self isTouching(revivePlayer.revivetrigger) || self InLastStand() || self HasThreat())
|
||||
if(event != "goal" || !isDefined(revivePlayer) || (isDefined(revivePlayer.currentlyBeingRevived) && revivePlayer.currentlyBeingRevived) || !self isTouching(revivePlayer.revivetrigger) || self InLastStand() || self isDefusing() || self isPlanting())
|
||||
{
|
||||
self.bot_lock_goal = false;
|
||||
continue;
|
||||
@ -2028,6 +2078,8 @@ bot_use_equipment_think()
|
||||
nade = undefined;
|
||||
if (self GetAmmoCount("mine_bouncing_betty_mp"))
|
||||
nade = "mine_bouncing_betty_mp";
|
||||
if (self GetAmmoCount("satchel_charge_mp"))
|
||||
nade = "satchel_charge_mp";
|
||||
|
||||
if (!isDefined(nade))
|
||||
continue;
|
||||
@ -2105,7 +2157,10 @@ bot_use_equipment_think()
|
||||
|
||||
if (self changeToWeapon(nade))
|
||||
{
|
||||
self thread fire_current_weapon();
|
||||
if (nade != "satchel_charge_mp")
|
||||
self thread fire_current_weapon();
|
||||
else
|
||||
self thread fire_c4();
|
||||
self waittill_any_timeout(5, "grenade_fire", "weapon_change");
|
||||
self notify("stop_firing_weapon");
|
||||
}
|
||||
@ -2348,9 +2403,19 @@ bot_revenge_think()
|
||||
if(self.pers["bots"]["skill"]["base"] <= 1)
|
||||
return;
|
||||
|
||||
if (isDefined(self.lastKiller) && isAlive(self.lastKiller))
|
||||
{
|
||||
if(bulletTracePassed(self getEyePos(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller))
|
||||
{
|
||||
self setAttacker(self.lastKiller);
|
||||
}
|
||||
}
|
||||
|
||||
if(!isDefined(self.killerLocation))
|
||||
return;
|
||||
|
||||
loc = self.killerLocation;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
wait( RandomIntRange( 1, 5 ) );
|
||||
@ -2361,13 +2426,80 @@ bot_revenge_think()
|
||||
if ( randomint( 100 ) < 75 )
|
||||
return;
|
||||
|
||||
self SetScriptGoal( self.killerLocation, 64 );
|
||||
self SetScriptGoal( loc, 64 );
|
||||
|
||||
if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
|
||||
self ClearScriptGoal();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Reload cancels
|
||||
*/
|
||||
doReloadCancel()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("death");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ret = self waittill_any_return("reload", "weapon_change");
|
||||
|
||||
if(self BotIsFrozen())
|
||||
continue;
|
||||
|
||||
if(self isDefusing() || self isPlanting())
|
||||
continue;
|
||||
|
||||
if (self InLastStand())
|
||||
continue;
|
||||
|
||||
curWeap = self GetCurrentWeapon();
|
||||
|
||||
if (!maps\mp\gametypes\_weapons::isSideArm( curWeap ) && !maps\mp\gametypes\_weapons::isPrimaryWeapon( curWeap ))
|
||||
continue;
|
||||
|
||||
if (ret == "reload")
|
||||
{
|
||||
// check single reloads
|
||||
if (self GetWeaponAmmoClip(curWeap) < WeaponClipSize(curWeap))
|
||||
continue;
|
||||
}
|
||||
|
||||
// check difficulty
|
||||
if (self.pers["bots"]["skill"]["base"] <= 3)
|
||||
continue;
|
||||
|
||||
// check if got another weapon
|
||||
weaponslist = self GetWeaponsListPrimaries();
|
||||
weap = "";
|
||||
while(weaponslist.size)
|
||||
{
|
||||
weapon = weaponslist[randomInt(weaponslist.size)];
|
||||
weaponslist = array_remove(weaponslist, weapon);
|
||||
|
||||
if (!maps\mp\gametypes\_weapons::isSideArm( weapon ) && !maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ))
|
||||
continue;
|
||||
|
||||
if(curWeap == weapon || weapon == "none" || weapon == "")
|
||||
continue;
|
||||
|
||||
weap = weapon;
|
||||
break;
|
||||
}
|
||||
|
||||
if(weap == "")
|
||||
continue;
|
||||
|
||||
// do the cancel
|
||||
wait 0.1;
|
||||
self BotChangeToWeapon(weap);
|
||||
wait 0.25;
|
||||
self BotChangeToWeapon(curWeap);
|
||||
wait 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Bot logic for switching weapons.
|
||||
*/
|
||||
@ -2377,6 +2509,8 @@ bot_weapon_think()
|
||||
self endon("disconnect");
|
||||
level endon("game_ended");
|
||||
|
||||
first = true;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
self waittill_any_timeout(randomIntRange(2, 4), "bot_force_check_switch");
|
||||
@ -2402,14 +2536,24 @@ bot_weapon_think()
|
||||
}
|
||||
}
|
||||
|
||||
if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "satchel_charge_mp" && curWeap != "squadcommand_mp")
|
||||
if (first)
|
||||
{
|
||||
if(randomInt(100) > self.pers["bots"]["behavior"]["switch"])
|
||||
continue;
|
||||
first = false;
|
||||
|
||||
if(hasTarget)
|
||||
if(randomInt(100) > self.pers["bots"]["behavior"]["initswitch"])
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "squadcommand_mp")
|
||||
{
|
||||
if(randomInt(100) > self.pers["bots"]["behavior"]["switch"])
|
||||
continue;
|
||||
|
||||
if(hasTarget)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
weaponslist = self getweaponslist();
|
||||
weap = "";
|
||||
@ -2427,7 +2571,7 @@ bot_weapon_think()
|
||||
if (maps\mp\gametypes\_weapons::isGrenade( weapon ))
|
||||
continue;
|
||||
|
||||
if(curWeap == weapon || weapon == "satchel_charge_mp" || weapon == "none" || weapon == "mine_bouncing_betty_mp" || weapon == "" || weapon == "squadcommand_mp")//c4 no work
|
||||
if(curWeap == weapon || weapon == "satchel_charge_mp" || weapon == "none" || weapon == "mine_bouncing_betty_mp" || weapon == "" || weapon == "squadcommand_mp")
|
||||
continue;
|
||||
|
||||
weap = weapon;
|
||||
@ -2441,6 +2585,52 @@ bot_weapon_think()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Bots play mw2
|
||||
*/
|
||||
bot_watch_think_mw2()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("death");
|
||||
level endon("game_ended");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait randomIntRange(1, 4);
|
||||
|
||||
if(self BotIsFrozen())
|
||||
continue;
|
||||
|
||||
if(self isDefusing() || self isPlanting())
|
||||
continue;
|
||||
|
||||
if (self InLastStand())
|
||||
continue;
|
||||
|
||||
if (self HasThreat())
|
||||
continue;
|
||||
|
||||
tube = self getValidTube();
|
||||
if (!isDefined(tube))
|
||||
{
|
||||
if (self GetAmmoCount("bazooka_mp"))
|
||||
tube = "bazooka_mp";
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self GetCurrentWeapon() == tube)
|
||||
continue;
|
||||
|
||||
chance = self.pers["bots"]["behavior"]["nade"];
|
||||
|
||||
if (randomInt(100) > chance)
|
||||
continue;
|
||||
|
||||
self ChangeToWeapon(tube);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Bot logic for killstreaks.
|
||||
*/
|
||||
@ -2538,8 +2728,12 @@ bot_killstreak_think()
|
||||
|
||||
if (isAirstrikePos && !isDefined( level.artilleryInProgress ))
|
||||
{
|
||||
self BotFreezeControls(true);
|
||||
|
||||
self notify( "confirm_location", targetPos );
|
||||
wait 1;
|
||||
|
||||
self BotFreezeControls(false);
|
||||
}
|
||||
|
||||
self thread changeToWeapon(curWeap);
|
||||
@ -2734,7 +2928,7 @@ bot_kill_dog_think()
|
||||
if(level.teamBased && dog.aiteam == self.pers["team"])
|
||||
continue;
|
||||
|
||||
if(getConeDot(dog.origin, self.origin, myAngles) < 0.6 && !hasRecon)
|
||||
if(DistanceSquared(dog.origin, self.origin) > 64*64 && getConeDot(dog.origin, self.origin, myAngles) < 0.6 && !hasRecon)
|
||||
continue;
|
||||
|
||||
if(!bulletTracePassed(myEye, dog.origin+(0, 0, 5), false, dog))
|
||||
@ -2803,6 +2997,9 @@ bot_equipment_kill_think()
|
||||
{
|
||||
item = grenades[i];
|
||||
|
||||
if (!isDefined(item))
|
||||
continue;
|
||||
|
||||
if ( !IsDefined( item.name ) )
|
||||
{
|
||||
continue;
|
||||
@ -3043,20 +3240,23 @@ bot_dom_cap_think()
|
||||
|
||||
otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
|
||||
|
||||
if ( myFlagCount < otherFlagCount )
|
||||
if (game["teamScores"][myteam] >= game["teamScores"][otherTeam])
|
||||
{
|
||||
if ( randomint( 100 ) < 15 )
|
||||
continue;
|
||||
}
|
||||
else if ( myFlagCount == otherFlagCount )
|
||||
{
|
||||
if ( randomint( 100 ) < 35 )
|
||||
continue;
|
||||
}
|
||||
else if ( myFlagCount > otherFlagCount )
|
||||
{
|
||||
if ( randomint( 100 ) < 95 )
|
||||
continue;
|
||||
if ( myFlagCount < otherFlagCount )
|
||||
{
|
||||
if ( randomint( 100 ) < 15 )
|
||||
continue;
|
||||
}
|
||||
else if ( myFlagCount == otherFlagCount )
|
||||
{
|
||||
if ( randomint( 100 ) < 35 )
|
||||
continue;
|
||||
}
|
||||
else if ( myFlagCount > otherFlagCount )
|
||||
{
|
||||
if ( randomint( 100 ) < 95 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
flag = undefined;
|
||||
|
@ -826,9 +826,9 @@ SmokeTrace(start, end, rad)
|
||||
*/
|
||||
getConeDot(to, from, dir)
|
||||
{
|
||||
dirToTarget = VectorNormalize(to-from);
|
||||
forward = AnglesToForward(dir);
|
||||
return vectordot(dirToTarget, forward);
|
||||
dirToTarget = VectorNormalize(to-from);
|
||||
forward = AnglesToForward(dir);
|
||||
return vectordot(dirToTarget, forward);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -971,25 +971,25 @@ float(num)
|
||||
*/
|
||||
tokenizeLine(line, tok)
|
||||
{
|
||||
tokens = [];
|
||||
tokens = [];
|
||||
|
||||
token = "";
|
||||
for (i = 0; i < line.size; i++)
|
||||
{
|
||||
c = line[i];
|
||||
token = "";
|
||||
for (i = 0; i < line.size; i++)
|
||||
{
|
||||
c = line[i];
|
||||
|
||||
if (c == tok)
|
||||
{
|
||||
tokens[tokens.size] = token;
|
||||
token = "";
|
||||
continue;
|
||||
}
|
||||
if (c == tok)
|
||||
{
|
||||
tokens[tokens.size] = token;
|
||||
token = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
token += c;
|
||||
}
|
||||
tokens[tokens.size] = token;
|
||||
token += c;
|
||||
}
|
||||
tokens[tokens.size] = token;
|
||||
|
||||
return tokens;
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1029,7 +1029,7 @@ parseTokensIntoWaypoint(tokens)
|
||||
getWaypointLinesFromFile(filename)
|
||||
{
|
||||
result = spawnStruct();
|
||||
result.lines = [];
|
||||
result.lines = [];
|
||||
|
||||
waypointStr = fileRead(filename);
|
||||
|
||||
@ -1051,7 +1051,7 @@ getWaypointLinesFromFile(filename)
|
||||
|
||||
line += c;
|
||||
}
|
||||
result.lines[result.lines.size] = line;
|
||||
result.lines[result.lines.size] = line;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1077,9 +1077,9 @@ readWpsFromFile(mapname)
|
||||
{
|
||||
tokens = tokenizeLine(res.lines[i], ",");
|
||||
|
||||
waypoint = parseTokensIntoWaypoint(tokens);
|
||||
waypoint = parseTokensIntoWaypoint(tokens);
|
||||
|
||||
waypoints[i-1] = waypoint;
|
||||
waypoints[i-1] = waypoint;
|
||||
}
|
||||
|
||||
return waypoints;
|
||||
@ -1543,7 +1543,7 @@ KDTree()
|
||||
*/
|
||||
KDTreeInsert(data)//as long as what you insert has a .origin attru, it will work.
|
||||
{
|
||||
self.root = self _KDTreeInsert(self.root, data, 0, -9999999999, -9999999999, -9999999999, 9999999999, 9999999999, 9999999999);
|
||||
self.root = self _KDTreeInsert(self.root, data, 0, -2147483647, -2147483647, -2147483647, 2147483647, 2147483647, 2147483647);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1822,7 +1822,7 @@ ReverseHeapAStar(item, item2)
|
||||
GetNearestWaypointWithSight(pos)
|
||||
{
|
||||
candidate = undefined;
|
||||
dist = 9999999999;
|
||||
dist = 2147483647;
|
||||
|
||||
for(i = 0; i < level.waypointCount; i++)
|
||||
{
|
||||
|
@ -27,6 +27,9 @@ watchPlayers()
|
||||
{
|
||||
wait 1;
|
||||
|
||||
if (!getDvarInt("bots_main_menu"))
|
||||
return;
|
||||
|
||||
for (i = level.players.size - 1; i >= 0; i--)
|
||||
{
|
||||
player = level.players[i];
|
||||
|
@ -335,7 +335,7 @@ watchSaveWaypointsCommand()
|
||||
{
|
||||
self iPrintlnBold("Auto link enabled");
|
||||
level.autoLink = true;
|
||||
level.wpToLink = self.nearest;
|
||||
level.wpToLink = self.closest;
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,6 +413,12 @@ DeleteAllWaypoints()
|
||||
{
|
||||
level.waypoints = [];
|
||||
level.waypointCount = 0;
|
||||
level.waypointsKDTree = WaypointsToKDTree();
|
||||
|
||||
level.waypointsCamp = [];
|
||||
level.waypointsTube = [];
|
||||
level.waypointsGren = [];
|
||||
level.waypointsClay = [];
|
||||
|
||||
self iprintln("DelAllWps");
|
||||
}
|
||||
@ -584,9 +590,7 @@ destroyOnDeath(hud)
|
||||
{
|
||||
hud endon("death");
|
||||
self waittill_either("death","disconnect");
|
||||
hud notify("death");
|
||||
hud destroy();
|
||||
hud = undefined;
|
||||
}
|
||||
|
||||
textScroll(string)
|
||||
|
Submodule main_shared/waypoints updated: 1d04b97e39...f005fd75d7
@ -13,12 +13,16 @@ Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your s
|
||||
## Installation
|
||||
T4M requires an unpacked steamless version of the multiplayer World at War executable (otherwise known as LanFixed). You can use a Steam Unpacker on your multiplayer World at War Steam executable to acquire the required executable.
|
||||
|
||||
Also make sure that PunkBuster is disabled!
|
||||
|
||||
0. Make sure that T4M is installed, updated and working properly.
|
||||
- Download the d3d9.dll from https://github.com/ineedbots/T4M/releases and place it into the root of your World at War install
|
||||
- Download the WaW MP LanFixed from https://bit.ly/3803IUC and place it into the root of your World at War install, you will use this executable to run the game.
|
||||
1. Extract all the files from the Bot Warfare release archive you downloaded to anywhere on your computer.
|
||||
2. Run the 'install.bat'. This copies the mod to your WaW mods folder.
|
||||
3. The mod is now installed, now run your game.
|
||||
- If you are a dedicated server, you will need to set the DVAR 'fs_game' to 'mods/mp_bots'
|
||||
- If you are not a dedicated server, open the 'Mods' option from the main menu of the game and select 'mp_bots' and then 'Launch'.
|
||||
- If you are a dedicated server, you will need to set the DVAR 'fs_game' to 'mods/mp_bots'
|
||||
- If you are not a dedicated server, open the 'Mods' option from the main menu of the game and select 'mp_bots' and then 'Launch'.
|
||||
4. The mod should be loaded! Now go start a map and play!
|
||||
|
||||
## Menu Usage
|
||||
@ -29,6 +33,22 @@ T4M requires an unpacked steamless version of the multiplayer World at War execu
|
||||
- Pressing the menu buttons again closes menus.
|
||||
|
||||
## Changelog
|
||||
- v2.0.1
|
||||
- Reduced bots crouching
|
||||
- Increased bots sprinting
|
||||
- Improved bots mantling, crouching and knifing glass when needed
|
||||
- Fixed possible script runtime errors
|
||||
- Improved domination
|
||||
- Bots use explosives more if they have it
|
||||
- Bots aim slower when ads'ing
|
||||
- Fixed bots holding breath
|
||||
- Fixed bots rubberbanding movement when their goal changes
|
||||
- Added bots quickscoping with snipers
|
||||
- Added bots reload canceling and fast swaps
|
||||
- Bots use C4
|
||||
- Improved revenge
|
||||
- Bots can swap weapons on spawn more likely
|
||||
|
||||
- v2.0.0
|
||||
- Initial reboot release
|
||||
|
||||
|
Binary file not shown.
BIN
out/ss.png
BIN
out/ss.png
Binary file not shown.
Before Width: | Height: | Size: 3.4 MiB After Width: | Height: | Size: 3.7 MiB |
Reference in New Issue
Block a user