diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 8ce8a81188..144b2d22fe 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -224,7 +224,6 @@ public class ContentParser{ readFields(result, data); return result; }); - //TODO this is untested put(PartProgress.class, (type, data) -> { //simple case: it's a string or number constant if(data.isString()) return field(PartProgress.class, data.asString()); @@ -1129,14 +1128,13 @@ public class ContentParser{ String tname = Strings.capitalize(data.getString("type", "NoiseMesh")); return switch(tname){ - //TODO NoiseMesh is bad case "NoiseMesh" -> new NoiseMesh(planet, - data.getInt("seed", 0), data.getInt("divisions", 1), data.getFloat("radius", 1f), - data.getInt("octaves", 1), data.getFloat("persistence", 0.5f), data.getFloat("scale", 1f), data.getFloat("mag", 0.5f), - Color.valueOf(data.getString("color1", data.getString("color", "ffffff"))), - Color.valueOf(data.getString("color2", data.getString("color", "ffffff"))), - data.getInt("colorOct", 1), data.getFloat("colorPersistence", 0.5f), data.getFloat("colorScale", 1f), - data.getFloat("colorThreshold", 0.5f)); + data.getInt("seed", 0), data.getInt("divisions", 1), data.getFloat("radius", 1f), + data.getInt("octaves", 1), data.getFloat("persistence", 0.5f), data.getFloat("scale", 1f), data.getFloat("mag", 0.5f), + Color.valueOf(data.getString("color1", data.getString("color", "ffffff"))), + Color.valueOf(data.getString("color2", data.getString("color", "ffffff"))), + data.getInt("colorOct", 1), data.getFloat("colorPersistence", 0.5f), data.getFloat("colorScale", 1f), + data.getFloat("colorThreshold", 0.5f)); case "SunMesh" -> { var cvals = data.get("colors").asStringArray(); var colors = new Color[cvals.length]; @@ -1149,9 +1147,9 @@ public class ContentParser{ data.getFloat("colorScale", 1f), colors); } case "HexSkyMesh" -> new HexSkyMesh(planet, - data.getInt("seed", 0), data.getFloat("speed", 0), data.getFloat("radius", 1f), - data.getInt("divisions", 3), Color.valueOf(data.getString("color", "ffffff")), data.getInt("octaves", 1), - data.getFloat("persistence", 0.5f), data.getFloat("scale", 1f), data.getFloat("thresh", 0.5f)); + data.getInt("seed", 0), data.getFloat("speed", 0), data.getFloat("radius", 1f), + data.getInt("divisions", 3), Color.valueOf(data.getString("color", "ffffff")), data.getInt("octaves", 1), + data.getFloat("persistence", 0.5f), data.getFloat("scale", 1f), data.getFloat("thresh", 0.5f)); case "MultiMesh" -> new MultiMesh(parseMeshes(planet, data.get("meshes"))); case "MatMesh" -> new MatMesh(parseMesh(planet, data.get("mesh")), parser.readValue(Mat3D.class, data.get("mat"))); default -> throw new RuntimeException("Unknown mesh type: " + tname); diff --git a/tools/extra-schemas/Consumes.json b/tools/extra-schemas/Consumes.json new file mode 100644 index 0000000000..6dc65d3714 --- /dev/null +++ b/tools/extra-schemas/Consumes.json @@ -0,0 +1,20 @@ +{ + "doc": "Things that the block consumes.", + "remove": {"type": "java.lang.String[]", "doc": "Removes consumers instead of adding one: 'all', or a type name from this list, e.g. 'items'."}, + "item": {"type": "mindustry.type.Item", "doc": "Adds a single-item consumer; shorthand for consumeItem(item)."}, + "itemCharged": {"type": "mindustry.world.consumers.ConsumeItemCharged"}, + "itemFlammable": {"type": "mindustry.world.consumers.ConsumeItemFlammable"}, + "itemRadioactive": {"type": "mindustry.world.consumers.ConsumeItemRadioactive"}, + "itemExplosive": {"type": "mindustry.world.consumers.ConsumeItemExplosive"}, + "itemList": {"type": "mindustry.world.consumers.ConsumeItemList"}, + "itemExplode": {"type": "mindustry.world.consumers.ConsumeItemExplode"}, + "items": {"type": "mindustry.type.ItemStack[]", "doc": "Also accepts a single ItemStack, or a full ConsumeItems object."}, + "itemsBoost": {"type": "mindustry.type.ItemStack[]", "doc": "Like 'items', but marked as a boost input (Consume#booster)."}, + "liquidFlammable": {"type": "mindustry.world.consumers.ConsumeLiquidFlammable"}, + "liquid": {"type": "mindustry.world.consumers.ConsumeLiquid"}, + "liquids": {"type": "mindustry.type.LiquidStack[]", "doc": "Also accepts a full ConsumeLiquids object."}, + "coolant": {"type": "mindustry.world.consumers.ConsumeCoolant"}, + "liquidsBoost": {"type": "mindustry.type.LiquidStack[]", "doc": "Like 'liquids', but marked as a boost input (Consume#booster)."}, + "power": {"type": "float", "doc": "Also accepts a full ConsumePower object, e.g. for buffered power."}, + "powerBuffered": {"type": "float", "doc": "Shorthand for a buffered power consumer with this capacity."} +} diff --git a/tools/extra-schemas/JsonUnitType.json b/tools/extra-schemas/JsonUnitType.json new file mode 100644 index 0000000000..5689a088ab --- /dev/null +++ b/tools/extra-schemas/JsonUnitType.json @@ -0,0 +1,5 @@ +{ + "doc": "Type of unit that is created.", + "superclass": "Enum", + "values": ["flying", "mech", "legs", "naval", "payload", "missile", "tank", "hover", "tether", "crawl"] +} diff --git a/tools/extra-schemas/Research.json b/tools/extra-schemas/Research.json new file mode 100644 index 0000000000..2cfe419eda --- /dev/null +++ b/tools/extra-schemas/Research.json @@ -0,0 +1,10 @@ +{ + "doc": "Tech tree placement for this content. Also accepts a plain string, treated as 'parent'.", + "parent": {"type": "mindustry.ctype.UnlockableContent", "doc": "Name of the parent tech tree node; required unless 'root' is true."}, + "requirements": {"type": "mindustry.type.ItemStack[]", "doc": "Overrides the default research cost, which is this content's build cost."}, + "objectives": {"type": "mindustry.type.Objective[]", "doc": "Extra objectives to complete; items/liquids get a Produce objective automatically."}, + "planet": {"type": "mindustry.type.Planet", "doc": "Name of the planet this node belongs to; inherited from the parent otherwise."}, + "root": {"type": "boolean", "doc": "If true, this is a root node and 'parent' is not required.", "default": "false"}, + "name": {"type": "java.lang.String", "doc": "Display name for a root node; ignored for non-root nodes."}, + "requiresUnlock": {"type": "boolean", "doc": "If true, a root node isn't unlocked by default.", "default": "false"} +} diff --git a/tools/extra-schemas/absin.json b/tools/extra-schemas/absin.json new file mode 100644 index 0000000000..a9ed97876d --- /dev/null +++ b/tools/extra-schemas/absin.json @@ -0,0 +1,16 @@ +{ + "doc": "Applies an absolute-value sine wave to progress.", + "superclass": "PartProgress", + "scl":{ + "type": "float", + "doc": "Scale (frequency) of the wave." + }, + "mag":{ + "type": "float", + "doc": "Magnitude (amplitude) of the wave." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/add.json b/tools/extra-schemas/add.json new file mode 100644 index 0000000000..825e065f97 --- /dev/null +++ b/tools/extra-schemas/add.json @@ -0,0 +1,16 @@ +{ + "doc": "Adds a constant or another PartProgress's value to this one. Set exactly one of 'amount' or 'other'.", + "superclass": "PartProgress", + "amount":{ + "type": "float", + "doc": "Constant amount to add." + }, + "other":{ + "type": "PartProgress", + "doc": "Another progress function whose value is added instead of a constant." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/arc.graphics.Blending.json b/tools/extra-schemas/arc.graphics.Blending.json new file mode 100644 index 0000000000..dff3b6b755 --- /dev/null +++ b/tools/extra-schemas/arc.graphics.Blending.json @@ -0,0 +1,5 @@ +{ + "doc": "Handles sprite blending.", + "superclass": "Enum", + "values": ["normal", "additive", "disabled"] +} diff --git a/tools/extra-schemas/blend.json b/tools/extra-schemas/blend.json new file mode 100644 index 0000000000..c603f6d000 --- /dev/null +++ b/tools/extra-schemas/blend.json @@ -0,0 +1,16 @@ +{ + "doc": "Blends between this progress and another PartProgress by a fixed amount.", + "superclass": "PartProgress", + "other":{ + "type": "PartProgress", + "doc": "Progress function to blend with." + }, + "amount":{ + "type": "float", + "doc": "Blend factor toward 'other'." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/charge.json b/tools/extra-schemas/charge.json new file mode 100644 index 0000000000..be1927b9bf --- /dev/null +++ b/tools/extra-schemas/charge.json @@ -0,0 +1,8 @@ +{ + "doc": "Weapon charge, 0 when beginning to charge, 1 when finished.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/clamp.json b/tools/extra-schemas/clamp.json new file mode 100644 index 0000000000..67e803b77f --- /dev/null +++ b/tools/extra-schemas/clamp.json @@ -0,0 +1,8 @@ +{ + "doc": "Clamps progress to the [0, 1] range.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/compress.json b/tools/extra-schemas/compress.json new file mode 100644 index 0000000000..39c291a64e --- /dev/null +++ b/tools/extra-schemas/compress.json @@ -0,0 +1,16 @@ +{ + "doc": "Compresses progress into the [start, end] sub-range.", + "superclass": "PartProgress", + "start":{ + "type": "float", + "doc": "Start of the compressed range." + }, + "end":{ + "type": "float", + "doc": "End of the compressed range." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/curve.json b/tools/extra-schemas/curve.json new file mode 100644 index 0000000000..7b785deec0 --- /dev/null +++ b/tools/extra-schemas/curve.json @@ -0,0 +1,20 @@ +{ + "doc": "Applies an interpolation curve to progress, or slices out a sub-range and interpolates within it. Set either 'interp', or both 'offset' and 'duration'.", + "superclass": "PartProgress", + "interp":{ + "type": "arc.util.Interp", + "doc": "Interpolation curve to apply directly to progress." + }, + "offset":{ + "type": "float", + "doc": "Start of the sub-range to slice out." + }, + "duration":{ + "type": "float", + "doc": "Length of the sub-range to slice out." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/delay.json b/tools/extra-schemas/delay.json new file mode 100644 index 0000000000..0ec19acba8 --- /dev/null +++ b/tools/extra-schemas/delay.json @@ -0,0 +1,12 @@ +{ + "doc": "Delays progress by a fixed amount.", + "superclass": "PartProgress", + "amount":{ + "type": "float", + "doc": "Amount to delay progress by." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/heat.json b/tools/extra-schemas/heat.json new file mode 100644 index 0000000000..6e26000769 --- /dev/null +++ b/tools/extra-schemas/heat.json @@ -0,0 +1,8 @@ +{ + "doc": "Weapon heat, 1 when just fired, 0 when it has cooled down (duration depends on weapon).", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/inv.json b/tools/extra-schemas/inv.json new file mode 100644 index 0000000000..1ce1e54a57 --- /dev/null +++ b/tools/extra-schemas/inv.json @@ -0,0 +1,8 @@ +{ + "doc": "Inverts progress (1 - progress).", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/life.json b/tools/extra-schemas/life.json new file mode 100644 index 0000000000..a730f27955 --- /dev/null +++ b/tools/extra-schemas/life.json @@ -0,0 +1,8 @@ +{ + "doc": "Lifetime fraction, 0 to 1. Only for missiles.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/loop.json b/tools/extra-schemas/loop.json new file mode 100644 index 0000000000..fed3721b8c --- /dev/null +++ b/tools/extra-schemas/loop.json @@ -0,0 +1,12 @@ +{ + "doc": "Loops progress over a fixed time period.", + "superclass": "PartProgress", + "time":{ + "type": "float", + "doc": "Length of one loop cycle." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/min.json b/tools/extra-schemas/min.json new file mode 100644 index 0000000000..5e7aae7a34 --- /dev/null +++ b/tools/extra-schemas/min.json @@ -0,0 +1,12 @@ +{ + "doc": "Takes the minimum of this progress and another PartProgress.", + "superclass": "PartProgress", + "other":{ + "type": "PartProgress", + "doc": "Progress function to compare against." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/mindustry.entities.part.DrawPart$PartProgress.json b/tools/extra-schemas/mindustry.entities.part.DrawPart$PartProgress.json new file mode 100644 index 0000000000..3fe359b4cf --- /dev/null +++ b/tools/extra-schemas/mindustry.entities.part.DrawPart$PartProgress.json @@ -0,0 +1,7 @@ +{ + "doc": "Base class for progress functions used to animate part transforms. The concrete operation is chosen by 'type' (see PartProgress's static methods for the full list: inv, slope, clamp, delay, sustain, shorten, compress, add, blend, mul, min, sin, absin, mod, loop, curve).", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/mindustry.graphics.g3d.HexMesh.json b/tools/extra-schemas/mindustry.graphics.g3d.HexMesh.json new file mode 100644 index 0000000000..e0354e6c2e --- /dev/null +++ b/tools/extra-schemas/mindustry.graphics.g3d.HexMesh.json @@ -0,0 +1,8 @@ +{ + "superclass": "mindustry.graphics.g3d.PlanetMesh", + "doc": "Not parsed via the mesh-type switch itself - falls through to the default (Planet, int divisions) constructor when 'type' is 'HexMesh'.", + "divisions": { + "type": "int", + "doc": "Subdivision count for the generated hex grid." + } +} diff --git a/tools/extra-schemas/mindustry.graphics.g3d.HexSkyMesh.json b/tools/extra-schemas/mindustry.graphics.g3d.HexSkyMesh.json new file mode 100644 index 0000000000..a34c4bdb06 --- /dev/null +++ b/tools/extra-schemas/mindustry.graphics.g3d.HexSkyMesh.json @@ -0,0 +1,42 @@ +{ + "superclass": "mindustry.graphics.g3d.PlanetMesh", + "seed": { + "type": "int", + "default": "0" + }, + "speed": { + "type": "float", + "doc": "Rotation speed of the cloud layer, relative to the planet's own rotation.", + "default": "0" + }, + "radius": { + "type": "float", + "doc": "Extra radius added on top of the planet's own radius, i.e. how high above the surface the cloud layer sits.", + "default": "1" + }, + "divisions": { + "type": "int", + "default": "3" + }, + "color": { + "type": "arc.graphics.Color", + "default": "\"ffffff\"" + }, + "octaves": { + "type": "int", + "default": "1" + }, + "persistence": { + "type": "float", + "default": "0.5" + }, + "scale": { + "type": "float", + "default": "1" + }, + "thresh": { + "type": "float", + "doc": "Noise threshold above which a hex is skipped (left as a gap in the cloud layer).", + "default": "0.5" + } +} diff --git a/tools/extra-schemas/mindustry.graphics.g3d.MatMesh.json b/tools/extra-schemas/mindustry.graphics.g3d.MatMesh.json new file mode 100644 index 0000000000..0f2db70ae8 --- /dev/null +++ b/tools/extra-schemas/mindustry.graphics.g3d.MatMesh.json @@ -0,0 +1,11 @@ +{ + "superclass": "java.lang.Object", + "mesh": { + "type": "mindustry.graphics.g3d.GenericMesh", + "doc": "Wrapped mesh to render with the extra transform applied. Required - no default." + }, + "mat": { + "type": "arc.math.geom.Mat3D", + "doc": "Extra transform matrix applied on top of the wrapped mesh's own transform. Required - no default." + } +} diff --git a/tools/extra-schemas/mindustry.graphics.g3d.MultiMesh.json b/tools/extra-schemas/mindustry.graphics.g3d.MultiMesh.json new file mode 100644 index 0000000000..28fa99c3db --- /dev/null +++ b/tools/extra-schemas/mindustry.graphics.g3d.MultiMesh.json @@ -0,0 +1,7 @@ +{ + "superclass": "java.lang.Object", + "meshes": { + "type": "mindustry.graphics.g3d.GenericMesh[]", + "doc": "Meshes to render together, in order. Required - no default." + } +} diff --git a/tools/extra-schemas/mindustry.graphics.g3d.NoiseMesh.json b/tools/extra-schemas/mindustry.graphics.g3d.NoiseMesh.json new file mode 100644 index 0000000000..521baa5269 --- /dev/null +++ b/tools/extra-schemas/mindustry.graphics.g3d.NoiseMesh.json @@ -0,0 +1,66 @@ +{ + "superclass": "mindustry.graphics.g3d.HexMesh", + "seed": { + "type": "int", + "default": "0" + }, + "divisions": { + "type": "int", + "default": "1" + }, + "radius": { + "type": "float", + "default": "1" + }, + "octaves": { + "type": "int", + "default": "1" + }, + "persistence": { + "type": "float", + "default": "0.5" + }, + "scale": { + "type": "float", + "default": "1" + }, + "mag": { + "type": "float", + "default": "0.5" + }, + "color": { + "type": "arc.graphics.Color", + "nullable": true, + "doc": "Fallback used for 'color1'/'color2' when they aren't set individually. Defaults to white if this is also unset." + }, + "color1": { + "type": "arc.graphics.Color", + "doc": "First color. Falls back to 'color', then white, if unset.", + "default": "\"ffffff\"" + }, + "color2": { + "type": "arc.graphics.Color", + "doc": "Second color, used for the two-color variant. Falls back to 'color', then white, if unset.", + "default": "\"ffffff\"" + }, + "colorOct": { + "type": "int", + "doc": "Octaves for the color-selection noise, used for the two-color variant.", + "default": "1" + }, + "colorPersistence": { + "type": "float", + "doc": "Persistence for the color-selection noise, used for the two-color variant.", + "default": "0.5" + }, + "colorScale": { + "type": "float", + "doc": "Scale for the color-selection noise, used for the two-color variant.", + "default": "1" + }, + "colorThreshold": { + "type": "float", + "doc": "Noise threshold above which 'color2' is used instead of 'color1'.", + "default": "0.5" + } +} diff --git a/tools/extra-schemas/mindustry.graphics.g3d.SunMesh.json b/tools/extra-schemas/mindustry.graphics.g3d.SunMesh.json new file mode 100644 index 0000000000..ced0c962ae --- /dev/null +++ b/tools/extra-schemas/mindustry.graphics.g3d.SunMesh.json @@ -0,0 +1,35 @@ +{ + "superclass": "mindustry.graphics.g3d.HexMesh", + "divisions": { + "type": "int", + "default": "1" + }, + "octaves": { + "type": "double", + "default": "1" + }, + "persistence": { + "type": "double", + "default": "0.5" + }, + "scl": { + "type": "double", + "default": "1" + }, + "pow": { + "type": "double", + "default": "1" + }, + "mag": { + "type": "double", + "default": "0.5" + }, + "colorScale": { + "type": "float", + "default": "1" + }, + "colors": { + "type": "arc.graphics.Color[]", + "doc": "Color gradient, indexed by noise height. Required - no default." + } +} diff --git a/tools/extra-schemas/mod.json b/tools/extra-schemas/mod.json new file mode 100644 index 0000000000..dc5e3be8fc --- /dev/null +++ b/tools/extra-schemas/mod.json @@ -0,0 +1,12 @@ +{ + "doc": "Wraps progress modulo a fixed amount.", + "superclass": "PartProgress", + "amount":{ + "type": "float", + "doc": "Modulus to wrap progress by." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/mul.json b/tools/extra-schemas/mul.json new file mode 100644 index 0000000000..6cbd04f982 --- /dev/null +++ b/tools/extra-schemas/mul.json @@ -0,0 +1,16 @@ +{ + "doc": "Multiplies by a constant or another PartProgress's value. Set exactly one of 'amount' or 'other'.", + "superclass": "PartProgress", + "amount":{ + "type": "float", + "doc": "Constant multiplier." + }, + "other":{ + "type": "PartProgress", + "doc": "Another progress function whose value is multiplied instead of a constant." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/recoil.json b/tools/extra-schemas/recoil.json new file mode 100644 index 0000000000..8c829079d1 --- /dev/null +++ b/tools/extra-schemas/recoil.json @@ -0,0 +1,8 @@ +{ + "doc": "Weapon recoil with no curve applied.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/reload.json b/tools/extra-schemas/reload.json new file mode 100644 index 0000000000..8087768051 --- /dev/null +++ b/tools/extra-schemas/reload.json @@ -0,0 +1,8 @@ +{ + "doc": "Reload of the weapon - 1 right after shooting, 0 when ready to fire.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/shorten.json b/tools/extra-schemas/shorten.json new file mode 100644 index 0000000000..526a5a8d0d --- /dev/null +++ b/tools/extra-schemas/shorten.json @@ -0,0 +1,12 @@ +{ + "doc": "Shortens the progress range by a fixed amount.", + "superclass": "PartProgress", + "amount":{ + "type": "float", + "doc": "Amount to shorten progress by." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/sin.json b/tools/extra-schemas/sin.json new file mode 100644 index 0000000000..28fd5b9d6e --- /dev/null +++ b/tools/extra-schemas/sin.json @@ -0,0 +1,21 @@ +{ + "doc": "Applies a sine wave to progress.", + "superclass": "PartProgress", + "offset":{ + "type": "float", + "doc": "Phase offset.", + "default": "0" + }, + "scl":{ + "type": "float", + "doc": "Scale (frequency) of the wave." + }, + "mag":{ + "type": "float", + "doc": "Magnitude (amplitude) of the wave." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/slope.json b/tools/extra-schemas/slope.json new file mode 100644 index 0000000000..b97c4d7d08 --- /dev/null +++ b/tools/extra-schemas/slope.json @@ -0,0 +1,8 @@ +{ + "doc": "Slopes progress: rises to 1 then falls back to 0.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/smoothReload.json b/tools/extra-schemas/smoothReload.json new file mode 100644 index 0000000000..6a61f3790f --- /dev/null +++ b/tools/extra-schemas/smoothReload.json @@ -0,0 +1,8 @@ +{ + "doc": "Reload, but smoothed out, so there is no sudden jump between 0-1.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/sustain.json b/tools/extra-schemas/sustain.json new file mode 100644 index 0000000000..2ff0df8040 --- /dev/null +++ b/tools/extra-schemas/sustain.json @@ -0,0 +1,22 @@ +{ + "doc": "Rises to and sustains progress at a plateau.", + "superclass": "PartProgress", + "offset":{ + "type": "float", + "doc": "Progress offset before rising.", + "default": "0" + }, + "grow":{ + "type": "float", + "doc": "Duration of the rise to the plateau.", + "default": "0" + }, + "sustain":{ + "type": "float", + "doc": "Length of the sustained plateau." + }, + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/time.json b/tools/extra-schemas/time.json new file mode 100644 index 0000000000..55b33b57b2 --- /dev/null +++ b/tools/extra-schemas/time.json @@ -0,0 +1,8 @@ +{ + "doc": "Current unscaled value of Time.time.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/extra-schemas/warmup.json b/tools/extra-schemas/warmup.json new file mode 100644 index 0000000000..682bf57044 --- /dev/null +++ b/tools/extra-schemas/warmup.json @@ -0,0 +1,8 @@ +{ + "doc": "Weapon warmup, 0 when not firing, 1 when actively shooting. Not equivalent to heat.", + "superclass": "PartProgress", + "ops":{ + "type": "Seq", + "doc": "Consecutive operations." + } +} \ No newline at end of file diff --git a/tools/src/mindustry/tools/SchemaGenerator.java b/tools/src/mindustry/tools/SchemaGenerator.java index 6bb41e6c94..8d0f8221a7 100644 --- a/tools/src/mindustry/tools/SchemaGenerator.java +++ b/tools/src/mindustry/tools/SchemaGenerator.java @@ -2,7 +2,6 @@ package mindustry.tools; import arc.files.*; import arc.func.*; -import arc.graphics.*; import arc.math.*; import arc.struct.*; import arc.util.*; @@ -12,6 +11,7 @@ import com.github.javaparser.*; import com.github.javaparser.ast.body.*; import mindustry.*; import mindustry.ctype.*; +import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.gen.*; import mindustry.type.*; @@ -135,14 +135,11 @@ public class SchemaGenerator{ file.writeString(val); } - static void writePartSchema(String name, String val){ - Jval base = Jval.read(val); - base.add("ops", field("Seq", "Consecutive operations.")); - - writeSchema(name, base.toString(Jformat.formatted)); - } - static void finalizeSchemas(Seq> allClasses){ + writeSchema(UnlockableContent.class); + writeSchema(MappableContent.class); + writeSchema(Effect.class); + writeSchema("TemplateUnitType", """ { "doc": "Template for unit types.", @@ -151,219 +148,6 @@ public class SchemaGenerator{ } """.replace("%TYPES%", allClasses.select(UnitType.class::isAssignableFrom).toString(", ", t -> "\"" + t.getSimpleName() + "\""))); - writePartSchema("mindustry.entities.part.DrawPart$PartProgress", """ - { - "doc": "Base class for progress functions used to animate part transforms. The concrete operation is chosen by 'type' (see PartProgress's static methods for the full list: inv, slope, clamp, delay, sustain, shorten, compress, add, blend, mul, min, sin, absin, mod, loop, curve)." - } - """); - - writePartSchema("reload", """ - { - "doc": "Reload of the weapon - 1 right after shooting, 0 when ready to fire.", - "superclass": "PartProgress" - } - """); - - writePartSchema("smoothReload", """ - { - "doc": "Reload, but smoothed out, so there is no sudden jump between 0-1.", - "superclass": "PartProgress" - } - """); - - writePartSchema("warmup", """ - { - "doc": "Weapon warmup, 0 when not firing, 1 when actively shooting. Not equivalent to heat.", - "superclass": "PartProgress" - } - """); - - writePartSchema("charge", """ - { - "doc": "Weapon charge, 0 when beginning to charge, 1 when finished.", - "superclass": "PartProgress" - } - """); - - writePartSchema("recoil", """ - { - "doc": "Weapon recoil with no curve applied.", - "superclass": "PartProgress" - } - """); - - writePartSchema("heat", """ - { - "doc": "Weapon heat, 1 when just fired, 0 when it has cooled down (duration depends on weapon).", - "superclass": "PartProgress" - } - """); - - writePartSchema("life", """ - { - "doc": "Lifetime fraction, 0 to 1. Only for missiles.", - "superclass": "PartProgress" - } - """); - - writePartSchema("time", """ - { - "doc": "Current unscaled value of Time.time.", - "superclass": "PartProgress" - } - """); - - writePartSchema("inv", """ - { - "doc": "Inverts progress (1 - progress).", - "superclass": "PartProgress" - } - """); - - writePartSchema("slope", """ - { - "doc": "Slopes progress: rises to 1 then falls back to 0.", - "superclass": "PartProgress" - } - """); - - writePartSchema("clamp", """ - { - "doc": "Clamps progress to the [0, 1] range.", - "superclass": "PartProgress" - } - """); - - writePartSchema("delay", """ - { - "doc": "Delays progress by a fixed amount.", - "superclass": "PartProgress", - "amount": { "type": "float", "doc": "Amount to delay progress by." } - } - """); - - writePartSchema("sustain", """ - { - "doc": "Rises to and sustains progress at a plateau.", - "superclass": "PartProgress", - "offset": { "type": "float", "doc": "Progress offset before rising.", "default": "0" }, - "grow": { "type": "float", "doc": "Duration of the rise to the plateau.", "default": "0" }, - "sustain": { "type": "float", "doc": "Length of the sustained plateau." } - } - """); - - writePartSchema("shorten", """ - { - "doc": "Shortens the progress range by a fixed amount.", - "superclass": "PartProgress", - "amount": { "type": "float", "doc": "Amount to shorten progress by." } - } - """); - - writePartSchema("compress", """ - { - "doc": "Compresses progress into the [start, end] sub-range.", - "superclass": "PartProgress", - "start": { "type": "float", "doc": "Start of the compressed range." }, - "end": { "type": "float", "doc": "End of the compressed range." } - } - """); - - writePartSchema("add", """ - { - "doc": "Adds a constant or another PartProgress's value to this one. Set exactly one of 'amount' or 'other'.", - "superclass": "PartProgress", - "amount": { "type": "float", "doc": "Constant amount to add." }, - "other": { "type": "PartProgress", "doc": "Another progress function whose value is added instead of a constant." } - } - """); - - writePartSchema("blend", """ - { - "doc": "Blends between this progress and another PartProgress by a fixed amount.", - "superclass": "PartProgress", - "other": { "type": "PartProgress", "doc": "Progress function to blend with." }, - "amount": { "type": "float", "doc": "Blend factor toward 'other'." } - } - """); - - writePartSchema("mul", """ - { - "doc": "Multiplies by a constant or another PartProgress's value. Set exactly one of 'amount' or 'other'.", - "superclass": "PartProgress", - "amount": { "type": "float", "doc": "Constant multiplier." }, - "other": { "type": "PartProgress", "doc": "Another progress function whose value is multiplied instead of a constant." } - } - """); - - writePartSchema("min", """ - { - "doc": "Takes the minimum of this progress and another PartProgress.", - "superclass": "PartProgress", - "other": { "type": "PartProgress", "doc": "Progress function to compare against." } - } - """); - - writePartSchema("sin", """ - { - "doc": "Applies a sine wave to progress.", - "superclass": "PartProgress", - "offset": { "type": "float", "doc": "Phase offset.", "default": "0" }, - "scl": { "type": "float", "doc": "Scale (frequency) of the wave." }, - "mag": { "type": "float", "doc": "Magnitude (amplitude) of the wave." } - } - """); - - writePartSchema("absin", """ - { - "doc": "Applies an absolute-value sine wave to progress.", - "superclass": "PartProgress", - "scl": { "type": "float", "doc": "Scale (frequency) of the wave." }, - "mag": { "type": "float", "doc": "Magnitude (amplitude) of the wave." } - } - """); - - writePartSchema("mod", """ - { - "doc": "Wraps progress modulo a fixed amount.", - "superclass": "PartProgress", - "amount": { "type": "float", "doc": "Modulus to wrap progress by." } - } - """); - - writePartSchema("loop", """ - { - "doc": "Loops progress over a fixed time period.", - "superclass": "PartProgress", - "time": { "type": "float", "doc": "Length of one loop cycle." } - } - """); - - writePartSchema("curve", """ - { - "doc": "Applies an interpolation curve to progress, or slices out a sub-range and interpolates within it. Set either 'interp', or both 'offset' and 'duration'.", - "superclass": "PartProgress", - "interp": { "type": "arc.util.Interp", "doc": "Interpolation curve to apply directly to progress." }, - "offset": { "type": "float", "doc": "Start of the sub-range to slice out." }, - "duration": { "type": "float", "doc": "Length of the sub-range to slice out." } - } - """); - } - - private static void registerBuiltinSchemas(){ - injectCustomField(UnitType.class, "type", field("JsonUnitType", "Type of the unit that is created.", false)); - injectCustomField(UnitType.class, "template", field("TemplateUnitType", "UnitType template class.", false)); - injectCustomField(UnitType.class, "defaultController", field(AIController.class.getCanonicalName(), "Unconditional controller; always assigned, even if on the player team. This overwrites RTS AI.", false)); - injectCustomField(UnitType.class, "aiController", field(AIController.class.getCanonicalName(), "Controller used when the unit is not on the player team.", false)); - - writeSchema("JsonUnitType", """ - { - "doc": "Type of unit that is created.", - "superclass": "Enum", - "values": ["flying", "mech", "legs", "naval", "payload", "missile", "tank", "hover", "tether", "crawl"] - } - """); - writeSchema(Interp.class.getCanonicalName(), """ { "doc": "Various types of interpolation.", @@ -372,54 +156,19 @@ public class SchemaGenerator{ } """.replace("%VALUES%", Seq.with(Interp.class.getFields()).toString(", ", t -> "\"" + t.getName() + "\""))); - writeSchema(Blending.class.getCanonicalName(), """ - { - "doc": "Handles sprite blending.", - "superclass": "Enum", - "values": ["normal", "additive", "disabled"] - } - """); + new Fi("../../tools/extra-schemas").copyFilesTo(outputDir); + } + + private static void registerBuiltinSchemas(){ + injectCustomField(UnitType.class, "type", field("JsonUnitType", "Type of the unit that is created.", false)); + injectCustomField(UnitType.class, "template", field("TemplateUnitType", "UnitType template class.", false)); + injectCustomField(UnitType.class, "defaultController", field(AIController.class.getCanonicalName(), "Unconditional controller; always assigned, even if on the player team. This overwrites RTS AI.", false)); + injectCustomField(UnitType.class, "aiController", field(AIController.class.getCanonicalName(), "Controller used when the unit is not on the player team.", false)); injectCustomField(Planet.class, "sectorSize", field("int", "Planet sector subdivisions.", false)); - writeSchema("Consumes", """ - { - "doc": "Things that the block consumes.", - "remove": {"type": "java.lang.String[]", "doc": "Removes consumers instead of adding one: 'all', or a type name from this list, e.g. 'items'."}, - "item": {"type": "mindustry.type.Item", "doc": "Adds a single-item consumer; shorthand for consumeItem(item)."}, - "itemCharged": {"type": "mindustry.world.consumers.ConsumeItemCharged"}, - "itemFlammable": {"type": "mindustry.world.consumers.ConsumeItemFlammable"}, - "itemRadioactive": {"type": "mindustry.world.consumers.ConsumeItemRadioactive"}, - "itemExplosive": {"type": "mindustry.world.consumers.ConsumeItemExplosive"}, - "itemList": {"type": "mindustry.world.consumers.ConsumeItemList"}, - "itemExplode": {"type": "mindustry.world.consumers.ConsumeItemExplode"}, - "items": {"type": "mindustry.type.ItemStack[]", "doc": "Also accepts a single ItemStack, or a full ConsumeItems object."}, - "itemsBoost": {"type": "mindustry.type.ItemStack[]", "doc": "Like 'items', but marked as a boost input (Consume#booster)."}, - "liquidFlammable": {"type": "mindustry.world.consumers.ConsumeLiquidFlammable"}, - "liquid": {"type": "mindustry.world.consumers.ConsumeLiquid"}, - "liquids": {"type": "mindustry.type.LiquidStack[]", "doc": "Also accepts a full ConsumeLiquids object."}, - "coolant": {"type": "mindustry.world.consumers.ConsumeCoolant"}, - "liquidsBoost": {"type": "mindustry.type.LiquidStack[]", "doc": "Like 'liquids', but marked as a boost input (Consume#booster)."}, - "power": {"type": "float", "doc": "Also accepts a full ConsumePower object, e.g. for buffered power."}, - "powerBuffered": {"type": "float", "doc": "Shorthand for a buffered power consumer with this capacity."} - } - """); - injectCustomField(Block.class, "consumes", field("Consumes", "Things that the block consumes.", true)); - writeSchema("Research", """ - { - "doc": "Tech tree placement for this content. Also accepts a plain string, treated as 'parent'.", - "parent": {"type": "mindustry.ctype.UnlockableContent", "doc": "Name of the parent tech tree node; required unless 'root' is true."}, - "requirements": {"type": "mindustry.type.ItemStack[]", "doc": "Overrides the default research cost, which is this content's build cost."}, - "objectives": {"type": "mindustry.type.Objective[]", "doc": "Extra objectives to complete; items/liquids get a Produce objective automatically."}, - "planet": {"type": "mindustry.type.Planet", "doc": "Name of the planet this node belongs to; inherited from the parent otherwise."}, - "root": {"type": "boolean", "doc": "If true, this is a root node and 'parent' is not required.", "default": "false"}, - "name": {"type": "java.lang.String", "doc": "Display name for a root node; ignored for non-root nodes."}, - "requiresUnlock": {"type": "boolean", "doc": "If true, a root node isn't unlocked by default.", "default": "false"} - } - """); - for(var type : Seq.with(Block.class, Liquid.class, UnitType.class, Item.class, StatusEffect.class, Planet.class, Weather.class, SectorPreset.class)){ injectCustomField(type, "research", field("Research", "Tech tree research dependencies.", true)); }