diff --git a/main_shared/maps/mp/bots/_bot_internal.gsc b/main_shared/maps/mp/bots/_bot_internal.gsc index 8cc09e6..b9d0dd9 100644 --- a/main_shared/maps/mp/bots/_bot_internal.gsc +++ b/main_shared/maps/mp/bots/_bot_internal.gsc @@ -14,34 +14,35 @@ added() self.pers["bots"] = []; self.pers["bots"]["skill"] = []; - self.pers["bots"]["skill"]["base"] = 7; - self.pers["bots"]["skill"]["aim_time"] = 0.05; - self.pers["bots"]["skill"]["init_react_time"] = 0; - self.pers["bots"]["skill"]["reaction_time"] = 0; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; - self.pers["bots"]["skill"]["no_trace_look_time"] = 10000; - self.pers["bots"]["skill"]["remember_time"] = 25000; - self.pers["bots"]["skill"]["fov"] = -1; - self.pers["bots"]["skill"]["dist"] = 100000; - self.pers["bots"]["skill"]["spawn_time"] = 0; - self.pers["bots"]["skill"]["help_dist"] = 10000; - self.pers["bots"]["skill"]["semi_time"] = 0.05; - self.pers["bots"]["skill"]["shoot_after_time"] = 1; - self.pers["bots"]["skill"]["aim_offset_time"] = 1; - self.pers["bots"]["skill"]["aim_offset_amount"] = 1; - self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; - self.pers["bots"]["skill"]["bones"] = "j_head"; + self.pers["bots"]["skill"]["base"] = 7; // a base knownledge of the bot + self.pers["bots"]["skill"]["aim_time"] = 0.05; // how long it takes for a bot to aim to a location + self.pers["bots"]["skill"]["init_react_time"] = 0; // the reaction time of the bot for inital targets + self.pers["bots"]["skill"]["reaction_time"] = 0; // reaction time for the bots of reoccuring targets + self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; // how long a bot ads's when they cant see the target + self.pers["bots"]["skill"]["no_trace_look_time"] = 10000; // how long a bot will look at a target's last position + self.pers["bots"]["skill"]["remember_time"] = 25000; // how long a bot will remember a target before forgetting about it when they cant see the target + self.pers["bots"]["skill"]["fov"] = -1; // the fov of the bot, -1 being 360, 1 being 0 + self.pers["bots"]["skill"]["dist_max"] = 100000 * 2; // the longest distance a bot will target + self.pers["bots"]["skill"]["dist_start"] = 100000; // the start distance before bot's target abilitys diminish + self.pers["bots"]["skill"]["spawn_time"] = 0; // how long a bot waits after spawning before targeting, etc + self.pers["bots"]["skill"]["help_dist"] = 10000; // how far a bot has awareness + self.pers["bots"]["skill"]["semi_time"] = 0.05; // how fast a bot shoots semiauto + self.pers["bots"]["skill"]["shoot_after_time"] = 1; // how long a bot shoots after target dies/cant be seen + self.pers["bots"]["skill"]["aim_offset_time"] = 1; // how long a bot correct's their aim after targeting + self.pers["bots"]["skill"]["aim_offset_amount"] = 1; // how far a bot's incorrect aim is + self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; // how often a bot changes their bone target + self.pers["bots"]["skill"]["bones"] = "j_head"; // a list of comma seperated bones the bot will aim at self.pers["bots"]["behavior"] = []; - self.pers["bots"]["behavior"]["strafe"] = 50; - self.pers["bots"]["behavior"]["nade"] = 50; - self.pers["bots"]["behavior"]["sprint"] = 50; - self.pers["bots"]["behavior"]["camp"] = 50; - self.pers["bots"]["behavior"]["follow"] = 50; - self.pers["bots"]["behavior"]["crouch"] = 10; - self.pers["bots"]["behavior"]["switch"] = 1; - self.pers["bots"]["behavior"]["class"] = 1; - self.pers["bots"]["behavior"]["jump"] = 100; + self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target + self.pers["bots"]["behavior"]["nade"] = 50; // percentage of how often the bot will grenade + self.pers["bots"]["behavior"]["sprint"] = 50; // percentage of how often the bot will sprint + self.pers["bots"]["behavior"]["camp"] = 50; // percentage of how often the bot will camp + self.pers["bots"]["behavior"]["follow"] = 50; // percentage of how often the bot will follow + self.pers["bots"]["behavior"]["crouch"] = 10; // percentage of how often the bot will crouch + self.pers["bots"]["behavior"]["switch"] = 1; // percentage of how often the bot will switch weapons + self.pers["bots"]["behavior"]["class"] = 1; // percentage of how often the bot will change classes + self.pers["bots"]["behavior"]["jump"] = 100; // percentage of how often the bot will jumpshot and dropshot } /* @@ -578,10 +579,25 @@ updateAimOffset(obj) /* Updates the target object to be traced Has LOS */ -targetObjUpdateTraced(obj, daDist, ent, theTime) +targetObjUpdateTraced(obj, daDist, ent, theTime, isScriptObj) { + distClose = self.pers["bots"]["skill"]["dist_start"]; + distClose *= distClose; + + distMax = self.pers["bots"]["skill"]["dist_max"]; + distMax *= distMax; + + timeMulti = 1; + if (!isScriptObj) + { + if (daDist > distMax) + timeMulti = 0; + else if (daDist > distClose) + timeMulti = 1 - ((daDist - distClose) / (distMax - distClose)); + } + obj.no_trace_time = 0; - obj.trace_time += 50; + obj.trace_time += int(50 * timeMulti); obj.dist = daDist; obj.last_seen_pos = ent.origin; obj.trace_time_time = theTime; @@ -617,8 +633,6 @@ target() myEye = self GetEyePos(); theTime = getTime(); myAngles = self GetPlayerAngles(); - distsq = self.pers["bots"]["skill"]["dist"]; - distsq *= distsq; myFov = self.pers["bots"]["skill"]["fov"]; bestTargets = []; bestTime = 9999999999; @@ -664,7 +678,7 @@ target() self.bot.targets[key] = obj; } - self targetObjUpdateTraced(obj, daDist, ent, theTime); + self targetObjUpdateTraced(obj, daDist, ent, theTime, true); } else { @@ -693,7 +707,7 @@ target() obj = self.bot.targets[key]; daDist = distanceSquared(self.origin, player.origin); isObjDef = isDefined(obj); - if((level.teamBased && self.team == player.team) || player.sessionstate != "playing" || !isAlive(player) || daDist > distsq) + if((level.teamBased && self.team == player.team) || player.sessionstate != "playing" || !isAlive(player)) { if(isObjDef) self.bot.targets[key] = undefined; @@ -731,7 +745,7 @@ target() self.bot.targets[key] = obj; } - self targetObjUpdateTraced(obj, daDist, player, theTime); + self targetObjUpdateTraced(obj, daDist, player, theTime, false); } else { @@ -1537,7 +1551,7 @@ movetowards(goal) { self botMoveTo(goal); - if(time > 2.5) + if(time > 3) { time = 0; if(distanceSquared(self.origin, lastOri) < 128) @@ -1556,8 +1570,6 @@ movetowards(goal) } else if(timeslow > 1.5) { - self stand(); - wait 1; self thread jump(); } else if(timeslow > 0.75) diff --git a/main_shared/maps/mp/bots/_bot_script.gsc b/main_shared/maps/mp/bots/_bot_script.gsc index ab8f218..0d0d4b5 100644 --- a/main_shared/maps/mp/bots/_bot_script.gsc +++ b/main_shared/maps/mp/bots/_bot_script.gsc @@ -275,7 +275,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 600; self.pers["bots"]["skill"]["remember_time"] = 750; self.pers["bots"]["skill"]["fov"] = 0.7; - self.pers["bots"]["skill"]["dist"] = 1000; + self.pers["bots"]["skill"]["dist_max"] = 2500; + self.pers["bots"]["skill"]["dist_start"] = 1000; self.pers["bots"]["skill"]["spawn_time"] = 0.75; self.pers["bots"]["skill"]["help_dist"] = 0; self.pers["bots"]["skill"]["semi_time"] = 0.9; @@ -303,7 +304,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 1250; self.pers["bots"]["skill"]["remember_time"] = 1500; self.pers["bots"]["skill"]["fov"] = 0.65; - self.pers["bots"]["skill"]["dist"] = 1500; + self.pers["bots"]["skill"]["dist_max"] = 3000; + self.pers["bots"]["skill"]["dist_start"] = 1500; self.pers["bots"]["skill"]["spawn_time"] = 0.65; self.pers["bots"]["skill"]["help_dist"] = 500; self.pers["bots"]["skill"]["semi_time"] = 0.75; @@ -331,7 +333,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; self.pers["bots"]["skill"]["remember_time"] = 2000; self.pers["bots"]["skill"]["fov"] = 0.6; - self.pers["bots"]["skill"]["dist"] = 2250; + self.pers["bots"]["skill"]["dist_max"] = 4000; + self.pers["bots"]["skill"]["dist_start"] = 2250; self.pers["bots"]["skill"]["spawn_time"] = 0.5; self.pers["bots"]["skill"]["help_dist"] = 750; self.pers["bots"]["skill"]["semi_time"] = 0.65; @@ -359,7 +362,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; self.pers["bots"]["skill"]["remember_time"] = 3000; self.pers["bots"]["skill"]["fov"] = 0.55; - self.pers["bots"]["skill"]["dist"] = 3350; + self.pers["bots"]["skill"]["dist_max"] = 5000; + self.pers["bots"]["skill"]["dist_start"] = 3350; self.pers["bots"]["skill"]["spawn_time"] = 0.35; self.pers["bots"]["skill"]["help_dist"] = 1000; self.pers["bots"]["skill"]["semi_time"] = 0.5; @@ -387,7 +391,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 2000; self.pers["bots"]["skill"]["remember_time"] = 4000; self.pers["bots"]["skill"]["fov"] = 0.5; - self.pers["bots"]["skill"]["dist"] = 5000; + self.pers["bots"]["skill"]["dist_max"] = 7500; + self.pers["bots"]["skill"]["dist_start"] = 5000; self.pers["bots"]["skill"]["spawn_time"] = 0.25; self.pers["bots"]["skill"]["help_dist"] = 1500; self.pers["bots"]["skill"]["semi_time"] = 0.4; @@ -415,7 +420,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 3000; self.pers["bots"]["skill"]["remember_time"] = 5000; self.pers["bots"]["skill"]["fov"] = 0.45; - self.pers["bots"]["skill"]["dist"] = 7500; + self.pers["bots"]["skill"]["dist_max"] = 10000; + self.pers["bots"]["skill"]["dist_start"] = 7500; self.pers["bots"]["skill"]["spawn_time"] = 0.2; self.pers["bots"]["skill"]["help_dist"] = 2000; self.pers["bots"]["skill"]["semi_time"] = 0.25; @@ -443,7 +449,8 @@ difficulty() self.pers["bots"]["skill"]["no_trace_look_time"] = 4000; self.pers["bots"]["skill"]["remember_time"] = 7500; self.pers["bots"]["skill"]["fov"] = 0.4; - self.pers["bots"]["skill"]["dist"] = 10000; + self.pers["bots"]["skill"]["dist_max"] = 15000; + self.pers["bots"]["skill"]["dist_start"] = 10000; self.pers["bots"]["skill"]["spawn_time"] = 0.05; self.pers["bots"]["skill"]["help_dist"] = 3000; self.pers["bots"]["skill"]["semi_time"] = 0.1; @@ -490,7 +497,11 @@ set_diff() self.pers["bots"]["skill"]["no_trace_look_time"] = 50 * randomInt(100); self.pers["bots"]["skill"]["remember_time"] = 50 * randomInt(100); self.pers["bots"]["skill"]["fov"] = randomFloatRange(-1, 1); - self.pers["bots"]["skill"]["dist"] = randomIntRange(500, 25000); + + randomNum = randomIntRange(500, 25000); + self.pers["bots"]["skill"]["dist_start"] = randomNum; + self.pers["bots"]["skill"]["dist_max"] = randomNum * 2; + self.pers["bots"]["skill"]["spawn_time"] = 0.05 * randomInt(20); self.pers["bots"]["skill"]["help_dist"] = randomIntRange(500, 25000); self.pers["bots"]["skill"]["semi_time"] = randomFloatRange(0.05, 1); diff --git a/main_shared/maps/mp/bots/_bot_utility.gsc b/main_shared/maps/mp/bots/_bot_utility.gsc index 1c54e5d..26d5507 100644 --- a/main_shared/maps/mp/bots/_bot_utility.gsc +++ b/main_shared/maps/mp/bots/_bot_utility.gsc @@ -663,19 +663,51 @@ waittill_notify_or_timeout(not, tim) /* Pezbot's line sphere intersection. + http://paulbourke.net/geometry/circlesphere/raysphere.c */ RaySphereIntersect(start, end, spherePos, radius) { - dp = end - start; - a = dp[0] * dp[0] + dp[1] * dp[1] + dp[2] * dp[2]; - b = 2 * (dp[0] * (start[0] - spherePos[0]) + dp[1] * (start[1] - spherePos[1]) + dp[2] * (start[2] - spherePos[2])); - c = spherePos[0] * spherePos[0] + spherePos[1] * spherePos[1] + spherePos[2] * spherePos[2]; - c += start[0] * start[0] + start[1] * start[1] + start[2] * start[2]; - c -= 2.0 * (spherePos[0] * start[0] + spherePos[1] * start[1] + spherePos[2] * start[2]); - c -= radius * radius; - bb4ac = b * b - 4.0 * a * c; - - return (bb4ac >= 0); + // check if the start or end points are in the sphere + r2 = radius * radius; + if (DistanceSquared(start, spherePos) < r2) + return true; + + if (DistanceSquared(end, spherePos) < r2) + return true; + + // check if the line made by start and end intersect the sphere + dp = end - start; + a = dp[0] * dp[0] + dp[1] * dp[1] + dp[2] * dp[2]; + b = 2 * (dp[0] * (start[0] - spherePos[0]) + dp[1] * (start[1] - spherePos[1]) + dp[2] * (start[2] - spherePos[2])); + c = spherePos[0] * spherePos[0] + spherePos[1] * spherePos[1] + spherePos[2] * spherePos[2]; + c += start[0] * start[0] + start[1] * start[1] + start[2] * start[2]; + c -= 2.0 * (spherePos[0] * start[0] + spherePos[1] * start[1] + spherePos[2] * start[2]); + c -= radius * radius; + bb4ac = b * b - 4.0 * a * c; + + if (abs(a) < 0.0001 || bb4ac < 0) + return false; + + mu1 = (0-b + sqrt(bb4ac)) / (2 * a); + //mu2 = (0-b - sqrt(bb4ac)) / (2 * a); + + // intersection points of the sphere + ip1 = start + mu1 * dp; + //ip2 = start + mu2 * dp; + + myDist = DistanceSquared(start, end); + + // check if both intersection points far + if (DistanceSquared(start, ip1) > myDist/* && DistanceSquared(start, ip2) > myDist*/) + return false; + + dpAngles = VectorToAngles(dp); + + // check if the point is behind us + if (getConeDot(ip1, start, dpAngles) < 0/* || getConeDot(ip2, start, dpAngles) < 0*/) + return false; + + return true; } /*