Basic implementation of evolutions
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-07-29 12:57:52 +02:00
parent 3f91f80982
commit d8b8559c2e
25 changed files with 437 additions and 115 deletions

View File

@@ -1,4 +1,4 @@
use crate::static_data::EffectParameter;
use crate::static_data::Parameter;
use crate::StringKey;
use std::fmt::Debug;
use std::sync::Arc;
@@ -10,7 +10,7 @@ pub trait Ability: Debug {
/// The name of the script effect of the ability.
fn effect(&self) -> &StringKey;
/// The parameters for the script effect of the ability.
fn parameters(&self) -> &Vec<Arc<EffectParameter>>;
fn parameters(&self) -> &Vec<Arc<Parameter>>;
}
/// An ability is a passive effect in battle that is attached to a Pokemon.
@@ -21,12 +21,12 @@ pub struct AbilityImpl {
/// The name of the script effect of the ability.
effect: StringKey,
/// The parameters for the script effect of the ability.
parameters: Vec<Arc<EffectParameter>>,
parameters: Vec<Arc<Parameter>>,
}
impl AbilityImpl {
/// Instantiates a new ability.
pub fn new(name: &StringKey, effect: &StringKey, parameters: Vec<Arc<EffectParameter>>) -> Self {
pub fn new(name: &StringKey, effect: &StringKey, parameters: Vec<Arc<Parameter>>) -> Self {
Self {
name: name.clone(),
effect: effect.clone(),
@@ -45,7 +45,7 @@ impl Ability for AbilityImpl {
&self.effect
}
/// The parameters for the script effect of the ability.
fn parameters(&self) -> &Vec<Arc<EffectParameter>> {
fn parameters(&self) -> &Vec<Arc<Parameter>> {
&self.parameters
}
}
@@ -74,7 +74,7 @@ pub(crate) mod tests {
impl Ability for Ability {
fn name(&self) -> &StringKey;
fn effect(&self) -> &StringKey;
fn parameters(&self) -> &Vec<Arc<EffectParameter>>;
fn parameters(&self) -> &Vec<Arc<Parameter >>;
}
}
}

View File

@@ -0,0 +1,118 @@
use crate::defines::LevelInt;
use crate::static_data::{Gender, Parameter};
use crate::StringKey;
use std::sync::Arc;
/// The different ways a Pokemon can evolve.
#[derive(Debug)]
pub enum EvolutionMethod {
/// Evolves when a certain level is reached.
Level {
/// The level at which the Pokemon evolves.
level: LevelInt,
},
/// Evolves when a certain level is reached, and the Pokemon is a specific gender.
LevelGender {
/// The level at which the Pokemon evolves.
level: LevelInt,
/// The gender the Pokemon needs to be.
gender: Gender,
},
/// Evolves when an item is used.
Item {
/// The item that needs to be used.
item: StringKey,
},
/// Evolves when an item is used, and the Pokemon is a specific gender.
ItemGender {
/// The item that needs to be used.
item: StringKey,
/// The gender the Pokemon needs to be.
gender: Gender,
},
/// Evolves if an item is held.
HoldItem {
/// The item that needs to be held.
item: StringKey,
},
/// Evolves if a held item is held, and it's day.
DayHoldItem {
/// The item that needs to be held.
item: StringKey,
},
/// Evolves if a held item is held, and it's night.
NightHoldItem {
/// The item that needs to be held.
item: StringKey,
},
/// Evolves if the Pokemon knows a certain move.
HasMove {
/// The move that needs to be known.
move_name: StringKey,
},
/// Evolves when above a certain happiness level.
Happiness {
/// The happiness level that needs to be reached.
happiness: u8,
},
/// Evolves when above a certain happiness level, and it's day.
HappinessDay {
/// The happiness level that needs to be reached.
happiness: u8,
},
/// Evolves when above a certain happiness level, and it's night.
HappinessNight {
/// The happiness level that needs to be reached.
happiness: u8,
},
/// Evolves when traded.
Trade,
/// Evolves when traded with a certain species.
TradeSpecies {
/// The species that needs to be traded with.
species: StringKey,
},
/// Evolves when traded while it's holding a certain item.
TradeItem {
/// The item that needs to be held.
item: StringKey,
},
/// Evolves in a certain location.
Location {
/// The location the Pokemon needs to be in.
location: StringKey,
},
/// A custom evolution method, implemented by the user.
Custom {
/// The name of the custom evolution method.
name: StringKey,
/// The parameters of the custom evolution method.
params: Vec<Arc<Parameter>>,
},
}
#[derive(Debug)]
/// Data about how and into which Pokemon a species can evolve.
pub struct EvolutionData {
/// The method of evolution.
method: EvolutionMethod,
/// The Pokemon the species evolves into.
to: StringKey,
}
impl EvolutionData {
/// Creates a new evolution data instance.
pub fn new(method: EvolutionMethod, to: StringKey) -> Self {
Self { method, to }
}
/// Returns the method of evolution.
pub fn method(&self) -> &EvolutionMethod {
&self.method
}
/// Returns the Pokemon the species evolves into.
pub fn to(&self) -> &StringKey {
&self.to
}
}

View File

@@ -1,6 +1,8 @@
#[doc(inline)]
pub use ability::*;
#[doc(inline)]
pub use evolution_data::*;
#[doc(inline)]
pub use form::*;
#[doc(inline)]
pub use gender::*;
@@ -19,6 +21,8 @@ pub(crate) mod tests {
/// An ability is a passive effect in battle that is attached to a Pokemon.
mod ability;
/// Data regarding into which Pokemon a species can evolve.
mod evolution_data;
/// A form is a variant of a specific species. A species always has at least one form, but can have
/// many more.
mod form;

View File

@@ -6,6 +6,7 @@ use hashbrown::{HashMap, HashSet};
use parking_lot::lock_api::RwLockReadGuard;
use parking_lot::{RawRwLock, RwLock};
use crate::static_data::species_data::evolution_data::EvolutionData;
use crate::static_data::Form;
use crate::static_data::Gender;
use crate::Random;
@@ -24,6 +25,8 @@ pub trait Species: Debug {
/// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is
/// uncatchable.
fn capture_rate(&self) -> u8;
/// The base happiness of the Pokemon.
fn base_happiness(&self) -> u8;
/// The forms that belong to this Pokemon.
fn forms(&self) -> RwLockReadGuard<'_, RawRwLock, HashMap<StringKey, Arc<dyn Form>>>;
/// The arbitrary flags that can be set on a Pokemon for script use.
@@ -42,6 +45,8 @@ pub trait Species: Debug {
fn has_flag(&self, key: &StringKey) -> bool;
/// Check whether the Pokemon has a specific flag set.
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
/// The data regarding into which Pokemons this species can evolve, and how.
fn evolution_data(&self) -> &Vec<EvolutionData>;
}
/// The data belonging to a Pokemon with certain characteristics.
@@ -58,10 +63,14 @@ pub struct SpeciesImpl {
/// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is
/// uncatchable.
capture_rate: u8,
/// The base happiness of the Pokemon.
base_happiness: u8,
/// The forms that belong to this Pokemon.
forms: RwLock<HashMap<StringKey, Arc<dyn Form>>>,
/// The arbitrary flags that can be set on a Pokemon for script use.
flags: HashSet<StringKey>,
/// The data regarding into which Pokemons this species can evolve, and how.
evolution_data: Vec<EvolutionData>,
}
/// A cached String Key to get the default form.
@@ -80,8 +89,10 @@ impl SpeciesImpl {
gender_rate: f32,
growth_rate: &StringKey,
capture_rate: u8,
base_happiness: u8,
default_form: Arc<dyn Form>,
flags: HashSet<StringKey>,
evolution_data: Vec<EvolutionData>,
) -> Self {
let mut forms = HashMap::with_capacity(1);
forms.insert_unique_unchecked(get_default_key(), default_form);
@@ -91,8 +102,10 @@ impl SpeciesImpl {
gender_rate,
growth_rate: growth_rate.clone(),
capture_rate,
base_happiness,
forms: RwLock::new(forms),
flags,
evolution_data,
}
}
}
@@ -119,6 +132,11 @@ impl Species for SpeciesImpl {
fn capture_rate(&self) -> u8 {
self.capture_rate
}
fn base_happiness(&self) -> u8 {
self.base_happiness
}
/// The forms that belong to this Pokemon.
fn forms(&self) -> RwLockReadGuard<'_, RawRwLock, HashMap<StringKey, Arc<dyn Form>>> {
self.forms.read()
@@ -171,6 +189,10 @@ impl Species for SpeciesImpl {
fn has_flag_by_hash(&self, key_hash: u32) -> bool {
self.flags.contains::<u32>(&key_hash)
}
fn evolution_data(&self) -> &Vec<EvolutionData> {
&self.evolution_data
}
}
#[cfg(test)]
@@ -188,6 +210,7 @@ pub(crate) mod tests {
fn gender_rate(&self) -> f32;
fn growth_rate(&self) -> &StringKey;
fn capture_rate(&self) -> u8;
fn base_happiness(&self) -> u8;
fn forms(&self) -> RwLockReadGuard<'_, RawRwLock, HashMap<StringKey, Arc<dyn Form>>>;
fn flags(&self) -> &HashSet<StringKey>;
fn add_form(&self, id: StringKey, form: Arc<dyn Form>);
@@ -197,6 +220,7 @@ pub(crate) mod tests {
fn get_random_gender(&self, rand: &mut Random) -> Gender;
fn has_flag(&self, key: &StringKey) -> bool;
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
fn evolution_data(&self) -> &Vec<EvolutionData>;
}
}
}