mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 14:00:54 +00:00
allow boating on lakes
This commit is contained in:
+9
-9
@@ -64,12 +64,12 @@ export function sourceDstOceanShore(
|
||||
tile: TileRef,
|
||||
): [TileRef | null, TileRef | null] {
|
||||
const dst = gm.owner(tile);
|
||||
let srcTile = closestOceanShoreFromPlayer(gm, src, tile);
|
||||
let srcTile = closestShoreFromPlayer(gm, src, tile);
|
||||
let dstTile: TileRef | null = null;
|
||||
if (dst.isPlayer()) {
|
||||
dstTile = closestOceanShoreFromPlayer(gm, dst as Player, tile);
|
||||
dstTile = closestShoreFromPlayer(gm, dst as Player, tile);
|
||||
} else {
|
||||
dstTile = closestOceanShoreTN(gm, tile, 300);
|
||||
dstTile = closestShoreTN(gm, tile, 50);
|
||||
}
|
||||
return [srcTile, dstTile];
|
||||
}
|
||||
@@ -78,20 +78,20 @@ export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null {
|
||||
const dst = gm.playerBySmallID(gm.ownerID(tile));
|
||||
let dstTile: TileRef | null = null;
|
||||
if (dst.isPlayer()) {
|
||||
dstTile = closestOceanShoreFromPlayer(gm, dst as Player, tile);
|
||||
dstTile = closestShoreFromPlayer(gm, dst as Player, tile);
|
||||
} else {
|
||||
dstTile = closestOceanShoreTN(gm, tile, 300);
|
||||
dstTile = closestShoreTN(gm, tile, 50);
|
||||
}
|
||||
return dstTile;
|
||||
}
|
||||
|
||||
export function closestOceanShoreFromPlayer(
|
||||
export function closestShoreFromPlayer(
|
||||
gm: GameMap,
|
||||
player: Player,
|
||||
target: TileRef,
|
||||
): TileRef | null {
|
||||
const shoreTiles = Array.from(player.borderTiles()).filter((t) =>
|
||||
gm.isOceanShore(t),
|
||||
gm.isShore(t),
|
||||
);
|
||||
if (shoreTiles.length == 0) {
|
||||
return null;
|
||||
@@ -112,7 +112,7 @@ export function closestOceanShoreFromPlayer(
|
||||
});
|
||||
}
|
||||
|
||||
function closestOceanShoreTN(
|
||||
function closestShoreTN(
|
||||
gm: GameMap,
|
||||
tile: TileRef,
|
||||
searchDist: number,
|
||||
@@ -123,7 +123,7 @@ function closestOceanShoreTN(
|
||||
andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist)),
|
||||
),
|
||||
)
|
||||
.filter((t) => gm.isOceanShore(t))
|
||||
.filter((t) => gm.isShore(t))
|
||||
.sort((a, b) => gm.manhattanDist(tile, a) - gm.manhattanDist(tile, b));
|
||||
if (tn.length == 0) {
|
||||
return null;
|
||||
|
||||
@@ -128,7 +128,7 @@ export class PlayerExecution implements Execution {
|
||||
const enemies = new Set<number>();
|
||||
for (const tile of cluster) {
|
||||
const isOceanShore = this.mg.isOceanShore(tile);
|
||||
if (this.mg.isShore(tile) && !isOceanShore) {
|
||||
if (this.mg.isOceanShore(tile) && !isOceanShore) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
|
||||
@@ -281,9 +281,9 @@ export class GameMapImpl implements GameMap {
|
||||
q.push(tile);
|
||||
while (q.length > 0) {
|
||||
const curr = q.pop();
|
||||
seen.add(curr);
|
||||
for (const n of this.neighbors(curr)) {
|
||||
if (!seen.has(n) && filter(this, n)) {
|
||||
seen.add(n);
|
||||
q.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
+56
-43
@@ -24,7 +24,7 @@ import { GameUpdateType } from "./GameUpdates";
|
||||
import { ClientID } from "../Schemas";
|
||||
import {
|
||||
assertNever,
|
||||
closestOceanShoreFromPlayer,
|
||||
closestShoreFromPlayer,
|
||||
distSortUnit,
|
||||
maxInt,
|
||||
minInt,
|
||||
@@ -731,10 +731,10 @@ export class PlayerImpl implements Player {
|
||||
}
|
||||
|
||||
transportShipSpawn(targetTile: TileRef): TileRef | false {
|
||||
if (!this.mg.isOceanShore(targetTile)) {
|
||||
if (!this.mg.isShore(targetTile)) {
|
||||
return false;
|
||||
}
|
||||
const spawn = closestOceanShoreFromPlayer(this.mg, this, targetTile);
|
||||
const spawn = closestShoreFromPlayer(this.mg, this, targetTile);
|
||||
if (spawn == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -782,7 +782,6 @@ export class PlayerImpl implements Player {
|
||||
}
|
||||
|
||||
public canBoat(tile: TileRef): boolean {
|
||||
const other = this.mg.owner(tile);
|
||||
if (
|
||||
this.units(UnitType.TransportShip).length >=
|
||||
this.mg.config().boatMaxNumber()
|
||||
@@ -790,54 +789,68 @@ export class PlayerImpl implements Player {
|
||||
return false;
|
||||
}
|
||||
|
||||
let myPlayerBordersOcean = false;
|
||||
for (const bt of this.borderTiles()) {
|
||||
if (this.mg.isOceanShore(bt)) {
|
||||
myPlayerBordersOcean = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let otherPlayerBordersOcean = false;
|
||||
if (!this.mg.hasOwner(tile)) {
|
||||
otherPlayerBordersOcean = true;
|
||||
} else {
|
||||
for (const bt of (other as Player).borderTiles()) {
|
||||
if (this.mg.isOceanShore(bt)) {
|
||||
otherPlayerBordersOcean = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const dst = targetTransportTile(this.mg, tile);
|
||||
if (dst == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const other = this.mg.owner(tile);
|
||||
if (other == this) {
|
||||
return false;
|
||||
}
|
||||
if (other.isPlayer() && this.allianceWith(other)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let nearOcean = false;
|
||||
for (const t of this.mg.bfs(
|
||||
tile,
|
||||
andFN(
|
||||
(gm, t) => gm.ownerID(t) == gm.ownerID(tile) && gm.isLand(t),
|
||||
manhattanDistFN(tile, 25),
|
||||
),
|
||||
)) {
|
||||
if (this.mg.isOceanShore(t)) {
|
||||
nearOcean = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nearOcean) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myPlayerBordersOcean && otherPlayerBordersOcean) {
|
||||
const dst = targetTransportTile(this.mg, tile);
|
||||
if (dst != null) {
|
||||
if (this.canBuild(UnitType.TransportShip, dst)) {
|
||||
return true;
|
||||
if (this.mg.isOceanShore(dst)) {
|
||||
let myPlayerBordersOcean = false;
|
||||
for (const bt of this.borderTiles()) {
|
||||
if (this.mg.isOceanShore(bt)) {
|
||||
myPlayerBordersOcean = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let otherPlayerBordersOcean = false;
|
||||
if (!this.mg.hasOwner(tile)) {
|
||||
otherPlayerBordersOcean = true;
|
||||
} else {
|
||||
for (const bt of (other as Player).borderTiles()) {
|
||||
if (this.mg.isOceanShore(bt)) {
|
||||
otherPlayerBordersOcean = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myPlayerBordersOcean && otherPlayerBordersOcean) {
|
||||
return this.canBuild(UnitType.TransportShip, dst) != false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we are boating in a lake, so do a bfs from target until we find
|
||||
// a border tile owned by the player
|
||||
|
||||
const tiles = this.mg.bfs(
|
||||
dst,
|
||||
andFN(
|
||||
manhattanDistFN(dst, 300),
|
||||
(_, t: TileRef) => this.mg.isLake(t) || this.mg.isShore(t),
|
||||
),
|
||||
);
|
||||
|
||||
const sorted = Array.from(tiles).sort(
|
||||
(a, b) => this.mg.manhattanDist(dst, a) - this.mg.manhattanDist(dst, b),
|
||||
);
|
||||
|
||||
for (const t of sorted) {
|
||||
if (this.mg.owner(t) == this) {
|
||||
return this.canBuild(UnitType.TransportShip, dst) != false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
createAttack(
|
||||
|
||||
@@ -33,7 +33,7 @@ export class PathFinder {
|
||||
if (canMoveOnLand) {
|
||||
return true;
|
||||
}
|
||||
return game.miniMap().isOcean(tr);
|
||||
return game.miniMap().isWater(tr);
|
||||
},
|
||||
iterations,
|
||||
maxTries,
|
||||
|
||||
Reference in New Issue
Block a user