привет поможешь мне у меня там ошибки прост я хз уже 40 мин сам пытаюсь фиксанутьРеспект тебе братишка
привет поможешь мне у меня там ошибки прост я хз уже 40 мин сам пытаюсь фиксанутьРеспект тебе братишка
Пздц...Шо делать
for (Feature feature : Features) {
if (feature.included && feature.getClass() == featureClass) {
return true;
}
Вот тут ошибка в features, included
ваще капец стал половина софта в ошибках
vpnPlugin "Minecraft Development" was not installed: We are sorry, but we are currently unable to provide our products or services to you due to export control regulations.че делать я просто новичек
привет можешь помочь? мой дс nettoperka , у меня с moduleManager проблемыРеспект тебе братишка
дайте готовые сурсыДля начала устанавливаем плагин Minecraft Development
Далее создаем новый проект
Посмотреть вложение 289600
Заходим в главный класс мода и оставляем для себя только
Далее мы берём ноги в зубы и идем плотно пастить утилки с гитхаба (Java:@Mod("bigbrain") public class ClientEntry { public ClientEntry() { init(); } public void init() { MinecraftForge.EVENT_BUS.register(this); } }
Пожалуйста, авторизуйтесь для просмотра ссылки.|Пожалуйста, авторизуйтесь для просмотра ссылки.)
После успешного пастинга едем реализовывать наши функции.
Создаем класс Module и ModuleCategory
Java:public abstract class Module { public String name; public ModuleCategory category; public String description; public int key; public boolean included; public List<Setting> settings = new ArrayList<>(); public Module(String name, ModuleCategory category, String description) { this.name = name; this.category = category; this.description = description; } public Module(String name, ModuleCategory category, String description, int key) { this.name = name; this.category = category; this.key = key; this.description = description; } public void onEnable() { included = true; MinecraftForge.EVENT_BUS.register(this); } public void onDisable() { included = false; MinecraftForge.EVENT_BUS.unregister(this); } public void toggle() { if (included) { onDisable(); } else { onEnable(); } } public boolean isEnabled() { return included; } public ModuleCategory getCategory() { return category; } }
Так-же нам нужно создать менеджер для наших будущих функцийJava:public enum ModuleCategory { Combat, Movement, Player, Visuals }
В ините нашего мейн класса вызываемJava:public class ModulesManager { public static ArrayList<Feature> modules = new ArrayList<>(); public static void addModules() { try { // modules.add(new Class()); new Thread(() -> { try { Thread.sleep(5000); } catch (Exception ignored) { } }).start(); } catch (Exception ignored) { } } public static boolean moduleIncluded(Class<?> featureClass) { for (Feature feature : features) { if (feature.included && feature.getClass() == featureClass) { return true; } } return false; } }
Так-же добавляем в наш главный класс обработку нажатий на кнопки биндовJava:ModuleManager.addModules();
Уже сейчас мы можем для примера написать какую нибудь простенькую функциюJava:@SubscribeEvent public void onKeyInput(InputEvent.KeyInputEvent keyInputEvent) { for (Module module : ModuleManager.modules) { if (Minecraft.getInstance().screen == null && keyInputEvent.getKey() == module.key && keyInputEvent.getAction() == 1) { module.toggle(); } } }
Не забываем зарегистрировать функцию с помощью ModuleManager'aJava:public class TestModule extends Module { public TestModule() { super("test module", ModuleCategory.Movement, "jumping$", GLFW.GLFW_KEY_X); } // логика нашего $elfcod'a @Override public void onEnable() { Minecraft.getInstance().player.jumpFromGround(); super.onDisable(); } }
Чисто для нашего удобства создадит класс ClientUtil
Пришло время создать максимально простенькое нечто, напоминающее клик гуиJava:public class ClientUtil { public static Minecraft mc = Minecraft.getInstance(); public static MainWindow mw = mc.getWindow(); // добавляем сюда все, что используем часто }
На выходе получаем микро вариант cs guiJava:public class ClickUi extends Screen { private final List<Module> modules; private ModuleCategory selected; private int offset; public ClickUi() { super(new StringTextComponent("gui")); this.modules = ModuleManager.modules; this.selected = ModuleCategory.Combat; this.offset = 0; } @Override protected void init() { int y = this.height / 2 - 75; for (ModuleCategory category : ModuleCategory.values()) { this.addButton(new Buttons(this.width / 2 - 105, y, 75, 20, category.name(), (btn) -> { selected = category; })); y += 25; } } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { this.renderBackground(matrixStack); int x = this.width / 2; int Ypos = this.height / 2; DrawHelper.drawRoundedRect(x - 110, Ypos + 80, 225, 160, 5, new Color(8, 10, 12).brighter()); DrawHelper.drawRoundedRect(x - 20, Ypos + 75, 130, 150, 5, new Color(8, 10, 12)); RenderSystem.enableScissor((x - 20) * this.minecraft.getWindow().getWidth() / this.width, (Ypos - 74) * this.minecraft.getWindow().getHeight() / this.height, 130 * this.minecraft.getWindow().getWidth() / this.width, 150 * this.minecraft.getWindow().getHeight() / this.height); int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { StyledFontRenderer.drawString(matrixStack, ClientEntry.big, module.name, x - 15, y + ClientEntry.big.getFontHeight(), module.isEnabled() ? new Color(56, 78, 126) : new Color(255, 255, 255)); y += 15; } } RenderSystem.disableScissor(); super.render(matrixStack, mouseX, mouseY, partialTicks); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (button == 0) { int x = this.width / 2; int Ypos = this.height / 2; int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { if (mouseX >= x - 15 && mouseX <= x + 85 && mouseY >= y && mouseY <= y + 15) { module.toggle(); return true; } y += 15; } } } return super.mouseClicked(mouseX, mouseY, button); } @Override public boolean mouseScrolled(double mouseX, double mouseY, double value) { offset += value * 10; offset = Math.max(Math.min(offset, 0), -getMaxScroll()); return true; } private int getMaxScroll() { int count = 0; for (Module module : modules) { if (module.getCategory() == selected) { count++; } } return Math.max(0, count * 15 - 125); } private static class Buttons extends Button { public Buttons(int x, int y, int width, int height, String text, IPressable onPress) { super(x, y, width, height, new StringTextComponent(text), onPress); } @Override public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { Color color = this.isHovered() ? new Color(56, 78, 126) : new Color(17, 24, 39); DrawHelper.drawRoundedRect(this.x, this.y + this.height, this.width, this.height, 3, color); StyledFontRenderer.drawCenteredXString(matrixStack, ClientEntry.big, this.getMessage().getString(), this.x + this.width / 2, this.y + (this.height / 2) + 4, Color.WHITE); } } }
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)
Но мы же блатные, поэтому надо сделать сеттинги
Создаем класс Setting
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSettingJava:public class Setting { public String name; public boolean isVisible = true; public Setting(String name) {this.name = name;} public boolean isVisible() {return isVisible;} public String getName() {return name;} }
Java:public class FloatSetting extends Setting { private double min, max, inc; public double value; double defaultvalue; public void setInc(double inc) { this.inc = inc; } public double getDefaultvalue() { return defaultvalue; } public void setDefaultvalue(double defaultvalue) { this.defaultvalue = defaultvalue; } public FloatSetting(String name, double min, double max, double defaultvalue, double inc) { super(name); this.max = max; this.min = min; this.defaultvalue = defaultvalue; this.inc = inc; this.value = clamp((float) defaultvalue, (float) min, (float) max); } public double getValue() { return (value != 0) ? value : defaultvalue; } public double getValueFloat() { return (float) value; } public void setValDouble(double in) { this.value = in; } public void setValue(double value) { value = Math.round(value / inc) * inc; this.value = clamp(value, min, max); } public static double clamp(double num, double min, double max) { return Math.max(min, Math.min(max, num)); } public void reset() { setValue(defaultvalue); } public double getMin() { return min; } public void setMin(double min) { this.min = min; } public double getMax() { return max; } public void setMax(double max) { this.max = max; } public double getInc() { return inc; } public static float clamp(float num, float min, float max) { return num < min ? min : num > max ? max : num; } public int getValueInt() { return (int) value; } public void inc(boolean isPositive) { if (isPositive) setValue(getValue() + getInc()); else setValue(getValue() - getInc()); } }
Java:public class BooleanSetting extends Setting { public boolean value; public BooleanSetting(String name, boolean defaultVal) { super(name); this.value = defaultVal; } public void toggle() { this.value = !this.value; } public boolean isEnabled() { return value; } public void setEnabled() { this.value = value; } public boolean getValue() { return this.value; } }
Сеттинги в гуи добавите сами, мне впадлу слишком <3Java:public class ModeSetting extends Setting { private List<String> modes; private int index; public String mode; public Animation animation; public String previousMode; private int previousIndex; public List<String> getModes() { return modes; } public void setModes(List<String> modes) { this.modes = modes; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; this.mode = modes.get(index); } public String getMode() { return mode; } public ModeSetting(String name, String... modes) { super(name); this.modes = Arrays.asList(modes); this.mode = this.modes.get(0); this.index = 0; this.animation = new Animation(1, 1, 0.1f); this.previousMode = null; this.previousIndex = 0; } public void cycle() { this.previousMode = this.mode; this.previousIndex = this.index; if (index < modes.size() - 1) { index++; } else { index = 0; } this.mode = modes.get(index); this.animation.setAnim(0); } public void setMode(String mode) { if (!this.mode.equals(mode)) { this.previousMode = this.mode; this.previousIndex = this.index; this.mode = mode; this.index = modes.indexOf(mode); this.animation.setAnim(0); } } public int getPreviousIndex() { return previousIndex; } public boolean isMode(String mode) { return Objects.equals(this.mode, mode); } public String getValue() { return this.mode; } }
Пример использованию наших сеттингов
Так-же для возможности открыть нашу гуи создаем классJava:public class TestModule() { BooleanSetting booleanSetting = new BooleanSetting("Bool Setting", true); public TestModule() { super("module", ModuleCategory.Visuals, "test"); addSettings(booleanSetting); } @SubscribeEvent public void onTick(TickEvent event) { if (booleanSetting.isEnabled()) { /* ... */ } } }
И регистрируем его в ModuleManager'eJava:public class ClickGUI extends Module { public ClickGUI() { super("gui", ModuleCategory.Visuals, "yougame gui", GLFW.GLFW_KEY_RIGHT_SHIFT); } @Override public void onEnable() { mc.setScreen(new ClickUi()); } }
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!
Нужно ли вообще делать тутор на хуки/миксины?
это схуялибля ну это да, но ты же понимаешь что в этом разделе человека 3 от силы будут свой рендер писать
ctrl c + ctrl vдайте готовые сурсы
MCP ЛУЧШЕ!!!Для начала устанавливаем плагин Minecraft Development
Далее создаем новый проект
Посмотреть вложение 289600
Заходим в главный класс мода и оставляем для себя только
Далее мы берём ноги в зубы и идем плотно пастить утилки с гитхаба (Java:@Mod("bigbrain") public class ClientEntry { public ClientEntry() { init(); } public void init() { MinecraftForge.EVENT_BUS.register(this); } }
Пожалуйста, авторизуйтесь для просмотра ссылки.|Пожалуйста, авторизуйтесь для просмотра ссылки.)
После успешного пастинга едем реализовывать наши функции.
Создаем класс Module и ModuleCategory
Java:public abstract class Module { public String name; public ModuleCategory category; public String description; public int key; public boolean included; public List<Setting> settings = new ArrayList<>(); public Module(String name, ModuleCategory category, String description) { this.name = name; this.category = category; this.description = description; } public Module(String name, ModuleCategory category, String description, int key) { this.name = name; this.category = category; this.key = key; this.description = description; } public void onEnable() { included = true; MinecraftForge.EVENT_BUS.register(this); } public void onDisable() { included = false; MinecraftForge.EVENT_BUS.unregister(this); } public void toggle() { if (included) { onDisable(); } else { onEnable(); } } public boolean isEnabled() { return included; } public ModuleCategory getCategory() { return category; } }
Так-же нам нужно создать менеджер для наших будущих функцийJava:public enum ModuleCategory { Combat, Movement, Player, Visuals }
В ините нашего мейн класса вызываемJava:public class ModulesManager { public static ArrayList<Feature> modules = new ArrayList<>(); public static void addModules() { try { // modules.add(new Class()); new Thread(() -> { try { Thread.sleep(5000); } catch (Exception ignored) { } }).start(); } catch (Exception ignored) { } } public static boolean moduleIncluded(Class<?> featureClass) { for (Feature feature : features) { if (feature.included && feature.getClass() == featureClass) { return true; } } return false; } }
Так-же добавляем в наш главный класс обработку нажатий на кнопки биндовJava:ModuleManager.addModules();
Уже сейчас мы можем для примера написать какую нибудь простенькую функциюJava:@SubscribeEvent public void onKeyInput(InputEvent.KeyInputEvent keyInputEvent) { for (Module module : ModuleManager.modules) { if (Minecraft.getInstance().screen == null && keyInputEvent.getKey() == module.key && keyInputEvent.getAction() == 1) { module.toggle(); } } }
Не забываем зарегистрировать функцию с помощью ModuleManager'aJava:public class TestModule extends Module { public TestModule() { super("test module", ModuleCategory.Movement, "jumping$", GLFW.GLFW_KEY_X); } // логика нашего $elfcod'a @Override public void onEnable() { Minecraft.getInstance().player.jumpFromGround(); super.onDisable(); } }
Чисто для нашего удобства создадит класс ClientUtil
Пришло время создать максимально простенькое нечто, напоминающее клик гуиJava:public class ClientUtil { public static Minecraft mc = Minecraft.getInstance(); public static MainWindow mw = mc.getWindow(); // добавляем сюда все, что используем часто }
На выходе получаем микро вариант cs guiJava:public class ClickUi extends Screen { private final List<Module> modules; private ModuleCategory selected; private int offset; public ClickUi() { super(new StringTextComponent("gui")); this.modules = ModuleManager.modules; this.selected = ModuleCategory.Combat; this.offset = 0; } @Override protected void init() { int y = this.height / 2 - 75; for (ModuleCategory category : ModuleCategory.values()) { this.addButton(new Buttons(this.width / 2 - 105, y, 75, 20, category.name(), (btn) -> { selected = category; })); y += 25; } } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { this.renderBackground(matrixStack); int x = this.width / 2; int Ypos = this.height / 2; DrawHelper.drawRoundedRect(x - 110, Ypos + 80, 225, 160, 5, new Color(8, 10, 12).brighter()); DrawHelper.drawRoundedRect(x - 20, Ypos + 75, 130, 150, 5, new Color(8, 10, 12)); RenderSystem.enableScissor((x - 20) * this.minecraft.getWindow().getWidth() / this.width, (Ypos - 74) * this.minecraft.getWindow().getHeight() / this.height, 130 * this.minecraft.getWindow().getWidth() / this.width, 150 * this.minecraft.getWindow().getHeight() / this.height); int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { StyledFontRenderer.drawString(matrixStack, ClientEntry.big, module.name, x - 15, y + ClientEntry.big.getFontHeight(), module.isEnabled() ? new Color(56, 78, 126) : new Color(255, 255, 255)); y += 15; } } RenderSystem.disableScissor(); super.render(matrixStack, mouseX, mouseY, partialTicks); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (button == 0) { int x = this.width / 2; int Ypos = this.height / 2; int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { if (mouseX >= x - 15 && mouseX <= x + 85 && mouseY >= y && mouseY <= y + 15) { module.toggle(); return true; } y += 15; } } } return super.mouseClicked(mouseX, mouseY, button); } @Override public boolean mouseScrolled(double mouseX, double mouseY, double value) { offset += value * 10; offset = Math.max(Math.min(offset, 0), -getMaxScroll()); return true; } private int getMaxScroll() { int count = 0; for (Module module : modules) { if (module.getCategory() == selected) { count++; } } return Math.max(0, count * 15 - 125); } private static class Buttons extends Button { public Buttons(int x, int y, int width, int height, String text, IPressable onPress) { super(x, y, width, height, new StringTextComponent(text), onPress); } @Override public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { Color color = this.isHovered() ? new Color(56, 78, 126) : new Color(17, 24, 39); DrawHelper.drawRoundedRect(this.x, this.y + this.height, this.width, this.height, 3, color); StyledFontRenderer.drawCenteredXString(matrixStack, ClientEntry.big, this.getMessage().getString(), this.x + this.width / 2, this.y + (this.height / 2) + 4, Color.WHITE); } } }
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)
Но мы же блатные, поэтому надо сделать сеттинги
Создаем класс Setting
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSettingJava:public class Setting { public String name; public boolean isVisible = true; public Setting(String name) {this.name = name;} public boolean isVisible() {return isVisible;} public String getName() {return name;} }
Java:public class FloatSetting extends Setting { private double min, max, inc; public double value; double defaultvalue; public void setInc(double inc) { this.inc = inc; } public double getDefaultvalue() { return defaultvalue; } public void setDefaultvalue(double defaultvalue) { this.defaultvalue = defaultvalue; } public FloatSetting(String name, double min, double max, double defaultvalue, double inc) { super(name); this.max = max; this.min = min; this.defaultvalue = defaultvalue; this.inc = inc; this.value = clamp((float) defaultvalue, (float) min, (float) max); } public double getValue() { return (value != 0) ? value : defaultvalue; } public double getValueFloat() { return (float) value; } public void setValDouble(double in) { this.value = in; } public void setValue(double value) { value = Math.round(value / inc) * inc; this.value = clamp(value, min, max); } public static double clamp(double num, double min, double max) { return Math.max(min, Math.min(max, num)); } public void reset() { setValue(defaultvalue); } public double getMin() { return min; } public void setMin(double min) { this.min = min; } public double getMax() { return max; } public void setMax(double max) { this.max = max; } public double getInc() { return inc; } public static float clamp(float num, float min, float max) { return num < min ? min : num > max ? max : num; } public int getValueInt() { return (int) value; } public void inc(boolean isPositive) { if (isPositive) setValue(getValue() + getInc()); else setValue(getValue() - getInc()); } }
Java:public class BooleanSetting extends Setting { public boolean value; public BooleanSetting(String name, boolean defaultVal) { super(name); this.value = defaultVal; } public void toggle() { this.value = !this.value; } public boolean isEnabled() { return value; } public void setEnabled() { this.value = value; } public boolean getValue() { return this.value; } }
Сеттинги в гуи добавите сами, мне впадлу слишком <3Java:public class ModeSetting extends Setting { private List<String> modes; private int index; public String mode; public Animation animation; public String previousMode; private int previousIndex; public List<String> getModes() { return modes; } public void setModes(List<String> modes) { this.modes = modes; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; this.mode = modes.get(index); } public String getMode() { return mode; } public ModeSetting(String name, String... modes) { super(name); this.modes = Arrays.asList(modes); this.mode = this.modes.get(0); this.index = 0; this.animation = new Animation(1, 1, 0.1f); this.previousMode = null; this.previousIndex = 0; } public void cycle() { this.previousMode = this.mode; this.previousIndex = this.index; if (index < modes.size() - 1) { index++; } else { index = 0; } this.mode = modes.get(index); this.animation.setAnim(0); } public void setMode(String mode) { if (!this.mode.equals(mode)) { this.previousMode = this.mode; this.previousIndex = this.index; this.mode = mode; this.index = modes.indexOf(mode); this.animation.setAnim(0); } } public int getPreviousIndex() { return previousIndex; } public boolean isMode(String mode) { return Objects.equals(this.mode, mode); } public String getValue() { return this.mode; } }
Пример использованию наших сеттингов
Так-же для возможности открыть нашу гуи создаем классJava:public class TestModule() { BooleanSetting booleanSetting = new BooleanSetting("Bool Setting", true); public TestModule() { super("module", ModuleCategory.Visuals, "test"); addSettings(booleanSetting); } @SubscribeEvent public void onTick(TickEvent event) { if (booleanSetting.isEnabled()) { /* ... */ } } }
И регистрируем его в ModuleManager'eJava:public class ClickGUI extends Module { public ClickGUI() { super("gui", ModuleCategory.Visuals, "yougame gui", GLFW.GLFW_KEY_RIGHT_SHIFT); } @Override public void onEnable() { mc.setScreen(new ClickUi()); } }
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!
Нужно ли вообще делать тутор на хуки/миксины?
Для начала устанавливаем плагин Minecraft Development
Далее создаем новый проект
Посмотреть вложение 289600
Заходим в главный класс мода и оставляем для себя только
Далее мы берём ноги в зубы и идем плотно пастить утилки с гитхаба (Java:@Mod("bigbrain") public class ClientEntry { public ClientEntry() { init(); } public void init() { MinecraftForge.EVENT_BUS.register(this); } }
Пожалуйста, авторизуйтесь для просмотра ссылки.|Пожалуйста, авторизуйтесь для просмотра ссылки.)
После успешного пастинга едем реализовывать наши функции.
Создаем класс Module и ModuleCategory
Java:public abstract class Module { public String name; public ModuleCategory category; public String description; public int key; public boolean included; public List<Setting> settings = new ArrayList<>(); public Module(String name, ModuleCategory category, String description) { this.name = name; this.category = category; this.description = description; } public Module(String name, ModuleCategory category, String description, int key) { this.name = name; this.category = category; this.key = key; this.description = description; } public void onEnable() { included = true; MinecraftForge.EVENT_BUS.register(this); } public void onDisable() { included = false; MinecraftForge.EVENT_BUS.unregister(this); } public void toggle() { if (included) { onDisable(); } else { onEnable(); } } public boolean isEnabled() { return included; } public ModuleCategory getCategory() { return category; } }
Так-же нам нужно создать менеджер для наших будущих функцийJava:public enum ModuleCategory { Combat, Movement, Player, Visuals }
В ините нашего мейн класса вызываемJava:public class ModulesManager { public static ArrayList<Feature> modules = new ArrayList<>(); public static void addModules() { try { // modules.add(new Class()); new Thread(() -> { try { Thread.sleep(5000); } catch (Exception ignored) { } }).start(); } catch (Exception ignored) { } } public static boolean moduleIncluded(Class<?> featureClass) { for (Feature feature : features) { if (feature.included && feature.getClass() == featureClass) { return true; } } return false; } }
Так-же добавляем в наш главный класс обработку нажатий на кнопки биндовJava:ModuleManager.addModules();
Уже сейчас мы можем для примера написать какую нибудь простенькую функциюJava:@SubscribeEvent public void onKeyInput(InputEvent.KeyInputEvent keyInputEvent) { for (Module module : ModuleManager.modules) { if (Minecraft.getInstance().screen == null && keyInputEvent.getKey() == module.key && keyInputEvent.getAction() == 1) { module.toggle(); } } }
Не забываем зарегистрировать функцию с помощью ModuleManager'aJava:public class TestModule extends Module { public TestModule() { super("test module", ModuleCategory.Movement, "jumping$", GLFW.GLFW_KEY_X); } // логика нашего $elfcod'a @Override public void onEnable() { Minecraft.getInstance().player.jumpFromGround(); super.onDisable(); } }
Чисто для нашего удобства создадит класс ClientUtil
Пришло время создать максимально простенькое нечто, напоминающее клик гуиJava:public class ClientUtil { public static Minecraft mc = Minecraft.getInstance(); public static MainWindow mw = mc.getWindow(); // добавляем сюда все, что используем часто }
На выходе получаем микро вариант cs guiJava:public class ClickUi extends Screen { private final List<Module> modules; private ModuleCategory selected; private int offset; public ClickUi() { super(new StringTextComponent("gui")); this.modules = ModuleManager.modules; this.selected = ModuleCategory.Combat; this.offset = 0; } @Override protected void init() { int y = this.height / 2 - 75; for (ModuleCategory category : ModuleCategory.values()) { this.addButton(new Buttons(this.width / 2 - 105, y, 75, 20, category.name(), (btn) -> { selected = category; })); y += 25; } } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { this.renderBackground(matrixStack); int x = this.width / 2; int Ypos = this.height / 2; DrawHelper.drawRoundedRect(x - 110, Ypos + 80, 225, 160, 5, new Color(8, 10, 12).brighter()); DrawHelper.drawRoundedRect(x - 20, Ypos + 75, 130, 150, 5, new Color(8, 10, 12)); RenderSystem.enableScissor((x - 20) * this.minecraft.getWindow().getWidth() / this.width, (Ypos - 74) * this.minecraft.getWindow().getHeight() / this.height, 130 * this.minecraft.getWindow().getWidth() / this.width, 150 * this.minecraft.getWindow().getHeight() / this.height); int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { StyledFontRenderer.drawString(matrixStack, ClientEntry.big, module.name, x - 15, y + ClientEntry.big.getFontHeight(), module.isEnabled() ? new Color(56, 78, 126) : new Color(255, 255, 255)); y += 15; } } RenderSystem.disableScissor(); super.render(matrixStack, mouseX, mouseY, partialTicks); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (button == 0) { int x = this.width / 2; int Ypos = this.height / 2; int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { if (mouseX >= x - 15 && mouseX <= x + 85 && mouseY >= y && mouseY <= y + 15) { module.toggle(); return true; } y += 15; } } } return super.mouseClicked(mouseX, mouseY, button); } @Override public boolean mouseScrolled(double mouseX, double mouseY, double value) { offset += value * 10; offset = Math.max(Math.min(offset, 0), -getMaxScroll()); return true; } private int getMaxScroll() { int count = 0; for (Module module : modules) { if (module.getCategory() == selected) { count++; } } return Math.max(0, count * 15 - 125); } private static class Buttons extends Button { public Buttons(int x, int y, int width, int height, String text, IPressable onPress) { super(x, y, width, height, new StringTextComponent(text), onPress); } @Override public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { Color color = this.isHovered() ? new Color(56, 78, 126) : new Color(17, 24, 39); DrawHelper.drawRoundedRect(this.x, this.y + this.height, this.width, this.height, 3, color); StyledFontRenderer.drawCenteredXString(matrixStack, ClientEntry.big, this.getMessage().getString(), this.x + this.width / 2, this.y + (this.height / 2) + 4, Color.WHITE); } } }
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)
Но мы же блатные, поэтому надо сделать сеттинги
Создаем класс Setting
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSettingJava:public class Setting { public String name; public boolean isVisible = true; public Setting(String name) {this.name = name;} public boolean isVisible() {return isVisible;} public String getName() {return name;} }
Java:public class FloatSetting extends Setting { private double min, max, inc; public double value; double defaultvalue; public void setInc(double inc) { this.inc = inc; } public double getDefaultvalue() { return defaultvalue; } public void setDefaultvalue(double defaultvalue) { this.defaultvalue = defaultvalue; } public FloatSetting(String name, double min, double max, double defaultvalue, double inc) { super(name); this.max = max; this.min = min; this.defaultvalue = defaultvalue; this.inc = inc; this.value = clamp((float) defaultvalue, (float) min, (float) max); } public double getValue() { return (value != 0) ? value : defaultvalue; } public double getValueFloat() { return (float) value; } public void setValDouble(double in) { this.value = in; } public void setValue(double value) { value = Math.round(value / inc) * inc; this.value = clamp(value, min, max); } public static double clamp(double num, double min, double max) { return Math.max(min, Math.min(max, num)); } public void reset() { setValue(defaultvalue); } public double getMin() { return min; } public void setMin(double min) { this.min = min; } public double getMax() { return max; } public void setMax(double max) { this.max = max; } public double getInc() { return inc; } public static float clamp(float num, float min, float max) { return num < min ? min : num > max ? max : num; } public int getValueInt() { return (int) value; } public void inc(boolean isPositive) { if (isPositive) setValue(getValue() + getInc()); else setValue(getValue() - getInc()); } }
Java:public class BooleanSetting extends Setting { public boolean value; public BooleanSetting(String name, boolean defaultVal) { super(name); this.value = defaultVal; } public void toggle() { this.value = !this.value; } public boolean isEnabled() { return value; } public void setEnabled() { this.value = value; } public boolean getValue() { return this.value; } }
Сеттинги в гуи добавите сами, мне впадлу слишком <3Java:public class ModeSetting extends Setting { private List<String> modes; private int index; public String mode; public Animation animation; public String previousMode; private int previousIndex; public List<String> getModes() { return modes; } public void setModes(List<String> modes) { this.modes = modes; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; this.mode = modes.get(index); } public String getMode() { return mode; } public ModeSetting(String name, String... modes) { super(name); this.modes = Arrays.asList(modes); this.mode = this.modes.get(0); this.index = 0; this.animation = new Animation(1, 1, 0.1f); this.previousMode = null; this.previousIndex = 0; } public void cycle() { this.previousMode = this.mode; this.previousIndex = this.index; if (index < modes.size() - 1) { index++; } else { index = 0; } this.mode = modes.get(index); this.animation.setAnim(0); } public void setMode(String mode) { if (!this.mode.equals(mode)) { this.previousMode = this.mode; this.previousIndex = this.index; this.mode = mode; this.index = modes.indexOf(mode); this.animation.setAnim(0); } } public int getPreviousIndex() { return previousIndex; } public boolean isMode(String mode) { return Objects.equals(this.mode, mode); } public String getValue() { return this.mode; } }
Пример использованию наших сеттингов
Так-же для возможности открыть нашу гуи создаем классJava:public class TestModule() { BooleanSetting booleanSetting = new BooleanSetting("Bool Setting", true); public TestModule() { super("module", ModuleCategory.Visuals, "test"); addSettings(booleanSetting); } @SubscribeEvent public void onTick(TickEvent event) { if (booleanSetting.isEnabled()) { /* ... */ } } }
И регистрируем его в ModuleManager'eJava:public class ClickGUI extends Module { public ClickGUI() { super("gui", ModuleCategory.Visuals, "yougame gui", GLFW.GLFW_KEY_RIGHT_SHIFT); } @Override public void onEnable() { mc.setScreen(new ClickUi()); } }
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!
Нужно ли вообще делать тутор на хуки/миксины?
руками установить :/
куда закинуть надоруками установить :/
берешь руки, пишешь впн и качаешь плагинкуда закинуть надо
Есть ли смысл таким образом делать "свою" базу? Это те же пасты, только заморочек большеДля начала устанавливаем плагин Minecraft Development
Далее создаем новый проект
Посмотреть вложение 289600
Заходим в главный класс мода и оставляем для себя только
Далее мы берём ноги в зубы и идем плотно пастить утилки с гитхаба (Java:@Mod("bigbrain") public class ClientEntry { public ClientEntry() { init(); } public void init() { MinecraftForge.EVENT_BUS.register(this); } }
Пожалуйста, авторизуйтесь для просмотра ссылки.|Пожалуйста, авторизуйтесь для просмотра ссылки.)
После успешного пастинга едем реализовывать наши функции.
Создаем класс Module и ModuleCategory
Java:public abstract class Module { public String name; public ModuleCategory category; public String description; public int key; public boolean included; public List<Setting> settings = new ArrayList<>(); public Module(String name, ModuleCategory category, String description) { this.name = name; this.category = category; this.description = description; } public Module(String name, ModuleCategory category, String description, int key) { this.name = name; this.category = category; this.key = key; this.description = description; } public void onEnable() { included = true; MinecraftForge.EVENT_BUS.register(this); } public void onDisable() { included = false; MinecraftForge.EVENT_BUS.unregister(this); } public void toggle() { if (included) { onDisable(); } else { onEnable(); } } public boolean isEnabled() { return included; } public ModuleCategory getCategory() { return category; } }
Так-же нам нужно создать менеджер для наших будущих функцийJava:public enum ModuleCategory { Combat, Movement, Player, Visuals }
В ините нашего мейн класса вызываемJava:public class ModulesManager { public static ArrayList<Feature> modules = new ArrayList<>(); public static void addModules() { try { // modules.add(new Class()); new Thread(() -> { try { Thread.sleep(5000); } catch (Exception ignored) { } }).start(); } catch (Exception ignored) { } } public static boolean moduleIncluded(Class<?> featureClass) { for (Feature feature : features) { if (feature.included && feature.getClass() == featureClass) { return true; } } return false; } }
Так-же добавляем в наш главный класс обработку нажатий на кнопки биндовJava:ModuleManager.addModules();
Уже сейчас мы можем для примера написать какую нибудь простенькую функциюJava:@SubscribeEvent public void onKeyInput(InputEvent.KeyInputEvent keyInputEvent) { for (Module module : ModuleManager.modules) { if (Minecraft.getInstance().screen == null && keyInputEvent.getKey() == module.key && keyInputEvent.getAction() == 1) { module.toggle(); } } }
Не забываем зарегистрировать функцию с помощью ModuleManager'aJava:public class TestModule extends Module { public TestModule() { super("test module", ModuleCategory.Movement, "jumping$", GLFW.GLFW_KEY_X); } // логика нашего $elfcod'a @Override public void onEnable() { Minecraft.getInstance().player.jumpFromGround(); super.onDisable(); } }
Чисто для нашего удобства создадит класс ClientUtil
Пришло время создать максимально простенькое нечто, напоминающее клик гуиJava:public class ClientUtil { public static Minecraft mc = Minecraft.getInstance(); public static MainWindow mw = mc.getWindow(); // добавляем сюда все, что используем часто }
На выходе получаем микро вариант cs guiJava:public class ClickUi extends Screen { private final List<Module> modules; private ModuleCategory selected; private int offset; public ClickUi() { super(new StringTextComponent("gui")); this.modules = ModuleManager.modules; this.selected = ModuleCategory.Combat; this.offset = 0; } @Override protected void init() { int y = this.height / 2 - 75; for (ModuleCategory category : ModuleCategory.values()) { this.addButton(new Buttons(this.width / 2 - 105, y, 75, 20, category.name(), (btn) -> { selected = category; })); y += 25; } } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { this.renderBackground(matrixStack); int x = this.width / 2; int Ypos = this.height / 2; DrawHelper.drawRoundedRect(x - 110, Ypos + 80, 225, 160, 5, new Color(8, 10, 12).brighter()); DrawHelper.drawRoundedRect(x - 20, Ypos + 75, 130, 150, 5, new Color(8, 10, 12)); RenderSystem.enableScissor((x - 20) * this.minecraft.getWindow().getWidth() / this.width, (Ypos - 74) * this.minecraft.getWindow().getHeight() / this.height, 130 * this.minecraft.getWindow().getWidth() / this.width, 150 * this.minecraft.getWindow().getHeight() / this.height); int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { StyledFontRenderer.drawString(matrixStack, ClientEntry.big, module.name, x - 15, y + ClientEntry.big.getFontHeight(), module.isEnabled() ? new Color(56, 78, 126) : new Color(255, 255, 255)); y += 15; } } RenderSystem.disableScissor(); super.render(matrixStack, mouseX, mouseY, partialTicks); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (button == 0) { int x = this.width / 2; int Ypos = this.height / 2; int y = Ypos - 70 + offset; for (Module module : modules) { if (module.getCategory() == selected) { if (mouseX >= x - 15 && mouseX <= x + 85 && mouseY >= y && mouseY <= y + 15) { module.toggle(); return true; } y += 15; } } } return super.mouseClicked(mouseX, mouseY, button); } @Override public boolean mouseScrolled(double mouseX, double mouseY, double value) { offset += value * 10; offset = Math.max(Math.min(offset, 0), -getMaxScroll()); return true; } private int getMaxScroll() { int count = 0; for (Module module : modules) { if (module.getCategory() == selected) { count++; } } return Math.max(0, count * 15 - 125); } private static class Buttons extends Button { public Buttons(int x, int y, int width, int height, String text, IPressable onPress) { super(x, y, width, height, new StringTextComponent(text), onPress); } @Override public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { Color color = this.isHovered() ? new Color(56, 78, 126) : new Color(17, 24, 39); DrawHelper.drawRoundedRect(this.x, this.y + this.height, this.width, this.height, 3, color); StyledFontRenderer.drawCenteredXString(matrixStack, ClientEntry.big, this.getMessage().getString(), this.x + this.width / 2, this.y + (this.height / 2) + 4, Color.WHITE); } } }
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)
Но мы же блатные, поэтому надо сделать сеттинги
Создаем класс Setting
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSettingJava:public class Setting { public String name; public boolean isVisible = true; public Setting(String name) {this.name = name;} public boolean isVisible() {return isVisible;} public String getName() {return name;} }
Java:public class FloatSetting extends Setting { private double min, max, inc; public double value; double defaultvalue; public void setInc(double inc) { this.inc = inc; } public double getDefaultvalue() { return defaultvalue; } public void setDefaultvalue(double defaultvalue) { this.defaultvalue = defaultvalue; } public FloatSetting(String name, double min, double max, double defaultvalue, double inc) { super(name); this.max = max; this.min = min; this.defaultvalue = defaultvalue; this.inc = inc; this.value = clamp((float) defaultvalue, (float) min, (float) max); } public double getValue() { return (value != 0) ? value : defaultvalue; } public double getValueFloat() { return (float) value; } public void setValDouble(double in) { this.value = in; } public void setValue(double value) { value = Math.round(value / inc) * inc; this.value = clamp(value, min, max); } public static double clamp(double num, double min, double max) { return Math.max(min, Math.min(max, num)); } public void reset() { setValue(defaultvalue); } public double getMin() { return min; } public void setMin(double min) { this.min = min; } public double getMax() { return max; } public void setMax(double max) { this.max = max; } public double getInc() { return inc; } public static float clamp(float num, float min, float max) { return num < min ? min : num > max ? max : num; } public int getValueInt() { return (int) value; } public void inc(boolean isPositive) { if (isPositive) setValue(getValue() + getInc()); else setValue(getValue() - getInc()); } }
Java:public class BooleanSetting extends Setting { public boolean value; public BooleanSetting(String name, boolean defaultVal) { super(name); this.value = defaultVal; } public void toggle() { this.value = !this.value; } public boolean isEnabled() { return value; } public void setEnabled() { this.value = value; } public boolean getValue() { return this.value; } }
Сеттинги в гуи добавите сами, мне впадлу слишком <3Java:public class ModeSetting extends Setting { private List<String> modes; private int index; public String mode; public Animation animation; public String previousMode; private int previousIndex; public List<String> getModes() { return modes; } public void setModes(List<String> modes) { this.modes = modes; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; this.mode = modes.get(index); } public String getMode() { return mode; } public ModeSetting(String name, String... modes) { super(name); this.modes = Arrays.asList(modes); this.mode = this.modes.get(0); this.index = 0; this.animation = new Animation(1, 1, 0.1f); this.previousMode = null; this.previousIndex = 0; } public void cycle() { this.previousMode = this.mode; this.previousIndex = this.index; if (index < modes.size() - 1) { index++; } else { index = 0; } this.mode = modes.get(index); this.animation.setAnim(0); } public void setMode(String mode) { if (!this.mode.equals(mode)) { this.previousMode = this.mode; this.previousIndex = this.index; this.mode = mode; this.index = modes.indexOf(mode); this.animation.setAnim(0); } } public int getPreviousIndex() { return previousIndex; } public boolean isMode(String mode) { return Objects.equals(this.mode, mode); } public String getValue() { return this.mode; } }
Пример использованию наших сеттингов
Так-же для возможности открыть нашу гуи создаем классJava:public class TestModule() { BooleanSetting booleanSetting = new BooleanSetting("Bool Setting", true); public TestModule() { super("module", ModuleCategory.Visuals, "test"); addSettings(booleanSetting); } @SubscribeEvent public void onTick(TickEvent event) { if (booleanSetting.isEnabled()) { /* ... */ } } }
И регистрируем его в ModuleManager'eJava:public class ClickGUI extends Module { public ClickGUI() { super("gui", ModuleCategory.Visuals, "yougame gui", GLFW.GLFW_KEY_RIGHT_SHIFT); } @Override public void onEnable() { mc.setScreen(new ClickUi()); } }
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!
Нужно ли вообще делать тутор на хуки/миксины?
по сути если ты все свое сделаешь то это уже не будет пастой прикиньЕсть ли смысл таким образом делать "свою" базу? Это те же пасты, только заморочек больше
Прикинь, база одна и та же будет, все равно паста. Или если я возьму базу рича? То я не пастер?по сути если ты все свое сделаешь то это уже не будет пастой прикинь
Если ты возьмешь базу рича это значит, что ты пастер ведь ты крадешь чужой кодПрикинь, база одна и та же будет, все равно паста. Или если я возьму базу рича? То я не пастер?
поэтому надо брать Fabric, ведь Fabric one love <3Если ты возьмешь базу рича это значит, что ты пастер ведь ты крадешь чужой код
Yeeees, Fabric one love, Fabric big love <3поэтому надо брать Fabric, ведь Fabric one love <3
Проект предоставляет различный материал, относящийся к сфере киберспорта, программирования, ПО для игр, а также позволяет его участникам общаться на многие другие темы. Почта для жалоб: admin@yougame.biz