Merge branch 'v26'

This commit is contained in:
evanpelle
2025-11-07 19:54:27 -08:00
14 changed files with 22 additions and 417 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
import { GameView } from "../../../core/game/GameView";
import { Layer } from "./Layer";
const AD_SHOW_TICKS = 60 * 10; // 1 minute
const AD_SHOW_TICKS = 2 * 60 * 10; // 2 minutes
export class AdTimer implements Layer {
private isHidden: boolean = false;
+4
View File
@@ -225,6 +225,7 @@ export async function postRefresh(): Promise<boolean> {
// Refresh the JWT
const response = await fetch(getApiBase() + "/refresh", {
method: "POST",
credentials: "include",
headers: {
authorization: `Bearer ${token}`,
},
@@ -242,6 +243,9 @@ export async function postRefresh(): Promise<boolean> {
return false;
}
localStorage.setItem("token", result.data.token);
// Clear the cached logged in state
// so that the next call to isLoggedIn() will refresh the token
__isLoggedIn = undefined;
return true;
} catch (e) {
__isLoggedIn = false;
+2 -3
View File
@@ -173,9 +173,8 @@ export abstract class DefaultServerConfig implements ServerConfig {
turnIntervalMs(): number {
return 100;
}
gameCreationRate(): number {
return 30 * 1000;
return 60 * 1000;
}
lobbyMaxPlayers(
@@ -693,7 +692,7 @@ export class DefaultConfig implements Config {
if (attacker.isPlayer() && defender.isPlayer()) {
if (defender.isDisconnected() && attacker.isOnSameTeam(defender)) {
// No troop loss if defender is disconnected and on same team
// No troop loss if defender is disconnected.
mag = 0;
}
if (
-6
View File
@@ -181,12 +181,6 @@ export class AttackExecution implements Execution {
this._owner.id(),
);
}
if (this.removeTroops === false) {
// startTroops are always added to attack troops at init but not always removed from owner troops
// subtract startTroops from attack troops so we don't give back startTroops to owner that were never removed
this.attack.setTroops(this.attack.troops() - (this.startTroops ?? 0));
}
const survivors = this.attack.troops() - deaths;
this._owner.addTroops(survivors);
this.attack.delete();
+4 -40
View File
@@ -33,17 +33,13 @@ export class TransportShipExecution implements Execution {
private pathFinder: PathFinder;
private originalOwner: Player;
constructor(
private attacker: Player,
private targetID: PlayerID | null,
private ref: TileRef,
private startTroops: number,
private src: TileRef | null,
) {
this.originalOwner = this.attacker;
}
) {}
activeDuringSpawnPhase(): boolean {
return false;
@@ -177,43 +173,11 @@ export class TransportShipExecution implements Execution {
}
this.lastMove = ticks;
// Team mate can conquer disconnected player and get their ships
// captureUnit has changed the owner of the unit, now update attacker
if (
this.originalOwner.isDisconnected() &&
this.boat.owner() !== this.originalOwner &&
this.boat.owner().isOnSameTeam(this.originalOwner)
) {
this.attacker = this.boat.owner();
this.originalOwner = this.boat.owner(); // for when this owner disconnects too
}
if (this.boat.retreating()) {
// Ensure retreat source is valid for the new owner
if (this.mg.owner(this.src!) !== this.attacker) {
// Use bestTransportShipSpawn, not canBuild because of its max boats check etc
const newSrc = this.attacker.bestTransportShipSpawn(this.dst);
if (newSrc === false) {
this.src = null;
} else {
this.src = newSrc;
}
}
this.dst = this.src!; // src is guaranteed to be set at this point
if (this.src === null) {
console.warn(
`TransportShipExecution: retreating but no src found for new attacker`,
);
this.attacker.addTroops(this.boat.troops());
this.boat.delete(false);
this.active = false;
return;
} else {
this.dst = this.src;
if (this.boat.targetTile() !== this.dst) {
this.boat.setTargetTile(this.dst);
}
if (this.boat.targetTile() !== this.dst) {
this.boat.setTargetTile(this.dst);
}
}
+5 -1
View File
@@ -55,6 +55,10 @@ export class WarshipExecution implements Execution {
this.warship.delete();
return;
}
if (this.warship.owner().isDisconnected()) {
this.warship.delete();
return;
}
const hasPort = this.warship.owner().unitCount(UnitType.Port) > 0;
if (hasPort) {
@@ -89,7 +93,7 @@ export class WarshipExecution implements Execution {
if (
unit.owner() === this.warship.owner() ||
unit === this.warship ||
unit.owner().isFriendly(this.warship.owner(), true) ||
unit.owner().isFriendly(this.warship.owner()) ||
this.alreadySentShell.has(unit)
) {
continue;
+1 -1
View File
@@ -594,7 +594,7 @@ export interface Player {
decayRelations(): void;
isOnSameTeam(other: Player): boolean;
// Either allied or on same team.
isFriendly(other: Player, treatAFKFriendly?: boolean): boolean;
isFriendly(other: Player): boolean;
team(): Team | null;
clan(): string | null;
incomingAllianceRequests(): AllianceRequest[];
-14
View File
@@ -895,20 +895,6 @@ export class GameImpl implements Game {
return this._railNetwork;
}
conquerPlayer(conqueror: Player, conquered: Player) {
if (conquered.isDisconnected() && conqueror.isOnSameTeam(conquered)) {
const ships = conquered
.units()
.filter(
(u) =>
u.type() === UnitType.Warship ||
u.type() === UnitType.TransportShip,
);
for (const ship of ships) {
conqueror.captureUnit(ship);
}
}
const gold = conquered.gold();
this.displayMessage(
`Conquered ${conquered.displayName()} received ${renderNumber(
+2 -2
View File
@@ -789,8 +789,8 @@ export class PlayerImpl implements Player {
return this._team === other.team();
}
isFriendly(other: Player, treatAFKFriendly: boolean = false): boolean {
if (other.isDisconnected() && !treatAFKFriendly) {
isFriendly(other: Player): boolean {
if (other.isDisconnected()) {
return false;
}
return this.isOnSameTeam(other) || this.isAlliedWith(other);
-2
View File
@@ -148,8 +148,6 @@ export function bestShoreDeploymentSource(
if (t === null) return false;
const candidates = candidateShoreTiles(gm, player, t);
if (candidates.length === 0) return false;
const aStar = new MiniAStar(gm, gm.miniMap(), candidates, t, 1_000_000, 1);
const result = aStar.compute();
if (result !== PathFindResultType.Completed) {
+1 -1
View File
@@ -25,7 +25,7 @@ const frequency: Partial<Record<GameMapName, number>> = {
Africa: 7,
Asia: 6,
Australia: 4,
Achiran: 14,
Achiran: 5,
Baikal: 5,
BetweenTwoSeas: 5,
BlackSea: 6,