mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Soft loot protection
This commit is contained in:
parent
256b3d1e16
commit
dccbfc4595
@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Location names are displayed in character selection dialog
|
- Location names are displayed in character selection dialog
|
||||||
- You can no longer write messages to old groups after being kicked and not having updated your chat mode.
|
- You can no longer write messages to old groups after being kicked and not having updated your chat mode.
|
||||||
- Location names are now also correct after editing and creating characters
|
- Location names are now also correct after editing and creating characters
|
||||||
|
- NPC's wont pick up recently dropped items (if not hostile towards you)
|
||||||
|
|
||||||
## [0.15.0] - 2023-07-01
|
## [0.15.0] - 2023-07-01
|
||||||
|
|
||||||
|
@ -15,16 +15,21 @@ pub struct LootOwner {
|
|||||||
#[serde(skip, default = "Instant::now")]
|
#[serde(skip, default = "Instant::now")]
|
||||||
expiry: Instant,
|
expiry: Instant,
|
||||||
owner: LootOwnerKind,
|
owner: LootOwnerKind,
|
||||||
|
/// This field stands as a wish for NPC's to not pick the loot up, they will
|
||||||
|
/// however be able to decide whether they want to follow your wishes or not
|
||||||
|
/// (players will be able to picke the item up)
|
||||||
|
soft: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loot becomes free-for-all after the initial ownership period
|
// Loot becomes free-for-all after the initial ownership period
|
||||||
const OWNERSHIP_SECS: u64 = 45;
|
const OWNERSHIP_SECS: u64 = 45;
|
||||||
|
|
||||||
impl LootOwner {
|
impl LootOwner {
|
||||||
pub fn new(kind: LootOwnerKind) -> Self {
|
pub fn new(kind: LootOwnerKind, soft: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
expiry: Instant::now().add(Duration::from_secs(OWNERSHIP_SECS)),
|
expiry: Instant::now().add(Duration::from_secs(OWNERSHIP_SECS)),
|
||||||
owner: kind,
|
owner: kind,
|
||||||
|
soft,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +48,8 @@ impl LootOwner {
|
|||||||
|
|
||||||
pub fn default_instant() -> Instant { Instant::now() }
|
pub fn default_instant() -> Instant { Instant::now() }
|
||||||
|
|
||||||
|
pub fn is_soft(&self) -> bool { self.soft }
|
||||||
|
|
||||||
pub fn can_pickup(
|
pub fn can_pickup(
|
||||||
&self,
|
&self,
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
@ -66,7 +73,7 @@ impl LootOwner {
|
|||||||
// Pet's can't pick up owned loot
|
// Pet's can't pick up owned loot
|
||||||
// Humanoids must own the loot
|
// Humanoids must own the loot
|
||||||
// Non-humanoids ignore loot ownership
|
// Non-humanoids ignore loot ownership
|
||||||
!is_pet && (owns_loot || !is_humanoid)
|
!is_pet && (self.soft || owns_loot || !is_humanoid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,10 +822,10 @@ impl<'a> AgentData<'a> {
|
|||||||
};
|
};
|
||||||
let is_valid_target = |entity: EcsEntity| match read_data.bodies.get(entity) {
|
let is_valid_target = |entity: EcsEntity| match read_data.bodies.get(entity) {
|
||||||
Some(Body::ItemDrop(item)) => {
|
Some(Body::ItemDrop(item)) => {
|
||||||
//If the agent is humanoid, it will pick up all kinds of item drops. If the
|
let is_humanoid = matches!(self.body, Some(Body::Humanoid(_)));
|
||||||
|
// If the agent is humanoid, it will pick up all kinds of item drops. If the
|
||||||
// agent isn't humanoid, it will pick up only consumable item drops.
|
// agent isn't humanoid, it will pick up only consumable item drops.
|
||||||
let wants_pickup = matches!(self.body, Some(Body::Humanoid(_)))
|
let wants_pickup = is_humanoid || matches!(item, item_drop::Body::Consumable);
|
||||||
|| matches!(item, item_drop::Body::Consumable);
|
|
||||||
|
|
||||||
// The agent will attempt to pickup the item if it wants to pick it up and
|
// The agent will attempt to pickup the item if it wants to pick it up and
|
||||||
// is allowed to
|
// is allowed to
|
||||||
@ -834,13 +834,20 @@ impl<'a> AgentData<'a> {
|
|||||||
.loot_owners
|
.loot_owners
|
||||||
.get(entity)
|
.get(entity)
|
||||||
.map_or(true, |loot_owner| {
|
.map_or(true, |loot_owner| {
|
||||||
loot_owner.can_pickup(
|
!(is_humanoid
|
||||||
*self.uid,
|
&& loot_owner.is_soft()
|
||||||
read_data.groups.get(entity),
|
// If we are hostile towards the owner, ignore their wish to not pick up the loot
|
||||||
self.alignment,
|
&& loot_owner
|
||||||
self.body,
|
.uid()
|
||||||
None,
|
.and_then(|uid| read_data.id_maps.uid_entity(uid))
|
||||||
)
|
.map_or(true, |entity| !is_enemy(self, entity, read_data)))
|
||||||
|
&& loot_owner.can_pickup(
|
||||||
|
*self.uid,
|
||||||
|
read_data.groups.get(entity),
|
||||||
|
self.alignment,
|
||||||
|
self.body,
|
||||||
|
None,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
if attempt_pickup {
|
if attempt_pickup {
|
||||||
|
@ -482,7 +482,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
|
|||||||
item,
|
item,
|
||||||
if let Some(loot_owner) = loot_owner {
|
if let Some(loot_owner) = loot_owner {
|
||||||
debug!("Assigned UID {loot_owner:?} as the winner for the loot drop");
|
debug!("Assigned UID {loot_owner:?} as the winner for the loot drop");
|
||||||
Some(LootOwner::new(loot_owner))
|
Some(LootOwner::new(loot_owner, false))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
@ -356,7 +356,9 @@ pub fn handle_mine_block(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for item in items {
|
for item in items {
|
||||||
let loot_owner = maybe_uid.map(LootOwnerKind::Player).map(LootOwner::new);
|
let loot_owner = maybe_uid
|
||||||
|
.map(LootOwnerKind::Player)
|
||||||
|
.map(|owner| LootOwner::new(owner, false));
|
||||||
state.create_item_drop(
|
state.create_item_drop(
|
||||||
Pos(pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0)),
|
Pos(pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0)),
|
||||||
comp::Vel(Vec3::zero()),
|
comp::Vel(Vec3::zero()),
|
||||||
|
@ -9,8 +9,9 @@ use common::{
|
|||||||
self,
|
self,
|
||||||
group::members,
|
group::members,
|
||||||
item::{self, flatten_counted_items, tool::AbilityMap, MaterialStatManifest},
|
item::{self, flatten_counted_items, tool::AbilityMap, MaterialStatManifest},
|
||||||
|
loot_owner::LootOwnerKind,
|
||||||
slot::{self, Slot},
|
slot::{self, Slot},
|
||||||
InventoryUpdate,
|
InventoryUpdate, LootOwner,
|
||||||
},
|
},
|
||||||
consts::MAX_PICKUP_RANGE,
|
consts::MAX_PICKUP_RANGE,
|
||||||
mounting::VolumePos,
|
mounting::VolumePos,
|
||||||
@ -387,7 +388,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
),
|
),
|
||||||
comp::Vel(Vec3::zero()),
|
comp::Vel(Vec3::zero()),
|
||||||
item,
|
item,
|
||||||
None,
|
Some(LootOwner::new(LootOwnerKind::Player(uid), false)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -959,7 +960,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
comp::Pos(pos.0 + *ori.look_dir() + Vec3::unit_z()),
|
comp::Pos(pos.0 + *ori.look_dir() + Vec3::unit_z()),
|
||||||
comp::Vel(Vec3::zero()),
|
comp::Vel(Vec3::zero()),
|
||||||
item,
|
item,
|
||||||
None,
|
Some(LootOwner::new(LootOwnerKind::Player(uid), true)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user