Гайд Своя $$$база Forge 1.16.5

Forge Api ;-;
Забаненный
Статус
Оффлайн
Регистрация
3 Май 2023
Сообщения
877
Реакции[?]
18
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Забаненный
Статус
Оффлайн
Регистрация
25 Сен 2024
Сообщения
1
Реакции[?]
0
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Plugin "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.че делать я просто новичек
 
Начинающий
Статус
Оффлайн
Регистрация
26 Дек 2023
Сообщения
791
Реакции[?]
10
Поинты[?]
4K
Начинающий
Статус
Оффлайн
Регистрация
27 Окт 2024
Сообщения
61
Реакции[?]
0
Поинты[?]
0
Для начала устанавливаем плагин 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();
        }
    }
}
Уже сейчас мы можем для примера написать какую нибудь простенькую функцию

Java:
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();
    }
}
Не забываем зарегистрировать функцию с помощью ModuleManager'a

Чисто для нашего удобства создадит класс ClientUtil
Java:
public class ClientUtil {
    public static Minecraft mc = Minecraft.getInstance();
    public static MainWindow mw = mc.getWindow();
 
    // добавляем сюда все, что используем часто
}
Пришло время создать максимально простенькое нечто, напоминающее клик гуи

Java:
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);
        }
    }
}
На выходе получаем микро вариант cs gui
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)

Но мы же блатные, поэтому надо сделать сеттинги

Создаем класс Setting

Java:
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;}
}
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSetting
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;
    }
}
Java:
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;
    }
}
Сеттинги в гуи добавите сами, мне впадлу слишком <3

Пример использованию наших сеттингов


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()) {
            /* ... */
        }
    }
}
Так-же для возможности открыть нашу гуи создаем класс

Java:
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());
    }
}
И регистрируем его в ModuleManager'e
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!

Нужно ли вообще делать тутор на хуки/миксины?
дайте готовые сурсы
 
Начинающий
Статус
Оффлайн
Регистрация
23 Апр 2024
Сообщения
450
Реакции[?]
1
Поинты[?]
2K
Начинающий
Статус
Оффлайн
Регистрация
2 Окт 2024
Сообщения
172
Реакции[?]
1
Поинты[?]
0
Для начала устанавливаем плагин 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();
        }
    }
}
Уже сейчас мы можем для примера написать какую нибудь простенькую функцию

Java:
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();
    }
}
Не забываем зарегистрировать функцию с помощью ModuleManager'a

Чисто для нашего удобства создадит класс ClientUtil
Java:
public class ClientUtil {
    public static Minecraft mc = Minecraft.getInstance();
    public static MainWindow mw = mc.getWindow();
  
    // добавляем сюда все, что используем часто
}
Пришло время создать максимально простенькое нечто, напоминающее клик гуи

Java:
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);
        }
    }
}
На выходе получаем микро вариант cs gui
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)

Но мы же блатные, поэтому надо сделать сеттинги

Создаем класс Setting

Java:
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;}
}
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSetting
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;
    }
}
Java:
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;
    }
}
Сеттинги в гуи добавите сами, мне впадлу слишком <3

Пример использованию наших сеттингов


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()) {
            /* ... */
        }
    }
}
Так-же для возможности открыть нашу гуи создаем класс

Java:
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());
    }
}
И регистрируем его в ModuleManager'e
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!

Нужно ли вообще делать тутор на хуки/миксины?
MCP ЛУЧШЕ!!!
 
Начинающий
Статус
Оффлайн
Регистрация
4 Июл 2021
Сообщения
232
Реакции[?]
1
Поинты[?]
2K
Для начала устанавливаем плагин 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();
        }
    }
}
Уже сейчас мы можем для примера написать какую нибудь простенькую функцию

Java:
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();
    }
}
Не забываем зарегистрировать функцию с помощью ModuleManager'a

Чисто для нашего удобства создадит класс ClientUtil
Java:
public class ClientUtil {
    public static Minecraft mc = Minecraft.getInstance();
    public static MainWindow mw = mc.getWindow();
 
    // добавляем сюда все, что используем часто
}
Пришло время создать максимально простенькое нечто, напоминающее клик гуи

Java:
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);
        }
    }
}
На выходе получаем микро вариант cs gui
Посмотреть вложение 289608
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)

Но мы же блатные, поэтому надо сделать сеттинги

Создаем класс Setting

Java:
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;}
}
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSetting
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;
    }
}
Java:
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;
    }
}
Сеттинги в гуи добавите сами, мне впадлу слишком <3

Пример использованию наших сеттингов


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()) {
            /* ... */
        }
    }
}
Так-же для возможности открыть нашу гуи создаем класс

Java:
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());
    }
}
И регистрируем его в ModuleManager'e
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!

Нужно ли вообще делать тутор на хуки/миксины?
1734446924410.png чо делать
 
Forge Api ;-;
Забаненный
Статус
Оффлайн
Регистрация
3 Май 2023
Сообщения
877
Реакции[?]
18
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сверху Снизу