377 lines
14 KiB
Java
Executable file
377 lines
14 KiB
Java
Executable file
package common.item.material;
|
|
|
|
import java.util.ArrayDeque;
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Queue;
|
|
import java.util.Set;
|
|
|
|
import common.block.Block;
|
|
import common.block.Material;
|
|
import common.block.liquid.BlockDynamicLiquid;
|
|
import common.block.liquid.BlockLiquid;
|
|
import common.block.liquid.BlockStaticLiquid;
|
|
import common.collect.Maps;
|
|
import common.collect.Sets;
|
|
import common.entity.npc.EntityNPC;
|
|
import common.init.Blocks;
|
|
import common.init.Items;
|
|
import common.init.SoundEvent;
|
|
import common.item.CheatTab;
|
|
import common.item.Item;
|
|
import common.item.ItemStack;
|
|
import common.model.Model;
|
|
import common.model.ModelProvider;
|
|
import common.tileentity.TileEntity;
|
|
import common.tileentity.TileEntityDispenser;
|
|
import common.util.BlockPos;
|
|
import common.util.Clientside;
|
|
import common.util.Facing;
|
|
import common.util.HitPosition;
|
|
import common.util.ParticleType;
|
|
import common.util.Serverside;
|
|
import common.util.Vec3;
|
|
import common.util.Vec3i;
|
|
import common.world.State;
|
|
import common.world.World;
|
|
import common.world.AWorldServer;
|
|
|
|
public class ItemBucket extends Item
|
|
{
|
|
private static final Map<BlockLiquid, ItemBucket> MAPPING = Maps.newHashMap();
|
|
|
|
private final boolean recursive;
|
|
private final BlockDynamicLiquid liquid;
|
|
|
|
public static ItemBucket getByFluid(BlockLiquid liquid) {
|
|
return MAPPING.get(liquid);
|
|
}
|
|
|
|
private static boolean test(AWorldServer world, BlockPos pos, Set<Block> blocks, int max, BlockPos origin, int radius) {
|
|
if(pos.getY() < -World.MAX_SIZE_Y || pos.getY() > max)
|
|
return false;
|
|
if(pos.getX() < origin.getX() - radius || pos.getX() > origin.getX() + radius)
|
|
return false;
|
|
if(pos.getY() < origin.getY() - radius || pos.getY() > origin.getY() + radius)
|
|
return false;
|
|
if(pos.getZ() < origin.getZ() - radius || pos.getZ() > origin.getZ() + radius)
|
|
return false;
|
|
Block block = world.getState(pos).getBlock();
|
|
return blocks == null ? block instanceof BlockLiquid : blocks.contains(block);
|
|
}
|
|
|
|
private static void setRecursive(AWorldServer world, BlockPos origin, int radius, BlockStaticLiquid liquid) {
|
|
Queue<BlockPos> queue = new ArrayDeque<BlockPos>();
|
|
Set<BlockPos> visited = new HashSet<BlockPos>();
|
|
List<Vec3i> dirs = new ArrayList<Vec3i>();
|
|
Set<Block> blocks = liquid == null ? null : Sets.newHashSet(liquid.getFlowingBlock(), liquid, Blocks.air);
|
|
State state = (liquid == null ? Blocks.air : liquid).getState();
|
|
int max = World.MAX_SIZE_Y - 1;
|
|
|
|
if(liquid != null) {
|
|
dirs.add(new Vec3i(1, 0, 0));
|
|
dirs.add(new Vec3i(-1, 0, 0));
|
|
dirs.add(new Vec3i(0, 0, 1));
|
|
dirs.add(new Vec3i(0, 0, -1));
|
|
dirs.add(new Vec3i(0, -1, 0));
|
|
max = Math.min(origin.getY(), max);
|
|
}
|
|
else {
|
|
dirs.add(new Vec3i(0, -1, 0));
|
|
dirs.add(new Vec3i(0, 1, 0));
|
|
dirs.add(new Vec3i(-1, 0, 0));
|
|
dirs.add(new Vec3i(1, 0, 0));
|
|
dirs.add(new Vec3i(0, 0, -1));
|
|
dirs.add(new Vec3i(0, 0, 1));
|
|
}
|
|
|
|
for(int x = -1; x <= 1; x++) {
|
|
for(int y = -1; y <= 1; y++) {
|
|
for(int z = -1; z <= 1; z++) {
|
|
BlockPos pos = new BlockPos(origin.getX() + x, origin.getY() + y, origin.getZ() + z);
|
|
if (!visited.contains(pos)) {
|
|
if(test(world, pos, blocks, max, origin, radius))
|
|
queue.add(pos);
|
|
visited.add(pos);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
BlockPos loc;
|
|
while ((loc = queue.poll()) != null) {
|
|
world.setState(loc, state);
|
|
for (Vec3i dir : dirs) {
|
|
BlockPos pos = loc.add(dir);
|
|
if (!visited.contains(pos)) {
|
|
visited.add(pos);
|
|
if (test(world, pos, blocks, max, origin, radius))
|
|
queue.add(pos);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ItemBucket(BlockDynamicLiquid liquid, boolean recursive)
|
|
{
|
|
if(liquid != null) {
|
|
this.setUnstackable();
|
|
this.setDisplay((recursive ? "Flutender" : "") + "Eimer mit " + liquid.getDisplay());
|
|
}
|
|
else {
|
|
this.setDisplay((recursive ? "Unendlicher" : "") + "Eimer");
|
|
}
|
|
this.liquid = liquid;
|
|
this.recursive = recursive;
|
|
this.setTab(liquid == null ? CheatTab.TOOLS : CheatTab.LIQUIDS);
|
|
this.setMagnetic();
|
|
if(liquid != null && !recursive) {
|
|
MAPPING.put(liquid, this);
|
|
MAPPING.put(liquid.getStaticBlock(), this);
|
|
}
|
|
}
|
|
|
|
public BlockDynamicLiquid getLiquid() {
|
|
return this.liquid;
|
|
}
|
|
|
|
/**
|
|
* Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
|
|
*/
|
|
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityNPC playerIn)
|
|
{
|
|
// boolean flag = this.fillBlock == Blocks.air;
|
|
HitPosition movingobjectposition = getMovingObjectPositionFromPlayer(worldIn, playerIn, this.liquid == null);
|
|
|
|
if (movingobjectposition == null)
|
|
{
|
|
return itemStackIn;
|
|
}
|
|
else
|
|
{
|
|
if (movingobjectposition.type == HitPosition.ObjectType.BLOCK)
|
|
{
|
|
BlockPos blockpos = movingobjectposition.block;
|
|
|
|
if (!World.isValidXZ(blockpos))
|
|
{
|
|
return itemStackIn;
|
|
}
|
|
|
|
if (this.liquid == null)
|
|
{
|
|
if (!playerIn.canPlayerEdit(blockpos.offset(movingobjectposition.side), movingobjectposition.side, itemStackIn))
|
|
{
|
|
return itemStackIn;
|
|
}
|
|
|
|
State iblockstate = worldIn.getState(blockpos);
|
|
Material material = iblockstate.getBlock().getMaterial();
|
|
|
|
// if (material == Material.water && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0)
|
|
// {
|
|
// worldIn.setBlockToAir(blockpos);
|
|
// playerIn.triggerAchievement(StatList.objectUseStats[ItemRegistry.getIdFromItem(this)]);
|
|
// return this.fillBucket(itemStackIn, playerIn, new ItemStack(Items.water_bucket));
|
|
// }
|
|
// else if (material == Material.lava && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0)
|
|
// {
|
|
// worldIn.setBlockToAir(blockpos);
|
|
// playerIn.triggerAchievement(StatList.objectUseStats[ItemRegistry.getIdFromItem(this)]);
|
|
// return this.fillBucket(itemStackIn, playerIn, new ItemStack(Items.lava_bucket));
|
|
// }
|
|
// else
|
|
if(this.recursive) {
|
|
if (material.isLiquid()) {
|
|
if(!worldIn.client)
|
|
setRecursive((AWorldServer)worldIn, blockpos, 4, null);
|
|
// playerIn.triggerAchievement(StatRegistry.objectUseStats[ItemRegistry.getIdFromItem(this)]);
|
|
// if(!playerIn.creative)
|
|
itemStackIn.decrSize();
|
|
return itemStackIn;
|
|
}
|
|
}
|
|
else {
|
|
if (material.isLiquid() && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0)
|
|
{
|
|
worldIn.setBlockToAir(blockpos);
|
|
// playerIn.triggerAchievement(StatRegistry.objectUseStats[ItemRegistry.getIdFromItem(this)]);
|
|
Block block = iblockstate.getBlock();
|
|
return this.fillBucket(itemStackIn, playerIn, new ItemStack(MAPPING.get((BlockLiquid)block)));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if (this.empty)
|
|
// {
|
|
// return new ItemStack(Items.bucket);
|
|
// }
|
|
|
|
BlockPos blockpos1 = blockpos.offset(movingobjectposition.side);
|
|
|
|
if (!playerIn.canPlayerEdit(blockpos1, movingobjectposition.side, itemStackIn))
|
|
{
|
|
return itemStackIn;
|
|
}
|
|
|
|
if (this.tryPlaceContainedLiquid(worldIn, blockpos1)) // && !playerIn.creative)
|
|
{
|
|
// playerIn.triggerAchievement(StatRegistry.objectUseStats[ItemRegistry.getIdFromItem(this)]);
|
|
if(this.recursive) {
|
|
itemStackIn.decrSize();
|
|
return itemStackIn;
|
|
}
|
|
return new ItemStack(Items.bucket);
|
|
}
|
|
}
|
|
}
|
|
|
|
return itemStackIn;
|
|
}
|
|
}
|
|
|
|
private ItemStack fillBucket(ItemStack emptyBuckets, EntityNPC player, ItemStack fullBucket)
|
|
{
|
|
// if (player.creative)
|
|
// {
|
|
// return emptyBuckets;
|
|
// }
|
|
// else
|
|
if (emptyBuckets.decrSize())
|
|
{
|
|
return fullBucket;
|
|
}
|
|
else
|
|
{
|
|
if (!player.inventory.addItemStackToInventory(fullBucket))
|
|
{
|
|
player.dropPlayerItemWithRandomChoice(fullBucket, false);
|
|
}
|
|
|
|
return emptyBuckets;
|
|
}
|
|
}
|
|
|
|
public boolean tryPlaceContainedLiquid(World worldIn, BlockPos pos)
|
|
{
|
|
if (this.liquid == null)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Material material = worldIn.getState(pos).getBlock().getMaterial();
|
|
boolean flag = !material.isSolid();
|
|
|
|
if (!worldIn.isAirBlock(pos) && !flag)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (worldIn.doesWaterVaporize(pos) && this.liquid.getMaterial() == Material.WATER)
|
|
{
|
|
int i = pos.getX();
|
|
int j = pos.getY();
|
|
int k = pos.getZ();
|
|
worldIn.sendSound(SoundEvent.FIZZ, (double)((float)i + 0.5F), (double)((float)j + 0.5F), (double)((float)k + 0.5F), 0.5F);
|
|
|
|
for (int l = 0; l < 8; ++l)
|
|
{
|
|
worldIn.clientParticle(ParticleType.SMOKE, (double)i + Math.random(), (double)j + Math.random(), (double)k + Math.random());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!worldIn.client && flag && !material.isLiquid())
|
|
{
|
|
worldIn.destroyBlock(pos, true);
|
|
}
|
|
|
|
if(this.recursive) {
|
|
if(!worldIn.client)
|
|
setRecursive((AWorldServer)worldIn, pos, 4, this.liquid.getStaticBlock());
|
|
}
|
|
else {
|
|
worldIn.setState(pos, this.liquid.getState(), 3);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// public void getSubItems(Item itemIn, CreativeTab tab, List<ItemStack> subItems)
|
|
// {
|
|
// if(this.empty) {
|
|
// super.getSubItems(itemIn, tab, subItems);
|
|
// }
|
|
// else {
|
|
// for(int z = 0; z < FluidRegistry.getNumFluids(); z++) {
|
|
// subItems.add(new ItemStack(itemIn, 1, z));
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// public int getColorFromItemStack(ItemStack stack, int renderPass)
|
|
// {
|
|
// return this.fillBlock == null && renderPass == 1 ? FluidRegistry.getLiquidColor(stack.getMetadata()) : 16777215;
|
|
// }
|
|
|
|
@Clientside
|
|
public String[] getTextures(String name) {
|
|
return super.getTextures(this.recursive ? name.substring("recursive_".length()) : name);
|
|
}
|
|
|
|
@Serverside
|
|
public ItemStack dispenseStack(AWorldServer world, TileEntity source, Vec3 position, BlockPos blockpos, Facing facing, ItemStack stack) {
|
|
if(this.recursive)
|
|
return super.dispenseStack(world, source, position, blockpos, facing, stack);
|
|
if(this.liquid == null) {
|
|
BlockPos pos = blockpos.offset(facing);
|
|
State iblockstate = world.getState(pos);
|
|
Block block = iblockstate.getBlock();
|
|
Material material = block.getMaterial();
|
|
Item item;
|
|
if (material.isLiquid() && block instanceof BlockLiquid && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0)
|
|
{
|
|
item = MAPPING.get((BlockLiquid)block);
|
|
}
|
|
else
|
|
{
|
|
return super.dispenseStack(world, source, position, blockpos, facing, stack);
|
|
}
|
|
|
|
world.setBlockToAir(pos);
|
|
|
|
if (stack.decrSize())
|
|
{
|
|
stack.setItem(item);
|
|
stack.setSize(1);
|
|
}
|
|
else if (source instanceof TileEntityDispenser dispenser && dispenser.addItemStack(new ItemStack(item)) < 0)
|
|
{
|
|
super.dispenseStack(world, source, position, blockpos, facing, new ItemStack(item));
|
|
}
|
|
|
|
return stack;
|
|
}
|
|
else {
|
|
BlockPos pos = blockpos.offset(facing);
|
|
|
|
if (this.tryPlaceContainedLiquid(world, pos))
|
|
{
|
|
stack.setItem(Items.bucket);
|
|
stack.setSize(1);
|
|
return stack;
|
|
}
|
|
else
|
|
{
|
|
return super.dispenseStack(world, source, position, blockpos, facing, stack);
|
|
}
|
|
}
|
|
}
|
|
}
|