mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Vines now ensnare you by applying a buff.
This commit is contained in:
parent
763461ebef
commit
0a32b676c8
@ -34,6 +34,8 @@
|
||||
"buff.desc.frozen": "Your movements and attacks are slowed.",
|
||||
"buff.title.wet": "Wet",
|
||||
"buff.desc.wet": "The ground rejects your feet, making it hard to stop.",
|
||||
"buff.title.ensnared": "Ensnared",
|
||||
"buff.desc.ensnared": "Vines grasp at your legs, impeding your movement.",
|
||||
// Buffs stats
|
||||
"buff.stat.health": "Restores {str_total} Health",
|
||||
"buff.stat.increase_max_stamina": "Raises Maximum Stamina by {strength}",
|
||||
|
@ -197,6 +197,7 @@ lazy_static! {
|
||||
BuffKind::Crippled => "crippled",
|
||||
BuffKind::Frozen => "frozen",
|
||||
BuffKind::Wet => "wet",
|
||||
BuffKind::Ensnared => "ensnared",
|
||||
};
|
||||
let mut buff_parser = HashMap::new();
|
||||
BuffKind::iter().for_each(|kind| {buff_parser.insert(string_from_buff(kind).to_string(), kind);});
|
||||
|
@ -1822,7 +1822,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
achieved_radius: 0,
|
||||
achieved_radius: summon_distance.0.floor() as i32 - 1,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -659,6 +659,9 @@ impl Body {
|
||||
Body::Object(object::Body::HaniwaSentry) => true,
|
||||
_ => false,
|
||||
},
|
||||
BuffKind::Ensnared => {
|
||||
matches!(self, Body::BipedLarge(b) if matches!(b.species, biped_large::Species::Harvester))
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ pub enum BuffKind {
|
||||
/// Strength scales the friction you ignore non-linearly. 0.5 is 50% ground
|
||||
/// friction, 1.0 is 33% ground friction.
|
||||
Wet,
|
||||
/// Makes you move slower.
|
||||
/// Strength scales the movement speed debuff non-linearly. 0.5 is 50%
|
||||
/// speed, 1.0 is 33% speed.
|
||||
Ensnared,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@ -91,6 +95,7 @@ impl BuffKind {
|
||||
BuffKind::Frenzied => true,
|
||||
BuffKind::Frozen => false,
|
||||
BuffKind::Wet => false,
|
||||
BuffKind::Ensnared => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,6 +324,10 @@ impl Buff {
|
||||
vec![BuffEffect::GroundFriction(1.0 - nn_scaling(data.strength))],
|
||||
data.duration,
|
||||
),
|
||||
BuffKind::Ensnared => (
|
||||
vec![BuffEffect::MovementSpeed(1.0 - nn_scaling(data.strength))],
|
||||
data.duration,
|
||||
),
|
||||
};
|
||||
Buff {
|
||||
kind,
|
||||
|
@ -592,7 +592,7 @@ pub fn handle_jump(data: &JoinData, update: &mut StateUpdate, strength: f32) ->
|
||||
.map(|impulse| {
|
||||
update.local_events.push_front(LocalEvent::Jump(
|
||||
data.entity,
|
||||
strength * impulse / data.mass.0,
|
||||
strength * impulse / data.mass.0 * data.stats.move_speed_modifier,
|
||||
));
|
||||
})
|
||||
.is_some()
|
||||
|
@ -1,11 +1,15 @@
|
||||
use common::{
|
||||
comp::{
|
||||
buff::{
|
||||
Buff, BuffCategory, BuffChange, BuffData, BuffEffect, BuffId, BuffKind, BuffSource,
|
||||
Buffs,
|
||||
},
|
||||
fluid_dynamics::{Fluid, LiquidKind},
|
||||
Buff, BuffCategory, BuffChange, BuffData, BuffEffect, BuffId, BuffKind, BuffSource, Buffs,
|
||||
Energy, Health, HealthChange, HealthSource, Inventory, ModifierKind, PhysicsState, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
resources::DeltaTime,
|
||||
terrain::SpriteKind,
|
||||
Damage, DamageSource,
|
||||
};
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
@ -55,25 +59,52 @@ impl<'a> System<'a> for Sys {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let in_fluid = physics_state.and_then(|p| p.in_fluid);
|
||||
|
||||
if matches!(
|
||||
in_fluid,
|
||||
Some(Fluid::Liquid {
|
||||
kind: LiquidKind::Lava,
|
||||
..
|
||||
})
|
||||
) && !buff_comp.contains(BuffKind::Burning)
|
||||
{
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity,
|
||||
buff_change: BuffChange::Add(Buff::new(
|
||||
BuffKind::Burning,
|
||||
BuffData::new(200.0, None),
|
||||
vec![BuffCategory::Natural],
|
||||
BuffSource::World,
|
||||
)),
|
||||
});
|
||||
// Apply buffs to entity based off of their current physics_state
|
||||
if let Some(physics_state) = physics_state {
|
||||
if matches!(
|
||||
physics_state.on_ground.and_then(|b| b.get_sprite()),
|
||||
Some(SpriteKind::EnsnaringVines)
|
||||
) {
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity,
|
||||
buff_change: BuffChange::Add(Buff::new(
|
||||
BuffKind::Ensnared,
|
||||
BuffData::new(1.5, Some(Duration::from_secs_f32(1.0))),
|
||||
Vec::new(),
|
||||
BuffSource::World,
|
||||
)),
|
||||
});
|
||||
}
|
||||
if matches!(
|
||||
physics_state.in_fluid,
|
||||
Some(Fluid::Liquid {
|
||||
kind: LiquidKind::Lava,
|
||||
..
|
||||
})
|
||||
) {
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity,
|
||||
buff_change: BuffChange::Add(Buff::new(
|
||||
BuffKind::Burning,
|
||||
BuffData::new(200.0, None),
|
||||
vec![BuffCategory::Natural],
|
||||
BuffSource::World,
|
||||
)),
|
||||
});
|
||||
} else if matches!(
|
||||
physics_state.in_fluid,
|
||||
Some(Fluid::Liquid {
|
||||
kind: LiquidKind::Water,
|
||||
..
|
||||
})
|
||||
) {
|
||||
if buff_comp.kinds.contains_key(&BuffKind::Burning) {
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity,
|
||||
buff_change: BuffChange::RemoveByKind(BuffKind::Burning),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (buff_comp_kinds, buff_comp_buffs): (
|
||||
@ -90,14 +121,14 @@ impl<'a> System<'a> for Sys {
|
||||
if let Some((Some(buff), id)) =
|
||||
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
||||
{
|
||||
tick_buff(*id, buff, dt, in_fluid, |id| expired_buffs.push(id));
|
||||
tick_buff(*id, buff, dt, |id| expired_buffs.push(id));
|
||||
}
|
||||
} else {
|
||||
for (id, buff) in buff_comp_buffs
|
||||
.iter_mut()
|
||||
.filter(|(i, _)| ids.iter().any(|id| id == *i))
|
||||
{
|
||||
tick_buff(*id, buff, dt, in_fluid, |id| expired_buffs.push(id));
|
||||
tick_buff(*id, buff, dt, |id| expired_buffs.push(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,7 +288,6 @@ 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
|
||||
@ -269,19 +299,6 @@ fn tick_buff(
|
||||
return;
|
||||
}
|
||||
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::Liquid {
|
||||
kind: LiquidKind::Water,
|
||||
..
|
||||
})
|
||||
)
|
||||
{
|
||||
*remaining_time = Duration::default();
|
||||
}
|
||||
|
||||
if let Some(new_duration) = remaining_time.checked_sub(Duration::from_secs_f32(dt)) {
|
||||
// The buff still continues.
|
||||
*remaining_time = new_duration;
|
||||
|
@ -10,7 +10,7 @@ use common::{
|
||||
outcome::Outcome,
|
||||
resources::DeltaTime,
|
||||
states,
|
||||
terrain::{Block, SpriteKind, TerrainGrid},
|
||||
terrain::{Block, TerrainGrid},
|
||||
uid::Uid,
|
||||
util::{Projection, SpatialGrid},
|
||||
vol::{BaseVol, ReadVol},
|
||||
@ -1596,13 +1596,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
||||
}
|
||||
}
|
||||
physics_state.on_wall = on_wall;
|
||||
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier)
|
||||
* physics_state
|
||||
.on_ground
|
||||
.map_or(1.0, |b| match b.get_sprite() {
|
||||
Some(SpriteKind::EnsnaringVines) => 5.0,
|
||||
_ => 1.0,
|
||||
});
|
||||
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier);
|
||||
if physics_state.on_ground.is_some() || (physics_state.on_wall.is_some() && climbing) {
|
||||
vel.0 *= (1.0 - FRIC_GROUND.min(1.0) * fric_mod).powf(dt.0 * 60.0);
|
||||
physics_state.ground_vel = ground_vel;
|
||||
|
@ -6,7 +6,7 @@ use common::{
|
||||
Ori, PhysicsState,
|
||||
},
|
||||
states,
|
||||
terrain::BlockKind,
|
||||
terrain::{Block, BlockKind},
|
||||
};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
@ -95,7 +95,7 @@ fn maps_idle() {
|
||||
let result = MovementEventMapper::map_movement_event(
|
||||
&CharacterState::Idle {},
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
&PreviousEntityState {
|
||||
@ -117,7 +117,7 @@ fn maps_run_with_sufficient_velocity() {
|
||||
let result = MovementEventMapper::map_movement_event(
|
||||
&CharacterState::Idle {},
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
&PreviousEntityState {
|
||||
@ -139,7 +139,7 @@ fn does_not_map_run_with_insufficient_velocity() {
|
||||
let result = MovementEventMapper::map_movement_event(
|
||||
&CharacterState::Idle {},
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
&PreviousEntityState {
|
||||
@ -194,7 +194,7 @@ fn maps_roll() {
|
||||
was_combo: None,
|
||||
}),
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
&PreviousEntityState {
|
||||
@ -216,7 +216,7 @@ fn maps_land_on_ground_to_run() {
|
||||
let result = MovementEventMapper::map_movement_event(
|
||||
&CharacterState::Idle {},
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
&PreviousEntityState {
|
||||
@ -296,7 +296,7 @@ fn maps_glider_close_when_landing() {
|
||||
let result = MovementEventMapper::map_movement_event(
|
||||
&CharacterState::Idle {},
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
&PreviousEntityState {
|
||||
@ -317,7 +317,7 @@ fn maps_glider_close_when_landing() {
|
||||
fn maps_quadrupeds_running() {
|
||||
let result = MovementEventMapper::map_non_humanoid_movement_event(
|
||||
&PhysicsState {
|
||||
on_ground: true,
|
||||
on_ground: Some(Block::empty()),
|
||||
..Default::default()
|
||||
},
|
||||
Vec3::new(0.5, 0.8, 0.0),
|
||||
|
@ -769,7 +769,7 @@ fn insert_killing_buff(buff: BuffKind, localized_strings: &Localization, templat
|
||||
tracing::error!("Player was killed by a positive buff!");
|
||||
localized_strings.get("hud.outcome.mysterious")
|
||||
},
|
||||
BuffKind::Wet => {
|
||||
BuffKind::Wet | BuffKind::Ensnared => {
|
||||
tracing::error!("Player was killed by a debuff that doesn't do damage!");
|
||||
localized_strings.get("hud.outcome.mysterious")
|
||||
},
|
||||
|
@ -3822,6 +3822,7 @@ pub fn get_buff_image(buff: BuffKind, imgs: &Imgs) -> conrod_core::image::Id {
|
||||
BuffKind::Crippled { .. } => imgs.debuff_crippled_0,
|
||||
BuffKind::Frozen { .. } => imgs.debuff_frozen_0,
|
||||
BuffKind::Wet { .. } => imgs.debuff_wet_0,
|
||||
BuffKind::Ensnared { .. } => imgs.debuff_crippled_0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3844,6 +3845,7 @@ pub fn get_buff_title(buff: BuffKind, localized_strings: &Localization) -> &str
|
||||
BuffKind::Crippled { .. } => localized_strings.get("buff.title.crippled"),
|
||||
BuffKind::Frozen { .. } => localized_strings.get("buff.title.frozen"),
|
||||
BuffKind::Wet { .. } => localized_strings.get("buff.title.wet"),
|
||||
BuffKind::Ensnared { .. } => localized_strings.get("buff.title.ensnared"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3878,6 +3880,7 @@ pub fn get_buff_desc(buff: BuffKind, data: BuffData, localized_strings: &Localiz
|
||||
BuffKind::Crippled { .. } => Cow::Borrowed(localized_strings.get("buff.desc.crippled")),
|
||||
BuffKind::Frozen { .. } => Cow::Borrowed(localized_strings.get("buff.desc.frozen")),
|
||||
BuffKind::Wet { .. } => Cow::Borrowed(localized_strings.get("buff.desc.wet")),
|
||||
BuffKind::Ensnared { .. } => Cow::Borrowed(localized_strings.get("buff.desc.ensnared")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> String {
|
||||
| BuffKind::Crippled
|
||||
| BuffKind::Frenzied
|
||||
| BuffKind::Frozen
|
||||
| BuffKind::Wet => continue,
|
||||
| BuffKind::Wet
|
||||
| BuffKind::Ensnared => continue,
|
||||
};
|
||||
|
||||
write!(&mut description, "{}", buff_desc).unwrap();
|
||||
@ -156,7 +157,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> String {
|
||||
| BuffKind::Crippled
|
||||
| BuffKind::Frenzied
|
||||
| BuffKind::Frozen
|
||||
| BuffKind::Wet => continue,
|
||||
| BuffKind::Wet
|
||||
| BuffKind::Ensnared => continue,
|
||||
}
|
||||
} else if let BuffKind::Saturation | BuffKind::Regeneration = buff.kind {
|
||||
i18n.get("buff.text.every_second").to_string()
|
||||
|
Loading…
Reference in New Issue
Block a user