From 95222c1c952959a6f327a6ee8bb84e195c21445b Mon Sep 17 00:00:00 2001 From: Zacharias Date: Thu, 10 Oct 2024 09:10:57 +0200 Subject: [PATCH] # 6.2 release ## Notes - This release addes the ablility to provide your own or a speedometer made by someone else and not the 2 option I(The developer) provides as hard coded features ## Added: - Resorcepack source for visual speedometer - Added documentation for resourcepack setup [resourcepack.md](https://github.com/zaze06/Speedometer/blob/master/resourcepack.md) - Override config for speedometer pointer (only works if it's not an image) ## Fixes: - Fixed [#2](https://github.com/zaze06/Speedometer/issues/2) ## TO-DO: ## Resourcepack This release contains a base resourcepack that shuld be like the old one, but there is also an optinaly downloadible resourcepack from GitHub, and as a additinal file in this release on Github and Modrith ## Code notes This push updates the development envirment to 1.21.1, but fabric is tested and works on 1.21 still --- .../speedometer/models/speedometer.json | 13 +++ .../speedometer/textures/meter/pointer.png | Bin 0 -> 652 bytes .../textures/meter/speedometer.png | Bin 0 -> 1447 bytes .../quarter_circle_speedometer/pack.mcmeta | 6 ++ .../quarter_circle_speedometer/pack.png | Bin 0 -> 1190 bytes build.gradle | 3 +- .../java/me/zacharias/speedometer/Client.java | 44 +++++++++-- .../java/me/zacharias/speedometer/Config.java | 60 +++++++++++++- .../me/zacharias/speedometer/ConfigMenu.java | 20 ++++- .../me/zacharias/speedometer/Debuger.java | 7 ++ .../zacharias/speedometer/ImageHandler.java | 57 +++++++++----- .../me/zacharias/speedometer/Speedometer.java | 21 ++++- .../speedometer/SpeedometerIcon.java | 59 +++++++++----- .../assets/speedometer/lang/en_us.json | 12 ++- .../assets/speedometer/lang/sv_se.json | 74 ++++++++++++++++++ .../speedometer/models/speedometer.json | 11 +-- .../speedometer/fabric/SpeedometerFabric.java | 25 ++++-- fabric/src/main/resources/fabric.mod.json | 2 +- .../src/main/resources/pack.mcmeta | 0 gradle.properties | 15 ++-- .../forge/SpeedometerNeoForge.java | 37 ++++++++- .../resources/META-INF/neoforge.mods.toml | 3 + neoforge/src/main/resources/pack.mcmeta | 6 ++ resourcepack.md | 6 +- 24 files changed, 403 insertions(+), 78 deletions(-) create mode 100644 Resourcepack/quarter_circle_speedometer/assets/speedometer/models/speedometer.json create mode 100644 Resourcepack/quarter_circle_speedometer/assets/speedometer/textures/meter/pointer.png create mode 100644 Resourcepack/quarter_circle_speedometer/assets/speedometer/textures/meter/speedometer.png create mode 100644 Resourcepack/quarter_circle_speedometer/pack.mcmeta create mode 100644 Resourcepack/quarter_circle_speedometer/pack.png create mode 100644 common/src/main/java/me/zacharias/speedometer/Debuger.java create mode 100644 common/src/main/resources/assets/speedometer/lang/sv_se.json rename {common => fabric}/src/main/resources/pack.mcmeta (100%) create mode 100644 neoforge/src/main/resources/pack.mcmeta diff --git a/Resourcepack/quarter_circle_speedometer/assets/speedometer/models/speedometer.json b/Resourcepack/quarter_circle_speedometer/assets/speedometer/models/speedometer.json new file mode 100644 index 0000000..52f9368 --- /dev/null +++ b/Resourcepack/quarter_circle_speedometer/assets/speedometer/models/speedometer.json @@ -0,0 +1,13 @@ +{ + "background": "speedometer:meter/speedometer.png", + "start": 0, + "end": 85, + "maxSpeed": 120, + "overflow": false, + "pointer": { + "image": "speedometer:meter/pointer.png", + "start": "(115,115)" + }, + "scale": 1, + "name": "Quarter circle" +} \ No newline at end of file diff --git a/Resourcepack/quarter_circle_speedometer/assets/speedometer/textures/meter/pointer.png b/Resourcepack/quarter_circle_speedometer/assets/speedometer/textures/meter/pointer.png new file mode 100644 index 0000000000000000000000000000000000000000..ea8a8eb4335d01563ecaf072fd5a4fffba7c9a91 GIT binary patch literal 652 zcmeAS@N?(olHy`uVBq!ia0y~yU?>J*4mJh`hSkot&lngOTQZ%U13aCb6$*;-(=u~X z85lGs)=sqbIP4(Nc7Ivd(k&J@9FHhEmu~77E7S?qX==R`mT~pqlS}p)mnJOPVZpVI zmAzhUHJ{$OT~<4|njY|XY;K;ssC&wf*q{u-$Fj$5_k7>0Uw)s_Y4^F1Vg<$(vr~^tbD|=G2&(N&i=@&0iBPJ1iD_; zh}YP$rr_SAHP>dZsrLVOD8MuNWZ~Rv7C{kCQj#4LF1qlRMs!?UH!(@c`?)9o{~3?Z zPw-X?=k1Z<&Twdb^5fwD2j%%^Kb_e!Tf~d0S%2GKLq?vrOmnB@*2~{6d(QH~o;f_~ z{QV5(;`vLqS4Dl{khsUDx2}5D9`=}b42%7DrFir`S*|+e^nu@!wZVcCJ6W5u^X~6@ zZc)qd>B{P-(hnX8%vclfZP)SL%ztZtZ(nwMzx+buqMc5^ztk`=Ft8?NMQuIw+kI61_vcRz^8V_;yAEOCt}an8@p zP0cG|a4t$sEJ;mKD9=$HYAQABD2-{3kPe1af;ziGSlLG16EJ;dgQ}rBIu*F^NlNSP+=IQF^vd$@? F2>{SM{<{DG literal 0 HcmV?d00001 diff --git a/Resourcepack/quarter_circle_speedometer/assets/speedometer/textures/meter/speedometer.png b/Resourcepack/quarter_circle_speedometer/assets/speedometer/textures/meter/speedometer.png new file mode 100644 index 0000000000000000000000000000000000000000..0da934a820c58354a60180e8bb67127e0e95c986 GIT binary patch literal 1447 zcmeAS@N?(olHy`uVBq!ia0y~yU?>J*4mJh`hSkot&lngOTQZ%U13aCb6$*;-(=u~X z85lGs)=sqbIP4(Nc7Ivd(k&J@9FHhEmu~77E7S?qX==R`mT~pqlS}p)mnJOPVZpVI zmAzhUHJ{$OT~<4|njY|XY;K;ssC&wf*q{u-$Fj$5_k7>0Uw)s_Y4^F1Vg<$(vr~^tbD|=G2&(N&i=@&0iBPJ1iD_; zh}YP$rr_SAHP>dZsrLVOD8MuNWZ~Rv7C{kCQj#4LF1qlRMs!?UH!(@c`?)9o{~3?Z zPw-X?=k1Z<&Twdb^5fwD2j%%^Kb_e!Tf~d0S%2GKLq?vrOmnB@*2~{6d(QH~o;f_~ z{QV5(;`vLqS4Dl{khsUDx2}5D9`=}b42%7DrFir`S*|+e^nu@!wZVcCJ6W5u^X~6@ zZc)qd>B{P-(hnX8%vclfZP)SL%ztZtZ(nwMzx+buqMc5^ztk`=Ft8?NMQuIw+kI5^oj-c1*`Vqjp9EOCt}an8@p zP0cG|a4t$sEJ;mKD9sSig zCuuDCDX+fo`H$bx0fNq@_P^#<=gKHMojH=s8KTA%tSNNXq=#*pp@l*3!^TX84N+_D zewSPFxVorxH(NLC^_a|dhK0d<=_D3Mf#3CfXIL4^%-6-OFW+~Jm+P5~Kzr|L1rDnP zCYJ+`WPaPdbkGI@uepzL`+2Peq;mfzq+z>F`YCPM`L)&-DoijTXryUNEE3*665Z_cRNuolgSgg)Fx;i>~XlVKfNy}d1c6?Eo#Xtd*^-6zhEN8 zd-D0`m50BqaoBeGZ}gu^n{?)9P2Z1K+Qc(IOOQP;{eD{X5yj(f#*HRToJ$0K6nYbw zGFgN@lxH{`n;@>|TxW0R<{|hj;KcRx^#8Wo9Ph|%W>&11lRde*oBQOwyQTZWlkZsF zKC`g;$@AXc^a)B%&a%1BZnV#>YcRPoH_fjk>n(eE(8>j73X04Gy=go9Y*vOWiPSlD{jBfLjhmWcnr0X~ZVTSAe|rAv)hkpx zB)L^Q|1pScJaTNkapux}hNmk`n>bUVj_F)%zPWvBX5FQj*E3`}XC8YV>DzlV??B~V z^S&du&rEEex5X}V9q;7J+RGy!MHy!49KdJCJBR9TtLG0{6`HQXn?cA*`&(9a($gY^VY~vqRzkkLn5+kP1W?*1o@O1TaS?83{1OTwliM9X$ literal 0 HcmV?d00001 diff --git a/Resourcepack/quarter_circle_speedometer/pack.mcmeta b/Resourcepack/quarter_circle_speedometer/pack.mcmeta new file mode 100644 index 0000000..60eacac --- /dev/null +++ b/Resourcepack/quarter_circle_speedometer/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "pack_format": 34, + "description": "A different speedometer" + } +} \ No newline at end of file diff --git a/Resourcepack/quarter_circle_speedometer/pack.png b/Resourcepack/quarter_circle_speedometer/pack.png new file mode 100644 index 0000000000000000000000000000000000000000..58924526181e2dc1d0cb743939f68b9ebaafcd15 GIT binary patch literal 1190 zcmeAS@N?(olHy`uVBq!ia0y~yU?>J*4mJh`hSkot&lnh3ay?xfLn`9l-d@`$;waJj z@Tu5`7*00FO`J@63@R+`P74AgCY9b{FmG^E+{mJnA;hBSD17P6@qm)r=OyP$&WDtS zht8jDlUBC9{uOW5&2Dbr%VDwRPTCm~>3X@Xi7g>p&Kzbw@9Ax0^FTF|v#ovB)vH&h zZvOpYJ@?xu7ZvAoEBkK!op{tHQRIQh^y$+@p2+O()_Qg%uxIC^=Is+0-7K%ZQ|qcs z5lPju$yqYvbnhddM)n$ySM_tdPA+yh{$Sy`iCRm3{&;aQ{`d78-!v{MR!mU+`Q2`| zOsiCLd)TTENzqbAr7pXEc;F=xSHQhEBKgomjkLA49?dXi;nlzMO5=ur%@ha2 z(-N%GP3?wDmM!>yf8WADla}^^j-++QU2PwpF5lF#Kkv?qefM@>-&_BwWnWy^KaE#% ztY00iVv=~m|-o7TSWU$!oAhs3@oVJ^>uk7~$x z{k+|A>&x+we;P4o;?%yr=gbzK8+vhZ#l|14+hk0v)+f1tO#0!J)~)DUl6E?`{Cf6} zn$Q2h*i){tZ(C4=~8b?fD_#Ey2q3;b7}g_MP7} z5*qk*4?j8_Q!HX|fPGrw$HsN0ToN@^KPJdU96Q>+>zGDDg5uln9drMc`iaTExwN?9 z;B$8Vf9+uX?Yp07BnZgq@U2{M`3U=-DV{*t@d&2RM` zB-{FE!u|aF@9b>qeC{i=9y!7;CG51X_FKt*g_>U0x48}|SA<4G~CEQ>qRPX9No^jzoC6zGv`9(3VPOsBECpl^+F>zUJ6EkNd- zRnZTB(i7;>Y(9BU%tT>#LEd{FpNd2M<~WHRN}p-ZmH9z!6HoZF7R?mLnpu?~OB7BQ zmZteBazFm;Bj0LLQ5ZQ*+a#GQQel3^EsZ4yxlezJS=t$V!s(~aad$=DxR7fPy?kdl ziJe()Wy6*Ep=py``0EoIDeNB}ZPJ;aT_bWS!N)arx^`KD$fY_7Wu-kcpFEx1n{SZT zAlUo&>b2{;%Xf$C$6xYQ<)5EZA#&+KtB=g5+jFh&z82SiQLQ2$o|`h+=~&&pJvaAO z{+nYreNWA{hiCgVUw^m>QtY~fXWg9xBAb-#Wc>}bA6@<#=+P`bp=d{yLF<~H^Us&h znELVOuRxDxd!5um*2S7Btu=@0x*`?lZAs0UV?D@@mj7MZsjNRip_GGV}HEykIX8Et25&BtEbaR&7(xkAn%R|nr`Z=X5 z(zG?FBgxFgPq6k!Jqj_}b_a!$^L! e;4@u`o9%Tk&F6n`YXYbgV(@hJb6Mw<&;$SyHZxEF literal 0 HcmV?d00001 diff --git a/build.gradle b/build.gradle index 67fb087..dcec043 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false + id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false } architectury { @@ -20,6 +20,7 @@ subprojects { mappings loom.officialMojangMappings() // The following line declares the yarn mappings you may select this one as well. // mappings "net.fabricmc:yarn:@YARN_MAPPINGS@:v2" + //api("org.json:json:${rootProject.json_version}") } } diff --git a/common/src/main/java/me/zacharias/speedometer/Client.java b/common/src/main/java/me/zacharias/speedometer/Client.java index a2d8b5b..bad8457 100644 --- a/common/src/main/java/me/zacharias/speedometer/Client.java +++ b/common/src/main/java/me/zacharias/speedometer/Client.java @@ -11,18 +11,13 @@ import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; 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.vehicle.Boat; import net.minecraft.world.phys.Vec3; import net.minecraft.network.chat.Component; -import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; import java.util.*; import static me.zacharias.speedometer.Speedometer.*; @@ -96,6 +91,39 @@ public class Client { ClientGuiEvent.RENDER_HUD.register(Client::render); LOGGER.info("Finished loading speedometer"); + + /*((IPackRepository) Minecraft.getInstance().getResourcePackRepository()).addSource(new RepositorySource() { + @Override + public void loadPacks(Consumer consumer) { + consumer.accept(new Pack(new PackLocationInfo( + "quarter_circle_speedometer", + Component.translatable("resourcepack.speedometer.quarter_circle_speedometer"), + new PackSource() { + @Override + public Component decorate(Component component) { + return component; + } + + @Override + public boolean shouldAddAutomatically() { + return false; + } + }, + Optional.empty() + ), + new Pack.ResourcesSupplier() { + @Override + public PackResources openPrimary(PackLocationInfo packLocationInfo) { + return packLocationInfo.; + } + + @Override + public PackResources openFull(PackLocationInfo packLocationInfo, Pack.Metadata metadata) { + return null; + } + })); + } + });*/ } private static void render(GuiGraphics graphics, DeltaTracker deltaTracker) { @@ -239,9 +267,9 @@ public class Client { " Total: " + lSpeed + "\n" + "Velocity total average: " + speed + "\n" + "Velocity total in " + speedType.name() + ": " + speedTypeSpeed + "\n" + - "Percentage point of visual speedometer: " + /*v*/"error" + "\n" + - "Degree end point: " + /*i*/"error" +"\n" + - (Config.getVisualSpeedometer()?"Visual Size: ":"Textual display") + Config.getImageSize(); + "Endpoint position: (" + Debuger.x + ", " + Debuger.y + ")\n" + + "Percentage point of visual speedometer: " + Debuger.angle + "\n" + + (Config.getVisualSpeedometer()?"Visual Size: "+Config.getImageSize():"Textual display"); Color color = new Color(255, 255, 255); diff --git a/common/src/main/java/me/zacharias/speedometer/Config.java b/common/src/main/java/me/zacharias/speedometer/Config.java index 898102c..073da51 100644 --- a/common/src/main/java/me/zacharias/speedometer/Config.java +++ b/common/src/main/java/me/zacharias/speedometer/Config.java @@ -1,18 +1,19 @@ package me.zacharias.speedometer; import dev.architectury.platform.Platform; +import net.minecraft.client.Minecraft; +import org.json.JSONException; import org.json.JSONObject; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; - -import static me.zacharias.speedometer.Speedometer.MOD_ID; +import static me.zacharias.speedometer.Speedometer.*; public class Config { private static JSONObject config; - public static final float configVersion = 3f; + public static final float configVersion = 4f; private static int counter = 0; private static String configPath; private static BufferedImage speedometer; @@ -40,15 +41,43 @@ public class Config { while((tmp = in.readLine()) != null){ builder.append(tmp); } - config = new JSONObject(builder.toString()); + + try{ + config = new JSONObject(builder.toString()); + }catch (JSONException e){ + File dump = new File(Platform.getConfigFolder().toString()+"/"+MOD_ID+"/config-dump_"+formatMillisToDHMS(System.currentTimeMillis())+"_.json"); + LOGGER.error("Config is reset due to invalid content, dumping old content to {}", dump.getPath()); + if(!dump.exists()){ + dump.createNewFile(); + } + + try{ + BufferedWriter out = new BufferedWriter(new FileWriter(dump)); + out.write(builder.toString()); + out.close(); + }catch (IOException ex) + { + LOGGER.error("Failed to create a dump file and write to it.", ex); + LOGGER.warn("Dump content: \n{{}}", builder.toString()); + } + + config = new JSONObject(); + defualt(); + return; + } + + LOGGER.info("Loaded config successfully"); + if(config.has("version")){ if(config.getFloat("version")!=configVersion){ if(config.getFloat("version") > configVersion){ + LOGGER.warn("Config version is too new, resting"); defualt(); save(); }else if(config.getFloat("version") < configVersion){ config = new JSONObject(); + LOGGER.warn("Config version is outdated, resting"); defualt(); save(); @@ -109,6 +138,10 @@ public class Config { if(!config.has("showSpeedType")){ config.put("showSpeedType", false); } + + if(!config.has("overrideColor")) { + config.put("overrideColor", false); + } } public static void save(){ @@ -162,6 +195,11 @@ public class Config { } } + public static int getColorRGB() + { + return getColor().getRGB() & 0xFFFFFF; + } + public static boolean isDebug() { if(config.has("debug")){ return config.getBoolean("debug"); @@ -231,10 +269,19 @@ public class Config { public static boolean isDisableVisualSpeedometer() { return disableVisualSpeedometer; } + + public static boolean isOverrideColor() { + if(config.has("overrideColor")){ + return config.getBoolean("overrideColor"); + } else { + return false; + } + } //endregion //region Config Setters + public static void setColor(int r, int g, int b){ config.put("color", new JSONObject() .put("r", r) @@ -282,5 +329,10 @@ public class Config { public static void setDisableVisualSpeedometer (boolean disableVisualSpeedometer){ Config.disableVisualSpeedometer = disableVisualSpeedometer; } + + public static void setOverrideColor (boolean overrideColor) + { + config.put("overrideColor", overrideColor); + } //endregion } diff --git a/common/src/main/java/me/zacharias/speedometer/ConfigMenu.java b/common/src/main/java/me/zacharias/speedometer/ConfigMenu.java index e485a90..7d4aa92 100644 --- a/common/src/main/java/me/zacharias/speedometer/ConfigMenu.java +++ b/common/src/main/java/me/zacharias/speedometer/ConfigMenu.java @@ -22,7 +22,7 @@ public class ConfigMenu { .build() ); - category.addEntry(entryBuilder.startColorField(Component.translatable("speedometer.config.color"), me.zacharias.speedometer.Config.getColor().getRGB()) + category.addEntry(entryBuilder.startColorField(Component.translatable("speedometer.config.color"), me.zacharias.speedometer.Config.getColorRGB()) .setSaveConsumer2(color -> { me.zacharias.speedometer.Config.setColor(color.getRed(), color.getGreen(), color.getBlue()); }) @@ -87,6 +87,15 @@ public class ConfigMenu { category.addEntry(entryBuilder.startIntField(Component.translatable("speedometer.config.imageSize"), Config.getImageSize()) .setSaveConsumer(Config::setImageSize) .setTooltip(Component.translatable("speedometer.config.tooltip.imageSize")) + .setErrorSupplier(size -> { + if(size > 300 || size < 10) + { + return Optional.of(Component.translatable("speedometer.config.error.size_outofbounds")); + } + else { + return Optional.empty(); + } + }) .build() ); @@ -99,7 +108,14 @@ public class ConfigMenu { .build() ); - + category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.override_color"), Config.isOverrideColor()) + .setSaveConsumer(Config::setOverrideColor) + .setTooltip( + Component.translatable("speedometer.config.tooltip.override_color.line1"), + Component.translatable("speedometer.config.tooltip.override_color.line2") + ) + .build() + ); category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("speedometer.config.debug"),Config.isDebug()) .setSaveConsumer(Config::setDebug) diff --git a/common/src/main/java/me/zacharias/speedometer/Debuger.java b/common/src/main/java/me/zacharias/speedometer/Debuger.java new file mode 100644 index 0000000..dc4cdb1 --- /dev/null +++ b/common/src/main/java/me/zacharias/speedometer/Debuger.java @@ -0,0 +1,7 @@ +package me.zacharias.speedometer; + +public class Debuger { + public static double angle; + public static double x; + public static double y; +} diff --git a/common/src/main/java/me/zacharias/speedometer/ImageHandler.java b/common/src/main/java/me/zacharias/speedometer/ImageHandler.java index e06f9ef..8d88d76 100644 --- a/common/src/main/java/me/zacharias/speedometer/ImageHandler.java +++ b/common/src/main/java/me/zacharias/speedometer/ImageHandler.java @@ -24,25 +24,44 @@ public class ImageHandler { } 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); + + /** + * Rotates a BufferedImage around a specific point. + * + * @param image The original BufferedImage to rotate. + * @param angle The angle to rotate in degrees (double precision). + * @param x The x coordinate of the point to rotate around (int precision). + * @param y The y coordinate of the point to rotate around (int precision). + * @return A new BufferedImage containing the rotated image. + */ + public static BufferedImage rotateImage(BufferedImage image, double angle, int x, int y) { + // Convert the angle from degrees to radians + double radians = Math.toRadians(angle); + + // Get image dimensions + int width = image.getWidth(); + int height = image.getHeight(); + + // Create a new BufferedImage with the same width and height + BufferedImage rotatedImage = new BufferedImage(width, height, image.getType()); + + // Create a Graphics2D object from the new image + Graphics2D g2d = rotatedImage.createGraphics(); + + // Perform the rotation around the specified point (x, y) + AffineTransform transform = new AffineTransform(); + // Translate the rotation point to the origin (0, 0) + transform.translate(x, y); + // Rotate around the origin + transform.rotate(radians); + // Translate back to the original position + transform.translate(-x, -y); + + // Draw the rotated image + g2d.setTransform(transform); + g2d.drawImage(image, 0, 0, null); g2d.dispose(); - - return rotated; + + return rotatedImage; } } \ No newline at end of file diff --git a/common/src/main/java/me/zacharias/speedometer/Speedometer.java b/common/src/main/java/me/zacharias/speedometer/Speedometer.java index 729b2b2..203c907 100644 --- a/common/src/main/java/me/zacharias/speedometer/Speedometer.java +++ b/common/src/main/java/me/zacharias/speedometer/Speedometer.java @@ -3,6 +3,7 @@ package me.zacharias.speedometer; import dev.architectury.platform.Platform; import dev.architectury.utils.Env; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; @@ -12,9 +13,9 @@ import org.json.JSONObject; import java.io.BufferedReader; import java.io.File; -import java.io.InputStream; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.TimeUnit; public class Speedometer { @@ -53,8 +54,9 @@ public class Speedometer public static void loadSpeedometers(ResourceManager resourceManager) { + //List< Resource > resource = Minecraft.getInstance().getResourceManager().getResourceStack(ResourceLocation.fromNamespaceAndPath(MOD_ID, "models/speedometer.json")); Optional< Resource > resource = resourceManager.getResource(ResourceLocation.fromNamespaceAndPath(MOD_ID, "models/speedometer.json")); - + if(resource.isEmpty()) { Config.setDisableVisualSpeedometer(true); @@ -70,6 +72,10 @@ public class Speedometer builder.append(tmp); } JSONObject data = new JSONObject(builder.toString()); + if(Config.isDebug()) + { + LOGGER.info("Loaded speedometer from {}, with speedometer name: {}", resource.get().source().packId(), data.get("name")); + } ICON = new SpeedometerIcon(data, resourceManager); } catch (Exception e){ @@ -80,4 +86,15 @@ public class Speedometer LOGGER.info("Successfully loaded speedometer config from {}", resource.get().source().packId()); } + + public static String formatMillisToDHMS(long millis) { + // Calculate the days, hours, minutes, and seconds + long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60; + long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60; + long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24; + long days = TimeUnit.MILLISECONDS.toDays(millis); + + // Format the result as DD+HH-MM-SS + return String.format("%02d+%02d-%02d-%02d", days, hours, minutes, seconds); + } } diff --git a/common/src/main/java/me/zacharias/speedometer/SpeedometerIcon.java b/common/src/main/java/me/zacharias/speedometer/SpeedometerIcon.java index f6cc1a2..58405b9 100644 --- a/common/src/main/java/me/zacharias/speedometer/SpeedometerIcon.java +++ b/common/src/main/java/me/zacharias/speedometer/SpeedometerIcon.java @@ -26,6 +26,7 @@ public class SpeedometerIcon { private float scale; private int max; private boolean overflow; + private boolean g = false; public SpeedometerIcon(JSONObject config, ResourceManager resourceManager) throws MissingPropertyException, IOException, JSONException { @@ -70,15 +71,17 @@ public class SpeedometerIcon { public BufferedImage getSpeedometerIcon(double speed) { - Graphics2D graphics = ImageHandler.clone(speedometerIcon).createGraphics(); + BufferedImage img = ImageHandler.clone(speedometerIcon); + Graphics2D graphics = img.createGraphics(); pointer.draw(graphics, start, end, max, overflow, Math.pow(speed, scale)); - return speedometerIcon; + return img; } } class Pointer { private BufferedImage image; + private Color color; private Vector2i start; private int length; private boolean g = false; @@ -96,7 +99,7 @@ class Pointer { if(str.isEmpty()) throw new MissingPropertyException("pointer/start"); - if(str.matches("^\\([0-9]+,( )?[0-9]\\)+$")) + 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))); @@ -126,7 +129,7 @@ class Pointer if(image.isEmpty()) throw new MissingPropertyException("pointer/image"); InputStream stream = image.get().open(); - this.image = ImageIO.read(stream); + this.image = ImageHandler.scale(ImageIO.read(stream), size.x, size.y); stream.close(); } else if(pointer.has("length")) @@ -145,32 +148,52 @@ class Pointer length = integer; } else throw new MissingPropertyException("pointer/length"); + + if(pointer.has("color")) + { + String c = pointer.getString("color"); + if(!c.matches("^#[0-9a-fA-F]{6}$")) throw new MissingPropertyException("pointer/color"); + color = new Color(Integer.parseInt(c.substring(1), 16)); + } + else throw new MissingPropertyException("pointer/color"); } 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; + Color c = color; + if(Config.isOverrideColor()) + { + c = Config.getColor(); + } + double angle = ((speed/max) * end)+start; + if(angle > end && !overflow) angle = end; + Debuger.angle = angle; 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); + int centerX = this.start.x; + int centerY = this.start.y; + BufferedImage image = ImageHandler.rotateImage(this.image, angle, centerX, centerY); + g2d.drawImage(image, 0, 0, null); + } + else if(c != null && length > 0) + { + double angleRads = Math.toRadians(180+angle); + int endX = (int) (Math.cos(angleRads) * length + this.start.x); + int endY = (int) (Math.sin(angleRads) * length + this.start.y); + Debuger.x = endX; + Debuger.y = endY; + + g2d.setColor(c); + g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + g2d.drawLine(this.start.x, this.start.y, endX, endY); } else { - + Config.setDisableVisualSpeedometer(true); + throw new NullPointerException("image and line pointer both are undefined"); } } } diff --git a/common/src/main/resources/assets/speedometer/lang/en_us.json b/common/src/main/resources/assets/speedometer/lang/en_us.json index 0924a28..2612aad 100644 --- a/common/src/main/resources/assets/speedometer/lang/en_us.json +++ b/common/src/main/resources/assets/speedometer/lang/en_us.json @@ -15,6 +15,7 @@ "speedometer.config.imageSize": "Image Size", "speedometer.config.showVisualSpeedType": "\u00A74⨻\u00A7rShow Visual Speed Type", "speedometer.config.showSpeedType": "Show Visual Speed Type", + "speedometer.config.override_color": "Override color", "speedometer.key.configKey": "Config Key", "speedometer.key.debugKey": "Debug Key", @@ -29,7 +30,7 @@ "speedometer.meter.large": "Large", "speedometer.meter.small": "Small", - "speedometer.meter.medium": "Small", + "speedometer.meter.medium": "Medium", "speedometer.visualSpeedometer.true": "Visual", "speedometer.visualSpeedometer.false": "Text", @@ -60,7 +61,14 @@ "speedometer.config.tooltip.showSpeedType.line1": "This setting shows the speed type above the visual meter which is better then within the visual meter", + "speedometer.config.tooltip.override_color.line1": "Override the color of a line pointer", + "speedometer.config.tooltip.override_color.line2": "OPS doesn't work if the pointer is an image!", + "speedometer.invalid": "Invalid String", + + "speedometer.config.error.size_outofbounds": "The size is out of bounds 10<=size<=300", - "speedometer.error.missing_cloth": "Missing Cloth Config API for Config Screen" + "speedometer.error.missing_cloth": "Missing Cloth Config API for Config Screen", + + "resourcepack.speedometer.quarter_circle_speedometer": "Quarter circle Speedometer" } \ No newline at end of file diff --git a/common/src/main/resources/assets/speedometer/lang/sv_se.json b/common/src/main/resources/assets/speedometer/lang/sv_se.json new file mode 100644 index 0000000..63a55ff --- /dev/null +++ b/common/src/main/resources/assets/speedometer/lang/sv_se.json @@ -0,0 +1,74 @@ +{ + "speedometer.config.name": "Speedometer Config", + "speedometer.config.category.name": "Speedometer Konfigurationskatigori", + "speedometer.config.speed": "Fart Typ", + "speedometer.config.color": "Färg", + "speedometer.config.knot": "Använd Knot i Båtar", + "speedometer.config.visualSpeedometer": "Visuel Fartmätare", + "speedometer.config.xPosition.visual": "X Positionen för Visuel Mätare", + "speedometer.config.yPosition.visual": "Y Positionen för Visuel Mätare", + "speedometer.config.xPosition.text": "X Positionen för Text Mätare", + "speedometer.config.yPosition.text": "Y Positionen för Text Mätare", + "speedometer.config.xPosition": "X Positionen för Mätare", + "speedometer.config.yPosition": "Y Positionen för Mätare", + "speedometer.config.debug": "Debug", + "speedometer.config.imageSize": "Bildstorlek", + "speedometer.config.showVisualSpeedType": "\u00A74⨻\u00A7rVisa Visuell Farttyp", + "speedometer.config.showSpeedType": "Visa Visuell Farttyp", + "speedometer.config.override_color": "Överskrid färgen", + + "speedometer.key.configKey": "Konfigurations Knapp", + "speedometer.key.debugKey": "Debug Knapp", + "speedometer.key.category": "Speedometer", + + "speedometer.speed.mph": "MPH", + "speedometer.speed.mps": "Meter/s", + "speedometer.speed.kmph": "Km/h", + "speedometer.speed.bps": "Blocks/s", + "speedometer.speed.knot": "Knot", + "speedometer.speed.error": "Okänd Fart Typ", + + "speedometer.meter.large": "Stor", + "speedometer.meter.small": "Liten", + "speedometer.meter.medium": "Mellan", + + "speedometer.visualSpeedometer.true": "Visuel", + "speedometer.visualSpeedometer.false": "Text", + + "speedometer.useKnot.true": "Ja", + "speedometer.useKnot.false": "Nej", + + "speedometer.debug.true": "\u00A74Ja", + "speedometer.debug.false": "\u00A74Nej", + + "speedometer.show": "Visa", + "speedometer.hide": "Göm", + + "speedometer.config.tooltip.xPosition.line1": "W = fönstrets bred", + "speedometer.config.tooltip.xPosition.line2": "w = halva fönstrets bred", + "speedometer.config.tooltip.xPosition.line3": "s = breden på texten eller bilden", + + "speedometer.config.tooltip.yPosition.line1": "H = fönstrets höjd", + "speedometer.config.tooltip.yPosition.line2": "h = halva fönstrets höjd", + "speedometer.config.tooltip.yPosition.line3": "s = höjden av texten eller bilden", + + "speedometer.config.tooltip.debug": "Debug Information", + + "speedometer.config.tooltip.imageSize": "Storleken på bilden. Detta bestämmer både bredden och höjden av bilden", + + "speedometer.config.tooltip.showVisualSpeedType.line1": "Denna instälningen funkar inte helt och hållet", + "speedometer.config.tooltip.showVisualSpeedType.line2": "Jag (utvecklaren) avråder användandet av denna inställning då den inte fungerar vid mindre storlekar och förstör FPS vid större storlekar", + + "speedometer.config.tooltip.showSpeedType.line1": "Denna inställning visar farttypen ovanför den visuella mätaren, vilket är bättre än inuti mätaren", + + "speedometer.config.tooltip.override_color.line1": "Överskrider förgen av linjen pekaren", + "speedometer.config.tooltip.override_color.line2": "OBS funkar inte om pekaren är en bild!", + + "speedometer.invalid": "Inte korrekt Sträng", + + "speedometer.config.error.size_outofbounds": "Stolekten är felakting 10<=stolek<=300", + + "speedometer.error.missing_cloth": "Saknar Cloth Config API för konfigurationsskärmen", + + "resourcepack.speedometer.quarter_circle_speedometer": "Quarter circle Speedometer" + } \ No newline at end of file diff --git a/common/src/main/resources/assets/speedometer/models/speedometer.json b/common/src/main/resources/assets/speedometer/models/speedometer.json index c6f3287..b7f922f 100644 --- a/common/src/main/resources/assets/speedometer/models/speedometer.json +++ b/common/src/main/resources/assets/speedometer/models/speedometer.json @@ -1,13 +1,14 @@ { "background": "speedometer:meter/speedometer.png", - "start": 45, - "end": 215, + "start": -45, + "end": 225, "maxSpeed": 120, "overflow": true, "pointer": { - "image": "speedometer:meter/pointer.png", - "start": "(0,0)" + "color": "#b00219", + "length": 50, + "start": "center" }, "scale": 1, - "name": "Test" + "name": "Full cycle style" } \ No newline at end of file diff --git a/fabric/src/main/java/me/zacharias/speedometer/fabric/SpeedometerFabric.java b/fabric/src/main/java/me/zacharias/speedometer/fabric/SpeedometerFabric.java index 2619936..22e3e53 100644 --- a/fabric/src/main/java/me/zacharias/speedometer/fabric/SpeedometerFabric.java +++ b/fabric/src/main/java/me/zacharias/speedometer/fabric/SpeedometerFabric.java @@ -3,24 +3,37 @@ package me.zacharias.speedometer.fabric; import me.zacharias.speedometer.Speedometer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.ResourcePackActivationType; import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.minecraft.ChatFormatting; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; import net.minecraft.client.Minecraft; -import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.RepositorySource; import net.minecraft.server.packs.resources.ResourceManager; -import org.intellij.lang.annotations.Identifier; -import java.awt.*; +import java.util.HashSet; +import java.util.Set; + +import static me.zacharias.speedometer.Speedometer.LOGGER; +import static me.zacharias.speedometer.Speedometer.MOD_ID; public class SpeedometerFabric implements ModInitializer { @Override public void onInitialize() { Speedometer.init(); + + //Minecraft.getInstance().getResourcePackRepository().addPack() + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + /** + * Register the reload listener for the speedometers + * This is required since i haven't found how to put this in the Architecture Abstraction layer(Common module) + * TODO: Find a way to put this in the Abstraction layer + * @param resourceManager The event that is fired when the client reloads resources + */ @Override public void onResourceManagerReload(ResourceManager resourceManager) { Speedometer.loadSpeedometers(resourceManager); @@ -28,7 +41,7 @@ public class SpeedometerFabric implements ModInitializer { @Override public ResourceLocation getFabricId() { - return ResourceLocation.fromNamespaceAndPath("speedometer", "Loading the visual speedometers"); + return ResourceLocation.fromNamespaceAndPath("speedometer", "visual_speedometer_reload_listener"); } }); } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index d12bdd9..8cdab2a 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -15,7 +15,7 @@ "icon": "icon.png", "environment": "client", - "entrypoint": { + "entrypoints": { "main": ["me.zacharias.speedometer.fabric.SpeedometerFabric"] }, "depends": { diff --git a/common/src/main/resources/pack.mcmeta b/fabric/src/main/resources/pack.mcmeta similarity index 100% rename from common/src/main/resources/pack.mcmeta rename to fabric/src/main/resources/pack.mcmeta diff --git a/gradle.properties b/gradle.properties index 4843bb7..d6f877a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,16 +1,19 @@ org.gradle.jvmargs=-Xmx8G -minecraft_version=1.21 +minecraft_version=1.21.1 archives_base_name=speedometer mod_version=6.2 maven_group=me.zacharias -architectury_version=13.0.4 +architectury_version=13.0.8 -fabric_loader_version=0.15.11 -fabric_api_version=0.100.6+1.21 +fabric_loader_version=0.16.5 +fabric_api_version=0.105.0+1.21.1 -neoforge_version = 21.0.78-beta +neoforge_version = 21.1.66 -cloth_config_version = 15.0.127 \ No newline at end of file +cloth_config_version = 15.0.140 + +# Version of the org.json json library +json_version = 20240303 \ No newline at end of file diff --git a/neoforge/src/main/java/me/zacharias/speedometer/forge/SpeedometerNeoForge.java b/neoforge/src/main/java/me/zacharias/speedometer/forge/SpeedometerNeoForge.java index cdabfad..2d42c48 100644 --- a/neoforge/src/main/java/me/zacharias/speedometer/forge/SpeedometerNeoForge.java +++ b/neoforge/src/main/java/me/zacharias/speedometer/forge/SpeedometerNeoForge.java @@ -2,32 +2,60 @@ package me.zacharias.speedometer.forge; import com.mojang.datafixers.util.Unit; import me.zacharias.speedometer.Speedometer; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.AbstractPackResources; +import net.minecraft.server.packs.PackLocationInfo; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.KnownPack; +import net.minecraft.server.packs.repository.Pack; +import net.minecraft.server.packs.repository.PackSource; +import net.minecraft.server.packs.resources.IoSupplier; 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.IEventBus; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.neoforge.client.ClientNeoForgeMod; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.resource.ResourcePackLoader; +import org.jetbrains.annotations.Nullable; +import java.io.InputStream; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import static me.zacharias.speedometer.Speedometer.*; + @Mod(Speedometer.MOD_ID) public class SpeedometerNeoForge { - public SpeedometerNeoForge() { + public SpeedometerNeoForge(IEventBus eventBus) { // Submit our event bus to let architectury register our content on the right time Speedometer.init(); + + //ResourcePackLoader.buildPackFinder() } } @EventBusSubscriber(modid = Speedometer.MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) -class stuff +class EventHandler { + /** + * Register the reload listener for the speedometers + * This is required since i havent found how to put this in the Architecture Abstraction layer(Common module) + * TODO: Find a way to put this in the Abstraction layer + * @param event The event that is fired when the client reloads resources + */ @SubscribeEvent private static void onResourceReload(RegisterClientReloadListenersEvent event) { event.registerReloadListener(new SimplePreparableReloadListener() { @@ -42,4 +70,9 @@ class stuff } }); } + + @SubscribeEvent + private static void clientStart(FMLClientSetupEvent event) { + //Minecraft.getInstance().getResourcePackRepository().addPackFinder(consumer -> consumer.accept()); + } } \ No newline at end of file diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index eb8a06f..ed70f69 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -58,6 +58,9 @@ description=''' Just displaying your speed ''' +[[resource_packs]] + secondary = "resourcepacks/quarter_circle_speedometer" + # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.speedometer]] #optional # the modid of the dependency diff --git a/neoforge/src/main/resources/pack.mcmeta b/neoforge/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..b51a819 --- /dev/null +++ b/neoforge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "pack_format": 34, + "description": "speedometer resources" + } +} \ No newline at end of file diff --git a/resourcepack.md b/resourcepack.md index 2141324..ca70502 100644 --- a/resourcepack.md +++ b/resourcepack.md @@ -69,9 +69,11 @@ base - length *not required if `image` is not defined* The length in picture based on the original size of the background. - start - The start parameter defines where the pointer begins. You can use predefined strings (center, left, right) or specify a custom position using the format (x, y), where x and y are the coordinates. Alternatively, you can define an object with x and y keys to set exact positions. + The start parameter defines where the pointer begins. You can use predefined strings (center, left, right) or specify a custom position using the format (x, y), where x and y are the coordinates. Alternatively, you can define an object with x and y keys to set exact positions.
+ If you use this with an image, it's the point of where the pointer image is rotates around - image - This defines the scaling factor for speed. The actual speed is calculated as baseSpeed^scale, where the base speed is raised to the power of the scale. + This defines the scaling factor for speed. The actual speed is calculated as baseSpeed^scale, where the base speed is raised to the power of the scale.
+ OPS this picture should be the same size as the background to not cause issues - scale The scale of how to modify the speed as a power, this is the speed that `maxSpeed` is based of. the way the speed passed to `maxSpeed` is calculated is `baseSpeed^scale`. - name