diff --git a/userraw/maps/mp/bots/_bot.gsc b/userraw/maps/mp/bots/_bot.gsc index d7e06cf..27e74e4 100644 --- a/userraw/maps/mp/bots/_bot.gsc +++ b/userraw/maps/mp/bots/_bot.gsc @@ -23,11 +23,6 @@ init() if (!getDvarInt("bots_main")) return; - if(getDvar("bots_main_lowmem") == "") - setDvar("bots_main_lowmem", false);//lower memory usage mode, more cpu - - level.bots_lowmem = getDvarInt("bots_main_lowmem"); - thread load_waypoints(); thread hook_callbacks(); diff --git a/userraw/maps/mp/bots/_bot_internal.gsc b/userraw/maps/mp/bots/_bot_internal.gsc index cc9a6ef..574f120 100644 --- a/userraw/maps/mp/bots/_bot_internal.gsc +++ b/userraw/maps/mp/bots/_bot_internal.gsc @@ -1823,7 +1823,7 @@ cleanUpAStar(team) self waittill_any("death", "disconnect", "kill_goal"); for(i = self.bot.astar.size - 1; i >= 0; i--) - level.waypoints[self.bot.astar[i]].bots[team]--; + RemoveWaypointUsage(self.bot.astar[i], team); } /* @@ -1851,7 +1851,7 @@ removeAStar() remove = self.bot.astar.size-1; if(level.teamBased) - level.waypoints[self.bot.astar[remove]].bots[self.team]--; + RemoveWaypointUsage(self.bot.astar[remove], self.team); self.bot.astar[remove] = undefined; diff --git a/userraw/maps/mp/bots/_bot_script.gsc b/userraw/maps/mp/bots/_bot_script.gsc index 0c59816..3b7aa6c 100644 --- a/userraw/maps/mp/bots/_bot_script.gsc +++ b/userraw/maps/mp/bots/_bot_script.gsc @@ -1594,47 +1594,6 @@ bots_watch_touch_obj(obj) } } -/* - Is bot near any of the given waypoints -*/ -nearAnyOfWaypoints(dist, waypoints) -{ - dist *= dist; - for (i = 0; i < waypoints.size; i++) - { - waypoint = waypoints[i]; - - if (DistanceSquared(waypoint.origin, self.origin) > dist) - continue; - - return true; - } - - return false; -} - -/* - Returns nearest waypoint of waypoints -*/ -getNearestWaypointOfWaypoints(waypoints) -{ - answer = undefined; - closestDist = 2147483647; - for (i = 0; i < waypoints.size; i++) - { - waypoint = waypoints[i]; - thisDist = DistanceSquared(self.origin, waypoint.origin); - - if (isDefined(answer) && thisDist > closestDist) - continue; - - answer = waypoint; - closestDist = thisDist; - } - - return answer; -} - /* Watches while the obj is being carried, calls 'goal' when complete */ @@ -2056,16 +2015,7 @@ bot_think_camp() if(randomInt(100) > self.pers["bots"]["behavior"]["camp"]) continue; - campSpots = []; - distSq = 1024*1024; - for (i = 0; i < level.waypointsCamp.size; i++) - { - if (DistanceSquared(self.origin, level.waypointsCamp[i].origin) > distSq) - continue; - - campSpots[campSpots.size] = level.waypointsCamp[i]; - } - campSpot = random(campSpots); + campSpot = getWaypointForIndex(random(self waypointsNear(getWaypointsOfType("camp"), 1024))); if (!isDefined(campSpot)) continue; @@ -2404,18 +2354,9 @@ bot_use_tube_think() loc = undefined; - if (!self nearAnyOfWaypoints(128, level.waypointsTube)) + if (!self nearAnyOfWaypoints(128, getWaypointsOfType("tube"))) { - tubeWps = []; - distSq = 1024*1024; - for (i = 0; i < level.waypointsTube.size; i++) - { - if (DistanceSquared(self.origin, level.waypointsTube[i].origin) > distSq) - continue; - - tubeWps[tubeWps.size] = level.waypointsTube[i]; - } - tubeWp = random(tubeWps); + tubeWp = getWaypointForIndex(random(self waypointsNear(getWaypointsOfType("tube"), 1024))); myEye = self GetEye(); if (!isDefined(tubeWp) || self HasScriptGoal() || self.bot_lock_goal) @@ -2453,7 +2394,7 @@ bot_use_tube_think() } else { - tubeWp = self getNearestWaypointOfWaypoints(level.waypointsTube); + tubeWp = getWaypointForIndex(self getNearestWaypointOfWaypoints(getWaypointsOfType("tube"))); loc = tubeWp.origin + AnglesToForward(tubeWp.angles) * 2048; } @@ -2534,18 +2475,9 @@ bot_use_equipment_think() loc = undefined; - if (!self nearAnyOfWaypoints(128, level.waypointsClay)) + if (!self nearAnyOfWaypoints(128, getWaypointsOfType("claymore"))) { - clayWps = []; - distSq = 1024*1024; - for (i = 0; i < level.waypointsClay.size; i++) - { - if (DistanceSquared(self.origin, level.waypointsClay[i].origin) > distSq) - continue; - - clayWps[clayWps.size] = level.waypointsClay[i]; - } - clayWp = random(clayWps); + clayWp = getWaypointForIndex(random(self waypointsNear(getWaypointsOfType("claymore"), 1024))); if (!isDefined(clayWp) || self HasScriptGoal() || self.bot_lock_goal) { @@ -2573,7 +2505,7 @@ bot_use_equipment_think() } else { - clayWp = self getNearestWaypointOfWaypoints(level.waypointsClay); + clayWp = getWaypointForIndex(self getNearestWaypointOfWaypoints(getWaypointsOfType("claymore"))); loc = clayWp.origin + AnglesToForward(clayWp.angles) * 2048; } @@ -2642,18 +2574,9 @@ bot_use_grenade_think() loc = undefined; - if (!self nearAnyOfWaypoints(128, level.waypointsGren)) + if (!self nearAnyOfWaypoints(128, getWaypointsOfType("grenade"))) { - nadeWps = []; - distSq = 1024*1024; - for (i = 0; i < level.waypointsGren.size; i++) - { - if (DistanceSquared(self.origin, level.waypointsGren[i].origin) > distSq) - continue; - - nadeWps[nadeWps.size] = level.waypointsGren[i]; - } - nadeWp = random(nadeWps); + nadeWp = getWaypointForIndex(random(self waypointsNear(getWaypointsOfType("grenade"), 1024))); myEye = self GetEye(); if (!isDefined(nadeWp) || self HasScriptGoal() || self.bot_lock_goal) @@ -2691,7 +2614,7 @@ bot_use_grenade_think() } else { - nadeWp = self getNearestWaypointOfWaypoints(level.waypointsGren); + nadeWp = getWaypointForIndex(self getNearestWaypointOfWaypoints(getWaypointsOfType("grenade"))); loc = nadeWp.origin + AnglesToForward(nadeWp.angles) * 2048; } @@ -2895,18 +2818,9 @@ bot_jav_loc_think() loc = undefined; - if (!self nearAnyOfWaypoints(128, level.waypointsJav)) + if (!self nearAnyOfWaypoints(128, getWaypointsOfType("javelin"))) { - javWps = []; - distSq = 1024*1024; - for (i = 0; i < level.waypointsJav.size; i++) - { - if (DistanceSquared(self.origin, level.waypointsJav[i].origin) > distSq) - continue; - - javWps[javWps.size] = level.waypointsJav[i]; - } - javWp = random(javWps); + javWp = getWaypointForIndex(random(self waypointsNear(getWaypointsOfType("javelin"), 1024))); if (!isDefined(javWp) || self HasScriptGoal() || self.bot_lock_goal) { @@ -2942,7 +2856,7 @@ bot_jav_loc_think() } else { - javWp = self getNearestWaypointOfWaypoints(level.waypointsJav); + javWp = getWaypointForIndex(self getNearestWaypointOfWaypoints(getWaypointsOfType("javelin"))); loc = javWp.jav_point; } @@ -4055,18 +3969,9 @@ bot_killstreak_think() if (self inLastStand()) continue; - if (lifeId == self.deaths && !self HasScriptGoal() && !self.bot_lock_goal && streakName != "sentry" && !self nearAnyOfWaypoints(128, level.waypointsCamp)) + if (lifeId == self.deaths && !self HasScriptGoal() && !self.bot_lock_goal && streakName != "sentry" && !self nearAnyOfWaypoints(128, getWaypointsOfType("camp"))) { - campSpots = []; - distSq = 1024*1024; - for (i = 0; i < level.waypointsCamp.size; i++) - { - if (DistanceSquared(self.origin, level.waypointsCamp[i].origin) > distSq) - continue; - - campSpots[campSpots.size] = level.waypointsCamp[i]; - } - campSpot = random(campSpots); + campSpot = getWaypointForIndex(random(self waypointsNear(getWaypointsOfType("camp"), 1024))); if (isDefined(campSpot)) { diff --git a/userraw/maps/mp/bots/_bot_utility.gsc b/userraw/maps/mp/bots/_bot_utility.gsc index c102f32..43471e4 100644 --- a/userraw/maps/mp/bots/_bot_utility.gsc +++ b/userraw/maps/mp/bots/_bot_utility.gsc @@ -779,7 +779,6 @@ parseTokensIntoWaypoint(tokens) childStr = tokens[1]; childToks = strtok(childStr, " "); - waypoint.childCount = childToks.size; waypoint.children = []; for( j=0; j dist) + continue; + + return true; } - - level.waypointsCamp = []; - level.waypointsTube = []; - level.waypointsGren = []; - level.waypointsClay = []; - level.waypointsJav = []; - + + return false; +} + +/* + Returns the waypoints that are near +*/ +waypointsNear(waypoints, dist) +{ + dist *= dist; + + answer = []; + + for (i = 0; i < waypoints.size; i++) + { + wp = level.waypoints[waypoints[i]]; + + if (DistanceSquared(wp.origin, self.origin) > dist) + continue; + + answer[answer.size] = waypoints[i]; + } + + return answer; +} + +/* + Returns nearest waypoint of waypoints +*/ +getNearestWaypointOfWaypoints(waypoints) +{ + answer = undefined; + closestDist = 2147483647; + for (i = 0; i < waypoints.size; i++) + { + waypoint = level.waypoints[waypoints[i]]; + thisDist = DistanceSquared(self.origin, waypoint.origin); + + if (isDefined(answer) && thisDist > closestDist) + continue; + + answer = waypoints[i]; + closestDist = thisDist; + } + + return answer; +} + +/* + Returns all waypoints of type +*/ +getWaypointsOfType(type) +{ + answer = []; for(i = 0; i < level.waypointCount; i++) - if(level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) - level.waypointsCamp[level.waypointsCamp.size] = level.waypoints[i]; - else if(level.waypoints[i].type == "tube") - level.waypointsTube[level.waypointsTube.size] = level.waypoints[i]; - else if(level.waypoints[i].type == "grenade") - level.waypointsGren[level.waypointsGren.size] = level.waypoints[i]; - else if(level.waypoints[i].type == "claymore") - level.waypointsClay[level.waypointsClay.size] = level.waypoints[i]; - else if(level.waypoints[i].type == "javelin") - level.waypointsJav[level.waypointsJav.size] = level.waypoints[i]; + { + wp = level.waypoints[i]; + + if (type == "camp") + { + if (wp.type != "crouch") + continue; + + if (wp.children.size != 1) + continue; + } + else if (type != wp.type) + continue; + + answer[answer.size] = i; + } + return answer; +} + +/* + Returns the waypoint for index +*/ +getWaypointForIndex(i) +{ + if (!isDefined(i)) + return undefined; + + return level.waypoints[i]; } /* @@ -1872,6 +1946,23 @@ ReverseHeapAStar(item, item2) return item.f < item2.f; } +/* + Removes the waypoint usage +*/ +RemoveWaypointUsage(wp, team) +{ + if (!isDefined(level.waypointUsage)) + return; + + if (!isDefined(level.waypointUsage[team][wp+""])) + return; + + level.waypointUsage[team][wp+""]--; + + if (level.waypointUsage[team][wp+""] <= 0) + level.waypointUsage[team][wp+""] = undefined; +} + /* Will linearly search for the nearest waypoint to pos that has a direct line of sight. */ @@ -1890,7 +1981,7 @@ GetNearestWaypointWithSight(pos) continue; dist = curdis; - candidate = level.waypoints[i]; + candidate = i; } return candidate; @@ -1911,7 +2002,7 @@ GetNearestWaypoint(pos) continue; dist = curdis; - candidate = level.waypoints[i]; + candidate = i; } return candidate; @@ -1920,71 +2011,48 @@ GetNearestWaypoint(pos) /* Modified Pezbot astar search. This makes use of sets for quick look up and a heap for a priority queue instead of simple lists which require to linearly search for elements everytime. - Also makes use of the KD tree to search for the nearest node to the goal. We only use the closest node from the KD tree if it has a direct line of sight, else we will have to linearly search for one that we have a line of sight on. It is also modified to make paths with bots already on more expensive and will try a less congested path first. Thus spliting up the bots onto more paths instead of just one (the smallest). */ AStarSearch(start, goal, team, greedy_path) { open = NewHeap(::ReverseHeapAStar);//heap openset = [];//set for quick lookup - closed = [];//set for quick lookup - startwp = undefined; - if (level.bots_lowmem) - startwp = getNearestWaypoint(start); - else - startwp = level.waypointsKDTree KDTreeNearest(start);//balanced kdtree, for nns - if(!isDefined(startwp)) + + startWp = getNearestWaypoint(start); + if(!isDefined(startWp)) return []; + _startwp = undefined; - if(!bulletTracePassed(start + (0, 0, 15), startwp.origin + (0, 0, 15), false, undefined)) + if(!bulletTracePassed(start + (0, 0, 15), level.waypoints[startWp].origin + (0, 0, 15), false, undefined)) _startwp = GetNearestWaypointWithSight(start); + if(isDefined(_startwp)) - startwp = _startwp; - startwp = startwp.index; + startWp = _startwp; + - goalwp = undefined; - if (level.bots_lowmem) - goalwp = getNearestWaypoint(goal); - else - goalwp = level.waypointsKDTree KDTreeNearest(goal); - if(!isDefined(goalwp)) + goalWp = getNearestWaypoint(goal); + if(!isDefined(goalWp)) return []; - _goalwp = undefined; - if(!bulletTracePassed(goal + (0, 0, 15), goalwp.origin + (0, 0, 15), false, undefined)) + + _goalWp = undefined; + if(!bulletTracePassed(goal + (0, 0, 15), level.waypoints[goalWp].origin + (0, 0, 15), false, undefined)) _goalwp = GetNearestWaypointWithSight(goal); + if(isDefined(_goalwp)) - goalwp = _goalwp; - goalwp = goalwp.index; + goalWp = _goalwp; - /*storeKey = "astarcache " + startwp + " " + goalwp; - if (StoreHas(storeKey)) - { - path = []; - pathArrStr = tokenizeLine(StoreGet(storeKey), ","); - - pathArrSize = pathArrStr.size; - for (i = 0; i < pathArrSize; i++) - { - path[path.size] = int(pathArrStr[i]); - } - - return path; - }*/ - - goalorg = level.waypoints[goalWp].origin; node = spawnStruct(); node.g = 0; //path dist so far - node.h = DistanceSquared(level.waypoints[startWp].origin, goalorg); //herustic, distance to goal for path finding - //node.f = node.h + node.g; // combine path dist and heru, use reverse heap to sort the priority queue by this attru - node.f = node.h; - node.index = startwp; + node.h = DistanceSquared(level.waypoints[startWp].origin, level.waypoints[goalWp].origin); //herustic, distance to goal for path finding + node.f = node.h + node.g; // combine path dist and heru, use reverse heap to sort the priority queue by this attru + node.index = startWp; node.parent = undefined; //we are start, so we have no parent //push node onto queue - openset[node.index] = node; + openset[node.index+""] = node; open HeapInsert(node); //while the queue is not empty @@ -1993,94 +2061,94 @@ AStarSearch(start, goal, team, greedy_path) //pop bestnode from queue bestNode = open.data[0]; open HeapRemove(); - openset[bestNode.index] = undefined; + openset[bestNode.index+""] = undefined; + wp = level.waypoints[bestNode.index]; //check if we made it to the goal - if(bestNode.index == goalwp) + if(bestNode.index == goalWp) { path = []; - //storeStr = ""; while(isDefined(bestNode)) { - if(isdefined(team)) - level.waypoints[bestNode.index].bots[team]++; + if(isdefined(team) && isDefined(level.waypointUsage)) + { + if (!isDefined(level.waypointUsage[team][bestNode.index+""])) + level.waypointUsage[team][bestNode.index+""] = 0; + + level.waypointUsage[team][bestNode.index+""]++; + } //construct path path[path.size] = bestNode.index; - - //storeStr += bestNode.index; bestNode = bestNode.parent; - - /*if (isDefined(bestNode)) - storeStr += ",";*/ } - //StoreSet(storeKey, storeStr); return path; } - - nodeorg = level.waypoints[bestNode.index].origin; - childcount = level.waypoints[bestNode.index].childCount; + //for each child of bestnode - for(i = 0; i < childcount; i++) + for(i = wp.children.size - 1; i >= 0; i--) { - child = level.waypoints[bestNode.index].children[i]; - childorg = level.waypoints[child].origin; - childtype = level.waypoints[child].type; + child = wp.children[i]; + childWp = level.waypoints[child]; penalty = 1; - if(!greedy_path && isdefined(team)) + if(!greedy_path && isdefined(team) && isDefined(level.waypointUsage)) { - temppen = level.waypoints[child].bots[team];//consider how many bots are taking this path + temppen = 1; + if (isDefined(level.waypointUsage[team][child+""])) + temppen = level.waypointUsage[team][child+""];//consider how many bots are taking this path + if(temppen > 1) penalty = temppen; } // have certain types of nodes more expensive - if (childtype == "climb" || childtype == "prone") + if (childWp.type == "climb" || childWp.type == "prone") penalty += 4; //calc the total path we have took - newg = bestNode.g + DistanceSquared(nodeorg, childorg)*penalty;//bots on same team's path are more expensive + newg = bestNode.g + DistanceSquared(wp.origin, childWp.origin)*penalty;//bots on same team's path are more expensive //check if this child is in open or close with a g value less than newg - inopen = isDefined(openset[child]); - if(inopen && openset[child].g <= newg) + inopen = isDefined(openset[child+""]); + if(inopen && openset[child+""].g <= newg) continue; - inclosed = isDefined(closed[child]); - if(inclosed && closed[child].g <= newg) + inclosed = isDefined(closed[child+""]); + if(inclosed && closed[child+""].g <= newg) continue; + node = undefined; if(inopen) - node = openset[child]; + node = openset[child+""]; else if(inclosed) - node = closed[child]; + node = closed[child+""]; else node = spawnStruct(); node.parent = bestNode; node.g = newg; - node.h = DistanceSquared(childorg, goalorg); + node.h = DistanceSquared(childWp.origin, level.waypoints[goalWp].origin); node.f = node.g + node.h; node.index = child; //check if in closed, remove it if(inclosed) - closed[child] = undefined; + closed[child+""] = undefined; //check if not in open, add it if(!inopen) { open HeapInsert(node); - openset[child] = node; + openset[child+""] = node; } } //done with children, push onto closed - closed[bestNode.index] = bestNode; + closed[bestNode.index+""] = bestNode; } return []; diff --git a/userraw/maps/mp/bots/_wp_editor.gsc b/userraw/maps/mp/bots/_wp_editor.gsc index 33f928d..675838c 100644 --- a/userraw/maps/mp/bots/_wp_editor.gsc +++ b/userraw/maps/mp/bots/_wp_editor.gsc @@ -51,7 +51,6 @@ init() level.waypoints = []; level.waypointCount = 0; - level.bots_lowmem = false; level waittill( "connected", player); player thread onPlayerSpawned(); @@ -186,7 +185,7 @@ updateWaypointsStats() if(distance(level.waypoints[i].origin, self.origin) < getDvarFloat("bots_main_debug_distance") && (bulletTracePassed(myEye, wpOrg, false, self) || getDVarint("bots_main_debug_drawThrough"))) { - for(h = 0; h < level.waypoints[i].childCount; h++) + for(h = level.waypoints[i].children.size - 1; h >= 0; h--) line(wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + (0, 0, 25), (1,0,1)); if(getConeDot(wpOrg, myEye, myAngles) > getDvarFloat("bots_main_debug_cone")) @@ -366,12 +365,11 @@ watchSaveWaypointsCommand() logprint("*/waypoints["+i+"] = spawnstruct();\n/*"); logprint("*/waypoints["+i+"].origin = "+level.waypoints[i].origin+";\n/*"); logprint("*/waypoints["+i+"].type = \""+level.waypoints[i].type+"\";\n/*"); - logprint("*/waypoints["+i+"].childCount = "+level.waypoints[i].childCount+";\n/*"); - for(c = 0; c < level.waypoints[i].childCount; c++) + for(c = 0; c < level.waypoints[i].children.size; c++) { logprint("*/waypoints["+i+"].children["+c+"] = "+level.waypoints[i].children[c]+";\n/*"); } - if(isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade")) + if(isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade")) logprint("*/waypoints["+i+"].angles = "+level.waypoints[i].angles+";\n/*"); if (isDefined(level.waypoints[i].jav_point) && level.waypoints[i].type == "javelin") @@ -392,11 +390,11 @@ watchSaveWaypointsCommand() str += wp.origin[0] + " " + wp.origin[1] + " " + wp.origin[2] + ","; - for(h = 0; h < wp.childCount; h++) + for(h = 0; h < wp.children.size; h++) { str += wp.children[h]; - if (h < wp.childCount - 1) + if (h < wp.children.size - 1) str += " "; } str += "," + wp.type + ","; @@ -447,8 +445,8 @@ checkForWarnings() continue; } - if(level.waypoints[i].childCount <= 0) - self iprintln("WARNING: waypoint "+i+" childCount is "+level.waypoints[i].childCount); + if(level.waypoints[i].children.size <= 0) + self iprintln("WARNING: waypoint "+i+" childCount is "+level.waypoints[i].children.size); else { if (!isDefined(level.waypoints[i].children) || !isDefined(level.waypoints[i].children.size)) @@ -457,10 +455,7 @@ checkForWarnings() } else { - if(level.waypoints[i].childCount != level.waypoints[i].children.size) - self iprintln("WARNING: waypoint "+i+" childCount is not "+level.waypoints[i].children.size); - - for (h = 0; h < level.waypoints[i].childCount; h++) + for(h = level.waypoints[i].children.size - 1; h >= 0; h--) { child = level.waypoints[i].children[h]; @@ -481,7 +476,7 @@ checkForWarnings() if (level.waypoints[i].type == "javelin" && !isDefined(level.waypoints[i].jav_point)) self iprintln("WARNING: waypoint "+i+" jav_point is undefined"); - if(!isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade")) + if(!isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade")) self iprintln("WARNING: waypoint "+i+" angles is undefined"); } } @@ -505,9 +500,6 @@ UnLinkWaypoint(nwp) level.waypoints[nwp].children = array_remove(level.waypoints[nwp].children, level.wpToLink); level.waypoints[level.wpToLink].children = array_remove(level.waypoints[level.wpToLink].children, nwp); - level.waypoints[nwp].childCount = level.waypoints[nwp].children.size; - level.waypoints[level.wpToLink].childCount = level.waypoints[level.wpToLink].children.size; - self iprintln("Waypoint " + nwp + " Broken to " + level.wpToLink); level.wpToLink = -1; } @@ -529,7 +521,7 @@ LinkWaypoint(nwp) } weGood = true; - for (i = 0; i < level.waypoints[level.wpToLink].childCount; i++) + for(i = level.waypoints[level.wpToLink].children.size - 1; i >= 0; i--) { child = level.waypoints[level.wpToLink].children[i]; @@ -542,7 +534,7 @@ LinkWaypoint(nwp) if(weGood) { - for (i = 0; i < level.waypoints[nwp].childCount; i++) + for(i = level.waypoints[nwp].children.size - 1; i >= 0; i--) { child = level.waypoints[nwp].children[i]; @@ -561,10 +553,8 @@ LinkWaypoint(nwp) return; } - level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].childcount] = nwp; - level.waypoints[level.wpToLink].childcount++; - level.waypoints[nwp].children[level.waypoints[nwp].childcount] = level.wpToLink; - level.waypoints[nwp].childcount++; + level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].children.size] = nwp; + level.waypoints[nwp].children[level.waypoints[nwp].children.size] = level.wpToLink; self iprintln("Waypoint " + nwp + " Linked to " + level.wpToLink); level.wpToLink = -1; @@ -580,18 +570,16 @@ DeleteWaypoint(nwp) level.wpToLink = -1; - for (i = 0; i < level.waypoints[nwp].childCount; i++) + for(i = level.waypoints[nwp].children.size - 1; i >= 0; i--) { child = level.waypoints[nwp].children[i]; level.waypoints[child].children = array_remove(level.waypoints[child].children, nwp); - - level.waypoints[child].childCount = level.waypoints[child].children.size; } for(i = 0; i < level.waypointCount; i++) { - for(h = 0; h < level.waypoints[i].childCount; h++) + for(h = level.waypoints[i].children.size - 1; h >= 0; h--) { if(level.waypoints[i].children[h] > nwp) level.waypoints[i].children[h]--; @@ -639,7 +627,6 @@ AddWaypoint() level.waypoints[level.waypointCount].angles = self getPlayerAngles(); level.waypoints[level.waypointCount].children = []; - level.waypoints[level.waypointCount].childCount = 0; if (level.waypoints[level.waypointCount].type == "javelin") { @@ -666,13 +653,6 @@ DeleteAllWaypoints() { level.waypoints = []; level.waypointCount = 0; - level.waypointsKDTree = WaypointsToKDTree(); - - level.waypointsCamp = []; - level.waypointsTube = []; - level.waypointsGren = []; - level.waypointsClay = []; - level.waypointsJav = []; self iprintln("DelAllWps"); } @@ -682,7 +662,7 @@ buildChildCountString ( wp ) if ( wp == -1 ) return ""; - wpstr = level.waypoints[wp].childCount + ""; + wpstr = level.waypoints[wp].children.size + ""; return wpstr; } @@ -694,7 +674,7 @@ buildChildString( wp ) wpstr = ""; - for(i = 0; i < level.waypoints[wp].childCount; i++) + for(i = 0; i < level.waypoints[wp].children.size; i++) { if(i != 0) wpstr = wpstr + "," + level.waypoints[wp].children[i];