Refine archive world spawn and interaction handling
All checks were successful
Build Org Website / build (push) Successful in 38s

This commit is contained in:
gitea-actions
2026-07-30 10:22:23 +01:00
parent 2f125f32ae
commit dc1ca5c00e
11 changed files with 112 additions and 33 deletions

View File

@@ -193,9 +193,47 @@
return Boolean(area && (area.safeZones || []).some((item) => pointInRect(x, y, item, 0)));
}
function interactionRadius(item) {
return {
npc: 46,
landmark: 64,
portal: 58,
chest: 48,
challenge: 52,
"boss-memory": 50
}[item && item.type] || 44;
}
function nearestInteraction(items, x, y) {
let nearest = null;
let best = Infinity;
(Array.isArray(items) ? items : []).forEach((item) => {
if (!item || !Number.isFinite(item.x) || !Number.isFinite(item.y)) return;
const distance = Math.hypot(item.x - x, item.y - y);
if (distance <= interactionRadius(item) && distance < best) {
nearest = item;
best = distance;
}
});
return nearest;
}
function safeSpawnForState(state) {
const position = state && state.position;
const gate = Data.AREAS.town.gates && Data.AREAS.town.gates[0];
const gateLocked = state && Array.isArray(state.sigils) && !state.sigils.includes("gate");
if (position && position.area === "town" && gate && gateLocked && position.y < gate.y + gate.height) {
return nearestNamedSafeSpawn("town", Data.AREAS.town.safeSpawns.gate.x, Data.AREAS.town.safeSpawns.gate.y);
}
return nearestSafeSpawn(
position && position.area || "town",
position && position.x,
position && position.y
);
}
function nearestSafeSpawn(areaId, x, y) {
const area = Data.AREAS[areaId] || Data.AREAS.town;
const points = Object.entries(area.safeSpawns || { entrance: area.spawn });
const safeCurrent = isSafe(areaId, x, y);
if (safeCurrent) return { area: areaId, spawn: "saved", x, y };
return nearestNamedSafeSpawn(areaId, x, y);
@@ -223,6 +261,7 @@
return Object.freeze({
normalizedVector, approachVelocity, discover, startQuest, progressQuest, completeQuest, updateStory, addItem, itemQuantity,
consumeItem, grantXp, takeDamage, respawn, recordBoss, isSafe, isCombatSafe,
interactionRadius, nearestInteraction, safeSpawnForState,
nearestSafeSpawn, nearestNamedSafeSpawn, currentObjective
});
}));