Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codechange: Reintroduce 0.4 syntax for compatibility #152

Merged
merged 3 commits into from May 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions nml/actions/action0.py
Expand Up @@ -433,12 +433,13 @@ def get_property_info_list(feature, name):
raise generic.ScriptError("Setting properties for feature '{}' is not possible, no properties are defined.".format(general.feature_name(feature)), name.pos)

if isinstance(name, expression.Identifier):
if not name.value in properties[feature]: raise generic.ScriptError("Unknown property name: " + name.value, name.pos)
prop_info_list = properties[feature][name.value]
prop_name = name.value
if prop_name not in properties[feature]:
raise generic.ScriptError("Unknown property name: " + prop_name, name.pos)
prop_info_list = properties[feature][prop_name]
if not isinstance(prop_info_list, list): prop_info_list = [prop_info_list]
elif isinstance(name, expression.ConstantNumeric):
for p in properties[feature]:
prop_info_list = properties[feature][p]
for prop_name, prop_info_list in properties[feature].items():
if not isinstance(prop_info_list, list): prop_info_list = [prop_info_list]
# Only non-compound properties may be set by number
if len(prop_info_list) == 1 and 'num' in prop_info_list[0] and prop_info_list[0]['num'] == name.value:
Expand All @@ -448,6 +449,8 @@ def get_property_info_list(feature, name):
else: assert False

for prop_info in prop_info_list:
if 'replaced_by' in prop_info:
generic.print_warning("'{}' is deprecated, consider using '{}' instead".format(prop_name, prop_info['replaced_by']), name.pos)
if 'warning' in prop_info:
generic.print_warning(prop_info['warning'], name.pos)
return prop_info_list
Expand Down
30 changes: 29 additions & 1 deletion nml/actions/action0properties.py
Expand Up @@ -709,6 +709,15 @@ def industry_layouts(value):
layouts.append(tilelayout_names[name.value])
return [IndustryLayoutProp(layouts)]

def industry_prod_multiplier(value):
if not isinstance(value, Array) or len(value.values) > 2:
raise generic.ScriptError("Prod multiplier must be an array of up to two values", value.pos)
props = []
for i in range(0, 2):
val = value.values[i].reduce_constant() if i < len(value.values) else ConstantNumeric(0)
props.append(Action0Property(0x12 + i, val, 1))
return props

class RandomSoundsProp(BaseAction0Property):
def __init__(self, sound_list):
self.sound_list = sound_list
Expand Down Expand Up @@ -755,6 +764,19 @@ def industry_conflicting_types(value):
types_list.append(ConstantNumeric(0xFF))
return [ConflictingTypesProp(types_list)]

def industry_input_multiplier(value, prop_num):
if not isinstance(value, Array) or len(value.values) > 2:
raise generic.ScriptError("Input multiplier must be an array of up to two values", value.pos)
val1 = value.values[0].reduce() if len(value.values) > 0 else ConstantNumeric(0)
val2 = value.values[1].reduce() if len(value.values) > 1 else ConstantNumeric(0)
if not isinstance(val1, (ConstantNumeric, ConstantFloat)) or not isinstance(val2, (ConstantNumeric, ConstantFloat)):
raise generic.ScriptError("Expected a compile-time constant", value.pos)
generic.check_range(val1.value, 0, 256, "input_multiplier", val1.pos)
generic.check_range(val2.value, 0, 256, "input_multiplier", val2.pos)
mul1 = int(val1.value * 256)
mul2 = int(val2.value * 256)
return [Action0Property(prop_num, ConstantNumeric(mul1 | (mul2 << 16)), 4)]

class IndustryInputMultiplierProp(BaseAction0Property):
def __init__(self, prop_num, data):
self.prop_num = prop_num
Expand Down Expand Up @@ -849,7 +871,9 @@ def check_accept(acp):
'prod_increase_msg' : {'size': 2, 'num': 0x0D, 'string': 0xDC},
'prod_decrease_msg' : {'size': 2, 'num': 0x0E, 'string': 0xDC},
'fund_cost_multiplier' : {'size': 1, 'num': 0x0F},
'cargo_types' : {'custom_function': industry_cargo_types}, # = prop 25+26+27+28 combined in one structure
'prod_cargo_types' : {'size': 2, 'num': 0x10, 'value_function': lambda value: cargo_list(value, 2), 'replaced_by': 'cargo_types'},
'accept_cargo_types' : {'size': 4, 'num': 0x11, 'value_function': lambda value: cargo_list(value, 3), 'replaced_by': 'cargo_types'},
'prod_multiplier' : {'custom_function': industry_prod_multiplier, 'replaced_by': 'cargo_types'}, # = prop 12,13
'min_cargo_distr' : {'size': 1, 'num': 0x14},
'random_sound_effects' : {'custom_function': random_sounds}, # = prop 15
'conflicting_ind_types' : {'custom_function': industry_conflicting_types}, # = prop 16
Expand All @@ -859,11 +883,15 @@ def check_accept(acp):
'map_colour' : {'size': 1, 'num': 0x19},
'spec_flags' : {'size': 4, 'num': 0x1A},
'new_ind_msg' : {'size': 2, 'num': 0x1B, 'string': 0xDC},
'input_multiplier_1' : {'custom_function': lambda value: industry_input_multiplier(value, 0x1C), 'replaced_by': 'cargo_types'},
'input_multiplier_2' : {'custom_function': lambda value: industry_input_multiplier(value, 0x1D), 'replaced_by': 'cargo_types'},
'input_multiplier_3' : {'custom_function': lambda value: industry_input_multiplier(value, 0x1E), 'replaced_by': 'cargo_types'},
'name' : {'size': 2, 'num': 0x1F, 'string': 0xDC},
'prospect_chance' : {'size': 4, 'num': 0x20, 'unit_conversion': 0xFFFFFFFF},
# prop 21, 22 (callback flags) are not set by user
'remove_cost_multiplier' : {'size': 4, 'num': 0x23},
'nearby_station_name' : {'size': 2, 'num': 0x24, 'string': 0xDC},
'cargo_types' : {'custom_function': industry_cargo_types}, # = prop 25+26+27+28 combined in one structure
FLHerne marked this conversation as resolved.
Show resolved Hide resolved
}

#
Expand Down
2 changes: 2 additions & 0 deletions nml/actions/action2var.py
Expand Up @@ -629,6 +629,8 @@ def parse(self, expr):
assert False #supported_by_action2 should have raised the correct error already

def parse_var(name, info, pos):
if 'replaced_by' in info:
generic.print_warning("'{}' is deprecated, consider using '{}' instead".format(name, info['replaced_by']), pos)
param = expression.ConstantNumeric(info['param']) if 'param' in info else None
res = expression.Variable(expression.ConstantNumeric(info['var']), expression.ConstantNumeric(info['start']),
expression.ConstantNumeric((1 << info['size']) - 1), param, pos)
Expand Down
17 changes: 17 additions & 0 deletions nml/actions/action2var_variables.py
Expand Up @@ -498,6 +498,9 @@ def nearest_house_matching_criterion(name, args, pos, info):
#

varact2vars_industries = {
'waiting_cargo_1' : {'var': 0x40, 'start': 0, 'size': 16, 'replaced_by': 'incoming_cargo_waiting'},
'waiting_cargo_2' : {'var': 0x41, 'start': 0, 'size': 16, 'replaced_by': 'incoming_cargo_waiting'},
'waiting_cargo_3' : {'var': 0x42, 'start': 0, 'size': 16, 'replaced_by': 'incoming_cargo_waiting'},
'water_distance' : {'var': 0x43, 'start': 0, 'size': 32},
'layout_num' : {'var': 0x44, 'start': 0, 'size': 8},
# bits 0 .. 16 are either useless or already covered by var A7
Expand All @@ -506,7 +509,21 @@ def nearest_house_matching_criterion(name, args, pos, info):
'founder_colour2' : {'var': 0x45, 'start': 28, 'size': 4},
'build_date' : {'var': 0x46, 'start': 0, 'size': 32},
'random_bits' : {'var': 0x5F, 'start': 8, 'size': 16},
'produced_cargo_waiting_1' : {'var': 0x8A, 'start': 0, 'size': 16, 'replaced_by': 'produced_cargo_waiting'},
'produced_cargo_waiting_2' : {'var': 0x8C, 'start': 0, 'size': 16, 'replaced_by': 'produced_cargo_waiting'},
'production_rate_1' : {'var': 0x8E, 'start': 0, 'size': 8, 'replaced_by': 'production_rate'},
'production_rate_2' : {'var': 0x8F, 'start': 0, 'size': 8, 'replaced_by': 'production_rate'},
'production_level' : {'var': 0x93, 'start': 0, 'size': 8},
'produced_this_month_1' : {'var': 0x94, 'start': 0, 'size': 16, 'replaced_by': 'this_month_production'},
'produced_this_month_2' : {'var': 0x96, 'start': 0, 'size': 16, 'replaced_by': 'this_month_production'},
'transported_this_month_1' : {'var': 0x98, 'start': 0, 'size': 16, 'replaced_by': 'this_month_transported'},
'transported_this_month_2' : {'var': 0x9A, 'start': 0, 'size': 16, 'replaced_by': 'this_month_transported'},
'transported_last_month_pct_1' : {'var': 0x9C, 'start': 0, 'size': 8, 'value_function': value_mul_div(101, 256), 'replaced_by': 'transported_last_month_pct'},
'transported_last_month_pct_2' : {'var': 0x9D, 'start': 0, 'size': 8, 'value_function': value_mul_div(101, 256), 'replaced_by': 'transported_last_month_pct'},
'produced_last_month_1' : {'var': 0x9E, 'start': 0, 'size': 16, 'replaced_by': 'last_month_production'},
'produced_last_month_2' : {'var': 0xA0, 'start': 0, 'size': 16, 'replaced_by': 'last_month_production'},
'transported_last_month_1' : {'var': 0xA2, 'start': 0, 'size': 16, 'replaced_by': 'last_month_transported'},
'transported_last_month_2' : {'var': 0xA4, 'start': 0, 'size': 16, 'replaced_by': 'last_month_transported'},
'founder' : {'var': 0xA7, 'start': 0, 'size': 8},
'colour' : {'var': 0xA8, 'start': 0, 'size': 8},
'counter' : {'var': 0xAA, 'start': 0, 'size': 16},
Expand Down
50 changes: 50 additions & 0 deletions nml/ast/produce.py
Expand Up @@ -19,6 +19,56 @@

produce_base_class = action2.make_sprite_group_class(False, True, True)

class ProduceOld(produce_base_class):
"""
AST node for a 'produce'-block, which is basically equivalent to the production callback.
Syntax: produce(name, sub1, sub2, sub3, add1, add2[, again])
@ivar param_list: List of parameters supplied to the produce-block.
- 0..2: Amounts of cargo to subtract from input
- 3..4: Amounts of cargo to add to output
- 5: Run the production CB again if nonzero
@type param_list: C{list} of L{Expression}
"""
def __init__(self, param_list, pos):
base_statement.BaseStatement.__init__(self, "produce-block", pos, False, False)
if not (6 <= len(param_list) <= 7):
raise generic.ScriptError("produce-block requires 6 or 7 parameters, encountered {:d}".format(len(param_list)), self.pos)
name = param_list[0]
if not isinstance(name, expression.Identifier):
raise generic.ScriptError("produce parameter 1 'name' should be an identifier.", name.pos)
self.initialize(name, 0x0A)
self.param_list = param_list[1:]
if len(self.param_list) < 6:
self.param_list.append(expression.ConstantNumeric(0))

def pre_process(self):
generic.print_warning("Consider using the new produce() syntax for '{}'".format(self.name), self.name.pos)
for i, param in enumerate(self.param_list):
self.param_list[i] = action2var.reduce_varaction2_expr(param, 0x0A)
produce_base_class.pre_process(self)

def collect_references(self):
return []

def __str__(self):
return 'produce({});\n'.format(', '.join(str(x) for x in [self.name] + self.param_list))

def debug_print(self, indentation):
generic.print_dbg(indentation, 'Produce, name =', self.name)
generic.print_dbg(indentation + 2, 'Subtract from input:')
for expr in self.param_list[0:3]:
expr.debug_print(indentation + 4)
generic.print_dbg(indentation + 2, 'Add to output:')
for expr in self.param_list[3:5]:
expr.debug_print(indentation + 4)
generic.print_dbg(indentation + 2, 'Again:')
self.param_list[5].debug_print(indentation + 4)

def get_action_list(self):
if self.prepare_act2_output():
return action2production.get_production_actions(self)
return []

class Produce(produce_base_class):
"""
AST node for a 'produce'-block for version 2 industry production callback.
Expand Down
7 changes: 5 additions & 2 deletions nml/parser.py
Expand Up @@ -458,9 +458,12 @@ def p_produce_cargo_list(self, t):
else: t[0] = t[2]

def p_produce(self, t):
'''produce : PRODUCE LPAREN ID COMMA produce_cargo_list COMMA produce_cargo_list COMMA expression RPAREN
'''produce : PRODUCE LPAREN ID COMMA expression_list RPAREN SEMICOLON
| PRODUCE LPAREN ID COMMA produce_cargo_list COMMA produce_cargo_list COMMA expression RPAREN
| PRODUCE LPAREN ID COMMA produce_cargo_list COMMA produce_cargo_list RPAREN'''
if len(t) == 11:
if len(t) == 8:
t[0] = produce.ProduceOld([t[3]] + t[5], t.lineno(1))
elif len(t) == 11:
t[0] = produce.Produce(t[3], t[5], t[7], t[9], t.lineno(1))
else:
t[0] = produce.Produce(t[3], t[5], t[7], expression.ConstantNumeric(0), t.lineno(1))
Expand Down