veloren_common/comp/
loot_owner.rs1use crate::{
2 comp::{Alignment, Body, Group, Player},
3 uid::Uid,
4};
5use serde::{Deserialize, Serialize};
6use specs::{Component, DerefFlaggedStorage};
7use std::{
8 ops::Add,
9 time::{Duration, Instant},
10};
11
12#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
13pub struct LootOwner {
14 #[serde(skip, default = "Instant::now")]
16 expiry: Instant,
17 owner: LootOwnerKind,
18 soft: bool,
19}
20
21const OWNERSHIP_SECS: u64 = 45;
23
24impl LootOwner {
25 pub fn new(kind: LootOwnerKind, soft: bool) -> Self {
26 Self {
27 expiry: Instant::now().add(Duration::from_secs(OWNERSHIP_SECS)),
28 owner: kind,
29 soft,
30 }
31 }
32
33 pub fn uid(&self) -> Option<Uid> {
34 match &self.owner {
35 LootOwnerKind::Player(uid) => Some(*uid),
36 LootOwnerKind::Group(_) => None,
37 }
38 }
39
40 pub fn owner(&self) -> LootOwnerKind { self.owner }
41
42 pub fn time_until_expiration(&self) -> Duration { self.expiry - Instant::now() }
43
44 pub fn expired(&self) -> bool { self.expiry <= Instant::now() }
45
46 pub fn default_instant() -> Instant { Instant::now() }
47
48 pub fn is_soft(&self) -> bool { self.soft }
52
53 pub fn can_pickup(
54 &self,
55 uid: Uid,
56 group: Option<&Group>,
57 alignment: Option<&Alignment>,
58 body: Option<&Body>,
59 player: Option<&Player>,
60 ) -> bool {
61 let is_owned = matches!(alignment, Some(Alignment::Owned(_)));
62 let is_player = player.is_some();
63 let is_pet = is_owned && !is_player;
64
65 let owns_loot = match self.owner {
66 LootOwnerKind::Player(loot_uid) => loot_uid.0 == uid.0,
67 LootOwnerKind::Group(loot_group) => {
68 matches!(group, Some(group) if loot_group == *group)
69 },
70 };
71 let is_humanoid = matches!(body, Some(Body::Humanoid(_)));
72
73 !is_pet && (self.soft || owns_loot || !is_humanoid)
77 }
78}
79
80impl Component for LootOwner {
81 type Storage = DerefFlaggedStorage<Self, specs::DenseVecStorage<Self>>;
82}
83
84#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
85pub enum LootOwnerKind {
86 Player(Uid),
87 Group(Group),
88}