mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Server event used to deal damage/heal with buffs. Buff kills now award xp.
This commit is contained in:
parent
de7191b985
commit
1a1ceb54bc
@ -184,6 +184,7 @@ https://account.veloren.net."#,
|
|||||||
"hud.chat.pvp_ranged_kill_msg": "[{attacker}] shot [{victim}]",
|
"hud.chat.pvp_ranged_kill_msg": "[{attacker}] shot [{victim}]",
|
||||||
"hud.chat.pvp_explosion_kill_msg": "[{attacker}] blew up [{victim}]",
|
"hud.chat.pvp_explosion_kill_msg": "[{attacker}] blew up [{victim}]",
|
||||||
"hud.chat.pvp_energy_kill_msg": "[{attacker}] used magic to kill [{victim}]",
|
"hud.chat.pvp_energy_kill_msg": "[{attacker}] used magic to kill [{victim}]",
|
||||||
|
"hud.chat.pvp_buff_kill_msg": "[{attacker}] killed [{victim}]",
|
||||||
|
|
||||||
"hud.chat.npc_melee_kill_msg": "{attacker} killed [{victim}]",
|
"hud.chat.npc_melee_kill_msg": "{attacker} killed [{victim}]",
|
||||||
"hud.chat.npc_ranged_kill_msg": "{attacker} shot [{victim}]",
|
"hud.chat.npc_ranged_kill_msg": "{attacker} shot [{victim}]",
|
||||||
|
@ -1715,6 +1715,11 @@ impl Client {
|
|||||||
alias_of_uid(attacker_uid),
|
alias_of_uid(attacker_uid),
|
||||||
alias_of_uid(victim)
|
alias_of_uid(victim)
|
||||||
),
|
),
|
||||||
|
KillSource::Player(attacker_uid, KillType::Buff) => format!(
|
||||||
|
"[{}] killed [{}]",
|
||||||
|
alias_of_uid(attacker_uid),
|
||||||
|
alias_of_uid(victim)
|
||||||
|
),
|
||||||
KillSource::NonPlayer(attacker_name, KillType::Melee) => {
|
KillSource::NonPlayer(attacker_name, KillType::Melee) => {
|
||||||
format!("{} killed [{}]", attacker_name, alias_of_uid(victim))
|
format!("{} killed [{}]", attacker_name, alias_of_uid(victim))
|
||||||
},
|
},
|
||||||
@ -1729,6 +1734,9 @@ impl Client {
|
|||||||
attacker_name,
|
attacker_name,
|
||||||
alias_of_uid(victim)
|
alias_of_uid(victim)
|
||||||
),
|
),
|
||||||
|
KillSource::NonPlayer(attacker_name, KillType::Buff) => {
|
||||||
|
format!("{} killed [{}]", attacker_name, alias_of_uid(victim))
|
||||||
|
},
|
||||||
KillSource::Environment(environment) => {
|
KillSource::Environment(environment) => {
|
||||||
format!("[{}] died in {}", alias_of_uid(victim), environment)
|
format!("[{}] died in {}", alias_of_uid(victim), environment)
|
||||||
},
|
},
|
||||||
@ -1754,6 +1762,9 @@ impl Client {
|
|||||||
KillSource::Player(attacker_uid, KillType::Energy) => message
|
KillSource::Player(attacker_uid, KillType::Energy) => message
|
||||||
.replace("{attacker}", &alias_of_uid(attacker_uid))
|
.replace("{attacker}", &alias_of_uid(attacker_uid))
|
||||||
.replace("{victim}", &alias_of_uid(victim)),
|
.replace("{victim}", &alias_of_uid(victim)),
|
||||||
|
KillSource::Player(attacker_uid, KillType::Buff) => message
|
||||||
|
.replace("{attacker}", &alias_of_uid(attacker_uid))
|
||||||
|
.replace("{victim}", &alias_of_uid(victim)),
|
||||||
KillSource::NonPlayer(attacker_name, KillType::Melee) => message
|
KillSource::NonPlayer(attacker_name, KillType::Melee) => message
|
||||||
.replace("{attacker}", attacker_name)
|
.replace("{attacker}", attacker_name)
|
||||||
.replace("{victim}", &alias_of_uid(victim)),
|
.replace("{victim}", &alias_of_uid(victim)),
|
||||||
@ -1766,6 +1777,9 @@ impl Client {
|
|||||||
KillSource::NonPlayer(attacker_name, KillType::Energy) => message
|
KillSource::NonPlayer(attacker_name, KillType::Energy) => message
|
||||||
.replace("{attacker}", attacker_name)
|
.replace("{attacker}", attacker_name)
|
||||||
.replace("{victim}", &alias_of_uid(victim)),
|
.replace("{victim}", &alias_of_uid(victim)),
|
||||||
|
KillSource::NonPlayer(attacker_name, KillType::Buff) => message
|
||||||
|
.replace("{attacker}", attacker_name)
|
||||||
|
.replace("{victim}", &alias_of_uid(victim)),
|
||||||
KillSource::Environment(environment) => message
|
KillSource::Environment(environment) => message
|
||||||
.replace("{name}", &alias_of_uid(victim))
|
.replace("{name}", &alias_of_uid(victim))
|
||||||
.replace("{environment}", environment),
|
.replace("{environment}", environment),
|
||||||
|
@ -16,11 +16,9 @@ use std::time::Duration;
|
|||||||
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
pub enum BuffId {
|
pub enum BuffId {
|
||||||
/// Restores health/time for some period
|
/// Restores health/time for some period
|
||||||
/// Has fields: strength (f32)
|
Regeneration { strength: f32 },
|
||||||
Regeneration(f32),
|
|
||||||
/// Lowers health over time for some duration
|
/// Lowers health over time for some duration
|
||||||
/// Has fields: strength (f32)
|
Bleeding { strength: f32 },
|
||||||
Bleeding(f32),
|
|
||||||
/// Prefixes an entity's name with "Cursed"
|
/// Prefixes an entity's name with "Cursed"
|
||||||
/// Currently placeholder buff to show other stuff is possible
|
/// Currently placeholder buff to show other stuff is possible
|
||||||
Cursed,
|
Cursed,
|
||||||
@ -73,6 +71,7 @@ pub struct Buff {
|
|||||||
pub cat_ids: Vec<BuffCategoryId>,
|
pub cat_ids: Vec<BuffCategoryId>,
|
||||||
pub time: Option<Duration>,
|
pub time: Option<Duration>,
|
||||||
pub effects: Vec<BuffEffect>,
|
pub effects: Vec<BuffEffect>,
|
||||||
|
pub source: BuffSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about whether buff addition or removal was requested.
|
/// Information about whether buff addition or removal was requested.
|
||||||
@ -144,9 +143,14 @@ impl Buffs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Buff {
|
impl Buff {
|
||||||
pub fn new(id: BuffId, time: Option<Duration>, cat_ids: Vec<BuffCategoryId>) -> Self {
|
pub fn new(
|
||||||
|
id: BuffId,
|
||||||
|
time: Option<Duration>,
|
||||||
|
cat_ids: Vec<BuffCategoryId>,
|
||||||
|
source: BuffSource,
|
||||||
|
) -> Self {
|
||||||
let effects = match id {
|
let effects = match id {
|
||||||
BuffId::Bleeding(strength) => vec![
|
BuffId::Bleeding { strength } => vec![
|
||||||
BuffEffect::HealthChangeOverTime {
|
BuffEffect::HealthChangeOverTime {
|
||||||
rate: -strength,
|
rate: -strength,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
@ -156,7 +160,7 @@ impl Buff {
|
|||||||
prefix: String::from("Injured "),
|
prefix: String::from("Injured "),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
BuffId::Regeneration(strength) => vec![BuffEffect::HealthChangeOverTime {
|
BuffId::Regeneration { strength } => vec![BuffEffect::HealthChangeOverTime {
|
||||||
rate: strength,
|
rate: strength,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
}],
|
}],
|
||||||
@ -169,6 +173,7 @@ impl Buff {
|
|||||||
cat_ids,
|
cat_ids,
|
||||||
time,
|
time,
|
||||||
effects,
|
effects,
|
||||||
|
source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ pub enum KillType {
|
|||||||
Projectile,
|
Projectile,
|
||||||
Explosion,
|
Explosion,
|
||||||
Energy,
|
Energy,
|
||||||
|
Buff,
|
||||||
// Projectile(String), TODO: add projectile name when available
|
// Projectile(String), TODO: add projectile name when available
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ pub use body::{
|
|||||||
biped_large, bird_medium, bird_small, dragon, fish_medium, fish_small, golem, humanoid, object,
|
biped_large, bird_medium, bird_small, dragon, fish_medium, fish_small, golem, humanoid, object,
|
||||||
quadruped_low, quadruped_medium, quadruped_small, theropod, AllBodies, Body, BodyData,
|
quadruped_low, quadruped_medium, quadruped_small, theropod, AllBodies, Body, BodyData,
|
||||||
};
|
};
|
||||||
pub use buff::{Buff, BuffCategoryId, BuffChange, BuffEffect, BuffId, Buffs};
|
pub use buff::{Buff, BuffCategoryId, BuffChange, BuffEffect, BuffId, BuffSource, Buffs};
|
||||||
pub use character_state::{Attacking, CharacterState, StateUpdate};
|
pub use character_state::{Attacking, CharacterState, StateUpdate};
|
||||||
pub use chat::{
|
pub use chat::{
|
||||||
ChatMode, ChatMsg, ChatType, Faction, SpeechBubble, SpeechBubbleType, UnresolvedChatMsg,
|
ChatMode, ChatMsg, ChatType, Faction, SpeechBubble, SpeechBubbleType, UnresolvedChatMsg,
|
||||||
|
@ -20,6 +20,7 @@ pub enum HealthSource {
|
|||||||
Projectile { owner: Option<Uid> },
|
Projectile { owner: Option<Uid> },
|
||||||
Explosion { owner: Option<Uid> },
|
Explosion { owner: Option<Uid> },
|
||||||
Energy { owner: Option<Uid> },
|
Energy { owner: Option<Uid> },
|
||||||
|
Buff { owner: Option<Uid> },
|
||||||
Suicide,
|
Suicide,
|
||||||
World,
|
World,
|
||||||
Revive,
|
Revive,
|
||||||
|
@ -601,6 +601,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
if let comp::HealthSource::Attack { by }
|
if let comp::HealthSource::Attack { by }
|
||||||
| comp::HealthSource::Projectile { owner: Some(by) }
|
| comp::HealthSource::Projectile { owner: Some(by) }
|
||||||
| comp::HealthSource::Energy { owner: Some(by) }
|
| comp::HealthSource::Energy { owner: Some(by) }
|
||||||
|
| comp::HealthSource::Buff { owner: Some(by) }
|
||||||
| comp::HealthSource::Explosion { owner: Some(by) } =
|
| comp::HealthSource::Explosion { owner: Some(by) } =
|
||||||
my_stats.health.last_change.1.cause
|
my_stats.health.last_change.1.cause
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{BuffChange, BuffEffect, Buffs, HealthChange, HealthSource, Stats},
|
comp::{BuffChange, BuffEffect, BuffSource, Buffs, HealthChange, HealthSource},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
state::DeltaTime,
|
state::DeltaTime,
|
||||||
sync::Uid,
|
sync::Uid,
|
||||||
};
|
};
|
||||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
use specs::{Join, Read, ReadStorage, System, WriteStorage};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// This system modifies entity stats, changing them using buffs
|
/// This system modifies entity stats, changing them using buffs
|
||||||
@ -16,17 +16,15 @@ pub struct Sys;
|
|||||||
impl<'a> System<'a> for Sys {
|
impl<'a> System<'a> for Sys {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
Entities<'a>,
|
|
||||||
Read<'a, DeltaTime>,
|
Read<'a, DeltaTime>,
|
||||||
Read<'a, EventBus<ServerEvent>>,
|
Read<'a, EventBus<ServerEvent>>,
|
||||||
ReadStorage<'a, Uid>,
|
ReadStorage<'a, Uid>,
|
||||||
WriteStorage<'a, Stats>,
|
|
||||||
WriteStorage<'a, Buffs>,
|
WriteStorage<'a, Buffs>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, (entities, dt, server_bus, uids, mut stats, mut buffs): Self::SystemData) {
|
fn run(&mut self, (dt, server_bus, uids, mut buffs): Self::SystemData) {
|
||||||
let mut server_emitter = server_bus.emitter();
|
let mut server_emitter = server_bus.emitter();
|
||||||
for (entity, uid, mut buffs) in (&entities, &uids, &mut buffs.restrict_mut()).join() {
|
for (uid, mut buffs) in (&uids, &mut buffs.restrict_mut()).join() {
|
||||||
let buff_comp = buffs.get_mut_unchecked();
|
let buff_comp = buffs.get_mut_unchecked();
|
||||||
let (mut active_buff_indices_for_removal, mut inactive_buff_indices_for_removal) =
|
let (mut active_buff_indices_for_removal, mut inactive_buff_indices_for_removal) =
|
||||||
(Vec::<usize>::new(), Vec::<usize>::new());
|
(Vec::<usize>::new(), Vec::<usize>::new());
|
||||||
@ -56,6 +54,12 @@ impl<'a> System<'a> for Sys {
|
|||||||
dt.0
|
dt.0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let buff_owner =
|
||||||
|
if let BuffSource::Character { by: owner } = buff_comp.active_buffs[i].source {
|
||||||
|
Some(owner)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
// Now, execute the buff, based on it's delta
|
// Now, execute the buff, based on it's delta
|
||||||
for effect in &mut buff_comp.active_buffs[i].effects {
|
for effect in &mut buff_comp.active_buffs[i].effects {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
@ -66,13 +70,18 @@ impl<'a> System<'a> for Sys {
|
|||||||
*accumulated += *rate * buff_delta;
|
*accumulated += *rate * buff_delta;
|
||||||
// Apply only 0.5 or higher damage
|
// Apply only 0.5 or higher damage
|
||||||
if accumulated.abs() > 5.0 {
|
if accumulated.abs() > 5.0 {
|
||||||
if let Some(stats) = stats.get_mut(entity) {
|
let cause = if *accumulated > 0.0 {
|
||||||
let change = HealthChange {
|
HealthSource::Healing { by: buff_owner }
|
||||||
|
} else {
|
||||||
|
HealthSource::Buff { owner: buff_owner }
|
||||||
|
};
|
||||||
|
server_emitter.emit(ServerEvent::Damage {
|
||||||
|
uid: *uid,
|
||||||
|
change: HealthChange {
|
||||||
amount: *accumulated as i32,
|
amount: *accumulated as i32,
|
||||||
cause: HealthSource::Unknown,
|
cause,
|
||||||
};
|
},
|
||||||
stats.health.change_by(change);
|
});
|
||||||
}
|
|
||||||
*accumulated = 0.0;
|
*accumulated = 0.0;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -155,9 +155,12 @@ impl<'a> System<'a> for Sys {
|
|||||||
server_emitter.emit(ServerEvent::Buff {
|
server_emitter.emit(ServerEvent::Buff {
|
||||||
uid: *uid_b,
|
uid: *uid_b,
|
||||||
buff_change: buff::BuffChange::Add(buff::Buff::new(
|
buff_change: buff::BuffChange::Add(buff::Buff::new(
|
||||||
buff::BuffId::Bleeding(-damage.healthchange),
|
buff::BuffId::Bleeding {
|
||||||
|
strength: -damage.healthchange,
|
||||||
|
},
|
||||||
Some(Duration::from_millis(10000)),
|
Some(Duration::from_millis(10000)),
|
||||||
vec![buff::BuffCategoryId::Physical],
|
vec![buff::BuffCategoryId::Physical],
|
||||||
|
buff::BuffSource::Character { by: *uid },
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
attack.hit_count += 1;
|
attack.hit_count += 1;
|
||||||
|
@ -166,11 +166,34 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
KillSource::NonPlayer("<?>".to_string(), KillType::Energy)
|
KillSource::NonPlayer("<?>".to_string(), KillType::Energy)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
HealthSource::Buff { owner: Some(by) } => {
|
||||||
|
// Get energy owner entity
|
||||||
|
if let Some(char_entity) = state.ecs().entity_from_uid(by.into()) {
|
||||||
|
// Check if attacker is another player or entity with stats (npc)
|
||||||
|
if state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<Player>()
|
||||||
|
.get(char_entity)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
KillSource::Player(by, KillType::Buff)
|
||||||
|
} else if let Some(stats) =
|
||||||
|
state.ecs().read_storage::<Stats>().get(char_entity)
|
||||||
|
{
|
||||||
|
KillSource::NonPlayer(stats.name.clone(), KillType::Buff)
|
||||||
|
} else {
|
||||||
|
KillSource::NonPlayer("<?>".to_string(), KillType::Buff)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KillSource::NonPlayer("<?>".to_string(), KillType::Buff)
|
||||||
|
}
|
||||||
|
},
|
||||||
HealthSource::World => KillSource::FallDamage,
|
HealthSource::World => KillSource::FallDamage,
|
||||||
HealthSource::Suicide => KillSource::Suicide,
|
HealthSource::Suicide => KillSource::Suicide,
|
||||||
HealthSource::Projectile { owner: None }
|
HealthSource::Projectile { owner: None }
|
||||||
| HealthSource::Explosion { owner: None }
|
| HealthSource::Explosion { owner: None }
|
||||||
| HealthSource::Energy { owner: None }
|
| HealthSource::Energy { owner: None }
|
||||||
|
| HealthSource::Buff { owner: None }
|
||||||
| HealthSource::Revive
|
| HealthSource::Revive
|
||||||
| HealthSource::Command
|
| HealthSource::Command
|
||||||
| HealthSource::LevelUp
|
| HealthSource::LevelUp
|
||||||
@ -190,6 +213,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
let by = if let HealthSource::Attack { by }
|
let by = if let HealthSource::Attack { by }
|
||||||
| HealthSource::Projectile { owner: Some(by) }
|
| HealthSource::Projectile { owner: Some(by) }
|
||||||
| HealthSource::Energy { owner: Some(by) }
|
| HealthSource::Energy { owner: Some(by) }
|
||||||
|
| HealthSource::Buff { owner: Some(by) }
|
||||||
| HealthSource::Explosion { owner: Some(by) } = cause
|
| HealthSource::Explosion { owner: Some(by) } = cause
|
||||||
{
|
{
|
||||||
by
|
by
|
||||||
@ -836,15 +860,25 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
|
|||||||
fn determine_replace_active_buff(active_buff: buff::Buff, new_buff: buff::Buff) -> bool {
|
fn determine_replace_active_buff(active_buff: buff::Buff, new_buff: buff::Buff) -> bool {
|
||||||
use buff::BuffId;
|
use buff::BuffId;
|
||||||
match new_buff.id {
|
match new_buff.id {
|
||||||
BuffId::Bleeding(new_strength) => {
|
BuffId::Bleeding {
|
||||||
if let BuffId::Bleeding(active_strength) = active_buff.id {
|
strength: new_strength,
|
||||||
|
} => {
|
||||||
|
if let BuffId::Bleeding {
|
||||||
|
strength: active_strength,
|
||||||
|
} = active_buff.id
|
||||||
|
{
|
||||||
new_strength > active_strength
|
new_strength > active_strength
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BuffId::Regeneration(new_strength) => {
|
BuffId::Regeneration {
|
||||||
if let BuffId::Regeneration(active_strength) = active_buff.id {
|
strength: new_strength,
|
||||||
|
} => {
|
||||||
|
if let BuffId::Regeneration {
|
||||||
|
strength: active_strength,
|
||||||
|
} = active_buff.id
|
||||||
|
{
|
||||||
new_strength > active_strength
|
new_strength > active_strength
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -373,6 +373,10 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.chat.pvp_energy_kill_msg")
|
.get("hud.chat.pvp_energy_kill_msg")
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
KillSource::Player(_, KillType::Buff) => self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.chat.pvp_buff_kill_msg")
|
||||||
|
.to_string(),
|
||||||
KillSource::NonPlayer(_, KillType::Melee) => self
|
KillSource::NonPlayer(_, KillType::Melee) => self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.chat.npc_melee_kill_msg")
|
.get("hud.chat.npc_melee_kill_msg")
|
||||||
@ -389,6 +393,10 @@ impl<'a> Widget for Chat<'a> {
|
|||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.chat.npc_energy_kill_msg")
|
.get("hud.chat.npc_energy_kill_msg")
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
KillSource::NonPlayer(_, KillType::Buff) => self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.chat.npc_buff_kill_msg")
|
||||||
|
.to_string(),
|
||||||
KillSource::Environment(_) => self
|
KillSource::Environment(_) => self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.chat.environmental_kill_msg")
|
.get("hud.chat.environmental_kill_msg")
|
||||||
|
Loading…
Reference in New Issue
Block a user