mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
228 lines
7.5 KiB
Rust
228 lines
7.5 KiB
Rust
use crate::{
|
|
comp::buff::{BuffCategory, BuffData, BuffKind},
|
|
effect::{self, BuffEffect},
|
|
uid::Uid,
|
|
Damage, DamageSource, Explosion, GroupTarget, Knockback, RadiusEffect,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
use specs::{Component, FlaggedStorage};
|
|
use specs_idvs::IdvStorage;
|
|
use std::time::Duration;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub enum Effect {
|
|
Damage(Option<GroupTarget>, Damage),
|
|
Knockback(Knockback),
|
|
RewardEnergy(u32),
|
|
Explode(Explosion),
|
|
Vanish,
|
|
Stick,
|
|
Possess,
|
|
Buff {
|
|
buff: BuffEffect,
|
|
chance: Option<f32>,
|
|
},
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub struct Projectile {
|
|
// TODO: use SmallVec for these effects
|
|
pub hit_solid: Vec<Effect>,
|
|
pub hit_entity: Vec<Effect>,
|
|
/// Time left until the projectile will despawn
|
|
pub time_left: Duration,
|
|
pub owner: Option<Uid>,
|
|
/// Whether projectile collides with entities in the same group as its
|
|
/// owner
|
|
pub ignore_group: bool,
|
|
}
|
|
|
|
impl Component for Projectile {
|
|
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub enum ProjectileConstructor {
|
|
Arrow {
|
|
damage: f32,
|
|
knockback: f32,
|
|
energy_regen: u32,
|
|
},
|
|
Fireball {
|
|
damage: f32,
|
|
radius: f32,
|
|
energy_regen: u32,
|
|
},
|
|
Heal {
|
|
heal: f32,
|
|
damage: f32,
|
|
radius: f32,
|
|
},
|
|
Possess,
|
|
}
|
|
|
|
impl ProjectileConstructor {
|
|
pub fn create_projectile(self, owner: Option<Uid>) -> Projectile {
|
|
use ProjectileConstructor::*;
|
|
match self {
|
|
Arrow {
|
|
damage,
|
|
knockback,
|
|
energy_regen,
|
|
} => {
|
|
let buff = BuffEffect {
|
|
kind: BuffKind::Bleeding,
|
|
data: BuffData {
|
|
strength: damage / 2.0,
|
|
duration: Some(Duration::from_secs(5)),
|
|
},
|
|
cat_ids: vec![BuffCategory::Physical],
|
|
};
|
|
Projectile {
|
|
hit_solid: vec![Effect::Stick],
|
|
hit_entity: vec![
|
|
Effect::Damage(Some(GroupTarget::OutOfGroup), Damage {
|
|
source: DamageSource::Projectile,
|
|
value: damage,
|
|
}),
|
|
Effect::Knockback(Knockback::Away(knockback)),
|
|
Effect::RewardEnergy(energy_regen),
|
|
Effect::Vanish,
|
|
Effect::Buff {
|
|
buff,
|
|
chance: Some(0.10),
|
|
},
|
|
],
|
|
time_left: Duration::from_secs(15),
|
|
owner,
|
|
ignore_group: true,
|
|
}
|
|
},
|
|
Fireball {
|
|
damage,
|
|
radius,
|
|
energy_regen,
|
|
} => Projectile {
|
|
hit_solid: vec![
|
|
Effect::Explode(Explosion {
|
|
effects: vec![
|
|
RadiusEffect::Entity(
|
|
Some(GroupTarget::OutOfGroup),
|
|
effect::Effect::Damage(Damage {
|
|
source: DamageSource::Explosion,
|
|
value: damage,
|
|
}),
|
|
),
|
|
RadiusEffect::TerrainDestruction(2.0),
|
|
],
|
|
radius,
|
|
energy_regen,
|
|
}),
|
|
Effect::Vanish,
|
|
],
|
|
hit_entity: vec![
|
|
Effect::Explode(Explosion {
|
|
effects: vec![RadiusEffect::Entity(
|
|
Some(GroupTarget::OutOfGroup),
|
|
effect::Effect::Damage(Damage {
|
|
source: DamageSource::Explosion,
|
|
value: damage,
|
|
}),
|
|
)],
|
|
radius,
|
|
energy_regen,
|
|
}),
|
|
Effect::Vanish,
|
|
],
|
|
time_left: Duration::from_secs(20),
|
|
owner,
|
|
ignore_group: true,
|
|
},
|
|
Heal {
|
|
heal,
|
|
damage,
|
|
radius,
|
|
} => Projectile {
|
|
hit_solid: vec![
|
|
Effect::Explode(Explosion {
|
|
effects: vec![
|
|
RadiusEffect::Entity(
|
|
Some(GroupTarget::OutOfGroup),
|
|
effect::Effect::Damage(Damage {
|
|
source: DamageSource::Explosion,
|
|
value: damage,
|
|
}),
|
|
),
|
|
RadiusEffect::Entity(
|
|
Some(GroupTarget::InGroup),
|
|
effect::Effect::Damage(Damage {
|
|
source: DamageSource::Healing,
|
|
value: heal,
|
|
}),
|
|
),
|
|
],
|
|
radius,
|
|
energy_regen: 0,
|
|
}),
|
|
Effect::Vanish,
|
|
],
|
|
hit_entity: vec![
|
|
Effect::Explode(Explosion {
|
|
effects: vec![
|
|
RadiusEffect::Entity(
|
|
Some(GroupTarget::OutOfGroup),
|
|
effect::Effect::Damage(Damage {
|
|
source: DamageSource::Explosion,
|
|
value: damage,
|
|
}),
|
|
),
|
|
RadiusEffect::Entity(
|
|
Some(GroupTarget::InGroup),
|
|
effect::Effect::Damage(Damage {
|
|
source: DamageSource::Healing,
|
|
value: heal,
|
|
}),
|
|
),
|
|
],
|
|
radius,
|
|
energy_regen: 0,
|
|
}),
|
|
Effect::Vanish,
|
|
],
|
|
time_left: Duration::from_secs(20),
|
|
owner,
|
|
ignore_group: true,
|
|
},
|
|
Possess => Projectile {
|
|
hit_solid: vec![Effect::Stick],
|
|
hit_entity: vec![Effect::Stick, Effect::Possess],
|
|
time_left: Duration::from_secs(10),
|
|
owner,
|
|
ignore_group: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn modified_projectile(mut self, power: f32) -> Self {
|
|
use ProjectileConstructor::*;
|
|
match self {
|
|
Arrow { ref mut damage, .. } => {
|
|
*damage *= power;
|
|
},
|
|
Fireball { ref mut damage, .. } => {
|
|
*damage *= power;
|
|
},
|
|
Heal {
|
|
ref mut damage,
|
|
ref mut heal,
|
|
..
|
|
} => {
|
|
*damage *= power;
|
|
*heal *= power;
|
|
},
|
|
Possess => {},
|
|
}
|
|
self
|
|
}
|
|
}
|