mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-21 04:08:41 +00:00
v1 slob
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { TileRef } from "../../../core/game/GameMap";
|
||||
import type { GameView } from "../../../core/game/GameView";
|
||||
|
||||
export type GridSegmentMotionPlanView = {
|
||||
planId: number;
|
||||
startTick: number;
|
||||
ticksPerStep: number;
|
||||
points: Uint32Array;
|
||||
segmentSteps: Uint32Array;
|
||||
segCumSteps: Uint32Array;
|
||||
};
|
||||
|
||||
export type SampledMotionPosition = {
|
||||
x: number;
|
||||
y: number;
|
||||
isComplete: boolean;
|
||||
tile0: TileRef;
|
||||
tile1: TileRef;
|
||||
};
|
||||
|
||||
function clamp01(v: number): number {
|
||||
if (v <= 0) return 0;
|
||||
if (v >= 1) return 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
export function sampleGridSegmentPlan(
|
||||
game: GameView,
|
||||
plan: GridSegmentMotionPlanView,
|
||||
tickFloat: number,
|
||||
): SampledMotionPosition | null {
|
||||
const points = plan.points;
|
||||
if (points.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (points.length === 1 || plan.segmentSteps.length === 0) {
|
||||
const t = points[0] as TileRef;
|
||||
return { x: game.x(t), y: game.y(t), isComplete: true, tile0: t, tile1: t };
|
||||
}
|
||||
|
||||
const ticksPerStep = Math.max(1, plan.ticksPerStep);
|
||||
const stepFloat = (tickFloat - plan.startTick) / ticksPerStep;
|
||||
|
||||
const segCum = plan.segCumSteps;
|
||||
const totalSteps = segCum.length === 0 ? 0 : segCum[segCum.length - 1] >>> 0;
|
||||
if (totalSteps <= 0) {
|
||||
const t = points[points.length - 1] as TileRef;
|
||||
return { x: game.x(t), y: game.y(t), isComplete: true, tile0: t, tile1: t };
|
||||
}
|
||||
|
||||
if (stepFloat <= 0) {
|
||||
const t = points[0] as TileRef;
|
||||
const t1 = points[1] as TileRef;
|
||||
return {
|
||||
x: game.x(t),
|
||||
y: game.y(t),
|
||||
isComplete: false,
|
||||
tile0: t,
|
||||
tile1: t1,
|
||||
};
|
||||
}
|
||||
if (stepFloat >= totalSteps) {
|
||||
const t = points[points.length - 1] as TileRef;
|
||||
return { x: game.x(t), y: game.y(t), isComplete: true, tile0: t, tile1: t };
|
||||
}
|
||||
|
||||
// Find the segment containing stepFloat.
|
||||
let seg = 0;
|
||||
let lo = 0;
|
||||
let hi = plan.segmentSteps.length - 1;
|
||||
while (lo <= hi) {
|
||||
const mid = (lo + hi) >>> 1;
|
||||
const start = segCum[mid] >>> 0;
|
||||
const end = segCum[mid + 1] >>> 0;
|
||||
if (stepFloat < start) {
|
||||
hi = mid - 1;
|
||||
} else if (stepFloat >= end) {
|
||||
lo = mid + 1;
|
||||
} else {
|
||||
seg = mid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const segStart = segCum[seg] >>> 0;
|
||||
const steps = Math.max(1, plan.segmentSteps[seg] >>> 0);
|
||||
const u = clamp01((stepFloat - segStart) / steps);
|
||||
|
||||
const tile0 = points[seg] as TileRef;
|
||||
const tile1 = points[seg + 1] as TileRef;
|
||||
const x0 = game.x(tile0);
|
||||
const y0 = game.y(tile0);
|
||||
const x1 = game.x(tile1);
|
||||
const y1 = game.y(tile1);
|
||||
|
||||
return {
|
||||
x: x0 + (x1 - x0) * u,
|
||||
y: y0 + (y1 - y0) * u,
|
||||
isComplete: false,
|
||||
tile0,
|
||||
tile1,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user