mirror of
https://code.chipmunk.land/ChomeNS/chipmunkmod.git
synced 2025-11-13 21:06:16 +00:00
refactor: improvements to place block core (so-called "deploy core")
- after 5 tries of failed deploy core attempts, it falls back to using chat instead. this happens a lot when you `/tp` to somewhere underground where the player's surroundings are covered with blocks and command blocks don't get executed for some reason - i'm using the obd sex mod way of determining block positions now - the deploy core block now gets set to the previous block only when the core is CONFIRMED to be filled, and not just a fixed 100ms waiting time after placed i hope this is enough to fix troubles, if there are more issues i'll try to fix them
This commit is contained in:
parent
03eb3c84f6
commit
aae472cb27
1 changed files with 110 additions and 58 deletions
|
|
@ -1,11 +1,13 @@
|
||||||
package land.chipmunk.chipmunkmod.modules;
|
package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
import land.chipmunk.chipmunkmod.listeners.Listener;
|
import land.chipmunk.chipmunkmod.listeners.Listener;
|
||||||
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.CommandBlock;
|
import net.minecraft.block.CommandBlock;
|
||||||
|
import net.minecraft.block.FallingBlock;
|
||||||
import net.minecraft.block.entity.CommandBlockBlockEntity;
|
import net.minecraft.block.entity.CommandBlockBlockEntity;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
|
|
@ -23,17 +25,18 @@ import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket;
|
||||||
import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket;
|
import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket;
|
||||||
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket;
|
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.tag.BlockTags;
|
||||||
import net.minecraft.state.property.Property;
|
import net.minecraft.state.property.Property;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockBox;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
@ -51,8 +54,10 @@ public class CommandCore implements Listener {
|
||||||
public boolean runFillCommand = true;
|
public boolean runFillCommand = true;
|
||||||
public boolean alreadyFilled = false;
|
public boolean alreadyFilled = false;
|
||||||
|
|
||||||
|
private final Map<BlockPos, String> pendingSetBlockCommands = Collections.synchronizedMap(new Object2ObjectArrayMap<>());
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private boolean shouldRefill = false;
|
private boolean shouldRefill = false;
|
||||||
|
private int refillTriesUsingPlaceBlock = 0;
|
||||||
private DimensionType oldDimension;
|
private DimensionType oldDimension;
|
||||||
|
|
||||||
public CommandCore (final MinecraftClient client) {
|
public CommandCore (final MinecraftClient client) {
|
||||||
|
|
@ -103,7 +108,30 @@ public class CommandCore implements Listener {
|
||||||
|
|
||||||
check();
|
check();
|
||||||
|
|
||||||
if (!shouldRefill) return;
|
if (!shouldRefill) {
|
||||||
|
refillTriesUsingPlaceBlock = 0;
|
||||||
|
synchronized (pendingSetBlockCommands) {
|
||||||
|
if (pendingSetBlockCommands.isEmpty()) return;
|
||||||
|
for (final Map.Entry<BlockPos, String> entry : pendingSetBlockCommands.entrySet()) {
|
||||||
|
final BlockPos blockPos = entry.getKey();
|
||||||
|
final String block = entry.getValue();
|
||||||
|
|
||||||
|
run(
|
||||||
|
String.format(
|
||||||
|
"setblock %d %d %d %s",
|
||||||
|
|
||||||
|
blockPos.getX(),
|
||||||
|
blockPos.getY(),
|
||||||
|
blockPos.getZ(),
|
||||||
|
|
||||||
|
block
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pendingSetBlockCommands.clear();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
refill();
|
refill();
|
||||||
|
|
||||||
|
|
@ -189,8 +217,17 @@ public class CommandCore implements Listener {
|
||||||
|
|
||||||
public void refill () {
|
public void refill () {
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
|
final ClientPlayerEntity player = client.player;
|
||||||
|
|
||||||
if (!runFillCommand || client.world == null || networkHandler == null || withPos == null) return;
|
if (
|
||||||
|
!runFillCommand
|
||||||
|
|| player == null
|
||||||
|
|| !player.isInCreativeMode()
|
||||||
|
|| !player.hasPermissionLevel(2)
|
||||||
|
|| client.world == null
|
||||||
|
|| networkHandler == null
|
||||||
|
|| withPos == null
|
||||||
|
) return;
|
||||||
|
|
||||||
final Chunk chunk = client.world.getChunk(withPos.getCenter());
|
final Chunk chunk = client.world.getChunk(withPos.getCenter());
|
||||||
|
|
||||||
|
|
@ -208,7 +245,13 @@ public class CommandCore implements Listener {
|
||||||
withPos.getMaxZ()
|
withPos.getMaxZ()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (refillTriesUsingPlaceBlock > 5) {
|
||||||
|
networkHandler.sendChatCommand(command);
|
||||||
|
refillTriesUsingPlaceBlock = 0;
|
||||||
|
} else {
|
||||||
runPlaceBlock(command);
|
runPlaceBlock(command);
|
||||||
|
refillTriesUsingPlaceBlock++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementCurrentBlock () {
|
public void incrementCurrentBlock () {
|
||||||
|
|
@ -360,29 +403,24 @@ public class CommandCore implements Listener {
|
||||||
|
|
||||||
final DimensionType dimensionType = world.getDimension();
|
final DimensionType dimensionType = world.getDimension();
|
||||||
|
|
||||||
|
final ClientPlayerInteractionManager interactionManager = client.interactionManager;
|
||||||
|
if (interactionManager == null) return;
|
||||||
|
|
||||||
|
// stolen from two five hundred million dollars
|
||||||
|
|
||||||
|
final Pair<BlockPos, BlockState> pair = findBlockLocation();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
player.getPos().getY() < dimensionType.minY()
|
pair == null
|
||||||
|| player.getPos().getY() > dimensionType.height() + dimensionType.minY()
|
|| pair.getLeft().getY() < dimensionType.minY()
|
||||||
|
|| pair.getLeft().getY() > dimensionType.height() + dimensionType.minY()
|
||||||
) {
|
) {
|
||||||
networkHandler.sendChatCommand(command);
|
networkHandler.sendChatCommand(command);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ClientPlayerInteractionManager interactionManager = client.interactionManager;
|
final BlockPos position = pair.getLeft();
|
||||||
if (interactionManager == null) return;
|
final BlockState oldBlockState = pair.getRight();
|
||||||
|
|
||||||
final float yaw = player.getYaw();
|
|
||||||
final float pitch = player.getPitch();
|
|
||||||
|
|
||||||
// Anti Block when flying around
|
|
||||||
final BlockPos position = player.getBlockPos().add(
|
|
||||||
(int) Math.round(3 * Math.cos(Math.toRadians(yaw))),
|
|
||||||
3 * (pitch < 0 ? -1 : 1),
|
|
||||||
(int) Math.round(3 * Math.sin(Math.toRadians(yaw)))
|
|
||||||
);
|
|
||||||
|
|
||||||
// stolen from two five hundred million dollars
|
|
||||||
final BlockState oldBlockState = world.getBlockState(position);
|
|
||||||
|
|
||||||
final int freeHotBarSlot = player.getInventory().getEmptySlot();
|
final int freeHotBarSlot = player.getInventory().getEmptySlot();
|
||||||
final int slot = 36 + freeHotBarSlot;
|
final int slot = 36 + freeHotBarSlot;
|
||||||
|
|
@ -430,43 +468,57 @@ public class CommandCore implements Listener {
|
||||||
}
|
}
|
||||||
connection.send(new CreativeInventoryActionC2SPacket(slot, oldStack));
|
connection.send(new CreativeInventoryActionC2SPacket(slot, oldStack));
|
||||||
|
|
||||||
final Timer timer = new Timer();
|
final StringBuilder oldBlockString = new StringBuilder(Registries.BLOCK.getId(oldBlockState.getBlock()).toString());
|
||||||
|
|
||||||
final TimerTask task = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run () {
|
|
||||||
final StringBuilder command = new StringBuilder(
|
|
||||||
String.format(
|
|
||||||
"setblock %d %d %d %s",
|
|
||||||
|
|
||||||
position.getX(),
|
|
||||||
position.getY(),
|
|
||||||
position.getZ(),
|
|
||||||
|
|
||||||
Registries.BLOCK.getId(oldBlockState.getBlock())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!oldBlockState.getProperties().isEmpty()) {
|
if (!oldBlockState.getProperties().isEmpty()) {
|
||||||
command.append('[');
|
oldBlockString.append('[');
|
||||||
|
|
||||||
for (final Property<?> property : oldBlockState.getProperties()) {
|
for (final Property<?> property : oldBlockState.getProperties()) {
|
||||||
command.append(property.getName())
|
oldBlockString.append(property.getName())
|
||||||
.append('=')
|
.append('=')
|
||||||
.append(Util.getValueAsString(property, property.getValues().getLast())) // water[level=15] instead of water[level=0,level=1,....,level=15]
|
.append(Util.getValueAsString(property, property.getValues().getLast())) // water[level=15] instead of water[level=0,level=1,....,level=15]
|
||||||
.append(',');
|
.append(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
command.deleteCharAt(command.length() - 1);
|
oldBlockString.deleteCharAt(oldBlockString.length() - 1);
|
||||||
|
|
||||||
command.append(']');
|
oldBlockString.append(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandCore.this.run(command.toString());
|
pendingSetBlockCommands.put(position, oldBlockString.toString());
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
timer.schedule(task, 100); // assuming the core has already been filled at this point
|
// also from two five hundred million dollars
|
||||||
|
private Pair<BlockPos, BlockState> findBlockLocation () {
|
||||||
|
final ClientPlayerEntity player = client.player;
|
||||||
|
if (player == null) return null;
|
||||||
|
final BlockPos position = player.getBlockPos();
|
||||||
|
final Box boundingBox = player.getBoundingBox();
|
||||||
|
boundingBox.expand(1.0);
|
||||||
|
for (int x = position.getX() - 2; x <= position.getX() + 2; x++) {
|
||||||
|
for (int y = position.getY() - 2; y <= position.getY() + 2; y++) {
|
||||||
|
for (int z = position.getZ() - 2; z <= position.getZ() + 2; z++) {
|
||||||
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
|
if (!player.canInteractWithBlockAt(blockPos, 1.0)) continue;
|
||||||
|
// we don't want to place a block inside ourselves
|
||||||
|
if (boundingBox.intersects(new Vec3d(blockPos), new Vec3d(blockPos))) continue;
|
||||||
|
final BlockState blockState = player.getWorld().getBlockState(blockPos);
|
||||||
|
if (blockState.getBlock() instanceof FallingBlock) continue;
|
||||||
|
final boolean replaceable = blockState.isIn(BlockTags.REPLACEABLE);
|
||||||
|
if (
|
||||||
|
!replaceable
|
||||||
|
&& !blockState.isIn(BlockTags.AXE_MINEABLE)
|
||||||
|
&& !blockState.isIn(BlockTags.HOE_MINEABLE)
|
||||||
|
&& !blockState.isIn(BlockTags.SHOVEL_MINEABLE)
|
||||||
|
&& !blockState.isIn(BlockTags.PICKAXE_MINEABLE)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return new Pair<>(blockPos, blockState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup () {
|
public void cleanup () {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue