Skip to content

Commit

Permalink
Add: Support for station property 1E
Browse files Browse the repository at this point in the history
  • Loading branch information
glx22 committed Aug 7, 2024
1 parent 3739dd4 commit 3327be3
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 22 deletions.
8 changes: 5 additions & 3 deletions examples/station/example_station.nml
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
53 changes: 41 additions & 12 deletions nml/actions/action0properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import itertools

from nml import generic, nmlop
from nml import generic, nmlop, global_constants
from nml.expression import (
AcceptCargo,
Array,
Expand Down Expand Up @@ -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()
Expand All @@ -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):
Expand All @@ -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):
Expand Down Expand Up @@ -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},
Expand All @@ -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},
Expand All @@ -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

Expand Down
5 changes: 5 additions & 0 deletions nml/global_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
13 changes: 12 additions & 1 deletion regression/040_station.nml
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Binary file modified regression/expected/040_station.grf
Binary file not shown.
5 changes: 4 additions & 1 deletion regression/expected/040_station.nfo
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Binary file modified regression/expected/example_station.grf
Binary file not shown.
18 changes: 13 additions & 5 deletions regression/expected/example_station.nfo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Escapes: D= = DR D+ = DF D- = DC Du* = DM D* = DnF Du<< = DnC D<< = DO D& D| Du/ D/ Du% D%
// Format: spritenum imagefile depth xpos ypos xsize ysize xrel yrel zoom flags

0 * 4 \d29
0 * 4 \d30

1 * 54 14 "C" "INFO"
"B" "VRSN" \w4 \dx00000001
Expand Down Expand Up @@ -62,8 +62,8 @@
08 "NML_"
10 \wx00A0
11 00
14 FF
15 FF
14 03
15 03

20 * 18 04 04 FF 01 \wxC400 "NML Example" 00

Expand Down Expand Up @@ -131,8 +131,16 @@
\wx00FF \dx00000000 \dx00000000 // cow_pen_half;
\wx00FF // cow_pen_half;

29 * 13 03 04 01 00 \b2
// Name: @action3_3
29 * 33 02 04 FF 89
0C 00 \dx0000FFFF
\b2
\wx00FF \dx00000000 \dx00000000 // @action3_2;
\wx8000 \dx00000024 \dx00000024 // return 0;
\wx00FD // @action3_0;

30 * 13 03 04 01 00 \b2
00 \wx00FE // @action3_1;
FF \wx00FF // @action3_2;
FF \wx00FF // @action3_3;
\wx00FD // @action3_0;

0 comments on commit 3327be3

Please sign in to comment.