diff --git a/src/core/execution/NationExecution.ts b/src/core/execution/NationExecution.ts index 854d07b03..25cc06b5a 100644 --- a/src/core/execution/NationExecution.ts +++ b/src/core/execution/NationExecution.ts @@ -360,7 +360,15 @@ export class NationExecution implements Execution { player.addEmbargo(other, false); } else if ( player.relation(other) >= Relation.Neutral && - player.hasEmbargoAgainst(other) + player.hasEmbargoAgainst(other) && + this.mg.config().gameConfig().difficulty !== Difficulty.Hard && + this.mg.config().gameConfig().difficulty !== Difficulty.Impossible + ) { + player.stopEmbargo(other); + } else if ( + player.relation(other) >= Relation.Friendly && + player.hasEmbargoAgainst(other) && + this.mg.config().gameConfig().difficulty !== Difficulty.Impossible ) { player.stopEmbargo(other); } diff --git a/src/core/execution/nation/NationAllianceBehavior.ts b/src/core/execution/nation/NationAllianceBehavior.ts index 5743b6d67..2cffd925f 100644 --- a/src/core/execution/nation/NationAllianceBehavior.ts +++ b/src/core/execution/nation/NationAllianceBehavior.ts @@ -143,10 +143,16 @@ export class NationAllianceBehavior { return false; } - const totalPlayers = this.game.players().length; + const totalPlayers = this.game + .players() + .filter((p) => p.type() !== PlayerType.Bot).length; const otherPlayerAlliances = otherPlayer.alliances().length; - return otherPlayerAlliances >= totalPlayers * 0.5; + if (difficulty !== Difficulty.Hard) { + return otherPlayerAlliances >= totalPlayers * 0.5; + } else { + return otherPlayerAlliances >= totalPlayers * 0.25; + } } private isConfused(): boolean { diff --git a/src/core/execution/nation/NationEmojiBehavior.ts b/src/core/execution/nation/NationEmojiBehavior.ts index e62515bfd..93ba8140a 100644 --- a/src/core/execution/nation/NationEmojiBehavior.ts +++ b/src/core/execution/nation/NationEmojiBehavior.ts @@ -42,6 +42,7 @@ export const EMOJI_BORED = (["🥱"] as const).map(emojiId); export const EMOJI_HANDSHAKE = (["🤝"] as const).map(emojiId); export const EMOJI_DONATION_OK = (["👍"] as const).map(emojiId); export const EMOJI_DONATION_TOO_SMALL = (["❓", "🥱"] as const).map(emojiId); +export const EMOJI_GREET = (["👋"] as const).map(emojiId); export class NationEmojiBehavior { private readonly lastEmojiSent = new Map(); @@ -63,6 +64,7 @@ export class NationEmojiBehavior { this.charmAllies(); this.annoyTraitors(); this.findRat(); + this.greetNearbyPlayers(); } private checkOverwhelmedByAttacks(): void { @@ -203,6 +205,22 @@ export class NationEmojiBehavior { this.sendEmoji(smallPlayer, EMOJI_RAT); } + private greetNearbyPlayers(): void { + if (this.game.ticks() > 600) return; // Only in the first minute + if (!this.random.chance(250)) return; + + const nearbyHumans = this.player + .neighbors() + .filter( + (p): p is Player => p.isPlayer() && p.type() === PlayerType.Human, + ); + + if (nearbyHumans.length === 0) return; + + const neighbor = this.random.randElement(nearbyHumans); + this.sendEmoji(neighbor, EMOJI_GREET); + } + maybeSendEmoji( otherPlayer: Player | typeof AllPlayers, emojisList: number[], diff --git a/src/core/execution/nation/NationWarshipBehavior.ts b/src/core/execution/nation/NationWarshipBehavior.ts index 5dc7b0344..d476e5653 100644 --- a/src/core/execution/nation/NationWarshipBehavior.ts +++ b/src/core/execution/nation/NationWarshipBehavior.ts @@ -99,7 +99,11 @@ export class NationWarshipBehavior { if (!ship.isActive()) { // Distinguish between arrival/retreat and enemy destruction if (ship.wasDestroyedByEnemy() && ship.destroyer() !== undefined) { - this.maybeRetaliateWithWarship(ship.tile(), ship.destroyer()!); + this.maybeRetaliateWithWarship( + ship.tile(), + ship.destroyer()!, + "transport", + ); } this.trackedTransportShips.delete(ship); } @@ -121,13 +125,17 @@ export class NationWarshipBehavior { } if (ship.owner().id() !== this.player.id()) { // Ship was ours and is now owned by someone else -> captured - this.maybeRetaliateWithWarship(ship.tile(), ship.owner()); + this.maybeRetaliateWithWarship(ship.tile(), ship.owner(), "trade"); this.trackedTradeShips.delete(ship); } } } - private maybeRetaliateWithWarship(tile: TileRef, enemy: Player): void { + private maybeRetaliateWithWarship( + tile: TileRef, + enemy: Player, + reason: "trade" | "transport", + ): void { // Don't send too many warships if (this.player.units(UnitType.Warship).length >= 10) { return; @@ -148,6 +156,7 @@ export class NationWarshipBehavior { new ConstructionExecution(this.player, UnitType.Warship, tile), ); this.emojiBehavior.maybeSendEmoji(enemy, EMOJI_WARSHIP_RETALIATION); + this.player.updateRelation(enemy, reason === "trade" ? -7.5 : -15); } }