Changed the representation of CrossMoveEffect.

This commit is contained in:
Filipe Rodrigues 2021-05-15 11:01:30 +01:00
parent 2656610902
commit e13e41aa52
3 changed files with 213 additions and 38 deletions

View File

@ -386,6 +386,7 @@ fn render_digimon_card(
ui.add(egui::Slider::new(&mut digimon.dp_give, 0..=100));
});
// Moves
ui.group(|ui| {
ui.heading("Moves");
@ -400,18 +401,10 @@ fn render_digimon_card(
}
});
// Cross move effect
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);
}
});
self::render_cross_move_effect(ui, &mut digimon.cross_move_effect);
});
ui.group(|ui| {
@ -745,6 +738,92 @@ fn render_digimon_card(
}
}
/// Displays a cross move effect
fn render_cross_move_effect(ui: &mut egui::Ui, cross_move_effect: &mut Option<CrossMoveEffect>) {
ui.horizontal(|ui| {
// Show the effect generically
egui::ComboBox::from_id_source("cross_move_effect")
.selected_text(cross_move_effect.map_or("None", CrossMoveEffect::as_str))
.show_ui(ui, |ui| {
ui.selectable_value(
cross_move_effect,
Some(CrossMoveEffect::AttackFirst),
CrossMoveEffect::AttackFirst.as_str(),
);
let is_attack_to_zero = cross_move_effect.map_or(false, CrossMoveEffect::is_attack_to_zero);
let attack_to_zero_default = CrossMoveEffect::AttackToZero(AttackType::Circle);
if ui
.selectable_label(is_attack_to_zero, attack_to_zero_default.as_str())
.clicked() && !is_attack_to_zero
{
*cross_move_effect = Some(attack_to_zero_default);
}
let is_counter = cross_move_effect.map_or(false, CrossMoveEffect::is_counter);
let counter_default = CrossMoveEffect::Counter(AttackType::Circle);
if ui.selectable_label(is_counter, counter_default.as_str()).clicked() && !is_counter {
*cross_move_effect = Some(counter_default);
}
ui.selectable_value(
cross_move_effect,
Some(CrossMoveEffect::Crash),
CrossMoveEffect::Crash.as_str(),
);
ui.selectable_value(
cross_move_effect,
Some(CrossMoveEffect::EatUpHP),
CrossMoveEffect::EatUpHP.as_str(),
);
ui.selectable_value(
cross_move_effect,
Some(CrossMoveEffect::Jamming),
CrossMoveEffect::Jamming.as_str(),
);
let is_triple_against = cross_move_effect.map_or(false, CrossMoveEffect::is_triple_against);
let triple_against_default = CrossMoveEffect::TripleAgainst(Speciality::Darkness);
if ui
.selectable_label(is_triple_against, triple_against_default.as_str())
.clicked() && !is_triple_against
{
*cross_move_effect = Some(triple_against_default);
}
});
// Then display extra arguments
match cross_move_effect {
Some(CrossMoveEffect::AttackToZero(attack_type)) | Some(CrossMoveEffect::Counter(attack_type)) => {
self::render_attack_type(ui, attack_type)
},
Some(CrossMoveEffect::TripleAgainst(speciality)) => self::render_speciality(ui, speciality),
_ => (),
};
});
}
/// Displays an attack type
fn render_attack_type(ui: &mut egui::Ui, cur_attack_type: &mut AttackType) {
egui::ComboBox::from_id_source(cur_attack_type as *const _)
.selected_text(cur_attack_type.as_str())
.show_ui(ui, |ui| {
for &attack_type in AttackType::ALL {
ui.selectable_value(cur_attack_type, attack_type, attack_type.as_str());
}
});
}
/// Displays a speciality
fn render_speciality(ui: &mut egui::Ui, cur_speciality: &mut Speciality) {
egui::ComboBox::from_id_source(cur_speciality as *const _)
.selected_text(cur_speciality.as_str())
.show_ui(ui, |ui| {
for &speciality in Speciality::ALL {
ui.selectable_value(cur_speciality, speciality, speciality.as_str());
}
});
}
/// Displays a move
fn render_move(ui: &mut egui::Ui, name: &str, mv: &mut Move, mv_name: &mut String) {
ui.group(|ui| {

View File

@ -144,34 +144,6 @@ dcb_util::generate_enum_property_mod!(
}
}
pub mod cross_move_effect {
/// A digimon's cross move effect
enum CrossMoveEffect
{
FirstAttack("Attack first") => 1,
CircleTo0("Circle to 0" ) => 2,
TriangleTo0("Triangle to 0") => 3,
CrossTo0("Cross to 0" ) => 4,
CircleCounter("Circle counter" ) => 5,
TriangleCounter("Triangle counter") => 6,
CrossCounter("Cross counter" ) => 7,
Crash ("Crash" ) => 8,
EatUpHP("Eat Up HP") => 9,
Jamming("Jamming" ) => 10,
FireFoe3x("Fire Foe x3" ) => 11,
IceFoe3x("Ice Foe x3" ) => 12,
NatureFoe3x("Nature Foe x3" ) => 13,
DarknessFoe3x("Darkness Foe x3") => 14,
RareFoe3x("Rare Foe x3" ) => 15,
_ => "Unknown byte {:#x} for a cross move effect",
}
}
pub mod digimon_property {
/// A digimon's property
enum DigimonProperty
@ -234,6 +206,7 @@ pub struct MaybeCrossMoveEffect(Option<CrossMoveEffect>);
pub struct MaybeDigimonProperty(Option<DigimonProperty>);
// Complex
pub mod cross_move_effect;
pub mod digivolve_effect;
pub mod effect;
pub mod effect_condition;

View File

@ -0,0 +1,123 @@
//! Cross move effect
// Imports
use super::{AttackType, Speciality};
/// A digimon's cross move effect
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum CrossMoveEffect {
/// Attack first
AttackFirst,
/// Attack to 0
AttackToZero(AttackType),
/// counter
Counter(AttackType),
/// Crash
Crash,
/// Eat up HP
EatUpHP,
/// Jamming
Jamming,
/// 3x against speciality
TripleAgainst(Speciality),
}
impl CrossMoveEffect {
/// Returns `true` if the effect is [`AttackToZero`].
#[must_use]
pub const fn is_attack_to_zero(self) -> bool {
matches!(self, Self::AttackToZero(..))
}
/// Returns `true` if the effect is [`Counter`].
#[must_use]
pub const fn is_counter(self) -> bool {
matches!(self, Self::Counter(..))
}
/// Returns `true` if the effect is [`TripleAgainst`].
#[must_use]
pub const fn is_triple_against(self) -> bool {
matches!(self, Self::TripleAgainst(..))
}
/// Returns a string representing this effect
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::AttackFirst => "Attack first",
Self::AttackToZero(_) => "Attack to zero",
Self::Counter(_) => "Counter",
Self::Crash => "Crash",
Self::EatUpHP => "Eat up HP",
Self::Jamming => "Jamming",
Self::TripleAgainst(_) => "Triple against",
}
}
}
/// Error type for [`::dcb_bytes::Bytes::from_bytes`]
#[derive(PartialEq, Eq, Clone, Copy, Debug, thiserror::Error)]
pub enum FromBytesError {
/// Unknown value
#[error("Unknown byte {:#x} for a cross move effect", byte)]
UnknownValue {
/// The byte found
byte: u8,
},
}
impl ::dcb_bytes::Bytes for CrossMoveEffect {
type ByteArray = u8;
type FromError = FromBytesError;
type ToError = !;
fn from_bytes(byte: &Self::ByteArray) -> Result<Self, Self::FromError> {
match byte {
1 => Ok(Self::AttackFirst),
2 => Ok(Self::AttackToZero(AttackType::Circle)),
3 => Ok(Self::AttackToZero(AttackType::Triangle)),
4 => Ok(Self::AttackToZero(AttackType::Cross)),
5 => Ok(Self::Counter(AttackType::Circle)),
6 => Ok(Self::Counter(AttackType::Triangle)),
7 => Ok(Self::Counter(AttackType::Cross)),
8 => Ok(Self::Crash),
9 => Ok(Self::EatUpHP),
10 => Ok(Self::Jamming),
11 => Ok(Self::TripleAgainst(Speciality::Fire)),
12 => Ok(Self::TripleAgainst(Speciality::Ice)),
13 => Ok(Self::TripleAgainst(Speciality::Nature)),
14 => Ok(Self::TripleAgainst(Speciality::Darkness)),
15 => Ok(Self::TripleAgainst(Speciality::Rare)),
&byte => Err(Self::FromError::UnknownValue { byte }),
}
}
#[allow(unreachable_code, unused_variables)]
fn to_bytes(&self, byte: &mut Self::ByteArray) -> Result<(), Self::ToError> {
*byte = match self {
Self::AttackFirst => 1,
Self::AttackToZero(AttackType::Circle) => 2,
Self::AttackToZero(AttackType::Triangle) => 3,
Self::AttackToZero(AttackType::Cross) => 4,
Self::Counter(AttackType::Circle) => 5,
Self::Counter(AttackType::Triangle) => 6,
Self::Counter(AttackType::Cross) => 7,
Self::Crash => 8,
Self::EatUpHP => 9,
Self::Jamming => 10,
Self::TripleAgainst(Speciality::Fire) => 11,
Self::TripleAgainst(Speciality::Ice) => 12,
Self::TripleAgainst(Speciality::Nature) => 13,
Self::TripleAgainst(Speciality::Darkness) => 14,
Self::TripleAgainst(Speciality::Rare) => 15,
};
Ok(())
}
}