mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'sam/potion-tweaks' into 'master'
Potion tweaks See merge request veloren/veloren!2976
This commit is contained in:
commit
e692f49463
@ -2,14 +2,15 @@ use crate::{
|
||||
comp::{
|
||||
self,
|
||||
inventory::item::{armor::Protection, ItemKind},
|
||||
Inventory,
|
||||
CharacterState, Inventory,
|
||||
},
|
||||
states,
|
||||
util::Dir,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::ops::Mul;
|
||||
use std::{ops::Mul, time::Duration};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
@ -52,6 +53,52 @@ pub enum PoiseState {
|
||||
KnockedDown,
|
||||
}
|
||||
|
||||
impl PoiseState {
|
||||
pub fn poise_effect(&self, was_wielded: bool) -> (Option<CharacterState>, Option<f32>) {
|
||||
use states::{
|
||||
stunned::{Data, StaticData},
|
||||
utils::StageSection,
|
||||
};
|
||||
// charstate_parameters is Option<(buildup_duration, recover_duration,
|
||||
// movement_speed)>
|
||||
let (charstate_parameters, impulse) = match self {
|
||||
PoiseState::Normal => (None, None),
|
||||
PoiseState::Interrupted => (
|
||||
Some((Duration::from_millis(125), Duration::from_millis(125), 0.80)),
|
||||
None,
|
||||
),
|
||||
PoiseState::Stunned => (
|
||||
Some((Duration::from_millis(300), Duration::from_millis(300), 0.65)),
|
||||
Some(5.0),
|
||||
),
|
||||
PoiseState::Dazed => (
|
||||
Some((Duration::from_millis(600), Duration::from_millis(250), 0.45)),
|
||||
Some(10.0),
|
||||
),
|
||||
PoiseState::KnockedDown => (
|
||||
Some((Duration::from_millis(750), Duration::from_millis(500), 0.4)),
|
||||
Some(10.0),
|
||||
),
|
||||
};
|
||||
(
|
||||
charstate_parameters.map(|(buildup_duration, recover_duration, movement_speed)| {
|
||||
CharacterState::Stunned(Data {
|
||||
static_data: StaticData {
|
||||
buildup_duration,
|
||||
recover_duration,
|
||||
movement_speed,
|
||||
poise_state: *self,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
was_wielded,
|
||||
})
|
||||
}),
|
||||
impulse,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Poise {
|
||||
/// Maximum value allowed for poise before scaling
|
||||
const MAX_POISE: u16 = u16::MAX - 1;
|
||||
|
@ -7,8 +7,7 @@ use common::{
|
||||
comp::{
|
||||
self, character_state::OutputEvents, inventory::item::MaterialStatManifest, Beam, Body,
|
||||
CharacterState, Combo, Controller, Density, Energy, Health, Inventory, InventoryManip,
|
||||
Mass, Melee, Mounting, Ori, PhysicsState, Poise, PoiseState, Pos, SkillSet, StateUpdate,
|
||||
Stats, Vel,
|
||||
Mass, Melee, Mounting, Ori, PhysicsState, Poise, Pos, SkillSet, StateUpdate, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
outcome::Outcome,
|
||||
@ -21,7 +20,6 @@ use common::{
|
||||
uid::Uid,
|
||||
};
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(SystemData)]
|
||||
pub struct ReadData<'a> {
|
||||
@ -142,92 +140,22 @@ impl<'a> System<'a> for Sys {
|
||||
let was_wielded = char_state.is_wield();
|
||||
let poise_state = poise.poise_state();
|
||||
let pos = pos.0;
|
||||
match poise_state {
|
||||
PoiseState::Normal => {},
|
||||
PoiseState::Interrupted => {
|
||||
poise.reset();
|
||||
*char_state = CharacterState::Stunned(common::states::stunned::Data {
|
||||
static_data: common::states::stunned::StaticData {
|
||||
buildup_duration: Duration::from_millis(125),
|
||||
recover_duration: Duration::from_millis(125),
|
||||
movement_speed: 0.80,
|
||||
poise_state,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: common::states::utils::StageSection::Buildup,
|
||||
was_wielded,
|
||||
});
|
||||
outcomes.push(Outcome::PoiseChange {
|
||||
pos,
|
||||
state: PoiseState::Interrupted,
|
||||
});
|
||||
},
|
||||
PoiseState::Stunned => {
|
||||
poise.reset();
|
||||
*char_state = CharacterState::Stunned(common::states::stunned::Data {
|
||||
static_data: common::states::stunned::StaticData {
|
||||
buildup_duration: Duration::from_millis(300),
|
||||
recover_duration: Duration::from_millis(300),
|
||||
movement_speed: 0.65,
|
||||
poise_state,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: common::states::utils::StageSection::Buildup,
|
||||
was_wielded,
|
||||
});
|
||||
outcomes.push(Outcome::PoiseChange {
|
||||
pos,
|
||||
state: PoiseState::Stunned,
|
||||
});
|
||||
if let (Some(stunned_state), impulse_strength) =
|
||||
poise_state.poise_effect(was_wielded)
|
||||
{
|
||||
// Reset poise if there is some stunned state to apply
|
||||
poise.reset();
|
||||
*char_state = stunned_state;
|
||||
outcomes.push(Outcome::PoiseChange {
|
||||
pos,
|
||||
state: poise_state,
|
||||
});
|
||||
if let Some(impulse_strength) = impulse_strength {
|
||||
server_emitter.emit(ServerEvent::Knockback {
|
||||
entity,
|
||||
impulse: 5.0 * *poise.knockback(),
|
||||
impulse: impulse_strength * *poise.knockback(),
|
||||
});
|
||||
},
|
||||
PoiseState::Dazed => {
|
||||
poise.reset();
|
||||
*char_state = CharacterState::Stunned(common::states::stunned::Data {
|
||||
static_data: common::states::stunned::StaticData {
|
||||
buildup_duration: Duration::from_millis(600),
|
||||
recover_duration: Duration::from_millis(250),
|
||||
movement_speed: 0.45,
|
||||
poise_state,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: common::states::utils::StageSection::Buildup,
|
||||
was_wielded,
|
||||
});
|
||||
outcomes.push(Outcome::PoiseChange {
|
||||
pos,
|
||||
state: PoiseState::Dazed,
|
||||
});
|
||||
server_emitter.emit(ServerEvent::Knockback {
|
||||
entity,
|
||||
impulse: 10.0 * *poise.knockback(),
|
||||
});
|
||||
},
|
||||
PoiseState::KnockedDown => {
|
||||
poise.reset();
|
||||
*char_state = CharacterState::Stunned(common::states::stunned::Data {
|
||||
static_data: common::states::stunned::StaticData {
|
||||
buildup_duration: Duration::from_millis(750),
|
||||
recover_duration: Duration::from_millis(500),
|
||||
movement_speed: 0.4,
|
||||
poise_state,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: common::states::utils::StageSection::Buildup,
|
||||
was_wielded,
|
||||
});
|
||||
outcomes.push(Outcome::PoiseChange {
|
||||
pos,
|
||||
state: PoiseState::KnockedDown,
|
||||
});
|
||||
server_emitter.emit(ServerEvent::Knockback {
|
||||
entity,
|
||||
impulse: 10.0 * *poise.knockback(),
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,14 +1095,35 @@ pub fn handle_teleport_to(server: &Server, entity: EcsEntity, target: Uid, max_r
|
||||
pub fn handle_entity_attacked_hook(server: &Server, entity: EcsEntity) {
|
||||
let ecs = &server.state.ecs();
|
||||
let server_eventbus = ecs.read_resource::<EventBus<ServerEvent>>();
|
||||
let mut outcomes = ecs.write_resource::<Vec<Outcome>>();
|
||||
|
||||
if let Some(mut char_state) = ecs.write_storage::<CharacterState>().get_mut(entity) {
|
||||
if let (Some(mut char_state), Some(mut poise), Some(pos)) = (
|
||||
ecs.write_storage::<CharacterState>().get_mut(entity),
|
||||
ecs.write_storage::<Poise>().get_mut(entity),
|
||||
ecs.read_storage::<Pos>().get(entity),
|
||||
) {
|
||||
// Interrupt sprite interaction and item use if any attack is applied to entity
|
||||
if matches!(
|
||||
*char_state,
|
||||
CharacterState::SpriteInteract(_) | CharacterState::UseItem(_)
|
||||
) {
|
||||
*char_state = CharacterState::Idle(common::states::idle::Data { is_sneaking: false });
|
||||
let poise_state = comp::poise::PoiseState::Dazed;
|
||||
let was_wielded = char_state.is_wield();
|
||||
if let (Some(stunned_state), impulse_strength) = poise_state.poise_effect(was_wielded) {
|
||||
// Reset poise if there is some stunned state to apply
|
||||
poise.reset();
|
||||
*char_state = stunned_state;
|
||||
outcomes.push(Outcome::PoiseChange {
|
||||
pos: pos.0,
|
||||
state: poise_state,
|
||||
});
|
||||
if let Some(impulse_strength) = impulse_strength {
|
||||
server_eventbus.emit_now(ServerEvent::Knockback {
|
||||
entity,
|
||||
impulse: impulse_strength * *poise.knockback(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1173,9 +1173,12 @@ fn consumable_bags(economy: Option<&trade::SiteInformation>, rng: &mut impl Rng)
|
||||
.and_then(|e| e.unconsumed_stock.get(&Good::Food))
|
||||
.copied()
|
||||
.map_or(Some(10_000.0), |food| Some(food.max(10_000.0)));
|
||||
// Reduce amount of potions so merchants do not oversupply potions.
|
||||
// TODO: Maybe remove when merchants and their inventories are rtsim?
|
||||
let mut potions = economy
|
||||
.and_then(|e| e.unconsumed_stock.get(&Good::Potions))
|
||||
.copied();
|
||||
.copied()
|
||||
.map(|potions| potions.powf(0.25));
|
||||
|
||||
let goods = [
|
||||
(Good::Food, &mut food, &mut bag3),
|
||||
|
Loading…
Reference in New Issue
Block a user