Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nml for openSUSE:Factory checked in 
at 2025-12-04 11:24:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nml (Old)
 and      /work/SRC/openSUSE:Factory/.nml.new.1939 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nml"

Thu Dec  4 11:24:56 2025 rev:30 rq:1320956 version:0.8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/nml/nml.changes  2025-10-28 14:50:12.036109174 
+0100
+++ /work/SRC/openSUSE:Factory/.nml.new.1939/nml.changes        2025-12-04 
11:27:28.840042282 +0100
@@ -0,0 +1,16 @@
+Wed Dec  3 09:26:34 UTC 2025 - Jan Baier <[email protected]>
+
+- update to 0.8.1:
+  * Add: station properties to editor symbols script by @Pixel-Tony in #383
+  * Change: move black options to pyproject.toml by @ahyangyi in #386
+  * Add: Extend FEAT_TRAIN track_type for prop 34 by @glx22 in #390
+  * Codefix 41d5cd4: standalone build references non existing files by @glx22 
in #397
+  * Add: Support for Action5 type 1B bridge deck overlays by @zephyris in #393
+  * Add: FEAT_AIRCRAFT flight_state variable (varE2) by @glx22 in #391
+  * Fix: Validation and handling of multiple settings in one parameter by 
@glx22 in #382
+  * Upgrade: bump the actions group across 1 directory with 6 updates by 
@dependabot[bot] in #396
+  * Codefix: Fix typos and grammar errors by @Rito13 in #389
+  * Change: Validate action 2 loaded list does not overlap special types. by 
@PeterN in #400
+  * Add: Station/RoadStop height and blocked pillar flag lists. by @PeterN in 
#388
+  * Update: changelog for 0.8.1 by @glx22 in #399
+

Old:
----
  nml-0.8.0.tar.gz

New:
----
  nml-0.8.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nml.spec ++++++
--- /var/tmp/diff_new_pack.7oItR5/_old  2025-12-04 11:27:29.356064118 +0100
+++ /var/tmp/diff_new_pack.7oItR5/_new  2025-12-04 11:27:29.360064287 +0100
@@ -1,6 +1,7 @@
 #
 # spec file for package nml
 #
+# Copyright (c) 2025 SUSE LLC
 # Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
@@ -17,7 +18,7 @@
 
 
 Name:           nml
-Version:        0.8.0
+Version:        0.8.1
 Release:        0
 Summary:        NewGRF Meta Language
 License:        GPL-2.0-or-later

++++++ nml-0.8.0.tar.gz -> nml-0.8.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/Makefile new/nml-0.8.1/Makefile
--- old/nml-0.8.0/Makefile      2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/Makefile      2025-12-02 20:17:25.000000000 +0100
@@ -1,6 +1,5 @@
 MAKE?=make
 PYTHON?=/usr/bin/env python3
-BLACK_OPTIONS=-l 120 --exclude 
'action2var_variables.py|action3_callbacks.py|ply'
 
 .PHONY: regression test install extensions clean flake black
 
@@ -21,8 +20,8 @@
        rm -f *.so
 
 flake:
-       $(PYTHON) -m black --check $(BLACK_OPTIONS) nml
+       $(PYTHON) -m black --check nml
        $(PYTHON) -m flake8 nml
 
 black:
-       $(PYTHON) -m black $(BLACK_OPTIONS) nml
+       $(PYTHON) -m black nml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/PKG-INFO new/nml-0.8.1/PKG-INFO
--- old/nml-0.8.0/PKG-INFO      2025-06-21 21:12:41.286344500 +0200
+++ new/nml-0.8.1/PKG-INFO      2025-12-02 20:17:28.717712000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: nml
-Version: 0.8.0
+Version: 0.8.1
 Summary: An OpenTTD NewGRF compiler for the nml language
 Home-page: https://github.com/OpenTTD/nml
 Author: NML Development Team
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/README.md new/nml-0.8.1/README.md
--- old/nml-0.8.0/README.md     2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/README.md     2025-12-02 20:17:25.000000000 +0100
@@ -1,6 +1,6 @@
 # NML NewGRF meta language
 
-NML is a a python-based compiler, capable of compiling NML files (along
+NML is a Python-based compiler, capable of compiling NML files (along
 with their associated language, sound and graphic files) into grf
 and / or nfo files.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/docs/changelog.txt 
new/nml-0.8.1/docs/changelog.txt
--- old/nml-0.8.0/docs/changelog.txt    2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/docs/changelog.txt    2025-12-02 20:17:25.000000000 +0100
@@ -1,3 +1,16 @@
+0.8.1 (2025-12-02)
+------------------------------------------------------------------------
+Support for NewGRF additions of OpenTTD 15:
+ - Add: Station/RoadStop height and blocked pillar flag lists (#388)
+ - Add: Extend FEAT_TRAIN track_type for prop 34 (#390)
+ - Add: Support for Action5 type 1B bridge deck overlays (#393)
+
+Other changes and fixes:
+ - Fix: Validation and handling of multiple settings in one parameter (#382)
+ - Add: FEAT_AIRCRAFT flight_state variable (varE2) (#391)
+ - Change: Validate action 2 loaded list does not overlap special types (#400)
+
+
 0.8.0 (2025-06-21)
 ------------------------------------------------------------------------
 This release removes external dependency for "ply".
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/__version__.py 
new/nml-0.8.1/nml/__version__.py
--- old/nml-0.8.0/nml/__version__.py    2025-06-21 21:12:41.000000000 +0200
+++ new/nml-0.8.1/nml/__version__.py    2025-12-02 20:17:28.000000000 +0100
@@ -1,2 +1,2 @@
 # this file is autogenerated by setup.py
-version = "0.8.0"
+version = "0.8.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action0.py 
new/nml-0.8.1/nml/actions/action0.py
--- old/nml-0.8.0/nml/actions/action0.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action0.py        2025-12-02 20:17:25.000000000 
+0100
@@ -48,7 +48,7 @@
     @ivar allocated: Mapping of allocated blocks.
     @type allocated: C{dict} of C{int} to allocation information.
 
-    @ivar filled: Mapping of block size to smallest address that may contain 
free space.
+    @ivar filled: Mapping of block size to the smallest address that may 
contain free space.
                   Serves as a cache to speed up searches.
     @type filled: C{dict} of C{int}
     """
@@ -72,7 +72,7 @@
 
     def get_max_allocated(self):
         """
-        Return maximum number of allocateable ids.
+        Return maximum number of allocatable ids.
         """
         if self.dynamic_allocation:
             return self.last - self.first + 1
@@ -90,7 +90,7 @@
         @param length: Number of addresses in the block.
         @type  length: C{int}
 
-        @return: Whether the block fits enitrely in the available address 
space.
+        @return: Whether the block fits entirely in the available address 
space.
         @rtype:  C{bool}
         """
         return addr >= 0 and addr + length - 1 <= self.last
@@ -923,7 +923,7 @@
 
         num_ids = 1  # Number of values that will be written in one go
         values = []
-        # try to capture as much values as possible
+        # try to capture as many values as possible
         while True:
             cost = basecost.costs[i]
             if isinstance(cost.value, expression.ConstantNumeric):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action0properties.py 
new/nml-0.8.1/nml/actions/action0properties.py
--- old/nml-0.8.0/nml/actions/action0properties.py      2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/actions/action0properties.py      2025-12-02 
20:17:25.000000000 +0100
@@ -108,7 +108,7 @@
 # Summary: If 'string' or 'string_literal' is set, the value should be a
 # string or literal string, else the value is a number. 'unit_type' and
 # 'unit_conversion' are used to convert user-entered values to nfo values.
-# If some more arithmetic is needed to convert the entered value into an nfo
+# If some more arithmetic is needed to convert the entered value into a nfo
 # value, 'value_function' can be used. For even more complicated things,
 # 'custom_function' can be used to create a special mapping of the value to nfo
 # properties, else 'num' and 'size' are used to provide a 'normal' action0.
@@ -214,7 +214,7 @@
 def animation_info(value, loop_bit=8, max_frame=253):
     """
     Convert animation info array of two elements to an animation info property.
-    The first is 0/1, and defines whether or not the animation loops.
+    The first is 0/1, and defines whether the animation loops.
     The second is the number of frames, at most 253 frames.
 
     @param value: Array of animation info.
@@ -412,6 +412,16 @@
     ]
 
 
+def single_or_list(prop_name, single_num, multiple_num, value):
+    if isinstance(value, ConstantNumeric):
+        return [Action0Property(single_num, value, 1)]
+    if isinstance(value, Array):
+        if len(value.values) == 1:
+            return [Action0Property(single_num, 
value.values[0].reduce_constant(), 1)]
+        return [VariableByteListProp(multiple_num, 
[[type.reduce_constant().value for type in value.values]])]
+    raise generic.ScriptError("'{}' must be a constant or an array of 
constants".format(prop_name))
+
+
 #
 # Feature 0x00 (Trains)
 #
@@ -419,7 +429,9 @@
 # fmt: off
 properties[0x00] = {
     **general_veh_props,
-    "track_type":                     {"size": 1, "num": 0x05},
+    "track_type": {
+        "custom_function": lambda value: single_or_list("track_type", 0x05, 
0x34, value)
+    },
     "ai_special_flag":                {"size": 1, "num": 0x08},
     "speed": {
         "size": 2,
@@ -428,12 +440,12 @@
         "unit_conversion": (5000, 1397),
         "adjust_value": lambda val, unit: ottd_display_speed(val, 1, 1, unit)
     },
-    # 09 doesn"t exist
+    # 09 doesn't exist
     "power":                          {"size": 2, "num": 0x0B, "unit_type": 
"power"},
-    # 0A doesn"t exist
+    # 0A doesn't exist
     "running_cost_factor":            {"size": 1, "num": 0x0D},
     "running_cost_base":              {"size": 4, "num": 0x0E},
-    # 0F -11 don"t exist
+    # 0F -11 don't exist
     "sprite_id":                      {"size": 1, "num": 0x12},
     "dual_headed":                    {"size": 1, "num": 0x13},
     "cargo_capacity":                 {"size": 1, "num": 0x14},
@@ -717,7 +729,7 @@
 
 def station_platforms_length(value):
     # Writing bitmask(2) to disable platform/length 3 is not very intuitive.
-    # Instead we expect the user will write bitmask(3) and we shift the result.
+    # Instead, we expect the user will write bitmask(3) and we shift the 
result.
     return nmlop.SHIFT_RIGHT(value, 1, value.pos).reduce()
 
 
@@ -818,6 +830,12 @@
     ]
 
 
+def station_tile_list(value, prop_num, description):
+    if not isinstance(value, Array) or len(value.values) % 2 != 0:
+        raise generic.ScriptError(f"{description} list must be an array of 
even length", value.pos)
+    return [VariableByteListProp(prop_num, [[x.reduce_constant().value for x 
in value.values]], True)]
+
+
 # fmt: off
 properties[0x04] = {
     "class":                 {"size": 4, "num": 0x08, "first": None, 
"string_literal": 4},
@@ -843,6 +861,8 @@
     "name":                  {"size": 2, "num": (256, -1, 0x1C), "string": 
(256, 0xC5, 0xDC), "required": True},
     "classname":             {"size": 2, "num": (256, -1, 0x1D), "string": 
(256, 0xC4, 0xDC)},
     "tile_flags":            {"custom_function": station_tile_flags},  # = 
prop 1E
+    "heights":               {"custom_function": lambda x: 
station_tile_list(x, 0x20, "Station height")},
+    "blocked_pillars":       {"custom_function": lambda x: 
station_tile_list(x, 0x21, "Station blocked pillar")},
 }
 # fmt: on
 
@@ -1566,7 +1586,7 @@
 properties[0x11] = {
     "substitute":         {"size": 1, "num": 0x08, "first": None},
     "override":           {"size": 1, "num": 0x09},
-    # 0A - 0D don"t exist (yet?)
+    # 0A - 0D don't exist (yet?)
     # 0E (callback flags) is not set by user
     "animation_info":     {"size": 2, "num": 0x0F, "value_function": 
animation_info},
     "animation_speed":    {"size": 1, "num": 0x10},
@@ -1656,5 +1676,7 @@
     "animation_triggers":        {"size": 2, "num": 0x10},
     # 11 (callback flags) is not set by user
     "general_flags":             {"size": 4, "num": 0x12},
+    "heights":                   {"custom_function": lambda x: 
station_tile_list(x, 0x13, "Station height")},
+    "blocked_pillars":           {"custom_function": lambda x: 
station_tile_list(x, 0x14, "Station blocked pillar")},
     "cost_multipliers":          {"custom_function": lambda x: 
byte_sequence_list(x, 0x15, "Cost multipliers", 2)},
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action1.py 
new/nml-0.8.1/nml/actions/action1.py
--- old/nml-0.8.0/nml/actions/action1.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action1.py        2025-12-02 20:17:25.000000000 
+0100
@@ -145,7 +145,7 @@
         Create a list of actions needed to write this collection to the 
output. This
         will generate a single Action1 and as many realsprites as needed.
 
-        @return: A list of actions needed to represet this collection in a GRF.
+        @return: A list of actions needed to represent this collection in a 
GRF.
         @rtype: C{list} of L{BaseAction}
         """
         actions = [Action1(self.feature, self.first_set, len(self.spritesets), 
self.num_sprites_per_spriteset)]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action14.py 
new/nml-0.8.1/nml/actions/action14.py
--- old/nml-0.8.0/nml/actions/action14.py       2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action14.py       2025-12-02 20:17:25.000000000 
+0100
@@ -278,9 +278,9 @@
                     setting_node.subnodes.append(value_names_node)
             else:
                 assert setting.type == "bool"
+                assert setting.bit_num is not None
                 setting_node.subnodes.append(BinaryNode("TYPE", 1, 1))
-                bit = setting.bit_num.value if setting.bit_num is not None 
else 0
-                setting_node.subnodes.append(SettingMaskNode(param_num, bit, 
1))
+                setting_node.subnodes.append(SettingMaskNode(param_num, 
setting.bit_num.value, 1))
             if setting.def_val is not None:
                 setting_node.subnodes.append(BinaryNode("DFLT", 4, 
setting.def_val.value))
             param_root.subnodes.append(setting_node)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action2.py 
new/nml-0.8.1/nml/actions/action2.py
--- old/nml-0.8.0/nml/actions/action2.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action2.py        2025-12-02 20:17:25.000000000 
+0100
@@ -139,7 +139,7 @@
     def remove_tmp_location(self, location, force_recursive):
         """
         Recursively remove a location from the list of available temporary
-        storage locations. It is not only removed from the the list of the
+        storage locations. It is not only removed from the list of the
         current Action2Var but also from all Action2Var it calls. If an
         Action2Var is referenced as a procedure call, the location is always
         removed recursively, otherwise only if force_recursive is True.
@@ -230,7 +230,7 @@
     Metaclass factory which makes base classes for all nodes 'Action 2 graph'
     This graph is made up of all blocks that are eventually compiled to 
Action2,
     which use the same name space. Spritesets do inherit from this class to 
make
-    referencing them possible, but they are not part of the refernce graph that
+    referencing them possible, but they are not part of the reference graph 
that
     is built.
 
     @param cls_is_spriteset: Whether this class represents a spriteset
@@ -244,7 +244,7 @@
     @type cls_has_explicit_feature: C{bool}
 
     @param cls_is_relocatable: Whether instances of this class can be freely 
moved around or whether they need
-                               to to be converted to nfo code at the same 
location as they are in the nml code.
+                               to be converted to nfo code at the same 
location as they are in the nml code.
     @type cls_is_relocatable: C{bool}
 
     @return: The constructed class
@@ -262,7 +262,7 @@
         Child classes should do the following:
             - Implement their own __init__ method
             - Call BaseStatement.__init__
-            - Call initialize, pre_process and perpare_output (in that order)
+            - Call initialize, pre_process and prepare_output (in that order)
             - Implement collect_references
             - Call set_action2 after generating the corresponding action2 (if 
applicable)
 
@@ -294,8 +294,8 @@
         def __init__(self):
             """
             Subclasses should implement their own __init__ method.
-            This method should not be called, because calling a method on a 
meta class can be troublesome.
-            Instead, call initialize(..).
+            This method should not be called, because calling a method on a 
metaclass can be troublesome.
+            Instead, call initialize(...).
             """
             raise NotImplementedError(
                 (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action2layout.py 
new/nml-0.8.1/nml/actions/action2layout.py
--- old/nml-0.8.0/nml/actions/action2layout.py  2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action2layout.py  2025-12-02 20:17:25.000000000 
+0100
@@ -117,7 +117,7 @@
             flags |= 1 << 2
         if self.palette_from_action1:
             flags |= 1 << 3
-        # for building sprites: bit 4 => xoffset+yoffset, bit 5 => zoffset (x 
and y always set totgether)
+        # for building sprites: bit 4 => xoffset+yoffset, bit 5 => zoffset (x 
and y always set together)
         # for child sprites: bit 4 => xoffset, bit 5 => yoffset
         if self.type == Action2LayoutSpriteType.BUILDING:
             assert (self.get_register("xoffset") is not None) == 
(self.get_register("yoffset") is not None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action2random.py 
new/nml-0.8.1/nml/actions/action2random.py
--- old/nml-0.8.0/nml/actions/action2random.py  2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action2random.py  2025-12-02 20:17:25.000000000 
+0100
@@ -105,7 +105,7 @@
 
 def parse_randomswitch_type(random_switch):
     """
-    Parse the type of a random switch to determine the type and random bits to 
use.
+    Parse the type of random switch to determine the type and random bits to 
use.
 
     @param random_switch: Random switch to parse the type of
     @type random_switch: L{RandomSwitch}
@@ -203,7 +203,7 @@
 
     @return: A tuple of two values:
                 - The first random bit to use
-                - The number of random choices to use. This may be higher the 
the original amount passed as paramter
+                - The number of random choices to use. This may be higher than 
the original amount passed as parameter
     @rtype: C{tuple} of (C{int}, C{int})
     """
     # Dependent random chains
@@ -240,7 +240,7 @@
     else:
         randbit = -1
 
-    # INdependent random chains
+    # Independent random chains
     possible_mask = ((1 << bits_available) - 1) << start_bit
     for indep in random_switch.independent:
         act2 = lookup_random_action2(indep)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action2real.py 
new/nml-0.8.1/nml/actions/action2real.py
--- old/nml-0.8.0/nml/actions/action2real.py    2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action2real.py    2025-12-02 20:17:25.000000000 
+0100
@@ -89,6 +89,11 @@
             else:
                 loaded_list.append(action1_index)
 
+    if len(loaded_list) >= 0x80:
+        raise generic.ScriptError("Too many 'loaded' sprite set(s).", 
spritegroup.pos)
+    if len(loading_list) >= 0xFF:
+        raise generic.ScriptError("Too many 'loading' sprite set(s).", 
spritegroup.pos)
+
     actions.append(
         Action2Real(
             feature,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action2var_variables.py 
new/nml-0.8.1/nml/actions/action2var_variables.py
--- old/nml-0.8.0/nml/actions/action2var_variables.py   2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/actions/action2var_variables.py   2025-12-02 
20:17:25.000000000 +0100
@@ -212,6 +212,7 @@
     'max_speed'           : {'var': 0x98, 'start': 0, 'size': 16, 
'value_function': value_mul_div(0x3939, 0x1000)},
     'current_speed'       : {'var': 0xB4, 'start': 0, 'size': 16, 
'value_function': value_mul_div(0x3939, 0x1000)},
     'current_max_speed'   : {'var': 0x4C, 'start': 0, 'size': 16, 
'value_function': value_mul_div(0x3939, 0x1000)},
+    'flight_state'        : {'var': 0xE2, 'start': 0, 'size':  8},
     'vehicle_is_in_depot' : {'var': 0xE6, 'start': 0, 'size':  8, 
'value_function': value_equals(0)},
 }
 
@@ -297,7 +298,7 @@
 varact2vars_stations = {
     **varact2vars_base_stations,
     # Vars 40, 41, 46, 47, 49 are implemented as 60+x vars,
-    # except for the 'tile type' part which is always the same anyways
+    # except for the 'tile type' part which is always the same anyway
     'tile_type'                : {'var': 0x40, 'start': 24, 'size': 8},
     'terrain_type'             : {'var': 0x42, 'start':  0, 'size': 8},
     'track_type'               : {'var': 0x42, 'start':  8, 'size': 8},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action3.py 
new/nml-0.8.1/nml/actions/action3.py
--- old/nml-0.8.0/nml/actions/action3.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action3.py        2025-12-02 20:17:25.000000000 
+0100
@@ -474,7 +474,7 @@
         # Special case for vehicle cb 36, maps var10 values to spritegroups
         cb36_mapping = {}
         cb36_buy_mapping = {}
-        # Sspecial case for industry production CB, maps var18 values to 
spritegroups
+        # Special case for industry production CB, maps var18 values to 
spritegroups
         prod_cb_mapping = {}
 
         for cb_info, gfx in callbacks:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action3_callbacks.py 
new/nml-0.8.1/nml/actions/action3_callbacks.py
--- old/nml-0.8.0/nml/actions/action3_callbacks.py      2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/actions/action3_callbacks.py      2025-12-02 
20:17:25.000000000 +0100
@@ -29,7 +29,7 @@
 general_vehicle_cbs = {
     'default'                 : {'type': 'cargo', 'num': None},
     'purchase'                : {'type': 'cargo', 'num': 0xFF},
-    'random_trigger'          : {'type': 'cb', 'num': 0x01}, # Almost 
undocumented, but really neccesary!
+    'random_trigger'          : {'type': 'cb', 'num': 0x01}, # Almost 
undocumented, but really necessary!
     'loading_speed'           : {'type': 'cb', 'num': 0x36, 'var10': 0x07},
     'cargo_subtype_text'      : {'type': 'cb', 'num': 0x19, 'flag_bit': 5},
     'additional_text'         : {'type': 'cb', 'num': 0x23, 'purchase': 2},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action5.py 
new/nml-0.8.1/nml/actions/action5.py
--- old/nml-0.8.0/nml/actions/action5.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action5.py        2025-12-02 20:17:25.000000000 
+0100
@@ -85,6 +85,7 @@
     "OTTD_RECOLOUR": (0x18, 1, Action5BlockType.OFFSET),
     "ROAD_WAYPOINTS": (0x19, 4, Action5BlockType.OFFSET),
     "OVERLAY_ROCKS": (0x1A, 95, Action5BlockType.OFFSET),
+    "BRIDGE_DECKS": (0x1B, 24, Action5BlockType.OFFSET),
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/action7.py 
new/nml-0.8.1/nml/actions/action7.py
--- old/nml-0.8.0/nml/actions/action7.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/action7.py        2025-12-02 20:17:25.000000000 
+0100
@@ -178,7 +178,7 @@
 
         # We need to create a new block
         if skip_opts[0]:
-            # We can just choose to not skip the preceeding actions without 
harm
+            # We can just choose to not skip the preceding actions without harm
             actions.extend(action_list[start : start + length])
         else:
             action_type = 7 if skip_opts[1] else 9
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/actionD.py 
new/nml-0.8.1/nml/actions/actionD.py
--- old/nml-0.8.0/nml/actions/actionD.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/actionD.py        2025-12-02 20:17:25.000000000 
+0100
@@ -27,13 +27,13 @@
     @ivar target: Number of the target parameter
     @ivar target: L{ConstantNumeric}
 
-    @ivar param1: Paramter number of the first operand
+    @ivar param1: Parameter number of the first operand
     @type param1: L{ConstantNumeric}
 
     @ivar op: (Binary) operator to use.
     @type op: L{Operator}
 
-    @ivar param2: Paramter number of the second operand
+    @ivar param2: Parameter number of the second operand
     @type param2: L{ConstantNumeric}
 
     @ivar data: Numerical data that will be used instead of parameter value,
@@ -324,7 +324,7 @@
     elif op == nmlop.CMP_NEQ:
         
extra_actions.extend(parse_actionD(ParameterAssignment(assignment.param, 
nmlop.SUB(expr1, expr2))))
         op = nmlop.DIV
-        # We rely here on the (ondocumented) behavior of both OpenTTD and 
TTDPatch
+        # We rely here on the (undocumented) behavior of both OpenTTD and 
TTDPatch
         # that expr/0==expr. What we do is compute A/A, which will result in 1 
if
         # A != 0 and in 0 if A == 0
         expr1 = assignment.param
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/actionF.py 
new/nml-0.8.1/nml/actions/actionF.py
--- old/nml-0.8.0/nml/actions/actionF.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/actionF.py        2025-12-02 20:17:25.000000000 
+0100
@@ -29,7 +29,7 @@
 # - unsafe numbered: Number is allocated by the user, and is not safe to refer 
to
 #                    (that is, it is below the point of 'prepare_output')
 # - invisible:       Number is allocated by a final town_name, without 
attaching a name to it.
-#                    It is not accessible any more.
+#                    It is not accessible anymore.
 # Instances of the TownNames class have a 'name' attribute, which can be 
'None' (for an invisible number),
 # a string (for a named number), or a (constant numeric) expression (for a 
safe/unsafe number).
 #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/actions/real_sprite.py 
new/nml-0.8.1/nml/actions/real_sprite.py
--- old/nml-0.8.0/nml/actions/real_sprite.py    2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/actions/real_sprite.py    2025-12-02 20:17:25.000000000 
+0100
@@ -201,10 +201,10 @@
         return [parse_real_sprite(self, default_file, default_mask_file, 
poslist, id_dict)]
 
     def check_sprite_size(self):
-        generic.check_range(self.xpos.value, 0, 0x7FFFFFFF, "Real sprite 
paramater 'xpos'", self.xpos.pos)
-        generic.check_range(self.ypos.value, 0, 0x7FFFFFFF, "Real sprite 
paramater 'ypos'", self.ypos.pos)
-        generic.check_range(self.xsize.value, 1, 0xFFFF, "Real sprite 
paramater 'xsize'", self.xsize.pos)
-        generic.check_range(self.ysize.value, 1, 0xFFFF, "Real sprite 
paramater 'ysize'", self.ysize.pos)
+        generic.check_range(self.xpos.value, 0, 0x7FFFFFFF, "Real sprite 
parameter 'xpos'", self.xpos.pos)
+        generic.check_range(self.ypos.value, 0, 0x7FFFFFFF, "Real sprite 
parameter 'ypos'", self.ypos.pos)
+        generic.check_range(self.xsize.value, 1, 0xFFFF, "Real sprite 
parameter 'xsize'", self.xsize.pos)
+        generic.check_range(self.ysize.value, 1, 0xFFFF, "Real sprite 
parameter 'ysize'", self.ysize.pos)
 
     def validate_size(self):
         """
@@ -232,7 +232,7 @@
 
     def get_cache_key(self, crop_sprites):
         """
-        Assemble the sprite meta data into a key, able to identify the sprite.
+        Assemble the sprite metadata into a key, able to identify the sprite.
 
         @param crop_sprites: Whether to crop sprites, which allow it.
         @type  crop_sprites: C{bool}
@@ -492,14 +492,14 @@
         new_sprite.xrel.value,
         -0x8000,
         0x7FFF,
-        "Real sprite paramater {:d} 'xrel'".format(param_offset + 1),
+        "Real sprite parameter {:d} 'xrel'".format(param_offset + 1),
         new_sprite.xrel.pos,
     )
     generic.check_range(
         new_sprite.yrel.value,
         -0x8000,
         0x7FFF,
-        "Real sprite paramater {:d} 'yrel'".format(param_offset + 2),
+        "Real sprite parameter {:d} 'yrel'".format(param_offset + 2),
         new_sprite.yrel.pos,
     )
     param_offset += 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/alt_sprites.py 
new/nml-0.8.1/nml/ast/alt_sprites.py
--- old/nml-0.8.0/nml/ast/alt_sprites.py        2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/ast/alt_sprites.py        2025-12-02 20:17:25.000000000 
+0100
@@ -65,7 +65,7 @@
             self.bit_depth = global_constants.bit_depths[param_list[2].value]
         else:
             raise generic.ScriptError(
-                "value for alternative_sprites parameter 3 'bit depth' is not 
a valid bit depthl", param_list[2].pos
+                "value for alternative_sprites parameter 3 'bit depth' is not 
a valid bit depth", param_list[2].pos
             )
         if self.bit_depth == 32:
             global_constants.any_32bpp_sprites = global_constants.allow_32bpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/base_statement.py 
new/nml-0.8.1/nml/ast/base_statement.py
--- old/nml-0.8.0/nml/ast/base_statement.py     2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/ast/base_statement.py     2025-12-02 20:17:25.000000000 
+0100
@@ -84,7 +84,7 @@
     def pre_process(self):
         """
         Called to do any pre-processing before the actual action generation.
-        For example, to remove identifiesr
+        For example, to remove identifiers
         """
         pass
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/error.py 
new/nml-0.8.1/nml/ast/error.py
--- old/nml-0.8.0/nml/ast/error.py      2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/error.py      2025-12-02 20:17:25.000000000 +0100
@@ -20,8 +20,8 @@
 
 class Error(base_statement.BaseStatement):
     """
-    An error has occured while parsing the GRF. This can be anything ranging 
from
-    an imcompatible GRF file that was found or a game setting that is set to 
the
+    An error has occurred while parsing the GRF. This can be anything ranging 
from
+    an incompatible GRF file that was found or a game setting that is set to 
the
     wrong value to a wrong combination of parameters. The action taken by the 
host
     depends on the severity level of the error.
     NML equivalent: error(level, message[, extra_text[, parameter1[, 
parameter2]]]).
@@ -33,7 +33,7 @@
     @type severity: L{Expression}
 
     @ivar msg: The string to be used for this error message. This can be either
-               one of the predifined error strings or a custom string from the
+               one of the predefined error strings or a custom string from the
                language file.
     @type msg: L{Expression}
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/grf.py new/nml-0.8.1/nml/ast/grf.py
--- old/nml-0.8.0/nml/ast/grf.py        2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/grf.py        2025-12-02 20:17:25.000000000 +0100
@@ -305,6 +305,8 @@
 
 
 class ParameterDescription:
+    free_bits = {}
+
     def __init__(self, setting_list, num=None, pos=None):
         self.setting_list = setting_list
         self.num = num
@@ -330,15 +332,31 @@
         if self.num is None:
             self.num = num
         self.num = self.num.reduce_constant()
+        if self.num.value not in ParameterDescription.free_bits:
+            ParameterDescription.free_bits[self.num.value] = list(range(0, 32))
         for setting in self.setting_list:
             setting.pre_process()
         for setting in self.setting_list:
             if setting.type == "int":
-                if len(self.setting_list) > 1:
+                if len(self.setting_list) > 1 or 
len(ParameterDescription.free_bits[self.num.value]) != 32:
                     raise generic.ScriptError(
-                        "When packing multiple settings in one parameter only 
bool settings are allowed", self.pos
+                        "When packing multiple settings in one parameter only 
bool settings are allowed",
+                        setting.name.pos,
                     )
                 global_constants.settings[setting.name.value] = {"num": 
self.num.value, "size": 4}
+                ParameterDescription.free_bits[self.num.value].clear()
             else:
-                bit = 0 if setting.bit_num is None else setting.bit_num.value
-                global_constants.misc_grf_bits[setting.name.value] = {"param": 
self.num.value, "bit": bit}
+                if setting.bit_num is None:
+                    if len(ParameterDescription.free_bits[self.num.value]) == 
0:
+                        raise generic.ScriptError("No bits available for this 
parameter", setting.name.pos)
+                    setting.bit_num = 
expression.ConstantNumeric(ParameterDescription.free_bits[self.num.value].pop(0))
+                else:
+                    if setting.bit_num.value not in 
ParameterDescription.free_bits[self.num.value]:
+                        raise generic.ScriptError(
+                            "Bit {} is already 
used".format(setting.bit_num.value), setting.name.pos
+                        )
+                    
ParameterDescription.free_bits[self.num.value].remove(setting.bit_num.value)
+                global_constants.misc_grf_bits[setting.name.value] = {
+                    "param": self.num.value,
+                    "bit": setting.bit_num.value,
+                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/item.py 
new/nml-0.8.1/nml/ast/item.py
--- old/nml-0.8.0/nml/ast/item.py       2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/item.py       2025-12-02 20:17:25.000000000 +0100
@@ -128,7 +128,7 @@
 class Property:
     """
     AST-node representing a single property. These are only valid
-    insde a PropertyBlock.
+    inside a PropertyBlock.
 
     @ivar name: The name (or number) of this property.
     @type name: L{Identifier} or L{ConstantNumeric}.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/override.py 
new/nml-0.8.1/nml/ast/override.py
--- old/nml-0.8.0/nml/ast/override.py   2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/override.py   2025-12-02 20:17:25.000000000 +0100
@@ -23,7 +23,7 @@
     AST Node for an engine override.
 
     @ivar grfid: GRFid of the grf to override the engines from.
-    @type grfid: C{int{
+    @type grfid: C{int}
 
     @ivar source_grfid: GRFid of the grf that overrides the engines.
     @type source_grfid: C{int}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/switch.py 
new/nml-0.8.1/nml/ast/switch.py
--- old/nml-0.8.0/nml/ast/switch.py     2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/switch.py     2025-12-02 20:17:25.000000000 +0100
@@ -117,7 +117,7 @@
             )
             return self.optimised is not self
 
-        self.optimised = self  # Prevent multiple run on the same non 
optimisable Switch
+        self.optimised = self  # Prevent multiple run on the same 
non-optimisable Switch
         return False
 
     def collect_references(self):
@@ -390,7 +390,7 @@
         if self.optimised:
             return self.optimised is not self
 
-        # Triggers have side-effects, and can't be skipped.
+        # Triggers have side effects, and can't be skipped.
         # Scope for expressions can be different in referencing location, so 
don't optimise them.
         if self.triggers.value == 0 and len(self.choices) == 1:
             optimised = self.choices[0].result.value
@@ -407,7 +407,7 @@
                 self.optimised = optimised
                 return True
 
-        self.optimised = self  # Prevent multiple run on the same non 
optimisable RandomSwitch
+        self.optimised = self  # Prevent multiple run on the same 
non-optimisable RandomSwitch
         return False
 
     def collect_references(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/tilelayout.py 
new/nml-0.8.1/nml/ast/tilelayout.py
--- old/nml-0.8.0/nml/ast/tilelayout.py 2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/tilelayout.py 2025-12-02 20:17:25.000000000 +0100
@@ -22,7 +22,7 @@
     """
     'tile_layout' AST node. A TileLayout is a list of x,y-offset/tileID pairs.
     The x and y offsets are from the northernmost tile of the industry/airport.
-    Additionally some extra properties can be stored in the TileLayout, like
+    Additionally, some extra properties can be stored in the TileLayout, like
     the orientation of the airport.
 
     @ivar name: The name of this layout by which it can be referenced later.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/ast/townnames.py 
new/nml-0.8.1/nml/ast/townnames.py
--- old/nml-0.8.0/nml/ast/townnames.py  2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/ast/townnames.py  2025-12-02 20:17:25.000000000 +0100
@@ -208,7 +208,7 @@
 
         finished_actions.extend(heap)
 
-        # To ensure the chances do not get messed up due to one part needing 
less bits for its
+        # To ensure the chances do not get messed up due to one part needing 
fewer bits for its
         # selection, all parts are forced to use the same number of bits.
         max_prob = max(sub[0] for sub in finished_actions)
         num_bits = 1
@@ -305,7 +305,7 @@
 class TownNamesParam:
     """
     Class containing a parameter of a town name.
-    Currently known key/values:
+    Currently, known key/values:
      - 'styles'  / string expression
     """
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/editors/extract_tables.py 
new/nml-0.8.1/nml/editors/extract_tables.py
--- old/nml-0.8.0/nml/editors/extract_tables.py 2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/editors/extract_tables.py 2025-12-02 20:17:25.000000000 
+0100
@@ -80,6 +80,7 @@
     action0properties.properties[0x01],
     action0properties.properties[0x02],
     action0properties.properties[0x03],
+    action0properties.properties[0x04],
     action0properties.properties[0x05],
     action0properties.properties[0x07],
     action0properties.properties[0x09],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/expression/binop.py 
new/nml-0.8.1/nml/expression/binop.py
--- old/nml-0.8.0/nml/expression/binop.py       2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/expression/binop.py       2025-12-02 20:17:25.000000000 
+0100
@@ -173,7 +173,7 @@
                     expr1.add = ConstantNumeric(0)
                 expr1.mod = expr2
                 return expr1
-            # Since we have a lot of nml-variables that are in fact only the 
high bits of an nfo
+            # Since we have a lot of nml-variables that are in fact only the 
high bits of a nfo
             # variable it can happen that we want to shift back the variable 
to the left.
             # Don't use any extra opcodes but just reduce the shift-right in 
that case.
             if (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/expression/functioncall.py 
new/nml-0.8.1/nml/expression/functioncall.py
--- old/nml-0.8.0/nml/expression/functioncall.py        2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/expression/functioncall.py        2025-12-02 
20:17:25.000000000 +0100
@@ -92,7 +92,7 @@
     @ivar varsize: Varsize for the action7/9 check
     @type varsize: C{int}
 
-    @ivar mask: Mask to to test only certain bits of the value
+    @ivar mask: Mask to test only certain bits of the value
     @type mask: C{int}
 
     @ivar pos: Position information
@@ -183,7 +183,7 @@
     """
     max(...) builtin function.
 
-    @return Heighest value of the given arguments.
+    @return Highest value of the given arguments.
     """
     if len(args) < 2:
         raise generic.ScriptError("max() requires at least 2 arguments", pos)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/expression/parameter.py 
new/nml-0.8.1/nml/expression/parameter.py
--- old/nml-0.8.0/nml/expression/parameter.py   2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/expression/parameter.py   2025-12-02 20:17:25.000000000 
+0100
@@ -47,7 +47,7 @@
         supported = isinstance(self.num, ConstantNumeric)
         if not supported and raise_error:
             raise generic.ScriptError(
-                "Parameter acessess with non-constant numbers are not 
supported in a switch-block.", self.pos
+                "Parameter accesses with non-constant numbers are not 
supported in a switch-block.", self.pos
             )
         return supported
 
@@ -100,12 +100,12 @@
 
 def parse_string_to_dword(string):
     """
-    Convert string literal expression of length 4 to it's equivalent 32 bit 
number.
+    Convert string literal expression of length 4 to its equivalent 32-bit 
number.
 
     @param string: Expression to convert.
     @type  string: L{Expression}
 
-    @return: Value of the converted expression (a 32 bit integer number, 
little endian).
+    @return: Value of the converted expression (a 32-bit integer number, 
little endian).
     @rtype:  C{int}
     """
     if not isinstance(string, StringLiteral) or 
grfstrings.get_string_size(string.value, False, True) != 4:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/expression/special_parameter.py 
new/nml-0.8.1/nml/expression/special_parameter.py
--- old/nml-0.8.0/nml/expression/special_parameter.py   2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/expression/special_parameter.py   2025-12-02 
20:17:25.000000000 +0100
@@ -36,7 +36,7 @@
                             Position information
                         Return value is a 2-tuple:
                             Left side of the assignment (must be a parameter)
-                            Right side of the assignment (may be any 
expression)
+                            Right side of the assignment (can be any 
expression)
     @type write_func: C{function}
 
     @ivar read_func: Function that will be called to read out the parameter 
value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/expression/storage_op.py 
new/nml-0.8.1/nml/expression/storage_op.py
--- old/nml-0.8.0/nml/expression/storage_op.py  2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/expression/storage_op.py  2025-12-02 20:17:25.000000000 
+0100
@@ -33,7 +33,7 @@
     @ivar name: Name of the called storage function
     @type name: C{str}
 
-    @ivar info: Dictionary containting information about the operation to 
perform
+    @ivar info: Dictionary containing information about the operation to 
perform
     @type info: C{dict}
 
     @ivar value: Value to store, or C{None} for loading operations
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/free_number_list.py 
new/nml-0.8.1/nml/free_number_list.py
--- old/nml-0.8.0/nml/free_number_list.py       2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/free_number_list.py       2025-12-02 20:17:25.000000000 
+0100
@@ -25,7 +25,7 @@
     @type total_amount: C{int}
 
     @ivar stats: Statistics about id usage.
-    @type stats: Tuple of C{int} and L{Position} refering to the amount on 
location of most concurrently used ids.
+    @type stats: Tuple of C{int} and L{Position} referring to the amount on 
location of most concurrently used ids.
 
     @ivar free_numbers: The list with currently unused numbers.
     @type free_numbers: C{list}
@@ -86,7 +86,7 @@
     def pop_global(self, pos):
         """
         Pop a free number from the list. The number may have been used before
-        and already been restored but it'll never be given out again.
+        and already been restored, but it'll never be given out again.
 
         @param pos: Positional context.
         @type  pos: L{Position}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/generic.py new/nml-0.8.1/nml/generic.py
--- old/nml-0.8.0/nml/generic.py        2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/generic.py        2025-12-02 20:17:25.000000000 +0100
@@ -378,7 +378,7 @@
 
 def print_progress(msg, incremental=False):
     """
-    Output progess information to the user.
+    Output progress information to the user.
 
     @param msg: Progress message.
     @type  msg: C{str}
@@ -411,7 +411,7 @@
 
 def print_info(msg):
     """
-    Output a pure informational message to th euser.
+    Output a pure informational message to the user.
     """
     if verbosity_level < VERBOSITY_INFO:
         return
@@ -590,7 +590,7 @@
                 path = os.path.join(cache_root_dir, path)
                 result = os.path.join(path, name)
             else:
-                # In case of multiple soure files, ignore the path component 
for all but the first
+                # In case of multiple source files, ignore the path component 
for all but the first
                 result += "_" + name
 
     return result + extension
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/global_constants.py 
new/nml-0.8.1/nml/global_constants.py
--- old/nml-0.8.0/nml/global_constants.py       2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/nml/global_constants.py       2025-12-02 20:17:25.000000000 
+0100
@@ -385,6 +385,16 @@
     # station tiles
     "STAT_ALL_TILES"     : 0xFF,
 
+    # bridge pillar flags
+    "BRIDGE_PILLAR_CORNER_W" : 0,
+    "BRIDGE_PILLAR_CORNER_S" : 1,
+    "BRIDGE_PILLAR_CORNER_E" : 2,
+    "BRIDGE_PILLAR_CORNER_N" : 3,
+    "BRIDGE_PILLAR_EDGE_NE"  : 4,
+    "BRIDGE_PILLAR_EDGE_SE"  : 5,
+    "BRIDGE_PILLAR_EDGE_SW"  : 6,
+    "BRIDGE_PILLAR_EDGE_NW"  : 7,
+
     # house flags
     "HOUSE_FLAG_NOT_SLOPED"         : 1,
     "HOUSE_FLAG_ANIMATE"            : 5,
@@ -1294,7 +1304,7 @@
 
 def map_exponentiate(expr, info):
     """
-    Given a exponent, add an offset to it and compute the exponentiation with 
base 2.
+    Given an exponent, add an offset to it and compute the exponentiation with 
base 2.
 
     @param expr: The exponent.
     @type expr: L{Expression}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/grfstrings.py 
new/nml-0.8.1/nml/grfstrings.py
--- old/nml-0.8.0/nml/grfstrings.py     2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/grfstrings.py     2025-12-02 20:17:25.000000000 +0100
@@ -49,7 +49,7 @@
 def is_ascii_string(string):
     """
     Check whether a given string can be written using the ASCII codeset or
-    that we need unicode.
+    that we need Unicode.
 
     @param string: The string to check.
     @type  string: C{str}
@@ -81,7 +81,7 @@
     @param string: The string to check.
     @type  string: C{str}
 
-    @param final_zero: Whether or not to account for a zero-byte directly 
after the string.
+    @param final_zero: Whether to account for a zero-byte directly after the 
string.
     @type  final_zero: C{bool}
 
     @param force_ascii: When true, make sure the string is written as ascii as 
opposed to unicode.
@@ -421,14 +421,14 @@
         """
         Convert the string command to output text.
 
-        @param str_type: Exptected type of result text, C{"unicode"} or 
C{"ascii"}.
+        @param str_type: Expected type of result text, C{"unicode"} or 
C{"ascii"}.
         @type  str_type: C{str}
 
         @param lang: Language of the string.
         @type  lang: L{Language}
 
         @param wanted_lang_id: Language-id to use for interpreting the command
-                               (this string may be from another language, eg 
with missing strings).
+                               (this string may be from another language, e.g. 
with missing strings).
 
         @param prev_command: Argument of previous string command (parameter 
number, size).
         @type  prev_command: C{tuple} or C{None}
@@ -677,7 +677,6 @@
                     raise generic.ScriptError('Invalid case-name 
"{}"'.format(case), pos)
                 command.case = lang.cases[case]
             if string[end] != "}":
-                command.argument_is_assigment = string[end] == "="
                 arg_start = end + 1
                 end = string.find("}", end + 1)
                 if end == -1 or not 
command.set_arguments(string[arg_start:end]):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/main.py new/nml-0.8.1/nml/main.py
--- old/nml-0.8.0/nml/main.py   2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/main.py   2025-12-02 20:17:25.000000000 +0100
@@ -308,7 +308,7 @@
         input = sys.stdin
     else:
         input = codecs.open(generic.find_file(input_filename), "r", "utf-8")
-        # Only append an output grf name, if no ouput is given, also not 
implicitly via -M
+        # Only append an output grf name, if no output is given, also not 
implicitly via -M
         if not opts.outputfile_given and not outputs:
             opts.grf_filename = filename_output_from_input(input_filename, 
".grf")
 
@@ -528,7 +528,7 @@
 
         last_file = None
         for f_pair in sprite_files:
-            # Palette is defined by mask_file, if present. Otherwise by the 
main file.
+            # Palette is defined by mask_file, if present. Otherwise, by the 
main file.
             f = f_pair[1]
             if f is None:
                 f = f_pair[0]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/output_base.py 
new/nml-0.8.1/nml/output_base.py
--- old/nml-0.8.0/nml/output_base.py    2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/output_base.py    2025-12-02 20:17:25.000000000 +0100
@@ -316,7 +316,7 @@
 
     def print_data(self, data):
         """
-        Print a chunck of data in one go
+        Print a chunk of data in one go
 
         @param data: Data to output
         @type data: C{array}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/output_grf.py 
new/nml-0.8.1/nml/output_grf.py
--- old/nml-0.8.0/nml/output_grf.py     2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/output_grf.py     2025-12-02 20:17:25.000000000 +0100
@@ -34,7 +34,7 @@
     def open_file(self):
         # Remove / unlink the file, most useful for linux systems
         # See also issue #4165
-        # If the file happens to be in use or non-existant, ignore
+        # If the file happens to be in use or non-existent, ignore
         try:
             os.unlink(self.filename)
         except OSError:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml/spriteencoder.py 
new/nml-0.8.1/nml/spriteencoder.py
--- old/nml-0.8.0/nml/spriteencoder.py  2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/nml/spriteencoder.py  2025-12-02 20:17:25.000000000 +0100
@@ -180,7 +180,7 @@
         """
         Get encoded sprite date, either from cache, or new.
 
-        @param sprite_info: Sprite meta data
+        @param sprite_info: Sprite metadata
         @type  sprite_info: C{RealSprite}
         """
 
@@ -253,7 +253,7 @@
         """
         Crop and compress a real sprite.
 
-        @param sprite_info: Sprite meta data
+        @param sprite_info: Sprite metadata
         @type  sprite_info: C{RealSprite}
 
         @return: size_x, size_y, xoffset, yoffset, compressed_data, info_byte, 
crop_rect, pixel_stats
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/nml.egg-info/PKG-INFO 
new/nml-0.8.1/nml.egg-info/PKG-INFO
--- old/nml-0.8.0/nml.egg-info/PKG-INFO 2025-06-21 21:12:41.000000000 +0200
+++ new/nml-0.8.1/nml.egg-info/PKG-INFO 2025-12-02 20:17:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: nml
-Version: 0.8.0
+Version: 0.8.1
 Summary: An OpenTTD NewGRF compiler for the nml language
 Home-page: https://github.com/OpenTTD/nml
 Author: NML Development Team
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/pyproject.toml new/nml-0.8.1/pyproject.toml
--- old/nml-0.8.0/pyproject.toml        2025-06-21 21:12:37.000000000 +0200
+++ new/nml-0.8.1/pyproject.toml        2025-12-02 20:17:25.000000000 +0100
@@ -1,2 +1,6 @@
 [build-system]
 requires = ["setuptools", "ply"]
+
+[tool.black]
+line-length = 120
+exclude = 'action2var_variables.py|action3_callbacks.py|ply|setup.py'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/regression/013_train_callback.nml 
new/nml-0.8.1/regression/013_train_callback.nml
--- old/nml-0.8.0/regression/013_train_callback.nml     2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/regression/013_train_callback.nml     2025-12-02 
20:17:25.000000000 +0100
@@ -136,6 +136,8 @@
         speed: 0;
         refit_cost: 40;
         track_type: RAIL;
+        track_type: [RAIL];
+        track_type: [RAIL, ELRL];
         power: 0;
         running_cost_base: RUNNING_COST_STEAM;
         cargo_capacity: 30;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/regression/021_grf_parameter.nml 
new/nml-0.8.1/regression/021_grf_parameter.nml
--- old/nml-0.8.0/regression/021_grf_parameter.nml      2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/regression/021_grf_parameter.nml      2025-12-02 
20:17:25.000000000 +0100
@@ -39,6 +39,22 @@
             };
         }
     }
+    param (2) {
+        param_NoGrid {
+            type:    bool;
+            name:    string(STR_PARAM_NOGRID);
+            desc:    string(STR_PARAM_NOGRID_DESC);
+            def_value: 1;
+        }
+    }
+    param (2) {
+        transmitter2rock {
+            type:    bool;
+            name:    string(STR_PARAM_TRANSMITTER);
+            desc:    string(STR_PARAM_TRANSMITTER_DESC);
+            def_value: 0;
+        }
+    }
 }
 
 param[10] = param_landscape;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/regression/040_station.nml 
new/nml-0.8.1/regression/040_station.nml
--- old/nml-0.8.0/regression/040_station.nml    2025-06-21 21:12:37.000000000 
+0200
+++ new/nml-0.8.1/regression/040_station.nml    2025-12-02 20:17:25.000000000 
+0100
@@ -135,6 +135,17 @@
                 [6, 7]
             ],
         ];
+        heights: [1, 1, 2, 2, 3, 3, 4, 4];
+        blocked_pillars: [
+            bitmask(BRIDGE_PILLAR_CORNER_N, BRIDGE_PILLAR_CORNER_E),
+            bitmask(BRIDGE_PILLAR_CORNER_S, BRIDGE_PILLAR_CORNER_W),
+            bitmask(BRIDGE_PILLAR_CORNER_N, BRIDGE_PILLAR_CORNER_E),
+            bitmask(BRIDGE_PILLAR_CORNER_S, BRIDGE_PILLAR_CORNER_W),
+            bitmask(BRIDGE_PILLAR_CORNER_N, BRIDGE_PILLAR_CORNER_E, 
BRIDGE_PILLAR_EDGE_NE, BRIDGE_PILLAR_EDGE_NW),
+            bitmask(BRIDGE_PILLAR_CORNER_S, BRIDGE_PILLAR_CORNER_W, 
BRIDGE_PILLAR_EDGE_SE, BRIDGE_PILLAR_EDGE_SW),
+            bitmask(BRIDGE_PILLAR_CORNER_N, BRIDGE_PILLAR_CORNER_E, 
BRIDGE_PILLAR_EDGE_NE, BRIDGE_PILLAR_EDGE_NW),
+            bitmask(BRIDGE_PILLAR_CORNER_S, BRIDGE_PILLAR_CORNER_W, 
BRIDGE_PILLAR_EDGE_SE, BRIDGE_PILLAR_EDGE_SW),
+        ];
     }
     graphics {
         foundations: 0;
Binary files old/nml-0.8.0/regression/expected/013_train_callback.grf and 
new/nml-0.8.1/regression/expected/013_train_callback.grf differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/regression/expected/013_train_callback.nfo 
new/nml-0.8.1/regression/expected/013_train_callback.nfo
--- old/nml-0.8.0/regression/expected/013_train_callback.nfo    2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/regression/expected/013_train_callback.nfo    2025-12-02 
20:17:25.000000000 +0100
@@ -223,11 +223,11 @@
 69 * 9 0D 7E \D<< 01 FF \dxFFFFFFF8
 
 70 * 12 06
-7F 01 FF \wx004D
-7E 01 FF \wx004F
+7F 01 FF \wx0053
+7E 01 FF \wx0055
 FF
 
-71 * 82 00 00 \b26 01 FF \wx0074
+71 * 88 00 00 \b28 01 FF \wx0074
 06 0F
 28 \wx0010
 1D \dx00000000
@@ -249,6 +249,9 @@
 09 \wx0000
 1C 28
 05 00
+05 00
+34 \b2
+00 01
 0B \wx0000
 0E \dx00004C30
 14 1E
Binary files old/nml-0.8.0/regression/expected/021_grf_parameter.grf and 
new/nml-0.8.1/regression/expected/021_grf_parameter.grf differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/regression/expected/021_grf_parameter.nfo 
new/nml-0.8.1/regression/expected/021_grf_parameter.nfo
--- old/nml-0.8.0/regression/expected/021_grf_parameter.nfo     2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/regression/expected/021_grf_parameter.nfo     2025-12-02 
20:17:25.000000000 +0100
@@ -7,10 +7,10 @@
 
 0 * 4 \d3
 
-1 * 817 14 "C" "INFO"
+1 * 1254 14 "C" "INFO"
 "B" "VRSN" \w4 \dx00000001
 "B" "MINV" \w4 \dx00000000
-"B" "NPAR" \w1 03
+"B" "NPAR" \w1 05
 "C" "PARA"
 "C" \d0
 "T" "NAME" 7F "Disable gridlines" 00
@@ -41,6 +41,20 @@
 00
 "B" "DFLT" \w4 \dx00000000
 00
+"C" \d3
+"T" "NAME" 7F "Disable gridlines" 00
+"T" "DESC" 7F "This setting allows to replace all ground sprites such that the 
landscape is painted (mostly) without grid lines. Note that roads and train 
tracks don't yet follow this rule" 00
+"B" "TYPE" \w1 01
+"B" "MASK" \w3 \b2 \b0 \b1
+"B" "DFLT" \w4 \dx00000001
+00
+"C" \d4
+"T" "NAME" 7F "Replace the transmitter tower by a rock" 00
+"T" "DESC" 7F "Enable to replace the transmitter tower by a rock (useful for 
early scenarios without telecomunication towers)" 00
+"B" "TYPE" \w1 01
+"B" "MASK" \w3 \b2 \b1 \b1
+"B" "DFLT" \w4 \dx00000000
+00
 00
 "B" "PALS" \w1 "A"
 "B" "BLTR" \w1 "8"
Binary files old/nml-0.8.0/regression/expected/040_station.grf and 
new/nml-0.8.1/regression/expected/040_station.grf differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nml-0.8.0/regression/expected/040_station.nfo 
new/nml-0.8.1/regression/expected/040_station.nfo
--- old/nml-0.8.0/regression/expected/040_station.nfo   2025-06-21 
21:12:37.000000000 +0200
+++ new/nml-0.8.1/regression/expected/040_station.nfo   2025-12-02 
20:17:25.000000000 +0100
@@ -21,7 +21,7 @@
 4 * 16 00 08 \b1 02 FF \wx0000
 09 "COAL" "LVST"
 
-5 * 47 00 04 \b6 01 FF \wx00FF
+5 * 71 00 04 \b8 01 FF \wx00FF
 08 "TEST"
 13 18
 12 \dx00000002
@@ -35,6 +35,10 @@
 04 04
 06 06
 \b0 \b0
+20 FF \w8
+01 01 02 02 03 03 04 04
+21 FF \w8
+0C 03 0C 03 9C 63 9C 63
 
 6 * 11 04 04 FF 01 \wxC4FF "Test" 00
 

Reply via email to