From 0adf19cfb7e1809e3a54d23da6cd1c3c7a948ec2 Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sat, 15 May 2021 06:31:16 +0100 Subject: [PATCH] Moved digimon rendering to it's own function. --- dcb-tools/dcb-card-editor/src/edit_state.rs | 5 + dcb-tools/dcb-card-editor/src/main.rs | 856 ++++++++++---------- 2 files changed, 420 insertions(+), 441 deletions(-) diff --git a/dcb-tools/dcb-card-editor/src/edit_state.rs b/dcb-tools/dcb-card-editor/src/edit_state.rs index 022a5a2..866297c 100644 --- a/dcb-tools/dcb-card-editor/src/edit_state.rs +++ b/dcb-tools/dcb-card-editor/src/edit_state.rs @@ -13,6 +13,11 @@ pub enum CardEditState { } impl CardEditState { + /// Creates an edit state from a digimon + pub fn digimon(digimon: &dcb::Digimon) -> Self { + Self::Digimon(DigimonEditState::new(digimon)) + } + /// Returns this card as digimon pub fn as_digimon_mut(&mut self) -> Option<&mut DigimonEditState> { match self { diff --git a/dcb-tools/dcb-card-editor/src/main.rs b/dcb-tools/dcb-card-editor/src/main.rs index 99bbff6..18491e8 100644 --- a/dcb-tools/dcb-card-editor/src/main.rs +++ b/dcb-tools/dcb-card-editor/src/main.rs @@ -238,450 +238,13 @@ impl epi::App for CardEditor { match card { Card::Digimon(digimon) => { // Get the current card edit state as digimon - let cur_card_edit_state = match cur_card_edit_state { - Some(state) => state, - None => { - cur_card_edit_state.insert(CardEditState::Digimon(DigimonEditState::new(digimon))) - }, - }; - let digimon_edit_state = cur_card_edit_state + let edit_state = cur_card_edit_state + .get_or_insert_with(|| CardEditState::digimon(digimon)) .as_digimon_mut() .expect("Edit state wasn't a digimon when a digimon was selected"); - // Write all ui - ui.heading(digimon.name.as_str()); - - let mut any_changed = false; - ui.horizontal(|ui| { - ui.label("Name"); - any_changed |= ui.text_edit_singleline(&mut digimon_edit_state.name).changed(); - }); - - ui.vertical(|ui| { - ui.label("Speciality"); - ui.horizontal(|ui| { - for &speciality in Speciality::ALL { - ui.radio_value(&mut digimon.speciality, speciality, speciality.as_str()); - } - }); - }); - - ui.vertical(|ui| { - ui.label("Level"); - ui.horizontal(|ui| { - for &level in Level::ALL { - ui.radio_value(&mut digimon.level, level, level.as_str()); - } - }); - }); - - ui.horizontal(|ui| { - ui.label("HP"); - ui.add(egui::Slider::new(&mut digimon.hp, 0..=5000)); - }); - ui.horizontal(|ui| { - ui.label("DP"); - ui.add(egui::Slider::new(&mut digimon.dp_cost, 0..=100)); - }); - ui.horizontal(|ui| { - ui.label("+P"); - ui.add(egui::Slider::new(&mut digimon.dp_give, 0..=100)); - }); - - for (name, mv, mv_name) in std::array::IntoIter::new([ - ( - "Circle", - &mut digimon.move_circle, - &mut digimon_edit_state.move_circle_name, - ), - ( - "Triangle", - &mut digimon.move_triangle, - &mut digimon_edit_state.move_triangle_name, - ), - ( - "Cross", - &mut digimon.move_cross, - &mut digimon_edit_state.move_cross_name, - ), - ]) { - ui.group(|ui| { - ui.heading(name); - ui.horizontal(|ui| { - ui.label("Name"); - any_changed |= ui.text_edit_singleline(mv_name).changed(); - }); - ui.horizontal(|ui| { - ui.label("Power"); - ui.add(egui::Slider::new(&mut mv.power, 0..=2000)); - }); - }); - } - - ui.group(|ui| { - ui.label("Cross move effect"); - ui.horizontal_wrapped(|ui| { - for cross_move_effect in - std::iter::once(None).chain(CrossMoveEffect::ALL.iter().map(Some)) - { - let text = match cross_move_effect { - Some(effect) => effect.as_str(), - None => "None", - }; - ui.radio_value( - &mut digimon.cross_move_effect, - cross_move_effect.copied(), - text, - ); - } - }); - }); - - ui.group(|ui| { - ui.label("Effect description"); - for line in &mut digimon_edit_state.effect_description { - any_changed |= ui.text_edit_singleline(line).changed(); - } - }); - - ui.group(|ui| { - ui.label("Effect arrow color"); - ui.horizontal(|ui| { - for arrow_color in std::iter::once(None).chain(ArrowColor::ALL.iter().map(Some)) { - let text = match arrow_color { - Some(arrow_color) => arrow_color.as_str(), - None => "None", - }; - ui.radio_value(&mut digimon.effect_arrow_color, arrow_color.copied(), text); - } - }); - }); - - ui.group(|ui| { - ui.label("Effect conditions"); - for cond in &mut digimon.effect_conditions { - ui.group(|ui| { - match cond { - Some(cond) => { - ui.vertical(|ui| { - ui.checkbox(&mut cond.misfire, "Misfire"); - - ui.label("Property cmp"); - ui.horizontal_wrapped(|ui| { - for &digimon_property in DigimonProperty::ALL { - ui.radio_value( - &mut cond.property_cmp, - digimon_property, - digimon_property.as_str(), - ); - } - }); - - ui.label("Arg property"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value( - &mut cond.arg_property, - digimon_property.copied(), - text, - ); - } - }); - - ui.horizontal(|ui| { - ui.label("Num property"); - ui.add(egui::Slider::new(&mut cond.arg_num, 0..=10)); - }); - - ui.label("Operation"); - ui.horizontal_wrapped(|ui| { - for &operation in EffectConditionOperation::ALL { - ui.radio_value( - &mut cond.operation, - operation, - operation.as_str(), - ); - } - }); - }); - }, - None => { - ui.label("None"); - // TODO: Be able to add new once all fields are figured out. - }, - } - }); - } - }); - - ui.group(|ui| { - ui.label("Effects"); - for effect in &mut digimon.effects { - ui.group(|ui| { - match effect { - Some(Effect::ChangeProperty { - property, - a, - b, - c, - x, - y, - op, - }) => { - ui.heading("Change Property"); - ui.vertical(|ui| { - ui.label("Property"); - ui.horizontal_wrapped(|ui| { - for &digimon_property in DigimonProperty::ALL { - ui.radio_value( - property, - digimon_property, - digimon_property.as_str(), - ); - } - }); - - ui.label("A"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value(a, digimon_property.copied(), text); - } - }); - ui.label("B"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value(b, digimon_property.copied(), text); - } - }); - ui.label("C"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value(c, digimon_property.copied(), text); - } - }); - - ui.horizontal(|ui| { - ui.label("X"); - ui.add(egui::Slider::new(x, 0..=500)); - }); - ui.horizontal(|ui| { - ui.label("Y"); - ui.add(egui::Slider::new(y, 0..=500)); - }); - - ui.label("Operation"); - ui.horizontal_wrapped(|ui| { - for &operation in EffectOperation::ALL { - ui.radio_value(op, operation, operation.as_str()); - } - }); - }); - }, - Some(Effect::UseAttack { player, attack }) => { - ui.heading("Use attack"); - - ui.label("Player"); - ui.horizontal_wrapped(|ui| { - for &player_type in PlayerType::ALL { - ui.radio_value(player, player_type, player_type.as_str()); - } - }); - - ui.label("Attack"); - ui.horizontal_wrapped(|ui| { - for &attack_type in AttackType::ALL { - ui.radio_value(attack, attack_type, attack_type.as_str()); - } - }); - }, - Some(Effect::SetTempSlot { a, b, c, op }) => { - ui.heading("Set temp slot"); - ui.vertical(|ui| { - ui.label("A"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value(a, digimon_property.copied(), text); - } - }); - ui.label("B"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value(b, digimon_property.copied(), text); - } - }); - ui.label("C"); - ui.horizontal_wrapped(|ui| { - for digimon_property in std::iter::once(None) - .chain(DigimonProperty::ALL.iter().map(Some)) - { - let text = match digimon_property { - Some(property) => property.as_str(), - None => "None", - }; - ui.radio_value(c, digimon_property.copied(), text); - } - }); - - ui.label("Operation"); - ui.horizontal_wrapped(|ui| { - for &operation in EffectOperation::ALL { - ui.radio_value(op, operation, operation.as_str()); - } - }); - }); - }, - Some(Effect::MoveCards { - player, - source, - destination, - count, - }) => { - ui.heading("Move cards"); - - ui.label("Player"); - ui.horizontal_wrapped(|ui| { - for &player_type in PlayerType::ALL { - ui.radio_value(player, player_type, player_type.as_str()); - } - }); - - ui.label("Source"); - ui.horizontal_wrapped(|ui| { - for &slot in Slot::ALL { - ui.radio_value(source, slot, slot.as_str()); - } - }); - - ui.label("Destination"); - ui.horizontal_wrapped(|ui| { - for &slot in Slot::ALL { - ui.radio_value(destination, slot, slot.as_str()); - } - }); - - ui.horizontal(|ui| { - ui.label("Count"); - ui.add(egui::Slider::new(count, 0..=40)); - }); - }, - Some(Effect::ShuffleOnlineDeck { player }) => { - ui.heading("Shuffle online deck"); - - ui.label("Player"); - ui.horizontal_wrapped(|ui| { - for &player_type in PlayerType::ALL { - ui.radio_value(player, player_type, player_type.as_str()); - } - }); - }, - Some(Effect::VoidOpponentSupportEffect) => { - ui.heading("Void opponent support effect"); - }, - Some(Effect::VoidOpponentSupportOptionEffect) => { - ui.heading("Void opponent support option effect"); - }, - Some(Effect::PickPartnerCard) => { - ui.heading("Pick partner card"); - }, - Some(Effect::CycleOpponentAttackType) => { - ui.heading("Cycle opponent attack type"); - }, - Some(Effect::KoDigimonRevives { health }) => { - ui.heading("Ko'd digimon revives"); - - ui.horizontal(|ui| { - ui.label("Health"); - ui.add(egui::Slider::new(health, 0..=2000)); - }); - }, - Some(Effect::DrawCards { player, count }) => { - ui.heading("Draw cards"); - - ui.label("Player"); - ui.horizontal_wrapped(|ui| { - for &player_type in PlayerType::ALL { - ui.radio_value(player, player_type, player_type.as_str()); - } - }); - - ui.horizontal(|ui| { - ui.label("Count"); - ui.add(egui::Slider::new(count, 0..=40)); - }); - }, - Some(Effect::OwnAttackBecomesEatUpHP) => { - ui.heading("Own attack becomes eat up hp"); - }, - Some(Effect::AttackFirst { player }) => { - ui.heading("Attack first"); - - ui.label("Player"); - ui.horizontal_wrapped(|ui| { - for &player_type in PlayerType::ALL { - ui.radio_value(player, player_type, player_type.as_str()); - } - }); - }, - None => { - ui.label("None"); - // TODO: Be able to add new once all fields are figured out. - }, - } - }); - } - }); - - - // Then try to apply if anything was changed - if any_changed { - let status = match digimon_edit_state.apply(digimon) { - Ok(()) => Cow::Borrowed("All ok"), - Err(err) => Cow::Owned(format!("Error: {:?}", err)), - }; - - *cur_card_edit_status = Some(status); - } - - if let Some(cur_card_edit_status) = cur_card_edit_status { - ui.separator(); - ui.label(&**cur_card_edit_status); - } + // Then render it + self::render_digimon_card(ui, digimon, edit_state, cur_card_edit_status); }, Card::Item(_) | Card::Digivolve(_) => { ui.heading("TODO"); @@ -737,3 +300,414 @@ pub enum Card<'a> { Item(&'a mut dcb::Item), Digivolve(&'a mut dcb::Digivolve), } + +/// Renders a digimon card +fn render_digimon_card( + ui: &mut egui::Ui, digimon: &mut dcb::Digimon, edit_state: &mut DigimonEditState, + cur_card_edit_status: &mut Option>, +) { + // Write all ui + ui.heading(digimon.name.as_str()); + + let mut any_changed = false; + ui.horizontal(|ui| { + ui.label("Name"); + any_changed |= ui.text_edit_singleline(&mut edit_state.name).changed(); + }); + + ui.vertical(|ui| { + ui.label("Speciality"); + ui.horizontal(|ui| { + for &speciality in Speciality::ALL { + ui.radio_value(&mut digimon.speciality, speciality, speciality.as_str()); + } + }); + }); + + ui.vertical(|ui| { + ui.label("Level"); + ui.horizontal(|ui| { + for &level in Level::ALL { + ui.radio_value(&mut digimon.level, level, level.as_str()); + } + }); + }); + + ui.horizontal(|ui| { + ui.label("HP"); + ui.add(egui::Slider::new(&mut digimon.hp, 0..=5000)); + }); + ui.horizontal(|ui| { + ui.label("DP"); + ui.add(egui::Slider::new(&mut digimon.dp_cost, 0..=100)); + }); + ui.horizontal(|ui| { + ui.label("+P"); + ui.add(egui::Slider::new(&mut digimon.dp_give, 0..=100)); + }); + + for (name, mv, mv_name) in std::array::IntoIter::new([ + ("Circle", &mut digimon.move_circle, &mut edit_state.move_circle_name), + ( + "Triangle", + &mut digimon.move_triangle, + &mut edit_state.move_triangle_name, + ), + ("Cross", &mut digimon.move_cross, &mut edit_state.move_cross_name), + ]) { + ui.group(|ui| { + ui.heading(name); + ui.horizontal(|ui| { + ui.label("Name"); + any_changed |= ui.text_edit_singleline(mv_name).changed(); + }); + ui.horizontal(|ui| { + ui.label("Power"); + ui.add(egui::Slider::new(&mut mv.power, 0..=2000)); + }); + }); + } + + ui.group(|ui| { + ui.label("Cross move effect"); + ui.horizontal_wrapped(|ui| { + for cross_move_effect in std::iter::once(None).chain(CrossMoveEffect::ALL.iter().map(Some)) { + let text = match cross_move_effect { + Some(effect) => effect.as_str(), + None => "None", + }; + ui.radio_value(&mut digimon.cross_move_effect, cross_move_effect.copied(), text); + } + }); + }); + + ui.group(|ui| { + ui.label("Effect description"); + for line in &mut edit_state.effect_description { + any_changed |= ui.text_edit_singleline(line).changed(); + } + }); + + ui.group(|ui| { + ui.label("Effect arrow color"); + ui.horizontal(|ui| { + for arrow_color in std::iter::once(None).chain(ArrowColor::ALL.iter().map(Some)) { + let text = match arrow_color { + Some(arrow_color) => arrow_color.as_str(), + None => "None", + }; + ui.radio_value(&mut digimon.effect_arrow_color, arrow_color.copied(), text); + } + }); + }); + + ui.group(|ui| { + ui.label("Effect conditions"); + for cond in &mut digimon.effect_conditions { + ui.group(|ui| { + match cond { + Some(cond) => { + ui.vertical(|ui| { + ui.checkbox(&mut cond.misfire, "Misfire"); + + ui.label("Property cmp"); + ui.horizontal_wrapped(|ui| { + for &digimon_property in DigimonProperty::ALL { + ui.radio_value(&mut cond.property_cmp, digimon_property, digimon_property.as_str()); + } + }); + + ui.label("Arg property"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(&mut cond.arg_property, digimon_property.copied(), text); + } + }); + + ui.horizontal(|ui| { + ui.label("Num property"); + ui.add(egui::Slider::new(&mut cond.arg_num, 0..=10)); + }); + + ui.label("Operation"); + ui.horizontal_wrapped(|ui| { + for &operation in EffectConditionOperation::ALL { + ui.radio_value(&mut cond.operation, operation, operation.as_str()); + } + }); + }); + }, + None => { + ui.label("None"); + // TODO: Be able to add new once all fields are figured out. + }, + } + }); + } + }); + + ui.group(|ui| { + ui.label("Effects"); + for effect in &mut digimon.effects { + ui.group(|ui| { + match effect { + Some(Effect::ChangeProperty { + property, + a, + b, + c, + x, + y, + op, + }) => { + ui.heading("Change Property"); + ui.vertical(|ui| { + ui.label("Property"); + ui.horizontal_wrapped(|ui| { + for &digimon_property in DigimonProperty::ALL { + ui.radio_value(property, digimon_property, digimon_property.as_str()); + } + }); + + ui.label("A"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(a, digimon_property.copied(), text); + } + }); + ui.label("B"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(b, digimon_property.copied(), text); + } + }); + ui.label("C"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(c, digimon_property.copied(), text); + } + }); + + ui.horizontal(|ui| { + ui.label("X"); + ui.add(egui::Slider::new(x, 0..=500)); + }); + ui.horizontal(|ui| { + ui.label("Y"); + ui.add(egui::Slider::new(y, 0..=500)); + }); + + ui.label("Operation"); + ui.horizontal_wrapped(|ui| { + for &operation in EffectOperation::ALL { + ui.radio_value(op, operation, operation.as_str()); + } + }); + }); + }, + Some(Effect::UseAttack { player, attack }) => { + ui.heading("Use attack"); + + ui.label("Player"); + ui.horizontal_wrapped(|ui| { + for &player_type in PlayerType::ALL { + ui.radio_value(player, player_type, player_type.as_str()); + } + }); + + ui.label("Attack"); + ui.horizontal_wrapped(|ui| { + for &attack_type in AttackType::ALL { + ui.radio_value(attack, attack_type, attack_type.as_str()); + } + }); + }, + Some(Effect::SetTempSlot { a, b, c, op }) => { + ui.heading("Set temp slot"); + ui.vertical(|ui| { + ui.label("A"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(a, digimon_property.copied(), text); + } + }); + ui.label("B"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(b, digimon_property.copied(), text); + } + }); + ui.label("C"); + ui.horizontal_wrapped(|ui| { + for digimon_property in + std::iter::once(None).chain(DigimonProperty::ALL.iter().map(Some)) + { + let text = match digimon_property { + Some(property) => property.as_str(), + None => "None", + }; + ui.radio_value(c, digimon_property.copied(), text); + } + }); + + ui.label("Operation"); + ui.horizontal_wrapped(|ui| { + for &operation in EffectOperation::ALL { + ui.radio_value(op, operation, operation.as_str()); + } + }); + }); + }, + Some(Effect::MoveCards { + player, + source, + destination, + count, + }) => { + ui.heading("Move cards"); + + ui.label("Player"); + ui.horizontal_wrapped(|ui| { + for &player_type in PlayerType::ALL { + ui.radio_value(player, player_type, player_type.as_str()); + } + }); + + ui.label("Source"); + ui.horizontal_wrapped(|ui| { + for &slot in Slot::ALL { + ui.radio_value(source, slot, slot.as_str()); + } + }); + + ui.label("Destination"); + ui.horizontal_wrapped(|ui| { + for &slot in Slot::ALL { + ui.radio_value(destination, slot, slot.as_str()); + } + }); + + ui.horizontal(|ui| { + ui.label("Count"); + ui.add(egui::Slider::new(count, 0..=40)); + }); + }, + Some(Effect::ShuffleOnlineDeck { player }) => { + ui.heading("Shuffle online deck"); + + ui.label("Player"); + ui.horizontal_wrapped(|ui| { + for &player_type in PlayerType::ALL { + ui.radio_value(player, player_type, player_type.as_str()); + } + }); + }, + Some(Effect::VoidOpponentSupportEffect) => { + ui.heading("Void opponent support effect"); + }, + Some(Effect::VoidOpponentSupportOptionEffect) => { + ui.heading("Void opponent support option effect"); + }, + Some(Effect::PickPartnerCard) => { + ui.heading("Pick partner card"); + }, + Some(Effect::CycleOpponentAttackType) => { + ui.heading("Cycle opponent attack type"); + }, + Some(Effect::KoDigimonRevives { health }) => { + ui.heading("Ko'd digimon revives"); + + ui.horizontal(|ui| { + ui.label("Health"); + ui.add(egui::Slider::new(health, 0..=2000)); + }); + }, + Some(Effect::DrawCards { player, count }) => { + ui.heading("Draw cards"); + + ui.label("Player"); + ui.horizontal_wrapped(|ui| { + for &player_type in PlayerType::ALL { + ui.radio_value(player, player_type, player_type.as_str()); + } + }); + + ui.horizontal(|ui| { + ui.label("Count"); + ui.add(egui::Slider::new(count, 0..=40)); + }); + }, + Some(Effect::OwnAttackBecomesEatUpHP) => { + ui.heading("Own attack becomes eat up hp"); + }, + Some(Effect::AttackFirst { player }) => { + ui.heading("Attack first"); + + ui.label("Player"); + ui.horizontal_wrapped(|ui| { + for &player_type in PlayerType::ALL { + ui.radio_value(player, player_type, player_type.as_str()); + } + }); + }, + None => { + ui.label("None"); + // TODO: Be able to add new once all fields are figured out. + }, + } + }); + } + }); + + + // Then try to apply if anything was changed + if any_changed { + let status = match edit_state.apply(digimon) { + Ok(()) => Cow::Borrowed("All ok"), + Err(err) => Cow::Owned(format!("Error: {:?}", err)), + }; + + *cur_card_edit_status = Some(status); + } + + if let Some(cur_card_edit_status) = cur_card_edit_status { + ui.separator(); + ui.label(&**cur_card_edit_status); + } +}