|
| 1 | +import grf |
| 2 | +from agrf.actions import FakeReferencingAction, FakeReferencedAction |
| 3 | +from agrf.lib.building.registers import code, default_code |
| 4 | +from agrf.lib.building.station_tile_switch import StationTileSwitch |
| 5 | +from agrf.strings import label_printable |
| 6 | +from agrf.utils import unique |
| 7 | + |
| 8 | + |
| 9 | +class AStation(grf.SpriteGenerator): |
| 10 | + def __init__( |
| 11 | + self, |
| 12 | + *, |
| 13 | + id, |
| 14 | + translation_name, |
| 15 | + layouts, |
| 16 | + callbacks=None, |
| 17 | + non_traversable_tiles=0x0, |
| 18 | + is_waypoint=False, |
| 19 | + doc_layout=None, |
| 20 | + enable_if=None, |
| 21 | + make_foundation=False, |
| 22 | + foundation_object=None, |
| 23 | + extra_code="", |
| 24 | + action2_pool=None, |
| 25 | + station_tile_switch_class=None, |
| 26 | + **props, |
| 27 | + ): |
| 28 | + super().__init__() |
| 29 | + self.id = id |
| 30 | + self.translation_name = translation_name |
| 31 | + self.layouts = layouts |
| 32 | + if callbacks is None: |
| 33 | + callbacks = {} |
| 34 | + self.callbacks = grf.make_callback_manager(grf.STATION, callbacks) |
| 35 | + self.is_waypoint = is_waypoint |
| 36 | + self.doc_layout = doc_layout |
| 37 | + self.enable_if = enable_if |
| 38 | + self.make_foundation = make_foundation |
| 39 | + self.foundation_object = foundation_object |
| 40 | + self.extra_code = extra_code |
| 41 | + self.action2_pool = action2_pool |
| 42 | + self._station_tile_switch_class = station_tile_switch_class |
| 43 | + self._props = { |
| 44 | + **props, |
| 45 | + "non_traversable_tiles": non_traversable_tiles, |
| 46 | + "draw_pylon_tiles": 0xFF ^ non_traversable_tiles, |
| 47 | + "hide_wire_tiles": non_traversable_tiles, |
| 48 | + } |
| 49 | + |
| 50 | + @property |
| 51 | + def class_label_plain(self): |
| 52 | + return label_printable(self._props["class_label"]) |
| 53 | + |
| 54 | + def _is_station_tile_switch(self, obj): |
| 55 | + return self._station_tile_switch_class is not None and isinstance(obj, self._station_tile_switch_class) |
| 56 | + |
| 57 | + def _map_foundation(self, obj): |
| 58 | + if self._is_station_tile_switch(obj): |
| 59 | + return obj.to_index(None) |
| 60 | + return obj |
| 61 | + |
| 62 | + def get_sprites(self, g, sprites=None): |
| 63 | + is_managed_by_metastation = sprites is not None |
| 64 | + if isinstance(self.translation_name, str): |
| 65 | + translated_name = g.strings[f"STR_STATION_{self.translation_name}"] |
| 66 | + elif callable(self.translation_name): |
| 67 | + translated_name = self.translation_name(g.strings) |
| 68 | + else: |
| 69 | + raise TypeError(f"translation_name must be a string or callable, got {type(self.translation_name)}") |
| 70 | + |
| 71 | + extra_props = {"station_name": g.strings.add(translated_name).get_persistent_id()} |
| 72 | + if not self.is_waypoint: |
| 73 | + extra_props["station_class_name"] = g.strings.add( |
| 74 | + g.strings[f"STR_STATION_CLASS_{self.class_label_plain}"] |
| 75 | + ).get_persistent_id() |
| 76 | + |
| 77 | + res = [] |
| 78 | + |
| 79 | + if self.action2_pool is not None: |
| 80 | + graphics = self.action2_pool.get_action_2_zero() |
| 81 | + else: |
| 82 | + graphics = grf.GenericSpriteLayout(ent1=[0], ent2=[0], feature=grf.STATION) |
| 83 | + |
| 84 | + props = self._props.copy() |
| 85 | + |
| 86 | + use_foundation = self.make_foundation or self.foundation_object is not None |
| 87 | + |
| 88 | + if use_foundation and self.action2_pool is not None: |
| 89 | + if self.make_foundation: |
| 90 | + cb14 = self.callbacks.select_sprite_layout.default |
| 91 | + self.callbacks.select_sprite_layout.default = cb14.to_index(self.layouts) |
| 92 | + foundations = self.action2_pool.map_switch(cb14) |
| 93 | + foundations = self._map_foundation(foundations) |
| 94 | + else: # foundation_object |
| 95 | + if self.foundation_object is self.foundation_object.M: |
| 96 | + foundation_object_list = [self.foundation_object] |
| 97 | + else: |
| 98 | + foundation_object_list = [self.foundation_object, self.foundation_object.M] |
| 99 | + |
| 100 | + foundation_list = [ |
| 101 | + self.action2_pool.map_foundation_switch(x.to_switch()) for x in foundation_object_list |
| 102 | + ] |
| 103 | + foundation_list = [self._map_foundation(x) for x in foundation_list] |
| 104 | + |
| 105 | + if len(foundation_list) == 1: |
| 106 | + foundations = foundation_list[0] |
| 107 | + else: |
| 108 | + foundations = grf.Switch( |
| 109 | + ranges={1: foundation_list[1]}, code="extra_callback_info2 % 2", default=foundation_list[0] |
| 110 | + ) |
| 111 | + |
| 112 | + self.callbacks.graphics = grf.GraphicsCallback( |
| 113 | + default=grf.Switch( |
| 114 | + ranges={2: foundations}, |
| 115 | + code=code + self.extra_code + default_code + "\nextra_callback_info1_byte", |
| 116 | + default=graphics, |
| 117 | + ), |
| 118 | + purchase=grf.Switch(ranges={0: graphics}, code=code + self.extra_code, default=graphics), |
| 119 | + ) |
| 120 | + props["general_flags"] = props.get("general_flags", 0) | 0b1000 |
| 121 | + else: |
| 122 | + self.callbacks.graphics = grf.Switch( |
| 123 | + ranges={0: graphics}, code=code + self.extra_code + default_code, default=graphics |
| 124 | + ) |
| 125 | + |
| 126 | + cb_props = {} |
| 127 | + self.callbacks.set_flag_props(cb_props) |
| 128 | + |
| 129 | + if not is_managed_by_metastation: |
| 130 | + sprites = self.sprites |
| 131 | + res.append(grf.Action1(feature=grf.STATION, set_count=1, sprite_count=len(self.sprites))) |
| 132 | + |
| 133 | + for s in self.sprites: |
| 134 | + res.append(s) |
| 135 | + |
| 136 | + if self.id >= 0xFF: |
| 137 | + res.append(grf.If(is_static=False, variable=0xA1, condition=0x04, value=0x1E000000, skip=255, varsize=4)) |
| 138 | + if self.enable_if: |
| 139 | + for cond in self.enable_if: |
| 140 | + res.append(cond.make_if(is_static=False, skip=255)) |
| 141 | + res.append( |
| 142 | + definition := grf.Define( |
| 143 | + feature=grf.STATION, |
| 144 | + id=self.id, |
| 145 | + props={ |
| 146 | + "class_label": (b"WAYP" if self.is_waypoint else props["class_label"]), |
| 147 | + "advanced_layout": grf.SpriteLayoutList([l.to_grf(sprites) for l in self.layouts]), |
| 148 | + **{k: v for k, v in props.items() if k != "class_label"}, |
| 149 | + **cb_props, |
| 150 | + **(extra_props if self.id >= 0xFF else {}), |
| 151 | + }, |
| 152 | + ) |
| 153 | + ) |
| 154 | + if self.id >= 0xFF or self.enable_if: |
| 155 | + res.append(grf.Label(255, bytes())) |
| 156 | + |
| 157 | + if self.is_waypoint: |
| 158 | + openttd_15_props = { |
| 159 | + "class_label": b"\xff" + self._props["class_label"][1:], |
| 160 | + "station_class_name": g.strings.add( |
| 161 | + g.strings[f"STR_STATION_CLASS_{self.class_label_plain}"] |
| 162 | + ).get_persistent_id(), |
| 163 | + } |
| 164 | + res.append(grf.If(is_static=False, variable=0xA1, condition=0x04, value=0x1F000000, skip=1, varsize=4)) |
| 165 | + res.append(grf.Define(feature=grf.STATION, id=self.id, props=openttd_15_props)) |
| 166 | + |
| 167 | + [map_action] = self.callbacks.make_map_action(definition) |
| 168 | + if self.id >= 0xFF: |
| 169 | + if_action = FakeReferencedAction( |
| 170 | + grf.If(is_static=False, variable=0xA1, condition=0x04, value=0x1E000000, skip=1, varsize=4), grf.STATION |
| 171 | + ) |
| 172 | + map_action = FakeReferencingAction(map_action, [if_action]) |
| 173 | + res.append(map_action) |
| 174 | + |
| 175 | + if self.id < 0xFF: |
| 176 | + class_name = g.strings[f"STR_STATION_CLASS_{self.class_label_plain}"] |
| 177 | + res.extend(class_name.get_actions(grf.STATION, 0xC400 + self.id, is_generic_offset=True)) |
| 178 | + res.extend(translated_name.get_actions(grf.STATION, 0xC500 + self.id, is_generic_offset=True)) |
| 179 | + |
| 180 | + return res |
| 181 | + |
| 182 | + @property |
| 183 | + def sprites(self): |
| 184 | + return unique(sub for l in self.layouts for sub in l.sprites) |
0 commit comments