From 681db293afbb0b2f4489b88abaf71597ee2c0f8c Mon Sep 17 00:00:00 2001 From: blubs Date: Thu, 30 Nov 2023 01:56:53 -0800 Subject: [PATCH] SERVER/FTE: Fix wrong pathfind results SERVER/FTE: Let AI advance to next path waypoint when already at first SERVER: Add zombie goaldummy drawing in dev mode SERVER/FTE: Fix parsing of waypoint files SERVER/FTE: Fix reading of unassigned waypoints --- source/server/ai/fte/waypoints_core.qc | 52 ++++++++++++++++++++++---- source/server/ai/pathfind_code.qc | 39 ++++++++++++++----- source/server/ai/zombie_core.qc | 5 +++ source/server/main.qc | 5 +++ 4 files changed, 84 insertions(+), 17 deletions(-) diff --git a/source/server/ai/fte/waypoints_core.qc b/source/server/ai/fte/waypoints_core.qc index 5817fa1..d2586fc 100644 --- a/source/server/ai/fte/waypoints_core.qc +++ b/source/server/ai/fte/waypoints_core.qc @@ -658,6 +658,11 @@ void() Load_Waypoints_Legacy return; } + // Clear all waypoints + for(float i = 0; i < MAX_WAYPOINTS; i++) { + waypoints[i].id = -1; + } + while (1) { // the first line is just a comment, ignore it @@ -733,15 +738,46 @@ void() Load_Waypoints_Legacy setmodel(new_way, "models/way/normal_way.spr"); } } + + + // Initialize neighbor slots to load + waypoints[which].target_id[0] = -1; + waypoints[which].target_id[1] = -1; + waypoints[which].target_id[2] = -1; + waypoints[which].target_id[3] = -1; + waypoints[which].target_id[4] = -1; + waypoints[which].target_id[5] = -1; + waypoints[which].target_id[6] = -1; + waypoints[which].target_id[7] = -1; + // Initialize extra neighbor slots + waypoints[which].target_id[8] = -1; + waypoints[which].target_id[9] = -1; - waypoints[which].target_id[0] = stof(trg); - waypoints[which].target_id[1] = stof(trg2); - waypoints[which].target_id[2] = stof(trg3); - waypoints[which].target_id[3] = stof(trg4); - waypoints[which].target_id[4] = stof(trg5); - waypoints[which].target_id[5] = stof(trg6); - waypoints[which].target_id[6] = stof(trg7); - waypoints[which].target_id[7] = stof(trg8); + + if(trg != "") { + waypoints[which].target_id[0] = stof(trg); + } + if(trg2 != "") { + waypoints[which].target_id[1] = stof(trg2); + } + if(trg3 != "") { + waypoints[which].target_id[2] = stof(trg3); + } + if(trg4 != "") { + waypoints[which].target_id[3] = stof(trg4); + } + if(trg5 != "") { + waypoints[which].target_id[4] = stof(trg5); + } + if(trg6 != "") { + waypoints[which].target_id[5] = stof(trg6); + } + if(trg7 != "") { + waypoints[which].target_id[6] = stof(trg7); + } + if(trg8 != "") { + waypoints[which].target_id[7] = stof(trg8); + } h = (fgets(file)); h = (fgets(file)); diff --git a/source/server/ai/pathfind_code.qc b/source/server/ai/pathfind_code.qc index 06c8e09..fae1832 100644 --- a/source/server/ai/pathfind_code.qc +++ b/source/server/ai/pathfind_code.qc @@ -129,7 +129,7 @@ float Pathfind (entity z, float s_wp, float e_wp) { if (s_wp == e_wp) { - return 2; + return s_wp; } SV_WP_ClearSet(); @@ -173,22 +173,28 @@ float Pathfind (entity z, float s_wp, float e_wp) { // keep 2 next steps with us //print("Result\n"); //print(ftos(current), "\n"); - while (waypoints[current].step != current) - { - j = i; - i = current; - current = waypoints[current].step; + while (waypoints[current].step != current) { + j = i; // 3rd waypoint along path + i = current; // 2nd waypoint along path + current = waypoints[current].step; // Start waypoint } // go to the furthest one on the path that we can actually see - - if (tracemove(waypoints[s_wp].org,VEC_HULL_MIN,VEC_HULL_MAX,waypoints[i].org,TRUE,z)) + // If within a radius of 6 qu of the first waypoint along the path, + // Always return the 2nd waypoint along the path + float is_at_first_waypoint = vlen(z.origin - waypoints[s_wp].org) <= 6; + + + + // Check if we can tracemove to the 3rd waypoint along the path + if (tracemove(z.origin,VEC_HULL_MIN,VEC_HULL_MAX,waypoints[i].org,TRUE,z)) { //VectorCopy(waypoints[i].origin, res); //print("Giving third wp ", ftos(i), "\n"); return i; } - else if (tracemove(waypoints[s_wp].org,VEC_HULL_MIN,VEC_HULL_MAX,waypoints[j].org,TRUE,z)) + // Check if we can tracemove to the 2nd waypoint along the path + else if (is_at_first_waypoint || tracemove(z.origin,VEC_HULL_MIN,VEC_HULL_MAX,waypoints[j].org,TRUE,z)) { //VectorCopy(waypoints[j].origin, res); //print("Giving second wp ", ftos(j), "\n"); @@ -207,6 +213,11 @@ float Pathfind (entity z, float s_wp, float e_wp) { for (j = 0; j < MAX_WAY_TARGETS; j++) { i = waypoints[current].target_id[j]; + // Skip empty neighbor slots + if(i == -1) { + continue; + } + if (waypoints[i].set != SET_CLOSED && i != current && IsActive(i)) { bestf = waypoints[current].g + HeuristicCostEstimate(i, current); @@ -244,6 +255,11 @@ float Do_Pathfind(entity from, entity to) { #ifndef PSP for (i = 0; i < MAX_WAYPOINTS; i = i + 1) { + // Skip unused waypoint slots + if(waypoints[i].id < 0) { + continue; + } + if (IsActive(i)) { TraceResult = tracemove (from.origin, VEC_HULL_MIN, VEC_HULL_MAX, waypoints[i].org, TRUE ,from); if (TraceResult) { @@ -260,6 +276,11 @@ float Do_Pathfind(entity from, entity to) { best_dist = 100000000; for (i = 0; i < MAX_WAYPOINTS; i = i + 1) { + // Skip unused waypoint slots + if(waypoints[i].id < 0) { + continue; + } + if (IsActive(i)) { TraceResult = tracemove (to.origin, VEC_HULL_MIN, VEC_HULL_MAX, waypoints[i].org, TRUE ,to); if (TraceResult) { diff --git a/source/server/ai/zombie_core.qc b/source/server/ai/zombie_core.qc index 4981ca1..6c9b6fa 100644 --- a/source/server/ai/zombie_core.qc +++ b/source/server/ai/zombie_core.qc @@ -1474,6 +1474,11 @@ void(float i) spawnSingleZombEnt = zSpawn.classname = "freeZombieEntity"; zSpawn.aistatus = "0"; zSpawn.goaldummy = spawn(); + if (cvar("developer")) { + setmodel(zSpawn.goaldummy, "models/way/normal_way.spr"); + } + + zSpawn.goaldummy.classname = "waypoint_target"; zSpawn.head = spawn(); diff --git a/source/server/main.qc b/source/server/main.qc index 473dc31..fee6b4b 100644 --- a/source/server/main.qc +++ b/source/server/main.qc @@ -179,6 +179,11 @@ void() precaches = precache_model ("models/ai/zb%.mdl"); precache_model ("models/ai/zh^.mdl"); + // For debugging zombie AI + if (cvar("developer")) { + precache_model ("models/way/normal_way.spr"); + } + // zombie crawler precache_model ("models/ai/zcfull.mdl"); precache_model ("models/ai/zbc%.mdl");