From 89e8267967d2c8cdb834966f9c2c10705f8de111 Mon Sep 17 00:00:00 2001 From: glx22 Date: Mon, 22 Nov 2021 01:52:07 +0100 Subject: [PATCH] Add: allow more non static spritesets --- examples/station/example_station.nml | 4 +- nml/actions/action2layout.py | 58 +++++++++++++++++----------- nml/actions/action3.py | 12 +++++- nml/actions/action3_callbacks.py | 1 + regression/040_station.nml | 2 +- 5 files changed, 50 insertions(+), 27 deletions(-) diff --git a/examples/station/example_station.nml b/examples/station/example_station.nml index 553ef49e..b6d08fb8 100644 --- a/examples/station/example_station.nml +++ b/examples/station/example_station.nml @@ -65,7 +65,7 @@ spritelayout cow_pen_X(a) { sprite: 2022 + a; // prevent railtype offset } building { - sprite: SPRITESET(0); // first sprite in active spriteset + sprite: DEFAULT(0); // first sprite in active spriteset zextent: 36; recolour_mode: RECOLOUR_REMAP; palette: PALETTE_USE_DEFAULT; @@ -77,7 +77,7 @@ spritelayout cow_pen_Y(a) { sprite: 2022 + a; // prevent railtype offset } building { - sprite: SPRITESET(1); // second sprite in active spriteset + sprite: DEFAULT(1); // second sprite in active spriteset zextent: 36; recolour_mode: RECOLOUR_REMAP; palette: PALETTE_USE_DEFAULT; diff --git a/nml/actions/action2layout.py b/nml/actions/action2layout.py index 8f338f35..b0649863 100644 --- a/nml/actions/action2layout.py +++ b/nml/actions/action2layout.py @@ -632,51 +632,63 @@ def __init__(self): self.spritesets = {} self.var10 = 1 # Reserving 0 for SPRITESET() (basic action2) - def is_empty(self): - return self.var10 == 1 - def translate(self, spriteset, args, pos): if spriteset not in self.spritesets: if self.var10 == 8: raise generic.ScriptError("A station can't use more than 6 different sprite sets", pos) self.spritesets[spriteset] = self.var10 self.var10 += 1 if self.var10 != 1 else 2 # Reserving 2 for custom foundations - return StationSpriteset(spriteset, args, self.spritesets[spriteset], pos) - - def append_mapping(self, mapping, feature, actions, default): - for spriteset in self.spritesets: - if not spriteset.has_action2(feature): - actions.extend(action1.add_to_action1([spriteset], feature, None)) - real_action2 = action2real.make_simple_real_action2( - feature, - spriteset.name.value + " - feature {:02X}".format(feature), - None, - action1.get_action1_index(spriteset), - ) - actions.append(real_action2) - spriteset.set_action2(real_action2, feature) - ref = expression.SpriteGroupRef(spriteset.name, [], None, spriteset.get_action2(feature)) + return StationSpriteset( + None if isinstance(spriteset, int) else spriteset, args, self.spritesets[spriteset], pos + ) + + def append_mapping(self, mapping, feature, actions, default, custom_spritesets): + for spriteset, var10 in self.spritesets.items(): + if not isinstance(spriteset, int): + if not spriteset.has_action2(feature): + actions.extend(action1.add_to_action1([spriteset], feature, None)) + real_action2 = action2real.make_simple_real_action2( + feature, + spriteset.name.value + " - feature {:02X}".format(feature), + None, + action1.get_action1_index(spriteset), + ) + actions.append(real_action2) + spriteset.set_action2(real_action2, feature) + ref = expression.SpriteGroupRef(spriteset.name, [], None, spriteset.get_action2(feature)) + else: + if spriteset > len(custom_spritesets): + raise generic.ScriptError("Index out of range") + ref = custom_spritesets[spriteset] # Skip default result if ref == default: continue - mapping[self.spritesets[spriteset]] = (ref, None) + mapping[var10] = (ref, None) return mapping def parse_station_layouts(feature, id, layouts): - # Add SPRITESET() to reference active spriteset, selected by basic action2 + var10map = StationSpritesetVar10Map() + + # Add DEFAULT([offset]) to reference active spriteset, selected by basic action2 + # and CUSTOM(index, [offset]) to reference a spriteset from the custom list def parse_spriteset(name, args, pos, info): - return StationSpriteset(None, args, None, pos) + if info: + if len(args) < 1: + raise generic.ScriptError("'{}' expects 1 or 2 parameters".format(name), pos) + if not isinstance(args[0], expression.ConstantNumeric): + raise generic.ScriptError("First parameter for '{}' must be a constant".format(name), pos) + return var10map.translate(args[0].value, args[1:], pos) + return StationSpriteset(None, args, info, pos) default_param = [ ( - {"SPRITESET": None}, + {"DEFAULT": None, "CUSTOM": True}, lambda name, value, pos: expression.FunctionPtr(expression.Identifier(name, pos), parse_spriteset, value), ) ] actions = [] - var10map = StationSpritesetVar10Map() param_registers = [] parsed_layouts = [] varact2parser = action2var.Varaction2Parser(feature) diff --git a/nml/actions/action3.py b/nml/actions/action3.py index 48072669..fd04ca6d 100644 --- a/nml/actions/action3.py +++ b/nml/actions/action3.py @@ -307,6 +307,7 @@ def parse_graphics_block_single_id( callbacks = [] livery_override = None # Used for rotor graphics layouts = [] + custom_spritesets = [] prepare_layout = None purchase_prepare_layout = None foundations = None @@ -362,6 +363,15 @@ def parse_graphics_block_single_id( ) prepend_action_list.extend(actions) station_sprite_layouts[id.value] = layouts + elif info["type"] == "custom_spritesets": + if ( + not isinstance(graphics.result.value, expression.Array) + or len(graphics.result.value.values) > 6 + ): + raise generic.ScriptError( + "'{}' must be an array of at most 6 elements".format(cb_name), cargo_id.pos + ) + custom_spritesets = graphics.result.value.values elif info["type"] == "prepare_layout": if "purchase" in info: assert purchase_prepare_layout is None @@ -431,7 +441,7 @@ def parse_graphics_block_single_id( # Fill var10 dependant choices mapping = {0x02: (foundations, None)} if foundations else {} if var10map: - var10map.append_mapping(mapping, feature, prepend_action_list, default) + var10map.append_mapping(mapping, feature, prepend_action_list, default, custom_spritesets) # No need for in-between varaction2 if there are no registers to set and no var10 dependant choices if len(mapping) == 0: if not varact2parser.var_list: diff --git a/nml/actions/action3_callbacks.py b/nml/actions/action3_callbacks.py index f16fb829..75f4f7b5 100644 --- a/nml/actions/action3_callbacks.py +++ b/nml/actions/action3_callbacks.py @@ -148,6 +148,7 @@ def vehicle_length(value): 'prepare_layout' : {'type': 'prepare_layout'}, 'purchase_prepare_layout' : {'type': 'prepare_layout', 'purchase': 2}, 'foundations' : {'type': 'foundations'}, + 'custom_spritesets' : {'type': 'custom_spritesets'}, 'default' : {'type': 'cargo', 'num': None}, 'purchase' : {'type': 'cargo', 'num': 0xFF}, } diff --git a/regression/040_station.nml b/regression/040_station.nml index ca120c28..073e7152 100644 --- a/regression/040_station.nml +++ b/regression/040_station.nml @@ -31,7 +31,7 @@ spritelayout station_sprite_layout_0 { palette: PALETTE_USE_DEFAULT; } childsprite { - sprite: SPRITESET(0); + sprite: DEFAULT(0); xoffset: 17; yoffset: 11; recolour_mode: RECOLOUR_REMAP;