PkmnLib_rs/src/dynamic_data/choices/mod.rs

360 lines
11 KiB
Rust
Raw Normal View History

2022-06-03 14:35:18 +00:00
use crate::dynamic_data::models::learned_move::LearnedMove;
use crate::dynamic_data::models::pokemon::Pokemon;
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)]
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;
}
pub(crate) fn get_move_turn_data<'b>(&'b mut self) -> &'b mut MoveChoice<'user, 'library> {
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>>>,
target_side: u8,
target_index: u8,
) -> 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>>,
}
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>>,
}
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>>,
}
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>>,
}
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 {
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
}
}
}