1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
use serde_string_enum::{
DeserializeLabeledStringEnum,
SerializeLabeledStringEnum,
};
/// The outcome of a move used on a single turn of battle.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, SerializeLabeledStringEnum, DeserializeLabeledStringEnum,
)]
pub enum MoveOutcome {
/// The move was skipped. In other words, it neither succeeded or failed.
#[string = "Skipped"]
Skipped,
/// THe move failed completely.
#[string = "Failed"]
Failed,
/// The move succeeded. This can also mean partially succeeded.
#[string = "Success"]
Success,
}
impl MoveOutcome {
pub fn success(&self) -> bool {
match self {
Self::Success => true,
_ => false,
}
}
pub fn failed(&self) -> bool {
match self {
Self::Failed => true,
_ => false,
}
}
}
impl From<bool> for MoveOutcome {
fn from(value: bool) -> Self {
if value { Self::Success } else { Self::Failed }
}
}
impl From<MoveEventResult> for MoveOutcome {
fn from(value: MoveEventResult) -> Self {
match value {
MoveEventResult::Advance => Self::Success,
MoveEventResult::Fail => Self::Failed,
MoveEventResult::Stop => Self::Skipped,
}
}
}
/// The outcome of a move used on a single target in a single turn of battle.
///
/// Differs from [`MoveOutcome`] in that it roughly tracks the effect a move had on a single target,
/// rather than the outcome of the use of the move as a whole.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum MoveOutcomeOnTarget {
/// It is unknown how the move affected the target.
#[default]
Unknown,
/// The move failed to do anything to the target.
Failure,
/// The move hit a Substitute.
HitSubstitute,
/// The move successfully hit the target.
Success,
/// The move successfully dealt damage to the target.
Damage(u16),
}
impl MoveOutcomeOnTarget {
/// Did the move hit anything (including a Substitute)?
pub fn hit(&self) -> bool {
match self {
Self::Failure => false,
_ => true,
}
}
/// Did the move hit the target as intended?
pub fn hit_target(&self) -> bool {
match self {
Self::Failure | Self::HitSubstitute => false,
_ => true,
}
}
/// Did the move fail?
pub fn failed(&self) -> bool {
match self {
Self::Failure => true,
_ => false,
}
}
/// How much damage the move dealt to the target.
pub fn damage(&self) -> u16 {
match self {
Self::Damage(damage) => *damage,
_ => 0,
}
}
/// Combines two move outcomes into one.
///
/// Important when moves do multiple things and we must determine the outcome on the target as a
/// whole.
pub fn combine(&self, other: Self) -> Self {
match (*self, other) {
(Self::Unknown, right @ _) => right,
(Self::Failure, Self::Unknown) => Self::Failure,
(Self::Failure, right @ _) => right,
(Self::HitSubstitute, Self::Unknown) => Self::HitSubstitute,
(Self::HitSubstitute, right @ _) => right,
(Self::Success, Self::Damage(right)) => Self::Damage(right),
(Self::Success, _) => Self::Success,
(Self::Damage(left), Self::Damage(right)) => Self::Damage(left + right),
(left @ Self::Damage(_), _) => left,
}
}
}
impl From<bool> for MoveOutcomeOnTarget {
fn from(value: bool) -> Self {
if value { Self::Success } else { Self::Failure }
}
}
/// The result of a move event, which indicates how the rest of the move should be handled.
#[derive(Clone, Copy, PartialEq, Eq, SerializeLabeledStringEnum, DeserializeLabeledStringEnum)]
pub enum MoveEventResult {
/// Fail the move immediately.
#[string = "fail"]
Fail,
/// Stop the move, but the move did not necessarily fail.
#[string = "stop"]
Stop,
/// Continue the move.
#[string = "continue"]
Advance,
}
impl MoveEventResult {
/// Keep executing the move?
pub fn advance(&self) -> bool {
match self {
Self::Advance => true,
_ => false,
}
}
/// Fail the move immediately?
pub fn failed(&self) -> bool {
match self {
Self::Fail => true,
_ => false,
}
}
/// Combines two results into one.
pub fn combine(&self, other: Self) -> Self {
match (*self, other) {
(Self::Advance, _) => Self::Advance,
(_, Self::Advance) => Self::Advance,
(Self::Fail, _) => Self::Fail,
(Self::Stop, right @ _) => right,
}
}
}
impl From<bool> for MoveEventResult {
fn from(value: bool) -> Self {
if value { Self::Advance } else { Self::Fail }
}
}