From f1d73af1ec6110ebc80e30336d918694684e0e50 Mon Sep 17 00:00:00 2001 From: frosch Date: Tue, 8 Dec 2020 21:44:15 +0100 Subject: [PATCH] Fix: expressions in random_switch cases should use the parent/self-scope of the random_switch. Regular switches already behaved this way. For random_switches with BACKWARD/FORWARD-scope there is no sane behavior, but these scopes are pretty useless anyway. --- nml/actions/action2random.py | 9 +- nml/ast/switch.py | 9 +- regression/035_switch_scope.nml | 40 +++++++ regression/expected/035_switch_scope.grf | Bin 0 -> 706 bytes regression/expected/035_switch_scope.nfo | 144 +++++++++++++++++++++++ 5 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 regression/035_switch_scope.nml create mode 100644 regression/expected/035_switch_scope.grf create mode 100644 regression/expected/035_switch_scope.nfo diff --git a/nml/actions/action2random.py b/nml/actions/action2random.py index 7c942323..35de7f37 100644 --- a/nml/actions/action2random.py +++ b/nml/actions/action2random.py @@ -334,7 +334,14 @@ def parse_randomswitch(random_switch): for choice in random_switch.choices: res_prob = resulting_prob[choice] result, comment = action2var.parse_result( - choice.result.value, action_list, act6, offset, random_action2, None, 0x89, res_prob + choice.result.value, + action_list, + act6, + offset, + random_action2, + None, + 0x8A if type_byte == 0x83 else 0x89, + res_prob, ) offset += res_prob * 2 comment = "({:d}/{:d}) -> ({:d}/{:d}): ".format(choice.probability.value, total_prob, res_prob, nrand) + comment diff --git a/nml/ast/switch.py b/nml/ast/switch.py index 31cf202e..cffe1734 100644 --- a/nml/ast/switch.py +++ b/nml/ast/switch.py @@ -14,7 +14,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.""" from nml import expression, generic, global_constants -from nml.actions import action2, action2random, action2var +from nml.actions import action2, action2random, action2var, action2var_variables from nml.ast import base_statement, general var_ranges = {"SELF": 0x89, "PARENT": 0x8A} @@ -319,8 +319,13 @@ def __init__(self, param_list, choices, pos): self.random_act2 = None # Set during action generation to resolve dependent/independent chains def pre_process(self): + feature = next(iter(self.feature_set)) + # var_feature is really weird for type=BACKWARD/FORWARD. + # Expressions in cases will still refer to the origin vehicle. + var_feature = action2var_variables.varact2parent_scope[feature] if self.type.value == "PARENT" else feature + for choice in self.choices: - choice.reduce_expressions(next(iter(self.feature_set))) + choice.reduce_expressions(var_feature) for dep_list in (self.dependent, self.independent): for i, dep in enumerate(dep_list[:]): diff --git a/regression/035_switch_scope.nml b/regression/035_switch_scope.nml new file mode 100644 index 00000000..766b64af --- /dev/null +++ b/regression/035_switch_scope.nml @@ -0,0 +1,40 @@ +grf { + grfid: "NML\35"; + name: string(STR_REGRESSION_NAME); + desc: string(STR_REGRESSION_DESC); + version: 0; + min_compatible_version: 0; +} + +random_switch(FEAT_INDUSTRYTILES, SELF, random1, bitmask(TRIGGER_INDUSTRYTILE_TILELOOP)) { + 2: relative_x < 2; + 1: relative_y > 5; +} + +switch(FEAT_INDUSTRYTILES, SELF, var1, town_zone) { + 0: relative_x < 2; + default: relative_y > 5; +} + +random_switch(FEAT_INDUSTRYTILES, PARENT, random2, bitmask(TRIGGER_INDUSTRYTILE_TILELOOP)) { + 2: founder_colour1 < 2; + 1: founder_colour2 > 5; +} + +switch(FEAT_INDUSTRYTILES, PARENT, var2, production_level) { + 0: founder_colour1 < 2; + default: founder_colour2 > 5; +} + +item(FEAT_INDUSTRYTILES, coal_mine) { + property { + substitute: 0; + override: 0; + } + graphics { + foundations: random1; + autoslope: random2; + anim_speed: var1; + anim_control: var2; + } +} diff --git a/regression/expected/035_switch_scope.grf b/regression/expected/035_switch_scope.grf new file mode 100644 index 0000000000000000000000000000000000000000..def632dd4c09ba7d219819eb8dc0365b4d40b7ac GIT binary patch literal 706 zcmb7CO-sW-5PeB2Ce95k^1dMVyFy%ak# 2u< 2u> 2/ 2% 2u/ 2u% 2* 2& 2| 2^ 2sto = 2s 2rst = 2r 2psto 2ror = 2rot 2cmp 2ucmp 2<< 2u>> 2>> +// Escapes: 71 70 7= 7! 7< 7> 7G 7g 7gG 7GG 7gg 7c 7C +// 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 \d20 + +1 * 54 14 "C" "INFO" +"B" "VRSN" \w4 \dx00000000 +"B" "MINV" \w4 \dx00000000 +"B" "NPAR" \w1 00 +"B" "PALS" \w1 "A" +"B" "BLTR" \w1 "8" +00 +00 +2 * 52 08 08 "NML\35" "NML regression test" 00 "A test newgrf testing NML" 00 +// Name: @return_action_0 +3 * 34 02 09 FF 89 +43 20 \dx000000FF +\2cmp 1A 20 \dx00000002 +\2< 1A 20 \dx00000001 +\2^ 1A 00 \dx00000001 +\b0 +\wx8000 // Return computed value + +// Name: @return_action_1 +4 * 34 02 09 FE 89 +43 28 \dx000000FF +\2cmp 1A 20 \dx00000005 +\2- 1A 20 \dx00000001 +\2> 1A 00 \dx00000000 +\b0 +\wx8000 // Return computed value + +// Name: random1 +5 * 15 02 09 FE 80 01 \b0 04 +\wx00FF \wx00FF \wx00FF // (2/3) -> (3/4): return (var[0x43, 0, 255] < 2) +\wx00FE // (1/3) -> (1/4): return (var[0x43, 8, 255] > 5) + +// Name: @return_action_0 +6 * 34 02 09 FF 89 +43 20 \dx000000FF +\2cmp 1A 20 \dx00000002 +\2< 1A 20 \dx00000001 +\2^ 1A 00 \dx00000001 +\b0 +\wx8000 // Return computed value + +// Name: @return_action_1 +7 * 34 02 09 FD 89 +43 28 \dx000000FF +\2cmp 1A 20 \dx00000005 +\2- 1A 20 \dx00000001 +\2> 1A 00 \dx00000000 +\b0 +\wx8000 // Return computed value + +// Name: var1 +8 * 23 02 09 FD 89 +42 00 \dx00000007 +\b1 +\wx00FF \dx00000000 \dx00000000 // 0 .. 0: return (var[0x43, 0, 255] < 2) +\wx00FD // default: return (var[0x43, 8, 255] > 5) + +// Name: @return_action_2 +9 * 34 02 09 FF 8A +45 38 \dx0000000F +\2cmp 1A 20 \dx00000002 +\2< 1A 20 \dx00000001 +\2^ 1A 00 \dx00000001 +\b0 +\wx8000 // Return computed value + +// Name: @return_action_3 +10 * 34 02 09 FC 8A +45 3C \dx0000000F +\2cmp 1A 20 \dx00000005 +\2- 1A 20 \dx00000001 +\2> 1A 00 \dx00000000 +\b0 +\wx8000 // Return computed value + +// Name: random2 +11 * 15 02 09 FC 83 01 \b0 04 +\wx00FF \wx00FF \wx00FF // (2/3) -> (3/4): return (var[0x45, 24, 15] < 2) +\wx00FC // (1/3) -> (1/4): return (var[0x45, 28, 15] > 5) + +// Name: @return_action_0 +12 * 34 02 09 FF 8A +45 38 \dx0000000F +\2cmp 1A 20 \dx00000002 +\2< 1A 20 \dx00000001 +\2^ 1A 00 \dx00000001 +\b0 +\wx8000 // Return computed value + +// Name: @return_action_1 +13 * 34 02 09 FB 8A +45 3C \dx0000000F +\2cmp 1A 20 \dx00000005 +\2- 1A 20 \dx00000001 +\2> 1A 00 \dx00000000 +\b0 +\wx8000 // Return computed value + +// Name: var2 +14 * 23 02 09 FB 8A +93 00 \dx000000FF +\b1 +\wx00FF \dx00000000 \dx00000000 // 0 .. 0: return (var[0x45, 24, 15] < 2) +\wx00FB // default: return (var[0x45, 28, 15] > 5) + +15 * 11 00 09 \b2 01 FF \wx0000 +08 00 +09 00 + +16 * 9 00 09 \b1 01 FF \wx0000 +0E 62 + +// Name: @CB_FAILED_LAYOUT09 +17 * 17 02 09 FF \b0 \dx00000000 +\dx00000000 \b0 \b0 \b0 \b0 \b0 +// Name: @CB_FAILED09 +18 * 23 02 09 FF 89 +0C 00 \dx0000FFFF +\b1 +\wx8000 \dx00000000 \dx00000000 // graphics callback -> return 0 +\wx00FF // Non-graphics callback, return graphics result + +// Name: @action3_0 +19 * 53 02 09 FF 89 +0C 00 \dx0000FFFF +\b4 +\wx00FB \dx00000025 \dx00000025 // var2; +\wx00FD \dx00000027 \dx00000027 // var1; +\wx00FE \dx00000030 \dx00000030 // random1; +\wx00FC \dx0000003C \dx0000003C // random2; +\wx00FF // @CB_FAILED09; + +20 * 7 03 09 01 00 \b0 +\wx00FF // @action3_0; +