use std::ops::{Mul, Sub};
use glam::{IVec3, DVec3};
use crate::entity::Item;
use crate::item::ItemStack;
use crate::{block, item};
use super::World;
impl World {
pub fn spawn_loot(&mut self, mut pos: DVec3, stack: ItemStack, spread: f32) {
if spread != 0.0 {
pos += self.rand.next_float_vec()
.mul(spread)
.as_dvec3()
.sub(spread as f64 * 0.5);
}
let entity = Item::new_with(|base, item| {
base.persistent = true;
base.pos = pos;
base.vel.x = self.rand.next_double() * 0.2 - 0.1;
base.vel.y = 0.2;
base.vel.z = self.rand.next_double() * 0.2 - 0.1;
item.stack = stack;
item.frozen_time = 10;
});
self.spawn_entity(entity);
}
pub fn spawn_block_loot(&mut self, pos: IVec3, id: u8, metadata: u8, chance: f32) {
let tries = self.get_block_loot_tries(id, metadata);
for try_num in 0..tries {
if self.rand.next_float() <= self.get_block_loot_chance(id, metadata, try_num, chance) {
let stack = self.get_block_loot_stack(id, metadata, try_num);
if !stack.is_empty() {
self.spawn_loot(pos.as_dvec3() + 0.5, stack, 0.7);
}
}
}
}
fn get_block_loot_tries(&mut self, id: u8, _metadata: u8) -> u8 {
match id {
block::AIR => 0,
block::BOOKSHELF => 0,
block::CAKE => 0,
block::CLAY => 4,
block::WHEAT => 4, block::FIRE => 0,
block::WATER_MOVING |
block::WATER_STILL |
block::LAVA_MOVING |
block::LAVA_STILL => 0,
block::GLASS => 0,
block::GLOWSTONE => 2 + self.rand.next_int_bounded(3) as u8,
block::ICE => 0,
block::LEAVES if self.rand.next_int_bounded(20) != 0 => 0,
block::SPAWNER => 0,
block::LAPIS_ORE => 4 + self.rand.next_int_bounded(5) as u8,
block::PISTON_EXT |
block::PISTON_MOVING => 0,
block::PORTAL => 0,
block::REDSTONE_ORE |
block::REDSTONE_ORE_LIT => 4 + self.rand.next_int_bounded(2) as u8,
block::SNOW => 0,
block::SNOW_BLOCK => 4,
block::DOUBLE_SLAB => 2,
block::TNT => 0,
_ => 1
}
}
fn get_block_loot_chance(&mut self, id: u8, metadata: u8, try_num: u8, default_chance: f32) -> f32 {
match id {
block::WHEAT if try_num != 0 => metadata as f32 / 14.0, _ => default_chance,
}
}
fn get_block_loot_stack(&mut self, id: u8, metadata: u8, try_num: u8) -> ItemStack {
match id {
block::BED if block::bed::is_head(metadata) => ItemStack::EMPTY,
block::BED => ItemStack::new_single(item::BED, 0),
block::CAKE => ItemStack::EMPTY,
block::CLAY => ItemStack::new_single(item::CLAY, 0),
block::WHEAT if try_num == 0 && metadata != 7 => return ItemStack::EMPTY,
block::WHEAT if try_num == 0 => ItemStack::new_single(item::WHEAT, 0),
block::WHEAT => ItemStack::new_single(item::WHEAT_SEEDS, 0),
block::DEAD_BUSH => ItemStack::EMPTY,
block::WOOD_DOOR |
block::IRON_DOOR if block::door::is_upper(metadata) => ItemStack::EMPTY,
block::WOOD_DOOR => ItemStack::new_single(item::WOOD_DOOR, 0),
block::IRON_DOOR => ItemStack::new_single(item::IRON_DOOR, 0),
block::FARMLAND |
block::GRASS => ItemStack::new_block(block::DIRT, 0),
block::WATER_MOVING |
block::WATER_STILL |
block::LAVA_MOVING |
block::LAVA_STILL => ItemStack::EMPTY,
block::FURNACE |
block::FURNACE_LIT => ItemStack::new_block(block::FURNACE, 0),
block::GLOWSTONE => ItemStack::new_single(item::GLOWSTONE_DUST, 0),
block::GRAVEL if self.rand.next_int_bounded(10) == 0 => ItemStack::new_single(item::FLINT, 0),
block::LEAVES => ItemStack::new_block(block::SAPLING, metadata & 3),
block::SPAWNER => ItemStack::EMPTY,
block::COAL_ORE => ItemStack::new_single(item::COAL, 0),
block::DIAMOND_ORE => ItemStack::new_single(item::DIAMOND, 0),
block::REDSTONE_ORE |
block::REDSTONE_ORE_LIT => ItemStack::new_single(item::REDSTONE, 0),
block::LAPIS_ORE => ItemStack::new_single(item::DYE, 4),
block::PISTON_EXT |
block::PISTON_MOVING => ItemStack::EMPTY,
block::REDSTONE => ItemStack::new_single(item::REDSTONE, 0),
block::REPEATER |
block::REPEATER_LIT => ItemStack::new_single(item::REPEATER, 0),
block::REDSTONE_TORCH |
block::REDSTONE_TORCH_LIT => ItemStack::new_block(block::REDSTONE_TORCH_LIT, 0),
block::SUGAR_CANES => ItemStack::new_single(item::SUGAR_CANES, 0),
block::SIGN |
block::WALL_SIGN => ItemStack::new_single(item::SIGN, 0),
block::SNOW_BLOCK |
block::SNOW => ItemStack::new_single(item::SNOWBALL, 0),
block::SLAB |
block::DOUBLE_SLAB => ItemStack::new_block(block::SLAB, metadata),
block::STONE => ItemStack::new_block(block::COBBLESTONE, 0),
block::TALL_GRASS if self.rand.next_int_bounded(8) == 0 => ItemStack::new_single(item::WHEAT_SEEDS, 0),
block::TALL_GRASS => ItemStack::EMPTY,
block::COBWEB => ItemStack::new_single(item::STRING, 0),
block::LOG => ItemStack::new_block(block::LOG, metadata),
block::WOOL => ItemStack::new_block(block::WOOL, metadata),
block::SAPLING => ItemStack::new_block(block::SAPLING, metadata & 3),
_ => ItemStack::new_block(id, 0),
}
}
}