Refine Archive World navigation and gate progression
All checks were successful
Build Org Website / build (push) Successful in 38s
All checks were successful
Build Org Website / build (push) Successful in 38s
This commit is contained in:
@@ -18,6 +18,30 @@
|
||||
return { x: (x / length) * speed, y: (y / length) * speed };
|
||||
}
|
||||
|
||||
function moveToward(value, target, maximumDelta) {
|
||||
if (Math.abs(target - value) <= maximumDelta) return target;
|
||||
return value + Math.sign(target - value) * maximumDelta;
|
||||
}
|
||||
|
||||
function approachVelocity(currentX, currentY, inputX, inputY, movement, deltaMs, hasBoots) {
|
||||
const config = movement || {};
|
||||
const speed = Math.max(1, Number(config.speed) || 160);
|
||||
const moving = Boolean(Number(inputX) || Number(inputY));
|
||||
const target = moving ? normalizedVector(inputX, inputY, speed) : { x: 0, y: 0 };
|
||||
const rate = moving
|
||||
? (hasBoots ? Number(config.bootAcceleration) || 1700 : Number(config.acceleration) || 1300)
|
||||
: Number(config.deceleration) || 1900;
|
||||
const step = Math.max(0, Math.min(50, Number(deltaMs) || 0)) / 1000 * rate;
|
||||
let x = moveToward(Number(currentX) || 0, target.x, step);
|
||||
let y = moveToward(Number(currentY) || 0, target.y, step);
|
||||
const length = Math.hypot(x, y);
|
||||
if (length > speed) {
|
||||
x = x / length * speed;
|
||||
y = y / length * speed;
|
||||
}
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
function discover(state, landmarkId) {
|
||||
const next = copy(state);
|
||||
if (!next || !Data.LANDMARK_IDS.includes(landmarkId)) return next;
|
||||
@@ -164,11 +188,22 @@
|
||||
return !area.collisions.some((item) => pointInRect(x, y, item, 10));
|
||||
}
|
||||
|
||||
function isCombatSafe(areaId, x, y) {
|
||||
const area = Data.AREAS[areaId];
|
||||
return Boolean(area && (area.safeZones || []).some((item) => pointInRect(x, y, item, 0)));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
function nearestNamedSafeSpawn(areaId, x, y) {
|
||||
const area = Data.AREAS[areaId] || Data.AREAS.town;
|
||||
const points = Object.entries(area.safeSpawns || { entrance: area.spawn });
|
||||
const best = points.sort((a, b) =>
|
||||
Math.hypot(a[1].x - x, a[1].y - y) - Math.hypot(b[1].x - x, b[1].y - y))[0];
|
||||
return { area: areaId, spawn: best[0], x: best[1].x, y: best[1].y };
|
||||
@@ -186,7 +221,8 @@
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
normalizedVector, discover, startQuest, progressQuest, completeQuest, updateStory, addItem, itemQuantity,
|
||||
consumeItem, grantXp, takeDamage, respawn, recordBoss, isSafe, nearestSafeSpawn, currentObjective
|
||||
normalizedVector, approachVelocity, discover, startQuest, progressQuest, completeQuest, updateStory, addItem, itemQuantity,
|
||||
consumeItem, grantXp, takeDamage, respawn, recordBoss, isSafe, isCombatSafe,
|
||||
nearestSafeSpawn, nearestNamedSafeSpawn, currentObjective
|
||||
});
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user