mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Projectiles now use attacks.
This commit is contained in:
parent
46dbb8aef4
commit
59ce8c6843
@ -469,7 +469,7 @@ impl CombatBuff {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn default_melee() -> Self {
|
||||
pub fn default_physical() -> Self {
|
||||
Self {
|
||||
kind: BuffKind::Bleeding,
|
||||
dur_secs: 10.0,
|
||||
|
@ -1,30 +1,33 @@
|
||||
use crate::{
|
||||
comp::buff::{BuffCategory, BuffData, BuffKind},
|
||||
effect::{self, BuffEffect},
|
||||
combat::{
|
||||
Attack, AttackEffect, CombatBuff, CombatRequirement, Damage, DamageComponent, DamageSource,
|
||||
EffectComponent, GroupTarget, Knockback, KnockbackDir,
|
||||
},
|
||||
effect,
|
||||
uid::Uid,
|
||||
Damage, DamageSource, Explosion, GroupTarget, Knockback, KnockbackDir, RadiusEffect,
|
||||
Explosion, RadiusEffect,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::Component;
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum Effect {
|
||||
Damage(Option<GroupTarget>, Damage),
|
||||
Knockback(Knockback),
|
||||
RewardEnergy(u32),
|
||||
Attack(Attack),
|
||||
//Knockback(Knockback),
|
||||
//RewardEnergy(u32),
|
||||
Explode(Explosion),
|
||||
Vanish,
|
||||
Stick,
|
||||
Possess,
|
||||
Buff {
|
||||
buff: BuffEffect,
|
||||
chance: Option<f32>,
|
||||
},
|
||||
/*Buff {
|
||||
* buff: BuffEffect,
|
||||
* chance: Option<f32>, */
|
||||
/* */
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Projectile {
|
||||
// TODO: use SmallVec for these effects
|
||||
pub hit_solid: Vec<Effect>,
|
||||
@ -74,32 +77,29 @@ impl ProjectileConstructor {
|
||||
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],
|
||||
let damage = Damage {
|
||||
source: DamageSource::Projectile,
|
||||
value: damage,
|
||||
};
|
||||
let knockback = AttackEffect::Knockback(Knockback {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
});
|
||||
let energy = AttackEffect::EnergyReward(energy_regen);
|
||||
let energy = EffectComponent::new(None, energy)
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
.with_crit(0.5, 1.2)
|
||||
.with_effect(energy);
|
||||
|
||||
Projectile {
|
||||
hit_solid: vec![Effect::Stick],
|
||||
hit_entity: vec![
|
||||
Effect::Damage(Some(GroupTarget::OutOfGroup), Damage {
|
||||
source: DamageSource::Projectile,
|
||||
value: damage,
|
||||
}),
|
||||
Effect::Knockback(Knockback {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
}),
|
||||
Effect::RewardEnergy(energy_regen),
|
||||
Effect::Vanish,
|
||||
Effect::Buff {
|
||||
buff,
|
||||
chance: Some(0.10),
|
||||
},
|
||||
],
|
||||
hit_entity: vec![Effect::Attack(attack), Effect::Vanish],
|
||||
time_left: Duration::from_secs(15),
|
||||
owner,
|
||||
ignore_group: true,
|
||||
@ -148,19 +148,24 @@ impl ProjectileConstructor {
|
||||
Firebolt {
|
||||
damage,
|
||||
energy_regen,
|
||||
} => Projectile {
|
||||
hit_solid: vec![Effect::Vanish],
|
||||
hit_entity: vec![
|
||||
Effect::Damage(Some(GroupTarget::OutOfGroup), Damage {
|
||||
source: DamageSource::Energy,
|
||||
value: damage,
|
||||
}),
|
||||
Effect::RewardEnergy(energy_regen),
|
||||
Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(10),
|
||||
owner,
|
||||
ignore_group: true,
|
||||
} => {
|
||||
let damage = Damage {
|
||||
source: DamageSource::Energy,
|
||||
value: damage,
|
||||
};
|
||||
let energy = AttackEffect::EnergyReward(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);
|
||||
|
||||
Projectile {
|
||||
hit_solid: vec![Effect::Vanish],
|
||||
hit_entity: vec![Effect::Attack(attack), Effect::Vanish],
|
||||
time_left: Duration::from_secs(10),
|
||||
owner,
|
||||
ignore_group: true,
|
||||
}
|
||||
},
|
||||
Heal {
|
||||
heal,
|
||||
|
@ -103,7 +103,7 @@ impl CharacterBehavior for Data {
|
||||
let energy = AttackEffect::EnergyReward(50);
|
||||
let energy = EffectComponent::new(None, energy)
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_melee());
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
|
@ -173,7 +173,7 @@ impl CharacterBehavior for Data {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
});
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_melee());
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
|
@ -1,16 +1,17 @@
|
||||
use crate::{
|
||||
combat::{
|
||||
Attack, AttackEffect, CombatBuff, Damage, DamageComponent, DamageSource, GroupTarget,
|
||||
Knockback, KnockbackDir,
|
||||
},
|
||||
comp::{
|
||||
buff::{BuffCategory, BuffData, BuffKind},
|
||||
projectile, Body, CharacterState, EnergyChange, EnergySource, Gravity, LightEmitter,
|
||||
Projectile, StateUpdate,
|
||||
},
|
||||
effect::BuffEffect,
|
||||
event::ServerEvent,
|
||||
states::{
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
utils::*,
|
||||
},
|
||||
Damage, DamageSource, GroupTarget, Knockback, KnockbackDir,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -109,27 +110,22 @@ impl CharacterBehavior for Data {
|
||||
};
|
||||
let knockback = self.static_data.initial_knockback
|
||||
+ charge_frac * self.static_data.scaled_knockback;
|
||||
let knockback = AttackEffect::Knockback(Knockback {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
});
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
let attack = Attack::default().with_damage(damage).with_crit(0.5, 1.2);
|
||||
|
||||
// Fire
|
||||
let projectile = Projectile {
|
||||
hit_solid: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(Some(GroupTarget::OutOfGroup), damage),
|
||||
projectile::Effect::Knockback(Knockback {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
}),
|
||||
projectile::Effect::Attack(attack),
|
||||
projectile::Effect::Vanish,
|
||||
projectile::Effect::Buff {
|
||||
buff: BuffEffect {
|
||||
kind: BuffKind::Bleeding,
|
||||
data: BuffData {
|
||||
strength: damage.value / 5.0,
|
||||
duration: Some(Duration::from_secs(5)),
|
||||
},
|
||||
cat_ids: vec![BuffCategory::Physical],
|
||||
},
|
||||
chance: Some(0.10),
|
||||
},
|
||||
],
|
||||
time_left: Duration::from_secs(15),
|
||||
owner: Some(*data.uid),
|
||||
|
@ -200,7 +200,7 @@ impl CharacterBehavior for Data {
|
||||
let energy = AttackEffect::EnergyReward(energy);
|
||||
let energy = EffectComponent::new(None, energy)
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_melee());
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
|
@ -150,7 +150,7 @@ impl CharacterBehavior for Data {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
});
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_melee());
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage =
|
||||
DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
|
@ -156,7 +156,7 @@ impl CharacterBehavior for Data {
|
||||
strength: self.static_data.knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
});
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_melee());
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
|
@ -124,7 +124,7 @@ impl CharacterBehavior for Data {
|
||||
strength: self.static_data.knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
});
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_melee());
|
||||
let buff = AttackEffect::Buff(CombatBuff::default_physical());
|
||||
let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup))
|
||||
.with_effect(knockback)
|
||||
.with_effect(buff);
|
||||
|
@ -1,9 +1,5 @@
|
||||
use common::{
|
||||
comp::{
|
||||
buff::{Buff, BuffChange, BuffSource},
|
||||
projectile, EnergyChange, EnergySource, Group, HealthSource, Inventory, Ori, PhysicsState,
|
||||
Pos, Projectile, Vel,
|
||||
},
|
||||
comp::{projectile, Group, HealthSource, Inventory, Ori, PhysicsState, Pos, Projectile, Vel},
|
||||
event::{EventBus, ServerEvent},
|
||||
metrics::SysMetrics,
|
||||
resources::DeltaTime,
|
||||
@ -11,7 +7,6 @@ use common::{
|
||||
uid::UidAllocator,
|
||||
GroupTarget,
|
||||
};
|
||||
use rand::{thread_rng, Rng};
|
||||
use specs::{
|
||||
saveload::MarkerAllocator, Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage,
|
||||
};
|
||||
@ -103,60 +98,55 @@ impl<'a> System<'a> for Sys {
|
||||
let projectile = &mut *projectile;
|
||||
for effect in projectile.hit_entity.drain(..) {
|
||||
match effect {
|
||||
projectile::Effect::Damage(target, damage) => {
|
||||
if Some(other) == projectile.owner {
|
||||
continue;
|
||||
}
|
||||
projectile::Effect::Attack(attack) => {
|
||||
if let Some(owner) = projectile.owner {
|
||||
if let (Some(owner_entity), Some(target_entity)) = (
|
||||
uid_allocator.retrieve_entity_internal(owner.into()),
|
||||
uid_allocator.retrieve_entity_internal(other.into()),
|
||||
) {
|
||||
let server_events = attack.apply_attack(
|
||||
target_group,
|
||||
owner_entity,
|
||||
target_entity,
|
||||
inventories.get(target_entity),
|
||||
owner,
|
||||
ori.0,
|
||||
false,
|
||||
);
|
||||
|
||||
if let Some(target) = target {
|
||||
if target != target_group {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(other_entity) =
|
||||
uid_allocator.retrieve_entity_internal(other.into())
|
||||
{
|
||||
let other_entity_inventory = inventories.get(other_entity);
|
||||
let change = damage.modify_damage(
|
||||
other_entity_inventory,
|
||||
projectile.owner,
|
||||
false,
|
||||
0.0,
|
||||
);
|
||||
server_emitter.emit(ServerEvent::Damage {
|
||||
entity: other_entity,
|
||||
change,
|
||||
});
|
||||
}
|
||||
},
|
||||
projectile::Effect::Knockback(knockback) => {
|
||||
if let Some(other_entity) =
|
||||
uid_allocator.retrieve_entity_internal(other.into())
|
||||
{
|
||||
let impulse = knockback.calculate_impulse(ori.0);
|
||||
if !impulse.is_approx_zero() {
|
||||
server_emitter.emit(ServerEvent::Knockback {
|
||||
entity: other_entity,
|
||||
impulse,
|
||||
});
|
||||
for event in server_events {
|
||||
server_emitter.emit(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
projectile::Effect::RewardEnergy(energy) => {
|
||||
if let Some(entity_owner) = projectile
|
||||
.owner
|
||||
.and_then(|u| uid_allocator.retrieve_entity_internal(u.into()))
|
||||
{
|
||||
server_emitter.emit(ServerEvent::EnergyChange {
|
||||
entity: entity_owner,
|
||||
change: EnergyChange {
|
||||
amount: energy as i32,
|
||||
source: EnergySource::HitEnemy,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
// projectile::Effect::Knockback(knockback) => {
|
||||
// if let Some(other_entity) =
|
||||
// uid_allocator.retrieve_entity_internal(other.into())
|
||||
// {
|
||||
// let impulse = knockback.calculate_impulse(ori.0);
|
||||
// if !impulse.is_approx_zero() {
|
||||
// server_emitter.emit(ServerEvent::Knockback {
|
||||
// entity: other_entity,
|
||||
// impulse,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// projectile::Effect::RewardEnergy(energy) => {
|
||||
// if let Some(entity_owner) = projectile
|
||||
// .owner
|
||||
// .and_then(|u| uid_allocator.retrieve_entity_internal(u.into()))
|
||||
// {
|
||||
// server_emitter.emit(ServerEvent::EnergyChange {
|
||||
// entity: entity_owner,
|
||||
// change: EnergyChange {
|
||||
// amount: energy as i32,
|
||||
// source: EnergySource::HitEnemy,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
projectile::Effect::Explode(e) => {
|
||||
server_emitter.emit(ServerEvent::Explosion {
|
||||
pos: pos.0,
|
||||
@ -180,25 +170,25 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
},
|
||||
// TODO: Change to effect after !1472 merges
|
||||
projectile::Effect::Buff { buff, chance } => {
|
||||
if let Some(entity) =
|
||||
uid_allocator.retrieve_entity_internal(other.into())
|
||||
{
|
||||
if chance.map_or(true, |c| thread_rng().gen::<f32>() < c) {
|
||||
let source = if let Some(owner) = projectile.owner {
|
||||
BuffSource::Character { by: owner }
|
||||
} else {
|
||||
BuffSource::Unknown
|
||||
};
|
||||
let buff =
|
||||
Buff::new(buff.kind, buff.data, buff.cat_ids, source);
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity,
|
||||
buff_change: BuffChange::Add(buff),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
// projectile::Effect::Buff { buff, chance } => {
|
||||
// if let Some(entity) =
|
||||
// uid_allocator.retrieve_entity_internal(other.into())
|
||||
// {
|
||||
// if chance.map_or(true, |c| thread_rng().gen::<f32>() < c) {
|
||||
// let source = if let Some(owner) = projectile.owner {
|
||||
// BuffSource::Character { by: owner }
|
||||
// } else {
|
||||
// BuffSource::Unknown
|
||||
// };
|
||||
// let buff =
|
||||
// Buff::new(buff.kind, buff.data, buff.cat_ids, source);
|
||||
// server_emitter.emit(ServerEvent::Buff {
|
||||
// entity,
|
||||
// buff_change: BuffChange::Add(buff),
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user