diff --git a/core/src/mindustry/editor/MapPatchesDialog.java b/core/src/mindustry/editor/MapPatchesDialog.java index 6f1de9c1cc..985f52fd7e 100644 --- a/core/src/mindustry/editor/MapPatchesDialog.java +++ b/core/src/mindustry/editor/MapPatchesDialog.java @@ -55,7 +55,7 @@ public class MapPatchesDialog extends BaseDialog{ for(var warning : patch.warnings){ p.table(Styles.grayPanel, in -> { - in.add(warning, Styles.monoLabel).grow().wrap(); + in.add(warning.replaceAll("\t", " "), Styles.monoLabel).grow().wrap(); }).margin(6f).growX().pad(3f).row(); } }).grow(); diff --git a/core/src/mindustry/mod/ContentPatcher.java b/core/src/mindustry/mod/ContentPatcher.java index 6e84a7870c..d07ce2fda1 100644 --- a/core/src/mindustry/mod/ContentPatcher.java +++ b/core/src/mindustry/mod/ContentPatcher.java @@ -302,6 +302,30 @@ public class ContentPatcher{ }else{ assignValue(object, field, new FieldData(metadata.elementType, null, null), () -> map.get(key), val -> map.put(key, val), value, false); } + }else if(object instanceof ObjectFloatMap map){ + if(metadata == null){ + warn("ObjectFloatMap cannot be parsed without metadata: @.@", parentObject, parentField); + return; + } + Object key = convertKeyType(field, metadata.elementType); + if(key == null){ + warn("Null key: '@'", field); + return; + } + + var copy = new ObjectFloatMap(map); + reset(() -> { + map.clear(); + map.putAll(copy); + }); + + if(value instanceof JsonValue jval && jval.isString() && (jval.asString().equals("-"))){ + //removal syntax: + //"value": "-" + map.remove(key, 0f); + }else{ + assignValue(object, field, new FieldData(float.class, null, null), () -> map.get(key, 0f), val -> map.put(key, (Float)val), value, false); + } }else if(object instanceof Attributes map && value instanceof JsonValue jval){ Attribute key = Attribute.getOrNull(field); if(key == null){ @@ -386,7 +410,7 @@ public class ContentPatcher{ for(var child : jsv){ if(child.name != null){ assign(prevValue, child.name, child, - metadata != null && metadata.type == ObjectMap.class ? metadata : + metadata != null && (metadata.type == ObjectMap.class || metadata.type == ObjectFloatMap.class) ? metadata : !childFields.containsKey(child.name) ? null : new FieldData(childFields.get(child.name)), object, field); } diff --git a/tests/src/test/java/PatcherTests.java b/tests/src/test/java/PatcherTests.java index f7ea1bc7fc..7ea2de59bc 100644 --- a/tests/src/test/java/PatcherTests.java +++ b/tests/src/test/java/PatcherTests.java @@ -7,6 +7,7 @@ import mindustry.entities.bullet.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.world.blocks.defense.turrets.*; +import mindustry.world.blocks.production.*; import mindustry.world.blocks.units.*; import mindustry.world.meta.*; import org.junit.jupiter.api.*; @@ -263,6 +264,32 @@ public class PatcherTests{ assertEquals(2, Vars.state.patcher.patches.first().warnings.size); } + @Test + void testObjectFloatMap() throws Exception{ + Vars.state.patcher.apply(Seq.with(""" + block.mechanical-drill.drillMultipliers: { + titanium: 2.0 + } + + block.mechanical-drill: { + drillMultipliers: { + copper: 3.0 + } + } + block.mechanical-drill.drillMultipliers.surge-alloy: 10 + """)); + + assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings); + assertEquals(2f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.titanium, 0f)); + assertEquals(3f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.copper, 0f)); + assertEquals(10f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.surgeAlloy, 0f)); + + Vars.logic.reset(); + + assertEquals(0f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.titanium, 0f)); + assertEquals(0f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.surgeAlloy, 0f)); + } + @Test void testAttributes() throws Exception{ Vars.state.patcher.apply(Seq.with("""