mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Campfires can set things on fire and water puts it out
This commit is contained in:
parent
607f8b289b
commit
4d4bc132f4
@ -103,6 +103,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Animal Trainers now spawn in tier-5 dungeon and not in tier-3
|
- Animal Trainers now spawn in tier-5 dungeon and not in tier-3
|
||||||
- Reworked clay golem to have unique attacks.
|
- Reworked clay golem to have unique attacks.
|
||||||
- Merchants now use `/tell` instead of `/say` to communicate prices
|
- Merchants now use `/tell` instead of `/say` to communicate prices
|
||||||
|
- Entities catch on fire if they stand too close to campfires
|
||||||
|
- Water extinguishes entities on fire
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
Buff, BuffCategory, BuffChange, BuffEffect, BuffId, BuffSource, Buffs, Energy, Health,
|
fluid_dynamics::Fluid, Buff, BuffCategory, BuffChange, BuffEffect, BuffId, BuffKind,
|
||||||
HealthChange, HealthSource, Inventory, ModifierKind, Stats,
|
BuffSource, Buffs, Energy, Health, HealthChange, HealthSource, Inventory, ModifierKind,
|
||||||
|
PhysicsState, Stats,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
@ -20,6 +21,7 @@ pub struct ReadData<'a> {
|
|||||||
server_bus: Read<'a, EventBus<ServerEvent>>,
|
server_bus: Read<'a, EventBus<ServerEvent>>,
|
||||||
inventories: ReadStorage<'a, Inventory>,
|
inventories: ReadStorage<'a, Inventory>,
|
||||||
healths: ReadStorage<'a, Health>,
|
healths: ReadStorage<'a, Health>,
|
||||||
|
physics_states: ReadStorage<'a, PhysicsState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -61,18 +63,28 @@ impl<'a> System<'a> for Sys {
|
|||||||
// duration of strongest buff of that kind, else it ticks durations of all buffs
|
// duration of strongest buff of that kind, else it ticks durations of all buffs
|
||||||
// of that kind. Any buffs whose durations expire are marked expired.
|
// of that kind. Any buffs whose durations expire are marked expired.
|
||||||
for (kind, ids) in buff_comp_kinds.iter() {
|
for (kind, ids) in buff_comp_kinds.iter() {
|
||||||
|
// Only get the physics state component if the entity has the burning buff, as
|
||||||
|
// we don't need it for any other conditions yet
|
||||||
|
let in_fluid = if matches!(kind, BuffKind::Burning) {
|
||||||
|
read_data
|
||||||
|
.physics_states
|
||||||
|
.get(entity)
|
||||||
|
.and_then(|p| p.in_fluid)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
if kind.queues() {
|
if kind.queues() {
|
||||||
if let Some((Some(buff), id)) =
|
if let Some((Some(buff), id)) =
|
||||||
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
||||||
{
|
{
|
||||||
tick_buff(*id, buff, dt, |id| expired_buffs.push(id));
|
tick_buff(*id, buff, dt, in_fluid, |id| expired_buffs.push(id));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (id, buff) in buff_comp_buffs
|
for (id, buff) in buff_comp_buffs
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter(|(i, _)| ids.iter().any(|id| id == *i))
|
.filter(|(i, _)| ids.iter().any(|id| id == *i))
|
||||||
{
|
{
|
||||||
tick_buff(*id, buff, dt, |id| expired_buffs.push(id));
|
tick_buff(*id, buff, dt, in_fluid, |id| expired_buffs.push(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +239,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_buff(id: u64, buff: &mut Buff, dt: f32, mut expire_buff: impl FnMut(u64)) {
|
fn tick_buff(
|
||||||
|
id: u64,
|
||||||
|
buff: &mut Buff,
|
||||||
|
dt: f32,
|
||||||
|
in_fluid: Option<Fluid>,
|
||||||
|
mut expire_buff: impl FnMut(u64),
|
||||||
|
) {
|
||||||
// If a buff is recently applied from an aura, do not tick duration
|
// If a buff is recently applied from an aura, do not tick duration
|
||||||
if buff
|
if buff
|
||||||
.cat_ids
|
.cat_ids
|
||||||
@ -237,6 +255,11 @@ fn tick_buff(id: u64, buff: &mut Buff, dt: f32, mut expire_buff: impl FnMut(u64)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(remaining_time) = &mut buff.time {
|
if let Some(remaining_time) = &mut buff.time {
|
||||||
|
// Extinguish Burning buff when in water
|
||||||
|
if matches!(buff.kind, BuffKind::Burning) && matches!(in_fluid, Some(Fluid::Water { .. })) {
|
||||||
|
*remaining_time = Duration::default();
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(new_duration) = remaining_time.checked_sub(Duration::from_secs_f32(dt)) {
|
if let Some(new_duration) = remaining_time.checked_sub(Duration::from_secs_f32(dt)) {
|
||||||
// The buff still continues.
|
// The buff still continues.
|
||||||
*remaining_time = new_duration;
|
*remaining_time = new_duration;
|
||||||
|
@ -1191,17 +1191,30 @@ fn handle_spawn_campfire(
|
|||||||
animated: true,
|
animated: true,
|
||||||
})
|
})
|
||||||
.with(WaypointArea::default())
|
.with(WaypointArea::default())
|
||||||
.with(comp::Auras::new(vec![Aura::new(
|
.with(comp::Auras::new(vec![
|
||||||
AuraKind::Buff {
|
Aura::new(
|
||||||
kind: BuffKind::CampfireHeal,
|
AuraKind::Buff {
|
||||||
data: BuffData::new(0.02, Some(Duration::from_secs(1))),
|
kind: BuffKind::CampfireHeal,
|
||||||
category: BuffCategory::Natural,
|
data: BuffData::new(0.02, Some(Duration::from_secs(1))),
|
||||||
source: BuffSource::World,
|
category: BuffCategory::Natural,
|
||||||
},
|
source: BuffSource::World,
|
||||||
5.0,
|
},
|
||||||
None,
|
5.0,
|
||||||
AuraTarget::All,
|
None,
|
||||||
)]))
|
AuraTarget::All,
|
||||||
|
),
|
||||||
|
Aura::new(
|
||||||
|
AuraKind::Buff {
|
||||||
|
kind: BuffKind::Burning,
|
||||||
|
data: BuffData::new(20.0, Some(Duration::from_secs(10))),
|
||||||
|
category: BuffCategory::Natural,
|
||||||
|
source: BuffSource::World,
|
||||||
|
},
|
||||||
|
0.7,
|
||||||
|
None,
|
||||||
|
AuraTarget::All,
|
||||||
|
),
|
||||||
|
]))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
|
@ -242,16 +242,29 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
|
|||||||
})
|
})
|
||||||
.with(WaypointArea::default())
|
.with(WaypointArea::default())
|
||||||
.with(comp::Mass(10_f32.powi(10)))
|
.with(comp::Mass(10_f32.powi(10)))
|
||||||
.with(comp::Auras::new(vec![Aura::new(
|
.with(comp::Auras::new(vec![
|
||||||
AuraKind::Buff {
|
Aura::new(
|
||||||
kind: BuffKind::CampfireHeal,
|
AuraKind::Buff {
|
||||||
data: BuffData::new(0.02, Some(Duration::from_secs(1))),
|
kind: BuffKind::CampfireHeal,
|
||||||
category: BuffCategory::Natural,
|
data: BuffData::new(0.02, Some(Duration::from_secs(1))),
|
||||||
source: BuffSource::World,
|
category: BuffCategory::Natural,
|
||||||
},
|
source: BuffSource::World,
|
||||||
5.0,
|
},
|
||||||
None,
|
5.0,
|
||||||
AuraTarget::All,
|
None,
|
||||||
)]))
|
AuraTarget::All,
|
||||||
|
),
|
||||||
|
Aura::new(
|
||||||
|
AuraKind::Buff {
|
||||||
|
kind: BuffKind::Burning,
|
||||||
|
data: BuffData::new(20.0, Some(Duration::from_secs(10))),
|
||||||
|
category: BuffCategory::Natural,
|
||||||
|
source: BuffSource::World,
|
||||||
|
},
|
||||||
|
0.7,
|
||||||
|
None,
|
||||||
|
AuraTarget::All,
|
||||||
|
),
|
||||||
|
]))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user