mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 17:36:38 +00:00
NPCs send boats at enemies when not adjacent
This commit is contained in:
@@ -16,6 +16,7 @@ import { NukeExecution } from "./NukeExecution";
|
||||
import { MissileSiloExecution } from "./MissileSiloExecution";
|
||||
import { EmojiExecution } from "./EmojiExecution";
|
||||
import { AllianceRequestReplyExecution } from "./alliance/AllianceRequestReplyExecution";
|
||||
import { closestTwoTiles } from "./Util";
|
||||
|
||||
export class FakeHumanExecution implements Execution {
|
||||
|
||||
@@ -186,10 +187,17 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.player.isAlliedWith(this.enemy)) {
|
||||
this.enemy = null
|
||||
return
|
||||
}
|
||||
|
||||
if (this.enemy) {
|
||||
this.maybeSendNuke(this.enemy)
|
||||
if (this.player.sharesBorderWith(this.enemy) && !this.player.isAlliedWith(this.enemy)) {
|
||||
if (this.player.sharesBorderWith(this.enemy)) {
|
||||
this.sendAttack(this.enemy)
|
||||
} else {
|
||||
this.maybeSendBoatAttack(this.enemy)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -221,6 +229,24 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
}
|
||||
|
||||
private maybeSendBoatAttack(other: Player) {
|
||||
const closest = closestTwoTiles(
|
||||
Array.from(this.player.borderTiles()).filter(t => t.isOceanShore()),
|
||||
Array.from(other.borderTiles()).filter(t => t.isOceanShore())
|
||||
)
|
||||
if (closest == null) {
|
||||
return
|
||||
}
|
||||
if (manhattanDist(closest.x.cell(), closest.y.cell()) < this.mg.config().boatMaxDistance()) {
|
||||
this.mg.addExecution(new TransportShipExecution(
|
||||
this.player.id(),
|
||||
other.id(),
|
||||
closest.y.cell(),
|
||||
this.player.troops() / 5
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
private handleUnits() {
|
||||
const ports = this.player.units(UnitType.Port)
|
||||
if (ports.length == 0 && this.player.gold() > this.cost(UnitType.Port)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Game, Cell} from "../game/Game";
|
||||
import { Game, Cell, Tile } from "../game/Game";
|
||||
|
||||
|
||||
export function getSpawnCells(gs: Game, cell: Cell): Cell[] {
|
||||
@@ -23,3 +23,48 @@ export function getSpawnCells(gs: Game, cell: Cell): Cell[] {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function closestTwoTiles(x: Iterable<Tile>, y: Iterable<Tile>): { x: Tile, y: Tile } {
|
||||
const xSorted = Array.from(x).sort((a, b) => a.cell().x - b.cell().x);
|
||||
const ySorted = Array.from(y).sort((a, b) => a.cell().x - b.cell().x);
|
||||
|
||||
if (xSorted.length == 0 || ySorted.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
let j = 0;
|
||||
let minDistance = Infinity;
|
||||
let result = { x: xSorted[0], y: ySorted[0] };
|
||||
|
||||
while (i < xSorted.length && j < ySorted.length) {
|
||||
const currentX = xSorted[i];
|
||||
const currentY = ySorted[j];
|
||||
|
||||
const distance =
|
||||
Math.abs(currentX.cell().x - currentY.cell().x) +
|
||||
Math.abs(currentX.cell().y - currentY.cell().y);
|
||||
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
result = { x: currentX, y: currentY };
|
||||
}
|
||||
|
||||
// If we're at the end of X, must move Y forward
|
||||
if (i === xSorted.length - 1) {
|
||||
j++;
|
||||
}
|
||||
// If we're at the end of Y, must move X forward
|
||||
else if (j === ySorted.length - 1) {
|
||||
i++;
|
||||
}
|
||||
// Otherwise, move whichever pointer has smaller x value
|
||||
else if (currentX.cell().x < currentY.cell().x) {
|
||||
i++;
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user