feat(civilization): add steampunk city theme and caravan diplomacy

- Add steampunk city sheet asset configuration
- Reassign Victor and other opponents to steampunk city theme
- Enable wheel scrolling on city choices list
- Allow non-combat units (e.g., caravans) to enter enemy cities
- Block movement into enemy cities when at war
This commit is contained in:
Brian Fertig 2026-07-24 18:09:22 -06:00
parent 79c18c595e
commit ab05e2f1cd
4 changed files with 13 additions and 6 deletions

View File

@ -16,6 +16,7 @@
"citySheets": { "citySheets": {
"classic": { "key": "civilization-cities-classic", "path": "assets/images/civilization/civilization-cities-classic.png", "frameWidth": 128, "frameHeight": 96 }, "classic": { "key": "civilization-cities-classic", "path": "assets/images/civilization/civilization-cities-classic.png", "frameWidth": 128, "frameHeight": 96 },
"cyberpunk": { "key": "civilization-cities-cyberpunk", "path": "assets/images/civilization/civilization-cities-cyberpunk.png", "frameWidth": 128, "frameHeight": 96 }, "cyberpunk": { "key": "civilization-cities-cyberpunk", "path": "assets/images/civilization/civilization-cities-cyberpunk.png", "frameWidth": 128, "frameHeight": 96 },
"japanese": { "key": "civilization-cities-japanese", "path": "assets/images/civilization/civilization-cities-japanese.png", "frameWidth": 128, "frameHeight": 96 } "japanese": { "key": "civilization-cities-japanese", "path": "assets/images/civilization/civilization-cities-japanese.png", "frameWidth": 128, "frameHeight": 96 },
"steampunk": { "key": "civilization-cities-steampunk", "path": "assets/images/civilization/civilization-cities-steampunk.png", "frameWidth": 128, "frameHeight": 96 }
} }
} }

View File

@ -89,7 +89,7 @@
"name": "Victor", "name": "Victor",
"trait": "pioneering", "trait": "pioneering",
"startingTechs": [], "startingTechs": [],
"citySheet": "cyberpunk", "citySheet": "steampunk",
"bio": "Patient and calculating. Moves are made using ancient technology.", "bio": "Patient and calculating. Moves are made using ancient technology.",
"voice": "Starfield - Vasco", "voice": "Starfield - Vasco",
"convo": [ "convo": [
@ -968,7 +968,7 @@
"ceremonialburial", "ceremonialburial",
"horsebackriding" "horsebackriding"
], ],
"citySheet": "classic", "citySheet": "steampunk",
"bio": "Ahoy you land lovers!", "bio": "Ahoy you land lovers!",
"voice": "Defiant Calder", "voice": "Defiant Calder",
"convo": [ "convo": [
@ -1010,7 +1010,7 @@
"pottery", "pottery",
"thewheel" "thewheel"
], ],
"citySheet": "classic", "citySheet": "steampunk",
"bio": "Bucky Beaver and I are there to TRAP all the fun and games!", "bio": "Bucky Beaver and I are there to TRAP all the fun and games!",
"speech": { "speech": {
"intro": [ "intro": [

View File

@ -393,6 +393,11 @@ export function openCityScreen(scene, rules, state, city, onClose) {
Logic.setBuild(rules, state, city, ch.type, ch.id); Logic.setBuild(rules, state, city, ch.type, ch.id);
redraw(); redraw();
}); });
rect.on('wheel', (pointer, _dx, dy) => {
scrollY = Phaser.Math.Clamp(scrollY + dy * 0.5, 0, maxScroll);
tooltip.hide();
syncRows();
});
tooltip.attachTo(rect, () => { tooltip.attachTo(rect, () => {
if (ch.type === 'unit') return describeUnitTooltip(rules, ch.ruleObj); if (ch.type === 'unit') return describeUnitTooltip(rules, ch.ruleObj);
if (ch.type === 'building') return describeBuildingTooltip(rules, ch.ruleObj); if (ch.type === 'building') return describeBuildingTooltip(rules, ch.ruleObj);
@ -423,7 +428,7 @@ export function openCityScreen(scene, rules, state, city, onClose) {
if (thumb) thumb.y = listY + (listH - thumbH) * (scrollY / maxScroll); if (thumb) thumb.y = listY + (listH - thumbH) * (scrollY / maxScroll);
}; };
listBg.setInteractive(); listBg.setInteractive();
listBg.on('wheel', (pointer, dx, dy) => { listBg.on('wheel', (pointer, _dx, dy) => {
scrollY = Phaser.Math.Clamp(scrollY + dy * 0.5, 0, maxScroll); scrollY = Phaser.Math.Clamp(scrollY + dy * 0.5, 0, maxScroll);
// A row disabled mid-hover never fires pointerout, so its tooltip would // A row disabled mid-hover never fires pointerout, so its tooltip would
// hang around over the list. // hang around over the list.

View File

@ -916,7 +916,8 @@ export function tryMove(rules, state, unit, dx, dy) {
} }
if (!canOccupy(rules, state, unit, tx, ty)) return { result: 'invalid' }; if (!canOccupy(rules, state, unit, tx, ty)) return { result: 'invalid' };
if (targetCity && targetCity.civ !== unit.civ) return { result: 'invalid' }; if (targetCity && targetCity.civ !== unit.civ && !def.flags.includes('caravan')) return { result: 'invalid' };
if (targetCity && targetCity.civ !== unit.civ && state.civs[unit.civ].relations[targetCity.civ] === 'war') return { result: 'invalid' };
const cost = moveCost(rules, state, unit, unit.x, unit.y, tx, ty); const cost = moveCost(rules, state, unit, unit.x, unit.y, tx, ty);
if (!Number.isFinite(cost)) return { result: 'invalid' }; if (!Number.isFinite(cost)) return { result: 'invalid' };