Release v0.1.3 2026-07-11
This commit is contained in:
@@ -9,6 +9,10 @@ const CHARGE_MARKERS = [0, 1, 2, 3, 4, 5, 6] as const;
|
||||
const STACK_DIRECTIONS = Array.from({ length: 8 }, (_, index) => (index / 8) * Math.PI * 2);
|
||||
const EMPTY_HAZARDS: never[] = [];
|
||||
const EMPTY_SLASH_LANES: never[] = [];
|
||||
const ACTIVE_LANE_MODES = new Set(["mantis_recover", "ram_charging", "ram_recover", "cinderback_ricochet", "cinderback_recover", "sandglass_burrowing", "sandglass_recover", "crab_scuttling", "crab_recover", "ghost_recover"]);
|
||||
const DANGER_WARNING_COLOR = "#ff3b30";
|
||||
const DANGER_ACTIVE_COLOR = "#d4142a";
|
||||
const DANGER_HIGHLIGHT_COLOR = "#ff8a80";
|
||||
type GameStoreState = ReturnType<typeof useGameStore.getState>;
|
||||
|
||||
function motionAt(state: GameStoreState, bossIndex: number) {
|
||||
@@ -37,7 +41,7 @@ export function ChargeLaneIndicator({ bossIndex = 0 }: { bossIndex?: number }) {
|
||||
0.045,
|
||||
(motion.chargeStart[1] + motion.chargeEnd[1]) / 2,
|
||||
];
|
||||
const color = motionMode === "charging" ? "#ffb04a" : "#ff4f37";
|
||||
const color = motionMode === "charging" ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR;
|
||||
const laneWidth = BULL_CHARGE.hitRadius * 2;
|
||||
return (
|
||||
<>
|
||||
@@ -77,16 +81,12 @@ function SlashLaneIndicator({ laneId, bossIndex }: { laneId: string; bossIndex:
|
||||
useFrame(({ clock }) => {
|
||||
if (!material.current || !edgeMaterial.current) return;
|
||||
const current = motionAt(useGameStore.getState(), bossIndex);
|
||||
const active = current?.mode === "mantis_recover";
|
||||
const active = current ? ACTIVE_LANE_MODES.has(current.mode) : false;
|
||||
material.current.opacity = active ? 0.5 : 0.14 + (Math.sin(clock.elapsedTime * 12) + 1) * 0.09;
|
||||
edgeMaterial.current.opacity = active ? 1 : 0.62 + (Math.sin(clock.elapsedTime * 12) + 1) * 0.15;
|
||||
});
|
||||
const lane = motion?.slashLanes.find((candidate) => candidate.id === laneId);
|
||||
if (!lane || phase !== "combat") return null;
|
||||
const visible = motion.mode === "mantis_line_telegraph"
|
||||
|| motion.mode === "mantis_cross_telegraph"
|
||||
|| motion.mode === "mantis_recover";
|
||||
if (!visible) return null;
|
||||
|
||||
const dx = lane.end[0] - lane.start[0];
|
||||
const dz = lane.end[1] - lane.start[1];
|
||||
@@ -97,8 +97,8 @@ function SlashLaneIndicator({ laneId, bossIndex }: { laneId: string; bossIndex:
|
||||
0.052,
|
||||
(lane.start[1] + lane.end[1]) * 0.5,
|
||||
];
|
||||
const active = motion.mode === "mantis_recover";
|
||||
const color = active ? "#ffd36a" : "#ff5128";
|
||||
const active = ACTIVE_LANE_MODES.has(motion.mode);
|
||||
const color = active ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR;
|
||||
return (
|
||||
<group position={midpoint} rotation={[0, angle, 0]}>
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]}>
|
||||
@@ -114,7 +114,7 @@ function SlashLaneIndicator({ laneId, bossIndex }: { laneId: string; bossIndex:
|
||||
{active && (
|
||||
<mesh position={[0, 0.055, 0]}>
|
||||
<boxGeometry args={[0.16, 0.08, length]} />
|
||||
<meshBasicMaterial color="#fff0a8" transparent opacity={0.92} depthWrite={false} />
|
||||
<meshBasicMaterial color={DANGER_HIGHLIGHT_COLOR} transparent opacity={0.92} depthWrite={false} />
|
||||
</mesh>
|
||||
)}
|
||||
</group>
|
||||
@@ -209,7 +209,7 @@ export function BreathConeIndicator({ bossIndex = 0 }: { bossIndex?: number }) {
|
||||
if (material.current) material.current.opacity = 0.2 + (Math.sin(clock.elapsedTime * 8) + 1) * 0.07;
|
||||
});
|
||||
if (!motion || phase !== "combat" || (motion.mode !== "breath_telegraph" && motion.mode !== "breath_sweeping")) return null;
|
||||
const color = motion.mode === "breath_sweeping" ? "#ff7b2e" : "#ffb04f";
|
||||
const color = motion.mode === "breath_sweeping" ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR;
|
||||
return (
|
||||
<group position={[motion.position[0], 0.07, motion.position[1]]} rotation={[0, motion.breathAngle, 0]}>
|
||||
<mesh rotation={[-Math.PI / 2, 0, -Math.PI / 2 - CINDER_BREATH.halfAngle]}>
|
||||
@@ -234,12 +234,27 @@ function CircleHazardIndicator({ hazardId, bossIndex }: { hazardId: string; boss
|
||||
});
|
||||
if (!hazard) return null;
|
||||
const active = time >= hazard.activatesAt;
|
||||
const venom = hazard.kind === "venom_pool";
|
||||
const color = venom ? "#a94ee6" : active ? "#ff642d" : "#ffc14d";
|
||||
const colors = {
|
||||
venom_pool: "#a94ee6",
|
||||
skyfall: active ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR,
|
||||
quake: active ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR,
|
||||
lava_pool: "#ff5a24",
|
||||
stinger_eruption: active ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR,
|
||||
hourglass: active ? DANGER_ACTIVE_COLOR : DANGER_WARNING_COLOR,
|
||||
tidal_burst: active ? DANGER_ACTIVE_COLOR : "#39c9df",
|
||||
soul_rift: active ? "#7446d8" : "#aa78ff",
|
||||
crownfall: active ? DANGER_ACTIVE_COLOR : "#e4c548",
|
||||
royal_shockwave: active ? DANGER_ACTIVE_COLOR : "#f0ca4d",
|
||||
} as const;
|
||||
const color = colors[hazard.kind];
|
||||
return (
|
||||
<group position={[hazard.center[0], 0.065, hazard.center[1]]}>
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<circleGeometry args={[hazard.radius, 40]} />
|
||||
{hazard.innerRadius ? (
|
||||
<ringGeometry args={[hazard.innerRadius, hazard.radius, 48]} />
|
||||
) : (
|
||||
<circleGeometry args={[hazard.radius, 40]} />
|
||||
)}
|
||||
<meshBasicMaterial ref={material} color={color} transparent opacity={active ? 0.24 : 0.16} depthWrite={false} />
|
||||
</mesh>
|
||||
<mesh position={[0, 0.012, 0]} rotation={[-Math.PI / 2, 0, 0]}>
|
||||
@@ -249,7 +264,7 @@ function CircleHazardIndicator({ hazardId, bossIndex }: { hazardId: string; boss
|
||||
{!active && (
|
||||
<mesh position={[0, 0.03, 0]} rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<ringGeometry args={[0.22, 0.34, 24]} />
|
||||
<meshBasicMaterial color="#fff0b0" transparent opacity={0.95} depthWrite={false} />
|
||||
<meshBasicMaterial color={DANGER_HIGHLIGHT_COLOR} transparent opacity={0.95} depthWrite={false} />
|
||||
</mesh>
|
||||
)}
|
||||
</group>
|
||||
|
||||
Reference in New Issue
Block a user