package com.carpentersblocks.block; import java.util.List; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import com.carpentersblocks.data.PressurePlate; import com.carpentersblocks.tileentity.TEBase; import com.carpentersblocks.util.handler.ChatHandler; import com.carpentersblocks.util.registry.BlockRegistry; import com.carpentersblocks.util.registry.IconRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class BlockCarpentersPressurePlate extends BlockSided { private static PressurePlate data = new PressurePlate(); /** Whether full bounds should be used for collision purposes. */ private boolean fullBounds = false; public BlockCarpentersPressurePlate(Material material) { super(material, data); } @Override @SideOnly(Side.CLIENT) /** * Returns a base icon that doesn't rely on blockIcon, which * is set prior to texture stitch events. */ public IIcon getIcon() { return IconRegistry.icon_uncovered_full; } @Override /** * Alters polarity. */ protected boolean onHammerLeftClick(TEBase TE, EntityPlayer entityPlayer) { int polarity = data.getPolarity(TE) == data.POLARITY_POSITIVE ? data.POLARITY_NEGATIVE : data.POLARITY_POSITIVE; data.setPolarity(TE, polarity); notifyBlocksOfPowerChange(TE.getWorldObj(), TE.xCoord, TE.yCoord, TE.zCoord); if (polarity == data.POLARITY_POSITIVE) { ChatHandler.sendMessageToPlayer("message.polarity_pos.name", entityPlayer); } else { ChatHandler.sendMessageToPlayer("message.polarity_neg.name", entityPlayer); } return true; } @Override /** * Alters trigger behavior. */ protected boolean onHammerRightClick(TEBase TE, EntityPlayer entityPlayer) { int trigger = data.getTriggerEntity(TE); if (++trigger > 3) { trigger = 0; } data.setTriggerEntity(TE, trigger); notifyBlocksOfPowerChange(TE.getWorldObj(), TE.xCoord, TE.yCoord, TE.zCoord); if (trigger == data.TRIGGER_PLAYER) { ChatHandler.sendMessageToPlayer("message.trigger_player.name", entityPlayer); } else if (trigger == data.TRIGGER_MONSTER) { ChatHandler.sendMessageToPlayer("message.trigger_monster.name", entityPlayer); } else if (trigger == data.TRIGGER_ANIMAL) { ChatHandler.sendMessageToPlayer("message.trigger_animal.name", entityPlayer); } else { ChatHandler.sendMessageToPlayer("message.trigger_all.name", entityPlayer); } return true; } /** * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been * cleared to be reused) */ @Override public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { return null; } @Override /** * Updates the blocks bounds based on its current state. Args: world, x, y, z */ public void setBlockBoundsBasedOnState(IBlockAccess blockAccess, int x, int y, int z) { TEBase TE = getTileEntity(blockAccess, x, y, z); if (TE != null) { float depth = fullBounds | !isDepressed(TE) ? 0.0625F : 0.03125F; setBlockBounds(0.0625F, 0.0625F, 0.0F, 0.9375F, 0.9375F, depth, data.getDirection(TE)); } } @Override /** * Ticks the block if it's been scheduled */ public void updateTick(World world, int x, int y, int z, Random random) { if (!world.isRemote) { TEBase TE = getTileEntity(world, x, y, z); if (TE != null) { boolean depressed = false; if (isDepressed(TE)) { depressed = hasTriggerInBounds(TE); } if (depressed) { world.scheduleBlockUpdate(x, y, z, this, tickRate(world)); } else { toggleOff(TE, world, x, y, z); } } } } @Override /** * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity */ public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) { if (!world.isRemote) { TEBase TE = getTileEntity(world, x, y, z); if (TE != null) { if (hasTriggerInBounds(TE)) { toggleOn(TE, world, x, y, z); } } } } /** * Returns whether sensitive area contains an entity that can * trigger a state change. * * @param TE the {@link TEBase} * @return whether sensitive area contains valid {@link Entity} */ private boolean hasTriggerInBounds(TEBase TE) { fullBounds = true; List entityList = TE.getWorldObj().getEntitiesWithinAABB(Entity.class, getSensitiveAABB(TE.getWorldObj(), TE.xCoord, TE.yCoord, TE.zCoord)); fullBounds = false; if (!entityList.isEmpty()) { for (int idx = 0; idx < entityList.size(); ++idx) { if (canEntityTrigger(TE, (Entity)entityList.get(idx))) { return true; } } } return false; } /** * Gets the area of bounding box that is sensitive to changes. * * @param x the x coordinate * @param y the y coordinate * @param z the z coordinate * @return the {@link AxisAlignedBB} */ private AxisAlignedBB getSensitiveAABB(World world, int x, int y, int z) { setBlockBoundsBasedOnState(world, x, y, z); return AxisAlignedBB.getBoundingBox(x + minX, y + minY, z + minZ, x + maxX, y + maxY, z + maxZ); } /** * Activates pressure plate. */ private void toggleOn(TEBase TE, World world, int x, int y, int z) { data.setState(TE, data.STATE_ON, true); notifyBlocksOfPowerChange(world, x, y, z); world.scheduleBlockUpdate(x, y, z, this, tickRate(world)); } /** * Deactivates pressure plate. */ private void toggleOff(TEBase TE, World world, int x, int y, int z) { data.setState(TE, data.STATE_OFF, true); notifyBlocksOfPowerChange(world, x, y, z); } /** * Returns whether pressure plate is in depressed state */ private boolean isDepressed(TEBase TE) { return data.getState(TE) == data.STATE_ON; } @Override /** * Can this block provide power. Only wire currently seems to have this change based on its state. */ public boolean canProvidePower() { return true; } /** * Returns power level (0 or 15) */ @Override public int getPowerOutput(TEBase TE) { int polarity = data.getPolarity(TE); if (isDepressed(TE)) { return polarity == data.POLARITY_POSITIVE ? 15 : 0; } else { return polarity == data.POLARITY_NEGATIVE ? 15 : 0; } } /** * Returns whether pressure plate should trigger based on entity colliding with it. */ private boolean canEntityTrigger(TEBase TE, Entity entity) { if (entity == null) { return false; } int trigger = data.getTriggerEntity(TE); if (trigger == data.TRIGGER_PLAYER) { return entity instanceof EntityPlayer; } else if (trigger == data.TRIGGER_MONSTER) { return entity.isCreatureType(EnumCreatureType.monster, false); } else if (trigger == data.TRIGGER_ANIMAL) { return entity.isCreatureType(EnumCreatureType.creature, false); } else { return true; } } @Override /** * Ejects contained items into the world, and notifies neighbours of an update, as appropriate */ public void breakBlock(World world, int x, int y, int z, Block block, int metadata) { TEBase TE = getSimpleTileEntity(world, x, y, z); if (TE != null) { if (isDepressed(TE)) { notifyBlocksOfPowerChange(world, x, y, z); } } super.breakBlock(world, x, y, z, block, metadata); } @Override /** * The type of render function that is called for this block */ public int getRenderType() { return BlockRegistry.carpentersPressurePlateRenderID; } }