From 4e9ed4acb9b2e1d219169fbf0e995cf0e1c16cba Mon Sep 17 00:00:00 2001 From: mand1nga Date: Wed, 11 Feb 2009 21:45:56 +0000 Subject: [PATCH] Bots: Evaluate the risks of picking up items or chasing players before rating them as potential goals Pretty good avoidance of edges on space maps Removal of goals leading to (dangerous) edges from the goal stack Prioritize movements over attacks when bots are under water/slime/lava Reverted scale for rating enemies on dm mode git-svn-id: svn://svn.icculus.org/nexuiz/trunk@5844 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/bots.qc | 5 ++++ data/qcsrc/server/havocbot.qc | 39 ++++++++++++++++++----------- data/qcsrc/server/havocbot_roles.qc | 36 ++++++++++++++++++++------ 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/data/qcsrc/server/bots.qc b/data/qcsrc/server/bots.qc index 0ace7d7f3..0deceafe5 100644 --- a/data/qcsrc/server/bots.qc +++ b/data/qcsrc/server/bots.qc @@ -1625,6 +1625,11 @@ float bot_shouldattack(entity e) void bot_lagfunc(float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4) { + if(self.flags & FL_INWATER) + { + self.bot_aimtarg = world; + return; + } self.bot_aimtarg = e1; self.bot_aimlatency = self.ping; // FIXME? Shouldn't this be in the lag item? self.bot_aimselforigin = v1; diff --git a/data/qcsrc/server/havocbot.qc b/data/qcsrc/server/havocbot.qc index 133c27f96..4d9f67edc 100644 --- a/data/qcsrc/server/havocbot.qc +++ b/data/qcsrc/server/havocbot.qc @@ -204,8 +204,8 @@ void havocbot_movetogoal() if (self.waterlevel) { makevectors(self.v_angle); - self.BUTTON_JUMP = 1; - // TODO: Make them swim up + self.BUTTON_JUMP = TRUE; + evadelava_z = 1; } else { @@ -236,22 +236,29 @@ void havocbot_movetogoal() dst_down = dst_ahead + '0 0 -1500'; traceline(self.origin + self.view_ofs , dst_ahead, TRUE, world); - + if(trace_fraction == 1){ traceline(dst_ahead , dst_down, TRUE, world); - // te_lightning2(world, self.origin, dst_ahead); // Draw "ahead" look - if(trace_fraction == 1) + // te_lightning2(world, self.origin, dst_ahead); // Draw "ahead" look + s = pointcontents(trace_endpos + '0 0 1'); + if (s != CONTENT_SOLID) + if (s == CONTENT_LAVA || s == CONTENT_SLIME) + evadelava = normalize(self.velocity) * -1; + else if (s == CONTENT_SKY) + evadeobstacle = normalize(self.velocity) * -1; + else if (tracebox_hits_trigger_hurt(dst_ahead, self.mins, self.maxs, trace_endpos)) { - s = pointcontents(trace_endpos + '0 0 1'); - if (s == CONTENT_LAVA || s == CONTENT_SLIME) - evadelava = normalize(self.velocity) * -1; - else if (s == CONTENT_SKY) - evadeobstacle = normalize(self.velocity) * -1; - else if (tracebox_hits_trigger_hurt(dst_ahead, self.mins, self.maxs, trace_endpos)) + // te_lightning2(world, dst_ahead, dst_down); // Draw "downwards" look + // if ain't a safe goal with "holes" (like the soylent jumpad) + if(!boxesoverlap(dst_ahead - self.view_ofs + self.mins, dst_ahead - self.view_ofs + self.maxs, + self.goalcurrent.absmin, self.goalcurrent.absmax)) { - // te_lightning2(world, dst_ahead, dst_down); // Draw "downards" look - // TODO: this could be better, but actually it stops lemming behavior - evadeobstacle = flatdir * -1; + // Remove dangerous dynamic goals from stack + if (self.goalcurrent.classname == "player" || self.goalcurrent.classname == "droppedweapon") + navigation_poproute(); + // try to stop + flatdir = '0 0 0'; + evadeobstacle = normalize(self.velocity) * -1; } } } @@ -358,7 +365,7 @@ void havocbot_chooseenemy() head = head.chain; } self.enemy = best; - self.havocbot_stickenemy = 1; + self.havocbot_stickenemy = TRUE; }; .float bot_chooseweapontime; @@ -574,6 +581,8 @@ void havocbot_chooseweapon() void havocbot_aim() { local vector selfvel, enemyvel; + if(self.flags & FL_INWATER) + return; if (time < self.nextaim) return; self.nextaim = time + 0.1; diff --git a/data/qcsrc/server/havocbot_roles.qc b/data/qcsrc/server/havocbot_roles.qc index 8896bd887..0bb9d7b26 100644 --- a/data/qcsrc/server/havocbot_roles.qc +++ b/data/qcsrc/server/havocbot_roles.qc @@ -107,6 +107,24 @@ void havocbot_goalrating_items(float ratingscale, vector org, float sradius) continue; } + // Check if the item can be picked up safely + if(head.classname == "droppedweapon") + { + traceline(head.origin, head.origin + '0 0 -1500', TRUE, world); + + d = pointcontents(trace_endpos + '0 0 1'); + if(d & CONTENT_WATER || d & CONTENT_SLIME || d & CONTENT_LAVA) + { + head = head.chain; + continue; + } + if(tracebox_hits_trigger_hurt(head.origin, head.mins, head.maxs, trace_endpos)) + { + head = head.chain; + continue; + } + } + if(teamplay) { discard = FALSE; @@ -114,7 +132,7 @@ void havocbot_goalrating_items(float ratingscale, vector org, float sradius) FOR_EACH_PLAYER(player) { - if ( self == player || player.deadflag != DEAD_NO) + if ( self == player || player.deadflag ) continue; d = vlen(player.origin - head.origin); // distance between player and item @@ -226,9 +244,6 @@ void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradi local entity head; local float t, noteam; noteam = ((self.team == 0) || (teamplay == 0)); // fteqcc sucks - //dprint("teamplay is "); dprint(ftos(teamplay)); dprint(", own team is "); - //dprint(ftos(self.team)); dprint(" -> noteam is "); dprint(ftos(noteam)); - //dprint("\n"); FOR_EACH_PLAYER(head) { @@ -246,16 +261,21 @@ void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradi continue; */ + if(head.flags & FL_INWATER || head.flags & FL_PARTIALGROUND) + continue; + // not falling if(head.flags & FL_ONGROUND == 0) { traceline(head.origin, head.origin + '0 0 -1500', TRUE, world); t = pointcontents(trace_endpos + '0 0 1'); - if (t != CONTENT_SOLID) + if( t != CONTENT_SOLID ) + if(t & CONTENT_WATER || t & CONTENT_SLIME || t & CONTENT_LAVA) + continue; + if(tracebox_hits_trigger_hurt(head.origin, head.mins, head.maxs, trace_endpos)) continue; - // TODO: check for trigger_hurt here } - + t = (self.health + self.armorvalue ) / (head.health + head.armorvalue ); navigation_routerating(head, t * ratingscale, 2000); } @@ -693,7 +713,7 @@ void havocbot_role_dm() self.bot_strategytime = time + cvar("bot_ai_strategyinterval"); navigation_goalrating_start(); havocbot_goalrating_items(10000, self.origin, 10000); - havocbot_goalrating_enemyplayers(10000, self.origin, 20000); + havocbot_goalrating_enemyplayers(5000, self.origin, 20000); //havocbot_goalrating_waypoints(1, self.origin, 1000); navigation_goalrating_end(); } -- 2.39.2