package net.slimevoid.library.tileentity; import net.minecraft.block.Block.SoundType; import net.minecraft.block.state.IBlockState; import net.minecraft.client.particle.EffectRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.server.gui.IUpdatePlayerListBox; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; import net.minecraft.world.Explosion; import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import net.slimevoid.library.blocks.BlockBase; import net.slimevoid.library.core.lib.NBTLib; import net.slimevoid.library.util.helpers.BlockHelper; import net.slimevoid.library.util.helpers.ItemHelper; import java.util.ArrayList; import java.util.List; public abstract class TileEntityBase extends TileEntity implements IUpdatePlayerListBox, IInventory { protected long tickSchedule; protected int rotation; protected boolean active; public TileEntityBase() { this.tickSchedule = -1L; this.rotation = 0; this.active = false; } public void onNeighborChange(BlockPos pos) { } public int onBlockPlaced(int side, float hitX, float hitY, float hitZ, int damage) { return damage; } public void onBlockPlacedBy(ItemStack itemstack, EntityLivingBase entity) { this.setRotation((int) Math.floor((double) ((entity.rotationYaw * 4F) / 360F) + 0.5D) & 3); } public int getRotation() { return this.rotation; } public void setRotation(int newRotation) { this.rotation = newRotation; } public void onTileTick() { } public boolean onBlockActivated(IBlockState blockState, EntityPlayer entityplayer, EnumFacing side, float xHit, float yHit, float zHit) { return false; } public abstract int getExtendedBlockID(); public int getExtendedMetadata() { return 0; } public boolean removeBlockByPlayer(EntityPlayer player, BlockBase blockBase, boolean willHarvest) { return blockBase.superRemoveBlockByPlayer(this.getWorld(), pos, player, willHarvest); } public ItemStack getPickBlock(MovingObjectPosition target, BlockBase blockBase) { return blockBase.superGetPickBlock(target, this.getWorld(), this.pos); } public float getBlockHardness(BlockBase blockBase) { return blockBase.superBlockHardness(this.getWorld(), this.pos); } public float getPlayerRelativeBlockHardness(EntityPlayer entityplayer, IBlockState blockState) { return ForgeHooks.blockStrength(blockState, entityplayer, this.getWorld(), this.pos); } public float getExplosionResistance(BlockBase blockBase, Entity exploder, Explosion explosion) { return blockBase.superGetExplosionResistance(this.getWorld(), this.pos, exploder, explosion); } public int colorMultiplier(BlockBase blockBase, int renderPass) { return blockBase.superColorMultiplier(this.getWorld(), this.pos, renderPass); } protected abstract void addHarvestContents(ArrayList<ItemStack> harvestList); public void scheduleTick(int time) { long worldTime = this.getWorld().getWorldTime() + (long) time; if (this.tickSchedule > 0L && this.tickSchedule < worldTime) { return; } else { this.tickSchedule = worldTime; this.markBlockDirty(); return; } } public int getLightValue() { return 0; } public void updateBlock() { this.getWorld().markBlockForUpdate(this.pos); this.getWorld().notifyLightSet(this.pos); } public void updateBlockAndNeighbours() { BlockHelper.updateIndirectNeighbors(this.getWorld(), this.pos, this.getBlockType()); this.updateBlock(); } public void markBlockDirty() { //BlockHelper.markBlockDirty(this.getWorld(), // this.pos); } public void breakBlock(IBlockState blockState) { ArrayList<ItemStack> harvestList = new ArrayList<ItemStack>(); this.addHarvestContents(harvestList); for (ItemStack itemstack : harvestList) { ItemHelper.dropItem(this.getWorld(), this.pos, itemstack); } } @Override public void update() { if (this.getWorld().isRemote) return; if (this.tickSchedule < 0L) return; long worldTime = this.getWorld().getWorldTime(); if (this.tickSchedule > worldTime + 1200L) this.tickSchedule = worldTime + 1200L; else if (this.tickSchedule <= worldTime) { this.tickSchedule = -1L; this.onTileTick(); this.markBlockDirty(); } } public EnumFacing getFacing() { switch (this.rotation) { case 0: return EnumFacing.NORTH; case 1: return EnumFacing.EAST; case 2: return EnumFacing.SOUTH; case 3: return EnumFacing.WEST; } return EnumFacing.NORTH; } //public IIcon getBlockTexture(int x, int y, int z, int metadata, int side) { // return this.getBlockType().getIcon(this.getRotatedSide(side), // metadata); //} public void setBlockBoundsBasedOnState(BlockBase blockBase) { blockBase.superSetBlockBoundsBasedOnState(this.getWorld(), this.pos); } public void setBlockBoundsForItemRender(BlockBase blockBase) { blockBase.setBlockBoundsForItemRender(); } public MovingObjectPosition collisionRayTrace(BlockBase blockbase, Vec3 startVec, Vec3 endVec) { return blockbase.superCollisionRayTrace(this.getWorld(), this.pos, startVec, endVec); } public void addCollisionBoxesToList(BlockBase blockBase, IBlockState blockState, AxisAlignedBB axisAlignedBB, List aList, Entity anEntity) { blockBase.superAddCollisionBoxesToList(this.getWorld(), this.pos, blockState, axisAlignedBB, aList, anEntity); } public boolean isSideSolid(BlockBase blockBase, EnumFacing side) { return blockBase.superSideSolid(this.getWorld(), this.pos, side); } public boolean addBlockDestroyEffects(BlockBase blockBase, EffectRenderer effectRenderer) { return blockBase.superDestroyEffects(this.getWorld(), this.pos, effectRenderer); } public boolean addBlockHitEffects(BlockBase blockBase, MovingObjectPosition target, EffectRenderer effectRenderer) { return blockBase.superHitEffects(this.getWorld(), target, effectRenderer); } public abstract IBlockState getActualState(IBlockState state, BlockBase blockBase); public abstract IBlockState getExtendedState(IBlockState state, BlockBase blockBase); /** * This can be overriden and used to retrieve the step sound based on * TileEntity information * * @return a Step Sound */ public SoundType getStepSound() { return null; } @Override public void readFromNBT(NBTTagCompound nbttagcompound) { super.readFromNBT(nbttagcompound); this.tickSchedule = nbttagcompound.getLong(NBTLib.TILE_TICK_SCHEDULE); this.rotation = nbttagcompound.getByte(NBTLib.TILE_ROTATION); int status = nbttagcompound.getByte(NBTLib.TILE_ACTIVE); this.active = status > 0; } @Override public void writeToNBT(NBTTagCompound nbttagcompound) { super.writeToNBT(nbttagcompound); nbttagcompound.setLong(NBTLib.TILE_TICK_SCHEDULE, this.tickSchedule); nbttagcompound.setByte(NBTLib.TILE_ROTATION, (byte) this.rotation); nbttagcompound.setByte(NBTLib.TILE_ACTIVE, (byte) (this.active ? 1 : 0)); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { this.readFromNBT(pkt.getNbtCompound()); this.onInventoryChanged(); this.updateBlock(); } public void onInventoryChanged() { this.markDirty(); this.onInventoryHasChanged(this.worldObj, this.pos); } /** * If we need to send information to the client it should be done here */ protected void onInventoryHasChanged(World world, BlockPos pos) { world.markBlockForUpdate(pos); } @Override public String getCommandSenderName() { return this.getInvName(); } public abstract String getInvName(); @Override public boolean hasCustomName() { return false; } @Override public void openInventory(EntityPlayer entityplayer) { } @Override public void closeInventory(EntityPlayer entityplayer) { } @Override public Packet getDescriptionPacket() { NBTTagCompound nbttagcompound = new NBTTagCompound(); this.writeToNBT(nbttagcompound); Packet packet = new S35PacketUpdateTileEntity(pos, 0, nbttagcompound); return packet; } }