mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
NPCs can drop nothing
This commit is contained in:
parent
82886dcd3f
commit
bbc366e1b3
@ -59,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Glider dimensions somewhat increased overall
|
||||
- Dungeon difficulty level starts at 1 instead of 0
|
||||
- The radius of the safe zone around the starting town has been doubled
|
||||
- NPCs can sometimes drop no loot at all
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
[
|
||||
(0.1, Item("common.items.food.meat.bird_large_raw")),
|
||||
(1.0, Item("common.items.crafting_ing.animal_misc.phoenix_feather")),
|
||||
|
||||
]
|
@ -1,4 +1,5 @@
|
||||
[
|
||||
(1.0, Item("common.items.food.meat.tough_raw")),
|
||||
(3.0, Item("common.items.crafting_ing.hide.carapace")),
|
||||
|
||||
]
|
@ -1,5 +1,4 @@
|
||||
[
|
||||
(4.0, LootTable("common.loot_tables.creature.quad_low.generic")),
|
||||
(2.0, Item("common.items.crafting_ing.animal_misc.sharp_fang")),
|
||||
|
||||
]
|
@ -1,5 +1,4 @@
|
||||
[
|
||||
(1.0, ItemQuantity("common.items.crafting_ing.animal_misc.fur", 1, 3)),
|
||||
(0.25, LootTable("common.loot_tables.creature.quad_low.generic")),
|
||||
|
||||
]
|
4
assets/common/loot_tables/nothing.ron
Normal file
4
assets/common/loot_tables/nothing.ron
Normal file
@ -0,0 +1,4 @@
|
||||
[
|
||||
// No loot is dropped
|
||||
(1.0, None),
|
||||
]
|
@ -267,6 +267,7 @@ fn loot_table(loot_table: &str) -> Result<(), Box<dyn Error>> {
|
||||
LootSpec::LootTable(table) => {
|
||||
wtr.write_record(&[&chance, "LootTable", table, "", ""])?
|
||||
},
|
||||
LootSpec::None => wtr.write_record(&[&chance, "None", "", ""])?,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,8 +468,9 @@ fn loot_table(loot_table: &str) -> Result<(), Box<dyn Error>> {
|
||||
.expect("No loot table")
|
||||
.to_string(),
|
||||
),
|
||||
"None" => LootSpec::None,
|
||||
a => panic!(
|
||||
"Loot specifier kind must be either \"Item\" or \"LootTable\"\n{}",
|
||||
"Loot specifier kind must be either \"Item\", \"LootTable\", or \"None\"\n{}",
|
||||
a
|
||||
),
|
||||
};
|
||||
|
@ -795,7 +795,7 @@ impl Item {
|
||||
pub fn slot_mut(&mut self, slot: usize) -> Option<&mut InvSlot> { self.slots.get_mut(slot) }
|
||||
|
||||
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
|
||||
Some(block.get_sprite()?.collectible_id()?.to_item())
|
||||
block.get_sprite()?.collectible_id()?.to_item()
|
||||
}
|
||||
|
||||
pub fn ability_spec(&self) -> Option<&AbilitySpec> { self.item_def.ability_spec.as_ref() }
|
||||
|
@ -113,6 +113,7 @@ impl From<Vec<(f32, LootSpec<String>)>> for ProbabilityFile {
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
},
|
||||
LootSpec::None => Vec::new().into_iter(),
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
|
@ -255,12 +255,16 @@ impl EntityInfo {
|
||||
|
||||
match loot {
|
||||
LootKind::Item(asset) => {
|
||||
self = self.with_loot_drop(Item::new_from_asset_expect(&asset));
|
||||
if let Ok(item) = Item::new_from_asset(&asset) {
|
||||
self = self.with_loot_drop(item);
|
||||
}
|
||||
},
|
||||
LootKind::LootTable(asset) => {
|
||||
let table = Lottery::<LootSpec<String>>::load_expect(&asset);
|
||||
let drop = table.read().choose().to_item();
|
||||
self = self.with_loot_drop(drop);
|
||||
if let Ok(table) = Lottery::<LootSpec<String>>::load(&asset) {
|
||||
if let Some(drop) = table.read().choose().to_item() {
|
||||
self = self.with_loot_drop(drop);
|
||||
}
|
||||
}
|
||||
},
|
||||
LootKind::Uninit => {},
|
||||
}
|
||||
|
@ -84,26 +84,32 @@ pub enum LootSpec<T: AsRef<str>> {
|
||||
ItemQuantity(T, u32, u32),
|
||||
/// Loot table
|
||||
LootTable(T),
|
||||
/// No loot given
|
||||
None,
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> LootSpec<T> {
|
||||
pub fn to_item(&self) -> Item {
|
||||
pub fn to_item(&self) -> Option<Item> {
|
||||
match self {
|
||||
Self::Item(item) => Item::new_from_asset_expect(item.as_ref()),
|
||||
Self::Item(item) => Item::new_from_asset(item.as_ref()).ok(),
|
||||
Self::ItemQuantity(item, lower, upper) => {
|
||||
let range = *lower..=*upper;
|
||||
let quantity = thread_rng().gen_range(range);
|
||||
let mut item = Item::new_from_asset_expect(item.as_ref());
|
||||
// TODO: Handle multiple of an item that is unstackable
|
||||
if item.set_amount(quantity).is_err() {
|
||||
warn!("Tried to set quantity on non stackable item");
|
||||
if let Ok(mut item) = Item::new_from_asset(item.as_ref()) {
|
||||
// TODO: Handle multiple of an item that is unstackable
|
||||
if item.set_amount(quantity).is_err() {
|
||||
warn!("Tried to set quantity on non stackable item");
|
||||
}
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
item
|
||||
},
|
||||
Self::LootTable(table) => Lottery::<LootSpec<String>>::load_expect(table.as_ref())
|
||||
.read()
|
||||
.choose()
|
||||
.to_item(),
|
||||
Self::None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,6 +147,7 @@ mod tests {
|
||||
Lottery::<LootSpec<String>>::load_expect_cloned(loot_table);
|
||||
validate_table_contents(loot_table);
|
||||
},
|
||||
LootSpec::None => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -529,41 +529,41 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
})
|
||||
};
|
||||
|
||||
let item = {
|
||||
if let Some(item) = {
|
||||
let mut item_drops = state.ecs().write_storage::<comp::ItemDrop>();
|
||||
item_drops.remove(entity).map_or_else(
|
||||
|| lottery().read().choose().to_item(),
|
||||
|item_drop| item_drop.0,
|
||||
|item_drop| Some(item_drop.0),
|
||||
)
|
||||
};
|
||||
} {
|
||||
let pos = state.ecs().read_storage::<comp::Pos>().get(entity).cloned();
|
||||
let vel = state.ecs().read_storage::<comp::Vel>().get(entity).cloned();
|
||||
if let Some(pos) = pos {
|
||||
let _ = state
|
||||
.create_object(comp::Pos(pos.0 + Vec3::unit_z() * 0.25), match old_body {
|
||||
Some(common::comp::Body::Humanoid(_)) => object::Body::Pouch,
|
||||
Some(common::comp::Body::BipedSmall(_)) => object::Body::Pouch,
|
||||
Some(common::comp::Body::Golem(_)) => object::Body::Chest,
|
||||
Some(common::comp::Body::QuadrupedSmall(_)) => object::Body::SmallMeat,
|
||||
Some(common::comp::Body::FishMedium(_))
|
||||
| Some(common::comp::Body::FishSmall(_)) => object::Body::FishMeat,
|
||||
Some(common::comp::Body::QuadrupedMedium(_)) => object::Body::BeastMeat,
|
||||
Some(common::comp::Body::BipedLarge(_))
|
||||
| Some(common::comp::Body::QuadrupedLow(_)) => object::Body::ToughMeat,
|
||||
Some(common::comp::Body::BirdLarge(_))
|
||||
| Some(common::comp::Body::BirdMedium(_)) => object::Body::BirdMeat,
|
||||
|
||||
let pos = state.ecs().read_storage::<comp::Pos>().get(entity).cloned();
|
||||
let vel = state.ecs().read_storage::<comp::Vel>().get(entity).cloned();
|
||||
if let Some(pos) = pos {
|
||||
let _ = state
|
||||
.create_object(comp::Pos(pos.0 + Vec3::unit_z() * 0.25), match old_body {
|
||||
Some(common::comp::Body::Humanoid(_)) => object::Body::Pouch,
|
||||
Some(common::comp::Body::BipedSmall(_)) => object::Body::Pouch,
|
||||
Some(common::comp::Body::Golem(_)) => object::Body::Chest,
|
||||
Some(common::comp::Body::QuadrupedSmall(_)) => object::Body::SmallMeat,
|
||||
Some(common::comp::Body::FishMedium(_))
|
||||
| Some(common::comp::Body::FishSmall(_)) => object::Body::FishMeat,
|
||||
Some(common::comp::Body::QuadrupedMedium(_)) => object::Body::BeastMeat,
|
||||
Some(common::comp::Body::BipedLarge(_))
|
||||
| Some(common::comp::Body::QuadrupedLow(_)) => object::Body::ToughMeat,
|
||||
Some(common::comp::Body::BirdLarge(_))
|
||||
| Some(common::comp::Body::BirdMedium(_)) => object::Body::BirdMeat,
|
||||
|
||||
_ => object::Body::BeastMeat,
|
||||
})
|
||||
.maybe_with(vel)
|
||||
.with(item)
|
||||
.build();
|
||||
} else {
|
||||
error!(
|
||||
?entity,
|
||||
"Entity doesn't have a position, no bag is being dropped"
|
||||
)
|
||||
_ => object::Body::BeastMeat,
|
||||
})
|
||||
.maybe_with(vel)
|
||||
.with(item)
|
||||
.build();
|
||||
} else {
|
||||
error!(
|
||||
?entity,
|
||||
"Entity doesn't have a position, no bag is being dropped"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
|
Loading…
Reference in New Issue
Block a user