Beams now use Attack, with limited functionality in some cases.

This commit is contained in:
Sam 2021-01-28 20:37:33 -05:00
parent 59ce8c6843
commit fdef168e82
7 changed files with 130 additions and 87 deletions

View File

@ -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,

View File

@ -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)]

View File

@ -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)]

View File

@ -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)]

View File

@ -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),
};

View File

@ -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);
// }
}
}
}

View File

@ -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();
}