]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Make so that bots chase players unless they go to dangerous places. If an enemy ends...
authorterencehill <piuntn@gmail.com>
Mon, 30 Jan 2017 15:38:45 +0000 (16:38 +0100)
committerterencehill <piuntn@gmail.com>
Mon, 30 Jan 2017 16:11:45 +0000 (17:11 +0100)
qcsrc/server/bot/default/havocbot/havocbot.qc
qcsrc/server/bot/default/havocbot/roles.qc
qcsrc/server/bot/default/navigation.qc

index 761300005321530823d3c8f1ddf60bc6f6bcded4..e2ff5e79905022fabb51e28001ca2af306af2627 100644 (file)
@@ -428,7 +428,6 @@ void havocbot_movetogoal(entity this)
        vector m2;
        vector evadeobstacle;
        vector evadelava;
-       float s;
        float maxspeed;
        vector gco;
        //float dist;
@@ -727,6 +726,7 @@ void havocbot_movetogoal(entity this)
                }
                else
                {
+                       float s;
                        if(this.aistatus & AI_STATUS_OUT_WATER)
                                this.aistatus &= ~AI_STATUS_OUT_WATER;
 
@@ -786,6 +786,8 @@ void havocbot_movetogoal(entity this)
                        // (only when the bot is on the ground or jumping intentionally)
                        this.aistatus &= ~AI_STATUS_DANGER_AHEAD;
 
+                       bool unreachable = false;
+                       s = CONTENT_SOLID;
                        if(trace_fraction == 1 && this.jumppadcount == 0 && !this.goalcurrent.wphardwired )
                        if((IS_ONGROUND(this)) || (this.aistatus & AI_STATUS_RUNNING) || (this.aistatus & AI_STATUS_ROAMING) || PHYS_INPUT_BUTTON_JUMP(this))
                        {
@@ -809,11 +811,9 @@ void havocbot_movetogoal(entity this)
                                                if (tracebox_hits_trigger_hurt(dst_ahead, this.mins, this.maxs, trace_endpos))
                                                {
                                                        if (gco.z > this.origin.z + jumpstepheightvec.z)
-                                                       { 
+                                                       {
                                                                // the goal is probably on an upper platform, assume bot can't get there
-                                                               LOG_TRACE("bot ", this.netname, " avoided the goal ", this.goalcurrent.classname, " ", etos(this.goalcurrent), " because it led to a dangerous path; goal stack cleared");
-                                                               navigation_clearroute(this);
-                                                               this.bot_strategytime = 0;
+                                                               unreachable = true;
                                                        }
                                                        else
                                                                evadelava = normalize(this.velocity) * -1;
@@ -827,8 +827,17 @@ void havocbot_movetogoal(entity this)
                        evadelava.z = 0;
                        makevectors(this.v_angle.y * '0 1 0');
 
-                       if(evadeobstacle!='0 0 0'||evadelava!='0 0 0')
+                       if(evadeobstacle || evadelava || (s == CONTENT_WATER))
+                       {
                                this.aistatus |= AI_STATUS_DANGER_AHEAD;
+                               if(IS_PLAYER(this.goalcurrent))
+                                       unreachable = true;
+                       }
+                       if(unreachable)
+                       {
+                               navigation_clearroute(this);
+                               this.bot_strategytime = 0;
+                       }
                }
 
                dodge = havocbot_dodge(this);
index 5c25806365f367d1b3337cbae77b1231018282aa..dfa2f4540617580d5c5dc0b821734ca355c3b835 100644 (file)
@@ -136,7 +136,6 @@ void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org
        ratingscale = ratingscale * 0.00005; // enemies are rated around 20000 already
 
        int t;
-
        FOREACH_CLIENT(IS_PLAYER(it) && bot_shouldattack(this, it), LAMBDA(
                // TODO: Merge this logic with the bot_shouldattack function
                if(vdist(it.origin - org, <, 100) || vdist(it.origin - org, >, sradius))
@@ -149,8 +148,9 @@ void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org
                        continue;
                */
 
+               bool rate_wps = false;
                if((it.flags & FL_INWATER) || (it.flags & FL_PARTIALGROUND))
-                       continue;
+                       rate_wps = true;
 
                // not falling
                if(!IS_ONGROUND(it))
@@ -158,16 +158,14 @@ void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org
                        traceline(it.origin, it.origin + '0 0 -1500', true, NULL);
                        t = pointcontents(trace_endpos + '0 0 1');
                        if(t != CONTENT_SOLID )
-                       if(t == CONTENT_WATER || t == CONTENT_SLIME || t == CONTENT_LAVA)
-                               continue;
-                       if(tracebox_hits_trigger_hurt(it.origin, it.mins, it.maxs, trace_endpos))
-                               continue;
+                       {
+                               if(t == CONTENT_WATER || t == CONTENT_SLIME || t == CONTENT_LAVA)
+                                       rate_wps = true;
+                               else if(tracebox_hits_trigger_hurt(it.origin, it.mins, it.maxs, trace_endpos))
+                                       continue;
+                       }
                }
 
-               // TODO: rate waypoints near the targeted player at that moment, instead of the player itself
-               //               adding a player as a goal seems to be quite dangerous, especially on space maps
-               //               remove hack in navigation_poptouchedgoals() after performing this change
-
                t = ((this.health + this.armorvalue) - (it.health + it.armorvalue)) / 150;
                t = bound(0, 1 + t, 3);
                if (skill > 3)
@@ -178,7 +176,27 @@ void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org
                t += max(0, 8 - skill) * 0.05; // less skilled bots attack more mindlessly
                ratingscale *= t;
                if (ratingscale > 0)
-                       navigation_routerating(this, it, ratingscale * BOT_RATING_ENEMY, 2000);
+               {
+                       if(rate_wps)
+                       {
+                               entity theEnemy = it;
+                               entity best_wp = NULL;
+                               float best_dist = 10000;
+                               IL_EACH(g_waypoints, vdist(it.origin - theEnemy.origin, <, 500) && vdist(it.origin - this.origin, >, 100),
+                               {
+                                       float dist = vlen(it.origin - theEnemy.origin);
+                                       if (dist < best_dist)
+                                       {
+                                               best_wp = it;
+                                               best_dist = dist;
+                                       }
+                               });
+                               if (best_wp)
+                                       navigation_routerating(this, best_wp, ratingscale * BOT_RATING_ENEMY, 2000);
+                       }
+                       else
+                               navigation_routerating(this, it, ratingscale * BOT_RATING_ENEMY, 2000);
+               }
        ));
 }
 
index d6bb2195f64ea9d4a3248f88bc5ec2f55e668f6f..eb869601a3f4e59f862ea8b4d944a37808639d2d 100644 (file)
@@ -920,11 +920,6 @@ void navigation_poptouchedgoals(entity this)
                // personality property
        }
 
-       // HACK: remove players/bots as goals, they can lead a bot to unexpected places (cliffs, lava, etc)
-       // TODO: rate waypoints near the targetted player at that moment, instead of the player itself
-       if(IS_PLAYER(this.goalcurrent))
-               navigation_poproute(this);
-
        // Loose goal touching check when running
        if(this.aistatus & AI_STATUS_RUNNING)
        if(this.speed >= autocvar_sv_maxspeed) // if -really- running
@@ -949,7 +944,7 @@ void navigation_poptouchedgoals(entity this)
                }
        }
 
-       while (this.goalcurrent && boxesoverlap(m1, m2, this.goalcurrent.absmin, this.goalcurrent.absmax))
+       while (this.goalcurrent && !IS_PLAYER(this.goalcurrent) && boxesoverlap(m1, m2, this.goalcurrent.absmin, this.goalcurrent.absmax))
        {
                if((this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT))
                        break;