aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/common')
-rw-r--r--src/main/java/gregtech/common/GT_Client.java61
-rw-r--r--src/main/java/gregtech/common/items/behaviors/Behaviour_Wrench.java341
-rw-r--r--src/main/java/gregtech/common/tools/GT_Tool_Crowbar.java12
-rw-r--r--src/main/java/gregtech/common/tools/GT_Tool_Wrench.java128
4 files changed, 358 insertions, 184 deletions
diff --git a/src/main/java/gregtech/common/GT_Client.java b/src/main/java/gregtech/common/GT_Client.java
index f9b83c1a34..ebce87fdb5 100644
--- a/src/main/java/gregtech/common/GT_Client.java
+++ b/src/main/java/gregtech/common/GT_Client.java
@@ -18,6 +18,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
+import java.util.function.Function;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
@@ -46,6 +47,8 @@ import com.glodblock.github.nei.recipes.extractor.GregTech5RecipeExtractor;
import com.gtnewhorizon.structurelib.alignment.IAlignment;
import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider;
+import appeng.api.util.IOrientable;
+import appeng.tile.misc.TileInterface;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Scale;
import codechicken.lib.vec.Transformation;
@@ -67,7 +70,9 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.interfaces.tileentity.ITurnable;
import gregtech.api.items.GT_MetaGenerated_Item;
import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.BaseMetaTileEntity;
import gregtech.api.metatileentity.MetaPipeEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine;
import gregtech.api.multitileentity.multiblock.base.MultiBlockPart;
import gregtech.api.net.GT_Packet_ClientPreference;
import gregtech.api.objects.GT_ItemStack;
@@ -350,12 +355,18 @@ public class GT_Client extends GT_Proxy implements Runnable {
for (final ForgeDirection tSide : ForgeDirection.VALID_DIRECTIONS) {
if (iCoverable.getCoverIDAtSide(tSide) != 0) tConnections |= tSide.flag;
}
- } else if (tTile instanceof BaseMetaPipeEntity) tConnections = ((BaseMetaPipeEntity) tTile).mConnections;
+ } else if (tTile instanceof BaseMetaTileEntity baseMetaTile && baseMetaTile.getAlignment() == null) {
+ if (!aIsSneaking) tConnections |= baseMetaTile.getFrontFacing().flag;
+ else if (baseMetaTile.getMetaTileEntity() instanceof GT_MetaTileEntity_BasicMachine basicMachine) {
+ tConnections |= basicMachine.mMainFacing.flag;
+ }
+ } else if (tTile instanceof BaseMetaPipeEntity pipeEntity) tConnections = pipeEntity.mConnections;
} else if (tTile instanceof IWrenchable wrenchable) {
tConnections |= ForgeDirection.getOrientation(wrenchable.getFacing()).flag;
} else if (ROTATABLE_VANILLA_BLOCKS.contains(block)) {
tConnections |= ForgeDirection.getOrientation(meta).flag;
- }
+ } else if (tTile instanceof TileInterface tileInterface) tConnections |= tileInterface.getUp()
+ .getOpposite().flag;
if (tConnections != 0) {
for (ForgeDirection tSide : ForgeDirection.VALID_DIRECTIONS) {
@@ -415,24 +426,36 @@ public class GT_Client extends GT_Proxy implements Runnable {
}
GL11.glEnd();
// draw turning indicator
- if (aIsWrench && tTile instanceof IAlignmentProvider) {
- final IAlignment tAlignment = ((IAlignmentProvider) (tTile)).getAlignment();
- if (tAlignment != null) {
- final ForgeDirection direction = tAlignment.getDirection();
- if (direction.ordinal() == tSideHit)
- drawExtendedRotationMarker(ROTATION_MARKER_TRANSFORM_CENTER, aIsSneaking, tAlignment);
+ Function<ForgeDirection, Transformation[]> getTransform = (ForgeDirection direction) -> {
+ try {
+ if (direction.ordinal() == tSideHit) return new Transformation[] { ROTATION_MARKER_TRANSFORM_CENTER };
else if (direction.getOpposite()
.ordinal() == tSideHit) {
- for (Transformation t : ROTATION_MARKER_TRANSFORMS_CORNER) {
- drawExtendedRotationMarker(t, aIsSneaking, tAlignment);
- }
+ return ROTATION_MARKER_TRANSFORMS_CORNER;
} else {
- drawExtendedRotationMarker(
+ return new Transformation[] {
ROTATION_MARKER_TRANSFORMS_SIDES_TRANSFORMS[ROTATION_MARKER_TRANSFORMS_SIDES[tSideHit * 6
- + direction.ordinal()]],
- aIsSneaking,
- tAlignment);
+ + direction.ordinal()]] };
}
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return new Transformation[] {};
+ }
+
+ };
+
+ if (aIsWrench && tTile instanceof IAlignmentProvider) {
+ final IAlignment tAlignment = ((IAlignmentProvider) (tTile)).getAlignment();
+ if (tAlignment != null) {
+ for (var transform : getTransform.apply(tAlignment.getDirection())) {
+ drawExtendedRotationMarker(transform, aIsSneaking, tAlignment);
+ }
+ }
+ }
+ if (aIsWrench && tTile instanceof IOrientable orientable
+ && !(tTile instanceof TileInterface)
+ && orientable.canBeRotated()) {
+ for (var transform : getTransform.apply(aIsSneaking ? orientable.getForward() : orientable.getUp())) {
+ drawExtendedRotationMarker(transform, aIsSneaking, orientable);
}
}
GL20.glUseProgram(program); // resume shader
@@ -451,6 +474,10 @@ public class GT_Client extends GT_Proxy implements Runnable {
}
}
+ private static void drawExtendedRotationMarker(Transformation transform, boolean sneaking, IOrientable orientable) {
+ drawRotationMarker(transform);
+ }
+
private static void drawRotationMarker(Transformation transform) {
if (!rotationMarkerDisplayListCompiled) {
rotationMarkerDisplayList = GLAllocation.generateDisplayLists(1);
@@ -796,7 +823,9 @@ public class GT_Client extends GT_Proxy implements Runnable {
if (GT_Utility.isStackInList(aEvent.currentItem, GregTech_API.sWrenchList)) {
if (aTileEntity instanceof ITurnable || ROTATABLE_VANILLA_BLOCKS.contains(aBlock)
- || aTileEntity instanceof IWrenchable) drawGrid(aEvent, false, true, aEvent.player.isSneaking());
+ || aTileEntity instanceof IWrenchable
+ || (aTileEntity instanceof IOrientable orientable && orientable.canBeRotated()))
+ drawGrid(aEvent, false, true, aEvent.player.isSneaking());
return;
}
diff --git a/src/main/java/gregtech/common/items/behaviors/Behaviour_Wrench.java b/src/main/java/gregtech/common/items/behaviors/Behaviour_Wrench.java
index df6f3bb0d4..edafab779f 100644
--- a/src/main/java/gregtech/common/items/behaviors/Behaviour_Wrench.java
+++ b/src/main/java/gregtech/common/items/behaviors/Behaviour_Wrench.java
@@ -2,21 +2,24 @@ package gregtech.common.items.behaviors;
import java.util.Arrays;
import java.util.List;
+import java.util.function.BooleanSupplier;
import net.minecraft.block.Block;
-import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.oredict.OreDictionary;
+import appeng.api.parts.IPartHost;
+import appeng.api.util.IOrientable;
+import appeng.tile.misc.TileInterface;
import gregtech.api.enums.SoundResource;
import gregtech.api.items.GT_MetaBase_Item;
import gregtech.api.items.GT_MetaGenerated_Tool;
import gregtech.api.util.GT_LanguageManager;
-import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_Utility;
import ic2.api.tile.IWrenchable;
@@ -33,150 +36,238 @@ public class Behaviour_Wrench extends Behaviour_None {
@Override
public boolean onItemUseFirst(GT_MetaBase_Item aItem, ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX,
int aY, int aZ, ForgeDirection side, float hitX, float hitY, float hitZ) {
- if (aWorld.isRemote || aPlayer.isSneaking()) {
- return false;
- }
final Block aBlock = aWorld.getBlock(aX, aY, aZ);
if (aBlock == null) {
return false;
}
- final byte aMeta = (byte) aWorld.getBlockMetadata(aX, aY, aZ);
+ final int aMeta = aWorld.getBlockMetadata(aX, aY, aZ);
final short targetSideOrdinal = (short) GT_Utility.determineWrenchingSide(side, hitX, hitY, hitZ)
.ordinal();
final TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+
+ final WrenchHandler handler = new WrenchHandler(
+ aBlock,
+ aMeta,
+ targetSideOrdinal,
+ aTileEntity,
+ aPlayer,
+ aWorld,
+ aX,
+ aY,
+ aZ,
+ aStack,
+ (GT_MetaGenerated_Tool) aItem,
+ mCosts);
+
try {
- if (aTileEntity instanceof IWrenchable wrenchable) {
- if (wrenchable.wrenchCanSetFacing(aPlayer, targetSideOrdinal)) {
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts))) {
- wrenchable.setFacing(targetSideOrdinal);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
- }
- return true;
+ return handler.handle();
+ } catch (Throwable ignored) {}
+ return false;
+ }
+
+ /**
+ * <p>
+ * A class to simplify wrenching operation,
+ * stopping "checking creative", "trying to damage tool",
+ * "doing the logic" and "playing sound" again and again.
+ * This should have been a record, but it's not available in Java 8.
+ * </p>
+ * <p>
+ * {@link WrenchHandler#handle()} is the entry point of main logic.
+ * </p>
+ */
+ private static class WrenchHandler {
+
+ boolean handle() {
+ ForgeDirection direction = ForgeDirection.getOrientation(targetSideOrdinal);
+
+ // AE2 logic
+ // default to change the up facing
+ // sneak to change the forward facing
+ if (tileEntity instanceof IOrientable orientable) {
+ if (!orientable.canBeRotated()) return false;
+ ForgeDirection front = orientable.getForward();
+ ForgeDirection up = orientable.getUp();
+
+ // mainly for me-interfaces, whose initial orientation is UNKNOWN
+ if (front == ForgeDirection.UNKNOWN) {
+ if (direction == ForgeDirection.UP || direction == ForgeDirection.DOWN)
+ front = ForgeDirection.NORTH;
+ else front = ForgeDirection.UP;
}
- if (wrenchable.wrenchCanRemove(aPlayer)) {
- final int tDamage = wrenchable.getWrenchDropRate() < 1.0F ? 10 : 3;
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, (long) tDamage * this.mCosts))) {
- ItemStack tOutput = wrenchable.getWrenchDrop(aPlayer);
- for (final ItemStack tStack : aBlock.getDrops(aWorld, aX, aY, aZ, aMeta, 0)) {
- if (tOutput == null) {
- aWorld.spawnEntityInWorld(
- new EntityItem(aWorld, aX + 0.5D, aY + 0.5D, aZ + 0.5D, tStack));
- } else {
- aWorld.spawnEntityInWorld(
- new EntityItem(aWorld, aX + 0.5D, aY + 0.5D, aZ + 0.5D, tOutput));
- tOutput = null;
- }
- }
- aWorld.setBlockToAir(aX, aY, aZ);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
+
+ ForgeDirection back = front.getOpposite();
+ ForgeDirection down = up.getOpposite();
+
+ if (tileEntity instanceof TileInterface) {
+ if (player.isSneaking()) return false;
+ if (direction == down) {
+ return doWrenchOperation(costs, () -> {
+ orientable.setOrientation(ForgeDirection.UNKNOWN, ForgeDirection.UNKNOWN);
+ return true;
+ });
}
- return true;
+ // interface's up-side is opposite to the arrow on texture
+ // make it intuitive by rotating it to the opposite side.
+ direction = direction.getOpposite();
+ up = up.getOpposite();
+ } else if (direction == up || direction == front) {
+ // rotate around the direction axis
+ final var tempFront = front;
+ final var tempUp = up;
+ if (!player.isSneaking() && direction == up) return doWrenchOperation(costs, () -> {
+ orientable.setOrientation(tempFront.getRotation(tempUp), tempUp);
+ return true;
+ });
+ if (player.isSneaking() && direction == front) return doWrenchOperation(costs, () -> {
+ orientable.setOrientation(
+ tempFront,
+ tempUp.getRotation(tempFront)
+ .getRotation(tempFront));
+ return true;
+ });
+ }
+
+ if (player.isSneaking()) {
+ if (direction == up || direction == down) {
+ orientable.setOrientation(direction, down.getRotation(front.getRotation(direction)));
+ } else orientable.setOrientation(direction, up);
+ } else {
+ if (direction == front || direction == back) {
+ orientable.setOrientation(back.getRotation(up.getRotation(direction)), direction);
+ } else orientable.setOrientation(front, direction);
}
- return true;
+
+ return damageWrench(costs);
}
- } catch (Throwable ignored) {}
- if ((aBlock == Blocks.log) || (aBlock == Blocks.log2) || (aBlock == Blocks.hay_block)) {
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts))) {
- aWorld.setBlockMetadataWithNotify(aX, aY, aZ, (aMeta + 4) % 12, 3);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
+ if (world.isRemote) return false;
+ // IC2 Wrenchable
+ if (tileEntity instanceof IWrenchable wrenchable) {
+ if (wrenchable.wrenchCanSetFacing(player, targetSideOrdinal)) {
+ return doWrenchOperation(costs, () -> {
+ wrenchable.setFacing(targetSideOrdinal);
+ return true;
+ });
+ }
+ return false;
}
- return true;
- }
- if ((aBlock == Blocks.powered_repeater) || (aBlock == Blocks.unpowered_repeater)) {
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts))) {
- aWorld.setBlockMetadataWithNotify(aX, aY, aZ, aMeta / 4 * 4 + (aMeta % 4 + 1) % 4, 3);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
+
+ if (block == Blocks.powered_repeater || block == Blocks.unpowered_repeater
+ || block == Blocks.powered_comparator
+ || block == Blocks.unpowered_comparator) return setBlockMeta(costs, meta / 4 * 4 + (meta % 4 + 1) % 4);
+
+ // hopper cannot face sky
+ if (block == Blocks.hopper && targetSideOrdinal != 1) return setBlockMeta(costs, targetSideOrdinal);
+
+ if (isVanillaAllSideRotatable(block)) if (meta < 6) return setBlockMeta(costs, targetSideOrdinal);
+
+ // blocks like chests and furnaces have only four directions
+ if (isVanillaCantFaceAxisY(block)) {
+ if (targetSideOrdinal > 1) return setBlockMeta(costs, targetSideOrdinal);
+ else return false;
}
- return true;
- }
- if ((aBlock == Blocks.powered_comparator) || (aBlock == Blocks.unpowered_comparator)) {
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts))) {
- aWorld.setBlockMetadataWithNotify(aX, aY, aZ, aMeta / 4 * 4 + (aMeta % 4 + 1) % 4, 3);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
+ if (tileEntity instanceof IPartHost) return false;
+
+ final int logWoodId = OreDictionary.getOreID("logWood");
+ if (Arrays.stream(OreDictionary.getOreIDs(new ItemStack(block)))
+ .anyMatch(id -> id == logWoodId)) {
+ // The meta just work
+ return setBlockMeta(costs, (meta + 4) % 12);
}
- return true;
+
+ // vanilla block rotate logic
+ if ((Arrays.asList(block.getValidRotations(world, x, y, z))
+ .contains(direction))) return rotateBlock(costs, direction);
+ return false;
+
+ // GT blocks' rotations are done by blocks themselves after this returning false
}
- if ((aBlock == Blocks.crafting_table) || (aBlock == Blocks.bookshelf)) {
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts))) {
- aWorld.spawnEntityInWorld(
- new EntityItem(aWorld, aX + 0.5D, aY + 0.5D, aZ + 0.5D, new ItemStack(aBlock, 1, aMeta)));
- aWorld.setBlockToAir(aX, aY, aZ);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
- }
- return true;
+
+ private final Block block;
+ private final short targetSideOrdinal;
+ private final TileEntity tileEntity;
+ private final EntityPlayer player;
+ private final World world;
+ private final int x, y, z, meta;
+ private final ItemStack stack;
+
+ private final GT_MetaGenerated_Tool item;
+ private final int costs;
+
+ public WrenchHandler(Block block, int meta, short targetSideOrdinal, TileEntity tileEntity, EntityPlayer player,
+ World world, int x, int y, int z, ItemStack stack, GT_MetaGenerated_Tool item, int costs) {
+ this.block = block;
+ this.meta = meta;
+ this.targetSideOrdinal = targetSideOrdinal;
+ this.tileEntity = tileEntity;
+ this.player = player;
+ this.world = world;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.stack = stack;
+ this.item = item;
+ this.costs = costs;
}
- if (aMeta == targetSideOrdinal) {
- if ((aBlock == Blocks.pumpkin) || (aBlock == Blocks.lit_pumpkin)
- || (aBlock == Blocks.piston)
- || (aBlock == Blocks.sticky_piston)
- || (aBlock == Blocks.dispenser)
- || (aBlock == Blocks.dropper)
- || (aBlock == Blocks.furnace)
- || (aBlock == Blocks.lit_furnace)
- || (aBlock == Blocks.chest)
- || (aBlock == Blocks.trapped_chest)
- || (aBlock == Blocks.ender_chest)
- || (aBlock == Blocks.hopper)) {
- if ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts))) {
- aWorld.spawnEntityInWorld(
- new EntityItem(aWorld, aX + 0.5D, aY + 0.5D, aZ + 0.5D, new ItemStack(aBlock, 1, 0)));
- aWorld.setBlockToAir(aX, aY, aZ);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
- }
- return true;
- }
- } else {
- if ((aBlock == Blocks.piston) || (aBlock == Blocks.sticky_piston)
- || (aBlock == Blocks.dispenser)
- || (aBlock == Blocks.dropper)) {
- if ((aMeta < 6) && ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts)))) {
- aWorld.setBlockMetadataWithNotify(aX, aY, aZ, targetSideOrdinal, 3);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
- }
- return true;
- }
- if ((aBlock == Blocks.pumpkin) || (aBlock == Blocks.lit_pumpkin)
- || (aBlock == Blocks.furnace)
- || (aBlock == Blocks.lit_furnace)
- || (aBlock == Blocks.chest)
- || (aBlock == Blocks.ender_chest)
- || (aBlock == Blocks.trapped_chest)) {
- if ((targetSideOrdinal > 1) && ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts)))) {
- aWorld.setBlockMetadataWithNotify(aX, aY, aZ, targetSideOrdinal, 3);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
- }
- return true;
- }
- if (aBlock == Blocks.hopper) {
- if ((targetSideOrdinal != 1) && ((aPlayer.capabilities.isCreativeMode)
- || (((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts)))) {
- aWorld.setBlockMetadataWithNotify(aX, aY, aZ, targetSideOrdinal, 3);
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
+
+ /**
+ * this will run the operation, damage the tool and play the sound if possible (creative mode or
+ * {@link GT_MetaGenerated_Tool#canWrench(EntityPlayer, int, int, int)})
+ *
+ * @param damage damage to be applied to the wrench
+ * @param operation the real operation of the click
+ * @return true if the operation was successful
+ * @see #setBlockMeta(int, int)
+ * @see #rotateBlock(int, ForgeDirection)
+ * @see #rotateBlock(int, ForgeDirection)
+ */
+ boolean doWrenchOperation(int damage, BooleanSupplier operation) {
+ if (player.capabilities.isCreativeMode || item.canWrench(player, x, y, z)) {
+ if (operation.getAsBoolean()) {
+ item.doDamage(stack, damage);
+ GT_Utility.sendSoundToPlayers(world, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, x, y, z);
+ return true;
}
- return true;
}
+ return false;
}
- if ((Arrays.asList(aBlock.getValidRotations(aWorld, aX, aY, aZ))
- .contains(ForgeDirection.getOrientation(targetSideOrdinal)))
- && ((aPlayer.capabilities.isCreativeMode) || (!GT_ModHandler.isElectricItem(aStack))
- || (GT_ModHandler.canUseElectricItem(aStack, this.mCosts)))
- && (aBlock.rotateBlock(aWorld, aX, aY, aZ, ForgeDirection.getOrientation(targetSideOrdinal)))) {
- if (!aPlayer.capabilities.isCreativeMode) {
- ((GT_MetaGenerated_Tool) aItem).doDamage(aStack, this.mCosts);
- }
- GT_Utility.sendSoundToPlayers(aWorld, SoundResource.IC2_TOOLS_WRENCH, 1.0F, -1.0F, aX, aY, aZ);
- return true;
+
+ boolean setBlockMeta(int damage, int newMeta) {
+ return doWrenchOperation(damage, () -> setBlockMetadataWithNotify(newMeta));
}
- return false;
+
+ boolean rotateBlock(int damage, ForgeDirection direction) {
+ return doWrenchOperation(damage, () -> block.rotateBlock(world, x, y, z, direction));
+ }
+
+ boolean damageWrench(int damage) {
+ return doWrenchOperation(damage, () -> true);
+ }
+
+ private boolean setBlockMetadataWithNotify(int newMeta) {
+ return world.setBlockMetadataWithNotify(x, y, z, newMeta, 3);
+ }
+
+ }
+
+ public static boolean isVanillaRotatable(Block block) {
+ return isVanillaCantFaceAxisY(block) || isVanillaAllSideRotatable(block) || block == Blocks.hopper;
+ }
+
+ public static boolean isVanillaCantFaceAxisY(Block block) {
+ return GT_Utility.arrayContains(
+ block,
+ Blocks.pumpkin,
+ Blocks.lit_pumpkin,
+ Blocks.furnace,
+ Blocks.lit_furnace,
+ Blocks.chest,
+ Blocks.trapped_chest,
+ Blocks.ender_chest);
+ }
+
+ public static boolean isVanillaAllSideRotatable(Block block) {
+ return GT_Utility.arrayContains(block, Blocks.piston, Blocks.sticky_piston, Blocks.dispenser, Blocks.dropper);
}
@Override
diff --git a/src/main/java/gregtech/common/tools/GT_Tool_Crowbar.java b/src/main/java/gregtech/common/tools/GT_Tool_Crowbar.java
index f9f82fd373..742d4b3fa0 100644
--- a/src/main/java/gregtech/common/tools/GT_Tool_Crowbar.java
+++ b/src/main/java/gregtech/common/tools/GT_Tool_Crowbar.java
@@ -1,7 +1,5 @@
package gregtech.common.tools;
-import java.util.Iterator;
-
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.EntityLivingBase;
@@ -10,10 +8,11 @@ import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
+import com.google.common.base.Strings;
+
import gregtech.api.enums.SoundResource;
import gregtech.api.enums.Textures;
import gregtech.api.interfaces.IIconContainer;
-import gregtech.api.interfaces.IToolStats;
import gregtech.api.items.GT_MetaGenerated_Tool;
import gregtech.common.items.GT_MetaGenerated_Tool_01;
import gregtech.common.items.behaviors.Behaviour_Crowbar;
@@ -96,10 +95,9 @@ public class GT_Tool_Crowbar extends GT_Tool {
return true;
}
String tTool = aBlock.getHarvestTool(aMetaData);
- if ((tTool == null) || (tTool.equals(""))) {
- for (Iterator<IToolStats> i$ = GT_MetaGenerated_Tool_01.INSTANCE.mToolStats.values()
- .iterator(); i$.hasNext(); i$.next()) {
- if (((i$ instanceof GT_Tool_Crowbar)) && (!((IToolStats) i$).isMinableBlock(aBlock, aMetaData))) {
+ if (Strings.isNullOrEmpty(tTool)) {
+ for (var i : GT_MetaGenerated_Tool_01.INSTANCE.mToolStats.values()) {
+ if (i instanceof GT_Tool_Crowbar && !i.isMinableBlock(aBlock, aMetaData)) {
return false;
}
}
diff --git a/src/main/java/gregtech/common/tools/GT_Tool_Wrench.java b/src/main/java/gregtech/common/tools/GT_Tool_Wrench.java
index 5a5a69ad80..91ecd71536 100644
--- a/src/main/java/gregtech/common/tools/GT_Tool_Wrench.java
+++ b/src/main/java/gregtech/common/tools/GT_Tool_Wrench.java
@@ -11,7 +11,6 @@ import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
-import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.monster.EntityIronGolem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
@@ -23,13 +22,14 @@ import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
import net.minecraftforge.event.world.BlockEvent;
+import appeng.api.parts.IPartHost;
+import appeng.block.AEBaseTileBlock;
+import appeng.parts.PartPlacement;
import gregtech.api.enums.SoundResource;
import gregtech.api.enums.Textures;
import gregtech.api.interfaces.IIconContainer;
-import gregtech.api.interfaces.IToolStats;
import gregtech.api.items.GT_MetaGenerated_Tool;
import gregtech.api.util.GT_ToolHarvestHelper;
-import gregtech.common.items.behaviors.Behaviour_Switch_Mode;
import gregtech.common.items.behaviors.Behaviour_Wrench;
import ic2.api.tile.IWrenchable;
@@ -123,10 +123,13 @@ public class GT_Tool_Wrench extends GT_Tool {
}
@Override
- public boolean isMinableBlock(Block aBlock, byte aMetaData) {
- return GT_ToolHarvestHelper.isAppropriateTool(aBlock, aMetaData, "wrench")
- || GT_ToolHarvestHelper.isAppropriateMaterial(aBlock, Material.piston)
- || GT_ToolHarvestHelper.isSpecialBlock(aBlock, Blocks.hopper, Blocks.dispenser, Blocks.dropper);
+ public boolean isMinableBlock(Block block, byte aMetaData) {
+ return GT_ToolHarvestHelper.isAppropriateTool(block, aMetaData, "wrench")
+ || GT_ToolHarvestHelper.isAppropriateMaterial(block, Material.piston)
+ || block instanceof AEBaseTileBlock
+ || GT_ToolHarvestHelper.isSpecialBlock(block, Blocks.crafting_table, Blocks.bookshelf)
+ || Behaviour_Wrench.isVanillaRotatable(block)
+ || GT_ToolHarvestHelper.isIC2Wrenchable(block);
}
@Override
@@ -146,7 +149,6 @@ public class GT_Tool_Wrench extends GT_Tool {
@Override
public void onStatsAddedToTool(GT_MetaGenerated_Tool aItem, int aID) {
- aItem.addItemBehavior(aID, new Behaviour_Switch_Mode());
aItem.addItemBehavior(aID, new Behaviour_Wrench(100));
}
@@ -161,43 +163,97 @@ public class GT_Tool_Wrench extends GT_Tool {
+ EnumChatFormatting.WHITE);
}
- @Override
- public float getMiningSpeed(Block block, byte metadata, float mineSpeed, EntityPlayer player, World world, int x,
- int y, int z) {
- ItemStack holding = player.getCurrentEquippedItem();
- if (holding == null || !(holding.getItem() instanceof GT_MetaGenerated_Tool tool)) return mineSpeed;
-
- IToolStats stats = tool.getToolStats(holding);
- if (stats == null) return mineSpeed;
-
- TileEntity tile = world.getTileEntity(x, y, z);
- if (tile == null) return mineSpeed;
-
- float newSpeed = Math.max(Float.MIN_NORMAL, getSpeedMultiplier() * getPrimaryMaterial(holding).mToolSpeed);
-
- if (tile instanceof IWrenchable) return newSpeed;
-
- return mineSpeed;
- }
+ /**
+ * <p>
+ * holding drop from {@link IWrenchable#getWrenchDrop(EntityPlayer)}
+ * </p>
+ * Since no tile available during
+ * {@link #convertBlockDrops(List, ItemStack, EntityPlayer, Block, int, int, int, byte, int, boolean, BlockEvent.HarvestDropsEvent)},
+ * this is filled during
+ * {@link #onBreakBlock(EntityPlayer, int, int, int, Block, byte, TileEntity, BlockEvent.BreakEvent)}
+ */
+ private ItemStack wrenchableDrop = null;
+ /**
+ * <p>
+ * drop rate from {@link IWrenchable#getWrenchDropRate()}
+ * </p>
+ * see {@link #wrenchableDrop}
+ */
+ private float wrenchableDropRate = 0.0f;
+
+ /**
+ * <p>
+ * prevent recursion from
+ * {@link AEBaseTileBlock#onBlockActivated(World, int, int, int, EntityPlayer, int, float, float, float)}
+ * </p>
+ */
+ private boolean LastEventFromThis = false;
@Override
public void onBreakBlock(@Nonnull EntityPlayer player, int x, int y, int z, @Nonnull Block block, byte metadata,
TileEntity tile, @Nonnull BlockEvent.BreakEvent event) {
- final World world = player.worldObj;
if (tile instanceof IWrenchable wrenchable) {
- ItemStack drop = wrenchable.getWrenchDrop(player);
- world.setBlockToAir(x, y, z);
- world.spawnEntityInWorld(new EntityItem(world, x, y, z, drop));
+ if (!wrenchable.wrenchCanRemove(player)) {
+ event.setCanceled(true);
+ return;
+ }
+ wrenchableDrop = wrenchable.getWrenchDrop(player);
+ wrenchableDropRate = wrenchable.getWrenchDropRate();
+ }
+ if (block instanceof AEBaseTileBlock aeBaseTileBlock) {
+ if (LastEventFromThis) {
+ return;
+ }
+ final boolean sneak = player.isSneaking();
+ try {
+ LastEventFromThis = true;
+ player.setSneaking(true);
+ final int sideHit = player.rayTrace(5, 1.0f).sideHit;
+ if (tile instanceof IPartHost) {
+ if (sneak && PartPlacement.place(
+ player.getHeldItem(),
+ x,
+ y,
+ z,
+ sideHit,
+ player,
+ player.worldObj,
+ PartPlacement.PlaceType.INTERACT_FIRST_PASS,
+ 0)) {
+ event.setCanceled(true);
+ }
+ return;
+ }
+ if (aeBaseTileBlock.onBlockActivated(event.world, x, y, z, player, sideHit, x, y, z)) {
+ event.setCanceled(true);
+ }
+ } finally {
+ LastEventFromThis = false;
+ player.setSneaking(sneak);
+ }
}
}
@Override
- public String getToolTypeName() {
- return "wrench";
- }
+ public int convertBlockDrops(List<ItemStack> drops, ItemStack Stack, EntityPlayer player, Block block, int x, int y,
+ int z, byte metaData, int fortune, boolean silkTouch, BlockEvent.HarvestDropsEvent event) {
+ ItemStack drop = null;
+ int modified = 0;
+ if (wrenchableDrop != null) {
+ drop = wrenchableDrop;
+ wrenchableDrop = null;
+ modified = wrenchableDropRate == 1.0f ? 3 : 10;
+ wrenchableDropRate = 0.0f;
+ } else if (block == Blocks.bookshelf || block == Blocks.ender_chest) {
+ drop = new ItemStack(block);
+ modified = 1;
+ }
- @Override
- public byte getMaxMode() {
- return 2;
+ if (drop != null) {
+ event.dropChance = 1.0f;
+ drops.clear();
+ drops.add(drop);
+ }
+ return modified;
}
}