From 6f00d556ad3e8d839f02a8d48201ddc96ec612b6 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 9 May 2021 16:18:36 -0500 Subject: [PATCH] Added equip slots for other weapons. --- common/src/combat.rs | 8 +- common/src/comp/inventory/loadout.rs | 6 +- common/src/comp/inventory/loadout_builder.rs | 72 ++++++++++-------- common/src/comp/inventory/mod.rs | 7 +- common/src/comp/inventory/slot.rs | 12 ++- common/src/lib.rs | 1 + common/src/states/utils.rs | 74 ++++++++++++++----- common/src/states/wielding.rs | 9 ++- common/systems/src/character_behavior.rs | 16 +++- server/src/character_creator.rs | 2 +- server/src/events/interaction.rs | 8 +- server/src/migrations/V37__equip_slots.sql | 8 ++ server/src/sys/agent.rs | 2 +- .../src/audio/sfx/event_mapper/combat/mod.rs | 2 +- voxygen/src/hud/bag.rs | 8 +- voxygen/src/hud/hotbar.rs | 21 +++--- voxygen/src/hud/skillbar.rs | 22 +++--- voxygen/src/hud/slots.rs | 20 ++--- voxygen/src/menu/char_selection/ui/mod.rs | 4 +- voxygen/src/scene/figure/cache.rs | 4 +- voxygen/src/scene/figure/mod.rs | 4 +- voxygen/src/scene/simple.rs | 4 +- voxygen/src/session/mod.rs | 2 +- 23 files changed, 197 insertions(+), 119 deletions(-) create mode 100644 server/src/migrations/V37__equip_slots.sql diff --git a/common/src/combat.rs b/common/src/combat.rs index d57e219e96..4755f3d170 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -805,8 +805,8 @@ fn equipped_item_and_tool(inv: &Inventory, slot: EquipSlot) -> Option<(&Item, &T #[cfg(not(target_arch = "wasm32"))] pub fn get_weapons(inv: &Inventory) -> (Option, Option) { ( - equipped_item_and_tool(inv, EquipSlot::Mainhand).map(|(_, tool)| tool.kind), - equipped_item_and_tool(inv, EquipSlot::Offhand).map(|(_, tool)| tool.kind), + equipped_item_and_tool(inv, EquipSlot::ActiveMainhand).map(|(_, tool)| tool.kind), + equipped_item_and_tool(inv, EquipSlot::ActiveOffhand).map(|(_, tool)| tool.kind), ) } @@ -845,14 +845,14 @@ fn weapon_skills(inventory: &Inventory, skill_set: &SkillSet) -> f32 { fn get_weapon_rating(inventory: &Inventory, msm: &MaterialStatManifest) -> f32 { let mainhand_rating = - if let Some((item, _)) = equipped_item_and_tool(inventory, EquipSlot::Mainhand) { + if let Some((item, _)) = equipped_item_and_tool(inventory, EquipSlot::ActiveMainhand) { weapon_rating(item, msm) } else { 0.0 }; let offhand_rating = - if let Some((item, _)) = equipped_item_and_tool(inventory, EquipSlot::Offhand) { + if let Some((item, _)) = equipped_item_and_tool(inventory, EquipSlot::ActiveOffhand) { weapon_rating(item, msm) } else { 0.0 diff --git a/common/src/comp/inventory/loadout.rs b/common/src/comp/inventory/loadout.rs index e095e401e2..c4b6566900 100644 --- a/common/src/comp/inventory/loadout.rs +++ b/common/src/comp/inventory/loadout.rs @@ -75,8 +75,10 @@ impl Loadout { (EquipSlot::Armor(ArmorSlot::Bag2), "bag2".to_string()), (EquipSlot::Armor(ArmorSlot::Bag3), "bag3".to_string()), (EquipSlot::Armor(ArmorSlot::Bag4), "bag4".to_string()), - (EquipSlot::Mainhand, "active_item".to_string()), - (EquipSlot::Offhand, "second_item".to_string()), + (EquipSlot::ActiveMainhand, "active_mainhand".to_string()), + (EquipSlot::ActiveOffhand, "active_offhand".to_string()), + (EquipSlot::InactiveMainhand, "inactive_mainhand".to_string()), + (EquipSlot::InactiveOffhand, "inactive_offhand".to_string()), ] .into_iter() .map(|(equip_slot, persistence_key)| LoadoutSlot::new(equip_slot, persistence_key)) diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index be0c2728c7..030851e417 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -30,7 +30,7 @@ use tracing::warn; /// // Build a loadout with character starter defaults and a specific sword with default sword abilities /// let loadout = LoadoutBuilder::new() /// .defaults() -/// .active_item(Some(Item::new_from_asset_expect("common.items.weapons.sword.steel-8"))) +/// .active_mainhand(Some(Item::new_from_asset_expect("common.items.weapons.sword.steel-8"))) /// .build(); /// ``` #[derive(Clone)] @@ -376,7 +376,7 @@ impl LoadoutBuilder { match config { Adlet => match active_tool_kind { Some(ToolKind::Bow) => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.adlet.head.adlet_bow", ))) @@ -397,7 +397,7 @@ impl LoadoutBuilder { ))) .build(), Some(ToolKind::Spear) | Some(ToolKind::Staff) => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.adlet.head.adlet_spear", ))) @@ -417,11 +417,11 @@ impl LoadoutBuilder { "common.items.npc_armor.biped_small.adlet.tail.adlet", ))) .build(), - _ => LoadoutBuilder::new().active_item(active_item).build(), + _ => LoadoutBuilder::new().active_mainhand(active_item).build(), }, Gnarling => match active_tool_kind { Some(ToolKind::Bow) => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.gnarling.head.gnarling", ))) @@ -442,7 +442,7 @@ impl LoadoutBuilder { ))) .build(), Some(ToolKind::Staff) => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.gnarling.head.gnarling", ))) @@ -463,7 +463,7 @@ impl LoadoutBuilder { ))) .build(), Some(ToolKind::Spear) => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.gnarling.head.gnarling", ))) @@ -480,10 +480,10 @@ impl LoadoutBuilder { "common.items.npc_armor.biped_small.gnarling.pants.gnarling", ))) .build(), - _ => LoadoutBuilder::new().active_item(active_item).build(), + _ => LoadoutBuilder::new().active_mainhand(active_item).build(), }, Sahagin => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.sahagin.head.sahagin", ))) @@ -504,7 +504,7 @@ impl LoadoutBuilder { ))) .build(), Haniwa => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.haniwa.head.haniwa", ))) @@ -522,7 +522,7 @@ impl LoadoutBuilder { ))) .build(), Myrmidon => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.myrmidon.head.myrmidon", ))) @@ -543,7 +543,7 @@ impl LoadoutBuilder { ))) .build(), Husk => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .head(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_small.husk.head.husk", ))) @@ -561,7 +561,7 @@ impl LoadoutBuilder { ))) .build(), Guard => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.leather_plate.shoulder", ))) @@ -703,7 +703,7 @@ impl LoadoutBuilder { } } LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.twigsflowers.shoulder", ))) @@ -742,7 +742,7 @@ impl LoadoutBuilder { .build() }, Outcast => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.cloth_purple.shoulder", ))) @@ -767,7 +767,7 @@ impl LoadoutBuilder { }) .build(), Highwayman => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.swift.shoulder", ))) @@ -795,7 +795,7 @@ impl LoadoutBuilder { ))) .build(), Bandit => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.assassin.shoulder", ))) @@ -823,7 +823,7 @@ impl LoadoutBuilder { ))) .build(), CultistNovice => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.steel.shoulder", ))) @@ -854,7 +854,7 @@ impl LoadoutBuilder { ))) .build(), CultistAcolyte => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.cultist.shoulder", ))) @@ -885,7 +885,7 @@ impl LoadoutBuilder { ))) .build(), Warlord => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.warlord.shoulder", ))) @@ -916,7 +916,7 @@ impl LoadoutBuilder { ))) .build(), Warlock => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .shoulder(Some(Item::new_from_asset_expect( "common.items.armor.warlock.shoulder", ))) @@ -947,7 +947,7 @@ impl LoadoutBuilder { ))) .build(), Villager => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .chest(Some(Item::new_from_asset_expect( match rand::thread_rng().gen_range(0..10) { 0 => "common.items.armor.misc.chest.worker_green_0", @@ -981,36 +981,46 @@ impl LoadoutBuilder { match body { Body::BipedLarge(b) => match b.species { biped_large::Species::Mindflayer => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .chest(Some(Item::new_from_asset_expect( "common.items.npc_armor.biped_large.mindflayer", ))) .build(), - _ => LoadoutBuilder::new().active_item(active_item).build(), + _ => LoadoutBuilder::new().active_mainhand(active_item).build(), }, Body::Golem(g) => match g.species { golem::Species::ClayGolem => LoadoutBuilder::new() - .active_item(active_item) + .active_mainhand(active_item) .chest(Some(Item::new_from_asset_expect( "common.items.npc_armor.golem.claygolem", ))) .build(), - _ => LoadoutBuilder::new().active_item(active_item).build(), + _ => LoadoutBuilder::new().active_mainhand(active_item).build(), }, - _ => LoadoutBuilder::new().active_item(active_item).build(), + _ => LoadoutBuilder::new().active_mainhand(active_item).build(), } }; Self(loadout) } - pub fn active_item(mut self, item: Option) -> Self { - self.0.swap(EquipSlot::Mainhand, item); + pub fn active_mainhand(mut self, item: Option) -> Self { + self.0.swap(EquipSlot::ActiveMainhand, item); self } - pub fn second_item(mut self, item: Option) -> Self { - self.0.swap(EquipSlot::Offhand, item); + pub fn active_offhand(mut self, item: Option) -> Self { + self.0.swap(EquipSlot::ActiveOffhand, item); + self + } + + pub fn inactive_mainhand(mut self, item: Option) -> Self { + self.0.swap(EquipSlot::InactiveMainhand, item); + self + } + + pub fn inactive_offhand(mut self, item: Option) -> Self { + self.0.swap(EquipSlot::InactiveOffhand, item); self } diff --git a/common/src/comp/inventory/mod.rs b/common/src/comp/inventory/mod.rs index 8b9108e016..3fd8caa2ed 100644 --- a/common/src/comp/inventory/mod.rs +++ b/common/src/comp/inventory/mod.rs @@ -553,10 +553,11 @@ impl Inventory { self.get(inv_slot) .and_then(|item| self.loadout.get_slot_to_equip_into(item.kind())) .map(|equip_slot| { - // Special case when equipping into main hand - swap with offhand first - if equip_slot == EquipSlot::Mainhand { + // Special case when equipping into active main hand - swap with active offhand + // first + if equip_slot == EquipSlot::ActiveMainhand { self.loadout - .swap_slots(EquipSlot::Mainhand, EquipSlot::Offhand); + .swap_slots(EquipSlot::ActiveMainhand, EquipSlot::InactiveMainhand); } self.swap_inventory_loadout(inv_slot, equip_slot) diff --git a/common/src/comp/inventory/slot.rs b/common/src/comp/inventory/slot.rs index 4a5ad3b97a..ec3319514a 100644 --- a/common/src/comp/inventory/slot.rs +++ b/common/src/comp/inventory/slot.rs @@ -81,8 +81,10 @@ impl From for SlotId { #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize)] pub enum EquipSlot { Armor(ArmorSlot), - Mainhand, - Offhand, + ActiveMainhand, + ActiveOffhand, + InactiveMainhand, + InactiveOffhand, Lantern, Glider, } @@ -120,8 +122,10 @@ impl EquipSlot { pub fn can_hold(self, item_kind: &item::ItemKind) -> bool { match (self, item_kind) { (Self::Armor(slot), ItemKind::Armor(armor::Armor { kind, .. })) => slot.can_hold(kind), - (Self::Mainhand, ItemKind::Tool(_)) => true, - (Self::Offhand, ItemKind::Tool(_)) => true, + (Self::ActiveMainhand, ItemKind::Tool(_)) => true, + (Self::ActiveOffhand, ItemKind::Tool(_)) => true, + (Self::InactiveMainhand, ItemKind::Tool(_)) => true, + (Self::InactiveOffhand, ItemKind::Tool(_)) => true, (Self::Lantern, ItemKind::Lantern(_)) => true, (Self::Glider, ItemKind::Glider(_)) => true, _ => false, diff --git a/common/src/lib.rs b/common/src/lib.rs index b561bf0720..132fee892a 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -14,6 +14,7 @@ option_expect_none, option_unwrap_none, option_zip, + or_patterns, trait_alias, type_alias_impl_trait )] diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 1547bc9838..880fc594e1 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -440,14 +440,34 @@ pub fn handle_wield(data: &JoinData, update: &mut StateUpdate) { /// If a tool is equipped, goes into Equipping state, otherwise goes to Idle pub fn attempt_wield(data: &JoinData, update: &mut StateUpdate) { - if let Some((item, ItemKind::Tool(tool))) = data - .inventory - .equipped(EquipSlot::Mainhand) - .map(|i| (i, i.kind())) - { + // Closure to get equip time provided an equip slot if a tool is equipped in + // equip slot + let equip_time = |equip_slot| { + data.inventory + .equipped(equip_slot) + .and_then(|item| match item.kind() { + ItemKind::Tool(tool) => Some((item, tool)), + _ => None, + }) + .map(|(item, tool)| tool.equip_time(data.msm, item.components())) + }; + + // Calcualtes time required to equip weapons, if weapon in mainhand and offhand, + // uses maximum duration + let mainhand_equip_time = equip_time(EquipSlot::ActiveMainhand); + let offhand_equip_time = equip_time(EquipSlot::ActiveOffhand); + let equip_time = match (mainhand_equip_time, offhand_equip_time) { + (Some(a), Some(b)) => Some(a.max(b)), + (Some(a), None) | (None, Some(a)) => Some(a), + (None, None) => None, + }; + + // Moves entity into equipping state if there is some equip time, else moves + // intantly into wield + if let Some(equip_time) = equip_time { update.character = CharacterState::Equipping(equipping::Data { static_data: equipping::StaticData { - buildup_duration: tool.equip_time(data.msm, item.components()), + buildup_duration: equip_time, }, timer: Duration::default(), }); @@ -504,7 +524,15 @@ pub fn handle_climb(data: &JoinData, update: &mut StateUpdate) -> bool { /// Checks that player can Swap Weapons and updates `Loadout` if so pub fn attempt_swap_equipped_weapons(data: &JoinData, update: &mut StateUpdate) { - if data.inventory.equipped(EquipSlot::Offhand).is_some() { + if data + .inventory + .equipped(EquipSlot::InactiveMainhand) + .is_some() + || data + .inventory + .equipped(EquipSlot::InactiveOffhand) + .is_some() + { update.swap_equipped_weapons = true; } } @@ -556,14 +584,14 @@ fn handle_ability(data: &JoinData, update: &mut StateUpdate, input: InputKind) { let no_main_hand = hands.0.is_none(); // skill_index used to select ability for the AbilityKey::Skill2 input let (equip_slot, skill_index) = if no_main_hand { - (Some(EquipSlot::Offhand), 1) + (Some(EquipSlot::ActiveOffhand), 1) } else if always_main_hand { - (Some(EquipSlot::Mainhand), 0) + (Some(EquipSlot::ActiveMainhand), 0) } else { match hands { - (Some(Hands::Two), _) => (Some(EquipSlot::Mainhand), 1), - (_, Some(Hands::One)) => (Some(EquipSlot::Offhand), 0), - (Some(Hands::One), _) => (Some(EquipSlot::Mainhand), 1), + (Some(Hands::Two), _) => (Some(EquipSlot::ActiveMainhand), 1), + (_, Some(Hands::One)) => (Some(EquipSlot::ActiveOffhand), 0), + (Some(Hands::One), _) => (Some(EquipSlot::ActiveMainhand), 1), (_, _) => (None, 0), } }; @@ -596,7 +624,11 @@ fn handle_ability(data: &JoinData, update: &mut StateUpdate, input: InputKind) { { update.character = CharacterState::from(( &ability, - AbilityInfo::from_input(data, matches!(equip_slot, EquipSlot::Offhand), input), + AbilityInfo::from_input( + data, + matches!(equip_slot, EquipSlot::ActiveOffhand), + input, + ), )); } } @@ -640,7 +672,8 @@ pub fn handle_block_input(data: &JoinData, update: &mut StateUpdate) { |equip_slot| matches!(unwrap_tool_data(data, equip_slot), Some(tool) if tool.can_block()); let hands = get_hands(data); if input_is_pressed(data, InputKind::Block) - && (can_block(EquipSlot::Mainhand) || (hands.0.is_none() && can_block(EquipSlot::Offhand))) + && (can_block(EquipSlot::ActiveMainhand) + || (hands.0.is_none() && can_block(EquipSlot::ActiveOffhand))) { let ability = CharacterAbility::default_block(); if ability.requirements_paid(data, update) { @@ -696,15 +729,18 @@ pub fn get_hands(data: &JoinData) -> (Option, Option) { None } }; - (hand(EquipSlot::Mainhand), hand(EquipSlot::Offhand)) + ( + hand(EquipSlot::ActiveMainhand), + hand(EquipSlot::ActiveOffhand), + ) } pub fn get_crit_data(data: &JoinData, ai: AbilityInfo) -> (f32, f32) { const DEFAULT_CRIT_DATA: (f32, f32) = (0.5, 1.3); use HandInfo::*; let slot = match ai.hand { - Some(TwoHanded) | Some(MainHand) => EquipSlot::Mainhand, - Some(OffHand) => EquipSlot::Offhand, + Some(TwoHanded) | Some(MainHand) => EquipSlot::ActiveMainhand, + Some(OffHand) => EquipSlot::ActiveOffhand, None => return DEFAULT_CRIT_DATA, }; if let Some(item) = data.inventory.equipped(slot) { @@ -792,9 +828,9 @@ pub struct AbilityInfo { impl AbilityInfo { pub fn from_input(data: &JoinData, from_offhand: bool, input: InputKind) -> Self { let tool_data = if from_offhand { - unwrap_tool_data(data, EquipSlot::Offhand) + unwrap_tool_data(data, EquipSlot::ActiveOffhand) } else { - unwrap_tool_data(data, EquipSlot::Mainhand) + unwrap_tool_data(data, EquipSlot::ActiveMainhand) }; let (tool, hand) = ( tool_data.map(|t| t.kind), diff --git a/common/src/states/wielding.rs b/common/src/states/wielding.rs index 4798b44834..48673483bd 100644 --- a/common/src/states/wielding.rs +++ b/common/src/states/wielding.rs @@ -60,9 +60,12 @@ impl CharacterBehavior for Data { fn manipulate_loadout(&self, data: &JoinData, inv_action: InventoryAction) -> StateUpdate { let mut update = StateUpdate::from(data); match inv_action { - InventoryAction::Drop(EquipSlot::Mainhand) - | InventoryAction::Swap(EquipSlot::Mainhand, _) - | InventoryAction::Swap(_, Slot::Equip(EquipSlot::Mainhand)) => { + InventoryAction::Drop(EquipSlot::ActiveMainhand | EquipSlot::ActiveOffhand) + | InventoryAction::Swap(EquipSlot::ActiveMainhand | EquipSlot::ActiveOffhand, _) + | InventoryAction::Swap( + _, + Slot::Equip(EquipSlot::ActiveMainhand | EquipSlot::ActiveOffhand), + ) => { update.character = CharacterState::Idle; }, _ => (), diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index a97350888b..7b9b4cb62d 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -51,12 +51,22 @@ fn incorporate_update(join: &mut JoinStruct, mut state_update: StateUpdate) { assert!( inventory .swap( - Slot::Equip(EquipSlot::Mainhand), - Slot::Equip(EquipSlot::Offhand), + Slot::Equip(EquipSlot::ActiveMainhand), + Slot::Equip(EquipSlot::InactiveMainhand), ) .first() .is_none(), - "Swapping main and offhand never results in leftover items", + "Swapping active and inactive mainhand never results in leftover items", + ); + assert!( + inventory + .swap( + Slot::Equip(EquipSlot::ActiveOffhand), + Slot::Equip(EquipSlot::InactiveOffhand), + ) + .first() + .is_none(), + "Swapping active and inactive offhand never results in leftover items", ); } } diff --git a/server/src/character_creator.rs b/server/src/character_creator.rs index 39df6e851c..fd9b896b7e 100644 --- a/server/src/character_creator.rs +++ b/server/src/character_creator.rs @@ -38,7 +38,7 @@ pub fn create_character( let loadout = LoadoutBuilder::new() .defaults() - .active_item(Some(Item::new_from_asset_expect(&tool_id))) + .active_mainhand(Some(Item::new_from_asset_expect(&tool_id))) .build(); let mut inventory = Inventory::new_with_loadout(loadout); diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs index d671b1e341..e8c4a5e0e9 100644 --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -254,15 +254,15 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possesse_uid: Uid assert!( inventory .swap( - Slot::Equip(EquipSlot::Mainhand), - Slot::Equip(EquipSlot::Offhand), + Slot::Equip(EquipSlot::ActiveMainhand), + Slot::Equip(EquipSlot::InactiveMainhand), ) .first() .is_none(), - "Swapping main and offhand never results in leftover items", + "Swapping active and inactive mainhands never results in leftover items", ); - inventory.replace_loadout_item(EquipSlot::Mainhand, Some(debug_item)); + inventory.replace_loadout_item(EquipSlot::ActiveMainhand, Some(debug_item)); } // Remove will of the entity diff --git a/server/src/migrations/V37__equip_slots.sql b/server/src/migrations/V37__equip_slots.sql new file mode 100644 index 0000000000..b9c3c0fc6a --- /dev/null +++ b/server/src/migrations/V37__equip_slots.sql @@ -0,0 +1,8 @@ +-- Sets active_item to active_mainhand and second_item to inactive_mainhand. +-- +-- second_item becomes inactive_mainhand because active_offhand is enforced to be 1h +-- and second_item was not necessarily guaranteed to be 1h. +UPDATE item +SET position = 'active_mainhand' WHERE position = 'active_item'; +UPDATE item +SET position = 'inactive_mainhand' WHERE position = 'second_item'; \ No newline at end of file diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 5182caee2d..7f7f987356 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -1568,7 +1568,7 @@ impl<'a> AgentData<'a> { let tactic = self .inventory - .equipped(EquipSlot::Mainhand) + .equipped(EquipSlot::ActiveMainhand) .as_ref() .map(|item| { if let Some(ability_spec) = item.ability_spec() { diff --git a/voxygen/src/audio/sfx/event_mapper/combat/mod.rs b/voxygen/src/audio/sfx/event_mapper/combat/mod.rs index c63f378b1d..58ec98bf46 100644 --- a/voxygen/src/audio/sfx/event_mapper/combat/mod.rs +++ b/voxygen/src/audio/sfx/event_mapper/combat/mod.rs @@ -145,7 +145,7 @@ impl CombatEventMapper { previous_state: &PreviousEntityState, inventory: &Inventory, ) -> SfxEvent { - if let Some(item) = inventory.equipped(EquipSlot::Mainhand) { + if let Some(item) = inventory.equipped(EquipSlot::ActiveMainhand) { if let ItemKind::Tool(data) = item.kind() { if character_state.is_attack() { return SfxEvent::Attack( diff --git a/voxygen/src/hud/bag.rs b/voxygen/src/hud/bag.rs index c9baa92f9b..0673f3132d 100644 --- a/voxygen/src/hud/bag.rs +++ b/voxygen/src/hud/bag.rs @@ -1154,11 +1154,11 @@ impl<'a> Widget for Bag<'a> { } // Mainhand/Left-Slot let mainhand_item = inventory - .equipped(EquipSlot::Mainhand) + .equipped(EquipSlot::ActiveMainhand) .map(|item| item.to_owned()); let slot = slot_maker - .fabricate(EquipSlot::Mainhand, [85.0; 2]) + .fabricate(EquipSlot::ActiveMainhand, [85.0; 2]) .bottom_right_with_margins_on(state.ids.back_slot, -95.0, 0.0) .with_icon(self.imgs.mainhand_bg, Vec2::new(75.0, 75.0), Some(UI_MAIN)) .filled_slot(filled_slot); @@ -1177,10 +1177,10 @@ impl<'a> Widget for Bag<'a> { } // Offhand/Right-Slot let offhand_item = inventory - .equipped(EquipSlot::Offhand) + .equipped(EquipSlot::ActiveOffhand) .map(|item| item.to_owned()); let slot = slot_maker - .fabricate(EquipSlot::Offhand, [85.0; 2]) + .fabricate(EquipSlot::ActiveOffhand, [85.0; 2]) .bottom_left_with_margins_on(state.ids.feet_slot, -95.0, 0.0) .with_icon(self.imgs.offhand_bg, Vec2::new(75.0, 75.0), Some(UI_MAIN)) .filled_slot(filled_slot); diff --git a/voxygen/src/hud/hotbar.rs b/voxygen/src/hud/hotbar.rs index 56107833de..7bfe10b8d4 100644 --- a/voxygen/src/hud/hotbar.rs +++ b/voxygen/src/hud/hotbar.rs @@ -88,9 +88,12 @@ impl State { _ => None, }; - let equip_slot = match (hands(EquipSlot::Mainhand), hands(EquipSlot::Offhand)) { - (Some(_), _) => Some(EquipSlot::Mainhand), - (_, Some(_)) => Some(EquipSlot::Offhand), + let equip_slot = match ( + hands(EquipSlot::ActiveMainhand), + hands(EquipSlot::ActiveOffhand), + ) { + (Some(_), _) => Some(EquipSlot::ActiveMainhand), + (_, Some(_)) => Some(EquipSlot::ActiveOffhand), _ => None, }; @@ -140,14 +143,14 @@ impl State { _ => None, }; - let active_tool_hands = hands(EquipSlot::Mainhand); - let second_tool_hands = hands(EquipSlot::Offhand); + let active_tool_hands = hands(EquipSlot::ActiveMainhand); + let second_tool_hands = hands(EquipSlot::ActiveOffhand); let (equip_slot, skill_index) = match (active_tool_hands, second_tool_hands) { - (Some(Hands::Two), _) => (Some(EquipSlot::Mainhand), 1), - (Some(_), Some(Hands::One)) => (Some(EquipSlot::Offhand), 0), - (Some(Hands::One), _) => (Some(EquipSlot::Mainhand), 1), - (None, Some(_)) => (Some(EquipSlot::Offhand), 1), + (Some(Hands::Two), _) => (Some(EquipSlot::ActiveMainhand), 1), + (Some(_), Some(Hands::One)) => (Some(EquipSlot::ActiveOffhand), 0), + (Some(Hands::One), _) => (Some(EquipSlot::ActiveMainhand), 1), + (None, Some(_)) => (Some(EquipSlot::ActiveOffhand), 1), (_, _) => (None, 0), }; diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs index a458a8aef8..f48eb11aa9 100644 --- a/voxygen/src/hud/skillbar.rs +++ b/voxygen/src/hud/skillbar.rs @@ -536,7 +536,7 @@ impl<'a> Widget for Skillbar<'a> { .map(|item| (item.name(), item.description())), hotbar::SlotContents::Ability3 => content_source .1 - .equipped(EquipSlot::Mainhand) + .equipped(EquipSlot::ActiveMainhand) .map(|i| i.kind()) .and_then(|kind| match kind { ItemKind::Tool(Tool { kind, .. }) => ability_description(kind), @@ -552,14 +552,14 @@ impl<'a> Widget for Skillbar<'a> { _ => None, }; - let active_tool_hands = hands(EquipSlot::Mainhand); - let second_tool_hands = hands(EquipSlot::Offhand); + let active_tool_hands = hands(EquipSlot::ActiveMainhand); + let second_tool_hands = hands(EquipSlot::ActiveOffhand); let equip_slot = match (active_tool_hands, second_tool_hands) { - (Some(Hands::Two), _) => Some(EquipSlot::Mainhand), - (Some(_), Some(Hands::One)) => Some(EquipSlot::Offhand), - (Some(Hands::One), _) => Some(EquipSlot::Mainhand), - (None, Some(_)) => Some(EquipSlot::Offhand), + (Some(Hands::Two), _) => Some(EquipSlot::ActiveMainhand), + (Some(_), Some(Hands::One)) => Some(EquipSlot::ActiveOffhand), + (Some(Hands::One), _) => Some(EquipSlot::ActiveMainhand), + (None, Some(_)) => Some(EquipSlot::ActiveOffhand), (_, _) => None, }; @@ -657,8 +657,8 @@ impl<'a> Widget for Skillbar<'a> { .right_from(state.ids.slot5, slot_offset) .set(state.ids.m1_slot_bg, ui); - let active_tool = get_item_and_tool(self.inventory, EquipSlot::Mainhand); - let second_tool = get_item_and_tool(self.inventory, EquipSlot::Offhand); + let active_tool = get_item_and_tool(self.inventory, EquipSlot::ActiveMainhand); + let second_tool = get_item_and_tool(self.inventory, EquipSlot::ActiveOffhand); let tool = match ( active_tool.map(|(_, x)| x.hands), @@ -700,8 +700,8 @@ impl<'a> Widget for Skillbar<'a> { } } - let active_tool = get_item_and_tool(self.inventory, EquipSlot::Mainhand); - let second_tool = get_item_and_tool(self.inventory, EquipSlot::Offhand); + let active_tool = get_item_and_tool(self.inventory, EquipSlot::ActiveMainhand); + let second_tool = get_item_and_tool(self.inventory, EquipSlot::ActiveOffhand); let tool = match ( active_tool.map(|(_, x)| x.hands), diff --git a/voxygen/src/hud/slots.rs b/voxygen/src/hud/slots.rs index d5b587f5ec..d77bebb153 100644 --- a/voxygen/src/hud/slots.rs +++ b/voxygen/src/hud/slots.rs @@ -143,12 +143,12 @@ impl<'a> SlotKey, HotbarImageSource<'a>> for HotbarSlot { _ => None, }; - let active_tool_hands = hands(EquipSlot::Mainhand); - let second_tool_hands = hands(EquipSlot::Offhand); + let active_tool_hands = hands(EquipSlot::ActiveMainhand); + let second_tool_hands = hands(EquipSlot::ActiveOffhand); let equip_slot = match (active_tool_hands, second_tool_hands) { - (Some(_), _) => Some(EquipSlot::Mainhand), - (None, Some(_)) => Some(EquipSlot::Offhand), + (Some(_), _) => Some(EquipSlot::ActiveMainhand), + (None, Some(_)) => Some(EquipSlot::ActiveOffhand), (_, _) => None, }; @@ -189,14 +189,14 @@ impl<'a> SlotKey, HotbarImageSource<'a>> for HotbarSlot { _ => None, }; - let active_tool_hands = hands(EquipSlot::Mainhand); - let second_tool_hands = hands(EquipSlot::Offhand); + let active_tool_hands = hands(EquipSlot::ActiveMainhand); + let second_tool_hands = hands(EquipSlot::ActiveOffhand); let (equip_slot, skill_index) = match (active_tool_hands, second_tool_hands) { - (Some(Hands::Two), _) => (Some(EquipSlot::Mainhand), 1), - (Some(_), Some(Hands::One)) => (Some(EquipSlot::Offhand), 0), - (Some(Hands::One), _) => (Some(EquipSlot::Mainhand), 1), - (None, Some(_)) => (Some(EquipSlot::Offhand), 1), + (Some(Hands::Two), _) => (Some(EquipSlot::ActiveMainhand), 1), + (Some(_), Some(Hands::One)) => (Some(EquipSlot::ActiveOffhand), 0), + (Some(Hands::One), _) => (Some(EquipSlot::ActiveMainhand), 1), + (None, Some(_)) => (Some(EquipSlot::ActiveOffhand), 1), (_, _) => (None, 0), }; diff --git a/voxygen/src/menu/char_selection/ui/mod.rs b/voxygen/src/menu/char_selection/ui/mod.rs index df028ea997..502320c95d 100644 --- a/voxygen/src/menu/char_selection/ui/mod.rs +++ b/voxygen/src/menu/char_selection/ui/mod.rs @@ -182,7 +182,7 @@ impl Mode { let loadout = LoadoutBuilder::new() .defaults() - .active_item(Some(Item::new_from_asset_expect(tool))) + .active_mainhand(Some(Item::new_from_asset_expect(tool))) .build(); let inventory = Box::new(Inventory::new_with_loadout(loadout)); @@ -1328,7 +1328,7 @@ impl Controls { { *tool = value; inventory.replace_loadout_item( - EquipSlot::Mainhand, + EquipSlot::ActiveMainhand, Some(Item::new_from_asset_expect(*tool)), ); } diff --git a/voxygen/src/scene/figure/cache.rs b/voxygen/src/scene/figure/cache.rs index 8ac24de101..c148d5a9dd 100644 --- a/voxygen/src/scene/figure/cache.rs +++ b/voxygen/src/scene/figure/cache.rs @@ -221,10 +221,10 @@ impl CharacterCacheKey { }; Some(CharacterToolKey { active: inventory - .equipped(EquipSlot::Mainhand) + .equipped(EquipSlot::ActiveMainhand) .map(tool_key_from_item), second: inventory - .equipped(EquipSlot::Offhand) + .equipped(EquipSlot::ActiveOffhand) .map(tool_key_from_item), }) } else { diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index be968bb815..b4b16a1778 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -740,9 +740,9 @@ impl FigureMgr { }; let (active_tool_kind, active_tool_hand, active_tool_spec) = - tool_info(EquipSlot::Mainhand); + tool_info(EquipSlot::ActiveMainhand); let (second_tool_kind, second_tool_hand, second_tool_spec) = - tool_info(EquipSlot::Offhand); + tool_info(EquipSlot::ActiveOffhand); let hands = (active_tool_hand, second_tool_hand); diff --git a/voxygen/src/scene/simple.rs b/voxygen/src/scene/simple.rs index 4901a5972c..2b0b0135a9 100644 --- a/voxygen/src/scene/simple.rs +++ b/voxygen/src/scene/simple.rs @@ -307,7 +307,7 @@ impl Scene { .clean(&mut self.col_lights, scene_data.tick); let active_item_kind = inventory - .and_then(|inv| inv.equipped(EquipSlot::Mainhand)) + .and_then(|inv| inv.equipped(EquipSlot::ActiveMainhand)) .map(|i| i.kind()); let (active_tool_kind, active_tool_hand) = @@ -318,7 +318,7 @@ impl Scene { }; let second_item_kind = inventory - .and_then(|inv| inv.equipped(EquipSlot::Offhand)) + .and_then(|inv| inv.equipped(EquipSlot::ActiveOffhand)) .map(|i| i.kind()); let (second_tool_kind, second_tool_hand) = diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index bbc2a76e05..647308dcf2 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -329,7 +329,7 @@ impl PlayState for SessionState { .borrow() .inventories() .get(player_entity) - .and_then(|inv| inv.equipped(EquipSlot::Mainhand)) + .and_then(|inv| inv.equipped(EquipSlot::ActiveMainhand)) .and_then(|item| item.tool()) .map_or(false, |tool| tool.kind == ToolKind::Pick) && self.client.borrow().is_wielding() == Some(true);