Exemplo n.º 1
0
def get_callback_flags_actions(feature, id, flags):
    """
    Get a list of actions to set the callback flags of a certain item

    @param feature: Feature of the item
    @type feature: C{int}

    @param id: ID of the item
    @type id: L{Expression}

    @param flags: Value of the 'callback_flags' property
    @type flags: C{int}

    @return: A list of actions
    @rtype: C{list} of L{BaseAction}
    """
    assert isinstance(id, expression.ConstantNumeric)
    act0, offset = create_action0(feature, id, None, None)
    act0.num_ids = 1
    assert feature in callback_flag_properties

    prop_info_list = callback_flag_properties[feature]
    if not isinstance(prop_info_list, list): prop_info_list = [prop_info_list]
    for prop_info in prop_info_list:
        act0.prop_list.append(
            Action0Property(
                prop_info['num'],
                parse_property_value(prop_info,
                                     expression.ConstantNumeric(flags)),
                prop_info['size']))

    return [act0]
Exemplo n.º 2
0
def get_disable_actions(disable):
    """
    Get the action list for a disable_item block

    @param disable: Disable block
    @type disable: L{DisableItem}

    @return: A list of resulting actions
    @rtype: C{list} of L{BaseAction}
    """
    feature = disable.feature.value
    if feature not in disable_info:
        raise generic.ScriptError("disable_item() is not available for feature {:d}.".format(feature), disable.pos)
    if disable.first_id is None:
        # No ids set -> disable all
        assert disable.last_id is None
        first = 0
        num = disable_info[feature]["num"]
    else:
        first = disable.first_id.value
        if disable.last_id is None:
            num = 1
        else:
            num = disable.last_id.value - first + 1

    act0 = Action0(feature, first)
    act0.num_ids = num
    for prop in disable_info[feature]["props"]:
        act0.prop_list.append(
            Action0Property(prop["num"], num * [expression.ConstantNumeric(prop["value"])], prop["size"])
        )

    return [act0]
Exemplo n.º 3
0
def get_volume_actions(volume_list):
    """
    Get a list of actions to set sound volumes

    @param volume_list: List of (sound id, volume) tuples, sorted in ascending order
    @type volume_list: C{list} of (C{int}, C{int})-tuples

    @return: A list of actions
    @rtype: C{list} of L{BaseAction}
    """
    action_list = []
    first_id = None  # First ID in a series of consecutive IDs
    value_series = []  # Series of values to write in a single action

    for id, volume in volume_list:
        if first_id is None:
            first_id = id
        continue_series = first_id + len(value_series) == id
        if continue_series:
            value_series.append(volume)

        if not continue_series or id == volume_list[-1][0]:
            # Write action for this series
            act0, offset = create_action0(0x0C, expression.ConstantNumeric(first_id), None, None)
            act0.num_ids = len(value_series)
            act0.prop_list.append(Action0Property(0x08, [expression.ConstantNumeric(v) for v in value_series], 1))
            action_list.append(act0)

            # start new series, if needed
            if not continue_series:
                first_id = id
                value_series = [volume]

    return action_list
Exemplo n.º 4
0
Arquivo: action0.py Projeto: spnda/nml
def get_basecost_action(basecost):
    action6.free_parameters.save()
    action_list = []
    tmp_param_map = {}  # Cache for tmp parameters

    # We want to avoid writing lots of action0s if possible
    i = 0
    while i < len(basecost.costs):
        cost = basecost.costs[i]
        act6 = action6.Action6()

        act0, offset = create_action0(0x08, cost.name, act6, action_list)
        first_id = cost.name.value if isinstance(
            cost.name, expression.ConstantNumeric) else None

        num_ids = 1  # Number of values that will be written in one go
        values = []
        # try to capture as much values as possible
        while True:
            cost = basecost.costs[i]
            if isinstance(cost.value, expression.ConstantNumeric):
                values.append(cost.value)
            else:
                # Cache lookup, saves some ActionDs
                if cost.value in tmp_param_map:
                    tmp_param, tmp_param_actions = tmp_param_map[
                        cost.value], []
                else:
                    tmp_param, tmp_param_actions = actionD.get_tmp_parameter(
                        cost.value)
                    tmp_param_map[cost.value] = tmp_param
                act6.modify_bytes(tmp_param, 1, offset + num_ids)
                action_list.extend(tmp_param_actions)
                values.append(expression.ConstantNumeric(0))

            # check if we can append the next to this one (it has to be consecutively numbered)
            if first_id is not None and (i + 1) < len(basecost.costs):
                nextcost = basecost.costs[i + 1]
                if isinstance(nextcost.name, expression.ConstantNumeric
                              ) and nextcost.name.value == first_id + num_ids:
                    num_ids += 1
                    i += 1
                    # Yes We Can, continue the loop to append this value to the list and try further
                    continue
            # No match, so stop it and write an action0
            break

        act0.prop_list.append(Action0Property(0x08, values, 1))
        act0.num_ids = num_ids
        if len(act6.modifications) > 0:
            action_list.append(act6)
        action_list.append(act0)
        i += 1
    action6.free_parameters.restore()
    return action_list
Exemplo n.º 5
0
def get_language_translation_tables(lang):
    action0 = Action0(0x08, lang.langid)
    if lang.genders is not None:
        action0.prop_list.append(LanguageTranslationTable(0x13, lang.genders, lang.gender_map))
    if lang.cases is not None:
        action0.prop_list.append(LanguageTranslationTable(0x14, lang.cases, lang.case_map))
    if lang.plural is not None:
        action0.prop_list.append(Action0Property(0x15, expression.ConstantNumeric(lang.plural), 1))
    if len(action0.prop_list) > 0:
        return [action0]
    return []
Exemplo n.º 6
0
def parse_sort_block(feature, vehid_list):
    prop_num = [0x1A, 0x20, 0x1B, 0x1B]
    action_list = []
    if len(vehid_list) >= 2:
        last = vehid_list[0]
        idx = len(vehid_list) - 1
        while idx >= 0:
            cur = vehid_list[idx]
            prop = Action0Property(prop_num[feature], [last], 3)
            action_list.append(Action0(feature, cur.value))
            action_list[-1].prop_list.append(prop)
            last = cur
            idx -= 1
    return action_list
Exemplo n.º 7
0
def parse_property(prop_info, value_list, feature, id):
    """
    Parse a single property

    @param prop_info: A dictionary with property information
    @type prop_info: C{dict}

    @param value_list: List of values for the property, with unit conversion applied
    @type value_list: C{list} of L{Expression}

    @param feature: Feature of the associated item
    @type feature: C{int}

    @param id: ID of the associated item
    @type id: L{Expression}

    @return: A tuple containing the following:
                - List of properties to add to the action 0
                - List of actions to prepend
                - List of modifications to apply via action 6
                - List of actions to append
    @rtype: C{tuple} of (C{list} of L{Action0Property}, C{list} of L{BaseAction}, C{list} of 3-C{tuple}, C{list} of L{BaseAction})
    """
    action_list = []
    action_list_append = []
    mods = []

    if 'custom_function' in prop_info:
        props = prop_info['custom_function'](*value_list)
    else:
        # First process each element in the value_list
        final_values = []
        for i, value in enumerate(value_list):
            if 'string_literal' in prop_info and (
                    isinstance(value, expression.StringLiteral)
                    or prop_info['string_literal'] != 4):
                # Parse non-string exprssions just like integers. User will have to take care of proper value.
                # This can be used to set a label (=string of length 4) to the value of a parameter.
                if not isinstance(value, expression.StringLiteral):
                    raise generic.ScriptError(
                        "Value for property {:d} must be a string literal".
                        format(prop_info['num']), value.pos)
                if len(value.value) != prop_info['string_literal']:
                    raise generic.ScriptError(
                        "Value for property {:d} must be of length {:d}".
                        format(prop_info['num'],
                               prop_info['string_literal']), value.pos)

            elif isinstance(value, expression.ConstantNumeric):
                pass

            elif isinstance(value, expression.Parameter) and isinstance(
                    value.num, expression.ConstantNumeric):
                mods.append((value.num.value, prop_info['size'],
                             i * prop_info['size'] + 1))
                value = expression.ConstantNumeric(0)

            elif isinstance(value, expression.String):
                if not 'string' in prop_info:
                    raise generic.ScriptError(
                        "String used as value for non-string property: " +
                        str(prop_info['num']), value.pos)
                string_range = prop_info['string']
                stringid, string_actions = action4.get_string_action4s(
                    feature, string_range, value, id)
                value = expression.ConstantNumeric(stringid)
                action_list_append.extend(string_actions)

            else:
                tmp_param, tmp_param_actions = actionD.get_tmp_parameter(value)
                mods.append(
                    (tmp_param, prop_info['size'], i * prop_info['size'] + 1))
                action_list.extend(tmp_param_actions)
                value = expression.ConstantNumeric(0)

            final_values.append(value)

        # Now, write a single Action0 Property with all of these values
        if prop_info['num'] != -1:
            props = [
                Action0Property(prop_info['num'], final_values,
                                prop_info['size'])
            ]
        else:
            props = []

    return (props, action_list, mods, action_list_append)