Skip to content

Commit 1f265df

Browse files
committed
refactor for cleanliness and add support for adding custom predicates to block breaking certain blocks
1 parent 0e526cd commit 1f265df

File tree

2 files changed

+99
-58
lines changed

2 files changed

+99
-58
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package gregtech.api.util.function;
2+
3+
@FunctionalInterface
4+
public interface TriPredicate<A, B, C> {
5+
6+
boolean test(A a, B b, C c);
7+
}

src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java

Lines changed: 92 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
import gregtech.api.util.GTTransferUtils;
1111
import gregtech.api.util.GregFakePlayer;
1212
import gregtech.api.util.Mods;
13+
import gregtech.api.util.function.TriPredicate;
1314
import gregtech.client.renderer.texture.Textures;
1415
import gregtech.client.utils.RenderUtil;
1516

1617
import net.minecraft.block.Block;
1718
import net.minecraft.block.BlockLiquid;
18-
import net.minecraft.block.material.Material;
1919
import net.minecraft.block.state.IBlockState;
2020
import net.minecraft.client.resources.I18n;
2121
import net.minecraft.entity.item.EntityItem;
@@ -31,6 +31,7 @@
3131
import net.minecraft.util.math.MathHelper;
3232
import net.minecraft.world.World;
3333
import net.minecraft.world.WorldServer;
34+
import net.minecraftforge.common.util.FakePlayer;
3435
import net.minecraftforge.items.IItemHandlerModifiable;
3536

3637
import codechicken.lib.raytracer.CuboidRayTraceResult;
@@ -46,9 +47,12 @@
4647
import com.cleanroommc.modularui.widgets.ItemSlot;
4748
import com.cleanroommc.modularui.widgets.SlotGroupWidget;
4849
import com.cleanroommc.modularui.widgets.layout.Grid;
50+
import com.feed_the_beast.ftblib.lib.EnumTeamStatus;
51+
import com.feed_the_beast.ftblib.lib.data.ForgePlayer;
4952
import com.feed_the_beast.ftblib.lib.math.ChunkDimPos;
5053
import com.feed_the_beast.ftbutilities.data.ClaimedChunk;
5154
import com.feed_the_beast.ftbutilities.data.ClaimedChunks;
55+
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
5256
import org.jetbrains.annotations.NotNull;
5357
import org.jetbrains.annotations.Nullable;
5458

@@ -63,6 +67,42 @@ public class MetaTileEntityBlockBreaker extends TieredMetaTileEntity {
6367
private EnumFacing outputFacing;
6468
private int breakProgressTicksLeft;
6569
private float currentBlockHardness;
70+
private static final List<@NotNull TriPredicate<@NotNull World, @NotNull BlockPos, @NotNull FakePlayer>> PREDICATE_LIST = new ObjectArrayList<>(
71+
2);
72+
73+
static {
74+
PREDICATE_LIST.add((world, blockPos, fakePlayer) -> !world.isAirBlock(blockPos));
75+
PREDICATE_LIST.add(
76+
(world, blockPos, fakePlayer) -> !(world.getBlockState(blockPos).getBlock() instanceof BlockLiquid));
77+
PREDICATE_LIST.add((world, blockPos, fakePlayer) -> world.isBlockModifiable(fakePlayer, blockPos));
78+
if (Mods.FTB_UTILITIES.isModLoaded()) {
79+
PREDICATE_LIST.add((world, blockPos, fakePlayer) -> {
80+
ClaimedChunks instance = ClaimedChunks.instance;
81+
ClaimedChunk claimedChunk = instance.getChunk(new ChunkDimPos(blockPos, world.provider.getDimension()));
82+
if (claimedChunk != null) {
83+
ForgePlayer forgePlayer = instance.universe.getPlayer(fakePlayer.getUniqueID());
84+
EnumTeamStatus status = claimedChunk.getData().getEditBlocksStatus();
85+
return !claimedChunk.getTeam().hasStatus(forgePlayer, status);
86+
} else {
87+
return true;
88+
}
89+
});
90+
}
91+
}
92+
93+
/**
94+
* Add a predicate check to the block breaker. Intended to be used to prevent a certain block from being broken.
95+
* <br/>
96+
* <b>Warning!</b> the {@link FakePlayer} passed to the predicate is not a real player, but a fake one with
97+
* the same UUID as the real player who placed the block breaker <br/>
98+
* Return {@code false} to cancel a break attempt on this block. <br/>
99+
* Return {@code true} to move onto the next predicate, and eventually break the block only if all other predicates
100+
* returned {@code false}.
101+
*/
102+
@SuppressWarnings("unused")
103+
public static void registerBlockBreakerPredicate(@NotNull TriPredicate<@NotNull World, @NotNull BlockPos, @NotNull FakePlayer> predicate) {
104+
PREDICATE_LIST.add(predicate);
105+
}
66106

67107
public MetaTileEntityBlockBreaker(ResourceLocation metaTileEntityId, int tier) {
68108
super(metaTileEntityId, tier);
@@ -89,84 +129,78 @@ public void update() {
89129

90130
World world = getWorld();
91131
if (!world.isRemote) {
92-
EntityPlayer fakePlayer = GregFakePlayer.get((WorldServer) world, getOwner());
93-
BlockPos selfPos = getPos();
94-
BlockPos lookingAtPos = selfPos.offset(getFrontFacing());
132+
tryBreakBlock(world);
95133

96-
boolean canEditBlock = world.isBlockModifiable(fakePlayer, lookingAtPos);
97-
if (Mods.FTB_UTILITIES.isModLoaded()) {
98-
ClaimedChunks instance = ClaimedChunks.instance;
99-
ClaimedChunk claimedChunk = instance
100-
.getChunk(new ChunkDimPos(lookingAtPos, world.provider.getDimension()));
101-
if (claimedChunk != null) {
102-
canEditBlock &= claimedChunk.getTeam()
103-
.hasStatus(instance.universe.getPlayer(getOwner()),
104-
claimedChunk.getData().getEditBlocksStatus());
105-
}
134+
if (getOffsetTimer() % 5 == 0) {
135+
pushItemsIntoNearbyHandlers(getOutputFacing());
106136
}
137+
}
138+
}
107139

108-
if (breakProgressTicksLeft > 0) {
109-
--breakProgressTicksLeft;
110-
if (breakProgressTicksLeft == 0 && energyContainer.getEnergyStored() >= getEnergyPerBlockBreak()) {
111-
IBlockState blockState = getWorld().getBlockState(lookingAtPos);
112-
float hardness = blockState.getBlockHardness(getWorld(), lookingAtPos);
113-
114-
if (hardness >= 0.0f && canEditBlock && Math.abs(hardness - currentBlockHardness) < 0.5f) {
115-
List<ItemStack> drops = attemptBreakBlockAndObtainDrops(lookingAtPos, blockState, fakePlayer);
116-
addToInventoryOrDropItems(drops);
117-
}
140+
protected void tryBreakBlock(@NotNull World world) {
141+
BlockPos selfPos = getPos();
142+
BlockPos lookingAtPos = selfPos.offset(getFrontFacing());
143+
FakePlayer fakePlayer = GregFakePlayer.get((WorldServer) world, getOwner());
118144

119-
currentBlockHardness = 0.0f;
120-
energyContainer.removeEnergy(getEnergyPerBlockBreak());
121-
}
145+
for (TriPredicate<World, BlockPos, FakePlayer> predicate : PREDICATE_LIST) {
146+
if (!predicate.test(world, lookingAtPos, fakePlayer)) {
147+
return;
122148
}
149+
}
123150

124-
if (breakProgressTicksLeft == 0 && isBlockRedstonePowered() && canEditBlock) {
125-
IBlockState blockState = getWorld().getBlockState(lookingAtPos);
126-
float hardness = blockState.getBlockHardness(getWorld(), lookingAtPos);
127-
boolean skipBlock = blockState.getMaterial() == Material.AIR ||
128-
blockState.getBlock().isAir(blockState, getWorld(), getPos()) ||
129-
blockState.getBlock() instanceof BlockLiquid;
130-
if (!skipBlock && hardness >= 0.0f) {
131-
breakProgressTicksLeft = getTicksPerBlockBreak(hardness);
132-
currentBlockHardness = hardness;
133-
}
151+
IBlockState blockState = world.getBlockState(lookingAtPos);
152+
if (breakProgressTicksLeft > 0 && --breakProgressTicksLeft == 0 &&
153+
energyContainer.getEnergyStored() >= getEnergyPerBlockBreak()) {
154+
float hardness = blockState.getBlockHardness(world, lookingAtPos);
155+
if (hardness >= 0.0f && Math.abs(hardness - currentBlockHardness) < 0.5f) {
156+
List<ItemStack> drops = attemptBreakBlockAndObtainDrops(world, lookingAtPos, blockState, fakePlayer);
157+
addToInventoryOrDropItems(drops, world, getFrontFacing());
134158
}
135159

136-
if (getOffsetTimer() % 5 == 0) {
137-
pushItemsIntoNearbyHandlers(getOutputFacing());
160+
currentBlockHardness = 0.0f;
161+
energyContainer.removeEnergy(getEnergyPerBlockBreak());
162+
}
163+
164+
if (breakProgressTicksLeft == 0 && isBlockRedstonePowered()) {
165+
float hardness = blockState.getBlockHardness(world, lookingAtPos);
166+
if (hardness >= 0.0f) {
167+
breakProgressTicksLeft = getTicksPerBlockBreak(hardness);
168+
currentBlockHardness = hardness;
138169
}
139170
}
140171
}
141172

142-
private void addToInventoryOrDropItems(List<ItemStack> drops) {
143-
EnumFacing outputFacing = getOutputFacing();
144-
double itemSpawnX = getPos().getX() + 0.5 + outputFacing.getXOffset();
145-
double itemSpawnY = getPos().getY() + 0.5 + outputFacing.getYOffset();
146-
double itemSpawnZ = getPos().getZ() + 0.5 + outputFacing.getZOffset();
173+
protected void addToInventoryOrDropItems(@NotNull List<ItemStack> drops, @NotNull World world,
174+
@NotNull EnumFacing frontFacing) {
175+
double itemSpawnX = getPos().getX() + 0.5 + frontFacing.getXOffset();
176+
double itemSpawnY = getPos().getY() + 0.5 + frontFacing.getYOffset();
177+
double itemSpawnZ = getPos().getZ() + 0.5 + frontFacing.getZOffset();
147178
for (ItemStack itemStack : drops) {
148179
ItemStack remainStack = GTTransferUtils.insertItem(exportItems, itemStack, false);
149180
if (!remainStack.isEmpty()) {
150-
EntityItem entityitem = new EntityItem(getWorld(), itemSpawnX, itemSpawnY, itemSpawnZ, remainStack);
181+
EntityItem entityitem = new EntityItem(world, itemSpawnX, itemSpawnY, itemSpawnZ, remainStack);
151182
entityitem.setDefaultPickupDelay();
152-
getWorld().spawnEntity(entityitem);
183+
world.spawnEntity(entityitem);
153184
}
154185
}
155186
}
156187

157-
private List<ItemStack> attemptBreakBlockAndObtainDrops(BlockPos blockPos, IBlockState blockState,
158-
EntityPlayer entityPlayer) {
159-
TileEntity tileEntity = getWorld().getTileEntity(blockPos);
160-
boolean result = blockState.getBlock().removedByPlayer(blockState, getWorld(), blockPos, entityPlayer, true);
188+
protected @NotNull List<ItemStack> attemptBreakBlockAndObtainDrops(@NotNull World world,
189+
@NotNull BlockPos lookingAtPos,
190+
@NotNull IBlockState blockState,
191+
@NotNull EntityPlayer entityPlayer) {
192+
TileEntity tileEntity = world.getTileEntity(lookingAtPos);
193+
Block block = blockState.getBlock();
194+
boolean result = block.removedByPlayer(blockState, world, lookingAtPos, entityPlayer, true);
161195
if (result) {
162-
getWorld().playEvent(null, 2001, blockPos, Block.getStateId(blockState));
163-
blockState.getBlock().onPlayerDestroy(getWorld(), blockPos, blockState);
196+
world.playEvent(null, 2001, lookingAtPos, Block.getStateId(blockState));
197+
block.onPlayerDestroy(world, lookingAtPos, blockState);
164198

165199
BlockUtility.startCaptureDrops();
166-
blockState.getBlock().harvestBlock(getWorld(), entityPlayer, blockPos, blockState, tileEntity,
167-
ItemStack.EMPTY);
200+
block.harvestBlock(world, entityPlayer, lookingAtPos, blockState, tileEntity, ItemStack.EMPTY);
168201
return BlockUtility.stopCaptureDrops();
169202
}
203+
170204
return Collections.emptyList();
171205
}
172206

@@ -249,23 +283,23 @@ public void setFrontFacing(EnumFacing frontFacing) {
249283
}
250284
}
251285

252-
private int getEnergyPerBlockBreak() {
286+
public int getEnergyPerBlockBreak() {
253287
return (int) GTValues.V[getTier()];
254288
}
255289

256-
private int getInventorySize() {
290+
protected int getInventorySize() {
257291
int sizeRoot = (1 + getTier());
258292
return sizeRoot * sizeRoot;
259293
}
260294

261-
private int getTicksPerBlockBreak(float blockHardness) {
295+
public int getTicksPerBlockBreak(float blockHardness) {
262296
int ticksPerOneDurability = 5;
263297
int totalTicksPerBlock = (int) Math.ceil(ticksPerOneDurability * blockHardness);
264298
float efficiencyMultiplier = 1.0f - getEfficiencyMultiplier();
265299
return (int) Math.ceil(totalTicksPerBlock * efficiencyMultiplier);
266300
}
267301

268-
private float getEfficiencyMultiplier() {
302+
public float getEfficiencyMultiplier() {
269303
return 1.0f - MathHelper.clamp(1.0f - 0.2f * (getTier() - 1.0f), 0.1f, 1.0f);
270304
}
271305

0 commit comments

Comments
 (0)