mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 07:50:45 +00:00
refactored alliance
This commit is contained in:
@@ -130,12 +130,13 @@
|
||||
* BUG: left click lost after right click DONE 9/20/2024
|
||||
* eventbox events dissapear after timeout DONE 9/20/2024
|
||||
* auto reject alliance when event dissapears DONE 9/20/2024
|
||||
* first place has crown DONE 9/20/2024
|
||||
* can't attack ally DONE 9/20/2024
|
||||
* add updates to eventbox: boats (max count, too far) DONE 9/20/2024
|
||||
* BUG: boats landing doesn't launch attack DONE 9/20/2024
|
||||
* fake humans handle alliances
|
||||
* first place has crown DONE 9/21/2024
|
||||
* can't attack ally DONE 9/21/2024
|
||||
* add updates to eventbox: boats (max count, too far) DONE 9/21/2024
|
||||
* BUG: boats landing doesn't launch attack DONE 9/21/2024
|
||||
* fake humans handle alliances DONE 9/22/2024
|
||||
* make alliances expire
|
||||
* make alliance request mobile friendly
|
||||
* make year clock
|
||||
* block user inputs if too far behind server
|
||||
* BUG: FakeHuman don't be enemy if don't share border
|
||||
|
||||
@@ -208,7 +208,7 @@ export class ClientGame {
|
||||
if (tile.owner() == this.myPlayer) {
|
||||
return
|
||||
}
|
||||
if (tile.owner().isPlayer() && this.myPlayer.alliedWith(tile.owner() as Player)) {
|
||||
if (tile.owner().isPlayer() && this.myPlayer.isAlliedWith(tile.owner() as Player)) {
|
||||
this.eventBus.emit(new DisplayMessageEvent("Cannot attack ally", MessageType.WARN))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ export class NameLayer implements Layer {
|
||||
}
|
||||
|
||||
const myPlayer = this.getPlayer()
|
||||
if (myPlayer != null && myPlayer.alliedWith(render.player)) {
|
||||
if (myPlayer != null && myPlayer.isAlliedWith(render.player)) {
|
||||
context.drawImage(
|
||||
this.allianceIconImage,
|
||||
nameCenterX - iconSize / 2,
|
||||
|
||||
@@ -260,7 +260,7 @@ export class UILayer implements Layer {
|
||||
return
|
||||
}
|
||||
|
||||
if (myPlayer.alliedWith(owner)) {
|
||||
if (myPlayer.isAlliedWith(owner)) {
|
||||
options.push({
|
||||
label: "Break Alliance",
|
||||
action: (): void => {
|
||||
|
||||
@@ -86,7 +86,7 @@ export class AttackExecution implements Execution {
|
||||
}
|
||||
|
||||
if (this.target.isPlayer()) {
|
||||
if (this._owner.alliedWith(this.target)) {
|
||||
if (this._owner.isAlliedWith(this.target)) {
|
||||
// No updates should happen in init.
|
||||
this.breakAlliance = true
|
||||
}
|
||||
@@ -109,11 +109,12 @@ export class AttackExecution implements Execution {
|
||||
if (ticks < this.mg.config().numSpawnPhaseTurns()) {
|
||||
return
|
||||
}
|
||||
if (this.breakAlliance && this._owner.alliedWith(this.target as Player)) {
|
||||
const alliance = this._owner.allianceWith(this.target as Player)
|
||||
if (this.breakAlliance && alliance != null) {
|
||||
this.breakAlliance = false
|
||||
this._owner.breakAllianceWith(this.target as Player)
|
||||
this._owner.breakAlliance(alliance)
|
||||
}
|
||||
if (this.target.isPlayer() && this._owner.alliedWith(this.target)) {
|
||||
if (this.target.isPlayer() && this._owner.isAlliedWith(this.target)) {
|
||||
// In this case a new alliance was created AFTER the attack started.
|
||||
this._owner.addTroops(this.troops)
|
||||
this.active = false
|
||||
|
||||
@@ -51,7 +51,7 @@ export class BotExecution implements Execution {
|
||||
const traitors = this.bot.neighbors().filter(n => n.isPlayer() && n.isTraitor()) as Player[]
|
||||
if (traitors.length > 0) {
|
||||
const toAttack = this.random.randElement(traitors)
|
||||
const odds = this.bot.alliedWith(toAttack) ? 6 : 3
|
||||
const odds = this.bot.isAlliedWith(toAttack) ? 6 : 3
|
||||
if (this.random.chance(odds)) {
|
||||
this.sendAttack(toAttack)
|
||||
return
|
||||
@@ -80,7 +80,7 @@ export class BotExecution implements Execution {
|
||||
const owner = toAttack.owner()
|
||||
|
||||
if (owner.isPlayer()) {
|
||||
if (this.bot.alliedWith(owner)) {
|
||||
if (this.bot.isAlliedWith(owner)) {
|
||||
return
|
||||
}
|
||||
if (owner.type() == PlayerType.FakeHuman) {
|
||||
|
||||
@@ -100,17 +100,17 @@ export class FakeHumanExecution implements Execution {
|
||||
|
||||
if (this.random.chance(10)) {
|
||||
const toAlly = this.random.randElement(enemies)
|
||||
if (!this.player.alliedWith(toAlly)) {
|
||||
if (!this.player.isAlliedWith(toAlly)) {
|
||||
this.player.createAllianceRequest(toAlly)
|
||||
}
|
||||
}
|
||||
|
||||
if (this.random.chance(2)) {
|
||||
if (!this.player.alliedWith(enemies[0]) || this.random.chance(30)) {
|
||||
if (!this.player.isAlliedWith(enemies[0]) || this.random.chance(30)) {
|
||||
this.sendAttack(enemies[0])
|
||||
}
|
||||
} else {
|
||||
if (!this.player.alliedWith(enemies[0]) || this.random.chance(60)) {
|
||||
if (!this.player.isAlliedWith(enemies[0]) || this.random.chance(60)) {
|
||||
this.sendAttack(this.random.randElement(enemies))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export class PlayerExecution implements Execution {
|
||||
|
||||
const main = clusters.shift()
|
||||
const surroundedBy = this.surroundedBySamePlayer(main)
|
||||
if (surroundedBy && !this.player.alliedWith(surroundedBy)) {
|
||||
if (surroundedBy && !this.player.isAlliedWith(surroundedBy)) {
|
||||
this.removeCluster(main)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export class AllianceRequestExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.requestor.alliedWith(this.recipient)) {
|
||||
if (this.requestor.isAlliedWith(this.recipient)) {
|
||||
console.warn('already allied')
|
||||
} else {
|
||||
this.requestor.createAllianceRequest(this.recipient)
|
||||
|
||||
@@ -15,7 +15,7 @@ export class AllianceRequestReplyExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.requestor.alliedWith(this.recipient)) {
|
||||
if (this.requestor.isAlliedWith(this.recipient)) {
|
||||
console.warn('already allied')
|
||||
} else {
|
||||
const request = this.requestor.outgoingAllianceRequests().find(ar => ar.recipient() == this.recipient)
|
||||
|
||||
@@ -13,10 +13,11 @@ export class BreakAllianceExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (!this.requestor.alliedWith(this.recipient)) {
|
||||
const alliance = this.requestor.allianceWith(this.recipient)
|
||||
if (alliance == null) {
|
||||
console.warn('cant break alliance, not allied')
|
||||
} else {
|
||||
this.requestor.breakAllianceWith(this.recipient)
|
||||
this.requestor.breakAlliance(alliance)
|
||||
}
|
||||
this.active = false
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {MutableAlliance, MutablePlayer, Player} from "./Game";
|
||||
import {MutableAlliance, MutableGame, MutablePlayer, Player, Tick} from "./Game";
|
||||
import {GameImpl} from "./GameImpl";
|
||||
import {PlayerImpl} from "./PlayerImpl";
|
||||
|
||||
export class AllianceImpl implements MutableAlliance {
|
||||
constructor(
|
||||
private readonly mg: GameImpl,
|
||||
readonly requestor_: PlayerImpl,
|
||||
readonly recepient_: PlayerImpl,
|
||||
readonly createdAtTick_: number,
|
||||
readonly recipient_: PlayerImpl,
|
||||
readonly createdAtTick_: Tick,
|
||||
) { }
|
||||
|
||||
requestor(): MutablePlayer {
|
||||
@@ -13,7 +15,15 @@ export class AllianceImpl implements MutableAlliance {
|
||||
}
|
||||
|
||||
recipient(): MutablePlayer {
|
||||
return this.recepient_
|
||||
return this.recipient_
|
||||
}
|
||||
|
||||
createdAt(): Tick {
|
||||
return this.createdAtTick_
|
||||
}
|
||||
|
||||
expire(): void {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,8 +3,10 @@ import {Config} from "../configuration/Config"
|
||||
import {GameEvent} from "../EventBus"
|
||||
import {ClientID, GameID} from "../Schemas"
|
||||
import {DisplayMessageEvent, MessageType} from "../../client/graphics/layers/EventsDisplay"
|
||||
import {BreakAllianceExecution} from "../execution/alliance/BreakAllianceExecution"
|
||||
|
||||
export type PlayerID = string
|
||||
export type Tick = number
|
||||
|
||||
export class Cell {
|
||||
|
||||
@@ -60,10 +62,11 @@ export interface MutableAllianceRequest extends AllianceRequest {
|
||||
export interface Alliance {
|
||||
requestor(): Player
|
||||
recipient(): Player
|
||||
createdAt(): Tick
|
||||
}
|
||||
|
||||
export interface MutableAlliance extends Alliance {
|
||||
|
||||
expire(): void
|
||||
}
|
||||
|
||||
export class PlayerInfo {
|
||||
@@ -138,7 +141,8 @@ export interface Player {
|
||||
incomingAllianceRequests(): AllianceRequest[]
|
||||
outgoingAllianceRequests(): AllianceRequest[]
|
||||
alliances(): Alliance[]
|
||||
alliedWith(other: Player): boolean
|
||||
isAlliedWith(other: Player): boolean
|
||||
allianceWith(other: Player): Alliance | null
|
||||
pendingAllianceRequestWith(other: Player): boolean
|
||||
isTraitor(): boolean
|
||||
toString(): string
|
||||
@@ -157,7 +161,8 @@ export interface MutablePlayer extends Player {
|
||||
incomingAllianceRequests(): MutableAllianceRequest[]
|
||||
outgoingAllianceRequests(): MutableAllianceRequest[]
|
||||
alliances(): MutableAlliance[]
|
||||
breakAllianceWith(other: Player): void
|
||||
allianceWith(other: Player): MutableAlliance | null
|
||||
breakAlliance(alliance: Alliance): void
|
||||
createAllianceRequest(recipient: Player): MutableAllianceRequest
|
||||
addBoat(troops: number, tile: Tile, target: Player | TerraNullius): MutableBoat
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {info} from "console";
|
||||
import {Config} from "../configuration/Config";
|
||||
import {EventBus} from "../EventBus";
|
||||
import {Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Boat, BoatEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent} from "./Game";
|
||||
import {Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Boat, BoatEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent, MutableAlliance, Alliance} from "./Game";
|
||||
import {TerrainMap} from "./TerrainMapLoader";
|
||||
import {PlayerImpl} from "./PlayerImpl";
|
||||
import {TerraNulliusImpl} from "./TerraNulliusImpl";
|
||||
@@ -50,7 +50,7 @@ export class GameImpl implements MutableGame {
|
||||
}
|
||||
|
||||
createAllianceRequest(requestor: MutablePlayer, recipient: Player): MutableAllianceRequest {
|
||||
if (requestor.alliedWith(recipient)) {
|
||||
if (requestor.isAlliedWith(recipient)) {
|
||||
console.log('cannot request alliance, already allied')
|
||||
return
|
||||
}
|
||||
@@ -72,7 +72,7 @@ export class GameImpl implements MutableGame {
|
||||
|
||||
acceptAllianceRequest(request: AllianceRequestImpl) {
|
||||
this.allianceRequests = this.allianceRequests.filter(ar => ar != request)
|
||||
const alliance = new AllianceImpl(request.requestor() as PlayerImpl, request.recipient() as PlayerImpl, this._ticks)
|
||||
const alliance = new AllianceImpl(this, request.requestor() as PlayerImpl, request.recipient() as PlayerImpl, this._ticks)
|
||||
this.alliances_.push(alliance)
|
||||
this.eventBus.emit(new AllianceRequestReplyEvent(request, true))
|
||||
}
|
||||
@@ -343,7 +343,20 @@ export class GameImpl implements MutableGame {
|
||||
this.eventBus.emit(new BoatEvent(boat, oldTile))
|
||||
}
|
||||
|
||||
public breakAlliance(breaker: Player, other: Player) {
|
||||
public breakAlliance(breaker: Player, alliance: Alliance) {
|
||||
let other: Player = null
|
||||
if (alliance.requestor() == breaker) {
|
||||
other = alliance.recipient()
|
||||
} else {
|
||||
other = alliance.requestor()
|
||||
}
|
||||
if (!breaker.isAlliedWith(other)) {
|
||||
throw new Error(`${breaker} not allied with ${other}, cannot break alliance`)
|
||||
}
|
||||
if (!other.isTraitor()) {
|
||||
(breaker as PlayerImpl).isTraitor_ = true
|
||||
}
|
||||
|
||||
const breakerSet = new Set(breaker.alliances())
|
||||
const alliances = other.alliances().filter(a => breakerSet.has(a))
|
||||
if (alliances.length != 1) {
|
||||
|
||||
+15
-15
@@ -1,4 +1,4 @@
|
||||
import {MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, MutableGame, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance} from "./Game";
|
||||
import {MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, MutableGame, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance} from "./Game";
|
||||
import {ClientID} from "../Schemas";
|
||||
import {simpleHash} from "../Util";
|
||||
import {CellString, GameImpl} from "./GameImpl";
|
||||
@@ -9,7 +9,7 @@ import {threadId} from "worker_threads";
|
||||
|
||||
|
||||
export class PlayerImpl implements MutablePlayer {
|
||||
private isTraitor_ = false
|
||||
isTraitor_ = false
|
||||
|
||||
public _borderTiles: Set<Tile> = new Set();
|
||||
|
||||
@@ -123,35 +123,35 @@ export class PlayerImpl implements MutablePlayer {
|
||||
return this.gs.alliances_.filter(a => a.requestor() == this || a.recipient() == this)
|
||||
}
|
||||
|
||||
alliedWith(other: Player): boolean {
|
||||
isAlliedWith(other: Player): boolean {
|
||||
if (other == this) {
|
||||
return false
|
||||
}
|
||||
return this.alliances().find(a => a.recipient() == other || a.requestor() == other) != null
|
||||
return this.allianceWith(other) != null
|
||||
}
|
||||
|
||||
allianceWith(other: Player): MutableAlliance | null {
|
||||
return this.alliances().find(a => a.recipient() == other || a.requestor() == other)
|
||||
}
|
||||
|
||||
|
||||
pendingAllianceRequestWith(other: Player): boolean {
|
||||
return this.incomingAllianceRequests().find(ar => ar.requestor() == other) != null
|
||||
|| this.outgoingAllianceRequests().find(ar => ar.recipient() == other) != null
|
||||
|
||||
}
|
||||
|
||||
breakAlliance(alliance: Alliance): void {
|
||||
this.gs.breakAlliance(this, alliance)
|
||||
}
|
||||
|
||||
|
||||
isTraitor(): boolean {
|
||||
return this.isTraitor_
|
||||
}
|
||||
|
||||
breakAllianceWith(other: Player): void {
|
||||
if (!this.alliedWith(other)) {
|
||||
throw new Error('cannot break alliance, already allied')
|
||||
}
|
||||
if (!other.isTraitor()) {
|
||||
this.isTraitor_ = true
|
||||
}
|
||||
this.gs.breakAlliance(this, other)
|
||||
}
|
||||
|
||||
createAllianceRequest(recipient: Player): MutableAllianceRequest {
|
||||
if (this.alliedWith(recipient)) {
|
||||
if (this.isAlliedWith(recipient)) {
|
||||
throw new Error(`cannot create alliance request, already allies`)
|
||||
}
|
||||
return this.gs.createAllianceRequest(this, recipient)
|
||||
|
||||
Reference in New Issue
Block a user