Remove lifetime mess, replace a lot of code with Arc instead of borrows.
Some checks failed
continuous-integration/drone/push Build is failing
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:
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user