fab95e8900
I went for what seemed like a good level of organisation: Java __________ Mekanism __________ Minecraft Forge FML __________ Netty LWJGL __________ Other APIs __________ Static Imports.
382 lines
9.5 KiB
Java
382 lines
9.5 KiB
Java
package mekanism.common.item;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import mekanism.api.Coord4D;
|
|
import mekanism.api.EnumColor;
|
|
import mekanism.api.util.ListUtils;
|
|
import mekanism.common.util.MekanismUtils;
|
|
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.client.renderer.texture.IIconRegister;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.util.ChatComponentText;
|
|
import net.minecraft.util.DamageSource;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
import net.minecraftforge.event.entity.player.UseHoeEvent;
|
|
import cpw.mods.fml.common.eventhandler.Event.Result;
|
|
|
|
public class ItemAtomicDisassembler extends ItemEnergized
|
|
{
|
|
public double ENERGY_USAGE = 10;
|
|
public double HOE_USAGE = 100;
|
|
|
|
public ItemAtomicDisassembler()
|
|
{
|
|
super(1000000);
|
|
}
|
|
|
|
@Override
|
|
public void registerIcons(IIconRegister register) {}
|
|
|
|
@Override
|
|
public boolean canHarvestBlock(Block block, ItemStack stack)
|
|
{
|
|
return block != Blocks.bedrock;
|
|
}
|
|
|
|
@Override
|
|
public void addInformation(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag)
|
|
{
|
|
super.addInformation(itemstack, entityplayer, list, flag);
|
|
|
|
list.add(MekanismUtils.localize("tooltip.mode") + ": " + EnumColor.INDIGO + getModeName(itemstack));
|
|
list.add(MekanismUtils.localize("tooltip.efficiency") + ": " + EnumColor.INDIGO + getEfficiency(itemstack));
|
|
}
|
|
|
|
@Override
|
|
public boolean hitEntity(ItemStack itemstack, EntityLivingBase hitEntity, EntityLivingBase player)
|
|
{
|
|
if(getEnergy(itemstack) > 0)
|
|
{
|
|
hitEntity.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer)player), 20);
|
|
setEnergy(itemstack, getEnergy(itemstack) - 2000);
|
|
}
|
|
else {
|
|
hitEntity.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer)player), 4);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public float getDigSpeed(ItemStack itemstack, Block block, int meta)
|
|
{
|
|
return getEnergy(itemstack) != 0 ? getEfficiency(itemstack) : 1F;
|
|
}
|
|
|
|
@Override
|
|
public boolean onBlockDestroyed(ItemStack itemstack, World world, Block block, int x, int y, int z, EntityLivingBase entityliving)
|
|
{
|
|
if(block.getBlockHardness(world, x, y, z) != 0.0D)
|
|
{
|
|
setEnergy(itemstack, getEnergy(itemstack) - (ENERGY_USAGE*getEfficiency(itemstack)));
|
|
}
|
|
else {
|
|
setEnergy(itemstack, getEnergy(itemstack) - (ENERGY_USAGE*(getEfficiency(itemstack))/2));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onBlockStartBreak(ItemStack itemstack, int x, int y, int z, EntityPlayer player)
|
|
{
|
|
super.onBlockStartBreak(itemstack, x, y, z, player);
|
|
|
|
if(!player.worldObj.isRemote)
|
|
{
|
|
Block block = player.worldObj.getBlock(x, y, z);
|
|
int meta = player.worldObj.getBlockMetadata(x, y, z);
|
|
|
|
if(block == Blocks.lit_redstone_ore)
|
|
{
|
|
block = Blocks.redstone_ore;
|
|
}
|
|
|
|
ItemStack stack = new ItemStack(block, 1, meta);
|
|
Coord4D orig = new Coord4D(x, y, z, player.worldObj.provider.dimensionId);
|
|
|
|
List<String> names = MekanismUtils.getOreDictName(stack);
|
|
|
|
boolean isOre = false;
|
|
|
|
for(String s : names)
|
|
{
|
|
if(s.startsWith("ore") || s.equals("logWood"))
|
|
{
|
|
isOre = true;
|
|
}
|
|
}
|
|
|
|
if(getMode(itemstack) == 3 && isOre && !player.capabilities.isCreativeMode)
|
|
{
|
|
Set<Coord4D> found = new Finder(player.worldObj, stack, new Coord4D(x, y, z, player.worldObj.provider.dimensionId)).calc();
|
|
|
|
for(Coord4D coord : found)
|
|
{
|
|
if(coord.equals(orig) || getEnergy(itemstack) < (ENERGY_USAGE*getEfficiency(itemstack)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Block block2 = coord.getBlock(player.worldObj);
|
|
|
|
block2.onBlockDestroyedByPlayer(player.worldObj, coord.xCoord, coord.yCoord, coord.zCoord, meta);
|
|
player.worldObj.playAuxSFXAtEntity(null, 2001, coord.xCoord, coord.yCoord, coord.zCoord, meta << 12);
|
|
player.worldObj.setBlockToAir(coord.xCoord, coord.yCoord, coord.zCoord);
|
|
block2.breakBlock(player.worldObj, coord.xCoord, coord.yCoord, coord.zCoord, block, meta);
|
|
block2.dropBlockAsItem(player.worldObj, coord.xCoord, coord.yCoord, coord.zCoord, meta, 0);
|
|
|
|
setEnergy(itemstack, getEnergy(itemstack) - (ENERGY_USAGE*getEfficiency(itemstack)));
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isFull3D()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer)
|
|
{
|
|
if(!world.isRemote && entityplayer.isSneaking())
|
|
{
|
|
toggleMode(itemstack);
|
|
entityplayer.addChatMessage(new ChatComponentText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + MekanismUtils.localize("tooltip.modeToggle") + " " + EnumColor.INDIGO + getModeName(itemstack) + EnumColor.AQUA + " (" + getEfficiency(itemstack) + ")"));
|
|
}
|
|
|
|
return itemstack;
|
|
}
|
|
|
|
@Override
|
|
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
|
|
{
|
|
if(!player.isSneaking())
|
|
{
|
|
if(!useHoe(stack, player, world, x, y, z, side))
|
|
{
|
|
if(world.getBlock(x, y, z) != Blocks.farmland)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
switch(getEfficiency(stack))
|
|
{
|
|
case 20:
|
|
for(int x1 = x-1; x1 <= x+1; x1++)
|
|
{
|
|
for(int z1 = z-1; z1 <= z+1; z1++)
|
|
{
|
|
useHoe(stack, player, world, x1, y, z1, side);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case 128:
|
|
for(int x1 = x-2; x1 <= x+2; x1++)
|
|
{
|
|
for(int z1 = z-2; z1 <= z+2; z1++)
|
|
{
|
|
useHoe(stack, player, world, x1, y, z1, side);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private boolean useHoe(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side)
|
|
{
|
|
if(!player.canPlayerEdit(x, y, z, side, stack) || (!player.capabilities.isCreativeMode && getEnergy(stack) < HOE_USAGE))
|
|
{
|
|
return false;
|
|
}
|
|
else {
|
|
UseHoeEvent event = new UseHoeEvent(player, stack, world, x, y, z);
|
|
|
|
if(MinecraftForge.EVENT_BUS.post(event))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(event.getResult() == Result.ALLOW)
|
|
{
|
|
setEnergy(stack, getEnergy(stack)-HOE_USAGE);
|
|
return true;
|
|
}
|
|
|
|
Block block1 = world.getBlock(x, y, z);
|
|
boolean air = world.isAirBlock(x, y + 1, z);
|
|
|
|
if(side != 0 && air && (block1 == Blocks.grass || block1 == Blocks.dirt))
|
|
{
|
|
Block farm = Blocks.farmland;
|
|
world.playSoundEffect(x + 0.5F, y + 0.5F, z + 0.5F, farm.stepSound.getStepResourcePath(), (farm.stepSound.getVolume() + 1.0F) / 2.0F, farm.stepSound.getPitch() * 0.8F);
|
|
|
|
if(world.isRemote)
|
|
{
|
|
return true;
|
|
}
|
|
else {
|
|
world.setBlock(x, y, z, farm);
|
|
|
|
if(!player.capabilities.isCreativeMode)
|
|
{
|
|
setEnergy(stack, getEnergy(stack)-HOE_USAGE);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public int getEfficiency(ItemStack itemStack)
|
|
{
|
|
switch(getMode(itemStack))
|
|
{
|
|
case 0:
|
|
return 20;
|
|
case 1:
|
|
return 8;
|
|
case 2:
|
|
return 128;
|
|
case 3:
|
|
return 20;
|
|
case 4:
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public int getMode(ItemStack itemStack)
|
|
{
|
|
if(itemStack.stackTagCompound == null)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return itemStack.stackTagCompound.getInteger("mode");
|
|
}
|
|
|
|
public String getModeName(ItemStack itemStack)
|
|
{
|
|
int mode = getMode(itemStack);
|
|
|
|
switch(mode)
|
|
{
|
|
case 0:
|
|
return MekanismUtils.localize("tooltip.disassembler.normal");
|
|
case 1:
|
|
return MekanismUtils.localize("tooltip.disassembler.slow");
|
|
case 2:
|
|
return MekanismUtils.localize("tooltip.disassembler.fast");
|
|
case 3:
|
|
return MekanismUtils.localize("tooltip.disassembler.vein");
|
|
case 4:
|
|
return MekanismUtils.localize("tooltip.disassembler.off");
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void toggleMode(ItemStack itemStack)
|
|
{
|
|
if(itemStack.stackTagCompound == null)
|
|
{
|
|
itemStack.setTagCompound(new NBTTagCompound());
|
|
}
|
|
|
|
itemStack.stackTagCompound.setInteger("mode", getMode(itemStack) < 4 ? getMode(itemStack)+1 : 0);
|
|
}
|
|
|
|
@Override
|
|
public boolean canSend(ItemStack itemStack)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public static class Finder
|
|
{
|
|
public World world;
|
|
|
|
public ItemStack stack;
|
|
|
|
public Coord4D location;
|
|
|
|
public Set<Coord4D> found = new HashSet<Coord4D>();
|
|
|
|
public static Map<Block, List<Block>> ignoreBlocks = new HashMap<Block, List<Block>>();
|
|
|
|
public Finder(World w, ItemStack s, Coord4D loc)
|
|
{
|
|
world = w;
|
|
stack = s;
|
|
location = loc;
|
|
}
|
|
|
|
public void loop(Coord4D pointer)
|
|
{
|
|
if(found.contains(pointer) || found.size() > 128)
|
|
{
|
|
return;
|
|
}
|
|
|
|
found.add(pointer);
|
|
|
|
for(ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
|
|
{
|
|
Coord4D coord = pointer.getFromSide(side);
|
|
|
|
if(coord.exists(world) && checkID(coord.getBlock(world)) && (coord.getMetadata(world) == stack.getItemDamage() || (MekanismUtils.getOreDictName(stack).contains("logWood") && coord.getMetadata(world) % 4 == stack.getItemDamage() % 4)))
|
|
{
|
|
loop(coord);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Set<Coord4D> calc()
|
|
{
|
|
loop(location);
|
|
|
|
return found;
|
|
}
|
|
|
|
public boolean checkID(Block b)
|
|
{
|
|
Block origBlock = location.getBlock(world);
|
|
return (ignoreBlocks.get(origBlock) == null && b == origBlock) || (ignoreBlocks.get(origBlock) != null && ignoreBlocks.get(origBlock).contains(b));
|
|
}
|
|
|
|
static {
|
|
ignoreBlocks.put(Blocks.redstone_ore, ListUtils.asList(Blocks.redstone_ore, Blocks.lit_redstone_ore));
|
|
ignoreBlocks.put(Blocks.lit_redstone_ore, ListUtils.asList(Blocks.redstone_ore, Blocks.lit_redstone_ore));
|
|
}
|
|
}
|
|
}
|