From 1493faf42e1c8e0bf7ae0d9f477d4a170d8f0881 Mon Sep 17 00:00:00 2001 From: charredUtensil Date: Sun, 30 Jun 2024 23:25:10 -0400 Subject: [PATCH] refactor strataflux --- src/core/architects/slugs.ts | 1 + .../architects/utils/creature_spawners.ts | 18 +- src/core/lore/graphs/events.ts | 14 ++ .../transformers/03_plastic/03_strataflux.ts | 227 ------------------ .../03_plastic/03_strataflux/base.ts | 9 + .../03_plastic/03_strataflux/corners.ts | 85 +++++++ .../03_plastic/03_strataflux/edges.ts | 114 +++++++++ .../03_plastic/03_strataflux/index.ts | 138 +++++++++++ .../transformers/04_ephemera/02_program.ts | 1 - src/webui/App.tsx | 4 +- src/webui/components/map_preview/index.tsx | 4 +- src/webui/components/map_preview/tiles.tsx | 1 + 12 files changed, 380 insertions(+), 236 deletions(-) delete mode 100644 src/core/transformers/03_plastic/03_strataflux.ts create mode 100644 src/core/transformers/03_plastic/03_strataflux/base.ts create mode 100644 src/core/transformers/03_plastic/03_strataflux/corners.ts create mode 100644 src/core/transformers/03_plastic/03_strataflux/edges.ts create mode 100644 src/core/transformers/03_plastic/03_strataflux/index.ts diff --git a/src/core/architects/slugs.ts b/src/core/architects/slugs.ts index 3d6c9ad..c551ce1 100644 --- a/src/core/architects/slugs.ts +++ b/src/core/architects/slugs.ts @@ -51,6 +51,7 @@ const SLUG_HALL: PartialArchitect = { slugSpawnScript: (args) => { const holes = getSlugHoles(args); return slugSpawnScript(args, { + emerges: holes.map(([x, y]) => ({x, y, radius: 1})), initialCooldown: { min: 60, max: 120 }, needCrystals: { base: args.plan.crystals * 2, increment: args.plan.crystals }, triggerPoints: holes, diff --git a/src/core/architects/utils/creature_spawners.ts b/src/core/architects/utils/creature_spawners.ts index 4b6e2b0..6030aa7 100644 --- a/src/core/architects/utils/creature_spawners.ts +++ b/src/core/architects/utils/creature_spawners.ts @@ -9,6 +9,7 @@ import { eventChain, mkVars, scriptFragment, transformPoint } from "./script"; type CreatureSpawnerArgs = { creature: CreatureTemplate; + emerges?: readonly Emerge[]; initialCooldown?: { min: number; max: number }; maxTriggerCount?: number; meanWaveSize?: number; @@ -36,12 +37,21 @@ const RETRIGGER_MODES = { export type RetriggerMode = keyof typeof RETRIGGER_MODES; -function getEmerges(plan: Plan, rng: PseudorandomStream, waveSize: number) { - const emerges = plan.path.baseplates.map((bp) => { +type Emerge = { + readonly x: number, + readonly y: number, + readonly radius: number, +}; + +function getEmerges(plan: Plan): Emerge[] { + return plan.path.baseplates.map((bp) => { const [x, y] = bp.center; return { x: Math.floor(x), y: Math.floor(y), radius: bp.pearlRadius }; }); - const result: typeof emerges = []; +} + +function cycleEmerges(emerges: readonly Emerge[], rng: PseudorandomStream, waveSize: number) { + const result: Emerge[] = []; while (result.length < waveSize) { result.push(...rng.shuffle(emerges)); } @@ -102,7 +112,7 @@ function creatureSpawnScript( }; const discoveryPoint = getDiscoveryPoint(cavern, plan); - const emerges = getEmerges(plan, opts.rng, waveSize); + const emerges = cycleEmerges(opts.emerges ?? getEmerges(plan), opts.rng, waveSize); const triggerPoints = opts.triggerPoints ?? getTriggerPoints(cavern, plan); const v = mkVars(`p${plan.id}${opts.creature.inspectAbbrev}Spawner`, [ diff --git a/src/core/lore/graphs/events.ts b/src/core/lore/graphs/events.ts index a221214..e552882 100644 --- a/src/core/lore/graphs/events.ts +++ b/src/core/lore/graphs/events.ts @@ -178,3 +178,17 @@ export const NOMADS_SETTLED = phraseGraph( .then(end); }, ); + +export const FOUND_SLUG_NEST = phraseGraph( + ({ pg, state, start, end, cut, skip }) => { + start.then( + "I don't like the look of this.", + "Look at that!", + "Oh, dear.", + "This could be a problem!", + ).then( + "It must be a nest of Slimy Slugs!", + "We need to keep these Slimy Slugs at bay.", + ) + } +); \ No newline at end of file diff --git a/src/core/transformers/03_plastic/03_strataflux.ts b/src/core/transformers/03_plastic/03_strataflux.ts deleted file mode 100644 index c2fa8e3..0000000 --- a/src/core/transformers/03_plastic/03_strataflux.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { PseudorandomStream } from "../../common"; -import { NSEW, Point } from "../../common/geometry"; -import { Grid, MutableGrid } from "../../common/grid"; -import { StrataformedCavern } from "./02_strataform"; - -export const HEIGHT_MIN = -600; -export const HEIGHT_MAX = 600; - -const FENCES = [ - [-1, -1], - [0, -1], - [-1, 0], - [0, 0], -] as const; - -type PointInfo = { - readonly target: number | undefined; - readonly x: number; - readonly y: number; - readonly localMin: boolean; - readonly neighbors: { info: PointInfo; ascent: number; descent: number }[]; - collapseQueued: boolean; - min: number; - max: number; - range: number; -}; - -function superflat(cavern: StrataformedCavern): Grid { - const result = new MutableGrid(); - for (let x = cavern.left; x <= cavern.right; x++) { - for (let y = cavern.top; y <= cavern.bottom; y++) { - result.set(x, y, 0); - } - } - return result; -} - -const sortFn = ({ range: a }: PointInfo, { range: b }: PointInfo) => b - a; - -function getTileSlopes(cavern: StrataformedCavern): Grid { - const result = new MutableGrid(); - const tileOobSlope = Math.max( - cavern.context.caveMaxSlope, - cavern.context.hallMaxSlope, - ); - for (let x = cavern.left; x < cavern.right; x++) { - for (let y = cavern.top; y < cavern.bottom; y++) { - const tile = cavern.tiles.get(x, y); - const forTile = tile - ? tile.maxSlope ?? tileOobSlope - : cavern.context.voidMaxSlope; - const forPlan = - cavern.pearlInnerDex.get(x, y)?.reduce((r, _, i) => { - const plan = cavern.plans[i]; - return plan.hasErosion - ? 0 - : Math.min( - r, - plan.architect.maxSlope ?? Infinity, - plan.kind === "cave" - ? cavern.context.caveMaxSlope - : cavern.context.hallMaxSlope, - ); - }, Infinity) ?? Infinity; - result.set(x, y, Math.min(forTile, forPlan)); - } - } - return result; -} - -function getBorders(cavern: StrataformedCavern): Point[] { - const result: Point[] = []; - for (let x = cavern.left; x <= cavern.right; x++) { - result.push([x, cavern.top]); - } - for (let y = cavern.top + 1; y < cavern.bottom; y++) { - result.push([cavern.left, y], [cavern.right, y]); - } - for (let x = cavern.left; x <= cavern.right; x++) { - result.push([x, cavern.bottom]); - } - return result; -} - -function getRandomHeight(info: PointInfo, rng: PseudorandomStream): number { - if (info.min === info.max) { - return info.min; - } - const targetInRange = (() => { - if (info.target === undefined) { - return 0.5; - } - if (info.target <= info.min) { - return 0; - } - if (info.target >= info.max) { - return 1; - } - return (info.target - info.min) / (info.max - info.min); - })(); - return rng.betaInt({ - a: 1 + 3 * targetInRange, - b: 1 + 3 * (1 - targetInRange), - min: info.min, - max: info.max + 1, - }); -} - -export default function strataflux( - cavern: StrataformedCavern, -): StrataformedCavern { - if (cavern.context.heightTargetRange <= 0) { - return { ...cavern, height: superflat(cavern) }; - } - - const tileSlopes = getTileSlopes(cavern); - const infos = new MutableGrid(); - const collapseQueue: PointInfo[] = getBorders(cavern).map(([x, y]) => { - const info = { - target: 0, - x, - y, - localMin: false, - neighbors: [], - collapseQueued: true, - min: 0, - max: 0, - range: 0, - }; - infos.set(x, y, info); - return info; - }); - for (let x = cavern.left + 1; x < cavern.right; x++) { - for (let y = cavern.top + 1; y < cavern.bottom; y++) { - infos.set(x, y, { - target: cavern.height.get(x, y), - x, - y, - localMin: !!FENCES.some( - ([ox, oy]) => - cavern.tiles.get(x + ox, y + oy)?.isFluid || - cavern.pearlInnerDex - .get(x + ox, y + oy) - ?.some((_, i) => cavern.plans[i].hasErosion), - ), - neighbors: [], - collapseQueued: false, - min: HEIGHT_MIN, - max: HEIGHT_MAX, - range: HEIGHT_MAX - HEIGHT_MIN, - }); - } - } - - for (let x = cavern.left; x <= cavern.right; x++) { - for (let y = cavern.top; y <= cavern.bottom; y++) { - const info = infos.get(x, y)!; - const [ni, si, ei, wi] = NSEW.map(([ox, oy]) => - infos.get(x + ox, y + oy), - ); - const [nw, ne, sw, se] = FENCES.map( - ([ox, oy]) => tileSlopes.get(x + ox, y + oy) ?? Infinity, - ); - ( - [ - [ni, Math.min(nw, ne)], - [si, Math.min(sw, se)], - [ei, Math.min(ne, se)], - [wi, Math.min(nw, sw)], - ] as [PointInfo | undefined, number][] - ).forEach(([ai, slope]) => { - if (ai) { - info.neighbors.push({ - info: ai, - ascent: ai.localMin ? 0 : slope, - descent: info.localMin ? 0 : slope, - }); - } - }); - } - } - - const height = new MutableGrid(); - const rng = cavern.dice.height; - const collapse = () => { - const info = collapseQueue.pop()!; - const h = getRandomHeight(info, rng); - height.set(info.x, info.y, h); - info.min = h; - info.max = h; - info.range = 0; - return info; - }; - - while (collapseQueue.length) { - const effectQueue = [collapse()]; - for (let i = 0; i < effectQueue.length; i++) { - const info = effectQueue.shift()!; - for (let j = 0; j < info.neighbors.length; j++) { - const neighbor = info.neighbors[j]; - if (!neighbor.info.range) { - continue; - } - neighbor.info.min = Math.max( - neighbor.info.min, - info.min - neighbor.descent, - ); - neighbor.info.max = Math.min( - neighbor.info.max, - info.max + neighbor.ascent, - ); - const range = neighbor.info.max - neighbor.info.min; - if (range < neighbor.info.range) { - neighbor.info.range = range; - effectQueue.push(neighbor.info); - if (!neighbor.info.collapseQueued) { - neighbor.info.collapseQueued = true; - collapseQueue.push(neighbor.info); - } - } - } - } - collapseQueue.sort(sortFn); - } - - return { ...cavern, height }; -} diff --git a/src/core/transformers/03_plastic/03_strataflux/base.ts b/src/core/transformers/03_plastic/03_strataflux/base.ts new file mode 100644 index 0000000..aea6e47 --- /dev/null +++ b/src/core/transformers/03_plastic/03_strataflux/base.ts @@ -0,0 +1,9 @@ +export const CORNER_OFFSETS = [ + [-1, -1], + [0, -1], + [-1, 0], + [0, 0], +] as const; + +export const HEIGHT_MIN = -600; +export const HEIGHT_MAX = 600; \ No newline at end of file diff --git a/src/core/transformers/03_plastic/03_strataflux/corners.ts b/src/core/transformers/03_plastic/03_strataflux/corners.ts new file mode 100644 index 0000000..38fe8da --- /dev/null +++ b/src/core/transformers/03_plastic/03_strataflux/corners.ts @@ -0,0 +1,85 @@ +import { Mutable } from "../../../common"; +import { NSEW } from "../../../common/geometry"; +import { Grid, MutableGrid } from "../../../common/grid"; +import { filterTruthy } from "../../../common/utils"; +import { StrataformedCavern } from "../02_strataform"; +import { HEIGHT_MAX, HEIGHT_MIN } from "./base"; +import getEdges from "./edges"; + +// IDEA: Don't use corners; use HeightNodes which do not have the x and y coord +// Start by finding lakes and assign everywhere in the lake the same HeightNode +// object. This will have some performance benefit, but also it means neighbors +// can be added between non-adjacent corners. As long as the relationship is +// defined symmetrically, there should be no issue with these as the algorithm +// doesn't require the space be Euclidean. + +export type Corner = { + readonly target: number | undefined; + readonly x: number; + readonly y: number; + readonly neighbors: readonly { + readonly corner: Corner; + // The maximum upward slope moving from here to the neighbor. + readonly ascent: number; + // The maximum downward slope moving from here to the neighbor. + readonly descent: number; + }[]; + collapseQueued: boolean; + min: number; + max: number; + range: number; +}; + +export default function getCorners(cavern: StrataformedCavern): Grid { + const corners = new MutableGrid(); + for (let x = cavern.left; x <= cavern.right; x++) { + for (let y = cavern.top; y <= cavern.bottom; y++) { + const target = cavern.height.get(x, y); + // Corners on the border are adjusted to a height of 0 when loaded in Manic + // Miners. This means they should be compressed here, but this also gives + // strataflux a starting point for which corners have known heights. + const isBorder = ( + x === cavern.left || + x === cavern.right || + y === cavern.top || + y === cavern.bottom + ); + corners.set(x, y, { + target, + x, + y, + neighbors: [], + collapseQueued: isBorder, + min: isBorder ? 0 : HEIGHT_MIN, + max: isBorder ? 0 : HEIGHT_MAX, + range: isBorder ? 0 : HEIGHT_MAX - HEIGHT_MIN, + }) + } + } + // With the corner objects created, add all neighbors. + const {edgesH, edgesV} = getEdges(cavern); + corners.forEach((corner, x, y) => { + (corner.neighbors as Mutable).push( + ...filterTruthy(NSEW.map(([ox, oy]) => { + const c = corners.get(x + ox, y + oy); + if (!c) { + return undefined; + } + // Find the edge. Since these are indexed by the minimum, the edges in + // the positive direction are found at [x, y]. + const e = (oy === 0 ? edgesH : edgesV).get( + x + Math.min(ox, 0), + y + Math.min(oy, 0), + ); + if (!e) { + return undefined; + } + // Determine ascent and descent from the edge slopes. + return (ox + oy < 0) + ? {corner: c, ascent: e.backwardSlope, descent: e.forwardSlope} + : {corner: c, ascent: e.forwardSlope, descent: e.backwardSlope}; + })) + ); + }); + return corners; +} \ No newline at end of file diff --git a/src/core/transformers/03_plastic/03_strataflux/edges.ts b/src/core/transformers/03_plastic/03_strataflux/edges.ts new file mode 100644 index 0000000..2a706f9 --- /dev/null +++ b/src/core/transformers/03_plastic/03_strataflux/edges.ts @@ -0,0 +1,114 @@ +import { Mutable } from "../../../common"; +import { Grid, MutableGrid } from "../../../common/grid"; +import { Tile } from "../../../models/tiles"; +import { StrataformedCavern } from "../02_strataform"; +import { CORNER_OFFSETS } from "./base"; + +export type Edge = { + // The maximum slope when going up toward the positive axis + readonly forwardSlope: number, + // The maximum slope when going up toward the negative axis + readonly backwardSlope: number, +} + +// Each tile has a maximum slope its edges are allowed to have. +// A variety of attributes are allowed to influence this slope, so combine them +// here into a single grid of max slopes. +function getTileSlopes(cavern: StrataformedCavern): Grid { + const result = new MutableGrid(); + // The max slope allowed for tile types that are within the play area but + // don't define a specific slope. + const tileOobSlope = Math.max( + cavern.context.caveMaxSlope, + cavern.context.hallMaxSlope, + ); + const maxSlopeForPlan = cavern.plans.map(plan => Math.min( + plan.hasErosion ? 0 : Infinity, + plan.architect.maxSlope ?? Infinity, + plan.kind === "cave" + ? cavern.context.caveMaxSlope + : cavern.context.hallMaxSlope, + )); + for (let x = cavern.left; x < cavern.right; x++) { + for (let y = cavern.top; y < cavern.bottom; y++) { + // Determine the max slope for the specific tile placed here. + const tile = cavern.tiles.get(x, y); + const forTile = tile + ? Math.min(tile.maxSlope ?? Infinity, tileOobSlope) + : cavern.context.voidMaxSlope; + // Determine the max slope for the plans at this tile. + const forPlan = + cavern.pearlInnerDex.get(x, y)?.reduce((r, _, i) => + Math.min(r, maxSlopeForPlan[i]), Infinity) ?? Infinity; + result.set(x, y, Math.min(forTile, forPlan)); + } + } + return result; +} + +// Turns the given point into a "bowl" where this point and all points around +// it up to the given size must slope downward toward this point. +function bowlify( + x: number, + y: number, + size: number, + edgesH: MutableGrid>, + edgesV: MutableGrid>, +) { + for (let i = 0; i <= size; i++) { + for (let j = -i; j <= i; j++) { + edgesH.get(x + i, y + j)!.backwardSlope = 0; + edgesH.get(x - i - 1, y + j)!.forwardSlope = 0; + edgesV.get(x + j, y + i)!.backwardSlope = 0; + edgesV.get(x + j, y - i - 1)!.forwardSlope = 0; + } + } +} + +export default function getEdges(cavern: StrataformedCavern): {edgesH: Grid, edgesV: Grid} { + const tileSlopes = getTileSlopes(cavern); + + const edgesH = new MutableGrid>(); + for (let x = cavern.left; x < cavern.right; x++) { + for (let y = cavern.top + 1; y < cavern.bottom; y++) { + const slope = Math.min( + tileSlopes.get(x, y - 1)!, + tileSlopes.get(x, y)!, + ); + edgesH.set(x, y, {forwardSlope: slope, backwardSlope: slope}); + } + } + const edgesV = new MutableGrid>(); + for (let x = cavern.left + 1; x < cavern.right; x++) { + for (let y = cavern.top; y < cavern.bottom; y++) { + const slope = Math.min( + tileSlopes.get(x - 1, y)!, + tileSlopes.get(x, y)!, + ); + edgesV.set(x, y, {forwardSlope: slope, backwardSlope: slope}); + } + } + + const bowls = new MutableGrid(); + cavern.tiles.forEach((tile, x, y) => { + let size; + if (tile === Tile.WATER) { + size = 1; + } else if (tile === Tile.LAVA) { + size = 1; + } else if (cavern.pearlInnerDex.get(x, y)?.some(p => cavern.plans[p].hasErosion)) { + size = 0; + } else { + return; + } + CORNER_OFFSETS.forEach(([ox, oy]) => { + bowls.set(x + ox, y + oy, Math.max( + size, + bowls.get(x + ox, y + oy) ?? 0), + ); + }); + }); + bowls.forEach((size, x, y) => bowlify(x, y, size, edgesH, edgesV)); + + return {edgesH, edgesV}; +} \ No newline at end of file diff --git a/src/core/transformers/03_plastic/03_strataflux/index.ts b/src/core/transformers/03_plastic/03_strataflux/index.ts new file mode 100644 index 0000000..c45f2a5 --- /dev/null +++ b/src/core/transformers/03_plastic/03_strataflux/index.ts @@ -0,0 +1,138 @@ +import { PseudorandomStream } from "../../../common"; +import { Grid, MutableGrid } from "../../../common/grid"; +import { StrataformedCavern } from "../02_strataform"; +import getCorners, { Corner } from "./corners"; + +// The "strataflux" algorithm is particularly complex mostly because it +// involves many data structures and concepts that are not really used +// elsewhere. The bulk of the code is simply generating the data structures +// needed to perform the algorithm, which work as follows: +// +// This algorithm deals with Tiles, Corners, and Edges - Tiles meaning the same +// thing as in the rest of this project and the others defined thusly: +// +// EdgeH [x, y] =====v +// Corner [x, y] => +--------+ <= Corner [x + 1, y] +// | | +// EdgeV [x, y] => | Tile | <= EdgeV [x + 1, y] +// | [x, y] | +// | | +// Corner [x, y + 1] => +--------+ <= Corner [x + 1, y + 1] +// ^===== EdgeH [x, y + 1] + +export const HEIGHT_MIN = -600; +export const HEIGHT_MAX = 600; + +// Superflat: Just return a cavern where all the heights are 0 +function superflat(cavern: StrataformedCavern): Grid { + const result = new MutableGrid(); + for (let x = cavern.left; x <= cavern.right; x++) { + for (let y = cavern.top; y <= cavern.bottom; y++) { + result.set(x, y, 0); + } + } + return result; +} + +const collapseQueueSort = ({ range: a }: Corner, { range: b }: Corner) => b - a; + +function getRandomHeight(corner: Corner, rng: PseudorandomStream): number { + if (corner.min === corner.max) { + return corner.min; + } + const targetInRange = (() => { + if (corner.target === undefined) { + return 0.5; + } + if (corner.target <= corner.min) { + return 0; + } + if (corner.target >= corner.max) { + return 1; + } + return (corner.target - corner.min) / (corner.max - corner.min); + })(); + return rng.betaInt({ + a: 1 + 3 * targetInRange, + b: 1 + 3 * (1 - targetInRange), + min: corner.min, + max: corner.max + 1, + }); +} + +export default function strataflux( + cavern: StrataformedCavern, +): StrataformedCavern { + // If height is disabled, just return a superflat map. + if (cavern.context.heightTargetRange <= 0) { + return { ...cavern, height: superflat(cavern) }; + } + + const corners = getCorners(cavern); + const height = new MutableGrid(); + const rng = cavern.dice.height; + + // The collapse queue is a priority queue. The algorithm will always take the + // corner with the smallest possible range of values. + const collapseQueue: Corner[] = corners + .map(c => c).filter(c => c.collapseQueued); + + // Collapsing a corner means picking a specific height in range for that corner. + const collapse = () => { + const corner = collapseQueue.pop()!; + const h = getRandomHeight(corner, rng); + height.set(corner.x, corner.y, h); + corner.min = h; + corner.max = h; + corner.range = 0; + return corner; + }; + + // I think this algorithm is like O(n^4) where N is the size of the cavern, + // so try to save some performance where possible. + + while (collapseQueue.length) { + // Take a corner off the collapse queue and collapse it. + // Then, put it on the spread queue. + const spreadQueue = [collapse()]; + while (spreadQueue.length) { + // Take a corner off the spread queue. + const corner = spreadQueue.shift()!; + // Spread to each of this corner's neighbors. + for (let i = 0; i < corner.neighbors.length; i++) { + const neighbor = corner.neighbors[i]; + // If the neighbor is already collapsed, nothing to do. + if (!neighbor.corner.range) { + continue; + } + // Pull the neighbor's minimum up and maximum down to fit within the + // allowed ascent/descent slope for this edge. + neighbor.corner.min = Math.max( + neighbor.corner.min, + corner.min - neighbor.descent, + ); + neighbor.corner.max = Math.min( + neighbor.corner.max, + corner.max + neighbor.ascent, + ); + const range = neighbor.corner.max - neighbor.corner.min; + // If the neighbor's range has shrunk, + if (range < neighbor.corner.range) { + neighbor.corner.range = range; + // put it on the spread queue + spreadQueue.push(neighbor.corner); + // and put it on the collapse queue if it wasn't already. + if (!neighbor.corner.collapseQueued) { + neighbor.corner.collapseQueued = true; + collapseQueue.push(neighbor.corner); + } + } + } + } + collapseQueue.sort(collapseQueueSort); + } + + debugger + + return { ...cavern, height }; +} diff --git a/src/core/transformers/04_ephemera/02_program.ts b/src/core/transformers/04_ephemera/02_program.ts index 5c8dff1..09a3cd9 100644 --- a/src/core/transformers/04_ephemera/02_program.ts +++ b/src/core/transformers/04_ephemera/02_program.ts @@ -1,4 +1,3 @@ -import { eventChain, mkVars, scriptFragment } from "../../architects/utils/script"; import { filterTruthy } from "../../common/utils"; import { Architect } from "../../models/architect"; import { EnscribedCavern } from "./01_enscribe"; diff --git a/src/webui/App.tsx b/src/webui/App.tsx index 1671c41..76ba7d5 100644 --- a/src/webui/App.tsx +++ b/src/webui/App.tsx @@ -66,7 +66,7 @@ function App() { ); const [autoGenerate, setAutoGenerate] = useState(true); - const [mapOverlay, setMapOverlay] = useState("tiles"); + const [mapOverlay, setMapOverlay] = useState("overview"); const [showOutlines, setShowOutlines] = useState(false); const [showPearls, setShowPearls] = useState(false); @@ -191,7 +191,7 @@ function App() { diff --git a/src/webui/components/map_preview/index.tsx b/src/webui/components/map_preview/index.tsx index 08ef75d..ade4378 100644 --- a/src/webui/components/map_preview/index.tsx +++ b/src/webui/components/map_preview/index.tsx @@ -1,4 +1,4 @@ -import React, { createRef, useLayoutEffect, useState } from "react"; +import React, { createRef } from "react"; import { Cavern } from "../../../core/models/cavern"; import BaseplatePreview from "./baseplate"; import PathPreview from "./path"; @@ -31,7 +31,7 @@ function getTransform(cavern: Cavern, mapOverlay: MapOverlay) { return undefined; } const {x, y, yaw, pitch} = cavern.cameraPosition; - return `scale(5) rotate3d(1, 0, 0, ${pitch}rad) rotate(${Math.PI / -2 - yaw}rad) translate(${-x * 6}px, ${-y * 6}px)` + return `scale(6) rotate3d(1, 0, 0, ${pitch}rad) rotate(${Math.PI / -2 - yaw}rad) translate(${-x * 6}px, ${-y * 6}px)` } export default function CavernPreview({ diff --git a/src/webui/components/map_preview/tiles.tsx b/src/webui/components/map_preview/tiles.tsx index 049c3b0..fa5e2c4 100644 --- a/src/webui/components/map_preview/tiles.tsx +++ b/src/webui/components/map_preview/tiles.tsx @@ -158,6 +158,7 @@ function getTitle( case "discovery": const dz = cavern.discoveryZones?.get(x, y); return dz && `${dz.openOnSpawn ? 'Cavern' : 'Undiscovered cavern'} ${dz.id}`; + case "overview": case "tiles": return t.name; case "about":