Skip to content

Commit

Permalink
Track stats
Browse files Browse the repository at this point in the history
  • Loading branch information
benfrankel committed Jul 28, 2024
1 parent b7e1726 commit 41d39f8
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 255 deletions.
2 changes: 2 additions & 0 deletions src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod combat;
pub mod ground;
pub mod spotlight;
pub mod sprite;
pub mod stats;
pub mod wave;

use std::borrow::Cow;
Expand All @@ -32,6 +33,7 @@ pub(super) fn plugin(app: &mut App) {
ground::plugin,
spotlight::plugin,
sprite::plugin,
stats::plugin,
wave::plugin,
));
}
Expand Down
34 changes: 32 additions & 2 deletions src/game/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use bevy_kira_audio::prelude::*;
use serde::Deserialize;
use serde::Serialize;

use crate::game::actor::faction::Faction;
use crate::game::card::action::CardAction;
use crate::game::card::action::CardActionKey;
use crate::game::card::action::CardActionMap;
Expand All @@ -20,7 +21,7 @@ pub mod deck;
pub mod movement;

pub(super) fn plugin(app: &mut App) {
app.configure::<ConfigHandle<CardConfig>>();
app.configure::<(ConfigHandle<CardConfig>, OnPlayCard)>();

app.add_plugins((
action::plugin,
Expand Down Expand Up @@ -179,7 +180,7 @@ pub struct Card {
#[serde(default = "one")]
pub play_sfx_volume: f64,
#[serde(rename = "action")]
action_key: CardActionKey,
pub action_key: CardActionKey,
#[serde(skip)]
pub action: CardAction,
pub action_modifier: CardActionModifier,
Expand Down Expand Up @@ -232,3 +233,32 @@ pub fn card(key: impl Into<String>, active: Option<bool>) -> impl EntityCommand
});
}
}

/// An observable event triggered when a card is played.
#[derive(Event)]
pub struct OnPlayCard(pub String);

impl Configure for OnPlayCard {
fn configure(app: &mut App) {
app.observe(play_card);
}
}

fn play_card(
trigger: Trigger<OnPlayCard>,
mut commands: Commands,
config: ConfigRef<CardConfig>,
audio: Res<Audio>,
faction_query: Query<&Faction>,
) {
let entity = r!(trigger.get_entity());
let config = r!(config.get());
let card = r!(config.card_map.get(&trigger.event().0));
let faction = r!(faction_query.get(entity));

if let (Faction::Player, Some(play_sfx)) = (faction, card.play_sfx.clone()) {
audio.play(play_sfx).with_volume(card.play_sfx_volume);
}

commands.run_system_with_input(card.action.0, (entity, card.action_modifier.clone()));
}
2 changes: 1 addition & 1 deletion src/game/card/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ impl FromWorld for CardActionMap {
#[derive(Reflect, Serialize, Deserialize, Eq, PartialEq, Hash, Copy, Clone)]
pub enum CardActionKey {
Step,
Heal,
Attack,
Heal,
}

/// A newtyped `SystemId` with a `Default` impl.
Expand Down
26 changes: 6 additions & 20 deletions src/game/card/deck.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use bevy::prelude::*;
use bevy_kira_audio::prelude::*;
use serde::Deserialize;
use serde::Serialize;

use crate::core::UpdateSet;
use crate::game::actor::faction::Faction;
use crate::game::audio::music::on_full_beat;
use crate::game::card::card;
use crate::game::card::CardConfig;
use crate::game::card::OnPlayCard;
use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
Expand Down Expand Up @@ -83,25 +81,13 @@ impl Deck {
}
}

fn play_card_from_deck(
mut commands: Commands,
config: ConfigRef<CardConfig>,
audio: Res<Audio>,
mut deck_query: Query<(Entity, &Faction, &mut Deck)>,
) {
let config = r!(config.get());

for (entity, &faction, mut deck) in &mut deck_query {
fn play_card_from_deck(mut commands: Commands, mut deck_query: Query<(Entity, &mut Deck)>) {
for (entity, mut deck) in &mut deck_query {
let card_key = c!(deck.advance(1));
let card = c!(config.card_map.get(card_key));

if let (Faction::Player, Some(play_sfx)) = (faction, card.play_sfx.clone()) {
audio.play(play_sfx).with_volume(card.play_sfx_volume);
}

let action = card.action;
let action_modifier = card.action_modifier.clone();
commands.run_system_with_input(action.0, (entity, action_modifier));
commands
.entity(entity)
.trigger(OnPlayCard(card_key.clone()));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/game/combat/death.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub(super) fn plugin(app: &mut App) {
app.configure::<(IsDead, DespawnOnDeath, DeathSfx)>();
}

/// An observable event on an actor's death.
/// An observable event triggered when an actor dies.
/// Remember to filter out `IsDead` entities before triggering this event.
#[derive(Event)]
pub struct OnDeath;
Expand Down
141 changes: 141 additions & 0 deletions src/game/stats.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use bevy::ecs::system::EntityCommand;
use bevy::ecs::system::SystemState;
use bevy::prelude::*;

use crate::core::UpdateSet;
use crate::game::actor::faction::Faction;
use crate::game::audio::music::on_beat;
use crate::game::audio::AudioConfig;
use crate::game::card::action::CardActionKey;
use crate::game::card::CardConfig;
use crate::game::card::OnPlayCard;
use crate::game::combat::death::OnDeath;
use crate::ui::prelude::*;
use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
app.configure::<Stats>();
}

#[derive(Resource, Reflect, Default, Copy, Clone)]
#[reflect(Resource)]
pub struct Stats {
pub beats: usize,
pub kills: usize,
pub played_moves: usize,
pub played_attacks: usize,
pub played_heals: usize,
}

impl Configure for Stats {
fn configure(app: &mut App) {
app.register_type::<Self>();
app.init_resource::<Self>();
app.add_systems(
Update,
count_beats.in_set(UpdateSet::Update).run_if(on_beat(1)),
);
app.observe(count_kills);
app.observe(count_played_cards);
}
}

fn count_beats(mut stats: ResMut<Stats>) {
stats.beats += 1;
}

fn count_kills(
trigger: Trigger<OnDeath>,
faction_query: Query<&Faction>,
mut stats: ResMut<Stats>,
) {
let entity = r!(trigger.get_entity());
let faction = r!(faction_query.get(entity));
if !faction.is_enemy() {
return;
}

stats.kills += 1;
}

fn count_played_cards(
trigger: Trigger<OnPlayCard>,
config: ConfigRef<CardConfig>,
faction_query: Query<&Faction>,
mut stats: ResMut<Stats>,
) {
let entity = r!(trigger.get_entity());
let faction = r!(faction_query.get(entity));
if !faction.is_player() {
return;
}

let config = r!(config.get());
let card = r!(config.card_map.get(&trigger.event().0));
match card.action_key {
CardActionKey::Attack => stats.played_attacks += 1,
CardActionKey::Heal => stats.played_heals += 1,
_ => stats.played_moves += 1,
}
}

impl EntityCommand for Stats {
fn apply(self, id: Entity, world: &mut World) {
let mut system_state = SystemState::<(ConfigRef<AudioConfig>, Res<Stats>)>::new(world);
let (audio_config, stats) = system_state.get(world);
let audio_config = r!(audio_config.get());
let stats = [
format!(
"[b]{:.0}",
stats.beats as f64 / 8.0 * 60.0 / audio_config.music_bpm
+ audio_config.music_zeroth_beat
),
"seconds partied".to_string(),
format!("[b]{}", stats.kills),
"blobos impressed".to_string(),
format!("[b]{}", stats.played_moves),
"dances performed".to_string(),
format!("[b]{}", stats.played_attacks),
"notes played".to_string(),
format!("[b]{}", stats.played_heals),
"rests taken".to_string(),
];

world
.entity_mut(id)
.insert((
Name::new("StatsGrid"),
NodeBundle {
style: Style {
display: Display::Grid,
grid_template_columns: RepeatedGridTrack::auto(2),
row_gap: Vw(1.2),
column_gap: Vw(2.5),
..default()
},
..default()
},
))
.with_children(|children| {
for (i, text) in stats.into_iter().enumerate() {
children.spawn((
Name::new("StatsSpan"),
TextBundle::from_sections(parse_rich(&text)).with_style(Style {
justify_self: if i % 2 == 0 {
JustifySelf::End
} else {
JustifySelf::Start
},
..default()
}),
DynamicFontSize::new(Vw(3.0)).with_step(8.0),
ThemeColorForText(vec![if i % 2 == 0 {
ThemeColor::Indicator
} else {
ThemeColor::BodyText
}]),
));
}
});
}
}
3 changes: 0 additions & 3 deletions src/screen.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
mod end;
mod loading;
pub mod playing;
mod splash;
Expand All @@ -23,7 +22,6 @@ pub fn plugin(app: &mut App) {
title::plugin,
loading::plugin,
playing::plugin,
end::plugin,
));
}

Expand All @@ -36,7 +34,6 @@ pub enum Screen {
Title,
Loading,
Playing,
End,
}

impl Configure for Screen {
Expand Down
Loading

0 comments on commit 41d39f8

Please sign in to comment.