feat(engine): add daily challenge, level-up toast, and daily_devotee achievement
Phase 6 part 2 (partial): - daily_seed_for(date) and PlayerProgress::record_daily_completion in solitaire_data, with streak logic that increments on consecutive days, resets on a skipped day, and is idempotent on same-day re-completions. - DailyChallengePlugin tracks today's seed, awards +100 XP and updates the streak when the player wins a game whose seed matches. Pressing C starts a new game with the daily seed. - LevelUpEvent toast in AnimationPlugin announces level changes. - AchievementContext gains daily_challenge_streak; daily_devotee achievement unlocks at streak >= 7. AchievementPlugin reads ProgressResource and runs after ProgressUpdate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -10,12 +10,14 @@ use crate::card_plugin::CardEntity;
|
||||
use crate::events::{AchievementUnlockedEvent, GameWonEvent};
|
||||
use crate::game_plugin::GameMutation;
|
||||
use crate::layout::LayoutResource;
|
||||
use crate::progress_plugin::LevelUpEvent;
|
||||
|
||||
/// Duration of a card slide (move) animation in seconds.
|
||||
pub const SLIDE_SECS: f32 = 0.15;
|
||||
|
||||
const WIN_TOAST_SECS: f32 = 4.0;
|
||||
const ACHIEVEMENT_TOAST_SECS: f32 = 3.0;
|
||||
const LEVELUP_TOAST_SECS: f32 = 3.0;
|
||||
const CASCADE_STAGGER: f32 = 0.05;
|
||||
const CASCADE_DURATION: f32 = 0.5;
|
||||
|
||||
@@ -50,12 +52,14 @@ impl Plugin for AnimationPlugin {
|
||||
// is idempotent in Bevy.
|
||||
app.add_event::<GameWonEvent>()
|
||||
.add_event::<AchievementUnlockedEvent>()
|
||||
.add_event::<LevelUpEvent>()
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
advance_card_anims,
|
||||
handle_win_cascade,
|
||||
handle_achievement_toast,
|
||||
handle_levelup_toast,
|
||||
tick_toasts,
|
||||
)
|
||||
.after(GameMutation),
|
||||
@@ -133,6 +137,16 @@ fn handle_achievement_toast(
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_levelup_toast(mut commands: Commands, mut events: EventReader<LevelUpEvent>) {
|
||||
for ev in events.read() {
|
||||
spawn_toast(
|
||||
&mut commands,
|
||||
format!("Level Up! → {}", ev.new_level),
|
||||
LEVELUP_TOAST_SECS,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn tick_toasts(
|
||||
mut commands: Commands,
|
||||
time: Res<Time>,
|
||||
|
||||
Reference in New Issue
Block a user