From 3327be387f59d377ee75fc971f8830b58a73a0a2 Mon Sep 17 00:00:00 2001 From: glx22 Date: Wed, 7 Aug 2024 18:13:32 +0200 Subject: [PATCH] Add: Support for station property 1E --- examples/station/example_station.nml | 8 ++-- nml/actions/action0properties.py | 53 ++++++++++++++++++------ nml/global_constants.py | 5 +++ regression/040_station.nml | 13 +++++- regression/expected/040_station.grf | Bin 1251 -> 1265 bytes regression/expected/040_station.nfo | 5 ++- regression/expected/example_station.grf | Bin 3927 -> 3965 bytes regression/expected/example_station.nfo | 18 +++++--- 8 files changed, 80 insertions(+), 22 deletions(-) diff --git a/examples/station/example_station.nml b/examples/station/example_station.nml index 05bf3e6f..0f95843e 100644 --- a/examples/station/example_station.nml +++ b/examples/station/example_station.nml @@ -109,12 +109,14 @@ item(FEAT_STATIONS, cow_pen) { /* Name of this particular station */ name: string(STR_NAME_STATION); cargo_threshold: 160; - draw_pylon_tiles: 0; - hide_wire_tiles: 0xFF; - non_traversable_tiles: 0xFF; + tile_flags: [ + bitmask(STAT_TILE_NOWIRE, STAT_TILE_BLOCKED), + bitmask(STAT_TILE_NOWIRE, STAT_TILE_BLOCKED) + ]; } graphics { sprite_layouts: [cow_pen_X(0), cow_pen_Y(0)]; + select_tile_type: 0; purchase: cow_pen_half; LVST: random_cow_pen; cow_pen_empty; diff --git a/nml/actions/action0properties.py b/nml/actions/action0properties.py index d260d0e2..b95784a4 100644 --- a/nml/actions/action0properties.py +++ b/nml/actions/action0properties.py @@ -15,7 +15,7 @@ import itertools -from nml import generic, nmlop +from nml import generic, nmlop, global_constants from nml.expression import ( AcceptCargo, Array, @@ -305,17 +305,22 @@ class VariableListProp(BaseAction0Property): Property value that is a variable-length list of variable sized values, the list length is written before the data. """ - def __init__(self, prop_num, data, size): + def __init__(self, prop_num, data, size, extended): # data is a list, each element belongs to an item ID # Each element in the list is a list of cargo types self.prop_num = prop_num self.data = data self.size = size + self.extended = extended def write(self, file): file.print_bytex(self.prop_num) for elem in self.data: - file.print_byte(len(elem)) + if self.extended: + file.print_bytex(0xFF) + file.print_word(len(elem)) + else: + file.print_byte(len(elem)) for i, val in enumerate(elem): if i % 8 == 0: file.newline() @@ -325,13 +330,13 @@ def write(self, file): def get_size(self): total_len = 1 # Prop number for elem in self.data: - # For each item ID to set, make space for all values + 1 for the length - total_len += len(elem) * self.size + 1 + # For each item ID to set, make space for all values + 3 or 1 for the length + total_len += len(elem) * self.size + (3 if self.extended else 1) return total_len -def VariableByteListProp(prop_num, data): - return VariableListProp(prop_num, data, 1) +def VariableByteListProp(prop_num, data, extended=False): + return VariableListProp(prop_num, data, 1, extended) def ctt_list(prop_num, *values): @@ -348,8 +353,8 @@ def ctt_list(prop_num, *values): ] -def VariableWordListProp(num_prop, data): - return VariableListProp(num_prop, data, 2) +def VariableWordListProp(num_prop, data, extended=False): + return VariableListProp(num_prop, data, 2, extended) def accepted_cargos(prop_num, *values): @@ -707,6 +712,29 @@ def cargo_bitmask(value): return BitMask(value.values, value.pos).reduce() +def station_tile_flags(value): + if not isinstance(value, Array) or len(value.values) % 2 != 0: + raise generic.ScriptError("Flag list must be an array of even length", value.pos) + if len(value.values) > 8: + return [VariableByteListProp(0x1E, [[flags.reduce_constant().value for flags in value.values]], True)] + pylons = 0 + wires = 0 + blocked = 0 + for i, val in enumerate(value.values): + flag = val.value + if flag & 1 << global_constants.constant_numbers["STAT_TILE_PYLON"]: + pylons = pylons | 1 << i + if flag & 1 << global_constants.constant_numbers["STAT_TILE_NOWIRE"]: + wires = wires | 1 << i + if flag & 1 << global_constants.constant_numbers["STAT_TILE_BLOCKED"]: + blocked = blocked | 1 << i + return [ + Action0Property(0x11, ConstantNumeric(pylons), 1), + Action0Property(0x14, ConstantNumeric(wires), 1), + Action0Property(0x15, ConstantNumeric(blocked), 1), + ] + + # fmt: off properties[0x04] = { "class": {"size": 4, "num": 0x08, "first": None, "string_literal": 4}, @@ -718,11 +746,11 @@ def cargo_bitmask(value): # 0E (station layout) callback 24 should be enough # 0F (copy station layout) "cargo_threshold": {"size": 2, "num": 0x10}, - "draw_pylon_tiles": {"size": 1, "num": 0x11}, + "draw_pylon_tiles": {"size": 1, "num": 0x11, "replaced_by": "tile_flags"}, "cargo_random_triggers": {"size": 4, "num": 0x12, "value_function": cargo_bitmask}, "general_flags": {"size": 1, "num": 0x13, "value_function": station_flags}, - "hide_wire_tiles": {"size": 1, "num": 0x14}, - "non_traversable_tiles": {"size": 1, "num": 0x15}, + "hide_wire_tiles": {"size": 1, "num": 0x14, "replaced_by": "tile_flags"}, + "non_traversable_tiles": {"size": 1, "num": 0x15, "replaced_by": "tile_flags"}, "animation_info": {"size": 2, "num": 0x16, "value_function": animation_info}, "animation_speed": {"size": 1, "num": 0x17}, "animation_triggers": {"size": 2, "num": 0x18}, @@ -731,6 +759,7 @@ def cargo_bitmask(value): # 1B (minimum bridge height) JGR only "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}, } # fmt: on diff --git a/nml/global_constants.py b/nml/global_constants.py index 47cabd35..9a062ab3 100644 --- a/nml/global_constants.py +++ b/nml/global_constants.py @@ -375,6 +375,11 @@ def constant_number(name, info, pos): "STAT_FLAG_CUSTOM_FOUNDATIONS" : 3, "STAT_FLAG_EXTENDED_FOUNDATIONS" : 4, + # station tile flags + "STAT_TILE_PYLON" : 0, + "STAT_TILE_NOWIRE" : 1, + "STAT_TILE_BLOCKED" : 2, + # station tiles "STAT_ALL_TILES" : 0xFF, diff --git a/regression/040_station.nml b/regression/040_station.nml index 65c3b2e9..c32fcda5 100644 --- a/regression/040_station.nml +++ b/regression/040_station.nml @@ -111,7 +111,18 @@ item (FEAT_STATIONS, basic_station, 255) { general_flags: bitmask(STAT_FLAG_EXTENDED_FOUNDATIONS); cargo_random_triggers: [LVST]; disabled_platforms: bitmask(5, 6, 7, 8); - + tile_flags: [ + 0, + bitmask(STAT_TILE_PYLON), + bitmask(STAT_TILE_NOWIRE), + bitmask(STAT_TILE_PYLON, STAT_TILE_NOWIRE), + bitmask(STAT_TILE_BLOCKED), + bitmask(STAT_TILE_PYLON, STAT_TILE_BLOCKED), + bitmask(STAT_TILE_NOWIRE, STAT_TILE_BLOCKED), + bitmask(STAT_TILE_PYLON, STAT_TILE_NOWIRE, STAT_TILE_BLOCKED), + bitmask(STAT_TILE_NOWIRE), + bitmask(STAT_TILE_PYLON, STAT_TILE_BLOCKED), + ]; } graphics { foundations: 0; diff --git a/regression/expected/040_station.grf b/regression/expected/040_station.grf index feba95f6b7a18dd28d96c22e09a444a69b3c2e26..5d21c8a2c6a23d97bdbffcb44f2094dae6f48f4d 100644 GIT binary patch delta 64 zcmaFN`H_>Gfx$h1_p-z3@ogS|Nk>^gt!KW2ulbt0mXPe$o=PH TU|?ioW?^MxXJXxWn}Y=a`aBK@ delta 50 zcmey!`IwWNfx$h^gt!KW2ulbt0mXPeY<$VV F0sury450u3 diff --git a/regression/expected/040_station.nfo b/regression/expected/040_station.nfo index d3b96c0d..17c9b1cd 100644 --- a/regression/expected/040_station.nfo +++ b/regression/expected/040_station.nfo @@ -21,11 +21,14 @@ 4 * 16 00 08 \b1 02 FF \wx0000 09 "COAL" "LVST" -5 * 21 00 04 \b4 01 FF \wx00FF +5 * 35 00 04 \b5 01 FF \wx00FF 08 "TEST" 13 18 12 \dx00000002 0C F0 +1E FF \w10 +00 01 02 03 04 05 06 07 +02 05 6 * 11 04 04 FF 01 \wxC4FF "Test" 00 diff --git a/regression/expected/example_station.grf b/regression/expected/example_station.grf index b0aca843275a72f2cbb8e78fffbd9be031b0cdf8..3ab4b1a422c888c6d54bdd65629997a32d1c23e5 100644 GIT binary patch delta 82 zcmcaE_g7Aofx$hDc!lZWB| Xe+C97Aclbk6(9?Q|89cph_Vf}H delta 44 ycmew>cU?}Dfx$h