2022-06-03 14:35:18 +00:00
|
|
|
use crate::dynamic_data::models::learned_move::LearnedMove;
|
|
|
|
use crate::dynamic_data::models::pokemon::Pokemon;
|
2022-06-16 15:59:33 +00:00
|
|
|
use crate::dynamic_data::script_handling::script::ScriptContainer;
|
|
|
|
use crate::dynamic_data::script_handling::{ScriptSource, ScriptSourceData, ScriptWrapper};
|
|
|
|
use parking_lot::RwLock;
|
|
|
|
use std::cmp::Ordering;
|
|
|
|
use std::sync::Arc;
|
2022-06-03 14:35:18 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
2022-06-16 15:59:33 +00:00
|
|
|
struct CommonChoiceData<'user, 'library> {
|
|
|
|
user: Arc<RwLock<Pokemon<'user, 'library>>>,
|
|
|
|
speed: u32,
|
|
|
|
random_value: u32,
|
|
|
|
has_failed: bool,
|
|
|
|
script_source_data: RwLock<ScriptSourceData>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum TurnChoice<'user, 'library> {
|
|
|
|
Move(MoveChoice<'user, 'library>),
|
|
|
|
Item(ItemChoice<'user, 'library>),
|
|
|
|
Switch(SwitchChoice<'user, 'library>),
|
|
|
|
Flee(FleeChoice<'user, 'library>),
|
|
|
|
Pass(PassChoice<'user, 'library>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> TurnChoice<'user, 'library> {
|
|
|
|
fn choice_data(&self) -> &CommonChoiceData<'user, 'library> {
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn choice_data_mut(&mut self) -> &mut Box<CommonChoiceData<'user, 'library>> {
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn user(&self) -> &Arc<RwLock<Pokemon<'user, 'library>>> {
|
|
|
|
&self.choice_data().user
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn speed(&self) -> u32 {
|
|
|
|
self.choice_data().speed
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn speed_mut(&mut self) -> &mut u32 {
|
|
|
|
&mut self.choice_data_mut().speed
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn has_failed(&self) -> bool {
|
|
|
|
self.choice_data().has_failed
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fail(&mut self) {
|
|
|
|
self.choice_data_mut().has_failed = true
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn random_value(&self) -> u32 {
|
|
|
|
self.choice_data().random_value
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_random_value(&mut self, val: u32) {
|
|
|
|
self.choice_data_mut().random_value = val;
|
|
|
|
}
|
|
|
|
|
2022-06-18 07:49:17 +00:00
|
|
|
pub(crate) fn get_move_turn_data<'b>(&'b self) -> &'b MoveChoice<'user, 'library> {
|
2022-06-16 15:59:33 +00:00
|
|
|
if let TurnChoice::Move(data) = self {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
panic!("Invalid turn choice");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> ScriptSource<'user> for TurnChoice<'user, 'library> {
|
|
|
|
fn get_script_count(&self) -> usize {
|
|
|
|
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(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
match self {
|
|
|
|
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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct MoveChoice<'user, 'library> {
|
|
|
|
used_move: Arc<RwLock<LearnedMove<'library>>>,
|
|
|
|
target_side: u8,
|
|
|
|
target_index: u8,
|
|
|
|
script: ScriptContainer,
|
|
|
|
priority: i8,
|
|
|
|
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> MoveChoice<'user, 'library> {
|
|
|
|
pub fn new(
|
|
|
|
user: Arc<RwLock<Pokemon<'user, 'library>>>,
|
|
|
|
used_move: Arc<RwLock<LearnedMove<'library>>>,
|
2022-06-14 17:11:24 +00:00
|
|
|
target_side: u8,
|
|
|
|
target_index: u8,
|
2022-06-16 15:59:33 +00:00
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
used_move,
|
|
|
|
target_side,
|
|
|
|
target_index,
|
|
|
|
script: Default::default(),
|
|
|
|
priority: 0,
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
|
|
|
user,
|
|
|
|
speed: 0,
|
|
|
|
random_value: 0,
|
|
|
|
has_failed: false,
|
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn used_move(&self) -> &Arc<RwLock<LearnedMove<'library>>> {
|
|
|
|
&self.used_move
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn target_side(&self) -> u8 {
|
|
|
|
self.target_side
|
|
|
|
}
|
|
|
|
pub fn target_index(&self) -> u8 {
|
|
|
|
self.target_index
|
|
|
|
}
|
|
|
|
pub fn priority(&self) -> i8 {
|
|
|
|
self.priority
|
|
|
|
}
|
|
|
|
pub fn user(&self) -> &Arc<RwLock<Pokemon<'user, 'library>>> {
|
|
|
|
&self.choice_data.user
|
|
|
|
}
|
|
|
|
pub fn script(&self) -> &ScriptContainer {
|
|
|
|
&self.script
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn priority_mut(&mut self) -> &mut i8 {
|
|
|
|
&mut self.priority
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> ScriptSource<'user> for MoveChoice<'user, 'library> {
|
|
|
|
fn get_script_count(&self) -> usize {
|
|
|
|
1 + self.choice_data.user.read().get_script_count()
|
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
self.get_own_scripts(scripts);
|
|
|
|
self.choice_data.user.read().collect_scripts(scripts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ItemChoice<'user, 'library> {
|
|
|
|
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
|
|
|
}
|
|
|
|
|
2022-06-17 17:53:33 +00:00
|
|
|
impl<'user, 'library> ItemChoice<'user, 'library> {
|
|
|
|
pub fn new(user: Arc<RwLock<Pokemon<'user, 'library>>>) -> Self {
|
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
|
|
|
user,
|
|
|
|
speed: 0,
|
|
|
|
random_value: 0,
|
|
|
|
has_failed: false,
|
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 15:59:33 +00:00
|
|
|
impl<'user, 'library> ScriptSource<'user> for ItemChoice<'user, 'library> {
|
|
|
|
fn get_script_count(&self) -> usize {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
self.choice_data.user.read().collect_scripts(scripts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct SwitchChoice<'user, 'library> {
|
|
|
|
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
|
|
|
}
|
|
|
|
|
2022-06-17 17:53:33 +00:00
|
|
|
impl<'user, 'library> SwitchChoice<'user, 'library> {
|
|
|
|
pub fn new(user: Arc<RwLock<Pokemon<'user, 'library>>>) -> Self {
|
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
|
|
|
user,
|
|
|
|
speed: 0,
|
|
|
|
random_value: 0,
|
|
|
|
has_failed: false,
|
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 15:59:33 +00:00
|
|
|
impl<'user, 'library> ScriptSource<'user> for SwitchChoice<'user, 'library> {
|
|
|
|
fn get_script_count(&self) -> usize {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
self.choice_data.user.read().collect_scripts(scripts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct FleeChoice<'user, 'library> {
|
|
|
|
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
|
|
|
}
|
|
|
|
|
2022-06-17 17:53:33 +00:00
|
|
|
impl<'user, 'library> FleeChoice<'user, 'library> {
|
|
|
|
pub fn new(user: Arc<RwLock<Pokemon<'user, 'library>>>) -> Self {
|
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
|
|
|
user,
|
|
|
|
speed: 0,
|
|
|
|
random_value: 0,
|
|
|
|
has_failed: false,
|
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 15:59:33 +00:00
|
|
|
impl<'user, 'library> ScriptSource<'user> for FleeChoice<'user, 'library> {
|
|
|
|
fn get_script_count(&self) -> usize {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
self.choice_data.user.read().collect_scripts(scripts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct PassChoice<'user, 'library> {
|
|
|
|
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
|
|
|
}
|
|
|
|
|
2022-06-17 17:53:33 +00:00
|
|
|
impl<'user, 'library> PassChoice<'user, 'library> {
|
|
|
|
pub fn new(user: Arc<RwLock<Pokemon<'user, 'library>>>) -> Self {
|
|
|
|
Self {
|
|
|
|
choice_data: Box::new(CommonChoiceData {
|
|
|
|
user,
|
|
|
|
speed: 0,
|
|
|
|
random_value: 0,
|
|
|
|
has_failed: false,
|
|
|
|
script_source_data: Default::default(),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-16 15:59:33 +00:00
|
|
|
impl<'user, 'library> ScriptSource<'user> for PassChoice<'user, 'library> {
|
|
|
|
fn get_script_count(&self) -> usize {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_script_source_data(&self) -> &RwLock<ScriptSourceData> {
|
|
|
|
&self.choice_data.script_source_data
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_own_scripts(&self, _scripts: &mut Vec<ScriptWrapper>) {}
|
|
|
|
|
|
|
|
fn collect_scripts(&self, scripts: &mut Vec<ScriptWrapper>) {
|
|
|
|
self.choice_data.user.read().collect_scripts(scripts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> PartialEq<Self> for TurnChoice<'user, 'library> {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
std::ptr::eq(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> Eq for TurnChoice<'user, 'library> {}
|
|
|
|
|
|
|
|
impl<'user, 'library> PartialOrd for TurnChoice<'user, 'library> {
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'user, 'library> Ord for TurnChoice<'user, 'library> {
|
|
|
|
fn cmp(&self, other: &Self) -> 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);
|
|
|
|
if priority_compare != Ordering::Equal {
|
|
|
|
return priority_compare;
|
|
|
|
}
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
|
|
|
if speed_compare != Ordering::Equal {
|
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
|
|
|
Ordering::Greater
|
|
|
|
}
|
|
|
|
TurnChoice::Item { .. } => {
|
|
|
|
if let TurnChoice::Move { .. } = other {
|
|
|
|
return Ordering::Less;
|
|
|
|
}
|
|
|
|
if let TurnChoice::Item { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
|
|
|
if speed_compare != Ordering::Equal {
|
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
|
|
|
Ordering::Greater
|
|
|
|
}
|
|
|
|
TurnChoice::Switch { .. } => {
|
|
|
|
if let TurnChoice::Move { .. } = other {
|
|
|
|
return Ordering::Less;
|
|
|
|
}
|
|
|
|
if let TurnChoice::Item { .. } = other {
|
|
|
|
return Ordering::Less;
|
|
|
|
}
|
|
|
|
if let TurnChoice::Switch { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
|
|
|
if speed_compare != Ordering::Equal {
|
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
|
|
|
Ordering::Greater
|
|
|
|
}
|
|
|
|
TurnChoice::Flee { .. } => {
|
|
|
|
if let TurnChoice::Flee { .. } = other {
|
|
|
|
let speed_compare = self.speed().cmp(&other.speed());
|
|
|
|
if speed_compare != Ordering::Equal {
|
|
|
|
return speed_compare;
|
|
|
|
}
|
|
|
|
return self.random_value().cmp(&other.random_value());
|
|
|
|
}
|
|
|
|
Ordering::Less
|
|
|
|
}
|
|
|
|
TurnChoice::Pass(..) => Ordering::Less,
|
2022-06-03 14:35:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|