Updates to research display
This commit is contained in:
parent
02b14b88c8
commit
8b5aa6064a
|
|
@ -1236,8 +1236,18 @@ export default class CivilizationGame extends Phaser.Scene {
|
|||
const civ = this.state.civs[human];
|
||||
if (!civ.alive) { this.onGameOver(); return; }
|
||||
|
||||
// Research prompt.
|
||||
if (!civ.researching && Logic.availableTechs(this.rules, civ).length) {
|
||||
// Research: announce the completed discovery FIRST, open the picker as
|
||||
// that popup is dismissed (onDismiss replaces the queue-resume; the tech
|
||||
// screen's close handler resumes it), and let everything else queue up
|
||||
// behind. Without a completion event (fresh game, resumed save) the
|
||||
// picker still opens directly.
|
||||
const techEvent = this.state.events.find((e) => e.type === 'techDone' && e.civ === human && !e.announced);
|
||||
const needsPick = !civ.researching && Logic.availableTechs(this.rules, civ).length > 0;
|
||||
if (techEvent) {
|
||||
techEvent.announced = true;
|
||||
this.announceStatus(`Research complete: ${this.rules.techs[techEvent.tech].name}`,
|
||||
needsPick ? () => this.openTech() : undefined);
|
||||
} else if (needsPick) {
|
||||
this.openTech();
|
||||
}
|
||||
this.presentAIProposals();
|
||||
|
|
@ -1283,20 +1293,26 @@ export default class CivilizationGame extends Phaser.Scene {
|
|||
// "resolve now, animate after" trick as the player's own moves, just
|
||||
// via a before/after snapshot instead of a waypoint path.
|
||||
const combatEvents = this.collectNewCombatEvents();
|
||||
// Combats against any city the human has explored — their own or a
|
||||
// rival's — are always deferred to a dedicated cinematic (camera pan +
|
||||
// replay + outcome popup) played at the start of the human's next
|
||||
// turn, rather than silently replayed here (possibly off-screen) like
|
||||
// ordinary field battles. City tiles stay marked once explored (see
|
||||
// MapView.refresh()'s `explored[idx]` check), so this reaches a known
|
||||
// rival city even if it's currently outside the fog-of-war vision set.
|
||||
// Combats against the HUMAN's cities are deferred to a dedicated
|
||||
// cinematic (camera pan + replay + outcome popup) at the start of the
|
||||
// human's next turn — those demand a response. Rival-vs-rival battles
|
||||
// at cities the human has explored play live right here instead: pan,
|
||||
// replay, and a status-log line, no blocking popup. City tiles stay
|
||||
// marked once explored (see MapView.refresh()'s `explored[idx]`
|
||||
// check), so this reaches a known rival city even if it's currently
|
||||
// outside the fog-of-war vision set. `e.defenderCiv === human` catches
|
||||
// a city the human just lost this step (city.civ already shows the
|
||||
// conqueror by the time we classify).
|
||||
const human = this.state.humanIndex;
|
||||
const elsewhere = [];
|
||||
const rivalCityCombats = [];
|
||||
for (const e of combatEvents) {
|
||||
const city = Logic.cityAt(this.state, e.x, e.y);
|
||||
const cityExplored = city && this.state.explored[human][Logic.tileIndex(this.state.world, city.x, city.y)];
|
||||
if (city && (city.civ === human || cityExplored)) {
|
||||
if (city && (city.civ === human || e.defenderCiv === human)) {
|
||||
this.pendingCityAttacks.push({ e, cityId: city.id, cityName: city.name, x: city.x, y: city.y });
|
||||
} else if (city && cityExplored) {
|
||||
rivalCityCombats.push({ e, city });
|
||||
} else {
|
||||
elsewhere.push(e);
|
||||
}
|
||||
|
|
@ -1318,8 +1334,25 @@ export default class CivilizationGame extends Phaser.Scene {
|
|||
this.time.delayedCall(90, stepCiv);
|
||||
});
|
||||
};
|
||||
if (visibleCombat.length) this.view.animateCombat(visibleCombat, afterCombat);
|
||||
else afterCombat();
|
||||
// Rival-vs-rival city battles first (pan + replay + log line, one at a
|
||||
// time), then ordinary visible field combats, then the move glide.
|
||||
const playRivalCityCombats = (done) => {
|
||||
const item = rivalCityCombats.shift();
|
||||
if (!item) { done(); return; }
|
||||
const { e, city } = item;
|
||||
const attackerName = this.state.civs[e.attackerCiv]?.name ?? 'An enemy';
|
||||
const captured = e.attackerWon && city.civ === e.attackerCiv;
|
||||
const outcome = captured ? `${city.name} has fallen to ${attackerName}!`
|
||||
: e.attackerWon ? `${city.name}'s defenders were defeated!`
|
||||
: `${city.name} held its ground!`;
|
||||
this.logMessage(`${attackerName} attacked ${city.name} — ${outcome}`);
|
||||
this.view.panToTile(city.x, city.y);
|
||||
this.view.animateCombat([e], () => playRivalCityCombats(done));
|
||||
};
|
||||
playRivalCityCombats(() => {
|
||||
if (visibleCombat.length) this.view.animateCombat(visibleCombat, afterCombat);
|
||||
else afterCombat();
|
||||
});
|
||||
};
|
||||
stepCiv();
|
||||
}
|
||||
|
|
@ -1342,10 +1375,10 @@ export default class CivilizationGame extends Phaser.Scene {
|
|||
}
|
||||
}
|
||||
|
||||
// Combats against any city the human has explored (their own or a
|
||||
// rival's), deferred from runToHumanTurn()'s per-civ stepping (see
|
||||
// stepCiv there) so they always get a camera pan + replay + outcome popup
|
||||
// instead of possibly playing silently off-screen.
|
||||
// Combats against the human's own cities, deferred from runToHumanTurn()'s
|
||||
// per-civ stepping (see stepCiv there) so they always get a camera pan +
|
||||
// replay + outcome popup at the start of the human's turn. Rival-vs-rival
|
||||
// city battles play live during the AI phase instead.
|
||||
announceCityAttacks() {
|
||||
const attacks = this.pendingCityAttacks;
|
||||
this.pendingCityAttacks = [];
|
||||
|
|
@ -1504,6 +1537,11 @@ export default class CivilizationGame extends Phaser.Scene {
|
|||
openTechScreen(this, this.rules, this.state, () => {
|
||||
this.modalOpen = false;
|
||||
this.refreshHud();
|
||||
// Resume any statuses that queued while the tech screen was up — in
|
||||
// particular the start-of-turn flow, where the research-complete
|
||||
// popup's onDismiss opens this screen with the rest of the turn's
|
||||
// announcements still waiting in the queue.
|
||||
this.showNextStatus();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue