mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 14:00:54 +00:00
add player death & quotes when win or lose
This commit is contained in:
@@ -75,7 +75,7 @@ export async function createClientGame(lobbyConfig: LobbyConfig, gameConfig: Gam
|
||||
const gameMap = await loadTerrainMap(gameConfig.gameMap);
|
||||
const worker = new WorkerClient(lobbyConfig.gameID, gameConfig)
|
||||
await worker.initialize()
|
||||
const gameView = new GameView(worker, config, gameMap.gameMap)
|
||||
const gameView = new GameView(worker, config, gameMap.gameMap, lobbyConfig.clientID)
|
||||
|
||||
|
||||
consolex.log('going to init path finder')
|
||||
|
||||
@@ -80,7 +80,6 @@ export function createRenderer(canvas: HTMLCanvasElement, game: GameView, eventB
|
||||
if (!(playerInfo instanceof WinModal)) {
|
||||
console.error('win modal not found')
|
||||
}
|
||||
winModel.clientID = clientID
|
||||
winModel.game = game
|
||||
|
||||
|
||||
|
||||
@@ -5,16 +5,160 @@ import { ClientID } from '../../../core/Schemas';
|
||||
import { GameView, PlayerView } from '../../../core/game/GameView';
|
||||
import { Layer } from './Layer';
|
||||
import { GameUpdateType } from '../../../core/game/GameUpdates';
|
||||
import { PseudoRandom } from '../../../core/PseudoRandom';
|
||||
import { simpleHash } from '../../../core/Util';
|
||||
|
||||
|
||||
const lowRadiationVictoryQuotes = [
|
||||
"Victory is mine. The world endures - under new management.",
|
||||
"They thought they could stop me. Now they serve me.",
|
||||
"The old order has fallen. My reign begins.",
|
||||
"Not every victory requires destruction.",
|
||||
"From this day forward, all will know who rules.",
|
||||
"The war is over. Long live the victor.",
|
||||
"A new empire rises - with me at its helm.",
|
||||
"The throne is claimed. The crown is mine.",
|
||||
"Today marks the beginning of my dynasty.",
|
||||
"They feared my wrath. Now they'll know my rule.",
|
||||
"Victory was inevitable. Surrender was optional.",
|
||||
"A new era dawns - under my command.",
|
||||
"The pieces are in place. The victory is complete.",
|
||||
"Let history remember who conquered all.",
|
||||
"Their resistance only delayed the inevitable.",
|
||||
"Power shifts. Empires fall. I remain.",
|
||||
"The world has a new master now.",
|
||||
"Their armies fell. Their nations surrendered. I prevailed.",
|
||||
"All paths led to this victory.",
|
||||
"The world bows to its new ruler.",
|
||||
"From the ashes of their defeat, my victory rises.",
|
||||
"Destiny called. I answered. The world followed.",
|
||||
"They called me tyrant. Now they call me emperor.",
|
||||
"The old powers have fallen. Mine endures.",
|
||||
"Every empire needs a beginning. This is mine.",
|
||||
"Their defiance crumbled before my ambition.",
|
||||
"No more rebels. No more resistance. Only order.",
|
||||
"The final piece falls into place.",
|
||||
"Let them write of this day in their histories.",
|
||||
"My vision becomes reality.",
|
||||
"Their surrender was wise. My victory was certain.",
|
||||
"The wheels of fate turn in my favor.",
|
||||
"A new chapter begins - written by the victor.",
|
||||
"They fought the inevitable. The inevitable won.",
|
||||
"All that was theirs is now mine.",
|
||||
"The gods themselves bow before my triumph.",
|
||||
"Their kingdoms shatter. My empire rises.",
|
||||
"Victory tastes sweeter than wine.",
|
||||
"The crown suits me well, don't you think?",
|
||||
"Behold the dawn of my eternal reign."
|
||||
];
|
||||
|
||||
const highRadiationVictoryQuotes = [
|
||||
"Let the world burn. I just want to rule the ashes.",
|
||||
"The old world died screaming. My new one rises from its bones.",
|
||||
"They could have surrendered. Now they glow.",
|
||||
"Everything burns. The throne of ashes awaits.",
|
||||
"A wasteland needs a king. I have answered the call.",
|
||||
"Their cities turned to glass. My victory endures.",
|
||||
"Who needs a pristine world when you can rule its ruins?",
|
||||
"They feared the fire. I embraced it.",
|
||||
"The radiation clears the way for my reign.",
|
||||
"A dead world makes for quiet subjects.",
|
||||
"From atomic fire, my kingdom rises.",
|
||||
"Nothing left but ashes and victory.",
|
||||
"They wanted war. I gave them annihilation.",
|
||||
"The world burns green. My empire glows eternal.",
|
||||
"All thrones are built on ashes. Mine just glows.",
|
||||
"Look upon my works and despair - if you can still see.",
|
||||
"The mushroom clouds herald my coronation.",
|
||||
"A crown of thorns for a radioactive realm.",
|
||||
"They chose extinction. I chose supremacy.",
|
||||
"The wasteland's throne is mine to claim.",
|
||||
"The Geiger counter clicks. The masses bow.",
|
||||
"Atoms split. Nations fall. I reign supreme.",
|
||||
"My kingdom radiates with possibility.",
|
||||
"The isotopes of victory decay slowly.",
|
||||
"Critical mass achieved. Dominion secured.",
|
||||
"Chain reaction complete: world falls, empire rises.",
|
||||
"In nuclear fire, I forge my legacy."
|
||||
];
|
||||
|
||||
export const defeatQuotes = [
|
||||
// Last words and final thoughts
|
||||
"The flame of our nation flickers out...",
|
||||
"History will remember we fought to the last.",
|
||||
"Our glory fades into darkness.",
|
||||
"The end comes for all nations. Today, it comes for us.",
|
||||
"We fought. We failed. We fade.",
|
||||
"Our time in the sun is done.",
|
||||
"The pages of history close on our chapter.",
|
||||
"So falls the dream of empire.",
|
||||
"We built in stone, but even stone crumbles.",
|
||||
"The stars themselves will remember our defiance.",
|
||||
|
||||
// Bitter defeats
|
||||
"Treachery and fate conspired against us.",
|
||||
"Our enemies dance on the graves of heroes.",
|
||||
"The vultures circle what remains.",
|
||||
"Let them celebrate. Dead men need no vengeance.",
|
||||
"The light dies. The darkness wins.",
|
||||
"Our walls fall. Our spirit breaks.",
|
||||
"Victory goes to the ruthless.",
|
||||
"Time claims another empire.",
|
||||
"The crown shatters. The throne burns.",
|
||||
"Our banners fall. Our story ends.",
|
||||
|
||||
// Philosophical acceptance
|
||||
"All great nations must face their sunset.",
|
||||
"Time is the ultimate conqueror.",
|
||||
"Today we join the ghosts of fallen empires.",
|
||||
"What rises must also fall.",
|
||||
"Our legacy scatters like dust in the wind.",
|
||||
"The wheel turns. We descend.",
|
||||
"From glory to ashes, as all things must.",
|
||||
"The tides of fate show no mercy.",
|
||||
"Let history judge if we were worthy.",
|
||||
"We join the eternal silence.",
|
||||
|
||||
// Defiant last stands
|
||||
"Our spirit remains unbroken.",
|
||||
"They may take our lands, but not our pride.",
|
||||
"Remember us as we were, not as we fell.",
|
||||
"We chose death before dishonor.",
|
||||
"Our courage lives beyond our defeat.",
|
||||
"Let them write of how we stood fast.",
|
||||
"We fall, but we fall fighting.",
|
||||
"Honor guides us to our end.",
|
||||
"Death before surrender.",
|
||||
"The echoes of our defiance will ring eternal.",
|
||||
|
||||
// Prophetic/Cursed
|
||||
"Our shadow will haunt their victory.",
|
||||
"They'll learn the price of empire.",
|
||||
"Time will prove our cause was just.",
|
||||
"The seeds of their downfall are sown in our ashes.",
|
||||
"Our fall heralds their doom.",
|
||||
"Victory today. Nemesis tomorrow.",
|
||||
"The wheel turns for all.",
|
||||
"They'll remember us in their nightmares.",
|
||||
"Our curse follows them to their graves.",
|
||||
"What rises in our place will shake the world."
|
||||
];
|
||||
|
||||
@customElement('win-modal')
|
||||
export class WinModal extends LitElement implements Layer {
|
||||
public clientID: ClientID
|
||||
public game: GameView
|
||||
private winner: PlayerView
|
||||
|
||||
|
||||
private rand: PseudoRandom;
|
||||
|
||||
private hasShownDeathModal = false
|
||||
|
||||
@state()
|
||||
isVisible = false
|
||||
|
||||
private _title: string
|
||||
private message: string
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
@@ -114,25 +258,19 @@ export class WinModal extends LitElement implements Layer {
|
||||
`;
|
||||
|
||||
render() {
|
||||
if (!this.winner) return null;
|
||||
const isWinner = this.winner.clientID() === this.clientID;
|
||||
const title = isWinner ? 'You Won!!!' : 'You Lost!!!';
|
||||
const message = `${this.winner.name()} won the game!`;
|
||||
|
||||
return html`
|
||||
<div class="modal ${this.isVisible ? 'visible' : ''}">
|
||||
<h2>${title}</h2>
|
||||
<p>${message}</p>
|
||||
<h2>${this._title}</h2>
|
||||
<p>${this.message}</p>
|
||||
<div class="button-container">
|
||||
<button @click=${this._handleExit}>Exit Game</button>
|
||||
<button @click=${this._handleContinue}>Keep Playing</button>
|
||||
<button @click=${this.hide}>Keep Playing</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
show(winner: PlayerView) {
|
||||
this.winner = winner;
|
||||
show() {
|
||||
this.isVisible = true;
|
||||
this.requestUpdate();
|
||||
}
|
||||
@@ -147,15 +285,34 @@ export class WinModal extends LitElement implements Layer {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
private _handleContinue() {
|
||||
this.hide();
|
||||
init() {
|
||||
this.rand = new PseudoRandom(simpleHash(this.game.myClientID()))
|
||||
}
|
||||
|
||||
init() { }
|
||||
|
||||
tick() {
|
||||
const myPlayer = this.game.myPlayer()
|
||||
if (!this.hasShownDeathModal && myPlayer && !myPlayer.isAlive()) {
|
||||
this.hasShownDeathModal = true
|
||||
this._title = 'You died'
|
||||
this.message = this.rand.randElement(defeatQuotes)
|
||||
this.show()
|
||||
}
|
||||
this.game.updatesSinceLastTick()[GameUpdateType.WinUpdate]
|
||||
.forEach(wu => this.show(this.game.playerBySmallID(wu.winnerID) as PlayerView))
|
||||
.forEach(wu => {
|
||||
const winner = this.game.playerBySmallID(wu.winnerID) as PlayerView
|
||||
if (winner == this.game.myPlayer()) {
|
||||
this._title = 'You Won!'
|
||||
if (this.game.numTilesWithFallout() / this.game.numLandTiles() > .6) {
|
||||
this.message = this.rand.randElement(highRadiationVictoryQuotes)
|
||||
} else {
|
||||
this.message = this.rand.randElement(lowRadiationVictoryQuotes)
|
||||
}
|
||||
} else {
|
||||
this._title = `${winner.name()} has won!`
|
||||
this.message = this.rand.randElement(defeatQuotes)
|
||||
}
|
||||
this.show()
|
||||
})
|
||||
}
|
||||
|
||||
renderLayer(context: CanvasRenderingContext2D) {
|
||||
|
||||
@@ -19,7 +19,7 @@ export class DevConfig extends DefaultConfig {
|
||||
}
|
||||
|
||||
numSpawnPhaseTurns(): number {
|
||||
return this.gameConfig().gameType == GameType.Singleplayer ? 40 : 200
|
||||
return this.gameConfig().gameType == GameType.Singleplayer ? 40 : 100
|
||||
// return 100
|
||||
}
|
||||
|
||||
@@ -30,23 +30,23 @@ export class DevConfig extends DefaultConfig {
|
||||
return info
|
||||
}
|
||||
|
||||
// percentageTilesOwnedToWin(): number {
|
||||
// return 10
|
||||
// }
|
||||
percentageTilesOwnedToWin(): number {
|
||||
return 1
|
||||
}
|
||||
|
||||
// populationIncreaseRate(player: Player): number {
|
||||
// return this.maxPopulation(player)
|
||||
// }
|
||||
populationIncreaseRate(player: Player): number {
|
||||
return this.maxPopulation(player)
|
||||
}
|
||||
|
||||
// boatMaxDistance(): number {
|
||||
// return 5000
|
||||
// }
|
||||
|
||||
// numBots(): number {
|
||||
// return 0
|
||||
// }
|
||||
// spawnNPCs(): boolean {
|
||||
// return false
|
||||
// }
|
||||
numBots(): number {
|
||||
return 0
|
||||
}
|
||||
spawnNPCs(): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -162,7 +162,15 @@ export class GameView implements GameMap {
|
||||
private _units = new Map<number, UnitView>()
|
||||
private updatedTiles: TileRef[] = []
|
||||
|
||||
constructor(public worker: WorkerClient, private _config: Config, private _map: GameMap) {
|
||||
|
||||
private _myPlayer: PlayerView | null = null
|
||||
|
||||
constructor(
|
||||
public worker: WorkerClient,
|
||||
private _config: Config,
|
||||
private _map: GameMap,
|
||||
private _myClientID: ClientID
|
||||
) {
|
||||
this.lastUpdate = {
|
||||
tick: 0,
|
||||
packedTileUpdates: new BigUint64Array([]),
|
||||
@@ -210,6 +218,17 @@ export class GameView implements GameMap {
|
||||
return this.updatedTiles
|
||||
}
|
||||
|
||||
myClientID(): ClientID {
|
||||
return this._myClientID
|
||||
}
|
||||
|
||||
myPlayer(): PlayerView | null {
|
||||
if (this._myPlayer == null) {
|
||||
this._myPlayer = this.playerByClientID(this._myClientID)
|
||||
}
|
||||
return this._myPlayer
|
||||
}
|
||||
|
||||
player(id: PlayerID): PlayerView {
|
||||
if (this._players.has(id)) {
|
||||
return this._players.get(id)
|
||||
|
||||
Reference in New Issue
Block a user