2023-04-15 17:33:29 +00:00
|
|
|
use anyhow::{bail, Result};
|
2022-09-07 16:01:26 +00:00
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
2022-06-16 15:59:33 +00:00
|
|
|
use std::sync::Arc;
|
2022-06-03 14:35:18 +00:00
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
use parking_lot::RwLock;
|
|
|
|
|
|
|
|
use crate::dynamic_data::Pokemon;
|
|
|
|
use crate::dynamic_data::ScriptContainer;
|
2022-07-01 15:07:22 +00:00
|
|
|
use crate::dynamic_data::{LearnedMove, ScriptWrapper};
|
|
|
|
use crate::dynamic_data::{ScriptSource, ScriptSourceData};
|
2022-10-22 10:08:58 +00:00
|
|
|
use crate::{ValueIdentifiable, ValueIdentifier};
|
2022-06-19 19:34:08 +00:00
|
|
|
|
|
|
|
/// The data on a turn choice that should be contained in every turn choice, regardless of type.
|
2022-06-03 14:35:18 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
struct CommonChoiceData {
|
2022-10-22 10:08:58 +00:00
|
|
|
/// A unique identifier so we know what value this is.
|
|
|
|
identifier: ValueIdentifier,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The user of the turn choice
|
2022-08-20 11:17:20 +00:00
|
|
|
user: Arc<Pokemon>,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The speed of the user at the beginning of the turn.
|
2022-06-16 15:59:33 +00:00
|
|
|
speed: u32,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// This random value is set at the beginning of the turn. It is used for tie breaking of the
|
|
|
|
/// turn order in a predictable way, regardless of implementation and hardware.
|
2022-06-16 15:59:33 +00:00
|
|
|
random_value: u32,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Whether or not the choice has failed. A failed choice will stop running, and execute special
|
|
|
|
/// fail handling during turn execution.
|
2022-09-07 16:01:26 +00:00
|
|
|
has_failed: AtomicBool,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The data we can use to retrieve scripts that are affecting this choice. This will be written
|
|
|
|
/// to once: when we need to initialize it. After that, this is only used to read. To prevent a
|
|
|
|
/// read while we're writing to it, this is a RwLock.
|
2022-06-16 15:59:33 +00:00
|
|
|
script_source_data: RwLock<ScriptSourceData>,
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// This enum defines a single choice for a Pokemon for a battle turn.
|
2022-06-16 15:59:33 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
pub enum TurnChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// A move choice tells a Pokemon to use a move on a target for this turn.
|
2022-08-20 11:17:20 +00:00
|
|
|
Move(MoveChoice),
|
2022-06-19 19:34:08 +00:00
|
|
|
/// An item choice tells a Pokemon to use an item.
|
2022-08-20 11:17:20 +00:00
|
|
|
Item(ItemChoice),
|
2022-06-19 19:34:08 +00:00
|
|
|
/// A switch choice tells a Pokemon to switch with another Pokemon from the party.
|
2022-08-20 11:17:20 +00:00
|
|
|
Switch(SwitchChoice),
|
2022-06-19 19:34:08 +00:00
|
|
|
/// A flee choice tells a Pokemon to flee from battle.
|
2022-08-20 11:17:20 +00:00
|
|
|
Flee(FleeChoice),
|
2022-06-19 19:34:08 +00:00
|
|
|
/// A pass choice tells the user to do nothing that turn.
|
2022-08-20 11:17:20 +00:00
|
|
|
Pass(PassChoice),
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl TurnChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The shared choice data between each of the different turn choices.
|
2022-08-20 11:17:20 +00:00
|
|
|
fn choice_data(&self) -> &CommonChoiceData {
|
2022-06-16 15:59:33 +00:00
|
|
|
match self {
|
|
|
|
TurnChoice::Move(data) => &data.choice_data,
|
|
|
|
TurnChoice::Item(data) => &data.choice_data,
|
|
|
|
TurnChoice::Switch(data) => &data.choice_data,
|
|
|
|
TurnChoice::Flee(data) => &data.choice_data,
|
|
|
|
TurnChoice::Pass(data) => &data.choice_data,
|
|
|
|
}
|
|
|
|
}
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The shared choice data between each of the different turn choices.
|
2022-08-20 11:17:20 +00:00
|
|
|
fn choice_data_mut(&mut self) -> &mut Box<CommonChoiceData> {
|
2022-06-16 15:59:33 +00:00
|
|
|
match self {
|
|
|
|
TurnChoice::Move(data) => &mut data.choice_data,
|
|
|
|
TurnChoice::Item(data) => &mut data.choice_data,
|
|
|
|
TurnChoice::Switch(data) => &mut data.choice_data,
|
|
|
|
TurnChoice::Flee(data) => &mut data.choice_data,
|
|
|
|
TurnChoice::Pass(data) => &mut data.choice_data,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Get the user of the given choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn user(&self) -> &Arc<Pokemon> {
|
2022-06-16 15:59:33 +00:00
|
|
|
&self.choice_data().user
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Get the speed of the user for the choice. Note that this speed is the speed of the Pokemon
|
|
|
|
/// at the start of the turn!
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn speed(&self) -> u32 {
|
|
|
|
self.choice_data().speed
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Get the mutable speed of the user for the choice. Note that this speed is the speed of the Pokemon
|
|
|
|
/// at the start of the turn!
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn speed_mut(&mut self) -> &mut u32 {
|
|
|
|
&mut self.choice_data_mut().speed
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Gets whether or not the choice has failed. If we notice this when we execute the choice, we
|
|
|
|
/// will not execute it.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn has_failed(&self) -> bool {
|
2022-09-07 16:01:26 +00:00
|
|
|
self.choice_data().has_failed.load(Ordering::SeqCst)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Fails the choice. This will prevent it from executing and run a specific fail handling during
|
|
|
|
/// execution. Note that this can not be undone.
|
2022-09-07 16:01:26 +00:00
|
|
|
pub fn fail(&self) {
|
|
|
|
self.choice_data().has_failed.store(true, Ordering::SeqCst)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The random value of a turn choice gets set during the start of a choice, and is used for tie
|
|
|
|
/// breaking of turn executions. This means that choices get executed with a predictable order,
|
|
|
|
/// regardless of implementation details.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub(crate) fn random_value(&self) -> u32 {
|
|
|
|
self.choice_data().random_value
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// This sets the above random value.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub(crate) fn set_random_value(&mut self, val: u32) {
|
|
|
|
self.choice_data_mut().random_value = val;
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Helper function to get the move choice data from a turn. Note that this will panic if not
|
|
|
|
/// used on a move choice.
|
2023-04-15 17:33:29 +00:00
|
|
|
pub(crate) fn get_move_turn_data(&self) -> Result<&MoveChoice> {
|
2022-06-16 15:59:33 +00:00
|
|
|
if let TurnChoice::Move(data) = self {
|
2023-04-15 17:33:29 +00:00
|
|
|
return Ok(data);
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
2023-04-15 17:33:29 +00:00
|
|
|
bail!("Invalid turn choice");
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ScriptSource for TurnChoice {
|
2023-04-15 17:33:29 +00:00
|
|
|
fn get_script_count(&self) -> Result<usize> {
|
|
|
|
Ok(match self {
|
|
|
|
TurnChoice::Move(data) => data.get_script_count()?,
|
|
|
|
TurnChoice::Item(data) => data.get_script_count()?,
|
|
|
|
TurnChoice::Switch(data) => data.get_script_count()?,
|
|
|
|
TurnChoice::Flee(data) => data.get_script_count()?,
|
|
|
|
TurnChoice::Pass(data) => data.get_script_count()?,
|
|
|
|
})
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
match self {
|
|
|
|
TurnChoice::Move(data) => data.get_script_source_data(),
|
|
|
|
TurnChoice::Item(data) => data.get_script_source_data(),
|
|
|
|
TurnChoice::Switch(data) => data.get_script_source_data(),
|
|
|
|
TurnChoice::Flee(data) => data.get_script_source_data(),
|
|
|
|
TurnChoice::Pass(data) => data.get_script_source_data(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
match self {
|
|
|
|
TurnChoice::Move(data) => data.get_own_scripts(scripts),
|
|
|
|
TurnChoice::Item(data) => data.get_own_scripts(scripts),
|
|
|
|
TurnChoice::Switch(data) => data.get_own_scripts(scripts),
|
|
|
|
TurnChoice::Flee(data) => data.get_own_scripts(scripts),
|
|
|
|
TurnChoice::Pass(data) => data.get_own_scripts(scripts),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-15 17:33:29 +00:00
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
|
2022-06-16 15:59:33 +00:00
|
|
|
match self {
|
2023-04-15 17:33:29 +00:00
|
|
|
TurnChoice::Move(data) => data.collect_scripts(scripts)?,
|
|
|
|
TurnChoice::Item(data) => data.collect_scripts(scripts)?,
|
|
|
|
TurnChoice::Switch(data) => data.collect_scripts(scripts)?,
|
|
|
|
TurnChoice::Flee(data) => data.collect_scripts(scripts)?,
|
|
|
|
TurnChoice::Pass(data) => data.collect_scripts(scripts)?,
|
|
|
|
};
|
|
|
|
Ok(())
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The data attached to a move choice.
|
2022-06-16 15:59:33 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
pub struct MoveChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The move that is used for this choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
used_move: Arc<LearnedMove>,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The side this move is aimed at.
|
2022-06-16 15:59:33 +00:00
|
|
|
target_side: u8,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The index of the Pokemon on the side we're aiming at.
|
2022-06-16 15:59:33 +00:00
|
|
|
target_index: u8,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The move script.
|
2022-06-16 15:59:33 +00:00
|
|
|
script: ScriptContainer,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The priority of the move choice at the beginning of the turn.
|
2022-06-16 15:59:33 +00:00
|
|
|
priority: i8,
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The common turn choice data.
|
2022-08-20 11:17:20 +00:00
|
|
|
choice_data: Box<CommonChoiceData>,
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-26 16:23:35 +00:00
|
|
|
impl MoveChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Initializes the data for a new move choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn new(user: Arc<Pokemon>, used_move: Arc<LearnedMove>, target_side: u8, target_index: u8) -> Self {
|
2022-11-26 14:33:50 +00:00
|
|
|
let speed = user.boosted_stats().speed();
|
2022-06-16 15:59:33 +00:00
|
|
|
Self {
|
|
|
|
used_move,
|
|
|
|
target_side,
|
|
|
|
target_index,
|
|
|
|
script: Default::default(),
|
|
|
|
priority: 0,
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
2022-10-22 10:08:58 +00:00
|
|
|
identifier: Default::default(),
|
2022-06-16 15:59:33 +00:00
|
|
|
user,
|
2022-11-26 14:33:50 +00:00
|
|
|
speed,
|
2022-06-16 15:59:33 +00:00
|
|
|
random_value: 0,
|
2022-09-07 16:01:26 +00:00
|
|
|
has_failed: Default::default(),
|
2022-06-16 15:59:33 +00:00
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The actual learned move on the Pokemon we use for this choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn used_move(&self) -> &Arc<LearnedMove> {
|
2022-06-16 15:59:33 +00:00
|
|
|
&self.used_move
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The target side the move is aimed at.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn target_side(&self) -> u8 {
|
|
|
|
self.target_side
|
|
|
|
}
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The Pokemon index on the side we're aiming at.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn target_index(&self) -> u8 {
|
|
|
|
self.target_index
|
|
|
|
}
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The priority of the move choice at the beginning of the turn.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn priority(&self) -> i8 {
|
|
|
|
self.priority
|
|
|
|
}
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The priority of the move choice at the beginning of the turn.
|
|
|
|
pub fn priority_mut(&mut self) -> &mut i8 {
|
|
|
|
&mut self.priority
|
|
|
|
}
|
|
|
|
/// The user of the choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn user(&self) -> &Arc<Pokemon> {
|
2022-06-16 15:59:33 +00:00
|
|
|
&self.choice_data.user
|
|
|
|
}
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The move script of the choice.
|
2022-06-16 15:59:33 +00:00
|
|
|
pub fn script(&self) -> &ScriptContainer {
|
|
|
|
&self.script
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ScriptSource for MoveChoice {
|
2023-04-15 17:33:29 +00:00
|
|
|
fn get_script_count(&self) -> Result<usize> {
|
|
|
|
Ok(self.choice_data.user.get_script_count()? + 1)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
scripts.push((&self.script).into());
|
|
|
|
}
|
|
|
|
|
2023-04-15 17:33:29 +00:00
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
|
2022-06-16 15:59:33 +00:00
|
|
|
self.get_own_scripts(scripts);
|
2023-04-15 17:33:29 +00:00
|
|
|
self.choice_data.user.collect_scripts(scripts)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The data given when we select an item choice.
|
2022-06-16 15:59:33 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
pub struct ItemChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The shared data of all turn choices.
|
2022-08-20 11:17:20 +00:00
|
|
|
choice_data: Box<CommonChoiceData>,
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ItemChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Initialised a new item choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
2022-11-26 14:33:50 +00:00
|
|
|
let speed = user.boosted_stats().speed();
|
2022-06-17 17:53:33 +00:00
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
2022-10-22 10:08:58 +00:00
|
|
|
identifier: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
user,
|
2022-11-26 14:33:50 +00:00
|
|
|
speed,
|
2022-06-17 17:53:33 +00:00
|
|
|
random_value: 0,
|
2022-09-07 16:01:26 +00:00
|
|
|
has_failed: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ScriptSource for ItemChoice {
|
2023-04-15 17:33:29 +00:00
|
|
|
fn get_script_count(&self) -> Result<usize> {
|
|
|
|
Ok(0)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
2023-04-15 17:33:29 +00:00
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
|
|
|
|
self.choice_data.user.collect_scripts(scripts)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The data given when we select a switch choice.
|
2022-06-16 15:59:33 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
pub struct SwitchChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The shared data of all turn choices.
|
2022-08-20 11:17:20 +00:00
|
|
|
choice_data: Box<CommonChoiceData>,
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl SwitchChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Initialise the turn choice data.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
2022-11-26 14:33:50 +00:00
|
|
|
let speed = user.boosted_stats().speed();
|
2022-06-17 17:53:33 +00:00
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
2022-10-22 10:08:58 +00:00
|
|
|
identifier: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
user,
|
2022-11-26 14:33:50 +00:00
|
|
|
speed,
|
2022-06-17 17:53:33 +00:00
|
|
|
random_value: 0,
|
2022-09-07 16:01:26 +00:00
|
|
|
has_failed: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ScriptSource for SwitchChoice {
|
2023-04-15 17:33:29 +00:00
|
|
|
fn get_script_count(&self) -> Result<usize> {
|
|
|
|
Ok(0)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
2023-04-15 17:33:29 +00:00
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
|
|
|
|
self.choice_data.user.collect_scripts(scripts)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The data given when we select a flee choice.
|
2022-06-16 15:59:33 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
pub struct FleeChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The common data all turn choices share.
|
2022-08-20 11:17:20 +00:00
|
|
|
choice_data: Box<CommonChoiceData>,
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl FleeChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Initialises a new flee choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
2022-06-17 17:53:33 +00:00
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
2022-10-22 10:08:58 +00:00
|
|
|
identifier: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
user,
|
|
|
|
speed: 0,
|
|
|
|
random_value: 0,
|
2022-09-07 16:01:26 +00:00
|
|
|
has_failed: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ScriptSource for FleeChoice {
|
2023-04-15 17:33:29 +00:00
|
|
|
fn get_script_count(&self) -> Result<usize> {
|
|
|
|
Ok(0)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
2023-04-15 17:33:29 +00:00
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
|
|
|
|
self.choice_data.user.collect_scripts(scripts)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The data given when we select a pass choice.
|
2022-06-16 15:59:33 +00:00
|
|
|
#[derive(Debug)]
|
2022-08-20 11:17:20 +00:00
|
|
|
pub struct PassChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// The common data of all turn choices.
|
2022-08-20 11:17:20 +00:00
|
|
|
choice_data: Box<CommonChoiceData>,
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl PassChoice {
|
2022-06-19 19:34:08 +00:00
|
|
|
/// Initialised a new pass choice.
|
2022-08-20 11:17:20 +00:00
|
|
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
2022-11-26 14:33:50 +00:00
|
|
|
let speed = user.boosted_stats().speed();
|
2022-06-17 17:53:33 +00:00
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
2022-10-22 10:08:58 +00:00
|
|
|
identifier: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
user,
|
2022-11-26 14:33:50 +00:00
|
|
|
speed,
|
2022-06-17 17:53:33 +00:00
|
|
|
random_value: 0,
|
2022-09-07 16:01:26 +00:00
|
|
|
has_failed: Default::default(),
|
2022-06-17 17:53:33 +00:00
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl ScriptSource for PassChoice {
|
2023-04-15 17:33:29 +00:00
|
|
|
fn get_script_count(&self) -> Result<usize> {
|
|
|
|
Ok(0)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
2023-04-15 17:33:29 +00:00
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) -> Result<()> {
|
|
|
|
self.choice_data.user.collect_scripts(scripts)
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl PartialEq<Self> for TurnChoice {
|
2022-06-16 15:59:33 +00:00
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
std::ptr::eq(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl Eq for TurnChoice {}
|
2022-06-16 15:59:33 +00:00
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl PartialOrd for TurnChoice {
|
2022-09-07 16:01:26 +00:00
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
2022-06-16 15:59:33 +00:00
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:17:20 +00:00
|
|
|
impl Ord for TurnChoice {
|
2022-09-07 16:01:26 +00:00
|
|
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
2022-06-03 14:35:18 +00:00
|
|
|
match self {
|
2022-06-16 15:59:33 +00:00
|
|
|
TurnChoice::Move(data) => {
|
|
|
|
if let TurnChoice::Move(other_data) = other {
|
|
|
|
let priority_compare = data.priority.cmp(&other_data.priority);
|
2022-09-07 16:01:26 +00:00
|
|
|
if priority_compare != std::cmp::Ordering::Equal {
|
2022-06-16 15:59:33 +00:00
|
|
|
return priority_compare;
|
|
|
|
}
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
2022-09-07 16:01:26 +00:00
|
|
|
if speed_compare != std::cmp::Ordering::Equal {
|
2022-06-16 15:59:33 +00:00
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
2022-09-07 16:01:26 +00:00
|
|
|
std::cmp::Ordering::Greater
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
TurnChoice::Item { .. } => {
|
|
|
|
if let TurnChoice::Move { .. } = other {
|
2022-09-07 16:01:26 +00:00
|
|
|
return std::cmp::Ordering::Less;
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
if let TurnChoice::Item { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
2022-09-07 16:01:26 +00:00
|
|
|
if speed_compare != std::cmp::Ordering::Equal {
|
2022-06-16 15:59:33 +00:00
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
2022-09-07 16:01:26 +00:00
|
|
|
std::cmp::Ordering::Greater
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
TurnChoice::Switch { .. } => {
|
|
|
|
if let TurnChoice::Move { .. } = other {
|
2022-09-07 16:01:26 +00:00
|
|
|
return std::cmp::Ordering::Less;
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
if let TurnChoice::Item { .. } = other {
|
2022-09-07 16:01:26 +00:00
|
|
|
return std::cmp::Ordering::Less;
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
if let TurnChoice::Switch { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
2022-09-07 16:01:26 +00:00
|
|
|
if speed_compare != std::cmp::Ordering::Equal {
|
2022-06-16 15:59:33 +00:00
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
2022-09-07 16:01:26 +00:00
|
|
|
std::cmp::Ordering::Greater
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
|
|
|
TurnChoice::Flee { .. } => {
|
|
|
|
if let TurnChoice::Flee { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
2022-09-07 16:01:26 +00:00
|
|
|
if speed_compare != std::cmp::Ordering::Equal {
|
2022-06-16 15:59:33 +00:00
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
2022-09-07 16:01:26 +00:00
|
|
|
std::cmp::Ordering::Less
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
2022-11-26 14:33:50 +00:00
|
|
|
TurnChoice::Pass(..) => {
|
|
|
|
if let TurnChoice::Pass { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
|
|
|
if speed_compare != std::cmp::Ordering::Equal {
|
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
|
|
|
std::cmp::Ordering::Less
|
|
|
|
}
|
2022-06-03 14:35:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-10-22 10:08:58 +00:00
|
|
|
|
|
|
|
impl ValueIdentifiable for TurnChoice {
|
|
|
|
fn value_identifier(&self) -> ValueIdentifier {
|
|
|
|
self.choice_data().identifier
|
|
|
|
}
|
|
|
|
}
|