From 6eee2ef2a778606b7d1cfdcd5d33d7c89c15486e Mon Sep 17 00:00:00 2001 From: gabidut Date: Sat, 23 Dec 2023 15:57:59 +0100 Subject: [PATCH 1/8] Small try --- .../fr/dynamx/addons/basics/BasicsAddon.java | 2 + .../common/infos/DashboardNeedleInfo.java | 171 ++++++++++++++++++ .../common/infos/SpeedDisplayInfos.java | 9 +- 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java diff --git a/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java b/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java index 5230f71..967b749 100644 --- a/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java +++ b/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java @@ -8,6 +8,7 @@ import fr.dynamx.addons.basics.utils.FuelJerrycanUtils; import fr.dynamx.addons.basics.utils.VehicleKeyUtils; import fr.dynamx.api.contentpack.DynamXAddon; +import fr.dynamx.api.contentpack.registry.DefinitionType; import fr.dynamx.common.contentpack.type.objects.ItemObject; import fr.dynamx.common.items.DynamXItem; import fr.dynamx.common.items.DynamXItemRegistry; @@ -18,6 +19,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraft.world.World; +import net.minecraftforge.common.util.EnumHelper; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Loader; diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java new file mode 100644 index 0000000..0fe8f36 --- /dev/null +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java @@ -0,0 +1,171 @@ +package fr.dynamx.addons.basics.common.infos; + +import com.jme3.math.Vector3f; +import fr.dynamx.api.contentpack.object.part.BasePart; +import fr.dynamx.api.contentpack.object.part.IDrawablePart; +import fr.dynamx.api.contentpack.registry.DefinitionType; +import fr.dynamx.api.contentpack.registry.PackFileProperty; +import fr.dynamx.api.contentpack.registry.RegisteredSubInfoType; +import fr.dynamx.api.contentpack.registry.SubInfoTypeRegistries; +import fr.dynamx.api.entities.VehicleEntityProperties; +import fr.dynamx.client.renders.model.renderer.DxModelRenderer; +import fr.dynamx.client.renders.scene.EntityRenderContext; +import fr.dynamx.client.renders.scene.SceneBuilder; +import fr.dynamx.client.renders.scene.SceneGraph; +import fr.dynamx.common.contentpack.type.vehicle.ModularVehicleInfo; +import fr.dynamx.common.entities.BaseVehicleEntity; +import fr.dynamx.common.entities.modules.engines.CarEngineModule; +import fr.dynamx.utils.DynamXUtils; +import net.minecraft.client.renderer.GlStateManager; +import org.lwjgl.opengl.GL11; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Objects; + +@RegisteredSubInfoType(name = "DashboardNeedle", registries = SubInfoTypeRegistries.WHEELED_VEHICLES, strictName = false) +public class DashboardNeedleInfo extends BasePart implements IDrawablePart, ModularVehicleInfo> { + @PackFileProperty(configNames = "Rotation", type = DefinitionType.DynamXDefinitionTypes.VECTOR3F) + protected Vector3f rotation; + + @PackFileProperty(configNames = "PartName", required = false, defaultValue = "speedneedle") + protected String partName; + + @PackFileProperty(configNames = "NeedleMaxTurn", required = false, defaultValue = "140", description = "common.NeedleMaxTurn") + protected int NeedleMaxTurn; + + @PackFileProperty(configNames = "DashboardMaxValue", required = false, defaultValue = "140", description = "common.DashboardMaxSpeed") + protected int DashboardMaxValue; + + @PackFileProperty(configNames = "DependsOnNode", required = false, description = "common.DependsOnNode") + protected String nodeDependingOnName; + + @PackFileProperty(configNames = "NeedleType", required = false, defaultValue = "SPEED", description = "common.NeedleType") + protected String needleType; + + @Override + public String[] getRenderedParts() { + return new String[0]; + } + + @Override + public String getNodeName() { + return "speedneedle"; + } + + @Override + public String getObjectName() { + return "speedneedle"; + } + + @Override + public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> sceneBuilder) { + if (nodeDependingOnName != null) { + sceneBuilder.addNode(this, nodeDependingOnName, getNodeName()); + } else { + sceneBuilder.addNode(this, getNodeName()); + } + } + + @Override + public SceneGraph, ModularVehicleInfo> createSceneGraph(Vector3f modelScale, List, ModularVehicleInfo>> childGraph) { + if(childGraph != null) + throw new IllegalArgumentException("DashboardNeedleInfo can't have children parts"); + return new SpeedNeedleNode<>(modelScale, null); + } + @Override + public String getName() { + return "PartShape named " + getPartName() + " in " + Objects.requireNonNull(getOwner()).getName(); + } + + public int getNeedleMaxTurn() { + return NeedleMaxTurn; + } + + public int getDashboardMaxValue() { + return DashboardMaxValue; + } + + public String getNeedleType() { + return needleType; + } + + public Vector3f getRotation() { + + return rotation; + } + + public String getNodeDependingOnName() { + return this.nodeDependingOnName; + } + + public DashboardNeedleInfo(ModularVehicleInfo owner, String partName) { + super(owner, partName); + } + + @Override + public String getPartName() { + return "speedneedle"; + } + + class SpeedNeedleNode, A extends ModularVehicleInfo> extends SceneGraph.Node { + + public SpeedNeedleNode(Vector3f scale, List> linkedChilds) { + super(null, null, scale, linkedChilds); + } + + @Override + public void render(@Nullable T t, EntityRenderContext entityRenderContext, A a) { + + + if (t == null) return; + DxModelRenderer vehicleModel = entityRenderContext.getModel(); + byte b = entityRenderContext.getTextureId(); + +// if(vehicleModel instanceof ObjModelRenderer) { +// ObjModelRenderer vehicleModel1 = (ObjModelRenderer) entityRenderContext.getModel(); +// System.out.println(vehicleModel1.getObjObjects()); +// } + + + if (entityRenderContext.getModel().containsObjectOrNode(DashboardNeedleInfo.this.getPartName()) && t.getModuleByType(CarEngineModule.class) != null && DashboardNeedleInfo.this.getPosition() != null) { + GlStateManager.pushMatrix(); + + + Vector3f pos = DashboardNeedleInfo.this.getPosition(); + GL11.glTranslatef(pos.x, pos.y, pos.z); + +// DynamXRenderUtils.drawSphere(new Vector3f(0,0,0), 0.1f, Color.YELLOW); + + try { + assert getRotation() != null; + float rotate = getRotation().x; + if (rotate != 0) + GlStateManager.rotate(rotate, 1, 0, 0); + rotate = getRotation().y; + if (rotate != 0) + GlStateManager.rotate(rotate, 0, 1, 0); + rotate = getRotation().z; + if (rotate != 0) + GlStateManager.rotate(rotate, 0, 0, 1); + + } catch (NullPointerException e) { + e.printStackTrace(); + } + + if(Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "SPEED")) { + + GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * DynamXUtils.getSpeed(t) / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); + } else if(Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "RPM")) { +// GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * DynamXUtils.getSpeed(t) / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); + GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * t.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) / DashboardNeedleInfo.this.NeedleMaxTurn, 0, 0, 1); + } + + vehicleModel.renderGroup(DashboardNeedleInfo.this.getPartName(), b, entityRenderContext.isUseVanillaRender()); + + GlStateManager.popMatrix(); + } + } + } + +} diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java index 575ca3e..b7b9c5c 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java @@ -15,8 +15,10 @@ import fr.dynamx.common.contentpack.type.vehicle.ModularVehicleInfo; import fr.dynamx.common.entities.BaseVehicleEntity; import fr.dynamx.utils.DynamXUtils; +import fr.dynamx.utils.client.DynamXRenderUtils; import javax.annotation.Nullable; +import java.awt.*; import java.util.List; @RegisteredSubInfoType( @@ -104,7 +106,12 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, if (entity == null) return; String speed = "" + DynamXUtils.getSpeed(entity); - TextUtils.drawText(SpeedDisplayInfos.this.getPosition(), SpeedDisplayInfos.this.getScale(), SpeedDisplayInfos.this.getRotation(), speed, getColor(), getFont()); + if(SpeedDisplayInfos.this.getRotation() != null) { + TextUtils.drawText(SpeedDisplayInfos.this.getPosition(), SpeedDisplayInfos.this.getScale(), SpeedDisplayInfos.this.getRotation(), speed, getColor(), getFont()); + + } + else + System.out.println("cpt"); } } } \ No newline at end of file From bd23c7b537886b58a6f0bf89cf28a5f1dd932650 Mon Sep 17 00:00:00 2001 From: gabidut Date: Sat, 23 Dec 2023 20:34:48 +0100 Subject: [PATCH 2/8] Needle totally works --- .../common/infos/DashboardNeedleInfo.java | 22 ++++++++----------- .../common/infos/SpeedDisplayInfos.java | 3 --- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java index 0fe8f36..17a265e 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java @@ -28,8 +28,8 @@ public class DashboardNeedleInfo extends BasePart implements @PackFileProperty(configNames = "Rotation", type = DefinitionType.DynamXDefinitionTypes.VECTOR3F) protected Vector3f rotation; - @PackFileProperty(configNames = "PartName", required = false, defaultValue = "speedneedle") - protected String partName; + @PackFileProperty(configNames = "ObjectName", required = false, defaultValue = "speedneedle") + protected String objectName; @PackFileProperty(configNames = "NeedleMaxTurn", required = false, defaultValue = "140", description = "common.NeedleMaxTurn") protected int NeedleMaxTurn; @@ -50,12 +50,12 @@ public String[] getRenderedParts() { @Override public String getNodeName() { - return "speedneedle"; + return getPartName(); } @Override public String getObjectName() { - return "speedneedle"; + return this.objectName; } @Override @@ -103,10 +103,6 @@ public DashboardNeedleInfo(ModularVehicleInfo owner, String partName) { super(owner, partName); } - @Override - public String getPartName() { - return "speedneedle"; - } class SpeedNeedleNode, A extends ModularVehicleInfo> extends SceneGraph.Node { @@ -128,7 +124,8 @@ public void render(@Nullable T t, EntityRenderContext entityRenderContext, A a) // } - if (entityRenderContext.getModel().containsObjectOrNode(DashboardNeedleInfo.this.getPartName()) && t.getModuleByType(CarEngineModule.class) != null && DashboardNeedleInfo.this.getPosition() != null) { + + if (entityRenderContext.getModel().containsObjectOrNode(DashboardNeedleInfo.this.getObjectName()) && t.getModuleByType(CarEngineModule.class) != null && DashboardNeedleInfo.this.getPosition() != null) { GlStateManager.pushMatrix(); @@ -154,14 +151,13 @@ public void render(@Nullable T t, EntityRenderContext entityRenderContext, A a) } if(Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "SPEED")) { - GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * DynamXUtils.getSpeed(t) / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); } else if(Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "RPM")) { -// GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * DynamXUtils.getSpeed(t) / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); - GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * t.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) / DashboardNeedleInfo.this.NeedleMaxTurn, 0, 0, 1); + int rpms = Math.round(t.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) * 10000 ); + GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * rpms / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); } - vehicleModel.renderGroup(DashboardNeedleInfo.this.getPartName(), b, entityRenderContext.isUseVanillaRender()); + vehicleModel.renderGroup(DashboardNeedleInfo.this.getObjectName(), b, entityRenderContext.isUseVanillaRender()); GlStateManager.popMatrix(); } diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java index b7b9c5c..537c83b 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java @@ -108,10 +108,7 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, String speed = "" + DynamXUtils.getSpeed(entity); if(SpeedDisplayInfos.this.getRotation() != null) { TextUtils.drawText(SpeedDisplayInfos.this.getPosition(), SpeedDisplayInfos.this.getScale(), SpeedDisplayInfos.this.getRotation(), speed, getColor(), getFont()); - } - else - System.out.println("cpt"); } } } \ No newline at end of file From 27ae1a876fa5d8e4b93ede0e45a3aebfeb8ec512 Mon Sep 17 00:00:00 2001 From: gabidut Date: Sat, 23 Dec 2023 21:02:41 +0100 Subject: [PATCH 3/8] Added dashboard details & added infos on readme --- README.md | 49 ++++++ exemple.png | Bin 0 -> 75942 bytes .../common/infos/DashboardTextInfos.java | 151 ++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 exemple.png create mode 100644 src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java diff --git a/README.md b/README.md index 51fa7ba..a4de513 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,55 @@ FuelTank#Op{ } ``` +#### Better speed-display + +``` +TextInfo#Op{ + Position: 0 0 0 + Scale: 1 1 1 + Rotation: 0 0 0 + Color: 0 0 0 + DetailToShow: GEAR + CarStartedReact: True +} +``` + +The `DetailToShow` can be one of the following: + - GEAR + - SPEED + - SPEEDLIMITOR + +It will display the current gear, speed or speedlimitor value at the position. + +The `CarStartedReact` can be `True` or `False` and will enable or disable the display when the car is started. + +### DashboardNeedle + +``` +DashboardNeedle_2 { + Position: 0 0 0 + Rotation: 0 0 -120 + ObjectName: speedneedle + NeedleMaxTurn: 160 + DashboardMaxValue: 6000 + NeedleType: RPM +} +``` + +| Key | Value | +|------------------- |------------------------------------------ | +| Rotation | Default rotation | +| Position | Default position | +| ObjectName | Name of the object in the 3D model | +| NeedleMaxTurn | Max rotation in degrees on the dashboard | +| DashboardMaxValue | Max value displayed on dashboard | +| NeedleType | It can be `RPM` or `SPEED` | + + +
+ +> Here for RPM, max DashboardMaxValue is 6000 and max NeedleMaxTurn is 160. + ## Links DynamX website: https://dynamx.fr diff --git a/exemple.png b/exemple.png new file mode 100644 index 0000000000000000000000000000000000000000..b391d52501f164f51dae1b250e24eefc52405479 GIT binary patch literal 75942 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 z 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

w53WZwXqu;UTk^l`T2bFIA3u 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 literal 0 HcmV?d00001 diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java new file mode 100644 index 0000000..cfcea5e --- /dev/null +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java @@ -0,0 +1,151 @@ +package fr.dynamx.addons.basics.common.infos; + +import com.jme3.math.Vector3f; +import fr.dynamx.addons.basics.BasicsAddon; +import fr.dynamx.addons.basics.utils.TextUtils; +import fr.dynamx.api.contentpack.object.part.BasePart; +import fr.dynamx.api.contentpack.object.part.IDrawablePart; +import fr.dynamx.api.contentpack.registry.DefinitionType; +import fr.dynamx.api.contentpack.registry.PackFileProperty; +import fr.dynamx.api.contentpack.registry.RegisteredSubInfoType; +import fr.dynamx.api.contentpack.registry.SubInfoTypeRegistries; +import fr.dynamx.api.entities.VehicleEntityProperties; +import fr.dynamx.client.renders.scene.EntityRenderContext; +import fr.dynamx.client.renders.scene.SceneBuilder; +import fr.dynamx.client.renders.scene.SceneGraph; +import fr.dynamx.common.contentpack.type.vehicle.ModularVehicleInfo; +import fr.dynamx.common.entities.BaseVehicleEntity; +import fr.dynamx.common.entities.modules.engines.CarEngineModule; +import fr.dynamx.utils.DynamXUtils; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Objects; + +@RegisteredSubInfoType( + name = "TextInfo", + registries = {SubInfoTypeRegistries.WHEELED_VEHICLES}, + strictName = false +) +public class DashboardTextInfos extends BasePart implements IDrawablePart, ModularVehicleInfo> { + @PackFileProperty(configNames = "Rotation", type = DefinitionType.DynamXDefinitionTypes.VECTOR3F, description = "common.rotation") + protected Vector3f rotation; + + @PackFileProperty(configNames = "Font", required = false) + protected String font = BasicsAddon.ID + ":e"; + + @PackFileProperty(configNames = "DetailToShow", required = false, defaultValue = "GEAR") + protected String DetailToShow; + @PackFileProperty(configNames = "CarStartedReact", required = false, defaultValue = "false", type = DefinitionType.DynamXDefinitionTypes.BOOL) + protected boolean CarStartedReact; + + @PackFileProperty(configNames = "Color", description = "common.color", required = false) + protected int[] color = new int[]{10, 10, 10}; + + @PackFileProperty(configNames = "DependsOnNode", required = false, description = "common.DependsOnNode") + protected String nodeDependingOnName; + + public DashboardTextInfos(ModularVehicleInfo owner, String partName) { + super(owner, partName); + } + + @Override + public void appendTo(ModularVehicleInfo owner) { + owner.addSubProperty(this); + } + + public Vector3f getRotation() { + return rotation; + } + + public int[] getColor() { + return color; + } + + public boolean isCarStartedReact() { + return CarStartedReact; + } + + public String getFont() { + return font; + } + + public String getDetailToShow() { + return DetailToShow; + } + + @Override + public String getName() { + return "PartShape named " + getPartName() + " in " + getOwner().getName(); + } + + @Override + public String getObjectName() { + return null; + } + + @Override + public String[] getRenderedParts() { + return new String[0]; + } + + @Override + public String getNodeName() { + + return getPartName(); + } + + @Override + public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> sceneBuilder) { + if (nodeDependingOnName != null) { + sceneBuilder.addNode(this, nodeDependingOnName, getNodeName()); + } else { + sceneBuilder.addNode(this, getNodeName()); + } + } + + @Override + public SceneGraph, ModularVehicleInfo> createSceneGraph(Vector3f modelScale, List, ModularVehicleInfo>> childGraph) { + if(childGraph != null) + throw new IllegalArgumentException("TextInfo can't have children parts"); + return new SpeedDisplayNode<>(modelScale, null); + } + + class SpeedDisplayNode, A extends ModularVehicleInfo> extends SceneGraph.Node { + public SpeedDisplayNode(Vector3f scale, List> linkedChilds) { + super(null, null, scale, linkedChilds); + } + + @Override + public void render(@Nullable T entity, EntityRenderContext entityRenderContext, A packInfo) { + if (entity == null) + return; + if(DashboardTextInfos.this.getRotation() != null) { + if(entity.getModuleByType(CarEngineModule.class).getPhysicsHandler().getEngine().isStarted() && DashboardTextInfos.this.isCarStartedReact()) { + if(Objects.equals(DashboardTextInfos.this.getDetailToShow(), "GEAR")) { + String value = ""; + float gear = entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.ACTIVE_GEAR); + if(gear == 0) { + value = "N"; + } else if(gear == -1) { + value = "R" + (int) Math.abs(gear); + } else { + value = "D" + (int) gear; + } + TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), value, getColor(), getFont()); + } + if(Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEEDLIMITOR")) { + int value = Math.round(entity.getModuleByType(CarEngineModule.class).getSpeedLimit()); + if(value != 0 & value < 10000000) { + TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), String.valueOf(value), getColor(), getFont()); + } + } + if(Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEED")) { + int value = DynamXUtils.getSpeed(entity); + TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), String.valueOf(value), getColor(), getFont()); + } + } + } + } + } +} \ No newline at end of file From 8256bc0ff365ea2ed367832eb1513f7f31f6e000 Mon Sep 17 00:00:00 2001 From: gabidut Date: Sat, 23 Dec 2023 21:08:13 +0100 Subject: [PATCH 4/8] (corrected readme) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a4de513..c02592a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ This addon adds new features to DynamX : - Klaxon and siren - Fuel tank - Immatriculation plates -- Speed display on the vehicle +- Speed, gear and speed limit display on the vehicle +- Needle ### How to add modules: From be914514185e6ba70de63ef8276a0a5acbff7294 Mon Sep 17 00:00:00 2001 From: gabidut Date: Sun, 24 Dec 2023 12:08:08 +0100 Subject: [PATCH 5/8] Cleaning code --- .../common/infos/DashboardNeedleInfo.java | 71 +++++-------------- .../common/infos/DashboardTextInfos.java | 51 ++++++------- .../common/infos/SpeedDisplayInfos.java | 6 +- .../dynamx/addons/basics/utils/TextUtils.java | 22 +++--- 4 files changed, 52 insertions(+), 98 deletions(-) diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java index 17a265e..336ee32 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java @@ -1,6 +1,7 @@ package fr.dynamx.addons.basics.common.infos; import com.jme3.math.Vector3f; +import fr.dynamx.addons.basics.utils.TextUtils; import fr.dynamx.api.contentpack.object.part.BasePart; import fr.dynamx.api.contentpack.object.part.IDrawablePart; import fr.dynamx.api.contentpack.registry.DefinitionType; @@ -24,7 +25,7 @@ import java.util.Objects; @RegisteredSubInfoType(name = "DashboardNeedle", registries = SubInfoTypeRegistries.WHEELED_VEHICLES, strictName = false) -public class DashboardNeedleInfo extends BasePart implements IDrawablePart, ModularVehicleInfo> { +public class DashboardNeedleInfo extends BasePart implements IDrawablePart, ModularVehicleInfo> { @PackFileProperty(configNames = "Rotation", type = DefinitionType.DynamXDefinitionTypes.VECTOR3F) protected Vector3f rotation; @@ -32,10 +33,10 @@ public class DashboardNeedleInfo extends BasePart implements protected String objectName; @PackFileProperty(configNames = "NeedleMaxTurn", required = false, defaultValue = "140", description = "common.NeedleMaxTurn") - protected int NeedleMaxTurn; + protected int needleMaxTurn; @PackFileProperty(configNames = "DashboardMaxValue", required = false, defaultValue = "140", description = "common.DashboardMaxSpeed") - protected int DashboardMaxValue; + protected int dashboardMaxValue; @PackFileProperty(configNames = "DependsOnNode", required = false, description = "common.DependsOnNode") protected String nodeDependingOnName; @@ -43,11 +44,6 @@ public class DashboardNeedleInfo extends BasePart implements @PackFileProperty(configNames = "NeedleType", required = false, defaultValue = "SPEED", description = "common.NeedleType") protected String needleType; - @Override - public String[] getRenderedParts() { - return new String[0]; - } - @Override public String getNodeName() { return getPartName(); @@ -69,21 +65,21 @@ public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> createSceneGraph(Vector3f modelScale, List, ModularVehicleInfo>> childGraph) { - if(childGraph != null) - throw new IllegalArgumentException("DashboardNeedleInfo can't have children parts"); + if (childGraph != null) throw new IllegalArgumentException("DashboardNeedleInfo can't have children parts"); return new SpeedNeedleNode<>(modelScale, null); } + @Override public String getName() { return "PartShape named " + getPartName() + " in " + Objects.requireNonNull(getOwner()).getName(); } public int getNeedleMaxTurn() { - return NeedleMaxTurn; + return needleMaxTurn; } public int getDashboardMaxValue() { - return DashboardMaxValue; + return dashboardMaxValue; } public String getNeedleType() { @@ -91,7 +87,6 @@ public String getNeedleType() { } public Vector3f getRotation() { - return rotation; } @@ -111,54 +106,22 @@ public SpeedNeedleNode(Vector3f scale, List> linkedChilds) { } @Override - public void render(@Nullable T t, EntityRenderContext entityRenderContext, A a) { - - - if (t == null) return; + public void render(@Nullable T entity, EntityRenderContext entityRenderContext, A packInfo) { + if (entity == null) return; DxModelRenderer vehicleModel = entityRenderContext.getModel(); byte b = entityRenderContext.getTextureId(); - -// if(vehicleModel instanceof ObjModelRenderer) { -// ObjModelRenderer vehicleModel1 = (ObjModelRenderer) entityRenderContext.getModel(); -// System.out.println(vehicleModel1.getObjObjects()); -// } - - - - if (entityRenderContext.getModel().containsObjectOrNode(DashboardNeedleInfo.this.getObjectName()) && t.getModuleByType(CarEngineModule.class) != null && DashboardNeedleInfo.this.getPosition() != null) { + if (entityRenderContext.getModel().containsObjectOrNode(DashboardNeedleInfo.this.getObjectName()) && entity.getModuleByType(CarEngineModule.class) != null && DashboardNeedleInfo.this.getPosition() != null) { GlStateManager.pushMatrix(); - - Vector3f pos = DashboardNeedleInfo.this.getPosition(); GL11.glTranslatef(pos.x, pos.y, pos.z); - -// DynamXRenderUtils.drawSphere(new Vector3f(0,0,0), 0.1f, Color.YELLOW); - - try { - assert getRotation() != null; - float rotate = getRotation().x; - if (rotate != 0) - GlStateManager.rotate(rotate, 1, 0, 0); - rotate = getRotation().y; - if (rotate != 0) - GlStateManager.rotate(rotate, 0, 1, 0); - rotate = getRotation().z; - if (rotate != 0) - GlStateManager.rotate(rotate, 0, 0, 1); - - } catch (NullPointerException e) { - e.printStackTrace(); + TextUtils.makeGLRotation(getRotation()); + if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "SPEED")) { + GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * DynamXUtils.getSpeed(entity) / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); + } else if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "RPM")) { + int rpms = Math.round(entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) * 10000); + GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * rpms / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); } - - if(Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "SPEED")) { - GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * DynamXUtils.getSpeed(t) / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); - } else if(Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "RPM")) { - int rpms = Math.round(t.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) * 10000 ); - GlStateManager.rotate((float) DashboardNeedleInfo.this.NeedleMaxTurn * rpms / DashboardNeedleInfo.this.DashboardMaxValue, 0, 0, 1); - } - vehicleModel.renderGroup(DashboardNeedleInfo.this.getObjectName(), b, entityRenderContext.isUseVanillaRender()); - GlStateManager.popMatrix(); } } diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java index cfcea5e..fc88342 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java @@ -35,9 +35,9 @@ public class DashboardTextInfos extends BasePart implements protected String font = BasicsAddon.ID + ":e"; @PackFileProperty(configNames = "DetailToShow", required = false, defaultValue = "GEAR") - protected String DetailToShow; + protected String detailToShow; @PackFileProperty(configNames = "CarStartedReact", required = false, defaultValue = "false", type = DefinitionType.DynamXDefinitionTypes.BOOL) - protected boolean CarStartedReact; + protected boolean carStartedReact; @PackFileProperty(configNames = "Color", description = "common.color", required = false) protected int[] color = new int[]{10, 10, 10}; @@ -63,7 +63,7 @@ public int[] getColor() { } public boolean isCarStartedReact() { - return CarStartedReact; + return carStartedReact; } public String getFont() { @@ -71,7 +71,7 @@ public String getFont() { } public String getDetailToShow() { - return DetailToShow; + return detailToShow; } @Override @@ -84,10 +84,6 @@ public String getObjectName() { return null; } - @Override - public String[] getRenderedParts() { - return new String[0]; - } @Override public String getNodeName() { @@ -106,7 +102,7 @@ public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> createSceneGraph(Vector3f modelScale, List, ModularVehicleInfo>> childGraph) { - if(childGraph != null) + if (childGraph != null) throw new IllegalArgumentException("TextInfo can't have children parts"); return new SpeedDisplayNode<>(modelScale, null); } @@ -120,30 +116,23 @@ public SpeedDisplayNode(Vector3f scale, List> linkedChilds) { public void render(@Nullable T entity, EntityRenderContext entityRenderContext, A packInfo) { if (entity == null) return; - if(DashboardTextInfos.this.getRotation() != null) { - if(entity.getModuleByType(CarEngineModule.class).getPhysicsHandler().getEngine().isStarted() && DashboardTextInfos.this.isCarStartedReact()) { - if(Objects.equals(DashboardTextInfos.this.getDetailToShow(), "GEAR")) { - String value = ""; + if (DashboardTextInfos.this.getRotation() != null) { + if (entity.getModuleByType(CarEngineModule.class).getPhysicsHandler().getEngine().isStarted() && DashboardTextInfos.this.isCarStartedReact()) { + String value = ""; + if (Objects.equals(DashboardTextInfos.this.getDetailToShow(), "GEAR")) { float gear = entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.ACTIVE_GEAR); - if(gear == 0) { - value = "N"; - } else if(gear == -1) { - value = "R" + (int) Math.abs(gear); - } else { - value = "D" + (int) gear; - } - TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), value, getColor(), getFont()); - } - if(Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEEDLIMITOR")) { - int value = Math.round(entity.getModuleByType(CarEngineModule.class).getSpeedLimit()); - if(value != 0 & value < 10000000) { - TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), String.valueOf(value), getColor(), getFont()); - } - } - if(Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEED")) { - int value = DynamXUtils.getSpeed(entity); - TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), String.valueOf(value), getColor(), getFont()); + if (gear == 0) value = "N"; + else if (gear == -1) value = "R" + (int) Math.abs(gear); + else value = "D" + (int) gear; + } else if (Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEEDLIMITOR")) { + int tempvalue = Math.round(entity.getModuleByType(CarEngineModule.class).getSpeedLimit()); + if (tempvalue != 0 & tempvalue < 10000000) value = String.valueOf(tempvalue); + else value = ""; + } else if (Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEED")) { + value = String.valueOf(DynamXUtils.getSpeed(entity)); + } + TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), value, getColor(), getFont()); } } } diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java index 537c83b..539b5ba 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java @@ -15,10 +15,8 @@ import fr.dynamx.common.contentpack.type.vehicle.ModularVehicleInfo; import fr.dynamx.common.entities.BaseVehicleEntity; import fr.dynamx.utils.DynamXUtils; -import fr.dynamx.utils.client.DynamXRenderUtils; import javax.annotation.Nullable; -import java.awt.*; import java.util.List; @RegisteredSubInfoType( @@ -91,7 +89,7 @@ public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> createSceneGraph(Vector3f modelScale, List, ModularVehicleInfo>> childGraph) { - if(childGraph != null) + if (childGraph != null) throw new IllegalArgumentException("SpeedDisplayInfos can't have children parts"); return new SpeedDisplayNode<>(modelScale, null); } @@ -106,7 +104,7 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, if (entity == null) return; String speed = "" + DynamXUtils.getSpeed(entity); - if(SpeedDisplayInfos.this.getRotation() != null) { + if (SpeedDisplayInfos.this.getRotation() != null) { TextUtils.drawText(SpeedDisplayInfos.this.getPosition(), SpeedDisplayInfos.this.getScale(), SpeedDisplayInfos.this.getRotation(), speed, getColor(), getFont()); } } diff --git a/src/main/java/fr/dynamx/addons/basics/utils/TextUtils.java b/src/main/java/fr/dynamx/addons/basics/utils/TextUtils.java index e5fccc8..b879898 100644 --- a/src/main/java/fr/dynamx/addons/basics/utils/TextUtils.java +++ b/src/main/java/fr/dynamx/addons/basics/utils/TextUtils.java @@ -19,15 +19,7 @@ public static void drawText(Vector3f pos, Vector3f scale, Vector3f rotation, Str GlStateManager.translate(pos.x, pos.y, pos.z); GlStateManager.rotate(180, 1, 0, 0); GlStateManager.rotate(180, 0, 1, 0); - float rotate = rotation.x; - if (rotate != 0) - GlStateManager.rotate(rotate, 1, 0, 0); - rotate = rotation.y; - if (rotate != 0) - GlStateManager.rotate(rotate, 0, 1, 0); - rotate = rotation.z; - if (rotate != 0) - GlStateManager.rotate(rotate, 0, 0, 1); + makeGLRotation(rotation); GlStateManager.scale(scale.x / 40, scale.y / 40, scale.z / 40); GlStateManager.disableLighting(); @@ -45,4 +37,16 @@ public static void drawText(Vector3f pos, Vector3f scale, Vector3f rotation, Str GlStateManager.popMatrix(); } } + + public static void makeGLRotation(Vector3f rotation) { + float rotate = rotation.x; + if (rotate != 0) + GlStateManager.rotate(rotate, 1, 0, 0); + rotate = rotation.y; + if (rotate != 0) + GlStateManager.rotate(rotate, 0, 1, 0); + rotate = rotation.z; + if (rotate != 0) + GlStateManager.rotate(rotate, 0, 0, 1); + } } From a3242ccdeba07ec45ce3e1bb0d5bde2bf2b7f6e1 Mon Sep 17 00:00:00 2001 From: gabidut Date: Sun, 24 Dec 2023 14:10:54 +0100 Subject: [PATCH 6/8] Added enums --- .../fr/dynamx/addons/basics/BasicsAddon.java | 6 +++-- .../common/infos/DashboardNeedleInfo.java | 21 +++++++++++++--- .../common/infos/DashboardTextInfos.java | 25 ++++++++++++------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java b/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java index 967b749..8e7ac79 100644 --- a/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java +++ b/src/main/java/fr/dynamx/addons/basics/BasicsAddon.java @@ -4,6 +4,8 @@ import fr.dynamx.addons.basics.client.BasicsAddonController; import fr.dynamx.addons.basics.client.InteractionKeyController; import fr.dynamx.addons.basics.common.infos.BasicsItemInfo; +import fr.dynamx.addons.basics.common.infos.DashboardNeedleInfo.EnumDashboardNeedleType; +import fr.dynamx.addons.basics.common.infos.DashboardTextInfos.EnumDashboardTextType; import fr.dynamx.addons.basics.server.CommandBasicsSpawn; import fr.dynamx.addons.basics.utils.FuelJerrycanUtils; import fr.dynamx.addons.basics.utils.VehicleKeyUtils; @@ -19,10 +21,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraft.world.World; -import net.minecraftforge.common.util.EnumHelper; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.relauncher.Side; @@ -49,6 +49,8 @@ public static void initAddon() { } registerKey(); registerJerrycan(); + new DefinitionType<>(EnumDashboardNeedleType.class, EnumDashboardNeedleType::fromString, "type.dashboardneedletype"); + new DefinitionType<>(EnumDashboardTextType.class, EnumDashboardTextType::fromString, "type.dashboardtexttype"); } private static void registerKey() { diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java index 336ee32..637db53 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java @@ -42,7 +42,7 @@ public class DashboardNeedleInfo extends BasePart implements protected String nodeDependingOnName; @PackFileProperty(configNames = "NeedleType", required = false, defaultValue = "SPEED", description = "common.NeedleType") - protected String needleType; + protected EnumDashboardNeedleType needleType; @Override public String getNodeName() { @@ -82,7 +82,7 @@ public int getDashboardMaxValue() { return dashboardMaxValue; } - public String getNeedleType() { + public EnumDashboardNeedleType getNeedleType() { return needleType; } @@ -115,9 +115,9 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, Vector3f pos = DashboardNeedleInfo.this.getPosition(); GL11.glTranslatef(pos.x, pos.y, pos.z); TextUtils.makeGLRotation(getRotation()); - if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "SPEED")) { + if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), EnumDashboardNeedleType.SPEED)) { GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * DynamXUtils.getSpeed(entity) / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); - } else if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), "RPM")) { + } else if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), EnumDashboardNeedleType.RPM)) { int rpms = Math.round(entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) * 10000); GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * rpms / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); } @@ -127,4 +127,17 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, } } + public enum EnumDashboardNeedleType { + SPEED, RPM; + + public static EnumDashboardNeedleType fromString(String targetName) { + for (EnumDashboardNeedleType dashboardNeedleType : values()) { + if (dashboardNeedleType.name().equalsIgnoreCase(targetName)) { + return dashboardNeedleType; + } + } + throw new IllegalArgumentException("Invalid DashboardNeedleType value '" + targetName + "'"); + } + } + } diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java index fc88342..46f12dd 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java @@ -22,11 +22,7 @@ import java.util.List; import java.util.Objects; -@RegisteredSubInfoType( - name = "TextInfo", - registries = {SubInfoTypeRegistries.WHEELED_VEHICLES}, - strictName = false -) +@RegisteredSubInfoType(name = "TextInfo", registries = {SubInfoTypeRegistries.WHEELED_VEHICLES}, strictName = false) public class DashboardTextInfos extends BasePart implements IDrawablePart, ModularVehicleInfo> { @PackFileProperty(configNames = "Rotation", type = DefinitionType.DynamXDefinitionTypes.VECTOR3F, description = "common.rotation") protected Vector3f rotation; @@ -102,8 +98,7 @@ public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> createSceneGraph(Vector3f modelScale, List, ModularVehicleInfo>> childGraph) { - if (childGraph != null) - throw new IllegalArgumentException("TextInfo can't have children parts"); + if (childGraph != null) throw new IllegalArgumentException("TextInfo can't have children parts"); return new SpeedDisplayNode<>(modelScale, null); } @@ -114,8 +109,7 @@ public SpeedDisplayNode(Vector3f scale, List> linkedChilds) { @Override public void render(@Nullable T entity, EntityRenderContext entityRenderContext, A packInfo) { - if (entity == null) - return; + if (entity == null) return; if (DashboardTextInfos.this.getRotation() != null) { if (entity.getModuleByType(CarEngineModule.class).getPhysicsHandler().getEngine().isStarted() && DashboardTextInfos.this.isCarStartedReact()) { String value = ""; @@ -137,4 +131,17 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, } } } + + public enum EnumDashboardTextType { + SPEED, GEAR, SPEEDLIMITOR; + + public static EnumDashboardTextType fromString(String targetName) { + for (EnumDashboardTextType dashboardNeedleType : values()) { + if (dashboardNeedleType.name().equalsIgnoreCase(targetName)) { + return dashboardNeedleType; + } + } + throw new IllegalArgumentException("Invalid EnumDashboardTextType value '" + targetName + "'"); + } + } } \ No newline at end of file From 707a44735602adef2dbc37b9d52af1f77a9f7ab5 Mon Sep 17 00:00:00 2001 From: gabidut Date: Sun, 24 Dec 2023 15:01:58 +0100 Subject: [PATCH 7/8] Added switchs --- .../common/infos/DashboardNeedleInfo.java | 13 +++++--- .../common/infos/DashboardTextInfos.java | 31 ++++++++++--------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java index 637db53..c303f3b 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardNeedleInfo.java @@ -115,11 +115,14 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, Vector3f pos = DashboardNeedleInfo.this.getPosition(); GL11.glTranslatef(pos.x, pos.y, pos.z); TextUtils.makeGLRotation(getRotation()); - if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), EnumDashboardNeedleType.SPEED)) { - GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * DynamXUtils.getSpeed(entity) / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); - } else if (Objects.equals(DashboardNeedleInfo.this.getNeedleType(), EnumDashboardNeedleType.RPM)) { - int rpms = Math.round(entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) * 10000); - GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * rpms / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); + switch (DashboardNeedleInfo.this.getNeedleType()) { + case RPM: + int rpms = Math.round(entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.REVS) * 10000); + GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * rpms / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); + break; + case SPEED: + GlStateManager.rotate((float) DashboardNeedleInfo.this.needleMaxTurn * DynamXUtils.getSpeed(entity) / DashboardNeedleInfo.this.dashboardMaxValue, 0, 0, 1); + break; } vehicleModel.renderGroup(DashboardNeedleInfo.this.getObjectName(), b, entityRenderContext.isUseVanillaRender()); GlStateManager.popMatrix(); diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java index 46f12dd..550bf04 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/DashboardTextInfos.java @@ -31,7 +31,7 @@ public class DashboardTextInfos extends BasePart implements protected String font = BasicsAddon.ID + ":e"; @PackFileProperty(configNames = "DetailToShow", required = false, defaultValue = "GEAR") - protected String detailToShow; + protected EnumDashboardTextType detailToShow; @PackFileProperty(configNames = "CarStartedReact", required = false, defaultValue = "false", type = DefinitionType.DynamXDefinitionTypes.BOOL) protected boolean carStartedReact; @@ -66,7 +66,7 @@ public String getFont() { return font; } - public String getDetailToShow() { + public EnumDashboardTextType getDetailToShow() { return detailToShow; } @@ -113,18 +113,21 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, if (DashboardTextInfos.this.getRotation() != null) { if (entity.getModuleByType(CarEngineModule.class).getPhysicsHandler().getEngine().isStarted() && DashboardTextInfos.this.isCarStartedReact()) { String value = ""; - if (Objects.equals(DashboardTextInfos.this.getDetailToShow(), "GEAR")) { - float gear = entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.ACTIVE_GEAR); - if (gear == 0) value = "N"; - else if (gear == -1) value = "R" + (int) Math.abs(gear); - else value = "D" + (int) gear; - } else if (Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEEDLIMITOR")) { - int tempvalue = Math.round(entity.getModuleByType(CarEngineModule.class).getSpeedLimit()); - if (tempvalue != 0 & tempvalue < 10000000) value = String.valueOf(tempvalue); - else value = ""; - } else if (Objects.equals(DashboardTextInfos.this.getDetailToShow(), "SPEED")) { - value = String.valueOf(DynamXUtils.getSpeed(entity)); - + switch (DashboardTextInfos.this.getDetailToShow()) { + case GEAR: + float gear = entity.getModuleByType(CarEngineModule.class).getEngineProperty(VehicleEntityProperties.EnumEngineProperties.ACTIVE_GEAR); + if (gear == 0) value = "N"; + else if (gear == -1) value = "R" + (int) Math.abs(gear); + else value = "D" + (int) gear; + break; + case SPEEDLIMITOR: + int tempvalue = Math.round(entity.getModuleByType(CarEngineModule.class).getSpeedLimit()); + if (tempvalue != 0 & tempvalue < 10000000) value = String.valueOf(tempvalue); + else value = ""; + break; + case SPEED: + value = String.valueOf(DynamXUtils.getSpeed(entity)); + break; } TextUtils.drawText(DashboardTextInfos.this.getPosition(), DashboardTextInfos.this.getScale(), DashboardTextInfos.this.getRotation(), value, getColor(), getFont()); } From f81f6b55089683947d08c3e6aef9740c38cdaf4b Mon Sep 17 00:00:00 2001 From: gabidut Date: Sun, 24 Dec 2023 15:05:18 +0100 Subject: [PATCH 8/8] Small correction* --- .../addons/basics/common/infos/SpeedDisplayInfos.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java index 539b5ba..30b7823 100644 --- a/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java +++ b/src/main/java/fr/dynamx/addons/basics/common/infos/SpeedDisplayInfos.java @@ -80,6 +80,7 @@ public String getNodeName() { @Override public void addToSceneGraph(ModularVehicleInfo packInfo, SceneBuilder, ModularVehicleInfo> sceneBuilder) { + if(getRotation() == null) return; if (nodeDependingOnName != null) { sceneBuilder.addNode(this, nodeDependingOnName, getNodeName()); } else { @@ -104,9 +105,8 @@ public void render(@Nullable T entity, EntityRenderContext entityRenderContext, if (entity == null) return; String speed = "" + DynamXUtils.getSpeed(entity); - if (SpeedDisplayInfos.this.getRotation() != null) { - TextUtils.drawText(SpeedDisplayInfos.this.getPosition(), SpeedDisplayInfos.this.getScale(), SpeedDisplayInfos.this.getRotation(), speed, getColor(), getFont()); - } + TextUtils.drawText(SpeedDisplayInfos.this.getPosition(), SpeedDisplayInfos.this.getScale(), SpeedDisplayInfos.this.getRotation(), speed, getColor(), getFont()); + } } } \ No newline at end of file