@@ 29,6 29,7 @@ mod util;
mod plugins;
mod game_status;
+use game_status::Card;
#[macro_export]
macro_rules! seed_gen {
@@ 92,6 93,10 @@ fn main() {
// clear color
app.insert_resource(ClearColor(Color::rgb(0.53, 0.53, 0.7)));
+ // yaml assets
+ app.add_asset::<util::YamlAsset>()
+ .init_asset_loader::<util::YamlLoader>();
+
// add the top level app state
app.add_state::<AppState>();
@@ 109,6 114,8 @@ fn main() {
app.add_plugin(plugins::MenuPlugin);
app.add_plugin(plugins::GamePlugin);
+ app.add_event::<LoadCardManifestEvent>()
+ .add_system(load_card_manifest.run_if(on_event::<LoadCardManifestEvent>()));
app.add_startup_system(setup).add_system(move_camera);
app.run();
@@ 118,7 125,14 @@ fn main() {
#[derive(Component)]
struct PlayerCamera;
-fn setup(mut commands: Commands) {
+fn setup(
+ mut commands: Commands,
+ asset_server: Res<AssetServer>,
+ mut lcm_ev_w: EventWriter<LoadCardManifestEvent>,
+) {
+ commands.insert_resource(CardManifestHandle { handle: asset_server.load("card_manifest.yaml") });
+ lcm_ev_w.send(LoadCardManifestEvent);
+
commands
.spawn((
Camera3dBundle {
@@ 134,6 148,18 @@ fn setup(mut commands: Commands) {
.insert(PlayerCamera);
}
+struct LoadCardManifestEvent;
+
+fn load_card_manifest(
+ mut commands: Commands,
+ yaml_assets: Res<Assets<util::YamlAsset>>,
+ card_manifest_handle: Res<CardManifestHandle>,
+) {
+ let card_manifest_yaml: String = yaml_assets.get(&card_manifest_handle.handle).unwrap().0.clone();
+ let card_manifest: CardManifest = serde_yaml::from_str(&card_manifest_yaml).unwrap();
+ commands.insert_resource(card_manifest);
+}
+
fn move_camera(
time: Res<Time>,
input: Res<Input<KeyCode>>,
@@ 211,6 237,17 @@ impl Default for NetworkingOptions {
}
}
+#[derive(Resource, serde::Deserialize)]
+pub struct CardManifest {
+ pub version: String,
+ pub cards: Vec<Card>,
+}
+
+#[derive(Resource)]
+pub struct CardManifestHandle {
+ pub handle: Handle<util::YamlAsset>,
+}
+
#[derive(Resource, Reflect)]
#[reflect(Resource)]
pub struct Global {
@@ 11,9 11,9 @@ use bevy_egui::{egui, EguiContexts};
use crate::{
api::game::{Action, Command, Game},
- game_status::{Card, CardAction, PlayerState},
+ game_status::PlayerState,
plugins::GameActionCreateCallEvent,
- AppState, Global,
+ AppState, Global, CardManifest,
};
use super::{GameData, RefreshGameEvent};
@@ 337,6 337,7 @@ pub fn dev_details_ui(
mut contexts: EguiContexts,
global: Res<Global>,
game_data: Res<GameData>,
+ card_manifest: Res<CardManifest>,
mut create_action_ev_w: EventWriter<GameActionCreateCallEvent>,
mut rg_ev_w: EventWriter<RefreshGameEvent>,
) {
@@ 357,7 358,7 @@ pub fn dev_details_ui(
if status.actions.is_empty() && game.host_id == global.user.as_ref().unwrap().id {
if ui.button("Init Game").clicked() {
// NOTE/FIXME: hardcoded game init
- hardcoded_init(game, &mut create_action_ev_w);
+ hardcoded_init(game, &mut create_action_ev_w, &card_manifest);
rg_ev_w.send(RefreshGameEvent);
}
}
@@ 380,85 381,26 @@ pub fn dev_details_ui(
});
}
-fn hardcoded_init(game: &Game, create_action_ev_w: &mut EventWriter<GameActionCreateCallEvent>) {
+fn hardcoded_init(
+ game: &Game,
+ create_action_ev_w: &mut EventWriter<GameActionCreateCallEvent>,
+ card_manifest: &CardManifest,
+) {
// first, piles
- create_action_ev_w.send(GameActionCreateCallEvent {
- action: Action::new(
- &game.id,
- &game.host_id,
- &game.host_id,
- &Command::InitSupplyPile {
- card: Card {
- name: "Narcissistic Cannibal".to_string(),
- short_details: vec![],
- long_details: vec![],
- cost: 4,
- actions: vec![],
- },
- amount: 10,
- },
- None,
- ),
- });
- create_action_ev_w.send(GameActionCreateCallEvent {
- action: Action::new(
- &game.id,
- &game.host_id,
- &game.host_id,
- &Command::InitSupplyPile {
- card: Card {
- name: "Gib Möney".to_string(),
- short_details: vec!["Roll 1d6 for currency".to_string()],
- long_details: vec![],
- cost: 0,
- actions: vec![CardAction {
- command: Command::RollForCurrency {
- amount: 1,
- sides: 6,
- },
- }],
- },
- amount: 10,
- },
- None,
- ),
- });
- create_action_ev_w.send(GameActionCreateCallEvent {
- action: Action::new(
- &game.id,
- &game.host_id,
- &game.host_id,
- &Command::InitSupplyPile {
- card: Card {
- name: "Test Card 3".to_string(),
- short_details: vec![],
- long_details: vec![],
- cost: 4,
- actions: vec![],
+ for card in &card_manifest.cards {
+ create_action_ev_w.send(GameActionCreateCallEvent {
+ action: Action::new(
+ &game.id,
+ &game.host_id,
+ &game.host_id,
+ &Command::InitSupplyPile {
+ card: card.clone(),
+ amount: 6,
},
- amount: 10,
- },
- None,
- ),
- });
- create_action_ev_w.send(GameActionCreateCallEvent {
- action: Action::new(
- &game.id,
- &game.host_id,
- &game.host_id,
- &Command::InitSupplyPile {
- card: Card {
- name: "Test Card 4".to_string(),
- short_details: vec![],
- long_details: vec![],
- cost: 2,
- actions: vec![],
- },
- amount: 10,
- },
- None,
- ),
- });
+ None,
+ ),
+ });
+ }
// second, set a player to the action phase, to start the game
create_action_ev_w.send(GameActionCreateCallEvent {
@@ 6,6 6,8 @@
* See LICENSE for licensing information.
*/
+use bevy::{asset::{AssetLoader, LoadedAsset}, reflect::TypeUuid};
+
pub mod egui;
mod action_to_log;
@@ 27,3 29,29 @@ pub fn get_next_player<'a>(player: &'a PlayerStatus, game_status: &'a GameStatus
.find(|np| np.1.turn_n == next_turn_n)
.unwrap()
}
+
+#[derive(Debug, TypeUuid)]
+#[uuid = "da42e27e-e968-4c6a-9892-d96e38b0e643"]
+pub struct YamlAsset(pub String);
+
+#[derive(Default)]
+pub struct YamlLoader;
+
+impl AssetLoader for YamlLoader {
+ fn load<'a>(
+ &'a self,
+ bytes: &'a [u8],
+ load_context: &'a mut bevy::asset::LoadContext,
+ ) -> bevy::utils::BoxedFuture<'a, Result<(), bevy::asset::Error>> {
+ Box::pin(async move {
+ let yaml_str = std::str::from_utf8(bytes)?;
+ let asset = YamlAsset(yaml_str.into());
+ load_context.set_default_asset(LoadedAsset::new(asset));
+ Ok(())
+ })
+ }
+
+ fn extensions(&self) -> &[&str] {
+ &["yaml"]
+ }
+}