diff --git a/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/FeetTrapFeature.java b/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/FeetTrapFeature.java index 5c2ccea3..4757b300 100644 --- a/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/FeetTrapFeature.java +++ b/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/FeetTrapFeature.java @@ -2,6 +2,7 @@ import namidevelopment.kiriyaga.api.annotation.RegisterFeature; import namidevelopment.kiriyaga.api.annotation.SubscribeEvent; +import namidevelopment.kiriyaga.api.event.impl.PacketReceiveEvent; import namidevelopment.kiriyaga.api.event.impl.PreTickEvent; import namidevelopment.kiriyaga.api.event.impl.Render3DEvent; import namidevelopment.kiriyaga.api.model.feature.Feature; @@ -63,6 +64,11 @@ public void onRender(Render3DEvent event) { trap.onRender(event); } + @SubscribeEvent + public void onPacketReceive(PacketReceiveEvent event) { + trap.handlePacket(event, this, getTrapTargets()); + } + private List getTrapTargets() { Set targets = new HashSet<>(getSurround(MC.player, 0, extension.get())); if (corners.get()) { @@ -88,4 +94,4 @@ private List getTrapTargets() { } return new ArrayList<>(targets); } -} +} \ No newline at end of file diff --git a/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/component/TrapComponent.java b/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/component/TrapComponent.java index f41eb83a..5ae732bc 100644 --- a/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/component/TrapComponent.java +++ b/nami-client/src/main/java/namidevelopment/kiriyaga/nami/impl/feature/combat/component/TrapComponent.java @@ -13,6 +13,12 @@ import namidevelopment.kiriyaga.api.util.render.RenderUtil; import namidevelopment.kiriyaga.nami.impl.feature.client.ColorFeature; import namidevelopment.kiriyaga.nami.impl.feature.client.TrapFeature; +import namidevelopment.kiriyaga.api.event.impl.PacketReceiveEvent; +import namidevelopment.kiriyaga.api.util.InventoryUtils; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Items; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.InteractionHand; @@ -54,6 +60,7 @@ public class TrapComponent { private final List targetPositions = new ArrayList<>(); private final List placedPositions = new ArrayList<>(); // todo: finish this + private final List pendingSimulations = new ArrayList<>(); public TrapComponent(Feature feature) { range = feature.addSetting(new DoubleSetting("Range", 4.50, 1.0, 6.0)); @@ -100,6 +107,8 @@ public void onTick(PreTickEvent event, Feature owner, List newTargets) TrapFeature trapFeature = FEATURE_SERVICE.getStorage().getByClass(TrapFeature.class); tickTimer(trapFeature); + pendingSimulations.removeIf(pos -> !MC.level.getBlockState(pos).canBeReplaced()); + /* if (simulate.get() && !placedPositions.isEmpty()) { Item handItem = MC.player.getMainHandItem().getItem(); @@ -315,4 +324,75 @@ private void tickTimer(TrapFeature trapFeature) { } } } + + public void handlePacket(PacketReceiveEvent event, Feature owner, List currentTargets) { + if (!simulate.get()) return; + if (MC.player == null || MC.level == null) return; + + if (event.getPacket() instanceof ClientboundAddEntityPacket packet && + packet.getType() == EntityType.END_CRYSTAL) { + handleSequentialCrystals(packet, owner, currentTargets); + } + } + + private void handleSequentialCrystals(ClientboundAddEntityPacket packet, Feature owner, List currentTargets) { + Vec3 crystalPos = new Vec3(packet.getX(), packet.getY(), packet.getZ()); + AABB crystalBox = new AABB( + crystalPos.add(-1.0, 0, -1.0), + crystalPos.add(1.0, 2.0, 1.0) + ); + + BlockPos targetPos = null; + for (BlockPos pos : currentTargets) { + if (new AABB(pos).intersects(crystalBox)) { + targetPos = pos; + break; + } + } + + if (targetPos == null) return; + if (!multiTask.get() && MC.player.isUsingItem()) return; + + int slot = findObsidianSlot(); + if (slot == -1 && !(MC.player.getOffhandItem().getItem() instanceof BlockItem)) + return; + + boolean isOffhand = MC.player.getOffhandItem().getItem() instanceof BlockItem; + int previousSlot = MC.player.getInventory().getSelectedSlot(); + boolean switched = false; + + if (!isOffhand && slot != -1 && slot != previousSlot) { + InventoryUtils.attemptSwitch(slot); + switched = true; + } + + EndCrystal tempCrystal = new EndCrystal(MC.level, packet.getX(), packet.getY(), packet.getZ()); + tempCrystal.setId(packet.getId()); + MC.gameMode.attack(MC.player, tempCrystal); + + if (swing.get()) { + MC.player.swing(InteractionHand.MAIN_HAND); + } + + Item item = isOffhand ? MC.player.getOffhandItem().getItem() : MC.player.getInventory().getItem(slot).getItem(); + + boolean placed = place(targetPos, item, airPlace.get(), grim.get(), owner); + + if (placed) { + pendingSimulations.add(targetPos); + } + + if (switched && swapBack.get()) { + InventoryUtils.attemptSwitch(previousSlot); + } + } + + private int findObsidianSlot() { + for (int i = 0; i < 9; i++) { + if (MC.player.getInventory().getItem(i).getItem() == Items.OBSIDIAN) { + return i; + } + } + return -1; + } }