mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 20:43:36 +00:00
add hospital unit
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<svg width="800" height="800" viewBox="0 0 800 800" xmlns="http://www.w3.org/2000/svg">
|
||||
<text x="400" y="570" font-size="600" font-family="Arial, sans-serif" font-weight="bold" text-anchor="middle" fill="white">H</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 229 B |
Binary file not shown.
|
After Width: | Height: | Size: 156 B |
@@ -225,7 +225,8 @@
|
||||
"sam_launcher": "SAM Launcher",
|
||||
"atom_bomb": "Atom Bomb",
|
||||
"hydrogen_bomb": "Hydrogen Bomb",
|
||||
"mirv": "MIRV"
|
||||
"mirv": "MIRV",
|
||||
"hospital": "Hospital"
|
||||
},
|
||||
"user_setting": {
|
||||
"title": "User Settings",
|
||||
@@ -354,7 +355,8 @@
|
||||
"warship": "Captures trade ships, destroys ships and boats",
|
||||
"port": "Sends trade ships to generate gold",
|
||||
"defense_post": "Increase defenses of nearby borders",
|
||||
"city": "Increase max population"
|
||||
"city": "Increase max population",
|
||||
"hospital": "Boosts population growth by 5%"
|
||||
},
|
||||
"not_enough_money": "Not enough money"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@ import { customElement, state } from "lit/decorators.js";
|
||||
import warshipIcon from "../../../../resources/images/BattleshipIconWhite.svg";
|
||||
import cityIcon from "../../../../resources/images/CityIconWhite.svg";
|
||||
import goldCoinIcon from "../../../../resources/images/GoldCoinIcon.svg";
|
||||
import hospitalIcon from "../../../../resources/images/HospitalIconWhite.svg";
|
||||
import mirvIcon from "../../../../resources/images/MIRVIcon.svg";
|
||||
import missileSiloIcon from "../../../../resources/images/MissileSiloIconWhite.svg";
|
||||
import hydrogenBombIcon from "../../../../resources/images/MushroomCloudIconWhite.svg";
|
||||
@@ -93,6 +94,13 @@ const buildTable: BuildItemDisplay[][] = [
|
||||
key: "unit_type.city",
|
||||
countable: true,
|
||||
},
|
||||
{
|
||||
unitType: UnitType.Hospital,
|
||||
icon: hospitalIcon,
|
||||
description: "build_menu.desc.hospital",
|
||||
key: "unit_type.hospital",
|
||||
countable: true,
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { UnitInfoModal } from "./UnitInfoModal";
|
||||
|
||||
import cityIcon from "../../../../resources/images/buildings/cityAlt1.png";
|
||||
import shieldIcon from "../../../../resources/images/buildings/fortAlt2.png";
|
||||
import hospitalIcon from "../../../../resources/images/buildings/hospital.png";
|
||||
import anchorIcon from "../../../../resources/images/buildings/port1.png";
|
||||
import MissileSiloReloadingIcon from "../../../../resources/images/buildings/silo1-reloading.png";
|
||||
import missileSiloIcon from "../../../../resources/images/buildings/silo1.png";
|
||||
@@ -83,6 +84,12 @@ export class StructureLayer implements Layer {
|
||||
territoryRadius: 6.525,
|
||||
borderType: UnitBorderType.Square,
|
||||
},
|
||||
[UnitType.Hospital]: {
|
||||
icon: hospitalIcon,
|
||||
borderRadius: 8.525,
|
||||
territoryRadius: 6.525,
|
||||
borderType: UnitBorderType.Square,
|
||||
},
|
||||
};
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -18,6 +18,7 @@ const unitOptions: { type: UnitType; translationKey: string }[] = [
|
||||
{ type: UnitType.AtomBomb, translationKey: "unit_type.atom_bomb" },
|
||||
{ type: UnitType.HydrogenBomb, translationKey: "unit_type.hydrogen_bomb" },
|
||||
{ type: UnitType.MIRV, translationKey: "unit_type.mirv" },
|
||||
{ type: UnitType.Hospital, translationKey: "unit_type.hospital" },
|
||||
];
|
||||
|
||||
export function renderUnitTypeOptions({
|
||||
|
||||
@@ -435,6 +435,23 @@ export class DefaultConfig implements Config {
|
||||
cost: () => 0n,
|
||||
territoryBound: true,
|
||||
};
|
||||
case UnitType.Hospital:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
12_000_000,
|
||||
Math.pow(
|
||||
2,
|
||||
p.unitsIncludingConstruction(UnitType.City).length,
|
||||
) * 3_000_000,
|
||||
),
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
};
|
||||
default:
|
||||
assertNever(type);
|
||||
}
|
||||
@@ -677,6 +694,10 @@ export class DefaultConfig implements Config {
|
||||
toAdd *= 0.7;
|
||||
}
|
||||
|
||||
if (player.units(UnitType.Hospital).length > 0) {
|
||||
toAdd *= 1 + 0.05 * player.units(UnitType.Hospital).length;
|
||||
// hospital boosts population growth
|
||||
}
|
||||
if (player.type() === PlayerType.FakeHuman) {
|
||||
switch (this._gameConfig.difficulty) {
|
||||
case Difficulty.Easy:
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { TileRef } from "../game/GameMap";
|
||||
import { CityExecution } from "./CityExecution";
|
||||
import { DefensePostExecution } from "./DefensePostExecution";
|
||||
import { HospitalExecution } from "./HospitalExecution";
|
||||
import { MirvExecution } from "./MIRVExecution";
|
||||
import { MissileSiloExecution } from "./MissileSiloExecution";
|
||||
import { NukeExecution } from "./NukeExecution";
|
||||
@@ -124,6 +125,9 @@ export class ConstructionExecution implements Execution {
|
||||
case UnitType.City:
|
||||
this.mg.addExecution(new CityExecution(player.id(), this.tile));
|
||||
break;
|
||||
case UnitType.Hospital:
|
||||
this.mg.addExecution(new HospitalExecution(player.id(), this.tile));
|
||||
break;
|
||||
default:
|
||||
throw Error(`unit type ${this.constructionType} not supported`);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { consolex } from "../Consolex";
|
||||
import {
|
||||
Execution,
|
||||
Game,
|
||||
Player,
|
||||
PlayerID,
|
||||
Unit,
|
||||
UnitType,
|
||||
} from "../game/Game";
|
||||
import { TileRef } from "../game/GameMap";
|
||||
|
||||
export class HospitalExecution implements Execution {
|
||||
private player: Player;
|
||||
private mg: Game;
|
||||
private hospital: Unit | null = null;
|
||||
private active: boolean = true;
|
||||
|
||||
constructor(
|
||||
private ownerId: PlayerID,
|
||||
private tile: TileRef,
|
||||
) {}
|
||||
|
||||
init(mg: Game, ticks: number): void {
|
||||
this.mg = mg;
|
||||
if (!mg.hasPlayer(this.ownerId)) {
|
||||
console.warn(`HospitalExecution: player ${this.ownerId} not found`);
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
this.player = mg.player(this.ownerId);
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.hospital === null) {
|
||||
const spawnTile = this.player.canBuild(UnitType.Hospital, this.tile);
|
||||
if (spawnTile === false) {
|
||||
consolex.warn("cannot build hospital");
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
this.hospital = this.player.buildUnit(UnitType.Hospital, spawnTile, {});
|
||||
}
|
||||
if (!this.hospital.isActive()) {
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.player !== this.hospital.owner()) {
|
||||
this.player = this.hospital.owner();
|
||||
}
|
||||
}
|
||||
|
||||
isActive(): boolean {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
activeDuringSpawnPhase(): boolean {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,7 @@ export enum UnitType {
|
||||
MIRV = "MIRV",
|
||||
MIRVWarhead = "MIRV Warhead",
|
||||
Construction = "Construction",
|
||||
Hospital = "Hospital",
|
||||
}
|
||||
|
||||
export interface OwnerComp {
|
||||
@@ -195,6 +196,8 @@ export interface UnitParamsMap {
|
||||
|
||||
[UnitType.MIRV]: {};
|
||||
|
||||
[UnitType.Hospital]: {};
|
||||
|
||||
[UnitType.MIRVWarhead]: {
|
||||
targetTile?: number;
|
||||
};
|
||||
|
||||
@@ -809,6 +809,7 @@ export class PlayerImpl implements Player {
|
||||
case UnitType.DefensePost:
|
||||
case UnitType.SAMLauncher:
|
||||
case UnitType.City:
|
||||
case UnitType.Hospital:
|
||||
case UnitType.Construction:
|
||||
return this.landBasedStructureSpawn(targetTile, validTiles);
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user