1.0.6 update
removed owo lib fixed some bugs
This commit is contained in:
parent
1ad16e6343
commit
e593859723
15
build.gradle
15
build.gradle
@ -17,6 +17,13 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||
|
||||
//add joml
|
||||
modImplementation 'org.joml:joml:1.10.4'
|
||||
include 'org.joml:joml:1.10.4'
|
||||
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
@ -30,13 +37,13 @@ dependencies {
|
||||
|
||||
// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
|
||||
|
||||
modImplementation "io.wispforest:owo-lib:${project.owo_version}"
|
||||
// only if you plan to use owo-config
|
||||
annotationProcessor "io.wispforest:owo-lib:${project.owo_version}"
|
||||
// modImplementation "io.wispforest:owo-lib:${project.owo_version}"
|
||||
// // only if you plan to use owo-config
|
||||
// annotationProcessor "io.wispforest:owo-lib:${project.owo_version}"
|
||||
|
||||
// include this if you don't want force your users to install owo
|
||||
// sentinel will warn them and give the option to download it automatically
|
||||
include "io.wispforest:owo-sentinel:${project.owo_version}"
|
||||
// include "io.wispforest:owo-sentinel:${project.owo_version}"
|
||||
}
|
||||
|
||||
base {
|
||||
|
@ -4,16 +4,16 @@ org.gradle.parallel=true
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/develop
|
||||
minecraft_version=1.19.3
|
||||
yarn_mappings=1.19.3+build.1
|
||||
loader_version=0.14.17
|
||||
minecraft_version=1.20
|
||||
yarn_mappings=1.20+build.1
|
||||
loader_version=0.14.23
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.5
|
||||
mod_version = 1.0.6
|
||||
maven_group = themixray.repeating.mod
|
||||
archives_base_name = repeating-mod
|
||||
|
||||
# Dependencies
|
||||
fabric_version=0.76.1+1.19.3
|
||||
fabric_version=0.83.0+1.20
|
||||
|
||||
owo_version=0.10.3+1.19.3
|
||||
#owo_version=0.11.1+1.20
|
||||
|
@ -71,10 +71,10 @@ public class EasyConfig {
|
||||
}
|
||||
|
||||
private String toText(Map<String,String> p) {
|
||||
String t = "";
|
||||
StringBuilder t = new StringBuilder();
|
||||
for (Map.Entry<String,String> e:p.entrySet())
|
||||
t += e.getKey() + "=" + e.getValue() + "\n";
|
||||
return t;
|
||||
t.append(e.getKey()).append("=").append(e.getValue()).append("\n");
|
||||
return t.toString();
|
||||
}
|
||||
private Map<String,String> toMap(String j) {
|
||||
Map<String,String> m = new HashMap<>();
|
||||
|
@ -4,22 +4,39 @@ import com.google.common.collect.Lists;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.DimensionRenderingRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.entity.MovementType;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TextColor;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import themixray.repeating.mod.render.RenderHelper;
|
||||
import themixray.repeating.mod.render.RenderSystem;
|
||||
import themixray.repeating.mod.render.buffer.WorldBuffer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class RepeatingMod implements ClientModInitializer {
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("repeating-mod");
|
||||
@ -27,6 +44,9 @@ public class RepeatingMod implements ClientModInitializer {
|
||||
public static final FabricLoader loader = FabricLoader.getInstance();
|
||||
public static RepeatingMod me;
|
||||
|
||||
public Vec3d start_record_pos = null;
|
||||
public Vec3d finish_record_pos = null;
|
||||
|
||||
public List<RecordEvent> record = new ArrayList<>();
|
||||
public boolean is_recording = false;
|
||||
public long last_record = -1;
|
||||
@ -46,6 +66,8 @@ public class RepeatingMod implements ClientModInitializer {
|
||||
|
||||
public long record_pos_delay = 20;
|
||||
|
||||
public static Random rand = new Random();
|
||||
|
||||
public EasyConfig conf;
|
||||
|
||||
@Override
|
||||
@ -53,6 +75,50 @@ public class RepeatingMod implements ClientModInitializer {
|
||||
LOGGER.info("Repeating mod initialized");
|
||||
me = this;
|
||||
|
||||
RenderSystem.init();
|
||||
WorldRenderEvents.LAST.register(context -> {
|
||||
WorldBuffer buffer = RenderHelper.startTri(context);
|
||||
if (start_record_pos != null) {
|
||||
RenderHelper.drawRectFromTri(buffer,
|
||||
(float) start_record_pos.getX() - 0.25F,
|
||||
(float) start_record_pos.getY() + 0.01F,
|
||||
(float) start_record_pos.getZ() - 0.25F,
|
||||
|
||||
(float) start_record_pos.getX() + 0.25F,
|
||||
(float) start_record_pos.getY() + 0.01F,
|
||||
(float) start_record_pos.getZ() - 0.25F,
|
||||
|
||||
(float) start_record_pos.getX() + 0.25F,
|
||||
(float) start_record_pos.getY() + 0.01F,
|
||||
(float) start_record_pos.getZ() + 0.25F,
|
||||
|
||||
(float) start_record_pos.getX() - 0.25F,
|
||||
(float) start_record_pos.getY() + 0.01F,
|
||||
(float) start_record_pos.getZ() + 0.25F,
|
||||
new Color(70,230,70,128));
|
||||
}
|
||||
if (finish_record_pos != null) {
|
||||
RenderHelper.drawRectFromTri(buffer,
|
||||
(float) finish_record_pos.getX() - 0.25F,
|
||||
(float) finish_record_pos.getY() + 0.01F,
|
||||
(float) finish_record_pos.getZ() - 0.25F,
|
||||
|
||||
(float) finish_record_pos.getX() + 0.25F,
|
||||
(float) finish_record_pos.getY() + 0.01F,
|
||||
(float) finish_record_pos.getZ() - 0.25F,
|
||||
|
||||
(float) finish_record_pos.getX() + 0.25F,
|
||||
(float) finish_record_pos.getY() + 0.01F,
|
||||
(float) finish_record_pos.getZ() + 0.25F,
|
||||
|
||||
(float) finish_record_pos.getX() - 0.25F,
|
||||
(float) finish_record_pos.getY() + 0.01F,
|
||||
(float) finish_record_pos.getZ() + 0.25F,
|
||||
new Color(230,70,70,128));
|
||||
}
|
||||
RenderHelper.endTri(buffer);
|
||||
});
|
||||
|
||||
Map<String,String> def = new HashMap<>();
|
||||
def.put("record_pos_delay", String.valueOf(record_pos_delay));
|
||||
|
||||
@ -109,14 +175,15 @@ public class RepeatingMod implements ClientModInitializer {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void startRecording() {
|
||||
is_recording = true;
|
||||
menu.update_btns();
|
||||
record.clear();
|
||||
|
||||
record.add(new RecordMoveEvent(client.player.getPos(),
|
||||
client.player.getHeadYaw(), client.player.getPitch()));
|
||||
finish_record_pos = null;
|
||||
Vec3d v = client.player.getPos();
|
||||
record.add(new RecordMoveEvent(v,client.player.getHeadYaw(),client.player.getPitch()));
|
||||
start_record_pos = v;
|
||||
|
||||
if (record_pos_delay > 0) {
|
||||
move_tick = new TickTask(
|
||||
@ -226,6 +293,7 @@ public class RepeatingMod implements ClientModInitializer {
|
||||
|
||||
public void stopRecording() {
|
||||
is_recording = false;
|
||||
finish_record_pos = client.player.getPos();
|
||||
if (move_tick != null) {
|
||||
move_tick.cancel();
|
||||
move_tick = null;
|
||||
@ -285,10 +353,11 @@ public class RepeatingMod implements ClientModInitializer {
|
||||
return (double) Math.round(value * factor) / factor;
|
||||
}
|
||||
|
||||
public static void sendMessage(Text text) {
|
||||
public static void sendMessage(MutableText text) {
|
||||
client.player.sendMessage(Text.literal("[")
|
||||
.append(Text.translatable("text.repeating-mod.name"))
|
||||
.append("] ").append(text));
|
||||
.append(Text.translatable("text.repeating-mod.name"))
|
||||
.append("] ").formatted(Formatting.BOLD,Formatting.DARK_GRAY)
|
||||
.append(text.formatted(Formatting.RESET).formatted(Formatting.GRAY)));
|
||||
}
|
||||
|
||||
public static void sendDebug(String s) {
|
||||
|
@ -1,192 +1,371 @@
|
||||
package themixray.repeating.mod;
|
||||
|
||||
import io.wispforest.owo.ui.base.*;
|
||||
import io.wispforest.owo.ui.component.*;
|
||||
import io.wispforest.owo.ui.container.*;
|
||||
import io.wispforest.owo.ui.container.FlowLayout;
|
||||
import io.wispforest.owo.ui.core.*;
|
||||
import io.wispforest.owo.ui.core.Insets;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.tooltip.Tooltip;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.OptionSliderWidget;
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class RepeatingScreen extends BaseOwoScreen<FlowLayout> {
|
||||
public RepeatingMod mod;
|
||||
public ButtonComponent replay_btn;
|
||||
public ButtonComponent record_btn;
|
||||
public ButtonComponent loop_btn;
|
||||
public boolean was_build = false;
|
||||
|
||||
public RepeatingScreen() {
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class RepeatingScreen extends Screen {
|
||||
protected RepeatingScreen() {
|
||||
super(Text.literal(""));
|
||||
this.mod = RepeatingMod.me;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull OwoUIAdapter<FlowLayout> createAdapter() {
|
||||
return OwoUIAdapter.create(this, Containers::horizontalFlow);
|
||||
}
|
||||
public RepeatingMod mod;
|
||||
|
||||
public ButtonWidget record_btn;
|
||||
public ButtonWidget replay_btn;
|
||||
public ButtonWidget loop_btn;
|
||||
|
||||
public ButtonWidget export_btn;
|
||||
public ButtonWidget import_btn;
|
||||
|
||||
public SliderWidget pos_delay_slider;
|
||||
|
||||
public boolean was_build = false;
|
||||
|
||||
public void update_btns() {
|
||||
if (was_build) {
|
||||
replay_btn.setMessage(Text.translatable("text.repeating-mod." +
|
||||
((mod.is_replaying) ? "stop" : "start")).append(" ")
|
||||
.append(Text.translatable("text.repeating-mod.replay")));
|
||||
((mod.is_replaying) ? "stop_replay" : "start_replay")));
|
||||
record_btn.setMessage(Text.translatable("text.repeating-mod." +
|
||||
((mod.is_recording) ? "stop" : "start")).append(" ")
|
||||
.append(Text.translatable("text.repeating-mod.record")));
|
||||
((mod.is_recording) ? "stop_record" : "start_record")));
|
||||
loop_btn.setMessage(Text.of(((mod.loop_replay) ? "\uefff " : "\ueffe ")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void build(FlowLayout rootComponent) {
|
||||
rootComponent
|
||||
.surface(Surface.VANILLA_TRANSLUCENT)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.verticalAlignment(VerticalAlignment.CENTER);
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
renderBackground(context);
|
||||
// context.drawCenteredTextWithShadow(textRenderer,
|
||||
// Text.literal("You must see me"),
|
||||
// width / 2, height / 2,
|
||||
// Color.white.getRGB());
|
||||
super.render(context, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
replay_btn = (ButtonComponent) Components.button(Text.of("replay"),
|
||||
(ButtonComponent btn) -> {
|
||||
if (!mod.is_recording) {
|
||||
if (mod.is_replaying)
|
||||
mod.stopReplay();
|
||||
else mod.startReplay();
|
||||
update_btns();
|
||||
}
|
||||
}).margins(Insets.of(1)).sizing(
|
||||
Sizing.fixed(98),Sizing.fixed(20));
|
||||
|
||||
loop_btn = (ButtonComponent) Components.button(Text.of(""),
|
||||
(ButtonComponent btn) -> {
|
||||
mod.loop_replay = !mod.loop_replay;
|
||||
update_btns();
|
||||
}).margins(Insets.of(1))
|
||||
.sizing(Sizing.fixed(20),Sizing.fixed(20));
|
||||
|
||||
record_btn = (ButtonComponent) Components.button(Text.of("record"),
|
||||
(ButtonComponent btn) -> {
|
||||
@Override
|
||||
protected void init() {
|
||||
record_btn = ButtonWidget.builder(
|
||||
Text.translatable("text.repeating-mod.start_record"), button -> {
|
||||
if (!mod.is_replaying) {
|
||||
if (mod.is_recording)
|
||||
mod.stopRecording();
|
||||
else mod.startRecording();
|
||||
update_btns();
|
||||
}
|
||||
}).margins(Insets.of(1)).sizing(
|
||||
Sizing.fixed(120),Sizing.fixed(20));
|
||||
})
|
||||
.dimensions(width / 2 - 60, height / 2 - 54, 120, 20)
|
||||
.tooltip(Tooltip.of(Text.translatable("text.repeating-mod.record_tooltip")))
|
||||
.build();
|
||||
|
||||
replay_btn = ButtonWidget.builder(
|
||||
Text.translatable("text.repeating-mod.start_replay"), button -> {
|
||||
if (!mod.is_recording) {
|
||||
if (mod.is_replaying)
|
||||
mod.stopReplay();
|
||||
else mod.startReplay();
|
||||
update_btns();
|
||||
}
|
||||
})
|
||||
.dimensions(width / 2 - 60, height / 2 - 32, 98, 20)
|
||||
.tooltip(Tooltip.of(Text.translatable("text.repeating-mod.replay_tooltip")))
|
||||
.build();
|
||||
|
||||
loop_btn = ButtonWidget.builder(Text.of(""), button -> {
|
||||
mod.loop_replay = !mod.loop_replay;
|
||||
update_btns();
|
||||
})
|
||||
.dimensions(width / 2 + 40, height / 2 - 32, 20, 20)
|
||||
.tooltip(Tooltip.of(Text.translatable("text.repeating-mod.loop_tooltip")))
|
||||
.build();
|
||||
|
||||
export_btn = ButtonWidget.builder(
|
||||
Text.translatable("text.repeating-mod.export"), button -> {
|
||||
if (mod.finish_record_pos == null) return;
|
||||
StringBuilder t = new StringBuilder();
|
||||
for (int i = 0; i < mod.record.size(); i++) {
|
||||
t.append(mod.record.get(i).toText());
|
||||
t.append("\n");
|
||||
}
|
||||
t.append(mod.start_record_pos.getX()+"n"+
|
||||
mod.start_record_pos.getY()+"n"+
|
||||
mod.start_record_pos.getZ()+"x"+
|
||||
mod.finish_record_pos.getX()+"n"+
|
||||
mod.finish_record_pos.getY()+"n"+
|
||||
mod.finish_record_pos.getZ());
|
||||
|
||||
File p = new File(FabricLoader.getInstance().getGameDir().toFile(),"repeating");
|
||||
if (!p.exists()) p.mkdir();
|
||||
File file = new File(p,"export_"+
|
||||
new SimpleDateFormat("MM_dd_yyyy").format(new Date())
|
||||
+"_"+RepeatingMod.rand.nextInt(10)+".txt");
|
||||
try {
|
||||
if (!file.exists()) file.createNewFile();
|
||||
Files.write(file.toPath(), t.toString().getBytes());
|
||||
Runtime.getRuntime().exec("explorer /select,\""+file.getAbsolutePath()+"\"");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
})
|
||||
.dimensions(width / 2 - 60, height / 2 - 10, 120, 20)
|
||||
.tooltip(Tooltip.of(Text.translatable("text.repeating-mod.export_tooltip")))
|
||||
.build();
|
||||
|
||||
import_btn = ButtonWidget.builder(
|
||||
Text.translatable("text.repeating-mod.import"), button -> {
|
||||
mod.record.clear();
|
||||
|
||||
File p = new File(FabricLoader.getInstance().getGameDir().toFile(),"repeating");
|
||||
if (!p.exists()) p.mkdir();
|
||||
File file = new File(p,"import.txt");
|
||||
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
Runtime.getRuntime().exec("explorer /select,\""+file.getAbsolutePath()+"\"");
|
||||
return;
|
||||
}
|
||||
String t = Files.readString(file.toPath());
|
||||
List<String> ss = List.of(t.split("\n"));
|
||||
String ls = ss.get(ss.size()-1);
|
||||
ss = ss.subList(0,ss.size()-1);
|
||||
for (String s:ss)
|
||||
mod.record.add(RepeatingMod.RecordEvent.fromText(s));
|
||||
String[] lss0 = ls.split("x");
|
||||
String[] lss1 = lss0[0].split("n");
|
||||
String[] lss2 = lss0[1].split("n");
|
||||
mod.start_record_pos = new Vec3d(
|
||||
Float.parseFloat(lss1[0]),
|
||||
Float.parseFloat(lss1[1]),
|
||||
Float.parseFloat(lss1[2]));
|
||||
mod.finish_record_pos = new Vec3d(
|
||||
Float.parseFloat(lss2[0]),
|
||||
Float.parseFloat(lss2[1]),
|
||||
Float.parseFloat(lss2[2]));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
})
|
||||
.dimensions(width / 2 - 60, height / 2 + 12, 120, 20)
|
||||
.tooltip(Tooltip.of(Text.translatable("text.repeating-mod.import_tooltip")))
|
||||
.build();
|
||||
|
||||
pos_delay_slider = new SliderWidget(
|
||||
width / 2 - 60, height / 2 + 34, 120, 20,
|
||||
(mod.record_pos_delay < 0) ? Text.translatable("text.repeating-mod.nan_pos_delay") :
|
||||
Text.translatable("text.repeating-mod.pos_delay", String.valueOf(mod.record_pos_delay)),
|
||||
(mod.record_pos_delay/10d+1d)/101d) {
|
||||
|
||||
@Override
|
||||
protected void updateMessage() {
|
||||
double v = value*101d-1d;
|
||||
if (v <= 1) setMessage(Text.translatable("text.repeating-mod.nan_pos_delay"));
|
||||
else setMessage(Text.translatable("text.repeating-mod.pos_delay", String.valueOf((long) (v*10))));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyValue() {
|
||||
double v = value*101d-1d;
|
||||
if (v <= 1) setMessage(Text.translatable("text.repeating-mod.nan_pos_delay"));
|
||||
else setMessage(Text.translatable("text.repeating-mod.pos_delay", String.valueOf((long) (v*10))));
|
||||
mod.record_pos_delay = (long) (v*10);
|
||||
mod.conf.data.put("record_pos_delay",String.valueOf(mod.record_pos_delay));
|
||||
mod.conf.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease(double mouseX, double mouseY) {
|
||||
super.onRelease(mouseX, mouseY);
|
||||
applyValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) {
|
||||
super.onDrag(mouseX, mouseY, deltaX, deltaY);
|
||||
applyValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
super.render(context, mouseX, mouseY, delta);
|
||||
updateMessage();
|
||||
}
|
||||
};
|
||||
pos_delay_slider.setTooltip(Tooltip.of(Text.translatable("text.repeating-mod.pos_delay_tooltip")));
|
||||
|
||||
was_build = true;
|
||||
|
||||
rootComponent.child(
|
||||
Containers.horizontalFlow(Sizing.content(), Sizing.content()).child(
|
||||
Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Components.label(Text.translatable("text.repeating-mod.basic")).margins(Insets.of(1)))
|
||||
.padding(Insets.of(5))
|
||||
.surface(Surface.DARK_PANEL)
|
||||
.verticalAlignment(VerticalAlignment.CENTER)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.margins(Insets.of(1)))
|
||||
.child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Containers.horizontalFlow(Sizing.content(), Sizing.content())
|
||||
.child(replay_btn).child(loop_btn))
|
||||
.child(record_btn)
|
||||
.child(Components.button(Text.translatable(
|
||||
"text.repeating-mod.export"),
|
||||
(ButtonComponent btn) -> {
|
||||
String t = "";
|
||||
for (int i = 0; i < mod.record.size(); i++) {
|
||||
t += mod.record.get(i).toText();
|
||||
if (i != mod.record.size()-1)
|
||||
t += "\n";
|
||||
}
|
||||
update_btns();
|
||||
|
||||
File p = new File(FabricLoader.getInstance().getGameDir().toFile(),"repeating");
|
||||
if (!p.exists()) p.mkdir();
|
||||
File file = new File(p,"export.txt");
|
||||
addDrawableChild(replay_btn);
|
||||
addDrawableChild(loop_btn);
|
||||
addDrawableChild(record_btn);
|
||||
addDrawableChild(export_btn);
|
||||
addDrawableChild(import_btn);
|
||||
addDrawableChild(pos_delay_slider);
|
||||
|
||||
try {
|
||||
if (!file.exists()) file.createNewFile();
|
||||
Files.write(file.toPath(), t.getBytes());
|
||||
Runtime.getRuntime().exec("explorer /select,\""+file.getAbsolutePath()+"\"");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).margins(Insets.of(10,1,1,1)).sizing(
|
||||
Sizing.fixed(120),Sizing.fixed(20)))
|
||||
.child(Components.button(Text.translatable(
|
||||
"text.repeating-mod.import"),
|
||||
(ButtonComponent btn) -> {
|
||||
mod.record.clear();
|
||||
|
||||
File p = new File(FabricLoader.getInstance().getGameDir().toFile(),"repeating");
|
||||
if (!p.exists()) p.mkdir();
|
||||
File file = new File(p,"import.txt");
|
||||
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
Runtime.getRuntime().exec("explorer /select,\""+file.getAbsolutePath()+"\"");
|
||||
return;
|
||||
}
|
||||
String t = Files.readString(file.toPath());
|
||||
for (String s:t.split("\n"))
|
||||
mod.record.add(RepeatingMod.RecordEvent.fromText(s));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).margins(Insets.of(1)).sizing(
|
||||
Sizing.fixed(120),Sizing.fixed(20)))
|
||||
.padding(Insets.of(10))
|
||||
.surface(Surface.DARK_PANEL)
|
||||
.verticalAlignment(VerticalAlignment.CENTER)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.margins(Insets.of(1)))
|
||||
/*).child(
|
||||
Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Components.label(Text.translatable("text.repeating-mod.parkour")).margins(Insets.of(1)))
|
||||
.padding(Insets.of(5))
|
||||
.surface(Surface.DARK_PANEL)
|
||||
.verticalAlignment(VerticalAlignment.CENTER)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.margins(Insets.of(1)))
|
||||
.child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Components.label(Text.translatable("text.repeating-mod.dev")).margins(Insets.of(1)))
|
||||
.padding(Insets.of(10))
|
||||
.surface(Surface.DARK_PANEL)
|
||||
.verticalAlignment(VerticalAlignment.CENTER)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.margins(Insets.of(1)))*/
|
||||
).child(
|
||||
Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Components.label(Text.translatable("text.repeating-mod.settings")).margins(Insets.of(1)))
|
||||
.padding(Insets.of(5))
|
||||
.surface(Surface.DARK_PANEL)
|
||||
.verticalAlignment(VerticalAlignment.CENTER)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.margins(Insets.of(1)))
|
||||
.child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
.child(Components.discreteSlider(Sizing.fixed(120),-20,100)
|
||||
.setFromDiscreteValue(mod.record_pos_delay)
|
||||
.message((String s)->{
|
||||
mod.record_pos_delay = Long.parseLong(s);
|
||||
mod.conf.data.put("record_pos_delay",String.valueOf(mod.record_pos_delay));
|
||||
mod.conf.save();
|
||||
if (mod.record_pos_delay > -1)
|
||||
return Text.translatable("text.repeating-mod.pos_delay", s);
|
||||
return Text.translatable("text.repeating-mod.nan_pos_delay");
|
||||
}).scrollStep(25)
|
||||
.margins(Insets.of(1))
|
||||
.tooltip(Text.translatable("text.repeating-mod.pos_delay_text")))
|
||||
.padding(Insets.of(10))
|
||||
.surface(Surface.DARK_PANEL)
|
||||
.verticalAlignment(VerticalAlignment.CENTER)
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.margins(Insets.of(1)))
|
||||
));
|
||||
// rootComponent
|
||||
// .surface(Surface.VANILLA_TRANSLUCENT)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER);
|
||||
//
|
||||
// replay_btn = (ButtonComponent) Components.button(Text.of("replay"),
|
||||
// (ButtonComponent btn) -> {
|
||||
// if (!mod.is_recording) {
|
||||
// if (mod.is_replaying)
|
||||
// mod.stopReplay();
|
||||
// else mod.startReplay();
|
||||
// update_btns();
|
||||
// }
|
||||
// }).margins(Insets.of(1)).sizing(
|
||||
// Sizing.fixed(98),Sizing.fixed(20));
|
||||
//
|
||||
// loop_btn = (ButtonComponent) Components.button(Text.of(""),
|
||||
// (ButtonComponent btn) -> {
|
||||
// mod.loop_replay = !mod.loop_replay;
|
||||
// update_btns();
|
||||
// }).margins(Insets.of(1))
|
||||
// .sizing(Sizing.fixed(20),Sizing.fixed(20));
|
||||
//
|
||||
// record_btn = (ButtonComponent) Components.button(Text.of("record"),
|
||||
// (ButtonComponent btn) -> {
|
||||
// if (!mod.is_replaying) {
|
||||
// if (mod.is_recording)
|
||||
// mod.stopRecording();
|
||||
// else mod.startRecording();
|
||||
// update_btns();
|
||||
// }
|
||||
// }).margins(Insets.of(1)).sizing(
|
||||
// Sizing.fixed(120),Sizing.fixed(20));
|
||||
// was_build = true;
|
||||
//
|
||||
// rootComponent.child(
|
||||
// Containers.horizontalFlow(Sizing.content(), Sizing.content()).child(
|
||||
// Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Components.label(Text.translatable("text.repeating-mod.basic")).margins(Insets.of(1)))
|
||||
// .padding(Insets.of(5))
|
||||
// .surface(Surface.DARK_PANEL)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .margins(Insets.of(1)))
|
||||
// .child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Containers.horizontalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(replay_btn).child(loop_btn))
|
||||
// .child(record_btn)
|
||||
// .child(Components.button(Text.translatable(
|
||||
// "text.repeating-mod.export"),
|
||||
// (ButtonComponent btn) -> {
|
||||
// String t = "";
|
||||
// for (int i = 0; i < mod.record.size(); i++) {
|
||||
// t += mod.record.get(i).toText();
|
||||
// if (i != mod.record.size()-1)
|
||||
// t += "\n";
|
||||
// }
|
||||
//
|
||||
// File p = new File(FabricLoader.getInstance().getGameDir().toFile(),"repeating");
|
||||
// if (!p.exists()) p.mkdir();
|
||||
// File file = new File(p,"export.txt");
|
||||
//
|
||||
// try {
|
||||
// if (!file.exists()) file.createNewFile();
|
||||
// Files.write(file.toPath(), t.getBytes());
|
||||
// Runtime.getRuntime().exec("explorer /select,\""+file.getAbsolutePath()+"\"");
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }).margins(Insets.of(10,1,1,1)).sizing(
|
||||
// Sizing.fixed(120),Sizing.fixed(20)))
|
||||
// .child(Components.button(Text.translatable(
|
||||
// "text.repeating-mod.import"),
|
||||
// (ButtonComponent btn) -> {
|
||||
// mod.record.clear();
|
||||
//
|
||||
// File p = new File(FabricLoader.getInstance().getGameDir().toFile(),"repeating");
|
||||
// if (!p.exists()) p.mkdir();
|
||||
// File file = new File(p,"import.txt");
|
||||
//
|
||||
// try {
|
||||
// if (!file.exists()) {
|
||||
// file.createNewFile();
|
||||
// Runtime.getRuntime().exec("explorer /select,\""+file.getAbsolutePath()+"\"");
|
||||
// return;
|
||||
// }
|
||||
// String t = Files.readString(file.toPath());
|
||||
// for (String s:t.split("\n"))
|
||||
// mod.record.add(RepeatingMod.RecordEvent.fromText(s));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }).margins(Insets.of(1)).sizing(
|
||||
// Sizing.fixed(120),Sizing.fixed(20)))
|
||||
// .padding(Insets.of(10))
|
||||
// .surface(Surface.DARK_PANEL)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .margins(Insets.of(1)))
|
||||
// /*).child(
|
||||
// Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Components.label(Text.translatable("text.repeating-mod.parkour")).margins(Insets.of(1)))
|
||||
// .padding(Insets.of(5))
|
||||
// .surface(Surface.DARK_PANEL)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .margins(Insets.of(1)))
|
||||
// .child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Components.label(Text.translatable("text.repeating-mod.dev")).margins(Insets.of(1)))
|
||||
// .padding(Insets.of(10))
|
||||
// .surface(Surface.DARK_PANEL)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .margins(Insets.of(1)))*/
|
||||
// ).child(
|
||||
// Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Components.label(Text.translatable("text.repeating-mod.settings")).margins(Insets.of(1)))
|
||||
// .padding(Insets.of(5))
|
||||
// .surface(Surface.DARK_PANEL)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .margins(Insets.of(1)))
|
||||
// .child(Containers.verticalFlow(Sizing.content(), Sizing.content())
|
||||
// .child(Components.discreteSlider(Sizing.fixed(120),-20,100)
|
||||
// .setFromDiscreteValue(mod.record_pos_delay)
|
||||
// .message((String s)->{
|
||||
// mod.record_pos_delay = Long.parseLong(s);
|
||||
// mod.conf.data.put("record_pos_delay",String.valueOf(mod.record_pos_delay));
|
||||
// mod.conf.save();
|
||||
// if (mod.record_pos_delay > -1)
|
||||
// return Text.translatable("text.repeating-mod.pos_delay", s);
|
||||
// return Text.translatable("text.repeating-mod.nan_pos_delay");
|
||||
// }).scrollStep(25)
|
||||
// .margins(Insets.of(1))
|
||||
// .tooltip(Text.translatable("text.repeating-mod.pos_delay_text")))
|
||||
// .padding(Insets.of(10))
|
||||
// .surface(Surface.DARK_PANEL)
|
||||
// .verticalAlignment(VerticalAlignment.CENTER)
|
||||
// .horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
// .margins(Insets.of(1)))
|
||||
// ));
|
||||
update_btns();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,6 @@
|
||||
package themixray.repeating.mod.mixin;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package themixray.repeating.mod.mixin;
|
||||
|
||||
import net.minecraft.client.input.KeyboardInput;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.*;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
200
src/main/java/themixray/repeating/mod/render/RenderHelper.java
Normal file
200
src/main/java/themixray/repeating/mod/render/RenderHelper.java
Normal file
@ -0,0 +1,200 @@
|
||||
package themixray.repeating.mod.render;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import themixray.repeating.mod.render.buffer.WorldBuffer;
|
||||
import themixray.repeating.mod.render.shader.ShaderManager;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static org.lwjgl.opengl.GL33.*;
|
||||
|
||||
@UtilityClass
|
||||
public class RenderHelper {
|
||||
public WorldBuffer startLines(WorldRenderContext context) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
return new WorldBuffer(GL_LINES, ShaderManager.getPositionColorShader(), context);
|
||||
}
|
||||
|
||||
public void endLines(WorldBuffer buffer) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(false);
|
||||
buffer.draw();
|
||||
glDepthMask(true);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
public void drawLine(WorldBuffer buffer, float x1, float y1, float z1, float x2, float y2, float z2, Color color) {
|
||||
buffer.vert(x1, y1, z1, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
|
||||
buffer.vert(x2, y2, z2, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
|
||||
}
|
||||
|
||||
public WorldBuffer startTri(WorldRenderContext context) {
|
||||
return new WorldBuffer(GL_TRIANGLES, ShaderManager.getPositionColorShader(), context);
|
||||
}
|
||||
|
||||
public void endTri(WorldBuffer buffer) {
|
||||
//glDepthRange(0, 0.7);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDepthMask(false);
|
||||
buffer.draw();
|
||||
glDepthMask(true);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glDepthRange(0, 1);
|
||||
}
|
||||
|
||||
public void drawTri(WorldBuffer buffer, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, Color color) {
|
||||
buffer.vert(x1, y1, z1, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
|
||||
buffer.vert(x2, y2, z2, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
|
||||
buffer.vert(x3, y3, z3, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f);
|
||||
}
|
||||
|
||||
public void drawRectFromTri(WorldBuffer buffer,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4,
|
||||
Color color) {
|
||||
drawTri(buffer,
|
||||
x1, y1, z1,
|
||||
x2, y2, z2,
|
||||
x3, y3, z3,
|
||||
color);
|
||||
drawTri(buffer,
|
||||
x3, y3, z3,
|
||||
x4, y4, z4,
|
||||
x1, y1, z1,
|
||||
color);
|
||||
}
|
||||
|
||||
public void drawRectFromLines(WorldBuffer buffer,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4,
|
||||
Color color) {
|
||||
drawLine(buffer,
|
||||
x1, y1, z1,
|
||||
x2, y2, z2,
|
||||
color);
|
||||
drawLine(buffer,
|
||||
x2, y2, z2,
|
||||
x3, y3, z3,
|
||||
color);
|
||||
drawLine(buffer,
|
||||
x3, y3, z3,
|
||||
x4, y4, z4,
|
||||
color);
|
||||
drawLine(buffer,
|
||||
x4, y4, z4,
|
||||
x1, y1, z1,
|
||||
color);
|
||||
}
|
||||
|
||||
public void drawBoxFromTri(WorldBuffer buffer,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2,
|
||||
Color color) {
|
||||
float[][] v = new float[][]{
|
||||
new float[]{Math.min(x1, x2), Math.min(y1, y2), Math.min(z1, z2)},
|
||||
new float[]{Math.max(x1, x2), Math.max(y1, y2), Math.max(z1, z2)}};
|
||||
|
||||
drawRectFromTri(buffer,
|
||||
v[0][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[0][2],
|
||||
v[1][0], v[1][1], v[0][2],
|
||||
v[0][0], v[1][1], v[0][2],
|
||||
color);
|
||||
|
||||
drawRectFromTri(buffer,
|
||||
v[0][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[1][2],
|
||||
v[0][0], v[0][1], v[1][2],
|
||||
color);
|
||||
|
||||
drawRectFromTri(buffer,
|
||||
v[0][0], v[0][1], v[0][2],
|
||||
v[0][0], v[0][1], v[1][2],
|
||||
v[0][0], v[1][1], v[1][2],
|
||||
v[0][0], v[1][1], v[0][2],
|
||||
color);
|
||||
|
||||
drawRectFromTri(buffer,
|
||||
v[0][0], v[0][1], v[1][2],
|
||||
v[1][0], v[0][1], v[1][2],
|
||||
v[1][0], v[1][1], v[1][2],
|
||||
v[0][0], v[1][1], v[1][2],
|
||||
color);
|
||||
|
||||
drawRectFromTri(buffer,
|
||||
v[0][0], v[1][1], v[0][2],
|
||||
v[1][0], v[1][1], v[0][2],
|
||||
v[1][0], v[1][1], v[1][2],
|
||||
v[0][0], v[1][1], v[1][2],
|
||||
color);
|
||||
|
||||
drawRectFromTri(buffer,
|
||||
v[1][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[1][2],
|
||||
v[1][0], v[1][1], v[1][2],
|
||||
v[1][0], v[1][1], v[0][2],
|
||||
color);
|
||||
}
|
||||
|
||||
public void drawBoxFromLines(WorldBuffer buffer,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2,
|
||||
Color color) {
|
||||
float[][] v = new float[][]{
|
||||
new float[]{Math.min(x1, x2), Math.min(y1, y2), Math.min(z1, z2)},
|
||||
new float[]{Math.max(x1, x2), Math.max(y1, y2), Math.max(z1, z2)}};
|
||||
|
||||
drawRectFromLines(buffer,
|
||||
v[0][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[0][2],
|
||||
v[1][0], v[1][1], v[0][2],
|
||||
v[0][0], v[1][1], v[0][2],
|
||||
color);
|
||||
|
||||
drawRectFromLines(buffer,
|
||||
v[0][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[1][2],
|
||||
v[0][0], v[0][1], v[1][2],
|
||||
color);
|
||||
|
||||
drawRectFromLines(buffer,
|
||||
v[0][0], v[0][1], v[0][2],
|
||||
v[0][0], v[0][1], v[1][2],
|
||||
v[0][0], v[1][1], v[1][2],
|
||||
v[0][0], v[1][1], v[0][2],
|
||||
color);
|
||||
|
||||
drawRectFromLines(buffer,
|
||||
v[0][0], v[0][1], v[1][2],
|
||||
v[1][0], v[0][1], v[1][2],
|
||||
v[1][0], v[1][1], v[1][2],
|
||||
v[0][0], v[1][1], v[1][2],
|
||||
color);
|
||||
|
||||
drawRectFromLines(buffer,
|
||||
v[0][0], v[1][1], v[0][2],
|
||||
v[1][0], v[1][1], v[0][2],
|
||||
v[1][0], v[1][1], v[1][2],
|
||||
v[0][0], v[1][1], v[1][2],
|
||||
color);
|
||||
|
||||
drawRectFromLines(buffer,
|
||||
v[1][0], v[0][1], v[0][2],
|
||||
v[1][0], v[0][1], v[1][2],
|
||||
v[1][0], v[1][1], v[1][2],
|
||||
v[1][0], v[1][1], v[0][2],
|
||||
color);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package themixray.repeating.mod.render;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import themixray.repeating.mod.render.buffer.BufferManager;
|
||||
import themixray.repeating.mod.render.shader.ShaderManager;
|
||||
|
||||
@UtilityClass
|
||||
public class RenderSystem {
|
||||
public void init() {
|
||||
BufferManager.init();
|
||||
ShaderManager.init();
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package themixray.repeating.mod.render.buffer;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL33.*;
|
||||
|
||||
@UtilityClass
|
||||
public class BufferManager {
|
||||
private int vao;
|
||||
private int vbo;
|
||||
|
||||
private int prevVao;
|
||||
|
||||
public void init() {
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
|
||||
vao = glGenVertexArrays();
|
||||
vbo = glGenBuffers();
|
||||
});
|
||||
}
|
||||
|
||||
public void bindBuffer() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
}
|
||||
|
||||
public void unbindBuffer() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
public void writeBuffer(FloatBuffer buffer) {
|
||||
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
public void draw(int drawMode, int verts) {
|
||||
glDrawArrays(drawMode, 0, verts);
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
prevVao = glGetInteger(GL_VERTEX_ARRAY_BINDING);
|
||||
glBindVertexArray(vao);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
glBindVertexArray(prevVao);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package themixray.repeating.mod.render.buffer;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class Vertex {
|
||||
@Getter
|
||||
private float x;
|
||||
@Getter
|
||||
private float y;
|
||||
@Getter
|
||||
private float z;
|
||||
@Getter
|
||||
private float r;
|
||||
@Getter
|
||||
private float g;
|
||||
@Getter
|
||||
private float b;
|
||||
@Getter
|
||||
private float a;
|
||||
|
||||
public Vertex(float x, float y, float z, float r, float g, float b, float a) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package themixray.repeating.mod.render.buffer;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import themixray.repeating.mod.render.shader.Shader;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.opengl.GL33.*;
|
||||
|
||||
public class WorldBuffer {
|
||||
private final List<Vertex> vertices = new ArrayList<>();
|
||||
private final int drawMode;
|
||||
private final Shader shader;
|
||||
private FloatBuffer projectionMatrix;
|
||||
private final Vec3d cameraPos;
|
||||
|
||||
public WorldBuffer(int drawMode, Shader shader, WorldRenderContext worldRenderContext) {
|
||||
this.drawMode = drawMode;
|
||||
this.shader = shader;
|
||||
this.cameraPos = worldRenderContext.camera().getPos();
|
||||
makeProjectionMatrix(worldRenderContext.projectionMatrix(), worldRenderContext.matrixStack().peek().getPositionMatrix());
|
||||
}
|
||||
|
||||
public void vert(float x, float y, float z, float r, float g, float b, float a) {
|
||||
vertices.add(new Vertex(x - (float) cameraPos.x, y - (float) cameraPos.y, z - (float) cameraPos.z, r, g, b, a));
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
BufferManager.bind();
|
||||
BufferManager.bindBuffer();
|
||||
|
||||
BufferManager.writeBuffer(getBuffer());
|
||||
applyProjectionMatrix();
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, vertices.size() * 3 * 4L);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
BufferManager.unbindBuffer();
|
||||
|
||||
shader.bind();
|
||||
BufferManager.draw(drawMode, this.vertices.size());
|
||||
shader.unbind();
|
||||
|
||||
BufferManager.unbind();
|
||||
}
|
||||
|
||||
private FloatBuffer getBuffer() {
|
||||
FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(vertices.size() * 7);
|
||||
ArrayList<Float> floats = new ArrayList<>();
|
||||
for (Vertex vertex : vertices) {
|
||||
floats.add(vertex.getX());
|
||||
floats.add(vertex.getY());
|
||||
floats.add(vertex.getZ());
|
||||
}
|
||||
for (Vertex vertex : vertices) {
|
||||
floats.add(vertex.getR());
|
||||
floats.add(vertex.getG());
|
||||
floats.add(vertex.getB());
|
||||
floats.add(vertex.getA());
|
||||
}
|
||||
Float[] floatArray = new Float[floats.size()];
|
||||
floats.toArray(floatArray);
|
||||
floatBuffer.put(ArrayUtils.toPrimitive(floatArray));
|
||||
return floatBuffer.flip();
|
||||
}
|
||||
|
||||
private void makeProjectionMatrix(Matrix4f projectionMatrix, Matrix4f viewModelMatrix) {
|
||||
this.projectionMatrix = projectionMatrix.mul(viewModelMatrix).get(BufferUtils.createFloatBuffer(16));
|
||||
}
|
||||
|
||||
private void applyProjectionMatrix() {
|
||||
shader.uniformMatrix4f("u_projection", projectionMatrix);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package themixray.repeating.mod.render.shader;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL33.*;
|
||||
|
||||
public class Shader {
|
||||
@Getter
|
||||
private final int id;
|
||||
|
||||
|
||||
public Shader(String name) {
|
||||
int v = ShaderManager.loadShaderProgram(name, ShaderManager.ShaderType.VERTEX);
|
||||
int f = ShaderManager.loadShaderProgram(name, ShaderManager.ShaderType.FRAGMENT);
|
||||
this.id = glCreateProgram();
|
||||
glAttachShader(id, v);
|
||||
glAttachShader(id, f);
|
||||
glLinkProgram(id);
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glUseProgram(id);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
public void uniformMatrix4f(String name, FloatBuffer matrix) {
|
||||
bind();
|
||||
glUniformMatrix4fv(glGetUniformLocation(id, name), false, matrix);
|
||||
unbind();
|
||||
}
|
||||
|
||||
public void uniformValue2f(String name, float value1, float value2) {
|
||||
bind();
|
||||
glUniform2f(glGetUniformLocation(id, name), value1, value2);
|
||||
unbind();
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package themixray.repeating.mod.render.shader;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.TextureUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gl.GlImportProcessor;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourceFactory;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.lwjgl.opengl.GL33.*;
|
||||
|
||||
@UtilityClass
|
||||
public class ShaderManager {
|
||||
@Getter
|
||||
private Shader positionColorShader;
|
||||
|
||||
public void init() {
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register(client -> loadShaders());
|
||||
}
|
||||
|
||||
private void loadShaders() {
|
||||
positionColorShader = new Shader("position_color");
|
||||
}
|
||||
|
||||
public int loadShaderProgram(String name, ShaderType type) {
|
||||
try {
|
||||
boolean file_present = true;
|
||||
ResourceFactory resourceFactory = MinecraftClient.getInstance().getResourceManager();
|
||||
Optional<Resource> resource = resourceFactory.getResource(new Identifier("renderer", "shader/" + name + type.fileExtension));
|
||||
int i = glCreateShader(type.glType);
|
||||
if (resource.isPresent()) {
|
||||
GlStateManager.glShaderSource(i, new GlImportProcessor() {
|
||||
@SneakyThrows
|
||||
@Nullable
|
||||
@Override
|
||||
public String loadImport(boolean inline, String name) {
|
||||
return IOUtils.toString(resource.get().getInputStream(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}.readSource(readResourceAsString(resource.get().getInputStream())));
|
||||
} else file_present = false;
|
||||
glCompileShader(i);
|
||||
if (glGetShaderi(i, GL_COMPILE_STATUS) == 0 || !file_present) {
|
||||
String shaderInfo = StringUtils.trim(glGetShaderInfoLog(i, 32768));
|
||||
throw new IOException("Couldn't compile " + type.name + " program (" + name + ") : " + shaderInfo);
|
||||
}
|
||||
return i;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private String readResourceAsString(InputStream inputStream) {
|
||||
ByteBuffer byteBuffer = null;
|
||||
try {
|
||||
byteBuffer = TextureUtil.readResource(inputStream);
|
||||
int i = byteBuffer.position();
|
||||
byteBuffer.rewind();
|
||||
return MemoryUtil.memASCII(byteBuffer, i);
|
||||
} catch (IOException ignored) {
|
||||
} finally {
|
||||
if (byteBuffer != null) {
|
||||
MemoryUtil.memFree(byteBuffer);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum ShaderType {
|
||||
VERTEX("vertex", ".vsh", GL_VERTEX_SHADER),
|
||||
FRAGMENT("fragment", ".fsh", GL_FRAGMENT_SHADER);
|
||||
private final String name;
|
||||
private final String fileExtension;
|
||||
private final int glType;
|
||||
|
||||
ShaderType(String name, String fileExtension, int glType) {
|
||||
this.name = name;
|
||||
this.fileExtension = fileExtension;
|
||||
this.glType = glType;
|
||||
}
|
||||
}
|
||||
}
|
12
src/main/resources/assets/renderer/shader/position_color.fsh
Normal file
12
src/main/resources/assets/renderer/shader/position_color.fsh
Normal file
@ -0,0 +1,12 @@
|
||||
#version 330
|
||||
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec4 fragmentColor;
|
||||
|
||||
void main() {
|
||||
if (vertexColor.a == 0.0f) {
|
||||
discard;
|
||||
}
|
||||
fragmentColor = vertexColor;
|
||||
}
|
13
src/main/resources/assets/renderer/shader/position_color.vsh
Normal file
13
src/main/resources/assets/renderer/shader/position_color.vsh
Normal file
@ -0,0 +1,13 @@
|
||||
#version 330
|
||||
|
||||
layout (location = 0) in vec3 i_pos;
|
||||
layout (location = 1) in vec4 i_color;
|
||||
|
||||
uniform mat4 u_projection;
|
||||
|
||||
out vec4 vertexColor;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * vec4(i_pos, 1.0f);
|
||||
vertexColor = i_color;
|
||||
}
|
@ -4,19 +4,21 @@
|
||||
"key.repeating-mod.toggle_record": "Toggle recording",
|
||||
|
||||
"text.repeating-mod.name": "Repeating Mod",
|
||||
"text.repeating-mod.record": "record",
|
||||
"text.repeating-mod.replay": "replay",
|
||||
"text.repeating-mod.start": "Start",
|
||||
"text.repeating-mod.stop": "Stop",
|
||||
"text.repeating-mod.start_record": "Start record",
|
||||
"text.repeating-mod.stop_record": "Stop record",
|
||||
"text.repeating-mod.start_replay": "Start replay",
|
||||
"text.repeating-mod.stop_replay": "Stop replay",
|
||||
"text.repeating-mod.record_tooltip": "Start/stop recording all activities",
|
||||
"text.repeating-mod.replay_tooltip": "Start/stop repeating recorded actions",
|
||||
"text.repeating-mod.loop_tooltip": "Enable/disable repeating of recorded actions replay",
|
||||
"text.repeating-mod.export": "Export record",
|
||||
"text.repeating-mod.import": "Import record",
|
||||
"text.repeating-mod.basic": "Basic mode",
|
||||
"text.repeating-mod.parkour": "Parkour mode",
|
||||
"text.repeating-mod.settings": "Settings",
|
||||
"text.repeating-mod.export_tooltip": "Exporting a recording to a file",
|
||||
"text.repeating-mod.import_tooltip": "Importing an entry from the import.txt file",
|
||||
"text.repeating-mod.dev": "In development...",
|
||||
"text.repeating-mod.nan_pos_delay": "No pos timer",
|
||||
"text.repeating-mod.pos_delay": "Pos timer: %s ticks",
|
||||
"text.repeating-mod.pos_delay_text": "Timer after which the pos\nevent is added (20 ticks = 1 sec)",
|
||||
"text.repeating-mod.pos_delay_tooltip": "Timer after which the pos\nevent is added (20 ticks = 1 sec)",
|
||||
|
||||
"message.repeating-mod.replay_start": "Replay started",
|
||||
"message.repeating-mod.replay_stop": "Replay finished",
|
||||
|
@ -4,19 +4,21 @@
|
||||
"key.repeating-mod.toggle_record": "Вкл/выкл запись",
|
||||
|
||||
"text.repeating-mod.name": "Репитинг Мод",
|
||||
"text.repeating-mod.record": "запись",
|
||||
"text.repeating-mod.replay": "повтор",
|
||||
"text.repeating-mod.start": "Начать",
|
||||
"text.repeating-mod.stop": "Остановить",
|
||||
"text.repeating-mod.start_record": "Начать запись",
|
||||
"text.repeating-mod.stop_record": "Остановить запись",
|
||||
"text.repeating-mod.start_replay": "Начать повтор",
|
||||
"text.repeating-mod.stop_replay": "Остановить повтор",
|
||||
"text.repeating-mod.record_tooltip": "Начать/остановить запись всех действий",
|
||||
"text.repeating-mod.replay_tooltip": "Начать/остановить повтор записанных действий",
|
||||
"text.repeating-mod.loop_tooltip": "Вкл/выкл повтор повтора записанных действий",
|
||||
"text.repeating-mod.export": "Экспорт записи",
|
||||
"text.repeating-mod.import": "Импорт записи",
|
||||
"text.repeating-mod.basic": "Обычный режим",
|
||||
"text.repeating-mod.parkour": "Режим паркура",
|
||||
"text.repeating-mod.settings": "Настройки",
|
||||
"text.repeating-mod.export_tooltip": "Экспорт записи в файл",
|
||||
"text.repeating-mod.import_tooltip": "Импорт записи из файла import.txt",
|
||||
"text.repeating-mod.dev": "В разработке...",
|
||||
"text.repeating-mod.nan_pos_delay": "Таймера позиции нету",
|
||||
"text.repeating-mod.pos_delay": "Таймер позиции: %s тиков",
|
||||
"text.repeating-mod.pos_delay_text": "Таймер, после которой добавляется\nивент позиции (20 тиков = 1 сек)",
|
||||
"text.repeating-mod.pos_delay_tooltip": "Таймер, после которой добавляется\nивент позиции (20 тиков = 1 сек)",
|
||||
|
||||
"message.repeating-mod.replay_start": "Повтор начат",
|
||||
"message.repeating-mod.replay_stop": "Повтор закончен",
|
||||
|
@ -29,7 +29,7 @@
|
||||
"depends": {
|
||||
"fabricloader": ">=0.14.14",
|
||||
"fabric-api": "*",
|
||||
"minecraft": "1.19.x",
|
||||
"minecraft": ">=1.20",
|
||||
"java": ">=17"
|
||||
},
|
||||
"suggests": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user