mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-19 09:04:59 +00:00
make radial menu boat button
This commit is contained in:
+1
-1
@@ -75,7 +75,7 @@ export const BoatAttackIntentSchema = BaseIntentSchema.extend({
|
||||
type: z.literal('boat'),
|
||||
attackerID: z.string(),
|
||||
targetID: z.string().nullable(),
|
||||
troops: z.number(),
|
||||
troops: z.number().nullable(),
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
})
|
||||
|
||||
+36
-1
@@ -1,7 +1,7 @@
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
|
||||
|
||||
import {Cell, Player, Tile} from "./game/Game";
|
||||
import {Cell, Game, Player, TerraNullius, Tile} from "./game/Game";
|
||||
|
||||
export function manhattanDist(c1: Cell, c2: Cell): number {
|
||||
return Math.abs(c1.x - c2.x) + Math.abs(c1.y - c2.y);
|
||||
@@ -32,6 +32,41 @@ export function and(x: (tile: Tile) => boolean, y: (tile: Tile) => boolean): (ti
|
||||
return (tile: Tile) => x(tile) && y(tile)
|
||||
}
|
||||
|
||||
// TODO: refactor to new file
|
||||
export function sourceDstOceanShore(game: Game, src: Player, dst: Player | TerraNullius, cell: Cell): [Tile | null, Tile | null] {
|
||||
let srcTile = closestOceanShoreFromPlayer(src, cell, game.width())
|
||||
let dstTile: Tile | null = null
|
||||
if (dst.isPlayer()) {
|
||||
dstTile = closestOceanShoreFromPlayer(dst as Player, cell, game.width())
|
||||
} else {
|
||||
dstTile = closestOceanShoreTN(game.tile(cell), 300)
|
||||
}
|
||||
return [srcTile, dstTile]
|
||||
}
|
||||
|
||||
function closestOceanShoreFromPlayer(player: Player, target: Cell, width: number): Tile | null {
|
||||
const shoreTiles = Array.from(player.borderTiles()).filter(t => t.isOceanShore())
|
||||
if (shoreTiles.length == 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return shoreTiles.reduce((closest, current) => {
|
||||
const closestDistance = manhattanDistWrapped(target, closest.cell(), width);
|
||||
const currentDistance = manhattanDistWrapped(target, current.cell(), width);
|
||||
return currentDistance < closestDistance ? current : closest;
|
||||
});
|
||||
}
|
||||
|
||||
function closestOceanShoreTN(tile: Tile, searchDist: number): Tile {
|
||||
const tn = Array.from(bfs(tile, and(t => !t.hasOwner(), dist(tile, searchDist))))
|
||||
.filter(t => t.isOceanShore())
|
||||
.sort((a, b) => manhattanDist(tile.cell(), a.cell()) - manhattanDist(tile.cell(), b.cell()))
|
||||
if (tn.length == 0) {
|
||||
return null
|
||||
}
|
||||
return tn[0]
|
||||
}
|
||||
|
||||
export function bfs(tile: Tile, filter: (tile: Tile) => boolean): Set<Tile> {
|
||||
const seen = new Set<Tile>
|
||||
const q: Tile[] = []
|
||||
|
||||
@@ -7,7 +7,7 @@ export const devConfig = new class extends DefaultConfig {
|
||||
return 95
|
||||
}
|
||||
numSpawnPhaseTurns(): number {
|
||||
return 80
|
||||
return 40
|
||||
}
|
||||
gameCreationRate(): number {
|
||||
return 2 * 1000
|
||||
@@ -27,9 +27,9 @@ export const devConfig = new class extends DefaultConfig {
|
||||
// return 10 * 10
|
||||
// }
|
||||
|
||||
// numFakeHumans(gameID: GameID): number {
|
||||
// return 0
|
||||
// }
|
||||
numFakeHumans(gameID: GameID): number {
|
||||
return 0
|
||||
}
|
||||
|
||||
// startTroops(playerInfo: PlayerInfo): number {
|
||||
// if (playerInfo.isBot) {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import {PriorityQueue} from "@datastructures-js/priority-queue";
|
||||
import {Boat, Cell, Execution, MutableBoat, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, Tile, TileEvent} from "../game/Game";
|
||||
import {manhattanDist, manhattanDistWrapped} from "../Util";
|
||||
import {and, bfs, manhattanDistWrapped, sourceDstOceanShore} from "../Util";
|
||||
import {AttackExecution} from "./AttackExecution";
|
||||
import {Config} from "../configuration/Config";
|
||||
import {EventBus} from "../EventBus";
|
||||
import {DisplayMessageEvent, MessageType} from "../../client/graphics/layers/EventsDisplay";
|
||||
|
||||
export class BoatAttackExecution implements Execution {
|
||||
@@ -21,8 +19,8 @@ export class BoatAttackExecution implements Execution {
|
||||
|
||||
// TODO make private
|
||||
public path: Tile[]
|
||||
private src: Tile
|
||||
private dst: Tile
|
||||
private src: Tile | null
|
||||
private dst: Tile | null
|
||||
|
||||
private currTileIndex: number = 0
|
||||
|
||||
@@ -37,7 +35,7 @@ export class BoatAttackExecution implements Execution {
|
||||
private attackerID: PlayerID,
|
||||
private targetID: PlayerID | null,
|
||||
private cell: Cell,
|
||||
private troops: number,
|
||||
private troops: number | null,
|
||||
) { }
|
||||
|
||||
activeDuringSpawnPhase(): boolean {
|
||||
@@ -63,11 +61,16 @@ export class BoatAttackExecution implements Execution {
|
||||
this.target = mg.player(this.targetID)
|
||||
}
|
||||
|
||||
if (this.troops == null) {
|
||||
this.troops = this.mg.config().boatAttackAmount(this.attacker, this.target)
|
||||
}
|
||||
|
||||
this.troops = Math.min(this.troops, this.attacker.troops())
|
||||
this.attacker.removeTroops(this.troops)
|
||||
|
||||
this.src = this.closestShoreTile(this.attacker, this.cell)
|
||||
this.dst = this.mg.tile(this.cell)
|
||||
const [srcTile, dstTile]: [Tile | null, Tile | null] = sourceDstOceanShore(this.mg, this.attacker, this.target, this.cell);
|
||||
this.src = srcTile
|
||||
this.dst = dstTile
|
||||
|
||||
if (this.src == null || this.dst == null) {
|
||||
this.active = false
|
||||
@@ -135,18 +138,6 @@ export class BoatAttackExecution implements Execution {
|
||||
return this.active
|
||||
}
|
||||
|
||||
private closestShoreTile(player: Player, target: Cell): Tile | null {
|
||||
const shoreTiles = Array.from(player.borderTiles()).filter(t => t.isOceanShore())
|
||||
if (shoreTiles.length == 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return shoreTiles.reduce((closest, current) => {
|
||||
const closestDistance = manhattanDistWrapped(target, closest.cell(), this.mg.width());
|
||||
const currentDistance = manhattanDistWrapped(target, current.cell(), this.mg.width());
|
||||
return currentDistance < closestDistance ? current : closest;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class AStar {
|
||||
|
||||
Reference in New Issue
Block a user