fix(engine): foundation→tableau drag hints, z-lift, and Android battery drain
Fixes #34, #35, #36 - all_hints: add Foundation as source for Tableau hints (guarded by take_from_foundation); previously H key never suggested Foundation→Tableau - end_drag / touch_end_drag: enforce take_from_foundation at input layer so a rejected-by-core MoveRequestEvent is never fired - animation_plugin: pub CARD_ANIM_Z_LIFT so card_plugin can consume it - update_card_entity: set CardAnim start.z = z + CARD_ANIM_Z_LIFT to eliminate 1-frame z artifact where animated card appeared behind resting cards - solitaire_app: use AutoVsync on Android (caps GPU at display Hz vs spinning at 200+ fps); add WinitSettings unfocused reactive_low_power so app draws ~1fps when backgrounded Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -734,8 +734,13 @@ fn end_drag(
|
||||
.is_some_and(|p| can_place_on_foundation(&bottom_card, p))
|
||||
}
|
||||
PileType::Tableau(_) => {
|
||||
game.0.piles.get(&target)
|
||||
.is_some_and(|p| can_place_on_tableau(&bottom_card, p))
|
||||
// Enforce the take-from-foundation rule at the input layer so the
|
||||
// engine never fires a MoveRequestEvent that game_state would reject.
|
||||
let foundation_allowed = !matches!(&origin, PileType::Foundation(_))
|
||||
|| game.0.take_from_foundation;
|
||||
foundation_allowed
|
||||
&& game.0.piles.get(&target)
|
||||
.is_some_and(|p| can_place_on_tableau(&bottom_card, p))
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
@@ -988,8 +993,13 @@ fn touch_end_drag(
|
||||
.is_some_and(|p| can_place_on_foundation(&bottom_card, p))
|
||||
}
|
||||
PileType::Tableau(_) => {
|
||||
game.0.piles.get(&target)
|
||||
.is_some_and(|p| can_place_on_tableau(&bottom_card, p))
|
||||
// Enforce the take-from-foundation rule at the input layer so the
|
||||
// engine never fires a MoveRequestEvent that game_state would reject.
|
||||
let foundation_allowed = !matches!(&origin, PileType::Foundation(_))
|
||||
|| game.0.take_from_foundation;
|
||||
foundation_allowed
|
||||
&& game.0.piles.get(&target)
|
||||
.is_some_and(|p| can_place_on_tableau(&bottom_card, p))
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
@@ -1591,6 +1601,26 @@ pub fn all_hints(game: &GameState) -> Vec<(PileType, PileType, usize)> {
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 2b — Foundation → Tableau moves (only when the rule allows it).
|
||||
// Foundation piles are excluded from Pass 1 & 2's source list because they
|
||||
// should never hint Foundation→Foundation. Here we handle the return path
|
||||
// separately so the guarded `take_from_foundation` rule is respected.
|
||||
if game.take_from_foundation {
|
||||
for slot in 0..4_u8 {
|
||||
let from = PileType::Foundation(slot);
|
||||
let Some(from_pile) = game.piles.get(&from) else { continue };
|
||||
let Some(card) = from_pile.cards.last().filter(|c| c.face_up) else { continue };
|
||||
for i in 0..7_usize {
|
||||
let dest = PileType::Tableau(i);
|
||||
if let Some(dest_pile) = game.piles.get(&dest)
|
||||
&& can_place_on_tableau(card, dest_pile) {
|
||||
hints.push((from.clone(), dest, 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 3 — suggest drawing from the stock when no other hint was found.
|
||||
if hints.is_empty() {
|
||||
let stock_non_empty = game.piles.get(&PileType::Stock)
|
||||
|
||||
Reference in New Issue
Block a user