add hospital visual

This commit is contained in:
1brucben
2025-06-05 18:02:38 +02:00
parent 71e677ce4c
commit 65115eb4ee
10 changed files with 59 additions and 15 deletions
+4 -2
View File
@@ -52,8 +52,10 @@ export class NewsModal extends LitElement {
<div class="news-content">
<p>
This test version introduces a new building:
<strong>Hospitals</strong>. Each hospital reduces your troop
losses in both offensive and defensive combat.
<strong>Hospitals</strong>. Each hospital restores some of
your troop losses from both offensive and defensive combat.
The restored troops are displayed next to your population
growth count in your control panel.
</p>
<p>
The first hospital provides a
+10 -3
View File
@@ -34,6 +34,9 @@ export class ControlPanel extends LitElement implements Layer {
@state()
private popRate: number;
@state()
private _hospitalReturns: number = 0;
@state()
private _troops: number;
@@ -121,6 +124,7 @@ export class ControlPanel extends LitElement implements Layer {
this._population = player.population();
this._maxPopulation = this.game.config().maxPopulation(player);
this._hospitalReturns = player.hospitalReturns() * 10;
this._gold = player.gold();
this._troops = player.troops();
this._workers = player.workers();
@@ -221,9 +225,12 @@ export class ControlPanel extends LitElement implements Layer {
? "text-green-500"
: "text-yellow-500"}"
translate="no"
>(+${renderTroops(this.popRate)})</span
></span
>
>
(+${renderTroops(
this.popRate,
)}${`/ +${renderTroops(this._hospitalReturns)}`})
</span>
</span>
</div>
<div class="flex justify-between">
<span class="font-bold"
+5 -1
View File
@@ -10,6 +10,7 @@ export class TopBar extends LitElement implements Layer {
public game: GameView;
private isVisible = false;
private _population = 0;
private _hospitalReturns = 0;
private _lastPopulationIncreaseRate = 0;
private _popRateIsIncreasing = false;
@@ -36,6 +37,7 @@ export class TopBar extends LitElement implements Layer {
popIncreaseRate >= this._lastPopulationIncreaseRate;
this._lastPopulationIncreaseRate = popIncreaseRate;
}
this._hospitalReturns = player.hospitalReturns?.() ?? 0;
}
render() {
@@ -72,8 +74,10 @@ export class TopBar extends LitElement implements Layer {
class="${this._popRateIsIncreasing
? "text-green-500"
: "text-yellow-500"}"
>(+${renderTroops(popRate)})</span
>
(+${renderTroops(popRate)} /
+${renderTroops(this._hospitalReturns)})
</span>
</div>
<!-- Gold section (takes 1 column on desktop) -->
<div
+1 -8
View File
@@ -569,12 +569,6 @@ export class DefaultConfig implements Config {
const traitorDebuff = defender.isTraitor()
? this.traitorDefenseDebuff()
: 1;
const attackerHospitalBonus =
0.6 + 0.4 * Math.pow(0.75, attacker.units(UnitType.Hospital).length);
const defenderHospitalBonus =
0.6 + 0.4 * Math.pow(0.75, defender.units(UnitType.Hospital).length);
console.log(attackerHospitalBonus, defenderHospitalBonus);
const baseTroopLoss = 10;
const attackLossModifier = 1.35;
const baseTileCost = 45;
@@ -582,10 +576,9 @@ export class DefaultConfig implements Config {
return {
attackerTroopLoss:
mag *
attackerHospitalBonus *
(baseTroopLoss +
attackLossModifier * defenderDensity * traitorDebuff),
defenderTroopLoss: defenderDensity * defenderHospitalBonus,
defenderTroopLoss: defenderDensity,
tilesPerTickUsed:
baseTileCost *
within(defenderDensity, 3, 50) ** 0.2 *
+15
View File
@@ -9,6 +9,7 @@ import {
PlayerType,
TerrainType,
TerraNullius,
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { PseudoRandom } from "../PseudoRandom";
@@ -294,6 +295,20 @@ export class AttackExecution implements Execution {
if (targetPlayer) {
targetPlayer.removeTroops(defenderTroopLoss);
}
const attackerMultiplier =
0.6 + 0.4 * Math.pow(0.75, this._owner.units(UnitType.Hospital).length);
const defenderMultiplier = targetPlayer
? 0.6 +
0.4 * Math.pow(0.75, this._owner.units(UnitType.Hospital).length)
: 1;
const attackerReturns = attackerTroopLoss * (1 - attackerMultiplier);
const defenderReturns = defenderTroopLoss * (1 - defenderMultiplier);
this._owner.addHospitalReturns(attackerReturns);
if (targetPlayer) {
targetPlayer.addHospitalReturns(defenderReturns);
}
this._owner.conquer(tileToConquer);
this.handleDeadDefender();
}
+4 -1
View File
@@ -74,7 +74,10 @@ export class PlayerExecution implements Execution {
return;
}
const popInc = this.config.populationIncreaseRate(this.player);
const popInc =
this.config.populationIncreaseRate(this.player) +
this.player.hospitalReturns();
this.player.resetHospitalReturns();
this.player.addWorkers(popInc * (1 - this.player.targetTroopRatio()));
this.player.addTroops(popInc * this.player.targetTroopRatio());
const goldFromWorkers = this.config.goldAdditionRate(this.player);
+3
View File
@@ -461,6 +461,9 @@ export interface Player {
setTroops(troops: number): void;
addTroops(troops: number): void;
removeTroops(troops: number): number;
hospitalReturns(): number;
addHospitalReturns(amount: number): void;
resetHospitalReturns(): void;
// Units
units(...types: UnitType[]): Unit[];
+1
View File
@@ -107,6 +107,7 @@ export interface PlayerUpdate {
gold: Gold;
population: number;
totalPopulation: number;
hospitalReturns: number;
workers: number;
troops: number;
targetTroopRatio: number;
+3
View File
@@ -292,6 +292,9 @@ export class PlayerView {
hasSpawned(): boolean {
return this.data.hasSpawned;
}
hospitalReturns(): number {
return this.data.hospitalReturns ?? 0;
}
}
export class GameView implements GameMap {
+13
View File
@@ -82,6 +82,7 @@ export class PlayerImpl implements Player {
private _flag: string | undefined;
private _name: string;
private _displayName: string;
private _hospitalReturns: number = 0;
public pastOutgoingAllianceRequests: AllianceRequest[] = [];
@@ -139,6 +140,7 @@ export class PlayerImpl implements Player {
gold: this._gold,
population: this.population(),
totalPopulation: this.totalPopulation(),
hospitalReturns: this.hospitalReturns(),
workers: this.workers(),
troops: this.troops(),
targetTroopRatio: this.targetTroopRatio(),
@@ -720,6 +722,17 @@ export class PlayerImpl implements Player {
return Number(toRemove);
}
hospitalReturns(): number {
return this._hospitalReturns;
}
addHospitalReturns(count: number): void {
this._hospitalReturns += count;
}
resetHospitalReturns(): void {
this._hospitalReturns = 0;
}
captureUnit(unit: Unit): void {
if (unit.owner() === this) {
throw new Error(`Cannot capture unit, ${this} already owns ${unit}`);