mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Beams now use Attack, with limited functionality in some cases.
This commit is contained in:
parent
59ce8c6843
commit
fdef168e82
@ -28,7 +28,7 @@ pub enum GroupTarget {
|
||||
OutOfGroup,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)] // TODO: Yeet clone derive
|
||||
pub struct Attack {
|
||||
damages: Vec<DamageComponent>,
|
||||
effects: Vec<EffectComponent>,
|
||||
@ -177,7 +177,7 @@ impl Attack {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct DamageComponent {
|
||||
damage: Damage,
|
||||
target: Option<GroupTarget>,
|
||||
@ -199,7 +199,7 @@ impl DamageComponent {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct EffectComponent {
|
||||
target: Option<GroupTarget>,
|
||||
effect: AttackEffect,
|
||||
@ -221,7 +221,7 @@ impl EffectComponent {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum AttackEffect {
|
||||
//Heal(f32),
|
||||
Buff(CombatBuff),
|
||||
@ -230,12 +230,12 @@ pub enum AttackEffect {
|
||||
//Lifesteal(f32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum CombatRequirement {
|
||||
AnyDamage,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum DamageSource {
|
||||
Buff(BuffKind),
|
||||
Melee,
|
||||
|
@ -1,22 +1,23 @@
|
||||
use crate::{uid::Uid, Damage, GroupTarget};
|
||||
use crate::{combat::Attack, uid::Uid};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Properties {
|
||||
pub attack: Attack,
|
||||
pub angle: f32,
|
||||
pub speed: f32,
|
||||
pub damages: Vec<(Option<GroupTarget>, Damage)>,
|
||||
pub lifesteal_eff: f32,
|
||||
pub energy_regen: u32,
|
||||
pub energy_cost: u32,
|
||||
//pub lifesteal_eff: f32,
|
||||
//pub energy_regen: u32,
|
||||
//pub energy_cost: u32,
|
||||
pub duration: Duration,
|
||||
pub owner: Option<Uid>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
// TODO: Separate components out for cheaper network syncing
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct BeamSegment {
|
||||
pub properties: Properties,
|
||||
#[serde(skip)]
|
||||
|
@ -21,10 +21,10 @@ pub enum Effect {
|
||||
Vanish,
|
||||
Stick,
|
||||
Possess,
|
||||
/*Buff {
|
||||
* buff: BuffEffect,
|
||||
* chance: Option<f32>, */
|
||||
/* */
|
||||
/* Buff {
|
||||
* buff: BuffEffect,
|
||||
* chance: Option<f32>,
|
||||
* }, */
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -4,7 +4,7 @@ use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Properties {
|
||||
pub angle: f32,
|
||||
pub vertical_angle: f32,
|
||||
@ -16,7 +16,7 @@ pub struct Properties {
|
||||
pub owner: Option<Uid>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Shockwave {
|
||||
pub properties: Properties,
|
||||
#[serde(skip)]
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{
|
||||
combat::{
|
||||
Attack, AttackEffect, CombatRequirement, Damage, DamageComponent, DamageSource,
|
||||
EffectComponent, GroupTarget,
|
||||
},
|
||||
comp::{beam, Body, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate},
|
||||
event::ServerEvent,
|
||||
states::{
|
||||
@ -6,7 +10,6 @@ use crate::{
|
||||
utils::*,
|
||||
},
|
||||
uid::Uid,
|
||||
Damage, DamageSource, GroupTarget,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -129,16 +132,17 @@ impl CharacterBehavior for Data {
|
||||
};
|
||||
let speed =
|
||||
self.static_data.range / self.static_data.beam_duration.as_secs_f32();
|
||||
|
||||
let energy = AttackEffect::EnergyReward(self.static_data.energy_regen);
|
||||
let energy = EffectComponent::new(None, energy)
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup));
|
||||
let attack = Attack::default().with_damage(damage).with_effect(energy);
|
||||
|
||||
let properties = beam::Properties {
|
||||
attack,
|
||||
angle: self.static_data.max_angle.to_radians(),
|
||||
speed,
|
||||
damages: vec![
|
||||
(Some(GroupTarget::OutOfGroup), damage),
|
||||
(Some(GroupTarget::InGroup), heal),
|
||||
],
|
||||
lifesteal_eff: self.static_data.lifesteal_eff,
|
||||
energy_regen: self.static_data.energy_regen,
|
||||
energy_cost: self.static_data.energy_cost,
|
||||
duration: self.static_data.beam_duration,
|
||||
owner: Some(*data.uid),
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
use common::{
|
||||
comp::{
|
||||
group, Beam, BeamSegment, Body, Energy, EnergyChange, EnergySource, Health, HealthChange,
|
||||
HealthSource, Inventory, Last, Ori, Pos, Scale,
|
||||
group, Beam, BeamSegment, Body, Energy, Health, HealthSource, Inventory, Last, Ori, Pos,
|
||||
Scale,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
resources::{DeltaTime, Time},
|
||||
@ -112,7 +112,16 @@ impl<'a> System<'a> for Sys {
|
||||
};
|
||||
|
||||
// Go through all other effectable entities
|
||||
for (b, uid_b, pos_b, last_pos_b_maybe, scale_b_maybe, health_b, body_b) in (
|
||||
for (
|
||||
b,
|
||||
uid_b,
|
||||
pos_b,
|
||||
last_pos_b_maybe,
|
||||
scale_b_maybe,
|
||||
health_b,
|
||||
body_b,
|
||||
inventory_b_maybe,
|
||||
) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&positions,
|
||||
@ -121,6 +130,7 @@ impl<'a> System<'a> for Sys {
|
||||
scales.maybe(),
|
||||
&healths,
|
||||
&bodies,
|
||||
inventories.maybe(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -158,68 +168,96 @@ impl<'a> System<'a> for Sys {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (target, damage) in beam_segment.damages.iter() {
|
||||
if let Some(target) = target {
|
||||
if *target != target_group {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Modify damage
|
||||
let change = damage.modify_damage(
|
||||
inventories.get(b),
|
||||
beam_segment.owner,
|
||||
if let (Some(beam_owner), Some(owner_uid)) = (beam_owner, beam_segment.owner) {
|
||||
let server_events = beam_segment.properties.attack.apply_attack(
|
||||
target_group,
|
||||
beam_owner,
|
||||
b,
|
||||
inventory_b_maybe,
|
||||
owner_uid,
|
||||
ori.0,
|
||||
false,
|
||||
0.0,
|
||||
);
|
||||
|
||||
match target {
|
||||
Some(GroupTarget::OutOfGroup) => {
|
||||
server_emitter.emit(ServerEvent::Damage { entity: b, change });
|
||||
if let Some(entity) = beam_owner {
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
entity,
|
||||
change: HealthChange {
|
||||
amount: (-change.amount as f32
|
||||
* beam_segment.lifesteal_eff)
|
||||
as i32,
|
||||
cause: HealthSource::Heal {
|
||||
by: beam_segment.owner,
|
||||
},
|
||||
},
|
||||
});
|
||||
server_emitter.emit(ServerEvent::EnergyChange {
|
||||
entity,
|
||||
change: EnergyChange {
|
||||
amount: beam_segment.energy_regen as i32,
|
||||
source: EnergySource::HitEnemy,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
Some(GroupTarget::InGroup) => {
|
||||
if let Some(energy) = beam_owner.and_then(|o| energies.get(o)) {
|
||||
if energy.current() > beam_segment.energy_cost {
|
||||
server_emitter.emit(ServerEvent::EnergyChange {
|
||||
entity: beam_owner.unwrap(), /* If it's able to get an energy
|
||||
* component, the entity exists */
|
||||
change: EnergyChange {
|
||||
amount: -(beam_segment.energy_cost as i32), // Stamina use
|
||||
source: EnergySource::Ability,
|
||||
},
|
||||
});
|
||||
server_emitter
|
||||
.emit(ServerEvent::Damage { entity: b, change });
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {},
|
||||
if !server_events.is_empty() {
|
||||
hit_entities.push(*uid_b);
|
||||
}
|
||||
|
||||
// Adds entities that were hit to the hit_entities list on the beam, sees if
|
||||
// it needs to purge the hit_entities list
|
||||
hit_entities.push(*uid_b);
|
||||
for event in server_events {
|
||||
server_emitter.emit(event);
|
||||
}
|
||||
}
|
||||
|
||||
// for (target, damage) in beam_segment.damages.iter() {
|
||||
// if let Some(target) = target {
|
||||
// if *target != target_group {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Modify damage
|
||||
// let change = damage.modify_damage(
|
||||
// inventories.get(b),
|
||||
// beam_segment.owner,
|
||||
// false,
|
||||
// 0.0,
|
||||
// );
|
||||
|
||||
// match target {
|
||||
// Some(GroupTarget::OutOfGroup) => {
|
||||
// server_emitter.emit(ServerEvent::Damage {
|
||||
// entity: b, change }); if
|
||||
// let Some(entity) = beam_owner {
|
||||
// server_emitter.emit(ServerEvent::Damage {
|
||||
// entity,
|
||||
// change: HealthChange {
|
||||
// amount: (-change.amount as f32
|
||||
// * beam_segment.lifesteal_eff)
|
||||
// as i32,
|
||||
// cause: HealthSource::Heal {
|
||||
// by: beam_segment.owner,
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
//
|
||||
// server_emitter.emit(ServerEvent::EnergyChange {
|
||||
// entity,
|
||||
// change: EnergyChange {
|
||||
// amount: beam_segment.energy_regen
|
||||
// as i32,
|
||||
// source: EnergySource::HitEnemy,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// Some(GroupTarget::InGroup) => {
|
||||
// if let Some(energy) = beam_owner.and_then(|o|
|
||||
// energies.get(o)) { if
|
||||
// energy.current() > beam_segment.energy_cost {
|
||||
//
|
||||
// server_emitter.emit(ServerEvent::EnergyChange {
|
||||
// entity: beam_owner.unwrap(), /*
|
||||
// If it's able to get an energy
|
||||
// * component, the entity exists */
|
||||
// change: EnergyChange {
|
||||
// amount:
|
||||
// -(beam_segment.energy_cost as i32), // Stamina use
|
||||
// source:
|
||||
// EnergySource::Ability,
|
||||
// }, });
|
||||
// server_emitter
|
||||
// .emit(ServerEvent::Damage {
|
||||
// entity: b, change });
|
||||
// } }
|
||||
// },
|
||||
// None => {},
|
||||
// }
|
||||
|
||||
// // Adds entities that were hit to the hit_entities
|
||||
// list on the beam, sees if // it needs
|
||||
// to purge the hit_entities list
|
||||
// hit_entities.push(*uid_b);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ pub fn handle_beam(server: &mut Server, properties: beam::Properties, pos: Pos,
|
||||
let ecs = state.ecs();
|
||||
ecs.write_resource::<Vec<Outcome>>().push(Outcome::Beam {
|
||||
pos: pos.0,
|
||||
heal: properties.lifesteal_eff > 0.0,
|
||||
heal: false, //properties.lifesteal_eff > 0.0,
|
||||
});
|
||||
state.create_beam(properties, pos, ori).build();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user