mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-24 02:28:55 +00:00
Merge branch 'v26'
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user