Начинающий
Начинающий
- Статус
- Оффлайн
- Регистрация
- 12 Янв 2025
- Сообщения
- 20
- Реакции
- 1
- Выберите загрузчик игры
- Fabric
Всем привет это моя первая тема судите строго)
Я знаю что уже есть этот свап колесом но там много багов я сделал все идеально наверно/
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;
}
}
}
Последнее редактирование: