Pushed version to 6.2
Starting to add speedometer into resourcepacks.
This commit is contained in:
@@ -5,7 +5,7 @@ dependencies {
|
|||||||
// Remove the next line if you don't want to depend on the API
|
// Remove the next line if you don't want to depend on the API
|
||||||
modApi "dev.architectury:architectury:${rootProject.architectury_version}"
|
modApi "dev.architectury:architectury:${rootProject.architectury_version}"
|
||||||
|
|
||||||
modApi "me.shedaniel.cloth:cloth-config-fabric:11.0.99"
|
modApi "me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_config_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
|
|||||||
@@ -11,22 +11,21 @@ import net.minecraft.client.KeyMapping;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
import net.minecraft.network.chat.ClickEvent;
|
import net.minecraft.network.chat.ClickEvent;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.packs.resources.Resource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.animal.Pig;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.entity.vehicle.Boat;
|
import net.minecraft.world.entity.vehicle.Boat;
|
||||||
import net.minecraft.world.entity.vehicle.Minecart;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.io.InputStream;
|
||||||
import java.util.Objects;
|
import java.util.*;
|
||||||
|
|
||||||
import static me.zacharias.speedometer.Speedometer.LOGGER;
|
import static me.zacharias.speedometer.Speedometer.*;
|
||||||
import static me.zacharias.speedometer.Speedometer.MOD_ID;
|
|
||||||
|
|
||||||
public class Client {
|
public class Client {
|
||||||
public static final KeyMapping CONFIG_KEY = new KeyMapping(
|
public static final KeyMapping CONFIG_KEY = new KeyMapping(
|
||||||
@@ -44,11 +43,10 @@ public class Client {
|
|||||||
|
|
||||||
private static final ArrayList<Double> speeds = new ArrayList<>();
|
private static final ArrayList<Double> speeds = new ArrayList<>();
|
||||||
private static boolean speedometerVisualDisplayFailed = false;
|
private static boolean speedometerVisualDisplayFailed = false;
|
||||||
public static BufferedImage img = null;
|
|
||||||
|
|
||||||
public static void init(){
|
public static void init(){
|
||||||
|
|
||||||
final boolean isClothLoaded = false;//Platform.isModLoaded("cloth_config") || Platform.isModLoaded("cloth-config");
|
final boolean isClothLoaded = Platform.isModLoaded("cloth_config") || Platform.isModLoaded("cloth-config");
|
||||||
|
|
||||||
if(isClothLoaded) {
|
if(isClothLoaded) {
|
||||||
Platform.getMod(MOD_ID).registerConfigurationScreen(parent -> ConfigMenu.getConfig(parent).build());
|
Platform.getMod(MOD_ID).registerConfigurationScreen(parent -> ConfigMenu.getConfig(parent).build());
|
||||||
@@ -97,11 +95,6 @@ public class Client {
|
|||||||
|
|
||||||
ClientGuiEvent.RENDER_HUD.register(Client::render);
|
ClientGuiEvent.RENDER_HUD.register(Client::render);
|
||||||
|
|
||||||
LOGGER.info("Loading speedometer ");
|
|
||||||
if(!MeterImages.LARGE.initiate()){
|
|
||||||
speedometerVisualDisplayFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.info("Finished loading speedometer");
|
LOGGER.info("Finished loading speedometer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,28 +102,22 @@ public class Client {
|
|||||||
if(Minecraft.getInstance().player == null) return;
|
if(Minecraft.getInstance().player == null) return;
|
||||||
Entity entity = Minecraft.getInstance().player.getRootVehicle();
|
Entity entity = Minecraft.getInstance().player.getRootVehicle();
|
||||||
|
|
||||||
Vec3 vec = entity.getDeltaMovement();
|
Vec3 vec = new Vec3(
|
||||||
|
entity.getX() - entity.xOld,
|
||||||
|
entity.getY() - entity.yOld,
|
||||||
|
entity.getZ() - entity.zOld
|
||||||
|
);
|
||||||
|
|
||||||
double yOffset = 0.0784000015258789D;
|
double yOffset = 0D;
|
||||||
double xOffset = 0D;
|
double xOffset = 0D;
|
||||||
double zOffset = 0D;
|
double zOffset = 0D;
|
||||||
double vOffset = 0D;
|
double vOffset = 0D;
|
||||||
|
|
||||||
if (entity instanceof Player e) {
|
|
||||||
if (!e.onGround() && e.isCreative()) {
|
|
||||||
yOffset = 0;
|
|
||||||
} else if (e.isInWater()) {
|
|
||||||
yOffset = 0.005;
|
|
||||||
}
|
|
||||||
} else if (entity instanceof Boat || entity instanceof Minecart || entity instanceof Pig) {
|
|
||||||
yOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double speed = (Math.sqrt(Math.pow(vec.x + xOffset, 2) + Math.pow(vec.y + yOffset, 2) + Math.pow(vec.z + zOffset, 2)) * 20)+vOffset;
|
double speed = (Math.sqrt(Math.pow(vec.x + xOffset, 2) + Math.pow(vec.y + yOffset, 2) + Math.pow(vec.z + zOffset, 2)) * 20)+vOffset;
|
||||||
double lSpeed = speed;
|
double lSpeed = speed;
|
||||||
|
|
||||||
if (speeds.size() >= 30) {
|
if (speeds.size() >= 30) {
|
||||||
speeds.remove(0);
|
speeds.removeFirst();
|
||||||
}
|
}
|
||||||
speeds.add(speed);
|
speeds.add(speed);
|
||||||
speed = 0;
|
speed = 0;
|
||||||
@@ -153,54 +140,32 @@ public class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String format = String.format("%.2f", speedTypeSpeed);
|
String format = String.format("%.2f", speedTypeSpeed);
|
||||||
|
|
||||||
//double v = (Math.pow(1.0233435, speedTypeSpeed)-1)/100;
|
|
||||||
double v = switch (speedType){
|
|
||||||
case KMPH -> Math.pow(speedTypeSpeed,0.87)-1;
|
|
||||||
case BlockPS, MPS -> Math.pow(speedTypeSpeed,1.25);
|
|
||||||
case MPH -> speedTypeSpeed;
|
|
||||||
case KNOT -> Math.pow(speedTypeSpeed,1.05);
|
|
||||||
}/100;
|
|
||||||
|
|
||||||
double i = (v *(316-45))+45;
|
|
||||||
|
|
||||||
String speedString = format + " " + SpeedTypes.getName(speedType).getString();
|
String speedString = format + " " + SpeedTypes.getName(speedType).getString();
|
||||||
|
|
||||||
int width = switch ((Config.getVisualSpeedometer() && !speedometerVisualDisplayFailed) ? 1 : 0){
|
int width = switch ((Config.getVisualSpeedometer() && !Config.isDisableVisualSpeedometer()) ? 1 : 0){
|
||||||
case 1 -> Config.getImageSize();
|
case 1 -> Config.getImageSize();
|
||||||
case 0 -> Minecraft.getInstance().font.width(speedString);
|
case 0 -> Minecraft.getInstance().font.width(speedString);
|
||||||
default -> 0;
|
default -> 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int yPos = getPos(graphics, width, Config.getYPosition(), 1);
|
int yPos = getPos(graphics, width, Config.getYPosition(), false);
|
||||||
int xPos = getPos(graphics, width, Config.getXPosition(), 0);
|
int xPos = getPos(graphics, width, Config.getXPosition(), true);
|
||||||
|
|
||||||
int lineHeight = Minecraft.getInstance().font.lineHeight;
|
int lineHeight = Minecraft.getInstance().font.lineHeight;
|
||||||
|
|
||||||
if(Config.getVisualSpeedometer() && !speedometerVisualDisplayFailed){
|
if(Config.getVisualSpeedometer() && !Config.isDisableVisualSpeedometer()){
|
||||||
|
|
||||||
//double v = speedTypeSpeed / speedType.gatMaxVisual();
|
//double v = speedTypeSpeed / speedType.gatMaxVisual();
|
||||||
|
|
||||||
img = ImageHandler.clone(MeterImages.LARGE.getImage());
|
BufferedImage img = ImageHandler.scale(ICON.getSpeedometerIcon(speedTypeSpeed), Config.getImageSize(), Config.getImageSize());
|
||||||
|
|
||||||
Graphics2D g2d = img.createGraphics();
|
/*int radius = img.getWidth()/2-4;
|
||||||
|
|
||||||
g2d.setColor(new Color(138, 0, 0));
|
|
||||||
g2d.setFont(new Font(g2d.getFont().getName(), Font.PLAIN, 15));
|
|
||||||
|
|
||||||
if(Config.getShowSpeedType()){
|
|
||||||
speedString = SpeedTypes.getName(speedType).getString();
|
|
||||||
drawString(graphics, xPos - width, yPos - Config.getImageSize() - lineHeight - 1, speedString, Config.getColor().getRGB());
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedImage img = ImageHandler.scale(Client.img, Config.getImageSize(), Config.getImageSize());
|
|
||||||
|
|
||||||
int radius = img.getWidth()/2-4;
|
|
||||||
|
|
||||||
int x3 = (int) Math.round(radius*Math.cos(Math.toRadians(i+90)))+(img.getWidth()/2);
|
int x3 = (int) Math.round(radius*Math.cos(Math.toRadians(i+90)))+(img.getWidth()/2);
|
||||||
int y3 = (int) Math.round(radius*Math.sin(Math.toRadians(i+90)))+(img.getHeight()/2);
|
int y3 = (int) Math.round(radius*Math.sin(Math.toRadians(i+90)))+(img.getHeight()/2);
|
||||||
|
|
||||||
g2d = img.createGraphics();
|
Graphics2D g2d = img.createGraphics();
|
||||||
|
|
||||||
g2d.setColor(new Color(138, 0, 0));
|
g2d.setColor(new Color(138, 0, 0));
|
||||||
|
|
||||||
@@ -227,9 +192,21 @@ public class Client {
|
|||||||
Minecraft.getInstance().font,
|
Minecraft.getInstance().font,
|
||||||
string,
|
string,
|
||||||
xPos-Minecraft.getInstance().font.width(string),
|
xPos-Minecraft.getInstance().font.width(string),
|
||||||
(int)(yPos-4.5-(Config.getImageSize()/2)),
|
(int)(yPos-4.5-((double) Config.getImageSize() /2)),
|
||||||
new Color(138, 0, 0).getRGB()
|
new Color(138, 0, 0).getRGB()
|
||||||
);
|
);
|
||||||
|
}*/
|
||||||
|
for(int x1 = 0; x1 < img.getWidth(); x1++){
|
||||||
|
for(int y1 = 0; y1 < img.getHeight(); y1++){
|
||||||
|
int x2 = x1 + xPos - img.getWidth();
|
||||||
|
int y2 = y1 + yPos - img.getHeight();
|
||||||
|
|
||||||
|
int rgb = img.getRGB(x1, y1);
|
||||||
|
|
||||||
|
if(new Color(rgb).equals(Color.black)) continue;
|
||||||
|
|
||||||
|
graphics.fill(x2, y2, x2+1, y2+1, rgb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
@@ -262,8 +239,8 @@ public class Client {
|
|||||||
" Total: " + lSpeed + "\n" +
|
" Total: " + lSpeed + "\n" +
|
||||||
"Velocity total average: " + speed + "\n" +
|
"Velocity total average: " + speed + "\n" +
|
||||||
"Velocity total in " + speedType.name() + ": " + speedTypeSpeed + "\n" +
|
"Velocity total in " + speedType.name() + ": " + speedTypeSpeed + "\n" +
|
||||||
"Percentage point of visual speedometer: " + v + "\n" +
|
"Percentage point of visual speedometer: " + /*v*/"error" + "\n" +
|
||||||
"Degree end point: " + i +"\n" +
|
"Degree end point: " + /*i*/"error" +"\n" +
|
||||||
(Config.getVisualSpeedometer()?"Visual Size: ":"Textual display") + Config.getImageSize();
|
(Config.getVisualSpeedometer()?"Visual Size: ":"Textual display") + Config.getImageSize();
|
||||||
|
|
||||||
Color color = new Color(255, 255, 255);
|
Color color = new Color(255, 255, 255);
|
||||||
@@ -286,20 +263,20 @@ public class Client {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getPos(GuiGraphics event, int width, String input, int type) {
|
private static int getPos(GuiGraphics event, int width, String input, boolean isXPosition) {
|
||||||
ArrayList<String> passerPose = new ArrayList<>();
|
ArrayList<String> passerPose = new ArrayList<>();
|
||||||
final char[] s = input.toCharArray();
|
final char[] s = input.toCharArray();
|
||||||
|
|
||||||
try{
|
try{
|
||||||
for(int i = 0; i <s.length; i++){
|
for(int i = 0; i <s.length; i++){
|
||||||
if(s[i] == 'W' || s[i] == 'H'){
|
if(s[i] == 'W' || s[i] == 'H'){
|
||||||
if(type == 0) passerPose.add(String.valueOf(event.guiWidth()));
|
if(isXPosition) passerPose.add(String.valueOf(event.guiWidth()));
|
||||||
else if(type == 1) passerPose.add(String.valueOf(event.guiHeight()));
|
else passerPose.add(String.valueOf(event.guiHeight()));
|
||||||
}else if(s[i] == 'h' || s[i] == 'w'){
|
}else if(s[i] == 'h' || s[i] == 'w'){
|
||||||
if(type == 0) passerPose.add(String.valueOf(event.guiWidth() / 2));
|
if(isXPosition) passerPose.add(String.valueOf(event.guiWidth() / 2));
|
||||||
else if(type == 1) passerPose.add(String.valueOf(event.guiHeight() / 2));
|
else passerPose.add(String.valueOf(event.guiHeight() / 2));
|
||||||
}else if(s[i] == 'S' || s[i] == 's'){
|
}else if(s[i] == 'S' || s[i] == 's'){
|
||||||
if(type == 0) passerPose.add(String.valueOf(width));
|
passerPose.add(String.valueOf(width));
|
||||||
else if(type == 1) passerPose.add(String.valueOf(width));
|
|
||||||
}else if(s[i] == '+'){
|
}else if(s[i] == '+'){
|
||||||
passerPose.add("+");
|
passerPose.add("+");
|
||||||
}else if(s[i] == '-'){
|
}else if(s[i] == '-'){
|
||||||
@@ -310,7 +287,7 @@ public class Client {
|
|||||||
passerPose.add("/");
|
passerPose.add("/");
|
||||||
}else if(Character.isDigit(s[i])){
|
}else if(Character.isDigit(s[i])){
|
||||||
try{
|
try{
|
||||||
if(i-1 > 0) {
|
if(i-1 > 0 && passerPose.get(i - 1).matches("^[0-9]+$")) {
|
||||||
Integer.parseInt(passerPose.get(i - 1));
|
Integer.parseInt(passerPose.get(i - 1));
|
||||||
passerPose.add(i - 1, passerPose.get(i - 1) + s[i]);
|
passerPose.add(i - 1, passerPose.get(i - 1) + s[i]);
|
||||||
}
|
}
|
||||||
@@ -327,17 +304,17 @@ public class Client {
|
|||||||
}
|
}
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
passerPose.clear();
|
passerPose.clear();
|
||||||
defaultValues(event, type, passerPose);
|
defaultValues(event, isXPosition, passerPose);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
int xPos;
|
int position;
|
||||||
try{
|
try{
|
||||||
xPos = Integer.parseInt(passerPose.get(0));
|
position = Integer.parseInt(passerPose.getFirst());
|
||||||
}catch (NumberFormatException e){
|
}catch (NumberFormatException e){
|
||||||
defaultValues(event, type, passerPose);
|
defaultValues(event, isXPosition, passerPose);
|
||||||
xPos = Integer.parseInt(passerPose.get(0));
|
position = Integer.parseInt(passerPose.getFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 1; i < passerPose.size(); i++){
|
for(int i = 1; i < passerPose.size(); i++){
|
||||||
@@ -351,31 +328,34 @@ public class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Objects.equals(s1, "+") && !first){
|
if(Objects.equals(s1, "+") && !first){
|
||||||
xPos += Integer.parseInt(s2);
|
position += Integer.parseInt(s2);
|
||||||
}else if(Objects.equals(s1, "-") && !first){
|
}else if(Objects.equals(s1, "-") && !first){
|
||||||
xPos -= Integer.parseInt(s2);
|
position -= Integer.parseInt(s2);
|
||||||
}else if(Objects.equals(s1, "*") && !first){
|
}else if(Objects.equals(s1, "*") && !first){
|
||||||
xPos *= Integer.parseInt(s2);
|
position *= Integer.parseInt(s2);
|
||||||
}else if(Objects.equals(s1, "/") && !first){
|
}else if(Objects.equals(s1, "/") && !first){
|
||||||
xPos /= Integer.parseInt(s2);
|
position /= Integer.parseInt(s2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((Config.isDebug()) && Config.getCounter() < 2) {
|
if((Config.isDebug()) && Config.getCounter() < 2) {
|
||||||
LOGGER.info("Selected speed type: "+SpeedTypes.getName(Config.getSpeedType()).getString()+"\n"+
|
String speedDisplayType = SpeedTypes.getName(Config.getSpeedType()).getString();
|
||||||
Arrays.toString(passerPose.toArray())+"\n\n"+
|
String splitRawSpeedPosition = Arrays.toString(passerPose.toArray());
|
||||||
xPos+"\n\n"+
|
String rawSpeedPosition = isXPosition ? Config.getXPosition() : Config.getYPosition();
|
||||||
(type==0?Config.getXPosition():Config.getYPosition()));
|
LOGGER.info("Selected speed type: {}\n{}\n\n{}\n\n{}", speedDisplayType, splitRawSpeedPosition, position, rawSpeedPosition);
|
||||||
Config.addCounter();
|
Config.addCounter();
|
||||||
}
|
}
|
||||||
return xPos;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void defaultValues(GuiGraphics event, int type, ArrayList<String> passerPose) {
|
private static void defaultValues(GuiGraphics event, boolean isXPosition, ArrayList<String> passerPose) {
|
||||||
if(type == 0){
|
if(isXPosition)
|
||||||
|
{
|
||||||
passerPose.add(String.valueOf(event.guiWidth()));
|
passerPose.add(String.valueOf(event.guiWidth()));
|
||||||
passerPose.add("-");
|
passerPose.add("-");
|
||||||
passerPose.add("3");
|
passerPose.add("3");
|
||||||
}else if(type == 1){
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
passerPose.add(String.valueOf(event.guiHeight()));
|
passerPose.add(String.valueOf(event.guiHeight()));
|
||||||
passerPose.add("-");
|
passerPose.add("-");
|
||||||
passerPose.add("3");
|
passerPose.add("3");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import dev.architectury.platform.Platform;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
|
||||||
@@ -14,6 +15,8 @@ public class Config {
|
|||||||
public static final float configVersion = 3f;
|
public static final float configVersion = 3f;
|
||||||
private static int counter = 0;
|
private static int counter = 0;
|
||||||
private static String configPath;
|
private static String configPath;
|
||||||
|
private static BufferedImage speedometer;
|
||||||
|
private static boolean disableVisualSpeedometer = false;
|
||||||
|
|
||||||
public static void initialize(){
|
public static void initialize(){
|
||||||
if(config != null) throw new RuntimeException("Already Initialized");
|
if(config != null) throw new RuntimeException("Already Initialized");
|
||||||
@@ -128,7 +131,8 @@ public class Config {
|
|||||||
}
|
}
|
||||||
counter=0;
|
counter=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//region Config Getters
|
||||||
public static SpeedTypes getSpeedType(){
|
public static SpeedTypes getSpeedType(){
|
||||||
if(config.has("speed")){
|
if(config.has("speed")){
|
||||||
return config.getEnum(SpeedTypes.class, "speed");
|
return config.getEnum(SpeedTypes.class, "speed");
|
||||||
@@ -169,7 +173,9 @@ public class Config {
|
|||||||
public static boolean getVisualSpeedometer(){
|
public static boolean getVisualSpeedometer(){
|
||||||
if(config.has("visualSpeedometer")){
|
if(config.has("visualSpeedometer")){
|
||||||
return config.getBoolean("visualSpeedometer");
|
return config.getBoolean("visualSpeedometer");
|
||||||
}else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +218,23 @@ public class Config {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getConfigPath()
|
||||||
|
{
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage getSpeedometer() {
|
||||||
|
return speedometer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDisableVisualSpeedometer() {
|
||||||
|
return disableVisualSpeedometer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Config Setters
|
||||||
public static void setColor(int r, int g, int b){
|
public static void setColor(int r, int g, int b){
|
||||||
config.put("color", new JSONObject()
|
config.put("color", new JSONObject()
|
||||||
.put("r", r)
|
.put("r", r)
|
||||||
@@ -253,8 +275,12 @@ public class Config {
|
|||||||
config.put("showSpeedType", showSpeedType);
|
config.put("showSpeedType", showSpeedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getConfigPath()
|
public static void setSpeedometer(BufferedImage speedometer) {
|
||||||
{
|
Config.speedometer = speedometer;
|
||||||
return configPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setDisableVisualSpeedometer (boolean disableVisualSpeedometer){
|
||||||
|
Config.disableVisualSpeedometer = disableVisualSpeedometer;
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package me.zacharias.speedometer;
|
package me.zacharias.speedometer;
|
||||||
|
|
||||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
import me.shedaniel.clothconfig2.api.*;
|
||||||
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
|
||||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
|
||||||
import net.minecraft.ChatFormatting;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
@@ -41,6 +38,7 @@ public class ConfigMenu {
|
|||||||
category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.visualSpeedometer"), me.zacharias.speedometer.Config.getVisualSpeedometer())
|
category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.visualSpeedometer"), me.zacharias.speedometer.Config.getVisualSpeedometer())
|
||||||
.setSaveConsumer(me.zacharias.speedometer.Config::setVisualSpeedometer)
|
.setSaveConsumer(me.zacharias.speedometer.Config::setVisualSpeedometer)
|
||||||
.setYesNoTextSupplier((visualSpeedometer -> Component.translatable("speedometer.visualSpeedometer."+visualSpeedometer)))
|
.setYesNoTextSupplier((visualSpeedometer -> Component.translatable("speedometer.visualSpeedometer."+visualSpeedometer)))
|
||||||
|
.setRequirement(Requirement.isFalse(Config::isDisableVisualSpeedometer))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package me.zacharias.speedometer;
|
package me.zacharias.speedometer;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
public class ImageHandler {
|
public class ImageHandler {
|
||||||
@@ -23,4 +24,25 @@ public class ImageHandler {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BufferedImage rotate(BufferedImage img, double angle) {
|
||||||
|
double rads = Math.toRadians(angle);
|
||||||
|
int w = img.getWidth();
|
||||||
|
int h = img.getHeight();
|
||||||
|
|
||||||
|
BufferedImage rotated = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g2d = rotated.createGraphics();
|
||||||
|
AffineTransform at = new AffineTransform();
|
||||||
|
at.translate(w / 2d, h / 2d);
|
||||||
|
|
||||||
|
int x = w / 2;
|
||||||
|
int y = h / 2;
|
||||||
|
|
||||||
|
at.rotate(rads, x, y);
|
||||||
|
g2d.setTransform(at);
|
||||||
|
g2d.drawImage(img, 0, h, null);
|
||||||
|
g2d.dispose();
|
||||||
|
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package me.zacharias.speedometer;
|
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static me.zacharias.speedometer.Speedometer.LOGGER;
|
|
||||||
|
|
||||||
public enum MeterImages {
|
|
||||||
LARGE(Component.translatable("speedometer.meter.large"), "/assets/speedometer/meter/meter-115.png", 115),
|
|
||||||
SMALL(Component.translatable("speedometer.meter.small"), "/assets/speedometer/meter/meter-19.png", 19),
|
|
||||||
MEDIUM(Component.translatable("speedometer.meter.small"), "/assets/speedometer/meter/meter-67.png", 67)
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
private final Component name;
|
|
||||||
private final String meterIcon;
|
|
||||||
private BufferedImage image;
|
|
||||||
private final int size;
|
|
||||||
|
|
||||||
MeterImages(Component name, String meterIcon, int size) {
|
|
||||||
this.name = name;
|
|
||||||
this.size = size;
|
|
||||||
this.meterIcon = meterIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean initiate(){
|
|
||||||
if(image != null){
|
|
||||||
LOGGER.warn("Already loaded \""+meterIcon+"\"");
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
LOGGER.info("Loading speedometer \""+meterIcon+"\"");
|
|
||||||
image = ImageIO.read(Objects.requireNonNull(Speedometer.class.getResourceAsStream(meterIcon)));
|
|
||||||
LOGGER.info("Loaded speedometer \""+meterIcon+"\"");
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
image = new BufferedImage(0,0, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
LOGGER.warn("Failed to load speedometer \""+meterIcon+"\"");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BufferedImage getImage() {
|
|
||||||
if(image == null){
|
|
||||||
LOGGER.warn("\""+meterIcon+"\" has not ben loaded yet!");
|
|
||||||
}
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Component getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package me.zacharias.speedometer;
|
||||||
|
|
||||||
|
public class MissingPropertyException extends Exception {
|
||||||
|
public MissingPropertyException(String field) {
|
||||||
|
super("Missing Speedometer config field: " + field);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,17 +3,25 @@ package me.zacharias.speedometer;
|
|||||||
import dev.architectury.platform.Platform;
|
import dev.architectury.platform.Platform;
|
||||||
import dev.architectury.utils.Env;
|
import dev.architectury.utils.Env;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.packs.resources.Resource;
|
||||||
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class Speedometer
|
public class Speedometer
|
||||||
{
|
{
|
||||||
public static final String MOD_ID = "speedometer";
|
public static final String MOD_ID = "speedometer";
|
||||||
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
||||||
public static final String VERSION = Platform.getMod(MOD_ID).getVersion();
|
public static final String VERSION = Platform.getMod(MOD_ID).getVersion();
|
||||||
|
public static SpeedometerIcon ICON = null;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
LOGGER.info("Loading speedometer by Allen");
|
LOGGER.info("Loading speedometer by Allen");
|
||||||
@@ -26,20 +34,50 @@ public class Speedometer
|
|||||||
if (f.getName().startsWith("speedometer")) {
|
if (f.getName().startsWith("speedometer")) {
|
||||||
String fileName = "speedometer-" + VERSION + ".jar.disable";
|
String fileName = "speedometer-" + VERSION + ".jar.disable";
|
||||||
if(f.renameTo(new File(f.getParent(), fileName))){
|
if(f.renameTo(new File(f.getParent(), fileName))){
|
||||||
LOGGER.warn("Successfully in renaming the mod jar file to "+fileName);
|
LOGGER.warn("Successfully in renaming the mod jar file to {}", fileName);
|
||||||
LOGGER.warn("You should remove the file from "+Platform.getModsFolder().toString());
|
LOGGER.warn("You should remove the file from {}", Platform.getModsFolder().toString());
|
||||||
}else{
|
}else{
|
||||||
LOGGER.warn("Unsuccessful in renaming mod jar");
|
LOGGER.warn("Unsuccessful in renaming mod jar");
|
||||||
LOGGER.warn("You should remove the mod from "+Platform.getModsFolder().toString()+" to no longer receive this message");
|
LOGGER.warn("You should remove the mod from {} to no longer receive this message", Platform.getModsFolder().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (NullPointerException e){
|
}catch (NullPointerException e){
|
||||||
LOGGER.warn("Can't disable the mod");
|
LOGGER.warn("Can't disable the mod. Please delete the file!");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Client.init();
|
Client.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void loadSpeedometers(ResourceManager resourceManager)
|
||||||
|
{
|
||||||
|
Optional< Resource > resource = resourceManager.getResource(ResourceLocation.fromNamespaceAndPath(MOD_ID, "models/speedometer.json"));
|
||||||
|
|
||||||
|
if(resource.isEmpty())
|
||||||
|
{
|
||||||
|
Config.setDisableVisualSpeedometer(true);
|
||||||
|
LOGGER.error("Failed to load speedometer config");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
BufferedReader stream = resource.get().openAsReader();
|
||||||
|
String tmp;
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
while ((tmp = stream.readLine()) != null) {
|
||||||
|
builder.append(tmp);
|
||||||
|
}
|
||||||
|
JSONObject data = new JSONObject(builder.toString());
|
||||||
|
ICON = new SpeedometerIcon(data, resourceManager);
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
Config.setDisableVisualSpeedometer(true);
|
||||||
|
LOGGER.error("Failed to load speedometer config", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Successfully loaded speedometer config from {}", resource.get().source().packId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
package me.zacharias.speedometer;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.packs.resources.Resource;
|
||||||
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
|
import org.joml.Vector2i;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static me.zacharias.speedometer.Speedometer.MOD_ID;
|
||||||
|
|
||||||
|
public class SpeedometerIcon {
|
||||||
|
private BufferedImage speedometerIcon;
|
||||||
|
private Pointer pointer;
|
||||||
|
private int start;
|
||||||
|
private int end;
|
||||||
|
private float scale;
|
||||||
|
private int max;
|
||||||
|
private boolean overflow;
|
||||||
|
|
||||||
|
public SpeedometerIcon(JSONObject config, ResourceManager resourceManager) throws MissingPropertyException, IOException, JSONException
|
||||||
|
{
|
||||||
|
if(!config.has("background")) throw new MissingPropertyException("background");
|
||||||
|
|
||||||
|
String background = config.getString("background");
|
||||||
|
|
||||||
|
if(background.contains(":"))
|
||||||
|
{
|
||||||
|
background = background.replaceFirst(":", ":textures/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
background = "textures/"+background;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Resource> speedometerIcon = resourceManager.getResource(ResourceLocation.read(background).getOrThrow(s -> new MissingPropertyException("background")));
|
||||||
|
if(speedometerIcon.isEmpty()) throw new MissingPropertyException("background");
|
||||||
|
|
||||||
|
InputStream stream = speedometerIcon.get().open();
|
||||||
|
this.speedometerIcon = ImageIO.read(stream);
|
||||||
|
stream.close();
|
||||||
|
|
||||||
|
if(!config.has("start")) throw new MissingPropertyException("start");
|
||||||
|
this.start = config.getInt("start");
|
||||||
|
|
||||||
|
if(!config.has("end")) throw new MissingPropertyException("end");
|
||||||
|
this.end = config.getInt("end");
|
||||||
|
|
||||||
|
if(!config.has("scale")) throw new MissingPropertyException("scale");
|
||||||
|
this.scale = config.getFloat("scale");
|
||||||
|
|
||||||
|
if(!config.has("pointer")) throw new MissingPropertyException("pointer");
|
||||||
|
this.pointer = new Pointer(config.getJSONObject("pointer"), resourceManager, new Vector2i(this.speedometerIcon.getWidth(), this.speedometerIcon.getHeight()));
|
||||||
|
|
||||||
|
if(!config.has("maxSpeed")) throw new MissingPropertyException("maxSpeed");
|
||||||
|
this.max = config.getInt("maxSpeed");
|
||||||
|
|
||||||
|
if(!config.has("overflow")) throw new MissingPropertyException("overflow");
|
||||||
|
this.overflow = config.getBoolean("overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getSpeedometerIcon(double speed)
|
||||||
|
{
|
||||||
|
Graphics2D graphics = ImageHandler.clone(speedometerIcon).createGraphics();
|
||||||
|
pointer.draw(graphics, start, end, max, overflow, Math.pow(speed, scale));
|
||||||
|
return speedometerIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pointer
|
||||||
|
{
|
||||||
|
private BufferedImage image;
|
||||||
|
private Vector2i start;
|
||||||
|
private int length;
|
||||||
|
private boolean g = false;
|
||||||
|
|
||||||
|
public Pointer(JSONObject pointer, ResourceManager resourceManager, Vector2i size) throws MissingPropertyException, IOException, JSONException
|
||||||
|
{
|
||||||
|
if(!pointer.has("start")) throw new MissingPropertyException("pointer/start");
|
||||||
|
if(pointer.get("start") instanceof JSONObject jsonObject)
|
||||||
|
{
|
||||||
|
if(!jsonObject.has("x")) throw new MissingPropertyException("pointer/start/x");
|
||||||
|
if(!jsonObject.has("y")) throw new MissingPropertyException("pointer/start/y");
|
||||||
|
start = new Vector2i(jsonObject.getInt("x"), jsonObject.getInt("y"));
|
||||||
|
}
|
||||||
|
else if(pointer.get("start") instanceof String str)
|
||||||
|
{
|
||||||
|
if(str.isEmpty()) throw new MissingPropertyException("pointer/start");
|
||||||
|
|
||||||
|
if(str.matches("^\\([0-9]+,( )?[0-9]\\)+$"))
|
||||||
|
{
|
||||||
|
String[] split = str.split(",");
|
||||||
|
start = new Vector2i(Integer.parseInt(split[0].substring(1)), Integer.parseInt(split[1].substring(0, split[1].length()-1)));
|
||||||
|
}
|
||||||
|
else if(str.equalsIgnoreCase("center"))
|
||||||
|
{
|
||||||
|
start = new Vector2i(size.x / 2, size.y / 2);
|
||||||
|
}
|
||||||
|
else throw new MissingPropertyException("pointer/start");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pointer.has("image"))
|
||||||
|
{
|
||||||
|
String imageResourceLocation = pointer.getString("image");
|
||||||
|
|
||||||
|
if(imageResourceLocation.contains(":"))
|
||||||
|
{
|
||||||
|
imageResourceLocation = imageResourceLocation.replaceFirst(":", ":textures/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imageResourceLocation = "textures/"+imageResourceLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Resource> image = resourceManager.getResource(ResourceLocation.read(imageResourceLocation).getOrThrow(s -> new MissingPropertyException("pointer/image")));
|
||||||
|
if(image.isEmpty()) throw new MissingPropertyException("pointer/image");
|
||||||
|
|
||||||
|
InputStream stream = image.get().open();
|
||||||
|
this.image = ImageIO.read(stream);
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
else if(pointer.has("length"))
|
||||||
|
{
|
||||||
|
if(pointer.get("length") instanceof String str)
|
||||||
|
{
|
||||||
|
length = switch (str.toLowerCase())
|
||||||
|
{
|
||||||
|
case "half" -> size.x / 2;
|
||||||
|
case "full" -> size.x;
|
||||||
|
default -> throw new MissingPropertyException("pointer/length");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(pointer.get("length") instanceof Integer integer)
|
||||||
|
{
|
||||||
|
length = integer;
|
||||||
|
}
|
||||||
|
else throw new MissingPropertyException("pointer/length");
|
||||||
|
}
|
||||||
|
else throw new MissingPropertyException("pointer/image or pointer/length");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Graphics2D g2d, int start, int end, int max, boolean overflow, double speed)
|
||||||
|
{
|
||||||
|
double angle = (speed * end)+start;
|
||||||
|
if(angle > max && overflow) angle = end;
|
||||||
|
|
||||||
|
if(Objects.nonNull(image))
|
||||||
|
{
|
||||||
|
BufferedImage image = ImageHandler.rotate(this.image, angle);
|
||||||
|
if(angle>start+10 && !g) {
|
||||||
|
try {
|
||||||
|
File output = new File("./dev.png");
|
||||||
|
ImageIO.write(image, "png", output);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
g = true;
|
||||||
|
}
|
||||||
|
g2d.drawImage(image, this.start.x, this.start.y, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 316 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"background": "speedometer:meter/speedometer.png",
|
||||||
|
"start": 45,
|
||||||
|
"end": 215,
|
||||||
|
"maxSpeed": 120,
|
||||||
|
"overflow": true,
|
||||||
|
"pointer": {
|
||||||
|
"image": "speedometer:meter/pointer.png",
|
||||||
|
"start": "(0,0)"
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"name": "Test"
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"pack": {
|
"pack": {
|
||||||
"pack_format": 15,
|
"pack_format": 34,
|
||||||
"description": "speedometer resources"
|
"description": "speedometer resources"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,17 @@ package me.zacharias.speedometer.fabric;
|
|||||||
|
|
||||||
import me.zacharias.speedometer.Speedometer;
|
import me.zacharias.speedometer.Speedometer;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||||
|
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.network.chat.ClickEvent;
|
import net.minecraft.network.chat.ClickEvent;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.packs.PackType;
|
||||||
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
|
import org.intellij.lang.annotations.Identifier;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
@@ -14,5 +20,16 @@ public class SpeedometerFabric implements ModInitializer {
|
|||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
Speedometer.init();
|
Speedometer.init();
|
||||||
|
ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
|
||||||
|
@Override
|
||||||
|
public void onResourceManagerReload(ResourceManager resourceManager) {
|
||||||
|
Speedometer.loadSpeedometers(resourceManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getFabricId() {
|
||||||
|
return ResourceLocation.fromNamespaceAndPath("speedometer", "Loading the visual speedometers");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"id": "speedometer",
|
"id": "speedometer",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
|
|
||||||
"name": "speedometer",
|
"name": "Speedometer",
|
||||||
"description": "just displaying your speed",
|
"description": "just displaying your speed",
|
||||||
"authors": ["Zacharias"],
|
"authors": ["Zacharias"],
|
||||||
"contact": {
|
"contact": {
|
||||||
@@ -15,12 +15,15 @@
|
|||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
|
|
||||||
"environment": "client",
|
"environment": "client",
|
||||||
"entrypoints": {
|
"entrypoint": {
|
||||||
"main": ["me.zacharias.speedometer.fabric.SpeedometerFabric"]
|
"main": ["me.zacharias.speedometer.fabric.SpeedometerFabric"]
|
||||||
},
|
},
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.15.11",
|
"fabricloader": ">=0.15.11",
|
||||||
"minecraft": ">=1.21",
|
"minecraft": ">=1.21",
|
||||||
"architectury": ">=13.0.1"
|
"architectury": ">=13.0.1"
|
||||||
|
},
|
||||||
|
"suggests": {
|
||||||
|
"cloth-config1": ">=15.0.127"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ org.gradle.jvmargs=-Xmx8G
|
|||||||
minecraft_version=1.21
|
minecraft_version=1.21
|
||||||
|
|
||||||
archives_base_name=speedometer
|
archives_base_name=speedometer
|
||||||
mod_version=6.0.1
|
mod_version=6.2
|
||||||
maven_group=me.zacharias
|
maven_group=me.zacharias
|
||||||
|
|
||||||
architectury_version=13.0.1
|
architectury_version=13.0.4
|
||||||
|
|
||||||
fabric_loader_version=0.15.11
|
fabric_loader_version=0.15.11
|
||||||
fabric_api_version=0.100.3+1.21
|
fabric_api_version=0.100.6+1.21
|
||||||
|
|
||||||
neoforge_version = 21.0.21-beta
|
neoforge_version = 21.0.78-beta
|
||||||
|
|
||||||
cloth_config_version = 15.0.127
|
cloth_config_version = 15.0.127
|
||||||
@@ -1,7 +1,21 @@
|
|||||||
package me.zacharias.speedometer.forge;
|
package me.zacharias.speedometer.forge;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Unit;
|
||||||
import me.zacharias.speedometer.Speedometer;
|
import me.zacharias.speedometer.Speedometer;
|
||||||
|
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||||
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
|
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
|
||||||
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
|
import net.neoforged.api.distmarker.Dist;
|
||||||
|
import net.neoforged.bus.api.SubscribeEvent;
|
||||||
|
import net.neoforged.fml.common.EventBusSubscriber;
|
||||||
import net.neoforged.fml.common.Mod;
|
import net.neoforged.fml.common.Mod;
|
||||||
|
import net.neoforged.neoforge.client.ClientNeoForgeMod;
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
|
||||||
|
import net.neoforged.neoforge.common.NeoForge;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@Mod(Speedometer.MOD_ID)
|
@Mod(Speedometer.MOD_ID)
|
||||||
public class SpeedometerNeoForge {
|
public class SpeedometerNeoForge {
|
||||||
@@ -9,4 +23,23 @@ public class SpeedometerNeoForge {
|
|||||||
// Submit our event bus to let architectury register our content on the right time
|
// Submit our event bus to let architectury register our content on the right time
|
||||||
Speedometer.init();
|
Speedometer.init();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventBusSubscriber(modid = Speedometer.MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
|
||||||
|
class stuff
|
||||||
|
{
|
||||||
|
@SubscribeEvent
|
||||||
|
private static void onResourceReload(RegisterClientReloadListenersEvent event) {
|
||||||
|
event.registerReloadListener(new SimplePreparableReloadListener<Unit>() {
|
||||||
|
@Override
|
||||||
|
protected Unit prepare(ResourceManager arg, ProfilerFiller arg2) {
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void apply(Unit object, ResourceManager resourceManager, ProfilerFiller arg2) {
|
||||||
|
Speedometer.loadSpeedometers(resourceManager);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,35 +3,48 @@
|
|||||||
# The overall format is standard TOML format, v0.5.0.
|
# The overall format is standard TOML format, v0.5.0.
|
||||||
# Note that there are a couple of TOML lists in this file.
|
# Note that there are a couple of TOML lists in this file.
|
||||||
# Find more information on toml format here: https://github.com/toml-lang/toml
|
# Find more information on toml format here: https://github.com/toml-lang/toml
|
||||||
|
|
||||||
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
||||||
modLoader="javafml" #mandatory
|
modLoader="javafml" #mandatory
|
||||||
|
|
||||||
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
|
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
|
||||||
loaderVersion="[2,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
loaderVersion="[2,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||||
|
|
||||||
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
||||||
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
||||||
license="All Rights Reserved"
|
license="All Rights Reserved"
|
||||||
|
|
||||||
# A URL to refer people to when problems occur with this mod
|
# A URL to refer people to when problems occur with this mod
|
||||||
issueTrackerURL="https://github.com/zaze06/speedometer/issues"
|
issueTrackerURL="https://github.com/zaze06/Speedometer/issues"
|
||||||
|
|
||||||
# A list of mods - how many allowed here is determined by the individual mod loader
|
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||||
[[mods]] #mandatory
|
[[mods]] #mandatory
|
||||||
|
|
||||||
# The modid of the mod
|
# The modid of the mod
|
||||||
modId="speedometer" #mandatory
|
modId="speedometer" #mandatory
|
||||||
|
|
||||||
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
||||||
# ${version} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
|
# ${version} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
|
||||||
# see the associated build.gradle script for how to populate this completely automatically during a build
|
# see the associated build.gradle script for how to populate this completely automatically during a build
|
||||||
version="${version}" #mandatory
|
version="${version}" #mandatory
|
||||||
|
|
||||||
# A display name for the mod
|
# A display name for the mod
|
||||||
displayName="speedometer" #mandatory
|
displayName="Speedometer" #mandatory
|
||||||
|
|
||||||
# A URL to query for updates for this mod. See the JSON update specification <here>
|
# A URL to query for updates for this mod. See the JSON update specification <here>
|
||||||
updateJSONURL="https://raw.githubusercontent.com/zaze06/Speedometer/master/forge/src/main/resources/updateChecker.json" #optional
|
updateJSONURL="https://raw.githubusercontent.com/zaze06/Speedometer/master/neoforge/src/main/resources/updateChecker.json" #optional
|
||||||
|
|
||||||
# A URL for the "homepage" for this mod, displayed in the mod UI
|
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||||
displayURL="https://modrinth.com/mod/speedometer" #optional
|
displayURL="https://modrinth.com/mod/speedometer" #optional
|
||||||
|
|
||||||
# A file name (in the root of the mod JAR) containing a logo for display
|
# A file name (in the root of the mod JAR) containing a logo for display
|
||||||
logoFile="icon.png" #optional
|
logoFile="icon.png" #optional
|
||||||
|
|
||||||
# A text field displayed in the mod UI
|
# A text field displayed in the mod UI
|
||||||
#credits="Thanks for this example mod goes to Java" #optional
|
#credits="Thanks for this example mod goes to Java" #optional
|
||||||
# A text field displayed in the mod UI
|
# A text field displayed in the mod UI
|
||||||
authors="Zacharias" #optional
|
authors="Zacharias" #optional
|
||||||
|
|
||||||
# Display Test controls the display for your mod in the server connection screen
|
# Display Test controls the display for your mod in the server connection screen
|
||||||
# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod.
|
# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod.
|
||||||
# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod.
|
# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod.
|
||||||
@@ -42,8 +55,9 @@ displayTest="IGNORE_ALL_VERSION" # MATCH_VERSION is the default if nothing is sp
|
|||||||
|
|
||||||
# The description text for the mod (multi line!) (#mandatory)
|
# The description text for the mod (multi line!) (#mandatory)
|
||||||
description='''
|
description='''
|
||||||
just displaying your speed
|
Just displaying your speed
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||||
[[dependencies.speedometer]] #optional
|
[[dependencies.speedometer]] #optional
|
||||||
# the modid of the dependency
|
# the modid of the dependency
|
||||||
@@ -51,16 +65,14 @@ just displaying your speed
|
|||||||
# Does this dependency have to exist - if not, ordering below must be specified
|
# Does this dependency have to exist - if not, ordering below must be specified
|
||||||
mandatory=true #mandatory
|
mandatory=true #mandatory
|
||||||
# The version range of the dependency
|
# The version range of the dependency
|
||||||
versionRange="[2,)" #mandatory
|
versionRange="[21.0.78-beta,)" #mandatory
|
||||||
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
|
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
|
||||||
ordering="NONE"
|
ordering="NONE"
|
||||||
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
||||||
side="CLIENT"
|
side="CLIENT"
|
||||||
# Here's another dependency
|
|
||||||
[[dependencies.speedometer]]
|
[[dependencies.speedometer]]
|
||||||
modId="minecraft"
|
modId="minecraft"
|
||||||
mandatory=true
|
mandatory=true
|
||||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
|
||||||
versionRange="[1.21,1.22)"
|
versionRange="[1.21,1.22)"
|
||||||
ordering="NONE"
|
ordering="NONE"
|
||||||
side="BOTH"
|
side="BOTH"
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"pack": {
|
|
||||||
"pack_format": 15,
|
|
||||||
"description": "speedometer resources",
|
|
||||||
"forge:server_data_pack_format": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
"1.21": {
|
"1.21": {
|
||||||
"6.0": "Lost support for Forge and gain NeoForge support",
|
"6.0": "Lost support for Forge and gain NeoForge support",
|
||||||
"6.0.1": "Small bug fix in Parser",
|
"6.0.1": "Small bug fix in Parser",
|
||||||
"6.1": "Small bug fix in Parser"
|
"6.1": "Small bug fix in Parser",
|
||||||
|
"6.2": "Making speedometer and pointer resource pack based"
|
||||||
},
|
},
|
||||||
"promos": {
|
"promos": {
|
||||||
"1.21-latest": "6.1",
|
"1.21-latest": "6.1",
|
||||||
|
|||||||
110
schemas/speedometer_config_schema.json
Normal file
110
schemas/speedometer_config_schema.json
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "A name for your speedometer"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to the background texture file (e.g., 'meter/speedometer.png')"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Start value for the speedometer scale in degrees"
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "End value for the speedometer scale in degrees"
|
||||||
|
},
|
||||||
|
"maxSpeed": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The max speed, as in the end point angle in Blocks/s"
|
||||||
|
},
|
||||||
|
"overflow": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Dose the pointer overflow after maxSpeed"
|
||||||
|
},
|
||||||
|
"pointer": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"color": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
||||||
|
"description": "Color code for the pointer (e.g., '#8a0000')"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["center", "left", "right"],
|
||||||
|
"description": "Starting position of the pointer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^\\([0-9]+,( )?[0-9]\\)+$",
|
||||||
|
"description": "Starting position of the pointer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"x": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "X position"
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Y position"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["x", "y"],
|
||||||
|
"description": "Starting position of the pointer",
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["half", "full"],
|
||||||
|
"description": "Length of the pointer relative to the scale"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "number",
|
||||||
|
"description": "Length of the pointer relative to the scale"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"image":{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Image location for a pointer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["start"],
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"required": [
|
||||||
|
"image"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"required": [
|
||||||
|
"color",
|
||||||
|
"length"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"scale": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0.1,
|
||||||
|
"maximum": 2.0,
|
||||||
|
"description": "Scale factor for the speedometer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["background", "start", "end", "pointer", "scale", "maxSpeed", "overflow"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user