Beispiel #1
0
    def get_attack_effects(line: GenieGameEntityGroup,
                           location_ref: str,
                           projectile: int = -1) -> list[ForwardRef]:
        """
        Creates effects that are used for attacking (unit command: 7)

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param location_ref: Reference to API object the effects are added to.
        :type location_ref: str
        :returns: The forward references for the effects.
        :rtype: list
        """
        dataset = line.data

        if projectile != 1:
            current_unit = line.get_head_unit()

        else:
            projectile_id = line.get_head_unit(
            )["attack_projectile_secondary_unit_id"].get_value()
            current_unit = dataset.genie_units[projectile_id]

        effects = []

        armor_lookup_dict = internal_name_lookups.get_armor_class_lookups(
            dataset.game_version)

        # FlatAttributeChangeDecrease
        effect_parent = "engine.effect.discrete.flat_attribute_change.FlatAttributeChange"
        attack_parent = "engine.effect.discrete.flat_attribute_change.type.FlatAttributeChangeDecrease"

        attacks = current_unit["attacks"].get_value()

        for attack in attacks.values():
            armor_class = attack["type_id"].get_value()
            attack_amount = attack["amount"].get_value()
            class_name = armor_lookup_dict[armor_class]

            attack_ref = f"{location_ref}.{class_name}"
            attack_raw_api_object = RawAPIObject(attack_ref, class_name,
                                                 dataset.nyan_api_objects)
            attack_raw_api_object.add_raw_parent(attack_parent)
            attack_location = ForwardRef(line, location_ref)
            attack_raw_api_object.set_location(attack_location)

            # Type
            type_ref = f"util.attribute_change_type.types.{class_name}"
            change_type = dataset.pregen_nyan_objects[
                type_ref].get_nyan_object()
            attack_raw_api_object.add_raw_member("type", change_type,
                                                 effect_parent)

            # Min value (optional)
            min_value = dataset.pregen_nyan_objects[(
                "effect.discrete.flat_attribute_change."
                "min_damage.AoE2MinChangeAmount")].get_nyan_object()
            attack_raw_api_object.add_raw_member("min_change_value", min_value,
                                                 effect_parent)

            # Max value (optional; not added because there is none in AoE2)

            # Change value
            # =================================================================================
            amount_name = f"{location_ref}.{class_name}.ChangeAmount"
            amount_raw_api_object = RawAPIObject(amount_name, "ChangeAmount",
                                                 dataset.nyan_api_objects)
            amount_raw_api_object.add_raw_parent(
                "engine.util.attribute.AttributeAmount")
            amount_location = ForwardRef(line, attack_ref)
            amount_raw_api_object.set_location(amount_location)

            attribute = dataset.pregen_nyan_objects[
                "util.attribute.types.Health"].get_nyan_object()
            amount_raw_api_object.add_raw_member(
                "type", attribute, "engine.util.attribute.AttributeAmount")
            amount_raw_api_object.add_raw_member(
                "amount", attack_amount,
                "engine.util.attribute.AttributeAmount")

            line.add_raw_api_object(amount_raw_api_object)
            # =================================================================================
            amount_forward_ref = ForwardRef(line, amount_name)
            attack_raw_api_object.add_raw_member("change_value",
                                                 amount_forward_ref,
                                                 effect_parent)

            # Ignore protection
            attack_raw_api_object.add_raw_member("ignore_protection", [],
                                                 effect_parent)

            line.add_raw_api_object(attack_raw_api_object)
            attack_forward_ref = ForwardRef(line, attack_ref)
            effects.append(attack_forward_ref)

        # Fallback effect
        fallback_effect = dataset.pregen_nyan_objects[(
            "effect.discrete.flat_attribute_change."
            "fallback.AoE2AttackFallback")].get_nyan_object()
        effects.append(fallback_effect)

        return effects
Beispiel #2
0
    def get_attack_resistances(line: GenieGameEntityGroup,
                               ability_ref: str) -> list[ForwardRef]:
        """
        Creates resistances that are used for attacking (unit command: 7)

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param ability_ref: Reference of the ability raw API object the effects are added to.
        :type ability_ref: str
        :returns: The forward references for the effects.
        :rtype: list
        """
        current_unit = line.get_head_unit()
        dataset = line.data

        armor_lookup_dict = internal_name_lookups.get_armor_class_lookups(
            dataset.game_version)

        resistances = []

        # FlatAttributeChangeDecrease
        resistance_parent = "engine.resistance.discrete.flat_attribute_change.FlatAttributeChange"
        armor_parent = "engine.resistance.discrete.flat_attribute_change.type.FlatAttributeChangeDecrease"

        if current_unit.has_member("armors"):
            armors = current_unit["armors"].get_value()

        else:
            # TODO: Trees and blast defense
            armors = {}

        for armor in armors.values():
            armor_class = armor["type_id"].get_value()
            armor_amount = armor["amount"].get_value()
            class_name = armor_lookup_dict[armor_class]

            armor_ref = f"{ability_ref}.{class_name}"
            armor_raw_api_object = RawAPIObject(armor_ref, class_name,
                                                dataset.nyan_api_objects)
            armor_raw_api_object.add_raw_parent(armor_parent)
            armor_location = ForwardRef(line, ability_ref)
            armor_raw_api_object.set_location(armor_location)

            # Type
            type_ref = f"util.attribute_change_type.types.{class_name}"
            change_type = dataset.pregen_nyan_objects[
                type_ref].get_nyan_object()
            armor_raw_api_object.add_raw_member("type", change_type,
                                                resistance_parent)

            # Block value
            # =================================================================================
            amount_name = f"{ability_ref}.{class_name}.BlockAmount"
            amount_raw_api_object = RawAPIObject(amount_name, "BlockAmount",
                                                 dataset.nyan_api_objects)
            amount_raw_api_object.add_raw_parent(
                "engine.util.attribute.AttributeAmount")
            amount_location = ForwardRef(line, armor_ref)
            amount_raw_api_object.set_location(amount_location)

            attribute = dataset.pregen_nyan_objects[
                "util.attribute.types.Health"].get_nyan_object()
            amount_raw_api_object.add_raw_member(
                "type", attribute, "engine.util.attribute.AttributeAmount")
            amount_raw_api_object.add_raw_member(
                "amount", armor_amount,
                "engine.util.attribute.AttributeAmount")

            line.add_raw_api_object(amount_raw_api_object)
            # =================================================================================
            amount_forward_ref = ForwardRef(line, amount_name)
            armor_raw_api_object.add_raw_member("block_value",
                                                amount_forward_ref,
                                                resistance_parent)

            line.add_raw_api_object(armor_raw_api_object)
            armor_forward_ref = ForwardRef(line, armor_ref)
            resistances.append(armor_forward_ref)

        # Fallback effect
        fallback_effect = dataset.pregen_nyan_objects[(
            "resistance.discrete.flat_attribute_change."
            "fallback.AoE2AttackFallback")].get_nyan_object()
        resistances.append(fallback_effect)

        return resistances
Beispiel #3
0
    def get_convert_effects(line: GenieGameEntityGroup,
                            location_ref: str) -> list[ForwardRef]:
        """
        Creates effects that are used for conversion (unit command: 104)

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param location_ref: Reference to API object the effects are added to.
        :type location_ref: str
        :returns: The forward references for the effects.
        :rtype: list
        """
        current_unit = line.get_head_unit()
        dataset = line.data

        effects = []

        effect_parent = "engine.effect.discrete.convert.Convert"
        convert_parent = "engine.effect.discrete.convert.type.AoE2Convert"

        unit_commands = current_unit["unit_commands"].get_value()
        for command in unit_commands:
            # Find the Heal command.
            type_id = command["type"].get_value()

            if type_id == 104:
                skip_guaranteed_rounds = -1 * command["work_value1"].get_value(
                )
                skip_protected_rounds = -1 * command["work_value2"].get_value()
                break

        else:
            # Return the empty set
            return effects

        # Unit conversion
        convert_ref = f"{location_ref}.ConvertUnitEffect"
        convert_raw_api_object = RawAPIObject(convert_ref, "ConvertUnitEffect",
                                              dataset.nyan_api_objects)
        convert_raw_api_object.add_raw_parent(convert_parent)
        convert_location = ForwardRef(line, location_ref)
        convert_raw_api_object.set_location(convert_location)

        # Type
        type_ref = "util.convert_type.types.UnitConvert"
        change_type = dataset.pregen_nyan_objects[type_ref].get_nyan_object()
        convert_raw_api_object.add_raw_member("type", change_type,
                                              effect_parent)

        # Min success (optional; not added because there is none in AoE2)
        # Max success (optional; not added because there is none in AoE2)

        # Chance
        # hardcoded resource
        chance_success = dataset.genie_civs[0]["resources"][182].get_value(
        ) / 100
        convert_raw_api_object.add_raw_member("chance_success", chance_success,
                                              effect_parent)

        # Fail cost (optional; not added because there is none in AoE2)

        # Guaranteed rounds skip
        convert_raw_api_object.add_raw_member("skip_guaranteed_rounds",
                                              skip_guaranteed_rounds,
                                              convert_parent)

        # Protected rounds skip
        convert_raw_api_object.add_raw_member("skip_protected_rounds",
                                              skip_protected_rounds,
                                              convert_parent)

        line.add_raw_api_object(convert_raw_api_object)
        attack_forward_ref = ForwardRef(line, convert_ref)
        effects.append(attack_forward_ref)

        # Building conversion
        convert_ref = f"{location_ref}.ConvertBuildingEffect"
        convert_raw_api_object = RawAPIObject(convert_ref,
                                              "ConvertBuildingUnitEffect",
                                              dataset.nyan_api_objects)
        convert_raw_api_object.add_raw_parent(convert_parent)
        convert_location = ForwardRef(line, location_ref)
        convert_raw_api_object.set_location(convert_location)

        # Type
        type_ref = "util.convert_type.types.BuildingConvert"
        change_type = dataset.pregen_nyan_objects[type_ref].get_nyan_object()
        convert_raw_api_object.add_raw_member("type", change_type,
                                              effect_parent)

        # Min success (optional; not added because there is none in AoE2)
        # Max success (optional; not added because there is none in AoE2)

        # Chance
        # hardcoded resource
        chance_success = dataset.genie_civs[0]["resources"][182].get_value(
        ) / 100
        convert_raw_api_object.add_raw_member("chance_success", chance_success,
                                              effect_parent)

        # Fail cost (optional; not added because there is none in AoE2)

        # Guaranteed rounds skip
        convert_raw_api_object.add_raw_member("skip_guaranteed_rounds", 0,
                                              convert_parent)

        # Protected rounds skip
        convert_raw_api_object.add_raw_member("skip_protected_rounds", 0,
                                              convert_parent)

        line.add_raw_api_object(convert_raw_api_object)
        attack_forward_ref = ForwardRef(line, convert_ref)
        effects.append(attack_forward_ref)

        return effects
Beispiel #4
0
    def get_heal_effects(line: GenieGameEntityGroup,
                         location_ref: str) -> list[ForwardRef]:
        """
        Creates effects that are used for healing (unit command: 105)

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param location_ref: Reference to API object the effects are added to.
        :type location_ref: str
        :returns: The forward references for the effects.
        :rtype: list
        """
        current_unit = line.get_head_unit()
        dataset = line.data

        effects = []

        effect_parent = "engine.effect.continuous.flat_attribute_change.FlatAttributeChange"
        heal_parent = "engine.effect.continuous.flat_attribute_change.type.FlatAttributeChangeIncrease"

        unit_commands = current_unit["unit_commands"].get_value()
        heal_command = None

        for command in unit_commands:
            # Find the Heal command.
            type_id = command["type"].get_value()

            if type_id == 105:
                heal_command = command
                break

        else:
            # Return the empty set
            return effects

        heal_rate = heal_command["work_value1"].get_value()

        heal_ref = f"{location_ref}.HealEffect"
        heal_raw_api_object = RawAPIObject(heal_ref, "HealEffect",
                                           dataset.nyan_api_objects)
        heal_raw_api_object.add_raw_parent(heal_parent)
        heal_location = ForwardRef(line, location_ref)
        heal_raw_api_object.set_location(heal_location)

        # Type
        type_ref = "util.attribute_change_type.types.Heal"
        change_type = dataset.pregen_nyan_objects[type_ref].get_nyan_object()
        heal_raw_api_object.add_raw_member("type", change_type, effect_parent)

        # Min value (optional)
        min_value = dataset.pregen_nyan_objects[(
            "effect.discrete.flat_attribute_change."
            "min_heal.AoE2MinChangeAmount")].get_nyan_object()
        heal_raw_api_object.add_raw_member("min_change_rate", min_value,
                                           effect_parent)

        # Max value (optional; not added because there is none in AoE2)

        # Change rate
        # =================================================================================
        rate_name = f"{location_ref}.HealEffect.ChangeRate"
        rate_raw_api_object = RawAPIObject(rate_name, "ChangeRate",
                                           dataset.nyan_api_objects)
        rate_raw_api_object.add_raw_parent(
            "engine.util.attribute.AttributeRate")
        rate_location = ForwardRef(line, heal_ref)
        rate_raw_api_object.set_location(rate_location)

        attribute = dataset.pregen_nyan_objects[
            "util.attribute.types.Health"].get_nyan_object()
        rate_raw_api_object.add_raw_member(
            "type", attribute, "engine.util.attribute.AttributeRate")
        rate_raw_api_object.add_raw_member(
            "rate", heal_rate, "engine.util.attribute.AttributeRate")

        line.add_raw_api_object(rate_raw_api_object)
        # =================================================================================
        rate_forward_ref = ForwardRef(line, rate_name)
        heal_raw_api_object.add_raw_member("change_rate", rate_forward_ref,
                                           effect_parent)

        # Ignore protection
        heal_raw_api_object.add_raw_member("ignore_protection", [],
                                           effect_parent)

        line.add_raw_api_object(heal_raw_api_object)
        heal_forward_ref = ForwardRef(line, heal_ref)
        effects.append(heal_forward_ref)

        return effects
Beispiel #5
0
    def ballistics_upgrade(converter_group: ConverterObjectGroup,
                           line: GenieGameEntityGroup,
                           value: typing.Any,
                           operator: MemberOperator,
                           team: bool = False) -> list[ForwardRef]:
        """
        Creates a patch for the ballistics modify effect (ID: 19).

        :param converter_group: Tech/Civ that gets the patch.
        :type converter_group: ...dataformat.converter_object.ConverterObjectGroup
        :param line: Unit/Building line that has the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param value: Value used for patching the member.
        :type value: Any
        :param operator: Operator used for patching the member.
        :type operator: MemberOperator
        :returns: The forward references for the generated patches.
        :rtype: list
        """
        head_unit = line.get_head_unit()
        head_unit_id = line.get_head_unit_id()
        dataset = line.data

        patches = []

        if value == 0:
            target_mode = dataset.nyan_api_objects[
                "engine.util.target_mode.type.CurrentPosition"]

        elif value == 1:
            target_mode = dataset.nyan_api_objects[
                "engine.util.target_mode.type.ExpectedPosition"]

        obj_id = converter_group.get_id()
        if isinstance(converter_group, GenieTechEffectBundleGroup):
            tech_lookup_dict = internal_name_lookups.get_tech_lookups(
                dataset.game_version)
            obj_name = tech_lookup_dict[obj_id][0]

        else:
            civ_lookup_dict = internal_name_lookups.get_civ_lookups(
                dataset.game_version)
            obj_name = civ_lookup_dict[obj_id][0]

        name_lookup_dict = internal_name_lookups.get_entity_lookups(
            dataset.game_version)

        game_entity_name = name_lookup_dict[head_unit_id][0]

        projectile_id0 = head_unit["projectile_id0"].value
        if projectile_id0 > -1:
            patch_target_ref = f"{game_entity_name}.ShootProjectile.Projectile0.Projectile"
            patch_target_forward_ref = ForwardRef(line, patch_target_ref)

            # Wrapper
            wrapper_name = f"Change{game_entity_name}Projectile0TargetModeWrapper"
            wrapper_ref = f"{obj_name}.{wrapper_name}"
            wrapper_location = ForwardRef(converter_group, obj_name)
            wrapper_raw_api_object = RawAPIObject(wrapper_ref, wrapper_name,
                                                  dataset.nyan_api_objects,
                                                  wrapper_location)
            wrapper_raw_api_object.add_raw_parent("engine.util.patch.Patch")

            # Nyan patch
            nyan_patch_name = f"Change{game_entity_name}Projectile0TargetMode"
            nyan_patch_ref = f"{obj_name}.{wrapper_name}.{nyan_patch_name}"
            nyan_patch_location = ForwardRef(converter_group, wrapper_ref)
            nyan_patch_raw_api_object = RawAPIObject(nyan_patch_ref,
                                                     nyan_patch_name,
                                                     dataset.nyan_api_objects,
                                                     nyan_patch_location)
            nyan_patch_raw_api_object.add_raw_parent(
                "engine.util.patch.NyanPatch")
            nyan_patch_raw_api_object.set_patch_target(
                patch_target_forward_ref)

            nyan_patch_raw_api_object.add_raw_patch_member(
                "target_mode", target_mode, "engine.ability.type.Projectile",
                operator)

            patch_forward_ref = ForwardRef(converter_group, nyan_patch_ref)
            wrapper_raw_api_object.add_raw_member("patch", patch_forward_ref,
                                                  "engine.util.patch.Patch")

            if team:
                team_property = dataset.pregen_nyan_objects[
                    "util.patch.property.types.Team"].get_nyan_object()
                properties = {
                    dataset.nyan_api_objects["engine.util.patch.property.type.Diplomatic"]:
                    team_property
                }
                wrapper_raw_api_object.add_raw_member(
                    "properties", properties, "engine.util.patch.Patch")

            converter_group.add_raw_api_object(wrapper_raw_api_object)
            converter_group.add_raw_api_object(nyan_patch_raw_api_object)

            wrapper_forward_ref = ForwardRef(converter_group, wrapper_ref)
            patches.append(wrapper_forward_ref)

        return patches
Beispiel #6
0
    def resource_cost_upgrade(converter_group: ConverterObjectGroup,
                              line: GenieGameEntityGroup,
                              value: typing.Union[int, float],
                              operator: MemberOperator,
                              team: bool = False) -> list[ForwardRef]:
        """
        Creates a patch for the resource modify effect (ID: 100).

        :param converter_group: Tech/Civ that gets the patch.
        :type converter_group: ...dataformat.converter_object.ConverterObjectGroup
        :param line: Unit/Building line that has the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param value: Value used for patching the member.
        :type value: int, float
        :param operator: Operator used for patching the member.
        :type operator: MemberOperator
        :returns: The forward references for the generated patches.
        :rtype: list
        """
        head_unit = line.get_head_unit()
        head_unit_id = line.get_head_unit_id()
        dataset = line.data

        patches = []

        obj_id = converter_group.get_id()
        if isinstance(converter_group, GenieTechEffectBundleGroup):
            tech_lookup_dict = internal_name_lookups.get_tech_lookups(
                dataset.game_version)
            obj_name = tech_lookup_dict[obj_id][0]

        else:
            civ_lookup_dict = internal_name_lookups.get_civ_lookups(
                dataset.game_version)
            obj_name = civ_lookup_dict[obj_id][0]

        name_lookup_dict = internal_name_lookups.get_entity_lookups(
            dataset.game_version)

        game_entity_name = name_lookup_dict[head_unit_id][0]

        for resource_amount in head_unit["resource_cost"].get_value():
            resource_id = resource_amount["type_id"].get_value()

            resource_name = ""
            if resource_id == -1:
                # Not a valid resource
                continue

            if resource_id == 0:
                resource_name = "Food"

            elif resource_id == 1:
                resource_name = "Carbon"

            elif resource_id == 2:
                resource_name = "Ore"

            elif resource_id == 3:
                resource_name = "Nova"

            else:
                # Other resource ids are handled differently
                continue

            # Skip resources that are only expected to be there
            if not resource_amount["enabled"].get_value():
                continue

            patch_target_ref = "%s.CreatableGameEntity.%sCost.%sAmount" % (
                game_entity_name, game_entity_name, resource_name)
            patch_target_forward_ref = ForwardRef(line, patch_target_ref)

            # Wrapper
            wrapper_name = f"Change{game_entity_name}{resource_name}CostWrapper"
            wrapper_ref = f"{obj_name}.{wrapper_name}"
            wrapper_location = ForwardRef(converter_group, obj_name)
            wrapper_raw_api_object = RawAPIObject(wrapper_ref, wrapper_name,
                                                  dataset.nyan_api_objects,
                                                  wrapper_location)
            wrapper_raw_api_object.add_raw_parent("engine.util.patch.Patch")

            # Nyan patch
            nyan_patch_name = f"Change{game_entity_name}{resource_name}Cost"
            nyan_patch_ref = f"{obj_name}.{wrapper_name}.{nyan_patch_name}"
            nyan_patch_location = ForwardRef(converter_group, wrapper_ref)
            nyan_patch_raw_api_object = RawAPIObject(nyan_patch_ref,
                                                     nyan_patch_name,
                                                     dataset.nyan_api_objects,
                                                     nyan_patch_location)
            nyan_patch_raw_api_object.add_raw_parent(
                "engine.util.patch.NyanPatch")
            nyan_patch_raw_api_object.set_patch_target(
                patch_target_forward_ref)

            nyan_patch_raw_api_object.add_raw_patch_member(
                "amount", value, "engine.util.resource.ResourceAmount",
                operator)

            patch_forward_ref = ForwardRef(converter_group, nyan_patch_ref)
            wrapper_raw_api_object.add_raw_member("patch", patch_forward_ref,
                                                  "engine.util.patch.Patch")

            if team:
                team_property = dataset.pregen_nyan_objects[
                    "util.patch.property.types.Team"].get_nyan_object()
                properties = {
                    dataset.nyan_api_objects["engine.util.patch.property.type.Diplomatic"]:
                    team_property
                }
                wrapper_raw_api_object.add_raw_member(
                    "properties", properties, "engine.util.patch.Patch")

            converter_group.add_raw_api_object(wrapper_raw_api_object)
            converter_group.add_raw_api_object(nyan_patch_raw_api_object)

            wrapper_forward_ref = ForwardRef(converter_group, wrapper_ref)
            patches.append(wrapper_forward_ref)

        return patches
Beispiel #7
0
    def shoot_projectile_ability(line: GenieGameEntityGroup, command_id: int) -> ForwardRef:
        """
        Adds the ShootProjectile ability to a line.

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :returns: The forward reference for the ability.
        :rtype: ...dataformat.forward_ref.ForwardRef
        """
        current_unit = line.get_head_unit()
        current_unit_id = line.get_head_unit_id()
        dataset = line.data
        api_objects = dataset.nyan_api_objects

        name_lookup_dict = internal_name_lookups.get_entity_lookups(dataset.game_version)
        command_lookup_dict = internal_name_lookups.get_command_lookups(dataset.game_version)

        ability_name = command_lookup_dict[command_id][0]

        game_entity_name = name_lookup_dict[current_unit_id][0]
        ability_ref = f"{game_entity_name}.{ability_name}"
        ability_raw_api_object = RawAPIObject(ability_ref, ability_name, dataset.nyan_api_objects)
        ability_raw_api_object.add_raw_parent("engine.ability.type.ShootProjectile")
        ability_location = ForwardRef(line, game_entity_name)
        ability_raw_api_object.set_location(ability_location)

        # Ability properties
        properties = {}

        # Animation
        ability_animation_id = current_unit["attack_sprite_id"].value
        if ability_animation_id > -1:
            property_ref = f"{ability_ref}.Animated"
            property_raw_api_object = RawAPIObject(property_ref,
                                                   "Animated",
                                                   dataset.nyan_api_objects)
            property_raw_api_object.add_raw_parent("engine.ability.property.type.Animated")
            property_location = ForwardRef(line, ability_ref)
            property_raw_api_object.set_location(property_location)

            line.add_raw_api_object(property_raw_api_object)

            animations_set = []
            animation_forward_ref = AoCAbilitySubprocessor.create_animation(
                line,
                ability_animation_id,
                property_ref,
                ability_name,
                f"{command_lookup_dict[command_id][1]}_"
            )
            animations_set.append(animation_forward_ref)
            property_raw_api_object.add_raw_member("animations",
                                                   animations_set,
                                                   "engine.ability.property.type.Animated")

            property_forward_ref = ForwardRef(line, property_ref)
            properties.update({
                api_objects["engine.ability.property.type.Animated"]: property_forward_ref
            })

        # Command Sound
        ability_comm_sound_id = current_unit["command_sound_id"].value
        if ability_comm_sound_id > -1:
            property_ref = f"{ability_ref}.CommandSound"
            property_raw_api_object = RawAPIObject(property_ref,
                                                   "CommandSound",
                                                   dataset.nyan_api_objects)
            property_raw_api_object.add_raw_parent("engine.ability.property.type.CommandSound")
            property_location = ForwardRef(line, ability_ref)
            property_raw_api_object.set_location(property_location)

            line.add_raw_api_object(property_raw_api_object)

            sounds_set = []
            sound_forward_ref = AoCAbilitySubprocessor.create_sound(line,
                                                                    ability_comm_sound_id,
                                                                    property_ref,
                                                                    ability_name,
                                                                    "command_")
            sounds_set.append(sound_forward_ref)
            property_raw_api_object.add_raw_member("sounds",
                                                   sounds_set,
                                                   "engine.ability.property.type.CommandSound")

            property_forward_ref = ForwardRef(line, property_ref)
            properties.update({
                api_objects["engine.ability.property.type.CommandSound"]: property_forward_ref
            })

        # Diplomacy settings
        property_ref = f"{ability_ref}.Diplomatic"
        property_raw_api_object = RawAPIObject(property_ref,
                                               "Diplomatic",
                                               dataset.nyan_api_objects)
        property_raw_api_object.add_raw_parent("engine.ability.property.type.Diplomatic")
        property_location = ForwardRef(line, ability_ref)
        property_raw_api_object.set_location(property_location)

        line.add_raw_api_object(property_raw_api_object)

        diplomatic_stances = [dataset.nyan_api_objects["engine.util.diplomatic_stance.type.Self"]]
        property_raw_api_object.add_raw_member("stances", diplomatic_stances,
                                               "engine.ability.property.type.Diplomatic")

        property_forward_ref = ForwardRef(line, property_ref)
        properties.update({
            api_objects["engine.ability.property.type.Diplomatic"]: property_forward_ref
        })

        ability_raw_api_object.add_raw_member("properties",
                                              properties,
                                              "engine.ability.Ability")

        # Projectile
        projectiles = []
        projectile_primary = current_unit["projectile_id0"].value
        if projectile_primary > -1:
            projectiles.append(ForwardRef(line,
                                          f"{game_entity_name}.ShootProjectile.Projectile0"))

        ability_raw_api_object.add_raw_member("projectiles",
                                              projectiles,
                                              "engine.ability.type.ShootProjectile")

        # Projectile count (does not exist in RoR)
        min_projectiles = 1
        max_projectiles = 1

        ability_raw_api_object.add_raw_member("min_projectiles",
                                              min_projectiles,
                                              "engine.ability.type.ShootProjectile")
        ability_raw_api_object.add_raw_member("max_projectiles",
                                              max_projectiles,
                                              "engine.ability.type.ShootProjectile")

        # Range
        min_range = current_unit["weapon_range_min"].value
        ability_raw_api_object.add_raw_member("min_range",
                                              min_range,
                                              "engine.ability.type.ShootProjectile")

        max_range = current_unit["weapon_range_max"].value
        ability_raw_api_object.add_raw_member("max_range",
                                              max_range,
                                              "engine.ability.type.ShootProjectile")

        # Reload time and delay
        reload_time = current_unit["attack_speed"].value
        ability_raw_api_object.add_raw_member("reload_time",
                                              reload_time,
                                              "engine.ability.type.ShootProjectile")

        if ability_animation_id > -1:
            animation = dataset.genie_graphics[ability_animation_id]
            frame_rate = animation.get_frame_rate()

        else:
            frame_rate = 0

        spawn_delay_frames = current_unit["frame_delay"].value
        spawn_delay = frame_rate * spawn_delay_frames
        ability_raw_api_object.add_raw_member("spawn_delay",
                                              spawn_delay,
                                              "engine.ability.type.ShootProjectile")

        # Projectile delay (unused because RoR has no multiple projectiles)
        ability_raw_api_object.add_raw_member("projectile_delay",
                                              0.0,
                                              "engine.ability.type.ShootProjectile")

        # Turning
        if isinstance(line, GenieBuildingLineGroup):
            require_turning = False

        else:
            require_turning = True

        ability_raw_api_object.add_raw_member("require_turning",
                                              require_turning,
                                              "engine.ability.type.ShootProjectile")

        # Manual aiming
        manual_aiming_allowed = line.get_head_unit_id() in (35, 250)
        ability_raw_api_object.add_raw_member("manual_aiming_allowed",
                                              manual_aiming_allowed,
                                              "engine.ability.type.ShootProjectile")

        # Spawning area
        spawning_area_offset_x = current_unit["weapon_offset"][0].value
        spawning_area_offset_y = current_unit["weapon_offset"][1].value
        spawning_area_offset_z = current_unit["weapon_offset"][2].value

        ability_raw_api_object.add_raw_member("spawning_area_offset_x",
                                              spawning_area_offset_x,
                                              "engine.ability.type.ShootProjectile")
        ability_raw_api_object.add_raw_member("spawning_area_offset_y",
                                              spawning_area_offset_y,
                                              "engine.ability.type.ShootProjectile")
        ability_raw_api_object.add_raw_member("spawning_area_offset_z",
                                              spawning_area_offset_z,
                                              "engine.ability.type.ShootProjectile")

        # Spawn Area (does not exist in RoR)
        spawning_area_width = 0
        spawning_area_height = 0
        spawning_area_randomness = 0

        ability_raw_api_object.add_raw_member("spawning_area_width",
                                              spawning_area_width,
                                              "engine.ability.type.ShootProjectile")
        ability_raw_api_object.add_raw_member("spawning_area_height",
                                              spawning_area_height,
                                              "engine.ability.type.ShootProjectile")
        ability_raw_api_object.add_raw_member("spawning_area_randomness",
                                              spawning_area_randomness,
                                              "engine.ability.type.ShootProjectile")

        # Restrictions on targets (only units and buildings allowed)
        allowed_types = [
            dataset.pregen_nyan_objects["util.game_entity_type.types.Building"].get_nyan_object(),
            dataset.pregen_nyan_objects["util.game_entity_type.types.Unit"].get_nyan_object()
        ]
        ability_raw_api_object.add_raw_member("allowed_types",
                                              allowed_types,
                                              "engine.ability.type.ShootProjectile")
        ability_raw_api_object.add_raw_member("blacklisted_entities",
                                              [],
                                              "engine.ability.type.ShootProjectile")

        line.add_raw_api_object(ability_raw_api_object)

        ability_forward_ref = ForwardRef(line, ability_raw_api_object.get_id())

        return ability_forward_ref
Beispiel #8
0
    def projectile_ability(line: GenieGameEntityGroup, position: int = 0) -> ForwardRef:
        """
        Adds a Projectile ability to projectiles in a line. Which projectile should
        be added is determined by the 'position' argument.

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :param position: When 0, gives the first projectile its ability. When 1, the second...
        :type position: int
        :returns: The forward reference for the ability.
        :rtype: ...dataformat.forward_ref.ForwardRef
        """
        current_unit = line.get_head_unit()
        current_unit_id = line.get_head_unit_id()
        dataset = line.data

        name_lookup_dict = internal_name_lookups.get_entity_lookups(dataset.game_version)

        game_entity_name = name_lookup_dict[current_unit_id][0]

        # First projectile is mandatory
        obj_ref = f"{game_entity_name}.ShootProjectile.Projectile{position}"
        ability_ref = f"{game_entity_name}.ShootProjectile.Projectile{position}.Projectile"
        ability_raw_api_object = RawAPIObject(ability_ref,
                                              "Projectile",
                                              dataset.nyan_api_objects)
        ability_raw_api_object.add_raw_parent("engine.ability.type.Projectile")
        ability_location = ForwardRef(line, obj_ref)
        ability_raw_api_object.set_location(ability_location)

        # Arc
        if position == 0:
            projectile_id = current_unit["projectile_id0"].value

        else:
            raise Exception("Invalid position")

        projectile = dataset.genie_units[projectile_id]
        arc = degrees(projectile["projectile_arc"].value)
        ability_raw_api_object.add_raw_member("arc",
                                              arc,
                                              "engine.ability.type.Projectile")

        # Accuracy
        accuracy_name = (f"{game_entity_name}.ShootProjectile."
                         f"Projectile{position}.Projectile.Accuracy")
        accuracy_raw_api_object = RawAPIObject(accuracy_name, "Accuracy", dataset.nyan_api_objects)
        accuracy_raw_api_object.add_raw_parent("engine.util.accuracy.Accuracy")
        accuracy_location = ForwardRef(line, ability_ref)
        accuracy_raw_api_object.set_location(accuracy_location)

        accuracy_value = current_unit["accuracy"].value
        accuracy_raw_api_object.add_raw_member("accuracy",
                                               accuracy_value,
                                               "engine.util.accuracy.Accuracy")

        accuracy_dispersion = 0
        accuracy_raw_api_object.add_raw_member("accuracy_dispersion",
                                               accuracy_dispersion,
                                               "engine.util.accuracy.Accuracy")
        dropoff_type = dataset.nyan_api_objects["engine.util.dropoff_type.type.NoDropoff"]
        accuracy_raw_api_object.add_raw_member("dispersion_dropoff",
                                               dropoff_type,
                                               "engine.util.accuracy.Accuracy")

        allowed_types = [
            dataset.pregen_nyan_objects["util.game_entity_type.types.Building"].get_nyan_object(),
            dataset.pregen_nyan_objects["util.game_entity_type.types.Unit"].get_nyan_object()
        ]
        accuracy_raw_api_object.add_raw_member("target_types",
                                               allowed_types,
                                               "engine.util.accuracy.Accuracy")
        accuracy_raw_api_object.add_raw_member("blacklisted_entities",
                                               [],
                                               "engine.util.accuracy.Accuracy")

        line.add_raw_api_object(accuracy_raw_api_object)
        accuracy_forward_ref = ForwardRef(line, accuracy_name)
        ability_raw_api_object.add_raw_member("accuracy",
                                              [accuracy_forward_ref],
                                              "engine.ability.type.Projectile")

        # Target mode
        target_mode = dataset.nyan_api_objects["engine.util.target_mode.type.CurrentPosition"]
        ability_raw_api_object.add_raw_member("target_mode",
                                              target_mode,
                                              "engine.ability.type.Projectile")

        # Ingore types; buildings are ignored unless targeted
        ignore_forward_refs = [
            dataset.pregen_nyan_objects["util.game_entity_type.types.Building"].get_nyan_object()
        ]
        ability_raw_api_object.add_raw_member("ignored_types",
                                              ignore_forward_refs,
                                              "engine.ability.type.Projectile")
        ability_raw_api_object.add_raw_member("unignored_entities",
                                              [],
                                              "engine.ability.type.Projectile")

        line.add_raw_api_object(ability_raw_api_object)

        ability_forward_ref = ForwardRef(line, ability_raw_api_object.get_id())

        return ability_forward_ref
Beispiel #9
0
    def game_entity_stance_ability(line: GenieGameEntityGroup) -> ForwardRef:
        """
        Adds the GameEntityStance ability to a line.

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :returns: The forward reference for the ability.
        :rtype: ...dataformat.forward_ref.ForwardRef
        """
        current_unit = line.get_head_unit()
        current_unit_id = line.get_head_unit_id()
        dataset = line.data

        name_lookup_dict = internal_name_lookups.get_entity_lookups(dataset.game_version)

        game_entity_name = name_lookup_dict[current_unit_id][0]

        ability_ref = f"{game_entity_name}.GameEntityStance"
        ability_raw_api_object = RawAPIObject(ability_ref,
                                              "GameEntityStance",
                                              dataset.nyan_api_objects)
        ability_raw_api_object.add_raw_parent("engine.ability.type.GameEntityStance")
        ability_location = ForwardRef(line, game_entity_name)
        ability_raw_api_object.set_location(ability_location)

        # Stances
        search_range = current_unit["search_radius"].value
        stance_names = ["Aggressive", "StandGround"]

        # Attacking is preferred
        ability_preferences = []
        if line.is_projectile_shooter():
            ability_preferences.append(ForwardRef(line, f"{game_entity_name}.Attack"))

        elif line.is_melee() or line.is_ranged():
            if line.has_command(7):
                ability_preferences.append(ForwardRef(line, f"{game_entity_name}.Attack"))

            if line.has_command(105):
                ability_preferences.append(ForwardRef(line, f"{game_entity_name}.Heal"))

        # Units are preferred before buildings
        type_preferences = [
            dataset.pregen_nyan_objects["util.game_entity_type.types.Unit"].get_nyan_object(),
            dataset.pregen_nyan_objects["util.game_entity_type.types.Building"].get_nyan_object(),
        ]

        stances = []
        for stance_name in stance_names:
            stance_api_ref = f"engine.util.game_entity_stance.type.{stance_name}"

            stance_ref = f"{game_entity_name}.GameEntityStance.{stance_name}"
            stance_raw_api_object = RawAPIObject(stance_ref, stance_name, dataset.nyan_api_objects)
            stance_raw_api_object.add_raw_parent(stance_api_ref)
            stance_location = ForwardRef(line, ability_ref)
            stance_raw_api_object.set_location(stance_location)

            # Search range
            stance_raw_api_object.add_raw_member("search_range",
                                                 search_range,
                                                 "engine.util.game_entity_stance.GameEntityStance")

            # Ability preferences
            stance_raw_api_object.add_raw_member("ability_preference",
                                                 ability_preferences,
                                                 "engine.util.game_entity_stance.GameEntityStance")

            # Type preferences
            stance_raw_api_object.add_raw_member("type_preference",
                                                 type_preferences,
                                                 "engine.util.game_entity_stance.GameEntityStance")

            line.add_raw_api_object(stance_raw_api_object)
            stance_forward_ref = ForwardRef(line, stance_ref)
            stances.append(stance_forward_ref)

        ability_raw_api_object.add_raw_member("stances",
                                              stances,
                                              "engine.ability.type.GameEntityStance")

        line.add_raw_api_object(ability_raw_api_object)

        ability_forward_ref = ForwardRef(line, ability_raw_api_object.get_id())

        return ability_forward_ref
Beispiel #10
0
    def apply_discrete_effect_ability(
        line: GenieGameEntityGroup,
        command_id: int,
        ranged: bool = False,
        projectile: int = -1
    ) -> ForwardRef:
        """
        Adds the ApplyDiscreteEffect ability to a line.

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :returns: The forward reference for the ability.
        :rtype: ...dataformat.forward_ref.ForwardRef
        """
        if isinstance(line, GenieVillagerGroup):
            current_unit = line.get_units_with_command(command_id)[0]
            current_unit_id = current_unit["id0"].value

        else:
            current_unit = line.get_head_unit()
            current_unit_id = line.get_head_unit_id()

        head_unit_id = line.get_head_unit_id()
        dataset = line.data
        api_objects = dataset.nyan_api_objects

        name_lookup_dict = internal_name_lookups.get_entity_lookups(dataset.game_version)
        command_lookup_dict = internal_name_lookups.get_command_lookups(dataset.game_version)
        gset_lookup_dict = internal_name_lookups.get_graphic_set_lookups(dataset.game_version)

        game_entity_name = name_lookup_dict[head_unit_id][0]

        ability_name = command_lookup_dict[command_id][0]

        if ranged:
            ability_parent = "engine.ability.type.RangedDiscreteEffect"

        else:
            ability_parent = "engine.ability.type.ApplyDiscreteEffect"

        if projectile == -1:
            ability_ref = f"{game_entity_name}.{ability_name}"
            ability_raw_api_object = RawAPIObject(ability_ref,
                                                  ability_name,
                                                  dataset.nyan_api_objects)
            ability_raw_api_object.add_raw_parent(ability_parent)
            ability_location = ForwardRef(line, game_entity_name)
            ability_raw_api_object.set_location(ability_location)

            if command_id == 104:
                # Get animation from commands proceed sprite
                unit_commands = current_unit["unit_commands"].value
                for command in unit_commands:
                    type_id = command["type"].value

                    if type_id != command_id:
                        continue

                    ability_animation_id = command["proceed_sprite_id"].value
                    break

                else:
                    ability_animation_id = -1

            else:
                ability_animation_id = current_unit["attack_sprite_id"].value

        else:
            ability_ref = (f"{game_entity_name}.ShootProjectile."
                           f"Projectile{projectile}.{ability_name}")
            ability_raw_api_object = RawAPIObject(ability_ref,
                                                  ability_name,
                                                  dataset.nyan_api_objects)
            ability_raw_api_object.add_raw_parent(ability_parent)
            ability_location = ForwardRef(line,
                                          (f"{game_entity_name}.ShootProjectile."
                                           f"Projectile{projectile}"))
            ability_raw_api_object.set_location(ability_location)

            ability_animation_id = -1

        # Ability properties
        properties = {}

        # Animated
        if ability_animation_id > -1:
            property_ref = f"{ability_ref}.Animated"
            property_raw_api_object = RawAPIObject(property_ref,
                                                   "Animated",
                                                   dataset.nyan_api_objects)
            property_raw_api_object.add_raw_parent("engine.ability.property.type.Animated")
            property_location = ForwardRef(line, ability_ref)
            property_raw_api_object.set_location(property_location)

            line.add_raw_api_object(property_raw_api_object)

            animations_set = []
            animation_forward_ref = AoCAbilitySubprocessor.create_animation(
                line,
                ability_animation_id,
                property_ref,
                ability_name,
                f"{command_lookup_dict[command_id][1]}_"
            )
            animations_set.append(animation_forward_ref)
            property_raw_api_object.add_raw_member("animations", animations_set,
                                                   "engine.ability.property.type.Animated")

            property_forward_ref = ForwardRef(line, property_ref)
            properties.update({
                api_objects["engine.ability.property.type.Animated"]: property_forward_ref
            })

            # Create custom civ graphics
            handled_graphics_set_ids = set()
            for civ_group in dataset.civ_groups.values():
                civ = civ_group.civ
                civ_id = civ_group.get_id()

                # Only proceed if the civ stores the unit in the line
                if current_unit_id not in civ["units"].value.keys():
                    continue

                civ_animation_id = civ["units"][current_unit_id]["attack_sprite_id"].value

                if civ_animation_id != ability_animation_id:
                    # Find the corresponding graphics set
                    graphics_set_id = -1
                    for set_id, items in gset_lookup_dict.items():
                        if civ_id in items[0]:
                            graphics_set_id = set_id
                            break

                    # Check if the object for the animation has been created before
                    obj_exists = graphics_set_id in handled_graphics_set_ids
                    if not obj_exists:
                        handled_graphics_set_ids.add(graphics_set_id)

                    obj_prefix = f"{gset_lookup_dict[graphics_set_id][1]}{ability_name}"
                    filename_prefix = (f"{command_lookup_dict[command_id][1]}_"
                                       f"{gset_lookup_dict[graphics_set_id][2]}_")
                    AoCAbilitySubprocessor.create_civ_animation(line,
                                                                civ_group,
                                                                civ_animation_id,
                                                                ability_ref,
                                                                obj_prefix,
                                                                filename_prefix,
                                                                obj_exists)

        # Command Sound
        if projectile == -1:
            ability_comm_sound_id = current_unit["command_sound_id"].value

        else:
            ability_comm_sound_id = -1

        if ability_comm_sound_id > -1:
            property_ref = f"{ability_ref}.CommandSound"
            property_raw_api_object = RawAPIObject(property_ref,
                                                   "CommandSound",
                                                   dataset.nyan_api_objects)
            property_raw_api_object.add_raw_parent("engine.ability.property.type.CommandSound")
            property_location = ForwardRef(line, ability_ref)
            property_raw_api_object.set_location(property_location)

            line.add_raw_api_object(property_raw_api_object)

            sounds_set = []

            if projectile == -1:
                sound_obj_prefix = ability_name

            else:
                sound_obj_prefix = "ProjectileAttack"

            sound_forward_ref = AoCAbilitySubprocessor.create_sound(line,
                                                                    ability_comm_sound_id,
                                                                    property_ref,
                                                                    sound_obj_prefix,
                                                                    "command_")
            sounds_set.append(sound_forward_ref)
            property_raw_api_object.add_raw_member("sounds", sounds_set,
                                                   "engine.ability.property.type.CommandSound")
            property_forward_ref = ForwardRef(line, property_ref)
            properties.update({
                api_objects["engine.ability.property.type.CommandSound"]: property_forward_ref
            })

        # Diplomacy settings
        property_ref = f"{ability_ref}.Diplomatic"
        property_raw_api_object = RawAPIObject(property_ref,
                                               "Diplomatic",
                                               dataset.nyan_api_objects)
        property_raw_api_object.add_raw_parent("engine.ability.property.type.Diplomatic")
        property_location = ForwardRef(line, ability_ref)
        property_raw_api_object.set_location(property_location)

        line.add_raw_api_object(property_raw_api_object)

        diplomatic_stances = [dataset.nyan_api_objects["engine.util.diplomatic_stance.type.Self"]]
        property_raw_api_object.add_raw_member("stances", diplomatic_stances,
                                               "engine.ability.property.type.Diplomatic")

        property_forward_ref = ForwardRef(line, property_ref)
        properties.update({
            api_objects["engine.ability.property.type.Diplomatic"]: property_forward_ref
        })

        ability_raw_api_object.add_raw_member("properties",
                                              properties,
                                              "engine.ability.Ability")

        if ranged:
            # Min range
            min_range = current_unit["weapon_range_min"].value
            ability_raw_api_object.add_raw_member("min_range",
                                                  min_range,
                                                  "engine.ability.type.RangedDiscreteEffect")

            # Max range
            max_range = current_unit["weapon_range_max"].value
            ability_raw_api_object.add_raw_member("max_range",
                                                  max_range,
                                                  "engine.ability.type.RangedDiscreteEffect")

        # Effects
        batch_ref = f"{ability_ref}.Batch"
        batch_raw_api_object = RawAPIObject(batch_ref, "Batch", dataset.nyan_api_objects)
        batch_raw_api_object.add_raw_parent("engine.util.effect_batch.type.UnorderedBatch")
        batch_location = ForwardRef(line, ability_ref)
        batch_raw_api_object.set_location(batch_location)

        line.add_raw_api_object(batch_raw_api_object)

        # Effects
        effects = []
        if command_id == 7:
            # Attack
            if projectile != 1:
                effects = AoCEffectSubprocessor.get_attack_effects(line, batch_ref)

            else:
                effects = AoCEffectSubprocessor.get_attack_effects(line, batch_ref, projectile=1)

        elif command_id == 104:
            # TODO: Convert
            # effects = AoCEffectSubprocessor.get_convert_effects(line, ability_ref)
            pass

        batch_raw_api_object.add_raw_member("effects",
                                            effects,
                                            "engine.util.effect_batch.EffectBatch")

        batch_forward_ref = ForwardRef(line, batch_ref)
        ability_raw_api_object.add_raw_member("batches",
                                              [batch_forward_ref],
                                              "engine.ability.type.ApplyDiscreteEffect")

        # Reload time
        if projectile == -1:
            reload_time = current_unit["attack_speed"].value

        else:
            reload_time = 0

        ability_raw_api_object.add_raw_member("reload_time",
                                              reload_time,
                                              "engine.ability.type.ApplyDiscreteEffect")

        # Application delay
        if projectile == -1:
            apply_graphic = dataset.genie_graphics[ability_animation_id]
            frame_rate = apply_graphic.get_frame_rate()
            frame_delay = current_unit["frame_delay"].value
            application_delay = frame_rate * frame_delay

        else:
            application_delay = 0

        ability_raw_api_object.add_raw_member("application_delay",
                                              application_delay,
                                              "engine.ability.type.ApplyDiscreteEffect")

        # Allowed types (all buildings/units)
        if command_id == 104:
            # Convert
            allowed_types = [
                dataset.pregen_nyan_objects["util.game_entity_type.types.Unit"].get_nyan_object()
            ]

        else:
            allowed_types = [
                dataset.pregen_nyan_objects["util.game_entity_type.types.Unit"].get_nyan_object(),
                dataset.pregen_nyan_objects["util.game_entity_type.types.Building"].get_nyan_object(
                )
            ]

        ability_raw_api_object.add_raw_member("allowed_types",
                                              allowed_types,
                                              "engine.ability.type.ApplyDiscreteEffect")

        if command_id == 104:
            # Convert
            blacklisted_entities = []
            for unit_line in dataset.unit_lines.values():
                if unit_line.has_command(104):
                    # Blacklist other monks
                    blacklisted_name = name_lookup_dict[unit_line.get_head_unit_id()][0]
                    blacklisted_entities.append(ForwardRef(unit_line, blacklisted_name))
                    continue

        else:
            blacklisted_entities = []

        ability_raw_api_object.add_raw_member("blacklisted_entities",
                                              blacklisted_entities,
                                              "engine.ability.type.ApplyDiscreteEffect")

        line.add_raw_api_object(ability_raw_api_object)

        ability_forward_ref = ForwardRef(line, ability_raw_api_object.get_id())

        return ability_forward_ref
Beispiel #11
0
    def regenerate_attribute_ability(line: GenieGameEntityGroup) -> ForwardRef:
        """
        Adds the RegenerateAttribute ability to a line.

        :param line: Unit/Building line that gets the ability.
        :type line: ...dataformat.converter_object.ConverterObjectGroup
        :returns: The forward references for the ability.
        :rtype: list
        """
        current_unit = line.get_head_unit()
        current_unit_id = line.get_head_unit_id()
        dataset = line.data

        attribute = None
        attribute_name = ""
        if current_unit_id == 125:
            # Monk; regenerates Faith
            attribute = dataset.pregen_nyan_objects[
                "util.attribute.types.Faith"].get_nyan_object()
            attribute_name = "Faith"

        elif current_unit_id == 692:
            # Berserk: regenerates Health
            attribute = dataset.pregen_nyan_objects[
                "util.attribute.types.Health"].get_nyan_object()
            attribute_name = "Health"

        else:
            return []

        name_lookup_dict = internal_name_lookups.get_entity_lookups(
            dataset.game_version)

        game_entity_name = name_lookup_dict[current_unit_id][0]

        ability_name = f"Regenerate{attribute_name}"
        ability_ref = f"{game_entity_name}.{ability_name}"
        ability_raw_api_object = RawAPIObject(ability_ref, ability_name,
                                              dataset.nyan_api_objects)
        ability_raw_api_object.add_raw_parent(
            "engine.ability.type.RegenerateAttribute")
        ability_location = ForwardRef(line, game_entity_name)
        ability_raw_api_object.set_location(ability_location)

        # Attribute rate
        # ===============================================================================
        rate_name = f"{attribute_name}Rate"
        rate_ref = f"{game_entity_name}.{ability_name}.{rate_name}"
        rate_raw_api_object = RawAPIObject(rate_ref, rate_name,
                                           dataset.nyan_api_objects)
        rate_raw_api_object.add_raw_parent(
            "engine.util.attribute.AttributeRate")
        rate_location = ForwardRef(line, ability_ref)
        rate_raw_api_object.set_location(rate_location)

        # Attribute
        rate_raw_api_object.add_raw_member(
            "type", attribute, "engine.util.attribute.AttributeRate")

        # Rate
        attribute_rate = 0
        if current_unit_id == 125:
            # stored in civ resources
            attribute_rate = dataset.genie_civs[0]["resources"][35].get_value()

        elif current_unit_id == 692:
            # stored in unit, but has to get converted to amount/second
            heal_timer = current_unit["heal_timer"].get_value()
            attribute_rate = 1 / heal_timer

        rate_raw_api_object.add_raw_member(
            "rate", attribute_rate, "engine.util.attribute.AttributeRate")

        line.add_raw_api_object(rate_raw_api_object)
        # ===============================================================================
        rate_forward_ref = ForwardRef(line, rate_ref)
        ability_raw_api_object.add_raw_member(
            "rate", rate_forward_ref,
            "engine.ability.type.RegenerateAttribute")

        line.add_raw_api_object(ability_raw_api_object)

        ability_forward_ref = ForwardRef(line, ability_raw_api_object.get_id())

        return [ability_forward_ref]