Remove lifetime mess, replace a lot of code with Arc instead of borrows.
Some checks failed
continuous-integration/drone/push Build is failing

This cleans up the codebase massively, and allows me to maintain some semblance of sanity.
This commit is contained in:
2022-08-20 13:17:20 +02:00
parent 2d4253e155
commit 55cc0906c9
34 changed files with 320 additions and 366 deletions

View File

@@ -22,11 +22,11 @@ use crate::{script_hook, PkmnResult, StringKey};
/// A pokemon battle, with any amount of sides and pokemon per side.
#[derive(Debug)]
pub struct Battle<'own, 'library> {
pub struct Battle {
/// The library the battle uses for handling.
library: &'own DynamicLibrary,
library: Arc<DynamicLibrary>,
/// 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.
can_flee: bool,
/// 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.
pokemon_per_side: u8,
/// A list of all sides in the battle.
sides: Vec<BattleSide<'own, 'library>>,
sides: Vec<BattleSide>,
/// The RNG used for the battle.
random: BattleRandom,
/// 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.
has_ended: AtomicBool,
/// 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>,
}
impl<'own, 'library> Battle<'own, 'library> {
impl<'own, 'library> Battle {
/// Initializes a new battle.
pub fn new(
library: &'own DynamicLibrary,
parties: Vec<BattleParty<'own, 'library>>,
library: Arc<DynamicLibrary>,
parties: Vec<BattleParty>,
can_flee: bool,
number_of_sides: u8,
pokemon_per_side: u8,
@@ -104,11 +104,11 @@ impl<'own, 'library> Battle<'own, 'library> {
}
/// The library the battle uses for handling.
pub fn library(&self) -> &'own DynamicLibrary {
self.library
pub fn library(&self) -> &Arc<DynamicLibrary> {
&self.library
}
/// 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
}
/// Whether or not Pokemon can flee from the battle.
@@ -124,11 +124,11 @@ impl<'own, 'library> Battle<'own, 'library> {
self.pokemon_per_side
}
/// A list of all sides in the battle.
pub fn sides(&self) -> &Vec<BattleSide<'own, 'library>> {
pub fn sides(&self) -> &Vec<BattleSide> {
&self.sides
}
/// 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
}
/// The RNG used for the battle.
@@ -156,12 +156,12 @@ impl<'own, 'library> Battle<'own, 'library> {
self.last_turn_time.load(Ordering::Relaxed)
}
/// 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
}
/// 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);
side?;
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.
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) {
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> {
&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 {
1
}

View File

@@ -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
/// on the field attached.
#[derive(Debug)]
pub struct BattleParty<'own, 'library> {
pub struct BattleParty {
/// 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)
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
/// 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 {
party,
responsible_indices,
@@ -44,7 +44,7 @@ impl<'own, 'library> BattleParty<'own, 'library> {
}
/// 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)
}
}

View File

@@ -18,22 +18,22 @@ use crate::{script_hook, PkmnResult, StringKey};
/// A side on a battle.
#[derive(Debug)]
pub struct BattleSide<'own, 'library> {
pub struct BattleSide {
/// The index of the side on the battle.
index: u8,
/// The number of Pokemon that can be on the side.
pokemon_per_side: u8,
/// 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.
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
/// has lost the battle.
fillable_slots: Vec<AtomicBool>,
/// The number of choices that are set.
choices_set: AtomicU8,
/// A reference to the battle we're part of.
battle: *mut Battle<'own, 'library>,
battle: *mut Battle,
/// Whether or not this side has fled.
has_fled_battle: bool,
/// The volatile scripts that are attached to the side.
@@ -43,7 +43,7 @@ pub struct BattleSide<'own, 'library> {
script_source_data: RwLock<ScriptSourceData>,
}
impl<'own, 'library> BattleSide<'own, 'library> {
impl<'own, 'library> BattleSide {
/// Instantiates a battle side.
pub fn new(index: u8, pokemon_per_side: u8) -> Self {
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.
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;
}
@@ -86,11 +86,11 @@ impl<'own, 'library> BattleSide<'own, 'library> {
self.pokemon_per_side
}
/// 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()
}
/// 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
}
/// 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)
}
/// 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() }
}
/// 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.
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() {
if let Some(pokemon) = pokemon_slot {
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.
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];
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.
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() {
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
return true;
@@ -218,7 +218,7 @@ impl<'own, 'library> BattleSide<'own, 'library> {
}
/// 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() {
if let Some(p) = slot {
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> {
&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 {
self.battle().get_script_count() + 1
}

View File

@@ -84,34 +84,34 @@ impl HitData {
/// An executing move is the data of the move for while it is executing.
#[derive(Debug)]
pub struct ExecutingMove<'own, 'battle, 'library> {
pub struct ExecutingMove {
/// The number of hits this move has.
number_of_hits: u8,
/// 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.
hits: Vec<HitData>,
/// The user of the move.
user: Arc<Pokemon<'battle, 'library>>,
user: Arc<Pokemon>,
/// 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.
use_move: &'own MoveData,
use_move: Arc<MoveData>,
/// The script of the move.
script: ScriptContainer,
/// The targets for this move.
targets: &'own TargetList<'battle, 'library>,
targets: TargetList,
/// Data required for this to be a script source.
script_source_data: RwLock<ScriptSourceData>,
}
impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> {
impl ExecutingMove {
/// Instantiates an executing move.
pub fn new(
targets: &'own TargetList<'battle, 'library>,
targets: TargetList,
number_of_hits: u8,
user: Arc<Pokemon<'battle, 'library>>,
chosen_move: Arc<LearnedMove<'library>>,
use_move: &'own MoveData,
user: Arc<Pokemon>,
chosen_move: Arc<LearnedMove>,
use_move: Arc<MoveData>,
script: ScriptContainer,
) -> Self {
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
}
/// The user of the move.
pub fn user(&self) -> &Arc<Pokemon<'battle, 'library>> {
pub fn user(&self) -> &Arc<Pokemon> {
&self.user
}
/// 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
}
/// The move that the user is actually going to do.
pub fn use_move(&self) -> &'own MoveData {
self.use_move
pub fn use_move(&self) -> &Arc<MoveData> {
&self.use_move
}
/// The script of the move.
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.
pub fn get_hit_data<'func>(
&'func self,
for_target: &'func Arc<Pokemon<'battle, 'library>>,
hit: u8,
) -> PkmnResult<&'func HitData> {
pub fn get_hit_data<'func>(&'func self, for_target: &'func Arc<Pokemon>, hit: u8) -> PkmnResult<&'func HitData> {
for (index, target) in self.targets.iter().enumerate() {
if let Some(target) = target {
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.
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() {
if std::ptr::eq(target.deref().deref(), pokemon.deref().deref()) {
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.
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() {
if let Some(target) = target {
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 {
1
}

View File

@@ -1,4 +1,5 @@
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
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.
#[derive(Debug)]
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
pub struct LearnedMove<'library> {
pub struct LearnedMove {
/// The immutable move information of the move.
move_data: &'library MoveData,
move_data: Arc<MoveData>,
/// The maximal power points for this move.
max_pp: u8,
/// 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,
}
impl<'a> LearnedMove<'a> {
impl LearnedMove {
/// 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 {
move_data,
move_data: move_data.clone(),
max_pp: move_data.base_usages(),
remaining_pp: AtomicU8::new(move_data.base_usages()),
learn_method,
@@ -40,8 +41,8 @@ impl<'a> LearnedMove<'a> {
}
/// The immutable move information of the move.
pub fn move_data(&self) -> &MoveData {
self.move_data
pub fn move_data(&self) -> &Arc<MoveData> {
&self.move_data
}
/// The maximal power points for this move.
pub fn max_pp(&self) -> u8 {

View File

@@ -26,23 +26,20 @@ use crate::{script_hook, PkmnResult, StringKey};
/// An individual Pokemon as we know and love them.
#[derive(Debug)]
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
pub struct Pokemon<'own, 'library>
where
'own: 'library,
{
pub struct Pokemon {
/// The library data of the Pokemon.
library: &'own DynamicLibrary,
library: Arc<DynamicLibrary>,
/// The species of the Pokemon.
species: &'own Species,
species: Arc<Species>,
/// 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
/// 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
// 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.
level: LevelInt,
@@ -57,7 +54,7 @@ where
/// currently not used, and can be used for other implementations.
coloring: u8,
/// 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.
current_health: AtomicU32,
@@ -78,7 +75,7 @@ where
/// The [effort values](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
effort_values: ClampedStatisticSet<u8, 0, 252>,
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
nature: &'own Nature,
nature: Arc<Nature>,
/// An optional nickname of the Pokemon.
nickname: Option<String>,
@@ -90,11 +87,11 @@ where
override_ability: Option<Ability>,
/// 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
/// 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.
allowed_experience: bool,
@@ -118,12 +115,12 @@ where
script_source_data: RwLock<ScriptSourceData>,
}
impl<'own, 'library> Pokemon<'own, 'library> {
impl Pokemon {
/// Instantiates a new Pokemon.
pub fn new(
library: &'own DynamicLibrary,
species: &'own Species,
form: &'own Form,
library: Arc<DynamicLibrary>,
species: Arc<Species>,
form: &Arc<Form>,
ability: AbilityIndex,
level: LevelInt,
unique_identifier: u32,
@@ -142,11 +139,12 @@ impl<'own, 'library> Pokemon<'own, 'library> {
.static_data()
.natures()
.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 {
library,
species,
form,
form: form.clone(),
display_species: None,
display_form: None,
level,
@@ -187,31 +185,31 @@ impl<'own, 'library> Pokemon<'own, 'library> {
}
/// The library data of the Pokemon.
pub fn library(&self) -> &'own DynamicLibrary {
self.library
pub fn library(&self) -> &Arc<DynamicLibrary> {
&self.library
}
/// The species of the Pokemon.
pub fn species(&self) -> &'own Species {
self.species
pub fn species(&self) -> &Arc<Species> {
&self.species
}
/// The form of the Pokemon.
pub fn form(&self) -> &'own Form {
self.form
pub fn form(&self) -> &Arc<Form> {
&self.form
}
/// The species that should be displayed to the user. This handles stuff like the Illusion ability.
pub fn display_species(&self) -> &'own Species {
if let Some(v) = self.display_species {
pub fn display_species(&self) -> &Arc<Species> {
if let Some(v) = &self.display_species {
v
} else {
self.species
&self.species
}
}
/// The form that should be displayed to the user. This handles stuff like the Illusion ability.
pub fn display_form(&self) -> &'own Form {
if let Some(v) = self.display_form {
pub fn display_form(&self) -> &Arc<Form> {
if let Some(v) = &self.display_form {
v
} else {
self.form
&self.form
}
}
/// The current level of the Pokemon.
@@ -235,8 +233,8 @@ impl<'own, 'library> Pokemon<'own, 'library> {
pub fn coloring(&self) -> u8 {
self.coloring
}
/// Checks whether the Pokemon is holding an item,
pub fn held_item(&self) -> &RwLock<Option<&'own Item>> {
/// Gets the held item of a Pokemon
pub fn held_item(&self) -> &RwLock<Option<Arc<Item>>> {
&self.held_item
}
/// Checks whether the Pokemon is holding a specific item.
@@ -248,11 +246,11 @@ impl<'own, 'library> Pokemon<'own, 'library> {
false
}
/// Changes the held item of the Pokemon/
pub fn set_held_item(&self, item: &'own Item) -> Option<&'own Item> {
self.held_item.write().replace(item)
pub fn set_held_item(&self, item: &Arc<Item>) -> Option<Arc<Item>> {
self.held_item.write().replace(item.clone())
}
/// 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()
}
/// Makes the Pokemon uses its held item.
@@ -260,7 +258,10 @@ impl<'own, 'library> Pokemon<'own, 'library> {
if self.held_item.read().is_none() {
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() {
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
/// 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
}
@@ -384,7 +385,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
}
/// 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();
if let Some(data) = &r.deref() {
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.
pub fn nature(&self) -> &'own Nature {
self.nature
pub fn nature(&self) -> &Arc<Nature> {
&self.nature
}
/// Calculates the flat stats on the Pokemon.
@@ -453,9 +454,9 @@ impl<'own, 'library> Pokemon<'own, 'library> {
}
/// Change the species of the Pokemon.
pub fn change_species(&mut self, species: &'own Species, form: &'own Form) {
self.species = species;
self.form = form;
pub fn change_species(&mut self, species: Arc<Species>, form: Arc<Form>) {
self.species = species.clone();
self.form = form.clone();
// 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 {
@@ -486,11 +487,11 @@ impl<'own, 'library> Pokemon<'own, 'library> {
}
/// Change the form of the Pokemon.
pub fn change_form(&mut self, form: &'own Form) {
if std::ptr::eq(self.form, form) {
pub fn change_form(&mut self, form: &Arc<Form>) {
if Arc::ptr_eq(&self.form, form) {
return;
}
self.form = form;
self.form = form.clone();
self.types.clear();
for t in form.types() {
@@ -512,7 +513,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
.set(ability_script)
.as_ref()
// 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 {
self.ability_script.clear();
}
@@ -547,7 +548,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
}
/// 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();
if let Some(battle_data) = w.deref_mut() {
battle_data.battle = battle;
@@ -590,7 +591,7 @@ impl<'own, 'library> Pokemon<'own, 'library> {
}
/// 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();
if let Some(battle_data) = &r.deref() {
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.
#[derive(Debug)]
pub struct PokemonBattleData<'pokemon, 'library> {
pub struct PokemonBattleData {
/// The battle data of the Pokemon
battle: *mut Battle<'pokemon, 'library>,
battle: *mut Battle,
/// The index of the side of the Pokemon
battle_side_index: AtomicU8,
/// 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.
on_battle_field: AtomicBool,
/// 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
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() }
}
/// 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() }
}
@@ -728,12 +729,12 @@ impl<'pokemon, 'library> PokemonBattleData<'pokemon, 'library> {
self.on_battle_field.load(Ordering::Relaxed)
}
/// 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
}
}
impl<'own, 'library> ScriptSource<'own> for Pokemon<'own, 'library> {
impl ScriptSource for Pokemon {
fn get_script_count(&self) -> usize {
let mut c = 3;
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> {
&self.volatile
}
@@ -794,7 +795,7 @@ pub mod test {
#[test]
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 form = species.get_form(&"default".into()).unwrap();

View File

@@ -1,3 +1,5 @@
use std::sync::Arc;
use crate::defines::LevelInt;
use crate::dynamic_data::models::learned_move::MoveLearnMethod;
use crate::dynamic_data::models::pokemon::Pokemon;
@@ -6,9 +8,9 @@ use crate::static_data::{AbilityIndex, DataLibrary, Gender};
use crate::{Random, StringKey};
/// This allows for the easy chain building of a Pokemon.
pub struct PokemonBuilder<'own> {
pub struct PokemonBuilder {
/// The library of the Pokemon.
library: &'own DynamicLibrary,
library: Arc<DynamicLibrary>,
/// The name of the species of the Pokemon.
species: StringKey,
/// The level of the Pokemon.
@@ -19,9 +21,9 @@ pub struct PokemonBuilder<'own> {
random_seed: Option<u128>,
}
impl<'own> PokemonBuilder<'own> {
impl PokemonBuilder {
/// 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 {
library,
species,
@@ -37,19 +39,19 @@ impl<'own> PokemonBuilder<'own> {
}
/// 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 {
Random::new(seed)
} else {
Random::default()
};
let species = self.library.static_data().species().get(&self.species).unwrap();
let form = species.get_default_form();
let species = self.library.static_data().species().get(&self.species).unwrap().clone();
let form = species.get_default_form().clone();
let p = Pokemon::new(
self.library,
species,
form,
&form,
AbilityIndex {
hidden: false,
index: 0,

View File

@@ -4,12 +4,12 @@ use crate::dynamic_data::models::pokemon::Pokemon;
/// A list of Pokemon belonging to a trainer.
#[derive(Debug)]
pub struct PokemonParty<'pokemon, 'library> {
pub struct PokemonParty {
/// 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.
pub fn new(size: usize) -> Self {
let mut pokemon = Vec::with_capacity(size);
@@ -20,12 +20,12 @@ impl<'own, 'library> PokemonParty<'own, 'library> {
}
/// 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 }
}
/// 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);
if let Some(v) = opt {
v
@@ -40,11 +40,7 @@ impl<'own, 'library> PokemonParty<'own, 'library> {
}
/// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon.
pub fn swap_into(
&mut self,
index: usize,
pokemon: Option<Arc<Pokemon<'own, 'library>>>,
) -> Option<Arc<Pokemon<'own, 'library>>> {
pub fn swap_into(&mut self, index: usize, pokemon: Option<Arc<Pokemon>>) -> Option<Arc<Pokemon>> {
if index >= self.pokemon.len() {
return pokemon;
}
@@ -69,7 +65,7 @@ impl<'own, 'library> PokemonParty<'own, 'library> {
}
/// 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
}