Basic implementation of evolutions
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -65,6 +65,7 @@ pub mod tests {
|
||||
0.5,
|
||||
&"test_growthrate".into(),
|
||||
0,
|
||||
120,
|
||||
Arc::new(FormImpl::new(
|
||||
&"default".into(),
|
||||
0.0,
|
||||
@@ -78,6 +79,7 @@ pub mod tests {
|
||||
HashSet::new(),
|
||||
)),
|
||||
HashSet::new(),
|
||||
Vec::new(),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ mod time_of_day;
|
||||
/// A parameter for an effect. This is basically a simple way to dynamically store multiple different
|
||||
/// primitives on data.
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum EffectParameter {
|
||||
pub enum Parameter {
|
||||
/// A boolean value.
|
||||
Bool(bool),
|
||||
/// An integer value. Stored as a 64 bit int to deal with potentially large numbers.
|
||||
@@ -70,37 +70,37 @@ pub enum EffectParameter {
|
||||
String(StringKey),
|
||||
}
|
||||
|
||||
impl From<bool> for EffectParameter {
|
||||
impl From<bool> for Parameter {
|
||||
fn from(b: bool) -> Self {
|
||||
EffectParameter::Bool(b)
|
||||
Parameter::Bool(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for EffectParameter {
|
||||
impl From<i64> for Parameter {
|
||||
fn from(i: i64) -> Self {
|
||||
EffectParameter::Int(i)
|
||||
Parameter::Int(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for EffectParameter {
|
||||
impl From<f32> for Parameter {
|
||||
fn from(f: f32) -> Self {
|
||||
EffectParameter::Float(f)
|
||||
Parameter::Float(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StringKey> for EffectParameter {
|
||||
impl From<StringKey> for Parameter {
|
||||
fn from(s: StringKey) -> Self {
|
||||
EffectParameter::String(s)
|
||||
Parameter::String(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for EffectParameter {
|
||||
impl Display for Parameter {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
EffectParameter::Bool(v) => f.write_fmt(format_args!("EffectParameter::Bool({v})")),
|
||||
EffectParameter::Int(v) => f.write_fmt(format_args!("EffectParameter::Int({v})")),
|
||||
EffectParameter::Float(v) => f.write_fmt(format_args!("EffectParameter::Float({v})")),
|
||||
EffectParameter::String(v) => f.write_fmt(format_args!("EffectParameter::String({v})")),
|
||||
Parameter::Bool(v) => f.write_fmt(format_args!("EffectParameter::Bool({v})")),
|
||||
Parameter::Int(v) => f.write_fmt(format_args!("EffectParameter::Int({v})")),
|
||||
Parameter::Float(v) => f.write_fmt(format_args!("EffectParameter::Float({v})")),
|
||||
Parameter::String(v) => f.write_fmt(format_args!("EffectParameter::String({v})")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 SecondaryEffect: Debug {
|
||||
/// The name of the effect.
|
||||
fn effect_name(&self) -> &StringKey;
|
||||
/// A list of parameters for the effect.
|
||||
fn parameters(&self) -> &Vec<Arc<EffectParameter>>;
|
||||
fn parameters(&self) -> &Vec<Arc<Parameter>>;
|
||||
}
|
||||
|
||||
/// A secondary effect is an effect on a move that happens after it hits.
|
||||
@@ -21,12 +21,12 @@ pub struct SecondaryEffectImpl {
|
||||
/// The name of the effect.
|
||||
effect_name: StringKey,
|
||||
/// A list of parameters for the effect.
|
||||
parameters: Vec<Arc<EffectParameter>>,
|
||||
parameters: Vec<Arc<Parameter>>,
|
||||
}
|
||||
|
||||
impl SecondaryEffectImpl {
|
||||
/// Instantiates a new Secondary Effect.
|
||||
pub fn new(chance: f32, effect_name: StringKey, parameters: Vec<Arc<EffectParameter>>) -> Self {
|
||||
pub fn new(chance: f32, effect_name: StringKey, parameters: Vec<Arc<Parameter>>) -> Self {
|
||||
Self {
|
||||
chance,
|
||||
effect_name,
|
||||
@@ -45,7 +45,7 @@ impl SecondaryEffect for SecondaryEffectImpl {
|
||||
&self.effect_name
|
||||
}
|
||||
/// A list of parameters for the effect.
|
||||
fn parameters(&self) -> &Vec<Arc<EffectParameter>> {
|
||||
fn parameters(&self) -> &Vec<Arc<Parameter>> {
|
||||
&self.parameters
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ pub(crate) mod tests {
|
||||
impl SecondaryEffect for SecondaryEffect {
|
||||
fn chance(&self) -> f32;
|
||||
fn effect_name(&self) -> &StringKey;
|
||||
fn parameters(&self) -> &Vec<Arc<EffectParameter>>;
|
||||
fn parameters(&self) -> &Vec<Arc<Parameter >>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 >>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
118
src/static_data/species_data/evolution_data.rs
Normal file
118
src/static_data/species_data/evolution_data.rs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user