Maintain character state when inventory is modified

If the mainhand slot is swapped out or dropped while the character is
wielding, the character will be set to idle (same behavior). However, if
an item is picked up or used; or a non-mainhand item is dropped; or two
non-mainhand items are swapped; the character state will not be set to
idle (new behavior).

Rationale for keeping the same behavior:

Swapping a weapon out while in a wielding state can put the player in a
barehanded wielding state, which would be inconsistent with the fact
that that state can't be entered by toggling wield while barehanded.

Rationale for setting the new behavior:

Setting character state to idle was originally added because "Interact"
was mapped to right mouse button, so picking up an item with RMB would
also activate secondary attack if the player was wielding during the
interaction. Now the default keybinding for "Interact" is E, so this
isn't a problem unless the player changes their keybinding to RMB.

In addition, setting character state to idle for any inventory
manipulation may cause players to fall out of glider unexpectedly.
This commit is contained in:
Ben Frankel 2020-07-07 08:50:26 -07:00
parent e8b4b29d70
commit 823141f825

View File

@ -1,5 +1,8 @@
use crate::{
comp::{CharacterState, ControlEvent, Controller},
comp::{
slot::{EquipSlot, Slot},
CharacterState, ControlEvent, Controller, InventoryManip,
},
event::{EventBus, LocalEvent, ServerEvent},
state::DeltaTime,
sync::{Uid, UidAllocator},
@ -79,7 +82,18 @@ impl<'a> System<'a> for Sys {
server_emitter.emit(ServerEvent::ToggleLantern(entity))
},
ControlEvent::InventoryManip(manip) => {
*character_state = CharacterState::Idle;
// Unwield if a wielded equipment slot is being modified, to avoid entering
// a barehanded wielding state.
if character_state.is_wield() {
match manip {
InventoryManip::Drop(Slot::Equip(EquipSlot::Mainhand))
| InventoryManip::Swap(_, Slot::Equip(EquipSlot::Mainhand))
| InventoryManip::Swap(Slot::Equip(EquipSlot::Mainhand), _) => {
*character_state = CharacterState::Idle;
},
_ => (),
}
}
server_emitter.emit(ServerEvent::InventoryManip(entity, manip))
},
ControlEvent::Respawn => server_emitter.emit(ServerEvent::Respawn(entity)),