Skip to content

Commit d367649

Browse files
authored
Fix: Validation and handling of multiple settings in one parameter (#382)
1 parent 900dab2 commit d367649

File tree

5 files changed

+56
-8
lines changed

5 files changed

+56
-8
lines changed

nml/actions/action14.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,9 @@ def param_desc_actions(root, params):
278278
setting_node.subnodes.append(value_names_node)
279279
else:
280280
assert setting.type == "bool"
281+
assert setting.bit_num is not None
281282
setting_node.subnodes.append(BinaryNode("TYPE", 1, 1))
282-
bit = setting.bit_num.value if setting.bit_num is not None else 0
283-
setting_node.subnodes.append(SettingMaskNode(param_num, bit, 1))
283+
setting_node.subnodes.append(SettingMaskNode(param_num, setting.bit_num.value, 1))
284284
if setting.def_val is not None:
285285
setting_node.subnodes.append(BinaryNode("DFLT", 4, setting.def_val.value))
286286
param_root.subnodes.append(setting_node)

nml/ast/grf.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ def set_property(self, name, value):
305305

306306

307307
class ParameterDescription:
308+
free_bits = {}
309+
308310
def __init__(self, setting_list, num=None, pos=None):
309311
self.setting_list = setting_list
310312
self.num = num
@@ -330,15 +332,31 @@ def pre_process(self, num):
330332
if self.num is None:
331333
self.num = num
332334
self.num = self.num.reduce_constant()
335+
if self.num.value not in ParameterDescription.free_bits:
336+
ParameterDescription.free_bits[self.num.value] = list(range(0, 32))
333337
for setting in self.setting_list:
334338
setting.pre_process()
335339
for setting in self.setting_list:
336340
if setting.type == "int":
337-
if len(self.setting_list) > 1:
341+
if len(self.setting_list) > 1 or len(ParameterDescription.free_bits[self.num.value]) != 32:
338342
raise generic.ScriptError(
339-
"When packing multiple settings in one parameter only bool settings are allowed", self.pos
343+
"When packing multiple settings in one parameter only bool settings are allowed",
344+
setting.name.pos,
340345
)
341346
global_constants.settings[setting.name.value] = {"num": self.num.value, "size": 4}
347+
ParameterDescription.free_bits[self.num.value].clear()
342348
else:
343-
bit = 0 if setting.bit_num is None else setting.bit_num.value
344-
global_constants.misc_grf_bits[setting.name.value] = {"param": self.num.value, "bit": bit}
349+
if setting.bit_num is None:
350+
if len(ParameterDescription.free_bits[self.num.value]) == 0:
351+
raise generic.ScriptError("No bits available for this parameter", setting.name.pos)
352+
setting.bit_num = expression.ConstantNumeric(ParameterDescription.free_bits[self.num.value].pop(0))
353+
else:
354+
if setting.bit_num.value not in ParameterDescription.free_bits[self.num.value]:
355+
raise generic.ScriptError(
356+
"Bit {} is already used".format(setting.bit_num.value), setting.name.pos
357+
)
358+
ParameterDescription.free_bits[self.num.value].remove(setting.bit_num.value)
359+
global_constants.misc_grf_bits[setting.name.value] = {
360+
"param": self.num.value,
361+
"bit": setting.bit_num.value,
362+
}

regression/021_grf_parameter.nml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ grf {
3939
};
4040
}
4141
}
42+
param (2) {
43+
param_NoGrid {
44+
type: bool;
45+
name: string(STR_PARAM_NOGRID);
46+
desc: string(STR_PARAM_NOGRID_DESC);
47+
def_value: 1;
48+
}
49+
}
50+
param (2) {
51+
transmitter2rock {
52+
type: bool;
53+
name: string(STR_PARAM_TRANSMITTER);
54+
desc: string(STR_PARAM_TRANSMITTER_DESC);
55+
def_value: 0;
56+
}
57+
}
4258
}
4359

4460
param[10] = param_landscape;
437 Bytes
Binary file not shown.

regression/expected/021_grf_parameter.nfo

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
0 * 4 \d3
99

10-
1 * 817 14 "C" "INFO"
10+
1 * 1254 14 "C" "INFO"
1111
"B" "VRSN" \w4 \dx00000001
1212
"B" "MINV" \w4 \dx00000000
13-
"B" "NPAR" \w1 03
13+
"B" "NPAR" \w1 05
1414
"C" "PARA"
1515
"C" \d0
1616
"T" "NAME" 7F "Disable gridlines" 00
@@ -41,6 +41,20 @@
4141
00
4242
"B" "DFLT" \w4 \dx00000000
4343
00
44+
"C" \d3
45+
"T" "NAME" 7F "Disable gridlines" 00
46+
"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
47+
"B" "TYPE" \w1 01
48+
"B" "MASK" \w3 \b2 \b0 \b1
49+
"B" "DFLT" \w4 \dx00000001
50+
00
51+
"C" \d4
52+
"T" "NAME" 7F "Replace the transmitter tower by a rock" 00
53+
"T" "DESC" 7F "Enable to replace the transmitter tower by a rock (useful for early scenarios without telecomunication towers)" 00
54+
"B" "TYPE" \w1 01
55+
"B" "MASK" \w3 \b2 \b1 \b1
56+
"B" "DFLT" \w4 \dx00000000
57+
00
4458
00
4559
"B" "PALS" \w1 "A"
4660
"B" "BLTR" \w1 "8"

0 commit comments

Comments
 (0)