mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed review
This commit is contained in:
parent
d0a902d918
commit
7fdfc0e71b
@ -1213,7 +1213,7 @@ impl Item {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn durability(&self) -> Option<u32> {
|
||||
pub fn durability_lost(&self) -> Option<u32> {
|
||||
self.durability_lost.map(|x| x.min(Self::MAX_DURABILITY))
|
||||
}
|
||||
|
||||
@ -1294,7 +1294,7 @@ pub trait ItemDesc {
|
||||
fn is_modular(&self) -> bool;
|
||||
fn components(&self) -> &[Item];
|
||||
fn has_durability(&self) -> bool;
|
||||
fn durability(&self) -> Option<u32>;
|
||||
fn durability_lost(&self) -> Option<u32>;
|
||||
fn stats_durability_multiplier(&self) -> DurabilityMultiplier;
|
||||
|
||||
fn tool_info(&self) -> Option<ToolKind> {
|
||||
@ -1327,7 +1327,7 @@ impl ItemDesc for Item {
|
||||
|
||||
fn has_durability(&self) -> bool { self.has_durability() }
|
||||
|
||||
fn durability(&self) -> Option<u32> { self.durability() }
|
||||
fn durability_lost(&self) -> Option<u32> { self.durability_lost() }
|
||||
|
||||
fn stats_durability_multiplier(&self) -> DurabilityMultiplier {
|
||||
self.stats_durability_multiplier()
|
||||
@ -1359,7 +1359,7 @@ impl ItemDesc for ItemDef {
|
||||
self.kind().has_durability() && self.quality != Quality::Debug
|
||||
}
|
||||
|
||||
fn durability(&self) -> Option<u32> { None }
|
||||
fn durability_lost(&self) -> Option<u32> { None }
|
||||
|
||||
fn stats_durability_multiplier(&self) -> DurabilityMultiplier { DurabilityMultiplier(1.0) }
|
||||
}
|
||||
@ -1399,7 +1399,7 @@ impl<'a, T: ItemDesc + ?Sized> ItemDesc for &'a T {
|
||||
|
||||
fn has_durability(&self) -> bool { (*self).has_durability() }
|
||||
|
||||
fn durability(&self) -> Option<u32> { (*self).durability() }
|
||||
fn durability_lost(&self) -> Option<u32> { (*self).durability_lost() }
|
||||
|
||||
fn stats_durability_multiplier(&self) -> DurabilityMultiplier {
|
||||
(*self).stats_durability_multiplier()
|
||||
|
@ -20,7 +20,10 @@ pub(super) const UNEQUIP_TRACKING_DURATION: f64 = 60.0;
|
||||
pub struct Loadout {
|
||||
slots: Vec<LoadoutSlot>,
|
||||
// Includes time that item was unequipped at
|
||||
pub(super) recently_unequipped_items: HashMap<ItemDefinitionIdOwned, Time>,
|
||||
#[serde(skip)]
|
||||
// Tracks time unequipped at and number that have been unequipped (for things like dual
|
||||
// wielding, rings, or other future cases)
|
||||
pub(super) recently_unequipped_items: HashMap<ItemDefinitionIdOwned, (Time, u8)>,
|
||||
}
|
||||
|
||||
/// NOTE: Please don't derive a PartialEq Instance for this; that's broken!
|
||||
@ -103,22 +106,26 @@ impl Loadout {
|
||||
item: Option<Item>,
|
||||
time: Time,
|
||||
) -> Option<Item> {
|
||||
self.recently_unequipped_items.retain(|def, unequip_time| {
|
||||
let item_reequipped = item
|
||||
.as_ref()
|
||||
.map_or(false, |i| def.as_ref() == i.item_definition_id());
|
||||
let old_unequip = time.0 - unequip_time.0 > UNEQUIP_TRACKING_DURATION;
|
||||
// Stop tracking item if it is re-equipped or if was unequipped a while ago
|
||||
!(item_reequipped || old_unequip)
|
||||
});
|
||||
if let Some(item_def_id) = item.as_ref().map(|item| item.item_definition_id()) {
|
||||
if let Some((_unequip_time, count)) = self
|
||||
.recently_unequipped_items
|
||||
.get_mut(&item_def_id.to_owned())
|
||||
{
|
||||
*count = count.saturating_sub(1);
|
||||
}
|
||||
}
|
||||
self.cull_recently_unequipped_items(time);
|
||||
let unequipped_item = self
|
||||
.slots
|
||||
.iter_mut()
|
||||
.find(|x| x.equip_slot == equip_slot)
|
||||
.and_then(|x| core::mem::replace(&mut x.slot, item));
|
||||
if let Some(unequipped_item) = unequipped_item.as_ref() {
|
||||
self.recently_unequipped_items
|
||||
.insert(unequipped_item.item_definition_id().to_owned(), time);
|
||||
let entry = self
|
||||
.recently_unequipped_items
|
||||
.entry(unequipped_item.item_definition_id().to_owned())
|
||||
.or_insert((time, 0));
|
||||
*entry = (time, entry.1 + 1);
|
||||
}
|
||||
unequipped_item
|
||||
}
|
||||
@ -485,6 +492,20 @@ impl Loadout {
|
||||
item.reset_durability(ability_map, msm);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn cull_recently_unequipped_items(&mut self, time: Time) {
|
||||
for (unequip_time, _count) in self.recently_unequipped_items.values_mut() {
|
||||
// If somehow time went backwards or faulty unequip time supplied, set unequip
|
||||
// time to minimum of current time and unequip time
|
||||
if time.0 < unequip_time.0 {
|
||||
*unequip_time = time;
|
||||
}
|
||||
}
|
||||
self.recently_unequipped_items
|
||||
.retain(|_def, (unequip_time, count)| {
|
||||
(time.0 - unequip_time.0 < UNEQUIP_TRACKING_DURATION) || *count > 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -899,39 +899,47 @@ impl Inventory {
|
||||
time: Time,
|
||||
) {
|
||||
self.loadout.damage_items(ability_map, msm);
|
||||
self.loadout
|
||||
.recently_unequipped_items
|
||||
.retain(|_item, unequip_time| {
|
||||
time.0 - unequip_time.0 <= loadout::UNEQUIP_TRACKING_DURATION
|
||||
});
|
||||
let inv_slots = self
|
||||
self.loadout.cull_recently_unequipped_items(time);
|
||||
|
||||
let slots = self
|
||||
.slots_with_id()
|
||||
.filter(|(_slot, item)| {
|
||||
item.as_ref().map_or(false, |item| {
|
||||
item.durability_lost()
|
||||
.map_or(false, |dur| dur < Item::MAX_DURABILITY)
|
||||
&& self
|
||||
.loadout
|
||||
.recently_unequipped_items
|
||||
.keys()
|
||||
.filter_map(|item_def_id| {
|
||||
self.slots_with_id()
|
||||
.find(|&(_, item)| {
|
||||
if let Some(item) = item {
|
||||
// Find an item with the matching item definition id and that is not yet
|
||||
// at maximum durability lost
|
||||
item.item_definition_id() == *item_def_id
|
||||
&& item
|
||||
.durability()
|
||||
.map_or(true, |dur| dur < Item::MAX_DURABILITY)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
.contains_key(&item.item_definition_id().to_owned())
|
||||
})
|
||||
.map(|(slot, _)| slot)
|
||||
})
|
||||
.map(|(slot, _item)| slot)
|
||||
.collect::<Vec<_>>();
|
||||
for inv_slot in inv_slots.iter() {
|
||||
if let Some(Some(item)) = self.slot_mut(*inv_slot) {
|
||||
if item.has_durability() {
|
||||
slots.into_iter().for_each(|slot| {
|
||||
let slot = if let Some(Some(item)) = self.slot(slot) {
|
||||
if let Some((_unequip_time, count)) = self
|
||||
.loadout
|
||||
.recently_unequipped_items
|
||||
.get_mut(&item.item_definition_id().to_owned())
|
||||
{
|
||||
if *count > 0 {
|
||||
*count -= 1;
|
||||
Some(slot)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(slot) = slot {
|
||||
if let Some(Some(item)) = self.slot_mut(slot) {
|
||||
item.increment_damage(ability_map, msm);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Resets durability of item in specified slot
|
||||
|
@ -976,7 +976,7 @@ impl RepairRecipe {
|
||||
}
|
||||
|
||||
pub fn inputs(&self, item: &Item) -> impl Iterator<Item = (&RecipeInput, u32)> {
|
||||
let item_durability = item.durability().unwrap_or(0);
|
||||
let item_durability = item.durability_lost().unwrap_or(0);
|
||||
self.inputs
|
||||
.iter()
|
||||
.filter_map(move |(input, original_amount)| {
|
||||
|
@ -1414,11 +1414,19 @@ pub fn handle_entity_attacked_hook(server: &Server, entity: EcsEntity) {
|
||||
// If entity was in an active trade, cancel it
|
||||
let mut trades = ecs.write_resource::<Trades>();
|
||||
let uids = ecs.read_storage::<Uid>();
|
||||
if let Some(uid) = uids.get(entity) {
|
||||
if let Some(trade) = trades.entity_trades.get(uid).copied() {
|
||||
trades
|
||||
.decline_trade(trade, *uid)
|
||||
.and_then(|uid| ecs.entity_from_uid(uid.0))
|
||||
.map(|entity_b| {
|
||||
// Notify both parties that the trade ended
|
||||
let clients = ecs.read_storage::<Client>();
|
||||
let mut agents = ecs.write_storage::<Agent>();
|
||||
let mut notify_trade_party = |entity| {
|
||||
if let Some(client) = clients.get(entity) {
|
||||
client.send_fallible(ServerGeneral::FinishedTrade(TradeResult::Declined));
|
||||
client
|
||||
.send_fallible(ServerGeneral::FinishedTrade(TradeResult::Declined));
|
||||
}
|
||||
if let Some(agent) = agents.get_mut(entity) {
|
||||
agent
|
||||
@ -1426,16 +1434,8 @@ pub fn handle_entity_attacked_hook(server: &Server, entity: EcsEntity) {
|
||||
.push_back(AgentEvent::FinishedTrade(TradeResult::Declined));
|
||||
}
|
||||
};
|
||||
if let Some(uid) = uids.get(entity) {
|
||||
// Notify attacked entity
|
||||
notify_trade_party(entity);
|
||||
if let Some(trade) = trades.entity_trades.get(uid).copied() {
|
||||
trades
|
||||
.decline_trade(trade, *uid)
|
||||
.and_then(|uid| ecs.entity_from_uid(uid.0))
|
||||
.map(|entity| {
|
||||
// Notify person trading with attacked person
|
||||
notify_trade_party(entity)
|
||||
notify_trade_party(entity_b);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1376,7 +1376,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
let repair_slot = CraftSlot {
|
||||
index: 0,
|
||||
slot: self.show.crafting_fields.recipe_inputs.get(&0).copied(),
|
||||
requirement: |item, _, _| item.durability().map_or(false, |d| d > 0),
|
||||
requirement: |item, _, _| item.durability_lost().map_or(false, |d| d > 0),
|
||||
info: None,
|
||||
};
|
||||
|
||||
@ -1413,7 +1413,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
let can_repair = |item: &Item| {
|
||||
// Check that item needs to be repaired, and that inventory has sufficient
|
||||
// materials to repair
|
||||
item.durability().map_or(false, |d| d > 0)
|
||||
item.durability_lost().map_or(false, |d| d > 0)
|
||||
&& self.client.repair_recipe_book().repair_recipe(item).map_or(
|
||||
false,
|
||||
|recipe| {
|
||||
|
@ -359,7 +359,7 @@ pub fn protec2string(stat: Protection) -> String {
|
||||
/// Gets the durability of an item in a format more intuitive for UI
|
||||
pub fn item_durability(item: &dyn ItemDesc) -> Option<u32> {
|
||||
let durability = item
|
||||
.durability()
|
||||
.durability_lost()
|
||||
.or_else(|| item.has_durability().then_some(0));
|
||||
durability.map(|d| Item::MAX_DURABILITY - d)
|
||||
}
|
||||
|
@ -670,7 +670,7 @@ impl<'a> Widget for ItemTooltip<'a> {
|
||||
);
|
||||
|
||||
if item.has_durability() {
|
||||
let durability = Item::MAX_DURABILITY - item.durability().unwrap_or(0);
|
||||
let durability = Item::MAX_DURABILITY - item.durability_lost().unwrap_or(0);
|
||||
stat_text(
|
||||
format!(
|
||||
"{} : {}/{}",
|
||||
|
Loading…
Reference in New Issue
Block a user