mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-17 14:49:16 +00:00
nuke icon (#207)
- **feat: white nuke icon next to name if player nukes you**  - **feat: red nuke icon if player sends nuke towards you** - 
This commit is contained in:
@@ -55,7 +55,9 @@ export class NukeExecution implements Execution {
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
this.nuke = this.player.buildUnit(this.type, 0, spawn);
|
||||
this.nuke = this.player.buildUnit(this.type, 0, spawn, {
|
||||
detonationDst: this.dst,
|
||||
});
|
||||
if (this.mg.hasOwner(this.dst)) {
|
||||
const target = this.mg.owner(this.dst) as Player;
|
||||
if (this.type == UnitType.AtomBomb) {
|
||||
|
||||
@@ -47,12 +47,9 @@ export class TradeShipExecution implements Execution {
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
this.tradeShip = this.origOwner.buildUnit(
|
||||
UnitType.TradeShip,
|
||||
0,
|
||||
spawn,
|
||||
this._dstPort,
|
||||
);
|
||||
this.tradeShip = this.origOwner.buildUnit(UnitType.TradeShip, 0, spawn, {
|
||||
dstPort: this._dstPort,
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.tradeShip.isActive()) {
|
||||
|
||||
@@ -79,10 +79,10 @@ export class WarshipExecution implements Execution {
|
||||
.filter((u) => u != this.warship)
|
||||
.filter((u) => !u.owner().isAlliedWith(this.warship.owner()))
|
||||
.filter((u) => !this.alreadySentShell.has(u))
|
||||
.filter(
|
||||
(u) =>
|
||||
u.type() != UnitType.TradeShip || u.dstPort().owner() != this.owner(),
|
||||
);
|
||||
.filter((u) => {
|
||||
const portOwner = u.dstPort() ? u.dstPort().owner() : null;
|
||||
return u.type() != UnitType.TradeShip || portOwner != this.owner();
|
||||
});
|
||||
|
||||
this.target =
|
||||
ships.sort((a, b) => {
|
||||
@@ -110,7 +110,7 @@ export class WarshipExecution implements Execution {
|
||||
return distSortUnit(this.mg, this.warship)(a, b);
|
||||
})[0] ?? null;
|
||||
|
||||
this.warship.setTarget(this.target);
|
||||
this.warship.setWarshipTarget(this.target);
|
||||
if (this.target == null || this.target.type() != UnitType.TradeShip) {
|
||||
// Patrol unless we are hunting down a tradeship
|
||||
const result = this.pathfinder.nextTile(
|
||||
|
||||
+22
-12
@@ -84,11 +84,14 @@ export enum UnitType {
|
||||
MIRVWarhead = "MIRV Warhead",
|
||||
Construction = "Construction",
|
||||
}
|
||||
export type NukeType =
|
||||
| UnitType.AtomBomb
|
||||
| UnitType.HydrogenBomb
|
||||
| UnitType.MIRVWarhead
|
||||
| UnitType.MIRV;
|
||||
|
||||
export const nukeTypes = [
|
||||
UnitType.AtomBomb,
|
||||
UnitType.HydrogenBomb,
|
||||
UnitType.MIRVWarhead,
|
||||
UnitType.MIRV,
|
||||
] as UnitType[];
|
||||
export type NukeType = (typeof nukeTypes)[number];
|
||||
|
||||
export enum Relation {
|
||||
Hostile = 0,
|
||||
@@ -201,6 +204,13 @@ export class PlayerInfo {
|
||||
) {}
|
||||
}
|
||||
|
||||
// Some units have info specific to them
|
||||
export interface UnitSpecificInfos {
|
||||
dstPort?: Unit; // Only for trade ships
|
||||
detonationDst?: TileRef; // Only for nukes
|
||||
warshipTarget?: Unit;
|
||||
}
|
||||
|
||||
export interface Unit {
|
||||
id(): number;
|
||||
|
||||
@@ -220,9 +230,12 @@ export interface Unit {
|
||||
hasHealth(): boolean;
|
||||
health(): number;
|
||||
modifyHealth(delta: number): void;
|
||||
// State for warships (currently)
|
||||
setTarget(target: Unit): void;
|
||||
target(): Unit;
|
||||
|
||||
setWarshipTarget(target: Unit): void; // warship only
|
||||
warshipTarget(): Unit;
|
||||
|
||||
dstPort(): Unit; // Only for trade ships
|
||||
detonationDst(): TileRef; // Only for nukes
|
||||
|
||||
// Mutations
|
||||
setTroops(troops: number): void;
|
||||
@@ -234,9 +247,6 @@ export interface Unit {
|
||||
|
||||
// Updates
|
||||
toUpdate(): UnitUpdate;
|
||||
|
||||
// Only for some types, otherwise return null
|
||||
dstPort(): Unit;
|
||||
}
|
||||
|
||||
export interface TerraNullius {
|
||||
@@ -294,7 +304,7 @@ export interface Player {
|
||||
type: UnitType,
|
||||
troops: number,
|
||||
tile: TileRef,
|
||||
dstPort?: Unit,
|
||||
unitSpecificInfos?: UnitSpecificInfos,
|
||||
): Unit;
|
||||
captureUnit(unit: Unit): void;
|
||||
|
||||
|
||||
@@ -69,9 +69,11 @@ export interface UnitUpdate {
|
||||
pos: TileRef;
|
||||
lastPos: TileRef;
|
||||
isActive: boolean;
|
||||
dstPortId?: number; // Only for trade ships
|
||||
detonationDst?: TileRef; // Only for nukes
|
||||
warshipTargetId?: number;
|
||||
health?: number;
|
||||
constructionType?: UnitType;
|
||||
targetId?: number;
|
||||
}
|
||||
|
||||
export interface AttackUpdate {
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
GameUpdates,
|
||||
MapPos,
|
||||
MessageType,
|
||||
nukeTypes,
|
||||
Player,
|
||||
PlayerActions,
|
||||
PlayerProfile,
|
||||
@@ -30,6 +31,7 @@ import { WorkerClient } from "../worker/WorkerClient";
|
||||
import { GameMap, GameMapImpl, TileRef, TileUpdate } from "./GameMap";
|
||||
import { GameUpdateViewData } from "./GameUpdates";
|
||||
import { DefenseGrid } from "./DefensePostGrid";
|
||||
import { consolex } from "../Consolex";
|
||||
|
||||
export class UnitView {
|
||||
public _wasUpdated = true;
|
||||
@@ -91,8 +93,23 @@ export class UnitView {
|
||||
constructionType(): UnitType | undefined {
|
||||
return this.data.constructionType;
|
||||
}
|
||||
targetId() {
|
||||
return this.data.targetId;
|
||||
dstPortId(): number {
|
||||
if (this.type() != UnitType.TradeShip) {
|
||||
throw Error("Must be a trade ship");
|
||||
}
|
||||
return this.data.dstPortId;
|
||||
}
|
||||
detonationDst(): TileRef {
|
||||
if (!nukeTypes.includes(this.type())) {
|
||||
throw Error("Must be a nuke");
|
||||
}
|
||||
return this.data.detonationDst;
|
||||
}
|
||||
warshipTargetId(): number {
|
||||
if (this.type() != UnitType.Warship) {
|
||||
throw Error("Must be a warship");
|
||||
}
|
||||
return this.data.warshipTargetId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
EmojiMessage,
|
||||
PlayerProfile,
|
||||
Attack,
|
||||
UnitSpecificInfos,
|
||||
} from "./Game";
|
||||
import { AttackUpdate, PlayerUpdate } from "./GameUpdates";
|
||||
import { GameUpdateType } from "./GameUpdates";
|
||||
@@ -648,7 +649,7 @@ export class PlayerImpl implements Player {
|
||||
type: UnitType,
|
||||
troops: number,
|
||||
spawnTile: TileRef,
|
||||
dstPort?: Unit,
|
||||
unitSpecificInfos: UnitSpecificInfos = {},
|
||||
): UnitImpl {
|
||||
const cost = this.mg.unitInfo(type).cost(this);
|
||||
const b = new UnitImpl(
|
||||
@@ -658,7 +659,7 @@ export class PlayerImpl implements Player {
|
||||
troops,
|
||||
this.mg.nextUnitID(),
|
||||
this,
|
||||
dstPort,
|
||||
unitSpecificInfos,
|
||||
);
|
||||
this._units.push(b);
|
||||
this.removeGold(cost);
|
||||
|
||||
+27
-11
@@ -1,4 +1,4 @@
|
||||
import { MessageType } from "./Game";
|
||||
import { MessageType, nukeTypes, UnitSpecificInfos } from "./Game";
|
||||
import { UnitUpdate } from "./GameUpdates";
|
||||
import { GameUpdateType } from "./GameUpdates";
|
||||
import { simpleHash, toInt, within, withinInt } from "../Util";
|
||||
@@ -6,6 +6,7 @@ import { Unit, TerraNullius, UnitType, Player, UnitInfo } from "./Game";
|
||||
import { GameImpl } from "./GameImpl";
|
||||
import { PlayerImpl } from "./PlayerImpl";
|
||||
import { TileRef } from "./GameMap";
|
||||
import { consolex } from "../Consolex";
|
||||
|
||||
export class UnitImpl implements Unit {
|
||||
private _active = true;
|
||||
@@ -16,6 +17,10 @@ export class UnitImpl implements Unit {
|
||||
|
||||
private _constructionType: UnitType = undefined;
|
||||
|
||||
private _dstPort: Unit | null = null; // Only for trade ships
|
||||
private _detonationDst: TileRef | null = null; // Only for nukes
|
||||
private _warshipTarget: Unit | null = null;
|
||||
|
||||
constructor(
|
||||
private _type: UnitType,
|
||||
private mg: GameImpl,
|
||||
@@ -23,10 +28,13 @@ export class UnitImpl implements Unit {
|
||||
private _troops: number,
|
||||
private _id: number,
|
||||
public _owner: PlayerImpl,
|
||||
private _dstPort?: Unit,
|
||||
unitsSpecificInfos: UnitSpecificInfos = {},
|
||||
) {
|
||||
this._health = toInt(this.mg.unitInfo(_type).maxHealth ?? 1);
|
||||
this._lastTile = _tile;
|
||||
this._dstPort = unitsSpecificInfos.dstPort;
|
||||
this._detonationDst = unitsSpecificInfos.detonationDst;
|
||||
this._warshipTarget = unitsSpecificInfos.warshipTarget;
|
||||
}
|
||||
|
||||
id() {
|
||||
@@ -34,6 +42,8 @@ export class UnitImpl implements Unit {
|
||||
}
|
||||
|
||||
toUpdate(): UnitUpdate {
|
||||
const warshipTarget = this.warshipTarget();
|
||||
const dstPort = this.dstPort();
|
||||
return {
|
||||
type: GameUpdateType.Unit,
|
||||
unitType: this._type,
|
||||
@@ -45,7 +55,9 @@ export class UnitImpl implements Unit {
|
||||
lastPos: this._lastTile,
|
||||
health: this.hasHealth() ? Number(this._health) : undefined,
|
||||
constructionType: this._constructionType,
|
||||
targetId: this.target() ? this.target().id() : null,
|
||||
dstPortId: dstPort ? dstPort.id() : null,
|
||||
warshipTargetId: warshipTarget ? warshipTarget.id() : null,
|
||||
detonationDst: this.detonationDst(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -153,15 +165,19 @@ export class UnitImpl implements Unit {
|
||||
return `Unit:${this._type},owner:${this.owner().name()}`;
|
||||
}
|
||||
|
||||
setWarshipTarget(target: Unit) {
|
||||
this._warshipTarget = target;
|
||||
}
|
||||
|
||||
warshipTarget(): Unit {
|
||||
return this._warshipTarget;
|
||||
}
|
||||
|
||||
detonationDst(): TileRef {
|
||||
return this._detonationDst;
|
||||
}
|
||||
|
||||
dstPort(): Unit {
|
||||
return this._dstPort;
|
||||
}
|
||||
|
||||
setTarget(target: Unit) {
|
||||
this._target = target;
|
||||
}
|
||||
|
||||
target() {
|
||||
return this._target;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user