feat(mastervega): add allocation icons and tooltips to colony sliders
- Replace □/■ glyphs with channel-specific icons inside the lock toggle boxes - Introduce `allocation.png` (5 frames) and register it in the artwork config - Add hover tooltips explaining each channel's production role and MOO1-style overflow behavior - Expose slider `zone` for tooltip attachment and adjust icon/layout positioning - Update sprite documentation and include minor audio asset update
This commit is contained in:
parent
44868e5032
commit
c84b668553
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
Binary file not shown.
|
|
@ -317,6 +317,16 @@
|
|||
"cols": 10,
|
||||
"rows": 10,
|
||||
"_layout": "One frame per individual tech (techs[].iconFrame), 0-90 — the 60 original techs plus two MOO1-branching passes added later, in rules order. Split out of the combined tech sheet so field icons and tech icons can be painted/sized independently. 91-99 spare."
|
||||
},
|
||||
"allocation": {
|
||||
"key": "vega-allocation",
|
||||
"path": "assets/images/vega/allocation.png",
|
||||
"kind": "icon",
|
||||
"frameWidth": 48,
|
||||
"frameHeight": 48,
|
||||
"cols": 5,
|
||||
"rows": 1,
|
||||
"_layout": "One frame per allocation channel, in CHANNELS order (VegaLogic.js): 0 ships (Construction), 1 defense (Defence), 2 industry (Industry), 3 ecology (Ecology), 4 research (Research). Shown beside each slider label on the colony screen (VegaColonyView.js)."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import { createShipMediaPool, makeShipIcon } from './VegaShipMedia.js';
|
|||
import { openShipDetail } from './VegaShipDetail.js';
|
||||
import { openLeaderDetail } from './VegaLeaderDetail.js';
|
||||
import { leaderOf } from './VegaLeaders.js';
|
||||
import { describeBuildingTooltip, describeLeaderTooltip } from './VegaTooltips.js';
|
||||
import { describeBuildingTooltip, describeLeaderTooltip, describeAllocationTooltip } from './VegaTooltips.js';
|
||||
import {
|
||||
CHANNELS, colonyMaxPop, colonyProduction, colonyFactoryCap, effectiveFactories,
|
||||
colonyDefenseCap, colonyTrade, colonyBuildRate, setSlider, enqueue, enqueueMany,
|
||||
|
|
@ -432,11 +432,18 @@ export function openColonyView(scene, rules, state, colony, art, opts = {}) {
|
|||
// renormalise (its `others.length === 0` early return), freezing the
|
||||
// allocation with no way back out. So the last one open cannot be shut.
|
||||
const lockable = locked || lockedCount < CHANNELS.length - 1;
|
||||
const box = add(scene.add.rectangle(x + 11, y + 28, 22, 22,
|
||||
locked ? 0x2a3550 : 0x16253c).setStrokeStyle(1, ACCENT, lockable ? 0.55 : 0.18));
|
||||
add(scene.add.text(x + 11, y + 27, locked ? '■' : '□', {
|
||||
fontFamily: FONT, fontSize: '15px', color: locked ? '#ffd88a' : (lockable ? '#8fa8c0' : '#3c4c60'),
|
||||
}).setOrigin(0.5));
|
||||
// The box itself is the lock toggle — its fill/border shows locked
|
||||
// state, and the channel's icon sits inside it (in place of the old
|
||||
// □/■ glyph) instead of getting its own separate column. Centred at
|
||||
// y+19: the midpoint between the slider's label (top, ~y+10) and its
|
||||
// track (y+28), so the icon reads as belonging to both.
|
||||
const boxCx = x + 17;
|
||||
const boxCy = y + 19;
|
||||
const box = add(scene.add.rectangle(boxCx, boxCy, 34, 34,
|
||||
locked ? 0x2a3550 : 0x16253c)
|
||||
.setStrokeStyle(locked ? 3 : 2, CHANNEL_COLOUR[ch], lockable ? 0.85 : 0.18));
|
||||
add(scene.add.image(boxCx, boxCy, art.allocation, i).setDisplaySize(26, 26)
|
||||
.setTint(locked ? 0xffd88a : (lockable ? 0xe8f4ff : 0x445566)));
|
||||
if (lockable) {
|
||||
box.setInteractive({ useHandCursor: true });
|
||||
box.on('pointerup', () => {
|
||||
|
|
@ -446,7 +453,7 @@ export function openColonyView(scene, rules, state, colony, art, opts = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
const s = slider(scene, x + 34, y, w - 34,
|
||||
const s = slider(scene, x + 42, y, w - 42,
|
||||
rules.economy.channelNames[ch] ?? ch, colony.sliders[ch] ?? 0, (v) => {
|
||||
setSlider(rules, state, colony, ch, v);
|
||||
// setSlider renormalises everything else, so they all have to be
|
||||
|
|
@ -463,6 +470,7 @@ export function openColonyView(scene, rules, state, colony, art, opts = {}) {
|
|||
onChanged?.();
|
||||
}, CHANNEL_COLOUR[ch]);
|
||||
panelLayer.add(s.container);
|
||||
tooltip.attachTo(s.zone, () => describeAllocationTooltip(rules, state, colony, ch));
|
||||
sliders.push(s);
|
||||
y += 56;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ export function slider(scene, x, y, w, label, value, onChange, colour = ACCENT)
|
|||
|
||||
return {
|
||||
container: c,
|
||||
zone, // exposed so callers can tooltip.attachTo(s.zone, ...)
|
||||
setValue(v) {
|
||||
fill.width = w * v;
|
||||
knob.x = w * v;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@
|
|||
// component; these functions only build the {title, lines} content it wants.
|
||||
|
||||
import { COLORS } from '../../config.js';
|
||||
import { coloniesAt, habitableForEmpire } from './VegaLogic.js';
|
||||
import {
|
||||
coloniesAt, habitableForEmpire, colonyProduction, colonyFactoryCap,
|
||||
effectiveFactories, colonyDefenseCap,
|
||||
} from './VegaLogic.js';
|
||||
import { techCost, techCostFactor } from './VegaRules.js';
|
||||
import { leaderSkillSummary } from './VegaLeaders.js';
|
||||
|
||||
|
|
@ -109,6 +112,49 @@ export function describeBuildingTooltip(rules, buildingId) {
|
|||
};
|
||||
}
|
||||
|
||||
// Hover tooltip for one of the colony screen's five allocation sliders
|
||||
// (VegaColonyView.js). Explains what that channel spends its share of
|
||||
// production on and what the MOO1-style spillover (VegaLogic.js's
|
||||
// processColony) does with any of it the channel can't use.
|
||||
export function describeAllocationTooltip(rules, state, colony, ch) {
|
||||
const label = rules.economy.channelNames[ch] ?? ch;
|
||||
const prod = colonyProduction(rules, state, colony);
|
||||
const share = prod * (colony.sliders[ch] ?? 0);
|
||||
const lines = [{ text: `${share.toFixed(1)} BC/turn from this channel`, color: COLORS.goldHex }];
|
||||
|
||||
switch (ch) {
|
||||
case 'ships':
|
||||
lines.push({ text: 'Pays for whatever is at the front of the build queue — ships and buildings, in order.' });
|
||||
lines.push({ text: 'Once the queue is empty, this overflows into Research instead of going to waste.', color: COLORS.mutedHex });
|
||||
break;
|
||||
case 'defense': {
|
||||
const cap = colonyDefenseCap(rules, state, colony);
|
||||
lines.push({ text: `Raises planetary defences (${Math.round(colony.defenseHp)} / ${cap}), capped by your defence tech.` });
|
||||
lines.push({ text: 'Once defences are maxed, this overflows into Construction instead of going to waste.', color: COLORS.mutedHex });
|
||||
break;
|
||||
}
|
||||
case 'industry': {
|
||||
const cap = colonyFactoryCap(rules, state, colony);
|
||||
const effF = effectiveFactories(rules, state, colony);
|
||||
lines.push({ text: `Builds factories (${Math.floor(effF)} / ${cap} staffed), which raise this colony's production every turn.` });
|
||||
lines.push({ text: 'Once factories are maxed, this overflows into Construction instead of going to waste.', color: COLORS.mutedHex });
|
||||
break;
|
||||
}
|
||||
case 'ecology':
|
||||
lines.push({ text: `Cleans industrial waste (backlog ${colony.waste.toFixed(1)}), which otherwise caps this colony's population.` });
|
||||
lines.push({ text: 'Mandatory — a shortfall is drawn from the other four channels automatically. Any surplus overflows into Research.', color: COLORS.mutedHex });
|
||||
break;
|
||||
case 'research':
|
||||
lines.push({ text: "Funds tech research toward your empire's research queue." });
|
||||
lines.push({ text: 'Also absorbs unused overflow from Ecology and Construction, so it is rarely wasted.', color: COLORS.mutedHex });
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return { title: label, titleColor: COLORS.goldHex, lines };
|
||||
}
|
||||
|
||||
// Hover tooltip for a colony's posted administrator, shown beside the
|
||||
// building icon row. `leader` is the rules leader def (name/bio/skills).
|
||||
export function describeLeaderTooltip(leader) {
|
||||
|
|
|
|||
|
|
@ -333,8 +333,53 @@ story page.
|
|||
|
||||
## 8. Menu icon — ✅ `assets/images/game-icons.png` frame **92**
|
||||
|
||||
The shared 660 × 660 sheet, 44 × 44 cells, 15 per row. Frame 92 is row 6,
|
||||
column 2 → pixel origin **(88, 264)**. **Painted.**
|
||||
Not part of any Vega sheet — this is the small tile icon shown for *Master of
|
||||
Vega* on the main game-selection screen's `arcade-console-pc` category list,
|
||||
i.e. outside the game itself, the thing you click to launch it. The sheet is
|
||||
shared by **every game in the app**, one frame each, claimed via `iconFrame`
|
||||
in `src/data/gamesRegistry.js` (`registerGame({ slug: 'mastervega', ...,
|
||||
iconFrame: 92 })`). Editing frame 92 only touches Vega's tile; the sheet
|
||||
itself is common infrastructure, not Vega's to redesign.
|
||||
|
||||
660 × 660 total, 44 × 44 cells, 15 per row. Frame 92 is row 6, column 2 →
|
||||
pixel origin **(88, 264)**. **Painted — nothing to do here.**
|
||||
|
||||
---
|
||||
|
||||
## 9. `allocation` — ✅ `assets/images/vega/allocation.png`
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Sheet size | **240 × 48** |
|
||||
| Frame | **48 × 48** |
|
||||
| Grid | 5 cols × 1 row = 5 frames |
|
||||
|
||||
One frame per allocation channel, in `CHANNELS` order (`VegaLogic.js`) — the
|
||||
same five sliders on the colony screen (`VegaColonyView.js`), each of which
|
||||
also carries a hover tooltip explaining what it does
|
||||
(`describeAllocationTooltip` in `VegaTooltips.js`):
|
||||
|
||||
| Frame | Channel id | UI label | Icon idea |
|
||||
|---|---|---|---|
|
||||
| 0 | `ships` | Construction | Shipyard gantry or a hull under construction — feeds the build queue |
|
||||
| 1 | `defense` | Defence | Shield or planetary turret — raises defence batteries |
|
||||
| 2 | `industry` | Industry | Factory or gear — builds factories |
|
||||
| 3 | `ecology` | Ecology | Leaf or recycling arrows — cleans waste |
|
||||
| 4 | `research` | Research | Flask or atom — funds tech |
|
||||
|
||||
Shown at 26px, inside each slider's 34px lock toggle box — replacing the old
|
||||
□/■ text glyph, not sitting in a separate column. The box sits vertically
|
||||
centred between the slider's label and its track, so the icon reads as
|
||||
belonging to both. Tinted gold when that channel is locked, near-white when
|
||||
unlockable, and dim grey on the one channel that can't be locked (the last
|
||||
one open); the box's stroke is that channel's own bar colour
|
||||
(`CHANNEL_COLOUR` in `VegaColonyView.js` — e.g. Construction blue, Defence
|
||||
red), thicker when locked. Declared in `data/mastervega-artwork.json`'s
|
||||
`sheets.allocation` (`"kind": "icon"`, same pattern as
|
||||
`buildings`/`techfields`); drawn by `VegaColonyView.js`'s slider loop as
|
||||
`art.allocation` frame `i` (the same index the loop already walks `CHANNELS`
|
||||
with), on top of the same rectangle that already handles the lock/unlock
|
||||
click.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue