package eiteam.esteemedinnovation.transport.block; import eiteam.esteemedinnovation.api.tile.SteamTransporterTileEntity; import eiteam.esteemedinnovation.api.wrench.WrenchDisplay; import eiteam.esteemedinnovation.api.wrench.Wrenchable; import eiteam.esteemedinnovation.commons.Config; import eiteam.esteemedinnovation.transport.TransportationModule; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayerFactory; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.function.Predicate; public class TileEntityPlonker extends SteamTransporterTileEntity implements Wrenchable, WrenchDisplay, IInventory { private static final String MODE_KEY = "Mode"; private static final String INV_KEY = "Inventory"; private boolean prevRedstoneActivated; private boolean curRedstoneActivated; @Nonnull private Mode mode = Mode.ALWAYS_ON; private ItemStack inventory; public TileEntityPlonker() { super(EnumFacing.VALUES); } @Override public boolean canUpdate(IBlockState target) { return target.getBlock() == TransportationModule.PLONKER; } @Override public void initialUpdate() { super.initialUpdate(); EnumFacing dir = worldObj.getBlockState(pos).getValue(BlockPlonker.FACING); addSideToGaugeBlacklist(dir); setValidDistributionDirectionsExcluding(dir); } @Override public void safeUpdate() { EnumFacing dir = worldObj.getBlockState(pos).getValue(BlockPlonker.FACING); if (getSteamShare() < Config.plonkerConsumption) { return; } curRedstoneActivated = worldObj.isBlockPowered(pos); if (canPlace() && worldObj instanceof WorldServer) { FakePlayer player = FakePlayerFactory.getMinecraft((WorldServer) worldObj); inventory.getItem().onItemUse(inventory, player, worldObj, getOffsetPos(dir), player.getActiveHand(), dir.getOpposite(), 0.5F, 0.5F, 0.5F); if (mode == Mode.ALWAYS_ON) { decrSteam(Config.plonkerConsumption); } } prevRedstoneActivated = worldObj.isBlockPowered(pos); super.safeUpdate(); } private boolean isTargetAvailable() { EnumFacing dir = worldObj.getBlockState(pos).getValue(BlockPlonker.FACING); BlockPos target = getOffsetPos(dir); return worldObj.getBlockState(target).getBlock().isReplaceable(worldObj, target); } private static boolean canSwitchMode(EntityPlayer player) { return player.isSneaking(); } private boolean canPlace() { return inventory != null && mode.canPlace(this) && isTargetAvailable(); } @Override public void displayWrench(RenderGameOverlayEvent.Post event) { GlStateManager.pushMatrix(); int color = canSwitchMode(Minecraft.getMinecraft().thePlayer) ? 0xC6C6C6 : 0x777777; int x = event.getResolution().getScaledWidth() / 2 - 8; int y = event.getResolution().getScaledHeight() / 2 - 8; String loc = I18n.format("esteemedinnovation.plonker." + mode.localizationKey()); Minecraft.getMinecraft().fontRendererObj.drawStringWithShadow(loc, x + 15, y + 13, color); GlStateManager.popMatrix(); } @Override public boolean onWrench(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, IBlockState state, float hitX, float hitY, float hitZ) { if (canSwitchMode(player)) { mode = mode.cycle(); markForResync(); } return true; } @Override public int getSizeInventory() { return 1; } @Nullable @Override public ItemStack getStackInSlot(int index) { return inventory; } @Nullable @Override public ItemStack decrStackSize(int index, int count) { inventory.stackSize--; return inventory; } @Nullable @Override public ItemStack removeStackFromSlot(int index) { ItemStack cache = inventory; inventory = null; return cache; } @Override public void setInventorySlotContents(int index, @Nullable ItemStack stack) { inventory = stack; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return false; } @Override public void openInventory(EntityPlayer player) {} @Override public void closeInventory(EntityPlayer player) {} @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return stack.getItem() instanceof ItemBlock; } @Override public void clear() { inventory = null; } @Override public boolean hasCustomName() { return false; } @Override public void readFromNBT(NBTTagCompound access) { super.readFromNBT(access); mode = Mode.LOOKUP[access.getInteger(MODE_KEY)]; inventory = access.hasKey(INV_KEY) ? ItemStack.loadItemStackFromNBT(access.getCompoundTag(INV_KEY)) : null; } @Override public NBTTagCompound writeToNBT(NBTTagCompound access) { super.writeToNBT(access); access.setInteger(MODE_KEY, mode.ordinal()); if (inventory != null) { access.setTag(INV_KEY, inventory.serializeNBT()); } return access; } @Override public SPacketUpdateTileEntity getUpdatePacket() { NBTTagCompound access = writeToNBT(getUpdateTag()); return new SPacketUpdateTileEntity(pos, 1, access); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { super.onDataPacket(net, pkt); readFromNBT(pkt.getNbtCompound()); markForResync(); } enum Mode { ALWAYS_ON("always", (plonker) -> true), REDSTONE_ACTIVATED("pulse", (plonker) -> plonker.curRedstoneActivated && !plonker.prevRedstoneActivated); static final Mode[] LOOKUP = new Mode[2]; static { for (Mode mode : values()) { LOOKUP[mode.ordinal()] = mode; } } private final String locKey; private final Predicate<TileEntityPlonker> canPlace; Mode(String locKey, Predicate<TileEntityPlonker> canPlace) { this.locKey = locKey; this.canPlace = canPlace; } Mode cycle() { return this == ALWAYS_ON ? REDSTONE_ACTIVATED : ALWAYS_ON; } String localizationKey() { return locKey; } boolean canPlace(TileEntityPlonker plonker) { return canPlace.test(plonker); } } // Ignore this crap... @Override public int getField(int id) { return 0; } @Override public void setField(int id, int value) {} @Override public int getFieldCount() { return 0; } }