mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-02 09:48:10 +00:00
feat: move warship (#196)
This commit is contained in:
@@ -36,6 +36,7 @@ import { fixProfaneUsername, isProfaneUsername } from "../validations/username";
|
||||
import { NoOpExecution } from "./NoOpExecution";
|
||||
import { EmbargoExecution } from "./EmbargoExecution";
|
||||
import { RetreatExecution } from "./RetreatExecution";
|
||||
import { MoveWarshipExecution } from "./MoveWarshipExecution";
|
||||
|
||||
export class Executor {
|
||||
// private random = new PseudoRandom(999)
|
||||
@@ -83,6 +84,8 @@ export class Executor {
|
||||
}
|
||||
case "cancel_attack":
|
||||
return new RetreatExecution(intent.playerID, intent.attackID);
|
||||
case "move_warship":
|
||||
return new MoveWarshipExecution(intent.unitId, intent.tile);
|
||||
case "spawn":
|
||||
return new SpawnExecution(
|
||||
new PlayerInfo(
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Execution, Game, Player, PlayerID } from "../game/Game";
|
||||
|
||||
const cancelDelay = 2;
|
||||
|
||||
export class MoveWarshipExecution implements Execution {
|
||||
private active = true;
|
||||
private mg: Game;
|
||||
|
||||
constructor(
|
||||
public readonly unitId: number,
|
||||
public readonly position: number,
|
||||
) {}
|
||||
|
||||
init(mg: Game, ticks: number): void {
|
||||
this.mg = mg;
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
const warship = this.mg.units().find((u) => u.id() == this.unitId);
|
||||
if (!warship) {
|
||||
console.log("MoveWarshipExecution: warship is already dead");
|
||||
return;
|
||||
}
|
||||
warship.setMoveTarget(this.position);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
owner(): Player {
|
||||
const warship = this.mg.units().find((u) => u.id() == this.unitId);
|
||||
return warship ? warship.owner() : null;
|
||||
}
|
||||
|
||||
isActive(): boolean {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
activeDuringSpawnPhase(): boolean {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,70 @@ export class WarshipExecution implements Execution {
|
||||
this.random = new PseudoRandom(mg.ticks());
|
||||
}
|
||||
|
||||
// Only for warships with "moveTarget" set
|
||||
goToMoveTarget(target: TileRef): boolean {
|
||||
// Patrol unless we are hunting down a tradeship
|
||||
const result = this.pathfinder.nextTile(this.warship.tile(), target);
|
||||
switch (result.type) {
|
||||
case PathFindResultType.Completed:
|
||||
this.warship.setMoveTarget(null);
|
||||
return;
|
||||
case PathFindResultType.NextTile:
|
||||
this.warship.move(result.tile);
|
||||
break;
|
||||
case PathFindResultType.Pending:
|
||||
break;
|
||||
case PathFindResultType.PathNotFound:
|
||||
consolex.log(`path not found to target`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private shoot() {
|
||||
if (this.mg.ticks() - this.lastShellAttack > this.shellAttackRate) {
|
||||
this.lastShellAttack = this.mg.ticks();
|
||||
this.mg.addExecution(
|
||||
new ShellExecution(
|
||||
this.warship.tile(),
|
||||
this.warship.owner(),
|
||||
this.warship,
|
||||
this.target,
|
||||
),
|
||||
);
|
||||
if (!this.target.hasHealth()) {
|
||||
// Don't send multiple shells to target that can be oneshotted
|
||||
this.alreadySentShell.add(this.target);
|
||||
this.target = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private patrol() {
|
||||
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(
|
||||
this.warship.tile(),
|
||||
this.patrolTile,
|
||||
);
|
||||
switch (result.type) {
|
||||
case PathFindResultType.Completed:
|
||||
this.patrolTile = this.randomTile();
|
||||
break;
|
||||
case PathFindResultType.NextTile:
|
||||
this.warship.move(result.tile);
|
||||
break;
|
||||
case PathFindResultType.Pending:
|
||||
return;
|
||||
case PathFindResultType.PathNotFound:
|
||||
consolex.log(`path not found to patrol tile`);
|
||||
this.patrolTile = this.randomTile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.warship == null) {
|
||||
const spawn = this._owner.canBuild(UnitType.Warship, this.patrolTile);
|
||||
@@ -110,28 +174,17 @@ export class WarshipExecution implements Execution {
|
||||
return distSortUnit(this.mg, this.warship)(a, b);
|
||||
})[0] ?? null;
|
||||
|
||||
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(
|
||||
this.warship.tile(),
|
||||
this.patrolTile,
|
||||
);
|
||||
switch (result.type) {
|
||||
case PathFindResultType.Completed:
|
||||
this.patrolTile = this.randomTile();
|
||||
break;
|
||||
case PathFindResultType.NextTile:
|
||||
this.warship.move(result.tile);
|
||||
break;
|
||||
case PathFindResultType.Pending:
|
||||
return;
|
||||
case PathFindResultType.PathNotFound:
|
||||
consolex.log(`path not found to patrol tile`);
|
||||
this.patrolTile = this.randomTile();
|
||||
break;
|
||||
if (this.warship.moveTarget()) {
|
||||
this.goToMoveTarget(this.warship.moveTarget());
|
||||
// If we have a "move target" then we cannot target trade ships as it
|
||||
// requires moving.
|
||||
if (this.target && this.target.type() == UnitType.TradeShip) {
|
||||
this.target = null;
|
||||
}
|
||||
} else if (!this.target || this.target.type() != UnitType.TradeShip) {
|
||||
this.patrol();
|
||||
}
|
||||
|
||||
if (
|
||||
this.target == null ||
|
||||
!this.target.isActive() ||
|
||||
@@ -141,25 +194,16 @@ export class WarshipExecution implements Execution {
|
||||
this.target = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.warship.setWarshipTarget(this.target);
|
||||
|
||||
// If we have a move target we do not want to go after trading ships
|
||||
if (!this.target) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.target.type() != UnitType.TradeShip) {
|
||||
if (this.mg.ticks() - this.lastShellAttack > this.shellAttackRate) {
|
||||
this.lastShellAttack = this.mg.ticks();
|
||||
this.mg.addExecution(
|
||||
new ShellExecution(
|
||||
this.warship.tile(),
|
||||
this.warship.owner(),
|
||||
this.warship,
|
||||
this.target,
|
||||
),
|
||||
);
|
||||
if (!this.target.hasHealth()) {
|
||||
// Don't send multiple shells to target that can be oneshotted
|
||||
this.alreadySentShell.add(this.target);
|
||||
this.target = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Only hunt down tradeships
|
||||
this.shoot();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user