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))
|
self.durability_lost.map(|x| x.min(Self::MAX_DURABILITY))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,7 +1294,7 @@ pub trait ItemDesc {
|
|||||||
fn is_modular(&self) -> bool;
|
fn is_modular(&self) -> bool;
|
||||||
fn components(&self) -> &[Item];
|
fn components(&self) -> &[Item];
|
||||||
fn has_durability(&self) -> bool;
|
fn has_durability(&self) -> bool;
|
||||||
fn durability(&self) -> Option<u32>;
|
fn durability_lost(&self) -> Option<u32>;
|
||||||
fn stats_durability_multiplier(&self) -> DurabilityMultiplier;
|
fn stats_durability_multiplier(&self) -> DurabilityMultiplier;
|
||||||
|
|
||||||
fn tool_info(&self) -> Option<ToolKind> {
|
fn tool_info(&self) -> Option<ToolKind> {
|
||||||
@ -1327,7 +1327,7 @@ impl ItemDesc for Item {
|
|||||||
|
|
||||||
fn has_durability(&self) -> bool { self.has_durability() }
|
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 {
|
fn stats_durability_multiplier(&self) -> DurabilityMultiplier {
|
||||||
self.stats_durability_multiplier()
|
self.stats_durability_multiplier()
|
||||||
@ -1359,7 +1359,7 @@ impl ItemDesc for ItemDef {
|
|||||||
self.kind().has_durability() && self.quality != Quality::Debug
|
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) }
|
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 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 {
|
fn stats_durability_multiplier(&self) -> DurabilityMultiplier {
|
||||||
(*self).stats_durability_multiplier()
|
(*self).stats_durability_multiplier()
|
||||||
|
@ -20,7 +20,10 @@ pub(super) const UNEQUIP_TRACKING_DURATION: f64 = 60.0;
|
|||||||
pub struct Loadout {
|
pub struct Loadout {
|
||||||
slots: Vec<LoadoutSlot>,
|
slots: Vec<LoadoutSlot>,
|
||||||
// Includes time that item was unequipped at
|
// 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!
|
/// NOTE: Please don't derive a PartialEq Instance for this; that's broken!
|
||||||
@ -103,22 +106,26 @@ impl Loadout {
|
|||||||
item: Option<Item>,
|
item: Option<Item>,
|
||||||
time: Time,
|
time: Time,
|
||||||
) -> Option<Item> {
|
) -> Option<Item> {
|
||||||
self.recently_unequipped_items.retain(|def, unequip_time| {
|
if let Some(item_def_id) = item.as_ref().map(|item| item.item_definition_id()) {
|
||||||
let item_reequipped = item
|
if let Some((_unequip_time, count)) = self
|
||||||
.as_ref()
|
.recently_unequipped_items
|
||||||
.map_or(false, |i| def.as_ref() == i.item_definition_id());
|
.get_mut(&item_def_id.to_owned())
|
||||||
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
|
*count = count.saturating_sub(1);
|
||||||
!(item_reequipped || old_unequip)
|
}
|
||||||
});
|
}
|
||||||
|
self.cull_recently_unequipped_items(time);
|
||||||
let unequipped_item = self
|
let unequipped_item = self
|
||||||
.slots
|
.slots
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|x| x.equip_slot == equip_slot)
|
.find(|x| x.equip_slot == equip_slot)
|
||||||
.and_then(|x| core::mem::replace(&mut x.slot, item));
|
.and_then(|x| core::mem::replace(&mut x.slot, item));
|
||||||
if let Some(unequipped_item) = unequipped_item.as_ref() {
|
if let Some(unequipped_item) = unequipped_item.as_ref() {
|
||||||
self.recently_unequipped_items
|
let entry = self
|
||||||
.insert(unequipped_item.item_definition_id().to_owned(), time);
|
.recently_unequipped_items
|
||||||
|
.entry(unequipped_item.item_definition_id().to_owned())
|
||||||
|
.or_insert((time, 0));
|
||||||
|
*entry = (time, entry.1 + 1);
|
||||||
}
|
}
|
||||||
unequipped_item
|
unequipped_item
|
||||||
}
|
}
|
||||||
@ -485,6 +492,20 @@ impl Loadout {
|
|||||||
item.reset_durability(ability_map, msm);
|
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)]
|
#[cfg(test)]
|
||||||
|
@ -899,39 +899,47 @@ impl Inventory {
|
|||||||
time: Time,
|
time: Time,
|
||||||
) {
|
) {
|
||||||
self.loadout.damage_items(ability_map, msm);
|
self.loadout.damage_items(ability_map, msm);
|
||||||
self.loadout
|
self.loadout.cull_recently_unequipped_items(time);
|
||||||
.recently_unequipped_items
|
|
||||||
.retain(|_item, unequip_time| {
|
let slots = self
|
||||||
time.0 - unequip_time.0 <= loadout::UNEQUIP_TRACKING_DURATION
|
.slots_with_id()
|
||||||
});
|
.filter(|(_slot, item)| {
|
||||||
let inv_slots = self
|
item.as_ref().map_or(false, |item| {
|
||||||
|
item.durability_lost()
|
||||||
|
.map_or(false, |dur| dur < Item::MAX_DURABILITY)
|
||||||
|
&& self
|
||||||
.loadout
|
.loadout
|
||||||
.recently_unequipped_items
|
.recently_unequipped_items
|
||||||
.keys()
|
.contains_key(&item.item_definition_id().to_owned())
|
||||||
.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
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|(slot, _)| slot)
|
|
||||||
})
|
})
|
||||||
|
.map(|(slot, _item)| slot)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
for inv_slot in inv_slots.iter() {
|
slots.into_iter().for_each(|slot| {
|
||||||
if let Some(Some(item)) = self.slot_mut(*inv_slot) {
|
let slot = if let Some(Some(item)) = self.slot(slot) {
|
||||||
if item.has_durability() {
|
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);
|
item.increment_damage(ability_map, msm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets durability of item in specified slot
|
/// Resets durability of item in specified slot
|
||||||
|
@ -976,7 +976,7 @@ impl RepairRecipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn inputs(&self, item: &Item) -> impl Iterator<Item = (&RecipeInput, u32)> {
|
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
|
self.inputs
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(move |(input, original_amount)| {
|
.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
|
// If entity was in an active trade, cancel it
|
||||||
let mut trades = ecs.write_resource::<Trades>();
|
let mut trades = ecs.write_resource::<Trades>();
|
||||||
let uids = ecs.read_storage::<Uid>();
|
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 clients = ecs.read_storage::<Client>();
|
||||||
let mut agents = ecs.write_storage::<Agent>();
|
let mut agents = ecs.write_storage::<Agent>();
|
||||||
let mut notify_trade_party = |entity| {
|
let mut notify_trade_party = |entity| {
|
||||||
if let Some(client) = clients.get(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) {
|
if let Some(agent) = agents.get_mut(entity) {
|
||||||
agent
|
agent
|
||||||
@ -1426,16 +1434,8 @@ pub fn handle_entity_attacked_hook(server: &Server, entity: EcsEntity) {
|
|||||||
.push_back(AgentEvent::FinishedTrade(TradeResult::Declined));
|
.push_back(AgentEvent::FinishedTrade(TradeResult::Declined));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(uid) = uids.get(entity) {
|
|
||||||
// Notify attacked entity
|
|
||||||
notify_trade_party(entity);
|
notify_trade_party(entity);
|
||||||
if let Some(trade) = trades.entity_trades.get(uid).copied() {
|
notify_trade_party(entity_b);
|
||||||
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)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1376,7 +1376,7 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
let repair_slot = CraftSlot {
|
let repair_slot = CraftSlot {
|
||||||
index: 0,
|
index: 0,
|
||||||
slot: self.show.crafting_fields.recipe_inputs.get(&0).copied(),
|
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,
|
info: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1413,7 +1413,7 @@ impl<'a> Widget for Crafting<'a> {
|
|||||||
let can_repair = |item: &Item| {
|
let can_repair = |item: &Item| {
|
||||||
// Check that item needs to be repaired, and that inventory has sufficient
|
// Check that item needs to be repaired, and that inventory has sufficient
|
||||||
// materials to repair
|
// 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(
|
&& self.client.repair_recipe_book().repair_recipe(item).map_or(
|
||||||
false,
|
false,
|
||||||
|recipe| {
|
|recipe| {
|
||||||
|
@ -359,7 +359,7 @@ pub fn protec2string(stat: Protection) -> String {
|
|||||||
/// Gets the durability of an item in a format more intuitive for UI
|
/// Gets the durability of an item in a format more intuitive for UI
|
||||||
pub fn item_durability(item: &dyn ItemDesc) -> Option<u32> {
|
pub fn item_durability(item: &dyn ItemDesc) -> Option<u32> {
|
||||||
let durability = item
|
let durability = item
|
||||||
.durability()
|
.durability_lost()
|
||||||
.or_else(|| item.has_durability().then_some(0));
|
.or_else(|| item.has_durability().then_some(0));
|
||||||
durability.map(|d| Item::MAX_DURABILITY - d)
|
durability.map(|d| Item::MAX_DURABILITY - d)
|
||||||
}
|
}
|
||||||
|
@ -670,7 +670,7 @@ impl<'a> Widget for ItemTooltip<'a> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if item.has_durability() {
|
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(
|
stat_text(
|
||||||
format!(
|
format!(
|
||||||
"{} : {}/{}",
|
"{} : {}/{}",
|
||||||
|
Loading…
Reference in New Issue
Block a user