From 19f8866f47bed707d7eb0215170b72580f2e782e Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:26:13 +0100 Subject: [PATCH 1/6] Add AlignObjectKeys and AutoPadSubObjects formatting properties AlignObjectKeys: aligns the colon separator for keys within an object, padding each key to the width of the longest key in the same object. AutoPadSubObjects: treats sibling ObjectKey values that are inline objects as rows of a table. Computes the max rendered value-width per sub-key name across all siblings and pads values so each named column starts at the same position across all rows. Complex sub-values (multi-item Objects/Arrays) are excluded from width computation and do not influence column widths. Also fixes transposeAndFormat crashing on empty input, and updates scalarLength to exclude multiline text rather than just { and [ prefixes from column width calculation. Adds a glowMap section to examples/jbeam/frame.jbeam as a test fixture demonstrating both properties together, matching the formatting style seen in real-world jbeam files. --- examples/ast/jbeam/frame.hs | 326 ++++++++ examples/ast/jbfl/complex.hs | 64 ++ .../formatted_jbeam/fender-complex-jbfl.jbeam | 10 +- .../formatted_jbeam/frame-complex-jbfl.jbeam | 30 +- .../formatted_jbeam/frame-minimal-jbfl.jbeam | 20 +- .../suspension-complex-jbfl.jbeam | 2 +- examples/jbeam/frame.jbeam | 778 +++++++++--------- examples/jbfl/complex.jbfl | 13 +- .../transformed_jbeam/frame-cfg-default.jbeam | 20 +- .../transformed_jbeam/frame-cfg-example.jbeam | 20 +- src/JbeamEdit/Formatting.hs | 123 ++- src/JbeamEdit/Formatting/Rules.hs | 16 +- src/JbeamEdit/Parsing/DSL.hs | 2 + tools/dump_ast/Main.hs | 2 +- 14 files changed, 1006 insertions(+), 420 deletions(-) diff --git a/examples/ast/jbeam/frame.hs b/examples/ast/jbeam/frame.hs index b36885f3..42aba2b2 100644 --- a/examples/ast/jbeam/frame.hs +++ b/examples/ast/jbeam/frame.hs @@ -1828,6 +1828,332 @@ Object ] ] ) + , ObjectKey + ( String "glowMap" + , Object + [ Comment + ( InternalComment + { cText = "main lights" + , cMultiline = False + , cAssociationDirection = NextNode + , cHadNewlineBefore = False + } + ) + , ObjectKey + ( String "chassis_headlight_L" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "lowhighbeam_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_headlight" + ) + , ObjectKey + ( String "on" + , String "chassis_headlight_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , ObjectKey + ( String "chassis_headlight_R" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "lowhighbeam_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_headlight" + ) + , ObjectKey + ( String "on" + , String "chassis_headlight_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , ObjectKey + ( String "chassis_signal_L" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "signal_L_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_signal_amber" + ) + , ObjectKey + ( String "on" + , String "chassis_signal_amber_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , ObjectKey + ( String "chassis_signal_R" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "signal_R_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_signal_amber" + ) + , ObjectKey + ( String "on" + , String "chassis_signal_amber_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , ObjectKey + ( String "chassis_reverselight" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "reverselight_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_reverselight" + ) + , ObjectKey + ( String "on" + , String "chassis_reverselight_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , ObjectKey + ( String "chassis_brakelight_L" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "brakelight_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_taillight" + ) + , ObjectKey + ( String "on" + , String "chassis_taillight_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , ObjectKey + ( String "chassis_brakelight_R" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "brakelight_filament" + ) + , ObjectKey + ( String "off" + , String "chassis_taillight" + ) + , ObjectKey + ( String "on" + , String "chassis_taillight_on" + ) + , ObjectKey + ( String "materialEmissiveScaling" + , Object + [ ObjectKey + ( String "on_max" + , Number 1.0 + ) + ] + ) + ] + ) + , Comment + ( InternalComment + { cText = "gauge lights" + , cMultiline = False + , cAssociationDirection = NextNode + , cHadNewlineBefore = False + } + ) + , ObjectKey + ( String "chassis_gaugelight_highbeam" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "highbeam" + ) + , ObjectKey + ( String "off" + , String "chassis_gauges" + ) + , ObjectKey + ( String "on" + , String "chassis_gauges_on" + ) + ] + ) + , ObjectKey + ( String "chassis_gaugelight_signal_L" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "signal_L" + ) + , ObjectKey + ( String "off" + , String "chassis_gauges" + ) + , ObjectKey + ( String "on" + , String "chassis_gauges_on" + ) + ] + ) + , ObjectKey + ( String "chassis_gaugelight_signal_R" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "signal_R" + ) + , ObjectKey + ( String "off" + , String "chassis_gauges" + ) + , ObjectKey + ( String "on" + , String "chassis_gauges_on" + ) + ] + ) + , ObjectKey + ( String "chassis_gaugelight_battery" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "battery" + ) + , ObjectKey + ( String "off" + , String "chassis_gauges" + ) + , ObjectKey + ( String "on" + , String "chassis_gauges_on" + ) + ] + ) + , ObjectKey + ( String "chassis_gaugelight_parkbrake" + , Object + [ ObjectKey + ( String "simpleFunction" + , String "parkingbrakelight" + ) + , ObjectKey + ( String "off" + , String "chassis_gauges" + ) + , ObjectKey + ( String "on" + , String "chassis_gauges_on" + ) + ] + ) + , Comment + ( InternalComment + { cText = "multi-condition warning light" + , cMultiline = False + , cAssociationDirection = NextNode + , cHadNewlineBefore = False + } + ) + , ObjectKey + ( String "chassis_gaugelight_warning" + , Object + [ ObjectKey + ( String "simpleFunction" + , Object + [ ObjectKey + ( String "checkengine" + , Number 1.0 + ) + , ObjectKey + ( String "battery" + , Number 1.0 + ) + , ObjectKey + ( String "lowpressure" + , Number 1.0 + ) + ] + ) + , ObjectKey + ( String "off" + , String "chassis_gauges" + ) + , ObjectKey + ( String "on" + , String "chassis_gauges_on" + ) + ] + ) + ] + ) ] ) ] diff --git a/examples/ast/jbfl/complex.hs b/examples/ast/jbfl/complex.hs index 667f8d80..375d9f77 100644 --- a/examples/ast/jbfl/complex.hs +++ b/examples/ast/jbfl/complex.hs @@ -191,6 +191,27 @@ RuleSet ) ] ) + , + ( NodePattern + ( fromList + [ AnyObjectKey + , Selector + ( ObjectKey "glowMap" ) + , Selector + ( ObjectKey "chassis_gaugelight_warning" ) + ] + ) + , fromList + [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , + ( SomeKey ForceComplexNewLine + , SomeProperty ForceComplexNewLine True + ) + ] + ) , ( NodePattern ( fromList @@ -220,6 +241,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -503,6 +528,25 @@ RuleSet ) ] ) + , + ( NodePattern + ( fromList + [ AnyObjectKey + , Selector + ( ObjectKey "glowMap" ) + ] + ) + , fromList + [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , + ( SomeKey AutoPadSubObjects + , SomeProperty AutoPadSubObjects True + ) + ] + ) , ( NodePattern ( fromList @@ -513,6 +557,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -528,6 +576,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey AutoPad , SomeProperty AutoPad True ) @@ -543,6 +595,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -558,6 +614,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -573,6 +633,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) diff --git a/examples/formatted_jbeam/fender-complex-jbfl.jbeam b/examples/formatted_jbeam/fender-complex-jbfl.jbeam index 96de2e77..135f298c 100644 --- a/examples/formatted_jbeam/fender-complex-jbfl.jbeam +++ b/examples/formatted_jbeam/fender-complex-jbfl.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", diff --git a/examples/formatted_jbeam/frame-complex-jbfl.jbeam b/examples/formatted_jbeam/frame-complex-jbfl.jbeam index f07a72ec..f6c0f702 100644 --- a/examples/formatted_jbeam/frame-complex-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-complex-jbfl.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* @@ -388,6 +388,32 @@ "flexbodies" : [ ["mesh", "[group]:", "nonFlexMaterials"], ["rails", ["chassis_rails"]] - ] + ], + "glowMap" : { + // main lights + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + // gauge lights + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light + "chassis_gaugelight_warning" : { + "simpleFunction" : { + "checkengine" : 1, + "battery" : 1, + "lowpressure" : 1 + }, + "off" : "chassis_gauges", + "on" : "chassis_gauges_on" + } + } } } diff --git a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam index f07a72ec..82d2e2b3 100644 --- a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam @@ -388,6 +388,24 @@ "flexbodies" : [ ["mesh", "[group]:", "nonFlexMaterials"], ["rails", ["chassis_rails"]] - ] + ], + "glowMap" : { + // main lights + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + // gauge lights + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + } } } diff --git a/examples/formatted_jbeam/suspension-complex-jbfl.jbeam b/examples/formatted_jbeam/suspension-complex-jbfl.jbeam index b3416b0f..1d1c3f1b 100644 --- a/examples/formatted_jbeam/suspension-complex-jbfl.jbeam +++ b/examples/formatted_jbeam/suspension-complex-jbfl.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* The purpose of this file is prove that moving metadata along with vertices when diff --git a/examples/jbeam/frame.jbeam b/examples/jbeam/frame.jbeam index b0480a57..f743266a 100644 --- a/examples/jbeam/frame.jbeam +++ b/examples/jbeam/frame.jbeam @@ -1,395 +1,411 @@ { -"chassis_rails":{ - "information":{ - "authors":"gittarrgy01", - "name":"", - }, - "slotType":"main", - /* - The purpose of this file is prove that moving metadata - along with vertices when moving vertices works as intended. - See issue for #69 explanation on the transformation part of the codebase. - */ -//--Nodes-- - "nodes":[ - ["id", "posX", "posY", "posZ"], - {"group":"chassis_rails"}, - ["rl_f0",0.523,-2.098,0.319], - ["rl_f1",-0.417,-2.098,0.319], - ["rl_f2",0.053,-2.095,0.319], - ["rl_f3",0.523,-2.093,0.268], - ["rl_f4",-0.417,-2.093,0.268], - ["rl_f5",0.053,-2.09,0.269], - ["rl_f6",0.531,-1.724,0.341], - ["rl_f7",-0.424,-1.724,0.341], - ["rl_f8",0.531,-1.721,0.289], - ["rl_f9",-0.424,-1.721,0.289], - ["rl_f10",0.547,-1.35,0.31], - ["rl_f11",0.547,-1.35,0.364], - ["rl_f12",-0.44,-1.35,0.31], - ["rl_f13",-0.44,-1.35,0.364], - ["rl_f14",0.053,-1.314,0.382], // support for front - ["rl15",0.79,-0.919,0.182], - ["rl16",0.79,-0.919,0.233], - ["rl17",-0.683,-0.919,0.182], - ["rl18",-0.683,-0.919,0.233], - ["rl19",0.053,-0.024,0.578], // support - ["rl20",0.837,0.002,0.182], - ["rl21",0.837,0.002,0.233], - ["rl22",0.415,0.002,0.182], - ["rl23",0.415,0.002,0.233], - ["rl24",0.053,0.002,0.182], - ["rl25",0.053,0.002,0.233], - ["rl26",-0.308,0.002,0.182], - ["rl27",-0.308,0.002,0.233], - ["rl28",-0.73,0.002,0.182], - ["rl29",-0.73,0.002,0.233], - ["rl30",0.822,0.791,0.182], - ["rl31",0.822,0.791,0.233], - ["rl32",-0.715,0.791,0.182], - ["rl33",-0.715,0.791,0.233], - ["rl_r34",0.651,1.121,0.628], - ["rl_r35",0.053,1.121,0.628], - ["rl_r36",-0.544,1.121,0.628], - ["rl_r37",0.651,1.152,0.565], - ["rl_r38",0.053,1.152,0.565], - ["rl_r39",-0.544,1.152,0.565], - ["rl_r40",0.602,1.514,0.566], - ["rl_r41",-0.495,1.514,0.566], - ["rl_r42",0.602,1.532,0.623], - ["rl_r43",-0.495,1.532,0.623], - ["rl_r44",0.553,1.654,0.359], - ["rl_r45",-0.446,1.654,0.359], - ["rl_r46",0.553,1.679,0.448], - ["rl_r47",-0.446,1.679,0.448], - ["rl_r48",0.053,1.71,0.565], // support for rear - ["rl_r49",0.558,2.284,0.364], - ["rl_r50",0.558,2.284,0.447], - ["rl_r51",0.053,2.284,0.37], - ["rl_r52",0.053,2.284,0.441], - ["rl_r53",-0.451,2.284,0.364], - ["rl_r54",-0.451,2.284,0.447], - {"group":""}, - ], -//--Beams-- - "beams":[ - ["id1:", "id2:"], + "chassis_rails" : { + "information" : { + "authors" : "gittarrgy01", + "name" : "" + }, + "slotType" : "main", + /* + The purpose of this file is prove that moving metadata + along with vertices when moving vertices works as intended. + See issue for #69 explanation on the transformation part of the codebase. + */ + // --Nodes-- + "nodes" : [ + ["id", "posX", "posY", "posZ" ], + {"group" : "chassis_rails"}, + ["rl_f0", 0.523, -2.098, 0.319 ], + ["rl_f1", -0.417, -2.098, 0.319 ], + ["rl_f2", 0.053, -2.095, 0.319 ], + ["rl_f3", 0.523, -2.093, 0.268 ], + ["rl_f4", -0.417, -2.093, 0.268 ], + ["rl_f5", 0.053, -2.090, 0.269 ], + ["rl_f6", 0.531, -1.724, 0.341 ], + ["rl_f7", -0.424, -1.724, 0.341 ], + ["rl_f8", 0.531, -1.721, 0.289 ], + ["rl_f9", -0.424, -1.721, 0.289 ], + ["rl_f10", 0.547, -1.350, 0.310 ], + ["rl_f11", 0.547, -1.350, 0.364 ], + ["rl_f12", -0.440, -1.350, 0.310 ], + ["rl_f13", -0.440, -1.350, 0.364 ], + ["rl_f14", 0.053, -1.314, 0.382 ], // support for front + ["rl15", 0.790, -0.919, 0.182 ], + ["rl16", 0.790, -0.919, 0.233 ], + ["rl17", -0.683, -0.919, 0.182 ], + ["rl18", -0.683, -0.919, 0.233 ], + ["rl19", 0.053, -0.024, 0.578 ], // support + ["rl20", 0.837, 0.002, 0.182 ], + ["rl21", 0.837, 0.002, 0.233 ], + ["rl22", 0.415, 0.002, 0.182 ], + ["rl23", 0.415, 0.002, 0.233 ], + ["rl24", 0.053, 0.002, 0.182 ], + ["rl25", 0.053, 0.002, 0.233 ], + ["rl26", -0.308, 0.002, 0.182 ], + ["rl27", -0.308, 0.002, 0.233 ], + ["rl28", -0.730, 0.002, 0.182 ], + ["rl29", -0.730, 0.002, 0.233 ], + ["rl30", 0.822, 0.791, 0.182 ], + ["rl31", 0.822, 0.791, 0.233 ], + ["rl32", -0.715, 0.791, 0.182 ], + ["rl33", -0.715, 0.791, 0.233 ], + ["rl_r34", 0.651, 1.121, 0.628 ], + ["rl_r35", 0.053, 1.121, 0.628 ], + ["rl_r36", -0.544, 1.121, 0.628 ], + ["rl_r37", 0.651, 1.152, 0.565 ], + ["rl_r38", 0.053, 1.152, 0.565 ], + ["rl_r39", -0.544, 1.152, 0.565 ], + ["rl_r40", 0.602, 1.514, 0.566 ], + ["rl_r41", -0.495, 1.514, 0.566 ], + ["rl_r42", 0.602, 1.532, 0.623 ], + ["rl_r43", -0.495, 1.532, 0.623 ], + ["rl_r44", 0.553, 1.654, 0.359 ], + ["rl_r45", -0.446, 1.654, 0.359 ], + ["rl_r46", 0.553, 1.679, 0.448 ], + ["rl_r47", -0.446, 1.679, 0.448 ], + ["rl_r48", 0.053, 1.710, 0.565 ], // support for rear + ["rl_r49", 0.558, 2.284, 0.364 ], + ["rl_r50", 0.558, 2.284, 0.447 ], + ["rl_r51", 0.053, 2.284, 0.370 ], + ["rl_r52", 0.053, 2.284, 0.441 ], + ["rl_r53", -0.451, 2.284, 0.364 ], + ["rl_r54", -0.451, 2.284, 0.447 ], + {"group" : ""} + ], + // --Beams-- + "beams" : [ + ["id1:", "id2:"], + + // Structural beams + {"beamStrength" : "FLT_MAX", "beamSpring" : "3800000"}, + {"beamDamp" : 130, "deformLimit" : 1.1}, + + // Front end + {"beamDeform" : 20600, "deformLimit" : 1.1}, + ["rl_f3", "rl_f5"], + ["rl_f0", "rl_f3"], + ["rl_f8", "rl_f3"], + ["rl15", "rl_f10"], + ["rl_f8", "rl_f6"], + ["rl_f11", "rl_f10"], + ["rl_f10", "rl_f8"], + ["rl_f9", "rl_f7"], + ["rl17", "rl_f12"], + ["rl_f6", "rl_f11"], + ["rl_f11", "rl16"], + ["rl_f13", "rl18"], + ["rl_f13", "rl_f12"], + ["rl_f1", "rl_f4"], + ["rl_f2", "rl_f1"], + ["rl_f2", "rl_f5"], + ["rl_f12", "rl_f9"], + ["rl_f7", "rl_f13"], + ["rl_f0", "rl_f6"], + ["rl_f9", "rl_f4"], + ["rl_f2", "rl_f0"], + ["rl_f4", "rl_f5"], + ["rl_f1", "rl_f7"], - //Structural beams - {"beamStrength":"FLT_MAX", "beamSpring":"3800000"}, - {"beamDamp":130, "deformLimit":1.1}, + // Middle + {"beamDeform" : 27000}, + ["rl16", "rl15"], + ["rl20", "rl30"], + ["rl16", "rl23"], + ["rl18", "rl17"], + ["rl17", "rl28"], + ["rl26", "rl17"], + ["rl18", "rl27"], + ["rl26", "rl24"], + ["rl25", "rl24"], + ["rl25", "rl27"], + ["rl21", "rl16"], + ["rl22", "rl15"], + ["rl15", "rl20"], + ["rl29", "rl27"], + ["rl28", "rl32"], + ["rl29", "rl18"], + ["rl22", "rl24"], + ["rl31", "rl21"], + ["rl28", "rl29"], + ["rl32", "rl33"], + ["rl30", "rl31"], + ["rl33", "rl29"], + ["rl30", "rl22"], + ["rl25", "rl23"], + ["rl32", "rl26"], + ["rl20", "rl21"], + ["rl31", "rl23"], + ["rl20", "rl22"], + ["rl21", "rl23"], + ["rl33", "rl27"], + ["rl23", "rl22"], + ["rl28", "rl26"], + ["rl27", "rl26"], - //Front end - {"beamDeform":20600, "deformLimit":1.1}, - ["rl_f3","rl_f5"], - ["rl_f0","rl_f3"], - ["rl_f8","rl_f3"], - ["rl15","rl_f10"], - ["rl_f8","rl_f6"], - ["rl_f11","rl_f10"], - ["rl_f10","rl_f8"], - ["rl_f9","rl_f7"], - ["rl17","rl_f12"], - ["rl_f6","rl_f11"], - ["rl_f11","rl16"], - ["rl_f13","rl18"], - ["rl_f13","rl_f12"], - ["rl_f1","rl_f4"], - ["rl_f2","rl_f1"], - ["rl_f2","rl_f5"], - ["rl_f12","rl_f9"], - ["rl_f7","rl_f13"], - ["rl_f0","rl_f6"], - ["rl_f9","rl_f4"], - ["rl_f2","rl_f0"], - ["rl_f4","rl_f5"], - ["rl_f1","rl_f7"], + // Rear end + {"beamDeform" : 22000}, + ["rl_r37", "rl_r34"], + ["rl_r39", "rl_r41"], + ["rl_r44", "rl_r46"], + ["rl33", "rl_r36"], + ["rl_r46", "rl_r42"], + ["rl31", "rl_r34"], + ["rl_r37", "rl30"], + ["rl_r49", "rl_r51"], + ["rl_r52", "rl_r50"], + ["rl_r50", "rl_r46"], + ["rl_r49", "rl_r50"], + ["rl_r42", "rl_r34"], + ["rl_r40", "rl_r44"], + ["rl_r40", "rl_r42"], + ["rl_r41", "rl_r45"], + ["rl_r39", "rl_r36"], + ["rl_r36", "rl_r35"], + ["rl_r38", "rl_r35"], + ["rl_r53", "rl_r54"], + ["rl_r52", "rl_r54"], + ["rl_r51", "rl_r52"], + ["rl_r45", "rl_r53"], + ["rl_r54", "rl_r47"], + ["rl_r43", "rl_r36"], + ["rl_r53", "rl_r51"], + ["rl_r34", "rl_r35"], + ["rl_r38", "rl_r37"], + ["rl_r45", "rl_r47"], + ["rl_r41", "rl_r43"], + ["rl_r38", "rl_r39"], + ["rl_r39", "rl32"], + ["rl_r47", "rl_r43"], + ["rl_r44", "rl_r49"], + ["rl_r37", "rl_r40"], - //Middle - {"beamDeform":27000}, - ["rl16","rl15"], - ["rl20","rl30"], - ["rl16","rl23"], - ["rl18","rl17"], - ["rl17","rl28"], - ["rl26","rl17"], - ["rl18","rl27"], - ["rl26","rl24"], - ["rl25","rl24"], - ["rl25","rl27"], - ["rl21","rl16"], - ["rl22","rl15"], - ["rl15","rl20"], - ["rl29","rl27"], - ["rl28","rl32"], - ["rl29","rl18"], - ["rl22","rl24"], - ["rl31","rl21"], - ["rl28","rl29"], - ["rl32","rl33"], - ["rl30","rl31"], - ["rl33","rl29"], - ["rl30","rl22"], - ["rl25","rl23"], - ["rl32","rl26"], - ["rl20","rl21"], - ["rl31","rl23"], - ["rl20","rl22"], - ["rl21","rl23"], - ["rl33","rl27"], - ["rl23","rl22"], - ["rl28","rl26"], - ["rl27","rl26"], - - //Rear end - {"beamDeform":22000}, - ["rl_r37","rl_r34"], - ["rl_r39","rl_r41"], - ["rl_r44","rl_r46"], - ["rl33","rl_r36"], - ["rl_r46","rl_r42"], - ["rl31","rl_r34"], - ["rl_r37","rl30"], - ["rl_r49","rl_r51"], - ["rl_r52","rl_r50"], - ["rl_r50","rl_r46"], - ["rl_r49","rl_r50"], - ["rl_r42","rl_r34"], - ["rl_r40","rl_r44"], - ["rl_r40","rl_r42"], - ["rl_r41","rl_r45"], - ["rl_r39","rl_r36"], - ["rl_r36","rl_r35"], - ["rl_r38","rl_r35"], - ["rl_r53","rl_r54"], - ["rl_r52","rl_r54"], - ["rl_r51","rl_r52"], - ["rl_r45","rl_r53"], - ["rl_r54","rl_r47"], - ["rl_r43","rl_r36"], - ["rl_r53","rl_r51"], - ["rl_r34","rl_r35"], - ["rl_r38","rl_r37"], - ["rl_r45","rl_r47"], - ["rl_r41","rl_r43"], - ["rl_r38","rl_r39"], - ["rl_r39","rl32"], - ["rl_r47","rl_r43"], - ["rl_r44","rl_r49"], - ["rl_r37","rl_r40"], + // Crossing beams - //Crossing beams - - //Front end - {"beamDeform":16000}, - ["rl_f4","rl_f2"], - ["rl_f0","rl_f8"], - ["rl16","rl_f10"], - ["rl15","rl_f11"], - ["rl_f10","rl_f6"], - ["rl_f11","rl_f8"], - ["rl_f1","rl_f5"], - ["rl_f4","rl_f7"], - ["rl_f1","rl_f9"], - ["rl_f12","rl_f7"], - ["rl_f3","rl_f6"], - ["rl_f0","rl_f5"], - ["rl_f3","rl_f2"], - ["rl_f13","rl_f9"], - ["rl17","rl_f13"], - ["rl18","rl_f12"], + // Front end + {"beamDeform" : 16000}, + ["rl_f4", "rl_f2"], + ["rl_f0", "rl_f8"], + ["rl16", "rl_f10"], + ["rl15", "rl_f11"], + ["rl_f10", "rl_f6"], + ["rl_f11", "rl_f8"], + ["rl_f1", "rl_f5"], + ["rl_f4", "rl_f7"], + ["rl_f1", "rl_f9"], + ["rl_f12", "rl_f7"], + ["rl_f3", "rl_f6"], + ["rl_f0", "rl_f5"], + ["rl_f3", "rl_f2"], + ["rl_f13", "rl_f9"], + ["rl17", "rl_f13"], + ["rl18", "rl_f12"], - //Middle - {"beamDeform":6500}, - ["rl16","rl20"], - ["rl15","rl23"], - ["rl18","rl28"], - ["rl18","rl26"], - ["rl17","rl27"], - ["rl27","rl24"], - ["rl26","rl25"], - ["rl31","rl20"], - ["rl15","rl21"], - ["rl16","rl22"], - ["rl32","rl29"], - ["rl30","rl21"], - ["rl23","rl24"], - ["rl32","rl27"], - ["rl17","rl29"], - ["rl33","rl28"], - ["rl29","rl26"], - ["rl30","rl23"], - ["rl33","rl26"], - ["rl22","rl25"], - ["rl20","rl23"], - ["rl28","rl27"], - ["rl31","rl22"], - ["rl21","rl22"], + // Middle + {"beamDeform" : 6500}, + ["rl16", "rl20"], + ["rl15", "rl23"], + ["rl18", "rl28"], + ["rl18", "rl26"], + ["rl17", "rl27"], + ["rl27", "rl24"], + ["rl26", "rl25"], + ["rl31", "rl20"], + ["rl15", "rl21"], + ["rl16", "rl22"], + ["rl32", "rl29"], + ["rl30", "rl21"], + ["rl23", "rl24"], + ["rl32", "rl27"], + ["rl17", "rl29"], + ["rl33", "rl28"], + ["rl29", "rl26"], + ["rl30", "rl23"], + ["rl33", "rl26"], + ["rl22", "rl25"], + ["rl20", "rl23"], + ["rl28", "rl27"], + ["rl31", "rl22"], + ["rl21", "rl22"], - //Rear end - {"beamDeform":16000}, - ["rl_r54","rl_r45"], - ["rl32","rl_r36"], - ["rl_r36","rl_r41"], - ["rl_r50","rl_r51"], - ["rl31","rl_r37"], - ["rl30","rl_r34"], - ["rl_r46","rl_r40"], - ["rl_r53","rl_r47"], - ["rl_r50","rl_r44"], - ["rl_r49","rl_r46"], - ["rl_r37","rl_r42"], - ["rl_r34","rl_r40"], - ["rl_r34","rl_r38"], - ["rl33","rl_r39"], - ["rl_r39","rl_r35"], - ["rl_r36","rl_r38"], - ["rl_r53","rl_r52"], - ["rl_r54","rl_r51"], - ["rl_r45","rl_r43"], - ["rl_r47","rl_r41"], - ["rl_r39","rl_r43"], - ["rl_r37","rl_r35"], - ["rl_r49","rl_r52"], - ["rl_r44","rl_r42"], + // Rear end + {"beamDeform" : 16000}, + ["rl_r54", "rl_r45"], + ["rl32", "rl_r36"], + ["rl_r36", "rl_r41"], + ["rl_r50", "rl_r51"], + ["rl31", "rl_r37"], + ["rl30", "rl_r34"], + ["rl_r46", "rl_r40"], + ["rl_r53", "rl_r47"], + ["rl_r50", "rl_r44"], + ["rl_r49", "rl_r46"], + ["rl_r37", "rl_r42"], + ["rl_r34", "rl_r40"], + ["rl_r34", "rl_r38"], + ["rl33", "rl_r39"], + ["rl_r39", "rl_r35"], + ["rl_r36", "rl_r38"], + ["rl_r53", "rl_r52"], + ["rl_r54", "rl_r51"], + ["rl_r45", "rl_r43"], + ["rl_r47", "rl_r41"], + ["rl_r39", "rl_r43"], + ["rl_r37", "rl_r35"], + ["rl_r49", "rl_r52"], + ["rl_r44", "rl_r42"], - //Support beams - - //Front end - {"beamDeform":19000}, - ["rl_f8","rl_f14"], - ["rl_f9","rl_f14"], - ["rl_f","rl_f3"], - ["rl_f10","rl_f14"], - ["rl_f14","rl_f13"], - ["rl_f1","rl_f14"], - ["rl_f0","rl_f14"], - ["rl_f12","rl_f14"], - ["rl_f5","rl_f14"], - ["rl_f14","rl_f4"], - ["rl_f14","rl_f6"], - ["rl_f14","rl_f7"], - ["rl_f14","rl_f2"], - ["rl_f14","rl_f11"], + // Support beams - //Middle - {"beamDeform":11000}, - ["rl27","rl19"], - ["rl26","rl19"], - ["rl24","rl19"], - ["rl23","rl19"], - ["rl20","rl19"], - ["rl19","rl16"], - ["rl19","rl15"], - ["rl31","rl19"], - ["rl33","rl19"], - ["rl28","rl19"], - ["rl19","rl25"], - ["rl21","rl19"], - ["rl22","rl19"], - ["rl19","rl32"], - ["rl29","rl19"], - ["rl19","rl18"], - ["rl19","rl17"], - ["rl19","rl30"], + // Front end + {"beamDeform" : 19000}, + ["rl_f8", "rl_f14"], + ["rl_f9", "rl_f14"], + ["rl_f", "rl_f3"], + ["rl_f10", "rl_f14"], + ["rl_f14", "rl_f13"], + ["rl_f1", "rl_f14"], + ["rl_f0", "rl_f14"], + ["rl_f12", "rl_f14"], + ["rl_f5", "rl_f14"], + ["rl_f14", "rl_f4"], + ["rl_f14", "rl_f6"], + ["rl_f14", "rl_f7"], + ["rl_f14", "rl_f2"], + ["rl_f14", "rl_f11"], - //Rear end - {"beamDeform":19000}, - ["rl_r48","rl_r51"], - ["rl_r48","rl_r54"], - ["rl_r45","rl_r48"], - ["rl_r48","rl_r50"], - ["rl_r48","rl_r42"], - ["rl_r48","rl_r47"], - ["rl_r49","rl_r48"], - ["rl_r35","rl_r48"], - ["rl_r48","rl_r43"], - ["rl_r44","rl_r48"], - ["rl_r53","rl_r48"], - ["rl_r52","rl_r48"], - ["rl_r40","rl_r48"], - ["rl_r48","rl_r38"], - ["rl_r41","rl_r48"], - ["rl_r4","rl_r46"], + // Middle + {"beamDeform" : 11000}, + ["rl27", "rl19"], + ["rl26", "rl19"], + ["rl24", "rl19"], + ["rl23", "rl19"], + ["rl20", "rl19"], + ["rl19", "rl16"], + ["rl19", "rl15"], + ["rl31", "rl19"], + ["rl33", "rl19"], + ["rl28", "rl19"], + ["rl19", "rl25"], + ["rl21", "rl19"], + ["rl22", "rl19"], + ["rl19", "rl32"], + ["rl29", "rl19"], + ["rl19", "rl18"], + ["rl19", "rl17"], + ["rl19", "rl30"], - //Front crush - {"beamDeform":8500}, - ["rl17","rl_f9"], - ["rl15","rl_f8"], + // Rear end + {"beamDeform" : 19000}, + ["rl_r48", "rl_r51"], + ["rl_r48", "rl_r54"], + ["rl_r45", "rl_r48"], + ["rl_r48", "rl_r50"], + ["rl_r48", "rl_r42"], + ["rl_r48", "rl_r47"], + ["rl_r49", "rl_r48"], + ["rl_r35", "rl_r48"], + ["rl_r48", "rl_r43"], + ["rl_r44", "rl_r48"], + ["rl_r53", "rl_r48"], + ["rl_r52", "rl_r48"], + ["rl_r40", "rl_r48"], + ["rl_r48", "rl_r38"], + ["rl_r41", "rl_r48"], + ["rl_r4", "rl_r46"], - ], -//--Collision Triangles-- - "triangles":[ - ["id1:", "id2:", "id3:"], - ["rl_f5","rl_f3","rl_f2"], - ["rl_f0","rl_f2","rl_f3"], - ["rl_f5","rl_f2","rl_f4"], - ["rl_f1","rl_f4","rl_f2"], - ["rl_f4","rl_f1","rl_f7"], - ["rl_f4","rl_f7","rl_f9"], - ["rl_f7","rl_f13","rl_f9"], - ["rl_f12","rl_f9","rl_f13"], - ["rl_f12","rl_f13","rl18"], - ["rl18","rl17","rl_f12"], - ["rl_f3","rl_f6","rl_f0"], - ["rl_f3","rl_f8","rl_f6"], - ["rl_f10","rl_f11","rl_f8"], - ["rl_f6","rl_f8","rl_f11"], - ["rl_f10","rl16","rl_f11"], - ["rl16","rl_f10","rl15"], - ["rl15","rl20","rl16"], - ["rl21","rl16","rl20"], - ["rl30","rl21","rl20"], - ["rl31","rl21","rl30"], - ["rl17","rl18","rl28"], - ["rl29","rl28","rl18"], - ["rl32","rl28","rl29"], - ["rl33","rl32","rl29"], - ["rl32","rl33","rl_r39"], - ["rl_r39","rl33","rl_r36"], - ["rl_r36","rl_r41","rl_r39"], - ["rl_r43","rl_r41","rl_r36"], - ["rl_r45","rl_r41","rl_r43"], - ["rl_r47","rl_r45","rl_r43"], - ["rl_r53","rl_r45","rl_r47"], - ["rl_r54","rl_r53","rl_r47"], - ["rl_r54","rl_r51","rl_r53"], - ["rl_r51","rl_r54","rl_r52"], - ["rl_r52","rl_r50","rl_r51"], - ["rl_r50","rl_r49","rl_r51"], - ["rl_r46","rl_r44","rl_r49"], - ["rl_r50","rl_r46","rl_r49"], - ["rl_r46","rl_r42","rl_r44"], - ["rl_r44","rl_r42","rl_r40"], - ["rl_r34","rl_r37","rl_r40"], - ["rl_r42","rl_r34","rl_r40"], - ["rl_r34","rl_r35","rl_r37"], - ["rl_r35","rl_r38","rl_r37"], - ["rl_r35","rl_r39","rl_r38"], - ["rl_r39","rl_r35","rl_r36"], - ["rl30","rl_r37","rl31"], - ["rl_r37","rl_r34","rl31"], - ["rl16","rl15","rl22"], - ["rl16","rl22","rl23"], - ["rl23","rl22","rl21"], - ["rl21","rl22","rl20"], - ["rl27","rl29","rl26"], - ["rl29","rl28","rl26"], - ["rl18","rl26","rl17"], - ["rl27","rl26","rl18"], - ["rl24","rl22","rl23"], - ["rl27","rl26","rl24"], - ["rl24","rl25","rl27"], - ["rl24","rl23","rl25"], - ["rl30","rl23","rl22"], - ["rl30","rl31","rl23"], - ["rl26","rl27","rl32"], - ["rl33","rl32","rl27"], - - ], - "flexbodies": [ - ["mesh", "[group]:", "nonFlexMaterials"], - ["rails", ["chassis_rails"]], + // Front crush + {"beamDeform" : 8500}, + ["rl17", "rl_f9"], + ["rl15", "rl_f8"] + ], + // --Collision Triangles-- + "triangles" : [ + ["id1:", "id2:", "id3:"], + ["rl_f5", "rl_f3", "rl_f2"], + ["rl_f0", "rl_f2", "rl_f3"], + ["rl_f5", "rl_f2", "rl_f4"], + ["rl_f1", "rl_f4", "rl_f2"], + ["rl_f4", "rl_f1", "rl_f7"], + ["rl_f4", "rl_f7", "rl_f9"], + ["rl_f7", "rl_f13", "rl_f9"], + ["rl_f12", "rl_f9", "rl_f13"], + ["rl_f12", "rl_f13", "rl18"], + ["rl18", "rl17", "rl_f12"], + ["rl_f3", "rl_f6", "rl_f0"], + ["rl_f3", "rl_f8", "rl_f6"], + ["rl_f10", "rl_f11", "rl_f8"], + ["rl_f6", "rl_f8", "rl_f11"], + ["rl_f10", "rl16", "rl_f11"], + ["rl16", "rl_f10", "rl15"], + ["rl15", "rl20", "rl16"], + ["rl21", "rl16", "rl20"], + ["rl30", "rl21", "rl20"], + ["rl31", "rl21", "rl30"], + ["rl17", "rl18", "rl28"], + ["rl29", "rl28", "rl18"], + ["rl32", "rl28", "rl29"], + ["rl33", "rl32", "rl29"], + ["rl32", "rl33", "rl_r39"], + ["rl_r39", "rl33", "rl_r36"], + ["rl_r36", "rl_r41", "rl_r39"], + ["rl_r43", "rl_r41", "rl_r36"], + ["rl_r45", "rl_r41", "rl_r43"], + ["rl_r47", "rl_r45", "rl_r43"], + ["rl_r53", "rl_r45", "rl_r47"], + ["rl_r54", "rl_r53", "rl_r47"], + ["rl_r54", "rl_r51", "rl_r53"], + ["rl_r51", "rl_r54", "rl_r52"], + ["rl_r52", "rl_r50", "rl_r51"], + ["rl_r50", "rl_r49", "rl_r51"], + ["rl_r46", "rl_r44", "rl_r49"], + ["rl_r50", "rl_r46", "rl_r49"], + ["rl_r46", "rl_r42", "rl_r44"], + ["rl_r44", "rl_r42", "rl_r40"], + ["rl_r34", "rl_r37", "rl_r40"], + ["rl_r42", "rl_r34", "rl_r40"], + ["rl_r34", "rl_r35", "rl_r37"], + ["rl_r35", "rl_r38", "rl_r37"], + ["rl_r35", "rl_r39", "rl_r38"], + ["rl_r39", "rl_r35", "rl_r36"], + ["rl30", "rl_r37", "rl31"], + ["rl_r37", "rl_r34", "rl31"], + ["rl16", "rl15", "rl22"], + ["rl16", "rl22", "rl23"], + ["rl23", "rl22", "rl21"], + ["rl21", "rl22", "rl20"], + ["rl27", "rl29", "rl26"], + ["rl29", "rl28", "rl26"], + ["rl18", "rl26", "rl17"], + ["rl27", "rl26", "rl18"], + ["rl24", "rl22", "rl23"], + ["rl27", "rl26", "rl24"], + ["rl24", "rl25", "rl27"], + ["rl24", "rl23", "rl25"], + ["rl30", "rl23", "rl22"], + ["rl30", "rl31", "rl23"], + ["rl26", "rl27", "rl32"], + ["rl33", "rl32", "rl27"] + ], + "flexbodies" : [ + ["mesh", "[group]:", "nonFlexMaterials"], + ["rails", ["chassis_rails"]] ], -}, + "glowMap" : { + // main lights + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + // gauge lights + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + } + } } diff --git a/examples/jbfl/complex.jbfl b/examples/jbfl/complex.jbfl index 734c3613..0b3596db 100644 --- a/examples/jbfl/complex.jbfl +++ b/examples/jbfl/complex.jbfl @@ -3,6 +3,10 @@ PadDecimals: 3; // Show 3 decimal places for uniformity } +.*.nodes { + AlignObjectKeys : true; +} + .*.nodes, .*.beams, .*.triangles { AutoPad : true; } @@ -19,9 +23,16 @@ NoComplexNewLine : true; } +.*.glowMap { + AlignObjectKeys: true; + AutoPadSubObjects: true; +} + .*.sounds, .*.soundConfig, .*.soundConfigExhaust, -.*.information, .*.glowMap.dumptruck_gaugelight_warning { +.*.information, .*.glowMap.dumptruck_gaugelight_warning, +.*.glowMap.chassis_gaugelight_warning { ForceComplexNewLine: true; + AlignObjectKeys: true; } // extra padding for glowMap indicators diff --git a/examples/transformed_jbeam/frame-cfg-default.jbeam b/examples/transformed_jbeam/frame-cfg-default.jbeam index f55010cc..63bdeafb 100644 --- a/examples/transformed_jbeam/frame-cfg-default.jbeam +++ b/examples/transformed_jbeam/frame-cfg-default.jbeam @@ -413,6 +413,24 @@ "flexbodies" : [ ["mesh", "[group]:", "nonFlexMaterials"], ["rails", ["chassis_rails"]] - ] + ], + "glowMap" : { + // main lights + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + // gauge lights + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + } } } diff --git a/examples/transformed_jbeam/frame-cfg-example.jbeam b/examples/transformed_jbeam/frame-cfg-example.jbeam index f55010cc..63bdeafb 100644 --- a/examples/transformed_jbeam/frame-cfg-example.jbeam +++ b/examples/transformed_jbeam/frame-cfg-example.jbeam @@ -413,6 +413,24 @@ "flexbodies" : [ ["mesh", "[group]:", "nonFlexMaterials"], ["rails", ["chassis_rails"]] - ] + ], + "glowMap" : { + // main lights + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + // gauge lights + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + } } } diff --git a/src/JbeamEdit/Formatting.hs b/src/JbeamEdit/Formatting.hs index c16b4e17..b7da5f96 100644 --- a/src/JbeamEdit/Formatting.hs +++ b/src/JbeamEdit/Formatting.hs @@ -14,6 +14,8 @@ import Data.Bool (bool) import Data.ByteString.Lazy qualified as LBS (fromStrict) import Data.Char (isSpace) import Data.Foldable.Extra (notNull) +import Data.Map.Strict (Map) +import Data.Map.Strict qualified as Map import Data.Maybe (fromMaybe) import Data.Monoid.Extra import Data.Scientific (FPFormat (Fixed), formatScientific) @@ -52,6 +54,8 @@ data FormattingState = FormattingState , fsFormattedCache :: Vector (Vector Text) , fsHeaderWasExtracted :: Bool , fsCurrentRowIdx :: Maybe Int + , fsObjectKeyWidth :: Maybe Int + , fsSubObjectWidths :: Map Text Int } emptyState :: FormattingState @@ -62,6 +66,8 @@ emptyState = , fsFormattedCache = V.empty , fsHeaderWasExtracted = False , fsCurrentRowIdx = Nothing + , fsObjectKeyWidth = Nothing + , fsSubObjectWidths = Map.empty } splitTrailing :: Bool -> Text -> (Text, Text) @@ -160,6 +166,22 @@ addDelimiters rs index rowIdx c complexChildren state acc ns@(node : rest) else emptyState (formatted, spaces) = splitTrailing comma (NC.applyCrumb c (formatWithCursor rs state') idx n) in formatted <> singleCharIf ',' comma <> spaces + ObjectKey (k, _) -> + let stateForObjKey = + emptyState + { fsObjectKeyWidth = fsObjectKeyWidth state + , fsSubObjectWidths = fsSubObjectWidths state + } + keyText = formatScalarNode k + raw = NC.applyCrumb c (formatWithCursor rs stateForObjKey) idx n + (formatted, spaces) = splitTrailing comma raw + withComma = formatted <> singleCharIf ',' comma <> spaces + in case Map.lookup keyText (fsSubObjectWidths state) of + Just vw + | comma -> + let kw = fromMaybe (T.length keyText) (fsObjectKeyWidth state) + in T.justifyLeft (kw + 3 + vw + 1) ' ' withComma + _ -> withComma _ -> let (formatted, spaces) = splitTrailing comma (NC.applyCrumb c (formatWithCursor rs emptyState) idx n) in formatted <> singleCharIf ',' comma <> spaces @@ -190,7 +212,7 @@ maxColumnLengthsWithCache rs cursor nodes in (columnWidths, formattedColumns, headerWasExtracted) where scalarLength n - | T.isPrefixOf "{" n || T.isPrefixOf "[" n = 0 + | T.any (== '\n') n = 0 | otherwise = T.length n extractArrayRows ns offset = let indexed = V.indexed ns @@ -209,21 +231,23 @@ transposeAndFormat -> Vector (Vector Node) -> Vector Int -> Vector (Vector Text) -transposeAndFormat rs cursor vvs arrayIndices = - let numCols = V.maximum (V.map V.length vvs) - in V.generate numCols $ \colIdx -> - V.imap - ( \rowIdx row -> - if colIdx < V.length row - then - let actualRowIdx = arrayIndices V.! rowIdx - formatRow rowCursor _rowNode = - let formatCell = formatWithCursor rs emptyState - in NC.applyCrumb rowCursor formatCell colIdx (row V.! colIdx) - in NC.applyCrumb cursor formatRow actualRowIdx (Array row) - else "" - ) - vvs +transposeAndFormat rs cursor vvs arrayIndices + | V.null vvs = V.empty + | otherwise = + let numCols = V.maximum (V.map V.length vvs) + in V.generate numCols $ \colIdx -> + V.imap + ( \rowIdx row -> + if colIdx < V.length row + then + let actualRowIdx = arrayIndices V.! rowIdx + formatRow rowCursor _rowNode = + let formatCell = formatWithCursor rs emptyState + in NC.applyCrumb rowCursor formatCell colIdx (row V.! colIdx) + in NC.applyCrumb cursor formatRow actualRowIdx (Array row) + else "" + ) + vvs doFormatNode :: RuleSet @@ -236,6 +260,8 @@ doFormatNode rs cursor state nodes = exactProps = findPropertiesForCursor ExactMatch cursor rs autoPadEnabled = lookupRule AutoPad exactProps == Just True + alignObjectKeysEnabled = lookupRule AlignObjectKeys exactProps == Just True + autopadSubObjectsEnabled = lookupRule AutoPadSubObjects exactProps == Just True complexChildren = (lookupRule ForceComplexNewLine prefixProps == Just True) @@ -245,17 +271,64 @@ doFormatNode rs cursor state nodes = (colWidths, formattedCache, headerWasExtracted) = maxColumnLengthsWithCache rs cursor nodes - state' = - if autoPadEnabled - then + objectKeyItems = + V.mapMaybe + ( \(i, n) -> case n of + ObjectKey (k, v) -> Just (i, k, v) + _ -> Nothing + ) + (V.indexed nodes) + + maxKeyW + | V.null objectKeyItems = Nothing + | otherwise = + Just . V.maximum . V.map (\(_, k, _) -> T.length (formatScalarNode k)) $ + objectKeyItems + + subObjectWidths :: Map Text Int + subObjectWidths + | autopadSubObjectsEnabled = + V.foldl' + ( \acc n -> case n of + ObjectKey (_, Object subNodes) -> + V.foldl' + ( \acc2 sn -> case sn of + ObjectKey (sk, sv) -> + let kt = formatScalarNode sk + vt = formatWithCursor rs emptyState cursor sv + vw = if T.any (== '\n') vt || isComplexNode sv then 0 else T.length vt + in Map.insertWith max kt vw acc2 + _ -> acc2 + ) + acc + subNodes + _ -> acc + ) + Map.empty + nodes + | otherwise = Map.empty + + newKeyWidth = if alignObjectKeysEnabled then maxKeyW else Nothing + newSubWidths = if autopadSubObjectsEnabled then subObjectWidths else Map.empty + + state' + | autoPadEnabled + , not (V.null colWidths) = FormattingState { fsUsePad = True , fsColumnWidths = colWidths , fsFormattedCache = formattedCache , fsHeaderWasExtracted = headerWasExtracted , fsCurrentRowIdx = Nothing + , fsObjectKeyWidth = Nothing + , fsSubObjectWidths = Map.empty + } + | alignObjectKeysEnabled || autopadSubObjectsEnabled = + emptyState + { fsObjectKeyWidth = newKeyWidth + , fsSubObjectWidths = newSubWidths } - else state + | otherwise = state formatted = reverse @@ -311,11 +384,11 @@ formatWithCursor rs state cursor (Object o) , "}" ] formatWithCursor rs state cursor (ObjectKey (k, v)) = - T.concat - [ formatWithCursor rs state cursor k - , " : " - , formatWithCursor rs state cursor v - ] + let keyText = formatWithCursor rs state cursor k + paddedKey = maybe keyText (\w -> T.justifyLeft w ' ' keyText) (fsObjectKeyWidth state) + stateForValue = emptyState {fsSubObjectWidths = fsSubObjectWidths state} + valueText = formatWithCursor rs stateForValue cursor v + in paddedKey <> " : " <> valueText formatWithCursor _ _ _ (Comment comment) = formatComment comment formatWithCursor rs _ cursor n = let ps = findPropertiesForCursor PrefixMatch cursor rs diff --git a/src/JbeamEdit/Formatting/Rules.hs b/src/JbeamEdit/Formatting/Rules.hs index 58f6dbcf..3335964d 100644 --- a/src/JbeamEdit/Formatting/Rules.hs +++ b/src/JbeamEdit/Formatting/Rules.hs @@ -75,6 +75,8 @@ data PropertyKey a where AutoPad :: PropertyKey Bool NoComplexNewLine :: PropertyKey Bool ForceComplexNewLine :: PropertyKey Bool + AlignObjectKeys :: PropertyKey Bool + AutoPadSubObjects :: PropertyKey Bool PadAmount :: PropertyKey Int PadDecimals :: PropertyKey Int Indent :: PropertyKey Int @@ -107,6 +109,8 @@ eqKey AutoPad AutoPad = Just Refl eqKey PadAmount PadAmount = Just Refl eqKey NoComplexNewLine NoComplexNewLine = Just Refl eqKey ForceComplexNewLine ForceComplexNewLine = Just Refl +eqKey AlignObjectKeys AlignObjectKeys = Just Refl +eqKey AutoPadSubObjects AutoPadSubObjects = Just Refl eqKey PadDecimals PadDecimals = Just Refl eqKey Indent Indent = Just Refl eqKey _ _ = Nothing @@ -147,6 +151,8 @@ propertyName :: PropertyKey a -> Text propertyName AutoPad = "AutoPad" propertyName NoComplexNewLine = "NoComplexNewLine" propertyName ForceComplexNewLine = "ForceComplexNewLine" +propertyName AlignObjectKeys = "AlignObjectKeys" +propertyName AutoPadSubObjects = "AutoPadSubObjects" propertyName PadAmount = "PadAmount" propertyName PadDecimals = "PadDecimals" propertyName Indent = "Indent" @@ -158,7 +164,15 @@ lookupKey :: Text -> [SomeKey] -> Maybe SomeKey lookupKey txt = find (\(SomeKey k) -> propertyName k == txt) boolProperties :: [SomeKey] -boolProperties = map SomeKey [ForceComplexNewLine, NoComplexNewLine, AutoPad] +boolProperties = + map + SomeKey + [ ForceComplexNewLine + , NoComplexNewLine + , AutoPad + , AlignObjectKeys + , AutoPadSubObjects + ] intProperties :: [SomeKey] intProperties = map SomeKey [PadAmount, PadDecimals, Indent] diff --git a/src/JbeamEdit/Parsing/DSL.hs b/src/JbeamEdit/Parsing/DSL.hs index c8ed9fec..595ad7f9 100644 --- a/src/JbeamEdit/Parsing/DSL.hs +++ b/src/JbeamEdit/Parsing/DSL.hs @@ -94,6 +94,8 @@ parseValueForKey :: PropertyKey a -> JbflParser a parseValueForKey AutoPad = parseBool "bool" parseValueForKey NoComplexNewLine = parseBool "bool" parseValueForKey ForceComplexNewLine = parseBool "bool" +parseValueForKey AlignObjectKeys = parseBool "bool" +parseValueForKey AutoPadSubObjects = parseBool "bool" parseValueForKey PadAmount = L.decimal "integer" parseValueForKey PadDecimals = L.decimal "integer" parseValueForKey Indent = L.decimal "integer" diff --git a/tools/dump_ast/Main.hs b/tools/dump_ast/Main.hs index 16025217..dfefb847 100644 --- a/tools/dump_ast/Main.hs +++ b/tools/dump_ast/Main.hs @@ -110,7 +110,7 @@ dumpJbflAST dir outDir filename = do contents <- LBS.readFile (dir filename) case parseDSL contents of Right rs -> dump rs >> pure (outDir filename) - Left _ -> error $ "error " ++ filename + Left err -> error $ "error " ++ filename ++ T.unpack err where dump contents = let outFile = outDir takeBaseName filename ++ ".hs" From 4d68115b2a61fd79d824164357d26bc3089c41e6 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:44:56 +0100 Subject: [PATCH 2/6] Update examples and fixtures for AlignObjectKeys and AutoPadSubObjects - Update minimal.jbfl with AlignObjectKeys and AutoPadSubObjects rules - Regenerate all affected formatted/transformed jbeam fixtures - Regenerate minimal.jbfl AST --- examples/ast/jbfl/minimal.hs | 262 +++--------------- .../formatted_jbeam/fender-minimal-jbfl.jbeam | 10 +- .../formatted_jbeam/frame-minimal-jbfl.jbeam | 28 +- .../suspension-minimal-jbfl.jbeam | 2 +- examples/jbfl/minimal.jbfl | 24 +- .../fender-after-frame-cfg-default.jbeam | 10 +- .../fender-after-frame-cfg-example.jbeam | 10 +- .../fender-cfg-default.jbeam | 10 +- .../fender-cfg-example.jbeam | 10 +- .../transformed_jbeam/frame-cfg-default.jbeam | 28 +- .../transformed_jbeam/frame-cfg-example.jbeam | 28 +- .../suspension-cfg-default.jbeam | 2 +- .../suspension-cfg-example.jbeam | 2 +- .../data/fender-custom-minimal-jbfl.jbeam | 10 +- 14 files changed, 124 insertions(+), 312 deletions(-) diff --git a/examples/ast/jbfl/minimal.hs b/examples/ast/jbfl/minimal.hs index 667f8d80..3c1509ed 100644 --- a/examples/ast/jbfl/minimal.hs +++ b/examples/ast/jbfl/minimal.hs @@ -20,42 +20,6 @@ RuleSet ) ] ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , AnyObjectKey - , Selector - ( ObjectKey "off" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 10 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , AnyObjectKey - , Selector - ( ObjectKey "on" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 10 - ) - ] - ) , ( NodePattern ( fromList @@ -157,193 +121,6 @@ RuleSet ) ] ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "abs" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "battery" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "checkengine" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "dumptruck_gaugelight_warning" ) - ] - ) - , fromList - [ - ( SomeKey ForceComplexNewLine - , SomeProperty ForceComplexNewLine True - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "hazard" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "highbeam" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "lowfuel" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "lowpressure" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "parkingbrake" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "signal_L" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) - , - ( NodePattern - ( fromList - [ AnyObjectKey - , Selector - ( ObjectKey "glowMap" ) - , Selector - ( ObjectKey "signal_R" ) - ] - ) - , fromList - [ - ( SomeKey PadAmount - , SomeProperty PadAmount 20 - ) - ] - ) , ( NodePattern ( fromList @@ -503,6 +280,25 @@ RuleSet ) ] ) + , + ( NodePattern + ( fromList + [ AnyObjectKey + , Selector + ( ObjectKey "glowMap" ) + ] + ) + , fromList + [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , + ( SomeKey AutoPadSubObjects + , SomeProperty AutoPadSubObjects True + ) + ] + ) , ( NodePattern ( fromList @@ -513,6 +309,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -528,6 +328,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey AutoPad , SomeProperty AutoPad True ) @@ -543,6 +347,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -558,6 +366,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) @@ -573,6 +385,10 @@ RuleSet ) , fromList [ + ( SomeKey AlignObjectKeys + , SomeProperty AlignObjectKeys True + ) + , ( SomeKey ForceComplexNewLine , SomeProperty ForceComplexNewLine True ) diff --git a/examples/formatted_jbeam/fender-minimal-jbfl.jbeam b/examples/formatted_jbeam/fender-minimal-jbfl.jbeam index 96de2e77..135f298c 100644 --- a/examples/formatted_jbeam/fender-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/fender-minimal-jbfl.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", diff --git a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam index 82d2e2b3..7b502c48 100644 --- a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* @@ -391,21 +391,21 @@ ], "glowMap" : { // main lights - "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights - "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, // multi-condition warning light - "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} } } } diff --git a/examples/formatted_jbeam/suspension-minimal-jbfl.jbeam b/examples/formatted_jbeam/suspension-minimal-jbfl.jbeam index b3416b0f..1d1c3f1b 100644 --- a/examples/formatted_jbeam/suspension-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/suspension-minimal-jbfl.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* The purpose of this file is prove that moving metadata along with vertices when diff --git a/examples/jbfl/minimal.jbfl b/examples/jbfl/minimal.jbfl index ac137868..4be5dcf6 100644 --- a/examples/jbfl/minimal.jbfl +++ b/examples/jbfl/minimal.jbfl @@ -1,13 +1,15 @@ .*.nodes[*][*] { - // Pad all node values to 8 chars and force 3 decimals (e.g., 1.000) PadDecimals: 3; } .*.nodes, .*.beams, .*.triangles { - AutoPad : true; + AutoPad: true; +} + +.*.nodes { + AlignObjectKeys: true; } -// Keep things inline where applicable (no extra newlines for nested content) .*.nodes[*], .*.flexbodies[*], .*.beams[*], .*.triangles[*], .*.variables[*], .*.glowMap.*, @@ -20,18 +22,12 @@ } .*.sounds, .*.soundConfig, .*.soundConfigExhaust, -.*.information, .*.glowMap.dumptruck_gaugelight_warning { +.*.information { ForceComplexNewLine: true; + AlignObjectKeys: true; } -.*.glowMap.signal_L, .*.glowMap.signal_R, -.*.glowMap.checkengine, .*.glowMap.hazard, -.*.glowMap.battery, .*.glowMap.highbeam, -.*.glowMap.parkingbrake, .*.glowMap.lowfuel, -.*.glowMap.lowpressure, .*.glowMap.abs { - PadAmount : 20; -} - -.*.glowMap.*.off, .*.glowMap.*.on { - PadAmount : 10; +.*.glowMap { + AlignObjectKeys: true; + AutoPadSubObjects: true; } diff --git a/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam b/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam index 706b7c5d..711461fa 100644 --- a/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam +++ b/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", diff --git a/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam b/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam index 706b7c5d..711461fa 100644 --- a/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam +++ b/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", diff --git a/examples/transformed_jbeam/fender-cfg-default.jbeam b/examples/transformed_jbeam/fender-cfg-default.jbeam index efe99497..c5438a58 100644 --- a/examples/transformed_jbeam/fender-cfg-default.jbeam +++ b/examples/transformed_jbeam/fender-cfg-default.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", diff --git a/examples/transformed_jbeam/fender-cfg-example.jbeam b/examples/transformed_jbeam/fender-cfg-example.jbeam index efe99497..c5438a58 100644 --- a/examples/transformed_jbeam/fender-cfg-example.jbeam +++ b/examples/transformed_jbeam/fender-cfg-example.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", diff --git a/examples/transformed_jbeam/frame-cfg-default.jbeam b/examples/transformed_jbeam/frame-cfg-default.jbeam index 63bdeafb..aa3d7177 100644 --- a/examples/transformed_jbeam/frame-cfg-default.jbeam +++ b/examples/transformed_jbeam/frame-cfg-default.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* @@ -416,21 +416,21 @@ ], "glowMap" : { // main lights - "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights - "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, // multi-condition warning light - "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} } } } diff --git a/examples/transformed_jbeam/frame-cfg-example.jbeam b/examples/transformed_jbeam/frame-cfg-example.jbeam index 63bdeafb..aa3d7177 100644 --- a/examples/transformed_jbeam/frame-cfg-example.jbeam +++ b/examples/transformed_jbeam/frame-cfg-example.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* @@ -416,21 +416,21 @@ ], "glowMap" : { // main lights - "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, - "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_L" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_headlight_R" : {"simpleFunction" : "lowhighbeam_filament", "off" : "chassis_headlight", "on" : "chassis_headlight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_L" : {"simpleFunction" : "signal_L_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_signal_R" : {"simpleFunction" : "signal_R_filament", "off" : "chassis_signal_amber", "on" : "chassis_signal_amber_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_reverselight" : {"simpleFunction" : "reverselight_filament", "off" : "chassis_reverselight", "on" : "chassis_reverselight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, + "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights - "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, - "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, // multi-condition warning light - "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} + "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} } } } diff --git a/examples/transformed_jbeam/suspension-cfg-default.jbeam b/examples/transformed_jbeam/suspension-cfg-default.jbeam index 11b38cd7..e238da62 100644 --- a/examples/transformed_jbeam/suspension-cfg-default.jbeam +++ b/examples/transformed_jbeam/suspension-cfg-default.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* The purpose of this file is prove that moving metadata along with vertices when diff --git a/examples/transformed_jbeam/suspension-cfg-example.jbeam b/examples/transformed_jbeam/suspension-cfg-example.jbeam index 11b38cd7..e238da62 100644 --- a/examples/transformed_jbeam/suspension-cfg-example.jbeam +++ b/examples/transformed_jbeam/suspension-cfg-example.jbeam @@ -2,7 +2,7 @@ "chassis_rails" : { "information" : { "authors" : "gittarrgy01", - "name" : "" + "name" : "" }, "slotType" : "main", /* The purpose of this file is prove that moving metadata along with vertices when diff --git a/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam b/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam index 90146df8..d73842aa 100644 --- a/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam +++ b/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam @@ -2,14 +2,14 @@ "cot_fender" : { "information" : { "authors" : "gittarrgy01", - "name" : "Fenders" + "name" : "Fenders" }, "sounds" : { - "impactMetal" : "event:>Destruction>Props>fender_metal", + "impactMetal" : "event:>Destruction>Props>fender_metal", "impactGeneric" : "event:>Destruction>Props>fender_generic", - "breakGeneric" : "event:>Destruction>Props>fender_break", - "wind" : false, - "scrapeMetal" : false, + "breakGeneric" : "event:>Destruction>Props>fender_break", + "wind" : false, + "scrapeMetal" : false, "scrapePlastic" : false }, "slotType" : "cot_fender", From 671be201f582816b8f5bcf5529dce773ec8f52ff Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Sat, 14 Mar 2026 17:47:28 +0100 Subject: [PATCH 3/6] Simplify AlignObjectKeys and AutoPadSubObjects implementation - Guard maxKeyW computation behind alignObjectKeysEnabled to avoid unconditional work when the feature is off - Remove redundant newKeyWidth/newSubWidths intermediate bindings - Check isComplexNode before calling formatWithCursor in subObjectWidths to short-circuit the expensive recursive format call --- src/JbeamEdit/Formatting.hs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/JbeamEdit/Formatting.hs b/src/JbeamEdit/Formatting.hs index b7da5f96..414643d7 100644 --- a/src/JbeamEdit/Formatting.hs +++ b/src/JbeamEdit/Formatting.hs @@ -271,19 +271,15 @@ doFormatNode rs cursor state nodes = (colWidths, formattedCache, headerWasExtracted) = maxColumnLengthsWithCache rs cursor nodes - objectKeyItems = - V.mapMaybe - ( \(i, n) -> case n of - ObjectKey (k, v) -> Just (i, k, v) - _ -> Nothing - ) - (V.indexed nodes) - maxKeyW - | V.null objectKeyItems = Nothing + | not alignObjectKeysEnabled = Nothing | otherwise = - Just . V.maximum . V.map (\(_, k, _) -> T.length (formatScalarNode k)) $ - objectKeyItems + let toKey (ObjectKey (k, _)) = Just k + toKey _ = Nothing + ks = V.mapMaybe toKey nodes + in if V.null ks + then Nothing + else Just (V.maximum (V.map (T.length . formatScalarNode) ks)) subObjectWidths :: Map Text Int subObjectWidths @@ -295,8 +291,12 @@ doFormatNode rs cursor state nodes = ( \acc2 sn -> case sn of ObjectKey (sk, sv) -> let kt = formatScalarNode sk - vt = formatWithCursor rs emptyState cursor sv - vw = if T.any (== '\n') vt || isComplexNode sv then 0 else T.length vt + vw = + if isComplexNode sv + then 0 + else + let vt = formatWithCursor rs emptyState cursor sv + in if T.any (== '\n') vt then 0 else T.length vt in Map.insertWith max kt vw acc2 _ -> acc2 ) @@ -308,9 +308,6 @@ doFormatNode rs cursor state nodes = nodes | otherwise = Map.empty - newKeyWidth = if alignObjectKeysEnabled then maxKeyW else Nothing - newSubWidths = if autopadSubObjectsEnabled then subObjectWidths else Map.empty - state' | autoPadEnabled , not (V.null colWidths) = @@ -325,8 +322,8 @@ doFormatNode rs cursor state nodes = } | alignObjectKeysEnabled || autopadSubObjectsEnabled = emptyState - { fsObjectKeyWidth = newKeyWidth - , fsSubObjectWidths = newSubWidths + { fsObjectKeyWidth = maxKeyW + , fsSubObjectWidths = subObjectWidths } | otherwise = state From c07e4607882a2df90b0112bc1c243560f91c3ab2 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Sat, 14 Mar 2026 18:34:29 +0100 Subject: [PATCH 4/6] Document AlignObjectKeys, AutoPadSubObjects, and AutoPad in JBFL docs and README --- JBFL_DOCS.md | 17 ++++++++++------- README.md | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/JBFL_DOCS.md b/JBFL_DOCS.md index e0b43e3c..ce69f037 100644 --- a/JBFL_DOCS.md +++ b/JBFL_DOCS.md @@ -46,13 +46,16 @@ Typical use cases include: # Properties Overview -| Setting Name | Description | Applies To | -|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------| -| `PadDecimals` | Adds trailing zeros only if the fractional part is shorter than `PadDecimals`, leaving existing extra decimals untouched. Guarantees a minimum number of decimal digits. | Numeric values | -| `PadAmount` | Specifies the **total length** (number of characters) the formatted value should occupy. | Any scalar except for comments | -| `NoComplexNewLine` | When true, disables multiline or indented formatting for arrays, outputting values inline. | Any complex data structure | -| `ForceComplexNewLine` | Forces complex structures (arrays or objects) to always use multiline and indented formatting, even if NoComplexNewLine is not set. Overrides inline formatting. | Any complex data structure | -| `Indent` | When set, controls the the amount of indentation. Defaults to 2 spaces. | Any complex data structure | +| Setting Name | Description | Applies To | +|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------| +| `PadDecimals` | Adds trailing zeros only if the fractional part is shorter than `PadDecimals`, leaving existing extra decimals untouched. Guarantees a minimum number of decimal digits. | Numeric values | +| `PadAmount` | Specifies the **total length** (number of characters) the formatted value should occupy. | Any scalar except for comments | +| `AutoPad` | Aligns values in array rows into columns by padding each cell to the maximum width in that column. Applies to the array it is set on (e.g. `nodes`, `beams`). | Arrays of arrays | +| `AlignObjectKeys` | Pads object keys so that `:` separators align vertically across all entries in the same object. | Objects | +| `AutoPadSubObjects` | Aligns values within sibling inline objects by treating matching sub-keys as columns. Useful for `glowMap`-style structures. | Objects with inline sub-objects | +| `NoComplexNewLine` | When true, disables multiline or indented formatting for arrays, outputting values inline. | Any complex data structure | +| `ForceComplexNewLine` | Forces complex structures (arrays or objects) to always use multiline and indented formatting, even if NoComplexNewLine is not set. Overrides inline formatting. | Any complex data structure | +| `Indent` | Controls the amount of indentation. Defaults to 4 spaces. | Any complex data structure | # How Matching Works diff --git a/README.md b/README.md index 3a0ff03b..ede8eab8 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ A fast, robust command-line parser, formatter, and editor for JBeam files, the J Renames nodes sequentially (e.g., `["bf1", ...]` → `["bf0", "bf1", "bf2"]`) and updates all references automatically. Feature currently unstable, enabled by build flag `transformation`. - **Configurable Formatting with JBFL:** - Customize formatting rules using JBFL, a mini-language to specify padding, decimals, indentation, and more with wildcard targeting. + Customize formatting rules using JBFL, a mini-language to specify padding, decimals, indentation, object key alignment, and more with wildcard targeting. Example JBFL snippet: From 7926eaf39663b783ba32fe54f77f7b6eb83205cf Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:08:38 +0100 Subject: [PATCH 5/6] Preserve blank lines between consecutive comments in objects In objectParser, comments were parsed with `skipWhiteSpace` which consumed whitespace without updating `lastSeparatorHadBlankLine`. This meant `cHadNewlineBefore` was never set on comments inside objects, so blank lines between consecutive comments were lost during formatting. Fix: use `separatorParser` instead of `skipWhiteSpace` after comments in objectParser, so blank-line state is tracked correctly. Additionally, the formatter was suppressing newlines before comments whenever `any isObjectKeyNode rest` was true, regardless of `cHadNewlineBefore`. This caused blank lines between comments that precede object keys to be dropped. Fix: only suppress the newline when `cHadNewlineBefore` is false, so that blank lines present in the source are preserved. Add a blank line and extra comment in the glowMap section of examples/jbeam/frame.jbeam to cover this case in the test fixtures. --- examples/ast/jbeam/frame.hs | 10 +++++++++- examples/formatted_jbeam/frame-complex-jbfl.jbeam | 1 + examples/formatted_jbeam/frame-minimal-jbfl.jbeam | 1 + examples/jbeam/frame.jbeam | 3 +++ examples/transformed_jbeam/frame-cfg-default.jbeam | 1 + examples/transformed_jbeam/frame-cfg-example.jbeam | 1 + src/JbeamEdit/Formatting.hs | 11 ++++++++--- src/JbeamEdit/Parsing/Jbeam.hs | 2 +- 8 files changed, 25 insertions(+), 5 deletions(-) diff --git a/examples/ast/jbeam/frame.hs b/examples/ast/jbeam/frame.hs index 42aba2b2..c192268d 100644 --- a/examples/ast/jbeam/frame.hs +++ b/examples/ast/jbeam/frame.hs @@ -2029,6 +2029,14 @@ Object , cHadNewlineBefore = False } ) + , Comment + ( InternalComment + { cText = "(turn signals, battery, parking brake, highbeam)" + , cMultiline = False + , cAssociationDirection = NextNode + , cHadNewlineBefore = True + } + ) , ObjectKey ( String "chassis_gaugelight_highbeam" , Object @@ -2119,7 +2127,7 @@ Object { cText = "multi-condition warning light" , cMultiline = False , cAssociationDirection = NextNode - , cHadNewlineBefore = False + , cHadNewlineBefore = True } ) , ObjectKey diff --git a/examples/formatted_jbeam/frame-complex-jbfl.jbeam b/examples/formatted_jbeam/frame-complex-jbfl.jbeam index f6c0f702..d93f9652 100644 --- a/examples/formatted_jbeam/frame-complex-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-complex-jbfl.jbeam @@ -399,6 +399,7 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, diff --git a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam index 7b502c48..a313d67b 100644 --- a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam @@ -399,6 +399,7 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, diff --git a/examples/jbeam/frame.jbeam b/examples/jbeam/frame.jbeam index f743266a..03f3cc88 100644 --- a/examples/jbeam/frame.jbeam +++ b/examples/jbeam/frame.jbeam @@ -399,11 +399,14 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} } diff --git a/examples/transformed_jbeam/frame-cfg-default.jbeam b/examples/transformed_jbeam/frame-cfg-default.jbeam index aa3d7177..da39af16 100644 --- a/examples/transformed_jbeam/frame-cfg-default.jbeam +++ b/examples/transformed_jbeam/frame-cfg-default.jbeam @@ -424,6 +424,7 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, diff --git a/examples/transformed_jbeam/frame-cfg-example.jbeam b/examples/transformed_jbeam/frame-cfg-example.jbeam index aa3d7177..da39af16 100644 --- a/examples/transformed_jbeam/frame-cfg-example.jbeam +++ b/examples/transformed_jbeam/frame-cfg-example.jbeam @@ -424,6 +424,7 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, diff --git a/src/JbeamEdit/Formatting.hs b/src/JbeamEdit/Formatting.hs index 414643d7..e0a22297 100644 --- a/src/JbeamEdit/Formatting.hs +++ b/src/JbeamEdit/Formatting.hs @@ -131,10 +131,15 @@ addDelimiters rs index rowIdx c complexChildren state acc ns@(node : rest) in addDelimiters rs (index + 1) nextRowIdx c complexChildren state new_acc rest where newlineBeforeComment = case node of - Comment ic | not (cMultiline ic) && not (cHadNewlineBefore ic) -> + Comment ic | not (cMultiline ic) -> case acc of - (prev : _) | T.isPrefixOf "// " (T.dropWhile (== '\n') prev) -> "" - _ -> singleCharIfNot '\n' (any isObjectKeyNode rest || ["\n"] == acc) + (prev : _) + | T.isPrefixOf "// " (T.dropWhile (== '\n') prev) -> + if cHadNewlineBefore ic then "\n" else "" + _ -> + singleCharIfNot + '\n' + (["\n"] == acc || (not (cHadNewlineBefore ic) && any isObjectKeyNode rest)) _ -> singleCharIfNot '\n' (any isObjectKeyNode rest || ["\n"] == acc) nextRowIdx = diff --git a/src/JbeamEdit/Parsing/Jbeam.hs b/src/JbeamEdit/Parsing/Jbeam.hs index 6d1edf3b..a8a50f3e 100644 --- a/src/JbeamEdit/Parsing/Jbeam.hs +++ b/src/JbeamEdit/Parsing/Jbeam.hs @@ -173,7 +173,7 @@ objectParser :: JbeamParser Node objectParser = do _ <- byteChar '{' skipWhiteSpace - keys <- MP.many (commentParser <* skipWhiteSpace <|> objectKeyParser) + keys <- MP.many (commentParser <* separatorParser <|> objectKeyParser) _ <- MP.optional separatorParser _ <- byteChar '}' pure . Object . V.fromList $ keys From 93761bbda488bd78d8173a22a61e987a83d17d80 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Sun, 15 Mar 2026 19:37:16 +0100 Subject: [PATCH 6/6] Updated example files --- examples/formatted_jbeam/frame-complex-jbfl.jbeam | 2 ++ examples/formatted_jbeam/frame-minimal-jbfl.jbeam | 2 ++ examples/transformed_jbeam/frame-cfg-default.jbeam | 2 ++ examples/transformed_jbeam/frame-cfg-example.jbeam | 2 ++ 4 files changed, 8 insertions(+) diff --git a/examples/formatted_jbeam/frame-complex-jbfl.jbeam b/examples/formatted_jbeam/frame-complex-jbfl.jbeam index d93f9652..7910d485 100644 --- a/examples/formatted_jbeam/frame-complex-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-complex-jbfl.jbeam @@ -399,12 +399,14 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light "chassis_gaugelight_warning" : { "simpleFunction" : { diff --git a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam index a313d67b..b99e0813 100644 --- a/examples/formatted_jbeam/frame-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/frame-minimal-jbfl.jbeam @@ -399,12 +399,14 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} } diff --git a/examples/transformed_jbeam/frame-cfg-default.jbeam b/examples/transformed_jbeam/frame-cfg-default.jbeam index da39af16..8149dc11 100644 --- a/examples/transformed_jbeam/frame-cfg-default.jbeam +++ b/examples/transformed_jbeam/frame-cfg-default.jbeam @@ -424,12 +424,14 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} } diff --git a/examples/transformed_jbeam/frame-cfg-example.jbeam b/examples/transformed_jbeam/frame-cfg-example.jbeam index da39af16..8149dc11 100644 --- a/examples/transformed_jbeam/frame-cfg-example.jbeam +++ b/examples/transformed_jbeam/frame-cfg-example.jbeam @@ -424,12 +424,14 @@ "chassis_brakelight_L" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, "chassis_brakelight_R" : {"simpleFunction" : "brakelight_filament", "off" : "chassis_taillight", "on" : "chassis_taillight_on", "materialEmissiveScaling" : {"on_max" : 1}}, // gauge lights + // (turn signals, battery, parking brake, highbeam) "chassis_gaugelight_highbeam" : {"simpleFunction" : "highbeam", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_L" : {"simpleFunction" : "signal_L", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_signal_R" : {"simpleFunction" : "signal_R", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_battery" : {"simpleFunction" : "battery", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, "chassis_gaugelight_parkbrake" : {"simpleFunction" : "parkingbrakelight", "off" : "chassis_gauges", "on" : "chassis_gauges_on"}, + // multi-condition warning light "chassis_gaugelight_warning" : {"simpleFunction" : {"checkengine" : 1, "battery" : 1, "lowpressure" : 1}, "off" : "chassis_gauges", "on" : "chassis_gauges_on"} }