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
|
## 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!
|
||||||
|

|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
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()
|
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);
|
||||||
|
@ -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(;;)
|
||||||
{
|
{
|
||||||
|
newWeapon = undefined;
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
first = false;
|
||||||
|
newWeapon = self getCurrentWeapon();
|
||||||
|
}
|
||||||
|
else
|
||||||
self waittill( "weapon_change", newWeapon );
|
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();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
while(current >= 0)
|
while(current >= 0)
|
||||||
{
|
{
|
||||||
// skip down the line of waypoints and go to the waypoint we have a direct path too
|
|
||||||
/*for (;;)
|
|
||||||
{
|
|
||||||
if (current <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (level.waypoints[self.bot.astar[current-1]].type == "climb" || level.waypoints[self.bot.astar[current]].type == "climb")
|
|
||||||
break;
|
|
||||||
|
|
||||||
current = self removeAStar();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
self.bot.next_wp = self.bot.astar[current];
|
self.bot.next_wp = self.bot.astar[current];
|
||||||
self.bot.second_next_wp = -1;
|
self.bot.second_next_wp = -1;
|
||||||
if(current != 0)
|
if(current > 0)
|
||||||
self.bot.second_next_wp = self.bot.astar[current-1];
|
self.bot.second_next_wp = self.bot.astar[current-1];
|
||||||
|
|
||||||
self notify("new_static_waypoint");
|
self notify("new_static_waypoint");
|
||||||
|
|
||||||
self movetowards(level.waypoints[self.bot.next_wp].origin);
|
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();
|
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.
|
||||||
*/
|
*/
|
||||||
|
@ -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,13 +278,10 @@ 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"])
|
switch(self.pers["bots"]["skill"]["base"])
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@ -302,13 +302,15 @@ difficulty()
|
|||||||
self.pers["bots"]["skill"]["aim_offset_amount"] = 4;
|
self.pers["bots"]["skill"]["aim_offset_amount"] = 4;
|
||||||
self.pers["bots"]["skill"]["bone_update_interval"] = 2;
|
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"]["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;
|
||||||
@ -331,13 +333,15 @@ difficulty()
|
|||||||
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;
|
||||||
@ -360,13 +364,15 @@ difficulty()
|
|||||||
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;
|
||||||
@ -389,13 +395,15 @@ difficulty()
|
|||||||
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;
|
||||||
@ -418,13 +426,15 @@ difficulty()
|
|||||||
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;
|
||||||
@ -447,13 +457,15 @@ difficulty()
|
|||||||
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;
|
||||||
@ -476,10 +488,12 @@ difficulty()
|
|||||||
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;
|
||||||
@ -489,6 +503,9 @@ difficulty()
|
|||||||
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))
|
||||||
{
|
{
|
||||||
|
if (nade != "satchel_charge_mp")
|
||||||
self thread fire_current_weapon();
|
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,7 +2536,16 @@ bot_weapon_think()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "satchel_charge_mp" && curWeap != "squadcommand_mp")
|
if (first)
|
||||||
|
{
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
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"])
|
if(randomInt(100) > self.pers["bots"]["behavior"]["switch"])
|
||||||
continue;
|
continue;
|
||||||
@ -2410,6 +2553,7 @@ bot_weapon_think()
|
|||||||
if(hasTarget)
|
if(hasTarget)
|
||||||
continue;
|
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,6 +3240,8 @@ bot_dom_cap_think()
|
|||||||
|
|
||||||
otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
|
otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam );
|
||||||
|
|
||||||
|
if (game["teamScores"][myteam] >= game["teamScores"][otherTeam])
|
||||||
|
{
|
||||||
if ( myFlagCount < otherFlagCount )
|
if ( myFlagCount < otherFlagCount )
|
||||||
{
|
{
|
||||||
if ( randomint( 100 ) < 15 )
|
if ( randomint( 100 ) < 15 )
|
||||||
@ -3058,6 +3257,7 @@ bot_dom_cap_think()
|
|||||||
if ( randomint( 100 ) < 95 )
|
if ( randomint( 100 ) < 95 )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flag = undefined;
|
flag = undefined;
|
||||||
flags = [];
|
flags = [];
|
||||||
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
@ -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];
|
||||||
|
@ -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)
|
||||||
|
Submodule main_shared/waypoints updated: 1d04b97e39...f005fd75d7
@ -13,7 +13,11 @@ 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.
|
||||||
@ -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.
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