use battler_data::Id;
use crate::battle::{
MonHandle,
MoveHandle,
OutsideEffect,
SpeedOrderable,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MonAction {
pub mon: MonHandle,
pub speed: u32,
}
impl MonAction {
pub fn new(mon: MonHandle) -> Self {
Self { mon, speed: 0 }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TeamActionInput {
pub mon: MonHandle,
pub index: usize,
pub priority: i32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TeamAction {
pub mon_action: MonAction,
pub index: usize,
pub priority: i32,
}
impl TeamAction {
pub fn new(input: TeamActionInput) -> Self {
Self {
mon_action: MonAction::new(input.mon),
index: input.index,
priority: input.priority,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SwitchActionInput {
pub instant: bool,
pub mon: MonHandle,
pub switching_out: MonHandle,
pub position: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SwitchAction {
pub instant: bool,
pub mon_action: MonAction,
pub switching_out: MonHandle,
pub position: usize,
}
impl SwitchAction {
pub fn new(input: SwitchActionInput) -> Self {
Self {
instant: input.instant,
mon_action: MonAction::new(input.mon),
switching_out: input.switching_out,
position: input.position,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MoveActionInput {
pub id: Id,
pub upgraded_id: Option<Id>,
pub mon: MonHandle,
pub target: Option<isize>,
pub mega: bool,
pub z_move: bool,
pub ultra: bool,
pub dyna: bool,
pub tera: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MoveAction {
pub action_id: usize,
pub id: Id,
pub upgraded_id: Option<Id>,
pub mon_action: MonAction,
pub target: Option<isize>,
pub original_target: Option<MonHandle>,
pub mega: bool,
pub z_move: bool,
pub ultra: bool,
pub dyna: bool,
pub tera: bool,
pub order: Option<u32>,
pub priority: i32,
pub sub_priority: i32,
pub active_move_handle: Option<MoveHandle>,
}
impl MoveAction {
pub fn new(input: MoveActionInput) -> Self {
Self {
action_id: usize::MAX,
id: input.id,
upgraded_id: input.upgraded_id,
mon_action: MonAction::new(input.mon),
target: input.target,
original_target: None,
mega: input.mega,
z_move: input.z_move,
ultra: input.ultra,
dyna: input.dyna,
tera: input.tera,
order: None,
priority: 0,
sub_priority: 0,
active_move_handle: None,
}
}
pub fn effective_move_id(&self) -> &Id {
if let Some(id) = &self.upgraded_id {
return id;
}
&self.id
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BeforeMoveActionInput {
pub id: Id,
pub mon: MonHandle,
pub active_move_handle: Option<MoveHandle>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BeforeMoveAction {
pub id: Id,
pub mon_action: MonAction,
pub active_move_handle: Option<MoveHandle>,
pub priority: i32,
pub sub_priority: i32,
}
impl BeforeMoveAction {
pub fn new(input: BeforeMoveActionInput) -> Self {
Self {
id: input.id,
mon_action: MonAction::new(input.mon),
active_move_handle: input.active_move_handle,
priority: 0,
sub_priority: 0,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExperienceAction {
pub mon: MonHandle,
pub player_index: usize,
pub mon_index: usize,
pub active: bool,
pub exp: u32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LevelUpAction {
pub mon: MonHandle,
pub level: Option<u8>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LearnMoveAction {
pub mon: MonHandle,
pub forget_move_slot: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EndAction {
pub winning_side: Option<usize>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EscapeActionInput {
pub mon: MonHandle,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EscapeAction {
pub mon_action: MonAction,
}
impl EscapeAction {
pub fn new(input: EscapeActionInput) -> Self {
Self {
mon_action: MonAction::new(input.mon),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SwitchEventsAction {
pub mon_action: MonAction,
}
impl SwitchEventsAction {
pub fn new(mon_handle: MonHandle) -> Self {
Self {
mon_action: MonAction::new(mon_handle),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ForfeitAction {
pub player: usize,
pub order: u32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ItemActionInput {
pub mon: MonHandle,
pub item: Id,
pub target: Option<isize>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ItemAction {
pub mon_action: MonAction,
pub item: Id,
pub target: Option<isize>,
pub move_slot: Option<Id>,
}
impl ItemAction {
pub fn new(input: ItemActionInput) -> Self {
Self {
mon_action: MonAction::new(input.mon),
item: input.item,
target: input.target,
move_slot: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ShiftAction {
pub mon_action: MonAction,
pub position: usize,
}
impl ShiftAction {
pub fn new(mon_handle: MonHandle, position: usize) -> Self {
Self {
mon_action: MonAction::new(mon_handle),
position,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SelectActionInput {
pub mon: MonHandle,
pub position: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SelectAction {
pub mon_action: MonAction,
pub position: usize,
}
impl SelectAction {
pub fn new(input: SelectActionInput) -> Self {
Self {
mon_action: MonAction::new(input.mon),
position: input.position,
}
}
}
#[derive(Debug, Clone)]
pub struct OutsideEffectAction {
pub outside_effect: OutsideEffect,
pub order: u32,
}
impl PartialEq for OutsideEffectAction {
fn eq(&self, other: &Self) -> bool {
self.order == other.order
}
}
impl Eq for OutsideEffectAction {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Action {
Start,
End(EndAction),
Pass,
BeforeTurn,
Residual,
Team(TeamAction),
Switch(SwitchAction),
BeforeSwitchEvents(SwitchEventsAction),
SwitchEvents(SwitchEventsAction),
Move(MoveAction),
BeforeTurnMove(BeforeMoveAction),
PriorityChargeMove(BeforeMoveAction),
MegaEvo(MonAction),
UltraBurst(MonAction),
Dynamax(MonAction),
Terastallize(MonAction),
Experience(ExperienceAction),
LevelUp(LevelUpAction),
LearnMove(LearnMoveAction),
Escape(EscapeAction),
Forfeit(ForfeitAction),
Item(ItemAction),
Shift(ShiftAction),
Select(SelectAction),
OutsideEffect(OutsideEffectAction),
}
impl Action {
pub fn action_id_mut(&mut self) -> Option<&mut usize> {
match self {
Self::Move(action) => Some(&mut action.action_id),
_ => None,
}
}
pub fn mon_action_mut(&mut self) -> Option<&mut MonAction> {
match self {
Self::Team(action) => Some(&mut action.mon_action),
Self::Switch(action) => Some(&mut action.mon_action),
Self::SwitchEvents(action) => Some(&mut action.mon_action),
Self::Move(action) => Some(&mut action.mon_action),
Self::BeforeTurnMove(action) => Some(&mut action.mon_action),
Self::PriorityChargeMove(action) => Some(&mut action.mon_action),
Self::MegaEvo(action) => Some(action),
Self::UltraBurst(action) => Some(action),
Self::Dynamax(action) => Some(action),
Self::Terastallize(action) => Some(action),
Self::Escape(action) => Some(&mut action.mon_action),
Self::Item(action) => Some(&mut action.mon_action),
Self::Shift(action) => Some(&mut action.mon_action),
_ => None,
}
}
pub fn independent(&self) -> bool {
match self {
Self::Move(_)
| Self::Item(_)
| Self::MegaEvo(_)
| Self::UltraBurst(_)
| Self::Dynamax(_)
| Self::Terastallize(_)
| Self::Residual => true,
_ => false,
}
}
}
impl SpeedOrderable for Action {
fn order(&self) -> u32 {
match self {
Self::Team(_) => 1,
Self::Start => 2,
Self::LearnMove(_) => 3,
Self::LevelUp(_) => 4,
Self::Select(_) => 5,
Self::Experience(_) => 6,
Self::OutsideEffect(_) => 7,
Self::Switch(action) => {
if action.instant {
8
} else {
100
}
}
Self::End(_) => 9,
Self::Forfeit(_) => 10,
Self::BeforeTurn => 11,
Self::Item(_) => 12,
Self::BeforeTurnMove(_) => 13,
Self::BeforeSwitchEvents(_) => 99,
Self::Escape(_) => 101,
Self::SwitchEvents(_) => 103,
Self::MegaEvo(_) => 104,
Self::UltraBurst(_) => 105,
Self::Dynamax(_) => 106,
Self::Terastallize(_) => 107,
Self::PriorityChargeMove(_) => 108,
Self::Move(action) => action.order.unwrap_or(200),
Self::Pass => 200,
Self::Shift(_) => 200,
Self::Residual => 300,
}
}
fn priority(&self) -> i32 {
match self {
Self::Team(action) => action.priority,
Self::Move(action) => action.priority,
Self::BeforeTurnMove(action) => action.priority,
Self::PriorityChargeMove(action) => action.priority,
Self::Experience(action) => action.player_index as i32,
_ => 0,
}
}
fn sub_priority(&self) -> i32 {
match self {
Self::Move(action) => action.sub_priority,
Self::BeforeTurnMove(action) => action.sub_priority,
Self::PriorityChargeMove(action) => action.sub_priority,
_ => 0,
}
}
fn speed(&self) -> u32 {
match self {
Self::Team(action) => action.mon_action.speed,
Self::Switch(action) => action.mon_action.speed,
Self::SwitchEvents(action) => action.mon_action.speed,
Self::Move(action) => action.mon_action.speed,
Self::BeforeTurnMove(action) => action.mon_action.speed,
Self::PriorityChargeMove(action) => action.mon_action.speed,
Self::MegaEvo(action) => action.speed,
Self::UltraBurst(action) => action.speed,
Self::Dynamax(action) => action.speed,
Self::Escape(action) => action.mon_action.speed,
Self::Item(action) => action.mon_action.speed,
Self::Shift(action) => action.mon_action.speed,
_ => 1,
}
}
fn sub_order(&self) -> u32 {
match self {
Self::Experience(action) => {
if action.active {
action.mon_index as u32
} else {
action.mon_index as u32 + 65535
}
}
Self::Forfeit(action) => action.order,
Self::OutsideEffect(action) => action.order,
_ => 0,
}
}
}