X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fdefault%2Fhavocbot%2Fhavocbot.qc;h=39665a6515ba11a1fd50491bbbed3e8f9445f201;hp=45051b6c270f1e738aa05786b3fbc9f54f1ecc34;hb=b5f61ddcce128eb0c10f6a1aa743c832f4713c90;hpb=29fae4d9d59e5ec8afbdd6ef0ebcc5dcdc1bfa3f diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qc b/qcsrc/server/bot/default/havocbot/havocbot.qc index 45051b6c27..39665a6515 100644 --- a/qcsrc/server/bot/default/havocbot/havocbot.qc +++ b/qcsrc/server/bot/default/havocbot/havocbot.qc @@ -9,6 +9,7 @@ #include "../waypoints.qh" #include +#include #include #include #include @@ -28,6 +29,13 @@ void havocbot_ai(entity this) if(bot_execute_commands(this)) return; + while(this.goalcurrent && wasfreed(this.goalcurrent)) + { + navigation_poproute(this); + if(!this.goalcurrent) + this.bot_strategytime = 0; + } + if (bot_strategytoken == this) if (!bot_strategytoken_taken) { @@ -43,7 +51,7 @@ void havocbot_ai(entity this) // TODO: tracewalk() should take care of this job (better path finding under water) // if we don't have a goal and we're under water look for a waypoint near the "shore" and push it - if(IS_DEAD(this)) + if(!(IS_DEAD(this))) if(!this.goalcurrent) if(this.waterlevel == WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER)) { @@ -129,7 +137,7 @@ void havocbot_ai(entity this) //heading = this.velocity; //dprint(this.goalstack01.classname,etos(this.goalstack01),"\n"); if( - this.goalstack01 != this && this.goalstack01 != NULL && ((this.aistatus & AI_STATUS_RUNNING) == 0) && + this.goalstack01 != this && this.goalstack01 && !wasfreed(this.goalstack01) && ((this.aistatus & AI_STATUS_RUNNING) == 0) && !(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT) ) next = ((this.goalstack01.absmin + this.goalstack01.absmax) * 0.5) - (this.origin + this.view_ofs); @@ -320,7 +328,7 @@ void havocbot_bunnyhop(entity this, vector dir) if(this.goalcurrent.classname=="waypoint") if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL)) if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z) - if(this.goalstack01!=NULL) + if(this.goalstack01 && !wasfreed(this.goalstack01)) { gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5; deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin); @@ -484,6 +492,7 @@ void havocbot_movetogoal(entity this) if(this.jumppadcount) { // If got stuck on the jump pad try to reach the farthest visible waypoint + // but with some randomness so it can try out different paths if(this.aistatus & AI_STATUS_OUT_JUMPPAD) { if(fabs(this.velocity.z)<50) @@ -496,7 +505,7 @@ void havocbot_movetogoal(entity this) if(trace_fraction < 1) continue; - if(!newgoal || vlen2(it.origin - this.origin) > vlen2(newgoal.origin - this.origin)) + if(!newgoal || ((random() < 0.8) && vlen2(it.origin - this.origin) > vlen2(newgoal.origin - this.origin))) newgoal = it; }); @@ -506,6 +515,8 @@ void havocbot_movetogoal(entity this) this.ignoregoaltime = time + autocvar_bot_ai_ignoregoal_timeout; navigation_clearroute(this); navigation_routetogoal(this, newgoal, this.origin); + if(autocvar_bot_debug_goalstack) + debuggoalstack(this); this.aistatus &= ~AI_STATUS_OUT_JUMPPAD; } } @@ -859,9 +870,6 @@ entity havocbot_gettarget(entity this, bool secondary) void havocbot_chooseenemy(entity this) { - entity head, best, head2; - float rating, bestrating, hf; - vector eye, v; if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(this)) { this.enemy = NULL; @@ -900,13 +908,12 @@ void havocbot_chooseenemy(entity this) if (time < this.havocbot_chooseenemy_finished) return; this.havocbot_chooseenemy_finished = time + autocvar_bot_ai_enemydetectioninterval; - eye = this.origin + this.view_ofs; - best = NULL; - bestrating = 100000000; - head = head2 = findchainfloat(bot_attack, true); + vector eye = this.origin + this.view_ofs; + entity best = NULL; + float bestrating = 100000000; // Backup hit flags - hf = this.dphitcontentsmask; + int hf = this.dphitcontentsmask; // Search for enemies, if no enemy can be seen directly try to look through transparent objects @@ -919,42 +926,38 @@ void havocbot_chooseenemy(entity this) { scan_secondary_targets = false; LABEL(scan_targets) - for( ; head; head = head.chain) + IL_EACH(g_bot_targets, it.bot_attack, { if(!scan_secondary_targets) { - if(head.classname == "misc_breakablemodel") + if(it.classname == "misc_breakablemodel") { have_secondary_targets = true; continue; } } - else - { - if(head.classname != "misc_breakablemodel") - continue; - } + else if(it.classname != "misc_breakablemodel") + continue; - v = (head.absmin + head.absmax) * 0.5; - rating = vlen(v - eye); - if (rating rating) - if (bot_shouldattack(this, head)) + if (bot_shouldattack(this, it)) { traceline(eye, v, true, this); - if (trace_ent == head || trace_fraction >= 1) + if (trace_ent == it || trace_fraction >= 1) { - best = head; + best = it; bestrating = rating; } } - } + }); if(!best && have_secondary_targets && !scan_secondary_targets) { scan_secondary_targets = true; // restart the loop - head = head2; bestrating = 100000000; goto scan_targets; } @@ -969,7 +972,6 @@ LABEL(scan_targets) // Set flags to see through transparent objects this.dphitcontentsmask |= DPCONTENTS_OPAQUE; - head = head2; scan_transparent = true; }