Merge branch 'main' into rejoingame

This commit is contained in:
Ryan
2026-02-04 19:13:46 +00:00
committed by GitHub
6 changed files with 40 additions and 4 deletions
+1
View File
@@ -655,6 +655,7 @@ export class HostLobbyModal extends BaseModal {
detail: {
gameID: this.lobbyId,
clientID: this.lobbyCreatorClientID,
source: "host",
} as JoinLobbyEvent,
bubbles: true,
composed: true,
+3
View File
@@ -336,6 +336,7 @@ export class JoinLobbyModal extends BaseModal {
detail: {
gameID: lobbyId,
clientID: this.currentClientID,
source: "public",
} as JoinLobbyEvent,
bubbles: true,
composed: true,
@@ -776,6 +777,7 @@ export class JoinLobbyModal extends BaseModal {
detail: {
gameID: lobbyId,
clientID: this.currentClientID,
source: "private",
} as JoinLobbyEvent,
bubbles: true,
composed: true,
@@ -834,6 +836,7 @@ export class JoinLobbyModal extends BaseModal {
gameID: lobbyId,
gameRecord: parsed.data,
clientID: this.currentClientID,
source: "private",
} as JoinLobbyEvent,
bubbles: true,
composed: true,
+1
View File
@@ -231,6 +231,7 @@ export class MatchmakingModal extends BaseModal {
detail: {
gameID: this.gameID,
clientID: getClientIDForGame(this.gameID),
source: "matchmaking",
} as JoinLobbyEvent,
bubbles: true,
composed: true,
+1
View File
@@ -967,6 +967,7 @@ export class SinglePlayerModal extends BaseModal {
},
lobbyCreatedAt: Date.now(), // ms; server should be authoritative in MP
},
source: "singleplayer",
} satisfies JoinLobbyEvent,
bubbles: true,
composed: true,
+11 -1
View File
@@ -1,7 +1,8 @@
import { Execution, Game, Player } from "../game/Game";
import { Execution, Game, isStructureType, Player } from "../game/Game";
import { PseudoRandom } from "../PseudoRandom";
import { simpleHash } from "../Util";
import { AllianceExtensionExecution } from "./alliance/AllianceExtensionExecution";
import { DeleteUnitExecution } from "./DeleteUnitExecution";
import { AiAttackBehavior } from "./utils/AiAttackBehavior";
export class BotExecution implements Execution {
@@ -58,6 +59,7 @@ export class BotExecution implements Execution {
}
this.acceptAllAllianceRequests();
this.deleteAllStructures();
this.maybeAttack();
}
@@ -80,6 +82,14 @@ export class BotExecution implements Execution {
}
}
private deleteAllStructures() {
for (const unit of this.bot.units()) {
if (isStructureType(unit.type()) && this.bot.canDeleteUnit()) {
this.mg.addExecution(new DeleteUnitExecution(this.bot, unit.id()));
}
}
}
private maybeAttack() {
if (this.attackBehavior === null) {
throw new Error("not initialized");
+23 -3
View File
@@ -20,6 +20,7 @@ import {
ColoredTeams,
Embargo,
EmojiMessage,
GameMode,
Gold,
MessageType,
MutableAlliance,
@@ -29,6 +30,7 @@ import {
PlayerProfile,
PlayerType,
Relation,
StructureTypes,
Team,
TerraNullius,
Tick,
@@ -994,10 +996,10 @@ export class PlayerImpl implements Player {
if (!this.mg.hasOwner(targetTile)) {
return false;
}
return this.nukeSpawn(targetTile);
return this.nukeSpawn(targetTile, unitType);
case UnitType.AtomBomb:
case UnitType.HydrogenBomb:
return this.nukeSpawn(targetTile);
return this.nukeSpawn(targetTile, unitType);
case UnitType.MIRVWarhead:
return targetTile;
case UnitType.Port:
@@ -1024,7 +1026,7 @@ export class PlayerImpl implements Player {
}
}
nukeSpawn(tile: TileRef): TileRef | false {
nukeSpawn(tile: TileRef, nukeType: UnitType): TileRef | false {
if (this.mg.isSpawnImmunityActive()) {
return false;
}
@@ -1034,6 +1036,24 @@ export class PlayerImpl implements Player {
return false;
}
}
// Prevent launching nukes that would hit teammate structures (only in team games)
if (
this.mg.config().gameConfig().gameMode === GameMode.Team &&
nukeType !== UnitType.MIRV
) {
const magnitude = this.mg.config().nukeMagnitudes(nukeType);
const wouldHitTeammate = this.mg.anyUnitNearby(
tile,
magnitude.outer,
StructureTypes,
(unit) => unit.owner().isPlayer() && this.isOnSameTeam(unit.owner()),
);
if (wouldHitTeammate) {
return false;
}
}
// only get missilesilos that are not on cooldown and not under construction
const spawns = this.units(UnitType.MissileSilo)
.filter((silo) => {