Item use now goes through use item character state if it is a consumable.

This commit is contained in:
Sam 2021-06-25 17:58:22 -05:00
parent 3559ce5803
commit 9ff7ecea81
2 changed files with 76 additions and 12 deletions

View File

@ -5,8 +5,9 @@ use crate::{
item::{ConsumableKind, ItemKind},
slot::Slot,
},
CharacterState, StateUpdate,
CharacterState, InventoryManip, StateUpdate,
},
event::ServerEvent,
states::behavior::{CharacterBehavior, JoinData},
};
use serde::{Deserialize, Serialize};
@ -25,6 +26,10 @@ pub struct StaticData {
pub inv_slot: Slot,
/// Kind of item used
pub item_kind: ItemUseKind,
/// Had weapon wielded
pub was_wielded: bool,
/// Was sneaking
pub was_sneak: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -36,16 +41,23 @@ pub struct Data {
pub timer: Duration,
/// What section the character stage is in
pub stage_section: StageSection,
/// Had weapon
pub was_wielded: bool,
/// Was sneaking
pub was_sneak: bool,
}
impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
match self.static_data.item_kind {
ItemUseKind::Consumable(ConsumableKind::Potion) => {
handle_orientation(data, &mut update, 1.0);
handle_move(data, &mut update, 1.0);
},
ItemUseKind::Consumable(ConsumableKind::Food) => {
handle_orientation(data, &mut update, 0.0);
handle_move(data, &mut update, 0.0);
},
}
match self.stage_section {
StageSection::Buildup => {
if self.timer < self.static_data.buildup_duration {
@ -61,6 +73,11 @@ impl CharacterBehavior for Data {
stage_section: StageSection::Use,
..*self
});
// Create inventory manipulation event
let inv_manip = InventoryManip::Use(self.static_data.inv_slot);
update
.server_events
.push_front(ServerEvent::InventoryManip(data.entity, inv_manip));
}
},
StageSection::Use => {
@ -88,9 +105,9 @@ impl CharacterBehavior for Data {
});
} else {
// Done
if self.was_wielded {
if self.static_data.was_wielded {
update.character = CharacterState::Wielding;
} else if self.was_sneak {
} else if self.static_data.was_sneak {
update.character = CharacterState::Sneak;
} else {
update.character = CharacterState::Idle;

View File

@ -2,8 +2,8 @@ use crate::{
combat,
comp::{
biped_large, biped_small,
inventory::slot::EquipSlot,
item::{Hands, ItemKind, Tool, ToolKind},
inventory::slot::{EquipSlot, Slot},
item::{ConsumableKind, Hands, ItemKind, Tool, ToolKind},
quadruped_low, quadruped_medium, quadruped_small,
skills::{Skill, SwimSkill},
theropod, Body, CharacterAbility, CharacterState, Density, InputAttr, InputKind,
@ -575,9 +575,56 @@ pub fn handle_manipulate_loadout(
update: &mut StateUpdate,
inv_action: InventoryAction,
) {
update
.server_events
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
use use_item::ItemUseKind;
if let InventoryAction::Use(Slot::Inventory(slot)) = inv_action {
// If inventory action is using a slot, and slot is in the inventory
// TODO: Do some non lazy way of handling the possibility that items equipped in
// the loadout will have effects that are desired to be non-instantaneous
if let Some(item_kind) = data
.inventory
.get(slot)
.and_then(|item| Option::<ItemUseKind>::from(item.kind()))
{
// (buildup, use, recover)
let durations = match item_kind {
ItemUseKind::Consumable(ConsumableKind::Potion) => (
Duration::from_secs_f32(0.25),
Duration::from_secs_f32(1.0),
Duration::from_secs_f32(0.25),
),
ItemUseKind::Consumable(ConsumableKind::Food) => (
Duration::from_secs_f32(1.0),
Duration::from_secs_f32(5.0),
Duration::from_secs_f32(1.0),
),
};
// If item returns a valid kind for item use, do into use item character state
update.character = CharacterState::UseItem(use_item::Data {
static_data: use_item::StaticData {
buildup_duration: durations.0,
use_duration: durations.1,
recover_duration: durations.2,
inv_slot: Slot::Inventory(slot),
item_kind,
was_wielded: matches!(data.character, CharacterState::Wielding),
was_sneak: matches!(data.character, CharacterState::Sneak),
},
timer: Duration::default(),
stage_section: StageSection::Buildup,
});
} else {
// Else emit inventory action instantnaneously
update
.server_events
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
}
} else {
// Else if inventory action is not item use, or if slot is in loadout, just do
// event instantaneously
update
.server_events
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
}
}
/// Checks that player can wield the glider and updates `CharacterState` if so