Начинающий
- Статус
- Оффлайн
- Регистрация
- 29 Окт 2025
- Сообщения
- 9
- Реакции
- 0
спс спастилВсем привет это моя первая тема судите строго)
Посмотреть вложение 325673
Я знаю что уже есть этот свап колесом но там много багов я сделал все идеально наверно/Java:package moscow.rockstar.systems.modules.modules.combat; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; import moscow.rockstar.systems.event.EventListener; import moscow.rockstar.systems.event.impl.render.HudRenderEvent; import moscow.rockstar.systems.event.impl.window.KeyPressEvent; import moscow.rockstar.systems.event.impl.window.MouseEvent; import moscow.rockstar.systems.modules.api.ModuleCategory; import moscow.rockstar.systems.modules.api.ModuleInfo; import moscow.rockstar.systems.modules.impl.BaseModule; import moscow.rockstar.systems.setting.settings.BindSetting; import moscow.rockstar.systems.setting.settings.SelectSetting; import moscow.rockstar.utility.gui.GuiUtility; import moscow.rockstar.utility.inventory.ItemSlot; import moscow.rockstar.utility.inventory.group.SlotGroup; import moscow.rockstar.utility.inventory.group.SlotGroups; import moscow.rockstar.utility.game.ItemUtility; import net.minecraft.client.gl.ShaderProgramKeys; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferRenderer; import net.minecraft.client.render.BuiltBuffer; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.registry.RegistryWrapper; import net.minecraft.screen.slot.SlotActionType; import org.joml.Matrix4f; @ModuleInfo(name="Swap Test", category=ModuleCategory.COMBAT) public class SwapTest extends BaseModule { @SuppressWarnings("unused") private final BindSetting wheelBind = new BindSetting(this, "modules.settings.swap_test.wheel_bind"); @SuppressWarnings("unused") private final SelectSetting show = new SelectSetting(this, "modules.settings.swap_test.show"); @SuppressWarnings("unused") private final SelectSetting.Value showTotems = new SelectSetting.Value(this.show, "modules.settings.swap_test.show.totems").select(); private final SelectSetting.Value showHeads = new SelectSetting.Value(this.show, "modules.settings.swap_test.show.heads").select(); private boolean wheelOpen; private boolean cursorUnlocked; private List<WheelEntry> wheelEntries = List.of(); @SuppressWarnings("unused") private final EventListener<KeyPressEvent> onKey = event -> { if (event.getAction() != 1) { return; } if (SwapTest.mc.currentScreen != null) { return; } if (this.wheelBind.isKey(event.getKey())) { this.toggleWheel(); } }; @SuppressWarnings("unused") private final EventListener<MouseEvent> onMouse = event -> { if (SwapTest.mc.currentScreen != null) { return; } if (this.wheelBind.isKey(event.getButton())) { this.toggleWheel(); return; } if (!this.wheelOpen || SwapTest.mc.currentScreen != null) { return; } if (event.getButton() == 0) { this.pickWheelSlot(); } if (event.getButton() == 1) { this.toggleWheel(); } }; @SuppressWarnings("unused") private final EventListener<HudRenderEvent> onHud = event -> { if (!this.wheelOpen) { return; } if (SwapTest.mc.currentScreen != null) { this.wheelOpen = false; this.updateWheelCursorState(false); return; } this.wheelEntries = this.buildWheelEntries(); this.updateWheelCursorState(true); int count = Math.max(3, this.wheelEntries.size()); float cx = sr.getScaledWidth() / 2.0f; float cy = sr.getScaledHeight() / 2.0f; float outerR = 92.0f + (float)Math.max(0, count - 8) * 6.0f; float innerR = Math.max(26.0f, outerR - 38.0f); float mouseX = (float)GuiUtility.getMouse().getX(); float mouseY = (float)GuiUtility.getMouse().getY(); int hover = this.getHoverIndex(mouseX, mouseY, cx, cy, innerR, outerR, count); RenderSystem.enableBlend(); RenderSystem.disableDepthTest(); RenderSystem.disableCull(); RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); Matrix4f matrix = event.getContext().getMatrices().peek().getPositionMatrix(); BufferBuilder buffer = RenderSystem.renderThreadTesselator().begin(VertexFormat.DrawMode.TRIANGLES, VertexFormats.POSITION_COLOR); for (int i = 0; i < count; i++) { boolean isHover = i == hover; int r = 205; int g = 205; int b = 205; int a = 95; if (isHover) { r = 255; g = 209; b = 47; a = 140; } float start = (float)(-Math.PI / 2.0 + 2.0 * Math.PI * (i / (double)count)); float end = (float)(-Math.PI / 2.0 + 2.0 * Math.PI * ((i + 1.0) / (double)count)); this.drawRingSegment(buffer, matrix, cx, cy, innerR, outerR, start, end, r, g, b, a); } BufferRenderer.drawWithGlobalProgram((BuiltBuffer)buffer.end()); for (int i = 0; i < count; i++) { float start = (float)(-Math.PI / 2.0 + 2.0 * Math.PI * (i / (double)count)); float end = (float)(-Math.PI / 2.0 + 2.0 * Math.PI * ((i + 1.0) / (double)count)); WheelEntry entry = i < this.wheelEntries.size() ? this.wheelEntries.get(i) : null; if (entry != null) { float mid = (start + end) / 2.0f; float iconR = (innerR + outerR) / 2.0f; float ix = cx + (float)Math.cos(mid) * iconR; float iy = cy + (float)Math.sin(mid) * iconR; event.getContext().drawItem(entry.displayStack, (int)(ix - 8.0f), (int)(iy - 8.0f)); if (entry.totalCount > 1) { event.getContext().drawTextWithShadow(mc.textRenderer, String.valueOf(entry.totalCount), (int)(ix + 5.0f), (int)(iy + 3.0f), 0xFFFFFF); } } } RenderSystem.enableCull(); RenderSystem.enableDepthTest(); RenderSystem.defaultBlendFunc(); RenderSystem.disableBlend(); if (hover >= 0 && hover < this.wheelEntries.size()) { WheelEntry entry = this.wheelEntries.get(hover); event.getContext().drawTextWithShadow(mc.textRenderer, entry.displayStack.getName(), (int)(mouseX + 10.0f), (int)(mouseY + 10.0f), 0xFFFFFF); } }; @Override public void onDisable() { this.wheelOpen = false; this.updateWheelCursorState(false); super.onDisable(); } private void toggleWheel() { this.wheelOpen = !this.wheelOpen; if (!this.wheelOpen) { this.updateWheelCursorState(false); return; } this.updateWheelCursorState(true); } private void updateWheelCursorState(boolean shouldBeUnlocked) { if (SwapTest.mc == null || SwapTest.mc.mouse == null) { return; } if (shouldBeUnlocked) { if (!this.cursorUnlocked) { SwapTest.mc.mouse.unlockCursor(); this.cursorUnlocked = true; } return; } if (this.cursorUnlocked) { if (SwapTest.mc.currentScreen == null) { SwapTest.mc.mouse.lockCursor(); } this.cursorUnlocked = false; } } private void pickWheelSlot() { int count = Math.max(3, this.wheelEntries.size()); float cx = sr.getScaledWidth() / 2.0f; float cy = sr.getScaledHeight() / 2.0f; float outerR = 92.0f + (float)Math.max(0, count - 8) * 6.0f; float innerR = Math.max(26.0f, outerR - 38.0f); float mouseX = (float)GuiUtility.getMouse().getX(); float mouseY = (float)GuiUtility.getMouse().getY(); int hover = this.getHoverIndex(mouseX, mouseY, cx, cy, innerR, outerR, count); if (hover == -1) { this.toggleWheel(); return; } if (hover >= this.wheelEntries.size()) { this.toggleWheel(); return; } WheelEntry entry = this.wheelEntries.get(hover); ItemSlot slot = this.findBestSlot(entry.predicate); if (slot == null) { this.toggleWheel(); return; } this.moveToOffhand(slot); this.toggleWheel(); } private void moveToOffhand(ItemSlot slot) { if (SwapTest.mc.player == null) { return; } if (slot.getIdForServer() == 45) { return; } if (SwapTest.mc.interactionManager == null || SwapTest.mc.player.currentScreenHandler == null) { return; } SwapTest.mc.interactionManager.clickSlot(SwapTest.mc.player.currentScreenHandler.syncId, slot.getIdForServer(), 40, SlotActionType.SWAP, SwapTest.mc.player); } @SuppressWarnings("unused") private ItemSlot findBestSlot(Item item) { if (item == null || item == Items.AIR) { return null; } SlotGroup<ItemSlot> slotsToSearch = SlotGroups.inventory().and(SlotGroups.hotbar()); List<ItemSlot> slots = slotsToSearch.findItems(item); return slots.stream().min(Comparator.comparingInt(this::bestFactorForSwap)).orElse(null); } private ItemSlot findBestSlot(java.util.function.Predicate<ItemStack> predicate) { if (predicate == null) { return null; } SlotGroup<ItemSlot> slotsToSearch = SlotGroups.inventory().and(SlotGroups.hotbar()); List<ItemSlot> slots = slotsToSearch.findItems(predicate); return slots.stream().min(Comparator.comparingInt(this::bestFactorForSwap)).orElse(null); } private int bestFactorForSwap(ItemSlot slot) { return ItemUtility.bestFactor(slot.itemStack()) - (slot.getIdForServer() == 45 ? 99 : 0); } private List<WheelEntry> buildWheelEntries() { if (mc.player == null || mc.world == null) { return List.of(); } SlotGroup<ItemSlot> group = SlotGroups.inventory().and(SlotGroups.hotbar()).and(SlotGroups.offhand()); List<ItemSlot> slots = group.getSlots(); HashMap<String, WheelEntryAccum> accum = new HashMap<>(); ArrayList<WheelEntry> result = new ArrayList<>(); for (ItemSlot slot : slots) { ItemStack stack = slot.itemStack(); if (stack == null || stack.isEmpty() || stack.getItem() == Items.AIR) { continue; } if (this.showTotems.isSelected() && stack.getItem() == Items.TOTEM_OF_UNDYING) { if (this.isNormalTotem(stack)) { String key = "totem:normal"; WheelEntryAccum entry = accum.computeIfAbsent(key, k -> new WheelEntryAccum(stack.copyWithCount(1), 0, s -> s.getItem() == Items.TOTEM_OF_UNDYING && this.isNormalTotem(s))); entry.totalCount += stack.getCount(); } else { ItemStack display = stack.copyWithCount(1); String key = "totem:enchanted:" + this.stackKey(display); result.add(new WheelEntry(display, stack.getCount(), s -> s.getItem() == Items.TOTEM_OF_UNDYING && !this.isNormalTotem(s) && this.stackKey(s).equals(this.stackKey(display)), key)); } } if (this.showHeads.isSelected() && stack.getItem() == Items.PLAYER_HEAD) { ItemStack display = stack.copyWithCount(1); String key = "head:" + this.stackKey(display); WheelEntryAccum entry = accum.computeIfAbsent(key, k -> new WheelEntryAccum(display, 0, s -> s.getItem() == Items.PLAYER_HEAD && this.stackKey(s).equals(this.stackKey(display)))); entry.totalCount += stack.getCount(); } } for (WheelEntryAccum entry : accum.values()) { result.add(new WheelEntry(entry.displayStack, entry.totalCount, entry.predicate, "accum")); } result.sort(Comparator.comparingInt(e -> e.displayStack.getItem() == Items.TOTEM_OF_UNDYING ? 0 : 1)); return result; } private boolean isNormalTotem(ItemStack stack) { return stack.getItem() == Items.TOTEM_OF_UNDYING && !stack.hasEnchantments() && !ItemUtility.isDonItem(stack); } private String stackKey(ItemStack stack) { if (mc.world == null) { return stack.getItem().toString(); } ItemStack copy = stack.copyWithCount(1); try { NbtElement nbt = copy.toNbtAllowEmpty((RegistryWrapper.WrapperLookup)mc.world.getRegistryManager()); if (nbt instanceof NbtCompound compound) { compound.remove("count"); return compound.toString(); } } catch (Exception ignored) { } return copy.getItem().toString() + "|" + copy.getComponents(); } private int getHoverIndex(float mouseX, float mouseY, float cx, float cy, float innerR, float outerR, int count) { float dx = mouseX - cx; float dy = mouseY - cy; float dist = (float)Math.sqrt(dx * dx + dy * dy); if (dist < innerR || dist > outerR) { return -1; } double ang = Math.atan2(dy, dx); ang = ang + Math.PI / 2.0; if (ang < 0.0) { ang += Math.PI * 2.0; } int idx = (int)Math.floor(ang / (Math.PI * 2.0) * count); if (idx < 0 || idx >= count) { return -1; } return idx; } private void drawRingSegment(BufferBuilder buffer, Matrix4f matrix, float cx, float cy, float innerR, float outerR, float start, float end, int r, int g, int b, int a) { int steps = Math.max(10, (int)(48.0f * (Math.abs(end - start) / ((float)Math.PI * 2.0f)))); float step = (end - start) / steps; for (int i = 0; i < steps; i++) { float a0 = start + step * i; float a1 = start + step * (i + 1); float x0o = cx + (float)Math.cos(a0) * outerR; float y0o = cy + (float)Math.sin(a0) * outerR; float x1o = cx + (float)Math.cos(a1) * outerR; float y1o = cy + (float)Math.sin(a1) * outerR; float x0i = cx + (float)Math.cos(a0) * innerR; float y0i = cy + (float)Math.sin(a0) * innerR; float x1i = cx + (float)Math.cos(a1) * innerR; float y1i = cy + (float)Math.sin(a1) * innerR; buffer.vertex(matrix, x0i, y0i, 0.0f).color(r, g, b, a); buffer.vertex(matrix, x0o, y0o, 0.0f).color(r, g, b, a); buffer.vertex(matrix, x1o, y1o, 0.0f).color(r, g, b, a); buffer.vertex(matrix, x0i, y0i, 0.0f).color(r, g, b, a); buffer.vertex(matrix, x1o, y1o, 0.0f).color(r, g, b, a); buffer.vertex(matrix, x1i, y1i, 0.0f).color(r, g, b, a); } } private static class WheelEntryAccum { final ItemStack displayStack; int totalCount; final java.util.function.Predicate<ItemStack> predicate; WheelEntryAccum(ItemStack displayStack, int totalCount, java.util.function.Predicate<ItemStack> predicate) { this.displayStack = displayStack; this.totalCount = totalCount; this.predicate = predicate; } } private static class WheelEntry { final ItemStack displayStack; final int totalCount; final java.util.function.Predicate<ItemStack> predicate; @SuppressWarnings("unused") final String debugKey; WheelEntry(ItemStack displayStack, int totalCount, java.util.function.Predicate<ItemStack> predicate, String debugKey) { this.displayStack = displayStack; this.totalCount = totalCount; this.predicate = predicate; this.debugKey = debugKey; } } }