Added ability to change width and height for the visual image

Change indentation to 2 spaces instead of 4
Added ImageHandler.java for basic Image related things
Added 2 new speedometer images for scaling purposes
Updated to version 3
Gave gradle more ram
Added the new translatable texts to en_us.json
This commit is contained in:
2023-07-11 15:17:48 +02:00
parent 64a35df67d
commit dc757d8fa1
13 changed files with 719 additions and 601 deletions

View File

@@ -10,227 +10,243 @@ import me.shedaniel.math.Color;
import static me.zacharias.speedometer.Speedometer.MOD_ID; import static me.zacharias.speedometer.Speedometer.MOD_ID;
public class Config { public class Config {
private static JSONObject Config; private static JSONObject Config;
public static final int configVersion = 2; public static final float configVersion = 2.1f;
public static void initialize(){ public static void initialize(){
if(Config != null) throw new RuntimeException("Already Initialized"); if(Config != null) throw new RuntimeException("Already Initialized");
File config = new File(Platform.getConfigFolder().toString()+"/"+MOD_ID+"/config.json"); File config = new File(Platform.getConfigFolder().toString()+"/"+MOD_ID+"/config.json");
if(!config.exists()){ if(!config.exists()){
try { try {
config.getParentFile().mkdir(); config.getParentFile().mkdir();
config.createNewFile(); config.createNewFile();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
}
Config = new JSONObject();
defualt();
}else {
try {
BufferedReader in = new BufferedReader(new FileReader(config));
String tmp;
StringBuilder builder = new StringBuilder();
while((tmp = in.readLine()) != null){
builder.append(tmp);
}
Config = new JSONObject(builder.toString());
if(Config.has("version")){
if(Config.getFloat("version")!=configVersion){
if(Config.getFloat("version") > configVersion){
defualt();
save();
}else if(Config.getFloat("version") < configVersion){
Config = new JSONObject();
defualt();
save();
} }
Config = new JSONObject(); }
defualt();
}else {
try {
BufferedReader in = new BufferedReader(new FileReader(config));
String tmp;
StringBuilder builder = new StringBuilder();
while((tmp = in.readLine()) != null){
builder.append(tmp);
}
Config = new JSONObject(builder.toString());
if(Config.has("version")){
if(Config.getInt("version")!=configVersion){
if(Config.getInt("version") > configVersion){
defualt();
save();
}else if(Config.getInt("version") < configVersion){
Config = new JSONObject();
defualt();
save();
}
}
}else{
Config = new JSONObject();
defualt();
save();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private static void defualt() {
if(!Config.has("speed")) {
Config.put("speed", SpeedTypes.BlockPS);
}
if(!Config.has("useKnot")) {
Config.put("useKnot", false);
}
if(!Config.has("color")) {
Config.put("color", new JSONObject()
.put("r", 16)
.put("g", 146)
.put("b", 158)
);
}
if(!Config.has("visualSpeedometer")) {
Config.put("visualSpeedometer", false);
}
if(!Config.has("xPositionVisual")) {
Config.put("xPositionVisual", "W-23");
}
if(!Config.has("yPositionVisual")) {
Config.put("yPositionVisual", "H-23");
}
if(!Config.has("xPositionText")) {
Config.put("xPositionText", "W-70");
}
if(!Config.has("yPositionText")) {
Config.put("yPositionText", "H-15");
}
if(!Config.has("debug")) {
Config.put("debug", false);
}
if(!Config.has("version")) {
Config.put("version", configVersion);
}
}
public static void save(){
File config = new File(Platform.getConfigFolder().toString()+"/"+MOD_ID+"/config.json");
if(!config.exists()){
try {
config.getParentFile().mkdir();
config.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
try {
BufferedWriter out = new BufferedWriter(new FileWriter(config));
out.write(Config.toString(4));
out.flush();
out.close();
}catch (Exception e){
throw new RuntimeException(e);
}
}
public static SpeedTypes getSpeedType(){
if(Config.has("speed")){
return Config.getEnum(SpeedTypes.class, "speed");
}else{ }else{
return SpeedTypes.BlockPS; Config = new JSONObject();
defualt();
save();
} }
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private static void defualt() {
if(!Config.has("speed")) {
Config.put("speed", SpeedTypes.BlockPS);
}
if(!Config.has("useKnot")) {
Config.put("useKnot", false);
}
if(!Config.has("color")) {
Config.put("color", new JSONObject()
.put("r", 16)
.put("g", 146)
.put("b", 158)
);
}
if(!Config.has("visualSpeedometer")) {
Config.put("visualSpeedometer", false);
}
if(!Config.has("xPositionVisual")) {
Config.put("xPositionVisual", "W-3");
}
if(!Config.has("yPositionVisual")) {
Config.put("yPositionVisual", "H-3");
}
if(!Config.has("xPositionText")) {
Config.put("xPositionText", "W-70");
}
if(!Config.has("yPositionText")) {
Config.put("yPositionText", "H-15");
} }
public static boolean getUseKnot() { if(!Config.has("debug")) {
if(Config.has("useKnot")){ Config.put("debug", false);
return Config.getBoolean("useKnot");
}else{
return false;
}
} }
public static Color getColor(){ if(!Config.has("imagSize")) {
if(Config.has("color")){ Config.put("imageSize", 19);
JSONObject color = Config.getJSONObject("color");
return Color.ofRGB(
color.getInt("r"),
color.getInt("g"),
color.getInt("b")
);
}else{
return Color.ofRGB(16, 146, 158);
}
} }
public static boolean isDebug() { if(!Config.has("version")) {
if(Config.has("debug")){ Config.put("version", configVersion);
return Config.getBoolean("debug");
}else{
return false;
}
} }
}
public static boolean getVisualSpeedometer(){ public static void save(){
if(Config.has("visualSpeedometer")){ File config = new File(Platform.getConfigFolder().toString()+"/"+MOD_ID+"/config.json");
return Config.getBoolean("visualSpeedometer"); if(!config.exists()){
}else { try {
return false; config.getParentFile().mkdir();
} config.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
try {
BufferedWriter out = new BufferedWriter(new FileWriter(config));
out.write(Config.toString(4));
out.flush();
out.close();
}catch (Exception e){
throw new RuntimeException(e);
}
}
public static String getXPositionVisual(){ public static SpeedTypes getSpeedType(){
if(Config.has("xPositionVisual")) { if(Config.has("speed")){
return Config.getString("xPositionVisual"); return Config.getEnum(SpeedTypes.class, "speed");
}else{ }else{
return "W-23"; return SpeedTypes.BlockPS;
}
} }
}
public static String getYPositionVisual() { public static boolean getUseKnot() {
if (Config.has("yPositionVisual")) { if(Config.has("useKnot")){
return Config.getString("yPositionVisual"); return Config.getBoolean("useKnot");
} else { }else{
return "H-23"; return false;
}
}
public static String getXPositionText(){
if(Config.has("xPositionText")) {
return Config.getString("xPositionText");
}else{
return "W-70";
}
} }
}
public static String getYPositionText(){ public static Color getColor(){
if(Config.has("yPositionText")) { if(Config.has("color")){
return Config.getString("yPositionText"); JSONObject color = Config.getJSONObject("color");
}else{ return Color.ofRGB(
return "H-15"; color.getInt("r"),
} color.getInt("g"),
color.getInt("b")
);
}else{
return Color.ofRGB(16, 146, 158);
} }
}
public static void setColor(Color color){ public static boolean isDebug() {
Config.put("color", new JSONObject() if(Config.has("debug")){
.put("r", color.getRed()) return Config.getBoolean("debug");
.put("g", color.getGreen()) }else{
.put("b", color.getBlue()) return false;
);
} }
}
public static void setUseKnot(boolean useKnot){ public static boolean getVisualSpeedometer(){
Config.put("useKnot", useKnot); if(Config.has("visualSpeedometer")){
return Config.getBoolean("visualSpeedometer");
}else {
return false;
} }
}
public static void setSpeedType(SpeedTypes speedType) { public static String getXPositionVisual(){
Config.put("speed", speedType); if(Config.has("xPositionVisual")) {
return Config.getString("xPositionVisual");
}else{
return "W-23";
} }
}
public static void setVisualSpeedometer(boolean visualSpeedometer){ public static String getYPositionVisual() {
Config.put("visualSpeedometer", visualSpeedometer); if (Config.has("yPositionVisual")) {
return Config.getString("yPositionVisual");
} else {
return "H-23";
} }
}
public static String getXPositionText(){
if(Config.has("xPositionText")) {
return Config.getString("xPositionText");
}else{
return "W-70";
}
}
public static void setXPositionVisual(String xPositionVisual){ public static String getYPositionText(){
Config.put("xPositionVisual", xPositionVisual); if(Config.has("yPositionText")) {
return Config.getString("yPositionText");
}else{
return "H-15";
} }
}
public static void setYPositionVisual(String yPositionVisual){ public static int getImageSize(){
Config.put("yPositionVisual", yPositionVisual); if(Config.has("imageSize")){
return Config.getInt("imageSize");
}else {
return 19;
} }
}
public static void setXPositionText(String xPositionText){ public static void setColor(Color color){
Config.put("xPositionText", xPositionText); Config.put("color", new JSONObject()
} .put("r", color.getRed())
.put("g", color.getGreen())
.put("b", color.getBlue())
);
}
public static void setYPositionText(String yPositionText){ public static void setUseKnot(boolean useKnot){
Config.put("yPositionText", yPositionText); Config.put("useKnot", useKnot);
} }
public static void setDebug(boolean debug){ public static void setSpeedType(SpeedTypes speedType) {
Config.put("debug", debug); Config.put("speed", speedType);
} }
public static void setVisualSpeedometer(boolean visualSpeedometer){
Config.put("visualSpeedometer", visualSpeedometer);
}
public static void setXPositionVisual(String xPositionVisual){
Config.put("xPositionVisual", xPositionVisual);
}
public static void setYPositionVisual(String yPositionVisual){
Config.put("yPositionVisual", yPositionVisual);
}
public static void setXPositionText(String xPositionText){
Config.put("xPositionText", xPositionText);
}
public static void setYPositionText(String yPositionText){
Config.put("yPositionText", yPositionText);
}
public static void setDebug(boolean debug){
Config.put("debug", debug);
}
public static void setImageSize(int imageSize){
Config.put("imageSize", imageSize);
}
} }

View File

@@ -0,0 +1,14 @@
package me.zacharias.speedometer;
import java.awt.*;
import java.awt.image.BufferedImage;
public class ImageHandler {
public static BufferedImage scale(BufferedImage img, int width, int height) {
Image img1 = img.getScaledInstance(width,height, Image.SCALE_DEFAULT);
BufferedImage out = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = out.createGraphics();
g2d.drawImage(img1,0,0,null);
return out;
}
}

View File

@@ -0,0 +1,60 @@
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;
public enum MeterImages {
LARGE(Component.translatable("speedometer.meter.large"), () -> {
try {
return ImageIO.read(Objects.requireNonNull(Speedometer.class.getResourceAsStream("/assets/speedometer/meter/meter-115.png")));
} catch (Exception e) {
return null;
}
}, 115),
SMALL(Component.translatable("speedometer.meter.small"), () -> {
try {
return ImageIO.read(Objects.requireNonNull(Speedometer.class.getResourceAsStream("/assets/speedometer/meter/meter-19.png")));
} catch (Exception e) {
return null;
}
}, 19),
MEDIUM(Component.translatable("speedometer.meter.small"), () -> {
try {
return ImageIO.read(Objects.requireNonNull(Speedometer.class.getResourceAsStream("/assets/speedometer/meter/meter-67.png")));
} catch (Exception e) {
return null;
}
}, 67)
;
private final Component name;
private final BufferedImage image;
private final int size;
MeterImages(Component name, Loader icon, int size) {
this.name = name;
this.image = icon.load();
this.size = size;
}
public BufferedImage getImage() {
return image;
}
public int getSize() {
return size;
}
public Component getName() {
return name;
}
private interface Loader{
BufferedImage load();
}
}

View File

@@ -3,33 +3,33 @@ package me.zacharias.speedometer;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
public enum SpeedTypes { public enum SpeedTypes {
MPH(20), MPH(20),
KMPH(200), KMPH(200),
MPS(10), MPS(10),
BlockPS(10), BlockPS(10),
KNOT(20); KNOT(20);
private final int maxVisual; private final int maxVisual;
SpeedTypes(int maxVisual){ SpeedTypes(int maxVisual){
this.maxVisual = maxVisual; this.maxVisual = maxVisual;
}
public static Component getName(Enum anEnum) {
if(anEnum instanceof SpeedTypes speedType) {
return Component.translatable("speedometer.speed." + switch (speedType) {
case MPH -> "mph";
case MPS -> "mps";
case KMPH -> "kmph";
case BlockPS -> "bps";
case KNOT -> "knot";
});
}else {
return Component.translatable("speedometer.speed.error");
} }
}
public static Component getName(Enum anEnum) { public int gatMaxVisual() {
if(anEnum instanceof SpeedTypes speedType) { return maxVisual;
return Component.translatable("speedometer.speed." + switch (speedType) { }
case MPH -> "mph";
case MPS -> "mps";
case KMPH -> "kmph";
case BlockPS -> "bps";
case KNOT -> "knot";
});
}else {
return Component.translatable("speedometer.speed.error");
}
}
public int gatMaxVisual() {
return maxVisual;
}
} }

View File

@@ -35,435 +35,458 @@ import java.util.*;
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 KeyMapping CONFIG_KEY = new KeyMapping( public static final KeyMapping CONFIG_KEY = new KeyMapping(
"speedometer.key.configKey", "speedometer.key.configKey",
InputConstants.Type.KEYSYM, InputConstants.Type.KEYSYM,
InputConstants.KEY_O, InputConstants.KEY_O,
"speedometer.key.category" "speedometer.key.category"
); );
public static final KeyMapping DEBUG_KEY = new KeyMapping( public static final KeyMapping DEBUG_KEY = new KeyMapping(
"speedometer.key.debugKey", "speedometer.key.debugKey",
InputConstants.Type.KEYSYM, InputConstants.Type.KEYSYM,
InputConstants.KEY_F6, InputConstants.KEY_F6,
"speedometer.key.category" "speedometer.key.category"
); );
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 BufferedImage img = null;
public static void init() { public static void init() {
LOGGER.info("Loading speedometer by Allen"); LOGGER.info("Loading speedometer by Allen");
if(Platform.getEnvironment() != Env.CLIENT) return; if(Platform.getEnvironment() != Env.CLIENT) return;
KeyMappingRegistry.register(CONFIG_KEY); KeyMappingRegistry.register(CONFIG_KEY);
ClientTickEvent.CLIENT_POST.register(minecraft -> { ClientTickEvent.CLIENT_POST.register(minecraft -> {
if(CONFIG_KEY.consumeClick()){ if(CONFIG_KEY.consumeClick()){
Minecraft.getInstance().setScreen(getConfig(Minecraft.getInstance().screen).build()); Minecraft.getInstance().setScreen(getConfig(Minecraft.getInstance().screen).build());
} }
}); });
KeyMappingRegistry.register(DEBUG_KEY); KeyMappingRegistry.register(DEBUG_KEY);
ClientTickEvent.CLIENT_POST.register(minecraft -> { ClientTickEvent.CLIENT_POST.register(minecraft -> {
if(DEBUG_KEY.consumeClick()){ if(DEBUG_KEY.consumeClick()){
Config.setDebug(!Config.isDebug()); Config.setDebug(!Config.isDebug());
} }
}); });
Config.initialize(); Config.initialize();
Config.save(); Config.save();
ClientGuiEvent.RENDER_HUD.register(Speedometer::render); ClientGuiEvent.RENDER_HUD.register(Speedometer::render);
try { try {
img = ImageIO.read(Objects.requireNonNull(Speedometer.class.getResourceAsStream("/assets/speedometer/meter/meter.png"))); img = ImageIO.read(Objects.requireNonNull(Speedometer.class.getResourceAsStream("/assets/speedometer/meter/meter-19.png")));
}catch (NullPointerException | IOException e){ }catch (NullPointerException | IOException e){
LOGGER.warn("Can't load speedometer icon. speedometer visual display is disabled"); LOGGER.warn("Can't load speedometer icon. speedometer visual display is disabled");
speedometerVisualDisplayFailed = true; speedometerVisualDisplayFailed = true;
} }
LOGGER.info("Finished loading speedometer"); if(img == null){
} speedometerVisualDisplayFailed = true;
}
private static void render(GuiGraphics graphics, float tick) { LOGGER.info("Finished loading speedometer");
if(Minecraft.getInstance().player == null) return; }
Entity entity = Minecraft.getInstance().player.getRootVehicle();
Vec3 vec = entity.getDeltaMovement(); private static void render(GuiGraphics graphics, float tick) {
if(Minecraft.getInstance().player == null) return;
Entity entity = Minecraft.getInstance().player.getRootVehicle();
double yOffset = 0.0784000015258789D; Vec3 vec = entity.getDeltaMovement();
double xOffset = 0D;
double zOffset = 0D;
double vOffset = 0D;
if (entity instanceof Player e) { double yOffset = 0.0784000015258789D;
if (!e.onGround() && e.isCreative()) { double xOffset = 0D;
yOffset = 0; double zOffset = 0D;
} else if (e.isInWater()) { double vOffset = 0D;
yOffset = 0;
}
} 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; if (entity instanceof Player e) {
double lSpeed = speed; if (!e.onGround() && e.isCreative()) {
yOffset = 0;
} else if (e.isInWater()) {
yOffset = 0;
}
} else if (entity instanceof Boat || entity instanceof Minecart || entity instanceof Pig) {
yOffset = 0;
}
if (speeds.size() >= 30) { double speed = (Math.sqrt(Math.pow(vec.x + xOffset, 2) + Math.pow(vec.y + yOffset, 2) + Math.pow(vec.z + zOffset, 2)) * 20)+vOffset;
speeds.remove(0); double lSpeed = speed;
}
speeds.add(speed);
speed = 0;
for (Double aDouble : speeds) {
speed += aDouble;
}
speed = speed / speeds.size();
double speedTypeSpeed = 0D; if (speeds.size() >= 30) {
speeds.remove(0);
}
speeds.add(speed);
speed = 0;
for (Double aDouble : speeds) {
speed += aDouble;
}
speed = speed / speeds.size();
SpeedTypes speedType = Config.getSpeedType(); double speedTypeSpeed = 0D;
if (speedType == SpeedTypes.KNOT || (entity instanceof Boat && Config.getUseKnot())) {
speedTypeSpeed = speed * 1.94384449;
}else if (speedType == SpeedTypes.KMPH) {
speedTypeSpeed = speed * 3.6;
} else if (speedType == SpeedTypes.MPH) {
speedTypeSpeed = speed * 2.23693629;
}else {
speedTypeSpeed = speed;
}
String format = String.format("%.2f", speedTypeSpeed); SpeedTypes speedType = Config.getSpeedType();
if (speedType == SpeedTypes.KNOT || (entity instanceof Boat && Config.getUseKnot())) {
speedTypeSpeed = speed * 1.94384449;
}else if (speedType == SpeedTypes.KMPH) {
speedTypeSpeed = speed * 3.6;
} else if (speedType == SpeedTypes.MPH) {
speedTypeSpeed = speed * 2.23693629;
}else {
speedTypeSpeed = speed;
}
//double v = (Math.pow(1.0233435, speedTypeSpeed)-1)/100; String format = String.format("%.2f", speedTypeSpeed);
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;
if(Config.getVisualSpeedometer() && !speedometerVisualDisplayFailed){ //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;
//double v = speedTypeSpeed / speedType.gatMaxVisual(); if(Config.getVisualSpeedometer() && !speedometerVisualDisplayFailed){
int x3 = (int) Math.round(7*Math.cos(Math.toRadians(i+90)))+(img.getWidth()/2); //double v = speedTypeSpeed / speedType.gatMaxVisual();
int y3 = (int) Math.round(7*Math.sin(Math.toRadians(i+90)))+(img.getWidth()/2);
BufferedImage img = new BufferedImage(Speedometer.img.getWidth(), Speedometer.img.getHeight(), Speedometer.img.getType()); MeterImages meterImage = null;
Graphics2D g2d = img.createGraphics(); int minDiff = 10000;
for(int x1 = 0; x1 < img.getWidth(); x1++) {
for (int y1 = 0; y1 < img.getHeight(); y1++) {
g2d.setColor(new Color(Speedometer.img.getRGB(x1,y1)));
g2d.fillRect(x1,y1,1,1);
}
}
g2d.setColor(new Color(138, 0, 0)); for(MeterImages meterImage1 : MeterImages.values()){
int diff = Math.abs(meterImage1.getSize()-Config.getImageSize());
if(minDiff > diff && meterImage1.getImage() != null){
minDiff = diff;
meterImage = meterImage1;
}
}
g2d.drawLine(x3,y3,img.getWidth()/2,img.getHeight()/2); img = meterImage.getImage();
int xPos = getPos(graphics, Config.getXPositionVisual(), 0, false, img.getWidth()); int radius = Config.getImageSize()/2-4;
int yPos = getPos(graphics, Config.getYPositionVisual(), 1, true, img.getHeight());
for(int x1 = 0; x1 < img.getWidth(); x1++){ int x3 = (int) Math.round(radius*Math.cos(Math.toRadians(i+90)))+(Config.getImageSize()/2);
for(int y1 = 0; y1 < img.getHeight(); y1++){ int y3 = (int) Math.round(radius*Math.sin(Math.toRadians(i+90)))+(Config.getImageSize()/2);
int x2 = x1 + xPos;
int y2 = y1 + yPos;
int rgb = img.getRGB(x1, y1); BufferedImage img = ImageHandler.scale(Speedometer.img, Config.getImageSize(), Config.getImageSize());
Graphics2D g2d = img.createGraphics();
if(new Color(rgb).equals(Color.black)) continue; g2d.setColor(new Color(138, 0, 0));
graphics.fill(x2, y2, x2+1, y2+1, rgb); g2d.setStroke(new BasicStroke(2));
}
}
if(i >= 360+45){ g2d.drawLine(x3,y3,img.getWidth()/2,img.getHeight()/2);
String string = "x" + (int)Math.floor(i/(365+45));
graphics.drawString(
Minecraft.getInstance().font,
string,
xPos-Minecraft.getInstance().font.width(string),
yPos+6,
new Color(138, 0, 0).getRGB()
);
}
}else { int xPos = getPos(graphics, Config.getXPositionVisual(), 0, false, img.getWidth());
// i -> x int yPos = getPos(graphics, Config.getYPositionVisual(), 1, true, img.getHeight());
// j -> y
// k -> color RGB int
String speedString = format + " " + SpeedTypes.getName(speedType).getString();
graphics.drawString(
Minecraft.getInstance().font,
speedString,
getPos(graphics, Config.getXPositionText(), 0, false, Minecraft.getInstance().font.width(speedString)),
getPos(graphics, Config.getYPositionText(), 1, true, Minecraft.getInstance().font.lineHeight),
Config.getColor().getColor()
);
}
if(Config.isDebug()){ for(int x1 = 0; x1 < img.getWidth(); x1++){
String debugData = "Velocity raw:" + "\n" + for(int y1 = 0; y1 < img.getHeight(); y1++){
" X: " + vec.x + "\n" + int x2 = x1 + xPos - img.getWidth();
" Y: " + vec.y + "\n" + int y2 = y1 + yPos - img.getHeight();
" Z: " + vec.z + "\n" +
"Offsets:" + "\n" +
" X: " + xOffset + "\n" +
" Y: " + yOffset + "\n" +
" Z: " + zOffset + "\n" +
" Total: " + vOffset + "\n" +
"Velocity modified:" + "\n" +
" X: " + (vec.x + xOffset) + "\n" +
" Y: " + (vec.y + yOffset) + "\n" +
" Z: " + (vec.z + zOffset) + "\n" +
" Total: " + lSpeed + "\n" +
"Velocity total average: " + speed + "\n" +
"Velocity total in " + speedType.name() + ": " + speedTypeSpeed + "\n" +
"Percentage point of visual speedometer: " + v + "\n" +
"Degree end point: " + (i+45);
Color color = new Color(255, 255, 255); int rgb = img.getRGB(x1, y1);
int y = 0; if(new Color(rgb).equals(Color.black)) continue;
for(String s : debugData.split("\n")){
drawString(graphics,0, y, s, color.getRGB());
y+=Minecraft.getInstance().font.lineHeight+1;
}
}
}
private static void drawString(GuiGraphics graphics, int x, int y, String text, int colorRGB){ graphics.fill(x2, y2, x2+1, y2+1, rgb);
graphics.drawString( }
Minecraft.getInstance().font, }
text,
x,
y,
colorRGB
);
}
static boolean flag = true; if(i >= 360+45){
String string = "x" + (int)Math.floor(i/(365+45));
graphics.drawString(
Minecraft.getInstance().font,
string,
xPos-Minecraft.getInstance().font.width(string),
(int)(yPos-4.5-(Config.getImageSize()/2)),
new Color(138, 0, 0).getRGB()
);
}
private static int getPos(GuiGraphics event, String input, int type, boolean changeFlag, int Size) { }else {
ArrayList<String> passerPose = new ArrayList<>(); // i -> x
final char[] s = input.toCharArray(); // j -> y
try{ // k -> color RGB int
for(int i = 0; i <s.length; i++){ String speedString = format + " " + SpeedTypes.getName(speedType).getString();
if(s[i] == 'W' || s[i] == 'H'){ graphics.drawString(
if(type == 0) passerPose.add(String.valueOf(event.guiWidth())); Minecraft.getInstance().font,
else if(type == 1) passerPose.add(String.valueOf(event.guiHeight())); speedString,
}else if(s[i] == 'h' || s[i] == 'w'){ getPos(graphics, Config.getXPositionText(), 0, false, Minecraft.getInstance().font.width(speedString)),
if(type == 0) passerPose.add(String.valueOf(event.guiWidth() / 2)); getPos(graphics, Config.getYPositionText(), 1, true, Minecraft.getInstance().font.lineHeight),
else if(type == 1) passerPose.add(String.valueOf(event.guiHeight() / 2)); Config.getColor().getColor()
}else if(s[i] == '+'){ );
passerPose.add("+"); }
}else if(s[i] == '-'){
passerPose.add("-"); if(Config.isDebug()){
}else if(s[i] == '*'){ String debugData = "Velocity raw:" + "\n" +
passerPose.add("/"); " X: " + vec.x + "\n" +
}else if(s[i] == '/'){ " Y: " + vec.y + "\n" +
passerPose.add("/"); " Z: " + vec.z + "\n" +
}else if(testIfInt(s[i])){ "Offsets:" + "\n" +
try{ " X: " + xOffset + "\n" +
Integer.parseInt(passerPose.get(i-1)); " Y: " + yOffset + "\n" +
passerPose.add(i-1,passerPose.get(i-1)+s[i]); " Z: " + zOffset + "\n" +
}catch (NumberFormatException e){ " Total: " + vOffset + "\n" +
passerPose.add(Character.toString(s[i])); "Velocity modified:" + "\n" +
} " X: " + (vec.x + xOffset) + "\n" +
}else if(s[i] == 'S' || s[i] == 's'){ " Y: " + (vec.y + yOffset) + "\n" +
passerPose.add(String.valueOf(Size)); " Z: " + (vec.z + zOffset) + "\n" +
}else{ " Total: " + lSpeed + "\n" +
throw new Exception(); "Velocity total average: " + speed + "\n" +
} "Velocity total in " + speedType.name() + ": " + speedTypeSpeed + "\n" +
} "Percentage point of visual speedometer: " + v + "\n" +
}catch (Exception e){ "Degree end point: " + (i+45);
passerPose.clear();
defaultValues(event, type, passerPose); Color color = new Color(255, 255, 255);
}
int y = 0;
for(String s : debugData.split("\n")){
drawString(graphics,0, y, s, color.getRGB());
y+=Minecraft.getInstance().font.lineHeight+1;
}
}
}
private static void drawString(GuiGraphics graphics, int x, int y, String text, int colorRGB){
graphics.drawString(
Minecraft.getInstance().font,
text,
x,
y,
colorRGB
);
}
static boolean flag = true;
private static int getPos(GuiGraphics event, String input, int type, boolean changeFlag, int Size) {
ArrayList<String> passerPose = new ArrayList<>();
final char[] s = input.toCharArray();
try{
for(int i = 0; i <s.length; i++){
if(s[i] == 'W' || s[i] == 'H'){
if(type == 0) passerPose.add(String.valueOf(event.guiWidth()));
else if(type == 1) passerPose.add(String.valueOf(event.guiHeight()));
}else if(s[i] == 'h' || s[i] == 'w'){
if(type == 0) passerPose.add(String.valueOf(event.guiWidth() / 2));
else if(type == 1) passerPose.add(String.valueOf(event.guiHeight() / 2));
}else if(s[i] == '+'){
passerPose.add("+");
}else if(s[i] == '-'){
passerPose.add("-");
}else if(s[i] == '*'){
passerPose.add("/");
}else if(s[i] == '/'){
passerPose.add("/");
}else if(testIfInt(s[i])){
try{
Integer.parseInt(passerPose.get(i-1));
passerPose.add(i-1,passerPose.get(i-1)+s[i]);
}catch (NumberFormatException e){
passerPose.add(Character.toString(s[i]));
}
}else if(s[i] == 'S' || s[i] == 's'){
passerPose.add(String.valueOf(Size));
}else{
throw new Exception();
}
}
}catch (Exception e){
passerPose.clear();
defaultValues(event, type, passerPose);
}
int xPos; int xPos;
try{ try{
xPos = Integer.parseInt(passerPose.get(0)); xPos = Integer.parseInt(passerPose.get(0));
}catch (NumberFormatException e){ }catch (NumberFormatException e){
defaultValues(event, type, passerPose); defaultValues(event, type, passerPose);
xPos = Integer.parseInt(passerPose.get(0)); xPos = Integer.parseInt(passerPose.get(0));
} }
for(int i = 1; i < passerPose.size(); i++){ for(int i = 1; i < passerPose.size(); i++){
boolean first = false; boolean first = false;
String s1 = passerPose.get(i); String s1 = passerPose.get(i);
String s2 = ""; String s2 = "";
try{ try{
s2 = passerPose.get(i+1); s2 = passerPose.get(i+1);
}catch (Exception e){ }catch (Exception e){
first = true; first = true;
} }
if(Objects.equals(s1, "+") && !first){ if(Objects.equals(s1, "+") && !first){
xPos += Integer.parseInt(s2); xPos += Integer.parseInt(s2);
}else if(Objects.equals(s1, "-") && !first){ }else if(Objects.equals(s1, "-") && !first){
xPos -= Integer.parseInt(s2); xPos -= Integer.parseInt(s2);
}else if(Objects.equals(s1, "*") && !first){ }else if(Objects.equals(s1, "*") && !first){
xPos *= Integer.parseInt(s2); xPos *= Integer.parseInt(s2);
}else if(Objects.equals(s1, "/") && !first){ }else if(Objects.equals(s1, "/") && !first){
xPos /= Integer.parseInt(s2); xPos /= Integer.parseInt(s2);
} }
} }
if((Platform.isDevelopmentEnvironment() || Config.isDebug()) && flag) { if((Platform.isDevelopmentEnvironment() || Config.isDebug()) && flag) {
LOGGER.info("Selected speed type: "+SpeedTypes.getName(Config.getSpeedType()).getString()+"\n"+ LOGGER.info("Selected speed type: "+SpeedTypes.getName(Config.getSpeedType()).getString()+"\n"+
Arrays.toString(passerPose.toArray())+"\n\n"+ Arrays.toString(passerPose.toArray())+"\n\n"+
xPos); xPos);
flag = !changeFlag; flag = !changeFlag;
} }
return xPos; return xPos;
} }
private static void defaultValues(GuiGraphics event, int type, ArrayList<String> passerPose) { private static void defaultValues(GuiGraphics event, int type, ArrayList<String> passerPose) {
if(type == 0){ if(type == 0){
passerPose.add(String.valueOf(event.guiWidth())); passerPose.add(String.valueOf(event.guiWidth()));
passerPose.add("-"); passerPose.add("-");
passerPose.add("70"); passerPose.add("70");
}else if(type == 1){ }else if(type == 1){
passerPose.add(String.valueOf(event.guiHeight())); passerPose.add(String.valueOf(event.guiHeight()));
passerPose.add("-"); passerPose.add("-");
passerPose.add("15"); passerPose.add("15");
} }
} }
private static boolean testIfInt(char c) { private static boolean testIfInt(char c) {
int i = Integer.parseInt(Character.toString(c)); int i = Integer.parseInt(Character.toString(c));
return (i == 0 || i == 1 || i == 2 || return (i == 0 || i == 1 || i == 2 ||
i == 3 || i == 4 || i == 5 || i == 3 || i == 4 || i == 5 ||
i == 6 || i == 7 || i == 8 || i == 6 || i == 7 || i == 8 ||
i == 9); i == 9);
} }
public static ConfigBuilder getConfig(Screen parent) { public static ConfigBuilder getConfig(Screen parent) {
ConfigBuilder builder = ConfigBuilder.create() ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parent) .setParentScreen(parent)
.setTitle(Component.translatable("speedometer.config.name")); .setTitle(Component.translatable("speedometer.config.name"));
ConfigCategory category = builder.getOrCreateCategory(Component.translatable("speedometer.config.category.name")); ConfigCategory category = builder.getOrCreateCategory(Component.translatable("speedometer.config.category.name"));
ConfigEntryBuilder entryBuilder = builder.entryBuilder(); ConfigEntryBuilder entryBuilder = builder.entryBuilder();
category.addEntry(entryBuilder.startEnumSelector(Component.translatable("speedometer.config.speed"), SpeedTypes.class, me.zacharias.speedometer.Config.getSpeedType()) category.addEntry(entryBuilder.startEnumSelector(Component.translatable("speedometer.config.speed"), SpeedTypes.class, me.zacharias.speedometer.Config.getSpeedType())
.setEnumNameProvider(SpeedTypes::getName) .setEnumNameProvider(SpeedTypes::getName)
.setSaveConsumer(me.zacharias.speedometer.Config::setSpeedType) .setSaveConsumer(me.zacharias.speedometer.Config::setSpeedType)
.build() .build()
); );
category.addEntry(entryBuilder.startColorField(Component.translatable("speedometer.config.color"), me.zacharias.speedometer.Config.getColor()) category.addEntry(entryBuilder.startColorField(Component.translatable("speedometer.config.color"), me.zacharias.speedometer.Config.getColor())
.setSaveConsumer2(me.zacharias.speedometer.Config::setColor) .setSaveConsumer2(me.zacharias.speedometer.Config::setColor)
.build() .build()
); );
category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.knot"), me.zacharias.speedometer.Config.getUseKnot()) category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.knot"), me.zacharias.speedometer.Config.getUseKnot())
.setSaveConsumer(me.zacharias.speedometer.Config::setUseKnot) .setSaveConsumer(me.zacharias.speedometer.Config::setUseKnot)
.setYesNoTextSupplier(useKnot -> Component.translatable("speedometer.useKnot."+useKnot)) .setYesNoTextSupplier(useKnot -> Component.translatable("speedometer.useKnot."+useKnot))
.build() .build()
); );
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)))
.build() .build()
); );
// Regex // Regex
String xRegex = "W*w*S*s*\\+*-*\\**/*[0-9]*"; String xRegex = "W*w*S*s*\\+*-*\\**/*[0-9]*";
String yRegex = "H*h*S*s*\\+*-*\\**/*[0-9]*"; String yRegex = "H*h*S*s*\\+*-*\\**/*[0-9]*";
// Text Placement // Text Placement
category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.xPosition.text"), Config.getXPositionText()) category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.xPosition.text"), Config.getXPositionText())
.setSaveConsumer(Config::setXPositionText) .setSaveConsumer(Config::setXPositionText)
.setErrorSupplier(xPosition -> { .setErrorSupplier(xPosition -> {
if(xPosition.matches(xRegex)){ if(xPosition.matches(xRegex)){
return Optional.empty(); return Optional.empty();
}else{ }else{
return Optional.of(Component.translatable("speedometer.invalid")); return Optional.of(Component.translatable("speedometer.invalid"));
} }
}) })
.setTooltip( .setTooltip(
Component.translatable("speedometer.config.tooltip.xPosition.line1"), Component.translatable("speedometer.config.tooltip.xPosition.line1"),
Component.translatable("speedometer.config.tooltip.xPosition.line2"), Component.translatable("speedometer.config.tooltip.xPosition.line2"),
Component.translatable("speedometer.config.tooltip.xPosition.line3") Component.translatable("speedometer.config.tooltip.xPosition.line3")
) )
.build() .build()
); );
category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.yPosition.text"), Config.getYPositionText()) category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.yPosition.text"), Config.getYPositionText())
.setSaveConsumer(Config::setYPositionText) .setSaveConsumer(Config::setYPositionText)
.setErrorSupplier(yPosition -> { .setErrorSupplier(yPosition -> {
if(yPosition.matches(yRegex)){ if(yPosition.matches(yRegex)){
return Optional.empty(); return Optional.empty();
}else{ }else{
return Optional.of(Component.translatable("speedometer.invalid")); return Optional.of(Component.translatable("speedometer.invalid"));
} }
}) })
.setTooltip( .setTooltip(
Component.translatable("speedometer.config.tooltip.yPosition.line1"), Component.translatable("speedometer.config.tooltip.yPosition.line1"),
Component.translatable("speedometer.config.tooltip.yPosition.line2"), Component.translatable("speedometer.config.tooltip.yPosition.line2"),
Component.translatable("speedometer.config.tooltip.yPosition.line3") Component.translatable("speedometer.config.tooltip.yPosition.line3")
) )
.build() .build()
); );
// Visual location // Visual location
category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.xPosition.visual"), Config.getXPositionVisual()) category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.xPosition.visual"), Config.getXPositionVisual())
.setSaveConsumer(Config::setXPositionVisual) .setSaveConsumer(Config::setXPositionVisual)
.setErrorSupplier(xPosition -> { .setErrorSupplier(xPosition -> {
if(xPosition.matches(xRegex)){ if(xPosition.matches(xRegex)){
return Optional.empty(); return Optional.empty();
}else{ }else{
return Optional.of(Component.translatable("speedometer.invalid")); return Optional.of(Component.translatable("speedometer.invalid"));
} }
}) })
.setTooltip( .setTooltip(
Component.translatable("speedometer.config.tooltip.xPosition.line1"), Component.translatable("speedometer.config.tooltip.xPosition.line1"),
Component.translatable("speedometer.config.tooltip.xPosition.line2"), Component.translatable("speedometer.config.tooltip.xPosition.line2"),
Component.translatable("speedometer.config.tooltip.xPosition.line3") Component.translatable("speedometer.config.tooltip.xPosition.line3")
) )
.build() .build()
); );
category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.yPosition.visual"), Config.getYPositionVisual()) category.addEntry(entryBuilder.startStringDropdownMenu(Component.translatable("speedometer.config.yPosition.visual"), Config.getYPositionVisual())
.setSaveConsumer(Config::setYPositionVisual) .setSaveConsumer(Config::setYPositionVisual)
.setErrorSupplier(yPosition -> { .setErrorSupplier(yPosition -> {
if(yPosition.matches(yRegex)){ if(yPosition.matches(yRegex)){
return Optional.empty(); return Optional.empty();
}else{ }else{
return Optional.of(Component.translatable("speedometer.invalid")); return Optional.of(Component.translatable("speedometer.invalid"));
} }
}) })
.setTooltip( .setTooltip(
Component.translatable("speedometer.config.tooltip.yPosition.line1"), Component.translatable("speedometer.config.tooltip.yPosition.line1"),
Component.translatable("speedometer.config.tooltip.yPosition.line2"), Component.translatable("speedometer.config.tooltip.yPosition.line2"),
Component.translatable("speedometer.config.tooltip.yPosition.line3") Component.translatable("speedometer.config.tooltip.yPosition.line3")
) )
.build() .build()
); );
category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.debug"),Config.isDebug()) category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.debug"),Config.isDebug())
.setSaveConsumer(Config::setDebug) .setSaveConsumer(Config::setDebug)
.setYesNoTextSupplier(isDebug -> Component.translatable("speedometer.debug."+isDebug)) .setYesNoTextSupplier(isDebug -> Component.translatable("speedometer.debug."+isDebug))
.setTooltip(Component.translatable("speedometer.config.tooltip.debug")) .setTooltip(Component.translatable("speedometer.config.tooltip.debug"))
.build() .build()
); );
builder.setSavingRunnable(me.zacharias.speedometer.Config::save); // Size of visual image
return builder; category.addEntry(entryBuilder.startIntField(Component.translatable("speedometer.config.imageWidth"), Config.getImageSize())
} .setSaveConsumer(Config::setImageSize)
.setTooltip(Component.translatable("speedometer.config.tooltip.imageWidth"))
.build()
);
builder.setSavingRunnable(me.zacharias.speedometer.Config::save);
return builder;
}
} }

View File

@@ -10,6 +10,7 @@
"speedometer.config.xPosition.text": "X Position for Text Meter", "speedometer.config.xPosition.text": "X Position for Text Meter",
"speedometer.config.yPosition.text": "Y Position for Text Meter", "speedometer.config.yPosition.text": "Y Position for Text Meter",
"speedometer.config.debug": "Debug", "speedometer.config.debug": "Debug",
"speedometer.config.imageWidth": "Image Width",
"speedometer.key.configKey": "Config Key", "speedometer.key.configKey": "Config Key",
"speedometer.key.debugKey": "Debug Key", "speedometer.key.debugKey": "Debug Key",
@@ -22,6 +23,9 @@
"speedometer.speed.knot": "Knot", "speedometer.speed.knot": "Knot",
"speedometer.speed.error": "Unknown Speed Type", "speedometer.speed.error": "Unknown Speed Type",
"speedometer.meter.large": "Large",
"speedometer.meter.small": "Small",
"speedometer.visualSpeedometer.true": "Visual", "speedometer.visualSpeedometer.true": "Visual",
"speedometer.visualSpeedometer.false": "Text", "speedometer.visualSpeedometer.false": "Text",
@@ -41,5 +45,7 @@
"speedometer.config.tooltip.debug": "Debug Information", "speedometer.config.tooltip.debug": "Debug Information",
"speedometer.config.tooltip.imageWidth": "Image width",
"speedometer.invalid": "Invalid String" "speedometer.invalid": "Invalid String"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -13,12 +13,11 @@ import net.minecraft.network.chat.Component;
import static me.zacharias.speedometer.Speedometer.LOGGER; import static me.zacharias.speedometer.Speedometer.LOGGER;
public class Config implements ModMenuApi { public class Config implements ModMenuApi {
@Override @Override
public ConfigScreenFactory<?> getModConfigScreenFactory() { public ConfigScreenFactory<?> getModConfigScreenFactory() {
return parent -> { return parent -> {
ConfigBuilder builder = Speedometer.getConfig(parent); ConfigBuilder builder = Speedometer.getConfig(parent);
return builder.build();
return builder.build(); };
}; }
} }
}

View File

@@ -4,8 +4,8 @@ import me.zacharias.speedometer.Speedometer;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
public class SpeedometerFabric implements ModInitializer { public class SpeedometerFabric implements ModInitializer {
@Override @Override
public void onInitialize() { public void onInitialize() {
Speedometer.init(); Speedometer.init();
} }
} }

View File

@@ -7,9 +7,9 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@Mod(Speedometer.MOD_ID) @Mod(Speedometer.MOD_ID)
public class SpeedometerForge { public class SpeedometerForge {
public SpeedometerForge() { public SpeedometerForge() {
// 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
EventBuses.registerModEventBus(Speedometer.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus()); EventBuses.registerModEventBus(Speedometer.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus());
Speedometer.init(); Speedometer.init();
} }
} }

View File

@@ -1,9 +1,9 @@
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx8G
minecraft_version=1.20.1 minecraft_version=1.20.1
archives_base_name=speedometer archives_base_name=speedometer
mod_version=2.0 mod_version=3.0
maven_group=me.zacharias maven_group=me.zacharias
architectury_version=9.0.8 architectury_version=9.0.8