Skip to content

Commit

Permalink
Merge pull request #1648 from heinezen/feature/convert-move-mode
Browse files Browse the repository at this point in the history
Update converter for nyan API v0.5.0
  • Loading branch information
TheJJ authored Jul 28, 2024
2 parents 23502d5 + e599b1f commit 4a8b88d
Show file tree
Hide file tree
Showing 22 changed files with 445 additions and 264 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019-2023 the openage authors. See copying.md for legal info.
# Copyright 2019-2024 the openage authors. See copying.md for legal info.
#
# pylint: disable=too-many-instance-attributes,too-few-public-methods

Expand Down Expand Up @@ -28,7 +28,7 @@
AgeUpgrade, BuildingLineUpgrade, BuildingUnlock, CivBonus, GenieTechEffectBundleGroup, \
InitiatedTech, StatUpgrade, UnitLineUpgrade, UnitUnlock
from openage.convert.entity_object.conversion.aoc.genie_terrain import GenieTerrainObject, \
GenieTerrainGroup
GenieTerrainGroup, GenieTerrainRestriction
from openage.convert.entity_object.conversion.aoc.genie_unit import GenieUnitObject, \
GenieAmbientGroup, GenieBuildingLineGroup, GenieMonkGroup, GenieUnitLineGroup, \
GenieUnitTaskGroup, GenieUnitTransformGroup, GenieVariantGroup, GenieVillagerGroup, \
Expand Down Expand Up @@ -75,6 +75,7 @@ def __init__(self):
self.genie_graphics: dict[int, GenieGraphic] = {}
self.genie_sounds: dict[int, GenieSound] = {}
self.genie_terrains: dict[int, GenieTerrainObject] = {}
self.genie_terrain_restrictions: dict[int, GenieTerrainRestriction] = {}

# Phase 2: API-like objects
# ConverterObjectGroup types (things that will become
Expand Down
41 changes: 40 additions & 1 deletion openage/convert/entity_object/conversion/aoc/genie_terrain.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019-2022 the openage authors. See copying.md for legal info.
# Copyright 2019-2024 the openage authors. See copying.md for legal info.

"""
Contains structures and API-like objects for terrain from AoC.
Expand Down Expand Up @@ -94,3 +94,42 @@ def get_terrain(self) -> GenieTerrainObject:

def __repr__(self):
return f"GenieTerrainGroup<{self.get_id()}>"


class GenieTerrainRestriction(ConverterObject):
"""
Terrain restriction definition from a .dat file.
"""

__slots__ = ('data',)

def __init__(
self,
restriction_id: int,
full_data_set: GenieObjectContainer,
members: dict[str, ValueMember] = None
):
"""
Creates a new Genie terrain restriction object.
:param restriction_id: The index of the terrain restriction in the .dat file.
:param full_data_set: GenieObjectContainer instance that
contains all relevant data for the conversion
process.
"""
super().__init__(restriction_id, members=members)

self.data = full_data_set

def is_accessible(self, terrain_index: int) -> bool:
"""
Checks if a terrain is accessible by this restriction.
:param terrain_index: Index of the terrain.
"""
multiplier = self.members["accessible_dmgmultiplier"][terrain_index].value

return multiplier > 0

def __repr__(self):
return f"GenieTerrainRestriction<{self.get_id()}>"
205 changes: 92 additions & 113 deletions openage/convert/processor/conversion/aoc/ability_subprocessor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020-2023 the openage authors. See copying.md for legal info.
# Copyright 2020-2024 the openage authors. See copying.md for legal info.
#
# pylint: disable=too-many-public-methods,too-many-lines,too-many-locals
# pylint: disable=too-many-branches,too-many-statements,too-many-arguments
Expand Down Expand Up @@ -820,6 +820,65 @@ def collect_storage_ability(line: GenieGameEntityGroup) -> ForwardRef:

return ability_forward_ref

@ staticmethod
def collision_ability(line: GenieGameEntityGroup) -> ForwardRef:
"""
Adds the Collision 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}.Collision"
ability_raw_api_object = RawAPIObject(ability_ref, "Collision", dataset.nyan_api_objects)
ability_raw_api_object.add_raw_parent("engine.ability.type.Collision")
ability_location = ForwardRef(line, game_entity_name)
ability_raw_api_object.set_location(ability_location)

# Hitbox object
hitbox_name = f"{game_entity_name}.Collision.{game_entity_name}Hitbox"
hitbox_raw_api_object = RawAPIObject(hitbox_name,
f"{game_entity_name}Hitbox",
dataset.nyan_api_objects)
hitbox_raw_api_object.add_raw_parent("engine.util.hitbox.Hitbox")
hitbox_location = ForwardRef(line, ability_ref)
hitbox_raw_api_object.set_location(hitbox_location)

radius_x = current_unit["radius_x"].value
radius_y = current_unit["radius_y"].value
radius_z = current_unit["radius_z"].value

hitbox_raw_api_object.add_raw_member("radius_x",
radius_x,
"engine.util.hitbox.Hitbox")
hitbox_raw_api_object.add_raw_member("radius_y",
radius_y,
"engine.util.hitbox.Hitbox")
hitbox_raw_api_object.add_raw_member("radius_z",
radius_z,
"engine.util.hitbox.Hitbox")

hitbox_forward_ref = ForwardRef(line, hitbox_name)
ability_raw_api_object.add_raw_member("hitbox",
hitbox_forward_ref,
"engine.ability.type.Collision")

line.add_raw_api_object(hitbox_raw_api_object)
line.add_raw_api_object(ability_raw_api_object)

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

return ability_forward_ref

@staticmethod
def constructable_ability(line: GenieGameEntityGroup) -> ForwardRef:
"""
Expand Down Expand Up @@ -4015,65 +4074,6 @@ def herdable_ability(line: GenieGameEntityGroup) -> ForwardRef:

return ability_forward_ref

@ staticmethod
def hitbox_ability(line: GenieGameEntityGroup) -> ForwardRef:
"""
Adds the Hitbox 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}.Hitbox"
ability_raw_api_object = RawAPIObject(ability_ref, "Hitbox", dataset.nyan_api_objects)
ability_raw_api_object.add_raw_parent("engine.ability.type.Hitbox")
ability_location = ForwardRef(line, game_entity_name)
ability_raw_api_object.set_location(ability_location)

# Hitbox object
hitbox_name = f"{game_entity_name}.Hitbox.{game_entity_name}Hitbox"
hitbox_raw_api_object = RawAPIObject(hitbox_name,
f"{game_entity_name}Hitbox",
dataset.nyan_api_objects)
hitbox_raw_api_object.add_raw_parent("engine.util.hitbox.Hitbox")
hitbox_location = ForwardRef(line, ability_ref)
hitbox_raw_api_object.set_location(hitbox_location)

radius_x = current_unit["radius_x"].value
radius_y = current_unit["radius_y"].value
radius_z = current_unit["radius_z"].value

hitbox_raw_api_object.add_raw_member("radius_x",
radius_x,
"engine.util.hitbox.Hitbox")
hitbox_raw_api_object.add_raw_member("radius_y",
radius_y,
"engine.util.hitbox.Hitbox")
hitbox_raw_api_object.add_raw_member("radius_z",
radius_z,
"engine.util.hitbox.Hitbox")

hitbox_forward_ref = ForwardRef(line, hitbox_name)
ability_raw_api_object.add_raw_member("hitbox",
hitbox_forward_ref,
"engine.ability.type.Hitbox")

line.add_raw_api_object(hitbox_raw_api_object)
line.add_raw_api_object(ability_raw_api_object)

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

return ability_forward_ref

@ staticmethod
def idle_ability(line: GenieGameEntityGroup) -> ForwardRef:
"""
Expand Down Expand Up @@ -4526,6 +4526,19 @@ def move_ability(line: GenieGameEntityGroup) -> ForwardRef:

ability_raw_api_object.add_raw_member("modes", move_modes, "engine.ability.type.Move")

# Path type
path_type = dataset.pregen_nyan_objects["util.path.types.Land"].get_nyan_object()
restrictions = current_unit["terrain_restriction"].value
if restrictions in (0x00, 0x0C, 0x0E, 0x17):
# air units
path_type = dataset.pregen_nyan_objects["util.path.types.Air"].get_nyan_object()

elif restrictions in (0x03, 0x0D, 0x0F):
# ships
path_type = dataset.pregen_nyan_objects["util.path.types.Water"].get_nyan_object()

ability_raw_api_object.add_raw_member("path_type", path_type, "engine.ability.type.Move")

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

return ability_forward_ref
Expand Down Expand Up @@ -4619,6 +4632,10 @@ def move_projectile_ability(line: GenieGameEntityGroup, position: int = -1) -> F
]
ability_raw_api_object.add_raw_member("modes", move_modes, "engine.ability.type.Move")

# Path type
path_type = dataset.pregen_nyan_objects["util.path.types.Air"].get_nyan_object()
ability_raw_api_object.add_raw_member("path_type", path_type, "engine.ability.type.Move")

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

return ability_forward_ref
Expand Down Expand Up @@ -4757,9 +4774,9 @@ def overlay_terrain_ability(line: GenieGameEntityGroup) -> ForwardRef:
return ability_forward_ref

@ staticmethod
def passable_ability(line: GenieGameEntityGroup) -> ForwardRef:
def pathable_ability(line: GenieGameEntityGroup) -> ForwardRef:
"""
Adds the Passable ability to a line.
Adds the Pathable ability to a line.
:param line: Unit/Building line that gets the ability.
:type line: ...dataformat.converter_object.ConverterObjectGroup
Expand All @@ -4773,67 +4790,29 @@ def passable_ability(line: GenieGameEntityGroup) -> ForwardRef:

game_entity_name = name_lookup_dict[current_unit_id][0]

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

# Hitbox
hitbox_ref = f"{game_entity_name}.Hitbox.{game_entity_name}Hitbox"
hitbox_ref = f"{game_entity_name}.Collision.{game_entity_name}Hitbox"
hitbox_forward_ref = ForwardRef(line, hitbox_ref)
ability_raw_api_object.add_raw_member("hitbox",
hitbox_forward_ref,
"engine.ability.type.Passable")

# Passable mode
# =====================================================================================
mode_name = f"{game_entity_name}.Passable.PassableMode"
mode_raw_api_object = RawAPIObject(mode_name, "PassableMode", dataset.nyan_api_objects)
mode_parent = "engine.util.passable_mode.type.Normal"
if isinstance(line, GenieStackBuildingGroup):
if line.is_gate():
mode_parent = "engine.util.passable_mode.type.Gate"

mode_raw_api_object.add_raw_parent(mode_parent)
mode_location = ForwardRef(line, ability_ref)
mode_raw_api_object.set_location(mode_location)
"engine.ability.type.Pathable")

# Allowed types
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(),
dataset.pregen_nyan_objects["util.game_entity_type.types.Projectile"].get_nyan_object()
]
mode_raw_api_object.add_raw_member("allowed_types",
allowed_types,
"engine.util.passable_mode.PassableMode")

# Blacklisted entities
mode_raw_api_object.add_raw_member("blacklisted_entities",
[],
"engine.util.passable_mode.PassableMode")

if isinstance(line, GenieStackBuildingGroup):
if line.is_gate():
# Let friendly and own units pass through gate
stances = [
dataset.pregen_nyan_objects["util.diplomatic_stance.types.Friendly"].get_nyan_object(
),
dataset.nyan_api_objects["engine.util.diplomatic_stance.type.Self"]
]
mode_raw_api_object.add_raw_member("stances",
stances,
mode_parent)

line.add_raw_api_object(mode_raw_api_object)
# =====================================================================================
mode_forward_ref = ForwardRef(line, mode_name)
ability_raw_api_object.add_raw_member("mode",
mode_forward_ref,
"engine.ability.type.Passable")
# Costs
path_costs = {
dataset.pregen_nyan_objects["util.path.types.Land"].get_nyan_object(): 255, # impassable
dataset.pregen_nyan_objects["util.path.types.Water"].get_nyan_object(): 255, # impassable
}
ability_raw_api_object.add_raw_member("path_costs",
path_costs,
"engine.ability.type.Pathable")

line.add_raw_api_object(ability_raw_api_object)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020-2023 the openage authors. See copying.md for legal info.
# Copyright 2020-2024 the openage authors. See copying.md for legal info.
#
# pylint: disable=too-many-locals,too-many-branches,too-few-public-methods,too-many-statements

Expand Down Expand Up @@ -198,7 +198,7 @@ def _set_static_aliases(modpack: Modpack, import_tree: ImportTree) -> None:
import_tree.add_alias(("engine", "util", "logic", "literal_scope", "type"), "literal_scope")
import_tree.add_alias(("engine", "util", "patch"), "patch")
import_tree.add_alias(("engine", "util", "patch", "property", "type"), "patch_prop")
import_tree.add_alias(("engine", "util", "passable_mode", "type"), "passable_mode")
import_tree.add_alias(("engine", "util", "path_type"), "path_type")
import_tree.add_alias(("engine", "util", "payment_mode", "type"), "payment_mode")
import_tree.add_alias(("engine", "util", "placement_mode", "type"), "placement_mode")
import_tree.add_alias(("engine", "util", "price_mode", "type"), "price_mode")
Expand Down Expand Up @@ -323,6 +323,10 @@ def _set_static_aliases(modpack: Modpack, import_tree: ImportTree) -> None:
"garrison_empty"),
"empty_garrison_condition"
)
import_tree.add_alias(
(modpack.name, "data", "util", "path_type", "types"),
prefix + "path_type"
)
import_tree.add_alias(
(modpack.name, "data", "util", "resource", "market_trading"),
prefix + "market_trading"
Expand Down
Loading

0 comments on commit 4a8b88d

Please sign in to comment.