diff --git a/docs/AUTHORING.md b/docs/AUTHORING.md index cb8058da..73ab9017 100644 --- a/docs/AUTHORING.md +++ b/docs/AUTHORING.md @@ -296,8 +296,9 @@ export default ( ); ``` -The example pack's `window/` sources are a complete JSX project: `index.ts` lists the documents, `art.ts` declares its -art, `handles.ts` declares the shop and search handles, and `shop.tsx`, `search.tsx`, and `status_hud.tsx` use them. +The example pack's `window/` sources are a complete project: `index.ts` lists the documents, `art.ts` declares its art, +`handles.ts` declares the windows' handles, `shop.tsx`, `search.tsx`, `upgrades.tsx`, and `status_hud.tsx` use them in +JSX, and `clock_hud.ts` is a HUD written with the [`raw` API](#raw-api). ### Slot sections diff --git a/example/README.md b/example/README.md index f7cc34f8..22d6d344 100644 --- a/example/README.md +++ b/example/README.md @@ -11,23 +11,26 @@ example/ │ ├── src/ │ │ └── window/ # UI sources — stripped from the built pack │ │ ├── index.ts # defineWindows entry: the sprite catalog, windows, HUDs, and previews -│ │ ├── handles.ts # typed bindings shared by the shop and search windows -│ │ ├── art.ts # inline art: icons, coin, vents, and the search field sprite +│ │ ├── handles.ts # typed bindings shared by the windows +│ │ ├── art.ts # inline art: icons, coin, vents, bars, and the rank sprites │ │ ├── shop.tsx # paged catalog, selections, toggles, and buttons │ │ ├── search.tsx # linked native-anvil catalog search +│ │ ├── upgrades.tsx # themed workshop: styles, vars, cards with a face per stage, choices, and a hotspot │ │ ├── status_hud.tsx # the shader-relocated actionbar HUDs -│ ├── build/previews/ # preview PNGs of the shop and HUDs, rewritten by every build +│ │ └── clock_hud.ts # the clock HUD, written with the function-style raw API +│ ├── build/previews/ # preview PNGs of the windows and HUDs, rewritten by every build │ └── dist/ # build output: fonts, glyph atlas, shaders, zip └── (server lives in ../jvm/example) ``` The Minestom server is the Gradle module `jvm/example`, which depends on `window-minestom`. `Main.kt` boots the server, -`Market.kt` is a throwaway domain model, and `MyShop.kt` implements the **generated** `ShopView`. `MyStatusHud.kt` -implements the **generated** HUD views. The pack uses `target: "minestom"`, so the shop view takes the `Player` it is -shown to: `Main.kt` opens it with `MyShop(player, market).open()`. Generated HUD views take no player; the handwritten -ones that need it take it themselves. `Main.kt` joins the status HUDs into one action-bar `HudStack` and resends it with -`player.sendHud(stack)` every second, which re-renders their clocks and stays ahead of the action bar fading out. The -bindings live under `generated/`, produced by the rpp plugin — committed, do not hand-edit. +`Market.kt` and `Workshop.kt` are a throwaway domain model, and `MyShop.kt` and `MyUpgrades.kt` implement the +**generated** `ShopView` and `UpgradesView`. `MyStatusHud.kt` implements the **generated** HUD views. The pack uses +`target: "minestom"`, so a window view takes the `Player` it is shown to: `Main.kt` opens the shop with +`MyShop(player, market).open()`. Generated HUD views take no player; the handwritten ones that need it take it +themselves. `Main.kt` joins the status HUDs into one action-bar `HudStack` and resends it with `player.sendHud(stack)` +every tick, which keeps the wave bar moving smoothly, re-renders the clocks, and stays ahead of the action bar fading +out. The bindings live under `generated/`, produced by the rpp plugin — committed, do not hand-edit. ## Run it @@ -39,12 +42,27 @@ just example-run # boot the Minestom server on :25565 ``` Then connect a 26.2 client. The catalog opens on spawn with 30 real item entries, category and sort choices, -favorites/affordability toggles, paging, reactive selection and wallet text, plus buy/search/exit actions. Search opens -a static anvil screen with the native rename field and back and search buttons; searching returns to the catalog -filtered by the query, which the catalog's clear button resets and reopening search restores. +favorites/affordability toggles, paging, reactive selection and wallet text, plus buy/search/workshop/exit actions. +Search opens a static anvil screen with the native rename field and back and search buttons; searching returns to the +catalog filtered by the query, which the catalog's clear button resets and reopening search restores. + +The workshop, under its own theme, sells three upgrades for the same coins: a click on a card buys the chosen amount of +levels, each card shows its level as text and is marked new, shows a bar, or is marked maxed, and the rank badge takes +the shared tone. A maxed card takes no clicks, so hovering it shows "Fully upgraded" and no outline. Its levels last +until the server stops. The actionbar-backed HUD demo is disabled by default so the inventory examples stay visually focused. Enable it with -`-Dwindow.hud.enabled=true`; use `-Dwindow.hud.spriteDebug=true` to print each HUD's static art to chat. +`-Dwindow.hud.enabled=true`; use `-Dwindow.hud.spriteDebug=true` to print each HUD's static art to chat. The pack blanks +vanilla's experience bar, and one of the HUDs draws its wave bar there. + +| command | does | +| -------------------------------- | ---------------------------------------------------------------------- | +| `/shop` | opens the catalog, like the hotbar emerald | +| `/upgrades` | opens the workshop, like the catalog's Workshop button | +| `/tone ` | pins the tone the HUDs and newly opened windows draw in; `auto` unpins | +| `/bar ` | pins how full the wave bar and a newly opened shop's bar are | + +`rpp build` prints where the compiler's output bytes go and fails above the `size.budget` in `rpp.config.ts`. Override the port with `-Dwindow.port=…`. The server also serves `dist/window-example.zip` as a required resource pack at `http://127.0.0.1:25567/pack.zip`; override with `-Dwindow.pack=…`, `-Dwindow.pack.port=…`, or `-Dwindow.pack.url=…` @@ -54,8 +72,11 @@ when testing from another machine. The rpp plugin emits `internal` pack data (`WindowPackData`, `WindowFonts`, `WindowSpacers`, and friends), the public `WindowDefinitions` and `WindowHudDefinitions`, and one public abstract class for each window/HUD. Each handle in -`handles.ts` becomes a member of `ShopView`: `text` handles such as `balance` and `status` are functions returning a -`Component`, `flag` handles such as `canBuy` are Boolean functions, `action` handles such as `buy` are `onBuy(click)` -handlers, `products` is a `WindowCollection` that `MyShop` backs with a `WindowList`, and the `category`/`sort` -selections and `favorites`/`affordable` toggles are UI-owned `var`s with `on…Changed` hooks. `MyStatusHud` implements -each HUD's `text` handles. Omit one, rebuild, and the breakage surfaces at compile time. +`handles.ts` becomes a member of the views that use it: `text` handles such as `balance` and `status` are functions +returning a `Component`, `flag` handles such as `canBuy` are Boolean functions, `action` handles such as `buy` are +`onBuy(click)` handlers, `products` is a `WindowCollection` that `MyShop` backs with a `WindowList`, and the +`category`/`sort` selections and `favorites`/`affordable` toggles are UI-owned `var`s with `on…Changed` hooks. In +`UpgradesView` the indexed handles take the card's index (`upgradeLevel(index)`, `onUpgrade(click)` with `click.index`), +the `upgradeStage` value and the `rank` sprite return generated enums, and `upgradeProgress` and `tone` return a bar's +fraction and a tint's palette entry. `MyStatusHud` implements each HUD's handles. Omit one, rebuild, and the breakage +surfaces at compile time. diff --git a/example/pack/rpp.config.ts b/example/pack/rpp.config.ts index b1ab509a..262c3856 100644 --- a/example/pack/rpp.config.ts +++ b/example/pack/rpp.config.ts @@ -17,7 +17,8 @@ export default defineConfig({ window({ namespace: "window", coreShaders: { hud: true, hover: true }, - vanilla: { anvil: { field: "search_field" }, slotHighlight: false }, + vanilla: { anvil: { field: "search_field" }, hud: { experience: false }, slotHighlight: false }, + size: { report: true, budget: 1_000_000 }, previews: { output: "build/previews" }, kotlin: { package: "com.chunkzero.window.example.generated", diff --git a/example/pack/src/window/art.ts b/example/pack/src/window/art.ts index 97ef33cc..f538f638 100644 --- a/example/pack/src/window/art.ts +++ b/example/pack/src/window/art.ts @@ -63,6 +63,23 @@ export const budgetFill = shape({ inset_depth: 0, }); +/** The plate a maxed upgrade shows in place of its level bar. */ +export const maxedPlate = shape({ + kind: "panel", + fill: "#ffb20b", + border_color: "#8d3c03", + border_width: 1, + radius: 2, + inset_depth: 0, +}); + +/** White art for the `rank` sprite slot, which a tint colors. */ +export const ranks = { + rank_1: texture("window/icons/rank_1.png"), + rank_2: texture("window/icons/rank_2.png"), + rank_3: texture("window/icons/rank_3.png"), +}; + export const icons = { back: texture("window/icons/back.png"), clear: texture("window/icons/clear.png"), diff --git a/example/pack/src/window/clock_hud.ts b/example/pack/src/window/clock_hud.ts new file mode 100644 index 00000000..bed7a8d9 --- /dev/null +++ b/example/pack/src/window/clock_hud.ts @@ -0,0 +1,20 @@ +import { text } from "plugin:window/bind"; +import * as raw from "plugin:window/raw"; +import { art } from "plugin:window/theme/industrial"; + +export const runtime = text("runtime"); + +/** The clock, written with the function-style `raw` API; it builds the same document as a ``. */ +export default raw.hud({ + name: "status_top_center", + frame: art.hud, + shader: { origin: { x: 0.5, y: 0 }, anchor: { x: 0.5, y: 0 }, x: 0, y: 4 }, + children: [ + raw.box({ + style: { direction: "column", padding: 3 }, + children: [ + raw.text(runtime, { width: 34, align: "center", color: "#ffffff", shadow: true, small_caps: true }), + ], + }), + ], +}); diff --git a/example/pack/src/window/handles.ts b/example/pack/src/window/handles.ts index 71d4b22b..c4986abe 100644 --- a/example/pack/src/window/handles.ts +++ b/example/pack/src/window/handles.ts @@ -1,6 +1,18 @@ -import { action, collection, flag, fraction, input, selection, text, tint, toggle } from "plugin:window/bind"; +import { + action, + collection, + flag, + fraction, + input, + selection, + sprite, + text, + tint, + toggle, + value, +} from "plugin:window/bind"; -// Shared by the shop and the status HUD +// Shared by the shop, the upgrades window, and the status HUD export const tone = tint("tone", { ok: "#3ddc84", warn: "#ffb020", danger: "#ff4d4d" }); // Shop @@ -36,8 +48,26 @@ export const balance = text("balance"); export const buy = action("buy"); export const canBuy = flag("can_buy"); export const buyLabel = text("buy_label"); +export const openUpgrades = action("open_upgrades"); // Catalog search export const query = input("query"); export const back = action("back"); export const confirm = action("confirm"); + +// Upgrades; `status` and `balance` are the shop's handles +export const UPGRADES = 3; +const cards = { shape: [UPGRADES] } as const; +export const upgrade = action("upgrade", cards); +export const upgradeName = text("upgrade_name", cards); +export const upgradeLevel = text("upgrade_level", cards); +export const upgradeCost = text("upgrade_cost", cards); +/** How far each upgrade is toward its last level. */ +export const upgradeProgress = fraction("upgrade_progress", cards); +export const upgradeStage = value("upgrade_stage", ["new", "open", "maxed"], cards); + +export const amount = selection("amount", ["one", "five", "max"]); +/** The workshop's rank badge, one of the catalog sprites `index.ts` registers. */ +export const rank = sprite("rank", { only: ["rank_1", "rank_2", "rank_3"] }); +export const rankName = text("rank_name"); +export const openShop = action("open_shop"); diff --git a/example/pack/src/window/icons/rank_1.png b/example/pack/src/window/icons/rank_1.png new file mode 100644 index 00000000..d5772dba Binary files /dev/null and b/example/pack/src/window/icons/rank_1.png differ diff --git a/example/pack/src/window/icons/rank_2.png b/example/pack/src/window/icons/rank_2.png new file mode 100644 index 00000000..3bdd3232 Binary files /dev/null and b/example/pack/src/window/icons/rank_2.png differ diff --git a/example/pack/src/window/icons/rank_3.png b/example/pack/src/window/icons/rank_3.png new file mode 100644 index 00000000..253d8143 Binary files /dev/null and b/example/pack/src/window/icons/rank_3.png differ diff --git a/example/pack/src/window/index.ts b/example/pack/src/window/index.ts index 22fbd819..3e5219fb 100644 --- a/example/pack/src/window/index.ts +++ b/example/pack/src/window/index.ts @@ -1,14 +1,37 @@ import { defineWindows, preview } from "plugin:window/ui"; +import type { PreviewOptions } from "plugin:window/ui"; import { art } from "plugin:window/theme/industrial"; +import { ranks } from "./art.ts"; +import clock, { runtime } from "./clock_hud.ts"; import * as handles from "./handles.ts"; import search from "./search.tsx"; import shop from "./shop.tsx"; -import statusHuds, { coins, hint, power, rate, waveCharge } from "./status_hud.tsx"; +import statusHuds, { bottomCenter, coins, hint, power, rate, topLeft, waveBar, waveCharge } from "./status_hud.tsx"; +import upgrades from "./upgrades.tsx"; + +/** A preview of the workshop with one card in each stage. */ +const upgradesPreview = (options: PreviewOptions) => + preview( + upgrades, + [ + [handles.upgradeName, ["Drill", "Furnace", "Conveyor"]], + [handles.upgradeLevel, ["Lv 0/5", "Lv 3/5", "Lv 5/5"]], + [handles.upgradeCost, ["900", "810", ""]], + [handles.upgradeProgress, [0, 0.6, 1]], + [handles.upgradeStage, ["new", "open", "maxed"]], + [handles.amount, "five"], + [handles.balance, "2500"], + [handles.rank, "rank_2"], + [handles.rankName, "Journeyman"], + [handles.status, "8 of 15 levels"], + ], + options, + ); export default defineWindows({ - sprites: { searchField: art.inputField }, - windows: [shop, search], + sprites: { searchField: art.inputField, ...ranks }, + windows: [shop, search, upgrades], huds: statusHuds, // `rpp build` writes these to build/previews/, one PNG per preview. previews: [ @@ -29,8 +52,11 @@ export default defineWindows({ [handles.canBuy, true], [handles.buyLabel, "Buy 210"], ]), + upgradesPreview({ scale: 3 }), + // The same window with its regions outlined. + upgradesPreview({ name: "upgrades_regions", outlines: true }), preview( - statusHuds[0], + topLeft, [ [coins, "2500"], [rate, "+10"], @@ -38,23 +64,17 @@ export default defineWindows({ ], { scale: 3 }, ), - // The tinted hint and wave bar in the tint's first palette entry, then in another. - preview( - statusHuds[5], - [ - [hint, "Next wave in 4s"], - [waveCharge, 0.6], - ], - { scale: 3 }, - ), + preview(clock, [[runtime, "4:07"]], { scale: 3 }), + // The tinted hint in the tint's first palette entry, then in another. + preview(bottomCenter, [[hint, "Next wave in 4s"]], { scale: 3 }), preview( - statusHuds[5], + bottomCenter, [ [hint, "Wave incoming"], [handles.tone, "danger"], - [waveCharge, 0.97], ], { name: "status_bottom_center_danger", scale: 3 }, ), + preview(waveBar, [[waveCharge, 0.6]], { scale: 3 }), ], }); diff --git a/example/pack/src/window/shop.tsx b/example/pack/src/window/shop.tsx index f844cafb..7f2e3c63 100644 --- a/example/pack/src/window/shop.tsx +++ b/example/pack/src/window/shop.tsx @@ -32,6 +32,7 @@ import { hasQuery, next, nextLabel, + openUpgrades, page, previous, previousLabel, @@ -122,7 +123,7 @@ export default ( - sortTooltips[value]} hover={false}> + sortTooltips[value]}> {(_, i) => } @@ -152,14 +153,17 @@ export default ( - + diff --git a/example/pack/src/window/status_hud.tsx b/example/pack/src/window/status_hud.tsx index 8875fcd0..5e42f3d7 100644 --- a/example/pack/src/window/status_hud.tsx +++ b/example/pack/src/window/status_hud.tsx @@ -1,16 +1,16 @@ -import { Bar, Box, Hud, Image, Switch, Text } from "plugin:window/ui"; +import { Bar, Box, Hud, Image, Text } from "plugin:window/ui"; import type { TextProps } from "plugin:window/ui"; -import { flag, fraction, text } from "plugin:window/bind"; +import { fraction, text } from "plugin:window/bind"; import type { TextHandle } from "plugin:window/bind"; import { Row, art } from "plugin:window/theme/industrial"; import { barTrack, coin, toneFill, tonePill } from "./art.ts"; +import clock from "./clock_hud.ts"; import { tone } from "./handles.ts"; export const coins = text("coins"); export const rate = text("rate"); export const power = text("power"); -const runtime = text("runtime"); const wave = text("wave"); const biome = text("biome"); const latency = text("latency"); @@ -19,7 +19,6 @@ const altitude = text("altitude"); const objective = text("objective"); const stock = text("stock"); export const hint = text("hint"); -const waveProgress = flag("wave_progress", { shape: [10] }); /** How far the current wave's countdown has run. */ export const waveCharge = fraction("wave_charge"); @@ -41,8 +40,7 @@ function Stat(props: { label: string; bind: TextHandle; color?: string; coin?: b ); } -/** The status HUDs, one per anchor. */ -export default [ +export const topLeft = ( - , - - - - , + +); +const topRight = ( - , + +); +const leftSide = ( - , + +); +const rightSide = ( - , + +); - +export const bottomCenter = ( + - - - {Array.from({ length: 10 }, (_, i) => ( - - {{ true: , false: }} - - ))} - - , -]; + +); + +/** + * Window's own bar where vanilla draws the experience bar, which `vanilla.hud.experience` blanks: 182x5, centered, + * its top 29 px above the bottom of the GUI. + */ +export const waveBar = ( + + + +); + +/** The status HUDs, one per anchor. */ +export default [topLeft, clock, topRight, leftSide, rightSide, bottomCenter, waveBar]; diff --git a/example/pack/src/window/upgrades.tsx b/example/pack/src/window/upgrades.tsx new file mode 100644 index 00000000..b58b41b0 --- /dev/null +++ b/example/pack/src/window/upgrades.tsx @@ -0,0 +1,189 @@ +import { + Bar, + Box, + Case, + Image, + Region, + Switch, + Text, + create, + createTheme, + defineVars, + variants, +} from "plugin:window/ui"; +import type { Child } from "plugin:window/ui"; +import { + Button, + Center, + Choice, + Column, + Container, + Grid, + Hotbar, + Hotspot, + Player, + Row, + Spacer, + Window, + art, + colors, +} from "plugin:window/theme/industrial"; + +import { barTrack, coin, maxedPlate, toneFill } from "./art.ts"; +import { + UPGRADES, + amount, + balance, + openShop, + rank, + rankName, + status, + tone, + upgrade, + upgradeCost, + upgradeLevel, + upgradeName, + upgradeProgress, + upgradeStage, +} from "./handles.ts"; + +/** Industrial's colors, recolored for everything in this window. */ +const forge = createTheme(colors, { + border: "#1a0d08", + highlight: "#e8a36b", + shell: "#3a2620", + panel: "#8a4b2c", + recess: "#24140f", + slot: "#5a3220", + button: "#b3663a", + selected: "#5a2c18", +}); + +const ink = defineVars({ name: "#ffe2b8", muted: "#f2c9a0", gold: "#ffb20b", pad: 4 }); + +const s = create({ + card: { frame: art.panel, justify: "center", align: "center", gap: 3 }, + amount: variants({ + base: { text: { color: ink.name } }, + selected: { frame: art.buttonAccent, text: { color: "#2a1200", shadow: false } }, + }), + strip: { frame: art.recess, padding: ink.pad, gap: 4 }, + name: { color: ink.name, align: "center" }, + level: { color: ink.muted, align: "center" }, + muted: { color: ink.muted }, +}); + +/** What the next purchase of upgrade `index` costs. */ +function Cost(props: { index: number }) { + return ( + + + + + ); +} + +/** + * One face of upgrade `index`'s card: its name and level above `children`. `buy` makes the face take clicks, which + * also outlines it on hover; a face without it only shows its tooltip. + */ +function Face(props: { index: number; tooltip: string; buy?: boolean; children: Child }) { + const i = props.index; + return [ + , + , + + {props.children} + , + , + ]; +} + +/** An upgrade card over 3x3 slots. Each stage is its own face, so a maxed card takes no clicks. */ +function Card(props: { index: number }) { + const i = props.index; + return ( + + + + + New + + + + + +
+ +
+ +
+
+ + +
+ + Maxed + +
+
+
+
+
+ ); +} + +const amounts = { + one: { label: "x1", tooltip: "Buy one level" }, + five: { label: "x5", tooltip: "Buy five levels" }, + max: { label: "Max", tooltip: "Buy every level you can afford" }, +}; + +export default ( + + + {Array.from({ length: UPGRADES }, (_, i) => ( + + ))} + + + + {amount.values.map((value) => ( + + {amounts[value].label} + + ))} + + + + {/* It takes no clicks, so `hover` opts it into the hover outline. */} + + + + +
+ +
+ + +
+
+ + + + + + +
+); diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/HudDebug.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/HudDebug.kt index d84dc6d3..cba814c1 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/HudDebug.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/HudDebug.kt @@ -13,6 +13,7 @@ private val HUD_DEBUG_DEFINITIONS = WindowHudDefinitions.statusLeftSide, WindowHudDefinitions.statusRightSide, WindowHudDefinitions.statusBottomCenter, + WindowHudDefinitions.statusWaveBar, ) internal fun sendHudSpriteDebug(player: Player) { diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/Main.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/Main.kt index 2f0d08a0..b139f2aa 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/Main.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/Main.kt @@ -33,7 +33,8 @@ import java.nio.file.Path * jvm/gradlew -p jvm :example:run * ``` * - * Then connect a Minecraft 26.2 client and the shop opens on spawn. Reopen it with `/shop` or the hotbar emerald. + * Then connect a Minecraft 26.2 client and the shop opens on spawn. Reopen it with `/shop` or the hotbar emerald, and + * open the workshop with `/upgrades` or the shop's Workshop button. */ fun main() { val server = MinecraftServer.init() @@ -114,11 +115,14 @@ private val SHOP_ITEM by lazy { .build() } -/** Reopens the shop from `/shop` or by using the hotbar emerald handed out on first spawn. */ +/** Reopens the shop from `/shop` or by using the hotbar emerald handed out on first spawn; `/upgrades` opens the workshop. */ private fun registerShopAccess(market: Market) { val command = Command("shop") command.setDefaultExecutor { sender, _ -> (sender as? Player)?.let { openShop(it, market) } } MinecraftServer.getCommandManager().register(command) + val upgrades = Command("upgrades") + upgrades.setDefaultExecutor { sender, _ -> (sender as? Player)?.let { MyUpgrades(it, market).open() } } + MinecraftServer.getCommandManager().register(upgrades) MinecraftServer.getGlobalEventHandler().addListener(PlayerUseItemEvent::class.java) { event -> if (event.itemStack.getTag(SHOP_ITEM_TAG) == true) openShop(event.player, market) } @@ -144,8 +148,8 @@ private fun openExampleUi( } } -// The action bar fades after about 60 ticks, so the merged status line is resent every second; each send renders the -// HUDs' current clock and player values. +// The merged status line is rendered and resent every tick, so the wave bar advances smoothly and the action bar, +// which fades after about 60 ticks, never does. private fun showHuds( player: Player, huds: List, @@ -155,7 +159,7 @@ private fun showHuds( player.scheduler().submitTask { if (!player.isOnline) return@submitTask TaskSchedule.stop() player.sendHud(stack) - TaskSchedule.seconds(1) + TaskSchedule.nextTick() } } @@ -176,6 +180,7 @@ private fun createStatusHuds( MyStatusLeftSideHud(player), MyStatusRightSideHud(market), MyStatusBottomCenterHud(player, startedAt), + MyStatusWaveBarHud(player, startedAt), ) /** Locate the built resource-pack zip, or use `-Dwindow.pack=/path/to/window-example.zip`. */ diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/Market.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/Market.kt index 37f0cb87..3190ed34 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/Market.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/Market.kt @@ -4,12 +4,13 @@ import net.minestom.server.entity.Player import java.util.UUID import java.util.concurrent.ConcurrentHashMap -/** Small in-memory catalog and wallet used by the visual example. */ +/** Small in-memory catalog, wallet, and workshop used by the visual example. */ class Market( val unitPrice: Int = 10, private val startingBalance: Int = 2_500, ) { val products: List = MARKET_CATALOG + val workshop = Workshop() private val balances = ConcurrentHashMap() diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyShop.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyShop.kt index 8c99b31f..1d4571a6 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyShop.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyShop.kt @@ -100,6 +100,10 @@ class MyShop( filtersChanged() } + override fun onOpenUpgrades(click: Click) { + MyUpgrades(player, market).open() + } + override fun onBuy(click: Click) { val product = catalog.selected ?: return val newBalance = market.purchase(player, product.price) diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyStatusHud.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyStatusHud.kt index 88fe8868..9c283415 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyStatusHud.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyStatusHud.kt @@ -6,6 +6,7 @@ import com.chunkzero.window.example.generated.StatusRightSideHud import com.chunkzero.window.example.generated.StatusTopCenterHud import com.chunkzero.window.example.generated.StatusTopLeftHud import com.chunkzero.window.example.generated.StatusTopRightHud +import com.chunkzero.window.example.generated.StatusWaveBarHud import net.kyori.adventure.text.Component import net.minestom.server.entity.Player @@ -63,27 +64,35 @@ class MyStatusBottomCenterHud( private val player: Player, private val startedAt: Long, ) : StatusBottomCenterHud() { - override fun hint(): Component = Component.text("Next wave in ${(remaining() + 999) / 1000}s") - - /** Turns from ok to warn to danger as the wave nears, unless `/tone` pinned one. */ - override fun tone(): Tone { - val pinned = pinnedTone(player) - if (pinned != null) return Tone.entries.first { it.value == pinned } - val remaining = remaining() - return when { - remaining > 6_000L -> Tone.OK - remaining > 3_000L -> Tone.WARN - else -> Tone.DANGER - } - } + override fun hint(): Component = Component.text("Next wave in ${(waveRemaining(startedAt) + 999) / 1000}s") - /** Fills as the wave nears, unless `/bar` pinned a fraction. */ - override fun waveCharge(): Float = pinnedBar(player) ?: (1f - remaining().toFloat() / WAVE_MILLIS) + override fun tone(): Tone = Tone.entries.first { it.value == waveTone(player, startedAt) } +} - private fun remaining(): Long = WAVE_MILLIS - (System.currentTimeMillis() - startedAt) % WAVE_MILLIS +/** Window's bar in place of vanilla's experience bar. */ +class MyStatusWaveBarHud( + private val player: Player, + private val startedAt: Long, +) : StatusWaveBarHud() { + override fun tone(): Tone = Tone.entries.first { it.value == waveTone(player, startedAt) } - override fun waveProgress(index: Int): Boolean = - (System.currentTimeMillis() - startedAt) % WAVE_MILLIS * 10 / WAVE_MILLIS >= index + /** Fills as the wave nears, unless `/bar` pinned a fraction. */ + override fun waveCharge(): Float = pinnedBar(player) ?: (1f - waveRemaining(startedAt).toFloat() / WAVE_MILLIS) +} + +private fun waveRemaining(startedAt: Long): Long = WAVE_MILLIS - (System.currentTimeMillis() - startedAt) % WAVE_MILLIS + +/** The `tone` entry: from ok to warn to danger as the wave nears, unless `/tone` pinned one. */ +private fun waveTone( + player: Player, + startedAt: Long, +): String { + val remaining = waveRemaining(startedAt) + return pinnedTone(player) ?: when { + remaining > 6_000L -> "ok" + remaining > 3_000L -> "warn" + else -> "danger" + } } private const val WAVE_MILLIS = 10_000L diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyUpgrades.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyUpgrades.kt new file mode 100644 index 00000000..7732dfea --- /dev/null +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/MyUpgrades.kt @@ -0,0 +1,120 @@ +package com.chunkzero.window.example + +import com.chunkzero.window.Click +import com.chunkzero.window.IndexedClick +import com.chunkzero.window.example.generated.UpgradesView +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import net.minestom.server.entity.Player + +/** The workshop: upgrade cards bought with the [market]'s coins, in the amount the player chose. */ +class MyUpgrades( + player: Player, + private val market: Market, +) : UpgradesView(player) { + private var coins by state(0) + private var levels by state(market.workshop.levelsOf(player)) + private var feedback by state(null) + + override fun onOpen() { + coins = market.balanceOf(player) + } + + override fun balance(): Component = Component.text(coins) + + override fun upgradeName(index: Int): Component = Component.text(Upgrade.entries[index].title) + + override fun upgradeLevel(index: Int): Component = Component.text("Lv ${levels[index]}/${Upgrade.MAX_LEVEL}") + + override fun upgradeProgress(index: Int): Float = levels[index].toFloat() / Upgrade.MAX_LEVEL + + override fun upgradeStage(index: Int): UpgradeStage = + when (levels[index]) { + 0 -> UpgradeStage.NEW + Upgrade.MAX_LEVEL -> UpgradeStage.MAXED + else -> UpgradeStage.OPEN + } + + /** The offer's price, red while the balance does not cover it. */ + override fun upgradeCost(index: Int): Component { + val offer = offer(index) ?: return Component.empty() + return if (offer.price <= + coins + ) { + Component.text(offer.price) + } else { + Component.text(offer.price, NamedTextColor.RED) + } + } + + override fun onUpgrade(click: IndexedClick) { + val upgrade = Upgrade.entries[click.index] + val offer = offer(click.index) ?: return + val newBalance = market.purchase(player, offer.price) + if (newBalance == null) { + feedback = "Need ${offer.price - coins} more" + } else { + coins = newBalance + levels = market.workshop.raise(player, upgrade, offer.count) + feedback = "Bought ${upgrade.title} x${offer.count}" + } + } + + override fun onAmountChanged(value: Amount) { + feedback = null + } + + override fun rankSprite(): RankSprite = RankSprite.entries[rank()] + + override fun rankName(): Component = Component.text(RANKS[rank()]) + + override fun status(): Component = Component.text(feedback ?: "${levels.sum()} of $TOTAL_LEVELS levels") + + /** Whether any offer is affordable, or warn once everything is maxed, unless `/tone` pinned a tone. */ + override fun tone(): Tone { + val pinned = pinnedTone(player) + if (pinned != null) return Tone.entries.first { it.value == pinned } + val offers = Upgrade.entries.indices.mapNotNull(::offer) + return when { + offers.isEmpty() -> Tone.WARN + offers.any { it.price <= coins } -> Tone.OK + else -> Tone.DANGER + } + } + + override fun onOpenShop(click: Click) { + MyShop(player, market).open() + } + + /** One rank per [Upgrade.MAX_LEVEL] levels bought. */ + private fun rank(): Int = minOf(levels.sum() / Upgrade.MAX_LEVEL, RANKS.lastIndex) + + /** + * What a click on upgrade [index] buys, or `null` when it is maxed. `Max` buys as many levels as the balance + * covers, and prices one level when it covers none. + */ + private fun offer(index: Int): Offer? { + val upgrade = Upgrade.entries[index] + val level = levels[index] + val left = Upgrade.MAX_LEVEL - level + if (left == 0) return null + var count = + when (amount) { + Amount.ONE -> 1 + Amount.FIVE -> minOf(5, left) + Amount.MAX -> left + } + if (amount == Amount.MAX) { + while (count > 1 && upgrade.cost(level, count) > coins) count-- + } + return Offer(count, upgrade.cost(level, count)) + } + + private data class Offer( + val count: Int, + val price: Int, + ) +} + +private val RANKS = listOf("Apprentice", "Journeyman", "Master") +private val TOTAL_LEVELS = Upgrade.entries.size * Upgrade.MAX_LEVEL diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/TonePin.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/TonePin.kt index ffa2f651..b5c19001 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/TonePin.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/TonePin.kt @@ -14,7 +14,7 @@ internal fun pinnedTone(player: Player): String? = player.getTag(TONE_TAG) /** * Registers `/tone `, a debug command pinning the tone the caller's status HUD draws in - * from its next send, and the shops the caller opens afterwards; `auto` unpins it. + * from its next send, and the windows the caller opens afterwards; `auto` unpins it. */ internal fun registerToneCommand() { val tone = ArgumentType.Word("tone").from("ok", "warn", "danger", AUTO) diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/Workshop.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/Workshop.kt new file mode 100644 index 00000000..94a25aec --- /dev/null +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/Workshop.kt @@ -0,0 +1,45 @@ +package com.chunkzero.window.example + +import net.minestom.server.entity.Player +import java.util.UUID +import java.util.concurrent.ConcurrentHashMap + +/** A foundry upgrade; each level costs [baseCost] more than the one before. */ +enum class Upgrade( + val title: String, + private val baseCost: Int, +) { + DRILL("Drill", 60), + FURNACE("Furnace", 90), + CONVEYOR("Conveyor", 120), + ; + + /** What the next [count] levels above [level] cost together. */ + fun cost( + level: Int, + count: Int, + ): Int = (1..count).sumOf { baseCost * (level + it) } + + companion object { + const val MAX_LEVEL = 5 + } +} + +/** Each player's upgrade levels, kept for the server's lifetime. */ +class Workshop { + private val levels = ConcurrentHashMap>() + + /** The level of every [Upgrade], in declaration order. */ + fun levelsOf(player: Player): List = levels[player.uuid] ?: Upgrade.entries.map { 0 } + + fun raise( + player: Player, + upgrade: Upgrade, + count: Int, + ): List { + val raised = levelsOf(player).toMutableList() + raised[upgrade.ordinal] = (raised[upgrade.ordinal] + count).coerceAtMost(Upgrade.MAX_LEVEL) + levels[player.uuid] = raised + return raised + } +} diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/ShopView.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/ShopView.kt index b9dc2561..fd7ae94a 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/ShopView.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/ShopView.kt @@ -76,6 +76,9 @@ public abstract class ShopView(protected val player: Player) : WindowView(WindowDefinitions.upgrades, MinestomHost(player)) { + /** The values of `amount`. */ + public enum class Amount(public val value: String) { + ONE("one"), + FIVE("five"), + MAX("max"), + } + + /** The `amount` selection. Clicks change it, then call [onAmountChanged]. */ + protected var amount: Amount by state(Amount.ONE) + + /** Called after a click changes `amount`; assigning it does not call this. */ + protected open fun onAmountChanged(value: Amount) {} + + /** Render the `balance` text. */ + protected abstract fun balance(): Component + + /** Handle a `open_shop` click. */ + protected abstract fun onOpenShop(click: Click) + + /** The sprites `rank` shows. */ + public enum class RankSprite(public val sprite: WindowSprite) { + RANK_1(WindowSprite.RANK_1), + RANK_2(WindowSprite.RANK_2), + RANK_3(WindowSprite.RANK_3), + } + + /** Render the `rank` sprite. */ + protected abstract fun rankSprite(): RankSprite? + + /** Render the `rank_name` text. */ + protected abstract fun rankName(): Component + + /** Render the `status` text. */ + protected abstract fun status(): Component + + /** The values of `tone`. */ + public enum class Tone(public val value: String) { + OK("ok"), + WARN("warn"), + DANGER("danger"), + } + + /** The palette entry the `tone` tint draws in. */ + protected abstract fun tone(): Tone + + /** Handle a `upgrade` click; `click.index` is the clicked entry, row-major. */ + protected abstract fun onUpgrade(click: IndexedClick) + + /** Render the `upgrade_cost` text. */ + protected abstract fun upgradeCost(index: Int): Component + + /** Render the `upgrade_level` text. */ + protected abstract fun upgradeLevel(index: Int): Component + + /** Render the `upgrade_name` text. */ + protected abstract fun upgradeName(index: Int): Component + + /** How much of the `upgrade_progress` bar is filled, from 0 to 1. */ + protected abstract fun upgradeProgress(index: Int): Float + + /** The values of `upgrade_stage`. */ + public enum class UpgradeStage(public val value: String) { + NEW("new"), + OPEN("open"), + MAXED("maxed"), + } + + /** The `upgrade_stage` value. */ + protected abstract fun upgradeStage(index: Int): UpgradeStage + + final override fun WindowScope.bind() { + switch("amount?one") { (amount == Amount.ONE).toString() } + button("amount=one") { _ -> + if (amount != Amount.ONE) { + amount = Amount.ONE + onAmountChanged(amount) + } + } + button("amount=one~2") { _ -> + if (amount != Amount.ONE) { + amount = Amount.ONE + onAmountChanged(amount) + } + } + switch("amount?five") { (amount == Amount.FIVE).toString() } + button("amount=five") { _ -> + if (amount != Amount.FIVE) { + amount = Amount.FIVE + onAmountChanged(amount) + } + } + button("amount=five~2") { _ -> + if (amount != Amount.FIVE) { + amount = Amount.FIVE + onAmountChanged(amount) + } + } + switch("amount?max") { (amount == Amount.MAX).toString() } + button("amount=max") { _ -> + if (amount != Amount.MAX) { + amount = Amount.MAX + onAmountChanged(amount) + } + } + button("amount=max~2") { _ -> + if (amount != Amount.MAX) { + amount = Amount.MAX + onAmountChanged(amount) + } + } + slot("balance") { balance() } + button("open_shop", ::onOpenShop) + sprite("rank") { rankSprite()?.sprite?.id } + slot("rank_name") { rankName() } + slot("status") { status() } + tint("tone") { tone().value } + button("upgrade[0]") { click -> + onUpgrade(IndexedClick(click.slot, 0, click.shift, click.right)) + } + button("upgrade[0]~2") { click -> + onUpgrade(IndexedClick(click.slot, 0, click.shift, click.right)) + } + button("upgrade[1]") { click -> + onUpgrade(IndexedClick(click.slot, 1, click.shift, click.right)) + } + button("upgrade[1]~2") { click -> + onUpgrade(IndexedClick(click.slot, 1, click.shift, click.right)) + } + button("upgrade[2]") { click -> + onUpgrade(IndexedClick(click.slot, 2, click.shift, click.right)) + } + button("upgrade[2]~2") { click -> + onUpgrade(IndexedClick(click.slot, 2, click.shift, click.right)) + } + slot("upgrade_cost[0]") { upgradeCost(0) } + slot("upgrade_cost[0]~2") { upgradeCost(0) } + slot("upgrade_cost[1]") { upgradeCost(1) } + slot("upgrade_cost[1]~2") { upgradeCost(1) } + slot("upgrade_cost[2]") { upgradeCost(2) } + slot("upgrade_cost[2]~2") { upgradeCost(2) } + slot("upgrade_level[0]") { upgradeLevel(0) } + slot("upgrade_level[0]~2") { upgradeLevel(0) } + slot("upgrade_level[0]~3") { upgradeLevel(0) } + slot("upgrade_level[1]") { upgradeLevel(1) } + slot("upgrade_level[1]~2") { upgradeLevel(1) } + slot("upgrade_level[1]~3") { upgradeLevel(1) } + slot("upgrade_level[2]") { upgradeLevel(2) } + slot("upgrade_level[2]~2") { upgradeLevel(2) } + slot("upgrade_level[2]~3") { upgradeLevel(2) } + slot("upgrade_name[0]") { upgradeName(0) } + slot("upgrade_name[0]~2") { upgradeName(0) } + slot("upgrade_name[0]~3") { upgradeName(0) } + slot("upgrade_name[1]") { upgradeName(1) } + slot("upgrade_name[1]~2") { upgradeName(1) } + slot("upgrade_name[1]~3") { upgradeName(1) } + slot("upgrade_name[2]") { upgradeName(2) } + slot("upgrade_name[2]~2") { upgradeName(2) } + slot("upgrade_name[2]~3") { upgradeName(2) } + for (index in 0 until UPGRADE_PROGRESS_SIZE) { + bar("upgrade_progress[$index]") { upgradeProgress(index) } + } + for (index in 0 until UPGRADE_STAGE_SIZE) { + switch("upgrade_stage[$index]") { upgradeStage(index).value } + } + } + + public companion object { + /** A shape dimension of `upgrade`. */ + public const val UPGRADE_SIZE: Int = 3 + /** A shape dimension of `upgrade_cost`. */ + public const val UPGRADE_COST_SIZE: Int = 3 + /** A shape dimension of `upgrade_level`. */ + public const val UPGRADE_LEVEL_SIZE: Int = 3 + /** A shape dimension of `upgrade_name`. */ + public const val UPGRADE_NAME_SIZE: Int = 3 + /** A shape dimension of `upgrade_progress`. */ + public const val UPGRADE_PROGRESS_SIZE: Int = 3 + /** A shape dimension of `upgrade_stage`. */ + public const val UPGRADE_STAGE_SIZE: Int = 3 + } +} diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowDefinitions.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowDefinitions.kt index 16b539d7..b3233e9d 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowDefinitions.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowDefinitions.kt @@ -7,4 +7,5 @@ import com.chunkzero.window.WindowDefinition public object WindowDefinitions { public val catalogSearch: WindowDefinition = WindowDefinition(WindowPackData.manifest, "catalog_search") public val shop: WindowDefinition = WindowDefinition(WindowPackData.manifest, "shop") + public val upgrades: WindowDefinition = WindowDefinition(WindowPackData.manifest, "upgrades") } diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowEntries.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowEntries.kt index 7770b80a..b3fb0b0f 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowEntries.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowEntries.kt @@ -340,7 +340,7 @@ internal object WindowEntries { "buy_label" to SlotEntry( x = 8, y = 201, - width = 106, + width = 70, align = Align.CENTER, font = "window:small_caps/y195", color = "#2a1200", @@ -357,7 +357,7 @@ internal object WindowEntries { "buy_label~2" to SlotEntry( x = 8, y = 201, - width = 106, + width = 70, align = Align.CENTER, font = "window:small_caps/y195", color = "#2a1200", @@ -576,7 +576,24 @@ internal object WindowEntries { shaderColor = null, ), "label_6" to SlotEntry( - x = 133, + x = 86, + y = 201, + width = 40, + align = Align.CENTER, + font = "window:small_caps/y195", + color = "#ffffff", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Workshop", + shaderMarker = null, + shaderColor = null, + ), + "label_7" to SlotEntry( + x = 142, y = 201, width = 19, align = Align.CENTER, @@ -908,7 +925,7 @@ internal object WindowEntries { "buy" to RegionEntry( x = 8, y = 197, - width = 106, + width = 70, height = 16, slots = listOf( SlotRefEntry( @@ -927,14 +944,6 @@ internal object WindowEntries { area = SlotAreaEntry.PLAYER, index = 3, ), - SlotRefEntry( - area = SlotAreaEntry.PLAYER, - index = 4, - ), - SlotRefEntry( - area = SlotAreaEntry.PLAYER, - index = 5, - ), ), fillSlots = null, action = "buy", @@ -948,7 +957,7 @@ internal object WindowEntries { ), source = "region `buy`", hover = HoverEntry( - text = "\uF517\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + text = "\uED43\uDB80\uDC04\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", x = -80, y = 86, ), @@ -1366,6 +1375,42 @@ internal object WindowEntries { y = -21, ), ), + "open_upgrades" to RegionEntry( + x = 80, + y = 197, + width = 52, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 4, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 5, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 6, + ), + ), + fillSlots = null, + action = "open_upgrades", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Upgrade the foundry", + lines = emptyList(), + ), + ), + source = "region `open_upgrades`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -8, + y = 86, + ), + ), "player_section" to RegionEntry( x = 8, y = 139, @@ -1539,7 +1584,7 @@ internal object WindowEntries { "region~3" to RegionEntry( x = 8, y = 197, - width = 106, + width = 70, height = 16, slots = listOf( SlotRefEntry( @@ -1558,14 +1603,6 @@ internal object WindowEntries { area = SlotAreaEntry.PLAYER, index = 3, ), - SlotRefEntry( - area = SlotAreaEntry.PLAYER, - index = 4, - ), - SlotRefEntry( - area = SlotAreaEntry.PLAYER, - index = 5, - ), ), fillSlots = null, action = null, @@ -1641,6 +1678,11 @@ internal object WindowEntries { ), ), source = "region `sort=featured`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -80, + y = 28, + ), ), "sort=featured~2" to RegionEntry( x = 8, @@ -1672,6 +1714,11 @@ internal object WindowEntries { ), ), source = "region `sort=featured~2`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -80, + y = 28, + ), ), "sort=name" to RegionEntry( x = 116, @@ -1703,6 +1750,11 @@ internal object WindowEntries { ), ), source = "region `sort=name`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = 28, + y = 28, + ), ), "sort=name~2" to RegionEntry( x = 116, @@ -1734,6 +1786,11 @@ internal object WindowEntries { ), ), source = "region `sort=name~2`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = 28, + y = 28, + ), ), "sort=price" to RegionEntry( x = 62, @@ -1765,6 +1822,11 @@ internal object WindowEntries { ), ), source = "region `sort=price`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -26, + y = 28, + ), ), "sort=price~2" to RegionEntry( x = 62, @@ -1796,17 +1858,18 @@ internal object WindowEntries { ), ), source = "region `sort=price~2`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -26, + y = 28, + ), ), "window:close" to RegionEntry( - x = 116, + x = 134, y = 197, - width = 52, + width = 34, height = 16, slots = listOf( - SlotRefEntry( - area = SlotAreaEntry.PLAYER, - index = 6, - ), SlotRefEntry( area = SlotAreaEntry.PLAYER, index = 7, @@ -1822,8 +1885,8 @@ internal object WindowEntries { hitbox = null, source = "region `window:close`", hover = HoverEntry( - text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", - x = 28, + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = 46, y = 86, ), ), @@ -2216,7 +2279,7 @@ internal object WindowEntries { cases = listOf( SwitchCaseEntry( value = "true", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uDB80\uDC0B\uE9A2\uDB80\uDC04\uDB80\uDC08", + static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uDB80\uDC0B\uE9A1\uDB80\uDC04\uDB80\uDC08", slots = emptyList(), spriteSlots = emptyList(), regions = emptyList(), @@ -2258,7 +2321,7 @@ internal object WindowEntries { cases = listOf( SwitchCaseEntry( value = "true", - static = "\uF4F4\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + static = "\uF4F4\uDB80\uDC04\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", slots = listOf("buy_label"), spriteSlots = emptyList(), regions = listOf("buy"), @@ -2266,7 +2329,7 @@ internal object WindowEntries { ), SwitchCaseEntry( value = "false", - static = "\uE80C\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + static = "\uE80C\uDB80\uDC04\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", slots = listOf("buy_label~2"), spriteSlots = emptyList(), regions = listOf("region~3"), @@ -2639,6 +2702,1949 @@ internal object WindowEntries { LayerEntry(LayerKind.SLOT, "buy_label"), LayerEntry(LayerKind.SLOT, "buy_label~2"), LayerEntry(LayerKind.SLOT, "label_6"), + LayerEntry(LayerKind.SLOT, "label_7"), + ), + ), + "upgrades" to + WindowEntry( + surface = SurfaceEntry( + kind = "container", + container = "generic_9x3", + size = listOf(176, 168), + titleOrigin = listOf(8, 6), + ), + static = "\uDB80\uDC07\uDB80\uDC08\uF06E\uDB80\uDC03\uDB80\uDC05\uDB80\uDC07\uDB80\uDC08\uDB80\uDC0A", + slots = mapOf( + "balance" to SlotEntry( + x = 119, + y = 89, + width = 34, + align = Align.RIGHT, + font = "window:small_caps/y83", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "label_0" to SlotEntry( + x = 48, + y = 5, + width = 80, + align = Align.LEFT, + font = "window:small_caps/ym1", + color = "#ffffff", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Foundry Workshop", + shaderMarker = null, + shaderColor = null, + ), + "label_1" to SlotEntry( + x = 27, + y = 46, + width = 15, + align = Align.CENTER, + font = "window:small_caps/y40", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "New", + shaderMarker = null, + shaderColor = null, + ), + "label_10" to SlotEntry( + x = 57, + y = 89, + width = 8, + align = Align.CENTER, + font = "window:small_caps/y83", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "x5", + shaderMarker = null, + shaderColor = null, + ), + "label_11" to SlotEntry( + x = 90, + y = 89, + width = 15, + align = Align.CENTER, + font = "window:small_caps/y83", + color = "#2a1200", + shadow = false, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Max", + shaderMarker = null, + shaderColor = null, + ), + "label_12" to SlotEntry( + x = 90, + y = 89, + width = 15, + align = Align.CENTER, + font = "window:small_caps/y83", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Max", + shaderMarker = null, + shaderColor = null, + ), + "label_13" to SlotEntry( + x = 25, + y = 147, + width = 19, + align = Align.CENTER, + font = "window:small_caps/y141", + color = "#ffffff", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Shop", + shaderMarker = null, + shaderColor = null, + ), + "label_14" to SlotEntry( + x = 133, + y = 147, + width = 19, + align = Align.CENTER, + font = "window:small_caps/y141", + color = "#ffffff", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Exit", + shaderMarker = null, + shaderColor = null, + ), + "label_2" to SlotEntry( + x = 22, + y = 52, + width = 25, + align = Align.LEFT, + font = "window:small_caps/y46", + color = "#2a1200", + shadow = false, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Maxed", + shaderMarker = null, + shaderColor = null, + ), + "label_3" to SlotEntry( + x = 81, + y = 46, + width = 15, + align = Align.CENTER, + font = "window:small_caps/y40", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "New", + shaderMarker = null, + shaderColor = null, + ), + "label_4" to SlotEntry( + x = 76, + y = 52, + width = 25, + align = Align.LEFT, + font = "window:small_caps/y46", + color = "#2a1200", + shadow = false, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Maxed", + shaderMarker = null, + shaderColor = null, + ), + "label_5" to SlotEntry( + x = 135, + y = 46, + width = 15, + align = Align.CENTER, + font = "window:small_caps/y40", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "New", + shaderMarker = null, + shaderColor = null, + ), + "label_6" to SlotEntry( + x = 130, + y = 52, + width = 25, + align = Align.LEFT, + font = "window:small_caps/y46", + color = "#2a1200", + shadow = false, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "Maxed", + shaderMarker = null, + shaderColor = null, + ), + "label_7" to SlotEntry( + x = 21, + y = 89, + width = 8, + align = Align.CENTER, + font = "window:small_caps/y83", + color = "#2a1200", + shadow = false, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "x1", + shaderMarker = null, + shaderColor = null, + ), + "label_8" to SlotEntry( + x = 21, + y = 89, + width = 8, + align = Align.CENTER, + font = "window:small_caps/y83", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "x1", + shaderMarker = null, + shaderColor = null, + ), + "label_9" to SlotEntry( + x = 57, + y = 89, + width = 8, + align = Align.CENTER, + font = "window:small_caps/y83", + color = "#2a1200", + shadow = false, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = "x5", + shaderMarker = null, + shaderColor = null, + ), + "rank_name" to SlotEntry( + x = 31, + y = 110, + width = 134, + align = Align.LEFT, + font = "window:small_caps/y104", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "status" to SlotEntry( + x = 31, + y = 122, + width = 134, + align = Align.LEFT, + font = "window:small_caps/y116", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_cost[0]" to SlotEntry( + x = 11, + y = 57, + width = 36, + align = Align.RIGHT, + font = "window:small_caps/y51", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_cost[0]~2" to SlotEntry( + x = 11, + y = 57, + width = 36, + align = Align.RIGHT, + font = "window:small_caps/y51", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_cost[1]" to SlotEntry( + x = 65, + y = 57, + width = 36, + align = Align.RIGHT, + font = "window:small_caps/y51", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_cost[1]~2" to SlotEntry( + x = 65, + y = 57, + width = 36, + align = Align.RIGHT, + font = "window:small_caps/y51", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_cost[2]" to SlotEntry( + x = 119, + y = 57, + width = 36, + align = Align.RIGHT, + font = "window:small_caps/y51", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_cost[2]~2" to SlotEntry( + x = 119, + y = 57, + width = 36, + align = Align.RIGHT, + font = "window:small_caps/y51", + color = "#ffb20b", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[0]" to SlotEntry( + x = 11, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[0]~2" to SlotEntry( + x = 11, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[0]~3" to SlotEntry( + x = 11, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[1]" to SlotEntry( + x = 65, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[1]~2" to SlotEntry( + x = 65, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[1]~3" to SlotEntry( + x = 65, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[2]" to SlotEntry( + x = 119, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[2]~2" to SlotEntry( + x = 119, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_level[2]~3" to SlotEntry( + x = 119, + y = 35, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y29", + color = "#f2c9a0", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[0]" to SlotEntry( + x = 11, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[0]~2" to SlotEntry( + x = 11, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[0]~3" to SlotEntry( + x = 11, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[1]" to SlotEntry( + x = 65, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[1]~2" to SlotEntry( + x = 65, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[1]~3" to SlotEntry( + x = 65, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[2]" to SlotEntry( + x = 119, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[2]~2" to SlotEntry( + x = 119, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + "upgrade_name[2]~3" to SlotEntry( + x = 119, + y = 24, + width = 46, + align = Align.CENTER, + font = "window:small_caps/y18", + color = "#ffe2b8", + shadow = true, + bold = false, + italic = false, + underlined = false, + strikethrough = false, + obfuscated = false, + text = null, + shaderMarker = null, + shaderColor = null, + ), + ), + spriteSlots = mapOf( + "rank" to SpriteSlotEntry( + x = 15, + y = 115, + width = 9, + height = 11, + align = Align.LEFT, + font = "window:sprite_y109", + sprite = null, + only = listOf("rank_1", "rank_2", "rank_3"), + tint = "tone", + ), + ), + regions = mapOf( + "amount=five" to RegionEntry( + x = 44, + y = 85, + width = 34, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 11, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 12, + ), + ), + fillSlots = null, + action = "amount=five", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Buy five levels", + lines = emptyList(), + ), + ), + source = "region `amount=five`", + hover = HoverEntry( + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = -44, + y = 1, + ), + ), + "amount=five~2" to RegionEntry( + x = 44, + y = 85, + width = 34, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 11, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 12, + ), + ), + fillSlots = null, + action = "amount=five~2", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Buy five levels", + lines = emptyList(), + ), + ), + source = "region `amount=five~2`", + hover = HoverEntry( + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = -44, + y = 1, + ), + ), + "amount=max" to RegionEntry( + x = 80, + y = 85, + width = 34, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 13, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 14, + ), + ), + fillSlots = null, + action = "amount=max", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Buy every level you can afford", + lines = emptyList(), + ), + ), + source = "region `amount=max`", + hover = HoverEntry( + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = -8, + y = 1, + ), + ), + "amount=max~2" to RegionEntry( + x = 80, + y = 85, + width = 34, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 13, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 14, + ), + ), + fillSlots = null, + action = "amount=max~2", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Buy every level you can afford", + lines = emptyList(), + ), + ), + source = "region `amount=max~2`", + hover = HoverEntry( + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = -8, + y = 1, + ), + ), + "amount=one" to RegionEntry( + x = 8, + y = 85, + width = 34, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 9, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 10, + ), + ), + fillSlots = null, + action = "amount=one", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Buy one level", + lines = emptyList(), + ), + ), + source = "region `amount=one`", + hover = HoverEntry( + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = -80, + y = 1, + ), + ), + "amount=one~2" to RegionEntry( + x = 8, + y = 85, + width = 34, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 9, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 10, + ), + ), + fillSlots = null, + action = "amount=one~2", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Buy one level", + lines = emptyList(), + ), + ), + source = "region `amount=one~2`", + hover = HoverEntry( + text = "\uE815\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + x = -80, + y = 1, + ), + ), + "hotbar_section" to RegionEntry( + x = 8, + y = 143, + width = 160, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 3, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 4, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 5, + ), + ), + fillSlots = null, + action = null, + defaultAction = null, + hitbox = null, + source = "hotbar section", + ), + "open_shop" to RegionEntry( + x = 8, + y = 143, + width = 52, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 0, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 1, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 2, + ), + ), + fillSlots = null, + action = "open_shop", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Back to the shop", + lines = emptyList(), + ), + ), + source = "region `open_shop`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -80, + y = 59, + ), + ), + "player_section" to RegionEntry( + x = 8, + y = 85, + width = 160, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 18, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 19, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 20, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 21, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 22, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 23, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 24, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 25, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 26, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 27, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 28, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 29, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 30, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 31, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 32, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 33, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 34, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 35, + ), + ), + fillSlots = null, + action = null, + defaultAction = null, + hitbox = null, + source = "player section", + ), + "region~0" to RegionEntry( + x = 8, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 0, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 1, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 2, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 9, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 10, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 11, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 18, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 19, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 20, + ), + ), + fillSlots = null, + action = null, + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Fully upgraded", + lines = emptyList(), + ), + ), + source = "region `region~0`", + ), + "region~1" to RegionEntry( + x = 62, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 3, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 4, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 5, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 12, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 13, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 14, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 21, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 22, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 23, + ), + ), + fillSlots = null, + action = null, + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Fully upgraded", + lines = emptyList(), + ), + ), + source = "region `region~1`", + ), + "region~2" to RegionEntry( + x = 116, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 6, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 7, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 8, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 15, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 16, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 17, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 24, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 25, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 26, + ), + ), + fillSlots = null, + action = null, + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Fully upgraded", + lines = emptyList(), + ), + ), + source = "region `region~2`", + ), + "region~3" to RegionEntry( + x = 115, + y = 84, + width = 54, + height = 18, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 15, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 16, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 17, + ), + ), + fillSlots = null, + action = null, + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Balance", + lines = listOf("Coins shared with the shop"), + ), + ), + source = "region `region~3`", + hover = HoverEntry( + text = "\uE9E2\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", + x = 27, + y = 0, + ), + ), + "upgrade[0]" to RegionEntry( + x = 8, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 0, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 1, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 2, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 9, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 10, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 11, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 18, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 19, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 20, + ), + ), + fillSlots = null, + action = "upgrade[0]", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Click to upgrade", + lines = emptyList(), + ), + ), + source = "region `upgrade[0]`", + hover = HoverEntry( + text = "\uE35E\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -80, + y = -66, + ), + ), + "upgrade[0]~2" to RegionEntry( + x = 8, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 0, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 1, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 2, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 9, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 10, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 11, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 18, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 19, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 20, + ), + ), + fillSlots = null, + action = "upgrade[0]~2", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Click to upgrade", + lines = emptyList(), + ), + ), + source = "region `upgrade[0]~2`", + hover = HoverEntry( + text = "\uE35E\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -80, + y = -66, + ), + ), + "upgrade[1]" to RegionEntry( + x = 62, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 3, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 4, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 5, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 12, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 13, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 14, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 21, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 22, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 23, + ), + ), + fillSlots = null, + action = "upgrade[1]", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Click to upgrade", + lines = emptyList(), + ), + ), + source = "region `upgrade[1]`", + hover = HoverEntry( + text = "\uE35E\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -26, + y = -66, + ), + ), + "upgrade[1]~2" to RegionEntry( + x = 62, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 3, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 4, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 5, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 12, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 13, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 14, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 21, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 22, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 23, + ), + ), + fillSlots = null, + action = "upgrade[1]~2", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Click to upgrade", + lines = emptyList(), + ), + ), + source = "region `upgrade[1]~2`", + hover = HoverEntry( + text = "\uE35E\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = -26, + y = -66, + ), + ), + "upgrade[2]" to RegionEntry( + x = 116, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 6, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 7, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 8, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 15, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 16, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 17, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 24, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 25, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 26, + ), + ), + fillSlots = null, + action = "upgrade[2]", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Click to upgrade", + lines = emptyList(), + ), + ), + source = "region `upgrade[2]`", + hover = HoverEntry( + text = "\uE35E\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = 28, + y = -66, + ), + ), + "upgrade[2]~2" to RegionEntry( + x = 116, + y = 18, + width = 52, + height = 52, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 6, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 7, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 8, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 15, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 16, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 17, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 24, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 25, + ), + SlotRefEntry( + area = SlotAreaEntry.CONTAINER, + index = 26, + ), + ), + fillSlots = null, + action = "upgrade[2]~2", + defaultAction = null, + hitbox = HitboxEntry( + itemModel = null, + tooltip = TooltipEntry( + title = "Click to upgrade", + lines = emptyList(), + ), + ), + source = "region `upgrade[2]~2`", + hover = HoverEntry( + text = "\uE35E\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = 28, + y = -66, + ), + ), + "window:close" to RegionEntry( + x = 116, + y = 143, + width = 52, + height = 16, + slots = listOf( + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 6, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 7, + ), + SlotRefEntry( + area = SlotAreaEntry.PLAYER, + index = 8, + ), + ), + fillSlots = null, + action = "window:close", + defaultAction = "window:close", + hitbox = null, + source = "region `window:close`", + hover = HoverEntry( + text = "\uF3F1\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + x = 28, + y = 59, + ), + ), + ), + items = emptyMap(), + collections = emptyMap(), + inputs = emptyMap(), + switches = mapOf( + "amount?five" to SwitchEntry( + cases = listOf( + SwitchCaseEntry( + value = "true", + static = "\uDB80\uDC10\uDB80\uDC0D\uE6C8\uDB80\uDC04\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("label_9"), + spriteSlots = emptyList(), + regions = listOf("amount=five"), + switches = emptyList(), + ), + SwitchCaseEntry( + value = "false", + static = "\uDB80\uDC10\uDB80\uDC0D\uE97B\uDB80\uDC04\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("label_10"), + spriteSlots = emptyList(), + regions = listOf("amount=five~2"), + switches = emptyList(), + ), + ), + source = null, + ), + "amount?max" to SwitchEntry( + cases = listOf( + SwitchCaseEntry( + value = "true", + static = "\uDB80\uDC11\uDB80\uDC0E\uF098\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("label_11"), + spriteSlots = emptyList(), + regions = listOf("amount=max"), + switches = emptyList(), + ), + SwitchCaseEntry( + value = "false", + static = "\uDB80\uDC11\uDB80\uDC0E\uE82F\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("label_12"), + spriteSlots = emptyList(), + regions = listOf("amount=max~2"), + switches = emptyList(), + ), + ), + source = null, + ), + "amount?one" to SwitchEntry( + cases = listOf( + SwitchCaseEntry( + value = "true", + static = "\uE7B9\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("label_7"), + spriteSlots = emptyList(), + regions = listOf("amount=one"), + switches = emptyList(), + ), + SwitchCaseEntry( + value = "false", + static = "\uE2CF\uDB80\uDC05\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("label_8"), + spriteSlots = emptyList(), + regions = listOf("amount=one~2"), + switches = emptyList(), + ), + ), + source = null, + ), + "upgrade_stage[0]" to SwitchEntry( + cases = listOf( + SwitchCaseEntry( + value = "new", + static = "\uF630\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + slots = listOf("upgrade_name[0]", "upgrade_level[0]", "label_1", "upgrade_cost[0]"), + spriteSlots = emptyList(), + regions = listOf("upgrade[0]"), + switches = emptyList(), + ), + SwitchCaseEntry( + value = "open", + static = "\uEF38\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + slots = listOf("upgrade_name[0]~2", "upgrade_level[0]~2", "upgrade_cost[0]~2"), + spriteSlots = emptyList(), + regions = listOf("upgrade[0]~2"), + switches = emptyList(), + art = listOf("art/0"), + ), + SwitchCaseEntry( + value = "maxed", + static = "\uF153\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC0A", + slots = listOf("upgrade_name[0]~3", "upgrade_level[0]~3", "label_2"), + spriteSlots = emptyList(), + regions = listOf("region~0"), + switches = emptyList(), + ), + ), + source = null, + ), + "upgrade_stage[1]" to SwitchEntry( + cases = listOf( + SwitchCaseEntry( + value = "new", + static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0D\uDB80\uDC0C\uE9F4\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("upgrade_name[1]", "upgrade_level[1]", "label_3", "upgrade_cost[1]"), + spriteSlots = emptyList(), + regions = listOf("upgrade[1]"), + switches = emptyList(), + ), + SwitchCaseEntry( + value = "open", + static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0D\uDB80\uDC0C\uE41B\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("upgrade_name[1]~2", "upgrade_level[1]~2", "upgrade_cost[1]~2"), + spriteSlots = emptyList(), + regions = listOf("upgrade[1]~2"), + switches = emptyList(), + art = listOf("art/1"), + ), + SwitchCaseEntry( + value = "maxed", + static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0D\uDB80\uDC0C\uE30A\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + slots = listOf("upgrade_name[1]~3", "upgrade_level[1]~3", "label_4"), + spriteSlots = emptyList(), + regions = listOf("region~1"), + switches = emptyList(), + ), + ), + source = null, + ), + "upgrade_stage[2]" to SwitchEntry( + cases = listOf( + SwitchCaseEntry( + value = "new", + static = "\uDB80\uDC11\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0D\uE9C7\uDB80\uDC03\uDB80\uDC05\uDB80\uDC0A", + slots = listOf("upgrade_name[2]", "upgrade_level[2]", "label_5", "upgrade_cost[2]"), + spriteSlots = emptyList(), + regions = listOf("upgrade[2]"), + switches = emptyList(), + ), + SwitchCaseEntry( + value = "open", + static = "\uDB80\uDC11\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0D\uE59B\uDB80\uDC03\uDB80\uDC05\uDB80\uDC0A", + slots = listOf("upgrade_name[2]~2", "upgrade_level[2]~2", "upgrade_cost[2]~2"), + spriteSlots = emptyList(), + regions = listOf("upgrade[2]~2"), + switches = emptyList(), + art = listOf("art/2"), + ), + SwitchCaseEntry( + value = "maxed", + static = "\uDB80\uDC11\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0D\uE5AE\uDB80\uDC03\uDB80\uDC05\uDB80\uDC0A", + slots = listOf("upgrade_name[2]~3", "upgrade_level[2]~3", "label_6"), + spriteSlots = emptyList(), + regions = listOf("region~2"), + switches = emptyList(), + ), + ), + source = null, + ), + ), + art = mapOf( + "art/0" to ArtEntry( + static = "\uDB80\uDC0C\uDB80\uDC0B\uEA5C\uDB80\uDC0A\uE43C\uDB80\uDC0A\uE69D\uDB80\uDC0A\uF82F\uDB80\uDC05\uDB80\uDC06\uDB80\uDC09", + bar = BarEntry( + name = "upgrade_progress[0]", + x = 3, + width = 46, + levels = listOf("\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB\uECFB", "\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F\uF82F", "\uE69D\uE69D\uE69D\uE69D\uE69D\uE69D", "\uE43C\uE43C\uE43C", "\uF5B3", "\uEA5C"), + advances = mapOf( + "\uE43C" to 9, + "\uE69D" to 5, + "\uEA5C" to 33, + "\uECFB" to 2, + "\uF5B3" to 17, + "\uF82F" to 3, + ), + ), + ), + "art/1" to ArtEntry( + static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0B\uF70F\uDB80\uDC0A\uE63B\uDB80\uDC0A\uE0E7\uDB80\uDC0A\uEAA6\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07", + bar = BarEntry( + name = "upgrade_progress[1]", + x = 57, + width = 46, + levels = listOf("\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337\uF337", "\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6\uEAA6", "\uE0E7\uE0E7\uE0E7\uE0E7\uE0E7\uE0E7", "\uE63B\uE63B\uE63B", "\uF15E", "\uF70F"), + advances = mapOf( + "\uE0E7" to 5, + "\uE63B" to 9, + "\uEAA6" to 3, + "\uF15E" to 17, + "\uF337" to 2, + "\uF70F" to 33, + ), + ), + ), + "art/2" to ArtEntry( + static = "\uDB80\uDC11\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uDB80\uDC0B\uE81C\uDB80\uDC0A\uE8F5\uDB80\uDC0A\uEAB4\uDB80\uDC0A\uF24B\uDB80\uDC03\uDB80\uDC06\uDB80\uDC07\uDB80\uDC08\uDB80\uDC09", + bar = BarEntry( + name = "upgrade_progress[2]", + x = 111, + width = 46, + levels = listOf("\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F\uEC3F", "\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B\uF24B", "\uEAB4\uEAB4\uEAB4\uEAB4\uEAB4\uEAB4", "\uE8F5\uE8F5\uE8F5", "\uE096", "\uE81C"), + advances = mapOf( + "\uE096" to 17, + "\uE81C" to 33, + "\uE8F5" to 9, + "\uEAB4" to 5, + "\uEC3F" to 2, + "\uF24B" to 3, + ), + ), + ), + ), + tints = mapOf( + "tone" to mapOf( + "danger" to "#ff4d4d", + "ok" to "#3ddc84", + "warn" to "#ffb020", + ), + ), + layers = listOf( + LayerEntry(LayerKind.SLOT, "label_0"), + LayerEntry(LayerKind.SWITCH, "upgrade_stage[0]"), + LayerEntry(LayerKind.SLOT, "upgrade_name[0]"), + LayerEntry(LayerKind.SLOT, "upgrade_level[0]"), + LayerEntry(LayerKind.SLOT, "label_1"), + LayerEntry(LayerKind.SLOT, "upgrade_cost[0]"), + LayerEntry(LayerKind.SLOT, "upgrade_name[0]~2"), + LayerEntry(LayerKind.SLOT, "upgrade_level[0]~2"), + LayerEntry(LayerKind.ART, "art/0"), + LayerEntry(LayerKind.SLOT, "upgrade_cost[0]~2"), + LayerEntry(LayerKind.SLOT, "upgrade_name[0]~3"), + LayerEntry(LayerKind.SLOT, "upgrade_level[0]~3"), + LayerEntry(LayerKind.SLOT, "label_2"), + LayerEntry(LayerKind.SWITCH, "upgrade_stage[1]"), + LayerEntry(LayerKind.SLOT, "upgrade_name[1]"), + LayerEntry(LayerKind.SLOT, "upgrade_level[1]"), + LayerEntry(LayerKind.SLOT, "label_3"), + LayerEntry(LayerKind.SLOT, "upgrade_cost[1]"), + LayerEntry(LayerKind.SLOT, "upgrade_name[1]~2"), + LayerEntry(LayerKind.SLOT, "upgrade_level[1]~2"), + LayerEntry(LayerKind.ART, "art/1"), + LayerEntry(LayerKind.SLOT, "upgrade_cost[1]~2"), + LayerEntry(LayerKind.SLOT, "upgrade_name[1]~3"), + LayerEntry(LayerKind.SLOT, "upgrade_level[1]~3"), + LayerEntry(LayerKind.SLOT, "label_4"), + LayerEntry(LayerKind.SWITCH, "upgrade_stage[2]"), + LayerEntry(LayerKind.SLOT, "upgrade_name[2]"), + LayerEntry(LayerKind.SLOT, "upgrade_level[2]"), + LayerEntry(LayerKind.SLOT, "label_5"), + LayerEntry(LayerKind.SLOT, "upgrade_cost[2]"), + LayerEntry(LayerKind.SLOT, "upgrade_name[2]~2"), + LayerEntry(LayerKind.SLOT, "upgrade_level[2]~2"), + LayerEntry(LayerKind.ART, "art/2"), + LayerEntry(LayerKind.SLOT, "upgrade_cost[2]~2"), + LayerEntry(LayerKind.SLOT, "upgrade_name[2]~3"), + LayerEntry(LayerKind.SLOT, "upgrade_level[2]~3"), + LayerEntry(LayerKind.SLOT, "label_6"), + LayerEntry(LayerKind.SWITCH, "amount?one"), + LayerEntry(LayerKind.SLOT, "label_7"), + LayerEntry(LayerKind.SLOT, "label_8"), + LayerEntry(LayerKind.SWITCH, "amount?five"), + LayerEntry(LayerKind.SLOT, "label_9"), + LayerEntry(LayerKind.SLOT, "label_10"), + LayerEntry(LayerKind.SWITCH, "amount?max"), + LayerEntry(LayerKind.SLOT, "label_11"), + LayerEntry(LayerKind.SLOT, "label_12"), + LayerEntry(LayerKind.SLOT, "balance"), + LayerEntry(LayerKind.SPRITE_SLOT, "rank"), + LayerEntry(LayerKind.SLOT, "rank_name"), + LayerEntry(LayerKind.SLOT, "status"), + LayerEntry(LayerKind.SLOT, "label_13"), + LayerEntry(LayerKind.SLOT, "label_14"), ), ), ) diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowFonts.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowFonts.kt index 09828795..0bb5f0e3 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowFonts.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowFonts.kt @@ -824,16 +824,23 @@ internal object WindowFonts { val metrics: Map = mapOf( "minecraft:default" to vanillaMetrics, + "window:small_caps/y104" to fontMetrics0, "window:small_caps/y106" to fontMetrics0, + "window:small_caps/y116" to fontMetrics0, "window:small_caps/y137" to fontMetrics0, + "window:small_caps/y141" to fontMetrics0, "window:small_caps/y155" to fontMetrics0, "window:small_caps/y16" to fontMetrics0, "window:small_caps/y173" to fontMetrics0, "window:small_caps/y18" to fontMetrics0, - "window:small_caps/y19" to fontMetrics0, "window:small_caps/y195" to fontMetrics0, + "window:small_caps/y29" to fontMetrics0, + "window:small_caps/y40" to fontMetrics0, + "window:small_caps/y46" to fontMetrics0, + "window:small_caps/y51" to fontMetrics0, + "window:small_caps/y83" to fontMetrics0, "window:small_caps/y88" to fontMetrics0, - "window:small_caps/y9" to fontMetrics0, + "window:small_caps/y96" to fontMetrics0, "window:small_caps/ym1" to fontMetrics0, ) } diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudDefinitions.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudDefinitions.kt index f2f4c287..f83b2dc9 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudDefinitions.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudDefinitions.kt @@ -11,4 +11,5 @@ public object WindowHudDefinitions { public val statusTopCenter: HudDefinition = HudDefinition(WindowPackData.manifest, "status_top_center") public val statusTopLeft: HudDefinition = HudDefinition(WindowPackData.manifest, "status_top_left") public val statusTopRight: HudDefinition = HudDefinition(WindowPackData.manifest, "status_top_right") + public val statusWaveBar: HudDefinition = HudDefinition(WindowPackData.manifest, "status_wave_bar") } diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudEntries.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudEntries.kt index 33ba54b0..c18faa19 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudEntries.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowHudEntries.kt @@ -10,8 +10,6 @@ import com.chunkzero.window.manifest.HudSurfaceEntry import com.chunkzero.window.manifest.LayerEntry import com.chunkzero.window.manifest.LayerKind import com.chunkzero.window.manifest.SlotEntry -import com.chunkzero.window.manifest.SwitchCaseEntry -import com.chunkzero.window.manifest.SwitchEntry /** Compiled HUD entries of this Window pack. */ internal object WindowHudEntries { @@ -22,9 +20,9 @@ internal object WindowHudEntries { kind = "hud", channel = "actionbar", width = 112, - height = 20, + height = 11, ), - static = "\uDB80\uDC0D\uDB80\uDC0C\uF744\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", + static = "", slots = mapOf( "hint" to SlotEntry( x = 6, @@ -61,218 +59,6 @@ internal object WindowHudEntries { offsetY = -72, rowOffset = -3, ), - switches = mapOf( - "wave_progress[0]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uE243\uDB80\uDC05\uDB80\uDC08\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uE888\uDB80\uDC05\uDB80\uDC08\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[1]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uDB80\uDC0D\uDB80\uDC0B\uF599\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uDB80\uDC0D\uDB80\uDC0B\uEFD8\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[2]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0C\uE407\uDB80\uDC05\uDB80\uDC07\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0C\uF709\uDB80\uDC05\uDB80\uDC07\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[3]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uDB80\uDC0B\uF545\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uDB80\uDC0B\uF53C\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[4]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0D\uE0C2\uDB80\uDC05\uDB80\uDC06\uDB80\uDC07\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0D\uF0AC\uDB80\uDC05\uDB80\uDC06\uDB80\uDC07\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[5]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0B\uEF32\uDB80\uDC05\uDB80\uDC06\uDB80\uDC07\uDB80\uDC08\uDB80\uDC09", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0B\uF734\uDB80\uDC05\uDB80\uDC06\uDB80\uDC07\uDB80\uDC08\uDB80\uDC09", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[6]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uF727\uDB80\uDC04\uDB80\uDC09\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC10\uDB80\uDC0F\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0C\uE293\uDB80\uDC04\uDB80\uDC09\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[7]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC11\uDB80\uDC0C\uDB80\uDC0B\uE678\uDB80\uDC04\uDB80\uDC07", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC11\uDB80\uDC0C\uDB80\uDC0B\uF2BC\uDB80\uDC04\uDB80\uDC07", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[8]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC11\uDB80\uDC0E\uEAA7\uDB80\uDC04\uDB80\uDC07\uDB80\uDC08\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC11\uDB80\uDC0E\uE17F\uDB80\uDC04\uDB80\uDC07\uDB80\uDC08\uDB80\uDC0A", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - "wave_progress[9]" to SwitchEntry( - cases = listOf( - SwitchCaseEntry( - value = "true", - static = "\uDB80\uDC11\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0B\uE244\uDB80\uDC04\uDB80\uDC06\uDB80\uDC09", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - SwitchCaseEntry( - value = "false", - static = "\uDB80\uDC11\uDB80\uDC0E\uDB80\uDC0D\uDB80\uDC0B\uE9A1\uDB80\uDC04\uDB80\uDC06\uDB80\uDC09", - slots = emptyList(), - spriteSlots = emptyList(), - regions = emptyList(), - switches = emptyList(), - ), - ), - source = null, - ), - ), art = mapOf( "art/0" to ArtEntry( static = "\uE364\uDB80\uDC04\uDB80\uDC05\uDB80\uDC06\uDB80\uDC0A", @@ -283,30 +69,6 @@ internal object WindowHudEntries { "warn" to "#1b002a", ), ), - "art/1" to ArtEntry( - static = "\uDB80\uDC0D\uDB80\uDC0C\uF06B\uDB80\uDC0A\uF4F7\uDB80\uDC0A\uEF7E\uDB80\uDC04\uDB80\uDC05\uDB80\uDC07\uDB80\uDC09\uDB80\uDC0A", - bar = BarEntry( - name = "wave_charge", - x = 6, - width = 100, - levels = listOf("\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214\uE214", "\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068\uE068", "\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E\uEF7E", "\uEAB9\uEAB9\uEAB9\uEAB9\uEAB9\uEAB9", "\uE4BA\uE4BA\uE4BA", "\uF4F7\uF4F7", "\uF06B"), - advances = mapOf( - "\uE068" to 3, - "\uE214" to 2, - "\uE4BA" to 17, - "\uEAB9" to 9, - "\uEF7E" to 5, - "\uF06B" to 65, - "\uF4F7" to 33, - ), - ), - tint = "tone", - tintMarkers = mapOf( - "danger" to "#ff001e", - "ok" to "#ba0044", - "warn" to "#e100a0", - ), - ), ), tints = mapOf( "tone" to mapOf( @@ -318,17 +80,6 @@ internal object WindowHudEntries { layers = listOf( LayerEntry(LayerKind.ART, "art/0"), LayerEntry(LayerKind.SLOT, "hint"), - LayerEntry(LayerKind.ART, "art/1"), - LayerEntry(LayerKind.SWITCH, "wave_progress[0]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[1]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[2]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[3]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[4]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[5]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[6]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[7]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[8]"), - LayerEntry(LayerKind.SWITCH, "wave_progress[9]"), ), ), "status_left_side" to HudEntry( @@ -345,7 +96,7 @@ internal object WindowHudEntries { y = 10, width = 64, align = Align.LEFT, - font = "window:small_caps/y9", + font = "window:small_caps/y116", color = "#e0edff", shadow = true, bold = false, @@ -362,7 +113,7 @@ internal object WindowHudEntries { y = 0, width = 64, align = Align.LEFT, - font = "window:small_caps/ym1", + font = "window:small_caps/y106", color = "#ffffff", shadow = true, bold = false, @@ -384,7 +135,7 @@ internal object WindowHudEntries { anchorY = 0.5, offsetX = 4, offsetY = 0, - rowOffset = -1, + rowOffset = 106, ), layers = listOf( LayerEntry(LayerKind.SLOT, "coords"), @@ -405,7 +156,7 @@ internal object WindowHudEntries { y = 0, width = 80, align = Align.RIGHT, - font = "window:small_caps/ym1", + font = "window:small_caps/y106", color = "#ffd75e", shadow = true, bold = false, @@ -422,7 +173,7 @@ internal object WindowHudEntries { y = 10, width = 80, align = Align.RIGHT, - font = "window:small_caps/y9", + font = "window:small_caps/y116", color = "#e0edff", shadow = true, bold = false, @@ -444,7 +195,7 @@ internal object WindowHudEntries { anchorY = 0.5, offsetX = -4, offsetY = 0, - rowOffset = -1, + rowOffset = 106, ), layers = listOf( LayerEntry(LayerKind.SLOT, "objective"), @@ -507,7 +258,7 @@ internal object WindowHudEntries { y = 4, width = 26, align = Align.RIGHT, - font = "window:small_caps/ym1", + font = "window:small_caps/y96", color = "#ffd75e", shadow = true, bold = false, @@ -524,7 +275,7 @@ internal object WindowHudEntries { y = 4, width = 34, align = Align.LEFT, - font = "window:small_caps/ym1", + font = "window:small_caps/y96", color = "#8fb3d9", shadow = true, bold = false, @@ -541,7 +292,7 @@ internal object WindowHudEntries { y = 14, width = 34, align = Align.LEFT, - font = "window:small_caps/y9", + font = "window:small_caps/y106", color = "#8fb3d9", shadow = true, bold = false, @@ -558,7 +309,7 @@ internal object WindowHudEntries { y = 24, width = 34, align = Align.LEFT, - font = "window:small_caps/y19", + font = "window:small_caps/y116", color = "#8fb3d9", shadow = true, bold = false, @@ -575,7 +326,7 @@ internal object WindowHudEntries { y = 24, width = 36, align = Align.RIGHT, - font = "window:small_caps/y19", + font = "window:small_caps/y116", color = "#ffffff", shadow = true, bold = false, @@ -592,7 +343,7 @@ internal object WindowHudEntries { y = 14, width = 36, align = Align.RIGHT, - font = "window:small_caps/y9", + font = "window:small_caps/y106", color = "#80ff80", shadow = true, bold = false, @@ -614,7 +365,7 @@ internal object WindowHudEntries { anchorY = 0.0, offsetX = 4, offsetY = 4, - rowOffset = -5, + rowOffset = 92, ), layers = listOf( LayerEntry(LayerKind.SLOT, "label_0"), @@ -639,7 +390,7 @@ internal object WindowHudEntries { y = 14, width = 36, align = Align.RIGHT, - font = "window:small_caps/y9", + font = "window:small_caps/y106", color = "#ffffff", shadow = true, bold = false, @@ -656,7 +407,7 @@ internal object WindowHudEntries { y = 4, width = 34, align = Align.LEFT, - font = "window:small_caps/ym1", + font = "window:small_caps/y96", color = "#8fb3d9", shadow = true, bold = false, @@ -673,7 +424,7 @@ internal object WindowHudEntries { y = 14, width = 34, align = Align.LEFT, - font = "window:small_caps/y9", + font = "window:small_caps/y106", color = "#8fb3d9", shadow = true, bold = false, @@ -690,7 +441,7 @@ internal object WindowHudEntries { y = 24, width = 34, align = Align.LEFT, - font = "window:small_caps/y19", + font = "window:small_caps/y116", color = "#8fb3d9", shadow = true, bold = false, @@ -707,7 +458,7 @@ internal object WindowHudEntries { y = 24, width = 36, align = Align.RIGHT, - font = "window:small_caps/y19", + font = "window:small_caps/y116", color = "#ffffff", shadow = true, bold = false, @@ -724,7 +475,7 @@ internal object WindowHudEntries { y = 4, width = 36, align = Align.RIGHT, - font = "window:small_caps/ym1", + font = "window:small_caps/y96", color = "#ffffff", shadow = true, bold = false, @@ -746,7 +497,7 @@ internal object WindowHudEntries { anchorY = 0.0, offsetX = -4, offsetY = 4, - rowOffset = -5, + rowOffset = 92, ), layers = listOf( LayerEntry(LayerKind.SLOT, "label_0"), @@ -757,5 +508,62 @@ internal object WindowHudEntries { LayerEntry(LayerKind.SLOT, "latency"), ), ), + "status_wave_bar" to HudEntry( + surface = HudSurfaceEntry( + kind = "hud", + channel = "actionbar", + width = 182, + height = 5, + ), + static = "\uF050\uDB80\uDC03\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", + slots = emptyMap(), + shader = HudShaderEntry( + staticMarker = "#9300e1", + sourceBottom = 59, + originX = 0.5, + originY = 1.0, + anchorX = 0.5, + anchorY = 1.0, + offsetX = 0, + offsetY = -24, + ), + art = mapOf( + "art/0" to ArtEntry( + static = "\uEF4C\uDB80\uDC0A\uF08E\uDB80\uDC0A\uEBA4\uDB80\uDC0A\uEECC\uDB80\uDC0A\uF37E\uDB80\uDC03\uDB80\uDC05\uDB80\uDC06\uDB80\uDC08\uDB80\uDC09\uDB80\uDC0A", + bar = BarEntry( + name = "wave_charge", + x = 0, + width = 182, + levels = listOf("\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D\uF39D", "\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E\uF37E", "\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC\uEECC", "\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0\uE4C0", "\uEBA4\uEBA4\uEBA4\uEBA4\uEBA4\uEBA4", "\uF08E\uF08E\uF08E", "\uF4C6", "\uEF4C"), + advances = mapOf( + "\uE4C0" to 9, + "\uEBA4" to 17, + "\uEECC" to 5, + "\uEF4C" to 129, + "\uF08E" to 33, + "\uF37E" to 3, + "\uF39D" to 2, + "\uF4C6" to 65, + ), + ), + tint = "tone", + tintMarkers = mapOf( + "danger" to "#85007a", + "ok" to "#a1009c", + "warn" to "#9400b2", + ), + ), + ), + tints = mapOf( + "tone" to mapOf( + "danger" to "#ff4d4d", + "ok" to "#3ddc84", + "warn" to "#ffb020", + ), + ), + layers = listOf( + LayerEntry(LayerKind.ART, "art/0"), + ), + ), ) } diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprite.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprite.kt index 5a58bf61..3e92622c 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprite.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprite.kt @@ -3,5 +3,8 @@ package com.chunkzero.window.example.generated /** Runtime sprites of this Window pack, returned by sprite slot members. */ public enum class WindowSprite(public val id: String) { + RANK_1("rank_1"), + RANK_2("rank_2"), + RANK_3("rank_3"), SEARCH_FIELD("search_field"), } diff --git a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprites.kt b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprites.kt index b258df6b..bfa78b9d 100644 --- a/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprites.kt +++ b/jvm/example/src/main/kotlin/com/chunkzero/window/example/generated/WindowSprites.kt @@ -15,6 +15,30 @@ internal object WindowSprites { advance = 19, glyph = "\uE409", ), + "rank_1" to SpriteEntry( + width = 9, + height = 11, + xOffset = 0, + glyphWidth = 9, + advance = 10, + glyph = "\uF1CB", + ), + "rank_2" to SpriteEntry( + width = 9, + height = 11, + xOffset = 0, + glyphWidth = 9, + advance = 10, + glyph = "\uE878", + ), + "rank_3" to SpriteEntry( + width = 9, + height = 11, + xOffset = 0, + glyphWidth = 9, + advance = 10, + glyph = "\uF7F5", + ), "search_field" to SpriteEntry( width = 110, height = 16,