-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Swap all existing powerup code over to using the effects system (#216)
* Add effects to MobPrototype * Add a new effect manager component * Add the new effect manager to the default component set * Refactor EffectPrototype in favour of PowerupPrototype * Rewrite effects component to use PowerupPrototype * Add a powerup prototype to the PlayerPowerup event * Add a speed modification effect * Add player powerup handler to add effects component * Add test for inferno behaviour * Remove speed effect * Add some helpers to effect component * Convert physics update to use effects component * Use effects within special * Use effect component as the source of truth for expiring powerups * Use effects within player missile collision handler * Convert main physics loop to use effects * Convert key handler to use effects * Convert get_server_upgrades to use effects * Remove logging within powerup expiry * Remove Powerups component and use effects everywhere
- Loading branch information
1 parent
2a27bc5
commit 691ff5a
Showing
24 changed files
with
420 additions
and
296 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,145 +1,65 @@ | ||
use std::borrow::Cow; | ||
use std::time::Duration; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::util::option_duration; | ||
use crate::ValidationError; | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
#[non_exhaustive] | ||
pub struct EffectPrototype { | ||
pub name: Cow<'static, str>, | ||
|
||
#[serde(with = "option_duration")] | ||
pub duration: Option<Duration>, | ||
|
||
#[serde(flatten)] | ||
pub data: EffectPrototypeData, | ||
#[serde(tag = "type", rename = "kebab-case")] | ||
pub enum EffectPrototype { | ||
Shield { | ||
damage_mult: f32, | ||
}, | ||
Inferno, | ||
FixedSpeed { | ||
speed: f32, | ||
}, | ||
Upgrade, | ||
/// Despawn the mob that just collided. | ||
Despawn, | ||
} | ||
|
||
impl EffectPrototype { | ||
pub const fn shield() -> Self { | ||
Self { | ||
name: Cow::Borrowed("shield"), | ||
duration: Some(Duration::from_secs(10)), | ||
data: EffectPrototypeData::Shield(ShieldEffectPrototype { damage_mult: 0.0 }), | ||
} | ||
} | ||
|
||
pub const fn spawn_shield() -> Self { | ||
Self { | ||
name: Cow::Borrowed("spawn-shield"), | ||
duration: Some(Duration::from_secs(2)), | ||
data: EffectPrototypeData::Shield(ShieldEffectPrototype { damage_mult: 0.0 }), | ||
} | ||
} | ||
|
||
pub const fn invulnerable() -> Self { | ||
Self { | ||
name: Cow::Borrowed("invulnerable"), | ||
duration: None, | ||
data: EffectPrototypeData::Shield(ShieldEffectPrototype { damage_mult: 0.0 }), | ||
} | ||
Self::Shield { damage_mult: 0.0 } | ||
} | ||
|
||
pub const fn inferno() -> Self { | ||
Self { | ||
name: Cow::Borrowed("inferno"), | ||
duration: Some(Duration::from_secs(10)), | ||
data: EffectPrototypeData::Inferno, | ||
} | ||
Self::Inferno | ||
} | ||
|
||
pub const fn flag_speed() -> Self { | ||
Self { | ||
name: Cow::Borrowed("flag-speed"), | ||
duration: None, | ||
data: EffectPrototypeData::FixedSpeed(FixedSpeedEffectPrototype { speed: 5.0 }), | ||
} | ||
Self::FixedSpeed { speed: 5.0 } | ||
} | ||
|
||
pub const fn upgrade() -> Self { | ||
Self { | ||
name: Cow::Borrowed("upgrade"), | ||
duration: None, | ||
data: EffectPrototypeData::Upgrade, | ||
} | ||
Self::Upgrade | ||
} | ||
|
||
pub const fn despawn() -> Self { | ||
Self::Despawn | ||
} | ||
} | ||
|
||
impl EffectPrototype { | ||
pub const fn is_shield(&self) -> bool { | ||
matches!(self.data, EffectPrototypeData::Shield(_)) | ||
} | ||
|
||
pub const fn as_shield(&self) -> Option<&ShieldEffectPrototype> { | ||
match &self.data { | ||
EffectPrototypeData::Shield(shield) => Some(shield), | ||
_ => None, | ||
} | ||
matches!(self, Self::Shield { .. }) | ||
} | ||
|
||
pub const fn is_inferno(&self) -> bool { | ||
matches!(self.data, EffectPrototypeData::Inferno) | ||
matches!(self, Self::Inferno) | ||
} | ||
|
||
pub const fn is_fixed_speed(&self) -> bool { | ||
matches!(self.data, EffectPrototypeData::FixedSpeed(_)) | ||
} | ||
|
||
pub const fn as_fixed_speed(&self) -> Option<&FixedSpeedEffectPrototype> { | ||
match &self.data { | ||
EffectPrototypeData::FixedSpeed(speed) => Some(speed), | ||
_ => None, | ||
} | ||
matches!(self, Self::FixedSpeed { .. }) | ||
} | ||
|
||
pub const fn is_upgrade(&self) -> bool { | ||
matches!(self.data, EffectPrototypeData::Upgrade) | ||
matches!(self, Self::Upgrade) | ||
} | ||
} | ||
|
||
impl EffectPrototype { | ||
pub(crate) fn resolve(self) -> Result<Self, ValidationError> { | ||
if self.name.is_empty() { | ||
return Err(ValidationError::custom("name", "prototype had empty name")); | ||
} | ||
|
||
Ok(self) | ||
pub const fn is_despawn(&self) -> bool { | ||
matches!(self, Self::Despawn) | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
#[non_exhaustive] | ||
#[serde(tag = "type", rename = "kebab-case")] | ||
pub enum EffectPrototypeData { | ||
Shield(ShieldEffectPrototype), | ||
Inferno, | ||
FixedSpeed(FixedSpeedEffectPrototype), | ||
Upgrade, | ||
} | ||
|
||
/// Effect that modifies the amount of damage done to a plane when it is hit by | ||
/// a missile. | ||
/// | ||
/// This is named after the shield (which sets all damage to 0) but can be used | ||
/// for any effect that needs to modify the damage taken by a plane. If multiple | ||
/// instances of this effect are present the all the damage multipliers will be | ||
/// applied. | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)] | ||
#[non_exhaustive] | ||
pub struct ShieldEffectPrototype { | ||
pub damage_mult: f32, | ||
} | ||
|
||
/// Effect that sets a plane's speed to a fixed value. | ||
/// | ||
/// This is used for the flag speed effect in CTF and will set the corresponding | ||
/// bit in the keystate. Note that setting the speed to anything other than 5 | ||
/// will cause client desyncs unless the client has been modified as well. | ||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)] | ||
#[non_exhaustive] | ||
pub struct FixedSpeedEffectPrototype { | ||
pub speed: f32, | ||
pub const fn is_instant(&self) -> bool { | ||
matches!(self, Self::Upgrade | Self::Despawn) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.