Implement potion sickness, which causes diminishing returns on healing from potions.

This commit is contained in:
Avi Weinstock 2023-01-13 19:48:59 -05:00
parent da9cd79973
commit 78845a0d73
25 changed files with 185 additions and 43 deletions

View File

@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Doors - Doors
- Debug hitboxes now scale with the `Scale` component - Debug hitboxes now scale with the `Scale` component
- Potion quaffing no longer makes characters practically immortal.
## [0.14.0] - 2023-01-07 ## [0.14.0] - 2023-01-07

View File

@ -15,6 +15,15 @@ ItemDef(
), ),
cat_ids: [Natural], cat_ids: [Natural],
)), )),
Buff((
kind: PotionSickness,
data: (
strength: 0.33,
duration: Some(( secs: 60, nanos: 0, )),
delay: Some(( secs: 1, nanos: 0, ))
),
cat_ids: [Natural],
)),
] ]
), ),
quality: High, quality: High,

View File

@ -15,6 +15,15 @@ ItemDef(
), ),
cat_ids: [Natural], cat_ids: [Natural],
)), )),
Buff((
kind: PotionSickness,
data: (
strength: 0.33,
duration: Some(( secs: 60, nanos: 0, )),
delay: Some(( secs: 1, nanos: 0, ))
),
cat_ids: [Natural],
)),
] ]
), ),
quality: Common, quality: Common,

View File

@ -15,6 +15,15 @@ ItemDef(
), ),
cat_ids: [Natural], cat_ids: [Natural],
)), )),
Buff((
kind: PotionSickness,
data: (
strength: 0.33,
duration: Some(( secs: 60, nanos: 0, )),
delay: Some(( secs: 1, nanos: 0, ))
),
cat_ids: [Natural],
)),
] ]
), ),
quality: Common, quality: Common,

View File

@ -15,6 +15,15 @@ ItemDef(
), ),
cat_ids: [Natural], cat_ids: [Natural],
)), )),
Buff((
kind: PotionSickness,
data: (
strength: 0.33,
duration: Some(( secs: 60, nanos: 0, )),
delay: Some(( secs: 1, nanos: 0, ))
),
cat_ids: [Natural],
)),
] ]
), ),
quality: Common, quality: Common,

BIN
assets/voxygen/element/de_buffs/debuff_potionsickness_0.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -67,6 +67,12 @@ buff-desc-fortitude = You can withstand staggers.
## Parried ## Parried
buff-title-parried = Parried buff-title-parried = Parried
buff-desc-parried = You were parried and now are slow to recover. buff-desc-parried = You were parried and now are slow to recover.
## Potion sickness
buff-title-potionsickness = Potion sickness
buff-desc-potionsickness = Potions heal you less after recently consuming a potion.
buff-stat-potionsickness =
Decreases the amount you heal from
subsequent potions by { $strength }%.
## Util ## Util
buff-text-over_seconds = over { $dur_secs } seconds buff-text-over_seconds = over { $dur_secs } seconds
buff-text-for_seconds = for { $dur_secs } seconds buff-text-for_seconds = for { $dur_secs } seconds

View File

@ -155,6 +155,7 @@ lazy_static! {
BuffKind::Hastened => "hastened", BuffKind::Hastened => "hastened",
BuffKind::Fortitude => "fortitude", BuffKind::Fortitude => "fortitude",
BuffKind::Parried => "parried", BuffKind::Parried => "parried",
BuffKind::PotionSickness => "potion_sickness",
}; };
let mut buff_parser = HashMap::new(); let mut buff_parser = HashMap::new();
for kind in BuffKind::iter() { for kind in BuffKind::iter() {

View File

@ -1039,6 +1039,7 @@ impl CombatBuff {
BuffData::new( BuffData::new(
self.strength.to_strength(damage, strength_modifier), self.strength.to_strength(damage, strength_modifier),
Some(Duration::from_secs_f32(self.dur_secs)), Some(Duration::from_secs_f32(self.dur_secs)),
None,
), ),
Vec::new(), Vec::new(),
source, source,

View File

@ -144,6 +144,7 @@ impl AuraBuffConstructor {
data: BuffData { data: BuffData {
strength: self.strength, strength: self.strength,
duration: self.duration.map(Duration::from_secs_f32), duration: self.duration.map(Duration::from_secs_f32),
delay: None,
}, },
category: self.category, category: self.category,
source: BuffSource::Character { by: *uid }, source: BuffSource::Character { by: *uid },

View File

@ -91,6 +91,9 @@ pub enum BuffKind {
/// Causes your attack speed to be slower to emulate the recover duration of /// Causes your attack speed to be slower to emulate the recover duration of
/// an ability being lengthened. /// an ability being lengthened.
Parried, Parried,
/// Results from drinking a potion.
/// Decreases the health gained from subsequent potions.
PotionSickness,
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -118,12 +121,21 @@ impl BuffKind {
| BuffKind::Wet | BuffKind::Wet
| BuffKind::Ensnared | BuffKind::Ensnared
| BuffKind::Poisoned | BuffKind::Poisoned
| BuffKind::Parried => false, | BuffKind::Parried
| BuffKind::PotionSickness => false,
} }
} }
/// Checks if buff should queue /// Checks if buff should queue
pub fn queues(self) -> bool { matches!(self, BuffKind::Saturation) } pub fn queues(self) -> bool { matches!(self, BuffKind::Saturation) }
/// Checks if the buff can affect other buff effects applied in the same
/// tick.
pub fn affects_subsequent_buffs(self) -> bool { matches!(self, BuffKind::PotionSickness) }
/// Checks if multiple instances of the buff should be processed, instead of
/// only the strongest.
pub fn stacks(self) -> bool { matches!(self, BuffKind::PotionSickness) }
} }
// Struct used to store data relevant to a buff // Struct used to store data relevant to a buff
@ -131,11 +143,18 @@ impl BuffKind {
pub struct BuffData { pub struct BuffData {
pub strength: f32, pub strength: f32,
pub duration: Option<Duration>, pub duration: Option<Duration>,
pub delay: Option<Duration>,
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl BuffData { impl BuffData {
pub fn new(strength: f32, duration: Option<Duration>) -> Self { Self { strength, duration } } pub fn new(strength: f32, duration: Option<Duration>, delay: Option<Duration>) -> Self {
Self {
strength,
duration,
delay,
}
}
} }
/// De/buff category ID. /// De/buff category ID.
@ -194,6 +213,8 @@ pub enum BuffEffect {
GroundFriction(f32), GroundFriction(f32),
/// Reduces poise damage taken after armor is accounted for by this fraction /// Reduces poise damage taken after armor is accounted for by this fraction
PoiseReduction(f32), PoiseReduction(f32),
/// Reduces amount healed by consumables
HealReduction { rate: f32 },
} }
/// Actual de/buff. /// Actual de/buff.
@ -212,6 +233,7 @@ pub struct Buff {
pub data: BuffData, pub data: BuffData,
pub cat_ids: Vec<BuffCategory>, pub cat_ids: Vec<BuffCategory>,
pub time: Option<Duration>, pub time: Option<Duration>,
pub delay: Option<Duration>,
pub effects: Vec<BuffEffect>, pub effects: Vec<BuffEffect>,
pub source: BuffSource, pub source: BuffSource,
} }
@ -396,12 +418,19 @@ impl Buff {
data.duration, data.duration,
), ),
BuffKind::Parried => (vec![BuffEffect::AttackSpeed(0.5)], data.duration), BuffKind::Parried => (vec![BuffEffect::AttackSpeed(0.5)], data.duration),
BuffKind::PotionSickness => (
vec![BuffEffect::HealReduction {
rate: data.strength,
}],
data.duration,
),
}; };
Buff { Buff {
kind, kind,
data, data,
cat_ids, cat_ids,
time, time,
delay: data.delay,
effects, effects,
source, source,
} }
@ -527,11 +556,17 @@ impl Buffs {
.map(move |id| (*id, &self.buffs[id])) .map(move |id| (*id, &self.buffs[id]))
} }
// Iterates through all active buffs (the most powerful buff of each kind) // Iterates through all active buffs (the most powerful buff of each
// non-stacking kind, and all of the stacking ones)
pub fn iter_active(&self) -> impl Iterator<Item = &Buff> + '_ { pub fn iter_active(&self) -> impl Iterator<Item = &Buff> + '_ {
self.kinds self.kinds.iter().flat_map(move |(kind, ids)| {
.values() if kind.stacks() {
.filter_map(move |ids| self.buffs.get(&ids[0])) Box::new(ids.iter().filter_map(|id| self.buffs.get(id)))
as Box<dyn Iterator<Item = &Buff>>
} else {
Box::new(self.buffs.get(&ids[0]).into_iter())
}
})
} }
// Gets most powerful buff of a given kind // Gets most powerful buff of a given kind

View File

@ -50,6 +50,7 @@ pub struct Stats {
pub name: String, pub name: String,
pub damage_reduction: f32, pub damage_reduction: f32,
pub poise_reduction: f32, pub poise_reduction: f32,
pub heal_multiplier: f32,
pub max_health_modifiers: StatsModifier, pub max_health_modifiers: StatsModifier,
pub move_speed_modifier: f32, pub move_speed_modifier: f32,
pub attack_speed_modifier: f32, pub attack_speed_modifier: f32,
@ -63,6 +64,7 @@ impl Stats {
name, name,
damage_reduction: 0.0, damage_reduction: 0.0,
poise_reduction: 0.0, poise_reduction: 0.0,
heal_multiplier: 1.0,
max_health_modifiers: StatsModifier::default(), max_health_modifiers: StatsModifier::default(),
move_speed_modifier: 1.0, move_speed_modifier: 1.0,
attack_speed_modifier: 1.0, attack_speed_modifier: 1.0,
@ -79,6 +81,7 @@ impl Stats {
pub fn reset_temp_modifiers(&mut self) { pub fn reset_temp_modifiers(&mut self) {
self.damage_reduction = 0.0; self.damage_reduction = 0.0;
self.poise_reduction = 0.0; self.poise_reduction = 0.0;
self.heal_multiplier = 1.0;
self.max_health_modifiers = StatsModifier::default(); self.max_health_modifiers = StatsModifier::default();
self.move_speed_modifier = 1.0; self.move_speed_modifier = 1.0;
self.attack_speed_modifier = 1.0; self.attack_speed_modifier = 1.0;

View File

@ -65,6 +65,7 @@ impl CharacterBehavior for Data {
BuffData { BuffData {
strength: self.static_data.buff_strength, strength: self.static_data.buff_strength,
duration: self.static_data.buff_duration, duration: self.static_data.buff_duration,
delay: None,
}, },
Vec::new(), Vec::new(),
BuffSource::Character { by: *data.uid }, BuffSource::Character { by: *data.uid },

View File

@ -146,7 +146,7 @@ impl<'a> System<'a> for Sys {
entity, entity,
buff_change: BuffChange::Add(Buff::new( buff_change: BuffChange::Add(Buff::new(
BuffKind::Ensnared, BuffKind::Ensnared,
BuffData::new(1.0, Some(Duration::from_secs_f32(1.0))), BuffData::new(1.0, Some(Duration::from_secs_f32(1.0)), None),
Vec::new(), Vec::new(),
BuffSource::World, BuffSource::World,
)), )),
@ -161,7 +161,7 @@ impl<'a> System<'a> for Sys {
entity, entity,
buff_change: BuffChange::Add(Buff::new( buff_change: BuffChange::Add(Buff::new(
BuffKind::Bleeding, BuffKind::Bleeding,
BuffData::new(1.0, Some(Duration::from_secs_f32(6.0))), BuffData::new(1.0, Some(Duration::from_secs_f32(6.0)), None),
Vec::new(), Vec::new(),
BuffSource::World, BuffSource::World,
)), )),
@ -179,7 +179,7 @@ impl<'a> System<'a> for Sys {
entity, entity,
buff_change: BuffChange::Add(Buff::new( buff_change: BuffChange::Add(Buff::new(
BuffKind::Burning, BuffKind::Burning,
BuffData::new(20.0, None), BuffData::new(20.0, None, None),
vec![BuffCategory::Natural], vec![BuffCategory::Natural],
BuffSource::World, BuffSource::World,
)), )),
@ -245,31 +245,56 @@ impl<'a> System<'a> for Sys {
// Iterator over the lists of buffs by kind // Iterator over the lists of buffs by kind
let buff_comp = &mut *buff_comp; let buff_comp = &mut *buff_comp;
for buff_ids in buff_comp.kinds.values() { let mut buff_kinds = buff_comp
// Get the strongest of this buff kind .kinds
if let Some(buff) = buff_comp.buffs.get_mut(&buff_ids[0]) { .iter()
// Get buff owner? .map(|(kind, ids)| (*kind, ids.clone()))
let buff_owner = if let BuffSource::Character { by: owner } = buff.source { .collect::<Vec<(BuffKind, Vec<BuffId>)>>();
Some(owner) buff_kinds.sort_by_key(|(kind, _)| {
} else { if kind.affects_subsequent_buffs() {
None 0
}; } else {
1
}
});
for (buff_kind, buff_ids) in buff_kinds.into_iter() {
let mut active_buff_ids = Vec::new();
if buff_kind.stacks() {
// Process all the buffs of this kind
active_buff_ids = buff_ids;
} else {
// Only process the strongest of this buff kind
active_buff_ids.push(buff_ids[0]);
}
for buff_id in active_buff_ids.into_iter() {
if let Some(buff) = buff_comp.buffs.get_mut(&buff_id) {
// Skip the effect of buffs whose start delay hasn't expired.
if buff.delay.is_some() {
continue;
}
// Get buff owner?
let buff_owner = if let BuffSource::Character { by: owner } = buff.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.effects { for effect in &mut buff.effects {
execute_effect( execute_effect(
effect, effect,
buff.kind, buff.kind,
buff.time, buff.time,
&read_data, &read_data,
&mut stat, &mut stat,
health, health,
energy, energy,
entity, entity,
buff_owner, buff_owner,
&mut server_emitter, &mut server_emitter,
dt, dt,
); );
}
} }
} }
} }
@ -331,7 +356,7 @@ fn execute_effect(
} else { } else {
(None, None) (None, None)
}; };
let amount = match *kind { let mut amount = match *kind {
ModifierKind::Additive => *accumulated, ModifierKind::Additive => *accumulated,
ModifierKind::Fractional => health.maximum() * *accumulated, ModifierKind::Fractional => health.maximum() * *accumulated,
}; };
@ -343,6 +368,9 @@ fn execute_effect(
DamageContributor::new(uid, read_data.groups.get(entity).cloned()) DamageContributor::new(uid, read_data.groups.get(entity).cloned())
}) })
}); });
if amount > 0.0 {
amount *= stat.heal_multiplier;
}
server_emitter.emit(ServerEvent::HealthChange { server_emitter.emit(ServerEvent::HealthChange {
entity, entity,
change: HealthChange { change: HealthChange {
@ -471,6 +499,9 @@ fn execute_effect(
BuffEffect::PoiseReduction(pr) => { BuffEffect::PoiseReduction(pr) => {
stat.poise_reduction = stat.poise_reduction.max(*pr).min(1.0); stat.poise_reduction = stat.poise_reduction.max(*pr).min(1.0);
}, },
BuffEffect::HealReduction { rate } => {
stat.heal_multiplier *= 1.0 - *rate;
},
}; };
} }
@ -483,6 +514,9 @@ fn tick_buff(id: u64, buff: &mut Buff, dt: f32, mut expire_buff: impl FnMut(u64)
{ {
return; return;
} }
if let Some(remaining_delay) = buff.delay {
buff.delay = remaining_delay.checked_sub(Duration::from_secs_f32(dt));
}
if let Some(remaining_time) = &mut buff.time { if let Some(remaining_time) = &mut buff.time {
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.

View File

@ -528,6 +528,10 @@ impl<'a> AgentData<'a> {
controller: &mut Controller, controller: &mut Controller,
relaxed: bool, relaxed: bool,
) -> bool { ) -> bool {
// Wait for potion sickness to wear off if potions are less than 20% effective.
if self.stats.map_or(1.0, |s| s.heal_multiplier) < 0.2 {
return false;
}
let healing_value = |item: &Item| { let healing_value = |item: &Item| {
let mut value = 0.0; let mut value = 0.0;

View File

@ -45,6 +45,7 @@ pub struct AgentData<'a> {
pub active_abilities: &'a ActiveAbilities, pub active_abilities: &'a ActiveAbilities,
pub combo: Option<&'a Combo>, pub combo: Option<&'a Combo>,
pub buffs: Option<&'a Buffs>, pub buffs: Option<&'a Buffs>,
pub stats: Option<&'a Stats>,
pub poise: Option<&'a Poise>, pub poise: Option<&'a Poise>,
pub cached_spatial_grid: &'a common::CachedSpatialGrid, pub cached_spatial_grid: &'a common::CachedSpatialGrid,
pub msm: &'a MaterialStatManifest, pub msm: &'a MaterialStatManifest,

View File

@ -1477,7 +1477,7 @@ fn handle_spawn_campfire(
Aura::new( Aura::new(
AuraKind::Buff { AuraKind::Buff {
kind: BuffKind::CampfireHeal, kind: BuffKind::CampfireHeal,
data: BuffData::new(0.02, Some(Duration::from_secs(1))), data: BuffData::new(0.02, Some(Duration::from_secs(1)), None),
category: BuffCategory::Natural, category: BuffCategory::Natural,
source: BuffSource::World, source: BuffSource::World,
}, },
@ -1488,7 +1488,7 @@ fn handle_spawn_campfire(
Aura::new( Aura::new(
AuraKind::Buff { AuraKind::Buff {
kind: BuffKind::Burning, kind: BuffKind::Burning,
data: BuffData::new(2.0, Some(Duration::from_secs(10))), data: BuffData::new(2.0, Some(Duration::from_secs(10)), None),
category: BuffCategory::Natural, category: BuffCategory::Natural,
source: BuffSource::World, source: BuffSource::World,
}, },
@ -3520,7 +3520,7 @@ fn handle_apply_buff(
if let (Some(buff), strength, duration) = parse_cmd_args!(args, String, f32, f64) { if let (Some(buff), strength, duration) = parse_cmd_args!(args, String, f32, f64) {
let strength = strength.unwrap_or(0.01); let strength = strength.unwrap_or(0.01);
let duration = Duration::from_secs_f64(duration.unwrap_or(1.0)); let duration = Duration::from_secs_f64(duration.unwrap_or(1.0));
let buffdata = BuffData::new(strength, Some(duration)); let buffdata = BuffData::new(strength, Some(duration), None);
if buff != "all" { if buff != "all" {
cast_buff(&buff, buffdata, server, target) cast_buff(&buff, buffdata, server, target)
} else { } else {

View File

@ -285,7 +285,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
Aura::new( Aura::new(
AuraKind::Buff { AuraKind::Buff {
kind: BuffKind::CampfireHeal, kind: BuffKind::CampfireHeal,
data: BuffData::new(0.02, Some(Duration::from_secs(1))), data: BuffData::new(0.02, Some(Duration::from_secs(1)), None),
category: BuffCategory::Natural, category: BuffCategory::Natural,
source: BuffSource::World, source: BuffSource::World,
}, },
@ -296,7 +296,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
Aura::new( Aura::new(
AuraKind::Buff { AuraKind::Buff {
kind: BuffKind::Burning, kind: BuffKind::Burning,
data: BuffData::new(2.0, Some(Duration::from_secs(10))), data: BuffData::new(2.0, Some(Duration::from_secs(10)), None),
category: BuffCategory::Natural, category: BuffCategory::Natural,
source: BuffSource::World, source: BuffSource::World,
}, },

View File

@ -1306,7 +1306,7 @@ pub fn handle_parry_hook(server: &Server, defender: EcsEntity, attacker: Option<
.map_or(0.5, |dur| dur.as_secs_f32()) .map_or(0.5, |dur| dur.as_secs_f32())
.max(0.5) .max(0.5)
.mul(2.0); .mul(2.0);
let data = buff::BuffData::new(1.0, Some(Duration::from_secs_f32(duration))); let data = buff::BuffData::new(1.0, Some(Duration::from_secs_f32(duration)), None);
let source = if let Some(uid) = ecs.read_storage::<Uid>().get(defender) { let source = if let Some(uid) = ecs.read_storage::<Uid>().get(defender) {
BuffSource::Character { by: *uid } BuffSource::Character { by: *uid }
} else { } else {

View File

@ -421,7 +421,7 @@ impl StateExt for State {
.with(Auras::new(vec![Aura::new( .with(Auras::new(vec![Aura::new(
AuraKind::Buff { AuraKind::Buff {
kind: BuffKind::Invulnerability, kind: BuffKind::Invulnerability,
data: BuffData::new(1.0, Some(Duration::from_secs(1))), data: BuffData::new(1.0, Some(Duration::from_secs(1)), None),
category: BuffCategory::Natural, category: BuffCategory::Natural,
source: BuffSource::World, source: BuffSource::World,
}, },

View File

@ -199,6 +199,7 @@ impl<'a> System<'a> for Sys {
active_abilities, active_abilities,
combo, combo,
buffs: read_data.buffs.get(entity), buffs: read_data.buffs.get(entity),
stats: read_data.stats.get(entity),
cached_spatial_grid: &read_data.cached_spatial_grid, cached_spatial_grid: &read_data.cached_spatial_grid,
msm: &read_data.msm, msm: &read_data.msm,
poise: read_data.poises.get(entity), poise: read_data.poises.get(entity),

View File

@ -106,7 +106,11 @@ pub fn localize_chat_message(
tracing::error!("Player was killed by a positive buff!"); tracing::error!("Player was killed by a positive buff!");
"hud-outcome-mysterious" "hud-outcome-mysterious"
}, },
BuffKind::Wet | BuffKind::Ensnared | BuffKind::Poisoned | BuffKind::Parried => { BuffKind::Wet
| BuffKind::Ensnared
| BuffKind::Poisoned
| BuffKind::Parried
| BuffKind::PotionSickness => {
tracing::error!("Player was killed by a debuff that doesn't do damage!"); tracing::error!("Player was killed by a debuff that doesn't do damage!");
"hud-outcome-mysterious" "hud-outcome-mysterious"
}, },

View File

@ -697,6 +697,7 @@ image_ids! {
debuff_ensnared_0: "voxygen.element.de_buffs.debuff_ensnared_0", debuff_ensnared_0: "voxygen.element.de_buffs.debuff_ensnared_0",
debuff_poisoned_0: "voxygen.element.de_buffs.debuff_poisoned_0", debuff_poisoned_0: "voxygen.element.de_buffs.debuff_poisoned_0",
debuff_parried_0: "voxygen.element.de_buffs.debuff_parried_0", debuff_parried_0: "voxygen.element.de_buffs.debuff_parried_0",
debuff_potionsickness_0: "voxygen.element.de_buffs.debuff_potionsickness_0",
// Animation Frames // Animation Frames
// Buff Frame // Buff Frame

View File

@ -4769,6 +4769,7 @@ pub fn get_buff_image(buff: BuffKind, imgs: &Imgs) -> conrod_core::image::Id {
BuffKind::Ensnared => imgs.debuff_ensnared_0, BuffKind::Ensnared => imgs.debuff_ensnared_0,
BuffKind::Poisoned => imgs.debuff_poisoned_0, BuffKind::Poisoned => imgs.debuff_poisoned_0,
BuffKind::Parried => imgs.debuff_parried_0, BuffKind::Parried => imgs.debuff_parried_0,
BuffKind::PotionSickness => imgs.debuff_potionsickness_0,
} }
} }
@ -4801,6 +4802,7 @@ pub fn get_buff_title(buff: BuffKind, localized_strings: &Localization) -> Cow<s
BuffKind::Ensnared { .. } => localized_strings.get_msg("buff-title-ensnared"), BuffKind::Ensnared { .. } => localized_strings.get_msg("buff-title-ensnared"),
BuffKind::Poisoned { .. } => localized_strings.get_msg("buff-title-poisoned"), BuffKind::Poisoned { .. } => localized_strings.get_msg("buff-title-poisoned"),
BuffKind::Parried { .. } => localized_strings.get_msg("buff-title-parried"), BuffKind::Parried { .. } => localized_strings.get_msg("buff-title-parried"),
BuffKind::PotionSickness { .. } => localized_strings.get_msg("buff-title-potionsickness"),
} }
} }
@ -4837,6 +4839,7 @@ pub fn get_buff_desc(buff: BuffKind, data: BuffData, localized_strings: &Localiz
BuffKind::Ensnared { .. } => localized_strings.get_msg("buff-desc-ensnared"), BuffKind::Ensnared { .. } => localized_strings.get_msg("buff-desc-ensnared"),
BuffKind::Poisoned { .. } => localized_strings.get_msg("buff-desc-poisoned"), BuffKind::Poisoned { .. } => localized_strings.get_msg("buff-desc-poisoned"),
BuffKind::Parried { .. } => localized_strings.get_msg("buff-desc-parried"), BuffKind::Parried { .. } => localized_strings.get_msg("buff-desc-parried"),
BuffKind::PotionSickness { .. } => localized_strings.get_msg("buff-desc-potionsickness"),
} }
} }

View File

@ -172,6 +172,11 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
"strength" => format_float(strength), "strength" => format_float(strength),
}) })
}, },
BuffKind::PotionSickness => {
i18n.get_msg_ctx("buff-stat-potionsickness", &i18n::fluent_args! {
"strength" => format_float(strength * 100.0),
})
},
BuffKind::Invulnerability => i18n.get_msg("buff-stat-invulnerability"), BuffKind::Invulnerability => i18n.get_msg("buff-stat-invulnerability"),
BuffKind::Bleeding BuffKind::Bleeding
| BuffKind::Burning | BuffKind::Burning
@ -199,7 +204,8 @@ pub fn consumable_desc(effects: &[Effect], i18n: &Localization) -> Vec<String> {
}), }),
BuffKind::IncreaseMaxEnergy BuffKind::IncreaseMaxEnergy
| BuffKind::IncreaseMaxHealth | BuffKind::IncreaseMaxHealth
| BuffKind::Invulnerability => { | BuffKind::Invulnerability
| BuffKind::PotionSickness => {
i18n.get_msg_ctx("buff-text-for_seconds", &i18n::fluent_args! { i18n.get_msg_ctx("buff-text-for_seconds", &i18n::fluent_args! {
"dur_secs" => dur_secs "dur_secs" => dur_secs
}) })