Remove lifetime mess, replace a lot of code with Arc instead of borrows.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This cleans up the codebase massively, and allows me to maintain some semblance of sanity.
This commit is contained in:
parent
2d4253e155
commit
55cc0906c9
|
@ -10,9 +10,9 @@ use crate::dynamic_data::{ScriptSource, ScriptSourceData};
|
||||||
|
|
||||||
/// The data on a turn choice that should be contained in every turn choice, regardless of type.
|
/// The data on a turn choice that should be contained in every turn choice, regardless of type.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CommonChoiceData<'user, 'library> {
|
struct CommonChoiceData {
|
||||||
/// The user of the turn choice
|
/// The user of the turn choice
|
||||||
user: Arc<Pokemon<'user, 'library>>,
|
user: Arc<Pokemon>,
|
||||||
/// The speed of the user at the beginning of the turn.
|
/// The speed of the user at the beginning of the turn.
|
||||||
speed: u32,
|
speed: u32,
|
||||||
/// This random value is set at the beginning of the turn. It is used for tie breaking of the
|
/// This random value is set at the beginning of the turn. It is used for tie breaking of the
|
||||||
|
@ -30,22 +30,22 @@ struct CommonChoiceData<'user, 'library> {
|
||||||
/// This enum defines a single choice for a Pokemon for a battle turn.
|
/// This enum defines a single choice for a Pokemon for a battle turn.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||||
pub enum TurnChoice<'user, 'library> {
|
pub enum TurnChoice {
|
||||||
/// A move choice tells a Pokemon to use a move on a target for this turn.
|
/// A move choice tells a Pokemon to use a move on a target for this turn.
|
||||||
Move(MoveChoice<'user, 'library>),
|
Move(MoveChoice),
|
||||||
/// An item choice tells a Pokemon to use an item.
|
/// An item choice tells a Pokemon to use an item.
|
||||||
Item(ItemChoice<'user, 'library>),
|
Item(ItemChoice),
|
||||||
/// A switch choice tells a Pokemon to switch with another Pokemon from the party.
|
/// A switch choice tells a Pokemon to switch with another Pokemon from the party.
|
||||||
Switch(SwitchChoice<'user, 'library>),
|
Switch(SwitchChoice),
|
||||||
/// A flee choice tells a Pokemon to flee from battle.
|
/// A flee choice tells a Pokemon to flee from battle.
|
||||||
Flee(FleeChoice<'user, 'library>),
|
Flee(FleeChoice),
|
||||||
/// A pass choice tells the user to do nothing that turn.
|
/// A pass choice tells the user to do nothing that turn.
|
||||||
Pass(PassChoice<'user, 'library>),
|
Pass(PassChoice),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> TurnChoice<'user, 'library> {
|
impl TurnChoice {
|
||||||
/// The shared choice data between each of the different turn choices.
|
/// The shared choice data between each of the different turn choices.
|
||||||
fn choice_data(&self) -> &CommonChoiceData<'user, 'library> {
|
fn choice_data(&self) -> &CommonChoiceData {
|
||||||
match self {
|
match self {
|
||||||
TurnChoice::Move(data) => &data.choice_data,
|
TurnChoice::Move(data) => &data.choice_data,
|
||||||
TurnChoice::Item(data) => &data.choice_data,
|
TurnChoice::Item(data) => &data.choice_data,
|
||||||
|
@ -55,7 +55,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// The shared choice data between each of the different turn choices.
|
/// The shared choice data between each of the different turn choices.
|
||||||
fn choice_data_mut(&mut self) -> &mut Box<CommonChoiceData<'user, 'library>> {
|
fn choice_data_mut(&mut self) -> &mut Box<CommonChoiceData> {
|
||||||
match self {
|
match self {
|
||||||
TurnChoice::Move(data) => &mut data.choice_data,
|
TurnChoice::Move(data) => &mut data.choice_data,
|
||||||
TurnChoice::Item(data) => &mut data.choice_data,
|
TurnChoice::Item(data) => &mut data.choice_data,
|
||||||
|
@ -66,7 +66,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the user of the given choice.
|
/// Get the user of the given choice.
|
||||||
pub fn user(&self) -> &Arc<Pokemon<'user, 'library>> {
|
pub fn user(&self) -> &Arc<Pokemon> {
|
||||||
&self.choice_data().user
|
&self.choice_data().user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> {
|
||||||
|
|
||||||
/// Helper function to get the move choice data from a turn. Note that this will panic if not
|
/// Helper function to get the move choice data from a turn. Note that this will panic if not
|
||||||
/// used on a move choice.
|
/// used on a move choice.
|
||||||
pub(crate) fn get_move_turn_data<'b>(&'b self) -> &'b MoveChoice<'user, 'library> {
|
pub(crate) fn get_move_turn_data(&self) -> &MoveChoice {
|
||||||
if let TurnChoice::Move(data) = self {
|
if let TurnChoice::Move(data) = self {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ScriptSource<'user> for TurnChoice<'user, 'library> {
|
impl ScriptSource for TurnChoice {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
TurnChoice::Move(data) => data.get_script_count(),
|
TurnChoice::Move(data) => data.get_script_count(),
|
||||||
|
@ -160,9 +160,9 @@ impl<'user, 'library> ScriptSource<'user> for TurnChoice<'user, 'library> {
|
||||||
|
|
||||||
/// The data attached to a move choice.
|
/// The data attached to a move choice.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MoveChoice<'user, 'library> {
|
pub struct MoveChoice {
|
||||||
/// The move that is used for this choice.
|
/// The move that is used for this choice.
|
||||||
used_move: Arc<LearnedMove<'library>>,
|
used_move: Arc<LearnedMove>,
|
||||||
/// The side this move is aimed at.
|
/// The side this move is aimed at.
|
||||||
target_side: u8,
|
target_side: u8,
|
||||||
/// The index of the Pokemon on the side we're aiming at.
|
/// The index of the Pokemon on the side we're aiming at.
|
||||||
|
@ -172,17 +172,12 @@ pub struct MoveChoice<'user, 'library> {
|
||||||
/// The priority of the move choice at the beginning of the turn.
|
/// The priority of the move choice at the beginning of the turn.
|
||||||
priority: i8,
|
priority: i8,
|
||||||
/// The common turn choice data.
|
/// The common turn choice data.
|
||||||
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
choice_data: Box<CommonChoiceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> MoveChoice<'user, 'library> {
|
impl<'user, 'library> MoveChoice {
|
||||||
/// Initializes the data for a new move choice.
|
/// Initializes the data for a new move choice.
|
||||||
pub fn new(
|
pub fn new(user: Arc<Pokemon>, used_move: Arc<LearnedMove>, target_side: u8, target_index: u8) -> Self {
|
||||||
user: Arc<Pokemon<'user, 'library>>,
|
|
||||||
used_move: Arc<LearnedMove<'library>>,
|
|
||||||
target_side: u8,
|
|
||||||
target_index: u8,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
used_move,
|
used_move,
|
||||||
target_side,
|
target_side,
|
||||||
|
@ -200,7 +195,7 @@ impl<'user, 'library> MoveChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The actual learned move on the Pokemon we use for this choice.
|
/// The actual learned move on the Pokemon we use for this choice.
|
||||||
pub fn used_move(&self) -> &Arc<LearnedMove<'library>> {
|
pub fn used_move(&self) -> &Arc<LearnedMove> {
|
||||||
&self.used_move
|
&self.used_move
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +216,7 @@ impl<'user, 'library> MoveChoice<'user, 'library> {
|
||||||
&mut self.priority
|
&mut self.priority
|
||||||
}
|
}
|
||||||
/// The user of the choice.
|
/// The user of the choice.
|
||||||
pub fn user(&self) -> &Arc<Pokemon<'user, 'library>> {
|
pub fn user(&self) -> &Arc<Pokemon> {
|
||||||
&self.choice_data.user
|
&self.choice_data.user
|
||||||
}
|
}
|
||||||
/// The move script of the choice.
|
/// The move script of the choice.
|
||||||
|
@ -230,7 +225,7 @@ impl<'user, 'library> MoveChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ScriptSource<'user> for MoveChoice<'user, 'library> {
|
impl ScriptSource for MoveChoice {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
1 + self.choice_data.user.get_script_count()
|
1 + self.choice_data.user.get_script_count()
|
||||||
}
|
}
|
||||||
|
@ -251,14 +246,14 @@ impl<'user, 'library> ScriptSource<'user> for MoveChoice<'user, 'library> {
|
||||||
|
|
||||||
/// The data given when we select an item choice.
|
/// The data given when we select an item choice.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ItemChoice<'user, 'library> {
|
pub struct ItemChoice {
|
||||||
/// The shared data of all turn choices.
|
/// The shared data of all turn choices.
|
||||||
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
choice_data: Box<CommonChoiceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ItemChoice<'user, 'library> {
|
impl ItemChoice {
|
||||||
/// Initialised a new item choice.
|
/// Initialised a new item choice.
|
||||||
pub fn new(user: Arc<Pokemon<'user, 'library>>) -> Self {
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
choice_data: Box::new(CommonChoiceData {
|
choice_data: Box::new(CommonChoiceData {
|
||||||
user,
|
user,
|
||||||
|
@ -271,7 +266,7 @@ impl<'user, 'library> ItemChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ScriptSource<'user> for ItemChoice<'user, 'library> {
|
impl ScriptSource for ItemChoice {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -289,14 +284,14 @@ impl<'user, 'library> ScriptSource<'user> for ItemChoice<'user, 'library> {
|
||||||
|
|
||||||
/// The data given when we select a switch choice.
|
/// The data given when we select a switch choice.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SwitchChoice<'user, 'library> {
|
pub struct SwitchChoice {
|
||||||
/// The shared data of all turn choices.
|
/// The shared data of all turn choices.
|
||||||
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
choice_data: Box<CommonChoiceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> SwitchChoice<'user, 'library> {
|
impl SwitchChoice {
|
||||||
/// Initialise the turn choice data.
|
/// Initialise the turn choice data.
|
||||||
pub fn new(user: Arc<Pokemon<'user, 'library>>) -> Self {
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
choice_data: Box::new(CommonChoiceData {
|
choice_data: Box::new(CommonChoiceData {
|
||||||
user,
|
user,
|
||||||
|
@ -309,7 +304,7 @@ impl<'user, 'library> SwitchChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ScriptSource<'user> for SwitchChoice<'user, 'library> {
|
impl ScriptSource for SwitchChoice {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -327,14 +322,14 @@ impl<'user, 'library> ScriptSource<'user> for SwitchChoice<'user, 'library> {
|
||||||
|
|
||||||
/// The data given when we select a flee choice.
|
/// The data given when we select a flee choice.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FleeChoice<'user, 'library> {
|
pub struct FleeChoice {
|
||||||
/// The common data all turn choices share.
|
/// The common data all turn choices share.
|
||||||
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
choice_data: Box<CommonChoiceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> FleeChoice<'user, 'library> {
|
impl FleeChoice {
|
||||||
/// Initialises a new flee choice.
|
/// Initialises a new flee choice.
|
||||||
pub fn new(user: Arc<Pokemon<'user, 'library>>) -> Self {
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
choice_data: Box::new(CommonChoiceData {
|
choice_data: Box::new(CommonChoiceData {
|
||||||
user,
|
user,
|
||||||
|
@ -347,7 +342,7 @@ impl<'user, 'library> FleeChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ScriptSource<'user> for FleeChoice<'user, 'library> {
|
impl ScriptSource for FleeChoice {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -365,14 +360,14 @@ impl<'user, 'library> ScriptSource<'user> for FleeChoice<'user, 'library> {
|
||||||
|
|
||||||
/// The data given when we select a pass choice.
|
/// The data given when we select a pass choice.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PassChoice<'user, 'library> {
|
pub struct PassChoice {
|
||||||
/// The common data of all turn choices.
|
/// The common data of all turn choices.
|
||||||
choice_data: Box<CommonChoiceData<'user, 'library>>,
|
choice_data: Box<CommonChoiceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> PassChoice<'user, 'library> {
|
impl PassChoice {
|
||||||
/// Initialised a new pass choice.
|
/// Initialised a new pass choice.
|
||||||
pub fn new(user: Arc<Pokemon<'user, 'library>>) -> Self {
|
pub fn new(user: Arc<Pokemon>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
choice_data: Box::new(CommonChoiceData {
|
choice_data: Box::new(CommonChoiceData {
|
||||||
user,
|
user,
|
||||||
|
@ -385,7 +380,7 @@ impl<'user, 'library> PassChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> ScriptSource<'user> for PassChoice<'user, 'library> {
|
impl ScriptSource for PassChoice {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -401,21 +396,21 @@ impl<'user, 'library> ScriptSource<'user> for PassChoice<'user, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> PartialEq<Self> for TurnChoice<'user, 'library> {
|
impl PartialEq<Self> for TurnChoice {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
std::ptr::eq(self, other)
|
std::ptr::eq(self, other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> Eq for TurnChoice<'user, 'library> {}
|
impl Eq for TurnChoice {}
|
||||||
|
|
||||||
impl<'user, 'library> PartialOrd for TurnChoice<'user, 'library> {
|
impl PartialOrd for TurnChoice {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
Some(self.cmp(other))
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'user, 'library> Ord for TurnChoice<'user, 'library> {
|
impl Ord for TurnChoice {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
match self {
|
match self {
|
||||||
TurnChoice::Move(data) => {
|
TurnChoice::Move(data) => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::dynamic_data::DamageSource;
|
use crate::dynamic_data::DamageSource;
|
||||||
use crate::dynamic_data::ExecutingMove;
|
use crate::dynamic_data::ExecutingMove;
|
||||||
|
@ -27,7 +28,7 @@ impl<'battle, 'library> EventHook {
|
||||||
|
|
||||||
/// Run a new event. This will send the event to all externally defined event listeners. It will
|
/// Run a new event. This will send the event to all externally defined event listeners. It will
|
||||||
/// dispose of the event afterwards.
|
/// dispose of the event afterwards.
|
||||||
pub fn trigger<'b>(&self, evt: Event<'b, 'battle, 'library>) {
|
pub fn trigger(&self, evt: Event) {
|
||||||
let b = Box::new(&evt);
|
let b = Box::new(&evt);
|
||||||
for f in &self.evt_hook_function {
|
for f in &self.evt_hook_function {
|
||||||
f(&b);
|
f(&b);
|
||||||
|
@ -43,7 +44,7 @@ impl Debug for EventHook {
|
||||||
|
|
||||||
/// The different events that can occur during the battle, for which a GUI should show something.
|
/// The different events that can occur during the battle, for which a GUI should show something.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Event<'own, 'battle, 'library> {
|
pub enum Event<'own> {
|
||||||
/// A switch event happens when a Pokemon gets switched out for something else.
|
/// A switch event happens when a Pokemon gets switched out for something else.
|
||||||
Switch {
|
Switch {
|
||||||
/// The side the Pokemon got switched from/on
|
/// The side the Pokemon got switched from/on
|
||||||
|
@ -51,7 +52,7 @@ pub enum Event<'own, 'battle, 'library> {
|
||||||
/// The index of the Pokemon that got switched in/out on its side
|
/// The index of the Pokemon that got switched in/out on its side
|
||||||
index: u8,
|
index: u8,
|
||||||
/// The new Pokemon that will be on the spot. If none, the spot will now be empty.
|
/// The new Pokemon that will be on the spot. If none, the spot will now be empty.
|
||||||
pokemon: Option<&'own Pokemon<'battle, 'library>>,
|
pokemon: Option<&'own Pokemon>,
|
||||||
},
|
},
|
||||||
/// A swap event happens when two Pokemon on a side swap positions. Note that this is rare.
|
/// A swap event happens when two Pokemon on a side swap positions. Note that this is rare.
|
||||||
Swap {
|
Swap {
|
||||||
|
@ -67,23 +68,23 @@ pub enum Event<'own, 'battle, 'library> {
|
||||||
/// enjoy.
|
/// enjoy.
|
||||||
SpeciesChange {
|
SpeciesChange {
|
||||||
/// The pokemon that changed species.
|
/// The pokemon that changed species.
|
||||||
pokemon: &'own Pokemon<'battle, 'library>,
|
pokemon: &'own Pokemon,
|
||||||
/// The new species of the Pokemon.
|
/// The new species of the Pokemon.
|
||||||
species: &'own Species,
|
species: Arc<Species>,
|
||||||
/// The form of the species the Pokemon will have.
|
/// The form of the species the Pokemon will have.
|
||||||
form: &'own Form,
|
form: Arc<Form>,
|
||||||
},
|
},
|
||||||
/// This event happens when a Pokemon changes form during battle. This is rather common.
|
/// This event happens when a Pokemon changes form during battle. This is rather common.
|
||||||
FormChange {
|
FormChange {
|
||||||
/// The pokemon that changed forms.
|
/// The pokemon that changed forms.
|
||||||
pokemon: &'own Pokemon<'battle, 'library>,
|
pokemon: &'own Pokemon,
|
||||||
/// The new form of the Pokemon.
|
/// The new form of the Pokemon.
|
||||||
form: &'own Form,
|
form: &'own Form,
|
||||||
},
|
},
|
||||||
/// This event happens when a Pokemon takes damage.
|
/// This event happens when a Pokemon takes damage.
|
||||||
Damage {
|
Damage {
|
||||||
/// The Pokemon that takes damage.
|
/// The Pokemon that takes damage.
|
||||||
pokemon: &'own Pokemon<'battle, 'library>,
|
pokemon: &'own Pokemon,
|
||||||
/// The source of damage.
|
/// The source of damage.
|
||||||
source: DamageSource,
|
source: DamageSource,
|
||||||
/// The health of the Pokemon before the damage.
|
/// The health of the Pokemon before the damage.
|
||||||
|
@ -94,7 +95,7 @@ pub enum Event<'own, 'battle, 'library> {
|
||||||
/// This event happens when a Pokemon gets healed
|
/// This event happens when a Pokemon gets healed
|
||||||
Heal {
|
Heal {
|
||||||
/// The Pokemon that gets healed.
|
/// The Pokemon that gets healed.
|
||||||
pokemon: &'own Pokemon<'battle, 'library>,
|
pokemon: &'own Pokemon,
|
||||||
/// The health of the Pokemon before the heal.
|
/// The health of the Pokemon before the heal.
|
||||||
original_health: u32,
|
original_health: u32,
|
||||||
/// The health of the Pokemon after the heal.
|
/// The health of the Pokemon after the heal.
|
||||||
|
@ -103,24 +104,24 @@ pub enum Event<'own, 'battle, 'library> {
|
||||||
/// This event happens when a Pokemon faints.
|
/// This event happens when a Pokemon faints.
|
||||||
Faint {
|
Faint {
|
||||||
/// The pokemon that has fainted.
|
/// The pokemon that has fainted.
|
||||||
pokemon: &'own Pokemon<'battle, 'library>,
|
pokemon: &'own Pokemon,
|
||||||
},
|
},
|
||||||
/// This event happens when a Pokemon uses a move on a target, just before any hits.
|
/// This event happens when a Pokemon uses a move on a target, just before any hits.
|
||||||
MoveUse {
|
MoveUse {
|
||||||
/// The data of the move used.
|
/// The data of the move used.
|
||||||
executing_move: &'own ExecutingMove<'own, 'battle, 'library>,
|
executing_move: &'own ExecutingMove,
|
||||||
},
|
},
|
||||||
/// This event happens when a Pokemon missed.
|
/// This event happens when a Pokemon missed.
|
||||||
Miss {
|
Miss {
|
||||||
/// The pokemon that missed.
|
/// The pokemon that missed.
|
||||||
user: &'own Pokemon<'battle, 'library>,
|
user: &'own Pokemon,
|
||||||
},
|
},
|
||||||
/// The turn is finished running, waiting for new input.
|
/// The turn is finished running, waiting for new input.
|
||||||
EndTurn,
|
EndTurn,
|
||||||
/// A pokemon had its stat boost changed
|
/// A pokemon had its stat boost changed
|
||||||
StatBoostChange {
|
StatBoostChange {
|
||||||
/// The pokemon that had its stat boosts changed.
|
/// The pokemon that had its stat boosts changed.
|
||||||
user: &'own Pokemon<'battle, 'library>,
|
user: &'own Pokemon,
|
||||||
/// The statistic that changed.
|
/// The statistic that changed.
|
||||||
stat: Statistic,
|
stat: Statistic,
|
||||||
/// The value of the stat before the change.
|
/// The value of the stat before the change.
|
||||||
|
|
|
@ -8,31 +8,31 @@ use crate::dynamic_data::Pokemon;
|
||||||
/// helper functions to change the turn order while doing the execution. This is needed, as several
|
/// helper functions to change the turn order while doing the execution. This is needed, as several
|
||||||
/// moves in Pokemon actively mess with this order.
|
/// moves in Pokemon actively mess with this order.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ChoiceQueue<'battle, 'library> {
|
pub struct ChoiceQueue {
|
||||||
/// Our storage of turn choices. Starts out completely filled, then slowly empties as turns get
|
/// Our storage of turn choices. Starts out completely filled, then slowly empties as turns get
|
||||||
/// executed.
|
/// executed.
|
||||||
queue: Vec<Option<TurnChoice<'battle, 'library>>>,
|
queue: Vec<Option<TurnChoice>>,
|
||||||
/// The current index of the turn we need to execute next.
|
/// The current index of the turn we need to execute next.
|
||||||
current: usize,
|
current: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'battle, 'library> ChoiceQueue<'battle, 'library> {
|
impl ChoiceQueue {
|
||||||
/// Initializes a ChoiceQueue. We expect the given queue to already be sorted here.
|
/// Initializes a ChoiceQueue. We expect the given queue to already be sorted here.
|
||||||
pub(crate) fn new(queue: Vec<Option<TurnChoice<'battle, 'library>>>) -> Self {
|
pub(crate) fn new(queue: Vec<Option<TurnChoice>>) -> Self {
|
||||||
Self { queue, current: 0 }
|
Self { queue, current: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dequeues the next turn choice to be executed. This gives ownership to the callee, and replaces
|
/// Dequeues the next turn choice to be executed. This gives ownership to the callee, and replaces
|
||||||
/// our own reference to the turn choice with an empty spot. It also increments the current position
|
/// our own reference to the turn choice with an empty spot. It also increments the current position
|
||||||
/// by one.
|
/// by one.
|
||||||
pub fn dequeue<'b>(&'b mut self) -> TurnChoice<'battle, 'library> {
|
pub fn dequeue<'b>(&'b mut self) -> TurnChoice {
|
||||||
let c = self.queue[self.current].take();
|
let c = self.queue[self.current].take();
|
||||||
self.current += 1;
|
self.current += 1;
|
||||||
c.unwrap()
|
c.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This reads what the next choice to execute will be, without modifying state.
|
/// This reads what the next choice to execute will be, without modifying state.
|
||||||
pub fn peek(&self) -> &'battle TurnChoice {
|
pub fn peek(&self) -> &TurnChoice {
|
||||||
self.queue[self.current].as_ref().unwrap()
|
self.queue[self.current].as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ impl<'battle, 'library> ChoiceQueue<'battle, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal helper function to be easily able to iterate over the yet to be executed choices.
|
/// Internal helper function to be easily able to iterate over the yet to be executed choices.
|
||||||
pub(crate) fn get_queue(&self) -> &[Option<TurnChoice<'battle, 'library>>] {
|
pub(crate) fn get_queue(&self) -> &[Option<TurnChoice>] {
|
||||||
&self.queue[self.current..self.queue.len()]
|
&self.queue[self.current..self.queue.len()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@ use crate::dynamic_data::Pokemon;
|
||||||
use crate::static_data::MoveTarget;
|
use crate::static_data::MoveTarget;
|
||||||
|
|
||||||
/// Helper type for the vector of targets we will return.
|
/// Helper type for the vector of targets we will return.
|
||||||
pub type TargetList<'own, 'library> = Vec<Option<Arc<Pokemon<'own, 'library>>>>;
|
pub type TargetList = Vec<Option<Arc<Pokemon>>>;
|
||||||
|
|
||||||
/// This returns all Pokemon in the battle.
|
/// This returns all Pokemon in the battle.
|
||||||
fn get_all_targets<'b, 'library>(battle: &Battle<'b, 'library>) -> TargetList<'b, 'library> {
|
fn get_all_targets<'b, 'library>(battle: &Battle) -> TargetList {
|
||||||
let mut v = Vec::with_capacity(battle.pokemon_per_side() as usize * battle.number_of_sides() as usize);
|
let mut v = Vec::with_capacity(battle.pokemon_per_side() as usize * battle.number_of_sides() as usize);
|
||||||
for side in battle.sides() {
|
for side in battle.sides() {
|
||||||
for pokemon in side.pokemon().deref() {
|
for pokemon in side.pokemon().deref() {
|
||||||
|
@ -31,11 +31,7 @@ fn get_opposite_side(side: u8) -> u8 {
|
||||||
|
|
||||||
/// Gets all Pokemon that are adjacent to of directly opposite of a Pokemon. This means the target,
|
/// Gets all Pokemon that are adjacent to of directly opposite of a Pokemon. This means the target,
|
||||||
/// the Pokemon left of it, the Pokemon right of it, and the Pokemon opposite of it.
|
/// the Pokemon left of it, the Pokemon right of it, and the Pokemon opposite of it.
|
||||||
fn get_all_adjacent_opponent<'b, 'library>(
|
fn get_all_adjacent_opponent<'b, 'library>(side: u8, index: u8, battle: &Battle) -> TargetList {
|
||||||
side: u8,
|
|
||||||
index: u8,
|
|
||||||
battle: &Battle<'b, 'library>,
|
|
||||||
) -> TargetList<'b, 'library> {
|
|
||||||
let left = index as i32 - 1;
|
let left = index as i32 - 1;
|
||||||
let right = index + 1;
|
let right = index + 1;
|
||||||
if left < 0 && right >= battle.pokemon_per_side() {
|
if left < 0 && right >= battle.pokemon_per_side() {
|
||||||
|
@ -80,7 +76,7 @@ fn get_all_adjacent_opponent<'b, 'library>(
|
||||||
|
|
||||||
/// Gets all Pokemon that are adjacent to a Pokemon. This includes the target, the Pokemon to the
|
/// Gets all Pokemon that are adjacent to a Pokemon. This includes the target, the Pokemon to the
|
||||||
/// left of it, and the Pokemon to the right of it.
|
/// left of it, and the Pokemon to the right of it.
|
||||||
fn get_all_adjacent<'b, 'library>(side: u8, index: u8, battle: &Battle<'b, 'library>) -> TargetList<'b, 'library> {
|
fn get_all_adjacent<'b, 'library>(side: u8, index: u8, battle: &Battle) -> TargetList {
|
||||||
let left = index as i32 - 1;
|
let left = index as i32 - 1;
|
||||||
let right = index + 1;
|
let right = index + 1;
|
||||||
if left < 0 && right >= battle.pokemon_per_side() {
|
if left < 0 && right >= battle.pokemon_per_side() {
|
||||||
|
@ -106,12 +102,7 @@ fn get_all_adjacent<'b, 'library>(side: u8, index: u8, battle: &Battle<'b, 'libr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the target for a specific move target type, given the targeted position.
|
/// Gets the target for a specific move target type, given the targeted position.
|
||||||
pub fn resolve_targets<'b, 'library>(
|
pub fn resolve_targets<'b, 'library>(side: u8, index: u8, target: MoveTarget, battle: &Battle) -> TargetList {
|
||||||
side: u8,
|
|
||||||
index: u8,
|
|
||||||
target: MoveTarget,
|
|
||||||
battle: &Battle<'b, 'library>,
|
|
||||||
) -> TargetList<'b, 'library> {
|
|
||||||
match target {
|
match target {
|
||||||
// These all resolve to a single position. We let the client deal with where the target is,
|
// These all resolve to a single position. We let the client deal with where the target is,
|
||||||
// and just return the Pokemon at that given target here.
|
// and just return the Pokemon at that given target here.
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::dynamic_data::Pokemon;
|
||||||
use crate::static_data::{DataLibrary, MoveCategory};
|
use crate::static_data::{DataLibrary, MoveCategory};
|
||||||
use crate::{run_scripts, script_hook, PkmnResult};
|
use crate::{run_scripts, script_hook, PkmnResult};
|
||||||
|
|
||||||
impl<'own, 'library> Battle<'own, 'library> {
|
impl Battle {
|
||||||
/// Execute the entire turn after the choices are all set.
|
/// Execute the entire turn after the choices are all set.
|
||||||
pub(crate) fn run_turn(&self) -> PkmnResult<()> {
|
pub(crate) fn run_turn(&self) -> PkmnResult<()> {
|
||||||
let choice_queue = self.current_turn_queue();
|
let choice_queue = self.current_turn_queue();
|
||||||
|
@ -62,7 +62,7 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes a single choice.
|
/// Executes a single choice.
|
||||||
fn execute_choice(&self, choice: &TurnChoice<'own, 'library>) -> PkmnResult<()> {
|
fn execute_choice(&self, choice: &TurnChoice) -> PkmnResult<()> {
|
||||||
// A pass turn choice means the user does not intend to do anything. As such, return.
|
// A pass turn choice means the user does not intend to do anything. As such, return.
|
||||||
if let TurnChoice::Pass(..) = choice {
|
if let TurnChoice::Pass(..) = choice {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -91,7 +91,7 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes a move choice.
|
/// Executes a move choice.
|
||||||
fn execute_move_choice<'func>(&'func self, choice: &'func TurnChoice<'own, 'library>) -> PkmnResult<()> {
|
fn execute_move_choice<'func>(&'func self, choice: &'func TurnChoice) -> PkmnResult<()> {
|
||||||
let choice = choice.get_move_turn_data();
|
let choice = choice.get_move_turn_data();
|
||||||
let used_move = choice.used_move();
|
let used_move = choice.used_move();
|
||||||
let move_data = {
|
let move_data = {
|
||||||
|
@ -111,11 +111,11 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let mut executing_move = ExecutingMove::new(
|
let mut executing_move = ExecutingMove::new(
|
||||||
&targets,
|
targets.clone(),
|
||||||
number_of_hits,
|
number_of_hits,
|
||||||
choice.user().clone(),
|
choice.user().clone(),
|
||||||
used_move.clone(),
|
used_move.clone(),
|
||||||
move_data,
|
move_data.clone(),
|
||||||
choice.script().clone(),
|
choice.script().clone(),
|
||||||
);
|
);
|
||||||
let mut prevented = false;
|
let mut prevented = false;
|
||||||
|
@ -148,11 +148,7 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes a move turn choice on a single target.
|
/// Executes a move turn choice on a single target.
|
||||||
fn handle_move_for_target(
|
fn handle_move_for_target(&self, executing_move: &mut ExecutingMove, target: &Arc<Pokemon>) -> PkmnResult<()> {
|
||||||
&self,
|
|
||||||
executing_move: &mut ExecutingMove<'_, 'own, 'library>,
|
|
||||||
target: &Arc<Pokemon<'own, 'library>>,
|
|
||||||
) -> PkmnResult<()> {
|
|
||||||
{
|
{
|
||||||
let mut fail = false;
|
let mut fail = false;
|
||||||
script_hook!(fail_incoming_move, target, executing_move, target, &mut fail);
|
script_hook!(fail_incoming_move, target, executing_move, target, &mut fail);
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub struct DynamicLibrary {
|
||||||
damage_calculator: Box<dyn DamageLibrary>,
|
damage_calculator: Box<dyn DamageLibrary>,
|
||||||
/// The Misc Library holds minor functions that do not fall in any of the other libraries and
|
/// The Misc Library holds minor functions that do not fall in any of the other libraries and
|
||||||
/// calculators.
|
/// calculators.
|
||||||
misc_library: Box<dyn MiscLibrary<'static>>,
|
misc_library: Box<dyn MiscLibrary>,
|
||||||
|
|
||||||
/// The script resolver deals with how to resolve the scripts from specific unique key combinations.
|
/// The script resolver deals with how to resolve the scripts from specific unique key combinations.
|
||||||
script_resolver: Box<dyn ScriptResolver>,
|
script_resolver: Box<dyn ScriptResolver>,
|
||||||
|
@ -40,7 +40,7 @@ impl DynamicLibrary {
|
||||||
static_data: StaticData,
|
static_data: StaticData,
|
||||||
stat_calculator: Box<dyn BattleStatCalculator>,
|
stat_calculator: Box<dyn BattleStatCalculator>,
|
||||||
damage_calculator: Box<dyn DamageLibrary>,
|
damage_calculator: Box<dyn DamageLibrary>,
|
||||||
misc_library: Box<dyn MiscLibrary<'static>>,
|
misc_library: Box<dyn MiscLibrary>,
|
||||||
script_resolver: Box<dyn ScriptResolver>,
|
script_resolver: Box<dyn ScriptResolver>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -67,7 +67,7 @@ impl DynamicLibrary {
|
||||||
}
|
}
|
||||||
/// The Misc Library holds minor functions that do not fall in any of the other libraries and
|
/// The Misc Library holds minor functions that do not fall in any of the other libraries and
|
||||||
/// calculators.
|
/// calculators.
|
||||||
pub fn misc_library(&self) -> &dyn MiscLibrary<'static> {
|
pub fn misc_library(&self) -> &dyn MiscLibrary {
|
||||||
self.misc_library.deref()
|
self.misc_library.deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ impl DynamicLibrary {
|
||||||
/// Loads an item script with the given unique key. If no script can be created with this
|
/// Loads an item script with the given unique key. If no script can be created with this
|
||||||
/// combinations, returns None. Note that ItemScripts are immutable, as their script should be
|
/// combinations, returns None. Note that ItemScripts are immutable, as their script should be
|
||||||
/// shared between all different usages.
|
/// shared between all different usages.
|
||||||
pub fn load_item_script(&self, _key: &Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
pub fn load_item_script(&self, _key: &Arc<Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,35 +10,26 @@ use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
|
||||||
/// The misc library holds several misc functions required for the battle to run.
|
/// The misc library holds several misc functions required for the battle to run.
|
||||||
pub trait MiscLibrary<'library>: Debug {
|
pub trait MiscLibrary: Debug {
|
||||||
/// Returns whether or not a Pokemon is allowed to flee or switch out.
|
/// Returns whether or not a Pokemon is allowed to flee or switch out.
|
||||||
fn can_flee(&self, choice: &TurnChoice) -> bool;
|
fn can_flee(&self, choice: &TurnChoice) -> bool;
|
||||||
/// Returns the move we need to use if we can't use another move. Typically Struggle.
|
/// Returns the move we need to use if we can't use another move. Typically Struggle.
|
||||||
fn replacement_move<'func>(
|
fn replacement_move<'func>(&'func self, user: &Arc<Pokemon>, target_side: u8, target_index: u8) -> TurnChoice;
|
||||||
&'func self,
|
|
||||||
user: &Arc<Pokemon<'func, 'library>>,
|
|
||||||
target_side: u8,
|
|
||||||
target_index: u8,
|
|
||||||
) -> TurnChoice<'func, 'library>;
|
|
||||||
// TODO: can evolve from level up?
|
// TODO: can evolve from level up?
|
||||||
// TODO: get time
|
// TODO: get time
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A gen 7 implementation for the MiscLibrary.
|
/// A gen 7 implementation for the MiscLibrary.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Gen7MiscLibrary<'library> {
|
pub struct Gen7MiscLibrary {
|
||||||
/// The move data for struggle. This is a pointer due to lifetime issues; we know that the
|
|
||||||
/// learned move based on this has the same lifetime as the move data, but the compiler does not.
|
|
||||||
/// If possible in a sane manner, we should get rid of this pointer.
|
|
||||||
struggle_data: *const MoveData,
|
|
||||||
/// The learned move data for struggle.
|
/// The learned move data for struggle.
|
||||||
struggle_learned_move: Arc<LearnedMove<'library>>,
|
struggle_learned_move: Arc<LearnedMove>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'library> Gen7MiscLibrary<'library> {
|
impl Gen7MiscLibrary {
|
||||||
/// Instantiates a new MiscLibrary.
|
/// Instantiates a new MiscLibrary.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let struggle_data = Box::new(MoveData::new(
|
let struggle_data = Arc::new(MoveData::new(
|
||||||
&StringKey::new("struggle"),
|
&StringKey::new("struggle"),
|
||||||
0.into(),
|
0.into(),
|
||||||
MoveCategory::Physical,
|
MoveCategory::Physical,
|
||||||
|
@ -50,40 +41,23 @@ impl<'library> Gen7MiscLibrary<'library> {
|
||||||
Some(SecondaryEffect::new(-1.0, StringKey::new("struggle"), vec![])),
|
Some(SecondaryEffect::new(-1.0, StringKey::new("struggle"), vec![])),
|
||||||
HashSet::new(),
|
HashSet::new(),
|
||||||
));
|
));
|
||||||
let struggle_ptr = Box::into_raw(struggle_data);
|
let struggle_learned_move = Arc::new(LearnedMove::new(&struggle_data.clone(), MoveLearnMethod::Unknown));
|
||||||
let struggle_learned_move = Arc::new(LearnedMove::new(unsafe { &*struggle_ptr }, MoveLearnMethod::Unknown));
|
Self { struggle_learned_move }
|
||||||
Self {
|
|
||||||
struggle_data: struggle_ptr,
|
|
||||||
struggle_learned_move,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'library> Default for Gen7MiscLibrary<'library> {
|
impl Default for Gen7MiscLibrary {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'library> Drop for Gen7MiscLibrary<'library> {
|
impl MiscLibrary for Gen7MiscLibrary {
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
let _ = Box::from_raw(self.struggle_data as *mut MoveData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'library> MiscLibrary<'library> for Gen7MiscLibrary<'library> {
|
|
||||||
fn can_flee(&self, _choice: &TurnChoice) -> bool {
|
fn can_flee(&self, _choice: &TurnChoice) -> bool {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replacement_move<'func>(
|
fn replacement_move<'func>(&'func self, user: &Arc<Pokemon>, target_side: u8, target_index: u8) -> TurnChoice {
|
||||||
&'func self,
|
|
||||||
user: &Arc<Pokemon<'func, 'library>>,
|
|
||||||
target_side: u8,
|
|
||||||
target_index: u8,
|
|
||||||
) -> TurnChoice<'func, 'library> {
|
|
||||||
self.struggle_learned_move.restore_all_uses();
|
self.struggle_learned_move.restore_all_uses();
|
||||||
TurnChoice::Move(MoveChoice::new(
|
TurnChoice::Move(MoveChoice::new(
|
||||||
user.clone(),
|
user.clone(),
|
||||||
|
|
|
@ -22,11 +22,11 @@ use crate::{script_hook, PkmnResult, StringKey};
|
||||||
|
|
||||||
/// A pokemon battle, with any amount of sides and pokemon per side.
|
/// A pokemon battle, with any amount of sides and pokemon per side.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Battle<'own, 'library> {
|
pub struct Battle {
|
||||||
/// The library the battle uses for handling.
|
/// The library the battle uses for handling.
|
||||||
library: &'own DynamicLibrary,
|
library: Arc<DynamicLibrary>,
|
||||||
/// A list of all different parties in the battle.
|
/// A list of all different parties in the battle.
|
||||||
parties: Vec<BattleParty<'own, 'library>>,
|
parties: Vec<BattleParty>,
|
||||||
/// Whether or not Pokemon can flee from the battle.
|
/// Whether or not Pokemon can flee from the battle.
|
||||||
can_flee: bool,
|
can_flee: bool,
|
||||||
/// The number of sides in the battle. Typically 2.
|
/// The number of sides in the battle. Typically 2.
|
||||||
|
@ -34,11 +34,11 @@ pub struct Battle<'own, 'library> {
|
||||||
/// The number of Pokemon that can be on each side.
|
/// The number of Pokemon that can be on each side.
|
||||||
pokemon_per_side: u8,
|
pokemon_per_side: u8,
|
||||||
/// A list of all sides in the battle.
|
/// A list of all sides in the battle.
|
||||||
sides: Vec<BattleSide<'own, 'library>>,
|
sides: Vec<BattleSide>,
|
||||||
/// The RNG used for the battle.
|
/// The RNG used for the battle.
|
||||||
random: BattleRandom,
|
random: BattleRandom,
|
||||||
/// A queue of the yet to be executed choices in a turn.
|
/// A queue of the yet to be executed choices in a turn.
|
||||||
current_turn_queue: RwLock<Option<ChoiceQueue<'own, 'library>>>,
|
current_turn_queue: RwLock<Option<ChoiceQueue>>,
|
||||||
/// Whether or not the battle has ended.
|
/// Whether or not the battle has ended.
|
||||||
has_ended: AtomicBool,
|
has_ended: AtomicBool,
|
||||||
/// The eventual result of the battle. Inconclusive until the battle is ended.
|
/// The eventual result of the battle. Inconclusive until the battle is ended.
|
||||||
|
@ -55,11 +55,11 @@ pub struct Battle<'own, 'library> {
|
||||||
script_source_data: RwLock<ScriptSourceData>,
|
script_source_data: RwLock<ScriptSourceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> Battle<'own, 'library> {
|
impl<'own, 'library> Battle {
|
||||||
/// Initializes a new battle.
|
/// Initializes a new battle.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
library: &'own DynamicLibrary,
|
library: Arc<DynamicLibrary>,
|
||||||
parties: Vec<BattleParty<'own, 'library>>,
|
parties: Vec<BattleParty>,
|
||||||
can_flee: bool,
|
can_flee: bool,
|
||||||
number_of_sides: u8,
|
number_of_sides: u8,
|
||||||
pokemon_per_side: u8,
|
pokemon_per_side: u8,
|
||||||
|
@ -104,11 +104,11 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The library the battle uses for handling.
|
/// The library the battle uses for handling.
|
||||||
pub fn library(&self) -> &'own DynamicLibrary {
|
pub fn library(&self) -> &Arc<DynamicLibrary> {
|
||||||
self.library
|
&self.library
|
||||||
}
|
}
|
||||||
/// A list of all different parties in the battle.
|
/// A list of all different parties in the battle.
|
||||||
pub fn parties(&self) -> &Vec<BattleParty<'own, 'library>> {
|
pub fn parties(&self) -> &Vec<BattleParty> {
|
||||||
&self.parties
|
&self.parties
|
||||||
}
|
}
|
||||||
/// Whether or not Pokemon can flee from the battle.
|
/// Whether or not Pokemon can flee from the battle.
|
||||||
|
@ -124,11 +124,11 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
self.pokemon_per_side
|
self.pokemon_per_side
|
||||||
}
|
}
|
||||||
/// A list of all sides in the battle.
|
/// A list of all sides in the battle.
|
||||||
pub fn sides(&self) -> &Vec<BattleSide<'own, 'library>> {
|
pub fn sides(&self) -> &Vec<BattleSide> {
|
||||||
&self.sides
|
&self.sides
|
||||||
}
|
}
|
||||||
/// A mutable list of all sides in the battle.
|
/// A mutable list of all sides in the battle.
|
||||||
pub fn sides_mut(&mut self) -> &mut Vec<BattleSide<'own, 'library>> {
|
pub fn sides_mut(&mut self) -> &mut Vec<BattleSide> {
|
||||||
&mut self.sides
|
&mut self.sides
|
||||||
}
|
}
|
||||||
/// The RNG used for the battle.
|
/// The RNG used for the battle.
|
||||||
|
@ -156,12 +156,12 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
self.last_turn_time.load(Ordering::Relaxed)
|
self.last_turn_time.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
/// A queue of the yet to be executed choices in a turn.
|
/// A queue of the yet to be executed choices in a turn.
|
||||||
pub fn current_turn_queue(&self) -> &RwLock<Option<ChoiceQueue<'own, 'library>>> {
|
pub fn current_turn_queue(&self) -> &RwLock<Option<ChoiceQueue>> {
|
||||||
&self.current_turn_queue
|
&self.current_turn_queue
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a Pokemon on the battlefield, on a specific side and an index on that side.
|
/// Get a Pokemon on the battlefield, on a specific side and an index on that side.
|
||||||
pub fn get_pokemon(&self, side: u8, index: u8) -> Option<Arc<Pokemon<'own, 'library>>> {
|
pub fn get_pokemon(&self, side: u8, index: u8) -> Option<Arc<Pokemon>> {
|
||||||
let side = self.sides.get(side as usize);
|
let side = self.sides.get(side as usize);
|
||||||
side?;
|
side?;
|
||||||
let pokemon_read_lock = side.unwrap().pokemon();
|
let pokemon_read_lock = side.unwrap().pokemon();
|
||||||
|
@ -254,7 +254,7 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try and set the choice for the battle. If the choice is not valid, this returns false.
|
/// Try and set the choice for the battle. If the choice is not valid, this returns false.
|
||||||
pub fn try_set_choice(&mut self, choice: TurnChoice<'own, 'library>) -> PkmnResult<bool> {
|
pub fn try_set_choice(&mut self, choice: TurnChoice) -> PkmnResult<bool> {
|
||||||
if !self.can_use(&choice) {
|
if !self.can_use(&choice) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ impl<'own, 'library> Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> VolatileScriptsOwner<'own> for Battle<'own, 'library> {
|
impl VolatileScriptsOwner for Battle {
|
||||||
fn volatile_scripts(&self) -> &Arc<ScriptSet> {
|
fn volatile_scripts(&self) -> &Arc<ScriptSet> {
|
||||||
&self.volatile_scripts
|
&self.volatile_scripts
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ impl<'own, 'library> VolatileScriptsOwner<'own> for Battle<'own, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> ScriptSource<'own> for Battle<'own, 'library> {
|
impl ScriptSource for Battle {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,17 @@ use crate::dynamic_data::models::pokemon_party::PokemonParty;
|
||||||
/// A battle party is a wrapper around a party, with the indices for which the party is responsible
|
/// A battle party is a wrapper around a party, with the indices for which the party is responsible
|
||||||
/// on the field attached.
|
/// on the field attached.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BattleParty<'own, 'library> {
|
pub struct BattleParty {
|
||||||
/// The party the BattleParty is holding.
|
/// The party the BattleParty is holding.
|
||||||
party: Arc<PokemonParty<'own, 'library>>,
|
party: Arc<PokemonParty>,
|
||||||
/// The indices for which the party is responsible, in the format (side, index)
|
/// The indices for which the party is responsible, in the format (side, index)
|
||||||
responsible_indices: Vec<(u8, u8)>,
|
responsible_indices: Vec<(u8, u8)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> BattleParty<'own, 'library> {
|
impl BattleParty {
|
||||||
/// Initializes a battle party with the underlying party, and the indices the party is responsible
|
/// Initializes a battle party with the underlying party, and the indices the party is responsible
|
||||||
/// for.
|
/// for.
|
||||||
pub fn new(party: Arc<PokemonParty<'own, 'library>>, responsible_indices: Vec<(u8, u8)>) -> Self {
|
pub fn new(party: Arc<PokemonParty>, responsible_indices: Vec<(u8, u8)>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
party,
|
party,
|
||||||
responsible_indices,
|
responsible_indices,
|
||||||
|
@ -44,7 +44,7 @@ impl<'own, 'library> BattleParty<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a Pokemon at an index.
|
/// Gets a Pokemon at an index.
|
||||||
pub fn get_pokemon(&self, index: usize) -> &Option<Arc<Pokemon<'own, 'library>>> {
|
pub fn get_pokemon(&self, index: usize) -> &Option<Arc<Pokemon>> {
|
||||||
self.party.at(index)
|
self.party.at(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,22 +18,22 @@ use crate::{script_hook, PkmnResult, StringKey};
|
||||||
|
|
||||||
/// A side on a battle.
|
/// A side on a battle.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BattleSide<'own, 'library> {
|
pub struct BattleSide {
|
||||||
/// The index of the side on the battle.
|
/// The index of the side on the battle.
|
||||||
index: u8,
|
index: u8,
|
||||||
/// The number of Pokemon that can be on the side.
|
/// The number of Pokemon that can be on the side.
|
||||||
pokemon_per_side: u8,
|
pokemon_per_side: u8,
|
||||||
/// A list of pokemon currently on the battlefield.
|
/// A list of pokemon currently on the battlefield.
|
||||||
pokemon: RwLock<Vec<Option<Arc<Pokemon<'own, 'library>>>>>,
|
pokemon: RwLock<Vec<Option<Arc<Pokemon>>>>,
|
||||||
/// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts.
|
/// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts.
|
||||||
choices: RwLock<Vec<Option<TurnChoice<'own, 'library>>>>,
|
choices: RwLock<Vec<Option<TurnChoice>>>,
|
||||||
/// The slots on the side that can still be filled. Once all slots are set to false, this side
|
/// The slots on the side that can still be filled. Once all slots are set to false, this side
|
||||||
/// has lost the battle.
|
/// has lost the battle.
|
||||||
fillable_slots: Vec<AtomicBool>,
|
fillable_slots: Vec<AtomicBool>,
|
||||||
/// The number of choices that are set.
|
/// The number of choices that are set.
|
||||||
choices_set: AtomicU8,
|
choices_set: AtomicU8,
|
||||||
/// A reference to the battle we're part of.
|
/// A reference to the battle we're part of.
|
||||||
battle: *mut Battle<'own, 'library>,
|
battle: *mut Battle,
|
||||||
/// Whether or not this side has fled.
|
/// Whether or not this side has fled.
|
||||||
has_fled_battle: bool,
|
has_fled_battle: bool,
|
||||||
/// The volatile scripts that are attached to the side.
|
/// The volatile scripts that are attached to the side.
|
||||||
|
@ -43,7 +43,7 @@ pub struct BattleSide<'own, 'library> {
|
||||||
script_source_data: RwLock<ScriptSourceData>,
|
script_source_data: RwLock<ScriptSourceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> BattleSide<'own, 'library> {
|
impl<'own, 'library> BattleSide {
|
||||||
/// Instantiates a battle side.
|
/// Instantiates a battle side.
|
||||||
pub fn new(index: u8, pokemon_per_side: u8) -> Self {
|
pub fn new(index: u8, pokemon_per_side: u8) -> Self {
|
||||||
let mut pokemon = Vec::with_capacity(pokemon_per_side as usize);
|
let mut pokemon = Vec::with_capacity(pokemon_per_side as usize);
|
||||||
|
@ -73,7 +73,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the battle this side belongs to.
|
/// Set the battle this side belongs to.
|
||||||
pub(crate) fn set_battle(&mut self, battle: *mut Battle<'own, 'library>) {
|
pub(crate) fn set_battle(&mut self, battle: *mut Battle) {
|
||||||
self.battle = battle;
|
self.battle = battle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,11 +86,11 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
self.pokemon_per_side
|
self.pokemon_per_side
|
||||||
}
|
}
|
||||||
/// A list of pokemon currently on the battlefield.
|
/// A list of pokemon currently on the battlefield.
|
||||||
pub fn pokemon(&self) -> RwLockReadGuard<'_, RawRwLock, Vec<Option<Arc<Pokemon<'own, 'library>>>>> {
|
pub fn pokemon(&self) -> RwLockReadGuard<'_, RawRwLock, Vec<Option<Arc<Pokemon>>>> {
|
||||||
self.pokemon.read()
|
self.pokemon.read()
|
||||||
}
|
}
|
||||||
/// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts.
|
/// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts.
|
||||||
pub fn choices(&self) -> &RwLock<Vec<Option<TurnChoice<'own, 'library>>>> {
|
pub fn choices(&self) -> &RwLock<Vec<Option<TurnChoice>>> {
|
||||||
&self.choices
|
&self.choices
|
||||||
}
|
}
|
||||||
/// The slots on the side that can still be filled. Once all slots are set to false, this side
|
/// The slots on the side that can still be filled. Once all slots are set to false, this side
|
||||||
|
@ -103,7 +103,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
self.choices_set.load(Ordering::SeqCst)
|
self.choices_set.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
/// A reference to the battle we're part of.
|
/// A reference to the battle we're part of.
|
||||||
pub fn battle(&self) -> &Battle<'own, 'library> {
|
pub fn battle(&self) -> &Battle {
|
||||||
unsafe { self.battle.as_ref().unwrap() }
|
unsafe { self.battle.as_ref().unwrap() }
|
||||||
}
|
}
|
||||||
/// Whether or not this side has fled.
|
/// Whether or not this side has fled.
|
||||||
|
@ -135,7 +135,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a choice for a Pokemon on this side.
|
/// Sets a choice for a Pokemon on this side.
|
||||||
pub(crate) fn set_choice(&self, choice: TurnChoice<'own, 'library>) {
|
pub(crate) fn set_choice(&self, choice: TurnChoice) {
|
||||||
for (index, pokemon_slot) in self.pokemon.read().iter().enumerate() {
|
for (index, pokemon_slot) in self.pokemon.read().iter().enumerate() {
|
||||||
if let Some(pokemon) = pokemon_slot {
|
if let Some(pokemon) = pokemon_slot {
|
||||||
if std::ptr::eq(pokemon.deref(), choice.user().deref()) {
|
if std::ptr::eq(pokemon.deref(), choice.user().deref()) {
|
||||||
|
@ -161,7 +161,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Switches out a spot on the field for a different Pokemon.
|
/// Switches out a spot on the field for a different Pokemon.
|
||||||
pub fn set_pokemon(&self, index: u8, pokemon: Option<Arc<Pokemon<'own, 'library>>>) {
|
pub fn set_pokemon(&self, index: u8, pokemon: Option<Arc<Pokemon>>) {
|
||||||
{
|
{
|
||||||
let old = &self.pokemon.read()[index as usize];
|
let old = &self.pokemon.read()[index as usize];
|
||||||
if let Some(old_pokemon) = old {
|
if let Some(old_pokemon) = old {
|
||||||
|
@ -202,7 +202,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether a Pokemon is on the field in this side.
|
/// Checks whether a Pokemon is on the field in this side.
|
||||||
pub fn is_pokemon_on_side(&self, pokemon: Arc<Pokemon<'own, 'library>>) -> bool {
|
pub fn is_pokemon_on_side(&self, pokemon: Arc<Pokemon>) -> bool {
|
||||||
for p in self.pokemon.read().iter().flatten() {
|
for p in self.pokemon.read().iter().flatten() {
|
||||||
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
|
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -218,7 +218,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether a slot is unfillable or not.
|
/// Checks whether a slot is unfillable or not.
|
||||||
pub fn is_slot_unfillable(&self, pokemon: Arc<Pokemon<'own, 'library>>) -> bool {
|
pub fn is_slot_unfillable(&self, pokemon: Arc<Pokemon>) -> bool {
|
||||||
for (i, slot) in self.pokemon.read().iter().enumerate() {
|
for (i, slot) in self.pokemon.read().iter().enumerate() {
|
||||||
if let Some(p) = slot {
|
if let Some(p) = slot {
|
||||||
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
|
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
|
||||||
|
@ -296,7 +296,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> VolatileScriptsOwner<'own> for BattleSide<'own, 'library> {
|
impl VolatileScriptsOwner for BattleSide {
|
||||||
fn volatile_scripts(&self) -> &Arc<ScriptSet> {
|
fn volatile_scripts(&self) -> &Arc<ScriptSet> {
|
||||||
&self.volatile_scripts
|
&self.volatile_scripts
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ impl<'own, 'library> VolatileScriptsOwner<'own> for BattleSide<'own, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> ScriptSource<'own> for BattleSide<'own, 'library> {
|
impl ScriptSource for BattleSide {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
self.battle().get_script_count() + 1
|
self.battle().get_script_count() + 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,34 +84,34 @@ impl HitData {
|
||||||
|
|
||||||
/// An executing move is the data of the move for while it is executing.
|
/// An executing move is the data of the move for while it is executing.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExecutingMove<'own, 'battle, 'library> {
|
pub struct ExecutingMove {
|
||||||
/// The number of hits this move has.
|
/// The number of hits this move has.
|
||||||
number_of_hits: u8,
|
number_of_hits: u8,
|
||||||
/// A list of hits for this move. For multi target multi hit moves, this stores the hits linearly,
|
/// A list of hits for this move. For multi target multi hit moves, this stores the hits linearly,
|
||||||
/// for example: (target1, hit1), (target1, hit2), (target2, hit1), (target2, hit2), etc.
|
/// for example: (target1, hit1), (target1, hit2), (target2, hit1), (target2, hit2), etc.
|
||||||
hits: Vec<HitData>,
|
hits: Vec<HitData>,
|
||||||
/// The user of the move.
|
/// The user of the move.
|
||||||
user: Arc<Pokemon<'battle, 'library>>,
|
user: Arc<Pokemon>,
|
||||||
/// The move the user has actually chosen to do.
|
/// The move the user has actually chosen to do.
|
||||||
chosen_move: Arc<LearnedMove<'library>>,
|
chosen_move: Arc<LearnedMove>,
|
||||||
/// The move that the user is actually going to do.
|
/// The move that the user is actually going to do.
|
||||||
use_move: &'own MoveData,
|
use_move: Arc<MoveData>,
|
||||||
/// The script of the move.
|
/// The script of the move.
|
||||||
script: ScriptContainer,
|
script: ScriptContainer,
|
||||||
/// The targets for this move.
|
/// The targets for this move.
|
||||||
targets: &'own TargetList<'battle, 'library>,
|
targets: TargetList,
|
||||||
/// Data required for this to be a script source.
|
/// Data required for this to be a script source.
|
||||||
script_source_data: RwLock<ScriptSourceData>,
|
script_source_data: RwLock<ScriptSourceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
|
impl ExecutingMove {
|
||||||
/// Instantiates an executing move.
|
/// Instantiates an executing move.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
targets: &'own TargetList<'battle, 'library>,
|
targets: TargetList,
|
||||||
number_of_hits: u8,
|
number_of_hits: u8,
|
||||||
user: Arc<Pokemon<'battle, 'library>>,
|
user: Arc<Pokemon>,
|
||||||
chosen_move: Arc<LearnedMove<'library>>,
|
chosen_move: Arc<LearnedMove>,
|
||||||
use_move: &'own MoveData,
|
use_move: Arc<MoveData>,
|
||||||
script: ScriptContainer,
|
script: ScriptContainer,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let total_hits = number_of_hits as usize * targets.len();
|
let total_hits = number_of_hits as usize * targets.len();
|
||||||
|
@ -140,16 +140,16 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
|
||||||
self.number_of_hits
|
self.number_of_hits
|
||||||
}
|
}
|
||||||
/// The user of the move.
|
/// The user of the move.
|
||||||
pub fn user(&self) -> &Arc<Pokemon<'battle, 'library>> {
|
pub fn user(&self) -> &Arc<Pokemon> {
|
||||||
&self.user
|
&self.user
|
||||||
}
|
}
|
||||||
/// The move the user has actually chosen to do.
|
/// The move the user has actually chosen to do.
|
||||||
pub fn chosen_move(&self) -> &Arc<LearnedMove<'library>> {
|
pub fn chosen_move(&self) -> &Arc<LearnedMove> {
|
||||||
&self.chosen_move
|
&self.chosen_move
|
||||||
}
|
}
|
||||||
/// The move that the user is actually going to do.
|
/// The move that the user is actually going to do.
|
||||||
pub fn use_move(&self) -> &'own MoveData {
|
pub fn use_move(&self) -> &Arc<MoveData> {
|
||||||
self.use_move
|
&self.use_move
|
||||||
}
|
}
|
||||||
/// The script of the move.
|
/// The script of the move.
|
||||||
pub fn script(&self) -> &ScriptContainer {
|
pub fn script(&self) -> &ScriptContainer {
|
||||||
|
@ -157,11 +157,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a hit data for a target, with a specific index.
|
/// Gets a hit data for a target, with a specific index.
|
||||||
pub fn get_hit_data<'func>(
|
pub fn get_hit_data<'func>(&'func self, for_target: &'func Arc<Pokemon>, hit: u8) -> PkmnResult<&'func HitData> {
|
||||||
&'func self,
|
|
||||||
for_target: &'func Arc<Pokemon<'battle, 'library>>,
|
|
||||||
hit: u8,
|
|
||||||
) -> PkmnResult<&'func HitData> {
|
|
||||||
for (index, target) in self.targets.iter().enumerate() {
|
for (index, target) in self.targets.iter().enumerate() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) {
|
if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) {
|
||||||
|
@ -174,7 +170,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether a Pokemon is a target for this move.
|
/// Checks whether a Pokemon is a target for this move.
|
||||||
pub fn is_pokemon_target(&self, pokemon: &Arc<Pokemon<'battle, 'library>>) -> bool {
|
pub fn is_pokemon_target(&self, pokemon: &Arc<Pokemon>) -> bool {
|
||||||
for target in self.targets.iter().flatten() {
|
for target in self.targets.iter().flatten() {
|
||||||
if std::ptr::eq(target.deref().deref(), pokemon.deref().deref()) {
|
if std::ptr::eq(target.deref().deref(), pokemon.deref().deref()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -184,7 +180,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the index of the hits in this move where the hits for a specific target start.
|
/// Gets the index of the hits in this move where the hits for a specific target start.
|
||||||
pub(crate) fn get_index_of_target(&self, for_target: &Arc<Pokemon<'battle, 'library>>) -> PkmnResult<usize> {
|
pub(crate) fn get_index_of_target(&self, for_target: &Arc<Pokemon>) -> PkmnResult<usize> {
|
||||||
for (index, target) in self.targets.iter().enumerate() {
|
for (index, target) in self.targets.iter().enumerate() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) {
|
if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) {
|
||||||
|
@ -202,7 +198,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'battle, 'library> ScriptSource<'own> for ExecutingMove<'own, 'battle, 'library> {
|
impl ScriptSource for ExecutingMove {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::sync::atomic::{AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicU8, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::static_data::MoveData;
|
use crate::static_data::MoveData;
|
||||||
|
|
||||||
|
@ -6,9 +7,9 @@ use crate::static_data::MoveData;
|
||||||
/// such as the remaining amount of users, how it has been learned, etc.
|
/// such as the remaining amount of users, how it has been learned, etc.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||||
pub struct LearnedMove<'library> {
|
pub struct LearnedMove {
|
||||||
/// The immutable move information of the move.
|
/// The immutable move information of the move.
|
||||||
move_data: &'library MoveData,
|
move_data: Arc<MoveData>,
|
||||||
/// The maximal power points for this move.
|
/// The maximal power points for this move.
|
||||||
max_pp: u8,
|
max_pp: u8,
|
||||||
/// The amount of remaining power points. If this is 0, we can not use the move anymore.
|
/// The amount of remaining power points. If this is 0, we can not use the move anymore.
|
||||||
|
@ -28,11 +29,11 @@ pub enum MoveLearnMethod {
|
||||||
Level = 1,
|
Level = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LearnedMove<'a> {
|
impl LearnedMove {
|
||||||
/// Instantiate a new learned move.
|
/// Instantiate a new learned move.
|
||||||
pub fn new(move_data: &'a MoveData, learn_method: MoveLearnMethod) -> Self {
|
pub fn new(move_data: &Arc<MoveData>, learn_method: MoveLearnMethod) -> Self {
|
||||||
Self {
|
Self {
|
||||||
move_data,
|
move_data: move_data.clone(),
|
||||||
max_pp: move_data.base_usages(),
|
max_pp: move_data.base_usages(),
|
||||||
remaining_pp: AtomicU8::new(move_data.base_usages()),
|
remaining_pp: AtomicU8::new(move_data.base_usages()),
|
||||||
learn_method,
|
learn_method,
|
||||||
|
@ -40,8 +41,8 @@ impl<'a> LearnedMove<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The immutable move information of the move.
|
/// The immutable move information of the move.
|
||||||
pub fn move_data(&self) -> &MoveData {
|
pub fn move_data(&self) -> &Arc<MoveData> {
|
||||||
self.move_data
|
&self.move_data
|
||||||
}
|
}
|
||||||
/// The maximal power points for this move.
|
/// The maximal power points for this move.
|
||||||
pub fn max_pp(&self) -> u8 {
|
pub fn max_pp(&self) -> u8 {
|
||||||
|
|
|
@ -26,23 +26,20 @@ use crate::{script_hook, PkmnResult, StringKey};
|
||||||
/// An individual Pokemon as we know and love them.
|
/// An individual Pokemon as we know and love them.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||||
pub struct Pokemon<'own, 'library>
|
pub struct Pokemon {
|
||||||
where
|
|
||||||
'own: 'library,
|
|
||||||
{
|
|
||||||
/// The library data of the Pokemon.
|
/// The library data of the Pokemon.
|
||||||
library: &'own DynamicLibrary,
|
library: Arc<DynamicLibrary>,
|
||||||
/// The species of the Pokemon.
|
/// The species of the Pokemon.
|
||||||
species: &'own Species,
|
species: Arc<Species>,
|
||||||
/// The form of the Pokemon.
|
/// The form of the Pokemon.
|
||||||
form: &'own Form,
|
form: Arc<Form>,
|
||||||
|
|
||||||
/// An optional display species of the Pokemon. If this is set, the client should display this
|
/// An optional display species of the Pokemon. If this is set, the client should display this
|
||||||
/// species. An example of usage for this is the Illusion ability.
|
/// species. An example of usage for this is the Illusion ability.
|
||||||
display_species: Option<&'own Species>,
|
display_species: Option<Arc<Species>>,
|
||||||
/// An optional display form of the Pokemon. If this is set, the client should display this
|
/// An optional display form of the Pokemon. If this is set, the client should display this
|
||||||
// species. An example of usage for this is the Illusion ability.
|
// species. An example of usage for this is the Illusion ability.
|
||||||
display_form: Option<&'own Form>,
|
display_form: Option<Arc<Form>>,
|
||||||
|
|
||||||
/// The current level of the Pokemon.
|
/// The current level of the Pokemon.
|
||||||
level: LevelInt,
|
level: LevelInt,
|
||||||
|
@ -57,7 +54,7 @@ where
|
||||||
/// currently not used, and can be used for other implementations.
|
/// currently not used, and can be used for other implementations.
|
||||||
coloring: u8,
|
coloring: u8,
|
||||||
/// The held item of the Pokemon.
|
/// The held item of the Pokemon.
|
||||||
held_item: RwLock<Option<&'own Item>>,
|
held_item: RwLock<Option<Arc<Item>>>,
|
||||||
/// The remaining health points of the Pokemon.
|
/// The remaining health points of the Pokemon.
|
||||||
current_health: AtomicU32,
|
current_health: AtomicU32,
|
||||||
|
|
||||||
|
@ -78,7 +75,7 @@ where
|
||||||
/// The [effort values](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
|
/// The [effort values](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
|
||||||
effort_values: ClampedStatisticSet<u8, 0, 252>,
|
effort_values: ClampedStatisticSet<u8, 0, 252>,
|
||||||
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
|
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
|
||||||
nature: &'own Nature,
|
nature: Arc<Nature>,
|
||||||
|
|
||||||
/// An optional nickname of the Pokemon.
|
/// An optional nickname of the Pokemon.
|
||||||
nickname: Option<String>,
|
nickname: Option<String>,
|
||||||
|
@ -90,11 +87,11 @@ where
|
||||||
override_ability: Option<Ability>,
|
override_ability: Option<Ability>,
|
||||||
|
|
||||||
/// If in battle, we have additional data.
|
/// If in battle, we have additional data.
|
||||||
battle_data: RwLock<Option<PokemonBattleData<'own, 'library>>>,
|
battle_data: RwLock<Option<PokemonBattleData>>,
|
||||||
|
|
||||||
/// The moves the Pokemon has learned. This is of a set length of [`MAX_MOVES`]. Empty move slots
|
/// The moves the Pokemon has learned. This is of a set length of [`MAX_MOVES`]. Empty move slots
|
||||||
/// are defined by None.
|
/// are defined by None.
|
||||||
moves: RwLock<[Option<Arc<LearnedMove<'library>>>; MAX_MOVES]>,
|
moves: RwLock<[Option<Arc<LearnedMove>>; MAX_MOVES]>,
|
||||||
/// Whether or not the Pokemon is allowed to gain experience.
|
/// Whether or not the Pokemon is allowed to gain experience.
|
||||||
allowed_experience: bool,
|
allowed_experience: bool,
|
||||||
|
|
||||||
|
@ -118,12 +115,12 @@ where
|
||||||
script_source_data: RwLock<ScriptSourceData>,
|
script_source_data: RwLock<ScriptSourceData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> Pokemon<'own, 'library> {
|
impl Pokemon {
|
||||||
/// Instantiates a new Pokemon.
|
/// Instantiates a new Pokemon.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
library: &'own DynamicLibrary,
|
library: Arc<DynamicLibrary>,
|
||||||
species: &'own Species,
|
species: Arc<Species>,
|
||||||
form: &'own Form,
|
form: &Arc<Form>,
|
||||||
ability: AbilityIndex,
|
ability: AbilityIndex,
|
||||||
level: LevelInt,
|
level: LevelInt,
|
||||||
unique_identifier: u32,
|
unique_identifier: u32,
|
||||||
|
@ -142,11 +139,12 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
.static_data()
|
.static_data()
|
||||||
.natures()
|
.natures()
|
||||||
.get_nature(nature)
|
.get_nature(nature)
|
||||||
.unwrap_or_else(|| panic!("Unknown nature name was given: {}.", &nature));
|
.unwrap_or_else(|| panic!("Unknown nature name was given: {}.", &nature))
|
||||||
|
.clone();
|
||||||
let mut pokemon = Self {
|
let mut pokemon = Self {
|
||||||
library,
|
library,
|
||||||
species,
|
species,
|
||||||
form,
|
form: form.clone(),
|
||||||
display_species: None,
|
display_species: None,
|
||||||
display_form: None,
|
display_form: None,
|
||||||
level,
|
level,
|
||||||
|
@ -187,31 +185,31 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The library data of the Pokemon.
|
/// The library data of the Pokemon.
|
||||||
pub fn library(&self) -> &'own DynamicLibrary {
|
pub fn library(&self) -> &Arc<DynamicLibrary> {
|
||||||
self.library
|
&self.library
|
||||||
}
|
}
|
||||||
/// The species of the Pokemon.
|
/// The species of the Pokemon.
|
||||||
pub fn species(&self) -> &'own Species {
|
pub fn species(&self) -> &Arc<Species> {
|
||||||
self.species
|
&self.species
|
||||||
}
|
}
|
||||||
/// The form of the Pokemon.
|
/// The form of the Pokemon.
|
||||||
pub fn form(&self) -> &'own Form {
|
pub fn form(&self) -> &Arc<Form> {
|
||||||
self.form
|
&self.form
|
||||||
}
|
}
|
||||||
/// The species that should be displayed to the user. This handles stuff like the Illusion ability.
|
/// The species that should be displayed to the user. This handles stuff like the Illusion ability.
|
||||||
pub fn display_species(&self) -> &'own Species {
|
pub fn display_species(&self) -> &Arc<Species> {
|
||||||
if let Some(v) = self.display_species {
|
if let Some(v) = &self.display_species {
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
self.species
|
&self.species
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// The form that should be displayed to the user. This handles stuff like the Illusion ability.
|
/// The form that should be displayed to the user. This handles stuff like the Illusion ability.
|
||||||
pub fn display_form(&self) -> &'own Form {
|
pub fn display_form(&self) -> &Arc<Form> {
|
||||||
if let Some(v) = self.display_form {
|
if let Some(v) = &self.display_form {
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
self.form
|
&self.form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// The current level of the Pokemon.
|
/// The current level of the Pokemon.
|
||||||
|
@ -235,8 +233,8 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
pub fn coloring(&self) -> u8 {
|
pub fn coloring(&self) -> u8 {
|
||||||
self.coloring
|
self.coloring
|
||||||
}
|
}
|
||||||
/// Checks whether the Pokemon is holding an item,
|
/// Gets the held item of a Pokemon
|
||||||
pub fn held_item(&self) -> &RwLock<Option<&'own Item>> {
|
pub fn held_item(&self) -> &RwLock<Option<Arc<Item>>> {
|
||||||
&self.held_item
|
&self.held_item
|
||||||
}
|
}
|
||||||
/// Checks whether the Pokemon is holding a specific item.
|
/// Checks whether the Pokemon is holding a specific item.
|
||||||
|
@ -248,11 +246,11 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
/// Changes the held item of the Pokemon/
|
/// Changes the held item of the Pokemon/
|
||||||
pub fn set_held_item(&self, item: &'own Item) -> Option<&'own Item> {
|
pub fn set_held_item(&self, item: &Arc<Item>) -> Option<Arc<Item>> {
|
||||||
self.held_item.write().replace(item)
|
self.held_item.write().replace(item.clone())
|
||||||
}
|
}
|
||||||
/// Removes the held item from the Pokemon.
|
/// Removes the held item from the Pokemon.
|
||||||
pub fn remove_held_item(&self) -> Option<&'own Item> {
|
pub fn remove_held_item(&self) -> Option<Arc<Item>> {
|
||||||
self.held_item.write().take()
|
self.held_item.write().take()
|
||||||
}
|
}
|
||||||
/// Makes the Pokemon uses its held item.
|
/// Makes the Pokemon uses its held item.
|
||||||
|
@ -260,7 +258,10 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
if self.held_item.read().is_none() {
|
if self.held_item.read().is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let script = self.library.load_item_script(self.held_item.read().unwrap()).unwrap();
|
let script = self
|
||||||
|
.library
|
||||||
|
.load_item_script(&self.held_item.read().as_ref().unwrap())
|
||||||
|
.unwrap();
|
||||||
if script.is_none() {
|
if script.is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +300,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
/// The moves the Pokemon has learned. This is of a set length of [`MAX_MOVES`]. Empty move slots
|
/// The moves the Pokemon has learned. This is of a set length of [`MAX_MOVES`]. Empty move slots
|
||||||
/// are defined by None.
|
/// are defined by None.
|
||||||
pub fn learned_moves(&self) -> &RwLock<[Option<Arc<LearnedMove<'library>>>; MAX_MOVES]> {
|
pub fn learned_moves(&self) -> &RwLock<[Option<Arc<LearnedMove>>; MAX_MOVES]> {
|
||||||
&self.moves
|
&self.moves
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +385,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the battle the battle is currently in.
|
/// Gets the battle the battle is currently in.
|
||||||
pub fn get_battle(&self) -> Option<&Battle<'own, 'library>> {
|
pub fn get_battle(&self) -> Option<&Battle> {
|
||||||
let r = self.battle_data.read();
|
let r = self.battle_data.read();
|
||||||
if let Some(data) = &r.deref() {
|
if let Some(data) = &r.deref() {
|
||||||
unsafe { data.battle.as_ref() }
|
unsafe { data.battle.as_ref() }
|
||||||
|
@ -434,8 +435,8 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
|
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
|
||||||
pub fn nature(&self) -> &'own Nature {
|
pub fn nature(&self) -> &Arc<Nature> {
|
||||||
self.nature
|
&self.nature
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the flat stats on the Pokemon.
|
/// Calculates the flat stats on the Pokemon.
|
||||||
|
@ -453,9 +454,9 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the species of the Pokemon.
|
/// Change the species of the Pokemon.
|
||||||
pub fn change_species(&mut self, species: &'own Species, form: &'own Form) {
|
pub fn change_species(&mut self, species: Arc<Species>, form: Arc<Form>) {
|
||||||
self.species = species;
|
self.species = species.clone();
|
||||||
self.form = form;
|
self.form = form.clone();
|
||||||
|
|
||||||
// If the pokemon is genderless, but it's new species is not, we want to set its gender
|
// If the pokemon is genderless, but it's new species is not, we want to set its gender
|
||||||
if self.gender != Gender::Genderless && species.gender_rate() < 0.0 {
|
if self.gender != Gender::Genderless && species.gender_rate() < 0.0 {
|
||||||
|
@ -486,11 +487,11 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the form of the Pokemon.
|
/// Change the form of the Pokemon.
|
||||||
pub fn change_form(&mut self, form: &'own Form) {
|
pub fn change_form(&mut self, form: &Arc<Form>) {
|
||||||
if std::ptr::eq(self.form, form) {
|
if Arc::ptr_eq(&self.form, form) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.form = form;
|
self.form = form.clone();
|
||||||
|
|
||||||
self.types.clear();
|
self.types.clear();
|
||||||
for t in form.types() {
|
for t in form.types() {
|
||||||
|
@ -512,7 +513,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
.set(ability_script)
|
.set(ability_script)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
// Ensure the ability script gets initialized with the parameters for the ability.
|
// Ensure the ability script gets initialized with the parameters for the ability.
|
||||||
.on_initialize(self.library, self.active_ability().parameters())
|
.on_initialize(self.library.as_ref(), self.active_ability().parameters())
|
||||||
} else {
|
} else {
|
||||||
self.ability_script.clear();
|
self.ability_script.clear();
|
||||||
}
|
}
|
||||||
|
@ -547,7 +548,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current battle the Pokemon is in.
|
/// Sets the current battle the Pokemon is in.
|
||||||
pub fn set_battle_data(&self, battle: *mut Battle<'own, 'library>, battle_side_index: u8) {
|
pub fn set_battle_data(&self, battle: *mut Battle, battle_side_index: u8) {
|
||||||
let mut w = self.battle_data.write();
|
let mut w = self.battle_data.write();
|
||||||
if let Some(battle_data) = w.deref_mut() {
|
if let Some(battle_data) = w.deref_mut() {
|
||||||
battle_data.battle = battle;
|
battle_data.battle = battle;
|
||||||
|
@ -590,7 +591,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marks an opponent as seen, for use in experience gain.
|
/// Marks an opponent as seen, for use in experience gain.
|
||||||
pub fn mark_opponent_as_seen(&self, pokemon: Weak<Pokemon<'own, 'library>>) {
|
pub fn mark_opponent_as_seen(&self, pokemon: Weak<Pokemon>) {
|
||||||
let r = self.battle_data.read();
|
let r = self.battle_data.read();
|
||||||
if let Some(battle_data) = &r.deref() {
|
if let Some(battle_data) = &r.deref() {
|
||||||
let mut opponents = battle_data.seen_opponents().write();
|
let mut opponents = battle_data.seen_opponents().write();
|
||||||
|
@ -692,9 +693,9 @@ impl<'own, 'library> Pokemon<'own, 'library> {
|
||||||
|
|
||||||
/// The data of the Pokemon related to being in a battle.
|
/// The data of the Pokemon related to being in a battle.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PokemonBattleData<'pokemon, 'library> {
|
pub struct PokemonBattleData {
|
||||||
/// The battle data of the Pokemon
|
/// The battle data of the Pokemon
|
||||||
battle: *mut Battle<'pokemon, 'library>,
|
battle: *mut Battle,
|
||||||
/// The index of the side of the Pokemon
|
/// The index of the side of the Pokemon
|
||||||
battle_side_index: AtomicU8,
|
battle_side_index: AtomicU8,
|
||||||
/// The index of the slot on the side of the Pokemon.
|
/// The index of the slot on the side of the Pokemon.
|
||||||
|
@ -702,16 +703,16 @@ pub struct PokemonBattleData<'pokemon, 'library> {
|
||||||
/// Whether or not the Pokemon is on the battlefield.
|
/// Whether or not the Pokemon is on the battlefield.
|
||||||
on_battle_field: AtomicBool,
|
on_battle_field: AtomicBool,
|
||||||
/// A list of opponents the Pokemon has seen this battle.
|
/// A list of opponents the Pokemon has seen this battle.
|
||||||
seen_opponents: RwLock<Vec<Weak<Pokemon<'pokemon, 'library>>>>,
|
seen_opponents: RwLock<Vec<Weak<Pokemon>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'pokemon, 'library> PokemonBattleData<'pokemon, 'library> {
|
impl PokemonBattleData {
|
||||||
/// The battle data of the Pokemon
|
/// The battle data of the Pokemon
|
||||||
pub fn battle_mut(&mut self) -> Option<&mut Battle<'pokemon, 'library>> {
|
pub fn battle_mut(&mut self) -> Option<&mut Battle> {
|
||||||
unsafe { self.battle.as_mut() }
|
unsafe { self.battle.as_mut() }
|
||||||
}
|
}
|
||||||
/// The battle data of the Pokemon
|
/// The battle data of the Pokemon
|
||||||
pub fn battle(&self) -> Option<&Battle<'pokemon, 'library>> {
|
pub fn battle(&self) -> Option<&Battle> {
|
||||||
unsafe { self.battle.as_ref() }
|
unsafe { self.battle.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,12 +729,12 @@ impl<'pokemon, 'library> PokemonBattleData<'pokemon, 'library> {
|
||||||
self.on_battle_field.load(Ordering::Relaxed)
|
self.on_battle_field.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
/// A list of opponents the Pokemon has seen this battle.
|
/// A list of opponents the Pokemon has seen this battle.
|
||||||
pub fn seen_opponents(&self) -> &RwLock<Vec<Weak<Pokemon<'pokemon, 'library>>>> {
|
pub fn seen_opponents(&self) -> &RwLock<Vec<Weak<Pokemon>>> {
|
||||||
&self.seen_opponents
|
&self.seen_opponents
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> ScriptSource<'own> for Pokemon<'own, 'library> {
|
impl ScriptSource for Pokemon {
|
||||||
fn get_script_count(&self) -> usize {
|
fn get_script_count(&self) -> usize {
|
||||||
let mut c = 3;
|
let mut c = 3;
|
||||||
if let Some(battle_data) = &self.battle_data.read().deref() {
|
if let Some(battle_data) = &self.battle_data.read().deref() {
|
||||||
|
@ -765,7 +766,7 @@ impl<'own, 'library> ScriptSource<'own> for Pokemon<'own, 'library> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> VolatileScriptsOwner<'own> for Pokemon<'own, 'library> {
|
impl VolatileScriptsOwner for Pokemon {
|
||||||
fn volatile_scripts(&self) -> &Arc<ScriptSet> {
|
fn volatile_scripts(&self) -> &Arc<ScriptSet> {
|
||||||
&self.volatile
|
&self.volatile
|
||||||
}
|
}
|
||||||
|
@ -794,7 +795,7 @@ pub mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn construct_pokemon() {
|
fn construct_pokemon() {
|
||||||
let lib = crate::dynamic_data::libraries::dynamic_library::test::build();
|
let lib = Arc::new(crate::dynamic_data::libraries::dynamic_library::test::build());
|
||||||
let species = lib.static_data().species().get(&"foo".into()).unwrap();
|
let species = lib.static_data().species().get(&"foo".into()).unwrap();
|
||||||
let form = species.get_form(&"default".into()).unwrap();
|
let form = species.get_form(&"default".into()).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
use crate::dynamic_data::models::learned_move::MoveLearnMethod;
|
use crate::dynamic_data::models::learned_move::MoveLearnMethod;
|
||||||
use crate::dynamic_data::models::pokemon::Pokemon;
|
use crate::dynamic_data::models::pokemon::Pokemon;
|
||||||
|
@ -6,9 +8,9 @@ use crate::static_data::{AbilityIndex, DataLibrary, Gender};
|
||||||
use crate::{Random, StringKey};
|
use crate::{Random, StringKey};
|
||||||
|
|
||||||
/// This allows for the easy chain building of a Pokemon.
|
/// This allows for the easy chain building of a Pokemon.
|
||||||
pub struct PokemonBuilder<'own> {
|
pub struct PokemonBuilder {
|
||||||
/// The library of the Pokemon.
|
/// The library of the Pokemon.
|
||||||
library: &'own DynamicLibrary,
|
library: Arc<DynamicLibrary>,
|
||||||
/// The name of the species of the Pokemon.
|
/// The name of the species of the Pokemon.
|
||||||
species: StringKey,
|
species: StringKey,
|
||||||
/// The level of the Pokemon.
|
/// The level of the Pokemon.
|
||||||
|
@ -19,9 +21,9 @@ pub struct PokemonBuilder<'own> {
|
||||||
random_seed: Option<u128>,
|
random_seed: Option<u128>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own> PokemonBuilder<'own> {
|
impl PokemonBuilder {
|
||||||
/// Creates a new PokemonBuilder with a library, species, and level.
|
/// Creates a new PokemonBuilder with a library, species, and level.
|
||||||
pub fn new(library: &'own DynamicLibrary, species: StringKey, level: LevelInt) -> Self {
|
pub fn new(library: Arc<DynamicLibrary>, species: StringKey, level: LevelInt) -> Self {
|
||||||
Self {
|
Self {
|
||||||
library,
|
library,
|
||||||
species,
|
species,
|
||||||
|
@ -37,19 +39,19 @@ impl<'own> PokemonBuilder<'own> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finally turn the builder into an actual Pokemon.
|
/// Finally turn the builder into an actual Pokemon.
|
||||||
pub fn build(self) -> Pokemon<'own, 'own> {
|
pub fn build(self) -> Pokemon {
|
||||||
let mut random = if let Some(seed) = self.random_seed {
|
let mut random = if let Some(seed) = self.random_seed {
|
||||||
Random::new(seed)
|
Random::new(seed)
|
||||||
} else {
|
} else {
|
||||||
Random::default()
|
Random::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let species = self.library.static_data().species().get(&self.species).unwrap();
|
let species = self.library.static_data().species().get(&self.species).unwrap().clone();
|
||||||
let form = species.get_default_form();
|
let form = species.get_default_form().clone();
|
||||||
let p = Pokemon::new(
|
let p = Pokemon::new(
|
||||||
self.library,
|
self.library,
|
||||||
species,
|
species,
|
||||||
form,
|
&form,
|
||||||
AbilityIndex {
|
AbilityIndex {
|
||||||
hidden: false,
|
hidden: false,
|
||||||
index: 0,
|
index: 0,
|
||||||
|
|
|
@ -4,12 +4,12 @@ use crate::dynamic_data::models::pokemon::Pokemon;
|
||||||
|
|
||||||
/// A list of Pokemon belonging to a trainer.
|
/// A list of Pokemon belonging to a trainer.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PokemonParty<'pokemon, 'library> {
|
pub struct PokemonParty {
|
||||||
/// The underlying list of Pokemon.
|
/// The underlying list of Pokemon.
|
||||||
pokemon: Vec<Option<Arc<Pokemon<'pokemon, 'library>>>>,
|
pokemon: Vec<Option<Arc<Pokemon>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'own, 'library> PokemonParty<'own, 'library> {
|
impl<'own, 'library> PokemonParty {
|
||||||
/// Instantiates a party with a set size.
|
/// Instantiates a party with a set size.
|
||||||
pub fn new(size: usize) -> Self {
|
pub fn new(size: usize) -> Self {
|
||||||
let mut pokemon = Vec::with_capacity(size);
|
let mut pokemon = Vec::with_capacity(size);
|
||||||
|
@ -20,12 +20,12 @@ impl<'own, 'library> PokemonParty<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiates a party with a list.
|
/// Instantiates a party with a list.
|
||||||
pub fn new_from_vec(pokemon: Vec<Option<Arc<Pokemon<'own, 'library>>>>) -> Self {
|
pub fn new_from_vec(pokemon: Vec<Option<Arc<Pokemon>>>) -> Self {
|
||||||
Self { pokemon }
|
Self { pokemon }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a Pokemon at an index in the party.
|
/// Gets a Pokemon at an index in the party.
|
||||||
pub fn at(&self, index: usize) -> &Option<Arc<Pokemon<'own, 'library>>> {
|
pub fn at(&self, index: usize) -> &Option<Arc<Pokemon>> {
|
||||||
let opt = self.pokemon.get(index);
|
let opt = self.pokemon.get(index);
|
||||||
if let Some(v) = opt {
|
if let Some(v) = opt {
|
||||||
v
|
v
|
||||||
|
@ -40,11 +40,7 @@ impl<'own, 'library> PokemonParty<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon.
|
/// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon.
|
||||||
pub fn swap_into(
|
pub fn swap_into(&mut self, index: usize, pokemon: Option<Arc<Pokemon>>) -> Option<Arc<Pokemon>> {
|
||||||
&mut self,
|
|
||||||
index: usize,
|
|
||||||
pokemon: Option<Arc<Pokemon<'own, 'library>>>,
|
|
||||||
) -> Option<Arc<Pokemon<'own, 'library>>> {
|
|
||||||
if index >= self.pokemon.len() {
|
if index >= self.pokemon.len() {
|
||||||
return pokemon;
|
return pokemon;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +65,7 @@ impl<'own, 'library> PokemonParty<'own, 'library> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the underlying list of Pokemon.
|
/// Gets the underlying list of Pokemon.
|
||||||
pub fn pokemon(&self) -> &Vec<Option<Arc<Pokemon<'own, 'library>>>> {
|
pub fn pokemon(&self) -> &Vec<Option<Arc<Pokemon>>> {
|
||||||
&self.pokemon
|
&self.pokemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub struct ScriptSourceData {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A script source is a struct on which we can trigger scripts to be run from.
|
/// A script source is a struct on which we can trigger scripts to be run from.
|
||||||
pub trait ScriptSource<'a> {
|
pub trait ScriptSource {
|
||||||
/// Gets an iterator over all the scripts that are relevant to this script source. If the data
|
/// Gets an iterator over all the scripts that are relevant to this script source. If the data
|
||||||
/// has not been initialised, it will do so here.
|
/// has not been initialised, it will do so here.
|
||||||
fn get_script_iterator(&self) -> ScriptIterator {
|
fn get_script_iterator(&self) -> ScriptIterator {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::dynamic_data::script_handling::script_set::ScriptSet;
|
||||||
use crate::{PkmnResult, StringKey};
|
use crate::{PkmnResult, StringKey};
|
||||||
|
|
||||||
/// This trait adds a bunch of helper functions to deal with volatile scripts on a struct.
|
/// This trait adds a bunch of helper functions to deal with volatile scripts on a struct.
|
||||||
pub trait VolatileScriptsOwner<'a> {
|
pub trait VolatileScriptsOwner {
|
||||||
/// Return the [`ScriptSet`] that are our volatile scripts.
|
/// Return the [`ScriptSet`] that are our volatile scripts.
|
||||||
fn volatile_scripts(&self) -> &Arc<ScriptSet>;
|
fn volatile_scripts(&self) -> &Arc<ScriptSet>;
|
||||||
/// Loads a volatile script by name.
|
/// Loads a volatile script by name.
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use std::intrinsics::transmute;
|
use std::intrinsics::transmute;
|
||||||
|
|
||||||
use crate::dynamic_data::{LearnedMove, MoveLearnMethod, Pokemon, TurnChoice};
|
use crate::dynamic_data::LearnedMove;
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::MoveData;
|
use crate::static_data::MoveData;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn learned_move_get_learn_method<'a>(
|
fn learned_move_get_learn_method(
|
||||||
env: &WebAssemblyEnv,
|
env: &WebAssemblyEnv,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
|
@ -16,7 +16,7 @@ register! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn learned_move_get_move_data<'a>(
|
fn learned_move_get_move_data(
|
||||||
env: &WebAssemblyEnv,
|
env: &WebAssemblyEnv,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) -> ExternRef<MoveData> {
|
) -> ExternRef<MoveData> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
|
||||||
use crate::dynamic_data::{DamageSource, DynamicLibrary, Pokemon};
|
use crate::dynamic_data::{DynamicLibrary, Pokemon};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
|
|
@ -7,10 +7,10 @@ use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
|
||||||
fn turn_choice_get_user<'a>(
|
fn turn_choice_get_user(
|
||||||
env: &WebAssemblyEnv,
|
env: &WebAssemblyEnv,
|
||||||
turn_choice: ExternRef<TurnChoice<'a, 'a>>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> ExternRef<Pokemon<'a, 'a>> {
|
) -> ExternRef<Pokemon> {
|
||||||
let turn_choice = turn_choice.value(env).unwrap();
|
let turn_choice = turn_choice.value(env).unwrap();
|
||||||
ExternRef::new(env.data().as_ref(), turn_choice.user().as_ref().deref())
|
ExternRef::new(env.data().as_ref(), turn_choice.user().as_ref().deref())
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,10 @@ register! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_used_move<'a>(
|
fn turn_choice_move_used_move(
|
||||||
env: &WebAssemblyEnv,
|
env: &WebAssemblyEnv,
|
||||||
turn_choice: ExternRef<TurnChoice<'a, 'a>>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> ExternRef<LearnedMove<'a>> {
|
) -> ExternRef<LearnedMove> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
|
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
|
||||||
return ExternRef::new(env.data().as_ref(), d.used_move().as_ref());
|
return ExternRef::new(env.data().as_ref(), d.used_move().as_ref());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem::{align_of, forget};
|
use std::mem::{align_of, forget};
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
use wasmer::{Exports, Store};
|
use wasmer::{Exports, Store};
|
||||||
|
|
||||||
pub(crate) use register;
|
|
||||||
pub(crate) use register_func_with_env;
|
|
||||||
|
|
||||||
use crate::dynamic_data::DynamicLibrary;
|
use crate::dynamic_data::DynamicLibrary;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
@ -35,7 +31,7 @@ macro_rules! register_func_with_env {
|
||||||
macro_rules! register {
|
macro_rules! register {
|
||||||
(
|
(
|
||||||
$(
|
$(
|
||||||
fn $name:ident$(<$($lt:lifetime)*>)?($($par:ident: $par_type:ty),*$(,)?) $(-> $return:ty)? $block:block
|
fn $name:ident($($par:ident: $par_type:ty),*$(,)?) $(-> $return:ty)? $block:block
|
||||||
)*
|
)*
|
||||||
) => {
|
) => {
|
||||||
pub(crate) fn register(exports: &mut crate::script_implementations::wasm::export_registry::Exports,
|
pub(crate) fn register(exports: &mut crate::script_implementations::wasm::export_registry::Exports,
|
||||||
|
@ -43,7 +39,7 @@ macro_rules! register {
|
||||||
env: crate::script_implementations::wasm::script_resolver::WebAssemblyEnv) {
|
env: crate::script_implementations::wasm::script_resolver::WebAssemblyEnv) {
|
||||||
$(
|
$(
|
||||||
|
|
||||||
fn $name<$($($lt)*)*>(
|
fn $name(
|
||||||
$(
|
$(
|
||||||
$par: $par_type,
|
$par: $par_type,
|
||||||
)*
|
)*
|
||||||
|
@ -55,6 +51,9 @@ macro_rules! register {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use register;
|
||||||
|
pub(crate) use register_func_with_env;
|
||||||
|
|
||||||
pub(crate) fn register_webassembly_funcs(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
|
pub(crate) fn register_webassembly_funcs(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
|
||||||
register_func_with_env!(exports, store, _print, env);
|
register_func_with_env!(exports, store, _print, env);
|
||||||
register_func_with_env!(exports, store, _error, env);
|
register_func_with_env!(exports, store, _error, env);
|
||||||
|
|
|
@ -21,10 +21,6 @@ impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn index(&self) -> u32 {
|
|
||||||
self.index
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
||||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self {
|
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::mem::{align_of, size_of};
|
|
||||||
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize};
|
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use wasmer::NativeFunc;
|
use wasmer::NativeFunc;
|
||||||
|
|
||||||
use crate::dynamic_data::{DynamicLibrary, Pokemon, Script, TurnChoice};
|
use crate::dynamic_data::{DynamicLibrary, Script, TurnChoice};
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
||||||
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
||||||
|
@ -92,8 +91,7 @@ impl Script for WebAssemblyScript {
|
||||||
let env = self.environment.upgrade().unwrap();
|
let env = self.environment.upgrade().unwrap();
|
||||||
let func = env.script_function_cache().on_before_turn(&env);
|
let func = env.script_function_cache().on_before_turn(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice).index())
|
func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice)).unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,5 +58,5 @@ macro_rules! script_function_cache {
|
||||||
|
|
||||||
script_function_cache! {
|
script_function_cache! {
|
||||||
on_initialize -> NativeFunc<(u32, ExternRef<DynamicLibrary>, VecExternRef<EffectParameter>), ()>
|
on_initialize -> NativeFunc<(u32, ExternRef<DynamicLibrary>, VecExternRef<EffectParameter>), ()>
|
||||||
on_before_turn -> NativeFunc<(u32, u32), ()>
|
on_before_turn -> NativeFunc<(u32, ExternRef<TurnChoice>), ()>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::static_data::Ability;
|
use crate::static_data::Ability;
|
||||||
|
@ -8,7 +10,7 @@ use crate::StringKey;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AbilityLibrary {
|
pub struct AbilityLibrary {
|
||||||
/// The underlying map for the library.
|
/// The underlying map for the library.
|
||||||
map: IndexMap<StringKey, Box<Ability>>,
|
map: IndexMap<StringKey, Arc<Ability>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityLibrary {
|
impl AbilityLibrary {
|
||||||
|
@ -20,11 +22,11 @@ impl AbilityLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<'_, Box<Ability>> for AbilityLibrary {
|
impl DataLibrary<'_, Ability> for AbilityLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Box<Ability>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<Ability>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Box<Ability>> {
|
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<Ability>> {
|
||||||
&mut self.map
|
&mut self.map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::Random;
|
use crate::Random;
|
||||||
|
@ -7,13 +9,13 @@ use crate::StringKey;
|
||||||
/// by both key, while keeping their insertion order.
|
/// by both key, while keeping their insertion order.
|
||||||
pub trait DataLibrary<'a, T: 'a> {
|
pub trait DataLibrary<'a, T: 'a> {
|
||||||
/// Returns the underlying map.
|
/// Returns the underlying map.
|
||||||
fn map(&self) -> &IndexMap<StringKey, T>;
|
fn map(&self) -> &IndexMap<StringKey, Arc<T>>;
|
||||||
/// Returns the underlying map in mutable manner.
|
/// Returns the underlying map in mutable manner.
|
||||||
fn get_modify(&mut self) -> &mut IndexMap<StringKey, T>;
|
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<T>>;
|
||||||
|
|
||||||
/// Adds a new value to the library.
|
/// Adds a new value to the library.
|
||||||
fn add(&mut self, key: &StringKey, value: T) {
|
fn add(&mut self, key: &StringKey, value: T) {
|
||||||
self.get_modify().insert(key.clone(), value);
|
self.get_modify().insert(key.clone(), Arc::new(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a value from the library.
|
/// Removes a value from the library.
|
||||||
|
@ -22,20 +24,15 @@ pub trait DataLibrary<'a, T: 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value from the library.
|
/// Gets a value from the library.
|
||||||
fn get(&'a self, key: &StringKey) -> Option<&'a T> {
|
fn get(&'a self, key: &StringKey) -> Option<&Arc<T>> {
|
||||||
self.map().get::<StringKey>(key)
|
self.map().get::<StringKey>(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value from the library.
|
/// Gets a value from the library.
|
||||||
fn get_by_hash(&'a self, key: u32) -> Option<&'a T> {
|
fn get_by_hash(&'a self, key: u32) -> Option<&Arc<T>> {
|
||||||
self.map().get::<u32>(&key)
|
self.map().get::<u32>(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable value from the library.
|
|
||||||
fn get_mut(&mut self, key: &StringKey) -> Option<&mut T> {
|
|
||||||
self.get_modify().get_mut(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the amount of values in the library.
|
/// Gets the amount of values in the library.
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.map().len()
|
self.map().len()
|
||||||
|
@ -46,7 +43,7 @@ pub trait DataLibrary<'a, T: 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a random value from the library.
|
/// Gets a random value from the library.
|
||||||
fn random_value(&self, rand: &mut Random) -> &T {
|
fn random_value(&self, rand: &mut Random) -> &Arc<T> {
|
||||||
let i = rand.get_between(0, self.len() as i32);
|
let i = rand.get_between(0, self.len() as i32);
|
||||||
return self.map().get_index(i as usize).unwrap().1;
|
return self.map().get_index(i as usize).unwrap().1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::static_data::DataLibrary;
|
use crate::static_data::DataLibrary;
|
||||||
|
@ -9,7 +11,7 @@ use crate::StringKey;
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||||
pub struct ItemLibrary {
|
pub struct ItemLibrary {
|
||||||
/// The underlying data structure.
|
/// The underlying data structure.
|
||||||
map: IndexMap<StringKey, Box<Item>>,
|
map: IndexMap<StringKey, Arc<Item>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemLibrary {
|
impl ItemLibrary {
|
||||||
|
@ -21,12 +23,12 @@ impl ItemLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<'_, Box<Item>> for ItemLibrary {
|
impl DataLibrary<'_, Item> for ItemLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Box<Item>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<Item>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Box<Item>> {
|
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<Item>> {
|
||||||
&mut self.map
|
&mut self.map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::static_data::DataLibrary;
|
use crate::static_data::DataLibrary;
|
||||||
|
@ -9,7 +11,7 @@ use crate::StringKey;
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||||
pub struct MoveLibrary {
|
pub struct MoveLibrary {
|
||||||
/// The underlying map.
|
/// The underlying map.
|
||||||
map: IndexMap<StringKey, MoveData>,
|
map: IndexMap<StringKey, Arc<MoveData>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MoveLibrary {
|
impl MoveLibrary {
|
||||||
|
@ -22,10 +24,10 @@ impl MoveLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataLibrary<'_, MoveData> for MoveLibrary {
|
impl DataLibrary<'_, MoveData> for MoveLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, MoveData> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<MoveData>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
fn get_modify(&mut self) -> &mut IndexMap<StringKey, MoveData> {
|
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<MoveData>> {
|
||||||
&mut self.map
|
&mut self.map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::static_data::DataLibrary;
|
use crate::static_data::DataLibrary;
|
||||||
|
@ -9,7 +11,7 @@ use crate::StringKey;
|
||||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||||
pub struct SpeciesLibrary {
|
pub struct SpeciesLibrary {
|
||||||
/// The underlying map.
|
/// The underlying map.
|
||||||
map: IndexMap<StringKey, Box<Species>>,
|
map: IndexMap<StringKey, Arc<Species>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpeciesLibrary {
|
impl SpeciesLibrary {
|
||||||
|
@ -21,11 +23,11 @@ impl SpeciesLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DataLibrary<'a, Box<Species>> for SpeciesLibrary {
|
impl<'a> DataLibrary<'a, Species> for SpeciesLibrary {
|
||||||
fn map(&self) -> &IndexMap<StringKey, Box<Species>> {
|
fn map(&self) -> &IndexMap<StringKey, Arc<Species>> {
|
||||||
&self.map
|
&self.map
|
||||||
}
|
}
|
||||||
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Box<Species>> {
|
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<Species>> {
|
||||||
&mut self.map
|
&mut self.map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::static_data::Statistic;
|
use crate::static_data::Statistic;
|
||||||
|
@ -60,7 +62,7 @@ impl Nature {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NatureLibrary {
|
pub struct NatureLibrary {
|
||||||
/// The underlying data structure.
|
/// The underlying data structure.
|
||||||
map: HashMap<StringKey, Nature>,
|
map: HashMap<StringKey, Arc<Nature>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NatureLibrary {
|
impl NatureLibrary {
|
||||||
|
@ -73,20 +75,20 @@ impl NatureLibrary {
|
||||||
|
|
||||||
/// Adds a new nature with name to the library.
|
/// Adds a new nature with name to the library.
|
||||||
pub fn load_nature(&mut self, name: StringKey, nature: Nature) {
|
pub fn load_nature(&mut self, name: StringKey, nature: Nature) {
|
||||||
self.map.insert(name, nature);
|
self.map.insert(name, Arc::new(nature));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a nature by name.
|
/// Gets a nature by name.
|
||||||
pub fn get_nature(&self, key: &StringKey) -> Option<&Nature> {
|
pub fn get_nature(&self, key: &StringKey) -> Option<&Arc<Nature>> {
|
||||||
self.map.get(key)
|
self.map.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds a nature name by nature.
|
/// Finds a nature name by nature.
|
||||||
pub fn get_nature_name(&self, nature: &Nature) -> StringKey {
|
pub fn get_nature_name(&self, nature: &Arc<Nature>) -> StringKey {
|
||||||
for kv in &self.map {
|
for kv in &self.map {
|
||||||
// As natures can't be copied, and should always be the same reference as the value
|
// As natures can't be copied, and should always be the same reference as the value
|
||||||
// in the map, we just compare by reference.
|
// in the map, we just compare by reference.
|
||||||
if std::ptr::eq(kv.1, nature) {
|
if Arc::ptr_eq(kv.1, nature) {
|
||||||
return kv.0.clone();
|
return kv.0.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
|
|
||||||
use crate::static_data::Form;
|
use crate::static_data::Form;
|
||||||
|
@ -21,7 +23,7 @@ pub struct Species {
|
||||||
/// uncatchable.
|
/// uncatchable.
|
||||||
capture_rate: u8,
|
capture_rate: u8,
|
||||||
/// The forms that belong to this Pokemon.
|
/// The forms that belong to this Pokemon.
|
||||||
forms: HashMap<StringKey, Form>,
|
forms: HashMap<StringKey, Arc<Form>>,
|
||||||
/// The arbitrary flags that can be set on a Pokemon for script use.
|
/// The arbitrary flags that can be set on a Pokemon for script use.
|
||||||
flags: HashSet<StringKey>,
|
flags: HashSet<StringKey>,
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ impl Species {
|
||||||
flags: HashSet<StringKey>,
|
flags: HashSet<StringKey>,
|
||||||
) -> Species {
|
) -> Species {
|
||||||
let mut forms = HashMap::with_capacity(1);
|
let mut forms = HashMap::with_capacity(1);
|
||||||
forms.insert_unique_unchecked(get_default_key(), default_form);
|
forms.insert_unique_unchecked(get_default_key(), Arc::new(default_form));
|
||||||
Species {
|
Species {
|
||||||
id,
|
id,
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
|
@ -80,7 +82,7 @@ impl Species {
|
||||||
self.capture_rate
|
self.capture_rate
|
||||||
}
|
}
|
||||||
/// The forms that belong to this Pokemon.
|
/// The forms that belong to this Pokemon.
|
||||||
pub fn forms(&self) -> &HashMap<StringKey, Form> {
|
pub fn forms(&self) -> &HashMap<StringKey, Arc<Form>> {
|
||||||
&self.forms
|
&self.forms
|
||||||
}
|
}
|
||||||
/// The arbitrary flags that can be set on a Pokemon for script use.
|
/// The arbitrary flags that can be set on a Pokemon for script use.
|
||||||
|
@ -90,16 +92,16 @@ impl Species {
|
||||||
|
|
||||||
/// Adds a new form to the species.
|
/// Adds a new form to the species.
|
||||||
pub fn add_form(&mut self, id: StringKey, form: Form) {
|
pub fn add_form(&mut self, id: StringKey, form: Form) {
|
||||||
self.forms.insert(id, form);
|
self.forms.insert(id, Arc::new(form));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a form by name.
|
/// Gets a form by name.
|
||||||
pub fn get_form(&self, id: &StringKey) -> Option<&Form> {
|
pub fn get_form(&self, id: &StringKey) -> Option<&Arc<Form>> {
|
||||||
self.forms.get(id)
|
self.forms.get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the form the Pokemon will have by default, if no other form is specified.
|
/// Gets the form the Pokemon will have by default, if no other form is specified.
|
||||||
pub fn get_default_form(&self) -> &Form {
|
pub fn get_default_form(&self) -> &Arc<Form> {
|
||||||
self.forms.get(&get_default_key()).unwrap()
|
self.forms.get(&get_default_key()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,10 +115,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lib.add(
|
lib.add(&name, Item::new(&name, category, battle_category, price as i32, flags));
|
||||||
&name,
|
|
||||||
Box::new(Item::new(&name, category, battle_category, price as i32, flags)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +158,7 @@ pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ability_library.add(&name, Box::new(Ability::new(&name, &effect, parameters)));
|
ability_library.add(&name, Ability::new(&name, &effect, parameters));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +259,7 @@ pub fn load_species(path: &String, library: &mut StaticData) {
|
||||||
let default_form_value = &forms["default"];
|
let default_form_value = &forms["default"];
|
||||||
let default_form = parse_form("default".into(), default_form_value, library);
|
let default_form = parse_form("default".into(), default_form_value, library);
|
||||||
|
|
||||||
let species = Box::new(Species::new(
|
let species = Species::new(
|
||||||
id as u16,
|
id as u16,
|
||||||
&name,
|
&name,
|
||||||
gender_rate as f32,
|
gender_rate as f32,
|
||||||
|
@ -270,7 +267,7 @@ pub fn load_species(path: &String, library: &mut StaticData) {
|
||||||
catch_rate as u8,
|
catch_rate as u8,
|
||||||
default_form,
|
default_form,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
));
|
);
|
||||||
library.species_mut().add(&name, species);
|
library.species_mut().add(&name, species);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,13 +43,13 @@ struct TestPokemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestCase {
|
impl TestCase {
|
||||||
pub fn run_test(&self, library: &DynamicLibrary) {
|
pub fn run_test(&self, library: Arc<DynamicLibrary>) {
|
||||||
let mut parties = Vec::new();
|
let mut parties = Vec::new();
|
||||||
for party in &self.battle_setup.parties {
|
for party in &self.battle_setup.parties {
|
||||||
let pokemon = party
|
let pokemon = party
|
||||||
.pokemon
|
.pokemon
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| Some(Arc::new(a.to_pokemon(library))))
|
.map(|a| Some(Arc::new(a.to_pokemon(library.clone()))))
|
||||||
.collect();
|
.collect();
|
||||||
let indices = party.indices.iter().map(|a| (a[0], a[1])).collect();
|
let indices = party.indices.iter().map(|a| (a[0], a[1])).collect();
|
||||||
parties.push((Arc::new(PokemonParty::new_from_vec(pokemon)), indices));
|
parties.push((Arc::new(PokemonParty::new_from_vec(pokemon)), indices));
|
||||||
|
@ -73,7 +73,7 @@ impl TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestPokemon {
|
impl TestPokemon {
|
||||||
fn to_pokemon<'a>(&'a self, library: &'a DynamicLibrary) -> Pokemon {
|
fn to_pokemon(&self, library: Arc<DynamicLibrary>) -> Pokemon {
|
||||||
let mut builder = PokemonBuilder::new(library, StringKey::new(self.species.as_str()), self.level);
|
let mut builder = PokemonBuilder::new(library, StringKey::new(self.species.as_str()), self.level);
|
||||||
for move_name in &self.moves {
|
for move_name in &self.moves {
|
||||||
builder = builder.learn_move(StringKey::new(move_name));
|
builder = builder.learn_move(StringKey::new(move_name));
|
||||||
|
|
|
@ -16,16 +16,18 @@ use crate::common::{library_loader, TestCase};
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
|
||||||
static LIBRARY: OnceCell<DynamicLibrary> = OnceCell::uninit();
|
static LIBRARY: OnceCell<Arc<DynamicLibrary>> = OnceCell::uninit();
|
||||||
|
|
||||||
fn get_library<'a>() -> &'a DynamicLibrary {
|
fn get_library<'a>() -> Arc<DynamicLibrary> {
|
||||||
LIBRARY.get_or_init(|| {
|
LIBRARY
|
||||||
|
.get_or_init(|| {
|
||||||
let start_time = chrono::Utc::now();
|
let start_time = chrono::Utc::now();
|
||||||
let lib = library_loader::load_library();
|
let lib = library_loader::load_library();
|
||||||
let end_time = chrono::Utc::now();
|
let end_time = chrono::Utc::now();
|
||||||
println!("Built library in {} ms", (end_time - start_time).num_milliseconds());
|
println!("Built library in {} ms", (end_time - start_time).num_milliseconds());
|
||||||
lib
|
Arc::new(lib)
|
||||||
})
|
})
|
||||||
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -73,7 +75,7 @@ fn validate_script_2() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let user = Arc::new(
|
let user = Arc::new(
|
||||||
PokemonBuilder::new(&lib, "charizard".into(), 100)
|
PokemonBuilder::new(lib, "charizard".into(), 100)
|
||||||
.learn_move("fire_blast".into())
|
.learn_move("fire_blast".into())
|
||||||
.build(),
|
.build(),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue