Added custom disable settings (#593)

## Description:
I will write an issue later as I don't have time.

![スクリーンショット 2025-04-23 22 04
24](https://github.com/user-attachments/assets/77754140-eee9-46bd-a98f-a3abec35ca6a)
<img width="735" alt="スクリーンショット 2025-04-23 22 04 40"
src="https://github.com/user-attachments/assets/24bb3461-8e05-418c-8dbf-2ba1a624fe27"
/>
<img width="790" alt="スクリーンショット 2025-04-23 22 04 47"
src="https://github.com/user-attachments/assets/33387200-d0af-4394-9d60-af1f88a036e9"
/>

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:
aotumuri
This commit is contained in:
Aotumuri
2025-05-07 22:14:54 +09:00
committed by GitHub
parent b3c59da29d
commit cddcc681dd
13 changed files with 177 additions and 71 deletions
+68 -13
View File
@@ -9,6 +9,7 @@ import {
Duos,
GameMapType,
GameMode,
UnitType,
mapCategories,
} from "../core/game/Game";
import { GameConfig, GameInfo } from "../core/Schemas";
@@ -39,6 +40,7 @@ export class HostLobbyModal extends LitElement {
@state() private copySuccess = false;
@state() private players: string[] = [];
@state() private useRandomMap: boolean = false;
@state() private disabledUnits: string[] = [];
private playersInterval = null;
// Add a new timer for debouncing bot changes
@@ -302,21 +304,72 @@ export class HostLobbyModal extends LitElement {
</div>
</label>
<label
for="disable-nukes"
class="option-card ${this.disableNukes ? "selected" : ""}"
<hr style="width: 100%; border-top: 1px solid #444; margin: 16px 0;" />
<!-- Individual disables for structures/weapons -->
<div
style="margin: 8px 0 12px 0; font-weight: bold; color: #ccc; text-align: center;"
>
<div class="checkbox-icon"></div>
<input
type="checkbox"
id="disable-nukes"
@change=${this.handleDisableNukesChange}
.checked=${this.disableNukes}
/>
<div class="option-card-title">
${translateText("host_modal.disable_nukes")}
${translateText("host_modal.enables_title")}
</div>
<div
style="display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;"
>
${[
[UnitType.City, "unit_type.city"],
[UnitType.DefensePost, "unit_type.defense_post"],
[UnitType.Port, "unit_type.port"],
[UnitType.Warship, "unit_type.warship"],
[UnitType.MissileSilo, "unit_type.missile_silo"],
[UnitType.SAMLauncher, "unit_type.sam_launcher"],
[UnitType.AtomBomb, "unit_type.atom_bomb"],
[UnitType.HydrogenBomb, "unit_type.hydrogen_bomb"],
[UnitType.MIRV, "unit_type.mirv"],
].map(
([unitType, translationKey]) => html`
<label
class="option-card ${this.disabledUnits.includes(
unitType,
)
? ""
: "selected"}"
style="width: 140px;"
>
<div class="checkbox-icon"></div>
<input
type="checkbox"
@change=${(e: Event) => {
const checked = (e.target as HTMLInputElement)
.checked;
const parsedUnitType =
UnitType[unitType as keyof typeof UnitType];
if (parsedUnitType) {
if (checked) {
this.disabledUnits = [
...this.disabledUnits,
parsedUnitType,
];
} else {
this.disabledUnits = this.disabledUnits.filter(
(u) => u !== parsedUnitType,
);
}
this.putGameConfig();
}
}}
.checked=${this.disabledUnits.includes(unitType)}
/>
<div
class="option-card-title"
style="text-align: center;"
>
${translateText(translationKey)}
</div>
</label>
`,
)}
</div>
</label>
</div>
</div>
</div>
</div>
@@ -490,6 +543,8 @@ export class HostLobbyModal extends LitElement {
infiniteTroops: this.infiniteTroops,
instantBuild: this.instantBuild,
gameMode: this.gameMode,
numPlayerTeams: this.teamCount,
disabledUnits: this.disabledUnits,
playerTeams: this.teamCount,
} as GameConfig),
},
+58 -15
View File
@@ -9,6 +9,7 @@ import {
GameMapType,
GameMode,
GameType,
UnitType,
mapCategories,
} from "../core/game/Game";
import { generateID } from "../core/Util";
@@ -39,6 +40,8 @@ export class SinglePlayerModal extends LitElement {
@state() private gameMode: GameMode = GameMode.FFA;
@state() private teamCount: number | typeof Duos = 2;
@state() private disabledUnits: string[] = [];
render() {
return html`
<o-modal title=${translateText("single_modal.title")}>
@@ -269,22 +272,61 @@ export class SinglePlayerModal extends LitElement {
${translateText("single_modal.infinite_troops")}
</div>
</label>
</div>
<label
for="singleplayer-modal-disable-nukes"
class="option-card ${this.disableNukes ? "selected" : ""}"
>
<div class="checkbox-icon"></div>
<input
type="checkbox"
id="singleplayer-modal-disable-nukes"
@change=${this.handleDisableNukesChange}
.checked=${this.disableNukes}
/>
<div class="option-card-title">
${translateText("single_modal.disable_nukes")}
</div>
</label>
<hr
style="width: 100%; border-top: 1px solid #444; margin: 16px 0;"
/>
<div
style="margin: 8px 0 12px 0; font-weight: bold; color: #ccc; text-align: center;"
>
${translateText("single_modal.enables_title")}
</div>
<div
style="display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;"
>
${[
[UnitType.City, "unit_type.city"],
[UnitType.DefensePost, "unit_type.defense_post"],
[UnitType.Port, "unit_type.port"],
[UnitType.Warship, "unit_type.warship"],
[UnitType.MissileSilo, "unit_type.missile_silo"],
[UnitType.SAMLauncher, "unit_type.sam_launcher"],
[UnitType.AtomBomb, "unit_type.atom_bomb"],
[UnitType.HydrogenBomb, "unit_type.hydrogen_bomb"],
[UnitType.MIRV, "unit_type.mirv"],
].map(
([unitType, translationKey]) => html`
<label
class="option-card ${this.disabledUnits.includes(unitType)
? ""
: "selected"}"
style="width: 140px;"
>
<div class="checkbox-icon"></div>
<input
type="checkbox"
@change=${(e: Event) => {
const checked = (e.target as HTMLInputElement).checked;
if (checked) {
this.disabledUnits = [
...this.disabledUnits,
unitType,
];
} else {
this.disabledUnits = this.disabledUnits.filter(
(u) => u !== unitType,
);
}
}}
.checked=${this.disabledUnits.includes(unitType)}
/>
<div class="option-card-title" style="text-align: center;">
${translateText(translationKey)}
</div>
</label>
`,
)}
</div>
</div>
</div>
@@ -419,6 +461,7 @@ export class SinglePlayerModal extends LitElement {
infiniteGold: this.infiniteGold,
infiniteTroops: this.infiniteTroops,
instantBuild: this.instantBuild,
disabledUnits: this.disabledUnits,
},
},
} as JoinLobbyEvent,
+3 -15
View File
@@ -409,21 +409,9 @@ export class BuildMenu extends LitElement implements Layer {
}
private getBuildableUnits(): BuildItemDisplay[][] {
if (this.game?.config()?.disableNukes()) {
return buildTable.map((row) =>
row.filter(
(item) =>
![
UnitType.AtomBomb,
UnitType.MIRV,
UnitType.HydrogenBomb,
UnitType.MissileSilo,
UnitType.SAMLauncher,
].includes(item.unitType),
),
);
}
return buildTable;
return buildTable.map((row) =>
row.filter((item) => !this.game?.config()?.isUnitDisabled(item.unitType)),
);
}
get isVisible() {