emergency: randomize route selection near start city
This commit is contained in:
1 parent
a6c0418153
commit
8f085e0db0
1 file changed
+53
-38
Vendored
+53
-38
@@ -3533,19 +3533,9 @@ function nearestEmergencyCity() {
|
||||
return best;
|
||||
}
|
||||
|
||||
function selectEmergencyRoutes() {
|
||||
emergencyRoutes = [];
|
||||
emergencyVehicles = [];
|
||||
emergencyCount = 0;
|
||||
emergencyLastT = null;
|
||||
if (!EMERGENCY_ON || !carGeo || !carGeo.secondary || !carGeo.secondary.cnts || !carGeo.secondary.cnts.length) {
|
||||
window.__emergencyDbg = { enabled: EMERGENCY_ON, startCity: null, routes: 0 };
|
||||
return;
|
||||
}
|
||||
emergencyStartCity = nearestEmergencyCity();
|
||||
var sec = carGeo.secondary;
|
||||
var targetKm = (EMERGENCY_MIN_KM + EMERGENCY_MAX_KM) / 2;
|
||||
var candidates = [];
|
||||
function emergencyCollectCandidates(sec, startCity, minKm, maxKm, nearLimit) {
|
||||
var targetKm = (minKm + maxKm) / 2;
|
||||
var out = [];
|
||||
var k = 0;
|
||||
for (var ci = 0; ci < sec.cnts.length; ci++) {
|
||||
var n = sec.cnts[ci];
|
||||
@@ -3555,11 +3545,11 @@ function selectEmergencyRoutes() {
|
||||
var lastX = sec.pts[last], lastZ = sec.pts[last + 1], lastD = sec.pts[last + 2];
|
||||
var len = Math.max(0, lastD - firstD);
|
||||
var lenKm = len * KM_PER_TILE;
|
||||
var dStart = Math.hypot(firstX - emergencyStartCity.x, firstZ - emergencyStartCity.z);
|
||||
var dEnd = Math.hypot(lastX - emergencyStartCity.x, lastZ - emergencyStartCity.z);
|
||||
var dStart = Math.hypot(firstX - startCity.x, firstZ - startCity.z);
|
||||
var dEnd = Math.hypot(lastX - startCity.x, lastZ - startCity.z);
|
||||
var near = Math.min(dStart, dEnd);
|
||||
if (near < 1.2 && lenKm >= EMERGENCY_MIN_KM * 0.55 && lenKm <= EMERGENCY_MAX_KM * 1.45) {
|
||||
candidates.push({
|
||||
if (near <= nearLimit && lenKm >= minKm && lenKm <= maxKm) {
|
||||
out.push({
|
||||
ci: ci, len: len, lenKm: lenKm, near: near,
|
||||
score: Math.abs(lenKm - targetKm) + near * 18,
|
||||
reverse: dEnd < dStart
|
||||
@@ -3567,35 +3557,58 @@ function selectEmergencyRoutes() {
|
||||
}
|
||||
k += n * 3;
|
||||
}
|
||||
candidates.sort(function (a, b) { return a.score - b.score; });
|
||||
if (!candidates.length) {
|
||||
var best = null, k2 = 0;
|
||||
for (var ci2 = 0; ci2 < sec.cnts.length; ci2++) {
|
||||
var n2 = sec.cnts[ci2];
|
||||
if (n2 < 2) { k2 += n2 * 3; continue; }
|
||||
var f2 = k2, l2 = k2 + (n2 - 1) * 3;
|
||||
var len2 = Math.max(0, sec.pts[l2 + 2] - sec.pts[f2 + 2]);
|
||||
var near2 = Math.min(
|
||||
Math.hypot(sec.pts[f2] - emergencyStartCity.x, sec.pts[f2 + 1] - emergencyStartCity.z),
|
||||
Math.hypot(sec.pts[l2] - emergencyStartCity.x, sec.pts[l2 + 1] - emergencyStartCity.z));
|
||||
if (near2 < 2.5 && (!best || len2 > best.len)) best = { ci: ci2, len: len2, lenKm: len2 * KM_PER_TILE, near: near2, reverse: false };
|
||||
k2 += n2 * 3;
|
||||
return out;
|
||||
}
|
||||
if (best) candidates.push(best);
|
||||
|
||||
function emergencyShuffle(arr) {
|
||||
for (var i = arr.length - 1; i > 0; i--) {
|
||||
var j = Math.floor(Math.random() * (i + 1));
|
||||
var t = arr[i]; arr[i] = arr[j]; arr[j] = t;
|
||||
}
|
||||
for (var r = 0; r < Math.min(EMERGENCY_COUNT, candidates.length); r++) {
|
||||
var route = emergencyChainAt(sec, candidates[r].ci);
|
||||
if (candidates[r].reverse) route.reverse();
|
||||
return arr;
|
||||
}
|
||||
|
||||
function selectEmergencyRoutes() {
|
||||
emergencyRoutes = [];
|
||||
emergencyVehicles = [];
|
||||
emergencyCount = 0;
|
||||
emergencyLastT = null;
|
||||
if (!EMERGENCY_ON || !carGeo || !carGeo.secondary || !carGeo.secondary.cnts || !carGeo.secondary.cnts.length) {
|
||||
window.__emergencyDbg = { enabled: EMERGENCY_ON, startCity: null, candidates: 0, routes: 0 };
|
||||
return;
|
||||
}
|
||||
emergencyStartCity = nearestEmergencyCity();
|
||||
var sec = carGeo.secondary;
|
||||
var pool = emergencyCollectCandidates(sec, emergencyStartCity, EMERGENCY_MIN_KM, EMERGENCY_MAX_KM, 1.2);
|
||||
var poolMode = 'strict';
|
||||
if (!pool.length) {
|
||||
pool = emergencyCollectCandidates(sec, emergencyStartCity, EMERGENCY_MIN_KM * 0.55, EMERGENCY_MAX_KM * 1.45, 1.8);
|
||||
poolMode = 'relaxed';
|
||||
}
|
||||
if (!pool.length) {
|
||||
pool = emergencyCollectCandidates(sec, emergencyStartCity, 10, 160, 3.0);
|
||||
poolMode = 'fallback';
|
||||
}
|
||||
pool.sort(function (a, b) { return a.score - b.score; });
|
||||
var top = pool.slice(0, Math.max(EMERGENCY_COUNT * 8, 24));
|
||||
emergencyShuffle(top);
|
||||
var used = {};
|
||||
for (var r = 0; r < top.length && emergencyRoutes.length < EMERGENCY_COUNT; r++) {
|
||||
var cand = top[r];
|
||||
if (used[cand.ci]) continue;
|
||||
used[cand.ci] = true;
|
||||
var route = emergencyChainAt(sec, cand.ci);
|
||||
if (cand.reverse) route.reverse();
|
||||
var len = route.length ? route[route.length - 1].d - route[0].d : 0;
|
||||
if (len <= 0) continue;
|
||||
emergencyRoutes.push({ pts: route, len: len, lenKm: len * KM_PER_TILE, nearKm: candidates[r].near * KM_PER_TILE });
|
||||
emergencyRoutes.push({ pts: route, len: len, lenKm: len * KM_PER_TILE, nearKm: cand.near * KM_PER_TILE });
|
||||
}
|
||||
for (var v = 0; v < emergencyRoutes.length; v++) {
|
||||
emergencyVehicles.push({
|
||||
route: v,
|
||||
d: emergencyRoutes[v].len * (0.08 + 0.72 * ((v * 0.371) % 1)),
|
||||
dir: ((v % 2) === 0) ? 1 : -1,
|
||||
seed: (v * 0.6180339887) % 1
|
||||
d: emergencyRoutes[v].len * (0.05 + 0.85 * Math.random()),
|
||||
dir: Math.random() < 0.5 ? 1 : -1,
|
||||
seed: Math.random()
|
||||
});
|
||||
}
|
||||
emergencyCount = emergencyVehicles.length;
|
||||
@@ -3608,6 +3621,8 @@ function selectEmergencyRoutes() {
|
||||
pop: emergencyStartCity.pop,
|
||||
km: +(emergencyStartCity.dist * KM_PER_TILE).toFixed(1)
|
||||
} : null,
|
||||
poolMode: poolMode,
|
||||
candidates: pool.length,
|
||||
routes: emergencyRoutes.map(function (r) { return { km: +r.lenKm.toFixed(1), nearKm: +r.nearKm.toFixed(1) }; })
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user