diff --git a/src/games/civilization/CivilizationLogic.js b/src/games/civilization/CivilizationLogic.js index c5267cd..96bc088 100644 --- a/src/games/civilization/CivilizationLogic.js +++ b/src/games/civilization/CivilizationLogic.js @@ -449,13 +449,14 @@ export function foundCity(rules, state, unit, name) { size: 1, foodBox: 0, shieldBox: 0, - build: { type: 'unit', id: 'warriors' }, + build: { type: 'unit', id: 'warriors' }, // safe fallback; pickNextBuild overrides below buildings: {}, worked: [], emphasis: 'balanced', routes: [], boughtThisTurn: false, }; + pickNextBuild(rules, state, city); // best available land defender, not always warriors state.nextCityId += 1; if (civCities(state, unit.civ).length === 0) city.buildings.palace = true; // Civ II treats the city square as having a road (its main early trade). @@ -1102,7 +1103,7 @@ export function captureCity(rules, state, unit, city) { city.size = Math.max(1, city.size - 1); city.routes = []; city.shieldBox = 0; - city.build = { type: 'unit', id: 'warriors' }; + pickNextBuild(rules, state, city); // best available land defender for the new owner for (const u of state.units.filter((un) => un.homeCity === city.id)) u.homeCity = null; unit.x = city.x; unit.y = city.y; diff --git a/tools/verifyCivilization.js b/tools/verifyCivilization.js index dc690a6..8a89ff8 100644 --- a/tools/verifyCivilization.js +++ b/tools/verifyCivilization.js @@ -393,6 +393,30 @@ if (RULES) { check('capital named for leader', city.name === 'Civ0 City'); check('min distance blocks adjacent city', !Logic.canFoundCity(RULES, st, 6, 5)); check('distance 2 allowed', Logic.canFoundCity(RULES, st, 7, 5)); + check('default build is the best available defender, not always warriors', + city.build.type === 'unit' && city.build.id === 'warriors'); + } + + // Founding/capturing picks the best available land defender, not a fixed + // 'warriors' default — a civ that already knows Bronze Working should + // found (and inherit captured cities) straight onto Phalanx. + { + const st = makeFlatState({ civs: 2 }); + st.civs[0].known.bronzeworking = true; + const settler = Logic.spawnUnit(RULES, st, 0, 'settlers', 5, 5, null); + const city = Logic.foundCity(RULES, st, settler); + check('founded city with Bronze Working known defaults to Phalanx', + city.build.type === 'unit' && city.build.id === 'phalanx'); + + st.civs[1].known.bronzeworking = false; + const enemySettler = Logic.spawnUnit(RULES, st, 1, 'settlers', 9, 9, null); + const enemyCity = Logic.foundCity(RULES, st, enemySettler); + check('enemy without Bronze Working still defaults to Warriors', + enemyCity.build.type === 'unit' && enemyCity.build.id === 'warriors'); + const attacker = Logic.spawnUnit(RULES, st, 0, 'legion', enemyCity.x, enemyCity.y, null); + Logic.captureCity(RULES, st, attacker, enemyCity); + check('captured city re-defaults using the new owner\'s tech (Phalanx)', + enemyCity.build.type === 'unit' && enemyCity.build.id === 'phalanx'); } // Growth on flat grassland: foodbox fills, granary keeps half.