refactor: improve captain data management and UI layout - Move captain configs to individual JSON files - Add dynamic captain indexing - Update UI to show missions above captain selector - Remove player labels for cleaner interface - Add captain selection filtering to prevent duplicate selections
This commit is contained in:
parent
c54e010801
commit
f0e597a3d8
12 changed files with 258 additions and 158 deletions
|
|
@ -4,9 +4,10 @@
|
|||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"build": "node scripts/generate-captains-index.js && astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
"astro": "astro",
|
||||
"generate-captains": "node scripts/generate-captains-index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
|
|
|
|||
41
scripts/generate-captains-index.js
Normal file
41
scripts/generate-captains-index.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const CAPTAINS_DIR = path.join(__dirname, '../src/assets/captains');
|
||||
const INDEX_FILE = path.join(CAPTAINS_DIR, 'index.json');
|
||||
|
||||
function generateCaptainsIndex() {
|
||||
try {
|
||||
// Read all JSON files in the captains directory
|
||||
const files = fs.readdirSync(CAPTAINS_DIR)
|
||||
.filter(file => file.endsWith('.json') && file !== 'index.json');
|
||||
|
||||
// Parse each captain file to get their id and name
|
||||
const captains = files.map(file => {
|
||||
const content = fs.readFileSync(path.join(CAPTAINS_DIR, file), 'utf-8');
|
||||
const captain = JSON.parse(content);
|
||||
return {
|
||||
id: captain.id,
|
||||
name: captain.name
|
||||
};
|
||||
});
|
||||
|
||||
// Create the index object
|
||||
const index = {
|
||||
captains: captains
|
||||
};
|
||||
|
||||
// Write the index file
|
||||
fs.writeFileSync(INDEX_FILE, JSON.stringify(index, null, 4));
|
||||
console.log('Successfully generated captains index');
|
||||
} catch (error) {
|
||||
console.error('Error generating captains index:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
generateCaptainsIndex();
|
||||
|
|
@ -44,17 +44,5 @@
|
|||
"name": "Time Crystal Recovery",
|
||||
"description": "Retrieve a valuable time crystal from a dangerous location.",
|
||||
"points": 3
|
||||
},
|
||||
"advancedMissions": [
|
||||
{
|
||||
"name": "Red Angel Investigation",
|
||||
"description": "Investigate the mysterious Red Angel phenomenon.",
|
||||
"points": 5
|
||||
},
|
||||
{
|
||||
"name": "Control Protocol Override",
|
||||
"description": "Override the Control AI's protocols to save the galaxy.",
|
||||
"points": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
28
src/assets/captains/index.json
Normal file
28
src/assets/captains/index.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"captains": [
|
||||
{
|
||||
"id": "burnham",
|
||||
"name": "Burnham"
|
||||
},
|
||||
{
|
||||
"id": "koloth",
|
||||
"name": "Koloth"
|
||||
},
|
||||
{
|
||||
"id": "picard",
|
||||
"name": "Picard"
|
||||
},
|
||||
{
|
||||
"id": "sela",
|
||||
"name": "Sela"
|
||||
},
|
||||
{
|
||||
"id": "shran",
|
||||
"name": "Shran"
|
||||
},
|
||||
{
|
||||
"id": "sisko",
|
||||
"name": "Sisko"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -44,17 +44,5 @@
|
|||
"name": "Klingon Honor",
|
||||
"description": "Uphold Klingon honor in a challenging diplomatic situation.",
|
||||
"points": 3
|
||||
},
|
||||
"advancedMissions": [
|
||||
{
|
||||
"name": "House Koloth",
|
||||
"description": "Strengthen the position of House Koloth in the Klingon Empire.",
|
||||
"points": 5
|
||||
},
|
||||
{
|
||||
"name": "Klingon Empire Conquest",
|
||||
"description": "Lead a successful military campaign to expand Klingon territory.",
|
||||
"points": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -44,17 +44,5 @@
|
|||
"name": "Diplomatic Mission",
|
||||
"description": "Lead a diplomatic mission to establish peaceful relations with a new species.",
|
||||
"points": 2
|
||||
},
|
||||
"advancedMissions": [
|
||||
{
|
||||
"name": "Scientific Discovery",
|
||||
"description": "Make a groundbreaking scientific discovery that advances Federation knowledge.",
|
||||
"points": 3
|
||||
},
|
||||
{
|
||||
"name": "First Contact Protocol",
|
||||
"description": "Successfully execute first contact protocols with a technologically advanced species.",
|
||||
"points": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -44,17 +44,5 @@
|
|||
"name": "Romulan Infiltration",
|
||||
"description": "Lead a covert operation to infiltrate a strategic Federation outpost.",
|
||||
"points": 3
|
||||
},
|
||||
"advancedMissions": [
|
||||
{
|
||||
"name": "Tal Shiar Operation",
|
||||
"description": "Execute a complex Tal Shiar intelligence gathering mission.",
|
||||
"points": 5
|
||||
},
|
||||
{
|
||||
"name": "Romulan Empire Expansion",
|
||||
"description": "Expand Romulan influence into a new sector of space.",
|
||||
"points": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import { UIService } from '../utils/ui';
|
||||
import { captainDataManager } from '../utils/captainData';
|
||||
|
||||
// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build
|
||||
// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh.
|
||||
|
|
@ -18,6 +19,9 @@ const captains: Captain[] = [
|
|||
{ id: 'shran', name: 'Shran' },
|
||||
{ id: 'koloth', name: 'Koloth' }
|
||||
];
|
||||
|
||||
// Initialize UI service
|
||||
const uiService = UIService.getInstance();
|
||||
---
|
||||
|
||||
<Layout title="STCC - Token Counter">
|
||||
|
|
@ -25,21 +29,26 @@ const captains: Captain[] = [
|
|||
<h1 class="text-4xl font-bold text-center mb-8 text-blue-400">Star Trek Captain's Chair</h1>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<!-- Player 1 -->
|
||||
<div class="bg-gray-800 rounded-lg p-6 shadow-lg border border-blue-500">
|
||||
<div class="mb-4">
|
||||
<!-- Player 1 Section -->
|
||||
<div class="bg-gray-800 p-6 rounded-lg shadow-lg">
|
||||
<div class="space-y-4">
|
||||
<!-- Missions Section -->
|
||||
<div id="player1-missions" class="hidden">
|
||||
<h3 class="text-lg font-semibold text-gray-300 mb-2 text-center">Available Missions</h3>
|
||||
<div id="player1-missions-list" class="space-y-2">
|
||||
<!-- Missions will be populated here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="player1-captain" class="block text-sm font-medium text-gray-300 mb-1">Select Captain</label>
|
||||
<select id="player1-captain" class="w-full bg-gray-700 text-white rounded px-3 py-2">
|
||||
<option value="">Choose a captain...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="flex-1">
|
||||
<label class="block text-sm font-medium text-gray-300 mb-2">Select Captain</label>
|
||||
<select
|
||||
id="player1-captain"
|
||||
class="w-full bg-gray-700 text-white rounded px-4 py-2 border border-blue-400 focus:outline-none focus:border-blue-300"
|
||||
>
|
||||
<option value="">Choose a captain...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<label class="text-sm font-medium text-gray-300">Mode:</label>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-2">Mode:</label>
|
||||
<button
|
||||
id="player1-mode-toggle"
|
||||
class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
||||
|
|
@ -135,32 +144,29 @@ const captains: Captain[] = [
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Missions Section -->
|
||||
<div id="player1-missions" class="hidden">
|
||||
<h3 class="text-lg font-semibold text-gray-300 mb-2 text-center">Available Missions</h3>
|
||||
<div id="player1-missions-list" class="space-y-2">
|
||||
<!-- Missions will be populated here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Player 2 -->
|
||||
<div class="bg-gray-800 rounded-lg p-6 shadow-lg border border-red-500">
|
||||
<div class="mb-4">
|
||||
<!-- Player 2 Section -->
|
||||
<div class="bg-gray-800 p-6 rounded-lg shadow-lg">
|
||||
<div class="space-y-4">
|
||||
<!-- Missions Section -->
|
||||
<div id="player2-missions" class="hidden">
|
||||
<h3 class="text-lg font-semibold text-gray-300 mb-2 text-center">Available Missions</h3>
|
||||
<div id="player2-missions-list" class="space-y-2">
|
||||
<!-- Missions will be populated here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="player2-captain" class="block text-sm font-medium text-gray-300 mb-1">Select Captain</label>
|
||||
<select id="player2-captain" class="w-full bg-gray-700 text-white rounded px-3 py-2">
|
||||
<option value="">Choose a captain...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="flex-1">
|
||||
<label class="block text-sm font-medium text-gray-300 mb-2">Select Captain</label>
|
||||
<select
|
||||
id="player2-captain"
|
||||
class="w-full bg-gray-700 text-white rounded px-4 py-2 border border-red-400 focus:outline-none focus:border-red-300"
|
||||
>
|
||||
<option value="">Choose a captain...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<label class="text-sm font-medium text-gray-300">Mode:</label>
|
||||
<label class="block text-sm font-medium text-gray-300 mb-2">Mode:</label>
|
||||
<button
|
||||
id="player2-mode-toggle"
|
||||
class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2"
|
||||
|
|
@ -256,14 +262,6 @@ const captains: Captain[] = [
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Missions Section -->
|
||||
<div id="player2-missions" class="hidden">
|
||||
<h3 class="text-lg font-semibold text-gray-300 mb-2 text-center">Available Missions</h3>
|
||||
<div id="player2-missions-list" class="space-y-2">
|
||||
<!-- Missions will be populated here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -319,7 +317,7 @@ const captains: Captain[] = [
|
|||
|
||||
<script>
|
||||
import { UIService } from '../utils/ui';
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
UIService.getInstance().initialize();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import type { Captain } from './types';
|
||||
|
||||
interface ThresholdTable {
|
||||
basic: {
|
||||
threshold: number;
|
||||
|
|
@ -38,12 +40,13 @@ interface CaptainConfig {
|
|||
[key: string]: ThresholdTable;
|
||||
};
|
||||
basicMission: Mission;
|
||||
advancedMissions: Mission[];
|
||||
advancedMissions?: Mission[];
|
||||
}
|
||||
|
||||
class CaptainDataManager {
|
||||
private static instance: CaptainDataManager;
|
||||
private captainConfigs: Map<string, CaptainConfig> = new Map();
|
||||
private availableCaptains: Captain[] = [];
|
||||
|
||||
private constructor() {}
|
||||
|
||||
|
|
@ -54,13 +57,35 @@ class CaptainDataManager {
|
|||
return CaptainDataManager.instance;
|
||||
}
|
||||
|
||||
async loadAvailableCaptains(): Promise<Captain[]> {
|
||||
if (this.availableCaptains.length > 0) {
|
||||
console.log('Returning cached captains:', this.availableCaptains);
|
||||
return this.availableCaptains;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Loading captains from index.json...');
|
||||
const response = await fetch('/src/assets/captains/index.json');
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load captains index');
|
||||
}
|
||||
const data = await response.json();
|
||||
this.availableCaptains = data.captains;
|
||||
console.log('Set available captains:', this.availableCaptains);
|
||||
return this.availableCaptains;
|
||||
} catch (error) {
|
||||
console.error('Error loading captains:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async loadCaptainConfig(captainId: string): Promise<CaptainConfig> {
|
||||
if (this.captainConfigs.has(captainId)) {
|
||||
return this.captainConfigs.get(captainId)!;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/src/assets/captains/${captainId}/config.json`);
|
||||
const response = await fetch(`/src/assets/captains/${captainId}.json`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load captain config for ${captainId}`);
|
||||
}
|
||||
|
|
@ -123,7 +148,7 @@ class CaptainDataManager {
|
|||
|
||||
// In advanced mode, include additional missions
|
||||
if (mode === 'advanced') {
|
||||
missions.push(...config.advancedMissions);
|
||||
missions.push(...config.advancedMissions || []);
|
||||
}
|
||||
|
||||
return missions;
|
||||
|
|
|
|||
171
src/utils/ui.ts
171
src/utils/ui.ts
|
|
@ -46,36 +46,61 @@ export class UIService {
|
|||
return element;
|
||||
}
|
||||
|
||||
private updateCaptainOptions(playerNum: PlayerNumber): void {
|
||||
const playerSelect = this.getElement<HTMLSelectElement>(`player${playerNum}-captain`);
|
||||
if (!playerSelect) return;
|
||||
private async updateCaptainOptions(playerNum: PlayerNumber): Promise<void> {
|
||||
const select = this.getElement<HTMLSelectElement>(`player${playerNum}-captain`);
|
||||
if (!select) return;
|
||||
|
||||
// Clear existing options except the first one
|
||||
while (playerSelect.options.length > 1) {
|
||||
playerSelect.remove(1);
|
||||
}
|
||||
try {
|
||||
console.log('Loading available captains...');
|
||||
const captains = await captainDataManager.loadAvailableCaptains();
|
||||
console.log('Loaded captains:', captains);
|
||||
const currentValue = select.value;
|
||||
|
||||
// Add available captains
|
||||
const captains = [
|
||||
{ id: 'picard', name: 'Picard' },
|
||||
{ id: 'sisko', name: 'Sisko' },
|
||||
{ id: 'sela', name: 'Sela' },
|
||||
{ id: 'burnham', name: 'Burnham' },
|
||||
{ id: 'shran', name: 'Shran' },
|
||||
{ id: 'koloth', name: 'Koloth' }
|
||||
];
|
||||
// Clear all existing options
|
||||
select.innerHTML = '';
|
||||
|
||||
captains.forEach(captain => {
|
||||
const otherPlayer = playerNum === 1 ? 'player2' : 'player1';
|
||||
if (captain.id !== this.gameState[otherPlayer].captain) {
|
||||
const option = new Option(captain.name, captain.id);
|
||||
playerSelect.add(option);
|
||||
// Get the other player's selected captain
|
||||
const otherPlayerNum = playerNum === 1 ? 2 : 1;
|
||||
const otherPlayerKey = `player${otherPlayerNum}` as keyof GameState;
|
||||
const otherPlayerCaptain = this.gameState[otherPlayerKey].captain;
|
||||
|
||||
// Filter out the other player's selected captain
|
||||
const availableCaptains = captains.filter(captain => captain.id !== otherPlayerCaptain);
|
||||
|
||||
// Add captain options
|
||||
availableCaptains.forEach(captain => {
|
||||
console.log('Adding captain option:', captain);
|
||||
const option = document.createElement('option');
|
||||
option.value = captain.id;
|
||||
option.textContent = captain.name;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
// If no captain is currently selected, select the first one
|
||||
if (!currentValue && availableCaptains.length > 0) {
|
||||
select.value = availableCaptains[0].id;
|
||||
this.gameState[`player${playerNum}` as keyof GameState].captain = availableCaptains[0].id;
|
||||
try {
|
||||
await captainDataManager.loadCaptainConfig(availableCaptains[0].id);
|
||||
} catch (error) {
|
||||
console.error('Error loading captain config:', error);
|
||||
}
|
||||
} else if (currentValue && availableCaptains.some(c => c.id === currentValue)) {
|
||||
// Restore the previously selected value if it exists and is still available
|
||||
select.value = currentValue;
|
||||
} else if (availableCaptains.length > 0) {
|
||||
// If the current selection is no longer available, select the first available captain
|
||||
select.value = availableCaptains[0].id;
|
||||
this.gameState[`player${playerNum}` as keyof GameState].captain = availableCaptains[0].id;
|
||||
try {
|
||||
await captainDataManager.loadCaptainConfig(availableCaptains[0].id);
|
||||
} catch (error) {
|
||||
console.error('Error loading captain config:', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Set the current value
|
||||
const playerKey = `player${playerNum}` as keyof GameState;
|
||||
playerSelect.value = this.gameState[playerKey].captain;
|
||||
} catch (error) {
|
||||
console.error('Error updating captain options:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private calculateMultiplier(playerNum: PlayerNumber, specialty: 'research' | 'influence' | 'military'): string {
|
||||
|
|
@ -123,11 +148,48 @@ export class UIService {
|
|||
const toggle = this.getElement<HTMLButtonElement>(`player${playerNum}-mode-toggle`);
|
||||
const label = this.getElement<HTMLSpanElement>(`player${playerNum}-mode-label`);
|
||||
|
||||
if (toggle) toggle.setAttribute('aria-checked', (player.mode === 'advanced').toString());
|
||||
// Disable/enable mode toggle based on captain selection
|
||||
const isCaptainSelected = player.captain !== '' && player.captain !== 'Choose a captain...';
|
||||
if (toggle) {
|
||||
toggle.disabled = !isCaptainSelected;
|
||||
toggle.setAttribute('aria-checked', (player.mode === 'advanced').toString());
|
||||
if (!isCaptainSelected) {
|
||||
toggle.classList.add('opacity-50', 'cursor-not-allowed');
|
||||
} else {
|
||||
toggle.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||
}
|
||||
}
|
||||
if (label) label.textContent = player.mode === 'advanced' ? 'Advanced' : 'Basic';
|
||||
|
||||
// Update missions display
|
||||
const missionsContainer = this.getElement<HTMLDivElement>(`player${playerNum}-missions`);
|
||||
const missionsList = this.getElement<HTMLDivElement>(`player${playerNum}-missions-list`);
|
||||
|
||||
if (missionsContainer && missionsList) {
|
||||
missionsList.innerHTML = '';
|
||||
if (isCaptainSelected) {
|
||||
const missions = captainDataManager.getAvailableMissions(
|
||||
player.captain,
|
||||
{
|
||||
research: player.research,
|
||||
influence: player.influence,
|
||||
military: player.military
|
||||
},
|
||||
player.mode
|
||||
);
|
||||
|
||||
missions.forEach(mission => {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = `${mission.name} (${mission.points} points)`;
|
||||
missionsList.appendChild(li);
|
||||
});
|
||||
missionsContainer.classList.remove('hidden');
|
||||
} else {
|
||||
missionsContainer.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// Disable/enable counter buttons based on captain selection
|
||||
const isCaptainSelected = !!player.captain;
|
||||
const playerButtons = document.querySelectorAll(`.token-btn[data-player="${playerNum}"]`);
|
||||
playerButtons.forEach(button => {
|
||||
(button as HTMLButtonElement).disabled = !isCaptainSelected;
|
||||
|
|
@ -137,6 +199,16 @@ export class UIService {
|
|||
button.classList.remove('opacity-50', 'cursor-not-allowed');
|
||||
}
|
||||
});
|
||||
|
||||
// Reset counters if no captain is selected
|
||||
if (!isCaptainSelected) {
|
||||
player.latinum = 0;
|
||||
player.dilithium = 0;
|
||||
player.glory = 0;
|
||||
player.research = 0;
|
||||
player.influence = 0;
|
||||
player.military = 0;
|
||||
}
|
||||
});
|
||||
|
||||
// Update resource counters
|
||||
|
|
@ -160,16 +232,9 @@ export class UIService {
|
|||
const multiplier = this.getElement<HTMLSpanElement>(`player${playerNum}-${specialty}-multiplier`);
|
||||
|
||||
if (counter) counter.textContent = player[specialty as keyof typeof player].toString();
|
||||
if (multiplier) {
|
||||
const multiplierValue = this.calculateMultiplier(playerNum as PlayerNumber, specialty as 'research' | 'influence' | 'military');
|
||||
console.log(`Updating multiplier for player ${playerNum} ${specialty}:`, multiplierValue);
|
||||
multiplier.textContent = multiplierValue;
|
||||
}
|
||||
if (multiplier) multiplier.textContent = this.calculateMultiplier(playerNum as PlayerNumber, specialty as 'research' | 'influence' | 'military');
|
||||
});
|
||||
});
|
||||
|
||||
// Update missions
|
||||
this.updateMissions();
|
||||
}
|
||||
|
||||
private updateMissions(): void {
|
||||
|
|
@ -254,18 +319,13 @@ export class UIService {
|
|||
if (player1CaptainSelect) {
|
||||
player1CaptainSelect.addEventListener('change', async (e: Event) => {
|
||||
const target = e.target as HTMLSelectElement;
|
||||
if (target.value === player2CaptainSelect?.value && target.value !== '') {
|
||||
alert('Cannot select the same captain for both players');
|
||||
target.value = '';
|
||||
return;
|
||||
}
|
||||
this.gameState.player1.captain = target.value;
|
||||
if (target.value) {
|
||||
try {
|
||||
await captainDataManager.loadCaptainConfig(target.value);
|
||||
} catch (error) {
|
||||
console.error('Error loading captain config:', error);
|
||||
}
|
||||
try {
|
||||
await captainDataManager.loadCaptainConfig(target.value);
|
||||
// Update player 2's options to remove the selected captain
|
||||
await this.updateCaptainOptions(2);
|
||||
} catch (error) {
|
||||
console.error('Error loading captain config:', error);
|
||||
}
|
||||
this.updateUI();
|
||||
StorageService.saveGameState(this.gameState);
|
||||
|
|
@ -275,18 +335,13 @@ export class UIService {
|
|||
if (player2CaptainSelect) {
|
||||
player2CaptainSelect.addEventListener('change', async (e: Event) => {
|
||||
const target = e.target as HTMLSelectElement;
|
||||
if (target.value === player1CaptainSelect?.value && target.value !== '') {
|
||||
alert('Cannot select the same captain for both players');
|
||||
target.value = '';
|
||||
return;
|
||||
}
|
||||
this.gameState.player2.captain = target.value;
|
||||
if (target.value) {
|
||||
try {
|
||||
await captainDataManager.loadCaptainConfig(target.value);
|
||||
} catch (error) {
|
||||
console.error('Error loading captain config:', error);
|
||||
}
|
||||
try {
|
||||
await captainDataManager.loadCaptainConfig(target.value);
|
||||
// Update player 1's options to remove the selected captain
|
||||
await this.updateCaptainOptions(1);
|
||||
} catch (error) {
|
||||
console.error('Error loading captain config:', error);
|
||||
}
|
||||
this.updateUI();
|
||||
StorageService.saveGameState(this.gameState);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue