Moved digimon rendering to it's own function.

This commit is contained in:
Filipe Rodrigues 2021-05-15 06:31:16 +01:00
parent 8c78a6ffaf
commit 0adf19cfb7
2 changed files with 420 additions and 441 deletions

View File

@ -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 {

View File

@ -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<Cow<'static, str>>,
) {
// 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);
}
}