Forge Api ;-;
-
Автор темы
- #1
Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:
- бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
- маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
- приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
- обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.
Спасибо!
Для начала устанавливаем плагин Minecraft Development
Далее создаем новый проект
Заходим в главный класс мода и оставляем для себя только
Далее мы берём ноги в зубы и идем плотно пастить утилки с гитхаба (
После успешного пастинга едем реализовывать наши функции.
Создаем класс Module и ModuleCategory
Так-же нам нужно создать менеджер для наших будущих функций
В ините нашего мейн класса вызываем
Так-же добавляем в наш главный класс обработку нажатий на кнопки биндов
Уже сейчас мы можем для примера написать какую нибудь простенькую функцию
Не забываем зарегистрировать функцию с помощью ModuleManager'a
Чисто для нашего удобства создадит класс ClientUtil
Пришло время создать максимально простенькое нечто, напоминающее клик гуи
На выходе получаем микро вариант cs gui
Визуально ее изменить думаю осилит каждый (если конечно iq чуть выше 15)
Но мы же блатные, поэтому надо сделать сеттинги
Создаем класс Setting
Далее к нему уже создаем классы FloatSetting, BooleanSetting, ModeSetting
Сеттинги в гуи добавите сами, мне впадлу слишком <3
Пример использованию наших сеттингов
Так-же для возможности открыть нашу гуи создаем класс
И регистрируем его в ModuleManager'e
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!
Нужно ли вообще делать тутор на хуки/миксины?
Далее создаем новый проект
Заходим в главный класс мода и оставляем для себя только
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();
}
}
Чисто для нашего удобства создадит класс 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);
}
}
}
Визуально ее изменить думаю осилит каждый (если конечно 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;}
}
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;
}
}
Пример использованию наших сеттингов
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());
}
}
По итогу мы имеем достаточно простенькую, но какую никакую собственную базу.
Спасибо за уделенное время!
Нужно ли вообще делать тутор на хуки/миксины?
Последнее редактирование: