Skip to content

Commit a80bd0b

Browse files
committed
Fix(clippy): Resolve compiler errors and clippy warnings
- Fix E0412: Define VolumeSliderInteractionQuery in audio.rs - Fix E0277: Correct system configuration in settings plugin - Fix clippy::unused_unit in tests/common.rs - Fix clippy::collapsible_if in mtgjson/mod.rs - Fix clippy::collapsible_else_if in save/load.rs and visual_testing/examples.rs - Refactor save/load.rs to use apply_game_state util - Fix pattern matching errors in save/utils.rs - Address various import errors and unused imports
1 parent 74019bf commit a80bd0b

22 files changed

Lines changed: 220 additions & 240 deletions

File tree

src/cards/mtgjson/mod.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::cards::{
1919
use crate::mana::{Mana, ManaColor};
2020
use async_trait::async_trait;
2121
use lazy_static::lazy_static;
22+
use log::info;
2223
use regex;
2324
use reqwest;
2425
use serde::{Deserialize, Serialize};
@@ -438,7 +439,6 @@ impl MTGService {
438439
}
439440

440441
/// Gets the path for set version information
441-
442442
fn get_set_version_path(&self, set_code: &str) -> std::path::PathBuf {
443443
std::path::PathBuf::from("sets").join(format!("{}.json.bz2.version", set_code))
444444
}
@@ -447,7 +447,6 @@ impl MTGService {
447447
///
448448
/// This includes the current version number and update date.
449449
/// Results are cached to avoid unnecessary API calls.
450-
451450
pub async fn fetch_meta(&self) -> Result<MTGJSONMeta, Error> {
452451
let mut meta = self.meta.lock().await;
453452
if meta.is_some() {
@@ -472,7 +471,6 @@ impl MTGService {
472471
///
473472
/// Checks both the version and checksum of the file against
474473
/// the current MTGJSON version.
475-
476474
pub async fn verify_file_checksum(&self, set_code: &str, path: &Path) -> Result<bool, Error> {
477475
// First check if we have a version file and if it matches current version
478476
let version_path = self.get_set_version_path(set_code);
@@ -550,30 +548,35 @@ impl MTGService {
550548
}
551549
drop(memory_cache);
552550

553-
// Check if we have a cached version and its checksum is valid
551+
// Check if set archive already exists and is valid
554552
let set_archive_path = self.get_set_archive_path(set_code);
555-
if set_archive_path.exists() {
556-
if self
553+
554+
if set_archive_path.exists()
555+
&& self
557556
.verify_file_checksum(set_code, &set_archive_path)
558557
.await?
559-
{
560-
let compressed_data = fs::read(&set_archive_path)?;
561-
let decompressed = bzip2::read::BzDecoder::new(&compressed_data[..]);
562-
let set: MTGJSONSetResponse = serde_json::from_reader(decompressed)?;
563-
let cards: Vec<Card> = set
564-
.data
565-
.cards
566-
.into_iter()
567-
.filter_map(convert_mtgjson_to_card)
568-
.map(|(card, _, _, _, _, _, _)| card)
569-
.collect();
570-
571-
// Update memory cache
572-
let mut memory_cache = self.cache.lock().await;
573-
memory_cache.insert(set_code.to_string(), cards.clone());
574-
575-
return Ok(cards);
576-
}
558+
{
559+
// Load from existing archive
560+
info!(
561+
"Loading set data for {} from existing archive: {:?}",
562+
set_code, set_archive_path
563+
);
564+
let compressed_data = fs::read(&set_archive_path)?;
565+
let decompressed = bzip2::read::BzDecoder::new(&compressed_data[..]);
566+
let set: MTGJSONSetResponse = serde_json::from_reader(decompressed)?;
567+
let cards: Vec<Card> = set
568+
.data
569+
.cards
570+
.into_iter()
571+
.filter_map(convert_mtgjson_to_card)
572+
.map(|(card, _, _, _, _, _, _)| card)
573+
.collect();
574+
575+
// Update memory cache
576+
let mut memory_cache = self.cache.lock().await;
577+
memory_cache.insert(set_code.to_string(), cards.clone());
578+
579+
return Ok(cards);
577580
}
578581

579582
// Get the set data from the client
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use bevy::prelude::*;
2+
3+
/// Converts a mana symbol string (e.g., "{W}") to its corresponding color.
4+
pub fn symbol_to_color(mana_symbol: &str) -> Color {
5+
let clean_symbol = mana_symbol.trim();
6+
match clean_symbol {
7+
"{W}" => Color::srgb(0.95, 0.95, 0.85), // White mana (off-white)
8+
"{U}" => Color::srgb(0.0, 0.4, 0.8), // Blue mana - more vibrant
9+
"{B}" => Color::srgb(0.0, 0.0, 0.0), // Black mana - true black
10+
"{R}" => Color::srgb(0.9, 0.1, 0.1), // Red mana - more vivid red
11+
"{G}" => Color::srgb(0.0, 0.6, 0.0), // Green mana - brighter green
12+
"{C}" => Color::srgb(0.7, 0.7, 0.8), // Colorless mana - slight blue tint
13+
_ => {
14+
// Generic/numeric mana or other symbols
15+
if clean_symbol.starts_with('{') && clean_symbol.ends_with('}') {
16+
let inner = &clean_symbol[1..clean_symbol.len() - 1];
17+
if inner.parse::<u32>().is_ok() || inner == "X" {
18+
// Generic mana is light gray with a slight brown tint
19+
Color::srgb(0.75, 0.73, 0.71)
20+
} else {
21+
// Other symbols like tap
22+
Color::srgb(0.3, 0.3, 0.3)
23+
}
24+
} else {
25+
// Default to black for other text
26+
Color::srgb(0.0, 0.0, 0.0)
27+
}
28+
}
29+
}
30+
}

src/game_engine/save/systems/load.rs

Lines changed: 11 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use bevy::prelude::*;
22
use bevy_persistent::prelude::*;
3-
use std::collections::{HashMap, VecDeque};
43

54
use crate::game_engine::commander::CommandZoneManager;
6-
use crate::game_engine::save::data::*;
7-
use crate::game_engine::save::events::*;
5+
use crate::game_engine::save::data::GameSaveData;
6+
use crate::game_engine::save::events::LoadGameEvent;
87
use crate::game_engine::save::resources::*;
98
use crate::game_engine::state::GameState;
109
use crate::game_engine::zones::ZoneManager;
@@ -44,115 +43,17 @@ pub fn handle_load_game(
4443

4544
match persistent_save {
4645
Ok(save) => {
47-
// Get the loaded data
4846
let save_data = save.clone();
4947

50-
// Rebuild entity mapping
51-
let mut index_to_entity = Vec::new();
52-
let mut existing_player_entities = HashMap::new();
53-
54-
// Map existing players if possible
55-
for (entity, player) in query_players.iter() {
56-
for saved_player in &save_data.players {
57-
if player.name == saved_player.name {
58-
existing_player_entities.insert(saved_player.id, entity);
59-
break;
60-
}
61-
}
62-
}
63-
64-
// Recreate player entities
65-
for player_data in &save_data.players {
66-
if let Some(&entity) = existing_player_entities.get(&player_data.id) {
67-
index_to_entity.push(entity);
68-
69-
// Update existing player data
70-
if let Ok((_, mut player)) = query_players.get_mut(entity) {
71-
player.life = player_data.life;
72-
player.mana_pool = player_data.mana_pool.clone();
73-
}
74-
} else {
75-
// Create new player entity
76-
let player_entity = commands
77-
.spawn((Player {
78-
name: player_data.name.clone(),
79-
life: player_data.life,
80-
mana_pool: player_data.mana_pool.clone(),
81-
..Default::default()
82-
},))
83-
.id();
84-
85-
index_to_entity.push(player_entity);
86-
}
87-
}
88-
89-
// Handle empty player list case gracefully
90-
if save_data.players.is_empty() {
91-
debug!("Loading a save with no players");
92-
// Add a placeholder to index_to_entity for GameState to reference safely
93-
if index_to_entity.is_empty() {
94-
index_to_entity.push(Entity::PLACEHOLDER);
95-
}
96-
}
97-
98-
// Restore game state - always attempt to restore basic properties even with empty players
99-
if let Some(game_state) = &mut game_state {
100-
// If there's a corrupted mapping, fall back to basic properties
101-
if index_to_entity.is_empty() || index_to_entity.contains(&Entity::PLACEHOLDER)
102-
{
103-
// Always restore turn number first
104-
game_state.turn_number = save_data.game_state.turn_number;
105-
106-
// Handle empty turn order case
107-
if save_data.game_state.turn_order_indices.is_empty() {
108-
debug!("Empty turn order detected, keeping turn order unchanged");
109-
// Keep the existing turn order
110-
} else {
111-
// Create a fallback turn order based on indices
112-
let mut turn_order = VecDeque::new();
113-
for &idx in &save_data.game_state.turn_order_indices {
114-
turn_order.push_back(Entity::from_raw(idx as u32));
115-
}
116-
game_state.turn_order = turn_order;
117-
}
118-
} else {
119-
// Full restore with valid player entities
120-
**game_state = save_data.to_game_state(&index_to_entity);
121-
}
122-
} else {
123-
if !index_to_entity.is_empty() {
124-
commands.insert_resource(save_data.to_game_state(&index_to_entity));
125-
} else {
126-
// Even with empty index, we should still restore basic properties
127-
let mut default_state = GameState::default();
128-
129-
// Only update turn number if turn order is not empty
130-
if !save_data.game_state.turn_order_indices.is_empty() {
131-
default_state.turn_number = save_data.game_state.turn_number;
132-
} else {
133-
debug!(
134-
"Empty turn order detected when creating default state, keeping turn number unchanged"
135-
);
136-
}
137-
138-
commands.insert_resource(default_state);
139-
warn!(
140-
"No player entities found when loading game, using modified default state"
141-
);
142-
}
143-
}
144-
145-
// Restore zone contents
146-
if let Some(zone_manager) = &mut zones {
147-
// Use the GameSaveData method to restore ZoneManager
148-
**zone_manager = save_data.to_zone_manager(&index_to_entity);
149-
}
150-
151-
// Restore commander zone contents
152-
if let Some(commander_manager) = &mut commanders {
153-
// Use the GameSaveData method to restore CommandZoneManager
154-
**commander_manager = save_data.to_commander_manager(&index_to_entity);
155-
}
48+
// Apply the loaded state using the fully qualified path
49+
crate::game_engine::save::systems::utils::apply_game_state(
50+
&save_data,
51+
&mut game_state,
52+
&mut commands,
53+
&mut query_players,
54+
&mut zones,
55+
&mut commanders,
56+
);
15657

15758
info!("Game loaded successfully from slot {}", event.slot_name);
15859
}

src/game_engine/save/systems/utils.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,22 @@ pub fn apply_game_state(
6363
}
6464

6565
// Restore game state
66-
if let Some(game_state) = game_state {
66+
if let Some(gs) = game_state {
6767
if index_to_entity.is_empty() || index_to_entity.contains(&Entity::PLACEHOLDER) {
6868
// At minimum, restore basic properties not tied to player entities
69-
game_state.turn_number = save_data.game_state.turn_number;
69+
gs.turn_number = save_data.game_state.turn_number;
7070
} else {
7171
// Full restore with valid player entities
72-
**game_state = save_data.to_game_state(&index_to_entity);
72+
**gs = save_data.to_game_state(&index_to_entity);
7373
}
74+
} else if index_to_entity.is_empty() || index_to_entity.contains(&Entity::PLACEHOLDER) {
75+
// Create a new game state with basic properties if mapping failed or is empty
76+
let mut new_state = GameState::default();
77+
new_state.turn_number = save_data.game_state.turn_number;
78+
commands.insert_resource(new_state);
7479
} else {
75-
if index_to_entity.is_empty() || index_to_entity.contains(&Entity::PLACEHOLDER) {
76-
// Create a new game state with basic properties
77-
let mut new_state = GameState::default();
78-
new_state.turn_number = save_data.game_state.turn_number;
79-
commands.insert_resource(new_state);
80-
} else {
81-
commands.insert_resource(save_data.to_game_state(&index_to_entity));
82-
}
80+
// Create a new game state from save data
81+
commands.insert_resource(save_data.to_game_state(&index_to_entity));
8382
}
8483

8584
// Restore zone contents if a valid ZoneManager exists and we have player entities

src/game_engine/tests/assertions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
// use crate::game_engine::state::Zone;
12
use bevy::prelude::*;
23

34
/// Game state assertions for testing
4-
55
/// Asserts that an entity is in a specific zone
66
#[allow(dead_code)]
77
pub fn assert_in_zone(
88
_app: &App,
99
_entity: Entity,
10-
_zone_type: crate::game_engine::zones::Zone,
10+
_zone_type: crate::game_engine::zones::types::Zone,
1111
_owner: Option<Entity>,
1212
) {
1313
// Placeholder implementation

src/game_engine/tests/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy::prelude::*;
55
66
/// Setup test logger
77
#[allow(dead_code)]
8-
pub fn setup_test_logger() -> () {
8+
pub fn setup_test_logger() {
99
// Placeholder for test logger setup
1010
// Usually sets up a test-specific logger configuration
1111
}

src/menu/camera/setup.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use bevy::prelude::*;
44
#[derive(Component, Debug)]
55
pub struct MenuCamera;
66

7+
#[derive(Resource)]
8+
pub struct MenuCameraEntity(pub Entity);
9+
710
/// Sets up a dedicated camera for the menu
811
pub fn setup_menu_camera(
912
mut commands: Commands,
@@ -52,7 +55,7 @@ pub fn setup_menu_camera(
5255
let new_order = highest_order + 1;
5356
let camera_entity = commands
5457
.spawn((
55-
Camera2d::default(),
58+
Camera2d,
5659
Camera {
5760
order: new_order,
5861
..default()
@@ -92,3 +95,27 @@ pub fn cleanup_menu_camera(mut commands: Commands, cameras: Query<Entity, With<M
9295
}
9396
}
9497
}
98+
99+
/// Ensure this camera renders above all other cameras.
100+
pub fn setup_main_menu_camera(
101+
mut commands: Commands,
102+
camera_query: Query<Entity, With<MenuCamera>>,
103+
) {
104+
let camera_entity = camera_query.single();
105+
commands.entity(camera_entity).insert(Camera {
106+
order: isize::MAX - 1,
107+
..default()
108+
});
109+
commands.insert_resource(MenuCameraEntity(camera_entity));
110+
111+
info!("Main Menu Camera setup complete");
112+
}
113+
114+
/// System to despawn the main menu camera
115+
pub fn despawn_menu_camera(mut commands: Commands, camera_query: Query<Entity, With<MenuCamera>>) {
116+
for entity in camera_query.iter() {
117+
commands.entity(entity).despawn_recursive();
118+
}
119+
commands.remove_resource::<MenuCameraEntity>();
120+
info!("Main Menu Camera despawned");
121+
}

src/menu/logo/plugin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fn setup_startup_logo(
6969
info!("No menu camera found - creating one before logo setup");
7070
let camera_entity = commands
7171
.spawn((
72-
Camera2d::default(),
72+
Camera2d,
7373
Camera {
7474
order: 100, // Use a much higher order to avoid conflicts with default cameras
7575
..default()

src/menu/main_menu/systems/interactions.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@ use crate::menu::{
44
};
55
use bevy::prelude::*;
66

7+
/// Type alias for the query used in `handle_main_menu_interactions`.
8+
type MainMenuButtonInteractionQuery<'w, 's> = Query<
9+
'w,
10+
's,
11+
(
12+
&'static Interaction,
13+
&'static MenuButtonAction,
14+
&'static mut BackgroundColor,
15+
),
16+
(Changed<Interaction>, With<Button>),
17+
>;
18+
719
/// Handles button interactions for the main menu
820
pub fn handle_main_menu_interactions(
9-
mut interaction_query: Query<
10-
(&Interaction, &MenuButtonAction, &mut BackgroundColor),
11-
(Changed<Interaction>, With<Button>),
12-
>,
21+
mut interaction_query: MainMenuButtonInteractionQuery,
1322
mut next_state: ResMut<NextState<GameMenuState>>,
1423
mut settings_state: ResMut<NextState<SettingsMenuState>>,
1524
mut context: ResMut<StateTransitionContext>,

0 commit comments

Comments
 (0)