package speedytools.clientside.tools; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.*; import net.minecraft.util.BlockPos; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.relauncher.Side; import speedytools.clientside.UndoManagerClient; import speedytools.clientside.network.PacketSenderClient; import speedytools.clientside.rendering.RendererWireframeSelection; import speedytools.clientside.rendering.SpeedyToolRenderers; import speedytools.clientside.selections.BlockMultiSelector; import speedytools.clientside.sound.SoundController; import speedytools.clientside.userinput.UserInput; import speedytools.common.blocks.BlockWithMetadata; import speedytools.common.items.ItemSpeedyTool; /** * User: The Grey Ghost * Date: 18/04/2014 */ public abstract class SpeedyTool { public SpeedyTool(ItemSpeedyTool i_parentItem, SpeedyToolRenderers i_renderers, SoundController i_speedyToolSounds, UndoManagerClient i_undoManagerClient, PacketSenderClient i_packetSenderClient) { speedyToolRenderers = i_renderers; parentItem = i_parentItem; iAmActive = false; undoManagerClient = i_undoManagerClient; soundController = i_speedyToolSounds; packetSenderClient = i_packetSenderClient; } public abstract boolean activateTool(ItemStack newToolItemStack); /** The user has unequipped this tool, deactivate it, stop any effects, etc * @return */ public abstract boolean deactivateTool(); /** * Process user input * no effect if the tool is not active. * * @param player * @param userInput * @return */ public abstract boolean processUserInput(EntityPlayerSP player, float partialTick, UserInput userInput); /** * update the tool state based on the player selected items; where the player is looking; etc * No effect if not active. * @param world * @param player * @param partialTick * @return */ public abstract boolean updateForThisFrame(World world, EntityPlayerSP player, float partialTick); /** * resets the tool state eg has a selection, moving selection, etc. */ public abstract void resetTool(); public void performTick(World world) {} protected boolean iAmActive; protected SpeedyToolRenderers speedyToolRenderers; protected SoundController soundController; protected UndoManagerClient undoManagerClient; protected PacketSenderClient packetSenderClient; protected ItemSpeedyTool parentItem; protected ItemStack currentToolItemStack; protected boolean controlKeyIsDown; protected RendererWireframeSelection.WireframeRenderInfoUpdateLink wireframeRendererUpdateLink; /** * when selecting the first block in a selection, how should it be done? * @return */ protected abstract BlockMultiSelector.BlockSelectionBehaviour getBlockSelectionBehaviour(); /** * Selects the Blocks that will be affected by the tool when the player presses right-click * default method just selects the first block. * @param player the player * @param itemStackToPlace the item that would be placed in the selection; or null if none * @param partialTick partial tick time. * @return returns the list of blocks in the selection (may be zero length) */ protected MovingObjectPosition selectBlockUnderCursor(EntityPlayer player, ItemStack itemStackToPlace, float partialTick) { BlockMultiSelector.BlockSelectionBehaviour blockSelectionBehaviour = getBlockSelectionBehaviour(); ItemSpeedyTool.CollideWithLiquids collideWithLiquids = blockSelectionBehaviour.isWaterCollision() ? ItemSpeedyTool.CollideWithLiquids.COLLIDE_WITH_LIQUIDS : ItemSpeedyTool.CollideWithLiquids.DO_NOT_COLLIDE_WITH_LIQUIDS; MovingObjectPosition target = null; if (blockSelectionBehaviour.isPerformCollisionTest()) { target = parentItem.rayTraceLineOfSight(player.worldObj, player, collideWithLiquids); } MovingObjectPosition updatedTarget = BlockMultiSelector.selectStartingBlock(target, blockSelectionBehaviour, player, partialTick); return updatedTarget; } /** * For the given ItemStack, returns the corresponding Block that will be placed by the tool * eg ItemCloth will give the Block cloth * ItemBlocks are converted to the appropriate block * Others: * @param itemToBePlaced - the Item to be placed, or null for none. * @return the Block (and metadata) corresponding to the item, or null for none. */ protected BlockWithMetadata getPlacedBlockFromItemStack(ItemStack itemToBePlaced) { assert FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT; BlockWithMetadata retval = new BlockWithMetadata(); if (itemToBePlaced == null) { retval.block = Blocks.air; retval.metaData = 0; return retval; } Item item = itemToBePlaced.getItem(); if (item instanceof ItemBlock) { ItemBlock itemBlock = (ItemBlock)item; retval.block = Block.getBlockFromItem(itemBlock); retval.metaData = itemBlock.getMetadata(itemToBePlaced.getItemDamage()); } else if (item == Items.water_bucket) { retval.block = Blocks.water; retval.metaData = 0; } else if (item == Items.lava_bucket) { retval.block = Blocks.lava; retval.metaData = 0; } else if (item instanceof ItemSeeds) { ItemSeeds itemSeeds = (ItemSeeds)item; World world = Minecraft.getMinecraft().theWorld; IBlockState blockState = itemSeeds.getPlant(world, BlockPos.ORIGIN); // method doesn't actually use x,y,z retval = new BlockWithMetadata(blockState); } else if (item instanceof ItemRedstone) { retval.block = Blocks.redstone_wire; retval.metaData = 0; } else { retval.block = Blocks.air; retval.metaData = 0; } return retval; } }