mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-28 12:00:30 +00:00
add hospital visual
This commit is contained in:
@@ -52,8 +52,10 @@ export class NewsModal extends LitElement {
|
|||||||
<div class="news-content">
|
<div class="news-content">
|
||||||
<p>
|
<p>
|
||||||
This test version introduces a new building:
|
This test version introduces a new building:
|
||||||
<strong>Hospitals</strong>. Each hospital reduces your troop
|
<strong>Hospitals</strong>. Each hospital restores some of
|
||||||
losses in both offensive and defensive combat.
|
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>
|
||||||
<p>
|
<p>
|
||||||
The first hospital provides a
|
The first hospital provides a
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ export class ControlPanel extends LitElement implements Layer {
|
|||||||
@state()
|
@state()
|
||||||
private popRate: number;
|
private popRate: number;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
private _hospitalReturns: number = 0;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
private _troops: number;
|
private _troops: number;
|
||||||
|
|
||||||
@@ -121,6 +124,7 @@ export class ControlPanel extends LitElement implements Layer {
|
|||||||
|
|
||||||
this._population = player.population();
|
this._population = player.population();
|
||||||
this._maxPopulation = this.game.config().maxPopulation(player);
|
this._maxPopulation = this.game.config().maxPopulation(player);
|
||||||
|
this._hospitalReturns = player.hospitalReturns() * 10;
|
||||||
this._gold = player.gold();
|
this._gold = player.gold();
|
||||||
this._troops = player.troops();
|
this._troops = player.troops();
|
||||||
this._workers = player.workers();
|
this._workers = player.workers();
|
||||||
@@ -221,9 +225,12 @@ export class ControlPanel extends LitElement implements Layer {
|
|||||||
? "text-green-500"
|
? "text-green-500"
|
||||||
: "text-yellow-500"}"
|
: "text-yellow-500"}"
|
||||||
translate="no"
|
translate="no"
|
||||||
>(+${renderTroops(this.popRate)})</span
|
>
|
||||||
></span
|
(+${renderTroops(
|
||||||
>
|
this.popRate,
|
||||||
|
)}${`/ +${renderTroops(this._hospitalReturns)}`})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<span class="font-bold"
|
<span class="font-bold"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export class TopBar extends LitElement implements Layer {
|
|||||||
public game: GameView;
|
public game: GameView;
|
||||||
private isVisible = false;
|
private isVisible = false;
|
||||||
private _population = 0;
|
private _population = 0;
|
||||||
|
private _hospitalReturns = 0;
|
||||||
private _lastPopulationIncreaseRate = 0;
|
private _lastPopulationIncreaseRate = 0;
|
||||||
private _popRateIsIncreasing = false;
|
private _popRateIsIncreasing = false;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ export class TopBar extends LitElement implements Layer {
|
|||||||
popIncreaseRate >= this._lastPopulationIncreaseRate;
|
popIncreaseRate >= this._lastPopulationIncreaseRate;
|
||||||
this._lastPopulationIncreaseRate = popIncreaseRate;
|
this._lastPopulationIncreaseRate = popIncreaseRate;
|
||||||
}
|
}
|
||||||
|
this._hospitalReturns = player.hospitalReturns?.() ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -72,8 +74,10 @@ export class TopBar extends LitElement implements Layer {
|
|||||||
class="${this._popRateIsIncreasing
|
class="${this._popRateIsIncreasing
|
||||||
? "text-green-500"
|
? "text-green-500"
|
||||||
: "text-yellow-500"}"
|
: "text-yellow-500"}"
|
||||||
>(+${renderTroops(popRate)})</span
|
|
||||||
>
|
>
|
||||||
|
(+${renderTroops(popRate)} /
|
||||||
|
+${renderTroops(this._hospitalReturns)})
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- Gold section (takes 1 column on desktop) -->
|
<!-- Gold section (takes 1 column on desktop) -->
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -569,12 +569,6 @@ export class DefaultConfig implements Config {
|
|||||||
const traitorDebuff = defender.isTraitor()
|
const traitorDebuff = defender.isTraitor()
|
||||||
? this.traitorDefenseDebuff()
|
? this.traitorDefenseDebuff()
|
||||||
: 1;
|
: 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 baseTroopLoss = 10;
|
||||||
const attackLossModifier = 1.35;
|
const attackLossModifier = 1.35;
|
||||||
const baseTileCost = 45;
|
const baseTileCost = 45;
|
||||||
@@ -582,10 +576,9 @@ export class DefaultConfig implements Config {
|
|||||||
return {
|
return {
|
||||||
attackerTroopLoss:
|
attackerTroopLoss:
|
||||||
mag *
|
mag *
|
||||||
attackerHospitalBonus *
|
|
||||||
(baseTroopLoss +
|
(baseTroopLoss +
|
||||||
attackLossModifier * defenderDensity * traitorDebuff),
|
attackLossModifier * defenderDensity * traitorDebuff),
|
||||||
defenderTroopLoss: defenderDensity * defenderHospitalBonus,
|
defenderTroopLoss: defenderDensity,
|
||||||
tilesPerTickUsed:
|
tilesPerTickUsed:
|
||||||
baseTileCost *
|
baseTileCost *
|
||||||
within(defenderDensity, 3, 50) ** 0.2 *
|
within(defenderDensity, 3, 50) ** 0.2 *
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
PlayerType,
|
PlayerType,
|
||||||
TerrainType,
|
TerrainType,
|
||||||
TerraNullius,
|
TerraNullius,
|
||||||
|
UnitType,
|
||||||
} from "../game/Game";
|
} from "../game/Game";
|
||||||
import { TileRef } from "../game/GameMap";
|
import { TileRef } from "../game/GameMap";
|
||||||
import { PseudoRandom } from "../PseudoRandom";
|
import { PseudoRandom } from "../PseudoRandom";
|
||||||
@@ -294,6 +295,20 @@ export class AttackExecution implements Execution {
|
|||||||
if (targetPlayer) {
|
if (targetPlayer) {
|
||||||
targetPlayer.removeTroops(defenderTroopLoss);
|
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._owner.conquer(tileToConquer);
|
||||||
this.handleDeadDefender();
|
this.handleDeadDefender();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,10 @@ export class PlayerExecution implements Execution {
|
|||||||
return;
|
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.addWorkers(popInc * (1 - this.player.targetTroopRatio()));
|
||||||
this.player.addTroops(popInc * this.player.targetTroopRatio());
|
this.player.addTroops(popInc * this.player.targetTroopRatio());
|
||||||
const goldFromWorkers = this.config.goldAdditionRate(this.player);
|
const goldFromWorkers = this.config.goldAdditionRate(this.player);
|
||||||
|
|||||||
@@ -461,6 +461,9 @@ export interface Player {
|
|||||||
setTroops(troops: number): void;
|
setTroops(troops: number): void;
|
||||||
addTroops(troops: number): void;
|
addTroops(troops: number): void;
|
||||||
removeTroops(troops: number): number;
|
removeTroops(troops: number): number;
|
||||||
|
hospitalReturns(): number;
|
||||||
|
addHospitalReturns(amount: number): void;
|
||||||
|
resetHospitalReturns(): void;
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
units(...types: UnitType[]): Unit[];
|
units(...types: UnitType[]): Unit[];
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ export interface PlayerUpdate {
|
|||||||
gold: Gold;
|
gold: Gold;
|
||||||
population: number;
|
population: number;
|
||||||
totalPopulation: number;
|
totalPopulation: number;
|
||||||
|
hospitalReturns: number;
|
||||||
workers: number;
|
workers: number;
|
||||||
troops: number;
|
troops: number;
|
||||||
targetTroopRatio: number;
|
targetTroopRatio: number;
|
||||||
|
|||||||
@@ -292,6 +292,9 @@ export class PlayerView {
|
|||||||
hasSpawned(): boolean {
|
hasSpawned(): boolean {
|
||||||
return this.data.hasSpawned;
|
return this.data.hasSpawned;
|
||||||
}
|
}
|
||||||
|
hospitalReturns(): number {
|
||||||
|
return this.data.hospitalReturns ?? 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GameView implements GameMap {
|
export class GameView implements GameMap {
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export class PlayerImpl implements Player {
|
|||||||
private _flag: string | undefined;
|
private _flag: string | undefined;
|
||||||
private _name: string;
|
private _name: string;
|
||||||
private _displayName: string;
|
private _displayName: string;
|
||||||
|
private _hospitalReturns: number = 0;
|
||||||
|
|
||||||
public pastOutgoingAllianceRequests: AllianceRequest[] = [];
|
public pastOutgoingAllianceRequests: AllianceRequest[] = [];
|
||||||
|
|
||||||
@@ -139,6 +140,7 @@ export class PlayerImpl implements Player {
|
|||||||
gold: this._gold,
|
gold: this._gold,
|
||||||
population: this.population(),
|
population: this.population(),
|
||||||
totalPopulation: this.totalPopulation(),
|
totalPopulation: this.totalPopulation(),
|
||||||
|
hospitalReturns: this.hospitalReturns(),
|
||||||
workers: this.workers(),
|
workers: this.workers(),
|
||||||
troops: this.troops(),
|
troops: this.troops(),
|
||||||
targetTroopRatio: this.targetTroopRatio(),
|
targetTroopRatio: this.targetTroopRatio(),
|
||||||
@@ -720,6 +722,17 @@ export class PlayerImpl implements Player {
|
|||||||
return Number(toRemove);
|
return Number(toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hospitalReturns(): number {
|
||||||
|
return this._hospitalReturns;
|
||||||
|
}
|
||||||
|
addHospitalReturns(count: number): void {
|
||||||
|
this._hospitalReturns += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
resetHospitalReturns(): void {
|
||||||
|
this._hospitalReturns = 0;
|
||||||
|
}
|
||||||
|
|
||||||
captureUnit(unit: Unit): void {
|
captureUnit(unit: Unit): void {
|
||||||
if (unit.owner() === this) {
|
if (unit.owner() === this) {
|
||||||
throw new Error(`Cannot capture unit, ${this} already owns ${unit}`);
|
throw new Error(`Cannot capture unit, ${this} already owns ${unit}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user