30 Commits

Author SHA1 Message Date
87744ba13a Bump version 2.0.1 2021-05-14 19:42:29 -06:00
837bec9c73 Improved c4 2021-05-14 15:20:15 -06:00
5d9c90cc25 Fix up wpedit 2021-05-09 11:44:35 -06:00
93ce2ae1b5 Fixed menu being in wp editor 2021-05-08 14:07:11 -06:00
cf40501f60 c4 support 2021-05-04 17:00:09 -06:00
979d1135be Fix weap swap vars, partial c4 support 2021-05-04 16:54:05 -06:00
5afc002126 Fix int overflow 2021-05-01 16:55:49 -06:00
6225ae74fb Fix script error 2021-04-26 20:21:09 -07:00
ca71fbee4b Fast swap, swap on spawn 2021-03-26 00:26:57 -06:00
4059b373c2 Fix sniper, add reload cancel 2021-03-19 15:29:29 -06:00
73dc1c17b1 clean 2021-03-12 14:06:26 -06:00
f41ab46747 Added qs 2021-03-12 13:56:05 -06:00
1d26bbd492 added lastKiller 2021-03-11 15:24:58 -06:00
52f1062793 FIx rubberbanding 2021-03-11 15:11:22 -06:00
9744ff6ccd Better crouch and mantle 2021-03-10 15:17:26 -06:00
3c7e07866f More sprinting 2021-03-03 22:54:41 -06:00
f0aa54189d added weapon class dist mutiplier 2021-03-03 18:11:37 -06:00
ff413d513b Added ads aimspeed delay 2021-03-02 00:48:25 -06:00
795ed863f6 Change crouch and sprint 2021-02-27 15:07:48 -06:00
861430e884 better dom 2021-02-27 15:06:12 -06:00
a9ccf1bcbd Improved mantle and knife glass 2021-02-27 15:02:26 -06:00
9d0bc09dee fix gsc errors 2021-01-22 21:25:49 -06:00
e7e13bffc0 fix scr_error 2021-01-19 13:35:30 -06:00
edc183c7e2 pb 2021-01-19 00:34:01 -06:00
dbe69a395a Disable punk buster 2021-01-19 00:31:28 -06:00
1578001094 Fix possible script error 2021-01-13 16:28:09 -06:00
1718f7c37a Fix dog target and planting revive 2021-01-11 16:14:15 -06:00
49597887f3 added 2021-01-09 17:05:56 -06:00
ad07563755 removed wps use the repo 2021-01-09 16:44:32 -06:00
2e775d9fb2 Updated readme 2021-01-04 15:01:54 -06:00
14 changed files with 826 additions and 340 deletions

View File

@ -59,7 +59,12 @@ Make sure to disable this DVAR by adding ```set bots_main_firstIsHost 0``` in yo
## Installation ## 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. 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!
![Disabling PunkBuster](/main_shared/bw-assets/disable_pb.png)
0. Make sure that [T4M](https://github.com/ineedbots/T4M) is installed, updated and working properly. 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. - 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. 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. 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 - bots_main_debug - a boolean value (0 or 1), enables or disables the waypoint editor
## Changelog ## 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 - v2.0.0
- Initial reboot release - Initial reboot release

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -8,7 +8,7 @@
*/ */
init() init()
{ {
level.bw_VERSION = "2.0.0"; level.bw_VERSION = "2.0.1";
if(getDvar("bots_main") == "") if(getDvar("bots_main") == "")
setDvar("bots_main", true); setDvar("bots_main", true);

View File

@ -12,34 +12,34 @@
*/ */
getRemoteWaypoints(mapname) 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"; filename = "waypoints/" + mapname + "_wp.csv";
PrintConsole("Attempting to get remote waypoints from " + url + "\n"); PrintConsole("Attempting to get remote waypoints from " + url + "\n");
res = getLinesFromUrl(url, filename); res = getLinesFromUrl(url, filename);
if (!res.lines.size) if (!res.lines.size)
return; return;
waypointCount = int(res.lines[0]); waypointCount = int(res.lines[0]);
waypoints = []; waypoints = [];
PrintConsole("Loading remote waypoints...\n"); PrintConsole("Loading remote waypoints...\n");
for (i = 1; i <= waypointCount; i++) 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) if (waypoints.size)
{ {
level.waypoints = waypoints; level.waypoints = waypoints;
PrintConsole("Loaded " + waypoints.size + " waypoints from remote.\n"); PrintConsole("Loaded " + waypoints.size + " waypoints from remote.\n");
} }
} }
/* /*
@ -71,12 +71,12 @@ doVersionCheck()
*/ */
getRemoteVersion() 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)) if (!isDefined(data))
return undefined; return undefined;
return strtok(data, "\n")[0]; return strtok(data, "\n")[0];
} }
/* /*
@ -84,8 +84,8 @@ getRemoteVersion()
*/ */
getLinesFromUrl(url, filename) getLinesFromUrl(url, filename)
{ {
result = spawnStruct(); result = spawnStruct();
result.lines = []; result.lines = [];
data = HTTPGet(url); data = HTTPGet(url);
@ -109,7 +109,7 @@ getLinesFromUrl(url, filename)
line += c; line += c;
} }
result.lines[result.lines.size] = line; result.lines[result.lines.size] = line;
return result; return result;
} }

View File

@ -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"]["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"]["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"]["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"] = [];
self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target 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"]["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"]["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"]["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.stop_move = false;
self.bot.greedy_path = false; self.bot.greedy_path = false;
self.bot.climbing = false; self.bot.climbing = false;
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self.bot.isfrozen = false; self.bot.isfrozen = false;
self.bot.sprintendtime = -1; self.bot.sprintendtime = -1;
@ -145,8 +152,11 @@ resetBotVars()
self.bot.semi_time = false; self.bot.semi_time = false;
self.bot.jump_time = undefined; self.bot.jump_time = undefined;
self.bot.last_fire_time = -1;
self.bot.is_cur_full_auto = false; 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); self.bot.rand = randomInt(100);
@ -188,7 +198,6 @@ onPlayerSpawned()
self thread onLastStand(); self thread onLastStand();
self thread reload_watch(); self thread reload_watch();
self thread doBotMovement();
self thread sprint_watch(); self thread sprint_watch();
self thread spawned(); self thread spawned();
@ -203,7 +212,9 @@ doBotMovement()
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
for (;;) FORWARDAMOUNT = 25;
for (i=0;;i+=0.05)
{ {
wait 0.05; wait 0.05;
@ -232,9 +243,43 @@ doBotMovement()
dir = (dir[0], 0-dir[1], 0); 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! // move!
self botMovement(int(dir[0]), int(dir[1])); 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"]; wait self.pers["bots"]["skill"]["spawn_time"];
self thread doBotMovement();
self thread grenade_danger(); self thread grenade_danger();
self thread check_reload(); self thread check_reload();
self thread stance(); self thread stance();
@ -257,10 +303,108 @@ spawned()
self thread aim(); self thread aim();
self thread watchHoldBreath(); self thread watchHoldBreath();
self thread onNewEnemy(); self thread onNewEnemy();
self thread watchGrenadeFire();
self notify("bot_spawned"); 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. The hold breath thread.
*/ */
@ -276,7 +420,7 @@ watchHoldBreath()
if(self.bot.isfrozen) if(self.bot.isfrozen)
continue; continue;
self holdbreath((self playerADS() && weaponClass(self getCurrentWEapon()) == "rifle")); self holdbreath(self playerADS() > 0);
} }
} }
@ -325,21 +469,24 @@ onWeaponChange()
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
weap = self GetCurrentWeapon(); first = true;
self.bot.is_cur_full_auto = WeaponIsFullAuto(weap);
if (weap != "none")
self changeToWeap(weap);
for(;;) 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.is_cur_full_auto = WeaponIsFullAuto(newWeapon);
self.bot.cur_weap_dist_multi = SetWeaponDistMulti(newWeapon);
self.bot.is_cur_sniper = IsWeapSniper(newWeapon);
if (newWeapon == "none") if (newWeapon == "none")
{
continue; continue;
}
self changeToWeap(newWeapon); self changeToWeap(newWeapon);
} }
@ -375,7 +522,18 @@ reload_watch()
{ {
self waittill("reload_start"); self waittill("reload_start");
self.bot.isreloading = true; 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; self.bot.isreloading = false;
} }
} }
@ -424,17 +582,25 @@ stance()
self prone(); self prone();
curweap = self getCurrentWeapon(); 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) if(toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter)
continue; continue;
if(randomInt(100) > self.pers["bots"]["behavior"]["sprint"]) if(randomInt(100) > chance)
continue; continue;
if(isDefined(self.bot.target) && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap)) if(isDefined(self.bot.target) && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
continue; continue;
if(self.bot.sprintendtime != -1 && getTime() - self.bot.sprintendtime < 2000) if(self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000)
continue; 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) 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) targetObjUpdateTraced(obj, daDist, ent, theTime, isScriptObj)
{ {
distClose = self.pers["bots"]["skill"]["dist_start"]; distClose = self.pers["bots"]["skill"]["dist_start"];
distClose *= self.bot.cur_weap_dist_multi;
distClose *= distClose; distClose *= distClose;
distMax = self.pers["bots"]["skill"]["dist_max"]; distMax = self.pers["bots"]["skill"]["dist_max"];
distMax *= self.bot.cur_weap_dist_multi;
distMax *= distMax; distMax *= distMax;
timeMulti = 1; timeMulti = 1;
@ -683,10 +851,12 @@ target()
myAngles = self GetPlayerAngles(); myAngles = self GetPlayerAngles();
myFov = self.pers["bots"]["skill"]["fov"]; myFov = self.pers["bots"]["skill"]["fov"];
bestTargets = []; bestTargets = [];
bestTime = 9999999999; bestTime = 2147483647;
rememberTime = self.pers["bots"]["skill"]["remember_time"]; rememberTime = self.pers["bots"]["skill"]["remember_time"];
initReactTime = self.pers["bots"]["skill"]["init_react_time"]; initReactTime = self.pers["bots"]["skill"]["init_react_time"];
hasTarget = isDefined(self.bot.target); hasTarget = isDefined(self.bot.target);
adsAmount = self PlayerADS();
adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"];
if(hasTarget && !isDefined(self.bot.target.entity)) if(hasTarget && !isDefined(self.bot.target.entity))
{ {
@ -695,7 +865,10 @@ target()
} }
// reduce fov if ads'ing // reduce fov if ads'ing
myFov *= 1 - 0.5 * self PlayerADS(); if (adsAmount > 0)
{
myFov *= 1 - adsFovFact * adsAmount;
}
playercount = level.players.size; playercount = level.players.size;
for(i = -1; i < playercount; i++) for(i = -1; i < playercount; i++)
@ -830,7 +1003,7 @@ target()
if(hasTarget && isDefined(bestTargets[self.bot.target.entity getEntityNumber()+""])) if(hasTarget && isDefined(bestTargets[self.bot.target.entity getEntityNumber()+""]))
continue; continue;
closest = 9999999999; closest = 2147483647;
toBeTarget = undefined; toBeTarget = undefined;
bestKeys = getArrayKeys(bestTargets); bestKeys = getArrayKeys(bestTargets);
@ -922,6 +1095,9 @@ watchToLook()
if(!self isInRange(self.bot.target.dist, curweap)) if(!self isInRange(self.bot.target.dist, curweap))
continue; continue;
if (self.bot.is_cur_sniper)
continue;
if(randomInt(100) > self.pers["bots"]["behavior"]["jump"]) if(randomInt(100) > self.pers["bots"]["behavior"]["jump"])
continue; continue;
@ -1006,6 +1182,14 @@ aim()
eyePos = self getEyePos(); eyePos = self getEyePos();
curweap = self getCurrentWeapon(); curweap = self getCurrentWeapon();
angles = self GetPlayerAngles(); 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)) if(isDefined(self.bot.target) && isDefined(self.bot.target.entity))
{ {
@ -1072,7 +1256,10 @@ aim()
else else
{ {
if (self canAds(dist, curweap)) 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); self thread bot_lookat(last_pos + (0, 0, self getEyeHeight() + nadeAimOffset), aimspeed);
@ -1083,7 +1270,14 @@ aim()
{ {
if(isplay) if(isplay)
{ {
if (!target IsPlayerModelOK())
continue;
aimpos = target getTagOrigin( bone ); aimpos = target getTagOrigin( bone );
if (!isDefined(aimpos))
continue;
aimpos += offset; aimpos += offset;
aimpos += aimoffset; aimpos += aimoffset;
aimpos += (0, 0, nadeAimOffset); aimpos += (0, 0, nadeAimOffset);
@ -1119,13 +1313,25 @@ aim()
//c4 logic here, but doesnt work anyway //c4 logic here, but doesnt work anyway
canADS = self canAds(dist, curweap); canADS = (self canAds(dist, curweap) && conedot > 0.75);
if (canADS) 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 (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(); self botFire();
if (isplay) if (isplay)
@ -1156,11 +1362,23 @@ aim()
if(!self canFire(curweap) || !self isInRange(dist, curweap)) if(!self canFire(curweap) || !self isInRange(dist, curweap))
continue; continue;
canADS = self canAds(dist, curweap); canADS = (self canAds(dist, curweap) && conedot > 0.75);
if (canADS) 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(); self botFire();
continue; continue;
@ -1196,6 +1414,8 @@ aim()
*/ */
botFire() botFire()
{ {
self.bot.last_fire_time = getTime();
if(self.bot.is_cur_full_auto) if(self.bot.is_cur_full_auto)
{ {
self thread pressFire(); self thread pressFire();
@ -1313,6 +1533,8 @@ walk()
if(self isFlared()) if(self isFlared())
{ {
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self botMoveTo(self.origin + self GetVelocity()*500); self botMoveTo(self.origin + self GetVelocity()*500);
continue; 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.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; continue;
if(self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"]) if(self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"])
@ -1428,6 +1650,8 @@ strafe(target)
if(traceRight["fraction"] > traceLeft["fraction"]) if(traceRight["fraction"] > traceLeft["fraction"])
strafe = traceRight["position"]; strafe = traceRight["position"];
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self botMoveTo(strafe); self botMoveTo(strafe);
wait 2; wait 2;
self notify("kill_goal"); self notify("kill_goal");
@ -1539,39 +1763,34 @@ doWalk(goal, dist, isScriptGoal)
self thread watchOnGoal(goal, distsq); self thread watchOnGoal(goal, distsq);
current = self initAStar(goal); current = self initAStar(goal);
// if a waypoint is closer than the goal // skip waypoints we already completed to prevent rubber banding
//if (current >= 0 && DistanceSquared(self.origin, level.waypoints[self.bot.astar[current]].origin) < DistanceSquared(self.origin, goal)) 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();
while(current >= 0)
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 while(current >= 0)
/*for (;;)
{ {
if (current <= 0) self.bot.next_wp = self.bot.astar[current];
break; 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); self notify("new_static_waypoint");
if (DistanceSquared(level.waypoints[self.bot.astar[current-1]].origin, ppt) > 1.0)
break;
if (level.waypoints[self.bot.astar[current-1]].type == "climb" || level.waypoints[self.bot.astar[current]].type == "climb") self movetowards(level.waypoints[self.bot.next_wp].origin);
break; self.bot.last_next_wp = self.bot.next_wp;
self.bot.last_second_next_wp = self.bot.second_next_wp;
current = self removeAStar(); 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.next_wp = -1;
self.bot.second_next_wp = -1; self.bot.second_next_wp = -1;
@ -1579,6 +1798,8 @@ doWalk(goal, dist, isScriptGoal)
if(DistanceSquared(self.origin, goal) > distsq) 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?? self movetowards(goal); // any better way??
} }
@ -1607,17 +1828,18 @@ movetowards(goal)
{ {
self botMoveTo(goal); self botMoveTo(goal);
if(time > 3) if(time > 3.5)
{ {
time = 0; time = 0;
if(distanceSquared(self.origin, lastOri) < 128) if(distanceSquared(self.origin, lastOri) < 128)
{ {
self thread knife();
wait 0.5;
stucks++; stucks++;
randomDir = self getRandomLargestStafe(stucks); randomDir = self getRandomLargestStafe(stucks);
self knife(); // knife glass
wait 0.25;
self botMoveTo(randomDir); self botMoveTo(randomDir);
wait stucks; wait stucks;
} }
@ -1626,7 +1848,7 @@ movetowards(goal)
} }
else if(timeslow > 1.5) else if(timeslow > 1.5)
{ {
self thread jump(); self thread doMantle();
} }
else if(timeslow > 0.75) else if(timeslow > 0.75)
{ {
@ -1648,6 +1870,22 @@ movetowards(goal)
self notify("completed_move_to"); 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. Will return the pos of the largest trace from the bot.
*/ */

View File

@ -28,6 +28,7 @@ connected()
self endon("disconnect"); self endon("disconnect");
self.killerLocation = undefined; self.killerLocation = undefined;
self.lastKiller = undefined;
self thread difficulty(); self thread difficulty();
self thread teamWatch(); self thread teamWatch();
@ -43,6 +44,7 @@ connected()
onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration) onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
{ {
self.killerLocation = undefined; self.killerLocation = undefined;
self.lastKiller = undefined;
if(!IsDefined( self ) || !isDefined(self.team)) if(!IsDefined( self ) || !isDefined(self.team))
return; return;
@ -69,6 +71,7 @@ onKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc,
return; return;
self.killerLocation = eAttacker.origin; self.killerLocation = eAttacker.origin;
self.lastKiller = eAttacker;
} }
/* /*
@ -275,219 +278,233 @@ difficulty()
for(;;) for(;;)
{ {
wait 1;
rankVar = GetDvarInt("bots_skill"); rankVar = GetDvarInt("bots_skill");
if(rankVar == 9) if(rankVar != 9)
continue;
switch(self.pers["bots"]["skill"]["base"])
{ {
case 1: switch(self.pers["bots"]["skill"]["base"])
self.pers["bots"]["skill"]["aim_time"] = 0.6; {
self.pers["bots"]["skill"]["init_react_time"] = 1500; case 1:
self.pers["bots"]["skill"]["reaction_time"] = 1000; self.pers["bots"]["skill"]["aim_time"] = 0.6;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 500; self.pers["bots"]["skill"]["init_react_time"] = 1500;
self.pers["bots"]["skill"]["no_trace_look_time"] = 600; self.pers["bots"]["skill"]["reaction_time"] = 1000;
self.pers["bots"]["skill"]["remember_time"] = 750; self.pers["bots"]["skill"]["no_trace_ads_time"] = 500;
self.pers["bots"]["skill"]["fov"] = 0.7; self.pers["bots"]["skill"]["no_trace_look_time"] = 600;
self.pers["bots"]["skill"]["dist_max"] = 2500; self.pers["bots"]["skill"]["remember_time"] = 750;
self.pers["bots"]["skill"]["dist_start"] = 1000; self.pers["bots"]["skill"]["fov"] = 0.7;
self.pers["bots"]["skill"]["spawn_time"] = 0.75; self.pers["bots"]["skill"]["dist_max"] = 2500;
self.pers["bots"]["skill"]["help_dist"] = 0; self.pers["bots"]["skill"]["dist_start"] = 1000;
self.pers["bots"]["skill"]["semi_time"] = 0.9; self.pers["bots"]["skill"]["spawn_time"] = 0.75;
self.pers["bots"]["skill"]["shoot_after_time"] = 1; self.pers["bots"]["skill"]["help_dist"] = 0;
self.pers["bots"]["skill"]["aim_offset_time"] = 1.5; self.pers["bots"]["skill"]["semi_time"] = 0.9;
self.pers["bots"]["skill"]["aim_offset_amount"] = 4; self.pers["bots"]["skill"]["shoot_after_time"] = 1;
self.pers["bots"]["skill"]["bone_update_interval"] = 2; self.pers["bots"]["skill"]["aim_offset_time"] = 1.5;
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri"; 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"]["strafe"] = 0;
self.pers["bots"]["behavior"]["nade"] = 10; self.pers["bots"]["behavior"]["nade"] = 10;
self.pers["bots"]["behavior"]["sprint"] = 10; self.pers["bots"]["behavior"]["sprint"] = 30;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 70; self.pers["bots"]["behavior"]["crouch"] = 20;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 0; self.pers["bots"]["behavior"]["jump"] = 0;
break; break;
case 2: case 2:
self.pers["bots"]["skill"]["aim_time"] = 0.55; self.pers["bots"]["skill"]["aim_time"] = 0.55;
self.pers["bots"]["skill"]["init_react_time"] = 1000; self.pers["bots"]["skill"]["init_react_time"] = 1000;
self.pers["bots"]["skill"]["reaction_time"] = 800; self.pers["bots"]["skill"]["reaction_time"] = 800;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 1250; self.pers["bots"]["skill"]["no_trace_look_time"] = 1250;
self.pers["bots"]["skill"]["remember_time"] = 1500; self.pers["bots"]["skill"]["remember_time"] = 1500;
self.pers["bots"]["skill"]["fov"] = 0.65; self.pers["bots"]["skill"]["fov"] = 0.65;
self.pers["bots"]["skill"]["dist_max"] = 3000; self.pers["bots"]["skill"]["dist_max"] = 3000;
self.pers["bots"]["skill"]["dist_start"] = 1500; self.pers["bots"]["skill"]["dist_start"] = 1500;
self.pers["bots"]["skill"]["spawn_time"] = 0.65; self.pers["bots"]["skill"]["spawn_time"] = 0.65;
self.pers["bots"]["skill"]["help_dist"] = 500; self.pers["bots"]["skill"]["help_dist"] = 500;
self.pers["bots"]["skill"]["semi_time"] = 0.75; self.pers["bots"]["skill"]["semi_time"] = 0.75;
self.pers["bots"]["skill"]["shoot_after_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_time"] = 1;
self.pers["bots"]["skill"]["aim_offset_amount"] = 3; self.pers["bots"]["skill"]["aim_offset_amount"] = 3;
self.pers["bots"]["skill"]["bone_update_interval"] = 1.5; 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"]["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"]["strafe"] = 10;
self.pers["bots"]["behavior"]["nade"] = 15; self.pers["bots"]["behavior"]["nade"] = 15;
self.pers["bots"]["behavior"]["sprint"] = 15; self.pers["bots"]["behavior"]["sprint"] = 45;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 60; self.pers["bots"]["behavior"]["crouch"] = 15;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 10; self.pers["bots"]["behavior"]["jump"] = 10;
break; break;
case 3: case 3:
self.pers["bots"]["skill"]["aim_time"] = 0.4; self.pers["bots"]["skill"]["aim_time"] = 0.4;
self.pers["bots"]["skill"]["init_react_time"] = 750; self.pers["bots"]["skill"]["init_react_time"] = 750;
self.pers["bots"]["skill"]["reaction_time"] = 500; self.pers["bots"]["skill"]["reaction_time"] = 500;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
self.pers["bots"]["skill"]["remember_time"] = 2000; self.pers["bots"]["skill"]["remember_time"] = 2000;
self.pers["bots"]["skill"]["fov"] = 0.6; self.pers["bots"]["skill"]["fov"] = 0.6;
self.pers["bots"]["skill"]["dist_max"] = 4000; self.pers["bots"]["skill"]["dist_max"] = 4000;
self.pers["bots"]["skill"]["dist_start"] = 2250; self.pers["bots"]["skill"]["dist_start"] = 2250;
self.pers["bots"]["skill"]["spawn_time"] = 0.5; self.pers["bots"]["skill"]["spawn_time"] = 0.5;
self.pers["bots"]["skill"]["help_dist"] = 750; self.pers["bots"]["skill"]["help_dist"] = 750;
self.pers["bots"]["skill"]["semi_time"] = 0.65; self.pers["bots"]["skill"]["semi_time"] = 0.65;
self.pers["bots"]["skill"]["shoot_after_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_time"] = 0.75;
self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5; self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5;
self.pers["bots"]["skill"]["bone_update_interval"] = 1; 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"]["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"]["strafe"] = 20;
self.pers["bots"]["behavior"]["nade"] = 20; self.pers["bots"]["behavior"]["nade"] = 20;
self.pers["bots"]["behavior"]["sprint"] = 20; self.pers["bots"]["behavior"]["sprint"] = 50;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 50; self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 25; self.pers["bots"]["behavior"]["jump"] = 25;
break; break;
case 4: case 4:
self.pers["bots"]["skill"]["aim_time"] = 0.3; self.pers["bots"]["skill"]["aim_time"] = 0.3;
self.pers["bots"]["skill"]["init_react_time"] = 600; self.pers["bots"]["skill"]["init_react_time"] = 600;
self.pers["bots"]["skill"]["reaction_time"] = 400; self.pers["bots"]["skill"]["reaction_time"] = 400;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; self.pers["bots"]["skill"]["no_trace_look_time"] = 1500;
self.pers["bots"]["skill"]["remember_time"] = 3000; self.pers["bots"]["skill"]["remember_time"] = 3000;
self.pers["bots"]["skill"]["fov"] = 0.55; self.pers["bots"]["skill"]["fov"] = 0.55;
self.pers["bots"]["skill"]["dist_max"] = 5000; self.pers["bots"]["skill"]["dist_max"] = 5000;
self.pers["bots"]["skill"]["dist_start"] = 3350; self.pers["bots"]["skill"]["dist_start"] = 3350;
self.pers["bots"]["skill"]["spawn_time"] = 0.35; self.pers["bots"]["skill"]["spawn_time"] = 0.35;
self.pers["bots"]["skill"]["help_dist"] = 1000; self.pers["bots"]["skill"]["help_dist"] = 1000;
self.pers["bots"]["skill"]["semi_time"] = 0.5; self.pers["bots"]["skill"]["semi_time"] = 0.5;
self.pers["bots"]["skill"]["shoot_after_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_time"] = 0.5;
self.pers["bots"]["skill"]["aim_offset_amount"] = 2; self.pers["bots"]["skill"]["aim_offset_amount"] = 2;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.75; 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"]["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"]["strafe"] = 30;
self.pers["bots"]["behavior"]["nade"] = 25; self.pers["bots"]["behavior"]["nade"] = 25;
self.pers["bots"]["behavior"]["sprint"] = 30; self.pers["bots"]["behavior"]["sprint"] = 55;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 40; self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 35; self.pers["bots"]["behavior"]["jump"] = 35;
break; break;
case 5: case 5:
self.pers["bots"]["skill"]["aim_time"] = 0.25; self.pers["bots"]["skill"]["aim_time"] = 0.25;
self.pers["bots"]["skill"]["init_react_time"] = 500; self.pers["bots"]["skill"]["init_react_time"] = 500;
self.pers["bots"]["skill"]["reaction_time"] = 300; self.pers["bots"]["skill"]["reaction_time"] = 300;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500; self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500;
self.pers["bots"]["skill"]["no_trace_look_time"] = 2000; self.pers["bots"]["skill"]["no_trace_look_time"] = 2000;
self.pers["bots"]["skill"]["remember_time"] = 4000; self.pers["bots"]["skill"]["remember_time"] = 4000;
self.pers["bots"]["skill"]["fov"] = 0.5; self.pers["bots"]["skill"]["fov"] = 0.5;
self.pers["bots"]["skill"]["dist_max"] = 7500; self.pers["bots"]["skill"]["dist_max"] = 7500;
self.pers["bots"]["skill"]["dist_start"] = 5000; self.pers["bots"]["skill"]["dist_start"] = 5000;
self.pers["bots"]["skill"]["spawn_time"] = 0.25; self.pers["bots"]["skill"]["spawn_time"] = 0.25;
self.pers["bots"]["skill"]["help_dist"] = 1500; self.pers["bots"]["skill"]["help_dist"] = 1500;
self.pers["bots"]["skill"]["semi_time"] = 0.4; self.pers["bots"]["skill"]["semi_time"] = 0.4;
self.pers["bots"]["skill"]["shoot_after_time"] = 0.35; self.pers["bots"]["skill"]["shoot_after_time"] = 0.35;
self.pers["bots"]["skill"]["aim_offset_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"]["aim_offset_amount"] = 1.5;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.5; self.pers["bots"]["skill"]["bone_update_interval"] = 0.5;
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head"; 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"]["strafe"] = 40;
self.pers["bots"]["behavior"]["nade"] = 35; self.pers["bots"]["behavior"]["nade"] = 35;
self.pers["bots"]["behavior"]["sprint"] = 40; self.pers["bots"]["behavior"]["sprint"] = 60;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 30; self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 50; self.pers["bots"]["behavior"]["jump"] = 50;
break; break;
case 6: case 6:
self.pers["bots"]["skill"]["aim_time"] = 0.2; self.pers["bots"]["skill"]["aim_time"] = 0.2;
self.pers["bots"]["skill"]["init_react_time"] = 250; self.pers["bots"]["skill"]["init_react_time"] = 250;
self.pers["bots"]["skill"]["reaction_time"] = 150; self.pers["bots"]["skill"]["reaction_time"] = 150;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000; self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000;
self.pers["bots"]["skill"]["no_trace_look_time"] = 3000; self.pers["bots"]["skill"]["no_trace_look_time"] = 3000;
self.pers["bots"]["skill"]["remember_time"] = 5000; self.pers["bots"]["skill"]["remember_time"] = 5000;
self.pers["bots"]["skill"]["fov"] = 0.45; self.pers["bots"]["skill"]["fov"] = 0.45;
self.pers["bots"]["skill"]["dist_max"] = 10000; self.pers["bots"]["skill"]["dist_max"] = 10000;
self.pers["bots"]["skill"]["dist_start"] = 7500; self.pers["bots"]["skill"]["dist_start"] = 7500;
self.pers["bots"]["skill"]["spawn_time"] = 0.2; self.pers["bots"]["skill"]["spawn_time"] = 0.2;
self.pers["bots"]["skill"]["help_dist"] = 2000; self.pers["bots"]["skill"]["help_dist"] = 2000;
self.pers["bots"]["skill"]["semi_time"] = 0.25; self.pers["bots"]["skill"]["semi_time"] = 0.25;
self.pers["bots"]["skill"]["shoot_after_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_time"] = 0.25;
self.pers["bots"]["skill"]["aim_offset_amount"] = 1; self.pers["bots"]["skill"]["aim_offset_amount"] = 1;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.25; self.pers["bots"]["skill"]["bone_update_interval"] = 0.25;
self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head,j_head"; 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"]["strafe"] = 50;
self.pers["bots"]["behavior"]["nade"] = 45; self.pers["bots"]["behavior"]["nade"] = 45;
self.pers["bots"]["behavior"]["sprint"] = 50; self.pers["bots"]["behavior"]["sprint"] = 65;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 20; self.pers["bots"]["behavior"]["crouch"] = 10;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 75; self.pers["bots"]["behavior"]["jump"] = 75;
break; break;
case 7: case 7:
self.pers["bots"]["skill"]["aim_time"] = 0.1; self.pers["bots"]["skill"]["aim_time"] = 0.1;
self.pers["bots"]["skill"]["init_react_time"] = 100; self.pers["bots"]["skill"]["init_react_time"] = 100;
self.pers["bots"]["skill"]["reaction_time"] = 50; self.pers["bots"]["skill"]["reaction_time"] = 50;
self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500;
self.pers["bots"]["skill"]["no_trace_look_time"] = 4000; self.pers["bots"]["skill"]["no_trace_look_time"] = 4000;
self.pers["bots"]["skill"]["remember_time"] = 7500; self.pers["bots"]["skill"]["remember_time"] = 7500;
self.pers["bots"]["skill"]["fov"] = 0.4; self.pers["bots"]["skill"]["fov"] = 0.4;
self.pers["bots"]["skill"]["dist_max"] = 15000; self.pers["bots"]["skill"]["dist_max"] = 15000;
self.pers["bots"]["skill"]["dist_start"] = 10000; self.pers["bots"]["skill"]["dist_start"] = 10000;
self.pers["bots"]["skill"]["spawn_time"] = 0.05; self.pers["bots"]["skill"]["spawn_time"] = 0.05;
self.pers["bots"]["skill"]["help_dist"] = 3000; self.pers["bots"]["skill"]["help_dist"] = 3000;
self.pers["bots"]["skill"]["semi_time"] = 0.1; self.pers["bots"]["skill"]["semi_time"] = 0.1;
self.pers["bots"]["skill"]["shoot_after_time"] = 0; self.pers["bots"]["skill"]["shoot_after_time"] = 0;
self.pers["bots"]["skill"]["aim_offset_time"] = 0; self.pers["bots"]["skill"]["aim_offset_time"] = 0;
self.pers["bots"]["skill"]["aim_offset_amount"] = 0; self.pers["bots"]["skill"]["aim_offset_amount"] = 0;
self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; self.pers["bots"]["skill"]["bone_update_interval"] = 0.05;
self.pers["bots"]["skill"]["bones"] = "j_head"; 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"]["strafe"] = 65;
self.pers["bots"]["behavior"]["nade"] = 65; self.pers["bots"]["behavior"]["nade"] = 65;
self.pers["bots"]["behavior"]["sprint"] = 65; self.pers["bots"]["behavior"]["sprint"] = 70;
self.pers["bots"]["behavior"]["camp"] = 5; self.pers["bots"]["behavior"]["camp"] = 5;
self.pers["bots"]["behavior"]["follow"] = 5; self.pers["bots"]["behavior"]["follow"] = 5;
self.pers["bots"]["behavior"]["crouch"] = 5; self.pers["bots"]["behavior"]["crouch"] = 5;
self.pers["bots"]["behavior"]["switch"] = 2; self.pers["bots"]["behavior"]["switch"] = 2;
self.pers["bots"]["behavior"]["class"] = 2; self.pers["bots"]["behavior"]["class"] = 2;
self.pers["bots"]["behavior"]["jump"] = 90; self.pers["bots"]["behavior"]["jump"] = 90;
break; break;
}
} }
wait 5;
} }
} }
@ -561,6 +578,11 @@ set_class(rankxp)
rank = self maps\mp\gametypes\_rank::getRankForXp( rankxp ) + 1; 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++) for(i=0; i < 5; i++)
{ {
primary = get_random_weapon(primaryGroups, rank); primary = get_random_weapon(primaryGroups, rank);
@ -969,6 +991,7 @@ start_bot_threads()
self thread bot_killstreak_think(); self thread bot_killstreak_think();
self thread bot_weapon_think(); self thread bot_weapon_think();
self thread doReloadCancel();
// script targeting // script targeting
if (getDvarInt("bots_play_target_other")) if (getDvarInt("bots_play_target_other"))
@ -997,6 +1020,7 @@ start_bot_threads()
self thread bot_use_tube_think(); self thread bot_use_tube_think();
self thread bot_use_grenade_think(); self thread bot_use_grenade_think();
self thread bot_use_equipment_think(); self thread bot_use_equipment_think();
self thread bot_watch_think_mw2();
} }
// obj // obj
@ -1029,6 +1053,9 @@ bot_inc_bots(obj, unreach)
level endon("game_ended"); level endon("game_ended");
self endon("bot_inc_bots"); self endon("bot_inc_bots");
if (!isDefined(obj))
return;
if (!isDefined(obj.bots)) if (!isDefined(obj.bots))
obj.bots = 0; obj.bots = 0;
@ -1094,7 +1121,7 @@ nearAnyOfWaypoints(dist, waypoints)
getNearestWaypointOfWaypoints(waypoints) getNearestWaypointOfWaypoints(waypoints)
{ {
answer = undefined; answer = undefined;
closestDist = 999999999999; closestDist = 2147483647;
for (i = 0; i < waypoints.size; i++) for (i = 0; i < waypoints.size; i++)
{ {
waypoint = waypoints[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 Changes to the weap
*/ */
@ -1556,6 +1600,12 @@ bot_revive_think()
if ( self HasScriptGoal() || self.bot_lock_goal ) if ( self HasScriptGoal() || self.bot_lock_goal )
continue; continue;
if(self isDefusing() || self isPlanting())
continue;
if (self inLastStand())
continue;
revivePlayer = undefined; revivePlayer = undefined;
for(i = 0; i < level.players.size; i++) for(i = 0; i < level.players.size; i++)
{ {
@ -1599,7 +1649,7 @@ bot_revive_think()
if (event != "new_goal") if (event != "new_goal")
self ClearScriptGoal(); 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; self.bot_lock_goal = false;
continue; continue;
@ -2028,6 +2078,8 @@ bot_use_equipment_think()
nade = undefined; nade = undefined;
if (self GetAmmoCount("mine_bouncing_betty_mp")) if (self GetAmmoCount("mine_bouncing_betty_mp"))
nade = "mine_bouncing_betty_mp"; nade = "mine_bouncing_betty_mp";
if (self GetAmmoCount("satchel_charge_mp"))
nade = "satchel_charge_mp";
if (!isDefined(nade)) if (!isDefined(nade))
continue; continue;
@ -2105,7 +2157,10 @@ bot_use_equipment_think()
if (self changeToWeapon(nade)) 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 waittill_any_timeout(5, "grenade_fire", "weapon_change");
self notify("stop_firing_weapon"); self notify("stop_firing_weapon");
} }
@ -2348,9 +2403,19 @@ bot_revenge_think()
if(self.pers["bots"]["skill"]["base"] <= 1) if(self.pers["bots"]["skill"]["base"] <= 1)
return; 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)) if(!isDefined(self.killerLocation))
return; return;
loc = self.killerLocation;
for(;;) for(;;)
{ {
wait( RandomIntRange( 1, 5 ) ); wait( RandomIntRange( 1, 5 ) );
@ -2361,13 +2426,80 @@ bot_revenge_think()
if ( randomint( 100 ) < 75 ) if ( randomint( 100 ) < 75 )
return; return;
self SetScriptGoal( self.killerLocation, 64 ); self SetScriptGoal( loc, 64 );
if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal")
self ClearScriptGoal(); 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. Bot logic for switching weapons.
*/ */
@ -2377,6 +2509,8 @@ bot_weapon_think()
self endon("disconnect"); self endon("disconnect");
level endon("game_ended"); level endon("game_ended");
first = true;
for(;;) for(;;)
{ {
self waittill_any_timeout(randomIntRange(2, 4), "bot_force_check_switch"); 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"]) first = false;
continue;
if(hasTarget) if(randomInt(100) > self.pers["bots"]["behavior"]["initswitch"])
continue; 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(); weaponslist = self getweaponslist();
weap = ""; weap = "";
@ -2427,7 +2571,7 @@ bot_weapon_think()
if (maps\mp\gametypes\_weapons::isGrenade( weapon )) if (maps\mp\gametypes\_weapons::isGrenade( weapon ))
continue; 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; continue;
weap = weapon; 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. Bot logic for killstreaks.
*/ */
@ -2538,8 +2728,12 @@ bot_killstreak_think()
if (isAirstrikePos && !isDefined( level.artilleryInProgress )) if (isAirstrikePos && !isDefined( level.artilleryInProgress ))
{ {
self BotFreezeControls(true);
self notify( "confirm_location", targetPos ); self notify( "confirm_location", targetPos );
wait 1; wait 1;
self BotFreezeControls(false);
} }
self thread changeToWeapon(curWeap); self thread changeToWeapon(curWeap);
@ -2734,7 +2928,7 @@ bot_kill_dog_think()
if(level.teamBased && dog.aiteam == self.pers["team"]) if(level.teamBased && dog.aiteam == self.pers["team"])
continue; 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; continue;
if(!bulletTracePassed(myEye, dog.origin+(0, 0, 5), false, dog)) if(!bulletTracePassed(myEye, dog.origin+(0, 0, 5), false, dog))
@ -2803,6 +2997,9 @@ bot_equipment_kill_think()
{ {
item = grenades[i]; item = grenades[i];
if (!isDefined(item))
continue;
if ( !IsDefined( item.name ) ) if ( !IsDefined( item.name ) )
{ {
continue; continue;
@ -3043,20 +3240,23 @@ bot_dom_cap_think()
otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
if ( myFlagCount < otherFlagCount ) if (game["teamScores"][myteam] >= game["teamScores"][otherTeam])
{ {
if ( randomint( 100 ) < 15 ) if ( myFlagCount < otherFlagCount )
continue; {
} if ( randomint( 100 ) < 15 )
else if ( myFlagCount == otherFlagCount ) continue;
{ }
if ( randomint( 100 ) < 35 ) else if ( myFlagCount == otherFlagCount )
continue; {
} if ( randomint( 100 ) < 35 )
else if ( myFlagCount > otherFlagCount ) continue;
{ }
if ( randomint( 100 ) < 95 ) else if ( myFlagCount > otherFlagCount )
continue; {
if ( randomint( 100 ) < 95 )
continue;
}
} }
flag = undefined; flag = undefined;

View File

@ -826,9 +826,9 @@ SmokeTrace(start, end, rad)
*/ */
getConeDot(to, from, dir) getConeDot(to, from, dir)
{ {
dirToTarget = VectorNormalize(to-from); dirToTarget = VectorNormalize(to-from);
forward = AnglesToForward(dir); forward = AnglesToForward(dir);
return vectordot(dirToTarget, forward); return vectordot(dirToTarget, forward);
} }
/* /*
@ -971,25 +971,25 @@ float(num)
*/ */
tokenizeLine(line, tok) tokenizeLine(line, tok)
{ {
tokens = []; tokens = [];
token = ""; token = "";
for (i = 0; i < line.size; i++) for (i = 0; i < line.size; i++)
{ {
c = line[i]; c = line[i];
if (c == tok) if (c == tok)
{ {
tokens[tokens.size] = token; tokens[tokens.size] = token;
token = ""; token = "";
continue; continue;
} }
token += c; token += c;
} }
tokens[tokens.size] = token; tokens[tokens.size] = token;
return tokens; return tokens;
} }
/* /*
@ -1029,7 +1029,7 @@ parseTokensIntoWaypoint(tokens)
getWaypointLinesFromFile(filename) getWaypointLinesFromFile(filename)
{ {
result = spawnStruct(); result = spawnStruct();
result.lines = []; result.lines = [];
waypointStr = fileRead(filename); waypointStr = fileRead(filename);
@ -1051,7 +1051,7 @@ getWaypointLinesFromFile(filename)
line += c; line += c;
} }
result.lines[result.lines.size] = line; result.lines[result.lines.size] = line;
return result; return result;
} }
@ -1077,9 +1077,9 @@ readWpsFromFile(mapname)
{ {
tokens = tokenizeLine(res.lines[i], ","); tokens = tokenizeLine(res.lines[i], ",");
waypoint = parseTokensIntoWaypoint(tokens); waypoint = parseTokensIntoWaypoint(tokens);
waypoints[i-1] = waypoint; waypoints[i-1] = waypoint;
} }
return waypoints; return waypoints;
@ -1543,7 +1543,7 @@ KDTree()
*/ */
KDTreeInsert(data)//as long as what you insert has a .origin attru, it will work. 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) GetNearestWaypointWithSight(pos)
{ {
candidate = undefined; candidate = undefined;
dist = 9999999999; dist = 2147483647;
for(i = 0; i < level.waypointCount; i++) for(i = 0; i < level.waypointCount; i++)
{ {

View File

@ -27,6 +27,9 @@ watchPlayers()
{ {
wait 1; wait 1;
if (!getDvarInt("bots_main_menu"))
return;
for (i = level.players.size - 1; i >= 0; i--) for (i = level.players.size - 1; i >= 0; i--)
{ {
player = level.players[i]; player = level.players[i];

View File

@ -335,7 +335,7 @@ watchSaveWaypointsCommand()
{ {
self iPrintlnBold("Auto link enabled"); self iPrintlnBold("Auto link enabled");
level.autoLink = true; level.autoLink = true;
level.wpToLink = self.nearest; level.wpToLink = self.closest;
} }
} }
@ -413,6 +413,12 @@ DeleteAllWaypoints()
{ {
level.waypoints = []; level.waypoints = [];
level.waypointCount = 0; level.waypointCount = 0;
level.waypointsKDTree = WaypointsToKDTree();
level.waypointsCamp = [];
level.waypointsTube = [];
level.waypointsGren = [];
level.waypointsClay = [];
self iprintln("DelAllWps"); self iprintln("DelAllWps");
} }
@ -584,9 +590,7 @@ destroyOnDeath(hud)
{ {
hud endon("death"); hud endon("death");
self waittill_either("death","disconnect"); self waittill_either("death","disconnect");
hud notify("death");
hud destroy(); hud destroy();
hud = undefined;
} }
textScroll(string) textScroll(string)

View File

@ -13,12 +13,16 @@ Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your s
## Installation ## 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. 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. 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. 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. 2. Run the 'install.bat'. This copies the mod to your WaW mods folder.
3. The mod is now installed, now run your game. 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 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 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! 4. The mod should be loaded! Now go start a map and play!
## Menu Usage ## 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. - Pressing the menu buttons again closes menus.
## Changelog ## 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 - v2.0.0
- Initial reboot release - Initial reboot release

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 3.7 MiB