From ddf298be5679aaf363a86f43b43cae115715c5a7 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:34:46 +0100 Subject: [PATCH 001/126] fast64_internal/oot -> fast64_internal/z64 --- __init__.py | 6 +++--- fast64_internal/__init__.py | 2 +- fast64_internal/{oot => z64}/README.md | 0 fast64_internal/{oot => z64}/__init__.py | 0 fast64_internal/{oot => z64}/actor/operators.py | 0 fast64_internal/{oot => z64}/actor/properties.py | 0 fast64_internal/{oot => z64}/animation/exporter/__init__.py | 0 fast64_internal/{oot => z64}/animation/exporter/classes.py | 0 .../{oot => z64}/animation/exporter/functions.py | 0 fast64_internal/{oot => z64}/animation/importer/__init__.py | 0 .../{oot => z64}/animation/importer/functions.py | 0 fast64_internal/{oot => z64}/animation/operators.py | 0 fast64_internal/{oot => z64}/animation/panels.py | 0 fast64_internal/{oot => z64}/animation/properties.py | 0 fast64_internal/{oot => z64}/collision/constants.py | 0 fast64_internal/{oot => z64}/collision/exporter/__init__.py | 0 fast64_internal/{oot => z64}/collision/exporter/classes.py | 0 .../{oot => z64}/collision/exporter/functions.py | 0 .../{oot => z64}/collision/exporter/to_c/__init__.py | 0 .../{oot => z64}/collision/exporter/to_c/collision.py | 0 fast64_internal/{oot => z64}/collision/operators.py | 0 fast64_internal/{oot => z64}/collision/panels.py | 0 fast64_internal/{oot => z64}/collision/properties.py | 0 fast64_internal/{oot => z64}/cutscene/classes.py | 0 fast64_internal/{oot => z64}/cutscene/constants.py | 0 fast64_internal/{oot => z64}/cutscene/exporter/__init__.py | 0 fast64_internal/{oot => z64}/cutscene/exporter/classes.py | 0 fast64_internal/{oot => z64}/cutscene/exporter/functions.py | 0 fast64_internal/{oot => z64}/cutscene/importer/__init__.py | 0 fast64_internal/{oot => z64}/cutscene/importer/classes.py | 0 fast64_internal/{oot => z64}/cutscene/importer/functions.py | 0 fast64_internal/{oot => z64}/cutscene/motion/operators.py | 0 fast64_internal/{oot => z64}/cutscene/motion/panels.py | 0 fast64_internal/{oot => z64}/cutscene/motion/preview.py | 0 fast64_internal/{oot => z64}/cutscene/motion/properties.py | 0 fast64_internal/{oot => z64}/cutscene/motion/utility.py | 0 fast64_internal/{oot => z64}/cutscene/operators.py | 0 fast64_internal/{oot => z64}/cutscene/panels.py | 0 fast64_internal/{oot => z64}/cutscene/preview.py | 0 fast64_internal/{oot => z64}/cutscene/properties.py | 0 fast64_internal/{oot => z64}/cutscene_docs.md | 0 fast64_internal/{oot => z64}/data/__init__.py | 0 fast64_internal/{oot => z64}/data/oot_actor_data.py | 0 fast64_internal/{oot => z64}/data/oot_data.py | 0 fast64_internal/{oot => z64}/data/oot_enum_data.py | 0 fast64_internal/{oot => z64}/data/oot_getters.py | 0 fast64_internal/{oot => z64}/data/oot_object_data.py | 0 fast64_internal/{oot => z64}/data/xml/ActorList.xml | 0 fast64_internal/{oot => z64}/data/xml/EnumData.xml | 0 fast64_internal/{oot => z64}/data/xml/ObjectList.xml | 0 fast64_internal/{oot => z64}/exporter/__init__.py | 0 fast64_internal/{oot => z64}/exporter/actor.py | 0 fast64_internal/{oot => z64}/exporter/collision/__init__.py | 0 fast64_internal/{oot => z64}/exporter/collision/camera.py | 0 fast64_internal/{oot => z64}/exporter/collision/polygons.py | 0 fast64_internal/{oot => z64}/exporter/collision/surface.py | 0 fast64_internal/{oot => z64}/exporter/collision/vertex.py | 0 fast64_internal/{oot => z64}/exporter/collision/waterbox.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/__init__.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/actor_cue.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/camera.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/common.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/data.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/misc.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/seq.py | 0 fast64_internal/{oot => z64}/exporter/cutscene/text.py | 0 .../{oot => z64}/exporter/decomp_edit/__init__.py | 0 fast64_internal/{oot => z64}/exporter/decomp_edit/config.py | 0 .../{oot => z64}/exporter/decomp_edit/scene_table.py | 0 fast64_internal/{oot => z64}/exporter/decomp_edit/spec.py | 0 fast64_internal/{oot => z64}/exporter/file.py | 0 fast64_internal/{oot => z64}/exporter/room/__init__.py | 0 fast64_internal/{oot => z64}/exporter/room/header.py | 0 fast64_internal/{oot => z64}/exporter/room/shape.py | 0 fast64_internal/{oot => z64}/exporter/scene/__init__.py | 0 fast64_internal/{oot => z64}/exporter/scene/actors.py | 0 fast64_internal/{oot => z64}/exporter/scene/general.py | 0 fast64_internal/{oot => z64}/exporter/scene/header.py | 0 fast64_internal/{oot => z64}/exporter/scene/pathways.py | 0 fast64_internal/{oot => z64}/exporter/scene/rooms.py | 0 fast64_internal/{oot => z64}/exporter/utility.py | 0 fast64_internal/{oot => z64}/f3d/operators.py | 0 fast64_internal/{oot => z64}/f3d/panels.py | 0 fast64_internal/{oot => z64}/f3d/properties.py | 0 fast64_internal/{oot => z64}/file_settings.py | 0 fast64_internal/{oot => z64}/importer/__init__.py | 0 fast64_internal/{oot => z64}/importer/actor.py | 0 fast64_internal/{oot => z64}/importer/classes.py | 0 fast64_internal/{oot => z64}/importer/constants.py | 0 fast64_internal/{oot => z64}/importer/room_header.py | 0 fast64_internal/{oot => z64}/importer/room_shape.py | 0 fast64_internal/{oot => z64}/importer/scene.py | 0 fast64_internal/{oot => z64}/importer/scene_collision.py | 0 fast64_internal/{oot => z64}/importer/scene_header.py | 0 fast64_internal/{oot => z64}/importer/scene_pathways.py | 0 fast64_internal/{oot => z64}/importer/utility.py | 0 fast64_internal/{oot => z64}/oot_constants.py | 0 fast64_internal/{oot => z64}/oot_f3d_writer.py | 0 fast64_internal/{oot => z64}/oot_model_classes.py | 0 fast64_internal/{oot => z64}/oot_object.py | 0 fast64_internal/{oot => z64}/oot_spline.py | 0 fast64_internal/{oot => z64}/oot_texture_array.py | 0 fast64_internal/{oot => z64}/oot_upgrade.py | 0 fast64_internal/{oot => z64}/oot_utility.py | 0 fast64_internal/{oot => z64}/props_panel_main.py | 0 fast64_internal/{oot => z64}/room/operators.py | 0 fast64_internal/{oot => z64}/room/properties.py | 0 fast64_internal/{oot => z64}/scene/operators.py | 0 fast64_internal/{oot => z64}/scene/panels.py | 0 fast64_internal/{oot => z64}/scene/properties.py | 0 fast64_internal/{oot => z64}/skeleton/constants.py | 0 fast64_internal/{oot => z64}/skeleton/exporter/__init__.py | 0 fast64_internal/{oot => z64}/skeleton/exporter/classes.py | 0 fast64_internal/{oot => z64}/skeleton/exporter/functions.py | 0 fast64_internal/{oot => z64}/skeleton/importer/__init__.py | 0 fast64_internal/{oot => z64}/skeleton/importer/functions.py | 0 fast64_internal/{oot => z64}/skeleton/operators.py | 0 fast64_internal/{oot => z64}/skeleton/panels.py | 0 fast64_internal/{oot => z64}/skeleton/properties.py | 0 fast64_internal/{oot => z64}/skeleton/utility.py | 0 fast64_internal/{oot => z64}/spline/panels.py | 0 fast64_internal/{oot => z64}/spline/properties.py | 0 fast64_internal/{oot => z64}/tools/__init__.py | 0 fast64_internal/{oot => z64}/tools/operators.py | 0 fast64_internal/{oot => z64}/tools/panel.py | 0 fast64_internal/{oot => z64}/tools/quick_import.py | 0 126 files changed, 4 insertions(+), 4 deletions(-) rename fast64_internal/{oot => z64}/README.md (100%) rename fast64_internal/{oot => z64}/__init__.py (100%) rename fast64_internal/{oot => z64}/actor/operators.py (100%) rename fast64_internal/{oot => z64}/actor/properties.py (100%) rename fast64_internal/{oot => z64}/animation/exporter/__init__.py (100%) rename fast64_internal/{oot => z64}/animation/exporter/classes.py (100%) rename fast64_internal/{oot => z64}/animation/exporter/functions.py (100%) rename fast64_internal/{oot => z64}/animation/importer/__init__.py (100%) rename fast64_internal/{oot => z64}/animation/importer/functions.py (100%) rename fast64_internal/{oot => z64}/animation/operators.py (100%) rename fast64_internal/{oot => z64}/animation/panels.py (100%) rename fast64_internal/{oot => z64}/animation/properties.py (100%) rename fast64_internal/{oot => z64}/collision/constants.py (100%) rename fast64_internal/{oot => z64}/collision/exporter/__init__.py (100%) rename fast64_internal/{oot => z64}/collision/exporter/classes.py (100%) rename fast64_internal/{oot => z64}/collision/exporter/functions.py (100%) rename fast64_internal/{oot => z64}/collision/exporter/to_c/__init__.py (100%) rename fast64_internal/{oot => z64}/collision/exporter/to_c/collision.py (100%) rename fast64_internal/{oot => z64}/collision/operators.py (100%) rename fast64_internal/{oot => z64}/collision/panels.py (100%) rename fast64_internal/{oot => z64}/collision/properties.py (100%) rename fast64_internal/{oot => z64}/cutscene/classes.py (100%) rename fast64_internal/{oot => z64}/cutscene/constants.py (100%) rename fast64_internal/{oot => z64}/cutscene/exporter/__init__.py (100%) rename fast64_internal/{oot => z64}/cutscene/exporter/classes.py (100%) rename fast64_internal/{oot => z64}/cutscene/exporter/functions.py (100%) rename fast64_internal/{oot => z64}/cutscene/importer/__init__.py (100%) rename fast64_internal/{oot => z64}/cutscene/importer/classes.py (100%) rename fast64_internal/{oot => z64}/cutscene/importer/functions.py (100%) rename fast64_internal/{oot => z64}/cutscene/motion/operators.py (100%) rename fast64_internal/{oot => z64}/cutscene/motion/panels.py (100%) rename fast64_internal/{oot => z64}/cutscene/motion/preview.py (100%) rename fast64_internal/{oot => z64}/cutscene/motion/properties.py (100%) rename fast64_internal/{oot => z64}/cutscene/motion/utility.py (100%) rename fast64_internal/{oot => z64}/cutscene/operators.py (100%) rename fast64_internal/{oot => z64}/cutscene/panels.py (100%) rename fast64_internal/{oot => z64}/cutscene/preview.py (100%) rename fast64_internal/{oot => z64}/cutscene/properties.py (100%) rename fast64_internal/{oot => z64}/cutscene_docs.md (100%) rename fast64_internal/{oot => z64}/data/__init__.py (100%) rename fast64_internal/{oot => z64}/data/oot_actor_data.py (100%) rename fast64_internal/{oot => z64}/data/oot_data.py (100%) rename fast64_internal/{oot => z64}/data/oot_enum_data.py (100%) rename fast64_internal/{oot => z64}/data/oot_getters.py (100%) rename fast64_internal/{oot => z64}/data/oot_object_data.py (100%) rename fast64_internal/{oot => z64}/data/xml/ActorList.xml (100%) rename fast64_internal/{oot => z64}/data/xml/EnumData.xml (100%) rename fast64_internal/{oot => z64}/data/xml/ObjectList.xml (100%) rename fast64_internal/{oot => z64}/exporter/__init__.py (100%) rename fast64_internal/{oot => z64}/exporter/actor.py (100%) rename fast64_internal/{oot => z64}/exporter/collision/__init__.py (100%) rename fast64_internal/{oot => z64}/exporter/collision/camera.py (100%) rename fast64_internal/{oot => z64}/exporter/collision/polygons.py (100%) rename fast64_internal/{oot => z64}/exporter/collision/surface.py (100%) rename fast64_internal/{oot => z64}/exporter/collision/vertex.py (100%) rename fast64_internal/{oot => z64}/exporter/collision/waterbox.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/__init__.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/actor_cue.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/camera.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/common.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/data.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/misc.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/seq.py (100%) rename fast64_internal/{oot => z64}/exporter/cutscene/text.py (100%) rename fast64_internal/{oot => z64}/exporter/decomp_edit/__init__.py (100%) rename fast64_internal/{oot => z64}/exporter/decomp_edit/config.py (100%) rename fast64_internal/{oot => z64}/exporter/decomp_edit/scene_table.py (100%) rename fast64_internal/{oot => z64}/exporter/decomp_edit/spec.py (100%) rename fast64_internal/{oot => z64}/exporter/file.py (100%) rename fast64_internal/{oot => z64}/exporter/room/__init__.py (100%) rename fast64_internal/{oot => z64}/exporter/room/header.py (100%) rename fast64_internal/{oot => z64}/exporter/room/shape.py (100%) rename fast64_internal/{oot => z64}/exporter/scene/__init__.py (100%) rename fast64_internal/{oot => z64}/exporter/scene/actors.py (100%) rename fast64_internal/{oot => z64}/exporter/scene/general.py (100%) rename fast64_internal/{oot => z64}/exporter/scene/header.py (100%) rename fast64_internal/{oot => z64}/exporter/scene/pathways.py (100%) rename fast64_internal/{oot => z64}/exporter/scene/rooms.py (100%) rename fast64_internal/{oot => z64}/exporter/utility.py (100%) rename fast64_internal/{oot => z64}/f3d/operators.py (100%) rename fast64_internal/{oot => z64}/f3d/panels.py (100%) rename fast64_internal/{oot => z64}/f3d/properties.py (100%) rename fast64_internal/{oot => z64}/file_settings.py (100%) rename fast64_internal/{oot => z64}/importer/__init__.py (100%) rename fast64_internal/{oot => z64}/importer/actor.py (100%) rename fast64_internal/{oot => z64}/importer/classes.py (100%) rename fast64_internal/{oot => z64}/importer/constants.py (100%) rename fast64_internal/{oot => z64}/importer/room_header.py (100%) rename fast64_internal/{oot => z64}/importer/room_shape.py (100%) rename fast64_internal/{oot => z64}/importer/scene.py (100%) rename fast64_internal/{oot => z64}/importer/scene_collision.py (100%) rename fast64_internal/{oot => z64}/importer/scene_header.py (100%) rename fast64_internal/{oot => z64}/importer/scene_pathways.py (100%) rename fast64_internal/{oot => z64}/importer/utility.py (100%) rename fast64_internal/{oot => z64}/oot_constants.py (100%) rename fast64_internal/{oot => z64}/oot_f3d_writer.py (100%) rename fast64_internal/{oot => z64}/oot_model_classes.py (100%) rename fast64_internal/{oot => z64}/oot_object.py (100%) rename fast64_internal/{oot => z64}/oot_spline.py (100%) rename fast64_internal/{oot => z64}/oot_texture_array.py (100%) rename fast64_internal/{oot => z64}/oot_upgrade.py (100%) rename fast64_internal/{oot => z64}/oot_utility.py (100%) rename fast64_internal/{oot => z64}/props_panel_main.py (100%) rename fast64_internal/{oot => z64}/room/operators.py (100%) rename fast64_internal/{oot => z64}/room/properties.py (100%) rename fast64_internal/{oot => z64}/scene/operators.py (100%) rename fast64_internal/{oot => z64}/scene/panels.py (100%) rename fast64_internal/{oot => z64}/scene/properties.py (100%) rename fast64_internal/{oot => z64}/skeleton/constants.py (100%) rename fast64_internal/{oot => z64}/skeleton/exporter/__init__.py (100%) rename fast64_internal/{oot => z64}/skeleton/exporter/classes.py (100%) rename fast64_internal/{oot => z64}/skeleton/exporter/functions.py (100%) rename fast64_internal/{oot => z64}/skeleton/importer/__init__.py (100%) rename fast64_internal/{oot => z64}/skeleton/importer/functions.py (100%) rename fast64_internal/{oot => z64}/skeleton/operators.py (100%) rename fast64_internal/{oot => z64}/skeleton/panels.py (100%) rename fast64_internal/{oot => z64}/skeleton/properties.py (100%) rename fast64_internal/{oot => z64}/skeleton/utility.py (100%) rename fast64_internal/{oot => z64}/spline/panels.py (100%) rename fast64_internal/{oot => z64}/spline/properties.py (100%) rename fast64_internal/{oot => z64}/tools/__init__.py (100%) rename fast64_internal/{oot => z64}/tools/operators.py (100%) rename fast64_internal/{oot => z64}/tools/panel.py (100%) rename fast64_internal/{oot => z64}/tools/quick_import.py (100%) diff --git a/__init__.py b/__init__.py index d822f902b..c7d015292 100644 --- a/__init__.py +++ b/__init__.py @@ -19,9 +19,9 @@ from .fast64_internal.sm64.sm64_geolayout_bone import SM64_BoneProperties from .fast64_internal.sm64.sm64_objects import SM64_ObjectProperties -from .fast64_internal.oot import OOT_Properties, oot_register, oot_unregister -from .fast64_internal.oot.oot_constants import oot_world_defaults -from .fast64_internal.oot.props_panel_main import OOT_ObjectProperties +from .fast64_internal.z64 import OOT_Properties, oot_register, oot_unregister +from .fast64_internal.z64.oot_constants import oot_world_defaults +from .fast64_internal.z64.props_panel_main import OOT_ObjectProperties from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister diff --git a/fast64_internal/__init__.py b/fast64_internal/__init__.py index 6bb605c2a..6e72454f6 100644 --- a/fast64_internal/__init__.py +++ b/fast64_internal/__init__.py @@ -1,5 +1,5 @@ from .f3d_material_converter import * from .f3d import * from .sm64 import * -from .oot import * # is this really needed? +from .z64 import * # is this really needed? from .panels import * diff --git a/fast64_internal/oot/README.md b/fast64_internal/z64/README.md similarity index 100% rename from fast64_internal/oot/README.md rename to fast64_internal/z64/README.md diff --git a/fast64_internal/oot/__init__.py b/fast64_internal/z64/__init__.py similarity index 100% rename from fast64_internal/oot/__init__.py rename to fast64_internal/z64/__init__.py diff --git a/fast64_internal/oot/actor/operators.py b/fast64_internal/z64/actor/operators.py similarity index 100% rename from fast64_internal/oot/actor/operators.py rename to fast64_internal/z64/actor/operators.py diff --git a/fast64_internal/oot/actor/properties.py b/fast64_internal/z64/actor/properties.py similarity index 100% rename from fast64_internal/oot/actor/properties.py rename to fast64_internal/z64/actor/properties.py diff --git a/fast64_internal/oot/animation/exporter/__init__.py b/fast64_internal/z64/animation/exporter/__init__.py similarity index 100% rename from fast64_internal/oot/animation/exporter/__init__.py rename to fast64_internal/z64/animation/exporter/__init__.py diff --git a/fast64_internal/oot/animation/exporter/classes.py b/fast64_internal/z64/animation/exporter/classes.py similarity index 100% rename from fast64_internal/oot/animation/exporter/classes.py rename to fast64_internal/z64/animation/exporter/classes.py diff --git a/fast64_internal/oot/animation/exporter/functions.py b/fast64_internal/z64/animation/exporter/functions.py similarity index 100% rename from fast64_internal/oot/animation/exporter/functions.py rename to fast64_internal/z64/animation/exporter/functions.py diff --git a/fast64_internal/oot/animation/importer/__init__.py b/fast64_internal/z64/animation/importer/__init__.py similarity index 100% rename from fast64_internal/oot/animation/importer/__init__.py rename to fast64_internal/z64/animation/importer/__init__.py diff --git a/fast64_internal/oot/animation/importer/functions.py b/fast64_internal/z64/animation/importer/functions.py similarity index 100% rename from fast64_internal/oot/animation/importer/functions.py rename to fast64_internal/z64/animation/importer/functions.py diff --git a/fast64_internal/oot/animation/operators.py b/fast64_internal/z64/animation/operators.py similarity index 100% rename from fast64_internal/oot/animation/operators.py rename to fast64_internal/z64/animation/operators.py diff --git a/fast64_internal/oot/animation/panels.py b/fast64_internal/z64/animation/panels.py similarity index 100% rename from fast64_internal/oot/animation/panels.py rename to fast64_internal/z64/animation/panels.py diff --git a/fast64_internal/oot/animation/properties.py b/fast64_internal/z64/animation/properties.py similarity index 100% rename from fast64_internal/oot/animation/properties.py rename to fast64_internal/z64/animation/properties.py diff --git a/fast64_internal/oot/collision/constants.py b/fast64_internal/z64/collision/constants.py similarity index 100% rename from fast64_internal/oot/collision/constants.py rename to fast64_internal/z64/collision/constants.py diff --git a/fast64_internal/oot/collision/exporter/__init__.py b/fast64_internal/z64/collision/exporter/__init__.py similarity index 100% rename from fast64_internal/oot/collision/exporter/__init__.py rename to fast64_internal/z64/collision/exporter/__init__.py diff --git a/fast64_internal/oot/collision/exporter/classes.py b/fast64_internal/z64/collision/exporter/classes.py similarity index 100% rename from fast64_internal/oot/collision/exporter/classes.py rename to fast64_internal/z64/collision/exporter/classes.py diff --git a/fast64_internal/oot/collision/exporter/functions.py b/fast64_internal/z64/collision/exporter/functions.py similarity index 100% rename from fast64_internal/oot/collision/exporter/functions.py rename to fast64_internal/z64/collision/exporter/functions.py diff --git a/fast64_internal/oot/collision/exporter/to_c/__init__.py b/fast64_internal/z64/collision/exporter/to_c/__init__.py similarity index 100% rename from fast64_internal/oot/collision/exporter/to_c/__init__.py rename to fast64_internal/z64/collision/exporter/to_c/__init__.py diff --git a/fast64_internal/oot/collision/exporter/to_c/collision.py b/fast64_internal/z64/collision/exporter/to_c/collision.py similarity index 100% rename from fast64_internal/oot/collision/exporter/to_c/collision.py rename to fast64_internal/z64/collision/exporter/to_c/collision.py diff --git a/fast64_internal/oot/collision/operators.py b/fast64_internal/z64/collision/operators.py similarity index 100% rename from fast64_internal/oot/collision/operators.py rename to fast64_internal/z64/collision/operators.py diff --git a/fast64_internal/oot/collision/panels.py b/fast64_internal/z64/collision/panels.py similarity index 100% rename from fast64_internal/oot/collision/panels.py rename to fast64_internal/z64/collision/panels.py diff --git a/fast64_internal/oot/collision/properties.py b/fast64_internal/z64/collision/properties.py similarity index 100% rename from fast64_internal/oot/collision/properties.py rename to fast64_internal/z64/collision/properties.py diff --git a/fast64_internal/oot/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py similarity index 100% rename from fast64_internal/oot/cutscene/classes.py rename to fast64_internal/z64/cutscene/classes.py diff --git a/fast64_internal/oot/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py similarity index 100% rename from fast64_internal/oot/cutscene/constants.py rename to fast64_internal/z64/cutscene/constants.py diff --git a/fast64_internal/oot/cutscene/exporter/__init__.py b/fast64_internal/z64/cutscene/exporter/__init__.py similarity index 100% rename from fast64_internal/oot/cutscene/exporter/__init__.py rename to fast64_internal/z64/cutscene/exporter/__init__.py diff --git a/fast64_internal/oot/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py similarity index 100% rename from fast64_internal/oot/cutscene/exporter/classes.py rename to fast64_internal/z64/cutscene/exporter/classes.py diff --git a/fast64_internal/oot/cutscene/exporter/functions.py b/fast64_internal/z64/cutscene/exporter/functions.py similarity index 100% rename from fast64_internal/oot/cutscene/exporter/functions.py rename to fast64_internal/z64/cutscene/exporter/functions.py diff --git a/fast64_internal/oot/cutscene/importer/__init__.py b/fast64_internal/z64/cutscene/importer/__init__.py similarity index 100% rename from fast64_internal/oot/cutscene/importer/__init__.py rename to fast64_internal/z64/cutscene/importer/__init__.py diff --git a/fast64_internal/oot/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py similarity index 100% rename from fast64_internal/oot/cutscene/importer/classes.py rename to fast64_internal/z64/cutscene/importer/classes.py diff --git a/fast64_internal/oot/cutscene/importer/functions.py b/fast64_internal/z64/cutscene/importer/functions.py similarity index 100% rename from fast64_internal/oot/cutscene/importer/functions.py rename to fast64_internal/z64/cutscene/importer/functions.py diff --git a/fast64_internal/oot/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py similarity index 100% rename from fast64_internal/oot/cutscene/motion/operators.py rename to fast64_internal/z64/cutscene/motion/operators.py diff --git a/fast64_internal/oot/cutscene/motion/panels.py b/fast64_internal/z64/cutscene/motion/panels.py similarity index 100% rename from fast64_internal/oot/cutscene/motion/panels.py rename to fast64_internal/z64/cutscene/motion/panels.py diff --git a/fast64_internal/oot/cutscene/motion/preview.py b/fast64_internal/z64/cutscene/motion/preview.py similarity index 100% rename from fast64_internal/oot/cutscene/motion/preview.py rename to fast64_internal/z64/cutscene/motion/preview.py diff --git a/fast64_internal/oot/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py similarity index 100% rename from fast64_internal/oot/cutscene/motion/properties.py rename to fast64_internal/z64/cutscene/motion/properties.py diff --git a/fast64_internal/oot/cutscene/motion/utility.py b/fast64_internal/z64/cutscene/motion/utility.py similarity index 100% rename from fast64_internal/oot/cutscene/motion/utility.py rename to fast64_internal/z64/cutscene/motion/utility.py diff --git a/fast64_internal/oot/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py similarity index 100% rename from fast64_internal/oot/cutscene/operators.py rename to fast64_internal/z64/cutscene/operators.py diff --git a/fast64_internal/oot/cutscene/panels.py b/fast64_internal/z64/cutscene/panels.py similarity index 100% rename from fast64_internal/oot/cutscene/panels.py rename to fast64_internal/z64/cutscene/panels.py diff --git a/fast64_internal/oot/cutscene/preview.py b/fast64_internal/z64/cutscene/preview.py similarity index 100% rename from fast64_internal/oot/cutscene/preview.py rename to fast64_internal/z64/cutscene/preview.py diff --git a/fast64_internal/oot/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py similarity index 100% rename from fast64_internal/oot/cutscene/properties.py rename to fast64_internal/z64/cutscene/properties.py diff --git a/fast64_internal/oot/cutscene_docs.md b/fast64_internal/z64/cutscene_docs.md similarity index 100% rename from fast64_internal/oot/cutscene_docs.md rename to fast64_internal/z64/cutscene_docs.md diff --git a/fast64_internal/oot/data/__init__.py b/fast64_internal/z64/data/__init__.py similarity index 100% rename from fast64_internal/oot/data/__init__.py rename to fast64_internal/z64/data/__init__.py diff --git a/fast64_internal/oot/data/oot_actor_data.py b/fast64_internal/z64/data/oot_actor_data.py similarity index 100% rename from fast64_internal/oot/data/oot_actor_data.py rename to fast64_internal/z64/data/oot_actor_data.py diff --git a/fast64_internal/oot/data/oot_data.py b/fast64_internal/z64/data/oot_data.py similarity index 100% rename from fast64_internal/oot/data/oot_data.py rename to fast64_internal/z64/data/oot_data.py diff --git a/fast64_internal/oot/data/oot_enum_data.py b/fast64_internal/z64/data/oot_enum_data.py similarity index 100% rename from fast64_internal/oot/data/oot_enum_data.py rename to fast64_internal/z64/data/oot_enum_data.py diff --git a/fast64_internal/oot/data/oot_getters.py b/fast64_internal/z64/data/oot_getters.py similarity index 100% rename from fast64_internal/oot/data/oot_getters.py rename to fast64_internal/z64/data/oot_getters.py diff --git a/fast64_internal/oot/data/oot_object_data.py b/fast64_internal/z64/data/oot_object_data.py similarity index 100% rename from fast64_internal/oot/data/oot_object_data.py rename to fast64_internal/z64/data/oot_object_data.py diff --git a/fast64_internal/oot/data/xml/ActorList.xml b/fast64_internal/z64/data/xml/ActorList.xml similarity index 100% rename from fast64_internal/oot/data/xml/ActorList.xml rename to fast64_internal/z64/data/xml/ActorList.xml diff --git a/fast64_internal/oot/data/xml/EnumData.xml b/fast64_internal/z64/data/xml/EnumData.xml similarity index 100% rename from fast64_internal/oot/data/xml/EnumData.xml rename to fast64_internal/z64/data/xml/EnumData.xml diff --git a/fast64_internal/oot/data/xml/ObjectList.xml b/fast64_internal/z64/data/xml/ObjectList.xml similarity index 100% rename from fast64_internal/oot/data/xml/ObjectList.xml rename to fast64_internal/z64/data/xml/ObjectList.xml diff --git a/fast64_internal/oot/exporter/__init__.py b/fast64_internal/z64/exporter/__init__.py similarity index 100% rename from fast64_internal/oot/exporter/__init__.py rename to fast64_internal/z64/exporter/__init__.py diff --git a/fast64_internal/oot/exporter/actor.py b/fast64_internal/z64/exporter/actor.py similarity index 100% rename from fast64_internal/oot/exporter/actor.py rename to fast64_internal/z64/exporter/actor.py diff --git a/fast64_internal/oot/exporter/collision/__init__.py b/fast64_internal/z64/exporter/collision/__init__.py similarity index 100% rename from fast64_internal/oot/exporter/collision/__init__.py rename to fast64_internal/z64/exporter/collision/__init__.py diff --git a/fast64_internal/oot/exporter/collision/camera.py b/fast64_internal/z64/exporter/collision/camera.py similarity index 100% rename from fast64_internal/oot/exporter/collision/camera.py rename to fast64_internal/z64/exporter/collision/camera.py diff --git a/fast64_internal/oot/exporter/collision/polygons.py b/fast64_internal/z64/exporter/collision/polygons.py similarity index 100% rename from fast64_internal/oot/exporter/collision/polygons.py rename to fast64_internal/z64/exporter/collision/polygons.py diff --git a/fast64_internal/oot/exporter/collision/surface.py b/fast64_internal/z64/exporter/collision/surface.py similarity index 100% rename from fast64_internal/oot/exporter/collision/surface.py rename to fast64_internal/z64/exporter/collision/surface.py diff --git a/fast64_internal/oot/exporter/collision/vertex.py b/fast64_internal/z64/exporter/collision/vertex.py similarity index 100% rename from fast64_internal/oot/exporter/collision/vertex.py rename to fast64_internal/z64/exporter/collision/vertex.py diff --git a/fast64_internal/oot/exporter/collision/waterbox.py b/fast64_internal/z64/exporter/collision/waterbox.py similarity index 100% rename from fast64_internal/oot/exporter/collision/waterbox.py rename to fast64_internal/z64/exporter/collision/waterbox.py diff --git a/fast64_internal/oot/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/__init__.py rename to fast64_internal/z64/exporter/cutscene/__init__.py diff --git a/fast64_internal/oot/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/actor_cue.py rename to fast64_internal/z64/exporter/cutscene/actor_cue.py diff --git a/fast64_internal/oot/exporter/cutscene/camera.py b/fast64_internal/z64/exporter/cutscene/camera.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/camera.py rename to fast64_internal/z64/exporter/cutscene/camera.py diff --git a/fast64_internal/oot/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/common.py rename to fast64_internal/z64/exporter/cutscene/common.py diff --git a/fast64_internal/oot/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/data.py rename to fast64_internal/z64/exporter/cutscene/data.py diff --git a/fast64_internal/oot/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/misc.py rename to fast64_internal/z64/exporter/cutscene/misc.py diff --git a/fast64_internal/oot/exporter/cutscene/seq.py b/fast64_internal/z64/exporter/cutscene/seq.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/seq.py rename to fast64_internal/z64/exporter/cutscene/seq.py diff --git a/fast64_internal/oot/exporter/cutscene/text.py b/fast64_internal/z64/exporter/cutscene/text.py similarity index 100% rename from fast64_internal/oot/exporter/cutscene/text.py rename to fast64_internal/z64/exporter/cutscene/text.py diff --git a/fast64_internal/oot/exporter/decomp_edit/__init__.py b/fast64_internal/z64/exporter/decomp_edit/__init__.py similarity index 100% rename from fast64_internal/oot/exporter/decomp_edit/__init__.py rename to fast64_internal/z64/exporter/decomp_edit/__init__.py diff --git a/fast64_internal/oot/exporter/decomp_edit/config.py b/fast64_internal/z64/exporter/decomp_edit/config.py similarity index 100% rename from fast64_internal/oot/exporter/decomp_edit/config.py rename to fast64_internal/z64/exporter/decomp_edit/config.py diff --git a/fast64_internal/oot/exporter/decomp_edit/scene_table.py b/fast64_internal/z64/exporter/decomp_edit/scene_table.py similarity index 100% rename from fast64_internal/oot/exporter/decomp_edit/scene_table.py rename to fast64_internal/z64/exporter/decomp_edit/scene_table.py diff --git a/fast64_internal/oot/exporter/decomp_edit/spec.py b/fast64_internal/z64/exporter/decomp_edit/spec.py similarity index 100% rename from fast64_internal/oot/exporter/decomp_edit/spec.py rename to fast64_internal/z64/exporter/decomp_edit/spec.py diff --git a/fast64_internal/oot/exporter/file.py b/fast64_internal/z64/exporter/file.py similarity index 100% rename from fast64_internal/oot/exporter/file.py rename to fast64_internal/z64/exporter/file.py diff --git a/fast64_internal/oot/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py similarity index 100% rename from fast64_internal/oot/exporter/room/__init__.py rename to fast64_internal/z64/exporter/room/__init__.py diff --git a/fast64_internal/oot/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py similarity index 100% rename from fast64_internal/oot/exporter/room/header.py rename to fast64_internal/z64/exporter/room/header.py diff --git a/fast64_internal/oot/exporter/room/shape.py b/fast64_internal/z64/exporter/room/shape.py similarity index 100% rename from fast64_internal/oot/exporter/room/shape.py rename to fast64_internal/z64/exporter/room/shape.py diff --git a/fast64_internal/oot/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py similarity index 100% rename from fast64_internal/oot/exporter/scene/__init__.py rename to fast64_internal/z64/exporter/scene/__init__.py diff --git a/fast64_internal/oot/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py similarity index 100% rename from fast64_internal/oot/exporter/scene/actors.py rename to fast64_internal/z64/exporter/scene/actors.py diff --git a/fast64_internal/oot/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py similarity index 100% rename from fast64_internal/oot/exporter/scene/general.py rename to fast64_internal/z64/exporter/scene/general.py diff --git a/fast64_internal/oot/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py similarity index 100% rename from fast64_internal/oot/exporter/scene/header.py rename to fast64_internal/z64/exporter/scene/header.py diff --git a/fast64_internal/oot/exporter/scene/pathways.py b/fast64_internal/z64/exporter/scene/pathways.py similarity index 100% rename from fast64_internal/oot/exporter/scene/pathways.py rename to fast64_internal/z64/exporter/scene/pathways.py diff --git a/fast64_internal/oot/exporter/scene/rooms.py b/fast64_internal/z64/exporter/scene/rooms.py similarity index 100% rename from fast64_internal/oot/exporter/scene/rooms.py rename to fast64_internal/z64/exporter/scene/rooms.py diff --git a/fast64_internal/oot/exporter/utility.py b/fast64_internal/z64/exporter/utility.py similarity index 100% rename from fast64_internal/oot/exporter/utility.py rename to fast64_internal/z64/exporter/utility.py diff --git a/fast64_internal/oot/f3d/operators.py b/fast64_internal/z64/f3d/operators.py similarity index 100% rename from fast64_internal/oot/f3d/operators.py rename to fast64_internal/z64/f3d/operators.py diff --git a/fast64_internal/oot/f3d/panels.py b/fast64_internal/z64/f3d/panels.py similarity index 100% rename from fast64_internal/oot/f3d/panels.py rename to fast64_internal/z64/f3d/panels.py diff --git a/fast64_internal/oot/f3d/properties.py b/fast64_internal/z64/f3d/properties.py similarity index 100% rename from fast64_internal/oot/f3d/properties.py rename to fast64_internal/z64/f3d/properties.py diff --git a/fast64_internal/oot/file_settings.py b/fast64_internal/z64/file_settings.py similarity index 100% rename from fast64_internal/oot/file_settings.py rename to fast64_internal/z64/file_settings.py diff --git a/fast64_internal/oot/importer/__init__.py b/fast64_internal/z64/importer/__init__.py similarity index 100% rename from fast64_internal/oot/importer/__init__.py rename to fast64_internal/z64/importer/__init__.py diff --git a/fast64_internal/oot/importer/actor.py b/fast64_internal/z64/importer/actor.py similarity index 100% rename from fast64_internal/oot/importer/actor.py rename to fast64_internal/z64/importer/actor.py diff --git a/fast64_internal/oot/importer/classes.py b/fast64_internal/z64/importer/classes.py similarity index 100% rename from fast64_internal/oot/importer/classes.py rename to fast64_internal/z64/importer/classes.py diff --git a/fast64_internal/oot/importer/constants.py b/fast64_internal/z64/importer/constants.py similarity index 100% rename from fast64_internal/oot/importer/constants.py rename to fast64_internal/z64/importer/constants.py diff --git a/fast64_internal/oot/importer/room_header.py b/fast64_internal/z64/importer/room_header.py similarity index 100% rename from fast64_internal/oot/importer/room_header.py rename to fast64_internal/z64/importer/room_header.py diff --git a/fast64_internal/oot/importer/room_shape.py b/fast64_internal/z64/importer/room_shape.py similarity index 100% rename from fast64_internal/oot/importer/room_shape.py rename to fast64_internal/z64/importer/room_shape.py diff --git a/fast64_internal/oot/importer/scene.py b/fast64_internal/z64/importer/scene.py similarity index 100% rename from fast64_internal/oot/importer/scene.py rename to fast64_internal/z64/importer/scene.py diff --git a/fast64_internal/oot/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py similarity index 100% rename from fast64_internal/oot/importer/scene_collision.py rename to fast64_internal/z64/importer/scene_collision.py diff --git a/fast64_internal/oot/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py similarity index 100% rename from fast64_internal/oot/importer/scene_header.py rename to fast64_internal/z64/importer/scene_header.py diff --git a/fast64_internal/oot/importer/scene_pathways.py b/fast64_internal/z64/importer/scene_pathways.py similarity index 100% rename from fast64_internal/oot/importer/scene_pathways.py rename to fast64_internal/z64/importer/scene_pathways.py diff --git a/fast64_internal/oot/importer/utility.py b/fast64_internal/z64/importer/utility.py similarity index 100% rename from fast64_internal/oot/importer/utility.py rename to fast64_internal/z64/importer/utility.py diff --git a/fast64_internal/oot/oot_constants.py b/fast64_internal/z64/oot_constants.py similarity index 100% rename from fast64_internal/oot/oot_constants.py rename to fast64_internal/z64/oot_constants.py diff --git a/fast64_internal/oot/oot_f3d_writer.py b/fast64_internal/z64/oot_f3d_writer.py similarity index 100% rename from fast64_internal/oot/oot_f3d_writer.py rename to fast64_internal/z64/oot_f3d_writer.py diff --git a/fast64_internal/oot/oot_model_classes.py b/fast64_internal/z64/oot_model_classes.py similarity index 100% rename from fast64_internal/oot/oot_model_classes.py rename to fast64_internal/z64/oot_model_classes.py diff --git a/fast64_internal/oot/oot_object.py b/fast64_internal/z64/oot_object.py similarity index 100% rename from fast64_internal/oot/oot_object.py rename to fast64_internal/z64/oot_object.py diff --git a/fast64_internal/oot/oot_spline.py b/fast64_internal/z64/oot_spline.py similarity index 100% rename from fast64_internal/oot/oot_spline.py rename to fast64_internal/z64/oot_spline.py diff --git a/fast64_internal/oot/oot_texture_array.py b/fast64_internal/z64/oot_texture_array.py similarity index 100% rename from fast64_internal/oot/oot_texture_array.py rename to fast64_internal/z64/oot_texture_array.py diff --git a/fast64_internal/oot/oot_upgrade.py b/fast64_internal/z64/oot_upgrade.py similarity index 100% rename from fast64_internal/oot/oot_upgrade.py rename to fast64_internal/z64/oot_upgrade.py diff --git a/fast64_internal/oot/oot_utility.py b/fast64_internal/z64/oot_utility.py similarity index 100% rename from fast64_internal/oot/oot_utility.py rename to fast64_internal/z64/oot_utility.py diff --git a/fast64_internal/oot/props_panel_main.py b/fast64_internal/z64/props_panel_main.py similarity index 100% rename from fast64_internal/oot/props_panel_main.py rename to fast64_internal/z64/props_panel_main.py diff --git a/fast64_internal/oot/room/operators.py b/fast64_internal/z64/room/operators.py similarity index 100% rename from fast64_internal/oot/room/operators.py rename to fast64_internal/z64/room/operators.py diff --git a/fast64_internal/oot/room/properties.py b/fast64_internal/z64/room/properties.py similarity index 100% rename from fast64_internal/oot/room/properties.py rename to fast64_internal/z64/room/properties.py diff --git a/fast64_internal/oot/scene/operators.py b/fast64_internal/z64/scene/operators.py similarity index 100% rename from fast64_internal/oot/scene/operators.py rename to fast64_internal/z64/scene/operators.py diff --git a/fast64_internal/oot/scene/panels.py b/fast64_internal/z64/scene/panels.py similarity index 100% rename from fast64_internal/oot/scene/panels.py rename to fast64_internal/z64/scene/panels.py diff --git a/fast64_internal/oot/scene/properties.py b/fast64_internal/z64/scene/properties.py similarity index 100% rename from fast64_internal/oot/scene/properties.py rename to fast64_internal/z64/scene/properties.py diff --git a/fast64_internal/oot/skeleton/constants.py b/fast64_internal/z64/skeleton/constants.py similarity index 100% rename from fast64_internal/oot/skeleton/constants.py rename to fast64_internal/z64/skeleton/constants.py diff --git a/fast64_internal/oot/skeleton/exporter/__init__.py b/fast64_internal/z64/skeleton/exporter/__init__.py similarity index 100% rename from fast64_internal/oot/skeleton/exporter/__init__.py rename to fast64_internal/z64/skeleton/exporter/__init__.py diff --git a/fast64_internal/oot/skeleton/exporter/classes.py b/fast64_internal/z64/skeleton/exporter/classes.py similarity index 100% rename from fast64_internal/oot/skeleton/exporter/classes.py rename to fast64_internal/z64/skeleton/exporter/classes.py diff --git a/fast64_internal/oot/skeleton/exporter/functions.py b/fast64_internal/z64/skeleton/exporter/functions.py similarity index 100% rename from fast64_internal/oot/skeleton/exporter/functions.py rename to fast64_internal/z64/skeleton/exporter/functions.py diff --git a/fast64_internal/oot/skeleton/importer/__init__.py b/fast64_internal/z64/skeleton/importer/__init__.py similarity index 100% rename from fast64_internal/oot/skeleton/importer/__init__.py rename to fast64_internal/z64/skeleton/importer/__init__.py diff --git a/fast64_internal/oot/skeleton/importer/functions.py b/fast64_internal/z64/skeleton/importer/functions.py similarity index 100% rename from fast64_internal/oot/skeleton/importer/functions.py rename to fast64_internal/z64/skeleton/importer/functions.py diff --git a/fast64_internal/oot/skeleton/operators.py b/fast64_internal/z64/skeleton/operators.py similarity index 100% rename from fast64_internal/oot/skeleton/operators.py rename to fast64_internal/z64/skeleton/operators.py diff --git a/fast64_internal/oot/skeleton/panels.py b/fast64_internal/z64/skeleton/panels.py similarity index 100% rename from fast64_internal/oot/skeleton/panels.py rename to fast64_internal/z64/skeleton/panels.py diff --git a/fast64_internal/oot/skeleton/properties.py b/fast64_internal/z64/skeleton/properties.py similarity index 100% rename from fast64_internal/oot/skeleton/properties.py rename to fast64_internal/z64/skeleton/properties.py diff --git a/fast64_internal/oot/skeleton/utility.py b/fast64_internal/z64/skeleton/utility.py similarity index 100% rename from fast64_internal/oot/skeleton/utility.py rename to fast64_internal/z64/skeleton/utility.py diff --git a/fast64_internal/oot/spline/panels.py b/fast64_internal/z64/spline/panels.py similarity index 100% rename from fast64_internal/oot/spline/panels.py rename to fast64_internal/z64/spline/panels.py diff --git a/fast64_internal/oot/spline/properties.py b/fast64_internal/z64/spline/properties.py similarity index 100% rename from fast64_internal/oot/spline/properties.py rename to fast64_internal/z64/spline/properties.py diff --git a/fast64_internal/oot/tools/__init__.py b/fast64_internal/z64/tools/__init__.py similarity index 100% rename from fast64_internal/oot/tools/__init__.py rename to fast64_internal/z64/tools/__init__.py diff --git a/fast64_internal/oot/tools/operators.py b/fast64_internal/z64/tools/operators.py similarity index 100% rename from fast64_internal/oot/tools/operators.py rename to fast64_internal/z64/tools/operators.py diff --git a/fast64_internal/oot/tools/panel.py b/fast64_internal/z64/tools/panel.py similarity index 100% rename from fast64_internal/oot/tools/panel.py rename to fast64_internal/z64/tools/panel.py diff --git a/fast64_internal/oot/tools/quick_import.py b/fast64_internal/z64/tools/quick_import.py similarity index 100% rename from fast64_internal/oot/tools/quick_import.py rename to fast64_internal/z64/tools/quick_import.py From 343da1b499f8dbc3b8a299cd5113fd17cab8a43b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:39:51 +0100 Subject: [PATCH 002/126] remove oot prefix from files --- __init__.py | 2 +- fast64_internal/z64/__init__.py | 2 +- fast64_internal/z64/actor/operators.py | 2 +- fast64_internal/z64/actor/properties.py | 6 +-- .../z64/animation/exporter/functions.py | 2 +- .../z64/animation/importer/functions.py | 4 +- fast64_internal/z64/animation/operators.py | 2 +- .../z64/collision/exporter/classes.py | 2 +- .../z64/collision/exporter/functions.py | 2 +- .../z64/collision/exporter/to_c/collision.py | 2 +- fast64_internal/z64/collision/operators.py | 2 +- fast64_internal/z64/collision/properties.py | 4 +- .../z64/{oot_constants.py => constants.py} | 0 fast64_internal/z64/cutscene/classes.py | 2 +- fast64_internal/z64/cutscene/constants.py | 2 +- .../z64/cutscene/exporter/classes.py | 2 +- .../z64/cutscene/motion/operators.py | 2 +- .../z64/cutscene/motion/properties.py | 6 +-- .../z64/cutscene/motion/utility.py | 2 +- fast64_internal/z64/cutscene/operators.py | 4 +- fast64_internal/z64/cutscene/properties.py | 6 +-- fast64_internal/z64/data/__init__.py | 4 +- .../data/{oot_actor_data.py => actor_data.py} | 4 +- .../z64/data/{oot_data.py => common.py} | 6 +-- .../data/{oot_enum_data.py => enum_data.py} | 4 +- .../z64/data/{oot_getters.py => getters.py} | 0 .../{oot_object_data.py => object_data.py} | 4 +- fast64_internal/z64/exporter/__init__.py | 6 +-- .../z64/exporter/collision/__init__.py | 2 +- .../z64/exporter/collision/camera.py | 2 +- .../z64/exporter/collision/waterbox.py | 2 +- .../z64/exporter/cutscene/__init__.py | 2 +- .../z64/exporter/cutscene/actor_cue.py | 2 +- .../z64/exporter/cutscene/common.py | 2 +- fast64_internal/z64/exporter/cutscene/data.py | 2 +- .../z64/exporter/decomp_edit/__init__.py | 2 +- .../z64/exporter/decomp_edit/scene_table.py | 2 +- .../z64/exporter/decomp_edit/spec.py | 2 +- fast64_internal/z64/exporter/room/__init__.py | 4 +- fast64_internal/z64/exporter/room/header.py | 4 +- fast64_internal/z64/exporter/room/shape.py | 4 +- .../z64/exporter/scene/__init__.py | 2 +- fast64_internal/z64/exporter/scene/actors.py | 4 +- .../z64/exporter/scene/pathways.py | 2 +- fast64_internal/z64/exporter/scene/rooms.py | 4 +- fast64_internal/z64/exporter/utility.py | 2 +- fast64_internal/z64/f3d/operators.py | 12 +++--- .../z64/{oot_f3d_writer.py => f3d_writer.py} | 6 +-- fast64_internal/z64/importer/actor.py | 4 +- fast64_internal/z64/importer/classes.py | 2 +- fast64_internal/z64/importer/room_header.py | 6 +-- fast64_internal/z64/importer/room_shape.py | 4 +- fast64_internal/z64/importer/scene.py | 6 +-- .../z64/importer/scene_collision.py | 4 +- fast64_internal/z64/importer/scene_header.py | 6 +-- fast64_internal/z64/importer/utility.py | 2 +- ...{oot_model_classes.py => model_classes.py} | 0 .../z64/{oot_object.py => object.py} | 2 +- fast64_internal/z64/oot_spline.py | 38 ------------------- fast64_internal/z64/props_panel_main.py | 2 +- fast64_internal/z64/room/operators.py | 2 +- fast64_internal/z64/room/properties.py | 6 +-- fast64_internal/z64/scene/operators.py | 4 +- fast64_internal/z64/scene/panels.py | 4 +- fast64_internal/z64/scene/properties.py | 4 +- .../z64/skeleton/exporter/functions.py | 6 +-- .../z64/skeleton/importer/functions.py | 8 ++-- fast64_internal/z64/skeleton/operators.py | 2 +- fast64_internal/z64/skeleton/utility.py | 4 +- fast64_internal/z64/spline/panels.py | 2 +- fast64_internal/z64/spline/properties.py | 2 +- ...{oot_texture_array.py => texture_array.py} | 2 +- fast64_internal/z64/tools/operators.py | 2 +- .../z64/{oot_upgrade.py => upgrade.py} | 4 +- .../z64/{oot_utility.py => utility.py} | 2 +- 75 files changed, 121 insertions(+), 159 deletions(-) rename fast64_internal/z64/{oot_constants.py => constants.py} (100%) rename fast64_internal/z64/data/{oot_actor_data.py => actor_data.py} (95%) rename fast64_internal/z64/data/{oot_data.py => common.py} (70%) rename fast64_internal/z64/data/{oot_enum_data.py => enum_data.py} (98%) rename fast64_internal/z64/data/{oot_getters.py => getters.py} (100%) rename fast64_internal/z64/data/{oot_object_data.py => object_data.py} (96%) rename fast64_internal/z64/{oot_f3d_writer.py => f3d_writer.py} (98%) rename fast64_internal/z64/{oot_model_classes.py => model_classes.py} (100%) rename fast64_internal/z64/{oot_object.py => object.py} (98%) delete mode 100644 fast64_internal/z64/oot_spline.py rename fast64_internal/z64/{oot_texture_array.py => texture_array.py} (99%) rename fast64_internal/z64/{oot_upgrade.py => upgrade.py} (99%) rename fast64_internal/z64/{oot_utility.py => utility.py} (99%) diff --git a/__init__.py b/__init__.py index c7d015292..02117b338 100644 --- a/__init__.py +++ b/__init__.py @@ -20,7 +20,7 @@ from .fast64_internal.sm64.sm64_objects import SM64_ObjectProperties from .fast64_internal.z64 import OOT_Properties, oot_register, oot_unregister -from .fast64_internal.z64.oot_constants import oot_world_defaults +from .fast64_internal.z64.constants import oot_world_defaults from .fast64_internal.z64.props_panel_main import OOT_ObjectProperties from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 5c4bd90a8..6af487842 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -7,7 +7,7 @@ from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister from .skeleton.properties import OOTSkeletonImportSettings, OOTSkeletonExportSettings -from .oot_utility import oot_utility_register, oot_utility_unregister, setAllActorsVisibility +from .utility import oot_utility_register, oot_utility_unregister, setAllActorsVisibility from .file_settings import file_register, file_unregister from .collision.properties import OOTCollisionExportSettings diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index e1702a8af..7e863c953 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -3,7 +3,7 @@ from bpy.props import EnumProperty, StringProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError -from ..oot_constants import ootData +from ..constants import ootData class OOT_SearchActorIDEnumOperator(Operator): diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 50f0a7054..21323c6b0 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -2,13 +2,13 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from ...utility import prop_split, label_split -from ..oot_constants import ootData, ootEnumCamTransition -from ..oot_upgrade import upgradeActors +from ..constants import ootData, ootEnumCamTransition +from ..upgrade import upgradeActors from ..scene.properties import OOTAlternateSceneHeaderProperty from ..room.properties import OOTAlternateRoomHeaderProperty from .operators import OOT_SearchActorIDEnumOperator -from ..oot_utility import ( +from ..utility import ( getRoomObj, getEnumName, drawAddButton, diff --git a/fast64_internal/z64/animation/exporter/functions.py b/fast64_internal/z64/animation/exporter/functions.py index 78585ae2c..d7c72cac4 100644 --- a/fast64_internal/z64/animation/exporter/functions.py +++ b/fast64_internal/z64/animation/exporter/functions.py @@ -14,7 +14,7 @@ stashActionInArmature, ) -from ...oot_utility import ( +from ...utility import ( checkForStartBone, getStartBone, getSortedChildren, diff --git a/fast64_internal/z64/animation/importer/functions.py b/fast64_internal/z64/animation/importer/functions.py index da35f233e..680b987ad 100644 --- a/fast64_internal/z64/animation/importer/functions.py +++ b/fast64_internal/z64/animation/importer/functions.py @@ -4,7 +4,7 @@ import math from ....utility import PluginError, hexOrDecInt from ....f3d.f3d_parser import getImportData -from ...oot_model_classes import ootGetIncludedAssetData +from ...model_classes import ootGetIncludedAssetData from ....utility_anim import ( getTranslationRelativeToRest, @@ -12,7 +12,7 @@ stashActionInArmature, ) -from ...oot_utility import ( +from ...utility import ( getStartBone, getNextBone, ) diff --git a/fast64_internal/z64/animation/operators.py b/fast64_internal/z64/animation/operators.py index 3756b8168..8fecf6726 100644 --- a/fast64_internal/z64/animation/operators.py +++ b/fast64_internal/z64/animation/operators.py @@ -8,7 +8,7 @@ from .exporter import ootExportLinkAnimation, ootExportNonLinkAnimation from .importer import ootImportLinkAnimationC, ootImportNonLinkAnimationC -from ..oot_utility import ( +from ..utility import ( ootGetPath, addIncludeFiles, checkEmptyName, diff --git a/fast64_internal/z64/collision/exporter/classes.py b/fast64_internal/z64/collision/exporter/classes.py index af8ba58ec..295d2d056 100644 --- a/fast64_internal/z64/collision/exporter/classes.py +++ b/fast64_internal/z64/collision/exporter/classes.py @@ -1,6 +1,6 @@ import math from ....utility import PluginError -from ...oot_utility import BoxEmpty, convertIntTo2sComplement, getCustomProperty +from ...utility import BoxEmpty, convertIntTo2sComplement, getCustomProperty class OOTCollisionVertex: diff --git a/fast64_internal/z64/collision/exporter/functions.py b/fast64_internal/z64/collision/exporter/functions.py index 19364ddd9..616127a51 100644 --- a/fast64_internal/z64/collision/exporter/functions.py +++ b/fast64_internal/z64/collision/exporter/functions.py @@ -2,7 +2,7 @@ import mathutils from ....utility import PluginError -from ...oot_utility import convertIntTo2sComplement +from ...utility import convertIntTo2sComplement from .classes import OOTCollisionVertex, OOTCollisionPolygon, getPolygonType diff --git a/fast64_internal/z64/collision/exporter/to_c/collision.py b/fast64_internal/z64/collision/exporter/to_c/collision.py index 563263c5d..e059a5226 100644 --- a/fast64_internal/z64/collision/exporter/to_c/collision.py +++ b/fast64_internal/z64/collision/exporter/to_c/collision.py @@ -16,7 +16,7 @@ toAlnum, ) -from ....oot_utility import ( +from ....utility import ( OOTObjectCategorizer, addIncludeFiles, ootDuplicateHierarchy, diff --git a/fast64_internal/z64/collision/operators.py b/fast64_internal/z64/collision/operators.py index 38fe2a5df..861ffab6d 100644 --- a/fast64_internal/z64/collision/operators.py +++ b/fast64_internal/z64/collision/operators.py @@ -3,7 +3,7 @@ from bpy.ops import object from mathutils import Matrix from ...utility import PluginError, raisePluginError -from ..oot_utility import getOOTScale +from ..utility import getOOTScale from ..collision.exporter.to_c import exportCollisionToC from .properties import OOTCollisionExportSettings diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 2b2373773..34cf2258d 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -3,8 +3,8 @@ from bpy.types import PropertyGroup, Camera, Object, Material, UILayout from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..oot_utility import drawEnumWithCustom -from ..oot_constants import ootEnumSceneID +from ..utility import drawEnumWithCustom +from ..constants import ootEnumSceneID from .constants import ( ootEnumFloorSetting, ootEnumWallSetting, diff --git a/fast64_internal/z64/oot_constants.py b/fast64_internal/z64/constants.py similarity index 100% rename from fast64_internal/z64/oot_constants.py rename to fast64_internal/z64/constants.py diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 72739a8cd..141e16a12 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from bpy.types import Object from typing import Optional -from ..oot_constants import ootData +from ..constants import ootData from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index d5e155e5b..90c613a01 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -1,4 +1,4 @@ -from ..oot_constants import ootData +from ..constants import ootData from .classes import ( CutsceneCmdActorCueList, CutsceneCmdActorCue, diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index 8b42ca5ef..3091f4477 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object from ....utility import PluginError, indent -from ...oot_constants import ootData +from ...constants import ootData from ..constants import ootEnumCSListTypeListC if TYPE_CHECKING: diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index d5d5668e7..e4ef36581 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty from ....utility import PluginError -from ...oot_constants import ootData +from ...constants import ootData from ..classes import CutsceneObjectFactory from ..constants import ootEnumCSActorCueListCommandType from ..preview import initFirstFrame, setupCompositorNodes diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index d18a48282..cd50737a8 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -3,9 +3,9 @@ from bpy.types import PropertyGroup, Object, UILayout, Armature, Bone, Scene, EditBone from bpy.props import IntProperty, StringProperty, PointerProperty, EnumProperty, FloatProperty from bpy.utils import register_class, unregister_class -from ...oot_upgrade import upgradeCutsceneMotion -from ...oot_utility import getEnumName -from ...oot_constants import ootData +from ...upgrade import upgradeCutsceneMotion +from ...utility import getEnumName +from ...constants import ootData from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType from .operators import ( diff --git a/fast64_internal/z64/cutscene/motion/utility.py b/fast64_internal/z64/cutscene/motion/utility.py index fa8b7c06d..4b9a5fedc 100644 --- a/fast64_internal/z64/cutscene/motion/utility.py +++ b/fast64_internal/z64/cutscene/motion/utility.py @@ -4,7 +4,7 @@ from bpy.types import Object, Bone, Context, EditBone, Armature from mathutils import Vector from ....utility import yUpToZUp -from ...oot_utility import ootParseRotation +from ...utility import ootParseRotation class BoneData: diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index f956158f4..efb8420f4 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -8,8 +8,8 @@ from bpy.types import Scene, Operator, Context from bpy.utils import register_class, unregister_class from ...utility import CData, PluginError, writeCData, raisePluginError -from ..oot_utility import getCollection -from ..oot_constants import ootData +from ..utility import getCollection +from ..constants import ootData from .constants import ootEnumCSTextboxType, ootEnumCSListType from .importer import importCutsceneData from .exporter import getNewCutsceneExport diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index f2f6c3c58..85cc22980 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -2,9 +2,9 @@ from bpy.props import StringProperty, EnumProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split -from ..oot_utility import OOTCollectionAdd, drawCollectionOps, getEnumName -from ..oot_constants import ootData -from ..oot_upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty +from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName +from ..constants import ootData +from ..upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty from .operators import OOTCSTextAdd, OOT_SearchCSDestinationEnumOperator, OOTCSListAdd, OOT_SearchCSSeqOperator from .motion.preview import previewFrameHandler from .motion.utility import getCutsceneCamera diff --git a/fast64_internal/z64/data/__init__.py b/fast64_internal/z64/data/__init__.py index ce6e88b62..52330206f 100644 --- a/fast64_internal/z64/data/__init__.py +++ b/fast64_internal/z64/data/__init__.py @@ -1,2 +1,2 @@ -from .oot_data import OoT_Data -from .oot_object_data import OoT_ObjectData +from .common import OoT_Data +from .object_data import OoT_ObjectData diff --git a/fast64_internal/z64/data/oot_actor_data.py b/fast64_internal/z64/data/actor_data.py similarity index 95% rename from fast64_internal/z64/data/oot_actor_data.py rename to fast64_internal/z64/data/actor_data.py index 7f7642b2a..4a7411d22 100644 --- a/fast64_internal/z64/data/oot_actor_data.py +++ b/fast64_internal/z64/data/actor_data.py @@ -1,7 +1,7 @@ from os import path from dataclasses import dataclass -from .oot_getters import getXMLRoot -from .oot_data import OoT_BaseElement +from .getters import getXMLRoot +from .common import OoT_BaseElement @dataclass diff --git a/fast64_internal/z64/data/oot_data.py b/fast64_internal/z64/data/common.py similarity index 70% rename from fast64_internal/z64/data/oot_data.py rename to fast64_internal/z64/data/common.py index c4619a925..cf75fd3d2 100644 --- a/fast64_internal/z64/data/oot_data.py +++ b/fast64_internal/z64/data/common.py @@ -14,9 +14,9 @@ class OoT_Data: """Contains data related to OoT, like actors or objects""" def __init__(self): - from .oot_enum_data import OoT_EnumData - from .oot_object_data import OoT_ObjectData - from .oot_actor_data import OoT_ActorData + from .enum_data import OoT_EnumData + from .object_data import OoT_ObjectData + from .actor_data import OoT_ActorData self.enumData = OoT_EnumData() self.objectData = OoT_ObjectData() diff --git a/fast64_internal/z64/data/oot_enum_data.py b/fast64_internal/z64/data/enum_data.py similarity index 98% rename from fast64_internal/z64/data/oot_enum_data.py rename to fast64_internal/z64/data/enum_data.py index 0644c6f4b..b0975ec81 100644 --- a/fast64_internal/z64/data/oot_enum_data.py +++ b/fast64_internal/z64/data/enum_data.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field from os import path -from .oot_getters import getXMLRoot -from .oot_data import OoT_BaseElement +from .getters import getXMLRoot +from .common import OoT_BaseElement # Note: "enumData" in this context refers to an OoT Object file (like ``gameplay_keep``) diff --git a/fast64_internal/z64/data/oot_getters.py b/fast64_internal/z64/data/getters.py similarity index 100% rename from fast64_internal/z64/data/oot_getters.py rename to fast64_internal/z64/data/getters.py diff --git a/fast64_internal/z64/data/oot_object_data.py b/fast64_internal/z64/data/object_data.py similarity index 96% rename from fast64_internal/z64/data/oot_object_data.py rename to fast64_internal/z64/data/object_data.py index 28970a80c..5f5183feb 100644 --- a/fast64_internal/z64/data/oot_object_data.py +++ b/fast64_internal/z64/data/object_data.py @@ -1,8 +1,8 @@ from dataclasses import dataclass from os import path from ...utility import PluginError -from .oot_getters import getXMLRoot -from .oot_data import OoT_BaseElement +from .getters import getXMLRoot +from .common import OoT_BaseElement # Note: "object" in this context refers to an OoT Object file (like ``gameplay_keep``) diff --git a/fast64_internal/z64/exporter/__init__.py b/fast64_internal/z64/exporter/__init__.py index e85ef12fc..d0fec594f 100644 --- a/fast64_internal/z64/exporter/__init__.py +++ b/fast64_internal/z64/exporter/__init__.py @@ -4,8 +4,8 @@ from mathutils import Matrix from bpy.types import Object from ...f3d.f3d_gbi import DLFormat, TextureExportSettings -from ..oot_model_classes import OOTModel -from ..oot_f3d_writer import writeTextureArraysNew, writeTextureArraysExisting1D +from ..model_classes import OOTModel +from ..f3d_writer import writeTextureArraysNew, writeTextureArraysExisting1D from .scene import Scene from .decomp_edit import Files @@ -19,7 +19,7 @@ writeFile, ) -from ..oot_utility import ( +from ..utility import ( ExportInfo, OOTObjectCategorizer, ootDuplicateHierarchy, diff --git a/fast64_internal/z64/exporter/collision/__init__.py b/fast64_internal/z64/exporter/collision/__init__.py index 3a1ad4949..b101bfe0b 100644 --- a/fast64_internal/z64/exporter/collision/__init__.py +++ b/fast64_internal/z64/exporter/collision/__init__.py @@ -6,7 +6,7 @@ from bpy.ops import object from typing import Optional from ....utility import PluginError, CData, indent -from ...oot_utility import convertIntTo2sComplement +from ...utility import convertIntTo2sComplement from ..utility import Utility from .polygons import CollisionPoly, CollisionPolygons from .surface import SurfaceType, SurfaceTypes diff --git a/fast64_internal/z64/exporter/collision/camera.py b/fast64_internal/z64/exporter/collision/camera.py index 012defcee..f4f2eccfb 100644 --- a/fast64_internal/z64/exporter/collision/camera.py +++ b/fast64_internal/z64/exporter/collision/camera.py @@ -4,7 +4,7 @@ from mathutils import Quaternion, Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...oot_utility import getObjectList +from ...utility import getObjectList from ...collision.constants import decomp_compat_map_CameraSType from ...collision.properties import OOTCameraPositionProperty from ..utility import Utility diff --git a/fast64_internal/z64/exporter/collision/waterbox.py b/fast64_internal/z64/exporter/collision/waterbox.py index 15d158239..1267fecf0 100644 --- a/fast64_internal/z64/exporter/collision/waterbox.py +++ b/fast64_internal/z64/exporter/collision/waterbox.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from mathutils import Matrix from bpy.types import Object -from ...oot_utility import getObjectList +from ...utility import getObjectList from ....utility import CData, checkIdentityRotation, indent from ..utility import Utility diff --git a/fast64_internal/z64/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py index a9d8c5b1a..8895b114c 100644 --- a/fast64_internal/z64/exporter/cutscene/__init__.py +++ b/fast64_internal/z64/exporter/cutscene/__init__.py @@ -4,7 +4,7 @@ from typing import Optional from bpy.types import Object from ....utility import PluginError, CData, indent -from ...oot_utility import getCustomProperty +from ...utility import getCustomProperty from ...scene.properties import OOTSceneHeaderProperty from .data import CutsceneData diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index 7a38c3f0d..7154ab521 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field from ....utility import PluginError, indent -from ...oot_constants import ootData +from ...constants import ootData from ...cutscene.motion.utility import getRotation, getInteger from .common import CutsceneCmdBase diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index ab91fb283..9b308b038 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional from ....utility import PluginError, indent -from ...oot_constants import ootData +from ...constants import ootData from ...cutscene.motion.utility import getInteger diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 25a92db7d..28decd627 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError -from ...oot_constants import ootData +from ...constants import ootData from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction diff --git a/fast64_internal/z64/exporter/decomp_edit/__init__.py b/fast64_internal/z64/exporter/decomp_edit/__init__.py index 4f0693f15..a84baea1e 100644 --- a/fast64_internal/z64/exporter/decomp_edit/__init__.py +++ b/fast64_internal/z64/exporter/decomp_edit/__init__.py @@ -2,7 +2,7 @@ import re import shutil -from ...oot_utility import ExportInfo, RemoveInfo, getSceneDirFromLevelName +from ...utility import ExportInfo, RemoveInfo, getSceneDirFromLevelName from ..scene import Scene from ..file import SceneFile from .scene_table import SceneTableUtility diff --git a/fast64_internal/z64/exporter/decomp_edit/scene_table.py b/fast64_internal/z64/exporter/decomp_edit/scene_table.py index 8ae966864..07997572c 100644 --- a/fast64_internal/z64/exporter/decomp_edit/scene_table.py +++ b/fast64_internal/z64/exporter/decomp_edit/scene_table.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile -from ...oot_constants import ootEnumSceneID, ootSceneNameToID +from ...constants import ootEnumSceneID, ootSceneNameToID ADDED_SCENES_COMMENT = "// Added scenes" diff --git a/fast64_internal/z64/exporter/decomp_edit/spec.py b/fast64_internal/z64/exporter/decomp_edit/spec.py index 2bc053178..5029ff21d 100644 --- a/fast64_internal/z64/exporter/decomp_edit/spec.py +++ b/fast64_internal/z64/exporter/decomp_edit/spec.py @@ -5,7 +5,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile, indent -from ...oot_utility import ExportInfo, getSceneDirFromLevelName +from ...utility import ExportInfo, getSceneDirFromLevelName from ..scene import Scene from ..file import SceneFile diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index 3fe3d6c2e..798db23ac 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -5,8 +5,8 @@ from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings from ...room.properties import OOTRoomHeaderProperty -from ...oot_object import addMissingObjectsToAllRoomHeaders -from ...oot_model_classes import OOTModel, OOTGfxFormatter +from ...object import addMissingObjectsToAllRoomHeaders +from ...model_classes import OOTModel, OOTGfxFormatter from ..file import RoomFile from ..utility import Utility, altHeaderList from .header import RoomAlternateHeader, RoomHeader diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index bcc275f73..f79aa88b3 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,8 +3,8 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData, indent -from ...oot_utility import getObjectList -from ...oot_constants import ootData +from ...utility import getObjectList +from ...constants import ootData from ...room.properties import OOTRoomHeaderProperty from ..utility import Utility from ..actor import Actor diff --git a/fast64_internal/z64/exporter/room/shape.py b/fast64_internal/z64/exporter/room/shape.py index 96278f917..e08f141d2 100644 --- a/fast64_internal/z64/exporter/room/shape.py +++ b/fast64_internal/z64/exporter/room/shape.py @@ -8,13 +8,13 @@ from ....f3d.f3d_gbi import SPDisplayList, SPEndDisplayList, GfxListTag, GfxList, DLFormat from ....f3d.f3d_writer import TriangleConverterInfo, saveStaticModel, getInfoDict from ...room.properties import OOTRoomHeaderProperty, OOTBGProperty -from ...oot_model_classes import OOTModel +from ...model_classes import OOTModel from ..utility import Utility from bpy.types import Object from mathutils import Matrix, Vector from ....f3d.occlusion_planes.exporter import addOcclusionQuads, OcclusionPlaneCandidatesList -from ...oot_utility import ( +from ...utility import ( CullGroup, checkUniformScale, ootConvertTranslation, diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index f8b83cdd2..3c6fceae2 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -5,7 +5,7 @@ from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import OOTSceneHeaderProperty -from ...oot_model_classes import OOTModel, OOTGfxFormatter +from ...model_classes import OOTModel, OOTGfxFormatter from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 8f7735b6e..b0900da16 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,8 +3,8 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...oot_utility import getObjectList -from ...oot_constants import ootData +from ...utility import getObjectList +from ...constants import ootData from ..utility import Utility from ..actor import Actor diff --git a/fast64_internal/z64/exporter/scene/pathways.py b/fast64_internal/z64/exporter/scene/pathways.py index 331af8dbe..7feb19248 100644 --- a/fast64_internal/z64/exporter/scene/pathways.py +++ b/fast64_internal/z64/exporter/scene/pathways.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...oot_utility import getObjectList +from ...utility import getObjectList from ..utility import Utility diff --git a/fast64_internal/z64/exporter/scene/rooms.py b/fast64_internal/z64/exporter/scene/rooms.py index 6948ef6bb..9efb03b81 100644 --- a/fast64_internal/z64/exporter/scene/rooms.py +++ b/fast64_internal/z64/exporter/scene/rooms.py @@ -2,8 +2,8 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...oot_utility import getObjectList -from ...oot_model_classes import OOTModel +from ...utility import getObjectList +from ...model_classes import OOTModel from ..room import Room diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index 16a76590f..297803bd2 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -2,7 +2,7 @@ from mathutils import Quaternion, Matrix from bpy.types import Object from ...utility import PluginError, indent -from ..oot_utility import ootConvertTranslation, ootConvertRotation +from ..utility import ootConvertTranslation, ootConvertRotation from ..actor.properties import OOTActorHeaderProperty diff --git a/fast64_internal/z64/f3d/operators.py b/fast64_internal/z64/f3d/operators.py index 5d8cab7d8..07a97d3f7 100644 --- a/fast64_internal/z64/f3d/operators.py +++ b/fast64_internal/z64/f3d/operators.py @@ -8,14 +8,14 @@ from ...f3d.f3d_parser import importMeshC, getImportData from ...f3d.f3d_gbi import DLFormat, F3D, TextureExportSettings, ScrollMethod, get_F3D_GBI from ...f3d.f3d_writer import TriangleConverterInfo, removeDL, saveStaticModel, getInfoDict -from ..oot_utility import ootGetObjectPath, getOOTScale -from ..oot_model_classes import OOTF3DContext, ootGetIncludedAssetData -from ..oot_texture_array import ootReadTextureArrays -from ..oot_model_classes import OOTModel, OOTGfxFormatter -from ..oot_f3d_writer import ootReadActorScale, writeTextureArraysNew, writeTextureArraysExisting +from ..utility import ootGetObjectPath, getOOTScale +from ..model_classes import OOTF3DContext, ootGetIncludedAssetData +from ..texture_array import ootReadTextureArrays +from ..model_classes import OOTModel, OOTGfxFormatter +from ..f3d_writer import ootReadActorScale, writeTextureArraysNew, writeTextureArraysExisting from .properties import OOTDLImportSettings, OOTDLExportSettings -from ..oot_utility import ( +from ..utility import ( OOTObjectCategorizer, ootDuplicateHierarchy, ootCleanupScene, diff --git a/fast64_internal/z64/oot_f3d_writer.py b/fast64_internal/z64/f3d_writer.py similarity index 98% rename from fast64_internal/z64/oot_f3d_writer.py rename to fast64_internal/z64/f3d_writer.py index b36644870..8bfc36e7d 100644 --- a/fast64_internal/z64/oot_f3d_writer.py +++ b/fast64_internal/z64/f3d_writer.py @@ -2,8 +2,8 @@ from ..utility import CData, getGroupIndexFromname, readFile, writeFile from ..f3d.flipbook import flipbook_to_c, flipbook_2d_to_c, flipbook_data_to_c from ..f3d.f3d_material import createF3DMat, F3DMaterial_UpdateLock, update_preset_manual -from .oot_utility import replaceMatchContent, getOOTScale -from .oot_texture_array import TextureFlipbook +from .utility import replaceMatchContent, getOOTScale +from .texture_array import TextureFlipbook from ..f3d.f3d_writer import ( checkForF3dMaterialInFaces, @@ -12,7 +12,7 @@ saveMeshByFaces, ) -from .oot_model_classes import ( +from .model_classes import ( OOTTriangleConverterInfo, OOTModel, ootGetActorData, diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 557c2d646..edaae14b2 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,8 +3,8 @@ from ...utility import parentObject, hexOrDecInt from ..scene.properties import OOTSceneHeaderProperty -from ..oot_utility import setCustomProperty, getEvalParams -from ..oot_constants import ootEnumCamTransition, ootData +from ..utility import setCustomProperty, getEvalParams +from ..constants import ootEnumCamTransition, ootData from .classes import SharedSceneData from .constants import actorsWithRotAsParam diff --git a/fast64_internal/z64/importer/classes.py b/fast64_internal/z64/importer/classes.py index 87f19d28c..65e7af441 100644 --- a/fast64_internal/z64/importer/classes.py +++ b/fast64_internal/z64/importer/classes.py @@ -1,5 +1,5 @@ from ...utility import PluginError -from ..oot_utility import getHeaderSettings +from ..utility import getHeaderSettings from .constants import headerNames diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 36fa422d6..b765f2bbe 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,10 +2,10 @@ import re from ...utility import hexOrDecInt -from ..oot_utility import setCustomProperty -from ..oot_model_classes import OOTF3DContext +from ..utility import setCustomProperty +from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty -from ..oot_constants import ootData, ootEnumLinkIdle, ootEnumRoomBehaviour +from ..constants import ootData, ootEnumLinkIdle, ootEnumRoomBehaviour from .utility import getDataMatch, stripName from .classes import SharedSceneData from .constants import headerNames diff --git a/fast64_internal/z64/importer/room_shape.py b/fast64_internal/z64/importer/room_shape.py index bff6d7c42..096f1ff57 100644 --- a/fast64_internal/z64/importer/room_shape.py +++ b/fast64_internal/z64/importer/room_shape.py @@ -5,9 +5,9 @@ from ...utility import parentObject, hexOrDecInt, yUpToZUp from ...f3d.f3d_parser import importMeshC -from ..oot_model_classes import OOTF3DContext +from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty -from ..oot_constants import ootEnumRoomShapeType +from ..constants import ootEnumRoomShapeType from .classes import SharedSceneData from .utility import getDataMatch, stripName diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 38541609a..418961104 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -7,15 +7,15 @@ from ...f3d.f3d_parser import parseMatrices from ...f3d.f3d_gbi import get_F3D_GBI from ...f3d.flipbook import TextureFlipbook -from ..oot_model_classes import OOTF3DContext +from ..model_classes import OOTF3DContext from ..exporter.decomp_edit.scene_table import SceneTableUtility from ..scene.properties import OOTImportSceneSettingsProperty -from ..oot_constants import ootEnumDrawConfig +from ..constants import ootEnumDrawConfig from .scene_header import parseSceneCommands from .classes import SharedSceneData from ..cutscene.importer import importCutsceneData -from ..oot_utility import ( +from ..utility import ( getSceneDirFromLevelName, setCustomProperty, sceneNameFromID, diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index 2cf26200e..40a4d8240 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -7,8 +7,8 @@ from collections import OrderedDict from ...utility import PluginError, parentObject, hexOrDecInt, yUpToZUp from ..collision.properties import OOTMaterialCollisionProperty -from ..oot_f3d_writer import getColliderMat -from ..oot_utility import setCustomProperty, ootParseRotation +from ..f3d_writer import getColliderMat +from ..utility import setCustomProperty, ootParseRotation from .utility import getDataMatch, getBits, checkBit, createCurveFromPoints, stripName from .classes import SharedSceneData diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 017667b33..b08950efe 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -6,9 +6,9 @@ from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse from ...f3d.f3d_parser import parseMatrices -from ..oot_model_classes import OOTF3DContext +from ..model_classes import OOTF3DContext from ..scene.properties import OOTSceneHeaderProperty, OOTLightProperty -from ..oot_utility import getEvalParams, setCustomProperty +from ..utility import getEvalParams, setCustomProperty from .constants import headerNames from .utility import getDataMatch, stripName from .classes import SharedSceneData @@ -17,7 +17,7 @@ from .scene_collision import parseCollisionHeader from .scene_pathways import parsePathList -from ..oot_constants import ( +from ..constants import ( ootEnumAudioSessionPreset, ootEnumNightSeq, ootEnumMusicSeq, diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index 8eb975813..e154c9413 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -4,7 +4,7 @@ from ...utility import PluginError, hexOrDecInt, removeComments, yUpToZUp from ..actor.properties import OOTActorProperty, OOTActorHeaderProperty -from ..oot_utility import ootParseRotation +from ..utility import ootParseRotation from .constants import headerNames, actorsWithRotAsParam diff --git a/fast64_internal/z64/oot_model_classes.py b/fast64_internal/z64/model_classes.py similarity index 100% rename from fast64_internal/z64/oot_model_classes.py rename to fast64_internal/z64/model_classes.py diff --git a/fast64_internal/z64/oot_object.py b/fast64_internal/z64/object.py similarity index 98% rename from fast64_internal/z64/oot_object.py rename to fast64_internal/z64/object.py index a4eb89f89..114a2e4c8 100644 --- a/fast64_internal/z64/oot_object.py +++ b/fast64_internal/z64/object.py @@ -1,6 +1,6 @@ from bpy.types import Object from ..utility import ootGetSceneOrRoomHeader -from .oot_constants import ootData +from .constants import ootData from .exporter.room.header import RoomHeader diff --git a/fast64_internal/z64/oot_spline.py b/fast64_internal/z64/oot_spline.py deleted file mode 100644 index 05084437c..000000000 --- a/fast64_internal/z64/oot_spline.py +++ /dev/null @@ -1,38 +0,0 @@ -import bpy -from ..utility import PluginError, toAlnum - - -class OOTPath: - def __init__(self, ownerName, objName: str): - self.ownerName = toAlnum(ownerName) - self.objName = objName - self.points = [] - - def pathName(self, headerIndex, index): - return f"{self.ownerName}_pathwayList{index}_header{headerIndex}" - - -def ootConvertPath(name, obj, transformMatrix): - path = OOTPath(name, obj.name) - - spline = obj.data.splines[0] - for point in spline.points: - position = transformMatrix @ point.co.xyz - path.points.append(position) - - return path - - -def onSplineTypeSet(self, context): - self.splines.active.order_u = 1 - - -def assertCurveValid(obj): - curve = obj.data - if not isinstance(curve, bpy.types.Curve) or curve.splines[0].type != "NURBS": - # Curve was likely not intended to be exported - return False - if len(curve.splines) != 1: - # Curve was intended to be exported but has multiple disconnected segments - raise PluginError("Exported curves should have only one single segment, found " + str(len(curve.splines))) - return True diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 3323825b3..2a989624d 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .oot_utility import getSceneObj, getRoomObj +from .utility import getSceneObj, getRoomObj from .scene.properties import OOTSceneProperties from .room.properties import OOTObjectProperty, OOTRoomHeaderProperty, OOTAlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index 954f2ee32..3ab7da2fa 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, IntProperty, StringProperty from ...utility import ootGetSceneOrRoomHeader -from ..oot_constants import ootData +from ..constants import ootData class OOT_SearchObjectEnumOperator(Operator): diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 1e9d643d2..f970655a8 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -2,8 +2,8 @@ from bpy.types import PropertyGroup, UILayout, Image, Object from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..oot_utility import drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton -from ..oot_upgrade import upgradeRoomHeaders +from ..utility import drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton +from ..upgrade import upgradeRoomHeaders from .operators import OOT_SearchObjectEnumOperator from bpy.props import ( @@ -17,7 +17,7 @@ IntVectorProperty, ) -from ..oot_constants import ( +from ..constants import ( ootData, ootEnumRoomBehaviour, ootEnumLinkIdle, diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 72e8b1971..4b18692db 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -9,8 +9,8 @@ from mathutils import Matrix, Vector from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader -from ..oot_utility import ExportInfo, RemoveInfo, sceneNameFromID -from ..oot_constants import ootEnumMusicSeq, ootEnumSceneID +from ..utility import ExportInfo, RemoveInfo, sceneNameFromID +from ..constants import ootEnumMusicSeq, ootEnumSceneID from ..importer import parseScene from ..exporter.decomp_edit.config import Config from ..exporter import SceneExport, Files diff --git a/fast64_internal/z64/scene/panels.py b/fast64_internal/z64/scene/panels.py index 009c4273b..a6a2c5ab6 100644 --- a/fast64_internal/z64/scene/panels.py +++ b/fast64_internal/z64/scene/panels.py @@ -4,8 +4,8 @@ from bpy.types import UILayout from bpy.utils import register_class, unregister_class from ...panels import OOT_Panel -from ..oot_constants import ootEnumSceneID -from ..oot_utility import getEnumName +from ..constants import ootEnumSceneID +from ..utility import getEnumName from .properties import ( OOTExportSceneSettingsProperty, OOTImportSceneSettingsProperty, diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index b48948e06..26c7f29b5 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -14,7 +14,7 @@ from ...utility import prop_split, customExportWarning from ..cutscene.constants import ootEnumCSWriteType -from ..oot_utility import ( +from ..utility import ( onMenuTabChange, onHeaderMenuTabChange, drawCollectionOps, @@ -22,7 +22,7 @@ drawAddButton, ) -from ..oot_constants import ( +from ..constants import ( ootEnumMusicSeq, ootEnumSceneID, ootEnumGlobalObject, diff --git a/fast64_internal/z64/skeleton/exporter/functions.py b/fast64_internal/z64/skeleton/exporter/functions.py index 3c508f7d7..f140ff00b 100644 --- a/fast64_internal/z64/skeleton/exporter/functions.py +++ b/fast64_internal/z64/skeleton/exporter/functions.py @@ -1,8 +1,8 @@ import mathutils, bpy, os from ....f3d.f3d_gbi import DLFormat, FMesh, TextureExportSettings, ScrollMethod from ....f3d.f3d_writer import getInfoDict -from ...oot_f3d_writer import ootProcessVertexGroup, writeTextureArraysNew, writeTextureArraysExisting -from ...oot_model_classes import OOTModel, OOTGfxFormatter +from ...f3d_writer import ootProcessVertexGroup, writeTextureArraysNew, writeTextureArraysExisting +from ...model_classes import OOTModel, OOTGfxFormatter from ..constants import ootSkeletonImportDict from ..properties import OOTSkeletonExportSettings from ..utility import ootDuplicateArmatureAndRemoveRotations, getGroupIndices, ootRemoveSkeleton @@ -17,7 +17,7 @@ cleanupDuplicatedObjects, ) -from ...oot_utility import ( +from ...utility import ( checkEmptyName, checkForStartBone, getStartBone, diff --git a/fast64_internal/z64/skeleton/importer/functions.py b/fast64_internal/z64/skeleton/importer/functions.py index 84699c009..2575b0af0 100644 --- a/fast64_internal/z64/skeleton/importer/functions.py +++ b/fast64_internal/z64/skeleton/importer/functions.py @@ -4,10 +4,10 @@ from ....f3d.f3d_gbi import F3D, get_F3D_GBI from ....f3d.f3d_parser import getImportData, parseF3D from ....utility import hexOrDecInt, applyRotation, PluginError -from ...oot_f3d_writer import ootReadActorScale -from ...oot_model_classes import OOTF3DContext, ootGetIncludedAssetData -from ...oot_utility import OOTEnum, ootGetObjectPath, getOOTScale, ootGetObjectHeaderPath, ootGetEnums, ootStripComments -from ...oot_texture_array import ootReadTextureArrays +from ...f3d_writer import ootReadActorScale +from ...model_classes import OOTF3DContext, ootGetIncludedAssetData +from ...utility import OOTEnum, ootGetObjectPath, getOOTScale, ootGetObjectHeaderPath, ootGetEnums, ootStripComments +from ...texture_array import ootReadTextureArrays from ..constants import ootSkeletonImportDict from ..properties import OOTSkeletonImportSettings from ..utility import ootGetLimb, ootGetLimbs, ootGetSkeleton, applySkeletonRestPose diff --git a/fast64_internal/z64/skeleton/operators.py b/fast64_internal/z64/skeleton/operators.py index 043bf8040..8d0d95ba5 100644 --- a/fast64_internal/z64/skeleton/operators.py +++ b/fast64_internal/z64/skeleton/operators.py @@ -5,7 +5,7 @@ from mathutils import Matrix from ...f3d.f3d_gbi import DLFormat from ...utility import PluginError, raisePluginError -from ..oot_utility import getStartBone, getNextBone, getOOTScale +from ..utility import getStartBone, getNextBone, getOOTScale from .exporter import ootConvertArmatureToC from .importer import ootImportSkeletonC from .properties import OOTSkeletonImportSettings, OOTSkeletonExportSettings diff --git a/fast64_internal/z64/skeleton/utility.py b/fast64_internal/z64/skeleton/utility.py index 0a565c355..ce92828bf 100644 --- a/fast64_internal/z64/skeleton/utility.py +++ b/fast64_internal/z64/skeleton/utility.py @@ -1,7 +1,7 @@ import mathutils, bpy, os, re from ...utility_anim import armatureApplyWithMesh -from ..oot_model_classes import OOTVertexGroupInfo -from ..oot_utility import checkForStartBone, getStartBone, getNextBone, ootStripComments +from ..model_classes import OOTVertexGroupInfo +from ..utility import checkForStartBone, getStartBone, getNextBone, ootStripComments from ...utility import ( PluginError, diff --git a/fast64_internal/z64/spline/panels.py b/fast64_internal/z64/spline/panels.py index e899b3075..6c2159e45 100644 --- a/fast64_internal/z64/spline/panels.py +++ b/fast64_internal/z64/spline/panels.py @@ -1,7 +1,7 @@ from bpy.types import Panel, Curve from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..oot_utility import getSceneObj, drawEnumWithCustom +from ..utility import getSceneObj, drawEnumWithCustom from ..actor.properties import OOTActorHeaderProperty from .properties import OOTSplineProperty diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index b0c32f27c..cd5d2a271 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -2,7 +2,7 @@ from bpy.props import EnumProperty, PointerProperty, StringProperty, IntProperty from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..oot_utility import drawEnumWithCustom +from ..utility import drawEnumWithCustom from ..collision.constants import ootEnumCameraCrawlspaceSType from ..actor.properties import OOTActorHeaderProperty from ..scene.properties import OOTAlternateSceneHeaderProperty diff --git a/fast64_internal/z64/oot_texture_array.py b/fast64_internal/z64/texture_array.py similarity index 99% rename from fast64_internal/z64/oot_texture_array.py rename to fast64_internal/z64/texture_array.py index 8803312ad..ad3f56772 100644 --- a/fast64_internal/z64/oot_texture_array.py +++ b/fast64_internal/z64/texture_array.py @@ -2,7 +2,7 @@ from typing import Callable from ..utility import hexOrDecInt -from .oot_model_classes import ( +from .model_classes import ( OOTF3DContext, TextureFlipbook, ootGetActorData, diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 5b40e36c3..4b5090a70 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -7,7 +7,7 @@ from ...operators import AddWaterBox, addMaterialByName from ...utility import parentObject, setOrigin from ..cutscene.motion.utility import setupCutscene, createNewCameraShot -from ..oot_utility import getNewPath +from ..utility import getNewPath from .quick_import import QuickImportAborted, quick_import_exec diff --git a/fast64_internal/z64/oot_upgrade.py b/fast64_internal/z64/upgrade.py similarity index 99% rename from fast64_internal/z64/oot_upgrade.py rename to fast64_internal/z64/upgrade.py index 75e3c4fb1..546fe6dd1 100644 --- a/fast64_internal/z64/oot_upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,8 +6,8 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from .data import OoT_ObjectData -from .oot_utility import getEvalParams -from .oot_constants import ootData +from .utility import getEvalParams +from .constants import ootData from .cutscene.constants import ootEnumCSMotionCamMode if TYPE_CHECKING: diff --git a/fast64_internal/z64/oot_utility.py b/fast64_internal/z64/utility.py similarity index 99% rename from fast64_internal/z64/oot_utility.py rename to fast64_internal/z64/utility.py index 3173cc299..50821d43a 100644 --- a/fast64_internal/z64/oot_utility.py +++ b/fast64_internal/z64/utility.py @@ -9,7 +9,7 @@ from bpy.utils import register_class, unregister_class from bpy.types import Object from typing import Callable, Optional, TYPE_CHECKING, List -from .oot_constants import ootSceneIDToName +from .constants import ootSceneIDToName from dataclasses import dataclass from ..utility import ( From a5511ab7d12057eec269b145731ece8d43233421 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:04:03 +0100 Subject: [PATCH 003/126] add MM xml data module --- fast64_internal/mm/data/xml/ActorList.xml | 928 ------------------ fast64_internal/z64/actor/operators.py | 4 +- fast64_internal/z64/actor/properties.py | 8 +- fast64_internal/z64/constants.py | 6 +- fast64_internal/z64/cutscene/classes.py | 10 +- fast64_internal/z64/cutscene/constants.py | 4 +- .../z64/cutscene/exporter/classes.py | 8 +- .../z64/cutscene/motion/operators.py | 4 +- .../z64/cutscene/motion/properties.py | 6 +- fast64_internal/z64/cutscene/operators.py | 6 +- fast64_internal/z64/cutscene/properties.py | 18 +- fast64_internal/z64/data/__init__.py | 5 +- fast64_internal/z64/data/mm/actor_data.py | 51 + fast64_internal/z64/data/mm/data.py | 21 + fast64_internal/z64/data/mm/enum_data.py | 162 +++ fast64_internal/z64/data/mm/getters.py | 12 + fast64_internal/z64/data/mm/xml/ActorList.xml | 928 ++++++++++++++++++ fast64_internal/z64/data/mm/xml/EnumData.xml | 719 ++++++++++++++ .../z64/data/{ => oot}/actor_data.py | 2 +- .../z64/data/{common.py => oot/data.py} | 0 .../z64/data/{ => oot}/enum_data.py | 2 +- fast64_internal/z64/data/{ => oot}/getters.py | 2 +- .../z64/data/{ => oot}/object_data.py | 4 +- .../z64/data/{ => oot}/xml/ActorList.xml | 0 .../z64/data/{ => oot}/xml/EnumData.xml | 0 .../z64/data/{ => oot}/xml/ObjectList.xml | 0 .../z64/exporter/cutscene/actor_cue.py | 4 +- .../z64/exporter/cutscene/common.py | 4 +- fast64_internal/z64/exporter/cutscene/data.py | 8 +- fast64_internal/z64/exporter/room/header.py | 6 +- fast64_internal/z64/exporter/scene/actors.py | 6 +- fast64_internal/z64/importer/actor.py | 8 +- fast64_internal/z64/importer/room_header.py | 4 +- fast64_internal/z64/object.py | 6 +- fast64_internal/z64/room/operators.py | 4 +- fast64_internal/z64/room/properties.py | 10 +- fast64_internal/z64/upgrade.py | 18 +- 37 files changed, 1978 insertions(+), 1010 deletions(-) delete mode 100644 fast64_internal/mm/data/xml/ActorList.xml create mode 100644 fast64_internal/z64/data/mm/actor_data.py create mode 100644 fast64_internal/z64/data/mm/data.py create mode 100644 fast64_internal/z64/data/mm/enum_data.py create mode 100644 fast64_internal/z64/data/mm/getters.py create mode 100644 fast64_internal/z64/data/mm/xml/ActorList.xml create mode 100644 fast64_internal/z64/data/mm/xml/EnumData.xml rename fast64_internal/z64/data/{ => oot}/actor_data.py (98%) rename fast64_internal/z64/data/{common.py => oot/data.py} (100%) rename fast64_internal/z64/data/{ => oot}/enum_data.py (99%) rename fast64_internal/z64/data/{ => oot}/getters.py (87%) rename fast64_internal/z64/data/{ => oot}/object_data.py (96%) rename fast64_internal/z64/data/{ => oot}/xml/ActorList.xml (100%) rename fast64_internal/z64/data/{ => oot}/xml/EnumData.xml (100%) rename fast64_internal/z64/data/{ => oot}/xml/ObjectList.xml (100%) diff --git a/fast64_internal/mm/data/xml/ActorList.xml b/fast64_internal/mm/data/xml/ActorList.xml deleted file mode 100644 index 11e286839..000000000 --- a/fast64_internal/mm/data/xml/ActorList.xml +++ /dev/null @@ -1,928 +0,0 @@ - - - - - - - - - - - - Large Orange Flame - Large Orange Flame - Large Blue Flame - Large Green Flame - Small Orange Flame - Large Orange Flame - Large Green Flame - Large Blue Flame - Large Magenta Flame - Large Pale Orange Flame - Large Pale Yellow Flame - Large Pale Green Flame - Large Pale Pink Flame - Large Pale Purple Flame - Large Pale Indigo Flame - Large Pale Blue Flame - - - - - - - - - - Golden - Golden - Appears - Clear Flag - Boss Key Chest - Golden - Falls - Switch Flag - Golden - Invisible - Wooden - Wooden - Invisible - Wooden - Clear Flag - Wooden - Falls - Switch Flag - Crash - Crash - Golden - Appears - Switch Flag - - - - - - - - - - - - - - - Regular - Large - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - Invisible - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 7e863c953..5d7d2458f 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -3,7 +3,7 @@ from bpy.props import EnumProperty, StringProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError -from ..constants import ootData +from ..constants import oot_data class OOT_SearchActorIDEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchActorIDEnumOperator(Operator): bl_property = "actorID" bl_options = {"REGISTER", "UNDO"} - actorID: EnumProperty(items=ootData.actorData.ootEnumActorID, default="ACTOR_PLAYER") + actorID: EnumProperty(items=oot_data.actorData.ootEnumActorID, default="ACTOR_PLAYER") actorUser: StringProperty(default="Actor") objName: StringProperty() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 21323c6b0..6cc227872 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -2,7 +2,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from ...utility import prop_split, label_split -from ..constants import ootData, ootEnumCamTransition +from ..constants import oot_data, ootEnumCamTransition from ..upgrade import upgradeActors from ..scene.properties import OOTAlternateSceneHeaderProperty from ..room.properties import OOTAlternateRoomHeaderProperty @@ -108,7 +108,7 @@ def draw_props( class OOTActorProperty(PropertyGroup): - actorID: EnumProperty(name="Actor", items=ootData.actorData.ootEnumActorID, default="ACTOR_PLAYER") + actorID: EnumProperty(name="Actor", items=oot_data.actorData.ootEnumActorID, default="ACTOR_PLAYER") actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") actorParam: StringProperty(name="Actor Parameter", default="0x0000") rotOverride: BoolProperty(name="Override Rotation", default=False) @@ -137,7 +137,7 @@ def draw_props(self, layout: UILayout, altRoomProp: OOTAlternateRoomHeaderProper return split.label(text="Actor ID") - split.label(text=getEnumName(ootData.actorData.ootEnumActorID, self.actorID)) + split.label(text=getEnumName(oot_data.actorData.ootEnumActorID, self.actorID)) if self.actorID == "Custom": # actorIDBox.prop(actorProp, 'actorIDCustom', text = 'Actor ID') @@ -180,7 +180,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - split.label(text=getEnumName(ootData.actorData.ootEnumActorID, self.actor.actorID)) + split.label(text=getEnumName(oot_data.actorData.ootEnumActorID, self.actor.actorID)) if self.actor.actorID == "Custom": prop_split(actorIDBox, self.actor, "actorIDCustom", "") diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index a0b33813c..564c54a16 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -1,6 +1,8 @@ -from .data import OoT_Data +from .data import OoT_Data, MM_Data -ootData = OoT_Data() + +oot_data = OoT_Data() +mm_data = MM_Data() ootEnumRoomShapeType = [ # ("Custom", "Custom", "Custom"), diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 141e16a12..ac7d2b560 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from bpy.types import Object from typing import Optional -from ..constants import ootData +from ..constants import oot_data from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger @@ -25,7 +25,7 @@ class CutsceneCmdBase: endFrame: Optional[int] = None def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): - enum = ootData.enumData.enumByKey[enumKey] + enum = oot_data.enumData.enumByKey[enumKey] item = enum.itemById.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -101,7 +101,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = ootData.enumData.enumByKey["csCmd"].itemById[self.commandType].key + self.commandType = oot_data.enumData.enumByKey["csCmd"].itemById[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -527,7 +527,7 @@ def getNewCutsceneObject(self, name: str, frameCount: int, parentObj: Object): def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Object): newActorCueListObj = self.getNewEmptyObject(name, False, parentObj) newActorCueListObj.ootEmptyType = f"CS {'Player' if 'Player' in name else 'Actor'} Cue List" - cmdEnum = ootData.enumData.enumByKey["csCmd"] + cmdEnum = oot_data.enumData.enumByKey["csCmd"] if commandType == "Player": commandType = "player_cue" @@ -566,7 +566,7 @@ def getNewActorCueObject( item = None if isPlayer: - playerEnum = ootData.enumData.enumByKey["csPlayerCueId"] + playerEnum = oot_data.enumData.enumByKey["csPlayerCueId"] if isinstance(actionID, int): item = playerEnum.itemByIndex.get(actionID) else: diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 90c613a01..b310fc075 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -1,4 +1,4 @@ -from ..constants import ootData +from ..constants import oot_data from .classes import ( CutsceneCmdActorCueList, CutsceneCmdActorCue, @@ -123,7 +123,7 @@ ] ootEnumCSActorCueListCommandType = [ - item for item in ootData.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] + item for item in oot_data.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] ] ootEnumCSActorCueListCommandType.sort() ootEnumCSActorCueListCommandType.insert(0, ("Custom", "Custom", "Custom")) diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index 3091f4477..fc8d0bf98 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object from ....utility import PluginError, indent -from ...constants import ootData +from ...constants import oot_data from ..constants import ootEnumCSListTypeListC if TYPE_CHECKING: @@ -40,7 +40,7 @@ class CutsceneCmdToC: """This class contains functions to create the cutscene commands""" def getEnumValue(self, enumKey: str, owner, propName: str): - item = ootData.enumData.enumByKey[enumKey].itemByKey.get(getattr(owner, propName)) + item = oot_data.enumData.enumByKey[enumKey].itemByKey.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def getGenericListCmd(self, cmdName: str, entryTotal: int): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = ootData.enumData.enumByKey["csCmd"].itemByKey[commandType].id + commandType = oot_data.enumData.enumByKey["csCmd"].itemByKey[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = ootData.enumData.enumByKey["csPlayerCueId"].itemByKey[cueID].id + actionID = oot_data.enumData.enumByKey["csPlayerCueId"].itemByKey[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index e4ef36581..f01d4e5a8 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty from ....utility import PluginError -from ...constants import ootData +from ...constants import oot_data from ..classes import CutsceneObjectFactory from ..constants import ootEnumCSActorCueListCommandType from ..preview import initFirstFrame, setupCompositorNodes @@ -318,7 +318,7 @@ class OOT_SearchPlayerCueIdEnumOperator(Operator): bl_property = "playerCueID" bl_options = {"REGISTER", "UNDO"} - playerCueID: EnumProperty(items=ootData.enumData.ootEnumCsPlayerCueId, default="cueid_none") + playerCueID: EnumProperty(items=oot_data.enumData.ootEnumCsPlayerCueId, default="cueid_none") objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index cd50737a8..80758099b 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...upgrade import upgradeCutsceneMotion from ...utility import getEnumName -from ...constants import ootData +from ...constants import oot_data from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType from .operators import ( @@ -86,7 +86,7 @@ class CutsceneCmdActorCueProperty(PropertyGroup): get=lambda self: getNextCuesStartFrame(self), ) - playerCueID: EnumProperty(items=ootData.enumData.ootEnumCsPlayerCueId, default="cueid_none") + playerCueID: EnumProperty(items=oot_data.enumData.ootEnumCsPlayerCueId, default="cueid_none") cueActionID: StringProperty( name="Action ID", default="0x0001", description="Actor action. Meaning is unique for each different actor." ) @@ -116,7 +116,7 @@ def draw_props(self, layout: UILayout, labelPrefix: str, isDummy: bool, objName: split = box.split(factor=0.5) searchOp = split.operator(OOT_SearchPlayerCueIdEnumOperator.bl_idname, icon="VIEWZOOM", text=label) searchOp.objName = objName - split.label(text=getEnumName(ootData.enumData.ootEnumCsPlayerCueId, self.playerCueID)) + split.label(text=getEnumName(oot_data.enumData.ootEnumCsPlayerCueId, self.playerCueID)) if not isPlayer or self.playerCueID == "Custom": split = box.split(factor=0.5) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index efb8420f4..c5719ab2c 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -9,7 +9,7 @@ from bpy.utils import register_class, unregister_class from ...utility import CData, PluginError, writeCData, raisePluginError from ..utility import getCollection -from ..constants import ootData +from ..constants import oot_data from .constants import ootEnumCSTextboxType, ootEnumCSListType from .importer import importCutsceneData from .exporter import getNewCutsceneExport @@ -238,7 +238,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty(items=ootData.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse") + csDestination: EnumProperty(items=oot_data.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse") objName: StringProperty() def execute(self, context): @@ -260,7 +260,7 @@ class OOT_SearchCSSeqOperator(Operator): bl_property = "seqId" bl_options = {"REGISTER", "UNDO"} - seqId: EnumProperty(items=ootData.enumData.ootEnumSeqId, default="general_sfx") + seqId: EnumProperty(items=oot_data.enumData.ootEnumSeqId, default="general_sfx") itemIndex: IntProperty() listType: StringProperty() diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 85cc22980..e2b6f902e 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName -from ..constants import ootData +from ..constants import oot_data from ..upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty from .operators import OOTCSTextAdd, OOT_SearchCSDestinationEnumOperator, OOTCSListAdd, OOT_SearchCSSeqOperator from .motion.preview import previewFrameHandler @@ -113,13 +113,13 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): # subprops textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( - name="Ocarina Action", items=ootData.enumData.ootEnumOcarinaSongActionId, default="teach_minuet" + name="Ocarina Action", items=oot_data.enumData.ootEnumOcarinaSongActionId, default="teach_minuet" ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") topOptionTextID: StringProperty(name="", default="0x0000") bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") - csTextType: EnumProperty(name="Text Type", items=ootData.enumData.ootEnumCsTextType, default="normal") + csTextType: EnumProperty(name="Text Type", items=oot_data.enumData.ootEnumCsTextType, default="normal") csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") def getName(self): @@ -152,10 +152,10 @@ class OOTCSTimeProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] - csSeqID: EnumProperty(name="Seq ID", items=ootData.enumData.ootEnumSeqId, default="general_sfx") + csSeqID: EnumProperty(name="Seq ID", items=oot_data.enumData.ootEnumSeqId, default="general_sfx") csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") csSeqPlayer: EnumProperty( - name="Seq Player", items=ootData.enumData.ootEnumCsFadeOutSeqPlayer, default="fade_out_fanfare" + name="Seq Player", items=oot_data.enumData.ootEnumCsFadeOutSeqPlayer, default="fade_out_fanfare" ) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") @@ -171,7 +171,7 @@ def filterName(self, name, listProp): class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] - csMiscType: EnumProperty(name="Type", items=ootData.enumData.ootEnumCsMiscType, default="rain") + csMiscType: EnumProperty(name="Type", items=oot_data.enumData.ootEnumCsMiscType, default="rain") csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -197,7 +197,7 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - transitionType: EnumProperty(items=ootData.enumData.ootEnumCsTransitionType, default="gray_fill_in") + transitionType: EnumProperty(items=oot_data.enumData.ootEnumCsTransitionType, default="gray_fill_in") transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) transitionEndFrame: IntProperty(name="", default=1, min=0) @@ -356,7 +356,7 @@ class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") csDestination: EnumProperty( - name="Destination", items=ootData.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse" + name="Destination", items=oot_data.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse" ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) @@ -407,7 +407,7 @@ def draw_props(self, layout: UILayout, obj: Object): boxRow = searchBox.row() searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") searchOp.objName = obj.name - boxRow.label(text=getEnumName(ootData.enumData.ootEnumCsDestination, self.csDestination)) + boxRow.label(text=getEnumName(oot_data.enumData.ootEnumCsDestination, self.csDestination)) if self.csDestination == "Custom": prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") diff --git a/fast64_internal/z64/data/__init__.py b/fast64_internal/z64/data/__init__.py index 52330206f..a9d9375c3 100644 --- a/fast64_internal/z64/data/__init__.py +++ b/fast64_internal/z64/data/__init__.py @@ -1,2 +1,3 @@ -from .common import OoT_Data -from .object_data import OoT_ObjectData +from .oot.data import OoT_Data +from .mm.data import MM_Data +from .oot.object_data import OoT_ObjectData diff --git a/fast64_internal/z64/data/mm/actor_data.py b/fast64_internal/z64/data/mm/actor_data.py new file mode 100644 index 000000000..a7929521c --- /dev/null +++ b/fast64_internal/z64/data/mm/actor_data.py @@ -0,0 +1,51 @@ +from os import path +from dataclasses import dataclass +from pathlib import Path +from .getters import get_xml_root +from .data import MM_BaseElement + + +@dataclass +class MM_ActorElement(MM_BaseElement): + category: str + tied_objects: list[str] + + +class MM_ActorData: + """Everything related to MM Actors""" + + def __init__(self): + # Path to the ``ActorList.xml`` file + actor_root = get_xml_root(Path(f"{path.dirname(path.abspath(__file__))}/xml/ActorList.xml").resolve()) + + # general actor list + self.actor_list: list[MM_ActorElement] = [] + + for actor in actor_root.iterfind("Actor"): + tied_objects = [] + obj_key = actor.get("ObjectKey") + actorName = f"{actor.attrib['Name']} - {actor.attrib['ID'].removeprefix('ACTOR_')}" + + if obj_key is not None: # actors don't always use an object + tied_objects = obj_key.split(",") + + self.actor_list.append( + MM_ActorElement( + actor.attrib["ID"], + actor.attrib["Key"], + actorName, + int(actor.attrib["Index"]), + actor.attrib["Category"], + tied_objects, + ) + ) + + self.actors_by_key = {actor.key: actor for actor in self.actor_list} + self.actors_by_id = {actor.id: actor for actor in self.actor_list} + + # list of tuples used by Blender's enum properties + last_index = max(1, *(actor.index for actor in self.actor_list)) + self.enum_actor_id = [("None", f"{i} (Deleted from the XML)", "None") for i in range(last_index)] + self.enum_actor_id.insert(0, ("Custom", "Custom Actor", "Custom")) + for actor in self.actor_list: + self.enum_actor_id[actor.index] = (actor.id, actor.name, actor.id) diff --git a/fast64_internal/z64/data/mm/data.py b/fast64_internal/z64/data/mm/data.py new file mode 100644 index 000000000..0644725a4 --- /dev/null +++ b/fast64_internal/z64/data/mm/data.py @@ -0,0 +1,21 @@ +from dataclasses import dataclass + + +@dataclass +class MM_BaseElement: + id: str + key: str + name: str + index: int + + +@dataclass +class MM_Data: + """Contains data related to MM, like actors or objects""" + + def __init__(self): + from .enum_data import MM_EnumData + from .actor_data import MM_ActorData + + self.enum_data = MM_EnumData() + self.actor_data = MM_ActorData() diff --git a/fast64_internal/z64/data/mm/enum_data.py b/fast64_internal/z64/data/mm/enum_data.py new file mode 100644 index 000000000..54b3336f5 --- /dev/null +++ b/fast64_internal/z64/data/mm/enum_data.py @@ -0,0 +1,162 @@ +from dataclasses import dataclass, field +from os import path +from pathlib import Path +from .getters import get_xml_root +from .data import MM_BaseElement + +# Note: "enumData" in this context refers to an MM Object file (like ``gameplay_keep``) + + +@dataclass +class MM_ItemElement(MM_BaseElement): + parent_key: str + + def __post_init__(self): + # generate the name from the id + if self.name is None: + key_to_prefix = { + "cmd": "CS_CMD", + "miscType": "CS_MISC", + "textType": "CS_TEXT", + "fadeOutSeqPlayer": "CS_FADE_OUT", + "modifySeqType": "CS_MOD", + "transitionType": "CS_TRANS", + "destinationType": "CS_DESTINATION", + "chooseCreditsSceneType": "CS_CREDITS", + "motionBlurType": "CS_MOTION_BLUR", + "rumbleType": "CS_RUMBLE", + "transitionGeneralType": "CS_TRANS_GENERAL", + "spawnFlag": "CS_SPAWN_FLAG", + "endSfx": "CS_END_SFX", + "csSplineInterpType": "CS_CAM_INTERP", + "csSplineRelTo": "CS_CAM_REL", + "playerCueId": "PLAYER_CUEID", + "naviQuestHintType": "NAVI_QUEST_HINTS", + "ocarinaSongActionId": "OCARINA_ACTION", + } + + self.name = self.id.removeprefix(f"{key_to_prefix[self.parent_key]}_") + + if self.parent_key in ["csCmd", "csPlayerCueId"]: + split = self.name.split("_") + if self.parent_key == "csCmd" and "ACTOR_CUE" in self.id: + self.name = f"Actor Cue {split[-2]}_{split[-1]}" + else: + self.name = f"Player Cue Id {split[-1]}" + else: + self.name = self.name.replace("_", " ").title() + + +@dataclass +class MM_EnumElement(MM_BaseElement): + items: list[MM_ItemElement] + item_by_key: dict[str, MM_ItemElement] = field(default_factory=dict) + item_by_index: dict[int, MM_ItemElement] = field(default_factory=dict) + item_by_id: dict[int, MM_ItemElement] = field(default_factory=dict) + + def __post_init__(self): + self.item_by_key = {item.key: item for item in self.items} + self.item_by_index = {item.index: item for item in self.items} + self.item_by_id = {item.id: item for item in self.items} + + +class MM_EnumData: + """Cutscene and misc enum data""" + + def __init__(self): + # general enumData list + self.enum_data_list: list[MM_EnumElement] = [] + + # Path to the ``EnumData.xml`` file + enum_data_root = get_xml_root(Path(f"{path.dirname(path.abspath(__file__))}/xml/EnumData.xml").resolve()) + + for enum in enum_data_root.iterfind("Enum"): + self.enum_data_list.append( + MM_EnumElement( + enum.attrib["ID"], + enum.attrib["Key"], + None, + None, + [ + MM_ItemElement( + item.attrib["ID"], + item.attrib["Key"], + # note: the name sets automatically after the init if None + item.attrib["Name"] if enum.attrib["Key"] == "seqId" else None, + int(item.attrib["Index"]), + enum.attrib["Key"], + ) + for item in enum + ], + ) + ) + + # create list of tuples used by Blender's enum properties + self.deleted_entry = ("None", "(Deleted from the XML)", "None") + + self.enum_cs_cmd: list[tuple[str, str, str]] = [] + self.enum_cs_misc_type: list[tuple[str, str, str]] = [] + self.enum_cs_text_type: list[tuple[str, str, str]] = [] + self.enum_cs_fade_out_seq_player: list[tuple[str, str, str]] = [] + self.enum_cs_modify_seq_type: list[tuple[str, str, str]] = [] + self.enum_cs_transition_type: list[tuple[str, str, str]] = [] + self.enum_cs_destination_type: list[tuple[str, str, str]] = [] + self.enum_cs_credits_scene_type: list[tuple[str, str, str]] = [] + self.enum_cs_motion_blur_type: list[tuple[str, str, str]] = [] + self.enum_cs_rumble_type: list[tuple[str, str, str]] = [] + self.enum_cs_transition_general_type: list[tuple[str, str, str]] = [] + self.enum_cs_spawn_flag: list[tuple[str, str, str]] = [] + self.enum_cs_end_sfx: list[tuple[str, str, str]] = [] + self.enum_cs_split_interp_type: list[tuple[str, str, str]] = [] + self.enum_cs_spline_rel_to: list[tuple[str, str, str]] = [] + self.enum_cs_player_cue_id: list[tuple[str, str, str]] = [] + self.enum_navi_quest_hint_type: list[tuple[str, str, str]] = [] + self.enum_ocarina_song_action_id: list[tuple[str, str, str]] = [] + self.enum_seq_id: list[tuple[str, str, str]] = [] + + self.enum_by_id = {enum.id: enum for enum in self.enum_data_list} + self.enum_by_key = {enum.key: enum for enum in self.enum_data_list} + + key_to_enum = { + "cmd": "enum_cs_cmd", + "miscType": "enum_cs_misc_type", + "textType": "enum_cs_text_type", + "fadeOutSeqPlayer": "enum_cs_fade_out_seq_player", + "modifySeqType": "enum_cs_modify_seq_type", + "transitionType": "enum_cs_transition_type", + "destinationType": "enum_cs_destination_type", + "chooseCreditsSceneType": "enum_cs_credits_scene_type", + "motionBlurType": "enum_cs_motion_blur_type", + "rumbleType": "enum_cs_rumble_type", + "transitionGeneralType": "enum_cs_transition_general_type", + "spawnFlag": "enum_cs_spawn_flag", + "endSfx": "enum_cs_end_sfx", + "csSplineInterpType": "enum_cs_split_interp_type", + "csSplineRelTo": "enum_cs_spline_rel_to", + "playerCueId": "enum_cs_player_cue_id", + "naviQuestHintType": "enum_navi_quest_hint_type", + "ocarinaSongActionId": "enum_ocarina_song_action_id", + "seqId": "enum_seq_id", + } + + for key in self.enum_by_key.keys(): + setattr(self, key_to_enum[key], self.get_enum_data(key)) + + def get_enum_data(self, enum_key: str): + enum = self.enum_by_key[enum_key] + first_index = min(1, *(item.index for item in enum.items)) + last_index = max(1, *(item.index for item in enum.items)) + 1 + enum_data = [self.deleted_entry] * last_index + custom = ("Custom", "Custom", "Custom") + + for item in enum.items: + if item.index < last_index: + identifier = item.key + enum_data[item.index] = (identifier, item.name, item.id) + + if first_index > 0: + enum_data[0] = custom + else: + enum_data.insert(0, custom) + + return enum_data diff --git a/fast64_internal/z64/data/mm/getters.py b/fast64_internal/z64/data/mm/getters.py new file mode 100644 index 000000000..538818462 --- /dev/null +++ b/fast64_internal/z64/data/mm/getters.py @@ -0,0 +1,12 @@ +from xml.etree.ElementTree import parse as parse_xml, Element +from pathlib import Path + + +def get_xml_root(xml_path: Path) -> Element: + """Parse an XML file and return its root element""" + try: + return parse_xml(xml_path.resolve()).getroot() + except: + from ....utility import PluginError + + raise PluginError(f"ERROR: File '{xml_path}' is missing or malformed.") diff --git a/fast64_internal/z64/data/mm/xml/ActorList.xml b/fast64_internal/z64/data/mm/xml/ActorList.xml new file mode 100644 index 000000000..ec1670321 --- /dev/null +++ b/fast64_internal/z64/data/mm/xml/ActorList.xml @@ -0,0 +1,928 @@ + + + + + + + + + + + + Large Orange Flame + Large Orange Flame + Large Blue Flame + Large Green Flame + Small Orange Flame + Large Orange Flame + Large Green Flame + Large Blue Flame + Large Magenta Flame + Large Pale Orange Flame + Large Pale Yellow Flame + Large Pale Green Flame + Large Pale Pink Flame + Large Pale Purple Flame + Large Pale Indigo Flame + Large Pale Blue Flame + + + + + + + + + + Golden + Golden - Appears - Clear Flag + Boss Key Chest + Golden - Falls - Switch Flag + Golden - Invisible + Wooden + Wooden - Invisible + Wooden - Clear Flag + Wooden - Falls - Switch Flag + Crash + Crash + Golden - Appears - Switch Flag + + + + + + + + + + + + + + + Regular + Large + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + Invisible + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/z64/data/mm/xml/EnumData.xml b/fast64_internal/z64/data/mm/xml/EnumData.xml new file mode 100644 index 000000000..f7321efa5 --- /dev/null +++ b/fast64_internal/z64/data/mm/xml/EnumData.xml @@ -0,0 +1,719 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/z64/data/actor_data.py b/fast64_internal/z64/data/oot/actor_data.py similarity index 98% rename from fast64_internal/z64/data/actor_data.py rename to fast64_internal/z64/data/oot/actor_data.py index 4a7411d22..4c3c746e6 100644 --- a/fast64_internal/z64/data/actor_data.py +++ b/fast64_internal/z64/data/oot/actor_data.py @@ -1,7 +1,7 @@ from os import path from dataclasses import dataclass from .getters import getXMLRoot -from .common import OoT_BaseElement +from .data import OoT_BaseElement @dataclass diff --git a/fast64_internal/z64/data/common.py b/fast64_internal/z64/data/oot/data.py similarity index 100% rename from fast64_internal/z64/data/common.py rename to fast64_internal/z64/data/oot/data.py diff --git a/fast64_internal/z64/data/enum_data.py b/fast64_internal/z64/data/oot/enum_data.py similarity index 99% rename from fast64_internal/z64/data/enum_data.py rename to fast64_internal/z64/data/oot/enum_data.py index b0975ec81..d970f93b3 100644 --- a/fast64_internal/z64/data/enum_data.py +++ b/fast64_internal/z64/data/oot/enum_data.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field from os import path from .getters import getXMLRoot -from .common import OoT_BaseElement +from .data import OoT_BaseElement # Note: "enumData" in this context refers to an OoT Object file (like ``gameplay_keep``) diff --git a/fast64_internal/z64/data/getters.py b/fast64_internal/z64/data/oot/getters.py similarity index 87% rename from fast64_internal/z64/data/getters.py rename to fast64_internal/z64/data/oot/getters.py index fb4fbfe09..a5e2d9237 100644 --- a/fast64_internal/z64/data/getters.py +++ b/fast64_internal/z64/data/oot/getters.py @@ -6,6 +6,6 @@ def getXMLRoot(xmlPath: str) -> Element: try: return parseXML(xmlPath).getroot() except: - from ...utility import PluginError + from ....utility import PluginError raise PluginError(f"ERROR: File '{xmlPath}' is missing or malformed.") diff --git a/fast64_internal/z64/data/object_data.py b/fast64_internal/z64/data/oot/object_data.py similarity index 96% rename from fast64_internal/z64/data/object_data.py rename to fast64_internal/z64/data/oot/object_data.py index 5f5183feb..69339d7c4 100644 --- a/fast64_internal/z64/data/object_data.py +++ b/fast64_internal/z64/data/oot/object_data.py @@ -1,8 +1,8 @@ from dataclasses import dataclass from os import path -from ...utility import PluginError +from ....utility import PluginError from .getters import getXMLRoot -from .common import OoT_BaseElement +from .data import OoT_BaseElement # Note: "object" in this context refers to an OoT Object file (like ``gameplay_keep``) diff --git a/fast64_internal/z64/data/xml/ActorList.xml b/fast64_internal/z64/data/oot/xml/ActorList.xml similarity index 100% rename from fast64_internal/z64/data/xml/ActorList.xml rename to fast64_internal/z64/data/oot/xml/ActorList.xml diff --git a/fast64_internal/z64/data/xml/EnumData.xml b/fast64_internal/z64/data/oot/xml/EnumData.xml similarity index 100% rename from fast64_internal/z64/data/xml/EnumData.xml rename to fast64_internal/z64/data/oot/xml/EnumData.xml diff --git a/fast64_internal/z64/data/xml/ObjectList.xml b/fast64_internal/z64/data/oot/xml/ObjectList.xml similarity index 100% rename from fast64_internal/z64/data/xml/ObjectList.xml rename to fast64_internal/z64/data/oot/xml/ObjectList.xml diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index 7154ab521..c1909d1b9 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field from ....utility import PluginError, indent -from ...constants import ootData +from ...constants import oot_data from ...cutscene.motion.utility import getRotation, getInteger from .common import CutsceneCmdBase @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = ootData.enumData.enumByKey["csCmd"].itemById[commandType].key + commandType = oot_data.enumData.enumByKey["csCmd"].itemById[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index 9b308b038..a913cce88 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional from ....utility import PluginError, indent -from ...constants import ootData +from ...constants import oot_data from ...cutscene.motion.utility import getInteger @@ -20,7 +20,7 @@ def validateFrames(self, checkEndFrame: bool = True): @staticmethod def getEnumValue(enumKey: str, value: str, isSeqLegacy: bool = False): - enum = ootData.enumData.enumByKey[enumKey] + enum = oot_data.enumData.enumByKey[enumKey] item = enum.itemById.get(value) if item is None: setting = getInteger(value) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 28decd627..f57273526 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError -from ...constants import ootData +from ...constants import oot_data from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction @@ -142,7 +142,7 @@ def getOoTPosition(self, pos): return [x, y, z] def getEnumValueFromProp(self, enumKey: str, owner, propName: str): - item = ootData.enumData.enumByKey[enumKey].itemByKey.get(getattr(owner, propName)) + item = oot_data.enumData.enumByKey[enumKey].itemByKey.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): @@ -169,7 +169,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = ootData.enumData.enumByKey["csCmd"].itemByKey[commandType].id + commandType = oot_data.enumData.enumByKey["csCmd"].itemByKey[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +183,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = ootData.enumData.enumByKey["csPlayerCueId"].itemByKey[cueID].id + actionID = oot_data.enumData.enumByKey["csPlayerCueId"].itemByKey[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index f79aa88b3..4a02ccb8e 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import CData, indent from ...utility import getObjectList -from ...constants import ootData +from ...constants import oot_data from ...room.properties import OOTRoomHeaderProperty from ..utility import Utility from ..actor import Actor @@ -96,7 +96,7 @@ def new(name: str, props: Optional[OOTRoomHeaderProperty]): if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objectList.append(ootData.objectData.objectsByKey[objProp.objectKey].id) + objectList.append(oot_data.objectData.objectsByKey[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -172,7 +172,7 @@ def new( actor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) actor.name = ( - ootData.actorData.actorsByID[actorProp.actorID].name.replace( + oot_data.actorData.actorsByID[actorProp.actorID].name.replace( f" - {actorProp.actorID.removeprefix('ACTOR_')}", "" ) if actorProp.actorID != "Custom" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index b0900da16..24acd07b3 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList -from ...constants import ootData +from ...constants import oot_data from ..utility import Utility from ..actor import Actor @@ -82,7 +82,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.id = transActorProp.actor.actorID transActor.name = ( - ootData.actorData.actorsByID[transActorProp.actor.actorID].name.replace( + oot_data.actorData.actorsByID[transActorProp.actor.actorID].name.replace( f" - {transActorProp.actor.actorID.removeprefix('ACTOR_')}", "" ) if transActorProp.actor.actorID != "Custom" @@ -153,7 +153,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor = EntranceActor() entranceActor.name = ( - ootData.actorData.actorsByID[entranceProp.actor.actorID].name.replace( + oot_data.actorData.actorsByID[entranceProp.actor.actorID].name.replace( f" - {entranceProp.actor.actorID.removeprefix('ACTOR_')}", "" ) if entranceProp.actor.actorID != "Custom" diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index edaae14b2..f8edb0e9e 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -4,7 +4,7 @@ from ...utility import parentObject, hexOrDecInt from ..scene.properties import OOTSceneHeaderProperty from ..utility import setCustomProperty, getEvalParams -from ..constants import ootEnumCamTransition, ootData +from ..constants import ootEnumCamTransition, oot_data from .classes import SharedSceneData from .constants import actorsWithRotAsParam @@ -77,7 +77,7 @@ def parseTransActorList( setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition) actorProp = transActorProp.actor - setCustomProperty(actorProp, "actorID", actorID, ootData.actorData.ootEnumActorID) + setCustomProperty(actorProp, "actorID", actorID, oot_data.actorData.ootEnumActorID) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -154,7 +154,7 @@ def parseSpawnList( spawnProp.spawnIndex = spawnIndex spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor - setCustomProperty(actorProp, "actorID", actorID, ootData.actorData.ootEnumActorID) + setCustomProperty(actorProp, "actorID", actorID, oot_data.actorData.ootEnumActorID) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -192,7 +192,7 @@ def parseActorList( actorObj.name = getDisplayNameFromActorID(actorID) actorProp = actorObj.ootActorProperty - setCustomProperty(actorProp, "actorID", actorID, ootData.actorData.ootEnumActorID) + setCustomProperty(actorProp, "actorID", actorID, oot_data.actorData.ootEnumActorID) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index b765f2bbe..4c09b9eda 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -5,7 +5,7 @@ from ..utility import setCustomProperty from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty -from ..constants import ootData, ootEnumLinkIdle, ootEnumRoomBehaviour +from ..constants import oot_data, ootEnumLinkIdle, ootEnumRoomBehaviour from .utility import getDataMatch, stripName from .classes import SharedSceneData from .constants import headerNames @@ -19,7 +19,7 @@ def parseObjectList(roomHeader: OOTRoomHeaderProperty, sceneData: str, objectLis for object in objects: objectProp = roomHeader.objectList.add() - objByID = ootData.objectData.objectsByID.get(object) + objByID = oot_data.objectData.objectsByID.get(object) if objByID is not None: objectProp.objectKey = objByID.key diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index 114a2e4c8..e8e8bf768 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -1,6 +1,6 @@ from bpy.types import Object from ..utility import ootGetSceneOrRoomHeader -from .constants import ootData +from .constants import oot_data from .exporter.room.header import RoomHeader @@ -18,11 +18,11 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header """Adds missing objects to the object list""" if len(curHeader.actors.actorList) > 0: for roomActor in curHeader.actors.actorList: - actor = ootData.actorData.actorsByID.get(roomActor.id) + actor = oot_data.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: if objKey not in ["obj_gameplay_keep", "obj_gameplay_field_keep", "obj_gameplay_dangeon_keep"]: - objID = ootData.objectData.objectsByKey[objKey].id + objID = oot_data.objectData.objectsByKey[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) addMissingObjectToProp(roomObj, headerIndex, objKey) diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index 3ab7da2fa..e25358a8f 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, IntProperty, StringProperty from ...utility import ootGetSceneOrRoomHeader -from ..constants import ootData +from ..constants import oot_data class OOT_SearchObjectEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=ootData.objectData.ootEnumObjectKey, default="obj_human") + objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index f970655a8..864bc1d23 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -18,7 +18,7 @@ ) from ..constants import ( - ootData, + oot_data, ootEnumRoomBehaviour, ootEnumLinkIdle, ootEnumRoomShapeType, @@ -36,21 +36,21 @@ class OOTObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=ootData.objectData.ootEnumObjectKey, default="obj_human") + objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod def upgrade_object(obj: Object): print(f"Processing '{obj.name}'...") - upgradeRoomHeaders(obj, ootData.objectData) + upgradeRoomHeaders(obj, oot_data.objectData) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): isLegacy = True if "objectID" in self else False if isLegacy: - objectName = ootData.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + objectName = oot_data.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] elif self.objectKey != "Custom": - objectName = ootData.objectData.objectsByKey[self.objectKey].name + objectName = oot_data.objectData.objectsByKey[self.objectKey].name else: objectName = self.objectIDCustom diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 546fe6dd1..e3bfa74bf 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -7,7 +7,7 @@ from ..utility import PluginError from .data import OoT_ObjectData from .utility import getEvalParams -from .constants import ootData +from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode if TYPE_CHECKING: @@ -180,12 +180,12 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox - Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", ootData.enumData.ootEnumOcarinaSongActionId), - Cutscene_UpgradeData("type", "csTextType", ootData.enumData.ootEnumCsTextType), + Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", oot_data.enumData.ootEnumOcarinaSongActionId), + Cutscene_UpgradeData("type", "csTextType", oot_data.enumData.ootEnumCsTextType), # Seq - Cutscene_UpgradeData("value", "csSeqID", ootData.enumData.ootEnumSeqId), + Cutscene_UpgradeData("value", "csSeqID", oot_data.enumData.ootEnumSeqId), # Misc - Cutscene_UpgradeData("operation", "csMiscType", ootData.enumData.ootEnumCsMiscType), + Cutscene_UpgradeData("operation", "csMiscType", oot_data.enumData.ootEnumCsMiscType), ] transferOldDataToNew(csListSubProp, subPropsOldToNew) @@ -210,7 +210,7 @@ def upgradeCSListProps(csListProp): # both are enums but the item list is different (the old one doesn't have a "custom" entry) convertOldDataToEnumData( - csListProp, [Cutscene_UpgradeData("fxType", "transitionType", ootData.enumData.ootEnumCsTransitionType)] + csListProp, [Cutscene_UpgradeData("fxType", "transitionType", oot_data.enumData.ootEnumCsTransitionType)] ) @@ -223,7 +223,7 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): transferOldDataToNew(csProp, csPropOldToNew) convertOldDataToEnumData( - csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", ootData.enumData.ootEnumCsDestination)] + csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", oot_data.enumData.ootEnumCsDestination)] ) @@ -242,7 +242,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): if "actor_id" in legacyData: index = legacyData["actor_id"] if index >= 0: - cmdEnum = ootData.enumData.enumByKey["csCmd"] + cmdEnum = oot_data.enumData.enumByKey["csCmd"] cmdType = cmdEnum.itemByIndex.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key @@ -263,7 +263,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): del legacyData["start_frame"] if "action_id" in legacyData: - playerEnum = ootData.enumData.enumByKey["csPlayerCueId"] + playerEnum = oot_data.enumData.enumByKey["csPlayerCueId"] item = None if isPlayer: item = playerEnum.itemByIndex.get(int(legacyData["action_id"], base=16)) From debb5dc2113f1ee416313cc663917d1a1b605079 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:32:45 +0100 Subject: [PATCH 004/126] panel renames and add game --- __init__.py | 3 ++- fast64_internal/panels.py | 6 +++--- fast64_internal/z64/animation/panels.py | 12 ++++++------ fast64_internal/z64/collision/panels.py | 8 ++++---- fast64_internal/z64/cutscene/motion/panels.py | 4 ++-- fast64_internal/z64/cutscene/panels.py | 15 +++++++-------- fast64_internal/z64/f3d/panels.py | 16 ++++++++-------- fast64_internal/z64/file_settings.py | 8 ++++---- fast64_internal/z64/scene/operators.py | 6 +++--- fast64_internal/z64/scene/panels.py | 8 ++++---- fast64_internal/z64/skeleton/panels.py | 16 ++++++++-------- fast64_internal/z64/tools/panel.py | 8 ++++---- 12 files changed, 55 insertions(+), 55 deletions(-) diff --git a/__init__.py b/__init__.py index 02117b338..38c65c35e 100644 --- a/__init__.py +++ b/__init__.py @@ -69,6 +69,7 @@ ("SM64", "SM64", "Super Mario 64", 0), ("OOT", "OOT", "Ocarina Of Time", 1), ("MK64", "MK64", "Mario Kart 64", 3), + ("MM", "MM", "Majora's Mask", 4), ("Homebrew", "Homebrew", "Homebrew", 2), ) @@ -391,7 +392,7 @@ def set_game_defaults(scene: bpy.types.Scene, set_ucode=True): if scene.gameEditorMode == "SM64": f3d_type = "F3D" world_defaults = sm64_world_defaults - elif scene.gameEditorMode == "OOT": + elif scene.gameEditorMode in {"OOT", "MM"}: f3d_type = "F3DEX2/LX2" world_defaults = oot_world_defaults elif scene.gameEditorMode == "MK64": diff --git a/fast64_internal/panels.py b/fast64_internal/panels.py index a7c986dac..812914231 100644 --- a/fast64_internal/panels.py +++ b/fast64_internal/panels.py @@ -38,15 +38,15 @@ def poll(cls, context): return scene_goal == "All" or sm64_props.goal == cls.goal or cls.goal == "All" -class OOT_Panel(bpy.types.Panel): +class Z64_Panel(bpy.types.Panel): bl_space_type = "VIEW_3D" bl_region_type = "UI" - bl_category = "OOT" + bl_category = "OOT/MM" bl_options = {"DEFAULT_CLOSED"} @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" + return context.scene.gameEditorMode in {"OOT", "MM"} class MK64_Panel(bpy.types.Panel): diff --git a/fast64_internal/z64/animation/panels.py b/fast64_internal/z64/animation/panels.py index ce3e8f00e..9fb7004ab 100644 --- a/fast64_internal/z64/animation/panels.py +++ b/fast64_internal/z64/animation/panels.py @@ -1,14 +1,14 @@ from bpy.types import Panel, Armature from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ...panels import OOT_Panel +from ...panels import Z64_Panel from .operators import OOT_ExportAnim, OOT_ImportAnim from .properties import OOTAnimExportSettingsProperty, OOTAnimImportSettingsProperty, OOTLinkTextureAnimProperty class OOT_LinkAnimPanel(Panel): - bl_idname = "OOT_PT_link_anim" - bl_label = "OOT Link Animation Properties" + bl_idname = "Z64_PT_link_anim" + bl_label = "Link Animation Properties" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "object" @@ -32,9 +32,9 @@ def draw(self, context): col.label(text="Index 0 is for auto, flipbook starts at index 1.", icon="INFO") -class OOT_ExportAnimPanel(OOT_Panel): - bl_idname = "OOT_PT_export_anim" - bl_label = "OOT Animation Exporter" +class OOT_ExportAnimPanel(Z64_Panel): + bl_idname = "Z64_PT_export_anim" + bl_label = "Animations" # called every frame def draw(self, context): diff --git a/fast64_internal/z64/collision/panels.py b/fast64_internal/z64/collision/panels.py index ee98b0745..62c96a3e8 100644 --- a/fast64_internal/z64/collision/panels.py +++ b/fast64_internal/z64/collision/panels.py @@ -1,6 +1,6 @@ from bpy.types import Panel, Camera from bpy.utils import register_class, unregister_class -from ...panels import OOT_Panel +from ...panels import Z64_Panel from .properties import OOTCollisionExportSettings, OOTCameraPositionProperty, OOTMaterialCollisionProperty from .operators import OOT_ExportCollision @@ -45,9 +45,9 @@ def draw(self, context): collisionProp.draw_props(box) -class OOT_ExportCollisionPanel(OOT_Panel): - bl_idname = "OOT_PT_export_collision" - bl_label = "OOT Collision Exporter" +class OOT_ExportCollisionPanel(Z64_Panel): + bl_idname = "Z64_PT_export_collision" + bl_label = "Collisions" # called every frame def draw(self, context): diff --git a/fast64_internal/z64/cutscene/motion/panels.py b/fast64_internal/z64/cutscene/motion/panels.py index a2018fed4..68de34d40 100644 --- a/fast64_internal/z64/cutscene/motion/panels.py +++ b/fast64_internal/z64/cutscene/motion/panels.py @@ -1,9 +1,9 @@ from bpy.utils import register_class, unregister_class -from ....panels import OOT_Panel +from ....panels import Z64_Panel from .properties import CutsceneCmdCameraShotProperty, CutsceneCmdCameraShotPointProperty -class OOT_CSMotionCameraShotPanel(OOT_Panel): +class OOT_CSMotionCameraShotPanel(Z64_Panel): bl_label = "Cutscene Motion Camera Shot Controls" bl_idname = "OOT_PT_camera_shot_panel" bl_space_type = "PROPERTIES" diff --git a/fast64_internal/z64/cutscene/panels.py b/fast64_internal/z64/cutscene/panels.py index 5cf84a908..31ecae605 100644 --- a/fast64_internal/z64/cutscene/panels.py +++ b/fast64_internal/z64/cutscene/panels.py @@ -2,24 +2,23 @@ from bpy.types import Scene from bpy.props import BoolProperty from ...utility import prop_split -from ...panels import OOT_Panel +from ...panels import Z64_Panel from .operators import OOT_ExportCutscene, OOT_ExportAllCutscenes, OOT_ImportCutscene -class OoT_PreviewSettingsPanel(OOT_Panel): - bl_idname = "OOT_PT_preview_settings" - bl_label = "OOT CS Preview Settings" +class OoT_PreviewSettingsPanel(Z64_Panel): + bl_idname = "Z64_PT_preview_settings" + bl_label = "CS Preview Settings" def draw(self, context): context.scene.ootPreviewSettingsProperty.draw_props(self.layout) -class OOT_CutscenePanel(OOT_Panel): - bl_idname = "OOT_PT_export_cutscene" - bl_label = "OOT Cutscene Exporter" +class OOT_CutscenePanel(Z64_Panel): + bl_idname = "Z64_PT_export_cutscene" + bl_label = "Cutscenes" bl_space_type = "VIEW_3D" bl_region_type = "UI" - bl_category = "OOT" def draw(self, context): layout = self.layout diff --git a/fast64_internal/z64/f3d/panels.py b/fast64_internal/z64/f3d/panels.py index 30b0bff20..637eb1c34 100644 --- a/fast64_internal/z64/f3d/panels.py +++ b/fast64_internal/z64/f3d/panels.py @@ -1,7 +1,7 @@ import bpy from bpy.types import Panel, Mesh, Armature from bpy.utils import register_class, unregister_class -from ...panels import OOT_Panel +from ...panels import Z64_Panel from ...utility import prop_split from .operators import OOT_ImportDL, OOT_ExportDL from .properties import ( @@ -49,8 +49,8 @@ def draw(self, context): class OOT_MaterialPanel(Panel): - bl_label = "OOT Material" - bl_idname = "MATERIAL_PT_OOT_Material_Inspector" + bl_label = "Material" + bl_idname = "MATERIAL_PT_Z64_Material_Inspector" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "material" @@ -82,8 +82,8 @@ def draw(self, context): class OOT_DrawLayersPanel(Panel): - bl_label = "OOT Draw Layers" - bl_idname = "WORLD_PT_OOT_Draw_Layers_Panel" + bl_label = "Draw Layers" + bl_idname = "WORLD_PT_Z64_Draw_Layers_Panel" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "world" @@ -101,9 +101,9 @@ def draw(self, context): ootDefaultRenderModeProp.draw_props(self.layout) -class OOT_ExportDLPanel(OOT_Panel): - bl_idname = "OOT_PT_export_dl" - bl_label = "OOT DL Exporter" +class OOT_ExportDLPanel(Z64_Panel): + bl_idname = "Z64_PT_export_dl" + bl_label = "Display Lists" # called every frame def draw(self, context): diff --git a/fast64_internal/z64/file_settings.py b/fast64_internal/z64/file_settings.py index b6bd246c6..4ff5162a4 100644 --- a/fast64_internal/z64/file_settings.py +++ b/fast64_internal/z64/file_settings.py @@ -3,12 +3,12 @@ from bpy.types import Scene from ..utility import prop_split from ..render_settings import on_update_render_settings -from ..panels import OOT_Panel +from ..panels import Z64_Panel -class OOT_FileSettingsPanel(OOT_Panel): - bl_idname = "OOT_PT_file_settings" - bl_label = "OOT File Settings" +class OOT_FileSettingsPanel(Z64_Panel): + bl_idname = "Z64_PT_file_settings" + bl_label = "Workspace Settings" bl_options = set() # default to being open # called every frame diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 4b18692db..eabec552b 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -214,10 +214,10 @@ def execute(self, context): class OOT_RemoveScene(Operator): - """Remove an OOT scene from an existing decomp directory.""" + """Remove a scene from an existing decomp directory.""" - bl_idname = "object.oot_remove_level" - bl_label = "OOT Remove Scene" + bl_idname = "object.z64_remove_level" + bl_label = "Remove Scene" bl_options = {"REGISTER", "UNDO"} def execute(self, context): diff --git a/fast64_internal/z64/scene/panels.py b/fast64_internal/z64/scene/panels.py index a6a2c5ab6..1ac6d1df6 100644 --- a/fast64_internal/z64/scene/panels.py +++ b/fast64_internal/z64/scene/panels.py @@ -3,7 +3,7 @@ from bpy.types import UILayout from bpy.utils import register_class, unregister_class -from ...panels import OOT_Panel +from ...panels import Z64_Panel from ..constants import ootEnumSceneID from ..utility import getEnumName from .properties import ( @@ -22,9 +22,9 @@ ) -class OOT_ExportScenePanel(OOT_Panel): - bl_idname = "OOT_PT_export_level" - bl_label = "OOT Scene Exporter" +class OOT_ExportScenePanel(Z64_Panel): + bl_idname = "Z64_PT_export_level" + bl_label = "Scenes" def drawSceneSearchOp(self, layout: UILayout, enumValue: str, opName: str): searchBox = layout.box().row() diff --git a/fast64_internal/z64/skeleton/panels.py b/fast64_internal/z64/skeleton/panels.py index f598e7b2e..8b3abd6e6 100644 --- a/fast64_internal/z64/skeleton/panels.py +++ b/fast64_internal/z64/skeleton/panels.py @@ -1,14 +1,14 @@ from bpy.types import Armature, Panel from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ...panels import OOT_Panel +from ...panels import Z64_Panel from .properties import OOTSkeletonImportSettings, OOTSkeletonExportSettings from .operators import OOT_ImportSkeleton, OOT_ExportSkeleton class OOT_SkeletonPanel(Panel): - bl_idname = "OOT_PT_skeleton" - bl_label = "OOT Skeleton Properties" + bl_idname = "Z64_PT_skeleton" + bl_label = "Skeleton Properties" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "object" @@ -34,8 +34,8 @@ def draw(self, context): class OOT_BonePanel(Panel): - bl_idname = "OOT_PT_bone" - bl_label = "OOT Bone Properties" + bl_idname = "Z64_PT_bone" + bl_label = "Bone Properties" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "bone" @@ -52,9 +52,9 @@ def draw(self, context): context.bone.ootBone.draw_props(col) -class OOT_ExportSkeletonPanel(OOT_Panel): - bl_idname = "OOT_PT_export_skeleton" - bl_label = "OOT Skeleton Exporter" +class OOT_ExportSkeletonPanel(Z64_Panel): + bl_idname = "Z64_PT_export_skeleton" + bl_label = "Skeletons" # called every frame def draw(self, context): diff --git a/fast64_internal/z64/tools/panel.py b/fast64_internal/z64/tools/panel.py index e72ac48a8..d77004b89 100644 --- a/fast64_internal/z64/tools/panel.py +++ b/fast64_internal/z64/tools/panel.py @@ -1,5 +1,5 @@ from bpy.utils import register_class, unregister_class -from ...panels import OOT_Panel +from ...panels import Z64_Panel from .operators import ( OOT_AddWaterBox, OOT_AddDoor, @@ -12,9 +12,9 @@ ) -class OoT_ToolsPanel(OOT_Panel): - bl_idname = "OOT_PT_tools" - bl_label = "OOT Tools" +class OoT_ToolsPanel(Z64_Panel): + bl_idname = "Z64_PT_tools" + bl_label = "Tools" def draw(self, context): col = self.layout.column() From d634ff947b85213d4f77ae1287f781aed08f09ba Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:46:11 +0100 Subject: [PATCH 005/126] more ui changes and add MM to game editor mode checks --- __init__.py | 2 +- fast64_internal/f3d/f3d_material.py | 4 ++-- fast64_internal/f3d/f3d_parser.py | 4 ++-- fast64_internal/f3d/flipbook.py | 4 ++-- fast64_internal/z64/__init__.py | 13 +++++++++++-- fast64_internal/z64/animation/panels.py | 4 ++-- fast64_internal/z64/collision/panels.py | 4 ++-- fast64_internal/z64/collision/properties.py | 2 +- fast64_internal/z64/f3d/panels.py | 8 ++++---- fast64_internal/z64/f3d/properties.py | 2 +- fast64_internal/z64/file_settings.py | 12 +++++++++--- fast64_internal/z64/props_panel_main.py | 6 +++--- fast64_internal/z64/skeleton/panels.py | 8 ++++---- fast64_internal/z64/spline/panels.py | 4 ++-- 14 files changed, 46 insertions(+), 31 deletions(-) diff --git a/__init__.py b/__init__.py index 38c65c35e..655acbd2a 100644 --- a/__init__.py +++ b/__init__.py @@ -68,8 +68,8 @@ gameEditorEnum = ( ("SM64", "SM64", "Super Mario 64", 0), ("OOT", "OOT", "Ocarina Of Time", 1), - ("MK64", "MK64", "Mario Kart 64", 3), ("MM", "MM", "Majora's Mask", 4), + ("MK64", "MK64", "Mario Kart 64", 3), ("Homebrew", "Homebrew", "Homebrew", 2), ) diff --git a/fast64_internal/f3d/f3d_material.py b/fast64_internal/f3d/f3d_material.py index 29d4eaa6d..fcc13d661 100644 --- a/fast64_internal/f3d/f3d_material.py +++ b/fast64_internal/f3d/f3d_material.py @@ -232,7 +232,7 @@ def update_draw_layer(self, context): drawLayer = material.f3d_mat.draw_layer if context.scene.gameEditorMode == "SM64": drawLayer.oot = drawLayerSM64toOOT[drawLayer.sm64] - elif context.scene.gameEditorMode == "OOT": + elif context.scene.gameEditorMode in {"OOT", "MM"}: if material.f3d_mat.draw_layer.oot == "Opaque": if int(material.f3d_mat.draw_layer.sm64) > 4: material.f3d_mat.draw_layer.sm64 = "1" @@ -1053,7 +1053,7 @@ def ui_uvCheck(self, layout, context): def ui_draw_layer(self, material, layout, context): if context.scene.gameEditorMode == "SM64": prop_split(layout, material.f3d_mat.draw_layer, "sm64", "Draw Layer") - elif context.scene.gameEditorMode == "OOT": + elif context.scene.gameEditorMode in {"OOT", "MM"}: prop_split(layout, material.f3d_mat.draw_layer, "oot", "Draw Layer") def ui_misc(self, f3dMat: "F3DMaterialProperty", inputCol: UILayout, showCheckBox: bool) -> None: diff --git a/fast64_internal/f3d/f3d_parser.py b/fast64_internal/f3d/f3d_parser.py index b91154916..306dba3c0 100644 --- a/fast64_internal/f3d/f3d_parser.py +++ b/fast64_internal/f3d/f3d_parser.py @@ -1983,7 +1983,7 @@ def parseVertexData(dlData: str, vertexDataName: str, f3dContext: F3DContext): pathMatch = re.search(r'\#include\s*"([^"]*)"', data) if pathMatch is not None: path = pathMatch.group(1) - if bpy.context.scene.gameEditorMode == "OOT": + if bpy.context.scene.gameEditorMode in {"OOT", "MM"}: path = f"{bpy.context.scene.fast64.oot.get_extracted_path()}/{path}" data = readFile(f3dContext.getVTXPathFromInclude(path)) @@ -2087,7 +2087,7 @@ def parseTextureData(dlData, textureName, f3dContext, imageFormat, imageSize, wi pathMatch = re.search(r'\#include\s*"(.*?)"', data, re.DOTALL) if pathMatch is not None: path = pathMatch.group(1) - if bpy.context.scene.gameEditorMode == "OOT": + if bpy.context.scene.gameEditorMode in {"OOT", "MM"}: path = f"{bpy.context.scene.fast64.oot.get_extracted_path()}/{path}" originalImage = bpy.data.images.load(f3dContext.getImagePathFromInclude(path)) image = originalImage.copy() diff --git a/fast64_internal/f3d/flipbook.py b/fast64_internal/f3d/flipbook.py index 86e9f3bdb..2377dd069 100644 --- a/fast64_internal/f3d/flipbook.py +++ b/fast64_internal/f3d/flipbook.py @@ -256,7 +256,7 @@ def ootFlipbookAnimUpdate(self, armatureObj: bpy.types.Object, segment: str, ind # we use a handler since update functions are not called when a property is animated. @persistent def flipbookAnimHandler(dummy): - if bpy.context.scene.gameEditorMode == "OOT": + if bpy.context.scene.gameEditorMode in {"OOT", "MM"}: for obj in bpy.data.objects: if obj.type == "ARMATURE": # we only want to update texture on keyframed armatures. @@ -291,7 +291,7 @@ def draw(self, context): mat = context.material col = layout.column() - if context.scene.gameEditorMode == "OOT": + if context.scene.gameEditorMode in {"OOT", "MM"}: checkFlipbookReference = ootFlipbookReferenceIsValid drawFlipbookRequirementMessage = ootFlipbookRequirementMessage else: diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 6af487842..1eedd8664 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -72,6 +72,12 @@ ("legacy", "Legacy", "Older Decomp Version"), ] +mm_versions_items = [ + ("Custom", "Custom", "Custom"), + ("n64-us", "n64-us", "n64-us"), + ("legacy", "Legacy", "Older Decomp Version"), +] + class OOT_Properties(bpy.types.PropertyGroup): """Global OOT Scene Properties found under scene.fast64.oot""" @@ -90,13 +96,16 @@ class OOT_Properties(bpy.types.PropertyGroup): animImportSettings: bpy.props.PointerProperty(type=OOTAnimImportSettingsProperty) collisionExportSettings: bpy.props.PointerProperty(type=OOTCollisionExportSettings) oot_version: bpy.props.EnumProperty(name="OoT Version", items=oot_versions_items, default="gc-eu-mq-dbg") + mm_version: bpy.props.EnumProperty(name="OoT Version", items=mm_versions_items, default="n64-us") oot_version_custom: bpy.props.StringProperty(name="Custom Version") def get_extracted_path(self): - if self.oot_version == "legacy": + version = self.oot_version if bpy.context.scene.gameEditorMode == "OOT" else self.mm_version + + if version == "legacy": return "." else: - return f"extracted/{self.oot_version if self.oot_version != 'Custom' else self.oot_version_custom}" + return f"extracted/{version if version != 'Custom' else self.oot_version_custom}" useDecompFeatures: bpy.props.BoolProperty( name="Use decomp for export", description="Use names and macros from decomp when exporting", default=True diff --git a/fast64_internal/z64/animation/panels.py b/fast64_internal/z64/animation/panels.py index 9fb7004ab..975900442 100644 --- a/fast64_internal/z64/animation/panels.py +++ b/fast64_internal/z64/animation/panels.py @@ -17,7 +17,7 @@ class OOT_LinkAnimPanel(Panel): @classmethod def poll(cls, context): return ( - context.scene.gameEditorMode == "OOT" + context.scene.gameEditorMode in {"OOT", "MM"} and hasattr(context, "object") and context.object is not None and isinstance(context.object.data, Armature) @@ -26,7 +26,7 @@ def poll(cls, context): # called every frame def draw(self, context): col = self.layout.box().column() - col.box().label(text="OOT Link Animation Inspector") + col.box().label(text="Link Animation Inspector") linkTextureAnim: OOTLinkTextureAnimProperty = context.object.ootLinkTextureAnim linkTextureAnim.draw_props(col) col.label(text="Index 0 is for auto, flipbook starts at index 1.", icon="INFO") diff --git a/fast64_internal/z64/collision/panels.py b/fast64_internal/z64/collision/panels.py index 62c96a3e8..8749c4c8d 100644 --- a/fast64_internal/z64/collision/panels.py +++ b/fast64_internal/z64/collision/panels.py @@ -15,7 +15,7 @@ class OOT_CameraPosPanel(Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" and isinstance(context.object.data, Camera) + return context.scene.gameEditorMode in {"OOT", "MM"} and isinstance(context.object.data, Camera) def draw(self, context): box = self.layout.box().column() @@ -36,7 +36,7 @@ class OOT_CollisionPanel(Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" and context.material is not None + return context.scene.gameEditorMode in {"OOT", "MM"} and context.material is not None def draw(self, context): box = self.layout.box().column() diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 34cf2258d..691fc02f3 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -93,7 +93,7 @@ def draw_props(self, layout: UILayout): layout.prop( self, "expandTab", - text="OOT Collision Properties", + text="Collision Properties", icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT", ) if self.expandTab: diff --git a/fast64_internal/z64/f3d/panels.py b/fast64_internal/z64/f3d/panels.py index 637eb1c34..641358f55 100644 --- a/fast64_internal/z64/f3d/panels.py +++ b/fast64_internal/z64/f3d/panels.py @@ -22,13 +22,13 @@ class OOT_DisplayListPanel(Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" and ( + return context.scene.gameEditorMode in {"OOT", "MM"} and ( context.object is not None and isinstance(context.object.data, Mesh) ) def draw(self, context): box = self.layout.box().column() - box.box().label(text="OOT DL Inspector") + box.box().label(text="DL Inspector") obj = context.object # prop_split(box, obj, "ootDrawLayer", "Draw Layer") @@ -58,7 +58,7 @@ class OOT_MaterialPanel(Panel): @classmethod def poll(cls, context): - return context.material is not None and context.scene.gameEditorMode == "OOT" + return context.material is not None and context.scene.gameEditorMode in {"OOT", "MM"} def draw(self, context): layout = self.layout @@ -91,7 +91,7 @@ class OOT_DrawLayersPanel(Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" + return context.scene.gameEditorMode in {"OOT", "MM"} def draw(self, context): world = context.scene.world diff --git a/fast64_internal/z64/f3d/properties.py b/fast64_internal/z64/f3d/properties.py index d4c0e4772..f7c1bd89d 100644 --- a/fast64_internal/z64/f3d/properties.py +++ b/fast64_internal/z64/f3d/properties.py @@ -140,7 +140,7 @@ def draw_props(self, layout: UILayout, mat: Object, drawLayer: str): return suffix = "(" + drawLayerSuffix[drawLayer] + ")" - layout.box().column().label(text="OOT Dynamic Material Properties " + suffix) + layout.box().column().label(text="Dynamic Material Properties " + suffix) layout.label(text="See gSPSegment calls in z_scene_table.c.") layout.label(text="Based off draw config index in gSceneTable.") dynMatLayerProp: OOTDynamicMaterialDrawLayerProperty = getattr(self, drawLayer.lower()) diff --git a/fast64_internal/z64/file_settings.py b/fast64_internal/z64/file_settings.py index 4ff5162a4..486c6d152 100644 --- a/fast64_internal/z64/file_settings.py +++ b/fast64_internal/z64/file_settings.py @@ -15,12 +15,18 @@ class OOT_FileSettingsPanel(Z64_Panel): def draw(self, context): col = self.layout.column() col.scale_y = 1.1 # extra padding, makes it easier to see these main settings - prop_split(col, context.scene, "ootBlenderScale", "OOT Scene Scale") + prop_split(col, context.scene, "ootBlenderScale", "Scene Scale") prop_split(col, context.scene, "ootDecompPath", "Decomp Path") - prop_split(col, context.scene.fast64.oot, "oot_version", "OoT Version") - if context.scene.fast64.oot.oot_version == "Custom": + if context.scene.gameEditorMode == "OOT": + version = "oot_version" + else: + version = "mm_version" + + prop_split(col, context.scene.fast64.oot, version, "Version") + + if getattr(context.scene.fast64.oot, version) == "Custom": prop_split(col, context.scene.fast64.oot, "oot_version_custom", "Custom Version") col.prop(context.scene.fast64.oot, "headerTabAffectsVisibility") diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 2a989624d..9b6ba6583 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -117,12 +117,12 @@ class OOTObjectPanel(bpy.types.Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" and (context.object is not None and context.object.type == "EMPTY") + return context.scene.gameEditorMode in {"OOT", "MM"} and (context.object is not None and context.object.type == "EMPTY") def draw(self, context): prop_split(self.layout, context.scene, "gameEditorMode", "Game") box = self.layout.box() - box.box().label(text="OOT Object Inspector") + box.box().label(text="Object Inspector") obj = context.object objName = obj.name prop_split(box, obj, "ootEmptyType", "Object Type") @@ -260,7 +260,7 @@ def oot_obj_register(): register_class(cls) bpy.types.Object.ootEmptyType = bpy.props.EnumProperty( - name="OOT Object Type", items=ootEnumEmptyType, default="None", update=onUpdateOOTEmptyType + name="Object Type", items=ootEnumEmptyType, default="None", update=onUpdateOOTEmptyType ) bpy.types.Scene.ootActiveHeaderLock = bpy.props.BoolProperty(default=False) diff --git a/fast64_internal/z64/skeleton/panels.py b/fast64_internal/z64/skeleton/panels.py index 8b3abd6e6..1c1dc5c23 100644 --- a/fast64_internal/z64/skeleton/panels.py +++ b/fast64_internal/z64/skeleton/panels.py @@ -17,7 +17,7 @@ class OOT_SkeletonPanel(Panel): @classmethod def poll(cls, context): return ( - context.scene.gameEditorMode == "OOT" + context.scene.gameEditorMode in {"OOT", "MM"} and hasattr(context, "object") and context.object is not None and isinstance(context.object.data, Armature) @@ -26,7 +26,7 @@ def poll(cls, context): # called every frame def draw(self, context): col = self.layout.box().column() - col.box().label(text="OOT Skeleton Inspector") + col.box().label(text="Skeleton Inspector") prop_split(col, context.object, "ootDrawLayer", "Draw Layer") context.object.ootSkeleton.draw_props(col) @@ -43,12 +43,12 @@ class OOT_BonePanel(Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" and context.bone is not None + return context.scene.gameEditorMode in {"OOT", "MM"} and context.bone is not None # called every frame def draw(self, context): col = self.layout.box().column() - col.box().label(text="OOT Bone Inspector") + col.box().label(text="Bone Inspector") context.bone.ootBone.draw_props(col) diff --git a/fast64_internal/z64/spline/panels.py b/fast64_internal/z64/spline/panels.py index 6c2159e45..43dc4c311 100644 --- a/fast64_internal/z64/spline/panels.py +++ b/fast64_internal/z64/spline/panels.py @@ -16,13 +16,13 @@ class OOTSplinePanel(Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode == "OOT" and ( + return context.scene.gameEditorMode in {"OOT", "MM"} and ( context.object is not None and type(context.object.data) == Curve ) def draw(self, context): box = self.layout.box().column() - box.box().label(text="OOT Spline Inspector") + box.box().label(text="Spline Inspector") curve = context.object.data if curve.splines[0].type != "NURBS": box.label(text="Only NURBS curves are compatible.") From bef6df94d3c5e0c9f95a428e0489c3ad5f627d43 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:20:51 +0100 Subject: [PATCH 006/126] implement importing scenes without custom path --- fast64_internal/z64/__init__.py | 4 +- fast64_internal/z64/constants.py | 223 +++++++ .../z64/exporter/decomp_edit/scene_table.py | 39 +- fast64_internal/z64/importer/scene.py | 27 +- fast64_internal/z64/room/properties.py | 2 + fast64_internal/z64/scene/operators.py | 41 +- fast64_internal/z64/scene/panels.py | 28 +- .../z64/scene/properties/__init__.py | 2 + .../z64/scene/properties/mm_props.py | 590 ++++++++++++++++++ .../oot_props.py} | 13 +- fast64_internal/z64/utility.py | 26 +- 11 files changed, 946 insertions(+), 49 deletions(-) create mode 100644 fast64_internal/z64/scene/properties/__init__.py create mode 100644 fast64_internal/z64/scene/properties/mm_props.py rename fast64_internal/z64/scene/{properties.py => properties/oot_props.py} (98%) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 1eedd8664..815723c88 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -2,7 +2,7 @@ from bpy.utils import register_class, unregister_class from .scene.operators import scene_ops_register, scene_ops_unregister -from .scene.properties import OOTBootupSceneOptions, scene_props_register, scene_props_unregister +from .scene.properties import OOTBootupSceneOptions, scene_props_register, scene_props_unregister, mm_scene_props_register, mm_scene_props_unregister from .scene.panels import scene_panels_register, scene_panels_unregister from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister @@ -156,6 +156,7 @@ def oot_register(registerPanels): cutscene_props_register() scene_ops_register() scene_props_register() + mm_scene_props_register() room_ops_register() room_props_register() actor_ops_register() @@ -196,6 +197,7 @@ def oot_unregister(unregisterPanels): cutscene_props_unregister() scene_ops_unregister() scene_props_unregister() + mm_scene_props_unregister() room_ops_unregister() room_props_unregister() actor_ops_unregister() diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index 564c54a16..c16719387 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -9,6 +9,7 @@ ("ROOM_SHAPE_TYPE_NORMAL", "Normal", "Normal"), ("ROOM_SHAPE_TYPE_IMAGE", "Image", "Image"), ("ROOM_SHAPE_TYPE_CULLABLE", "Cullable", "Cullable"), + ("ROOM_SHAPE_TYPE_NONE", "None", "None"), ] ootEnumHeaderMenu = [ @@ -412,6 +413,113 @@ ("SCENE_TESTROOM", "Treasure Chest Room (Testroom)", "Testroom"), ] +# The order of this list matters (normal MM scene order as defined by ``scene_table.h``) +mm_enum_scene_id = [ + ("Custom", "Custom", "Custom"), + ("SCENE_20SICHITAI2", "Southern Swamp (Clear) (Z2_20SICHITAI2)", "Z2_20SICHITAI2"), + ("SCENE_KAKUSIANA", "Lone Peak Shrine & Grottos (KAKUSIANA)", "KAKUSIANA"), + ("SCENE_SPOT00", "Cutscene Scene (SPOT00)", "SPOT00"), + ("SCENE_WITCH_SHOP", "Magic Hags' Potion Shop (Z2_WITCH_SHOP)", "Z2_WITCH_SHOP"), + ("SCENE_LAST_BS", "Majora's Lair (Z2_LAST_BS)", "Z2_LAST_BS"), + ("SCENE_HAKASHITA", "Beneath the Graveyard (Z2_HAKASHITA)", "Z2_HAKASHITA"), + ("SCENE_AYASHIISHOP", "Curiosity Shop (Z2_AYASHIISHOP)", "Z2_AYASHIISHOP"), + ("SCENE_OMOYA", "Mama's House (Ranch House in PAL) & Barn (Z2_OMOYA)", "Z2_OMOYA"), + ("SCENE_BOWLING", "Honey & Darling's Shop (Z2_BOWLING)", "Z2_BOWLING"), + ("SCENE_SONCHONOIE", "The Mayor's Residence (Z2_SONCHONOIE)", "Z2_SONCHONOIE"), + ("SCENE_IKANA", "Ikana Canyon (Z2_IKANA)", "Z2_IKANA"), + ("SCENE_KAIZOKU", "Pirates' Fortress (Z2_KAIZOKU)", "Z2_KAIZOKU"), + ("SCENE_MILK_BAR", "Milk Bar (Z2_MILK_BAR)", "Z2_MILK_BAR"), + ("SCENE_INISIE_N", "Stone Tower Temple (Z2_INISIE_N)", "Z2_INISIE_N"), + ("SCENE_TAKARAYA", "Treasure Chest Shop (Z2_TAKARAYA)", "Z2_TAKARAYA"), + ("SCENE_INISIE_R", "Inverted Stone Tower Temple (Z2_INISIE_R)", "Z2_INISIE_R"), + ("SCENE_OKUJOU", "Clock Tower Rooftop (Z2_OKUJOU)", "Z2_OKUJOU"), + ("SCENE_OPENINGDAN", "Before Clock Town (Z2_OPENINGDAN)", "Z2_OPENINGDAN"), + ("SCENE_MITURIN", "Woodfall Temple (Z2_MITURIN)", "Z2_MITURIN"), + ("SCENE_13HUBUKINOMITI", "Path to Mountain Village (Z2_13HUBUKINOMITI)", "Z2_13HUBUKINOMITI"), + ("SCENE_CASTLE", "Ancient Castle of Ikana (Z2_CASTLE)", "Z2_CASTLE"), + ("SCENE_DEKUTES", "Deku Scrub Playground (Z2_DEKUTES)", "Z2_DEKUTES"), + ("SCENE_MITURIN_BS", "Odolwa's Lair (Z2_MITURIN_BS)", "Z2_MITURIN_BS"), + ("SCENE_SYATEKI_MIZU", "Town Shooting Gallery (Z2_SYATEKI_MIZU)", "Z2_SYATEKI_MIZU"), + ("SCENE_HAKUGIN", "Snowhead Temple (Z2_HAKUGIN)", "Z2_HAKUGIN"), + ("SCENE_ROMANYMAE", "Milk Road (Z2_ROMANYMAE)", "Z2_ROMANYMAE"), + ("SCENE_PIRATE", "Pirates' Fortress Interior (Z2_PIRATE)", "Z2_PIRATE"), + ("SCENE_SYATEKI_MORI", "Swamp Shooting Gallery (Z2_SYATEKI_MORI)", "Z2_SYATEKI_MORI"), + ("SCENE_SINKAI", "Pinnacle Rock (Z2_SINKAI)", "Z2_SINKAI"), + ("SCENE_YOUSEI_IZUMI", "Fairy's Fountain (Z2_YOUSEI_IZUMI)", "Z2_YOUSEI_IZUMI"), + ("SCENE_KINSTA1", "Swamp Spider House (Z2_KINSTA1)", "Z2_KINSTA1"), + ("SCENE_KINDAN2", "Oceanside Spider House (Z2_KINDAN2)", "Z2_KINDAN2"), + ("SCENE_TENMON_DAI", "Astral Observatory (Z2_TENMON_DAI)", "Z2_TENMON_DAI"), + ("SCENE_LAST_DEKU", "Moon Deku Trial (Z2_LAST_DEKU)", "Z2_LAST_DEKU"), + ("SCENE_22DEKUCITY", "Deku Palace (Z2_22DEKUCITY)", "Z2_22DEKUCITY"), + ("SCENE_KAJIYA", "Mountain Smithy (Z2_KAJIYA)", "Z2_KAJIYA"), + ("SCENE_00KEIKOKU", "Termina Field (Z2_00KEIKOKU)", "Z2_00KEIKOKU"), + ("SCENE_POSTHOUSE", "Post Office (Z2_POSTHOUSE)", "Z2_POSTHOUSE"), + ("SCENE_LABO", "Marine Research Lab (Z2_LABO)", "Z2_LABO"), + ("SCENE_DANPEI2TEST", "Beneath the Graveyard (Day 3) and Dampe's House (Z2_DANPEI2TEST)", "Z2_DANPEI2TEST"), + ("SCENE_16GORON_HOUSE", "Goron Shrine (Z2_16GORON_HOUSE)", "Z2_16GORON_HOUSE"), + ("SCENE_33ZORACITY", "Zora Hall (Z2_33ZORACITY)", "Z2_33ZORACITY"), + ("SCENE_8ITEMSHOP", "Trading Post (Z2_8ITEMSHOP)", "Z2_8ITEMSHOP"), + ("SCENE_F01", "Romani Ranch (Z2_F01)", "Z2_F01"), + ("SCENE_INISIE_BS", "Twinmold's Lair (Z2_INISIE_BS)", "Z2_INISIE_BS"), + ("SCENE_30GYOSON", "Great Bay Coast (Z2_30GYOSON)", "Z2_30GYOSON"), + ("SCENE_31MISAKI", "Zora Cape (Z2_31MISAKI)", "Z2_31MISAKI"), + ("SCENE_TAKARAKUJI", "Lottery Shop (Z2_TAKARAKUJI)", "Z2_TAKARAKUJI"), + ("SCENE_TORIDE", "Pirates' Fortress Moat (Z2_TORIDE)", "Z2_TORIDE"), + ("SCENE_FISHERMAN", "Fisherman's Hut (Z2_FISHERMAN)", "Z2_FISHERMAN"), + ("SCENE_GORONSHOP", "Goron Shop (Z2_GORONSHOP)", "Z2_GORONSHOP"), + ("SCENE_DEKU_KING", "Deku King's Chamber (Z2_DEKU_KING)", "Z2_DEKU_KING"), + ("SCENE_LAST_GORON", "Moon Goron Trial (Z2_LAST_GORON)", "Z2_LAST_GORON"), + ("SCENE_24KEMONOMITI", "Road to Southern Swamp (Z2_24KEMONOMITI)", "Z2_24KEMONOMITI"), + ("SCENE_F01_B", "Doggy Racetrack (Z2_F01_B)", "Z2_F01_B"), + ("SCENE_F01C", "Cucco Shack (Z2_F01C)", "Z2_F01C"), + ("SCENE_BOTI", "Ikana Graveyard (Z2_BOTI)", "Z2_BOTI"), + ("SCENE_HAKUGIN_BS", "Goht's Lair (Z2_HAKUGIN_BS)", "Z2_HAKUGIN_BS"), + ("SCENE_20SICHITAI", "Southern Swamp (poison) (Z2_20SICHITAI)", "Z2_20SICHITAI"), + ("SCENE_21MITURINMAE", "Woodfall (Z2_21MITURINMAE)", "Z2_21MITURINMAE"), + ("SCENE_LAST_ZORA", "Moon Zora Trial (Z2_LAST_ZORA)", "Z2_LAST_ZORA"), + ("SCENE_11GORONNOSATO2", "Goron Village (spring) (Z2_11GORONNOSATO2)", "Z2_11GORONNOSATO2"), + ("SCENE_SEA", "Great Bay Temple (Z2_SEA)", "Z2_SEA"), + ("SCENE_35TAKI", "Waterfall Rapids (Z2_35TAKI)", "Z2_35TAKI"), + ("SCENE_REDEAD", "Beneath the Well (Z2_REDEAD)", "Z2_REDEAD"), + ("SCENE_BANDROOM", "Zora Hall Rooms (Z2_BANDROOM)", "Z2_BANDROOM"), + ("SCENE_11GORONNOSATO", "Goron Village (winter) (Z2_11GORONNOSATO)", "Z2_11GORONNOSATO"), + ("SCENE_GORON_HAKA", "Goron Graveyard (Z2_GORON_HAKA)", "Z2_GORON_HAKA"), + ("SCENE_SECOM", "Sakon's Hideout (Z2_SECOM)", "Z2_SECOM"), + ("SCENE_10YUKIYAMANOMURA", "Mountain Village (winter) (Z2_10YUKIYAMANOMURA)", "Z2_10YUKIYAMANOMURA"), + ("SCENE_TOUGITES", "Ghost Hut (Z2_TOUGITES)", "Z2_TOUGITES"), + ("SCENE_DANPEI", "Deku Shrine (Z2_DANPEI)", "Z2_DANPEI"), + ("SCENE_IKANAMAE", "Road to Ikana (Z2_IKANAMAE)", "Z2_IKANAMAE"), + ("SCENE_DOUJOU", "Swordsman's School (Z2_DOUJOU)", "Z2_DOUJOU"), + ("SCENE_MUSICHOUSE", "Music Box House (Z2_MUSICHOUSE)", "Z2_MUSICHOUSE"), + ("SCENE_IKNINSIDE", "Igos du Ikana's Lair (Z2_IKNINSIDE)", "Z2_IKNINSIDE"), + ("SCENE_MAP_SHOP", "Tourist Information (Z2_MAP_SHOP)", "Z2_MAP_SHOP"), + ("SCENE_F40", "Stone Tower (Z2_F40)", "Z2_F40"), + ("SCENE_F41", "Inverted Stone Tower (Z2_F41)", "Z2_F41"), + ("SCENE_10YUKIYAMANOMURA2", "Mountain Village (spring) (Z2_10YUKIYAMANOMURA2)", "Z2_10YUKIYAMANOMURA2"), + ("SCENE_14YUKIDAMANOMITI", "Path to Snowhead (Z2_14YUKIDAMANOMITI)", "Z2_14YUKIDAMANOMITI"), + ("SCENE_12HAKUGINMAE", "Snowhead (Z2_12HAKUGINMAE)", "Z2_12HAKUGINMAE"), + ("SCENE_17SETUGEN", "Path to Goron Village (winter) (Z2_17SETUGEN)", "Z2_17SETUGEN"), + ("SCENE_17SETUGEN2", "Path to Goron Village (spring) (Z2_17SETUGEN2)", "Z2_17SETUGEN2"), + ("SCENE_SEA_BS", "Gyorg's Lair (Z2_SEA_BS)", "Z2_SEA_BS"), + ("SCENE_RANDOM", "Secret Shrine (Z2_RANDOM)", "Z2_RANDOM"), + ("SCENE_YADOYA", "Stock Pot Inn (Z2_YADOYA)", "Z2_YADOYA"), + ("SCENE_KONPEKI_ENT", "Great Bay Cutscene (Z2_KONPEKI_ENT)", "Z2_KONPEKI_ENT"), + ("SCENE_INSIDETOWER", "Clock Tower Interior (Z2_INSIDETOWER)", "Z2_INSIDETOWER"), + ("SCENE_26SARUNOMORI", "Woods of Mystery (Z2_26SARUNOMORI)", "Z2_26SARUNOMORI"), + ("SCENE_LOST_WOODS", "Lost Woods (Intro) (Z2_LOST_WOODS)", "Z2_LOST_WOODS"), + ("SCENE_LAST_LINK", "Moon Link Trial (Z2_LAST_LINK)", "Z2_LAST_LINK"), + ("SCENE_SOUGEN", "The Moon (Z2_SOUGEN)", "Z2_SOUGEN"), + ("SCENE_BOMYA", "Bomb Shop (Z2_BOMYA)", "Z2_BOMYA"), + ("SCENE_KYOJINNOMA", "Giants' Chamber (Z2_KYOJINNOMA)", "Z2_KYOJINNOMA"), + ("SCENE_KOEPONARACE", "Gorman Track (Z2_KOEPONARACE)", "Z2_KOEPONARACE"), + ("SCENE_GORONRACE", "Goron Racetrack (Z2_GORONRACE)", "Z2_GORONRACE"), + ("SCENE_TOWN", "East Clock Town (Z2_TOWN)", "Z2_TOWN"), + ("SCENE_ICHIBA", "West Clock Town (Z2_ICHIBA)", "Z2_ICHIBA"), + ("SCENE_BACKTOWN", "North Clock Town (Z2_BACKTOWN)", "Z2_BACKTOWN"), + ("SCENE_CLOCKTOWER", "South Clock Town (Z2_CLOCKTOWER)", "Z2_CLOCKTOWER"), + ("SCENE_ALLEY", "Laundry Pool (Z2_ALLEY)", "Z2_ALLEY"), +] + ootSceneIDToName = { "SCENE_DEKU_TREE": "ydan", "SCENE_DODONGOS_CAVERN": "ddan", @@ -526,6 +634,112 @@ } ootSceneNameToID = {val: key for key, val in ootSceneIDToName.items()} +mm_scene_id_to_name = { + "SCENE_20SICHITAI2": "Z2_20SICHITAI2", + "SCENE_KAKUSIANA": "KAKUSIANA", + "SCENE_SPOT00": "SPOT00", + "SCENE_WITCH_SHOP": "Z2_WITCH_SHOP", + "SCENE_LAST_BS": "Z2_LAST_BS", + "SCENE_HAKASHITA": "Z2_HAKASHITA", + "SCENE_AYASHIISHOP": "Z2_AYASHIISHOP", + "SCENE_OMOYA": "Z2_OMOYA", + "SCENE_BOWLING": "Z2_BOWLING", + "SCENE_SONCHONOIE": "Z2_SONCHONOIE", + "SCENE_IKANA": "Z2_IKANA", + "SCENE_KAIZOKU": "Z2_KAIZOKU", + "SCENE_MILK_BAR": "Z2_MILK_BAR", + "SCENE_INISIE_N": "Z2_INISIE_N", + "SCENE_TAKARAYA": "Z2_TAKARAYA", + "SCENE_INISIE_R": "Z2_INISIE_R", + "SCENE_OKUJOU": "Z2_OKUJOU", + "SCENE_OPENINGDAN": "Z2_OPENINGDAN", + "SCENE_MITURIN": "Z2_MITURIN", + "SCENE_13HUBUKINOMITI": "Z2_13HUBUKINOMITI", + "SCENE_CASTLE": "Z2_CASTLE", + "SCENE_DEKUTES": "Z2_DEKUTES", + "SCENE_MITURIN_BS": "Z2_MITURIN_BS", + "SCENE_SYATEKI_MIZU": "Z2_SYATEKI_MIZU", + "SCENE_HAKUGIN": "Z2_HAKUGIN", + "SCENE_ROMANYMAE": "Z2_ROMANYMAE", + "SCENE_PIRATE": "Z2_PIRATE", + "SCENE_SYATEKI_MORI": "Z2_SYATEKI_MORI", + "SCENE_SINKAI": "Z2_SINKAI", + "SCENE_YOUSEI_IZUMI": "Z2_YOUSEI_IZUMI", + "SCENE_KINSTA1": "Z2_KINSTA1", + "SCENE_KINDAN2": "Z2_KINDAN2", + "SCENE_TENMON_DAI": "Z2_TENMON_DAI", + "SCENE_LAST_DEKU": "Z2_LAST_DEKU", + "SCENE_22DEKUCITY": "Z2_22DEKUCITY", + "SCENE_KAJIYA": "Z2_KAJIYA", + "SCENE_00KEIKOKU": "Z2_00KEIKOKU", + "SCENE_POSTHOUSE": "Z2_POSTHOUSE", + "SCENE_LABO": "Z2_LABO", + "SCENE_DANPEI2TEST": "Z2_DANPEI2TEST", + "SCENE_16GORON_HOUSE": "Z2_16GORON_HOUSE", + "SCENE_33ZORACITY": "Z2_33ZORACITY", + "SCENE_8ITEMSHOP": "Z2_8ITEMSHOP", + "SCENE_F01": "Z2_F01", + "SCENE_INISIE_BS": "Z2_INISIE_BS", + "SCENE_30GYOSON": "Z2_30GYOSON", + "SCENE_31MISAKI": "Z2_31MISAKI", + "SCENE_TAKARAKUJI": "Z2_TAKARAKUJI", + "SCENE_TORIDE": "Z2_TORIDE", + "SCENE_FISHERMAN": "Z2_FISHERMAN", + "SCENE_GORONSHOP": "Z2_GORONSHOP", + "SCENE_DEKU_KING": "Z2_DEKU_KING", + "SCENE_LAST_GORON": "Z2_LAST_GORON", + "SCENE_24KEMONOMITI": "Z2_24KEMONOMITI", + "SCENE_F01_B": "Z2_F01_B", + "SCENE_F01C": "Z2_F01C", + "SCENE_BOTI": "Z2_BOTI", + "SCENE_HAKUGIN_BS": "Z2_HAKUGIN_BS", + "SCENE_20SICHITAI": "Z2_20SICHITAI", + "SCENE_21MITURINMAE": "Z2_21MITURINMAE", + "SCENE_LAST_ZORA": "Z2_LAST_ZORA", + "SCENE_11GORONNOSATO2": "Z2_11GORONNOSATO2", + "SCENE_SEA": "Z2_SEA", + "SCENE_35TAKI": "Z2_35TAKI", + "SCENE_REDEAD": "Z2_REDEAD", + "SCENE_BANDROOM": "Z2_BANDROOM", + "SCENE_11GORONNOSATO": "Z2_11GORONNOSATO", + "SCENE_GORON_HAKA": "Z2_GORON_HAKA", + "SCENE_SECOM": "Z2_SECOM", + "SCENE_10YUKIYAMANOMURA": "Z2_10YUKIYAMANOMURA", + "SCENE_TOUGITES": "Z2_TOUGITES", + "SCENE_DANPEI": "Z2_DANPEI", + "SCENE_IKANAMAE": "Z2_IKANAMAE", + "SCENE_DOUJOU": "Z2_DOUJOU", + "SCENE_MUSICHOUSE": "Z2_MUSICHOUSE", + "SCENE_IKNINSIDE": "Z2_IKNINSIDE", + "SCENE_MAP_SHOP": "Z2_MAP_SHOP", + "SCENE_F40": "Z2_F40", + "SCENE_F41": "Z2_F41", + "SCENE_10YUKIYAMANOMURA2": "Z2_10YUKIYAMANOMURA2", + "SCENE_14YUKIDAMANOMITI": "Z2_14YUKIDAMANOMITI", + "SCENE_12HAKUGINMAE": "Z2_12HAKUGINMAE", + "SCENE_17SETUGEN": "Z2_17SETUGEN", + "SCENE_17SETUGEN2": "Z2_17SETUGEN2", + "SCENE_SEA_BS": "Z2_SEA_BS", + "SCENE_RANDOM": "Z2_RANDOM", + "SCENE_YADOYA": "Z2_YADOYA", + "SCENE_KONPEKI_ENT": "Z2_KONPEKI_ENT", + "SCENE_INSIDETOWER": "Z2_INSIDETOWER", + "SCENE_26SARUNOMORI": "Z2_26SARUNOMORI", + "SCENE_LOST_WOODS": "Z2_LOST_WOODS", + "SCENE_LAST_LINK": "Z2_LAST_LINK", + "SCENE_SOUGEN": "Z2_SOUGEN", + "SCENE_BOMYA": "Z2_BOMYA", + "SCENE_KYOJINNOMA": "Z2_KYOJINNOMA", + "SCENE_KOEPONARACE": "Z2_KOEPONARACE", + "SCENE_GORONRACE": "Z2_GORONRACE", + "SCENE_TOWN": "Z2_TOWN", + "SCENE_ICHIBA": "Z2_ICHIBA", + "SCENE_BACKTOWN": "Z2_BACKTOWN", + "SCENE_CLOCKTOWER": "Z2_CLOCKTOWER", + "SCENE_ALLEY": "Z2_ALLEY", +} +mm_scene_name_to_id = {val: key for key, val in mm_scene_id_to_name.items()} + ootEnumCamTransition = [ ("Custom", "Custom", "Custom"), ("0x00", "0x00", "0x00"), @@ -605,6 +819,15 @@ ("SDC_INSIDE_GANONS_CASTLE_COLLAPSE", "Inside Ganon's Castle (Collapsing) (Ganontika Sonogo)", "Ganontika Sonogo"), ] +mm_enum_draw_config = [ + ("Custom", "Custom", "Custom"), + ("SCENE_DRAW_CFG_DEFAULT", "Default", "Default"), + ("SCENE_DRAW_CFG_MAT_ANIM", "Material Animated", "Material Animated"), + ("SCENE_DRAW_CFG_NOTHING", "Nothing", "Nothing"), + ("SCENE_DRAW_CFG_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), + ("SCENE_DRAW_CFG_MAT_ANIM_MANUAL_STEP", "Material Animated (manual step)", "Material Animated (manual step)"), +] + oot_world_defaults = { "geometryMode": { "zBuffer": True, diff --git a/fast64_internal/z64/exporter/decomp_edit/scene_table.py b/fast64_internal/z64/exporter/decomp_edit/scene_table.py index 07997572c..1e5d51b80 100644 --- a/fast64_internal/z64/exporter/decomp_edit/scene_table.py +++ b/fast64_internal/z64/exporter/decomp_edit/scene_table.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile -from ...constants import ootEnumSceneID, ootSceneNameToID +from ...constants import ootEnumSceneID, ootSceneNameToID, mm_enum_scene_id, mm_scene_name_to_id ADDED_SCENES_COMMENT = "// Added scenes" @@ -13,8 +13,13 @@ def get_original_index(enum_value: str) -> Optional[int]: """ Returns the original index of a specific scene """ + if bpy.context.scene.gameEditorMode == "OOT": + enum_scene_id = ootEnumSceneID + else: + enum_scene_id = mm_enum_scene_id + for index, scene_enum in enumerate( - [elem[0] for elem in ootEnumSceneID[1:]] + [elem[0] for elem in enum_scene_id[1:]] ): # ignore first value in array ('Custom') if scene_enum == enum_value: return index @@ -22,7 +27,10 @@ def get_original_index(enum_value: str) -> Optional[int]: def get_scene_enum_from_name(scene_name: str): - return ootSceneNameToID.get(scene_name, f"SCENE_{scene_name.upper()}") + if bpy.context.scene.gameEditorMode == "OOT": + return ootSceneNameToID.get(scene_name, f"SCENE_{scene_name.upper()}") + else: + return mm_scene_name_to_id.get(scene_name, f"SCENE_{scene_name.upper()}") @dataclass @@ -46,10 +54,22 @@ def from_line(original_line: str): index = original_line.index(macro_start) + len(macro_start) parsed = original_line[index:].removesuffix(")") - params = parsed.split(", ") - assert len(params) == 6 + if bpy.context.scene.gameEditorMode == "OOT": + params = parsed.split(", ") + assert len(params) == 6 + return SceneTableEntry(*params) + else: + split = parsed.split(", ") + params = [] + for i, elem in enumerate(split): + if i == 5: + break + else: + params.append(elem) + params.append(", ".join(split[i:])) + assert len(params) == 6 + return SceneTableEntry(params[0], params[2], params[1], params[3], params[4], params[5]) - return SceneTableEntry(*params) else: raise PluginError("ERROR: This line is not a scene table entry!") @@ -138,7 +158,7 @@ def new(export_path: str): if current_section: # handles non-directive section preceding directive section sections.append(current_section) current_section = SceneTableSection(line) - else: + elif "DEFINE_SCENE_UNSET" not in line: if not current_section: current_section = SceneTableSection(None) current_section.entries.append(SceneTableEntry.from_line(line)) @@ -252,12 +272,15 @@ class SceneTableUtility: @staticmethod def get_draw_config(scene_name: str): """Read draw config from scene table""" + if bpy.context.scene.gameEditorMode == "OOT": + scene_name = f"{scene_name}_scene" + scene_table = SceneTable.new( os.path.join(bpy.path.abspath(bpy.context.scene.ootDecompPath), "include/tables/scene_table.h") ) spec_dict = {entry.spec_name: entry for entry in scene_table.get_entries_flattened()} - entry = spec_dict.get(f"{scene_name}_scene") + entry = spec_dict.get(f"{scene_name}") if entry is not None: return entry.draw_config diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 418961104..cc4c27f5b 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -9,8 +9,8 @@ from ...f3d.flipbook import TextureFlipbook from ..model_classes import OOTF3DContext from ..exporter.decomp_edit.scene_table import SceneTableUtility -from ..scene.properties import OOTImportSceneSettingsProperty -from ..constants import ootEnumDrawConfig +from ..scene.properties import OOTImportSceneSettingsProperty, MM_ImportSceneSettingsProperty +from ..constants import ootEnumDrawConfig, mm_enum_draw_config from .scene_header import parseSceneCommands from .classes import SharedSceneData from ..cutscene.importer import importCutsceneData @@ -75,10 +75,11 @@ def parseDrawConfig(drawConfigName: str, sceneData: str, drawConfigData: str, f3 def parseScene( - settings: OOTImportSceneSettingsProperty, + settings: OOTImportSceneSettingsProperty | MM_ImportSceneSettingsProperty, option: str, ): sceneName = settings.name + if settings.isCustomDest: importPath = bpy.path.abspath(settings.destPath) subfolder = None @@ -90,6 +91,9 @@ def parseScene( subfolder = None importPath = bpy.path.abspath(bpy.context.scene.ootDecompPath) + if bpy.context.scene.gameEditorMode == "OOT": + sceneName = f"{sceneName}_scene" + importSubdir = "" if settings.isCustomDest is not None: importSubdir = subfolder @@ -104,18 +108,9 @@ def parseScene( False, True, ) - filePath = os.path.join(sceneFolderPath, f"{sceneName}_scene.c") + filePath = os.path.join(sceneFolderPath, f"{sceneName}.c") sceneData = readFile(filePath) - # roomData = "" - # sceneFolderFiles = [f for f in listdir(sceneFolderPath) if isfile(join(sceneFolderPath, f))] - # for sceneFile in sceneFolderFiles: - # if re.search(rf"{sceneName}_room_[0-9]+\.c", sceneFile): - # roomPath = os.path.join(sceneFolderPath, sceneFile) - # roomData += readFile(roomPath) - - # sceneData += roomData - if bpy.context.mode != "OBJECT": bpy.context.mode = "OBJECT" @@ -136,9 +131,9 @@ def parseScene( bpy.context.space_data.overlay.show_curve_normals = True bpy.context.space_data.overlay.normals_length = 2 - sceneCommandsName = f"{sceneName}_sceneCommands" + sceneCommandsName = f"{sceneName}Commands" if sceneCommandsName not in sceneData: - sceneCommandsName = f"{sceneName}_scene_header00" # fast64 naming + sceneCommandsName = f"{sceneName}_header00" # fast64 naming sharedSceneData = SharedSceneData( sceneFolderPath, settings.includeMesh, @@ -163,7 +158,7 @@ def parseScene( sceneObj.ootSceneHeader.sceneTableEntry, "drawConfig", SceneTableUtility.get_draw_config(sceneName), - ootEnumDrawConfig, + ootEnumDrawConfig if bpy.context.scene.gameEditorMode == "OOT" else mm_enum_draw_config, ) if bpy.context.scene.fast64.oot.headerTabAffectsVisibility: diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 864bc1d23..2ddae37e9 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -176,6 +176,8 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general.label(text="and requires meshes to be parented to Custom Cull Group empties.") general.label(text="RSP culling is done automatically regardless of room shape.") prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") + if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and bpy.context.scene.gameEditorMode == "OOT": + general.label(text="This shape type is only implemented on MM", icon="INFO") # Behaviour behaviourBox = layout.column() behaviourBox.box().label(text="Behaviour") diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index eabec552b..137fa8d48 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -10,7 +10,7 @@ from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader from ..utility import ExportInfo, RemoveInfo, sceneNameFromID -from ..constants import ootEnumMusicSeq, ootEnumSceneID +from ..constants import ootEnumMusicSeq, ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config from ..exporter import SceneExport, Files @@ -33,7 +33,10 @@ def dummy_view_layer_update(context): def parseSceneFunc(): - settings = bpy.context.scene.ootSceneImportSettings + if bpy.context.scene.gameEditorMode == "OOT": + settings = bpy.context.scene.ootSceneImportSettings + else: + settings = bpy.context.scene.mm_scene_import_settings parseScene(settings, settings.option) @@ -65,6 +68,34 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} +class MM_SearchSceneEnumOperator(Operator): + bl_idname = "object.mm_search_scene_enum_operator" + bl_label = "Choose Scene" + bl_property = "scene_id" + bl_options = {"REGISTER", "UNDO"} + + scene_id: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + op_name: StringProperty(default="Export") + + def execute(self, context): + if self.op_name == "Export": + context.scene.mm_scene_export_settings.option = self.scene_id + elif self.op_name == "Import": + context.scene.mm_scene_import_settings.option = self.scene_id + elif self.op_name == "Remove": + context.scene.mm_scene_remove_settings.option = self.scene_id + else: + raise Exception(f'Invalid MM scene search operator name: "{self.op_name}"') + + context.region.tag_redraw() + self.report({"INFO"}, "Selected: " + self.scene_id) + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {"RUNNING_MODAL"} + + class OOT_SearchMusicSeqEnumOperator(Operator): bl_idname = "object.oot_search_music_seq_enum_operator" bl_label = "Search Music Sequence" @@ -221,7 +252,10 @@ class OOT_RemoveScene(Operator): bl_options = {"REGISTER", "UNDO"} def execute(self, context): - settings = context.scene.ootSceneRemoveSettings # Type: OOTRemoveSceneSettingsProperty + if context.scene.gameEditorMode == "OOT": + settings = context.scene.ootSceneRemoveSettings # Type: OOTRemoveSceneSettingsProperty + else: + settings = context.scene.mm_scene_remove_settings # Type: MM_RemoveSceneSettingsProperty option = settings.option if settings.customExport: @@ -256,6 +290,7 @@ def draw(self, context): OOT_ImportScene, OOT_ExportScene, OOT_RemoveScene, + MM_SearchSceneEnumOperator, ) diff --git a/fast64_internal/z64/scene/panels.py b/fast64_internal/z64/scene/panels.py index 1ac6d1df6..ff58a656c 100644 --- a/fast64_internal/z64/scene/panels.py +++ b/fast64_internal/z64/scene/panels.py @@ -4,13 +4,16 @@ from bpy.types import UILayout from bpy.utils import register_class, unregister_class from ...panels import Z64_Panel -from ..constants import ootEnumSceneID +from ..constants import ootEnumSceneID, mm_enum_scene_id from ..utility import getEnumName from .properties import ( OOTExportSceneSettingsProperty, OOTImportSceneSettingsProperty, OOTRemoveSceneSettingsProperty, OOTBootupSceneOptions, + MM_ExportSceneSettingsProperty, + MM_ImportSceneSettingsProperty, + MM_RemoveSceneSettingsProperty, ) from .operators import ( @@ -19,6 +22,7 @@ OOT_RemoveScene, OOT_ClearBootupScene, OOT_SearchSceneEnumOperator, + MM_SearchSceneEnumOperator, ) @@ -28,8 +32,13 @@ class OOT_ExportScenePanel(Z64_Panel): def drawSceneSearchOp(self, layout: UILayout, enumValue: str, opName: str): searchBox = layout.box().row() - searchBox.operator(OOT_SearchSceneEnumOperator.bl_idname, icon="VIEWZOOM", text="").opName = opName - searchBox.label(text=getEnumName(ootEnumSceneID, enumValue)) + + if bpy.context.scene.gameEditorMode == "OOT": + searchBox.operator(OOT_SearchSceneEnumOperator.bl_idname, icon="VIEWZOOM", text="").opName = opName + searchBox.label(text=getEnumName(ootEnumSceneID, enumValue)) + else: + searchBox.operator(MM_SearchSceneEnumOperator.bl_idname, icon="VIEWZOOM", text="").op_name = opName + searchBox.label(text=getEnumName(mm_enum_scene_id, enumValue)) def draw(self, context): col = self.layout.column() @@ -38,7 +47,15 @@ def draw(self, context): exportBox = col.box().column() exportBox.label(text="Scene Exporter") - settings: OOTExportSceneSettingsProperty = context.scene.ootSceneExportSettings + if bpy.context.scene.gameEditorMode == "OOT": + settings: OOTExportSceneSettingsProperty = context.scene.ootSceneExportSettings + importSettings: OOTImportSceneSettingsProperty = context.scene.ootSceneImportSettings + removeSettings: OOTRemoveSceneSettingsProperty = context.scene.ootSceneRemoveSettings + else: + settings: MM_ExportSceneSettingsProperty = context.scene.mm_scene_export_settings + importSettings: MM_ImportSceneSettingsProperty = context.scene.mm_scene_import_settings + removeSettings: MM_RemoveSceneSettingsProperty = context.scene.mm_scene_remove_settings + if not settings.customExport: self.drawSceneSearchOp(exportBox, settings.option, "Export") settings.draw_props(exportBox) @@ -61,8 +78,6 @@ def draw(self, context): importBox = col.box().column() importBox.label(text="Scene Importer") - importSettings: OOTImportSceneSettingsProperty = context.scene.ootSceneImportSettings - if not importSettings.isCustomDest: self.drawSceneSearchOp(importBox, importSettings.option, "Import") @@ -73,7 +88,6 @@ def draw(self, context): removeBox = col.box().column() removeBox.label(text="Remove Scene") - removeSettings: OOTRemoveSceneSettingsProperty = context.scene.ootSceneRemoveSettings self.drawSceneSearchOp(removeBox, removeSettings.option, "Remove") removeSettings.draw_props(removeBox) diff --git a/fast64_internal/z64/scene/properties/__init__.py b/fast64_internal/z64/scene/properties/__init__.py new file mode 100644 index 000000000..748d8b959 --- /dev/null +++ b/fast64_internal/z64/scene/properties/__init__.py @@ -0,0 +1,2 @@ +from .oot_props import OOTSceneHeaderProperty, OOTBootupSceneOptions, OOTSceneProperties, OOTAlternateSceneHeaderProperty, OOTLightProperty, OOTExportSceneSettingsProperty, OOTImportSceneSettingsProperty, OOTRemoveSceneSettingsProperty, scene_props_register, scene_props_unregister +from .mm_props import MM_ExportSceneSettingsProperty, MM_ImportSceneSettingsProperty, MM_RemoveSceneSettingsProperty, mm_scene_props_register, mm_scene_props_unregister diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py new file mode 100644 index 000000000..7120c794a --- /dev/null +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -0,0 +1,590 @@ +# WORK IN PROGRESS! + +import bpy + +from bpy.types import PropertyGroup, Object, Light, UILayout, Scene +from bpy.props import ( + EnumProperty, + IntProperty, + StringProperty, + CollectionProperty, + PointerProperty, + BoolProperty, + FloatVectorProperty, +) +from bpy.utils import register_class, unregister_class +from ....render_settings import on_update_oot_render_settings +from ....utility import prop_split, customExportWarning +from ...cutscene.constants import ootEnumCSWriteType + +from ...utility import ( + onMenuTabChange, + onHeaderMenuTabChange, + drawCollectionOps, + drawEnumWithCustom, + drawAddButton, +) + +from ...constants import ( + ootEnumMusicSeq, + mm_enum_scene_id, + ootEnumGlobalObject, + ootEnumNaviHints, + ootEnumSkybox, + ootEnumCloudiness, + ootEnumSkyboxLighting, + ootEnumMapLocation, + ootEnumCameraMode, + ootEnumNightSeq, + ootEnumAudioSessionPreset, + ootEnumHeaderMenu, + mm_enum_draw_config, + ootEnumHeaderMenuComplete, +) + +ootEnumSceneMenuAlternate = [ + ("General", "General", "General"), + ("Lighting", "Lighting", "Lighting"), + ("Cutscene", "Cutscene", "Cutscene"), + ("Exits", "Exits", "Exits"), +] +ootEnumSceneMenu = ootEnumSceneMenuAlternate + [ + ("Alternate", "Alternate", "Alternate"), +] + +ootEnumLightGroupMenu = [ + ("Dawn", "Dawn", "Dawn"), + ("Day", "Day", "Day"), + ("Dusk", "Dusk", "Dusk"), + ("Night", "Night", "Night"), +] + +ootEnumTransitionAnims = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Spiky", "Spiky"), + ("0x01", "Triforce", "Triforce"), + ("0x02", "Slow Black Fade", "Slow Black Fade"), + ("0x03", "Slow Day/White, Slow Night/Black Fade", "Slow Day/White, Slow Night/Black Fade"), + ("0x04", "Fast Day/Black, Slow Night/Black Fade", "Fast Day/Black, Slow Night/Black Fade"), + ("0x05", "Fast Day/White, Slow Night/Black Fade", "Fast Day/White, Slow Night/Black Fade"), + ("0x06", "Very Slow Day/White, Slow Night/Black Fade", "Very Slow Day/White, Slow Night/Black Fade"), + ("0x07", "Very Slow Day/White, Slow Night/Black Fade", "Very Slow Day/White, Slow Night/Black Fade"), + ("0x0E", "Slow Sandstorm Fade", "Slow Sandstorm Fade"), + ("0x0F", "Fast Sandstorm Fade", "Fast Sandstorm Fade"), + ("0x20", "Iris Fade", "Iris Fade"), + ("0x2C", "Shortcut Transition", "Shortcut Transition"), +] + +ootEnumExitIndex = [ + ("Custom", "Custom", "Custom"), + ("Default", "Default", "Default"), +] + + +class OOTSceneCommon: + ootEnumBootMode = [ + ("Play", "Play", "Play"), + ("Map Select", "Map Select", "Map Select"), + ("File Select", "File Select", "File Select"), + ] + + def isSceneObj(self, obj): + return obj.type == "EMPTY" and obj.ootEmptyType == "Scene" + + +class OOTSceneProperties(PropertyGroup): + write_dummy_room_list: BoolProperty( + name="Dummy Room List", + default=False, + description=( + "When exporting the scene to C, use NULL for the pointers to room " + "start/end offsets, instead of the appropriate symbols" + ), + ) + + +class MM_ExitProperty(PropertyGroup): + expandTab: BoolProperty(name="Expand Tab") + + exitIndex: EnumProperty(items=ootEnumExitIndex, default="Default") + exitIndexCustom: StringProperty(default="0x0000") + + # These are used when adding an entry to gEntranceTable + scene: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + sceneCustom: StringProperty(default="SCENE_DEKU_TREE") + + # These are used when adding an entry to gEntranceTable + continueBGM: BoolProperty(default=False) + displayTitleCard: BoolProperty(default=True) + fadeInAnim: EnumProperty(items=ootEnumTransitionAnims, default="0x02") + fadeInAnimCustom: StringProperty(default="0x02") + fadeOutAnim: EnumProperty(items=ootEnumTransitionAnims, default="0x02") + fadeOutAnimCustom: StringProperty(default="0x02") + + def draw_props(self, layout: UILayout, index: int, headerIndex: int, objName: str): + box = layout.box() + box.prop(self, "expandTab", text="Exit " + str(index + 1), icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") + if self.expandTab: + drawCollectionOps(box, index, "Exit", headerIndex, objName) + drawEnumWithCustom(box, self, "exitIndex", "Exit Index", "") + if self.exitIndex != "Custom": + box.label(text='This is unfinished, use "Custom".') + exitGroup = box.column() + exitGroup.enabled = False + drawEnumWithCustom(exitGroup, self, "scene", "Scene", "") + exitGroup.prop(self, "continueBGM", text="Continue BGM") + exitGroup.prop(self, "displayTitleCard", text="Display Title Card") + drawEnumWithCustom(exitGroup, self, "fadeInAnim", "Fade In Animation", "") + drawEnumWithCustom(exitGroup, self, "fadeOutAnim", "Fade Out Animation", "") + + +class OOTLightProperty(PropertyGroup): + ambient: FloatVectorProperty( + name="Ambient Color", + size=4, + min=0, + max=1, + default=(70 / 255, 40 / 255, 57 / 255, 1), + subtype="COLOR", + update=on_update_oot_render_settings, + ) + useCustomDiffuse0: BoolProperty(name="Use Custom Diffuse 0 Light Object", update=on_update_oot_render_settings) + useCustomDiffuse1: BoolProperty(name="Use Custom Diffuse 1 Light Object", update=on_update_oot_render_settings) + diffuse0: FloatVectorProperty( + name="", + size=4, + min=0, + max=1, + default=(180 / 255, 154 / 255, 138 / 255, 1), + subtype="COLOR", + update=on_update_oot_render_settings, + ) + diffuse1: FloatVectorProperty( + name="", + size=4, + min=0, + max=1, + default=(20 / 255, 20 / 255, 60 / 255, 1), + subtype="COLOR", + update=on_update_oot_render_settings, + ) + diffuse0Custom: PointerProperty(name="Diffuse 0", type=Light, update=on_update_oot_render_settings) + diffuse1Custom: PointerProperty(name="Diffuse 1", type=Light, update=on_update_oot_render_settings) + fogColor: FloatVectorProperty( + name="", + size=4, + min=0, + max=1, + default=(140 / 255, 120 / 255, 110 / 255, 1), + subtype="COLOR", + update=on_update_oot_render_settings, + ) + fogNear: IntProperty(name="", default=993, min=0, max=2**10 - 1, update=on_update_oot_render_settings) + transitionSpeed: IntProperty(name="", default=1, min=0, max=63, update=on_update_oot_render_settings) + z_far: IntProperty(name="", default=0x3200, min=0, max=2**15 - 1, update=on_update_oot_render_settings) + expandTab: BoolProperty(name="Expand Tab") + + def draw_props( + self, layout: UILayout, name: str, showExpandTab: bool, index: int, sceneHeaderIndex: int, objName: str + ): + if showExpandTab: + box = layout.box().column() + box.prop(self, "expandTab", text=name, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") + expandTab = self.expandTab + else: + box = layout + expandTab = True + + if expandTab: + if index is not None: + drawCollectionOps(box, index, "Light", sceneHeaderIndex, objName) + prop_split(box, self, "ambient", "Ambient Color") + + if self.useCustomDiffuse0: + prop_split(box, self, "diffuse0Custom", "Diffuse 0") + box.label(text="Make sure light is not part of scene hierarchy.", icon="FILE_PARENT") + else: + prop_split(box, self, "diffuse0", "Diffuse 0") + box.prop(self, "useCustomDiffuse0") + + if self.useCustomDiffuse1: + prop_split(box, self, "diffuse1Custom", "Diffuse 1") + box.label(text="Make sure light is not part of scene hierarchy.", icon="FILE_PARENT") + else: + prop_split(box, self, "diffuse1", "Diffuse 1") + box.prop(self, "useCustomDiffuse1") + + prop_split(box, self, "fogColor", "Fog Color") + prop_split(box, self, "fogNear", "Fog Near (Fog Far=1000)") + prop_split(box, self, "z_far", "Z Far (Draw Distance)") + prop_split(box, self, "transitionSpeed", "Transition Speed") + + +class OOTLightGroupProperty(PropertyGroup): + expandTab: BoolProperty() + menuTab: EnumProperty(items=ootEnumLightGroupMenu) + dawn: PointerProperty(type=OOTLightProperty) + day: PointerProperty(type=OOTLightProperty) + dusk: PointerProperty(type=OOTLightProperty) + night: PointerProperty(type=OOTLightProperty) + defaultsSet: BoolProperty() + + def draw_props(self, layout: UILayout): + box = layout.column() + box.row().prop(self, "menuTab", expand=True) + if self.menuTab == "Dawn": + self.dawn.draw_props(box, "Dawn", False, None, None, None) + if self.menuTab == "Day": + self.day.draw_props(box, "Day", False, None, None, None) + if self.menuTab == "Dusk": + self.dusk.draw_props(box, "Dusk", False, None, None, None) + if self.menuTab == "Night": + self.night.draw_props(box, "Night", False, None, None, None) + + +class OOTSceneTableEntryProperty(PropertyGroup): + drawConfig: EnumProperty(items=mm_enum_draw_config, name="Scene Draw Config", default="SCENE_DRAW_CFG_DEFAULT") + drawConfigCustom: StringProperty(name="Scene Draw Config Custom") + hasTitle: BoolProperty(default=True) + + def draw_props(self, layout: UILayout): + drawEnumWithCustom(layout, self, "drawConfig", "Draw Config", "") + + +class OOTExtraCutsceneProperty(PropertyGroup): + csObject: PointerProperty( + name="Cutscene Object", + type=Object, + poll=lambda self, object: object.type == "EMPTY" and object.ootEmptyType == "Cutscene", + ) + + +class OOTSceneHeaderProperty(PropertyGroup): + expandTab: BoolProperty(name="Expand Tab") + usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) + + globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) + globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") + naviCup: EnumProperty(name="Navi Hints", default="0x00", items=ootEnumNaviHints) + naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") + + skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") + skyboxIDCustom: StringProperty(name="Skybox ID", default="0") + skyboxCloudiness: EnumProperty(name="Cloudiness", items=ootEnumCloudiness, default="0x00") + skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") + skyboxLighting: EnumProperty( + name="Skybox Lighting", + items=ootEnumSkyboxLighting, + default="LIGHT_MODE_TIME", + update=on_update_oot_render_settings, + ) + skyboxLightingCustom: StringProperty( + name="Skybox Lighting Custom", default="0x00", update=on_update_oot_render_settings + ) + + mapLocation: EnumProperty(name="Map Location", items=ootEnumMapLocation, default="0x00") + mapLocationCustom: StringProperty(name="Skybox Lighting Custom", default="0x00") + cameraMode: EnumProperty(name="Camera Mode", items=ootEnumCameraMode, default="0x00") + cameraModeCustom: StringProperty(name="Camera Mode Custom", default="0x00") + + musicSeq: EnumProperty(name="Music Sequence", items=ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") + nightSeq: EnumProperty(name="Nighttime SFX", items=ootEnumNightSeq, default="0x00") + nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") + audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") + audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") + + timeOfDayLights: PointerProperty(type=OOTLightGroupProperty, name="Time Of Day Lighting") + lightList: CollectionProperty(type=OOTLightProperty, name="Lighting List") + exitList: CollectionProperty(type=MM_ExitProperty, name="Exit List") + + writeCutscene: BoolProperty(name="Write Cutscene") + csWriteType: EnumProperty(name="Cutscene Data Type", items=ootEnumCSWriteType, default="Object") + csWriteCustom: StringProperty(name="CS hdr var:", default="") + csWriteObject: PointerProperty( + name="Cutscene Object", + type=Object, + poll=lambda self, object: object.type == "EMPTY" and object.ootEmptyType == "Cutscene", + ) + + extraCutscenes: CollectionProperty(type=OOTExtraCutsceneProperty, name="Extra Cutscenes") + sceneTableEntry: PointerProperty(type=OOTSceneTableEntryProperty) + menuTab: EnumProperty(name="Menu", items=ootEnumSceneMenu, update=onMenuTabChange) + altMenuTab: EnumProperty(name="Menu", items=ootEnumSceneMenuAlternate) + + appendNullEntrance: BoolProperty( + name="Append Null Entrance", + description="Add an additional {0, 0} to the end of the EntranceEntry list.", + default=False, + ) + + def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): + from ..operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix + + if dropdownLabel is not None: + layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") + if not self.expandTab: + return + if headerIndex is not None and headerIndex > 3: + drawCollectionOps(layout, headerIndex - 4, "Scene", None, objName) + + if headerIndex is not None and headerIndex > 0 and headerIndex < 4: + layout.prop(self, "usePreviousHeader", text="Use Previous Header") + if self.usePreviousHeader: + return + + if headerIndex is None or headerIndex == 0: + layout.row().prop(self, "menuTab", expand=True) + menuTab = self.menuTab + else: + layout.row().prop(self, "altMenuTab", expand=True) + menuTab = self.altMenuTab + + if menuTab == "General": + general = layout.column() + general.box().label(text="General") + drawEnumWithCustom(general, self, "globalObject", "Global Object", "") + drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") + if headerIndex is None or headerIndex == 0: + self.sceneTableEntry.draw_props(general) + general.prop(self, "appendNullEntrance") + + skyboxAndSound = layout.column() + skyboxAndSound.box().label(text="Skybox And Sound") + drawEnumWithCustom(skyboxAndSound, self, "skyboxID", "Skybox", "") + drawEnumWithCustom(skyboxAndSound, self, "skyboxCloudiness", "Cloudiness", "") + drawEnumWithCustom(skyboxAndSound, self, "musicSeq", "Music Sequence", "") + musicSearch = skyboxAndSound.operator(OOT_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") + musicSearch.objName = objName + musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 + drawEnumWithCustom(skyboxAndSound, self, "nightSeq", "Nighttime SFX", "") + drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") + + cameraAndWorldMap = layout.column() + cameraAndWorldMap.box().label(text="Camera And World Map") + drawEnumWithCustom(cameraAndWorldMap, self, "mapLocation", "Map Location", "") + drawEnumWithCustom(cameraAndWorldMap, self, "cameraMode", "Camera Mode", "") + + elif menuTab == "Lighting": + lighting = layout.column() + lighting.box().label(text="Lighting List") + drawEnumWithCustom(lighting, self, "skyboxLighting", "Lighting Mode", "") + if self.skyboxLighting == "LIGHT_MODE_TIME": # Time of Day + self.timeOfDayLights.draw_props(lighting) + else: + for i in range(len(self.lightList)): + self.lightList[i].draw_props(lighting, "Lighting " + str(i), True, i, headerIndex, objName) + drawAddButton(lighting, len(self.lightList), "Light", headerIndex, objName) + + elif menuTab == "Cutscene": + cutscene = layout.column() + r = cutscene.row() + r.prop(self, "writeCutscene", text="Write Cutscene") + if self.writeCutscene: + r.prop(self, "csWriteType", text="Data") + if self.csWriteType == "Custom": + cutscene.prop(self, "csWriteCustom") + else: + cutscene.prop(self, "csWriteObject") + + if headerIndex is None or headerIndex == 0: + cutscene.label(text="Extra cutscenes (not in any header):") + for i in range(len(self.extraCutscenes)): + box = cutscene.box().column() + drawCollectionOps(box, i, "extraCutscenes", None, objName, True) + box.prop(self.extraCutscenes[i], "csObject", text="CS obj") + if len(self.extraCutscenes) == 0: + drawAddButton(cutscene, 0, "extraCutscenes", 0, objName) + + elif menuTab == "Exits": + exitBox = layout.column() + exitBox.box().label(text="Exit List") + for i in range(len(self.exitList)): + self.exitList[i].draw_props(exitBox, i, headerIndex, objName) + + drawAddButton(exitBox, len(self.exitList), "Exit", headerIndex, objName) + + +class OOTAlternateSceneHeaderProperty(PropertyGroup): + childNightHeader: PointerProperty(name="Child Night Header", type=OOTSceneHeaderProperty) + adultDayHeader: PointerProperty(name="Adult Day Header", type=OOTSceneHeaderProperty) + adultNightHeader: PointerProperty(name="Adult Night Header", type=OOTSceneHeaderProperty) + cutsceneHeaders: CollectionProperty(type=OOTSceneHeaderProperty) + + headerMenuTab: EnumProperty(name="Header Menu", items=ootEnumHeaderMenu, update=onHeaderMenuTabChange) + currentCutsceneIndex: IntProperty(min=4, default=4, update=onHeaderMenuTabChange) + + def draw_props(self, layout: UILayout, objName: str): + headerSetup = layout.column() + # headerSetup.box().label(text = "Alternate Headers") + headerSetupBox = headerSetup.column() + + headerSetupBox.row().prop(self, "headerMenuTab", expand=True) + if self.headerMenuTab == "Child Night": + self.childNightHeader.draw_props(headerSetupBox, None, 1, objName) + elif self.headerMenuTab == "Adult Day": + self.adultDayHeader.draw_props(headerSetupBox, None, 2, objName) + elif self.headerMenuTab == "Adult Night": + self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) + elif self.headerMenuTab == "Cutscene": + prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") + drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) + index = self.currentCutsceneIndex + if index - 4 < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - 4].draw_props(headerSetup, None, index, objName) + else: + headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") + + +class OOTBootupSceneOptions(PropertyGroup): + bootToScene: BoolProperty(default=False, name="Boot To Scene") + overrideHeader: BoolProperty(default=False, name="Override Header") + headerOption: EnumProperty(items=ootEnumHeaderMenuComplete, name="Header", default="Child Day") + spawnIndex: IntProperty(name="Spawn", min=0) + newGameOnly: BoolProperty( + default=False, + name="Override Scene On New Game Only", + description="Only use this starting scene after loading a new save file", + ) + newGameName: StringProperty(default="Link", name="New Game Name") + bootMode: EnumProperty(default="Play", name="Boot Mode", items=OOTSceneCommon.ootEnumBootMode) + + # see src/code/z_play.c:Play_Init() - can't access more than 16 cutscenes? + cutsceneIndex: IntProperty(min=4, max=19, default=4, name="Cutscene Index") + + def draw_props(self, layout: UILayout): + layout.prop(self, "bootToScene", text="Boot To Scene (HackerOOT)") + if self.bootToScene: + layout.prop(self, "newGameOnly") + prop_split(layout, self, "bootMode", "Boot Mode") + if self.bootMode == "Play": + prop_split(layout, self, "newGameName", "New Game Name") + if self.bootMode != "Map Select": + prop_split(layout, self, "spawnIndex", "Spawn") + layout.prop(self, "overrideHeader") + if self.overrideHeader: + prop_split(layout, self, "headerOption", "Header Option") + if self.headerOption == "Cutscene": + prop_split(layout, self, "cutsceneIndex", "Cutscene Index") + + +class MM_RemoveSceneSettingsProperty(PropertyGroup): + name: StringProperty(name="Name", default="spot03") + subFolder: StringProperty(name="Subfolder", default="overworld") + customExport: BoolProperty(name="Custom Export Path") + option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + + def draw_props(self, layout: UILayout): + if self.option == "Custom": + prop_split(layout, self, "subFolder", "Subfolder") + prop_split(layout, self, "name", "Name") + + +class MM_ExportSceneSettingsProperty(PropertyGroup): + name: StringProperty(name="Name", default="spot03") + subFolder: StringProperty(name="Subfolder", default="overworld") + exportPath: StringProperty(name="Directory", subtype="FILE_PATH") + customExport: BoolProperty(name="Custom Export Path") + singleFile: BoolProperty( + name="Export as Single File", + default=False, + description="Does not split the scene and rooms into multiple files.", + ) + option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + + def draw_props(self, layout: UILayout): + if self.customExport: + prop_split(layout, self, "exportPath", "Directory") + prop_split(layout, self, "name", "Name") + customExportWarning(layout) + else: + if self.option == "Custom": + prop_split(layout, self, "subFolder", "Subfolder") + prop_split(layout, self, "name", "Name") + + prop_split(layout, bpy.context.scene, "ootSceneExportObj", "Scene Object") + + layout.prop(self, "singleFile") + layout.prop(self, "customExport") + + +class MM_ImportSceneSettingsProperty(PropertyGroup): + name: StringProperty(name="Name", default="spot03") + subFolder: StringProperty(name="Subfolder", default="overworld") + destPath: StringProperty(name="Directory", subtype="FILE_PATH") + isCustomDest: BoolProperty(name="Custom Path") + includeMesh: BoolProperty(name="Mesh", default=True) + includeCollision: BoolProperty(name="Collision", default=True) + includeActors: BoolProperty(name="Actors", default=True) + includeCullGroups: BoolProperty(name="Cull Groups", default=True) + includeLights: BoolProperty(name="Lights", default=True) + includeCameras: BoolProperty(name="Cameras", default=True) + includePaths: BoolProperty(name="Paths", default=True) + includeWaterBoxes: BoolProperty(name="Water Boxes", default=True) + includeCutscenes: BoolProperty(name="Cutscenes", default=False) + option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + + def draw_props(self, layout: UILayout, sceneOption: str): + col = layout.column() + includeButtons1 = col.row(align=True) + includeButtons1.prop(self, "includeMesh", toggle=1) + includeButtons1.prop(self, "includeCollision", toggle=1) + includeButtons1.prop(self, "includeActors", toggle=1) + + includeButtons2 = col.row(align=True) + includeButtons2.prop(self, "includeCullGroups", toggle=1) + includeButtons2.prop(self, "includeLights", toggle=1) + includeButtons2.prop(self, "includeCameras", toggle=1) + + includeButtons3 = col.row(align=True) + includeButtons3.prop(self, "includePaths", toggle=1) + includeButtons3.prop(self, "includeWaterBoxes", toggle=1) + includeButtons3.prop(self, "includeCutscenes", toggle=1) + col.prop(self, "isCustomDest") + + if self.isCustomDest: + prop_split(col, self, "destPath", "Directory") + prop_split(col, self, "name", "Name") + else: + if self.option == "Custom": + prop_split(col, self, "subFolder", "Subfolder") + prop_split(col, self, "name", "Name") + + +classes = ( + MM_ExitProperty, + OOTLightProperty, + OOTLightGroupProperty, + OOTSceneTableEntryProperty, + OOTExtraCutsceneProperty, + OOTSceneHeaderProperty, + OOTAlternateSceneHeaderProperty, + OOTBootupSceneOptions, + MM_RemoveSceneSettingsProperty, + MM_ExportSceneSettingsProperty, + MM_ImportSceneSettingsProperty, +) + + +def mm_scene_props_register(): + for cls in classes: + register_class(cls) + + Object.mm_scene_header = PointerProperty(type=OOTSceneHeaderProperty) + Object.mm_alternate_scene_headers = PointerProperty(type=OOTAlternateSceneHeaderProperty) + Scene.mm_scene_export_obj = PointerProperty(type=Object, poll=OOTSceneCommon.isSceneObj) + Scene.mm_scene_export_settings = PointerProperty(type=MM_ExportSceneSettingsProperty) + Scene.mm_scene_import_settings = PointerProperty(type=MM_ImportSceneSettingsProperty) + Scene.mm_scene_remove_settings = PointerProperty(type=MM_RemoveSceneSettingsProperty) + + +def mm_scene_props_unregister(): + del Object.mm_scene_header + del Object.mm_alternate_scene_headers + del Scene.mm_scene_export_obj + del Scene.mm_scene_export_settings + del Scene.mm_scene_import_settings + del Scene.mm_scene_remove_settings + + for cls in reversed(classes): + unregister_class(cls) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties/oot_props.py similarity index 98% rename from fast64_internal/z64/scene/properties.py rename to fast64_internal/z64/scene/properties/oot_props.py index 26c7f29b5..6e26369bd 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties/oot_props.py @@ -10,11 +10,11 @@ FloatVectorProperty, ) from bpy.utils import register_class, unregister_class -from ...render_settings import on_update_oot_render_settings -from ...utility import prop_split, customExportWarning -from ..cutscene.constants import ootEnumCSWriteType +from ....render_settings import on_update_oot_render_settings +from ....utility import prop_split, customExportWarning +from ...cutscene.constants import ootEnumCSWriteType -from ..utility import ( +from ...utility import ( onMenuTabChange, onHeaderMenuTabChange, drawCollectionOps, @@ -22,9 +22,10 @@ drawAddButton, ) -from ..constants import ( +from ...constants import ( ootEnumMusicSeq, ootEnumSceneID, + mm_enum_scene_id, ootEnumGlobalObject, ootEnumNaviHints, ootEnumSkybox, @@ -316,7 +317,7 @@ class OOTSceneHeaderProperty(PropertyGroup): ) def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from .operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix + from ..operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 50821d43a..324eed643 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -9,7 +9,7 @@ from bpy.utils import register_class, unregister_class from bpy.types import Object from typing import Callable, Optional, TYPE_CHECKING, List -from .constants import ootSceneIDToName +from .constants import ootSceneIDToName, mm_scene_id_to_name from dataclasses import dataclass from ..utility import ( @@ -173,11 +173,16 @@ def isPathObject(obj: bpy.types.Object) -> bool: } -def sceneNameFromID(sceneID): - if sceneID in ootSceneIDToName: - return ootSceneIDToName[sceneID] +def sceneNameFromID(scene_id: str): + if bpy.context.scene.gameEditorMode == "OOT": + scene_id_to_name = ootSceneIDToName else: - raise PluginError("Cannot find scene ID " + str(sceneID)) + scene_id_to_name = mm_scene_id_to_name + + if scene_id in scene_id_to_name: + return scene_id_to_name[scene_id] + else: + raise PluginError("Cannot find scene ID " + str(scene_id)) def getOOTScale(actorScale: float) -> float: @@ -250,9 +255,14 @@ def addIncludeFilesExtension(objectName, objectPath, assetName, extension): def getSceneDirFromLevelName(name: str, include_extracted: bool = False): extracted = bpy.context.scene.fast64.oot.get_extracted_path() if include_extracted else "." - for sceneDir, dirLevels in ootSceneDirs.items(): - if name in dirLevels: - return f"{extracted}/" + sceneDir + name + + if bpy.context.scene.gameEditorMode == "OOT": + for sceneDir, dirLevels in ootSceneDirs.items(): + if name in dirLevels: + return f"{extracted}/" + sceneDir + name + else: + return f"{extracted}/assets/scenes/{name}" + return None From 8ae49823309a9dbd09f8109562e8a059f129a17a Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:21:02 +0100 Subject: [PATCH 007/126] format --- fast64_internal/z64/__init__.py | 8 ++++++- fast64_internal/z64/props_panel_main.py | 4 +++- .../z64/scene/properties/__init__.py | 21 +++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 815723c88..03ca3a8ed 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -2,7 +2,13 @@ from bpy.utils import register_class, unregister_class from .scene.operators import scene_ops_register, scene_ops_unregister -from .scene.properties import OOTBootupSceneOptions, scene_props_register, scene_props_unregister, mm_scene_props_register, mm_scene_props_unregister +from .scene.properties import ( + OOTBootupSceneOptions, + scene_props_register, + scene_props_unregister, + mm_scene_props_register, + mm_scene_props_unregister, +) from .scene.panels import scene_panels_register, scene_panels_unregister from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 9b6ba6583..77bf98352 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -117,7 +117,9 @@ class OOTObjectPanel(bpy.types.Panel): @classmethod def poll(cls, context): - return context.scene.gameEditorMode in {"OOT", "MM"} and (context.object is not None and context.object.type == "EMPTY") + return context.scene.gameEditorMode in {"OOT", "MM"} and ( + context.object is not None and context.object.type == "EMPTY" + ) def draw(self, context): prop_split(self.layout, context.scene, "gameEditorMode", "Game") diff --git a/fast64_internal/z64/scene/properties/__init__.py b/fast64_internal/z64/scene/properties/__init__.py index 748d8b959..7ffebffd9 100644 --- a/fast64_internal/z64/scene/properties/__init__.py +++ b/fast64_internal/z64/scene/properties/__init__.py @@ -1,2 +1,19 @@ -from .oot_props import OOTSceneHeaderProperty, OOTBootupSceneOptions, OOTSceneProperties, OOTAlternateSceneHeaderProperty, OOTLightProperty, OOTExportSceneSettingsProperty, OOTImportSceneSettingsProperty, OOTRemoveSceneSettingsProperty, scene_props_register, scene_props_unregister -from .mm_props import MM_ExportSceneSettingsProperty, MM_ImportSceneSettingsProperty, MM_RemoveSceneSettingsProperty, mm_scene_props_register, mm_scene_props_unregister +from .oot_props import ( + OOTSceneHeaderProperty, + OOTBootupSceneOptions, + OOTSceneProperties, + OOTAlternateSceneHeaderProperty, + OOTLightProperty, + OOTExportSceneSettingsProperty, + OOTImportSceneSettingsProperty, + OOTRemoveSceneSettingsProperty, + scene_props_register, + scene_props_unregister, +) +from .mm_props import ( + MM_ExportSceneSettingsProperty, + MM_ImportSceneSettingsProperty, + MM_RemoveSceneSettingsProperty, + mm_scene_props_register, + mm_scene_props_unregister, +) From 66b6c8704b6d624714da2b80a3c3c40c86741d31 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 01:26:25 +0100 Subject: [PATCH 008/126] implement scene's "general" tab ui --- fast64_internal/utility.py | 14 +- fast64_internal/z64/__init__.py | 5 +- fast64_internal/z64/constants.py | 210 +++++------------- fast64_internal/z64/data/mm/data.py | 156 +++++++++++++ fast64_internal/z64/data/oot/data.py | 147 ++++++++++++ .../z64/exporter/decomp_edit/scene_table.py | 35 ++- .../z64/exporter/scene/__init__.py | 3 +- fast64_internal/z64/importer/scene.py | 30 ++- fast64_internal/z64/importer/scene_header.py | 77 +++++-- fast64_internal/z64/props_panel_main.py | 19 +- fast64_internal/z64/room/properties.py | 4 +- fast64_internal/z64/scene/operators.py | 31 ++- fast64_internal/z64/scene/panels.py | 6 +- .../z64/scene/properties/__init__.py | 2 + .../z64/scene/properties/mm_props.py | 148 ++++++++---- .../z64/scene/properties/oot_props.py | 10 +- fast64_internal/z64/utility.py | 66 +++++- 17 files changed, 695 insertions(+), 268 deletions(-) diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index 702ddd697..4c48a41ec 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -1665,17 +1665,25 @@ def lightDataToObj(lightData): raise PluginError("A material is referencing a light that is no longer in the scene (i.e. has been deleted).") -def ootGetSceneOrRoomHeader(parent, idx, isRoom): +def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): # This should be in oot_utility.py, but it is needed in f3d_material.py # which creates a circular import. The real problem is that the F3D render # settings stuff should be in a place which can import both SM64 and OoT # code without circular dependencies. if idx < 0: raise PluginError("Alternate scene/room header index too low: " + str(idx)) + target = "Room" if isRoom else "Scene" - altHeaders = getattr(parent, "ootAlternate" + target + "Headers") + + if bpy.context.scene.gameEditorMode == "OOT": + header = getattr(parent, "oot" + target + "Header") + altHeaders = getattr(parent, "ootAlternate" + target + "Headers") + else: + header = getattr(parent, f"mm_{target.lower()}_header") + altHeaders = getattr(parent, f"mm_alternate_{target.lower()}_headers") + if idx == 0: - return getattr(parent, "oot" + target + "Header") + return header elif 1 <= idx <= 3: if idx == 1: ret = altHeaders.childNightHeader diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 03ca3a8ed..03a72eff6 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -64,6 +64,9 @@ oot_operator_unregister, ) +from .utility import is_game_oot + + oot_versions_items = [ ("Custom", "Custom", "Custom"), ("gc-jp", "gc-jp", "gc-jp"), @@ -106,7 +109,7 @@ class OOT_Properties(bpy.types.PropertyGroup): oot_version_custom: bpy.props.StringProperty(name="Custom Version") def get_extracted_path(self): - version = self.oot_version if bpy.context.scene.gameEditorMode == "OOT" else self.mm_version + version = self.oot_version if is_game_oot() else self.mm_version if version == "legacy": return "." diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index c16719387..1ceeec2a4 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -40,6 +40,38 @@ ("0x01", "Cloudy", "Cloudy"), ] +mm_enum_skybox_config = [ + ("Custom", "Custom", "Custom"), + ("0x00", "SKYBOX_CONFIG_0", "SKYBOX_CONFIG_0"), + ("0x01", "SKYBOX_CONFIG_1", "SKYBOX_CONFIG_1"), + ("0x02", "SKYBOX_CONFIG_2", "SKYBOX_CONFIG_2"), + ("0x03", "SKYBOX_CONFIG_3", "SKYBOX_CONFIG_3"), + ("0x04", "SKYBOX_CONFIG_4", "SKYBOX_CONFIG_4"), + ("0x05", "SKYBOX_CONFIG_5", "SKYBOX_CONFIG_5"), + ("0x06", "SKYBOX_CONFIG_6", "SKYBOX_CONFIG_6"), + ("0x07", "SKYBOX_CONFIG_7", "SKYBOX_CONFIG_7"), + ("0x08", "SKYBOX_CONFIG_8", "SKYBOX_CONFIG_8"), + ("0x09", "SKYBOX_CONFIG_9", "SKYBOX_CONFIG_9"), + ("0x0A", "SKYBOX_CONFIG_10", "SKYBOX_CONFIG_10"), + ("0x0B", "SKYBOX_CONFIG_11", "SKYBOX_CONFIG_11"), + ("0x0C", "SKYBOX_CONFIG_12", "SKYBOX_CONFIG_12"), + ("0x0D", "SKYBOX_CONFIG_13", "SKYBOX_CONFIG_13"), + ("0x0E", "SKYBOX_CONFIG_14", "SKYBOX_CONFIG_14"), + ("0x0F", "SKYBOX_CONFIG_15", "SKYBOX_CONFIG_15"), + ("0x10", "SKYBOX_CONFIG_16", "SKYBOX_CONFIG_16"), + ("0x11", "SKYBOX_CONFIG_17", "SKYBOX_CONFIG_17"), + ("0x12", "SKYBOX_CONFIG_18", "SKYBOX_CONFIG_18"), + ("0x13", "SKYBOX_CONFIG_19", "SKYBOX_CONFIG_19"), + ("0x14", "SKYBOX_CONFIG_20", "SKYBOX_CONFIG_20"), + ("0x15", "SKYBOX_CONFIG_21", "SKYBOX_CONFIG_21"), + ("0x16", "SKYBOX_CONFIG_22", "SKYBOX_CONFIG_22"), + ("0x17", "SKYBOX_CONFIG_23", "SKYBOX_CONFIG_23"), + ("0x18", "SKYBOX_CONFIG_24", "SKYBOX_CONFIG_24"), + ("0x19", "SKYBOX_CONFIG_25", "SKYBOX_CONFIG_25"), + ("0x1A", "SKYBOX_CONFIG_26", "SKYBOX_CONFIG_26"), + ("0x1B", "SKYBOX_CONFIG_27", "SKYBOX_CONFIG_27"), +] + ootEnumCameraMode = [ ("Custom", "Custom", "Custom"), ("0x00", "Default", "Default"), @@ -108,6 +140,15 @@ ("0x22", "Dog Guy's House", "Dog Guy's House"), ] +mm_enum_skybox = [ + ("Custom", "Custom", "Custom"), + ("0x00", "None", "SKYBOX_NONE"), + ("0x01", "Standard Sky", "SKYBOX_NORMAL_SKY"), + ("0x02", "SKYBOX_2", "SKYBOX_2"), + ("0x03", "SKYBOX_3", "SKYBOX_3"), + ("0x05", "Cutscene Map", "SKYBOX_CUTSCENE_MAP"), +] + ootEnumSkyboxLighting = [ # see ``LightMode`` enum in ``z64environment.h`` ("Custom", "Custom", "Custom"), @@ -120,162 +161,6 @@ ("0x00", "0x00", "0x00"), ] -ootEnumMusicSeq = [ - # see https://github.com/zeldaret/oot/blob/9f09505d34619883748a7dab05071883281c14fd/include/sequence.h#L4-L118 - ("Custom", "Custom", "Custom"), - ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), - ("NA_BGM_NATURE_AMBIENCE", "Nature Ambiance", "Nature Ambiance"), - ("NA_BGM_FIELD_LOGIC", "Hyrule Field", "Hyrule Field"), - ( - "NA_BGM_FIELD_INIT", - "Hyrule Field (Initial Segment From Loading Area)", - "Hyrule Field (Initial Segment From Loading Area)", - ), - ("NA_BGM_FIELD_DEFAULT_1", "Hyrule Field (Moving Segment 1)", "Hyrule Field (Moving Segment 1)"), - ("NA_BGM_FIELD_DEFAULT_2", "Hyrule Field (Moving Segment 2)", "Hyrule Field (Moving Segment 2)"), - ("NA_BGM_FIELD_DEFAULT_3", "Hyrule Field (Moving Segment 3)", "Hyrule Field (Moving Segment 3)"), - ("NA_BGM_FIELD_DEFAULT_4", "Hyrule Field (Moving Segment 4)", "Hyrule Field (Moving Segment 4)"), - ("NA_BGM_FIELD_DEFAULT_5", "Hyrule Field (Moving Segment 5)", "Hyrule Field (Moving Segment 5)"), - ("NA_BGM_FIELD_DEFAULT_6", "Hyrule Field (Moving Segment 6)", "Hyrule Field (Moving Segment 6)"), - ("NA_BGM_FIELD_DEFAULT_7", "Hyrule Field (Moving Segment 7)", "Hyrule Field (Moving Segment 7)"), - ("NA_BGM_FIELD_DEFAULT_8", "Hyrule Field (Moving Segment 8)", "Hyrule Field (Moving Segment 8)"), - ("NA_BGM_FIELD_DEFAULT_9", "Hyrule Field (Moving Segment 9)", "Hyrule Field (Moving Segment 9)"), - ("NA_BGM_FIELD_DEFAULT_A", "Hyrule Field (Moving Segment 10)", "Hyrule Field (Moving Segment 10)"), - ("NA_BGM_FIELD_DEFAULT_B", "Hyrule Field (Moving Segment 11)", "Hyrule Field (Moving Segment 11)"), - ("NA_BGM_FIELD_ENEMY_INIT", "Hyrule Field (Enemy Approaches)", "Hyrule Field (Enemy Approaches)"), - ("NA_BGM_FIELD_ENEMY_1", "Hyrule Field (Enemy Near Segment 1)", "Hyrule Field (Enemy Near Segment 1)"), - ("NA_BGM_FIELD_ENEMY_2", "Hyrule Field (Enemy Near Segment 2)", "Hyrule Field (Enemy Near Segment 2)"), - ("NA_BGM_FIELD_ENEMY_3", "Hyrule Field (Enemy Near Segment 3)", "Hyrule Field (Enemy Near Segment 3)"), - ("NA_BGM_FIELD_ENEMY_4", "Hyrule Field (Enemy Near Segment 4)", "Hyrule Field (Enemy Near Segment 4)"), - ("NA_BGM_FIELD_STILL_1", "Hyrule Field (Standing Still Segment 1)", "Hyrule Field (Standing Still Segment 1)"), - ("NA_BGM_FIELD_STILL_2", "Hyrule Field (Standing Still Segment 2)", "Hyrule Field (Standing Still Segment 2)"), - ("NA_BGM_FIELD_STILL_3", "Hyrule Field (Standing Still Segment 3)", "Hyrule Field (Standing Still Segment 3)"), - ("NA_BGM_FIELD_STILL_4", "Hyrule Field (Standing Still Segment 4)", "Hyrule Field (Standing Still Segment 4)"), - ("NA_BGM_DUNGEON", "Dodongo's Cavern", "Dodongo's Cavern"), - ("NA_BGM_KAKARIKO_ADULT", "Kakariko Village (Adult)", "Kakariko Village (Adult)"), - ("NA_BGM_ENEMY", "Enemy Battle", "Enemy Battle"), - ("NA_BGM_BOSS", "Boss Battle 00", "Boss Battle 00"), - ("NA_BGM_INSIDE_DEKU_TREE", "Inside the Deku Tree", "Inside the Deku Tree"), - ("NA_BGM_MARKET", "Market", "Market"), - ("NA_BGM_TITLE", "Title Theme", "Title Theme"), - ("NA_BGM_LINK_HOUSE", "Link's House", "Link's House"), - ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), - ("NA_BGM_BOSS_CLEAR", "Boss Clear", "Boss Clear"), - ("NA_BGM_ITEM_GET", "Item Get", "Item Get"), - ("NA_BGM_OPENING_GANON", "Opening Ganon", "Opening Ganon"), - ("NA_BGM_HEART_GET", "Heart Get", "Heart Get"), - ("NA_BGM_OCA_LIGHT", "Prelude Of Light", "Prelude Of Light"), - ("NA_BGM_JABU_JABU", "Inside Jabu-Jabu's Belly", "Inside Jabu-Jabu's Belly"), - ("NA_BGM_KAKARIKO_KID", "Kakariko Village (Child)", "Kakariko Village (Child)"), - ("NA_BGM_GREAT_FAIRY", "Great Fairy's Fountain", "Great Fairy's Fountain"), - ("NA_BGM_ZELDA_THEME", "Zelda's Theme", "Zelda's Theme"), - ("NA_BGM_FIRE_TEMPLE", "Fire Temple", "Fire Temple"), - ("NA_BGM_OPEN_TRE_BOX", "Open Treasure Chest", "Open Treasure Chest"), - ("NA_BGM_FOREST_TEMPLE", "Forest Temple", "Forest Temple"), - ("NA_BGM_COURTYARD", "Hyrule Castle Courtyard", "Hyrule Castle Courtyard"), - ("NA_BGM_GANON_TOWER", "Ganondorf's Theme", "Ganondorf's Theme"), - ("NA_BGM_LONLON", "Lon Lon Ranch", "Lon Lon Ranch"), - ("NA_BGM_GORON_CITY", "Goron City", "Goron City"), - ("NA_BGM_FIELD_MORNING", "Hyrule Field Morning Theme", "Hyrule Field Morning Theme"), - ("NA_BGM_SPIRITUAL_STONE", "Spiritual Stone Get", "Spiritual Stone Get"), - ("NA_BGM_OCA_BOLERO", "Bolero of Fire", "Bolero of Fire"), - ("NA_BGM_OCA_MINUET", "Minuet of Woods", "Minuet of Woods"), - ("NA_BGM_OCA_SERENADE", "Serenade of Water", "Serenade of Water"), - ("NA_BGM_OCA_REQUIEM", "Requiem of Spirit", "Requiem of Spirit"), - ("NA_BGM_OCA_NOCTURNE", "Nocturne of Shadow", "Nocturne of Shadow"), - ("NA_BGM_MINI_BOSS", "Mini-Boss Battle", "Mini-Boss Battle"), - ("NA_BGM_SMALL_ITEM_GET", "Obtain Small Item", "Obtain Small Item"), - ("NA_BGM_TEMPLE_OF_TIME", "Temple of Time", "Temple of Time"), - ("NA_BGM_EVENT_CLEAR", "Escape from Lon Lon Ranch", "Escape from Lon Lon Ranch"), - ("NA_BGM_KOKIRI", "Kokiri Forest", "Kokiri Forest"), - ("NA_BGM_OCA_FAIRY_GET", "Obtain Fairy Ocarina", "Obtain Fairy Ocarina"), - ("NA_BGM_SARIA_THEME", "Lost Woods", "Lost Woods"), - ("NA_BGM_SPIRIT_TEMPLE", "Spirit Temple", "Spirit Temple"), - ("NA_BGM_HORSE", "Horse Race", "Horse Race"), - ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), - ("NA_BGM_INGO", "Ingo's Theme", "Ingo's Theme"), - ("NA_BGM_MEDALLION_GET", "Obtain Medallion", "Obtain Medallion"), - ("NA_BGM_OCA_SARIA", "Ocarina Saria's Song", "Ocarina Saria's Song"), - ("NA_BGM_OCA_EPONA", "Ocarina Epona's Song", "Ocarina Epona's Song"), - ("NA_BGM_OCA_ZELDA", "Ocarina Zelda's Lullaby", "Ocarina Zelda's Lullaby"), - ("NA_BGM_OCA_SUNS", "Sun's Song", "Sun's Song"), - ("NA_BGM_OCA_TIME", "Song of Time", "Song of Time"), - ("NA_BGM_OCA_STORM", "Song of Storms", "Song of Storms"), - ("NA_BGM_NAVI_OPENING", "Fairy Flying", "Fairy Flying"), - ("NA_BGM_DEKU_TREE_CS", "Deku Tree", "Deku Tree"), - ("NA_BGM_WINDMILL", "Windmill Hut", "Windmill Hut"), - ("NA_BGM_HYRULE_CS", "Legend of Hyrule", "Legend of Hyrule"), - ("NA_BGM_MINI_GAME", "Shooting Gallery", "Shooting Gallery"), - ("NA_BGM_SHEIK", "Sheik's Theme", "Sheik's Theme"), - ("NA_BGM_ZORA_DOMAIN", "Zora's Domain", "Zora's Domain"), - ("NA_BGM_APPEAR", "Enter Zelda", "Enter Zelda"), - ("NA_BGM_ADULT_LINK", "Goodbye to Zelda", "Goodbye to Zelda"), - ("NA_BGM_MASTER_SWORD", "Master Sword", "Master Sword"), - ("NA_BGM_INTRO_GANON", "Ganon Intro", "Ganon Intro"), - ("NA_BGM_SHOP", "Shop", "Shop"), - ("NA_BGM_CHAMBER_OF_SAGES", "Chamber of the Sages", "Chamber of the Sages"), - ("NA_BGM_FILE_SELECT", "File Select", "File Select"), - ("NA_BGM_ICE_CAVERN", "Ice Cavern", "Ice Cavern"), - ("NA_BGM_DOOR_OF_TIME", "Open Door of Temple of Time", "Open Door of Temple of Time"), - ("NA_BGM_OWL", "Kaepora Gaebora's Theme", "Kaepora Gaebora's Theme"), - ("NA_BGM_SHADOW_TEMPLE", "Shadow Temple", "Shadow Temple"), - ("NA_BGM_WATER_TEMPLE", "Water Temple", "Water Temple"), - ("NA_BGM_BRIDGE_TO_GANONS", "Ganon's Castle Bridge", "Ganon's Castle Bridge"), - ("NA_BGM_OCARINA_OF_TIME", "Ocarina of Time", "Ocarina of Time"), - ("NA_BGM_GERUDO_VALLEY", "Gerudo Valley", "Gerudo Valley"), - ("NA_BGM_POTION_SHOP", "Potion Shop", "Potion Shop"), - ("NA_BGM_KOTAKE_KOUME", "Kotake & Koume's Theme", "Kotake & Koume's Theme"), - ("NA_BGM_ESCAPE", "Escape from Ganon's Castle", "Escape from Ganon's Castle"), - ("NA_BGM_UNDERGROUND", "Ganon's Castle Under Ground", "Ganon's Castle Under Ground"), - ("NA_BGM_GANONDORF_BOSS", "Ganondorf Battle", "Ganondorf Battle"), - ("NA_BGM_GANON_BOSS", "Ganon Battle", "Ganon Battle"), - ("NA_BGM_END_DEMO", "Seal of Six Sages", "Seal of Six Sages"), - ("NA_BGM_STAFF_1", "End Credits I", "End Credits I"), - ("NA_BGM_STAFF_2", "End Credits II", "End Credits II"), - ("NA_BGM_STAFF_3", "End Credits III", "End Credits III"), - ("NA_BGM_STAFF_4", "End Credits IV", "End Credits IV"), - ("NA_BGM_FIRE_BOSS", "King Dodongo & Volvagia Boss Battle", "King Dodongo & Volvagia Boss Battle"), - ("NA_BGM_TIMED_MINI_GAME", "Mini-Game", "Mini-Game"), - ("NA_BGM_CUTSCENE_EFFECTS", "Various Cutscene Sounds", "Various Cutscene Sounds"), - ("NA_BGM_NO_MUSIC", "No Music", "No Music"), - ("NA_BGM_NATURE_SFX_RAIN", "Nature Ambiance: Rain", "Nature Ambiance: Rain"), -] - -ootEnumNightSeq = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Standard night [day and night cycle]", "0x00"), - ("0x01", "Standard night [Kakariko]", "0x01"), - ("0x02", "Distant storm [Graveyard]", "0x02"), - ("0x03", "Howling wind and cawing [Ganon's Castle]", "0x03"), - ("0x04", "Wind + night birds [Kokiri]", "0x04"), - ("0x05", "Wind + crickets", "0x05"), - ("0x06", "Wind", "0x06"), - ("0x07", "Howling wind", "0x07"), - ("0x08", "Wind + crickets", "0x08"), - ("0x09", "Wind + crickets", "0x09"), - ("0x0A", "Tubed howling wind [Wasteland]", "0x0A"), - ("0x0B", "Tubed howling wind [Colossus]", "0x0B"), - ("0x0C", "Wind", "0x0C"), - ("0x0D", "Wind + crickets", "0x0D"), - ("0x0E", "Wind + crickets", "0x0E"), - ("0x0F", "Wind + birds", "0x0F"), - ("0x10", "Wind + crickets", "0x10"), - ("0x11", "?", "0x11"), - ("0x12", "Wind + crickets", "0x12"), - ("0x13", "Day music always playing", "0x13"), - ("0x14", "Silence", "0x14"), - ("0x16", "Silence", "0x16"), - ("0x17", "High tubed wind + rain", "0x17"), - ("0x18", "Silence", "0x18"), - ("0x19", "Silence", "0x19"), - ("0x1A", "High tubed wind + rain", "0x1A"), - ("0x1B", "Silence", "0x1B"), - ("0x1C", "Rain", "0x1C"), - ("0x1D", "High tubed wind + rain", "0x1D"), - ("0x1E", "Silence", "0x1E"), - ("0x1F", "High tubed wind + rain ", "0x1F"), -] - ootEnumGlobalObject = [ ("Custom", "Custom", "Custom"), ("OBJECT_INVALID", "None", "None"), @@ -283,11 +168,18 @@ ("OBJECT_GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), ] +mm_enum_global_object = [ + ("Custom", "Custom", "Custom"), + ("None", "None", "None"), + ("GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), + ("GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), +] + ootEnumNaviHints = [ ("Custom", "Custom", "Custom"), - ("0x00", "None", "None"), - ("0x01", "Overworld", "elf_message_field"), - ("0x02", "Dungeon", "elf_message_ydan"), + ("NAVI_QUEST_HINTS_NONE", "None", "None"), + ("NAVI_QUEST_HINTS_OVERWORLD", "Overworld", "elf_message_field"), + ("NAVI_QUEST_HINTS_DUNGEON", "Dungeon", "elf_message_ydan"), ] # The order of this list matters (normal OoT scene order as defined by ``scene_table.h``) diff --git a/fast64_internal/z64/data/mm/data.py b/fast64_internal/z64/data/mm/data.py index 0644725a4..4a3650ea0 100644 --- a/fast64_internal/z64/data/mm/data.py +++ b/fast64_internal/z64/data/mm/data.py @@ -19,3 +19,159 @@ def __init__(self): self.enum_data = MM_EnumData() self.actor_data = MM_ActorData() + + self.enum_seq_id = [ + ("Custom", "Custom", "Custom"), + ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), + ("NA_BGM_AMBIENCE", "Ambient background noises", "Ambient background noises"), + ("NA_BGM_TERMINA_FIELD", "Termina Field", "Termina Field"), + ("NA_BGM_CHASE", "Chase", "Chase"), + ("NA_BGM_MAJORAS_THEME", "Majora's Theme", "Majora's Theme"), + ("NA_BGM_CLOCK_TOWER", "Clock Tower", "Clock Tower"), + ("NA_BGM_STONE_TOWER_TEMPLE", "Stone Tower Temple", "Stone Tower Temple"), + ("NA_BGM_INV_STONE_TOWER_TEMPLE", "Stone Tower Temple Upside-down", "Stone Tower Temple Upside-down"), + ("NA_BGM_FAILURE_0", "Missed Event 1", "Missed Event 1"), + ("NA_BGM_FAILURE_1", "Missed Event 2", "Missed Event 2"), + ("NA_BGM_HAPPY_MASK_SALESMAN", "Happy Mask Saleman's Theme", "Happy Mask Saleman's Theme"), + ("NA_BGM_SONG_OF_HEALING", "Song Of Healing", "Song Of Healing"), + ("NA_BGM_SWAMP_REGION", "Southern Swamp", "Southern Swamp"), + ("NA_BGM_ALIEN_INVASION", "Ghost Attack", "Ghost Attack"), + ("NA_BGM_SWAMP_CRUISE", "Boat Cruise", "Boat Cruise"), + ("NA_BGM_SHARPS_CURSE", "Sharp's Curse", "Sharp's Curse"), + ("NA_BGM_GREAT_BAY_REGION", "Great Bay Coast", "Great Bay Coast"), + ("NA_BGM_IKANA_REGION", "Ikana Valley", "Ikana Valley"), + ("NA_BGM_DEKU_PALACE", "Deku Palace", "Deku Palace"), + ("NA_BGM_MOUNTAIN_REGION", "Mountain Village", "Mountain Village"), + ("NA_BGM_PIRATES_FORTRESS", "Pirates' Fortress", "Pirates' Fortress"), + ("NA_BGM_CLOCK_TOWN_DAY_1", "Clock Town, First Day", "Clock Town, First Day"), + ("NA_BGM_CLOCK_TOWN_DAY_2", "Clock Town, Second Day", "Clock Town, Second Day"), + ("NA_BGM_CLOCK_TOWN_DAY_3", "Clock Town, Third Day", "Clock Town, Third Day"), + ("NA_BGM_FILE_SELECT", "File Select", "File Select"), + ("NA_BGM_CLEAR_EVENT", "Event Clear", "Event Clear"), + ("NA_BGM_ENEMY", "Battle", "Battle"), + ("NA_BGM_BOSS", "Boss Battle", "Boss Battle"), + ("NA_BGM_WOODFALL_TEMPLE", "Woodfall Temple", "Woodfall Temple"), + ("NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE"), + ("NA_BGM_OPENING", "Opening", "Opening"), + ("NA_BGM_INSIDE_A_HOUSE", "House", "House"), + ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), + ("NA_BGM_CLEAR_BOSS", "Boss Clear", "Boss Clear"), + ("NA_BGM_GET_ITEM", "Item Catch", "Item Catch"), + ("NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR"), + ("NA_BGM_GET_HEART", "Get A Heart Container", "Get A Heart Container"), + ("NA_BGM_TIMED_MINI_GAME", "Mini Game", "Mini Game"), + ("NA_BGM_GORON_RACE", "Goron Race", "Goron Race"), + ("NA_BGM_MUSIC_BOX_HOUSE", "Music Box House", "Music Box House"), + ("NA_BGM_FAIRY_FOUNTAIN", "Fairy's Fountain", "Fairy's Fountain"), + ("NA_BGM_ZELDAS_LULLABY", "Zelda's Theme", "Zelda's Theme"), + ("NA_BGM_ROSA_SISTERS", "Rosa Sisters", "Rosa Sisters"), + ("NA_BGM_OPEN_CHEST", "Open Treasure Box", "Open Treasure Box"), + ("NA_BGM_MARINE_RESEARCH_LAB", "Marine Research Laboratory", "Marine Research Laboratory"), + ("NA_BGM_GIANTS_THEME", "Giants' Theme", "Giants' Theme"), + ("NA_BGM_SONG_OF_STORMS", "Guru-Guru's Song", "Guru-Guru's Song"), + ("NA_BGM_ROMANI_RANCH", "Romani Ranch", "Romani Ranch"), + ("NA_BGM_GORON_VILLAGE", "Goron Village", "Goron Village"), + ("NA_BGM_MAYORS_OFFICE", "Mayor's Meeting", "Mayor's Meeting"), + ("NA_BGM_OCARINA_EPONA", "Ocarina “Epona's Song”", "Ocarina “Epona's Song”"), + ("NA_BGM_OCARINA_SUNS", "Ocarina “Sun's Song”", "Ocarina “Sun's Song”"), + ("NA_BGM_OCARINA_TIME", "Ocarina “Song Of Time”", "Ocarina “Song Of Time”"), + ("NA_BGM_OCARINA_STORM", "Ocarina “Song Of Storms”", "Ocarina “Song Of Storms”"), + ("NA_BGM_ZORA_HALL", "Zora Hall", "Zora Hall"), + ("NA_BGM_GET_NEW_MASK", "Get A Mask", "Get A Mask"), + ("NA_BGM_MINI_BOSS", "Middle Boss Battle", "Middle Boss Battle"), + ("NA_BGM_GET_SMALL_ITEM", "Small Item Catch", "Small Item Catch"), + ("NA_BGM_ASTRAL_OBSERVATORY", "Astral Observatory", "Astral Observatory"), + ("NA_BGM_CAVERN", "Cavern", "Cavern"), + ("NA_BGM_MILK_BAR", "Milk Bar", "Milk Bar"), + ("NA_BGM_ZELDA_APPEAR", "Enter Zelda", "Enter Zelda"), + ("NA_BGM_SARIAS_SONG", "Woods Of Mystery", "Woods Of Mystery"), + ("NA_BGM_GORON_GOAL", "Goron Race Goal", "Goron Race Goal"), + ("NA_BGM_HORSE", "Horse Race", "Horse Race"), + ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), + ("NA_BGM_INGO", "Gorman Track", "Gorman Track"), + ("NA_BGM_KOTAKE_POTION_SHOP", "Magic Hags' Potion Shop", "Magic Hags' Potion Shop"), + ("NA_BGM_SHOP", "Shop", "Shop"), + ("NA_BGM_OWL", "Owl", "Owl"), + ("NA_BGM_SHOOTING_GALLERY", "Shooting Gallery", "Shooting Gallery"), + ("NA_BGM_OCARINA_SOARING", "Ocarina “Song Of Soaring”", "Ocarina “Song Of Soaring”"), + ("NA_BGM_OCARINA_HEALING", "Ocarina “Song Of Healing”", "Ocarina “Song Of Healing”"), + ("NA_BGM_INVERTED_SONG_OF_TIME", "Ocarina “Inverted Song Of Time”", "Ocarina “Inverted Song Of Time”"), + ("NA_BGM_SONG_OF_DOUBLE_TIME", "Ocarina “Song Of Double Time”", "Ocarina “Song Of Double Time”"), + ("NA_BGM_SONATA_OF_AWAKENING", "Sonata of Awakening", "Sonata of Awakening"), + ("NA_BGM_GORON_LULLABY", "Goron Lullaby", "Goron Lullaby"), + ("NA_BGM_NEW_WAVE_BOSSA_NOVA", "New Wave Bossa Nova", "New Wave Bossa Nova"), + ("NA_BGM_ELEGY_OF_EMPTINESS", "Elegy Of Emptiness", "Elegy Of Emptiness"), + ("NA_BGM_OATH_TO_ORDER", "Oath To Order", "Oath To Order"), + ("NA_BGM_SWORD_TRAINING_HALL", "Swordsman's School", "Swordsman's School"), + ("NA_BGM_OCARINA_LULLABY_INTRO", "Ocarina “Goron Lullaby Intro”", "Ocarina “Goron Lullaby Intro”"), + ("NA_BGM_LEARNED_NEW_SONG", "Get The Ocarina", "Get The Ocarina"), + ("NA_BGM_BREMEN_MARCH", "Bremen March", "Bremen March"), + ("NA_BGM_BALLAD_OF_THE_WIND_FISH", "Ballad Of The Wind Fish", "Ballad Of The Wind Fish"), + ("NA_BGM_SONG_OF_SOARING", "Song Of Soaring", "Song Of Soaring"), + ("NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE"), + ("NA_BGM_FINAL_HOURS", "Last Day", "Last Day"), + ("NA_BGM_MIKAU_RIFF", "Mikau", "Mikau"), + ("NA_BGM_MIKAU_FINALE", "Mikau", "Mikau"), + ("NA_BGM_FROG_SONG", "Frog Song", "Frog Song"), + ("NA_BGM_OCARINA_SONATA", "Ocarina “Sonata Of Awakening”", "Ocarina “Sonata Of Awakening”"), + ("NA_BGM_OCARINA_LULLABY", "Ocarina “Goron Lullaby”", "Ocarina “Goron Lullaby”"), + ("NA_BGM_OCARINA_NEW_WAVE", "Ocarina “New Wave Bossa Nova”", "Ocarina “New Wave Bossa Nova”"), + ("NA_BGM_OCARINA_ELEGY", "Ocarina “Elegy of Emptiness”", "Ocarina “Elegy of Emptiness”"), + ("NA_BGM_OCARINA_OATH", "Ocarina “Oath To Order”", "Ocarina “Oath To Order”"), + ("NA_BGM_MAJORAS_LAIR", "Majora Boss Room", "Majora Boss Room"), + ("NA_BGM_OCARINA_LULLABY_INTRO_PTR", "NA_BGM_OCARINA_LULLABY_INTRO", "NA_BGM_OCARINA_LULLABY_INTRO"), + ("NA_BGM_OCARINA_GUITAR_BASS_SESSION", "Bass and Guitar Session", "Bass and Guitar Session"), + ("NA_BGM_PIANO_SESSION", "Piano Solo", "Piano Solo"), + ("NA_BGM_INDIGO_GO_SESSION", "The Indigo-Go's", "The Indigo-Go's"), + ("NA_BGM_SNOWHEAD_TEMPLE", "Snowhead Temple", "Snowhead Temple"), + ("NA_BGM_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), + ("NA_BGM_NEW_WAVE_SAXOPHONE", "New Wave Bossa Nova", "New Wave Bossa Nova"), + ("NA_BGM_NEW_WAVE_VOCAL", "New Wave Bossa Nova", "New Wave Bossa Nova"), + ("NA_BGM_MAJORAS_WRATH", "Majora's Wrath Battle", "Majora's Wrath Battle"), + ("NA_BGM_MAJORAS_INCARNATION", "Majora's Incarnate Battle", "Majora's Incarnate Battle"), + ("NA_BGM_MAJORAS_MASK", "Majora's Mask Battle", "Majora's Mask Battle"), + ("NA_BGM_BASS_PLAY", "Bass Practice", "Bass Practice"), + ("NA_BGM_DRUMS_PLAY", "Drums Practice", "Drums Practice"), + ("NA_BGM_PIANO_PLAY", "Piano Practice", "Piano Practice"), + ("NA_BGM_IKANA_CASTLE", "Ikana Castle", "Ikana Castle"), + ("NA_BGM_GATHERING_GIANTS", "Calling The Four Giants", "Calling The Four Giants"), + ("NA_BGM_KAMARO_DANCE", "Kamaro's Dance", "Kamaro's Dance"), + ("NA_BGM_CREMIA_CARRIAGE", "Cremia's Carriage", "Cremia's Carriage"), + ("NA_BGM_KEATON_QUIZ", "Keaton's Quiz", "Keaton's Quiz"), + ("NA_BGM_END_CREDITS", "The End / Credits", "The End / Credits"), + ("NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP"), + ("NA_BGM_TITLE_THEME", "Title Theme", "Title Theme"), + ("NA_BGM_DUNGEON_APPEAR", "Woodfall Rises", "Woodfall Rises"), + ("NA_BGM_WOODFALL_CLEAR", "Southern Swamp Clears", "Southern Swamp Clears"), + ("NA_BGM_SNOWHEAD_CLEAR", "Snowhead Clear", "Snowhead Clear"), + ("NA_BGM_INTO_THE_MOON", "To The Moon", "To The Moon"), + ("NA_BGM_GOODBYE_GIANT", "The Giants' Exit", "The Giants' Exit"), + ("NA_BGM_TATL_AND_TAEL", "Tatl and Tael", "Tatl and Tael"), + ("NA_BGM_MOONS_DESTRUCTION", "Moon's Destruction", "Moon's Destruction"), + ("NA_BGM_END_CREDITS_SECOND_HALF", "The End / Credits (Half 2)", "The End / Credits (Half 2)"), + ] + + self.enum_ambiance_id = [ + ("Custom", "Custom", "Custom"), + ("0x00", "AMBIENCE_ID_00", "AMBIENCE_ID_00"), + ("0x01", "AMBIENCE_ID_01", "AMBIENCE_ID_01"), + ("0x02", "AMBIENCE_ID_02", "AMBIENCE_ID_02"), + ("0x03", "AMBIENCE_ID_03", "AMBIENCE_ID_03"), + ("0x04", "AMBIENCE_ID_04", "AMBIENCE_ID_04"), + ("0x05", "AMBIENCE_ID_05", "AMBIENCE_ID_05"), + ("0x06", "AMBIENCE_ID_06", "AMBIENCE_ID_06"), + ("0x07", "AMBIENCE_ID_07", "AMBIENCE_ID_07"), + ("0x08", "AMBIENCE_ID_08", "AMBIENCE_ID_08"), + ("0x09", "AMBIENCE_ID_09", "AMBIENCE_ID_09"), + ("0x0A", "AMBIENCE_ID_0A", "AMBIENCE_ID_0A"), + ("0x0B", "AMBIENCE_ID_0B", "AMBIENCE_ID_0B"), + ("0x0C", "AMBIENCE_ID_0C", "AMBIENCE_ID_0C"), + ("0x0D", "AMBIENCE_ID_0D", "AMBIENCE_ID_0D"), + ("0x0E", "AMBIENCE_ID_0E", "AMBIENCE_ID_0E"), + ("0x0F", "AMBIENCE_ID_0F", "AMBIENCE_ID_0F"), + ("0x10", "AMBIENCE_ID_10", "AMBIENCE_ID_10"), + ("0x11", "AMBIENCE_ID_11", "AMBIENCE_ID_11"), + ("0x12", "AMBIENCE_ID_12", "AMBIENCE_ID_12"), + ("0x13", "AMBIENCE_ID_13", "AMBIENCE_ID_13"), + ("0xFF", "AMBIENCE_ID_DISABLED", "AMBIENCE_ID_DISABLED"), + ] diff --git a/fast64_internal/z64/data/oot/data.py b/fast64_internal/z64/data/oot/data.py index cf75fd3d2..2cd903da8 100644 --- a/fast64_internal/z64/data/oot/data.py +++ b/fast64_internal/z64/data/oot/data.py @@ -21,3 +21,150 @@ def __init__(self): self.enumData = OoT_EnumData() self.objectData = OoT_ObjectData() self.actorData = OoT_ActorData() + + # `EnumProperty` requires fixed values + self.ootEnumMusicSeq = [ + # see https://github.com/zeldaret/oot/blob/9f09505d34619883748a7dab05071883281c14fd/include/sequence.h#L4-L118 + ("Custom", "Custom", "Custom"), + ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), + ("NA_BGM_NATURE_AMBIENCE", "Nature Ambiance", "Nature Ambiance"), + ("NA_BGM_FIELD_LOGIC", "Hyrule Field", "Hyrule Field"), + ( + "NA_BGM_FIELD_INIT", + "Hyrule Field (Initial Segment From Loading Area)", + "Hyrule Field (Initial Segment From Loading Area)", + ), + ("NA_BGM_FIELD_DEFAULT_1", "Hyrule Field (Moving Segment 1)", "Hyrule Field (Moving Segment 1)"), + ("NA_BGM_FIELD_DEFAULT_2", "Hyrule Field (Moving Segment 2)", "Hyrule Field (Moving Segment 2)"), + ("NA_BGM_FIELD_DEFAULT_3", "Hyrule Field (Moving Segment 3)", "Hyrule Field (Moving Segment 3)"), + ("NA_BGM_FIELD_DEFAULT_4", "Hyrule Field (Moving Segment 4)", "Hyrule Field (Moving Segment 4)"), + ("NA_BGM_FIELD_DEFAULT_5", "Hyrule Field (Moving Segment 5)", "Hyrule Field (Moving Segment 5)"), + ("NA_BGM_FIELD_DEFAULT_6", "Hyrule Field (Moving Segment 6)", "Hyrule Field (Moving Segment 6)"), + ("NA_BGM_FIELD_DEFAULT_7", "Hyrule Field (Moving Segment 7)", "Hyrule Field (Moving Segment 7)"), + ("NA_BGM_FIELD_DEFAULT_8", "Hyrule Field (Moving Segment 8)", "Hyrule Field (Moving Segment 8)"), + ("NA_BGM_FIELD_DEFAULT_9", "Hyrule Field (Moving Segment 9)", "Hyrule Field (Moving Segment 9)"), + ("NA_BGM_FIELD_DEFAULT_A", "Hyrule Field (Moving Segment 10)", "Hyrule Field (Moving Segment 10)"), + ("NA_BGM_FIELD_DEFAULT_B", "Hyrule Field (Moving Segment 11)", "Hyrule Field (Moving Segment 11)"), + ("NA_BGM_FIELD_ENEMY_INIT", "Hyrule Field (Enemy Approaches)", "Hyrule Field (Enemy Approaches)"), + ("NA_BGM_FIELD_ENEMY_1", "Hyrule Field (Enemy Near Segment 1)", "Hyrule Field (Enemy Near Segment 1)"), + ("NA_BGM_FIELD_ENEMY_2", "Hyrule Field (Enemy Near Segment 2)", "Hyrule Field (Enemy Near Segment 2)"), + ("NA_BGM_FIELD_ENEMY_3", "Hyrule Field (Enemy Near Segment 3)", "Hyrule Field (Enemy Near Segment 3)"), + ("NA_BGM_FIELD_ENEMY_4", "Hyrule Field (Enemy Near Segment 4)", "Hyrule Field (Enemy Near Segment 4)"), + ("NA_BGM_FIELD_STILL_1", "Hyrule Field (Standing Still Segment 1)", "Hyrule Field (Standing Still Segment 1)"), + ("NA_BGM_FIELD_STILL_2", "Hyrule Field (Standing Still Segment 2)", "Hyrule Field (Standing Still Segment 2)"), + ("NA_BGM_FIELD_STILL_3", "Hyrule Field (Standing Still Segment 3)", "Hyrule Field (Standing Still Segment 3)"), + ("NA_BGM_FIELD_STILL_4", "Hyrule Field (Standing Still Segment 4)", "Hyrule Field (Standing Still Segment 4)"), + ("NA_BGM_DUNGEON", "Dodongo's Cavern", "Dodongo's Cavern"), + ("NA_BGM_KAKARIKO_ADULT", "Kakariko Village (Adult)", "Kakariko Village (Adult)"), + ("NA_BGM_ENEMY", "Enemy Battle", "Enemy Battle"), + ("NA_BGM_BOSS", "Boss Battle 00", "Boss Battle 00"), + ("NA_BGM_INSIDE_DEKU_TREE", "Inside the Deku Tree", "Inside the Deku Tree"), + ("NA_BGM_MARKET", "Market", "Market"), + ("NA_BGM_TITLE", "Title Theme", "Title Theme"), + ("NA_BGM_LINK_HOUSE", "Link's House", "Link's House"), + ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), + ("NA_BGM_BOSS_CLEAR", "Boss Clear", "Boss Clear"), + ("NA_BGM_ITEM_GET", "Item Get", "Item Get"), + ("NA_BGM_OPENING_GANON", "Opening Ganon", "Opening Ganon"), + ("NA_BGM_HEART_GET", "Heart Get", "Heart Get"), + ("NA_BGM_OCA_LIGHT", "Prelude Of Light", "Prelude Of Light"), + ("NA_BGM_JABU_JABU", "Inside Jabu-Jabu's Belly", "Inside Jabu-Jabu's Belly"), + ("NA_BGM_KAKARIKO_KID", "Kakariko Village (Child)", "Kakariko Village (Child)"), + ("NA_BGM_GREAT_FAIRY", "Great Fairy's Fountain", "Great Fairy's Fountain"), + ("NA_BGM_ZELDA_THEME", "Zelda's Theme", "Zelda's Theme"), + ("NA_BGM_FIRE_TEMPLE", "Fire Temple", "Fire Temple"), + ("NA_BGM_OPEN_TRE_BOX", "Open Treasure Chest", "Open Treasure Chest"), + ("NA_BGM_FOREST_TEMPLE", "Forest Temple", "Forest Temple"), + ("NA_BGM_COURTYARD", "Hyrule Castle Courtyard", "Hyrule Castle Courtyard"), + ("NA_BGM_GANON_TOWER", "Ganondorf's Theme", "Ganondorf's Theme"), + ("NA_BGM_LONLON", "Lon Lon Ranch", "Lon Lon Ranch"), + ("NA_BGM_GORON_CITY", "Goron City", "Goron City"), + ("NA_BGM_FIELD_MORNING", "Hyrule Field Morning Theme", "Hyrule Field Morning Theme"), + ("NA_BGM_SPIRITUAL_STONE", "Spiritual Stone Get", "Spiritual Stone Get"), + ("NA_BGM_OCA_BOLERO", "Bolero of Fire", "Bolero of Fire"), + ("NA_BGM_OCA_MINUET", "Minuet of Woods", "Minuet of Woods"), + ("NA_BGM_OCA_SERENADE", "Serenade of Water", "Serenade of Water"), + ("NA_BGM_OCA_REQUIEM", "Requiem of Spirit", "Requiem of Spirit"), + ("NA_BGM_OCA_NOCTURNE", "Nocturne of Shadow", "Nocturne of Shadow"), + ("NA_BGM_MINI_BOSS", "Mini-Boss Battle", "Mini-Boss Battle"), + ("NA_BGM_SMALL_ITEM_GET", "Obtain Small Item", "Obtain Small Item"), + ("NA_BGM_TEMPLE_OF_TIME", "Temple of Time", "Temple of Time"), + ("NA_BGM_EVENT_CLEAR", "Escape from Lon Lon Ranch", "Escape from Lon Lon Ranch"), + ("NA_BGM_KOKIRI", "Kokiri Forest", "Kokiri Forest"), + ("NA_BGM_OCA_FAIRY_GET", "Obtain Fairy Ocarina", "Obtain Fairy Ocarina"), + ("NA_BGM_SARIA_THEME", "Lost Woods", "Lost Woods"), + ("NA_BGM_SPIRIT_TEMPLE", "Spirit Temple", "Spirit Temple"), + ("NA_BGM_HORSE", "Horse Race", "Horse Race"), + ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), + ("NA_BGM_INGO", "Ingo's Theme", "Ingo's Theme"), + ("NA_BGM_MEDALLION_GET", "Obtain Medallion", "Obtain Medallion"), + ("NA_BGM_OCA_SARIA", "Ocarina Saria's Song", "Ocarina Saria's Song"), + ("NA_BGM_OCA_EPONA", "Ocarina Epona's Song", "Ocarina Epona's Song"), + ("NA_BGM_OCA_ZELDA", "Ocarina Zelda's Lullaby", "Ocarina Zelda's Lullaby"), + ("NA_BGM_OCA_SUNS", "Sun's Song", "Sun's Song"), + ("NA_BGM_OCA_TIME", "Song of Time", "Song of Time"), + ("NA_BGM_OCA_STORM", "Song of Storms", "Song of Storms"), + ("NA_BGM_NAVI_OPENING", "Fairy Flying", "Fairy Flying"), + ("NA_BGM_DEKU_TREE_CS", "Deku Tree", "Deku Tree"), + ("NA_BGM_WINDMILL", "Windmill Hut", "Windmill Hut"), + ("NA_BGM_HYRULE_CS", "Legend of Hyrule", "Legend of Hyrule"), + ("NA_BGM_MINI_GAME", "Shooting Gallery", "Shooting Gallery"), + ("NA_BGM_SHEIK", "Sheik's Theme", "Sheik's Theme"), + ("NA_BGM_ZORA_DOMAIN", "Zora's Domain", "Zora's Domain"), + ("NA_BGM_APPEAR", "Enter Zelda", "Enter Zelda"), + ("NA_BGM_ADULT_LINK", "Goodbye to Zelda", "Goodbye to Zelda"), + ("NA_BGM_MASTER_SWORD", "Master Sword", "Master Sword"), + ("NA_BGM_INTRO_GANON", "Ganon Intro", "Ganon Intro"), + ("NA_BGM_SHOP", "Shop", "Shop"), + ("NA_BGM_CHAMBER_OF_SAGES", "Chamber of the Sages", "Chamber of the Sages"), + ("NA_BGM_FILE_SELECT", "File Select", "File Select"), + ("NA_BGM_ICE_CAVERN", "Ice Cavern", "Ice Cavern"), + ("NA_BGM_DOOR_OF_TIME", "Open Door of Temple of Time", "Open Door of Temple of Time"), + ("NA_BGM_OWL", "Kaepora Gaebora's Theme", "Kaepora Gaebora's Theme"), + ("NA_BGM_SHADOW_TEMPLE", "Shadow Temple", "Shadow Temple"), + ("NA_BGM_WATER_TEMPLE", "Water Temple", "Water Temple"), + ("NA_BGM_BRIDGE_TO_GANONS", "Ganon's Castle Bridge", "Ganon's Castle Bridge"), + ("NA_BGM_OCARINA_OF_TIME", "Ocarina of Time", "Ocarina of Time"), + ("NA_BGM_GERUDO_VALLEY", "Gerudo Valley", "Gerudo Valley"), + ("NA_BGM_POTION_SHOP", "Potion Shop", "Potion Shop"), + ("NA_BGM_KOTAKE_KOUME", "Kotake & Koume's Theme", "Kotake & Koume's Theme"), + ("NA_BGM_ESCAPE", "Escape from Ganon's Castle", "Escape from Ganon's Castle"), + ("NA_BGM_UNDERGROUND", "Ganon's Castle Under Ground", "Ganon's Castle Under Ground"), + ("NA_BGM_GANONDORF_BOSS", "Ganondorf Battle", "Ganondorf Battle"), + ("NA_BGM_GANON_BOSS", "Ganon Battle", "Ganon Battle"), + ("NA_BGM_END_DEMO", "Seal of Six Sages", "Seal of Six Sages"), + ("NA_BGM_STAFF_1", "End Credits I", "End Credits I"), + ("NA_BGM_STAFF_2", "End Credits II", "End Credits II"), + ("NA_BGM_STAFF_3", "End Credits III", "End Credits III"), + ("NA_BGM_STAFF_4", "End Credits IV", "End Credits IV"), + ("NA_BGM_FIRE_BOSS", "King Dodongo & Volvagia Boss Battle", "King Dodongo & Volvagia Boss Battle"), + ("NA_BGM_TIMED_MINI_GAME", "Mini-Game", "Mini-Game"), + ("NA_BGM_CUTSCENE_EFFECTS", "Various Cutscene Sounds", "Various Cutscene Sounds"), + ("NA_BGM_NO_MUSIC", "No Music", "No Music"), + ("NA_BGM_NATURE_SFX_RAIN", "Nature Ambiance: Rain", "Nature Ambiance: Rain"), + ] + + self.ootEnumNightSeq = [ + ("Custom", "Custom", "Custom"), + ("0x00", "General Night", "NATURE_ID_GENERAL_NIGHT"), + ("0x01", "Market Entrance", "NATURE_ID_MARKET_ENTRANCE"), + ("0x02", "Kakariko Region", "NATURE_ID_KAKARIKO_REGION"), + ("0x03", "Market Ruins", "NATURE_ID_MARKET_RUINS"), + ("0x04", "Kokiri Region", "NATURE_ID_KOKIRI_REGION"), + ("0x05", "Market Night", "NATURE_ID_MARKET_NIGHT"), + ("0x06", "NATURE_ID_06", "NATURE_ID_06"), + ("0x07", "Ganon's Lair", "NATURE_ID_GANONS_LAIR"), + ("0x08", "NATURE_ID_08", "NATURE_ID_08"), + ("0x09", "NATURE_ID_09", "NATURE_ID_09"), + ("0x0A", "Wasteland", "NATURE_ID_WASTELAND"), + ("0x0B", "Colossus", "NATURE_ID_COLOSSUS"), + ("0x0C", "Nature DMT", "NATURE_ID_DEATH_MOUNTAIN_TRAIL"), + ("0x0D", "NATURE_ID_0D", "NATURE_ID_0D"), + ("0x0E", "NATURE_ID_0E", "NATURE_ID_0E"), + ("0x0F", "NATURE_ID_0F", "NATURE_ID_0F"), + ("0x10", "NATURE_ID_10", "NATURE_ID_10"), + ("0x11", "NATURE_ID_11", "NATURE_ID_11"), + ("0x12", "NATURE_ID_12", "NATURE_ID_12"), + ("0x13", "None", "NATURE_ID_NONE"), + ("0xFF", "Disabled", "NATURE_ID_DISABLED"), + ] diff --git a/fast64_internal/z64/exporter/decomp_edit/scene_table.py b/fast64_internal/z64/exporter/decomp_edit/scene_table.py index 1e5d51b80..2aa6fd0d9 100644 --- a/fast64_internal/z64/exporter/decomp_edit/scene_table.py +++ b/fast64_internal/z64/exporter/decomp_edit/scene_table.py @@ -4,6 +4,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile +from ...utility import is_game_oot from ...constants import ootEnumSceneID, ootSceneNameToID, mm_enum_scene_id, mm_scene_name_to_id ADDED_SCENES_COMMENT = "// Added scenes" @@ -13,7 +14,7 @@ def get_original_index(enum_value: str) -> Optional[int]: """ Returns the original index of a specific scene """ - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): enum_scene_id = ootEnumSceneID else: enum_scene_id = mm_enum_scene_id @@ -27,7 +28,7 @@ def get_original_index(enum_value: str) -> Optional[int]: def get_scene_enum_from_name(scene_name: str): - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): return ootSceneNameToID.get(scene_name, f"SCENE_{scene_name.upper()}") else: return mm_scene_name_to_id.get(scene_name, f"SCENE_{scene_name.upper()}") @@ -54,7 +55,7 @@ def from_line(original_line: str): index = original_line.index(macro_start) + len(macro_start) parsed = original_line[index:].removesuffix(")") - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): params = parsed.split(", ") assert len(params) == 6 return SceneTableEntry(*params) @@ -87,11 +88,18 @@ def from_scene(scene_name: str, draw_config: str): def to_c(self, index: int): """Returns the entry as C code""" - return ( - f"/* 0x{index:02X} */ " - f"DEFINE_SCENE({self.spec_name}, {self.title_card_name}, {self.enum_value}, " - f"{self.draw_config}, {self.unk1}, {self.unk2})" - ) + if is_game_oot(): + return ( + f"/* 0x{index:02X} */ " + f"DEFINE_SCENE({self.spec_name}, {self.title_card_name}, {self.enum_value}, " + f"{self.draw_config}, {self.unk1}, {self.unk2})" + ) + else: + return ( + f"/* 0x{index:02X} */ " + f"DEFINE_SCENE({self.spec_name}, {self.enum_value}, {self.title_card_name}, " + f"{self.draw_config}, {self.unk1}, {self.unk2})" + ) @dataclass @@ -103,9 +111,14 @@ class SceneTableSection: def to_c(self, index: int): directive = f"{self.directive}\n" if self.directive else "" - terminator = "\n#endif" if self.directive and self.directive.startswith("#if") else "" + terminator = "\n#endif" if self.directive is not None and self.directive.startswith("#if") else "" entry_string = "\n".join(entry.to_c(index + i) for i, entry in enumerate(self.entries)) - return f"{directive}{entry_string}{terminator}\n\n" + section_c = f"{directive}{entry_string}{terminator}\n" + + if is_game_oot(): + section_c += "\n" + + return section_c @dataclass @@ -272,7 +285,7 @@ class SceneTableUtility: @staticmethod def get_draw_config(scene_name: str): """Read draw config from scene table""" - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): scene_name = f"{scene_name}_scene" scene_table = SceneTable.new( diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 3c6fceae2..5c68d6782 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -6,6 +6,7 @@ from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import OOTSceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter +from ...utility import get_scene_header_props from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -41,7 +42,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex True, ) - mainHeader = SceneHeader.new(f"{name}_header{i:02}", sceneObj.ootSceneHeader, sceneObj, transform, i, useMacros) + mainHeader = SceneHeader.new(f"{name}_header{i:02}", get_scene_header_props(sceneObj), sceneObj, transform, i, useMacros) hasAlternateHeaders = False altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") altProp = sceneObj.ootAlternateSceneHeaders diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index cc4c27f5b..d148bdbd7 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -21,13 +21,28 @@ sceneNameFromID, ootGetPath, setAllActorsVisibility, + is_game_oot, + get_scene_header_props, ) def parseDrawConfig(drawConfigName: str, sceneData: str, drawConfigData: str, f3dContext: OOTF3DContext): - drawFunctionName = "Scene_DrawConfig" + "".join( - [value.strip().lower().capitalize() for value in drawConfigName.replace("SDC_", "").split("_")] - ) + if is_game_oot(): + drawFunctionName = "Scene_DrawConfig" + "".join( + [value.strip().lower().capitalize() for value in drawConfigName.replace("SDC_", "").split("_")] + ) + else: + mm_draw_config_to_func_name = { + "SCENE_DRAW_CFG_DEFAULT": "Scene_DrawConfigDefault", + "SCENE_DRAW_CFG_MAT_ANIM": "Scene_DrawConfigMatAnim", + "SCENE_DRAW_CFG_NOTHING": "Scene_DrawConfigDoNothing", + "SCENE_DRAW_CFG_UNUSED_3": "Scene_DrawConfig3", + "SCENE_DRAW_CFG_UNUSED_4": "Scene_DrawConfig4", + "SCENE_DRAW_CFG_UNUSED_5": "Scene_DrawConfig5", + "SCENE_DRAW_CFG_GREAT_BAY_TEMPLE": "Scene_DrawConfigGreatBayTemple", + "SCENE_DRAW_CFG_MAT_ANIM_MANUAL_STEP": "Scene_DrawConfigMatAnimManualStep", + } + drawFunctionName = mm_draw_config_to_func_name[drawConfigName] # get draw function match = re.search(rf"void\s*{re.escape(drawFunctionName)}(.*?)CLOSE\_DISPS", drawConfigData, flags=re.DOTALL) @@ -91,7 +106,7 @@ def parseScene( subfolder = None importPath = bpy.path.abspath(bpy.context.scene.ootDecompPath) - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): sceneName = f"{sceneName}_scene" importSubdir = "" @@ -124,7 +139,8 @@ def parseScene( if not settings.isCustomDest: drawConfigName = SceneTableUtility.get_draw_config(sceneName) - drawConfigData = readFile(os.path.join(importPath, "src/code/z_scene_table.c")) + filename = "z_scene_table" if is_game_oot() else "z_scene_proc" + drawConfigData = readFile(os.path.join(importPath, f"src/code/{filename}.c")) parseDrawConfig(drawConfigName, sceneData, drawConfigData, f3dContext) bpy.context.space_data.overlay.show_relationship_lines = False @@ -155,10 +171,10 @@ def parseScene( if not settings.isCustomDest: setCustomProperty( - sceneObj.ootSceneHeader.sceneTableEntry, + get_scene_header_props(sceneObj).sceneTableEntry, "drawConfig", SceneTableUtility.get_draw_config(sceneName), - ootEnumDrawConfig if bpy.context.scene.gameEditorMode == "OOT" else mm_enum_draw_config, + ootEnumDrawConfig if is_game_oot() else mm_enum_draw_config, ) if bpy.context.scene.fast64.oot.headerTabAffectsVisibility: diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index b08950efe..abb205129 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -7,8 +7,8 @@ from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext -from ..scene.properties import OOTSceneHeaderProperty, OOTLightProperty -from ..utility import getEvalParams, setCustomProperty +from ..scene.properties import OOTSceneHeaderProperty, OOTLightProperty, MM_SceneHeaderProperty +from ..utility import getEvalParams, setCustomProperty, get_game_enum, get_scene_header_props, is_game_oot, convertIntTo2sComplement from .constants import headerNames from .utility import getDataMatch, stripName from .classes import SharedSceneData @@ -18,14 +18,16 @@ from .scene_pathways import parsePathList from ..constants import ( + oot_data, + mm_data, ootEnumAudioSessionPreset, - ootEnumNightSeq, - ootEnumMusicSeq, ootEnumCameraMode, ootEnumMapLocation, ootEnumNaviHints, ootEnumGlobalObject, + mm_enum_global_object, ootEnumSkybox, + mm_enum_skybox, ootEnumCloudiness, ootEnumSkyboxLighting, ) @@ -79,7 +81,7 @@ def parseLight( def parseLightList( sceneObj: bpy.types.Object, - sceneHeader: OOTSceneHeaderProperty, + sceneHeader: OOTSceneHeaderProperty | MM_SceneHeaderProperty, sceneData: str, lightListName: str, headerIndex: int, @@ -154,7 +156,7 @@ def parseLightList( index += 1 -def parseExitList(sceneHeader: OOTSceneHeaderProperty, sceneData: str, exitListName: str): +def parseExitList(sceneHeader: OOTSceneHeaderProperty | MM_SceneHeaderProperty, sceneData: str, exitListName: str): exitData = getDataMatch(sceneData, exitListName, "u16", "exit list") # see also start position list @@ -239,6 +241,44 @@ def parseAlternateSceneHeaders( ) +# from https://stackoverflow.com/a/6727975 +def twos_complement(hexstr: str, bits: int): + value = int(hexstr, 16) + if value & (1 << (bits - 1)): + value -= 1 << bits + return value + + +def parse_mm_minimap_info(scene_header: MM_SceneHeaderProperty, scene_data: str, list_name: str): + data_match = getDataMatch(scene_data, list_name, ["MapDataScene", "MinimapList"], "minimap scene", False) + scene_map_data = data_match.strip().split(", ") + scene_header.minimap_scale = int(scene_map_data[1], base=0) + + data_match = getDataMatch(scene_data, scene_map_data[0], ["MapDataRoom", "MinimapEntry"], "minimap room") + room_map_data = data_match.strip().split("\n") + for data in room_map_data: + map_data = data.strip().removeprefix("{ ").removesuffix(" },").split(", ") + new_prop = scene_header.minimap_room_list.add() + new_prop.map_id = map_data[0] + new_prop.center_x = twos_complement(map_data[1], 16) + new_prop.floor_y = twos_complement(map_data[2], 16) + new_prop.center_z = twos_complement(map_data[3], 16) + new_prop.flags = map_data[4] + + # TODO: complete chest map data import when actors are handled + # data_match = getDataMatch(scene_data, scene_map_data[0], ["MapDataChest", "MinimapChest"], "minimap chest") + # chest_map_data = data_match.strip().split("\n") + # for data in chest_map_data: + # map_data = data.strip().removeprefix("{ ").removesuffix(" },").split(", ") + + +def get_enum_id_from_index(enum_key: str, index: int): + if is_game_oot(): + return oot_data.enumData.enumByKey[enum_key].itemByIndex[index].id + else: + return mm_data.enum_data.enum_by_key[enum_key].item_by_index[index].id + + def parseSceneCommands( sceneName: str | None, sceneObj: bpy.types.Object | None, @@ -257,7 +297,7 @@ def parseSceneCommands( sceneObj.name = sceneName if headerIndex == 0: - sceneHeader = sceneObj.ootSceneHeader + sceneHeader = get_scene_header_props(sceneObj) elif headerIndex < 4: sceneHeader = getattr(sceneObj.ootAlternateSceneHeaders, headerNames[headerIndex]) sceneHeader.usePreviousHeader = False @@ -275,8 +315,8 @@ def parseSceneCommands( args = [arg.strip() for arg in commandMatch.group(2).split(",")] if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) - setCustomProperty(sceneHeader, "nightSeq", args[1], ootEnumNightSeq) - setCustomProperty(sceneHeader, "musicSeq", args[2], ootEnumMusicSeq) + setCustomProperty(sceneHeader, "nightSeq", args[1], get_game_enum("enum_ambiance_id")) + setCustomProperty(sceneHeader, "musicSeq", get_enum_id_from_index("seqId", int(args[2])), get_game_enum("enum_seq_id")) elif command == "SCENE_CMD_ROOM_LIST": # Assumption that all scenes use the same room list. if headerIndex == 0: @@ -290,7 +330,7 @@ def parseSceneCommands( transActorListName = stripName(args[1]) parseTransActorList(roomObjs, sceneData, transActorListName, sharedSceneData, headerIndex) - elif command == "SCENE_CMD_MISC_SETTINGS": + elif is_game_oot() and command == "SCENE_CMD_MISC_SETTINGS": setCustomProperty(sceneHeader, "cameraMode", args[0], ootEnumCameraMode) setCustomProperty(sceneHeader, "mapLocation", args[1], ootEnumMapLocation) elif command == "SCENE_CMD_COL_HEADER": @@ -304,7 +344,7 @@ def parseSceneCommands( entranceList = parseEntranceList(sceneHeader, roomObjs, sceneData, entranceListName) elif command == "SCENE_CMD_SPECIAL_FILES": setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) - setCustomProperty(sceneHeader, "globalObject", args[1], ootEnumGlobalObject) + setCustomProperty(sceneHeader, "globalObject", args[1], get_game_enum("enum_global_object")) elif command == "SCENE_CMD_PATH_LIST" and sharedSceneData.includePaths: pathListName = stripName(args[0]) parsePathList(sceneObj, sceneData, pathListName, headerIndex, sharedSceneData) @@ -319,7 +359,7 @@ def parseSceneCommands( entranceList = None elif command == "SCENE_CMD_SKYBOX_SETTINGS": - setCustomProperty(sceneHeader, "skyboxID", args[0], ootEnumSkybox) + setCustomProperty(sceneHeader, "skyboxID", args[0], get_game_enum("enum_skybox")) setCustomProperty(sceneHeader, "skyboxCloudiness", args[1], ootEnumCloudiness) setCustomProperty(sceneHeader, "skyboxLighting", args[2], ootEnumSkyboxLighting) elif command == "SCENE_CMD_EXIT_LIST": @@ -337,11 +377,18 @@ def parseSceneCommands( sceneHeader.csWriteObject = bpy.data.objects[csObjName] except: print(f"ERROR: Cutscene ``{csObjName}`` do not exist!") - elif command == "SCENE_CMD_ALTERNATE_HEADER_LIST": + elif is_game_oot() and command == "SCENE_CMD_ALTERNATE_HEADER_LIST": # Delay until after rooms are parsed altHeadersListName = stripName(args[0]) - - if altHeadersListName is not None: + + # handle Majora's Mask exclusive commands + elif not is_game_oot(): + if command == "SCENE_CMD_SET_REGION_VISITED": + sceneHeader.set_region_visited = True + elif command == "SCENE_CMD_MINIMAP_INFO": + parse_mm_minimap_info(sceneHeader, sceneData, stripName(args[0])) + + if is_game_oot() and altHeadersListName is not None: parseAlternateSceneHeaders(sceneObj, roomObjs, sceneData, altHeadersListName, f3dContext, sharedSceneData) return sceneObj diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 77bf98352..1a33d59f3 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj +from .utility import getSceneObj, getRoomObj, get_scene_header_props from .scene.properties import OOTSceneProperties from .room.properties import OOTObjectProperty, OOTRoomHeaderProperty, OOTAlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -43,8 +43,9 @@ def drawSceneHeader(box: bpy.types.UILayout, obj: bpy.types.Object): objName = obj.name - obj.ootSceneHeader.draw_props(box, None, None, objName) - if obj.ootSceneHeader.menuTab == "Alternate": + props = get_scene_header_props(obj) + props.draw_props(box, None, None, objName) + if props.menuTab == "Alternate": obj.ootAlternateSceneHeaders.draw_props(box, objName) box.prop(obj.fast64.oot.scene, "write_dummy_room_list") @@ -79,12 +80,14 @@ def onUpdateOOTEmptyType(self, context): if isSphereEmpty: self.empty_display_type = "SPHERE" + header_props = get_scene_header_props(self) + if self.ootEmptyType == "Scene": - if len(self.ootSceneHeader.lightList) == 0: - light = self.ootSceneHeader.lightList.add() - if not self.ootSceneHeader.timeOfDayLights.defaultsSet: - self.ootSceneHeader.timeOfDayLights.defaultsSet = True - timeOfDayLights = self.ootSceneHeader.timeOfDayLights + if len(header_props.lightList) == 0: + light = header_props.lightList.add() + if not header_props.timeOfDayLights.defaultsSet: + header_props.timeOfDayLights.defaultsSet = True + timeOfDayLights = header_props.timeOfDayLights setLightPropertyValues( timeOfDayLights.dawn, [70, 45, 57], [180, 154, 138], [20, 20, 60], [140, 120, 100], 0x3E1 ) diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 2ddae37e9..0755a843e 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -2,7 +2,7 @@ from bpy.types import PropertyGroup, UILayout, Image, Object from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton +from ..utility import drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton, is_game_oot from ..upgrade import upgradeRoomHeaders from .operators import OOT_SearchObjectEnumOperator @@ -176,7 +176,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general.label(text="and requires meshes to be parented to Custom Cull Group empties.") general.label(text="RSP culling is done automatically regardless of room shape.") prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") - if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and bpy.context.scene.gameEditorMode == "OOT": + if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_game_oot(): general.label(text="This shape type is only implemented on MM", icon="INFO") # Behaviour behaviourBox = layout.column() diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 137fa8d48..26213ee53 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -9,8 +9,8 @@ from mathutils import Matrix, Vector from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader -from ..utility import ExportInfo, RemoveInfo, sceneNameFromID -from ..constants import ootEnumMusicSeq, ootEnumSceneID, mm_enum_scene_id +from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot +from ..constants import oot_data, mm_data, ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config from ..exporter import SceneExport, Files @@ -33,7 +33,7 @@ def dummy_view_layer_update(context): def parseSceneFunc(): - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): settings = bpy.context.scene.ootSceneImportSettings else: settings = bpy.context.scene.mm_scene_import_settings @@ -102,7 +102,7 @@ class OOT_SearchMusicSeqEnumOperator(Operator): bl_property = "ootMusicSeq" bl_options = {"REGISTER", "UNDO"} - ootMusicSeq: EnumProperty(items=ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + ootMusicSeq: EnumProperty(items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") headerIndex: IntProperty(default=0, min=0) objName: StringProperty() @@ -118,6 +118,28 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} +class MM_SearchMusicSeqEnumOperator(Operator): + bl_idname = "object.mm_search_music_seq_enum_operator" + bl_label = "Search Music Sequence" + bl_property = "seq_id" + bl_options = {"REGISTER", "UNDO"} + + seq_id: EnumProperty(items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") + headerIndex: IntProperty(default=0, min=0) + objName: StringProperty() + + def execute(self, context): + sceneHeader = ootGetSceneOrRoomHeader(bpy.data.objects[self.objName], self.headerIndex, False) + sceneHeader.musicSeq = self.seq_id + context.region.tag_redraw() + self.report({"INFO"}, "Selected: " + self.seq_id) + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {"RUNNING_MODAL"} + + class OOT_ClearBootupScene(Operator): bl_idname = "object.oot_clear_bootup_scene" bl_label = "Undo Boot To Scene" @@ -291,6 +313,7 @@ def draw(self, context): OOT_ExportScene, OOT_RemoveScene, MM_SearchSceneEnumOperator, + MM_SearchMusicSeqEnumOperator, ) diff --git a/fast64_internal/z64/scene/panels.py b/fast64_internal/z64/scene/panels.py index ff58a656c..add87e0b6 100644 --- a/fast64_internal/z64/scene/panels.py +++ b/fast64_internal/z64/scene/panels.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...panels import Z64_Panel from ..constants import ootEnumSceneID, mm_enum_scene_id -from ..utility import getEnumName +from ..utility import getEnumName, is_game_oot from .properties import ( OOTExportSceneSettingsProperty, OOTImportSceneSettingsProperty, @@ -33,7 +33,7 @@ class OOT_ExportScenePanel(Z64_Panel): def drawSceneSearchOp(self, layout: UILayout, enumValue: str, opName: str): searchBox = layout.box().row() - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): searchBox.operator(OOT_SearchSceneEnumOperator.bl_idname, icon="VIEWZOOM", text="").opName = opName searchBox.label(text=getEnumName(ootEnumSceneID, enumValue)) else: @@ -47,7 +47,7 @@ def draw(self, context): exportBox = col.box().column() exportBox.label(text="Scene Exporter") - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): settings: OOTExportSceneSettingsProperty = context.scene.ootSceneExportSettings importSettings: OOTImportSceneSettingsProperty = context.scene.ootSceneImportSettings removeSettings: OOTRemoveSceneSettingsProperty = context.scene.ootSceneRemoveSettings diff --git a/fast64_internal/z64/scene/properties/__init__.py b/fast64_internal/z64/scene/properties/__init__.py index 7ffebffd9..a2f12f400 100644 --- a/fast64_internal/z64/scene/properties/__init__.py +++ b/fast64_internal/z64/scene/properties/__init__.py @@ -10,7 +10,9 @@ scene_props_register, scene_props_unregister, ) + from .mm_props import ( + MM_SceneHeaderProperty, MM_ExportSceneSettingsProperty, MM_ImportSceneSettingsProperty, MM_RemoveSceneSettingsProperty, diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py index 7120c794a..dde6d8233 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -26,16 +26,14 @@ ) from ...constants import ( - ootEnumMusicSeq, + mm_data, mm_enum_scene_id, - ootEnumGlobalObject, - ootEnumNaviHints, - ootEnumSkybox, - ootEnumCloudiness, + mm_enum_global_object, + mm_enum_skybox, + mm_enum_skybox_config, ootEnumSkyboxLighting, ootEnumMapLocation, ootEnumCameraMode, - ootEnumNightSeq, ootEnumAudioSessionPreset, ootEnumHeaderMenu, mm_enum_draw_config, @@ -242,10 +240,9 @@ def draw_props(self, layout: UILayout): self.night.draw_props(box, "Night", False, None, None, None) -class OOTSceneTableEntryProperty(PropertyGroup): +class MM_SceneTableEntryProperty(PropertyGroup): drawConfig: EnumProperty(items=mm_enum_draw_config, name="Scene Draw Config", default="SCENE_DRAW_CFG_DEFAULT") drawConfigCustom: StringProperty(name="Scene Draw Config Custom") - hasTitle: BoolProperty(default=True) def draw_props(self, layout: UILayout): drawEnumWithCustom(layout, self, "drawConfig", "Draw Config", "") @@ -259,19 +256,62 @@ class OOTExtraCutsceneProperty(PropertyGroup): ) -class OOTSceneHeaderProperty(PropertyGroup): +def minimap_chest_poll(self: "MM_MinimapChestProperty", object: Object): + return object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" + + +class MM_MinimapChestProperty(PropertyGroup): + expand_tab: BoolProperty(name="Expand Tab") + + # used to get the room index, the coordinates and the chest flag + chest_obj: PointerProperty(type=Object, poll=minimap_chest_poll, name="Chest Empty Object") + + def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: str): + box = layout.box() + box.prop(self, "expand_tab", text=f"Chest Actor No.{index + 1}", icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT") + + if self.expand_tab: + drawCollectionOps(box, index, "Minimap Chest", header_index, obj_name) + box.prop(self, "chest_obj") + + +class MM_MinimapRoomProperty(PropertyGroup): + expand_tab: BoolProperty(name="Expand Tab") + + map_id: StringProperty(name="Minimap ID", default="MAP_DATA_NO_MAP") + center_x: IntProperty(name="Center X", default=0) + floor_y: IntProperty(name="Floor Y", default=0) + center_z: IntProperty(name="Center Z", default=0) + flags: StringProperty(name="Flags", default="0x0000") + + def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: str): + box = layout.box() + box.prop(self, "expand_tab", text=f"Minimap Room Index {index}", icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT") + + if self.expand_tab: + drawCollectionOps(box, index, "Minimap Room", header_index, obj_name) + prop_split(box, self, "map_id", "Minimap ID") + prop_split(box, self, "center_x", "Center X") + prop_split(box, self, "floor_y", "Floor Y") + prop_split(box, self, "center_z", "Center Z") + prop_split(box, self, "flags", "Flags") + + +class MM_SceneHeaderProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) - globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) + # SCENE_CMD_SPECIAL_FILES + globalObject: EnumProperty(name="Global Object", default="None", items=mm_enum_global_object) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") - naviCup: EnumProperty(name="Navi Hints", default="0x00", items=ootEnumNaviHints) - naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") - skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") + # SCENE_CMD_SKYBOX_SETTINGS + skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") + skybox_texture_id_custom: StringProperty(name="Skybox Texture ID Custom", default="0x00") + skyboxID: EnumProperty(name="Skybox", items=mm_enum_skybox, default="0x01") skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=ootEnumCloudiness, default="0x00") - skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") + skyboxCloudiness: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="0x00") + skyboxCloudinessCustom: StringProperty(name="Skybox Config Custom", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", items=ootEnumSkyboxLighting, @@ -282,20 +322,30 @@ class OOTSceneHeaderProperty(PropertyGroup): name="Skybox Lighting Custom", default="0x00", update=on_update_oot_render_settings ) - mapLocation: EnumProperty(name="Map Location", items=ootEnumMapLocation, default="0x00") - mapLocationCustom: StringProperty(name="Skybox Lighting Custom", default="0x00") - cameraMode: EnumProperty(name="Camera Mode", items=ootEnumCameraMode, default="0x00") - cameraModeCustom: StringProperty(name="Camera Mode Custom", default="0x00") + # SCENE_CMD_SET_REGION_VISITED + set_region_visited: BoolProperty(name="Set Region Visited Flag", default=False, description="Sets a flag that indicates the region has been visited. Scene indices are mapped to their region in `gSceneIdsPerRegion` from `z_inventory.c`") + + # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `MM_RoomHeaderProperty`) + minimap_room_expand: BoolProperty(name="Expand Tab") + minimap_room_list: CollectionProperty(type=MM_MinimapRoomProperty, name="Minimap Room List") + minimap_scale: IntProperty(name="Minimap Scale", default=0) - musicSeq: EnumProperty(name="Music Sequence", items=ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + # SCENE_CMD_MINIMAP_COMPASS_ICON_INFO + minimap_chest_expand: BoolProperty(name="Expand Tab") + minimap_chest_list: CollectionProperty(type=MM_MinimapChestProperty, name="Minimap Chest List") + + # SCENE_CMD_SOUND_SETTINGS + musicSeq: EnumProperty(name="Music Sequence", items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=ootEnumNightSeq, default="0x00") + nightSeq: EnumProperty(name="Nighttime SFX", items=mm_data.enum_ambiance_id, default="0x00") nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") + # SCENE_CMD_ENV_LIGHT_SETTINGS timeOfDayLights: PointerProperty(type=OOTLightGroupProperty, name="Time Of Day Lighting") lightList: CollectionProperty(type=OOTLightProperty, name="Lighting List") + exitList: CollectionProperty(type=MM_ExitProperty, name="Exit List") writeCutscene: BoolProperty(name="Write Cutscene") @@ -308,7 +358,7 @@ class OOTSceneHeaderProperty(PropertyGroup): ) extraCutscenes: CollectionProperty(type=OOTExtraCutsceneProperty, name="Extra Cutscenes") - sceneTableEntry: PointerProperty(type=OOTSceneTableEntryProperty) + sceneTableEntry: PointerProperty(type=MM_SceneTableEntryProperty) menuTab: EnumProperty(name="Menu", items=ootEnumSceneMenu, update=onMenuTabChange) altMenuTab: EnumProperty(name="Menu", items=ootEnumSceneMenuAlternate) @@ -319,7 +369,7 @@ class OOTSceneHeaderProperty(PropertyGroup): ) def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from ..operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix + from ..operators import MM_SearchMusicSeqEnumOperator # temp circular import fix if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") @@ -344,26 +394,44 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general = layout.column() general.box().label(text="General") drawEnumWithCustom(general, self, "globalObject", "Global Object", "") - drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: self.sceneTableEntry.draw_props(general) + general.prop(self, "set_region_visited") general.prop(self, "appendNullEntrance") skyboxAndSound = layout.column() skyboxAndSound.box().label(text="Skybox And Sound") + drawEnumWithCustom(skyboxAndSound, self, "skybox_texture_id", "Skybox Texture ID", "") drawEnumWithCustom(skyboxAndSound, self, "skyboxID", "Skybox", "") drawEnumWithCustom(skyboxAndSound, self, "skyboxCloudiness", "Cloudiness", "") drawEnumWithCustom(skyboxAndSound, self, "musicSeq", "Music Sequence", "") - musicSearch = skyboxAndSound.operator(OOT_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") + musicSearch = skyboxAndSound.operator(MM_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") musicSearch.objName = objName musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 drawEnumWithCustom(skyboxAndSound, self, "nightSeq", "Nighttime SFX", "") drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") - cameraAndWorldMap = layout.column() - cameraAndWorldMap.box().label(text="Camera And World Map") - drawEnumWithCustom(cameraAndWorldMap, self, "mapLocation", "Map Location", "") - drawEnumWithCustom(cameraAndWorldMap, self, "cameraMode", "Camera Mode", "") + minimap = layout.column() + minimap.box().label(text="Minimap Settings") + prop_split(minimap, self, "minimap_scale", "Minimap Scale") + + map_room_box = minimap.column().box() + list_length = len(self.minimap_room_list) + item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" + map_room_box.prop(self, "minimap_room_expand", text=f"Minimap Room List ({item_count})", icon="TRIA_DOWN" if self.minimap_room_expand else "TRIA_RIGHT") + if self.minimap_room_expand: + for i in range(list_length): + self.minimap_room_list[i].draw_props(map_room_box, i, headerIndex, objName) + drawAddButton(map_room_box, list_length, "Minimap Room", headerIndex, objName) + + chest_box = minimap.column().box() + list_length = len(self.minimap_chest_list) + item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" + chest_box.prop(self, "minimap_chest_expand", text=f"Minimap Chest List ({item_count})", icon="TRIA_DOWN" if self.minimap_chest_expand else "TRIA_RIGHT") + if self.minimap_chest_expand: + for i in range(list_length): + self.minimap_chest_list[i].draw_props(chest_box, i, headerIndex, objName) + drawAddButton(chest_box, list_length, "Minimap Chest", headerIndex, objName) elif menuTab == "Lighting": lighting = layout.column() @@ -405,11 +473,11 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawAddButton(exitBox, len(self.exitList), "Exit", headerIndex, objName) -class OOTAlternateSceneHeaderProperty(PropertyGroup): - childNightHeader: PointerProperty(name="Child Night Header", type=OOTSceneHeaderProperty) - adultDayHeader: PointerProperty(name="Adult Day Header", type=OOTSceneHeaderProperty) - adultNightHeader: PointerProperty(name="Adult Night Header", type=OOTSceneHeaderProperty) - cutsceneHeaders: CollectionProperty(type=OOTSceneHeaderProperty) +class MM_AlternateSceneHeaderProperty(PropertyGroup): + childNightHeader: PointerProperty(name="Child Night Header", type=MM_SceneHeaderProperty) + adultDayHeader: PointerProperty(name="Adult Day Header", type=MM_SceneHeaderProperty) + adultNightHeader: PointerProperty(name="Adult Night Header", type=MM_SceneHeaderProperty) + cutsceneHeaders: CollectionProperty(type=MM_SceneHeaderProperty) headerMenuTab: EnumProperty(name="Header Menu", items=ootEnumHeaderMenu, update=onHeaderMenuTabChange) currentCutsceneIndex: IntProperty(min=4, default=4, update=onHeaderMenuTabChange) @@ -555,10 +623,12 @@ def draw_props(self, layout: UILayout, sceneOption: str): MM_ExitProperty, OOTLightProperty, OOTLightGroupProperty, - OOTSceneTableEntryProperty, + MM_SceneTableEntryProperty, OOTExtraCutsceneProperty, - OOTSceneHeaderProperty, - OOTAlternateSceneHeaderProperty, + MM_MinimapChestProperty, + MM_MinimapRoomProperty, + MM_SceneHeaderProperty, + MM_AlternateSceneHeaderProperty, OOTBootupSceneOptions, MM_RemoveSceneSettingsProperty, MM_ExportSceneSettingsProperty, @@ -570,8 +640,8 @@ def mm_scene_props_register(): for cls in classes: register_class(cls) - Object.mm_scene_header = PointerProperty(type=OOTSceneHeaderProperty) - Object.mm_alternate_scene_headers = PointerProperty(type=OOTAlternateSceneHeaderProperty) + Object.mm_scene_header = PointerProperty(type=MM_SceneHeaderProperty) + Object.mm_alternate_scene_headers = PointerProperty(type=MM_AlternateSceneHeaderProperty) Scene.mm_scene_export_obj = PointerProperty(type=Object, poll=OOTSceneCommon.isSceneObj) Scene.mm_scene_export_settings = PointerProperty(type=MM_ExportSceneSettingsProperty) Scene.mm_scene_import_settings = PointerProperty(type=MM_ImportSceneSettingsProperty) diff --git a/fast64_internal/z64/scene/properties/oot_props.py b/fast64_internal/z64/scene/properties/oot_props.py index 6e26369bd..dde74b1f3 100644 --- a/fast64_internal/z64/scene/properties/oot_props.py +++ b/fast64_internal/z64/scene/properties/oot_props.py @@ -23,9 +23,8 @@ ) from ...constants import ( - ootEnumMusicSeq, + oot_data, ootEnumSceneID, - mm_enum_scene_id, ootEnumGlobalObject, ootEnumNaviHints, ootEnumSkybox, @@ -33,7 +32,6 @@ ootEnumSkyboxLighting, ootEnumMapLocation, ootEnumCameraMode, - ootEnumNightSeq, ootEnumAudioSessionPreset, ootEnumHeaderMenu, ootEnumDrawConfig, @@ -263,7 +261,7 @@ class OOTSceneHeaderProperty(PropertyGroup): globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") - naviCup: EnumProperty(name="Navi Hints", default="0x00", items=ootEnumNaviHints) + naviCup: EnumProperty(name="Navi Hints", default="NAVI_QUEST_HINTS_NONE", items=ootEnumNaviHints) naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") @@ -285,9 +283,9 @@ class OOTSceneHeaderProperty(PropertyGroup): cameraMode: EnumProperty(name="Camera Mode", items=ootEnumCameraMode, default="0x00") cameraModeCustom: StringProperty(name="Camera Mode Custom", default="0x00") - musicSeq: EnumProperty(name="Music Sequence", items=ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + musicSeq: EnumProperty(name="Music Sequence", items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=ootEnumNightSeq, default="0x00") + nightSeq: EnumProperty(name="Nighttime SFX", items=oot_data.ootEnumNightSeq, default="0x00") nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 324eed643..02cc429c4 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -9,7 +9,22 @@ from bpy.utils import register_class, unregister_class from bpy.types import Object from typing import Callable, Optional, TYPE_CHECKING, List -from .constants import ootSceneIDToName, mm_scene_id_to_name +from .constants import ( + ootSceneIDToName, + mm_scene_id_to_name, + oot_data, + mm_data, + ootEnumAudioSessionPreset, + ootEnumCameraMode, + ootEnumMapLocation, + ootEnumNaviHints, + ootEnumGlobalObject, + mm_enum_global_object, + ootEnumSkybox, + mm_enum_skybox, + ootEnumCloudiness, + ootEnumSkyboxLighting, +) from dataclasses import dataclass from ..utility import ( @@ -27,13 +42,42 @@ ) if TYPE_CHECKING: - from .scene.properties import OOTBootupSceneOptions + from .scene.properties import OOTBootupSceneOptions, OOTSceneHeaderProperty, MM_SceneHeaderProperty + + +game_enum_map = { + "OOT": { + "enum_global_object": ootEnumGlobalObject, + "enum_skybox": ootEnumSkybox, + "enum_seq_id": oot_data.ootEnumMusicSeq, + "enum_ambiance_id": oot_data.ootEnumNightSeq # TODO: generate this from xml (not for enumproperties) + }, + "MM": { + "enum_global_object": mm_enum_global_object, + "enum_skybox": mm_enum_skybox, + "enum_seq_id": mm_data.enum_seq_id, + "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above + } +} + +def get_game_enum(enum_type: str): + return game_enum_map[bpy.context.scene.gameEditorMode][enum_type] + + +def is_game_oot(): + return bpy.context.scene.gameEditorMode == "OOT" + + +def get_scene_header_props(obj: Object): + if is_game_oot(): + return obj.ootSceneHeader + else: + return obj.mm_scene_header def isPathObject(obj: bpy.types.Object) -> bool: return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" - ootSceneDungeons = [ "bdan", "bdan_boss", @@ -174,7 +218,7 @@ def isPathObject(obj: bpy.types.Object) -> bool: def sceneNameFromID(scene_id: str): - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): scene_id_to_name = ootSceneIDToName else: scene_id_to_name = mm_scene_id_to_name @@ -256,7 +300,7 @@ def addIncludeFilesExtension(objectName, objectPath, assetName, extension): def getSceneDirFromLevelName(name: str, include_extracted: bool = False): extracted = bpy.context.scene.fast64.oot.get_extracted_path() if include_extracted else "." - if bpy.context.scene.gameEditorMode == "OOT": + if is_game_oot(): for sceneDir, dirLevels in ootSceneDirs.items(): if name in dirLevels: return f"{extracted}/" + sceneDir + name @@ -604,7 +648,7 @@ def getCustomProperty(data, prop): return value if value != "Custom" else getattr(data, prop + str("Custom")) -def convertIntTo2sComplement(value, length, signed): +def convertIntTo2sComplement(value: int, length: int, signed: bool): return int.from_bytes(int(round(value)).to_bytes(length, "big", signed=signed), "big") @@ -679,6 +723,10 @@ def getCollection(objName, collectionType, subIndex): collection = getCollectionFromIndex(obj, "lightList", subIndex, False) elif collectionType == "Exit": collection = getCollectionFromIndex(obj, "exitList", subIndex, False) + elif collectionType == "Minimap Chest": + collection = getCollectionFromIndex(obj, "minimap_chest_list", subIndex, False) + elif collectionType == "Minimap Room": + collection = getCollectionFromIndex(obj, "minimap_room_list", subIndex, False) elif collectionType == "Object": collection = getCollectionFromIndex(obj, "objectList", subIndex, True) elif collectionType == "Curve": @@ -701,7 +749,7 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Cutscene": collection = obj.ootCutsceneProperty.csLists elif collectionType == "extraCutscenes": - collection = obj.ootSceneHeader.extraCutscenes + collection = get_scene_header_props(obj).extraCutscenes elif collectionType == "BgImage": collection = obj.ootRoomHeader.bgImageList else: @@ -853,7 +901,7 @@ def getActiveHeaderIndex() -> int: headerObj = headerObjs[0] if headerObj.ootEmptyType == "Scene": - header = headerObj.ootSceneHeader + header = get_scene_header_props(headerObj) altHeader = headerObj.ootAlternateSceneHeaders else: header = headerObj.ootRoomHeader @@ -915,7 +963,7 @@ def setActorVisibility(actorObj: bpy.types.Object, activeHeaderInfo: tuple[int, def onMenuTabChange(self, context: bpy.types.Context): def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": - header = otherObj.ootSceneHeader + header = get_scene_header_props(otherObj) else: header = otherObj.ootRoomHeader From d2458a53360934e514542a7ae7768de243130cfd Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 02:32:28 +0100 Subject: [PATCH 009/126] scene alt headers --- .../z64/exporter/scene/__init__.py | 2 +- fast64_internal/z64/importer/scene_header.py | 19 +++++--- fast64_internal/z64/props_panel_main.py | 5 +- .../z64/scene/properties/mm_props.py | 48 +++++++------------ fast64_internal/z64/spline/panels.py | 6 +-- fast64_internal/z64/utility.py | 12 ++--- 6 files changed, 40 insertions(+), 52 deletions(-) diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 5c68d6782..633476e00 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -45,7 +45,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex mainHeader = SceneHeader.new(f"{name}_header{i:02}", get_scene_header_props(sceneObj), sceneObj, transform, i, useMacros) hasAlternateHeaders = False altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") - altProp = sceneObj.ootAlternateSceneHeaders + altProp = get_scene_header_props(sceneObj, True) for i, header in enumerate(altHeaderList, 1): altP: OOTSceneHeaderProperty = getattr(altProp, f"{header}Header") diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index abb205129..43f698649 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -296,16 +296,21 @@ def parseSceneCommands( sceneObj.ootEmptyType = "Scene" sceneObj.name = sceneName + if is_game_oot(): + cs_header_start = 4 + else: + cs_header_start = 1 + if headerIndex == 0: sceneHeader = get_scene_header_props(sceneObj) - elif headerIndex < 4: - sceneHeader = getattr(sceneObj.ootAlternateSceneHeaders, headerNames[headerIndex]) + elif is_game_oot() and headerIndex < cs_header_start: + sceneHeader = getattr(get_scene_header_props(sceneObj, True), headerNames[headerIndex]) sceneHeader.usePreviousHeader = False else: - cutsceneHeaders = sceneObj.ootAlternateSceneHeaders.cutsceneHeaders - while len(cutsceneHeaders) < headerIndex - 3: + cutsceneHeaders = get_scene_header_props(sceneObj, True).cutsceneHeaders + while len(cutsceneHeaders) < headerIndex - (cs_header_start - 1): cutsceneHeaders.add() - sceneHeader = cutsceneHeaders[headerIndex - 4] + sceneHeader = cutsceneHeaders[headerIndex - cs_header_start] commands = getDataMatch(sceneData, sceneCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") entranceList = None @@ -377,7 +382,7 @@ def parseSceneCommands( sceneHeader.csWriteObject = bpy.data.objects[csObjName] except: print(f"ERROR: Cutscene ``{csObjName}`` do not exist!") - elif is_game_oot() and command == "SCENE_CMD_ALTERNATE_HEADER_LIST": + elif command == "SCENE_CMD_ALTERNATE_HEADER_LIST": # Delay until after rooms are parsed altHeadersListName = stripName(args[0]) @@ -388,7 +393,7 @@ def parseSceneCommands( elif command == "SCENE_CMD_MINIMAP_INFO": parse_mm_minimap_info(sceneHeader, sceneData, stripName(args[0])) - if is_game_oot() and altHeadersListName is not None: + if altHeadersListName is not None: parseAlternateSceneHeaders(sceneObj, roomObjs, sceneData, altHeadersListName, f3dContext, sharedSceneData) return sceneObj diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 1a33d59f3..d395821a2 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -46,7 +46,8 @@ def drawSceneHeader(box: bpy.types.UILayout, obj: bpy.types.Object): props = get_scene_header_props(obj) props.draw_props(box, None, None, objName) if props.menuTab == "Alternate": - obj.ootAlternateSceneHeaders.draw_props(box, objName) + alt_props = get_scene_header_props(obj, True) + alt_props.draw_props(box, objName) box.prop(obj.fast64.oot.scene, "write_dummy_room_list") @@ -135,7 +136,7 @@ def draw(self, context): sceneObj = getSceneObj(obj) roomObj = getRoomObj(obj) - altSceneProp = sceneObj.ootAlternateSceneHeaders if sceneObj is not None else None + altSceneProp = get_scene_header_props(sceneObj, True) if sceneObj is not None else None altRoomProp = roomObj.ootAlternateRoomHeaders if roomObj is not None else None if obj.ootEmptyType == "Actor": diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py index dde6d8233..9e5fa178f 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -299,7 +299,6 @@ def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: class MM_SceneHeaderProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES globalObject: EnumProperty(name="Global Object", default="None", items=mm_enum_global_object) @@ -346,6 +345,7 @@ class MM_SceneHeaderProperty(PropertyGroup): timeOfDayLights: PointerProperty(type=OOTLightGroupProperty, name="Time Of Day Lighting") lightList: CollectionProperty(type=OOTLightProperty, name="Lighting List") + # SCENE_CMD_EXIT_LIST exitList: CollectionProperty(type=MM_ExitProperty, name="Exit List") writeCutscene: BoolProperty(name="Write Cutscene") @@ -375,13 +375,8 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") if not self.expandTab: return - if headerIndex is not None and headerIndex > 3: - drawCollectionOps(layout, headerIndex - 4, "Scene", None, objName) - - if headerIndex is not None and headerIndex > 0 and headerIndex < 4: - layout.prop(self, "usePreviousHeader", text="Use Previous Header") - if self.usePreviousHeader: - return + if headerIndex is not None and headerIndex > 0: + drawCollectionOps(layout, headerIndex - 1, "Scene", None, objName) if headerIndex is None or headerIndex == 0: layout.row().prop(self, "menuTab", expand=True) @@ -445,7 +440,11 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawAddButton(lighting, len(self.lightList), "Light", headerIndex, objName) elif menuTab == "Cutscene": + layout.label(text="Cutscenes aren't implemented yet.") cutscene = layout.column() + + cutscene.enabled = False + r = cutscene.row() r.prop(self, "writeCutscene", text="Write Cutscene") if self.writeCutscene: @@ -474,34 +473,19 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj class MM_AlternateSceneHeaderProperty(PropertyGroup): - childNightHeader: PointerProperty(name="Child Night Header", type=MM_SceneHeaderProperty) - adultDayHeader: PointerProperty(name="Adult Day Header", type=MM_SceneHeaderProperty) - adultNightHeader: PointerProperty(name="Adult Night Header", type=MM_SceneHeaderProperty) cutsceneHeaders: CollectionProperty(type=MM_SceneHeaderProperty) - - headerMenuTab: EnumProperty(name="Header Menu", items=ootEnumHeaderMenu, update=onHeaderMenuTabChange) - currentCutsceneIndex: IntProperty(min=4, default=4, update=onHeaderMenuTabChange) + currentCutsceneIndex: IntProperty(min=1, default=1, update=onHeaderMenuTabChange) def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - # headerSetup.box().label(text = "Alternate Headers") - headerSetupBox = headerSetup.column() - - headerSetupBox.row().prop(self, "headerMenuTab", expand=True) - if self.headerMenuTab == "Child Night": - self.childNightHeader.draw_props(headerSetupBox, None, 1, objName) - elif self.headerMenuTab == "Adult Day": - self.adultDayHeader.draw_props(headerSetupBox, None, 2, objName) - elif self.headerMenuTab == "Adult Night": - self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) - elif self.headerMenuTab == "Cutscene": - prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") - drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) - index = self.currentCutsceneIndex - if index - 4 < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - 4].draw_props(headerSetup, None, index, objName) - else: - headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") + + prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") + drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) + index = self.currentCutsceneIndex + if index - 1 < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - 1].draw_props(headerSetup, None, index, objName) + else: + headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") class OOTBootupSceneOptions(PropertyGroup): diff --git a/fast64_internal/z64/spline/panels.py b/fast64_internal/z64/spline/panels.py index 43dc4c311..ed7ffb833 100644 --- a/fast64_internal/z64/spline/panels.py +++ b/fast64_internal/z64/spline/panels.py @@ -1,8 +1,6 @@ from bpy.types import Panel, Curve from bpy.utils import register_class, unregister_class -from ...utility import prop_split -from ..utility import getSceneObj, drawEnumWithCustom -from ..actor.properties import OOTActorHeaderProperty +from ..utility import getSceneObj, get_scene_header_props from .properties import OOTSplineProperty @@ -28,7 +26,7 @@ def draw(self, context): box.label(text="Only NURBS curves are compatible.") else: sceneObj = getSceneObj(context.object) - altSceneProp = sceneObj.ootAlternateSceneHeaders if sceneObj is not None else None + altSceneProp = get_scene_header_props(sceneObj, True) if sceneObj is not None else None splineProp: OOTSplineProperty = context.object.ootSplineProperty splineProp.draw_props(box, altSceneProp, context.object.name) diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 02cc429c4..25f652bd1 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -68,11 +68,11 @@ def is_game_oot(): return bpy.context.scene.gameEditorMode == "OOT" -def get_scene_header_props(obj: Object): +def get_scene_header_props(obj: Object, is_alt_header: bool = False): if is_game_oot(): - return obj.ootSceneHeader + return obj.ootAlternateSceneHeaders if is_alt_header else obj.ootSceneHeader else: - return obj.mm_scene_header + return obj.mm_alternate_scene_headers if is_alt_header else obj.mm_scene_header def isPathObject(obj: bpy.types.Object) -> bool: @@ -718,7 +718,7 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Room": collection = obj.ootAlternateRoomHeaders.cutsceneHeaders elif collectionType == "Scene": - collection = obj.ootAlternateSceneHeaders.cutsceneHeaders + collection = get_scene_header_props(obj, True).cutsceneHeaders elif collectionType == "Light": collection = getCollectionFromIndex(obj, "lightList", subIndex, False) elif collectionType == "Exit": @@ -902,7 +902,7 @@ def getActiveHeaderIndex() -> int: headerObj = headerObjs[0] if headerObj.ootEmptyType == "Scene": header = get_scene_header_props(headerObj) - altHeader = headerObj.ootAlternateSceneHeaders + altHeader = get_scene_header_props(headerObj, True) else: header = headerObj.ootRoomHeader altHeader = headerObj.ootAlternateRoomHeaders @@ -978,7 +978,7 @@ def callback(thisHeader, otherObj: bpy.types.Object): def onHeaderMenuTabChange(self, context: bpy.types.Context): def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": - header = otherObj.ootAlternateSceneHeaders + header = get_scene_header_props(otherObj, True) else: header = otherObj.ootAlternateRoomHeaders From 3efd146c402d4b2126311af313267d628b79b5c8 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 02:32:43 +0100 Subject: [PATCH 010/126] format --- fast64_internal/z64/data/oot/data.py | 24 +++++++++-- .../z64/exporter/scene/__init__.py | 4 +- fast64_internal/z64/importer/scene_header.py | 15 +++++-- fast64_internal/z64/room/properties.py | 9 ++++- .../z64/scene/properties/mm_props.py | 40 +++++++++++++++---- fast64_internal/z64/utility.py | 8 ++-- 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/fast64_internal/z64/data/oot/data.py b/fast64_internal/z64/data/oot/data.py index 2cd903da8..01123572e 100644 --- a/fast64_internal/z64/data/oot/data.py +++ b/fast64_internal/z64/data/oot/data.py @@ -50,10 +50,26 @@ def __init__(self): ("NA_BGM_FIELD_ENEMY_2", "Hyrule Field (Enemy Near Segment 2)", "Hyrule Field (Enemy Near Segment 2)"), ("NA_BGM_FIELD_ENEMY_3", "Hyrule Field (Enemy Near Segment 3)", "Hyrule Field (Enemy Near Segment 3)"), ("NA_BGM_FIELD_ENEMY_4", "Hyrule Field (Enemy Near Segment 4)", "Hyrule Field (Enemy Near Segment 4)"), - ("NA_BGM_FIELD_STILL_1", "Hyrule Field (Standing Still Segment 1)", "Hyrule Field (Standing Still Segment 1)"), - ("NA_BGM_FIELD_STILL_2", "Hyrule Field (Standing Still Segment 2)", "Hyrule Field (Standing Still Segment 2)"), - ("NA_BGM_FIELD_STILL_3", "Hyrule Field (Standing Still Segment 3)", "Hyrule Field (Standing Still Segment 3)"), - ("NA_BGM_FIELD_STILL_4", "Hyrule Field (Standing Still Segment 4)", "Hyrule Field (Standing Still Segment 4)"), + ( + "NA_BGM_FIELD_STILL_1", + "Hyrule Field (Standing Still Segment 1)", + "Hyrule Field (Standing Still Segment 1)", + ), + ( + "NA_BGM_FIELD_STILL_2", + "Hyrule Field (Standing Still Segment 2)", + "Hyrule Field (Standing Still Segment 2)", + ), + ( + "NA_BGM_FIELD_STILL_3", + "Hyrule Field (Standing Still Segment 3)", + "Hyrule Field (Standing Still Segment 3)", + ), + ( + "NA_BGM_FIELD_STILL_4", + "Hyrule Field (Standing Still Segment 4)", + "Hyrule Field (Standing Still Segment 4)", + ), ("NA_BGM_DUNGEON", "Dodongo's Cavern", "Dodongo's Cavern"), ("NA_BGM_KAKARIKO_ADULT", "Kakariko Village (Adult)", "Kakariko Village (Adult)"), ("NA_BGM_ENEMY", "Enemy Battle", "Enemy Battle"), diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 633476e00..038e54cea 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -42,7 +42,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex True, ) - mainHeader = SceneHeader.new(f"{name}_header{i:02}", get_scene_header_props(sceneObj), sceneObj, transform, i, useMacros) + mainHeader = SceneHeader.new( + f"{name}_header{i:02}", get_scene_header_props(sceneObj), sceneObj, transform, i, useMacros + ) hasAlternateHeaders = False altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") altProp = get_scene_header_props(sceneObj, True) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 43f698649..4a32e4caf 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -8,7 +8,14 @@ from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext from ..scene.properties import OOTSceneHeaderProperty, OOTLightProperty, MM_SceneHeaderProperty -from ..utility import getEvalParams, setCustomProperty, get_game_enum, get_scene_header_props, is_game_oot, convertIntTo2sComplement +from ..utility import ( + getEvalParams, + setCustomProperty, + get_game_enum, + get_scene_header_props, + is_game_oot, + convertIntTo2sComplement, +) from .constants import headerNames from .utility import getDataMatch, stripName from .classes import SharedSceneData @@ -321,7 +328,9 @@ def parseSceneCommands( if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) setCustomProperty(sceneHeader, "nightSeq", args[1], get_game_enum("enum_ambiance_id")) - setCustomProperty(sceneHeader, "musicSeq", get_enum_id_from_index("seqId", int(args[2])), get_game_enum("enum_seq_id")) + setCustomProperty( + sceneHeader, "musicSeq", get_enum_id_from_index("seqId", int(args[2])), get_game_enum("enum_seq_id") + ) elif command == "SCENE_CMD_ROOM_LIST": # Assumption that all scenes use the same room list. if headerIndex == 0: @@ -385,7 +394,7 @@ def parseSceneCommands( elif command == "SCENE_CMD_ALTERNATE_HEADER_LIST": # Delay until after rooms are parsed altHeadersListName = stripName(args[0]) - + # handle Majora's Mask exclusive commands elif not is_game_oot(): if command == "SCENE_CMD_SET_REGION_VISITED": diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 0755a843e..6d4cbc877 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -2,7 +2,14 @@ from bpy.types import PropertyGroup, UILayout, Image, Object from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton, is_game_oot +from ..utility import ( + drawCollectionOps, + onMenuTabChange, + onHeaderMenuTabChange, + drawEnumWithCustom, + drawAddButton, + is_game_oot, +) from ..upgrade import upgradeRoomHeaders from .operators import OOT_SearchObjectEnumOperator diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py index 9e5fa178f..f55fb560b 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -257,7 +257,9 @@ class OOTExtraCutsceneProperty(PropertyGroup): def minimap_chest_poll(self: "MM_MinimapChestProperty", object: Object): - return object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" + return ( + object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" + ) class MM_MinimapChestProperty(PropertyGroup): @@ -268,7 +270,12 @@ class MM_MinimapChestProperty(PropertyGroup): def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: str): box = layout.box() - box.prop(self, "expand_tab", text=f"Chest Actor No.{index + 1}", icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT") + box.prop( + self, + "expand_tab", + text=f"Chest Actor No.{index + 1}", + icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT", + ) if self.expand_tab: drawCollectionOps(box, index, "Minimap Chest", header_index, obj_name) @@ -286,7 +293,12 @@ class MM_MinimapRoomProperty(PropertyGroup): def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: str): box = layout.box() - box.prop(self, "expand_tab", text=f"Minimap Room Index {index}", icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT") + box.prop( + self, + "expand_tab", + text=f"Minimap Room Index {index}", + icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT", + ) if self.expand_tab: drawCollectionOps(box, index, "Minimap Room", header_index, obj_name) @@ -322,7 +334,11 @@ class MM_SceneHeaderProperty(PropertyGroup): ) # SCENE_CMD_SET_REGION_VISITED - set_region_visited: BoolProperty(name="Set Region Visited Flag", default=False, description="Sets a flag that indicates the region has been visited. Scene indices are mapped to their region in `gSceneIdsPerRegion` from `z_inventory.c`") + set_region_visited: BoolProperty( + name="Set Region Visited Flag", + default=False, + description="Sets a flag that indicates the region has been visited. Scene indices are mapped to their region in `gSceneIdsPerRegion` from `z_inventory.c`", + ) # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `MM_RoomHeaderProperty`) minimap_room_expand: BoolProperty(name="Expand Tab") @@ -413,7 +429,12 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj map_room_box = minimap.column().box() list_length = len(self.minimap_room_list) item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" - map_room_box.prop(self, "minimap_room_expand", text=f"Minimap Room List ({item_count})", icon="TRIA_DOWN" if self.minimap_room_expand else "TRIA_RIGHT") + map_room_box.prop( + self, + "minimap_room_expand", + text=f"Minimap Room List ({item_count})", + icon="TRIA_DOWN" if self.minimap_room_expand else "TRIA_RIGHT", + ) if self.minimap_room_expand: for i in range(list_length): self.minimap_room_list[i].draw_props(map_room_box, i, headerIndex, objName) @@ -422,11 +443,16 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj chest_box = minimap.column().box() list_length = len(self.minimap_chest_list) item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" - chest_box.prop(self, "minimap_chest_expand", text=f"Minimap Chest List ({item_count})", icon="TRIA_DOWN" if self.minimap_chest_expand else "TRIA_RIGHT") + chest_box.prop( + self, + "minimap_chest_expand", + text=f"Minimap Chest List ({item_count})", + icon="TRIA_DOWN" if self.minimap_chest_expand else "TRIA_RIGHT", + ) if self.minimap_chest_expand: for i in range(list_length): self.minimap_chest_list[i].draw_props(chest_box, i, headerIndex, objName) - drawAddButton(chest_box, list_length, "Minimap Chest", headerIndex, objName) + drawAddButton(chest_box, list_length, "Minimap Chest", headerIndex, objName) elif menuTab == "Lighting": lighting = layout.column() diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 25f652bd1..876cd3f23 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -50,16 +50,17 @@ "enum_global_object": ootEnumGlobalObject, "enum_skybox": ootEnumSkybox, "enum_seq_id": oot_data.ootEnumMusicSeq, - "enum_ambiance_id": oot_data.ootEnumNightSeq # TODO: generate this from xml (not for enumproperties) + "enum_ambiance_id": oot_data.ootEnumNightSeq, # TODO: generate this from xml (not for enumproperties) }, "MM": { "enum_global_object": mm_enum_global_object, "enum_skybox": mm_enum_skybox, "enum_seq_id": mm_data.enum_seq_id, - "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above - } + "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above + }, } + def get_game_enum(enum_type: str): return game_enum_map[bpy.context.scene.gameEditorMode][enum_type] @@ -78,6 +79,7 @@ def get_scene_header_props(obj: Object, is_alt_header: bool = False): def isPathObject(obj: bpy.types.Object) -> bool: return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" + ootSceneDungeons = [ "bdan", "bdan_boss", From 2d6a893c9509ea98592d9e9d02e8282ea9315d30 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 03:00:39 +0100 Subject: [PATCH 011/126] room props basics --- fast64_internal/z64/__init__.py | 4 +- .../z64/exporter/collision/waterbox.py | 4 +- fast64_internal/z64/exporter/room/__init__.py | 5 +- fast64_internal/z64/exporter/room/shape.py | 3 +- fast64_internal/z64/exporter/scene/actors.py | 12 +- fast64_internal/z64/exporter/scene/rooms.py | 4 +- fast64_internal/z64/importer/actor.py | 4 +- fast64_internal/z64/importer/room_header.py | 10 +- fast64_internal/z64/importer/room_shape.py | 5 +- fast64_internal/z64/props_panel_main.py | 10 +- .../z64/room/properties/__init__.py | 2 + .../z64/room/properties/mm_props.py | 275 ++++++++++++++++++ .../oot_props.py} | 12 +- fast64_internal/z64/tools/operators.py | 6 +- fast64_internal/z64/upgrade.py | 8 +- fast64_internal/z64/utility.py | 21 +- 16 files changed, 337 insertions(+), 48 deletions(-) create mode 100644 fast64_internal/z64/room/properties/__init__.py create mode 100644 fast64_internal/z64/room/properties/mm_props.py rename fast64_internal/z64/room/{properties.py => properties/oot_props.py} (98%) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 03a72eff6..f06511915 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -18,7 +18,7 @@ from .collision.properties import OOTCollisionExportSettings from .room.operators import room_ops_register, room_ops_unregister -from .room.properties import room_props_register, room_props_unregister +from .room.properties import room_props_register, room_props_unregister, mm_room_props_register, mm_room_props_unregister from .actor.operators import actor_ops_register, actor_ops_unregister from .actor.properties import actor_props_register, actor_props_unregister @@ -168,6 +168,7 @@ def oot_register(registerPanels): mm_scene_props_register() room_ops_register() room_props_register() + mm_room_props_register() actor_ops_register() actor_props_register() oot_obj_register() @@ -209,6 +210,7 @@ def oot_unregister(unregisterPanels): mm_scene_props_unregister() room_ops_unregister() room_props_unregister() + mm_room_props_unregister() actor_ops_unregister() actor_props_unregister() spline_props_unregister() diff --git a/fast64_internal/z64/exporter/collision/waterbox.py b/fast64_internal/z64/exporter/collision/waterbox.py index 1267fecf0..a5c90eeff 100644 --- a/fast64_internal/z64/exporter/collision/waterbox.py +++ b/fast64_internal/z64/exporter/collision/waterbox.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from mathutils import Matrix from bpy.types import Object -from ...utility import getObjectList +from ...utility import getObjectList, get_room_header_props from ....utility import CData, checkIdentityRotation, indent from ..utility import Utility @@ -121,7 +121,7 @@ def new(name: str, dataHolder: Object, transform: Matrix, useMacros: bool): emptyScale, wboxProp.camera, wboxProp.lighting, - roomObj.ootRoomHeader.roomIndex if roomObj is not None else 0x3F, + get_room_header_props(roomObj).roomIndex if roomObj is not None else 0x3F, wboxProp.flag19, useMacros, ) diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index 798db23ac..449285bb1 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -4,6 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings +from ...utility import get_room_header_props from ...room.properties import OOTRoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -37,9 +38,9 @@ def new( saveTexturesAsPNG: bool, ): i = 0 - mainHeaderProps = roomObj.ootRoomHeader + mainHeaderProps = get_room_header_props(roomObj) altHeader = RoomAlternateHeader(f"{name}_alternateHeaders") - altProp = roomObj.ootAlternateRoomHeaders + altProp = get_room_header_props(roomObj, True) if mainHeaderProps.roomShape == "ROOM_SHAPE_TYPE_IMAGE" and len(mainHeaderProps.bgImageList) == 0: raise PluginError(f'Room {roomObj.name} uses room shape "Image" but doesn\'t have any BG images.') diff --git a/fast64_internal/z64/exporter/room/shape.py b/fast64_internal/z64/exporter/room/shape.py index e08f141d2..18febf8f5 100644 --- a/fast64_internal/z64/exporter/room/shape.py +++ b/fast64_internal/z64/exporter/room/shape.py @@ -18,6 +18,7 @@ CullGroup, checkUniformScale, ootConvertTranslation, + get_room_header_props, ) @@ -544,7 +545,7 @@ def create_shape( room_shape.bg_entries.append(RoomShapeImageEntry.new(scene_name, bg_image)) pos, _, scale, _ = Utility.getConvertedTransform(transform, sceneObj, roomObj, True) - cull_group = CullGroup(pos, scale, roomObj.ootRoomHeader.defaultCullDistance) + cull_group = CullGroup(pos, scale, get_room_header_props(roomObj).defaultCullDistance) dl_entry = room_shape.add_dl_entry(cull_group) boundingBox = BoundingBox() ootProcessMesh( diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 24acd07b3..9383cb88b 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList +from ...utility import getObjectList, get_room_header_props from ...constants import oot_data from ..utility import Utility from ..actor import Actor @@ -54,7 +54,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): actorToRoom[childObj] = obj actorObjList = getObjectList(sceneObj.children_recursive, "EMPTY", "Transition Actor") - actorObjList.sort(key=lambda obj: actorToRoom[obj].ootRoomHeader.roomIndex) + actorObjList.sort(key=lambda obj: get_room_header_props(actorToRoom[obj]).roomIndex) entries: list[TransitionActor] = [] for obj in actorObjList: @@ -69,10 +69,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if transActorProp.isRoomTransition: if transActorProp.fromRoom is None or transActorProp.toRoom is None: raise PluginError("ERROR: Missing room empty object assigned to transition.") - fromIndex = transActorProp.fromRoom.ootRoomHeader.roomIndex - toIndex = transActorProp.toRoom.ootRoomHeader.roomIndex + fromIndex = get_room_header_props(transActorProp.fromRoom).roomIndex + toIndex = get_room_header_props(transActorProp.toRoom).roomIndex else: - fromIndex = toIndex = actorToRoom[obj].ootRoomHeader.roomIndex + fromIndex = toIndex = get_room_header_props(actorToRoom[obj]).roomIndex front = (fromIndex, Utility.getPropValue(transActorProp, "cameraTransitionFront")) back = (toIndex, Utility.getPropValue(transActorProp, "cameraTransitionBack")) @@ -165,7 +165,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) entranceActor.params = entranceProp.actor.actorParam if entranceProp.tiedRoom is not None: - entranceActor.roomIndex = entranceProp.tiedRoom.ootRoomHeader.roomIndex + entranceActor.roomIndex = get_room_header_props(entranceProp.tiedRoom).roomIndex else: raise PluginError("ERROR: Missing room empty object assigned to the entrance.") entranceActor.spawnIndex = entranceProp.spawnIndex diff --git a/fast64_internal/z64/exporter/scene/rooms.py b/fast64_internal/z64/exporter/scene/rooms.py index 9efb03b81..bcd9a0cfe 100644 --- a/fast64_internal/z64/exporter/scene/rooms.py +++ b/fast64_internal/z64/exporter/scene/rooms.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList +from ...utility import getObjectList, get_room_header_props from ...model_classes import OOTModel from ..room import Room @@ -23,7 +23,7 @@ def new(name: str, sceneName: str, model: OOTModel, sceneObj: Object, transform: raise PluginError("ERROR: The scene has no child empties with the 'Room' empty type.") for roomObj in roomObjs: - roomHeader = roomObj.ootRoomHeader + roomHeader = get_room_header_props(roomObj) roomIndex = roomHeader.roomIndex if roomIndex in roomDict: diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index f8edb0e9e..8d3ce031e 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,7 +3,7 @@ from ...utility import parentObject, hexOrDecInt from ..scene.properties import OOTSceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams +from ..utility import setCustomProperty, getEvalParams, get_room_header_props from ..constants import ootEnumCamTransition, oot_data from .classes import SharedSceneData from .constants import actorsWithRotAsParam @@ -182,7 +182,7 @@ def parseActorList( regex, nestedBrackets = getActorRegex(actorList) for actorMatch in re.finditer(regex, actorList, flags=re.DOTALL): - actorHash = parseActorInfo(actorMatch, nestedBrackets) + (roomObj.ootRoomHeader.roomIndex,) + actorHash = parseActorInfo(actorMatch, nestedBrackets) + (get_room_header_props(roomObj).roomIndex,) if not sharedSceneData.addHeaderIfItemExists(actorHash, "Actor", headerIndex): actorID, position, rotation, actorParam, roomIndex = actorHash diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 4c09b9eda..96ffe8b0f 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,7 @@ import re from ...utility import hexOrDecInt -from ..utility import setCustomProperty +from ..utility import setCustomProperty, get_room_header_props from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty from ..constants import oot_data, ootEnumLinkIdle, ootEnumRoomBehaviour @@ -44,16 +44,16 @@ def parseRoomCommands( roomObj.empty_display_type = "SPHERE" roomObj.location = [0, 0, (roomIndex + 1) * -2] roomObj.ootEmptyType = "Room" - roomObj.ootRoomHeader.roomIndex = roomIndex + get_room_header_props(roomObj).roomIndex = roomIndex roomObj.name = roomName if headerIndex == 0: - roomHeader = roomObj.ootRoomHeader + roomHeader = get_room_header_props(roomObj) elif headerIndex < 4: - roomHeader = getattr(roomObj.ootAlternateRoomHeaders, headerNames[headerIndex]) + roomHeader = getattr(get_room_header_props(roomObj, True), headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: - cutsceneHeaders = roomObj.ootAlternateRoomHeaders.cutsceneHeaders + cutsceneHeaders = get_room_header_props(roomObj, True).cutsceneHeaders while len(cutsceneHeaders) < headerIndex - 3: cutsceneHeaders.add() roomHeader = cutsceneHeaders[headerIndex - 4] diff --git a/fast64_internal/z64/importer/room_shape.py b/fast64_internal/z64/importer/room_shape.py index 096f1ff57..389ea28af 100644 --- a/fast64_internal/z64/importer/room_shape.py +++ b/fast64_internal/z64/importer/room_shape.py @@ -8,6 +8,7 @@ from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty from ..constants import ootEnumRoomShapeType +from ..utility import get_room_header_props from .classes import SharedSceneData from .utility import getDataMatch, stripName @@ -19,7 +20,7 @@ def parseMeshHeader( f3dContext: OOTF3DContext, sharedSceneData: SharedSceneData, ): - roomHeader = roomObj.ootRoomHeader + roomHeader = get_room_header_props(roomObj) meshData = getDataMatch(sceneData, meshHeaderName, "", "mesh header", False) meshData = meshData.replace("{", "").replace("}", "") @@ -78,7 +79,7 @@ def parseMeshList( f3dContext: OOTF3DContext, sharedSceneData: SharedSceneData, ): - roomHeader = roomObj.ootRoomHeader + roomHeader = get_room_header_props(roomObj) meshEntryData = getDataMatch(sceneData, meshListName, "", "mesh list", roomShape != 1) if roomShape == 2: diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index d395821a2..7902a0c90 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj, get_scene_header_props +from .utility import getSceneObj, getRoomObj, get_scene_header_props, get_room_header_props from .scene.properties import OOTSceneProperties from .room.properties import OOTObjectProperty, OOTRoomHeaderProperty, OOTAlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -137,7 +137,7 @@ def draw(self, context): roomObj = getRoomObj(obj) altSceneProp = get_scene_header_props(sceneObj, True) if sceneObj is not None else None - altRoomProp = roomObj.ootAlternateRoomHeaders if roomObj is not None else None + altRoomProp = get_room_header_props(roomObj, True) if roomObj is not None else None if obj.ootEmptyType == "Actor": actorProp: OOTActorProperty = obj.ootActorProperty @@ -155,10 +155,10 @@ def draw(self, context): drawSceneHeader(box, obj) elif obj.ootEmptyType == "Room": - roomProp: OOTRoomHeaderProperty = obj.ootRoomHeader + roomProp: OOTRoomHeaderProperty = get_room_header_props(obj) roomProp.draw_props(box, None, None, objName) - if obj.ootRoomHeader.menuTab == "Alternate": - roomAltProp: OOTAlternateRoomHeaderProperty = obj.ootAlternateRoomHeaders + if get_room_header_props(obj).menuTab == "Alternate": + roomAltProp: OOTAlternateRoomHeaderProperty = get_room_header_props(obj, True) roomAltProp.draw_props(box, objName) elif obj.ootEmptyType == "Entrance": diff --git a/fast64_internal/z64/room/properties/__init__.py b/fast64_internal/z64/room/properties/__init__.py new file mode 100644 index 000000000..8dc7f3296 --- /dev/null +++ b/fast64_internal/z64/room/properties/__init__.py @@ -0,0 +1,2 @@ +from .oot_props import OOTRoomHeaderProperty, OOTBGProperty, OOTAlternateRoomHeaderProperty, OOTObjectProperty, room_props_register, room_props_unregister +from .mm_props import MM_RoomHeaderProperty, MM_AlternateRoomHeaderProperty, mm_room_props_register, mm_room_props_unregister diff --git a/fast64_internal/z64/room/properties/mm_props.py b/fast64_internal/z64/room/properties/mm_props.py new file mode 100644 index 000000000..d26613155 --- /dev/null +++ b/fast64_internal/z64/room/properties/mm_props.py @@ -0,0 +1,275 @@ +import bpy +from bpy.types import PropertyGroup, UILayout, Image, Object +from bpy.utils import register_class, unregister_class +from ....utility import prop_split +from ...utility import ( + drawCollectionOps, + onMenuTabChange, + onHeaderMenuTabChange, + drawEnumWithCustom, + drawAddButton, + is_game_oot, +) +from ..operators import OOT_SearchObjectEnumOperator + +from bpy.props import ( + EnumProperty, + IntProperty, + StringProperty, + FloatProperty, + CollectionProperty, + PointerProperty, + BoolProperty, + IntVectorProperty, +) + +from ...constants import ( + oot_data, + ootEnumRoomBehaviour, + ootEnumLinkIdle, + ootEnumRoomShapeType, + ootEnumHeaderMenu, +) + +ootEnumRoomMenuAlternate = [ + ("General", "General", "General"), + ("Objects", "Objects", "Objects"), +] +ootEnumRoomMenu = ootEnumRoomMenuAlternate + [ + ("Alternate", "Alternate", "Alternate"), +] + + +class MM_ObjectProperty(PropertyGroup): + expandTab: BoolProperty(name="Expand Tab") + objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") + objectIDCustom: StringProperty(default="OBJECT_CUSTOM") + + def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): + isLegacy = True if "objectID" in self else False + + if isLegacy: + objectName = oot_data.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + elif self.objectKey != "Custom": + objectName = oot_data.objectData.objectsByKey[self.objectKey].name + else: + objectName = self.objectIDCustom + + objItemBox = layout.column() + row = objItemBox.row() + row.label(text=f"{objectName}") + buttons = row.row(align=True) + objSearch = buttons.operator(OOT_SearchObjectEnumOperator.bl_idname, icon="VIEWZOOM", text="Select") + drawCollectionOps(buttons, index, "Object", headerIndex, objName, compact=True) + objSearch.objName = objName + objSearch.headerIndex = headerIndex if headerIndex is not None else 0 + objSearch.index = index + + if self.objectKey == "Custom": + prop_split(objItemBox, self, "objectIDCustom", "Object ID Custom") + + +class MM_BGProperty(PropertyGroup): + image: PointerProperty(type=Image) + # camera: IntProperty(name="Camera Index", min=0) + otherModeFlags: StringProperty( + name="DPSetOtherMode Flags", default="0x0000", description="See src/code/z_room.c:func_8009638C()" + ) + + def draw_props(self, layout: UILayout, index: int, objName: str, isMulti: bool): + box = layout.box().column() + + box.template_ID(self, "image", new="image.new", open="image.open") + # if isMulti: + # prop_split(box, self, "camera", "Camera") + prop_split(box, self, "otherModeFlags", "Other Mode Flags") + drawCollectionOps(box, index, "BgImage", None, objName) + + +class MM_RoomHeaderProperty(PropertyGroup): + expandTab: BoolProperty(name="Expand Tab") + menuTab: EnumProperty(items=ootEnumRoomMenu, update=onMenuTabChange) + altMenuTab: EnumProperty(items=ootEnumRoomMenuAlternate) + usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) + + roomIndex: IntProperty(name="Room Index", default=0, min=0) + roomBehaviour: EnumProperty(items=ootEnumRoomBehaviour, default="0x00") + roomBehaviourCustom: StringProperty(default="0x00") + disableWarpSongs: BoolProperty(name="Disable Warp Songs") + showInvisibleActors: BoolProperty(name="Show Invisible Actors") + linkIdleMode: EnumProperty(name="Link Idle Mode", items=ootEnumLinkIdle, default="0x00") + linkIdleModeCustom: StringProperty(name="Link Idle Mode Custom", default="0x00") + roomIsHot: BoolProperty( + name="Use Hot Room Behavior", + description="Use heat timer/screen effect, overrides Link Idle Mode", + default=False, + ) + + setWind: BoolProperty(name="Set Wind") + windVector: IntVectorProperty(name="Wind Vector", size=3, min=-127, max=127) + windStrength: IntProperty(name="Wind Strength", min=0, max=255) + + leaveTimeUnchanged: BoolProperty(name="Leave Time Unchanged", default=True) + timeHours: IntProperty(name="Hours", default=0, min=0, max=23) # 0xFFFE + timeMinutes: IntProperty(name="Minutes", default=0, min=0, max=59) + timeSpeed: FloatProperty(name="Time Speed", default=1, min=-13, max=13) # 0xA + + disableSkybox: BoolProperty(name="Disable Skybox") + disableSunMoon: BoolProperty(name="Disable Sun/Moon") + + echo: StringProperty(name="Echo", default="0x00") + + objectList: CollectionProperty(type=MM_ObjectProperty) + + roomShape: EnumProperty(items=ootEnumRoomShapeType, default="ROOM_SHAPE_TYPE_NORMAL") + defaultCullDistance: IntProperty(name="Default Cull Distance", min=1, default=100) + bgImageList: CollectionProperty(type=MM_BGProperty) + bgImageTab: BoolProperty(name="BG Images") + + def drawBGImageList(self, layout: UILayout, objName: str): + box = layout.column() + box.label(text="BG images do not work currently.", icon="ERROR") + box.prop(self, "bgImageTab", text="BG Images", icon="TRIA_DOWN" if self.bgImageTab else "TRIA_RIGHT") + if self.bgImageTab: + box.label(text="Only one room allowed per scene.", icon="INFO") + box.label(text="Must be framebuffer sized (320x240).", icon="INFO") + box.label(text="Must be jpg file with file marker.", icon="INFO") + box.label(text="Ex. MsPaint compatible, Photoshop not.") + box.label(text="Can't use files generated in Blender.") + imageCount = len(self.bgImageList) + for i in range(imageCount): + self.bgImageList[i].draw_props(box, i, objName, imageCount > 1) + + drawAddButton(box, len(self.bgImageList), "BgImage", None, objName) + + def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): + from ...props_panel_main import OOT_ManualUpgrade + + if dropdownLabel is not None: + layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") + if not self.expandTab: + return + if headerIndex is not None and headerIndex > 0: + drawCollectionOps(layout, headerIndex - 1, "Room", None, objName) + + if headerIndex is None or headerIndex == 0: + layout.row().prop(self, "menuTab", expand=True) + menuTab = self.menuTab + else: + layout.row().prop(self, "altMenuTab", expand=True) + menuTab = self.altMenuTab + + if menuTab == "General": + if headerIndex is None or headerIndex == 0: + general = layout.column() + general.box().label(text="General") + prop_split(general, self, "roomIndex", "Room Index") + prop_split(general, self, "roomShape", "Room Shape") + if self.roomShape == "ROOM_SHAPE_TYPE_IMAGE": + self.drawBGImageList(general, objName) + if self.roomShape == "ROOM_SHAPE_TYPE_CULLABLE": + general.label(text="The 'Cullable' room shape type is for CPU culling,", icon="INFO") + general.label(text="and requires meshes to be parented to Custom Cull Group empties.") + general.label(text="RSP culling is done automatically regardless of room shape.") + prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") + if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_game_oot(): + general.label(text="This shape type is only implemented on MM", icon="INFO") + # Behaviour + behaviourBox = layout.column() + behaviourBox.box().label(text="Behaviour") + drawEnumWithCustom(behaviourBox, self, "roomBehaviour", "Room Behaviour", "") + drawEnumWithCustom(behaviourBox, self, "linkIdleMode", "Link Idle Mode", "") + behaviourBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") + behaviourBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") + + # Time + skyboxAndTime = layout.column() + skyboxAndTime.box().label(text="Skybox And Time") + + # Skybox + skyboxAndTime.prop(self, "disableSkybox", text="Disable Skybox") + skyboxAndTime.prop(self, "disableSunMoon", text="Disable Sun/Moon") + skyboxAndTime.prop(self, "leaveTimeUnchanged", text="Leave Time Unchanged") + if not self.leaveTimeUnchanged: + skyboxAndTime.label(text="Time") + timeRow = skyboxAndTime.row() + timeRow.prop(self, "timeHours", text="Hours") + timeRow.prop(self, "timeMinutes", text="Minutes") + # prop_split(skyboxAndTime, self, "timeValue", "Time Of Day") + prop_split(skyboxAndTime, self, "timeSpeed", "Time Speed") + + # Echo + prop_split(skyboxAndTime, self, "echo", "Echo") + + # Wind + windBox = layout.column() + windBox.box().label(text="Wind") + windBox.prop(self, "setWind", text="Set Wind") + if self.setWind: + windBoxRow = windBox.row() + windBoxRow.prop(self, "windVector", text="") + windBox.prop(self, "windStrength", text="Strength") + # prop_split(windBox, self, "windVector", "Wind Vector") + + elif menuTab == "Objects": + upgradeLayout = layout.column() + objBox = layout.column() + objBox.box().label(text="Objects") + + if len(self.objectList) > 16: + objBox.label(text="You are over the 16 object limit.", icon="ERROR") + objBox.label(text="You must allocate more memory in code.") + + isLegacy = False + for i, objProp in enumerate(self.objectList): + objProp.draw_props(objBox, headerIndex, i, objName) + + if "objectID" in objProp: + isLegacy = True + + if isLegacy: + upgradeLayout.label(text="Legacy data has not been upgraded!") + upgradeLayout.operator(OOT_ManualUpgrade.bl_idname, text="Upgrade Data Now!") + objBox.enabled = False if isLegacy else True + + drawAddButton(objBox, len(self.objectList), "Object", headerIndex, objName) + + +class MM_AlternateRoomHeaderProperty(PropertyGroup): + cutsceneHeaders: CollectionProperty(type=MM_RoomHeaderProperty) + currentCutsceneIndex: IntProperty(min=1, default=1, update=onHeaderMenuTabChange) + + def draw_props(self, layout: UILayout, objName: str): + headerSetup = layout.column() + + prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") + drawAddButton(headerSetup, len(self.cutsceneHeaders), "Room", None, objName) + index = self.currentCutsceneIndex + if index - 1 < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - 1].draw_props(headerSetup, None, index, objName) + else: + headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") + + +classes = ( + MM_ObjectProperty, + MM_BGProperty, + MM_RoomHeaderProperty, + MM_AlternateRoomHeaderProperty, +) + + +def mm_room_props_register(): + for cls in classes: + register_class(cls) + + Object.mm_room_header = PointerProperty(type=MM_RoomHeaderProperty) + Object.mm_alternate_room_headers = PointerProperty(type=MM_AlternateRoomHeaderProperty) + + +def mm_room_props_unregister(): + del bpy.types.Object.mm_room_header + del bpy.types.Object.mm_alternate_room_headers + + for cls in reversed(classes): + unregister_class(cls) diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties/oot_props.py similarity index 98% rename from fast64_internal/z64/room/properties.py rename to fast64_internal/z64/room/properties/oot_props.py index 6d4cbc877..73e2feb8c 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties/oot_props.py @@ -1,8 +1,8 @@ import bpy from bpy.types import PropertyGroup, UILayout, Image, Object from bpy.utils import register_class, unregister_class -from ...utility import prop_split -from ..utility import ( +from ....utility import prop_split +from ...utility import ( drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, @@ -10,8 +10,8 @@ drawAddButton, is_game_oot, ) -from ..upgrade import upgradeRoomHeaders -from .operators import OOT_SearchObjectEnumOperator +from ...upgrade import upgradeRoomHeaders +from ..operators import OOT_SearchObjectEnumOperator from bpy.props import ( EnumProperty, @@ -24,7 +24,7 @@ IntVectorProperty, ) -from ..constants import ( +from ...constants import ( oot_data, ootEnumRoomBehaviour, ootEnumLinkIdle, @@ -149,7 +149,7 @@ def drawBGImageList(self, layout: UILayout, objName: str): drawAddButton(box, len(self.bgImageList), "BgImage", None, objName) def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from ..props_panel_main import OOT_ManualUpgrade + from ...props_panel_main import OOT_ManualUpgrade if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 4b5090a70..b2fb9630c 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -7,7 +7,7 @@ from ...operators import AddWaterBox, addMaterialByName from ...utility import parentObject, setOrigin from ..cutscene.motion.utility import setupCutscene, createNewCameraShot -from ..utility import getNewPath +from ..utility import getNewPath, get_room_header_props from .quick_import import QuickImportAborted, quick_import_exec @@ -133,11 +133,11 @@ def execute(self, context): indices = [] for sceneChild in sceneObj.children: if sceneChild.ootEmptyType == "Room": - indices.append(sceneChild.ootRoomHeader.roomIndex) + indices.append(get_room_header_props(sceneChild).roomIndex) nextIndex = 0 while nextIndex in indices: nextIndex += 1 - roomObj.ootRoomHeader.roomIndex = nextIndex + get_room_header_props(roomObj).roomIndex = nextIndex parentObject(sceneObj, roomObj) object.select_all(action="DESELECT") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index e3bfa74bf..492aa9b59 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,7 +6,7 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from .data import OoT_ObjectData -from .utility import getEvalParams +from .utility import getEvalParams, get_room_header_props from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode @@ -38,9 +38,9 @@ def upgradeObjectList(objList: CollectionProperty, objData: OoT_ObjectData): def upgradeRoomHeaders(roomObj: Object, objData: OoT_ObjectData): """Main upgrade logic for room headers""" - altHeaders = roomObj.ootAlternateRoomHeaders + altHeaders = get_room_header_props(roomObj, True) for sceneLayer in [ - roomObj.ootRoomHeader, + get_room_header_props(roomObj), altHeaders.childNightHeader, altHeaders.adultDayHeader, altHeaders.adultNightHeader, @@ -344,7 +344,7 @@ def upgradeActors(actorObj: Object): obj != transActorProp.fromRoom and obj.type == "EMPTY" and obj.ootEmptyType == "Room" - and obj.ootRoomHeader.roomIndex == transActorProp["roomIndex"] + and get_room_header_props(obj).roomIndex == transActorProp["roomIndex"] ): transActorProp.toRoom = obj del transActorProp["roomIndex"] diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 876cd3f23..70911e48e 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -76,6 +76,13 @@ def get_scene_header_props(obj: Object, is_alt_header: bool = False): return obj.mm_alternate_scene_headers if is_alt_header else obj.mm_scene_header +def get_room_header_props(obj: Object, is_alt_header: bool = False): + if is_game_oot(): + return get_room_header_props(obj, True) if is_alt_header else get_room_header_props(obj) + else: + return obj.mm_alternate_room_headers if is_alt_header else obj.mm_room_header + + def isPathObject(obj: bpy.types.Object) -> bool: return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" @@ -718,7 +725,7 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Entrance": collection = obj.ootEntranceProperty.actor.headerSettings.cutsceneHeaders elif collectionType == "Room": - collection = obj.ootAlternateRoomHeaders.cutsceneHeaders + collection = get_room_header_props(obj, True).cutsceneHeaders elif collectionType == "Scene": collection = get_scene_header_props(obj, True).cutsceneHeaders elif collectionType == "Light": @@ -753,7 +760,7 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "extraCutscenes": collection = get_scene_header_props(obj).extraCutscenes elif collectionType == "BgImage": - collection = obj.ootRoomHeader.bgImageList + collection = get_room_header_props(obj).bgImageList else: raise PluginError("Invalid collection type: " + collectionType) @@ -906,8 +913,8 @@ def getActiveHeaderIndex() -> int: header = get_scene_header_props(headerObj) altHeader = get_scene_header_props(headerObj, True) else: - header = headerObj.ootRoomHeader - altHeader = headerObj.ootAlternateRoomHeaders + header = get_room_header_props(headerObj) + altHeader = get_room_header_props(headerObj, True) if header.menuTab != "Alternate": headerIndex = 0 @@ -967,7 +974,7 @@ def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": header = get_scene_header_props(otherObj) else: - header = otherObj.ootRoomHeader + header = get_room_header_props(otherObj) if thisHeader.menuTab != "Alternate" and header.menuTab == "Alternate": header.menuTab = "General" @@ -982,7 +989,7 @@ def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": header = get_scene_header_props(otherObj, True) else: - header = otherObj.ootAlternateRoomHeaders + header = get_room_header_props(otherObj, True) header.headerMenuTab = thisHeader.headerMenuTab header.currentCutsceneIndex = thisHeader.currentCutsceneIndex @@ -1148,7 +1155,7 @@ def getObjectList( cond = obj.ootSplineProperty.splineType == splineType if parentObj is not None: - if emptyType == "Actor" and obj.ootEmptyType == "Room" and obj.ootRoomHeader.roomIndex == room_index: + if emptyType == "Actor" and obj.ootEmptyType == "Room" and get_room_header_props(obj).roomIndex == room_index: for o in obj.children_recursive: if o.type == objType and o.ootEmptyType == emptyType and o not in ret: ret.append(o) From 3bd1fc0b266f56bdbf6adf1b16fb1c5a77f82ca7 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 03:00:50 +0100 Subject: [PATCH 012/126] format --- fast64_internal/z64/__init__.py | 7 ++++++- fast64_internal/z64/room/properties/__init__.py | 16 ++++++++++++++-- fast64_internal/z64/utility.py | 6 +++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index f06511915..84f7dec75 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -18,7 +18,12 @@ from .collision.properties import OOTCollisionExportSettings from .room.operators import room_ops_register, room_ops_unregister -from .room.properties import room_props_register, room_props_unregister, mm_room_props_register, mm_room_props_unregister +from .room.properties import ( + room_props_register, + room_props_unregister, + mm_room_props_register, + mm_room_props_unregister, +) from .actor.operators import actor_ops_register, actor_ops_unregister from .actor.properties import actor_props_register, actor_props_unregister diff --git a/fast64_internal/z64/room/properties/__init__.py b/fast64_internal/z64/room/properties/__init__.py index 8dc7f3296..cdf320ae9 100644 --- a/fast64_internal/z64/room/properties/__init__.py +++ b/fast64_internal/z64/room/properties/__init__.py @@ -1,2 +1,14 @@ -from .oot_props import OOTRoomHeaderProperty, OOTBGProperty, OOTAlternateRoomHeaderProperty, OOTObjectProperty, room_props_register, room_props_unregister -from .mm_props import MM_RoomHeaderProperty, MM_AlternateRoomHeaderProperty, mm_room_props_register, mm_room_props_unregister +from .oot_props import ( + OOTRoomHeaderProperty, + OOTBGProperty, + OOTAlternateRoomHeaderProperty, + OOTObjectProperty, + room_props_register, + room_props_unregister, +) +from .mm_props import ( + MM_RoomHeaderProperty, + MM_AlternateRoomHeaderProperty, + mm_room_props_register, + mm_room_props_unregister, +) diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 70911e48e..0408ebe64 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -1155,7 +1155,11 @@ def getObjectList( cond = obj.ootSplineProperty.splineType == splineType if parentObj is not None: - if emptyType == "Actor" and obj.ootEmptyType == "Room" and get_room_header_props(obj).roomIndex == room_index: + if ( + emptyType == "Actor" + and obj.ootEmptyType == "Room" + and get_room_header_props(obj).roomIndex == room_index + ): for o in obj.children_recursive: if o.type == objType and o.ootEmptyType == emptyType and o not in ret: ret.append(o) From da63e2e200acf46e31e4aec48f8fdcc4ce4fb701 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:18:54 +0100 Subject: [PATCH 013/126] implement room ui --- fast64_internal/z64/constants.py | 22 +- fast64_internal/z64/data/mm/data.py | 2 + fast64_internal/z64/data/mm/object_data.py | 47 ++ .../z64/data/mm/xml/ObjectList.xml | 653 ++++++++++++++++++ fast64_internal/z64/importer/room_header.py | 35 +- fast64_internal/z64/room/operators.py | 30 +- .../z64/room/properties/mm_props.py | 72 +- .../z64/room/properties/oot_props.py | 5 - fast64_internal/z64/utility.py | 8 + 9 files changed, 814 insertions(+), 60 deletions(-) create mode 100644 fast64_internal/z64/data/mm/object_data.py create mode 100644 fast64_internal/z64/data/mm/xml/ObjectList.xml diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index 1ceeec2a4..ed28877b3 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -34,6 +34,17 @@ ("0xFF", "Hops On Epona", "Hops On Epona"), ] +mm_enum_environvment_type = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "ROOM_ENV_DEFAULT"), + ("0x01", "Cold", "ROOM_ENV_COLD"), + ("0x02", "Warm", "ROOM_ENV_WARM"), + ("0x03", "Hot", "ROOM_ENV_HOT"), + ("0x04", "Unknown Stretch 1", "ROOM_ENV_UNK_STRETCH_1"), + ("0x05", "Unknown Stretch 2", "ROOM_ENV_UNK_STRETCH_2"), + ("0x06", "Unknown Stretch 3", "ROOM_ENV_UNK_STRETCH_3"), +] + ootEnumCloudiness = [ ("Custom", "Custom", "Custom"), ("0x00", "Sunny", "Sunny"), @@ -639,7 +650,7 @@ # ("0xFF", "0xFF", "0xFF"), ] -# see curRoom.behaviorType1 +# see RoomType enum ootEnumRoomBehaviour = [ ("Custom", "Custom", "Custom"), ("0x00", "Default", "Default"), @@ -650,6 +661,15 @@ ("0x05", "Disable Darker Screen Effect (NL/Spins)", "Disable Darker Screen Effect (NL/Spins)"), ] +mm_enum_room_type = [ + ("0x00", "Normal", "ROOM_TYPE_NORMAL"), + ("0x01", "Dungeon", "ROOM_TYPE_DUNGEON"), + ("0x02", "Indoors", "ROOM_TYPE_INDOORS"), + ("0x03", "Type 3", "ROOM_TYPE_3"), + ("0x04", "Type 4 (Horse related)", "ROOM_TYPE_4"), + ("0x05", "Boss", "ROOM_TYPE_BOSS"), +] + ootEnumDrawConfig = [ ("Custom", "Custom", "Custom"), ("SDC_DEFAULT", "Default", "Default"), diff --git a/fast64_internal/z64/data/mm/data.py b/fast64_internal/z64/data/mm/data.py index 4a3650ea0..0530df442 100644 --- a/fast64_internal/z64/data/mm/data.py +++ b/fast64_internal/z64/data/mm/data.py @@ -16,9 +16,11 @@ class MM_Data: def __init__(self): from .enum_data import MM_EnumData from .actor_data import MM_ActorData + from .object_data import MM_ObjectData self.enum_data = MM_EnumData() self.actor_data = MM_ActorData() + self.object_data = MM_ObjectData() self.enum_seq_id = [ ("Custom", "Custom", "Custom"), diff --git a/fast64_internal/z64/data/mm/object_data.py b/fast64_internal/z64/data/mm/object_data.py new file mode 100644 index 000000000..60eded1e6 --- /dev/null +++ b/fast64_internal/z64/data/mm/object_data.py @@ -0,0 +1,47 @@ +from dataclasses import dataclass +from os import path +from pathlib import Path +from .getters import get_xml_root +from .data import MM_BaseElement + +# Note: "object" in this context refers to an MM Object file (like `gameplay_keep`) + + +@dataclass +class MM_ObjectElement(MM_BaseElement): + pass + + +class MM_ObjectData: + """Everything related to MM objects""" + + def __init__(self): + # general object list + self.object_list: list[MM_ObjectElement] = [] + + # Path to the ``ObjectList.xml`` file + object_root = get_xml_root(Path(f"{path.dirname(path.abspath(__file__))}/xml/ObjectList.xml")) + + for obj in object_root.iterfind("Object"): + obj_name = f"{obj.attrib['Name']} - {obj.attrib['ID'].removeprefix('OBJECT_')}" + self.object_list.append( + MM_ObjectElement(obj.attrib["ID"], obj.attrib["Key"], obj_name, int(obj.attrib["Index"])) + ) + + self.objects_by_id = {obj.id: obj for obj in self.object_list} + self.objects_by_key = {obj.key: obj for obj in self.object_list} + + # list of tuples used by Blender's enum properties + self.deleted_entry = ("None", "(Deleted from the XML)", "None") + last_index = max(1, *(obj.index for obj in self.object_list)) + self.enum_object_key = self.get_object_id_list(last_index + 1) + + def get_object_id_list(self, max: int): + """Generates and returns the object list in the right order""" + objList = [self.deleted_entry] * max + for obj in self.object_list: + if obj.index < max: + identifier = obj.key + objList[obj.index] = (identifier, obj.name, obj.id) + objList[0] = ("Custom", "Custom Object", "Custom") + return objList diff --git a/fast64_internal/z64/data/mm/xml/ObjectList.xml b/fast64_internal/z64/data/mm/xml/ObjectList.xml new file mode 100644 index 000000000..6c06cc7ad --- /dev/null +++ b/fast64_internal/z64/data/mm/xml/ObjectList.xml @@ -0,0 +1,653 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 96ffe8b0f..c8e7c8a5a 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,10 +2,10 @@ import re from ...utility import hexOrDecInt -from ..utility import setCustomProperty, get_room_header_props +from ..utility import setCustomProperty, get_room_header_props, is_game_oot, get_game_enum from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty -from ..constants import oot_data, ootEnumLinkIdle, ootEnumRoomBehaviour +from ..constants import oot_data, mm_data from .utility import getDataMatch, stripName from .classes import SharedSceneData from .constants import headerNames @@ -13,13 +13,20 @@ from .room_shape import parseMeshHeader +def get_object_from_id(object: str): + if is_game_oot(): + return oot_data.objectData.objectsByID.get(object) + else: + return mm_data.object_data.objects_by_id.get(object) + + def parseObjectList(roomHeader: OOTRoomHeaderProperty, sceneData: str, objectListName: str): objectData = getDataMatch(sceneData, objectListName, "s16", "object list") objects = [value.strip() for value in objectData.split(",") if value.strip() != ""] for object in objects: objectProp = roomHeader.objectList.add() - objByID = oot_data.objectData.objectsByID.get(object) + objByID = get_object_from_id(object) if objByID is not None: objectProp.objectKey = objByID.key @@ -47,16 +54,21 @@ def parseRoomCommands( get_room_header_props(roomObj).roomIndex = roomIndex roomObj.name = roomName + if is_game_oot(): + cs_header_start = 4 + else: + cs_header_start = 1 + if headerIndex == 0: roomHeader = get_room_header_props(roomObj) - elif headerIndex < 4: + elif is_game_oot() and headerIndex < cs_header_start: roomHeader = getattr(get_room_header_props(roomObj, True), headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: cutsceneHeaders = get_room_header_props(roomObj, True).cutsceneHeaders - while len(cutsceneHeaders) < headerIndex - 3: + while len(cutsceneHeaders) < headerIndex - (cs_header_start - 1): cutsceneHeaders.add() - roomHeader = cutsceneHeaders[headerIndex - 4] + roomHeader = cutsceneHeaders[headerIndex - cs_header_start] commands = getDataMatch(sceneData, roomCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") for commandMatch in re.finditer(rf"(SCENE\_CMD\_[a-zA-Z0-9\_]*)\s*\((.*?)\)\s*,", commands, flags=re.DOTALL): @@ -68,10 +80,15 @@ def parseRoomCommands( elif command == "SCENE_CMD_ECHO_SETTINGS": roomHeader.echo = args[0] elif command == "SCENE_CMD_ROOM_BEHAVIOR": - setCustomProperty(roomHeader, "roomBehaviour", args[0], ootEnumRoomBehaviour) - setCustomProperty(roomHeader, "linkIdleMode", args[1], ootEnumLinkIdle) + setCustomProperty(roomHeader, "roomBehaviour", args[0], get_game_enum("enum_room_type")) + setCustomProperty(roomHeader, "linkIdleMode", args[1], get_game_enum("enum_env_type")) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" - roomHeader.disableWarpSongs = args[3] == "true" or args[3] == "1" + + if is_game_oot(): + roomHeader.disableWarpSongs = args[3] == "true" or args[3] == "1" + else: + roomHeader.enable_pos_lights = args[4] == "true" or args[4] == "1" + roomHeader.enable_storm = args[5] == "true" or args[5] == "1" elif command == "SCENE_CMD_SKYBOX_DISABLES": roomHeader.disableSkybox = args[0] == "true" or args[0] == "1" roomHeader.disableSunMoon = args[1] == "true" or args[1] == "1" diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index e25358a8f..8f686c15e 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, IntProperty, StringProperty from ...utility import ootGetSceneOrRoomHeader -from ..constants import oot_data +from ..constants import oot_data, mm_data class OOT_SearchObjectEnumOperator(Operator): @@ -29,7 +29,33 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} -classes = (OOT_SearchObjectEnumOperator,) +class MM_SearchObjectEnumOperator(Operator): + bl_idname = "object.mm_search_object_enum_operator" + bl_label = "Search Object ID" + bl_property = "object_key" + bl_options = {"REGISTER", "UNDO"} + + object_key: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") + header_index: IntProperty(default=0, min=0) + index: IntProperty(default=0, min=0) + obj_name: StringProperty() + + def execute(self, context): + roomHeader = ootGetSceneOrRoomHeader(bpy.data.objects[self.obj_name], self.header_index, True) + roomHeader.objectList[self.index].object_key = self.object_key + context.region.tag_redraw() + self.report({"INFO"}, "Selected: " + self.object_key) + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {"RUNNING_MODAL"} + + +classes = ( + OOT_SearchObjectEnumOperator, + MM_SearchObjectEnumOperator, +) def room_ops_register(): diff --git a/fast64_internal/z64/room/properties/mm_props.py b/fast64_internal/z64/room/properties/mm_props.py index d26613155..6a8352790 100644 --- a/fast64_internal/z64/room/properties/mm_props.py +++ b/fast64_internal/z64/room/properties/mm_props.py @@ -10,7 +10,7 @@ drawAddButton, is_game_oot, ) -from ..operators import OOT_SearchObjectEnumOperator +from ..operators import MM_SearchObjectEnumOperator from bpy.props import ( EnumProperty, @@ -24,11 +24,10 @@ ) from ...constants import ( - oot_data, - ootEnumRoomBehaviour, - ootEnumLinkIdle, + mm_data, + mm_enum_room_type, + mm_enum_environvment_type, ootEnumRoomShapeType, - ootEnumHeaderMenu, ) ootEnumRoomMenuAlternate = [ @@ -42,16 +41,12 @@ class MM_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") + objectKey: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") objectIDCustom: StringProperty(default="OBJECT_CUSTOM") def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): - isLegacy = True if "objectID" in self else False - - if isLegacy: - objectName = oot_data.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] - elif self.objectKey != "Custom": - objectName = oot_data.objectData.objectsByKey[self.objectKey].name + if self.objectKey != "Custom": + objectName = mm_data.object_data.objects_by_key[self.objectKey].name else: objectName = self.objectIDCustom @@ -59,10 +54,10 @@ def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: st row = objItemBox.row() row.label(text=f"{objectName}") buttons = row.row(align=True) - objSearch = buttons.operator(OOT_SearchObjectEnumOperator.bl_idname, icon="VIEWZOOM", text="Select") + objSearch = buttons.operator(MM_SearchObjectEnumOperator.bl_idname, icon="VIEWZOOM", text="Select") drawCollectionOps(buttons, index, "Object", headerIndex, objName, compact=True) - objSearch.objName = objName - objSearch.headerIndex = headerIndex if headerIndex is not None else 0 + objSearch.obj_name = objName + objSearch.header_index = headerIndex if headerIndex is not None else 0 objSearch.index = index if self.objectKey == "Custom": @@ -90,37 +85,40 @@ class MM_RoomHeaderProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") menuTab: EnumProperty(items=ootEnumRoomMenu, update=onMenuTabChange) altMenuTab: EnumProperty(items=ootEnumRoomMenuAlternate) - usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=ootEnumRoomBehaviour, default="0x00") + + # SCENE_CMD_ROOM_BEHAVIOR + roomBehaviour: EnumProperty(items=mm_enum_room_type, default="0x00") roomBehaviourCustom: StringProperty(default="0x00") - disableWarpSongs: BoolProperty(name="Disable Warp Songs") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Link Idle Mode", items=ootEnumLinkIdle, default="0x00") - linkIdleModeCustom: StringProperty(name="Link Idle Mode Custom", default="0x00") - roomIsHot: BoolProperty( - name="Use Hot Room Behavior", - description="Use heat timer/screen effect, overrides Link Idle Mode", - default=False, - ) + enable_pos_lights: BoolProperty(name="Enable Pos Lights") + enable_storm: BoolProperty(name="Enable Storm") + linkIdleMode: EnumProperty(name="Environment Type", items=mm_enum_environvment_type, default="0x00") + linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") + # SCENE_CMD_WIND_SETTINGS setWind: BoolProperty(name="Set Wind") windVector: IntVectorProperty(name="Wind Vector", size=3, min=-127, max=127) windStrength: IntProperty(name="Wind Strength", min=0, max=255) + # SCENE_CMD_TIME_SETTINGS leaveTimeUnchanged: BoolProperty(name="Leave Time Unchanged", default=True) timeHours: IntProperty(name="Hours", default=0, min=0, max=23) # 0xFFFE timeMinutes: IntProperty(name="Minutes", default=0, min=0, max=59) timeSpeed: FloatProperty(name="Time Speed", default=1, min=-13, max=13) # 0xA + # SCENE_CMD_SKYBOX_DISABLES disableSkybox: BoolProperty(name="Disable Skybox") disableSunMoon: BoolProperty(name="Disable Sun/Moon") + # SCENE_CMD_ECHO_SETTINGS echo: StringProperty(name="Echo", default="0x00") + # SCENE_CMD_OBJECT_LIST objectList: CollectionProperty(type=MM_ObjectProperty) + # SCENE_CMD_ROOM_SHAPE roomShape: EnumProperty(items=ootEnumRoomShapeType, default="ROOM_SHAPE_TYPE_NORMAL") defaultCullDistance: IntProperty(name="Default Cull Distance", min=1, default=100) bgImageList: CollectionProperty(type=MM_BGProperty) @@ -174,13 +172,15 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_game_oot(): general.label(text="This shape type is only implemented on MM", icon="INFO") + # Behaviour behaviourBox = layout.column() behaviourBox.box().label(text="Behaviour") - drawEnumWithCustom(behaviourBox, self, "roomBehaviour", "Room Behaviour", "") - drawEnumWithCustom(behaviourBox, self, "linkIdleMode", "Link Idle Mode", "") - behaviourBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") - behaviourBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") + drawEnumWithCustom(behaviourBox, self, "roomBehaviour", "Room Type", "") + drawEnumWithCustom(behaviourBox, self, "linkIdleMode", "Environment Type", "") + behaviourBox.prop(self, "showInvisibleActors") + behaviourBox.prop(self, "enable_pos_lights") + behaviourBox.prop(self, "enable_storm") # Time skyboxAndTime = layout.column() @@ -212,26 +212,12 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj # prop_split(windBox, self, "windVector", "Wind Vector") elif menuTab == "Objects": - upgradeLayout = layout.column() objBox = layout.column() objBox.box().label(text="Objects") - if len(self.objectList) > 16: - objBox.label(text="You are over the 16 object limit.", icon="ERROR") - objBox.label(text="You must allocate more memory in code.") - - isLegacy = False for i, objProp in enumerate(self.objectList): objProp.draw_props(objBox, headerIndex, i, objName) - if "objectID" in objProp: - isLegacy = True - - if isLegacy: - upgradeLayout.label(text="Legacy data has not been upgraded!") - upgradeLayout.operator(OOT_ManualUpgrade.bl_idname, text="Upgrade Data Now!") - objBox.enabled = False if isLegacy else True - drawAddButton(objBox, len(self.objectList), "Object", headerIndex, objName) diff --git a/fast64_internal/z64/room/properties/oot_props.py b/fast64_internal/z64/room/properties/oot_props.py index 73e2feb8c..5117f8681 100644 --- a/fast64_internal/z64/room/properties/oot_props.py +++ b/fast64_internal/z64/room/properties/oot_props.py @@ -105,11 +105,6 @@ class OOTRoomHeaderProperty(PropertyGroup): showInvisibleActors: BoolProperty(name="Show Invisible Actors") linkIdleMode: EnumProperty(name="Link Idle Mode", items=ootEnumLinkIdle, default="0x00") linkIdleModeCustom: StringProperty(name="Link Idle Mode Custom", default="0x00") - roomIsHot: BoolProperty( - name="Use Hot Room Behavior", - description="Use heat timer/screen effect, overrides Link Idle Mode", - default=False, - ) setWind: BoolProperty(name="Set Wind") windVector: IntVectorProperty(name="Wind Vector", size=3, min=-127, max=127) diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 0408ebe64..9f5ad1119 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -24,6 +24,10 @@ mm_enum_skybox, ootEnumCloudiness, ootEnumSkyboxLighting, + ootEnumLinkIdle, + ootEnumRoomBehaviour, + mm_enum_room_type, + mm_enum_environvment_type, ) from dataclasses import dataclass @@ -51,12 +55,16 @@ "enum_skybox": ootEnumSkybox, "enum_seq_id": oot_data.ootEnumMusicSeq, "enum_ambiance_id": oot_data.ootEnumNightSeq, # TODO: generate this from xml (not for enumproperties) + "enum_env_type": ootEnumLinkIdle, + "enum_room_type": ootEnumRoomBehaviour, }, "MM": { "enum_global_object": mm_enum_global_object, "enum_skybox": mm_enum_skybox, "enum_seq_id": mm_data.enum_seq_id, "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above + "enum_env_type": mm_enum_environvment_type, + "enum_room_type": mm_enum_room_type, }, } From 33bb03d4b9bb9f3c6b549d712ce6df7feee3b8c5 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:11:37 +0100 Subject: [PATCH 014/126] implement actors --- fast64_internal/z64/__init__.py | 9 +- fast64_internal/z64/actor/operators.py | 37 ++- .../z64/actor/properties/__init__.py | 17 ++ .../z64/actor/properties/mm_props.py | 247 ++++++++++++++++++ .../oot_props.py} | 17 +- .../z64/exporter/collision/waterbox.py | 4 +- fast64_internal/z64/exporter/room/__init__.py | 6 +- fast64_internal/z64/exporter/room/header.py | 4 +- fast64_internal/z64/exporter/room/shape.py | 4 +- .../z64/exporter/scene/__init__.py | 6 +- fast64_internal/z64/exporter/scene/actors.py | 16 +- fast64_internal/z64/exporter/scene/rooms.py | 4 +- fast64_internal/z64/importer/actor.py | 76 ++++-- fast64_internal/z64/importer/room_header.py | 10 +- fast64_internal/z64/importer/room_shape.py | 6 +- fast64_internal/z64/importer/scene.py | 4 +- fast64_internal/z64/importer/scene_header.py | 9 +- fast64_internal/z64/importer/utility.py | 20 +- fast64_internal/z64/props_panel_main.py | 24 +- .../z64/scene/properties/__init__.py | 1 + .../z64/scene/properties/mm_props.py | 2 +- fast64_internal/z64/spline/panels.py | 4 +- fast64_internal/z64/tools/operators.py | 14 +- fast64_internal/z64/upgrade.py | 12 +- fast64_internal/z64/utility.py | 118 +++++---- 25 files changed, 512 insertions(+), 159 deletions(-) create mode 100644 fast64_internal/z64/actor/properties/__init__.py create mode 100644 fast64_internal/z64/actor/properties/mm_props.py rename fast64_internal/z64/actor/{properties.py => properties/oot_props.py} (96%) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 84f7dec75..da0041623 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -26,7 +26,12 @@ ) from .actor.operators import actor_ops_register, actor_ops_unregister -from .actor.properties import actor_props_register, actor_props_unregister +from .actor.properties import ( + actor_props_register, + actor_props_unregister, + mm_actor_props_register, + mm_actor_props_unregister, +) from .f3d.operators import f3d_ops_register, f3d_ops_unregister from .f3d.properties import OOTDLExportSettings, OOTDLImportSettings, f3d_props_register, f3d_props_unregister @@ -176,6 +181,7 @@ def oot_register(registerPanels): mm_room_props_register() actor_ops_register() actor_props_register() + mm_actor_props_register() oot_obj_register() spline_props_register() f3d_props_register() @@ -218,6 +224,7 @@ def oot_unregister(unregisterPanels): mm_room_props_unregister() actor_ops_unregister() actor_props_unregister() + mm_actor_props_unregister() spline_props_unregister() f3d_props_unregister() anim_ops_unregister() diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 5d7d2458f..0f1cef187 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -3,7 +3,7 @@ from bpy.props import EnumProperty, StringProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError -from ..constants import oot_data +from ..constants import oot_data, mm_data class OOT_SearchActorIDEnumOperator(Operator): @@ -36,7 +36,40 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} -classes = (OOT_SearchActorIDEnumOperator,) +class MM_SearchActorIDEnumOperator(Operator): + bl_idname = "object.mm_search_actor_id_enum_operator" + bl_label = "Select Actor ID" + bl_property = "actorID" + bl_options = {"REGISTER", "UNDO"} + + actorID: EnumProperty(items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") + actorUser: StringProperty(default="Actor") + objName: StringProperty() + + def execute(self, context): + obj = bpy.data.objects[self.objName] + if self.actorUser == "Transition Actor": + obj.mm_transition_actor_property.actor.actorID = self.actorID + elif self.actorUser == "Actor": + obj.mm_actor_property.actorID = self.actorID + elif self.actorUser == "Entrance": + obj.ootEntrmm_entrance_propertyanceProperty.actor.actorID = self.actorID + else: + raise PluginError("Invalid actor user for search: " + str(self.actorUser)) + + context.region.tag_redraw() + self.report({"INFO"}, "Selected: " + self.actorID) + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {"RUNNING_MODAL"} + + +classes = ( + OOT_SearchActorIDEnumOperator, + MM_SearchActorIDEnumOperator, +) def actor_ops_register(): diff --git a/fast64_internal/z64/actor/properties/__init__.py b/fast64_internal/z64/actor/properties/__init__.py new file mode 100644 index 000000000..0f47efeaf --- /dev/null +++ b/fast64_internal/z64/actor/properties/__init__.py @@ -0,0 +1,17 @@ +from .oot_props import ( + OOTActorProperty, + OOTTransitionActorProperty, + OOTEntranceProperty, + OOTActorHeaderProperty, + actor_props_register, + actor_props_unregister, +) + +from .mm_props import ( + MM_ActorProperty, + MM_TransitionActorProperty, + MM_EntranceProperty, + MM_ActorHeaderProperty, + mm_actor_props_register, + mm_actor_props_unregister, +) diff --git a/fast64_internal/z64/actor/properties/mm_props.py b/fast64_internal/z64/actor/properties/mm_props.py new file mode 100644 index 000000000..9775fb099 --- /dev/null +++ b/fast64_internal/z64/actor/properties/mm_props.py @@ -0,0 +1,247 @@ +from bpy.types import Object, PropertyGroup, UILayout +from bpy.utils import register_class, unregister_class +from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty +from ....utility import prop_split, label_split +from ...constants import mm_data, ootEnumCamTransition +from ...upgrade import upgradeActors +from ...scene.properties import MM_AlternateSceneHeaderProperty +from ...room.properties import MM_AlternateRoomHeaderProperty +from ..operators import MM_SearchActorIDEnumOperator + +from ...utility import ( + getRoomObj, + getEnumName, + drawAddButton, + drawCollectionOps, + drawEnumWithCustom, +) + + +class MM_ActorHeaderItemProperty(PropertyGroup): + headerIndex: IntProperty(name="Scene Setup", min=1, default=1) + + def draw_props( + self, + layout: UILayout, + propUser: str, + index: int, + altProp: MM_AlternateSceneHeaderProperty | MM_AlternateRoomHeaderProperty, + objName: str, + ): + box = layout.column() + row = box.row() + row.prop(self, "headerIndex", text="") + + drawCollectionOps(row.row(align=True), index, propUser, None, objName, compact=True) + + if altProp is not None and self.headerIndex >= len(altProp.cutsceneHeaders) + 1: + box.label(text="Above header does not exist.", icon="QUESTION") + + +class MM_ActorHeaderProperty(PropertyGroup): + include_in_all_setups: BoolProperty(name="Include in all scene setups") + childDayHeader: BoolProperty(name="Child Day Header", default=True) + cutsceneHeaders: CollectionProperty(type=MM_ActorHeaderItemProperty) + expand_tab: BoolProperty(name="Expand Tab") + + def checkHeader(self, index: int) -> bool: + if index == 0: + return self.childDayHeader + else: + return index in [value.headerIndex for value in self.cutsceneHeaders] + + def draw_props( + self, + layout: UILayout, + propUser: str, + altProp: MM_AlternateSceneHeaderProperty | MM_AlternateRoomHeaderProperty, + objName: str, + ): + headerSetup = layout.column() + + header_settings_box = headerSetup.column().box() + header_settings_box.label(text="Header Settings") + header_settings_box.prop(self, "include_in_all_setups") + + if not self.include_in_all_setups: + header_settings_box.prop(self, "childDayHeader", text="Default Header") + + cs_header_box = header_settings_box.box() + cs_header_box.row().prop( + self, + "expand_tab", + text="Cutscene Headers", + icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT", + ) + + if self.expand_tab: + for i in range(len(self.cutsceneHeaders)): + headerItemProps: MM_ActorHeaderItemProperty = self.cutsceneHeaders[i] + headerItemProps.draw_props(cs_header_box, propUser, i, altProp, objName) + + drawAddButton(cs_header_box, len(self.cutsceneHeaders), propUser, None, objName) + + +class MM_ActorProperty(PropertyGroup): + actorID: EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") + actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") + actor_id_flags: StringProperty(name="Actor ID Flags", default="0x0000") + actorParam: StringProperty(name="Actor Parameter", default="0x0000") + rot_flags_x: StringProperty(name="Rot Flags X", default="0x0000") + rot_flags_y: StringProperty(name="Rot Flags Y", default="0x0000") + rot_flags_z: StringProperty(name="Rot Flags Z", default="0x0000") + rotOverride: BoolProperty(name="Override Rotation", default=False) + rotOverrideX: StringProperty(name="Rot X", default="0") + rotOverrideY: StringProperty(name="Rot Y", default="0") + rotOverrideZ: StringProperty(name="Rot Z", default="0") + headerSettings: PointerProperty(type=MM_ActorHeaderProperty) + + def draw_settings(self, layout: UILayout): + prop_split(layout, self, "actorParam", "Actor Parameter") + + flag_box = layout.box() + prop_split(flag_box, self, "actor_id_flags", "Actor ID Flags") + prop_split(flag_box, self, "rot_flags_x", "Rot Flags X") + prop_split(flag_box, self, "rot_flags_y", "Rot Flags Y") + prop_split(flag_box, self, "rot_flags_z", "Rot Flags Z") + + def draw_props(self, layout: UILayout, altRoomProp: MM_AlternateRoomHeaderProperty, objName: str): + actorIDBox = layout.column() + searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") + searchOp.actorUser = "Actor" + searchOp.objName = objName + + split = actorIDBox.split(factor=0.5) + + if self.actorID == "None": + actorIDBox.box().label(text="This Actor was deleted from the XML file.") + return + + split.label(text="Actor ID") + split.label(text=getEnumName(mm_data.actor_data.enum_actor_id, self.actorID)) + + if self.actorID == "Custom": + prop_split(actorIDBox, self, "actorIDCustom", "") + + self.draw_settings(actorIDBox) + + actorIDBox.prop(self, "rotOverride", text="Override Rotation (ignore Blender rot)") + if self.rotOverride: + prop_split(actorIDBox, self, "rotOverrideX", "Rot X") + prop_split(actorIDBox, self, "rotOverrideY", "Rot Y") + prop_split(actorIDBox, self, "rotOverrideZ", "Rot Z") + + headerProp: MM_ActorHeaderProperty = self.headerSettings + headerProp.draw_props(actorIDBox, "Actor", altRoomProp, objName) + + +class MM_TransitionActorProperty(PropertyGroup): + fromRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) + toRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) + cameraTransitionFront: EnumProperty(items=ootEnumCamTransition, default="0x00") + cameraTransitionFrontCustom: StringProperty(default="0x00") + cameraTransitionBack: EnumProperty(items=ootEnumCamTransition, default="0x00") + cameraTransitionBackCustom: StringProperty(default="0x00") + isRoomTransition: BoolProperty(name="Is Room Transition", default=True) + + actor: PointerProperty(type=MM_ActorProperty) + + def isRoomEmptyObject(self, obj: Object): + return obj.type == "EMPTY" and obj.ootEmptyType == "Room" + + def draw_props( + self, layout: UILayout, altSceneProp: MM_AlternateSceneHeaderProperty, roomObj: Object, objName: str + ): + actorIDBox = layout.column() + searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") + searchOp.actorUser = "Transition Actor" + searchOp.objName = objName + + split = actorIDBox.split(factor=0.5) + split.label(text="Actor ID") + split.label(text=getEnumName(mm_data.actor_data.enum_actor_id, self.actor.actorID)) + + if self.actor.actorID == "Custom": + prop_split(actorIDBox, self.actor, "actorIDCustom", "") + + prop_split(actorIDBox, self.actor, "actorParam", "Actor Parameter") + + if roomObj is None: + actorIDBox.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") + else: + actorIDBox.prop(self, "isRoomTransition") + if self.isRoomTransition: + prop_split(actorIDBox, self, "fromRoom", "Room To Transition From") + prop_split(actorIDBox, self, "toRoom", "Room To Transition To") + if self.fromRoom == self.toRoom: + actorIDBox.label(text="Warning: You selected the same room!", icon="ERROR") + actorIDBox.label(text='Y+ side of door faces toward the "from" room.', icon="ORIENTATION_NORMAL") + drawEnumWithCustom(actorIDBox, self, "cameraTransitionFront", "Camera Transition Front", "") + drawEnumWithCustom(actorIDBox, self, "cameraTransitionBack", "Camera Transition Back", "") + + headerProps: MM_ActorHeaderProperty = self.actor.headerSettings + headerProps.draw_props(actorIDBox, "Transition Actor", altSceneProp, objName) + + +class MM_EntranceProperty(PropertyGroup): + # This is also used in entrance list. + spawnIndex: IntProperty(min=0) + customActor: BoolProperty(name="Use Custom Actor") + actor: PointerProperty(type=MM_ActorProperty) + + tiedRoom: PointerProperty( + type=Object, + poll=lambda self, object: self.isRoomEmptyObject(object), + description="Used to set the room index", + ) + + def isRoomEmptyObject(self, obj: Object): + return obj.type == "EMPTY" and obj.ootEmptyType == "Room" + + def draw_props(self, layout: UILayout, obj: Object, altSceneProp: MM_AlternateSceneHeaderProperty, objName: str): + box = layout.column() + + roomObj = getRoomObj(obj) + if roomObj is None: + box.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") + + entranceProp = obj.mm_entrance_property + box.prop(entranceProp, "customActor") + + if entranceProp.customActor: + prop_split(box, entranceProp.actor, "actorIDCustom", "Actor ID Custom") + + prop_split(box, entranceProp, "tiedRoom", "Room") + prop_split(box, entranceProp, "spawnIndex", "Spawn Index") + + entranceProp.actor.draw_settings(box) + + headerProps: MM_ActorHeaderProperty = entranceProp.actor.headerSettings + headerProps.draw_props(box, "Entrance", altSceneProp, objName) + + +classes = ( + MM_ActorHeaderItemProperty, + MM_ActorHeaderProperty, + MM_ActorProperty, + MM_TransitionActorProperty, + MM_EntranceProperty, +) + + +def mm_actor_props_register(): + for cls in classes: + register_class(cls) + + Object.mm_actor_property = PointerProperty(type=MM_ActorProperty) + Object.mm_transition_actor_property = PointerProperty(type=MM_TransitionActorProperty) + Object.mm_entrance_property = PointerProperty(type=MM_EntranceProperty) + + +def mm_actor_props_unregister(): + del Object.mm_actor_property + del Object.mm_transition_actor_property + del Object.mm_entrance_property + + for cls in reversed(classes): + unregister_class(cls) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties/oot_props.py similarity index 96% rename from fast64_internal/z64/actor/properties.py rename to fast64_internal/z64/actor/properties/oot_props.py index 6cc227872..d825a2470 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties/oot_props.py @@ -1,14 +1,14 @@ from bpy.types import Object, PropertyGroup, UILayout from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty -from ...utility import prop_split, label_split -from ..constants import oot_data, ootEnumCamTransition -from ..upgrade import upgradeActors -from ..scene.properties import OOTAlternateSceneHeaderProperty -from ..room.properties import OOTAlternateRoomHeaderProperty -from .operators import OOT_SearchActorIDEnumOperator - -from ..utility import ( +from ....utility import prop_split, label_split +from ...constants import oot_data, ootEnumCamTransition +from ...upgrade import upgradeActors +from ...scene.properties import OOTAlternateSceneHeaderProperty +from ...room.properties import OOTAlternateRoomHeaderProperty +from ..operators import OOT_SearchActorIDEnumOperator + +from ...utility import ( getRoomObj, getEnumName, drawAddButton, @@ -25,7 +25,6 @@ class OOTActorHeaderItemProperty(PropertyGroup): headerIndex: IntProperty(name="Scene Setup", min=4, default=4) - expandTab: BoolProperty(name="Expand Tab") def draw_props( self, diff --git a/fast64_internal/z64/exporter/collision/waterbox.py b/fast64_internal/z64/exporter/collision/waterbox.py index a5c90eeff..b23f208e6 100644 --- a/fast64_internal/z64/exporter/collision/waterbox.py +++ b/fast64_internal/z64/exporter/collision/waterbox.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from mathutils import Matrix from bpy.types import Object -from ...utility import getObjectList, get_room_header_props +from ...utility import getObjectList, get_game_props from ....utility import CData, checkIdentityRotation, indent from ..utility import Utility @@ -121,7 +121,7 @@ def new(name: str, dataHolder: Object, transform: Matrix, useMacros: bool): emptyScale, wboxProp.camera, wboxProp.lighting, - get_room_header_props(roomObj).roomIndex if roomObj is not None else 0x3F, + get_game_props(roomObj, "room").roomIndex if roomObj is not None else 0x3F, wboxProp.flag19, useMacros, ) diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index 449285bb1..db29845b7 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings -from ...utility import get_room_header_props +from ...utility import get_game_props from ...room.properties import OOTRoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -38,9 +38,9 @@ def new( saveTexturesAsPNG: bool, ): i = 0 - mainHeaderProps = get_room_header_props(roomObj) + mainHeaderProps = get_game_props(roomObj, "room") altHeader = RoomAlternateHeader(f"{name}_alternateHeaders") - altProp = get_room_header_props(roomObj, True) + altProp = get_game_props(roomObj, "alt_room") if mainHeaderProps.roomShape == "ROOM_SHAPE_TYPE_IMAGE" and len(mainHeaderProps.bgImageList) == 0: raise PluginError(f'Room {roomObj.name} uses room shape "Image" but doesn\'t have any BG images.') diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 4a02ccb8e..a66a88933 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData, indent -from ...utility import getObjectList +from ...utility import getObjectList, get_game_props from ...constants import oot_data from ...room.properties import OOTRoomHeaderProperty from ..utility import Utility @@ -148,7 +148,7 @@ def new( actorList: list[Actor] = [] actorObjList = getObjectList(sceneObj.children, "EMPTY", "Actor", parentObj=roomObj, room_index=room_index) for obj in actorObjList: - actorProp = obj.ootActorProperty + actorProp = get_game_props(obj, "actor") if not Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex): continue diff --git a/fast64_internal/z64/exporter/room/shape.py b/fast64_internal/z64/exporter/room/shape.py index 18febf8f5..e1fd0f37f 100644 --- a/fast64_internal/z64/exporter/room/shape.py +++ b/fast64_internal/z64/exporter/room/shape.py @@ -18,7 +18,7 @@ CullGroup, checkUniformScale, ootConvertTranslation, - get_room_header_props, + get_game_props, ) @@ -545,7 +545,7 @@ def create_shape( room_shape.bg_entries.append(RoomShapeImageEntry.new(scene_name, bg_image)) pos, _, scale, _ = Utility.getConvertedTransform(transform, sceneObj, roomObj, True) - cull_group = CullGroup(pos, scale, get_room_header_props(roomObj).defaultCullDistance) + cull_group = CullGroup(pos, scale, get_game_props(roomObj, "room").defaultCullDistance) dl_entry = room_shape.add_dl_entry(cull_group) boundingBox = BoundingBox() ootProcessMesh( diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 038e54cea..f4d42b8f6 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -6,7 +6,7 @@ from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import OOTSceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter -from ...utility import get_scene_header_props +from ...utility import get_game_props from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -43,11 +43,11 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex ) mainHeader = SceneHeader.new( - f"{name}_header{i:02}", get_scene_header_props(sceneObj), sceneObj, transform, i, useMacros + f"{name}_header{i:02}", get_game_props(sceneObj, "scene"), sceneObj, transform, i, useMacros ) hasAlternateHeaders = False altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") - altProp = get_scene_header_props(sceneObj, True) + altProp = get_game_props(sceneObj, "alt_scene") for i, header in enumerate(altHeaderList, 1): altP: OOTSceneHeaderProperty = getattr(altProp, f"{header}Header") diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 9383cb88b..007320385 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, get_room_header_props +from ...utility import getObjectList, get_game_props from ...constants import oot_data from ..utility import Utility from ..actor import Actor @@ -54,11 +54,11 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): actorToRoom[childObj] = obj actorObjList = getObjectList(sceneObj.children_recursive, "EMPTY", "Transition Actor") - actorObjList.sort(key=lambda obj: get_room_header_props(actorToRoom[obj]).roomIndex) + actorObjList.sort(key=lambda obj: get_game_props(actorToRoom[obj], "room").roomIndex) entries: list[TransitionActor] = [] for obj in actorObjList: - transActorProp = obj.ootTransitionActorProperty + transActorProp = get_game_props(obj, "transition_actor") if ( Utility.isCurrentHeaderValid(transActorProp.actor.headerSettings, headerIndex) and transActorProp.actor.actorID != "None" @@ -69,10 +69,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if transActorProp.isRoomTransition: if transActorProp.fromRoom is None or transActorProp.toRoom is None: raise PluginError("ERROR: Missing room empty object assigned to transition.") - fromIndex = get_room_header_props(transActorProp.fromRoom).roomIndex - toIndex = get_room_header_props(transActorProp.toRoom).roomIndex + fromIndex = get_game_props(transActorProp.fromRoom, "room").roomIndex + toIndex = get_game_props(transActorProp.toRoom, "room").roomIndex else: - fromIndex = toIndex = get_room_header_props(actorToRoom[obj]).roomIndex + fromIndex = toIndex = get_game_props(actorToRoom[obj], "room").roomIndex front = (fromIndex, Utility.getPropValue(transActorProp, "cameraTransitionFront")) back = (toIndex, Utility.getPropValue(transActorProp, "cameraTransitionBack")) @@ -144,7 +144,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActorFromIndex: dict[int, EntranceActor] = {} actorObjList = getObjectList(sceneObj.children_recursive, "EMPTY", "Entrance") for obj in actorObjList: - entranceProp = obj.ootEntranceProperty + entranceProp = get_game_props(obj, "entrance_actor") if ( Utility.isCurrentHeaderValid(entranceProp.actor.headerSettings, headerIndex) and entranceProp.actor.actorID != "None" @@ -165,7 +165,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) entranceActor.params = entranceProp.actor.actorParam if entranceProp.tiedRoom is not None: - entranceActor.roomIndex = get_room_header_props(entranceProp.tiedRoom).roomIndex + entranceActor.roomIndex = get_game_props(entranceProp.tiedRoom, "room").roomIndex else: raise PluginError("ERROR: Missing room empty object assigned to the entrance.") entranceActor.spawnIndex = entranceProp.spawnIndex diff --git a/fast64_internal/z64/exporter/scene/rooms.py b/fast64_internal/z64/exporter/scene/rooms.py index bcd9a0cfe..d2b78047a 100644 --- a/fast64_internal/z64/exporter/scene/rooms.py +++ b/fast64_internal/z64/exporter/scene/rooms.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, get_room_header_props +from ...utility import getObjectList, get_game_props from ...model_classes import OOTModel from ..room import Room @@ -23,7 +23,7 @@ def new(name: str, sceneName: str, model: OOTModel, sceneObj: Object, transform: raise PluginError("ERROR: The scene has no child empties with the 'Room' empty type.") for roomObj in roomObjs: - roomHeader = get_room_header_props(roomObj) + roomHeader = get_game_props(roomObj, "room") roomIndex = roomHeader.roomIndex if roomIndex in roomDict: diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 8d3ce031e..e81007274 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,8 +3,8 @@ from ...utility import parentObject, hexOrDecInt from ..scene.properties import OOTSceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams, get_room_header_props -from ..constants import ootEnumCamTransition, oot_data +from ..utility import setCustomProperty, getEvalParams, get_game_props, is_game_oot, get_game_enum +from ..constants import ootEnumCamTransition from .classes import SharedSceneData from .constants import actorsWithRotAsParam @@ -58,7 +58,7 @@ def parseTransActorList( actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) actorObj.ootEmptyType = "Transition Actor" actorObj.name = "Transition " + getDisplayNameFromActorID(params[4]) - transActorProp = actorObj.ootTransitionActorProperty + transActorProp = get_game_props(actorObj, "transition_actor") sharedSceneData.transDict[actorHash] = actorObj @@ -77,7 +77,7 @@ def parseTransActorList( setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition) actorProp = transActorProp.actor - setCustomProperty(actorProp, "actorID", actorID, oot_data.actorData.ootEnumActorID) + setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -104,28 +104,57 @@ def parseEntranceList( return entrances -def parseActorInfo(actorMatch: re.Match, nestedBrackets: bool) -> tuple[str, list[int], list[int], str]: +def parseActorInfo( + actorMatch: re.Match, nestedBrackets: bool +) -> tuple[str, str, list[int], tuple[int], tuple[int], str]: + spawn_flags = ["0x0000"] * 3 + actor_id_flags = "0x0000" + if nestedBrackets: actorID = actorMatch.group(1).strip() position = tuple( [hexOrDecInt(value.strip()) for value in actorMatch.group(2).split(",") if value.strip() != ""] ) - rotation = tuple( - [ - hexOrDecInt(getEvalParams(value.strip())) - for value in actorMatch.group(3).split(",") - if value.strip() != "" - ] - ) + + if is_game_oot(): + spawn_rotation = tuple( + [ + hexOrDecInt(getEvalParams(value.strip())) + for value in actorMatch.group(3).split(",") + if value.strip() != "" + ] + ) + else: + if "|" in actorID: + split = actorID.split(" | ") + actorID = split[0] + actor_id_flags = split[1] + + spawn_rotation = [] + spawn_flags = [] + for value in actorMatch.group(3).replace(" ", "").replace("\n", "").split("SPAWN_ROT_FLAGS"): + if value != "": + rot, flags = value.removeprefix("(").removesuffix(",").removesuffix(")").split(",") + spawn_rotation.append(hexOrDecInt(getEvalParams(rot))) + spawn_flags.append(flags) + actorParam = actorMatch.group(4).strip() else: params = [getEvalParams(value.strip()) for value in actorMatch.group(1).split(",")] actorID = params[0] position = tuple([hexOrDecInt(value) for value in params[1:4]]) - rotation = tuple([hexOrDecInt(value) for value in params[4:7]]) + spawn_rotation = tuple([hexOrDecInt(value) for value in params[4:7]]) actorParam = params[7] - return actorID, position, rotation, actorParam + return actorID, actor_id_flags, position, tuple(spawn_rotation), tuple(spawn_flags), actorParam + + +def set_actor_flags(actor_prop, actor_id_flags: str, spawn_flags: tuple[str, str, str]): + if not is_game_oot(): + actor_prop.actor_id_flags = actor_id_flags + actor_prop.rot_flags_x = spawn_flags[0] + actor_prop.rot_flags_y = spawn_flags[1] + actor_prop.rot_flags_z = spawn_flags[2] def parseSpawnList( @@ -141,7 +170,9 @@ def parseSpawnList( index = 0 regex, nestedBrackets = getActorRegex(spawnList) for spawnMatch in re.finditer(regex, spawnList, flags=re.DOTALL): - actorID, position, rotation, actorParam = parseActorInfo(spawnMatch, nestedBrackets) + actorID, actor_id_flags, position, rotation, spawn_flags, actorParam = parseActorInfo( + spawnMatch, nestedBrackets + ) spawnIndex, roomIndex = [value for value in entranceList if value[0] == index][0] actorHash = (actorID, position, rotation, actorParam, spawnIndex, roomIndex) @@ -149,12 +180,13 @@ def parseSpawnList( spawnObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) spawnObj.ootEmptyType = "Entrance" spawnObj.name = "Entrance" - spawnProp = spawnObj.ootEntranceProperty + spawnProp = get_game_props(spawnObj, "entrance_actor") spawnProp.tiedRoom = roomObjs[roomIndex] spawnProp.spawnIndex = spawnIndex spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor - setCustomProperty(actorProp, "actorID", actorID, oot_data.actorData.ootEnumActorID) + set_actor_flags(actorProp, actor_id_flags, spawn_flags) + setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -182,17 +214,17 @@ def parseActorList( regex, nestedBrackets = getActorRegex(actorList) for actorMatch in re.finditer(regex, actorList, flags=re.DOTALL): - actorHash = parseActorInfo(actorMatch, nestedBrackets) + (get_room_header_props(roomObj).roomIndex,) + actorHash = parseActorInfo(actorMatch, nestedBrackets) + (get_game_props(roomObj, "room").roomIndex,) if not sharedSceneData.addHeaderIfItemExists(actorHash, "Actor", headerIndex): - actorID, position, rotation, actorParam, roomIndex = actorHash + actorID, actor_id_flags, position, rotation, spawn_flags, actorParam, roomIndex = actorHash actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) actorObj.ootEmptyType = "Actor" actorObj.name = getDisplayNameFromActorID(actorID) - actorProp = actorObj.ootActorProperty - - setCustomProperty(actorProp, "actorID", actorID, oot_data.actorData.ootEnumActorID) + actorProp = get_game_props(actorObj, "actor") + set_actor_flags(actorProp, actor_id_flags, spawn_flags) + setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index c8e7c8a5a..90ea22741 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,7 @@ import re from ...utility import hexOrDecInt -from ..utility import setCustomProperty, get_room_header_props, is_game_oot, get_game_enum +from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty from ..constants import oot_data, mm_data @@ -51,7 +51,7 @@ def parseRoomCommands( roomObj.empty_display_type = "SPHERE" roomObj.location = [0, 0, (roomIndex + 1) * -2] roomObj.ootEmptyType = "Room" - get_room_header_props(roomObj).roomIndex = roomIndex + get_game_props(roomObj, "room").roomIndex = roomIndex roomObj.name = roomName if is_game_oot(): @@ -60,12 +60,12 @@ def parseRoomCommands( cs_header_start = 1 if headerIndex == 0: - roomHeader = get_room_header_props(roomObj) + roomHeader = get_game_props(roomObj, "room") elif is_game_oot() and headerIndex < cs_header_start: - roomHeader = getattr(get_room_header_props(roomObj, True), headerNames[headerIndex]) + roomHeader = getattr(get_game_props(roomObj, "alt_room"), headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: - cutsceneHeaders = get_room_header_props(roomObj, True).cutsceneHeaders + cutsceneHeaders = get_game_props(roomObj, "alt_room").cutsceneHeaders while len(cutsceneHeaders) < headerIndex - (cs_header_start - 1): cutsceneHeaders.add() roomHeader = cutsceneHeaders[headerIndex - cs_header_start] diff --git a/fast64_internal/z64/importer/room_shape.py b/fast64_internal/z64/importer/room_shape.py index 389ea28af..c46a6a51b 100644 --- a/fast64_internal/z64/importer/room_shape.py +++ b/fast64_internal/z64/importer/room_shape.py @@ -8,7 +8,7 @@ from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty from ..constants import ootEnumRoomShapeType -from ..utility import get_room_header_props +from ..utility import get_game_props from .classes import SharedSceneData from .utility import getDataMatch, stripName @@ -20,7 +20,7 @@ def parseMeshHeader( f3dContext: OOTF3DContext, sharedSceneData: SharedSceneData, ): - roomHeader = get_room_header_props(roomObj) + roomHeader = get_game_props(roomObj, "room") meshData = getDataMatch(sceneData, meshHeaderName, "", "mesh header", False) meshData = meshData.replace("{", "").replace("}", "") @@ -79,7 +79,7 @@ def parseMeshList( f3dContext: OOTF3DContext, sharedSceneData: SharedSceneData, ): - roomHeader = get_room_header_props(roomObj) + roomHeader = get_game_props(roomObj, "room") meshEntryData = getDataMatch(sceneData, meshListName, "", "mesh list", roomShape != 1) if roomShape == 2: diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index d148bdbd7..869a569de 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -22,7 +22,7 @@ ootGetPath, setAllActorsVisibility, is_game_oot, - get_scene_header_props, + get_game_props, ) @@ -171,7 +171,7 @@ def parseScene( if not settings.isCustomDest: setCustomProperty( - get_scene_header_props(sceneObj).sceneTableEntry, + get_game_props(sceneObj, "scene").sceneTableEntry, "drawConfig", SceneTableUtility.get_draw_config(sceneName), ootEnumDrawConfig if is_game_oot() else mm_enum_draw_config, diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 4a32e4caf..65403d6bd 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -12,9 +12,8 @@ getEvalParams, setCustomProperty, get_game_enum, - get_scene_header_props, + get_game_props, is_game_oot, - convertIntTo2sComplement, ) from .constants import headerNames from .utility import getDataMatch, stripName @@ -309,12 +308,12 @@ def parseSceneCommands( cs_header_start = 1 if headerIndex == 0: - sceneHeader = get_scene_header_props(sceneObj) + sceneHeader = get_game_props(sceneObj, "scene") elif is_game_oot() and headerIndex < cs_header_start: - sceneHeader = getattr(get_scene_header_props(sceneObj, True), headerNames[headerIndex]) + sceneHeader = getattr(get_game_props(sceneObj, "alt_scene"), headerNames[headerIndex]) sceneHeader.usePreviousHeader = False else: - cutsceneHeaders = get_scene_header_props(sceneObj, True).cutsceneHeaders + cutsceneHeaders = get_game_props(sceneObj, "alt_scene").cutsceneHeaders while len(cutsceneHeaders) < headerIndex - (cs_header_start - 1): cutsceneHeaders.add() sceneHeader = cutsceneHeaders[headerIndex - cs_header_start] diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index e154c9413..094054edf 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -3,8 +3,8 @@ import mathutils from ...utility import PluginError, hexOrDecInt, removeComments, yUpToZUp -from ..actor.properties import OOTActorProperty, OOTActorHeaderProperty -from ..utility import ootParseRotation +from ..actor.properties import OOTActorProperty, OOTActorHeaderProperty, MM_ActorHeaderProperty +from ..utility import ootParseRotation, is_game_oot from .constants import headerNames, actorsWithRotAsParam @@ -16,12 +16,18 @@ def getBits(value: int, index: int, size: int) -> int: return ((1 << size) - 1) & (value >> index) -def unsetAllHeadersExceptSpecified(headerSettings: OOTActorHeaderProperty, headerIndex: int): - headerSettings.sceneSetupPreset = "Custom" - for i in range(len(headerNames)): - setattr(headerSettings, headerNames[i], i == headerIndex) +def unsetAllHeadersExceptSpecified(headerSettings: OOTActorHeaderProperty | MM_ActorHeaderProperty, headerIndex: int): + if is_game_oot(): + headerSettings.sceneSetupPreset = "Custom" - if headerIndex >= 4: + for i in range(len(headerNames)): + setattr(headerSettings, headerNames[i], i == headerIndex) + else: + headerSettings.include_in_all_setups = False + headerSettings.childDayHeader = headerIndex == 0 + + cs_start = 4 if is_game_oot() else 1 + if headerIndex >= cs_start: headerSettings.cutsceneHeaders.add().headerIndex = headerIndex diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 7902a0c90..89583d0db 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj, get_scene_header_props, get_room_header_props +from .utility import getSceneObj, getRoomObj, get_game_props from .scene.properties import OOTSceneProperties from .room.properties import OOTObjectProperty, OOTRoomHeaderProperty, OOTAlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -43,10 +43,10 @@ def drawSceneHeader(box: bpy.types.UILayout, obj: bpy.types.Object): objName = obj.name - props = get_scene_header_props(obj) + props = get_game_props(obj, "scene") props.draw_props(box, None, None, objName) if props.menuTab == "Alternate": - alt_props = get_scene_header_props(obj, True) + alt_props = get_game_props(obj, "alt_scene") alt_props.draw_props(box, objName) box.prop(obj.fast64.oot.scene, "write_dummy_room_list") @@ -81,7 +81,7 @@ def onUpdateOOTEmptyType(self, context): if isSphereEmpty: self.empty_display_type = "SPHERE" - header_props = get_scene_header_props(self) + header_props = get_game_props(self, "scene") if self.ootEmptyType == "Scene": if len(header_props.lightList) == 0: @@ -136,15 +136,15 @@ def draw(self, context): sceneObj = getSceneObj(obj) roomObj = getRoomObj(obj) - altSceneProp = get_scene_header_props(sceneObj, True) if sceneObj is not None else None - altRoomProp = get_room_header_props(roomObj, True) if roomObj is not None else None + altSceneProp = get_game_props(sceneObj, "alt_scene") if sceneObj is not None else None + altRoomProp = get_game_props(roomObj, "alt_room") if roomObj is not None else None if obj.ootEmptyType == "Actor": - actorProp: OOTActorProperty = obj.ootActorProperty + actorProp: OOTActorProperty = get_game_props(obj, "actor") actorProp.draw_props(box, altRoomProp, objName) elif obj.ootEmptyType == "Transition Actor": - transActorProp: OOTTransitionActorProperty = obj.ootTransitionActorProperty + transActorProp: OOTTransitionActorProperty = get_game_props(obj, "transition_actor") transActorProp.draw_props(box, altSceneProp, roomObj, objName) elif obj.ootEmptyType == "Water Box": @@ -155,14 +155,14 @@ def draw(self, context): drawSceneHeader(box, obj) elif obj.ootEmptyType == "Room": - roomProp: OOTRoomHeaderProperty = get_room_header_props(obj) + roomProp: OOTRoomHeaderProperty = get_game_props(obj, "room") roomProp.draw_props(box, None, None, objName) - if get_room_header_props(obj).menuTab == "Alternate": - roomAltProp: OOTAlternateRoomHeaderProperty = get_room_header_props(obj, True) + if get_game_props(obj, "room").menuTab == "Alternate": + roomAltProp: OOTAlternateRoomHeaderProperty = get_game_props(obj, "alt_room") roomAltProp.draw_props(box, objName) elif obj.ootEmptyType == "Entrance": - entranceProp: OOTEntranceProperty = obj.ootEntranceProperty + entranceProp: OOTEntranceProperty = get_game_props(obj, "entrance_actor") entranceProp.draw_props(box, obj, altSceneProp, objName) elif obj.ootEmptyType == "Cull Group": diff --git a/fast64_internal/z64/scene/properties/__init__.py b/fast64_internal/z64/scene/properties/__init__.py index a2f12f400..659d12af2 100644 --- a/fast64_internal/z64/scene/properties/__init__.py +++ b/fast64_internal/z64/scene/properties/__init__.py @@ -13,6 +13,7 @@ from .mm_props import ( MM_SceneHeaderProperty, + MM_AlternateSceneHeaderProperty, MM_ExportSceneSettingsProperty, MM_ImportSceneSettingsProperty, MM_RemoveSceneSettingsProperty, diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py index f55fb560b..a9d412da4 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -258,7 +258,7 @@ class OOTExtraCutsceneProperty(PropertyGroup): def minimap_chest_poll(self: "MM_MinimapChestProperty", object: Object): return ( - object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" + object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.mm_actor_property.actorID == "ACTOR_EN_BOX" ) diff --git a/fast64_internal/z64/spline/panels.py b/fast64_internal/z64/spline/panels.py index ed7ffb833..456d1ca2c 100644 --- a/fast64_internal/z64/spline/panels.py +++ b/fast64_internal/z64/spline/panels.py @@ -1,6 +1,6 @@ from bpy.types import Panel, Curve from bpy.utils import register_class, unregister_class -from ..utility import getSceneObj, get_scene_header_props +from ..utility import getSceneObj, get_game_props from .properties import OOTSplineProperty @@ -26,7 +26,7 @@ def draw(self, context): box.label(text="Only NURBS curves are compatible.") else: sceneObj = getSceneObj(context.object) - altSceneProp = get_scene_header_props(sceneObj, True) if sceneObj is not None else None + altSceneProp = get_game_props(sceneObj, "alt_scene") if sceneObj is not None else None splineProp: OOTSplineProperty = context.object.ootSplineProperty splineProp.draw_props(box, altSceneProp, context.object.name) diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index b2fb9630c..365637b9a 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -7,7 +7,7 @@ from ...operators import AddWaterBox, addMaterialByName from ...utility import parentObject, setOrigin from ..cutscene.motion.utility import setupCutscene, createNewCameraShot -from ..utility import getNewPath, get_room_header_props +from ..utility import getNewPath, get_game_props from .quick_import import QuickImportAborted, quick_import_exec @@ -54,8 +54,8 @@ def execute(self, context): emptyObj = context.view_layer.objects.active emptyObj.ootEmptyType = "Transition Actor" emptyObj.name = "Door Actor" - emptyObj.ootTransitionActorProperty.actor.actorID = "ACTOR_DOOR_SHUTTER" - emptyObj.ootTransitionActorProperty.actor.actorParam = "0x0000" + get_game_props(emptyObj, "transition_actor").actor.actorID = "ACTOR_DOOR_SHUTTER" + get_game_props(emptyObj, "transition_actor").actor.actorParam = "0x0000" parentObject(cubeObj, emptyObj) @@ -89,7 +89,7 @@ def execute(self, context): entranceObj = context.view_layer.objects.active entranceObj.ootEmptyType = "Entrance" entranceObj.name = "Entrance" - entranceObj.ootEntranceProperty.actor.actorParam = "0x0FFF" + get_game_props(entranceObj, "entrance_actor").actor.actorParam = "0x0FFF" parentObject(planeObj, entranceObj) location += Vector([0, 0, 10]) @@ -97,7 +97,7 @@ def execute(self, context): roomObj = context.view_layer.objects.active roomObj.ootEmptyType = "Room" roomObj.name = "Room" - entranceObj.ootEntranceProperty.tiedRoom = roomObj + get_game_props(entranceObj, "entrance_actor").tiedRoom = roomObj parentObject(roomObj, planeObj) location += Vector([0, 0, 2]) @@ -133,11 +133,11 @@ def execute(self, context): indices = [] for sceneChild in sceneObj.children: if sceneChild.ootEmptyType == "Room": - indices.append(get_room_header_props(sceneChild).roomIndex) + indices.append(get_game_props(sceneChild, "room").roomIndex) nextIndex = 0 while nextIndex in indices: nextIndex += 1 - get_room_header_props(roomObj).roomIndex = nextIndex + get_game_props(roomObj, "room").roomIndex = nextIndex parentObject(sceneObj, roomObj) object.select_all(action="DESELECT") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 492aa9b59..f15be1feb 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,7 +6,7 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from .data import OoT_ObjectData -from .utility import getEvalParams, get_room_header_props +from .utility import getEvalParams, get_game_props from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode @@ -38,9 +38,9 @@ def upgradeObjectList(objList: CollectionProperty, objData: OoT_ObjectData): def upgradeRoomHeaders(roomObj: Object, objData: OoT_ObjectData): """Main upgrade logic for room headers""" - altHeaders = get_room_header_props(roomObj, True) + altHeaders = get_game_props(roomObj, "alt_room") for sceneLayer in [ - get_room_header_props(roomObj), + get_game_props(roomObj, "room"), altHeaders.childNightHeader, altHeaders.adultDayHeader, altHeaders.adultNightHeader, @@ -308,7 +308,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): ##################################### def upgradeActors(actorObj: Object): if actorObj.ootEmptyType == "Entrance": - entranceProp = actorObj.ootEntranceProperty + entranceProp = get_game_props(actorObj, "entrance_actor") for obj in bpy.data.objects: if obj.type == "EMPTY" and obj.ootEmptyType == "Room": @@ -328,7 +328,7 @@ def upgradeActors(actorObj: Object): print("WARNING: Ignoring Door Actor not parented to a room") return - transActorProp = actorObj.ootTransitionActorProperty + transActorProp = get_game_props(actorObj, "transition_actor") if "dontTransition" in transActorProp or "roomIndex" in transActorProp: # look for old data since we don't want to overwrite newer existing data transActorProp.fromRoom = roomParent @@ -344,7 +344,7 @@ def upgradeActors(actorObj: Object): obj != transActorProp.fromRoom and obj.type == "EMPTY" and obj.ootEmptyType == "Room" - and get_room_header_props(obj).roomIndex == transActorProp["roomIndex"] + and get_game_props(obj, "room").roomIndex == transActorProp["roomIndex"] ): transActorProp.toRoom = obj del transActorProp["roomIndex"] diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 9f5ad1119..05f238c46 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -49,46 +49,58 @@ from .scene.properties import OOTBootupSceneOptions, OOTSceneHeaderProperty, MM_SceneHeaderProperty -game_enum_map = { - "OOT": { - "enum_global_object": ootEnumGlobalObject, - "enum_skybox": ootEnumSkybox, - "enum_seq_id": oot_data.ootEnumMusicSeq, - "enum_ambiance_id": oot_data.ootEnumNightSeq, # TODO: generate this from xml (not for enumproperties) - "enum_env_type": ootEnumLinkIdle, - "enum_room_type": ootEnumRoomBehaviour, - }, - "MM": { - "enum_global_object": mm_enum_global_object, - "enum_skybox": mm_enum_skybox, - "enum_seq_id": mm_data.enum_seq_id, - "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above - "enum_env_type": mm_enum_environvment_type, - "enum_room_type": mm_enum_room_type, - }, -} - - def get_game_enum(enum_type: str): - return game_enum_map[bpy.context.scene.gameEditorMode][enum_type] + game_enum_map = { + "OOT": { + "enum_global_object": ootEnumGlobalObject, + "enum_skybox": ootEnumSkybox, + "enum_seq_id": oot_data.ootEnumMusicSeq, + "enum_ambiance_id": oot_data.ootEnumNightSeq, # TODO: generate this from xml (not for enumproperties) + "enum_env_type": ootEnumLinkIdle, + "enum_room_type": ootEnumRoomBehaviour, + "enum_actor_id": oot_data.actorData.ootEnumActorID, + }, + "MM": { + "enum_global_object": mm_enum_global_object, + "enum_skybox": mm_enum_skybox, + "enum_seq_id": mm_data.enum_seq_id, + "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above + "enum_env_type": mm_enum_environvment_type, + "enum_room_type": mm_enum_room_type, + "enum_actor_id": mm_data.actor_data.enum_actor_id, + }, + } - -def is_game_oot(): - return bpy.context.scene.gameEditorMode == "OOT" + return game_enum_map[bpy.context.scene.gameEditorMode][enum_type] -def get_scene_header_props(obj: Object, is_alt_header: bool = False): - if is_game_oot(): - return obj.ootAlternateSceneHeaders if is_alt_header else obj.ootSceneHeader - else: - return obj.mm_alternate_scene_headers if is_alt_header else obj.mm_scene_header +def get_game_props(obj: Object, header_type: str): + game_header_map = { + "OOT": { + "scene": obj.ootSceneHeader, + "alt_scene": obj.ootAlternateSceneHeaders, + "room": obj.ootRoomHeader, + "alt_room": obj.ootAlternateRoomHeaders, + "actor": obj.ootActorProperty, + "transition_actor": obj.ootTransitionActorProperty, + "entrance_actor": obj.ootEntranceProperty, + }, + "MM": { + "scene": obj.mm_scene_header, + "alt_scene": obj.mm_alternate_scene_headers, + "room": obj.mm_room_header, + "alt_room": obj.mm_alternate_room_headers, + "actor": obj.mm_actor_property, + "transition_actor": obj.mm_transition_actor_property, + "entrance_actor": obj.mm_entrance_property, + }, + } + + return game_header_map[bpy.context.scene.gameEditorMode][header_type] -def get_room_header_props(obj: Object, is_alt_header: bool = False): - if is_game_oot(): - return get_room_header_props(obj, True) if is_alt_header else get_room_header_props(obj) - else: - return obj.mm_alternate_room_headers if is_alt_header else obj.mm_room_header +def is_game_oot(): + return bpy.context.scene.gameEditorMode == "OOT" def isPathObject(obj: bpy.types.Object) -> bool: @@ -727,15 +739,15 @@ def getCollectionFromIndex(obj, prop, subIndex, isRoom): def getCollection(objName, collectionType, subIndex): obj = bpy.data.objects[objName] if collectionType == "Actor": - collection = obj.ootActorProperty.headerSettings.cutsceneHeaders + collection = get_game_props(obj, "actor").headerSettings.cutsceneHeaders elif collectionType == "Transition Actor": - collection = obj.ootTransitionActorProperty.actor.headerSettings.cutsceneHeaders + collection = get_game_props(obj, "transition_actor").actor.headerSettings.cutsceneHeaders elif collectionType == "Entrance": - collection = obj.ootEntranceProperty.actor.headerSettings.cutsceneHeaders + collection = get_game_props(obj, "entrance_actor").actor.headerSettings.cutsceneHeaders elif collectionType == "Room": - collection = get_room_header_props(obj, True).cutsceneHeaders + collection = get_game_props(obj, "alt_room").cutsceneHeaders elif collectionType == "Scene": - collection = get_scene_header_props(obj, True).cutsceneHeaders + collection = get_game_props(obj, "alt_scene").cutsceneHeaders elif collectionType == "Light": collection = getCollectionFromIndex(obj, "lightList", subIndex, False) elif collectionType == "Exit": @@ -766,9 +778,9 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Cutscene": collection = obj.ootCutsceneProperty.csLists elif collectionType == "extraCutscenes": - collection = get_scene_header_props(obj).extraCutscenes + collection = get_game_props(obj, "scene").extraCutscenes elif collectionType == "BgImage": - collection = get_room_header_props(obj).bgImageList + collection = get_game_props(obj, "room").bgImageList else: raise PluginError("Invalid collection type: " + collectionType) @@ -878,11 +890,11 @@ def getHeaderSettings(actorObj: bpy.types.Object): itemType = actorObj.ootEmptyType if actorObj.type == "EMPTY": if itemType == "Actor": - headerSettings = actorObj.ootActorProperty.headerSettings + headerSettings = get_game_props(actorObj, "actor").headerSettings elif itemType == "Entrance": - headerSettings = actorObj.ootEntranceProperty.actor.headerSettings + headerSettings = get_game_props(actorObj, "transition_actor").actor.headerSettings elif itemType == "Transition Actor": - headerSettings = actorObj.ootTransitionActorProperty.actor.headerSettings + headerSettings = get_game_props(actorObj, "entrance_actor").actor.headerSettings else: headerSettings = None elif isPathObject(actorObj): @@ -918,11 +930,11 @@ def getActiveHeaderIndex() -> int: headerObj = headerObjs[0] if headerObj.ootEmptyType == "Scene": - header = get_scene_header_props(headerObj) - altHeader = get_scene_header_props(headerObj, True) + header = get_game_props(headerObj, "scene") + altHeader = get_game_props(headerObj, "alt_scene") else: - header = get_room_header_props(headerObj) - altHeader = get_room_header_props(headerObj, True) + header = get_game_props(headerObj, "room") + altHeader = get_game_props(headerObj, "alt_room") if header.menuTab != "Alternate": headerIndex = 0 @@ -980,9 +992,9 @@ def setActorVisibility(actorObj: bpy.types.Object, activeHeaderInfo: tuple[int, def onMenuTabChange(self, context: bpy.types.Context): def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": - header = get_scene_header_props(otherObj) + header = get_game_props(otherObj, "scene") else: - header = get_room_header_props(otherObj) + header = get_game_props(otherObj, "room") if thisHeader.menuTab != "Alternate" and header.menuTab == "Alternate": header.menuTab = "General" @@ -995,9 +1007,9 @@ def callback(thisHeader, otherObj: bpy.types.Object): def onHeaderMenuTabChange(self, context: bpy.types.Context): def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": - header = get_scene_header_props(otherObj, True) + header = get_game_props(otherObj, "alt_scene") else: - header = get_room_header_props(otherObj, True) + header = get_game_props(otherObj, "alt_room") header.headerMenuTab = thisHeader.headerMenuTab header.currentCutsceneIndex = thisHeader.currentCutsceneIndex @@ -1166,7 +1178,7 @@ def getObjectList( if ( emptyType == "Actor" and obj.ootEmptyType == "Room" - and get_room_header_props(obj).roomIndex == room_index + and get_game_props(obj, "room").roomIndex == room_index ): for o in obj.children_recursive: if o.type == objType and o.ootEmptyType == emptyType and o not in ret: From 15e123de6dc565ae3e6fdd19ef2e9b112e4396e5 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:13:53 +0100 Subject: [PATCH 015/126] fixed paths --- fast64_internal/z64/collision/constants.py | 2 +- .../z64/exporter/scene/pathways.py | 4 +- fast64_internal/z64/exporter/utility.py | 30 ++++---- fast64_internal/z64/importer/classes.py | 5 +- .../z64/importer/scene_collision.py | 4 +- .../z64/importer/scene_pathways.py | 25 +++++-- fast64_internal/z64/spline/panels.py | 4 +- fast64_internal/z64/spline/properties.py | 48 ++++++++---- fast64_internal/z64/utility.py | 74 ++++++++++++------- 9 files changed, 126 insertions(+), 70 deletions(-) diff --git a/fast64_internal/z64/collision/constants.py b/fast64_internal/z64/collision/constants.py index 031125a54..7642699e6 100644 --- a/fast64_internal/z64/collision/constants.py +++ b/fast64_internal/z64/collision/constants.py @@ -77,7 +77,7 @@ ("0x03", "Fast", "Fast"), ] -ootEnumCameraCrawlspaceSType = [ +enum_camera_crawlspace_stype = [ ("Custom", "Custom", "Custom"), ("CAM_SET_CRAWLSPACE", "Crawlspace", "Crawlspace"), ] diff --git a/fast64_internal/z64/exporter/scene/pathways.py b/fast64_internal/z64/exporter/scene/pathways.py index 7feb19248..64e322633 100644 --- a/fast64_internal/z64/exporter/scene/pathways.py +++ b/fast64_internal/z64/exporter/scene/pathways.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList +from ...utility import getObjectList, get_game_props from ..utility import Utility @@ -50,7 +50,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in pathObjList: relativeTransform = transform @ sceneObj.matrix_world.inverted() @ obj.matrix_world pathProps = obj.ootSplineProperty - isHeaderValid = Utility.isCurrentHeaderValid(pathProps.headerSettings, headerIndex) + isHeaderValid = Utility.isCurrentHeaderValid(get_game_props(obj, "path_header_settings"), headerIndex) if isHeaderValid and Utility.validateCurveData(obj): if pathProps.index not in pathFromIndex: pathFromIndex[pathProps.index] = Path( diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index 297803bd2..560c74e1b 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -2,8 +2,8 @@ from mathutils import Quaternion, Matrix from bpy.types import Object from ...utility import PluginError, indent -from ..utility import ootConvertTranslation, ootConvertRotation -from ..actor.properties import OOTActorHeaderProperty +from ..utility import ootConvertTranslation, ootConvertRotation, is_game_oot +from ..actor.properties import OOTActorHeaderProperty, MM_ActorHeaderProperty altHeaderList = ["childNight", "adultDay", "adultNight"] @@ -34,22 +34,26 @@ def roundPosition(position) -> tuple[int, int, int]: return (round(position[0]), round(position[1]), round(position[2])) @staticmethod - def isCurrentHeaderValid(headerSettings: OOTActorHeaderProperty, headerIndex: int): + def isCurrentHeaderValid(headerSettings: OOTActorHeaderProperty | MM_ActorHeaderProperty, headerIndex: int): """Checks if the an alternate header can be used""" - preset = headerSettings.sceneSetupPreset + if is_game_oot(): + preset = headerSettings.sceneSetupPreset - if preset == "All Scene Setups" or (preset == "All Non-Cutscene Scene Setups" and headerIndex < 4): - return True + if preset == "All Scene Setups" or (preset == "All Non-Cutscene Scene Setups" and headerIndex < 4): + return True - if preset == "Custom": - for i, header in enumerate(["childDay"] + altHeaderList): - if getattr(headerSettings, f"{header}Header") and i == headerIndex: - return True + if preset == "Custom": + for i, header in enumerate(["childDay"] + altHeaderList): + if getattr(headerSettings, f"{header}Header") and i == headerIndex: + return True + else: + if headerSettings.include_in_all_setups or headerSettings.childDayHeader and headerIndex == 0: + return True - for csHeader in headerSettings.cutsceneHeaders: - if csHeader.headerIndex == headerIndex: - return True + for csHeader in headerSettings.cutsceneHeaders: + if csHeader.headerIndex == headerIndex: + return True return False diff --git a/fast64_internal/z64/importer/classes.py b/fast64_internal/z64/importer/classes.py index 65e7af441..031d1c97e 100644 --- a/fast64_internal/z64/importer/classes.py +++ b/fast64_internal/z64/importer/classes.py @@ -1,5 +1,5 @@ from ...utility import PluginError -from ..utility import getHeaderSettings +from ..utility import getHeaderSettings, is_game_oot from .constants import headerNames @@ -50,8 +50,9 @@ def addHeaderIfItemExists(self, hash, itemType: str, headerIndex: int): actorObj = dictToAdd[hash] headerSettings = getHeaderSettings(actorObj) + cs_start = 4 if is_game_oot() else 1 - if headerIndex < 4: + if headerIndex < cs_start: setattr(headerSettings, headerNames[headerIndex], True) else: cutsceneHeaders = headerSettings.cutsceneHeaders diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index 40a4d8240..fb8149db9 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -19,7 +19,7 @@ ootEnumCollisionTerrain, ootEnumCollisionSound, ootEnumCameraSType, - ootEnumCameraCrawlspaceSType, + enum_camera_crawlspace_stype, ) @@ -40,7 +40,7 @@ def parseCrawlSpaceData( crawlProp = curveObj.ootSplineProperty crawlProp.splineType = "Crawlspace" crawlProp.index = orderIndex - setCustomProperty(crawlProp, "camSType", "CAM_SET_CRAWLSPACE", ootEnumCameraCrawlspaceSType) + setCustomProperty(crawlProp, "camSType", "CAM_SET_CRAWLSPACE", enum_camera_crawlspace_stype) return curveObj diff --git a/fast64_internal/z64/importer/scene_pathways.py b/fast64_internal/z64/importer/scene_pathways.py index 55e435553..0852b66d7 100644 --- a/fast64_internal/z64/importer/scene_pathways.py +++ b/fast64_internal/z64/importer/scene_pathways.py @@ -1,6 +1,8 @@ import bpy +from typing import Optional from ...utility import hexOrDecInt, parentObject +from ..utility import is_game_oot, get_game_props from .utility import getDataMatch, createCurveFromPoints, unsetAllHeadersExceptSpecified from .classes import SharedSceneData @@ -8,12 +10,14 @@ def parsePath( sceneObj: bpy.types.Object, sceneData: str, - pathName: str, + points_ptr: str, + opt_path_idx: Optional[str], + custom_value: Optional[str], headerIndex: int, sharedSceneData: SharedSceneData, orderIndex: int, ): - pathData = getDataMatch(sceneData, pathName, "Vec3s", "path") + pathData = getDataMatch(sceneData, points_ptr, "Vec3s", "path") pathPointsEntries = [value.replace("{", "").strip() for value in pathData.split("},") if value.strip() != ""] pathPointsInfo = [] for pathPoint in pathPointsEntries: @@ -23,11 +27,15 @@ def parsePath( if sharedSceneData.addHeaderIfItemExists(pathPoints, "Curve", headerIndex): return - curveObj = createCurveFromPoints(pathPoints, pathName) + curveObj = createCurveFromPoints(pathPoints, points_ptr) splineProp = curveObj.ootSplineProperty splineProp.index = orderIndex - unsetAllHeadersExceptSpecified(splineProp.headerSettings, headerIndex) + if not is_game_oot() and opt_path_idx is not None and custom_value is not None: + splineProp.mm_opt_path_index = int(opt_path_idx) + splineProp.mm_custom_value = int(custom_value) + + unsetAllHeadersExceptSpecified(get_game_props(curveObj, "path_header_settings"), headerIndex) sharedSceneData.pathDict[pathPoints] = curveObj parentObject(sceneObj, curveObj) @@ -43,5 +51,10 @@ def parsePathList( pathData = getDataMatch(sceneData, pathListName, "Path", "path list") pathList = [value.replace("{", "").strip() for value in pathData.split("},") if value.strip() != ""] for i, pathEntry in enumerate(pathList): - numPoints, pathName = [value.strip() for value in pathEntry.split(",")] - parsePath(sceneObj, sceneData, pathName, headerIndex, sharedSceneData, i) + if is_game_oot(): + count, points_ptr = [value.strip() for value in pathEntry.split(",")] + opt_path_idx = custom_value = None + else: + count, opt_path_idx, custom_value, points_ptr = [value.strip() for value in pathEntry.split(",")] + + parsePath(sceneObj, sceneData, points_ptr, opt_path_idx, custom_value, headerIndex, sharedSceneData, i) diff --git a/fast64_internal/z64/spline/panels.py b/fast64_internal/z64/spline/panels.py index 456d1ca2c..b2fb5d520 100644 --- a/fast64_internal/z64/spline/panels.py +++ b/fast64_internal/z64/spline/panels.py @@ -1,7 +1,7 @@ from bpy.types import Panel, Curve from bpy.utils import register_class, unregister_class from ..utility import getSceneObj, get_game_props -from .properties import OOTSplineProperty +from .properties import Z64_SplineProperty class OOTSplinePanel(Panel): @@ -27,7 +27,7 @@ def draw(self, context): else: sceneObj = getSceneObj(context.object) altSceneProp = get_game_props(sceneObj, "alt_scene") if sceneObj is not None else None - splineProp: OOTSplineProperty = context.object.ootSplineProperty + splineProp: Z64_SplineProperty = context.object.ootSplineProperty splineProp.draw_props(box, altSceneProp, context.object.name) diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index cd5d2a271..47824e5f3 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -1,45 +1,61 @@ +import bpy + from bpy.types import PropertyGroup, Object, UILayout from bpy.props import EnumProperty, PointerProperty, StringProperty, IntProperty from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom -from ..collision.constants import ootEnumCameraCrawlspaceSType -from ..actor.properties import OOTActorHeaderProperty -from ..scene.properties import OOTAlternateSceneHeaderProperty +from ..utility import drawEnumWithCustom, is_game_oot, get_game_props +from ..collision.constants import enum_camera_crawlspace_stype +from ..actor.properties import OOTActorHeaderProperty, MM_ActorHeaderProperty +from ..scene.properties import OOTAlternateSceneHeaderProperty, MM_AlternateSceneHeaderProperty -ootSplineEnum = [("Path", "Path", "Path"), ("Crawlspace", "Crawlspace", "Crawlspace")] +enum_spline = [("Path", "Path", "Path"), ("Crawlspace", "Crawlspace", "Crawlspace")] -class OOTSplineProperty(PropertyGroup): - splineType: EnumProperty(items=ootSplineEnum, default="Path") +class Z64_SplineProperty(PropertyGroup): + splineType: EnumProperty(items=enum_spline, default="Path") index: IntProperty(min=0) # only used for crawlspace, not path headerSettings: PointerProperty(type=OOTActorHeaderProperty) - camSType: EnumProperty(items=ootEnumCameraCrawlspaceSType, default="CAM_SET_CRAWLSPACE") + camSType: EnumProperty(items=enum_camera_crawlspace_stype, default="CAM_SET_CRAWLSPACE") camSTypeCustom: StringProperty(default="CAM_SET_CRAWLSPACE") - def draw_props(self, layout: UILayout, altSceneProp: OOTAlternateSceneHeaderProperty, objName: str): - camIndexName = "" + mm_header_settings: PointerProperty(type=MM_ActorHeaderProperty) + mm_opt_path_index: IntProperty(name="Additional Path Index", min=-1, default=-1) + mm_custom_value: IntProperty(name="Custom Value", min=-1, default=-1) + + def draw_props( + self, + layout: UILayout, + altSceneProp: OOTAlternateSceneHeaderProperty | MM_AlternateSceneHeaderProperty, + objName: str, + ): + camIndexName = "Path Index" if self.splineType == "Path" else "Camera Index" prop_split(layout, self, "splineType", "Type") + prop_split(layout, self, "index", camIndexName) + + if not is_game_oot(): + prop_split(layout, self, "mm_opt_path_index", "Additional Path Index") + prop_split(layout, self, "mm_custom_value", "Custom Value") + if self.splineType == "Path": - headerProp: OOTActorHeaderProperty = self.headerSettings + headerProp: OOTActorHeaderProperty | MM_ActorHeaderProperty = get_game_props( + bpy.data.objects[objName], "path_header_settings" + ) headerProp.draw_props(layout, "Curve", altSceneProp, objName) - camIndexName = "Path Index" elif self.splineType == "Crawlspace": layout.label(text="This counts as a camera for index purposes.", icon="INFO") drawEnumWithCustom(layout, self, "camSType", "Camera S Type", "") - camIndexName = "Camera Index" - prop_split(layout, self, "index", camIndexName) -oot_spline_classes = (OOTSplineProperty,) +oot_spline_classes = (Z64_SplineProperty,) def spline_props_register(): for cls in oot_spline_classes: register_class(cls) - Object.ootSplineProperty = PointerProperty(type=OOTSplineProperty) + Object.ootSplineProperty = PointerProperty(type=Z64_SplineProperty) def spline_props_unregister(): diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 05f238c46..e4e14e90d 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -84,6 +84,7 @@ def get_game_props(obj: Object, header_type: str): "actor": obj.ootActorProperty, "transition_actor": obj.ootTransitionActorProperty, "entrance_actor": obj.ootEntranceProperty, + "path_header_settings": obj.ootSplineProperty.headerSettings, }, "MM": { "scene": obj.mm_scene_header, @@ -93,6 +94,7 @@ def get_game_props(obj: Object, header_type: str): "actor": obj.mm_actor_property, "transition_actor": obj.mm_transition_actor_property, "entrance_actor": obj.mm_entrance_property, + "path_header_settings": obj.ootSplineProperty.mm_header_settings, }, } @@ -759,7 +761,7 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Object": collection = getCollectionFromIndex(obj, "objectList", subIndex, True) elif collectionType == "Curve": - collection = obj.ootSplineProperty.headerSettings.cutsceneHeaders + collection = get_game_props(obj, "path_header_settings").cutsceneHeaders elif collectionType.startswith("CSHdr."): # CSHdr.HeaderNumber[.ListType] # Specifying ListType means uses subIndex @@ -898,7 +900,7 @@ def getHeaderSettings(actorObj: bpy.types.Object): else: headerSettings = None elif isPathObject(actorObj): - headerSettings = actorObj.ootSplineProperty.headerSettings + headerSettings = get_game_props(actorObj, "path_header_settings") else: headerSettings = None @@ -925,6 +927,7 @@ def oot_utility_unregister(): def getActiveHeaderIndex() -> int: # All scenes/rooms should have synchronized tabs from property callbacks headerObjs = [obj for obj in bpy.data.objects if obj.ootEmptyType == "Scene" or obj.ootEmptyType == "Room"] + if len(headerObjs) == 0: return 0 @@ -939,21 +942,27 @@ def getActiveHeaderIndex() -> int: if header.menuTab != "Alternate": headerIndex = 0 else: - if altHeader.headerMenuTab == "Child Night": - headerIndex = 1 - elif altHeader.headerMenuTab == "Adult Day": - headerIndex = 2 - elif altHeader.headerMenuTab == "Adult Night": - headerIndex = 3 + if is_game_oot(): + if altHeader.headerMenuTab == "Child Night": + headerIndex = 1 + elif altHeader.headerMenuTab == "Adult Day": + headerIndex = 2 + elif altHeader.headerMenuTab == "Adult Night": + headerIndex = 3 + else: + headerIndex = altHeader.currentCutsceneIndex else: headerIndex = altHeader.currentCutsceneIndex - return ( - headerIndex, - altHeader.childNightHeader.usePreviousHeader, - altHeader.adultDayHeader.usePreviousHeader, - altHeader.adultNightHeader.usePreviousHeader, - ) + if is_game_oot(): + return ( + headerIndex, + altHeader.childNightHeader.usePreviousHeader, + altHeader.adultDayHeader.usePreviousHeader, + altHeader.adultNightHeader.usePreviousHeader, + ) + else: + return headerIndex, None, None, None def setAllActorsVisibility(self, context: bpy.types.Context): @@ -969,24 +978,37 @@ def setAllActorsVisibility(self, context: bpy.types.Context): setActorVisibility(actorObj, activeHeaderInfo) -def setActorVisibility(actorObj: bpy.types.Object, activeHeaderInfo: tuple[int, bool, bool, bool]): +def setActorVisibility( + actorObj: bpy.types.Object, activeHeaderInfo: tuple[int, Optional[bool], Optional[bool], Optional[bool]] +): headerIndex, childNightHeader, adultDayHeader, adultNightHeader = activeHeaderInfo - usePreviousHeader = [False, childNightHeader, adultDayHeader, adultNightHeader] - if headerIndex < 4: - while usePreviousHeader[headerIndex]: - headerIndex -= 1 + + if is_game_oot(): + usePreviousHeader = [False, childNightHeader, adultDayHeader, adultNightHeader] + + if headerIndex < 4: + while usePreviousHeader[headerIndex]: + headerIndex -= 1 headerSettings = getHeaderSettings(actorObj) + if headerSettings is None: return - if headerSettings.sceneSetupPreset == "All Scene Setups": - actorObj.hide_set(False) - elif headerSettings.sceneSetupPreset == "All Non-Cutscene Scene Setups": - actorObj.hide_set(headerIndex >= 4) - elif headerSettings.sceneSetupPreset == "Custom": - actorObj.hide_set(not headerSettings.checkHeader(headerIndex)) + + if is_game_oot(): + if headerSettings.sceneSetupPreset == "All Scene Setups": + actorObj.hide_set(False) + elif headerSettings.sceneSetupPreset == "All Non-Cutscene Scene Setups": + actorObj.hide_set(headerIndex >= 4) + elif headerSettings.sceneSetupPreset == "Custom": + actorObj.hide_set(not headerSettings.checkHeader(headerIndex)) + else: + print("Error: unhandled header case") else: - print("Error: unhandled header case") + if headerSettings.include_in_all_setups: + actorObj.hide_set(False) + else: + actorObj.hide_set(not headerSettings.checkHeader(headerIndex)) def onMenuTabChange(self, context: bpy.types.Context): From d69d1a65c1e67d48a0e0a53aab00ee3f06538739 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:26:13 +0100 Subject: [PATCH 016/126] disable cutscene ui --- fast64_internal/z64/cutscene/panels.py | 11 +++++++++++ fast64_internal/z64/scene/properties/mm_props.py | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/cutscene/panels.py b/fast64_internal/z64/cutscene/panels.py index 31ecae605..2b0aca01e 100644 --- a/fast64_internal/z64/cutscene/panels.py +++ b/fast64_internal/z64/cutscene/panels.py @@ -3,6 +3,7 @@ from bpy.props import BoolProperty from ...utility import prop_split from ...panels import Z64_Panel +from ..utility import is_game_oot from .operators import OOT_ExportCutscene, OOT_ExportAllCutscenes, OOT_ImportCutscene @@ -26,6 +27,10 @@ def draw(self, context): exportBox = layout.box() exportBox.label(text="Cutscene Exporter") + exportBox.enabled = is_game_oot() + if not exportBox.enabled: + layout.label(text="Export not implemented yet.") + prop_split(exportBox, context.scene, "ootCutsceneExportPath", "Export To") activeObj = context.view_layer.objects.active @@ -45,8 +50,14 @@ def draw(self, context): colcol.operator(OOT_ExportCutscene.bl_idname) col.operator(OOT_ExportAllCutscenes.bl_idname) + importBox = layout.box() importBox.label(text="Cutscene Importer") + + importBox.enabled = is_game_oot() + if not importBox.enabled: + layout.label(text="Import not implemented yet.") + prop_split(importBox, context.scene, "ootCSImportName", "Import") prop_split(importBox, context.scene, "ootCutsceneImportPath", "From") diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py index a9d412da4..0343f1572 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -617,7 +617,8 @@ def draw_props(self, layout: UILayout, sceneOption: str): includeButtons3 = col.row(align=True) includeButtons3.prop(self, "includePaths", toggle=1) includeButtons3.prop(self, "includeWaterBoxes", toggle=1) - includeButtons3.prop(self, "includeCutscenes", toggle=1) + # TODO: implement cutscenes + # includeButtons3.prop(self, "includeCutscenes", toggle=1) col.prop(self, "isCustomDest") if self.isCustomDest: From 50c3fb2d2e1c119e24d50442d4847f69e41b3d07 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:47:21 +0100 Subject: [PATCH 017/126] implement export to c --- fast64_internal/z64/constants.py | 1 - fast64_internal/z64/cutscene/panels.py | 1 - .../z64/data/mm/xml/ObjectList.xml | 1280 ++++++++--------- .../z64/exporter/decomp_edit/spec.py | 4 +- fast64_internal/z64/exporter/room/__init__.py | 34 +- fast64_internal/z64/exporter/room/header.py | 62 +- .../z64/exporter/scene/__init__.py | 42 +- fast64_internal/z64/exporter/scene/actors.py | 20 +- fast64_internal/z64/exporter/scene/general.py | 162 ++- fast64_internal/z64/exporter/scene/header.py | 10 +- fast64_internal/z64/importer/classes.py | 5 +- fast64_internal/z64/importer/room_header.py | 13 +- fast64_internal/z64/importer/scene_header.py | 14 +- fast64_internal/z64/importer/utility.py | 5 +- fast64_internal/z64/scene/operators.py | 10 +- .../z64/scene/properties/__init__.py | 2 + .../z64/scene/properties/mm_props.py | 2 +- fast64_internal/z64/utility.py | 58 +- 18 files changed, 972 insertions(+), 753 deletions(-) diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index ed28877b3..63cf7846c 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -181,7 +181,6 @@ mm_enum_global_object = [ ("Custom", "Custom", "Custom"), - ("None", "None", "None"), ("GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), ("GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), ] diff --git a/fast64_internal/z64/cutscene/panels.py b/fast64_internal/z64/cutscene/panels.py index 2b0aca01e..40f37535e 100644 --- a/fast64_internal/z64/cutscene/panels.py +++ b/fast64_internal/z64/cutscene/panels.py @@ -50,7 +50,6 @@ def draw(self, context): colcol.operator(OOT_ExportCutscene.bl_idname) col.operator(OOT_ExportAllCutscenes.bl_idname) - importBox = layout.box() importBox.label(text="Cutscene Importer") diff --git a/fast64_internal/z64/data/mm/xml/ObjectList.xml b/fast64_internal/z64/data/mm/xml/ObjectList.xml index 6c06cc7ad..71706d83c 100644 --- a/fast64_internal/z64/data/mm/xml/ObjectList.xml +++ b/fast64_internal/z64/data/mm/xml/ObjectList.xml @@ -7,647 +7,647 @@ Documentation on this file's format: - Name: display name - Index: corresponds to the index of the object in the old object list, used for compatibility with blends --> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fast64_internal/z64/exporter/decomp_edit/spec.py b/fast64_internal/z64/exporter/decomp_edit/spec.py index 5029ff21d..835ba0c7d 100644 --- a/fast64_internal/z64/exporter/decomp_edit/spec.py +++ b/fast64_internal/z64/exporter/decomp_edit/spec.py @@ -5,7 +5,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile, indent -from ...utility import ExportInfo, getSceneDirFromLevelName +from ...utility import ExportInfo, getSceneDirFromLevelName, get_game_props from ..scene import Scene from ..file import SceneFile @@ -238,7 +238,7 @@ def add_segments(exportInfo: "ExportInfo", scene: "Scene", sceneFile: "SceneFile SpecUtility.remove_segments_from_spec(specFile, exportInfo.name) assert build_directory is not None - isSingleFile = bpy.context.scene.ootSceneExportSettings.singleFile + isSingleFile = get_game_props(None, "export_settings").singleFile includeDir = f"{build_directory}/" if exportInfo.customSubPath is not None: includeDir += f"{exportInfo.customSubPath + sceneName}" diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index db29845b7..a4a733f9f 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings -from ...utility import get_game_props +from ...utility import get_game_props, is_game_oot from ...room.properties import OOTRoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -58,19 +58,20 @@ def new( ) hasAlternateHeaders = False - for i, header in enumerate(altHeaderList, 1): - altP: OOTRoomHeaderProperty = getattr(altProp, f"{header}Header") - if not altP.usePreviousHeader: - hasAlternateHeaders = True - newRoomHeader = RoomHeader.new( - f"{name}_header{i:02}", - altP, - sceneObj, - roomObj, - transform, - i, - ) - setattr(altHeader, header, newRoomHeader) + if is_game_oot(): + for i, header in enumerate(altHeaderList, 1): + altP: OOTRoomHeaderProperty = getattr(altProp, f"{header}Header") + if not altP.usePreviousHeader: + hasAlternateHeaders = True + newRoomHeader = RoomHeader.new( + f"{name}_header{i:02}", + altP, + sceneObj, + roomObj, + transform, + i, + ) + setattr(altHeader, header, newRoomHeader) altHeader.cutscenes = [ RoomHeader.new( @@ -81,7 +82,7 @@ def new( transform, i, ) - for i, csHeader in enumerate(altProp.cutsceneHeaders, 4) + for i, csHeader in enumerate(altProp.cutsceneHeaders, 4 if is_game_oot() else 1) ] hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders @@ -170,7 +171,8 @@ def getRoomMainC(self): + "\n};\n\n" ) - roomHeaders.insert(0, (self.mainHeader, "Child Day (Default)")) + header_name = "Child Day (Default)" if is_game_oot() else "Default" + roomHeaders.insert(0, (self.mainHeader, header_name)) for i, (curHeader, headerDesc) in enumerate(roomHeaders): if curHeader is not None: roomC.source += "/**\n * " + f"Header {headerDesc}\n" + "*/\n" diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index a66a88933..8309fe893 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,9 +3,9 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData, indent -from ...utility import getObjectList, get_game_props +from ...utility import getObjectList, get_game_props, is_game_oot, getEvalParams from ...constants import oot_data -from ...room.properties import OOTRoomHeaderProperty +from ...room.properties import OOTRoomHeaderProperty, MM_RoomHeaderProperty from ..utility import Utility from ..actor import Actor @@ -23,9 +23,15 @@ class RoomInfos: roomBehavior: str playerIdleType: str - disableWarpSongs: bool showInvisActors: bool + # OoT + disableWarpSongs: bool + + # MM + enable_pos_lights: bool + enable_storm: bool + ### Skybox And Time ### disableSky: bool @@ -42,14 +48,26 @@ class RoomInfos: strength: int @staticmethod - def new(props: Optional[OOTRoomHeaderProperty]): + def new(props: Optional[OOTRoomHeaderProperty | MM_RoomHeaderProperty]): + disableWarpSongs = False + enable_pos_lights = False + enable_storm = False + + if is_game_oot(): + disableWarpSongs = props.disableWarpSongs + else: + enable_pos_lights = props.enable_pos_lights + enable_storm = props.enable_storm + return RoomInfos( props.roomIndex, props.roomShape, Utility.getPropValue(props, "roomBehaviour"), Utility.getPropValue(props, "linkIdleMode"), - props.disableWarpSongs, props.showInvisibleActors, + disableWarpSongs, + enable_pos_lights, + enable_storm, props.disableSkybox, props.disableSunMoon, 0xFF if props.leaveTimeUnchanged else props.timeHours, @@ -64,11 +82,19 @@ def new(props: Optional[OOTRoomHeaderProperty]): def getCmds(self): """Returns the echo settings, room behavior, skybox disables and time settings room commands""" showInvisActors = "true" if self.showInvisActors else "false" - disableWarpSongs = "true" if self.disableWarpSongs else "false" disableSkybox = "true" if self.disableSky else "false" disableSunMoon = "true" if self.disableSunMoon else "false" - roomBehaviorArgs = f"{self.roomBehavior}, {self.playerIdleType}, {showInvisActors}, {disableWarpSongs}" + if is_game_oot(): + disableWarpSongs = "true" if self.disableWarpSongs else "false" + roomBehaviorArgs = f"{self.roomBehavior}, {self.playerIdleType}, {showInvisActors}, {disableWarpSongs}" + else: + enable_pos_lights = "true" if self.enable_pos_lights else "false" + enable_storm = "true" if self.enable_storm else "false" + roomBehaviorArgs = ( + f"{self.roomBehavior}, {self.playerIdleType}, {showInvisActors}, 0, {enable_pos_lights}, {enable_storm}" + ) + cmdList = [ f"SCENE_CMD_ECHO_SETTINGS({self.echo})", f"SCENE_CMD_ROOM_BEHAVIOR({roomBehaviorArgs})", @@ -166,10 +192,26 @@ def new( else: actor.id = actorProp.actorID - if actorProp.rotOverride: - actor.rot = ", ".join([actorProp.rotOverrideX, actorProp.rotOverrideY, actorProp.rotOverrideZ]) + if is_game_oot(): + if actorProp.rotOverride: + actor.rot = ", ".join([actorProp.rotOverrideX, actorProp.rotOverrideY, actorProp.rotOverrideZ]) + else: + actor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: - actor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) + if int(getEvalParams(actorProp.actor_id_flags), base=0) > 0: + actor.id = f"{actor.id} | {actorProp.actor_id_flags}" + + spawn_flags = [actorProp.rot_flags_x, actorProp.rot_flags_y, actorProp.rot_flags_z] + + if actorProp.rotOverride: + spawn_rot = [ + f"SPAWN_ROT_FLAGS({actorProp.rotOverrideX}", + f"SPAWN_ROT_FLAGS({actorProp.rotOverrideY}", + f"SPAWN_ROT_FLAGS({actorProp.rotOverrideZ}", + ] + else: + spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] + actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actor.name = ( oot_data.actorData.actorsByID[actorProp.actorID].name.replace( diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index f4d42b8f6..dc99b86a7 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -6,7 +6,7 @@ from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import OOTSceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter -from ...utility import get_game_props +from ...utility import get_game_props, is_game_oot, get_cs_index_start from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -49,17 +49,20 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") altProp = get_game_props(sceneObj, "alt_scene") - for i, header in enumerate(altHeaderList, 1): - altP: OOTSceneHeaderProperty = getattr(altProp, f"{header}Header") - if not altP.usePreviousHeader: - setattr( - altHeader, header, SceneHeader.new(f"{name}_header{i:02}", altP, sceneObj, transform, i, useMacros) - ) - hasAlternateHeaders = True + if is_game_oot(): + for i, header in enumerate(altHeaderList, 1): + altP: OOTSceneHeaderProperty = getattr(altProp, f"{header}Header") + if not altP.usePreviousHeader: + setattr( + altHeader, + header, + SceneHeader.new(f"{name}_header{i:02}", altP, sceneObj, transform, i, useMacros), + ) + hasAlternateHeaders = True altHeader.cutscenes = [ SceneHeader.new(f"{name}_header{i:02}", csHeader, sceneObj, transform, i, useMacros) - for i, csHeader in enumerate(altProp.cutsceneHeaders, 4) + for i, csHeader in enumerate(altProp.cutsceneHeaders, 4 if is_game_oot() else 1) ] hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders @@ -122,6 +125,7 @@ def getCmdList(self, curHeader: SceneHeader, hasAltHeaders: bool): + curHeader.entranceActors.getCmd() + (curHeader.exits.getCmd() if len(curHeader.exits.exitList) > 0 else "") + (curHeader.cutscene.getCmd() if len(curHeader.cutscene.entries) > 0 else "") + + (curHeader.map_data.get_cmds() if not is_game_oot() and curHeader.map_data is not None else "") + Utility.getEndCmd() + "};\n\n" ) @@ -136,21 +140,27 @@ def getSceneMainC(self): altHeaderPtrs = None if self.hasAlternateHeaders: - headers = [ - (self.altHeader.childNight, "Child Night"), - (self.altHeader.adultDay, "Adult Day"), - (self.altHeader.adultNight, "Adult Night"), - ] + if is_game_oot(): + headers = [ + (self.altHeader.childNight, "Child Night"), + (self.altHeader.adultDay, "Adult Day"), + (self.altHeader.adultNight, "Adult Night"), + ] for i, csHeader in enumerate(self.altHeader.cutscenes): headers.append((csHeader, f"Cutscene No. {i + 1}")) altHeaderPtrs = "\n".join( - indent + curHeader.name + "," if curHeader is not None else indent + "NULL," if i < 4 else "" + indent + curHeader.name + "," + if curHeader is not None + else indent + "NULL," + if i < get_cs_index_start() + else "" for i, (curHeader, _) in enumerate(headers, 1) ) - headers.insert(0, (self.mainHeader, "Child Day (Default)")) + header_name = "Child Day (Default)" if is_game_oot() else "Default" + headers.insert(0, (self.mainHeader, header_name)) for i, (curHeader, headerDesc) in enumerate(headers): if curHeader is not None: sceneC.source += "/**\n * " + f"Header {headerDesc}\n" + "*/\n" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 007320385..5cae0821f 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, get_game_props +from ...utility import getObjectList, get_game_props, is_game_oot, getEvalParams from ...constants import oot_data from ..utility import Utility from ..actor import Actor @@ -162,7 +162,21 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.id = "ACTOR_PLAYER" if not entranceProp.customActor else entranceProp.actor.actorIDCustom entranceActor.pos = pos - entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) + + if is_game_oot(): + entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) + else: + if int(getEvalParams(entranceProp.actor.actor_id_flags), base=0) > 0: + entranceActor.id = f"{entranceActor.id} | {entranceProp.actor.actor_id_flags}" + + spawn_flags = [ + entranceProp.actor.rot_flags_x, + entranceProp.actor.rot_flags_y, + entranceProp.actor.rot_flags_z, + ] + spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] + entranceActor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) + entranceActor.params = entranceProp.actor.actorParam if entranceProp.tiedRoom is not None: entranceActor.roomIndex = get_game_props(entranceProp.tiedRoom, "room").roomIndex @@ -220,7 +234,7 @@ def getC(self): """Returns the spawn array""" spawnList = CData() - listName = f"Spawn {self.name}" + listName = f"Spawn {self.name}" if is_game_oot() else f"EntranceEntry {self.name}" # .h spawnList.header = f"extern {listName}[];\n" diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 2a1638dea..09d3488b1 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -1,7 +1,15 @@ from dataclasses import dataclass +from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, exportColor, ootGetBaseOrCustomLight, indent -from ...scene.properties import OOTSceneHeaderProperty, OOTLightProperty +from ...utility import is_game_oot, getObjectList, getEvalParams +from ...scene.properties import ( + OOTSceneHeaderProperty, + OOTLightProperty, + MM_SceneHeaderProperty, + MM_MinimapChestProperty, + MM_MinimapRoomProperty, +) from ..utility import Utility @@ -160,13 +168,14 @@ class SceneInfos: # Skybox skyboxID: str skyboxConfig: str + skybox_texture_id: str # MM # Sound sequenceID: str ambienceID: str specID: str - ### Camera And World Map ### + ### Camera And World Map (OoT) ### # World Map worldMapLocation: str @@ -174,38 +183,57 @@ class SceneInfos: # Camera sceneCamType: str + ### REGION VISITED (MM) ### + + set_region_visited: bool + @staticmethod def new(props: OOTSceneHeaderProperty, sceneObj: Object): + if is_game_oot(): + skybox_texture_id = "" + else: + skybox_texture_id = Utility.getPropValue(props, "skybox_texture_id") + return SceneInfos( Utility.getPropValue(props, "globalObject"), - Utility.getPropValue(props, "naviCup"), + Utility.getPropValue(props, "naviCup") if is_game_oot() else "NAVI_QUEST_HINTS_NONE", Utility.getPropValue(props.sceneTableEntry, "drawConfig"), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, Utility.getPropValue(props, "skyboxID"), Utility.getPropValue(props, "skyboxCloudiness"), + skybox_texture_id, Utility.getPropValue(props, "musicSeq"), Utility.getPropValue(props, "nightSeq"), Utility.getPropValue(props, "audioSessionPreset"), - Utility.getPropValue(props, "mapLocation"), - Utility.getPropValue(props, "cameraMode"), + Utility.getPropValue(props, "mapLocation") if is_game_oot() else "", + Utility.getPropValue(props, "cameraMode") if is_game_oot() else "", + props.set_region_visited if not is_game_oot() else False, ) def getCmds(self, lights: SceneLighting): """Returns the sound settings, misc settings, special files and skybox settings scene commands""" + commands = [ + f"SCENE_CMD_SOUND_SETTINGS({self.specID}, {self.ambienceID}, {self.sequenceID})", + f"SCENE_CMD_SPECIAL_FILES({self.naviHintType}, {self.keepObjectID})", + ] - return ( - indent - + f",\n{indent}".join( + if is_game_oot(): + commands.extend( [ - f"SCENE_CMD_SOUND_SETTINGS({self.specID}, {self.ambienceID}, {self.sequenceID})", f"SCENE_CMD_MISC_SETTINGS({self.sceneCamType}, {self.worldMapLocation})", - f"SCENE_CMD_SPECIAL_FILES({self.naviHintType}, {self.keepObjectID})", f"SCENE_CMD_SKYBOX_SETTINGS({self.skyboxID}, {self.skyboxConfig}, {lights.envLightMode})", ] ) - + ",\n" - ) + else: + commands.append( + f"SCENE_CMD_SKYBOX_SETTINGS({self.skybox_texture_id}, {self.skyboxID}, {self.skyboxConfig}, {lights.envLightMode})" + ) + + if self.set_region_visited: + commands.append("SCENE_CMD_SET_REGION_VISITED()") + + return indent + f",\n{indent}".join(commands) + ",\n" @dataclass @@ -249,3 +277,113 @@ def getC(self): ) return exitListC + + +class MapDataChest: + def __init__(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object, transform: Matrix): + if chest_prop.chest_obj is None: + raise PluginError("ERROR: The chest empty object is unset.") + + pos, _, _, _ = Utility.getConvertedTransform(transform, scene_obj, chest_prop.chest_obj, True) + + self.room_idx = self.get_room_index(chest_prop, scene_obj) + self.chest_flag = int(getEvalParams(chest_prop.chest_obj.mm_actor_property.actorParam), base=0) & 0x1F + self.pos = pos + + def get_room_index(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object) -> int: + room_obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Room") + + for room_obj in room_obj_list: + if chest_prop.chest_obj in room_obj.children_recursive: + return room_obj.mm_room_header.roomIndex + + raise PluginError(f"ERROR: Can't find the room associated with '{chest_prop.chest_obj.name}'") + + def to_c(self): + return "{ " + f"{self.room_idx}, {self.chest_flag}, {self.pos[0]}, {self.pos[1]}, {self.pos[2]}" + " }" + + +class MapDataRoom: + def __init__(self, room_prop: MM_MinimapRoomProperty): + self.map_id: str = room_prop.map_id + self.center_x: int = room_prop.center_x + self.floor_y: int = room_prop.floor_y + self.center_z: int = room_prop.center_z + self.flags: str = room_prop.flags + + def to_c(self): + return "{ " + f"{self.map_id}, {self.center_x}, {self.floor_y}, {self.center_z}, {self.flags}" + " }" + + +@dataclass +class SceneMapData: + """This class hosts exit data""" + + name: str + map_scale: int + room_list: list[MapDataRoom] + chest_list: list[MapDataChest] + + @staticmethod + def new(name: str, props: MM_SceneHeaderProperty, scene_obj: Object, transform: Matrix): + return SceneMapData( + name, + props.minimap_scale, + [MapDataRoom(room_prop) for room_prop in props.minimap_room_list], + [MapDataChest(chest_prop, scene_obj, transform) for chest_prop in props.minimap_chest_list], + ) + + def get_cmds(self): + """Returns the sound settings, misc settings, special files and skybox settings scene commands""" + commands = [] + + if len(self.room_list) > 0: + commands.append(f"SCENE_CMD_MAP_DATA(&{self.name})") + + if len(self.chest_list) > 0: + commands.append(f"SCENE_CMD_MAP_DATA_CHESTS({len(self.chest_list)}, {self.name}Chest)") + + if len(commands) > 0: + return indent + f",\n{indent}".join(commands) + ",\n" + + return "" + + def to_c(self): + map_data_c = CData() + scene_list_name = f"MapDataScene {self.name}" + room_list_name = f"MapDataRoom {self.name}Room[{len(self.room_list)}]" + chest_list_name = f"MapDataChest {self.name}Chest[{len(self.chest_list)}]" + map_data_header = [] + map_data_source = "" + + if len(self.room_list) > 0: + map_data_header.extend([f"extern {scene_list_name}", f"extern {room_list_name}"]) + map_data_source += ( + # MapDataRoom + (room_list_name + " = {\n") + + "\n".join(indent + f"{room.to_c()}," for room in self.room_list) + + "\n};\n\n" + # MapDataScene + + (scene_list_name + " = {\n") + + (indent + f"{self.name}Room, {self.map_scale}") + + "\n};\n\n" + ) + + if len(self.chest_list) > 0: + map_data_header.append(f"extern {chest_list_name}") + map_data_source += ( + # MapDataChest + (chest_list_name + " = {\n") + + "\n".join(indent + f"{chest.to_c()}," for chest in self.chest_list) + + "\n};\n\n" + ) + + # .h + if len(map_data_header) > 0: + map_data_c.header = ";\n".join(map_data_header) + + # .c + if len(map_data_source) > 0: + map_data_c.source = map_data_source + + return map_data_c diff --git a/fast64_internal/z64/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py index 72bc8d32f..3e32c7174 100644 --- a/fast64_internal/z64/exporter/scene/header.py +++ b/fast64_internal/z64/exporter/scene/header.py @@ -3,9 +3,10 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData +from ...utility import is_game_oot from ...scene.properties import OOTSceneHeaderProperty from ..cutscene import SceneCutscene -from .general import SceneLighting, SceneInfos, SceneExits +from .general import SceneLighting, SceneInfos, SceneExits, SceneMapData from .actors import SceneTransitionActors, SceneEntranceActors, SceneSpawns from .pathways import ScenePathways @@ -24,6 +25,9 @@ class SceneHeader: spawns: Optional[SceneSpawns] path: Optional[ScenePathways] + # MM + map_data: Optional[SceneMapData] + @staticmethod def new( name: str, props: OOTSceneHeaderProperty, sceneObj: Object, transform: Matrix, headerIndex: int, useMacros: bool @@ -39,6 +43,7 @@ def new( entranceActors, SceneSpawns(f"{name}_entranceList", entranceActors.entries), ScenePathways.new(f"{name}_pathway", sceneObj, transform, headerIndex), + SceneMapData.new(f"{name}_mapData", props, sceneObj, transform) if not is_game_oot() else None, ) def getC(self): @@ -63,6 +68,9 @@ def getC(self): if len(self.lighting.settings) > 0: headerData.append(self.lighting.getC()) + if not is_game_oot() and self.map_data is not None: + headerData.append(self.map_data.to_c()) + # Write the path data, if used if len(self.path.pathList) > 0: headerData.append(self.path.getC()) diff --git a/fast64_internal/z64/importer/classes.py b/fast64_internal/z64/importer/classes.py index 031d1c97e..f099d541c 100644 --- a/fast64_internal/z64/importer/classes.py +++ b/fast64_internal/z64/importer/classes.py @@ -1,5 +1,5 @@ from ...utility import PluginError -from ..utility import getHeaderSettings, is_game_oot +from ..utility import getHeaderSettings, get_cs_index_start from .constants import headerNames @@ -50,9 +50,8 @@ def addHeaderIfItemExists(self, hash, itemType: str, headerIndex: int): actorObj = dictToAdd[hash] headerSettings = getHeaderSettings(actorObj) - cs_start = 4 if is_game_oot() else 1 - if headerIndex < cs_start: + if headerIndex < get_cs_index_start(): setattr(headerSettings, headerNames[headerIndex], True) else: cutsceneHeaders = headerSettings.cutsceneHeaders diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 90ea22741..a8eb93f0c 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,7 @@ import re from ...utility import hexOrDecInt -from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum +from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum, get_cs_index_start from ..model_classes import OOTF3DContext from ..room.properties import OOTRoomHeaderProperty from ..constants import oot_data, mm_data @@ -54,21 +54,16 @@ def parseRoomCommands( get_game_props(roomObj, "room").roomIndex = roomIndex roomObj.name = roomName - if is_game_oot(): - cs_header_start = 4 - else: - cs_header_start = 1 - if headerIndex == 0: roomHeader = get_game_props(roomObj, "room") - elif is_game_oot() and headerIndex < cs_header_start: + elif is_game_oot() and headerIndex < get_cs_index_start(): roomHeader = getattr(get_game_props(roomObj, "alt_room"), headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: cutsceneHeaders = get_game_props(roomObj, "alt_room").cutsceneHeaders - while len(cutsceneHeaders) < headerIndex - (cs_header_start - 1): + while len(cutsceneHeaders) < headerIndex - (get_cs_index_start() - 1): cutsceneHeaders.add() - roomHeader = cutsceneHeaders[headerIndex - cs_header_start] + roomHeader = cutsceneHeaders[headerIndex - get_cs_index_start()] commands = getDataMatch(sceneData, roomCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") for commandMatch in re.finditer(rf"(SCENE\_CMD\_[a-zA-Z0-9\_]*)\s*\((.*?)\)\s*,", commands, flags=re.DOTALL): diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 65403d6bd..366c6cb1f 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -14,6 +14,7 @@ get_game_enum, get_game_props, is_game_oot, + get_cs_index_start, ) from .constants import headerNames from .utility import getDataMatch, stripName @@ -302,21 +303,16 @@ def parseSceneCommands( sceneObj.ootEmptyType = "Scene" sceneObj.name = sceneName - if is_game_oot(): - cs_header_start = 4 - else: - cs_header_start = 1 - if headerIndex == 0: sceneHeader = get_game_props(sceneObj, "scene") - elif is_game_oot() and headerIndex < cs_header_start: + elif is_game_oot() and headerIndex < get_cs_index_start(): sceneHeader = getattr(get_game_props(sceneObj, "alt_scene"), headerNames[headerIndex]) sceneHeader.usePreviousHeader = False else: cutsceneHeaders = get_game_props(sceneObj, "alt_scene").cutsceneHeaders - while len(cutsceneHeaders) < headerIndex - (cs_header_start - 1): + while len(cutsceneHeaders) < headerIndex - (get_cs_index_start() - 1): cutsceneHeaders.add() - sceneHeader = cutsceneHeaders[headerIndex - cs_header_start] + sceneHeader = cutsceneHeaders[headerIndex - get_cs_index_start()] commands = getDataMatch(sceneData, sceneCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") entranceList = None @@ -398,7 +394,7 @@ def parseSceneCommands( elif not is_game_oot(): if command == "SCENE_CMD_SET_REGION_VISITED": sceneHeader.set_region_visited = True - elif command == "SCENE_CMD_MINIMAP_INFO": + elif command in {"SCENE_CMD_MINIMAP_INFO", "SCENE_CMD_MAP_DATA"}: parse_mm_minimap_info(sceneHeader, sceneData, stripName(args[0])) if altHeadersListName is not None: diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index 094054edf..c2b7fd0da 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -4,7 +4,7 @@ from ...utility import PluginError, hexOrDecInt, removeComments, yUpToZUp from ..actor.properties import OOTActorProperty, OOTActorHeaderProperty, MM_ActorHeaderProperty -from ..utility import ootParseRotation, is_game_oot +from ..utility import ootParseRotation, is_game_oot, get_cs_index_start from .constants import headerNames, actorsWithRotAsParam @@ -26,8 +26,7 @@ def unsetAllHeadersExceptSpecified(headerSettings: OOTActorHeaderProperty | MM_A headerSettings.include_in_all_setups = False headerSettings.childDayHeader = headerIndex == 0 - cs_start = 4 if is_game_oot() else 1 - if headerIndex >= cs_start: + if headerIndex >= get_cs_index_start(): headerSettings.cutsceneHeaders.add().headerIndex = headerIndex diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 26213ee53..ec8f09da8 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -9,7 +9,7 @@ from mathutils import Matrix, Vector from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader -from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot +from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot, get_game_props from ..constants import oot_data, mm_data, ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config @@ -203,12 +203,14 @@ def execute(self, context): raisePluginError(self, e) return {"CANCELLED"} try: - settings = context.scene.ootSceneExportSettings + settings = get_game_props(None, "export_settings") levelName = settings.name option = settings.option + hackerFeaturesEnabled = False - bootOptions = context.scene.fast64.oot.bootupSceneOptions - hackerFeaturesEnabled = context.scene.fast64.oot.hackerFeaturesEnabled + if is_game_oot(): + bootOptions = context.scene.fast64.oot.bootupSceneOptions + hackerFeaturesEnabled = context.scene.fast64.oot.hackerFeaturesEnabled if settings.customExport: isCustomExport = True diff --git a/fast64_internal/z64/scene/properties/__init__.py b/fast64_internal/z64/scene/properties/__init__.py index 659d12af2..c81be385d 100644 --- a/fast64_internal/z64/scene/properties/__init__.py +++ b/fast64_internal/z64/scene/properties/__init__.py @@ -12,6 +12,8 @@ ) from .mm_props import ( + MM_MinimapChestProperty, + MM_MinimapRoomProperty, MM_SceneHeaderProperty, MM_AlternateSceneHeaderProperty, MM_ExportSceneSettingsProperty, diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties/mm_props.py index 0343f1572..dc98bd144 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties/mm_props.py @@ -313,7 +313,7 @@ class MM_SceneHeaderProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty(name="Global Object", default="None", items=mm_enum_global_object) + globalObject: EnumProperty(name="Global Object", default="GAMEPLAY_DANGEON_KEEP", items=mm_enum_global_object) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index e4e14e90d..4d33e6022 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -75,28 +75,38 @@ def get_game_enum(enum_type: str): def get_game_props(obj: Object, header_type: str): - game_header_map = { - "OOT": { - "scene": obj.ootSceneHeader, - "alt_scene": obj.ootAlternateSceneHeaders, - "room": obj.ootRoomHeader, - "alt_room": obj.ootAlternateRoomHeaders, - "actor": obj.ootActorProperty, - "transition_actor": obj.ootTransitionActorProperty, - "entrance_actor": obj.ootEntranceProperty, - "path_header_settings": obj.ootSplineProperty.headerSettings, - }, - "MM": { - "scene": obj.mm_scene_header, - "alt_scene": obj.mm_alternate_scene_headers, - "room": obj.mm_room_header, - "alt_room": obj.mm_alternate_room_headers, - "actor": obj.mm_actor_property, - "transition_actor": obj.mm_transition_actor_property, - "entrance_actor": obj.mm_entrance_property, - "path_header_settings": obj.ootSplineProperty.mm_header_settings, - }, - } + if obj is not None: + game_header_map = { + "OOT": { + "scene": obj.ootSceneHeader, + "alt_scene": obj.ootAlternateSceneHeaders, + "room": obj.ootRoomHeader, + "alt_room": obj.ootAlternateRoomHeaders, + "actor": obj.ootActorProperty, + "transition_actor": obj.ootTransitionActorProperty, + "entrance_actor": obj.ootEntranceProperty, + "path_header_settings": obj.ootSplineProperty.headerSettings, + }, + "MM": { + "scene": obj.mm_scene_header, + "alt_scene": obj.mm_alternate_scene_headers, + "room": obj.mm_room_header, + "alt_room": obj.mm_alternate_room_headers, + "actor": obj.mm_actor_property, + "transition_actor": obj.mm_transition_actor_property, + "entrance_actor": obj.mm_entrance_property, + "path_header_settings": obj.ootSplineProperty.mm_header_settings, + }, + } + else: + game_header_map = { + "OOT": { + "export_settings": bpy.context.scene.ootSceneExportSettings, + }, + "MM": { + "export_settings": bpy.context.scene.mm_scene_export_settings, + }, + } return game_header_map[bpy.context.scene.gameEditorMode][header_type] @@ -109,6 +119,10 @@ def isPathObject(obj: bpy.types.Object) -> bool: return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" +def get_cs_index_start(): + return 4 if is_game_oot() else 1 + + ootSceneDungeons = [ "bdan", "bdan_boss", From 21fbb731e5ec22c80ba76a9513bb75997e52db40 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:54:53 +0100 Subject: [PATCH 018/126] small fix --- fast64_internal/z64/exporter/scene/general.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 09d3488b1..67adca628 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -357,7 +357,7 @@ def to_c(self): map_data_source = "" if len(self.room_list) > 0: - map_data_header.extend([f"extern {scene_list_name}", f"extern {room_list_name}"]) + map_data_header.extend([f"extern {scene_list_name};\n", f"extern {room_list_name};\n"]) map_data_source += ( # MapDataRoom (room_list_name + " = {\n") @@ -370,7 +370,7 @@ def to_c(self): ) if len(self.chest_list) > 0: - map_data_header.append(f"extern {chest_list_name}") + map_data_header.append(f"extern {chest_list_name};\n") map_data_source += ( # MapDataChest (chest_list_name + " = {\n") @@ -380,7 +380,7 @@ def to_c(self): # .h if len(map_data_header) > 0: - map_data_c.header = ";\n".join(map_data_header) + map_data_c.header = "".join(map_data_header) # .c if len(map_data_source) > 0: From 3392e47bac6e4fe8fdd37ffb48c02a2bfab9c28b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sat, 21 Dec 2024 01:35:04 +0100 Subject: [PATCH 019/126] door adjustements --- .../z64/actor/properties/mm_props.py | 31 ++++++------------- fast64_internal/z64/exporter/room/header.py | 29 +++++++++++------ fast64_internal/z64/exporter/scene/actors.py | 19 +++++------- fast64_internal/z64/importer/actor.py | 31 ++++++++++--------- fast64_internal/z64/importer/utility.py | 15 ++++++--- fast64_internal/z64/props_panel_main.py | 6 ++-- 6 files changed, 66 insertions(+), 65 deletions(-) diff --git a/fast64_internal/z64/actor/properties/mm_props.py b/fast64_internal/z64/actor/properties/mm_props.py index 9775fb099..478c91503 100644 --- a/fast64_internal/z64/actor/properties/mm_props.py +++ b/fast64_internal/z64/actor/properties/mm_props.py @@ -85,26 +85,13 @@ def draw_props( class MM_ActorProperty(PropertyGroup): actorID: EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") - actor_id_flags: StringProperty(name="Actor ID Flags", default="0x0000") actorParam: StringProperty(name="Actor Parameter", default="0x0000") - rot_flags_x: StringProperty(name="Rot Flags X", default="0x0000") - rot_flags_y: StringProperty(name="Rot Flags Y", default="0x0000") - rot_flags_z: StringProperty(name="Rot Flags Z", default="0x0000") - rotOverride: BoolProperty(name="Override Rotation", default=False) + rotOverride: BoolProperty(name="Override Rotation", default=False, description="Non-zero values means the rotation is used as additional flags and will set the matching flag in the actor ID automatically") rotOverrideX: StringProperty(name="Rot X", default="0") rotOverrideY: StringProperty(name="Rot Y", default="0") rotOverrideZ: StringProperty(name="Rot Z", default="0") headerSettings: PointerProperty(type=MM_ActorHeaderProperty) - def draw_settings(self, layout: UILayout): - prop_split(layout, self, "actorParam", "Actor Parameter") - - flag_box = layout.box() - prop_split(flag_box, self, "actor_id_flags", "Actor ID Flags") - prop_split(flag_box, self, "rot_flags_x", "Rot Flags X") - prop_split(flag_box, self, "rot_flags_y", "Rot Flags Y") - prop_split(flag_box, self, "rot_flags_z", "Rot Flags Z") - def draw_props(self, layout: UILayout, altRoomProp: MM_AlternateRoomHeaderProperty, objName: str): actorIDBox = layout.column() searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") @@ -123,13 +110,14 @@ def draw_props(self, layout: UILayout, altRoomProp: MM_AlternateRoomHeaderProper if self.actorID == "Custom": prop_split(actorIDBox, self, "actorIDCustom", "") - self.draw_settings(actorIDBox) + prop_split(actorIDBox, self, "actorParam", "Actor Parameter") - actorIDBox.prop(self, "rotOverride", text="Override Rotation (ignore Blender rot)") + rot_box = actorIDBox.box() + rot_box.prop(self, "rotOverride", text="Use Rotation Flags") if self.rotOverride: - prop_split(actorIDBox, self, "rotOverrideX", "Rot X") - prop_split(actorIDBox, self, "rotOverrideY", "Rot Y") - prop_split(actorIDBox, self, "rotOverrideZ", "Rot Z") + prop_split(rot_box, self, "rotOverrideX", "Rot X") + prop_split(rot_box, self, "rotOverrideY", "Rot Y") + prop_split(rot_box, self, "rotOverrideZ", "Rot Z") headerProp: MM_ActorHeaderProperty = self.headerSettings headerProp.draw_props(actorIDBox, "Actor", altRoomProp, objName) @@ -143,6 +131,7 @@ class MM_TransitionActorProperty(PropertyGroup): cameraTransitionBack: EnumProperty(items=ootEnumCamTransition, default="0x00") cameraTransitionBackCustom: StringProperty(default="0x00") isRoomTransition: BoolProperty(name="Is Room Transition", default=True) + cutscene_id: StringProperty(name="Cutscene ID", default="CS_ID_GLOBAL_END", description="See the `CutsceneId` enum for more values") actor: PointerProperty(type=MM_ActorProperty) @@ -164,6 +153,7 @@ def draw_props( if self.actor.actorID == "Custom": prop_split(actorIDBox, self.actor, "actorIDCustom", "") + prop_split(actorIDBox, self, "cutscene_id", "Cutscene ID") prop_split(actorIDBox, self.actor, "actorParam", "Actor Parameter") if roomObj is None: @@ -213,8 +203,7 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: MM_AlternateSc prop_split(box, entranceProp, "tiedRoom", "Room") prop_split(box, entranceProp, "spawnIndex", "Spawn Index") - - entranceProp.actor.draw_settings(box) + prop_split(box, self, "actorParam", "Actor Parameter") headerProps: MM_ActorHeaderProperty = entranceProp.actor.headerSettings headerProps.draw_props(box, "Entrance", altSceneProp, objName) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 8309fe893..e8fcfa1b6 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -198,19 +198,28 @@ def new( else: actor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: - if int(getEvalParams(actorProp.actor_id_flags), base=0) > 0: - actor.id = f"{actor.id} | {actorProp.actor_id_flags}" - - spawn_flags = [actorProp.rot_flags_x, actorProp.rot_flags_y, actorProp.rot_flags_z] - if actorProp.rotOverride: - spawn_rot = [ - f"SPAWN_ROT_FLAGS({actorProp.rotOverrideX}", - f"SPAWN_ROT_FLAGS({actorProp.rotOverrideY}", - f"SPAWN_ROT_FLAGS({actorProp.rotOverrideZ}", + actor_flags = [0x4000, 0x8000, 0x2000] + actor_flag_masks = [] + spawn_flags = [ + f"0x{int(getEvalParams(actorProp.rotOverrideX), base=0):02X}", + f"0x{int(getEvalParams(actorProp.rotOverrideY), base=0):02X}", + f"0x{int(getEvalParams(actorProp.rotOverrideZ), base=0):02X}", ] + + for i, rot_flag in enumerate(spawn_flags): + if int(rot_flag, base=0) > 0: + actor_flag_masks.append(actor_flags[i]) + + if len(actor_flag_masks) > 0: + mask = 0 + for val in actor_flag_masks: + mask |= val + actor.id = f"{actor.id} | 0x{mask:04X}" else: - spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] + spawn_flags = ["0x00"] * 3 + + spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actor.name = ( diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 5cae0821f..c528c4158 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -90,7 +90,13 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): ) transActor.pos = pos - transActor.rot = f"DEG_TO_BINANG({(rot[1] * (180 / 0x8000)):.3f})" # TODO: Correct axis? + + rot_deg = (rot[1] * (180 / 0x8000)) + if is_game_oot(): + transActor.rot = f"DEG_TO_BINANG({rot_deg:.3f})" # TODO: Correct axis? + else: + transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({transActorProp.cutscene_id} & 0x7F)" + transActor.params = transActorProp.actor.actorParam transActor.roomFrom, transActor.cameraFront = front transActor.roomTo, transActor.cameraBack = back @@ -166,16 +172,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if is_game_oot(): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: - if int(getEvalParams(entranceProp.actor.actor_id_flags), base=0) > 0: - entranceActor.id = f"{entranceActor.id} | {entranceProp.actor.actor_id_flags}" - - spawn_flags = [ - entranceProp.actor.rot_flags_x, - entranceProp.actor.rot_flags_y, - entranceProp.actor.rot_flags_z, - ] - spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] - entranceActor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) + entranceActor.rot = ", ".join(f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f}), 0x00)" for r in rot) entranceActor.params = entranceProp.actor.actorParam if entranceProp.tiedRoom is not None: diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index e81007274..300972f8e 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -35,6 +35,13 @@ def parseTransActorList( position = tuple([hexOrDecInt(value) for value in params[5:8]]) rotY = getEvalParams(params[8]) if "DEG_TO_BINANG" in params[8] else params[8] + cutscene_id = "CS_ID_GLOBAL_END" + + if not is_game_oot(): + rotY_int = int(rotY, base=0) + rotY = f"0x{(rotY_int >> 7) & 0x1FF:04X}" + cutscene_id = f"0x{rotY_int & 0x7F:02X}" + rotation = tuple([0, hexOrDecInt(rotY), 0]) roomIndexFront = hexOrDecInt(params[0]) @@ -53,6 +60,7 @@ def parseTransActorList( position, rotation, actorParam, + cutscene_id, ) if not sharedSceneData.addHeaderIfItemExists(actorHash, "Transition Actor", headerIndex): actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) @@ -73,6 +81,9 @@ def parseTransActorList( transActorProp.isRoomTransition = False parentObject(toRoom, actorObj) + if not is_game_oot(): + transActorProp.cutscene_id = cutscene_id + setCustomProperty(transActorProp, "cameraTransitionFront", camFront, ootEnumCamTransition) setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition) @@ -107,8 +118,8 @@ def parseEntranceList( def parseActorInfo( actorMatch: re.Match, nestedBrackets: bool ) -> tuple[str, str, list[int], tuple[int], tuple[int], str]: - spawn_flags = ["0x0000"] * 3 - actor_id_flags = "0x0000" + spawn_flags = [0x0000] * 3 + actor_id_flags = 0x0000 if nestedBrackets: actorID = actorMatch.group(1).strip() @@ -136,7 +147,7 @@ def parseActorInfo( if value != "": rot, flags = value.removeprefix("(").removesuffix(",").removesuffix(")").split(",") spawn_rotation.append(hexOrDecInt(getEvalParams(rot))) - spawn_flags.append(flags) + spawn_flags.append(hexOrDecInt(getEvalParams(flags))) actorParam = actorMatch.group(4).strip() else: @@ -149,14 +160,6 @@ def parseActorInfo( return actorID, actor_id_flags, position, tuple(spawn_rotation), tuple(spawn_flags), actorParam -def set_actor_flags(actor_prop, actor_id_flags: str, spawn_flags: tuple[str, str, str]): - if not is_game_oot(): - actor_prop.actor_id_flags = actor_id_flags - actor_prop.rot_flags_x = spawn_flags[0] - actor_prop.rot_flags_y = spawn_flags[1] - actor_prop.rot_flags_z = spawn_flags[2] - - def parseSpawnList( roomObjs: list[bpy.types.Object], sceneData: str, @@ -185,10 +188,9 @@ def parseSpawnList( spawnProp.spawnIndex = spawnIndex spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor - set_actor_flags(actorProp, actor_id_flags, spawn_flags) setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam - handleActorWithRotAsParam(actorProp, actorID, rotation) + handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) sharedSceneData.entranceDict[actorHash] = spawnObj @@ -223,10 +225,9 @@ def parseActorList( actorObj.ootEmptyType = "Actor" actorObj.name = getDisplayNameFromActorID(actorID) actorProp = get_game_props(actorObj, "actor") - set_actor_flags(actorProp, actor_id_flags, spawn_flags) setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam - handleActorWithRotAsParam(actorProp, actorID, rotation) + handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) sharedSceneData.actorDict[actorHash] = actorObj diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index c2b7fd0da..781c4709f 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -51,11 +51,16 @@ def getDisplayNameFromActorID(actorID: str): def handleActorWithRotAsParam(actorProp: OOTActorProperty, actorID: str, rotation: list[int]): - if actorID in actorsWithRotAsParam: - actorProp.rotOverride = True - actorProp.rotOverrideX = hex(rotation[0]) - actorProp.rotOverrideY = hex(rotation[1]) - actorProp.rotOverrideZ = hex(rotation[2]) + if is_game_oot(): + if actorID in actorsWithRotAsParam: + actorProp.rotOverride = True + else: + actorProp.rotOverride = rotation[0] != 0 or rotation[1] != 0 or rotation[2] != 0 + + if actorProp.rotOverride: + actorProp.rotOverrideX = f"0x{rotation[0]:04X}" + actorProp.rotOverrideY = f"0x{rotation[1]:04X}" + actorProp.rotOverrideZ = f"0x{rotation[2]:04X}" def getDataMatch( diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 89583d0db..bfd9c810e 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj, get_game_props +from .utility import getSceneObj, getRoomObj, get_game_props, is_game_oot from .scene.properties import OOTSceneProperties from .room.properties import OOTObjectProperty, OOTRoomHeaderProperty, OOTAlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -201,7 +201,7 @@ class OOT_ObjectProperties(bpy.types.PropertyGroup): @staticmethod def upgrade_changed_props(): for obj in bpy.data.objects: - if obj.type == "EMPTY": + if obj.type == "EMPTY" and is_game_oot(): if obj.ootEmptyType == "Room": OOTObjectProperty.upgrade_object(obj) if obj.ootEmptyType in {"Entrance", "Transition Actor"}: @@ -218,7 +218,7 @@ def upgrade_changed_props(): obj.ootEmptyType = "CS Dummy Cue" else: print("WARNING: An Actor Cue has been detected outside an Actor Cue List: " + obj.name) - elif obj.type == "ARMATURE": + elif obj.type == "ARMATURE" and is_game_oot(): parentObj = obj.parent if parentObj is not None and ( parentObj.name.startswith("Cutscene.") or parentObj.ootEmptyType == "Cutscene" From 28ccd1e699012f8d6e03d6375aa9ffd390fead44 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:47:00 +0100 Subject: [PATCH 020/126] merge OoT and MM for scene properties (1/2) --- fast64_internal/z64/__init__.py | 8 +- .../z64/actor/properties/mm_props.py | 21 +- .../z64/actor/properties/oot_props.py | 10 +- .../z64/exporter/cutscene/__init__.py | 4 +- .../z64/exporter/decomp_edit/config.py | 8 +- .../z64/exporter/scene/__init__.py | 4 +- fast64_internal/z64/exporter/scene/actors.py | 6 +- fast64_internal/z64/exporter/scene/general.py | 15 +- fast64_internal/z64/exporter/scene/header.py | 9 +- fast64_internal/z64/importer/actor.py | 4 +- fast64_internal/z64/importer/scene.py | 4 +- fast64_internal/z64/importer/scene_header.py | 10 +- fast64_internal/z64/scene/operators.py | 22 +- fast64_internal/z64/scene/panels.py | 36 +- .../{properties/mm_props.py => properties.py} | 404 +++++++----- .../z64/scene/properties/__init__.py | 24 - .../z64/scene/properties/oot_props.py | 593 ------------------ fast64_internal/z64/spline/properties.py | 4 +- fast64_internal/z64/utility.py | 10 +- 19 files changed, 336 insertions(+), 860 deletions(-) rename fast64_internal/z64/scene/{properties/mm_props.py => properties.py} (63%) delete mode 100644 fast64_internal/z64/scene/properties/__init__.py delete mode 100644 fast64_internal/z64/scene/properties/oot_props.py diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index da0041623..b98410871 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -3,11 +3,9 @@ from .scene.operators import scene_ops_register, scene_ops_unregister from .scene.properties import ( - OOTBootupSceneOptions, + OOT_BootupSceneOptions, scene_props_register, scene_props_unregister, - mm_scene_props_register, - mm_scene_props_unregister, ) from .scene.panels import scene_panels_register, scene_panels_unregister @@ -106,7 +104,7 @@ class OOT_Properties(bpy.types.PropertyGroup): headerTabAffectsVisibility: bpy.props.BoolProperty( default=False, name="Header Sets Actor Visibility", update=setAllActorsVisibility ) - bootupSceneOptions: bpy.props.PointerProperty(type=OOTBootupSceneOptions) + bootupSceneOptions: bpy.props.PointerProperty(type=OOT_BootupSceneOptions) DLExportSettings: bpy.props.PointerProperty(type=OOTDLExportSettings) DLImportSettings: bpy.props.PointerProperty(type=OOTDLImportSettings) skeletonExportSettings: bpy.props.PointerProperty(type=OOTSkeletonExportSettings) @@ -175,7 +173,6 @@ def oot_register(registerPanels): cutscene_props_register() scene_ops_register() scene_props_register() - mm_scene_props_register() room_ops_register() room_props_register() mm_room_props_register() @@ -218,7 +215,6 @@ def oot_unregister(unregisterPanels): cutscene_props_unregister() scene_ops_unregister() scene_props_unregister() - mm_scene_props_unregister() room_ops_unregister() room_props_unregister() mm_room_props_unregister() diff --git a/fast64_internal/z64/actor/properties/mm_props.py b/fast64_internal/z64/actor/properties/mm_props.py index 478c91503..c575793d3 100644 --- a/fast64_internal/z64/actor/properties/mm_props.py +++ b/fast64_internal/z64/actor/properties/mm_props.py @@ -4,7 +4,6 @@ from ....utility import prop_split, label_split from ...constants import mm_data, ootEnumCamTransition from ...upgrade import upgradeActors -from ...scene.properties import MM_AlternateSceneHeaderProperty from ...room.properties import MM_AlternateRoomHeaderProperty from ..operators import MM_SearchActorIDEnumOperator @@ -25,7 +24,7 @@ def draw_props( layout: UILayout, propUser: str, index: int, - altProp: MM_AlternateSceneHeaderProperty | MM_AlternateRoomHeaderProperty, + altProp: MM_AlternateRoomHeaderProperty, objName: str, ): box = layout.column() @@ -54,7 +53,7 @@ def draw_props( self, layout: UILayout, propUser: str, - altProp: MM_AlternateSceneHeaderProperty | MM_AlternateRoomHeaderProperty, + altProp: MM_AlternateRoomHeaderProperty, objName: str, ): headerSetup = layout.column() @@ -86,7 +85,11 @@ class MM_ActorProperty(PropertyGroup): actorID: EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") actorParam: StringProperty(name="Actor Parameter", default="0x0000") - rotOverride: BoolProperty(name="Override Rotation", default=False, description="Non-zero values means the rotation is used as additional flags and will set the matching flag in the actor ID automatically") + rotOverride: BoolProperty( + name="Override Rotation", + default=False, + description="Non-zero values means the rotation is used as additional flags and will set the matching flag in the actor ID automatically", + ) rotOverrideX: StringProperty(name="Rot X", default="0") rotOverrideY: StringProperty(name="Rot Y", default="0") rotOverrideZ: StringProperty(name="Rot Z", default="0") @@ -131,16 +134,16 @@ class MM_TransitionActorProperty(PropertyGroup): cameraTransitionBack: EnumProperty(items=ootEnumCamTransition, default="0x00") cameraTransitionBackCustom: StringProperty(default="0x00") isRoomTransition: BoolProperty(name="Is Room Transition", default=True) - cutscene_id: StringProperty(name="Cutscene ID", default="CS_ID_GLOBAL_END", description="See the `CutsceneId` enum for more values") + cutscene_id: StringProperty( + name="Cutscene ID", default="CS_ID_GLOBAL_END", description="See the `CutsceneId` enum for more values" + ) actor: PointerProperty(type=MM_ActorProperty) def isRoomEmptyObject(self, obj: Object): return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - def draw_props( - self, layout: UILayout, altSceneProp: MM_AlternateSceneHeaderProperty, roomObj: Object, objName: str - ): + def draw_props(self, layout: UILayout, altSceneProp, roomObj: Object, objName: str): actorIDBox = layout.column() searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") searchOp.actorUser = "Transition Actor" @@ -188,7 +191,7 @@ class MM_EntranceProperty(PropertyGroup): def isRoomEmptyObject(self, obj: Object): return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - def draw_props(self, layout: UILayout, obj: Object, altSceneProp: MM_AlternateSceneHeaderProperty, objName: str): + def draw_props(self, layout: UILayout, obj: Object, altSceneProp, objName: str): box = layout.column() roomObj = getRoomObj(obj) diff --git a/fast64_internal/z64/actor/properties/oot_props.py b/fast64_internal/z64/actor/properties/oot_props.py index d825a2470..937219c50 100644 --- a/fast64_internal/z64/actor/properties/oot_props.py +++ b/fast64_internal/z64/actor/properties/oot_props.py @@ -4,7 +4,7 @@ from ....utility import prop_split, label_split from ...constants import oot_data, ootEnumCamTransition from ...upgrade import upgradeActors -from ...scene.properties import OOTAlternateSceneHeaderProperty +from ...scene.properties import Z64_AlternateSceneHeaderProperty from ...room.properties import OOTAlternateRoomHeaderProperty from ..operators import OOT_SearchActorIDEnumOperator @@ -31,7 +31,7 @@ def draw_props( layout: UILayout, propUser: str, index: int, - altProp: OOTAlternateSceneHeaderProperty | OOTAlternateRoomHeaderProperty, + altProp: Z64_AlternateSceneHeaderProperty | OOTAlternateRoomHeaderProperty, objName: str, ): box = layout.column() @@ -66,7 +66,7 @@ def draw_props( self, layout: UILayout, propUser: str, - altProp: OOTAlternateSceneHeaderProperty | OOTAlternateRoomHeaderProperty, + altProp: Z64_AlternateSceneHeaderProperty | OOTAlternateRoomHeaderProperty, objName: str, ): headerSetup = layout.column() @@ -170,7 +170,7 @@ def isRoomEmptyObject(self, obj: Object): return obj.type == "EMPTY" and obj.ootEmptyType == "Room" def draw_props( - self, layout: UILayout, altSceneProp: OOTAlternateSceneHeaderProperty, roomObj: Object, objName: str + self, layout: UILayout, altSceneProp: Z64_AlternateSceneHeaderProperty, roomObj: Object, objName: str ): actorIDBox = layout.column() searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") @@ -219,7 +219,7 @@ class OOTEntranceProperty(PropertyGroup): def isRoomEmptyObject(self, obj: Object): return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - def draw_props(self, layout: UILayout, obj: Object, altSceneProp: OOTAlternateSceneHeaderProperty, objName: str): + def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateSceneHeaderProperty, objName: str): box = layout.column() # box.box().label(text = "Properties") roomObj = getRoomObj(obj) diff --git a/fast64_internal/z64/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py index 8895b114c..8303e2d45 100644 --- a/fast64_internal/z64/exporter/cutscene/__init__.py +++ b/fast64_internal/z64/exporter/cutscene/__init__.py @@ -5,7 +5,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getCustomProperty -from ...scene.properties import OOTSceneHeaderProperty +from ...scene.properties import Z64_SceneHeaderProperty from .data import CutsceneData @@ -102,7 +102,7 @@ class SceneCutscene: entries: list[Cutscene] @staticmethod - def new(props: OOTSceneHeaderProperty, headerIndex: int, useMacros: bool): + def new(props: Z64_SceneHeaderProperty, headerIndex: int, useMacros: bool): csObj: Object = props.csWriteObject cutsceneObjects: list[Object] = [csObj for csObj in props.extraCutscenes] entries: list[Cutscene] = [] diff --git a/fast64_internal/z64/exporter/decomp_edit/config.py b/fast64_internal/z64/exporter/decomp_edit/config.py index a11eec82e..7c1069c63 100644 --- a/fast64_internal/z64/exporter/decomp_edit/config.py +++ b/fast64_internal/z64/exporter/decomp_edit/config.py @@ -2,7 +2,7 @@ import re from ....utility import PluginError, readFile, writeFile -from ...scene.properties import OOTBootupSceneOptions +from ...scene.properties import OOT_BootupSceneOptions class Config: @@ -64,8 +64,8 @@ def writeBootupSettings( writeFile(configPath, data) @staticmethod - def setBootupScene(configPath: str, entranceIndex: str, options: "OOTBootupSceneOptions"): - # ``options`` argument type: OOTBootupSceneOptions + def setBootupScene(configPath: str, entranceIndex: str, options: "OOT_BootupSceneOptions"): + # ``options`` argument type: OOT_BootupSceneOptions linkAge = "LINK_AGE_CHILD" timeOfDay = "NEXT_TIME_NONE" cutsceneIndex = "0xFFEF" @@ -108,7 +108,7 @@ def clearBootupScene(configPath: str): ) @staticmethod - def getParamsFromOptions(options: "OOTBootupSceneOptions") -> tuple[str, str]: + def getParamsFromOptions(options: "OOT_BootupSceneOptions") -> tuple[str, str]: timeOfDay = ( "NEXT_TIME_DAY" if options.headerOption == "Child Day" or options.headerOption == "Adult Day" diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index dc99b86a7..dd90b5da6 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -4,7 +4,7 @@ from typing import Optional from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod -from ...scene.properties import OOTSceneHeaderProperty +from ...scene.properties import Z64_SceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter from ...utility import get_game_props, is_game_oot, get_cs_index_start from ..file import SceneFile @@ -51,7 +51,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex if is_game_oot(): for i, header in enumerate(altHeaderList, 1): - altP: OOTSceneHeaderProperty = getattr(altProp, f"{header}Header") + altP: Z64_SceneHeaderProperty = getattr(altProp, f"{header}Header") if not altP.usePreviousHeader: setattr( altHeader, diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index c528c4158..bbba05dc4 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -91,7 +91,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.pos = pos - rot_deg = (rot[1] * (180 / 0x8000)) + rot_deg = rot[1] * (180 / 0x8000) if is_game_oot(): transActor.rot = f"DEG_TO_BINANG({rot_deg:.3f})" # TODO: Correct axis? else: @@ -172,7 +172,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if is_game_oot(): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: - entranceActor.rot = ", ".join(f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f}), 0x00)" for r in rot) + entranceActor.rot = ", ".join( + f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f}), 0x00)" for r in rot + ) entranceActor.params = entranceProp.actor.actorParam if entranceProp.tiedRoom is not None: diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 67adca628..495082b9f 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -4,9 +4,8 @@ from ....utility import PluginError, CData, exportColor, ootGetBaseOrCustomLight, indent from ...utility import is_game_oot, getObjectList, getEvalParams from ...scene.properties import ( - OOTSceneHeaderProperty, - OOTLightProperty, - MM_SceneHeaderProperty, + Z64_SceneHeaderProperty, + Z64_LightProperty, MM_MinimapChestProperty, MM_MinimapRoomProperty, ) @@ -97,9 +96,9 @@ class SceneLighting: settings: list[EnvLightSettings] @staticmethod - def new(name: str, props: OOTSceneHeaderProperty): + def new(name: str, props: Z64_SceneHeaderProperty): envLightMode = Utility.getPropValue(props, "skyboxLighting") - lightList: list[OOTLightProperty] = [] + lightList: list[Z64_LightProperty] = [] settings: list[EnvLightSettings] = [] if envLightMode == "LIGHT_MODE_TIME": @@ -188,7 +187,7 @@ class SceneInfos: set_region_visited: bool @staticmethod - def new(props: OOTSceneHeaderProperty, sceneObj: Object): + def new(props: Z64_SceneHeaderProperty, sceneObj: Object): if is_game_oot(): skybox_texture_id = "" else: @@ -244,7 +243,7 @@ class SceneExits(Utility): exitList: list[tuple[int, str]] @staticmethod - def new(name: str, props: OOTSceneHeaderProperty): + def new(name: str, props: Z64_SceneHeaderProperty): # TODO: proper implementation of exits exitList: list[tuple[int, str]] = [] @@ -325,7 +324,7 @@ class SceneMapData: chest_list: list[MapDataChest] @staticmethod - def new(name: str, props: MM_SceneHeaderProperty, scene_obj: Object, transform: Matrix): + def new(name: str, props: Z64_SceneHeaderProperty, scene_obj: Object, transform: Matrix): return SceneMapData( name, props.minimap_scale, diff --git a/fast64_internal/z64/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py index 3e32c7174..ade72636b 100644 --- a/fast64_internal/z64/exporter/scene/header.py +++ b/fast64_internal/z64/exporter/scene/header.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import CData from ...utility import is_game_oot -from ...scene.properties import OOTSceneHeaderProperty +from ...scene.properties import Z64_SceneHeaderProperty from ..cutscene import SceneCutscene from .general import SceneLighting, SceneInfos, SceneExits, SceneMapData from .actors import SceneTransitionActors, SceneEntranceActors, SceneSpawns @@ -30,7 +30,12 @@ class SceneHeader: @staticmethod def new( - name: str, props: OOTSceneHeaderProperty, sceneObj: Object, transform: Matrix, headerIndex: int, useMacros: bool + name: str, + props: Z64_SceneHeaderProperty, + sceneObj: Object, + transform: Matrix, + headerIndex: int, + useMacros: bool, ): entranceActors = SceneEntranceActors.new(f"{name}_playerEntryList", sceneObj, transform, headerIndex) return SceneHeader( diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 300972f8e..1a63f5c96 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -2,7 +2,7 @@ import bpy from ...utility import parentObject, hexOrDecInt -from ..scene.properties import OOTSceneHeaderProperty +from ..scene.properties import Z64_SceneHeaderProperty from ..utility import setCustomProperty, getEvalParams, get_game_props, is_game_oot, get_game_enum from ..constants import ootEnumCamTransition from .classes import SharedSceneData @@ -95,7 +95,7 @@ def parseTransActorList( def parseEntranceList( - sceneHeader: OOTSceneHeaderProperty, roomObjs: list[bpy.types.Object], sceneData: str, entranceListName: str + sceneHeader: Z64_SceneHeaderProperty, roomObjs: list[bpy.types.Object], sceneData: str, entranceListName: str ): entranceList = getDataMatch(sceneData, entranceListName, ["EntranceEntry", "Spawn"], "entrance List") diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 869a569de..cf855136c 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -9,7 +9,7 @@ from ...f3d.flipbook import TextureFlipbook from ..model_classes import OOTF3DContext from ..exporter.decomp_edit.scene_table import SceneTableUtility -from ..scene.properties import OOTImportSceneSettingsProperty, MM_ImportSceneSettingsProperty +from ..scene.properties import Z64_ImportSceneSettingsProperty from ..constants import ootEnumDrawConfig, mm_enum_draw_config from .scene_header import parseSceneCommands from .classes import SharedSceneData @@ -90,7 +90,7 @@ def parseDrawConfig(drawConfigName: str, sceneData: str, drawConfigData: str, f3 def parseScene( - settings: OOTImportSceneSettingsProperty | MM_ImportSceneSettingsProperty, + settings: Z64_ImportSceneSettingsProperty, option: str, ): sceneName = settings.name diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 366c6cb1f..7fdd032b4 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -7,7 +7,7 @@ from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext -from ..scene.properties import OOTSceneHeaderProperty, OOTLightProperty, MM_SceneHeaderProperty +from ..scene.properties import Z64_SceneHeaderProperty, Z64_LightProperty from ..utility import ( getEvalParams, setCustomProperty, @@ -67,7 +67,7 @@ def parseDirection(index: int, values: tuple[str, str, str]) -> tuple[float, flo def parseLight( - lightHeader: OOTLightProperty, index: int, rotation: mathutils.Euler, color: mathutils.Vector + lightHeader: Z64_LightProperty, index: int, rotation: mathutils.Euler, color: mathutils.Vector ) -> bpy.types.Object | None: setattr(lightHeader, f"useCustomDiffuse{index}", rotation != "Zero" and rotation != "Default") @@ -88,7 +88,7 @@ def parseLight( def parseLightList( sceneObj: bpy.types.Object, - sceneHeader: OOTSceneHeaderProperty | MM_SceneHeaderProperty, + sceneHeader: Z64_SceneHeaderProperty, sceneData: str, lightListName: str, headerIndex: int, @@ -163,7 +163,7 @@ def parseLightList( index += 1 -def parseExitList(sceneHeader: OOTSceneHeaderProperty | MM_SceneHeaderProperty, sceneData: str, exitListName: str): +def parseExitList(sceneHeader: Z64_SceneHeaderProperty, sceneData: str, exitListName: str): exitData = getDataMatch(sceneData, exitListName, "u16", "exit list") # see also start position list @@ -256,7 +256,7 @@ def twos_complement(hexstr: str, bits: int): return value -def parse_mm_minimap_info(scene_header: MM_SceneHeaderProperty, scene_data: str, list_name: str): +def parse_mm_minimap_info(scene_header, scene_data: str, list_name: str): data_match = getDataMatch(scene_data, list_name, ["MapDataScene", "MinimapList"], "minimap scene", False) scene_map_data = data_match.strip().split(", ") scene_header.minimap_scale = int(scene_map_data[1], base=0) diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index ec8f09da8..61809a747 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -33,11 +33,8 @@ def dummy_view_layer_update(context): def parseSceneFunc(): - if is_game_oot(): - settings = bpy.context.scene.ootSceneImportSettings - else: - settings = bpy.context.scene.mm_scene_import_settings - parseScene(settings, settings.option) + settings = bpy.context.scene.ootSceneImportSettings + parseScene(settings, settings.option if is_game_oot() else settings.mm_option) class OOT_SearchSceneEnumOperator(Operator): @@ -79,11 +76,11 @@ class MM_SearchSceneEnumOperator(Operator): def execute(self, context): if self.op_name == "Export": - context.scene.mm_scene_export_settings.option = self.scene_id + context.scene.ootSceneExportSettings.mm_option = self.scene_id elif self.op_name == "Import": - context.scene.mm_scene_import_settings.option = self.scene_id + context.scene.ootSceneImportSettings.mm_option = self.scene_id elif self.op_name == "Remove": - context.scene.mm_scene_remove_settings.option = self.scene_id + context.scene.ootSceneRemoveSettings.mm_option = self.scene_id else: raise Exception(f'Invalid MM scene search operator name: "{self.op_name}"') @@ -205,7 +202,7 @@ def execute(self, context): try: settings = get_game_props(None, "export_settings") levelName = settings.name - option = settings.option + option = settings.option if is_game_oot() else settings.mm_option hackerFeaturesEnabled = False if is_game_oot(): @@ -276,11 +273,8 @@ class OOT_RemoveScene(Operator): bl_options = {"REGISTER", "UNDO"} def execute(self, context): - if context.scene.gameEditorMode == "OOT": - settings = context.scene.ootSceneRemoveSettings # Type: OOTRemoveSceneSettingsProperty - else: - settings = context.scene.mm_scene_remove_settings # Type: MM_RemoveSceneSettingsProperty - option = settings.option + settings = context.scene.ootSceneRemoveSettings # Type: Z64_RemoveSceneSettingsProperty + option = settings.option if is_game_oot() else settings.mm_option if settings.customExport: self.report({"ERROR"}, "You can only remove scenes from your decomp path.") diff --git a/fast64_internal/z64/scene/panels.py b/fast64_internal/z64/scene/panels.py index add87e0b6..7cbf32a49 100644 --- a/fast64_internal/z64/scene/panels.py +++ b/fast64_internal/z64/scene/panels.py @@ -7,13 +7,10 @@ from ..constants import ootEnumSceneID, mm_enum_scene_id from ..utility import getEnumName, is_game_oot from .properties import ( - OOTExportSceneSettingsProperty, - OOTImportSceneSettingsProperty, - OOTRemoveSceneSettingsProperty, - OOTBootupSceneOptions, - MM_ExportSceneSettingsProperty, - MM_ImportSceneSettingsProperty, - MM_RemoveSceneSettingsProperty, + Z64_ExportSceneSettingsProperty, + Z64_ImportSceneSettingsProperty, + Z64_RemoveSceneSettingsProperty, + OOT_BootupSceneOptions, ) from .operators import ( @@ -47,24 +44,16 @@ def draw(self, context): exportBox = col.box().column() exportBox.label(text="Scene Exporter") - if is_game_oot(): - settings: OOTExportSceneSettingsProperty = context.scene.ootSceneExportSettings - importSettings: OOTImportSceneSettingsProperty = context.scene.ootSceneImportSettings - removeSettings: OOTRemoveSceneSettingsProperty = context.scene.ootSceneRemoveSettings - else: - settings: MM_ExportSceneSettingsProperty = context.scene.mm_scene_export_settings - importSettings: MM_ImportSceneSettingsProperty = context.scene.mm_scene_import_settings - removeSettings: MM_RemoveSceneSettingsProperty = context.scene.mm_scene_remove_settings - + settings: Z64_ExportSceneSettingsProperty = context.scene.ootSceneExportSettings if not settings.customExport: - self.drawSceneSearchOp(exportBox, settings.option, "Export") + self.drawSceneSearchOp(exportBox, settings.option if is_game_oot() else settings.mm_option, "Export") settings.draw_props(exportBox) if context.scene.fast64.oot.hackerFeaturesEnabled: hackerOoTBox = exportBox.box().column() hackerOoTBox.label(text="HackerOoT Options") - bootOptions: OOTBootupSceneOptions = context.scene.fast64.oot.bootupSceneOptions + bootOptions: OOT_BootupSceneOptions = context.scene.fast64.oot.bootupSceneOptions bootOptions.draw_props(hackerOoTBox) hackerOoTBox.label( @@ -78,17 +67,22 @@ def draw(self, context): importBox = col.box().column() importBox.label(text="Scene Importer") + importSettings: Z64_ImportSceneSettingsProperty = context.scene.ootSceneImportSettings + option = importSettings.option if is_game_oot() else importSettings.mm_option + if not importSettings.isCustomDest: - self.drawSceneSearchOp(importBox, importSettings.option, "Import") + self.drawSceneSearchOp(importBox, option, "Import") - importSettings.draw_props(importBox, importSettings.option) + importSettings.draw_props(importBox, option) importBox.operator(OOT_ImportScene.bl_idname) # Remove Scene removeBox = col.box().column() removeBox.label(text="Remove Scene") - self.drawSceneSearchOp(removeBox, removeSettings.option, "Remove") + removeSettings: Z64_RemoveSceneSettingsProperty = context.scene.ootSceneRemoveSettings + option = removeSettings.option if is_game_oot() else removeSettings.mm_option + self.drawSceneSearchOp(removeBox, option, "Remove") removeSettings.draw_props(removeBox) removeRow = removeBox.row() diff --git a/fast64_internal/z64/scene/properties/mm_props.py b/fast64_internal/z64/scene/properties.py similarity index 63% rename from fast64_internal/z64/scene/properties/mm_props.py rename to fast64_internal/z64/scene/properties.py index dc98bd144..ebd8a971c 100644 --- a/fast64_internal/z64/scene/properties/mm_props.py +++ b/fast64_internal/z64/scene/properties.py @@ -1,8 +1,5 @@ -# WORK IN PROGRESS! - import bpy - -from bpy.types import PropertyGroup, Object, Light, UILayout, Scene +from bpy.types import PropertyGroup, Object, Light, UILayout, Scene, Context from bpy.props import ( EnumProperty, IntProperty, @@ -13,31 +10,40 @@ FloatVectorProperty, ) from bpy.utils import register_class, unregister_class -from ....render_settings import on_update_oot_render_settings -from ....utility import prop_split, customExportWarning -from ...cutscene.constants import ootEnumCSWriteType +from ...render_settings import on_update_oot_render_settings +from ...utility import prop_split, customExportWarning +from ..cutscene.constants import ootEnumCSWriteType -from ...utility import ( +from ..utility import ( onMenuTabChange, onHeaderMenuTabChange, drawCollectionOps, drawEnumWithCustom, drawAddButton, + is_game_oot, + get_cs_index_start, ) -from ...constants import ( - mm_data, - mm_enum_scene_id, - mm_enum_global_object, - mm_enum_skybox, - mm_enum_skybox_config, +from ..constants import ( + oot_data, + ootEnumSceneID, + ootEnumGlobalObject, + ootEnumNaviHints, + ootEnumSkybox, + ootEnumCloudiness, ootEnumSkyboxLighting, ootEnumMapLocation, ootEnumCameraMode, ootEnumAudioSessionPreset, ootEnumHeaderMenu, - mm_enum_draw_config, + ootEnumDrawConfig, ootEnumHeaderMenuComplete, + mm_data, + mm_enum_scene_id, + mm_enum_global_object, + mm_enum_skybox, + mm_enum_skybox_config, + mm_enum_draw_config, ) ootEnumSceneMenuAlternate = [ @@ -101,14 +107,14 @@ class OOTSceneProperties(PropertyGroup): ) -class MM_ExitProperty(PropertyGroup): +class Z64_ExitProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") exitIndex: EnumProperty(items=ootEnumExitIndex, default="Default") exitIndexCustom: StringProperty(default="0x0000") # These are used when adding an entry to gEntranceTable - scene: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + scene: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") sceneCustom: StringProperty(default="SCENE_DEKU_TREE") # These are used when adding an entry to gEntranceTable @@ -125,7 +131,7 @@ def draw_props(self, layout: UILayout, index: int, headerIndex: int, objName: st if self.expandTab: drawCollectionOps(box, index, "Exit", headerIndex, objName) drawEnumWithCustom(box, self, "exitIndex", "Exit Index", "") - if self.exitIndex != "Custom": + if is_game_oot() and self.exitIndex != "Custom": box.label(text='This is unfinished, use "Custom".') exitGroup = box.column() exitGroup.enabled = False @@ -136,7 +142,7 @@ def draw_props(self, layout: UILayout, index: int, headerIndex: int, objName: st drawEnumWithCustom(exitGroup, self, "fadeOutAnim", "Fade Out Animation", "") -class OOTLightProperty(PropertyGroup): +class Z64_LightProperty(PropertyGroup): ambient: FloatVectorProperty( name="Ambient Color", size=4, @@ -218,13 +224,13 @@ def draw_props( prop_split(box, self, "transitionSpeed", "Transition Speed") -class OOTLightGroupProperty(PropertyGroup): +class Z64_LightGroupProperty(PropertyGroup): expandTab: BoolProperty() menuTab: EnumProperty(items=ootEnumLightGroupMenu) - dawn: PointerProperty(type=OOTLightProperty) - day: PointerProperty(type=OOTLightProperty) - dusk: PointerProperty(type=OOTLightProperty) - night: PointerProperty(type=OOTLightProperty) + dawn: PointerProperty(type=Z64_LightProperty) + day: PointerProperty(type=Z64_LightProperty) + dusk: PointerProperty(type=Z64_LightProperty) + night: PointerProperty(type=Z64_LightProperty) defaultsSet: BoolProperty() def draw_props(self, layout: UILayout): @@ -240,15 +246,17 @@ def draw_props(self, layout: UILayout): self.night.draw_props(box, "Night", False, None, None, None) -class MM_SceneTableEntryProperty(PropertyGroup): - drawConfig: EnumProperty(items=mm_enum_draw_config, name="Scene Draw Config", default="SCENE_DRAW_CFG_DEFAULT") +class Z64_SceneTableEntryProperty(PropertyGroup): + drawConfig: EnumProperty(items=ootEnumDrawConfig, name="Scene Draw Config", default="SDC_DEFAULT") + mm_draw_config: EnumProperty(items=mm_enum_draw_config, name="Scene Draw Config", default="SCENE_DRAW_CFG_DEFAULT") drawConfigCustom: StringProperty(name="Scene Draw Config Custom") def draw_props(self, layout: UILayout): - drawEnumWithCustom(layout, self, "drawConfig", "Draw Config", "") + prop_name = "drawConfig" if is_game_oot() else "mm_draw_config" + drawEnumWithCustom(layout, self, prop_name, "Draw Config", "") -class OOTExtraCutsceneProperty(PropertyGroup): +class Z64_ExtraCutsceneProperty(PropertyGroup): csObject: PointerProperty( name="Cutscene Object", type=Object, @@ -309,20 +317,24 @@ def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: prop_split(box, self, "flags", "Flags") -class MM_SceneHeaderProperty(PropertyGroup): +class Z64_SceneHeaderProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") + usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty(name="Global Object", default="GAMEPLAY_DANGEON_KEEP", items=mm_enum_global_object) + globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) + mm_global_obj: EnumProperty(name="Global Object", default="GAMEPLAY_DANGEON_KEEP", items=mm_enum_global_object) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") + naviCup: EnumProperty(name="Navi Hints", default="NAVI_QUEST_HINTS_NONE", items=ootEnumNaviHints) + naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") - skybox_texture_id_custom: StringProperty(name="Skybox Texture ID Custom", default="0x00") - skyboxID: EnumProperty(name="Skybox", items=mm_enum_skybox, default="0x01") + skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") + mm_skybox_id: EnumProperty(name="Skybox", items=mm_enum_skybox, default="0x01") skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="0x00") - skyboxCloudinessCustom: StringProperty(name="Skybox Config Custom", default="0x00") + skyboxCloudiness: EnumProperty(name="Cloudiness", items=ootEnumCloudiness, default="0x00") + mm_skybox_config: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="0x00") + skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", items=ootEnumSkyboxLighting, @@ -333,36 +345,22 @@ class MM_SceneHeaderProperty(PropertyGroup): name="Skybox Lighting Custom", default="0x00", update=on_update_oot_render_settings ) - # SCENE_CMD_SET_REGION_VISITED - set_region_visited: BoolProperty( - name="Set Region Visited Flag", - default=False, - description="Sets a flag that indicates the region has been visited. Scene indices are mapped to their region in `gSceneIdsPerRegion` from `z_inventory.c`", - ) - - # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `MM_RoomHeaderProperty`) - minimap_room_expand: BoolProperty(name="Expand Tab") - minimap_room_list: CollectionProperty(type=MM_MinimapRoomProperty, name="Minimap Room List") - minimap_scale: IntProperty(name="Minimap Scale", default=0) - - # SCENE_CMD_MINIMAP_COMPASS_ICON_INFO - minimap_chest_expand: BoolProperty(name="Expand Tab") - minimap_chest_list: CollectionProperty(type=MM_MinimapChestProperty, name="Minimap Chest List") - # SCENE_CMD_SOUND_SETTINGS - musicSeq: EnumProperty(name="Music Sequence", items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") + musicSeq: EnumProperty(name="Music Sequence", items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + mm_seq_id: EnumProperty(name="Music Sequence", items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=mm_data.enum_ambiance_id, default="0x00") + nightSeq: EnumProperty(name="Nighttime SFX", items=oot_data.ootEnumNightSeq, default="0x00") + mm_ambience_id: EnumProperty(name="Nighttime SFX", items=mm_data.enum_ambiance_id, default="0x00") nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") # SCENE_CMD_ENV_LIGHT_SETTINGS - timeOfDayLights: PointerProperty(type=OOTLightGroupProperty, name="Time Of Day Lighting") - lightList: CollectionProperty(type=OOTLightProperty, name="Lighting List") + timeOfDayLights: PointerProperty(type=Z64_LightGroupProperty, name="Time Of Day Lighting") + lightList: CollectionProperty(type=Z64_LightProperty, name="Lighting List") # SCENE_CMD_EXIT_LIST - exitList: CollectionProperty(type=MM_ExitProperty, name="Exit List") + exitList: CollectionProperty(type=Z64_ExitProperty, name="Exit List") writeCutscene: BoolProperty(name="Write Cutscene") csWriteType: EnumProperty(name="Cutscene Data Type", items=ootEnumCSWriteType, default="Object") @@ -373,8 +371,8 @@ class MM_SceneHeaderProperty(PropertyGroup): poll=lambda self, object: object.type == "EMPTY" and object.ootEmptyType == "Cutscene", ) - extraCutscenes: CollectionProperty(type=OOTExtraCutsceneProperty, name="Extra Cutscenes") - sceneTableEntry: PointerProperty(type=MM_SceneTableEntryProperty) + extraCutscenes: CollectionProperty(type=Z64_ExtraCutsceneProperty, name="Extra Cutscenes") + sceneTableEntry: PointerProperty(type=Z64_SceneTableEntryProperty) menuTab: EnumProperty(name="Menu", items=ootEnumSceneMenu, update=onMenuTabChange) altMenuTab: EnumProperty(name="Menu", items=ootEnumSceneMenuAlternate) @@ -384,15 +382,48 @@ class MM_SceneHeaderProperty(PropertyGroup): default=False, ) + ## OoT exclusive + + # SCENE_CMD_MISC_SETTINGS + mapLocation: EnumProperty(name="Map Location", items=ootEnumMapLocation, default="0x00") + mapLocationCustom: StringProperty(name="Skybox Lighting Custom", default="0x00") + cameraMode: EnumProperty(name="Camera Mode", items=ootEnumCameraMode, default="0x00") + cameraModeCustom: StringProperty(name="Camera Mode Custom", default="0x00") + + ## MM exclusive + + # SCENE_CMD_SET_REGION_VISITED + set_region_visited: BoolProperty( + name="Set Region Visited Flag", + default=False, + description="Sets a flag that indicates the region has been visited. Scene indices are mapped to their region in `gSceneIdsPerRegion` from `z_inventory.c`", + ) + + # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `MM_RoomHeaderProperty`) + minimap_room_expand: BoolProperty(name="Expand Tab") + minimap_room_list: CollectionProperty(type=MM_MinimapRoomProperty, name="Minimap Room List") + minimap_scale: IntProperty(name="Minimap Scale", default=0) + + # SCENE_CMD_MINIMAP_COMPASS_ICON_INFO + minimap_chest_expand: BoolProperty(name="Expand Tab") + minimap_chest_list: CollectionProperty(type=MM_MinimapChestProperty, name="Minimap Chest List") + def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from ..operators import MM_SearchMusicSeqEnumOperator # temp circular import fix + from .operators import OOT_SearchMusicSeqEnumOperator, MM_SearchMusicSeqEnumOperator # temp circular import fix + + cs_index_start = get_cs_index_start() if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") if not self.expandTab: return - if headerIndex is not None and headerIndex > 0: - drawCollectionOps(layout, headerIndex - 1, "Scene", None, objName) + if headerIndex is not None and headerIndex > (cs_index_start - 1): + drawCollectionOps(layout, headerIndex - cs_index_start, "Scene", None, objName) + + if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < cs_index_start: + layout.prop(self, "usePreviousHeader", text="Use Previous Header") + if self.usePreviousHeader: + return if headerIndex is None or headerIndex == 0: layout.row().prop(self, "menuTab", expand=True) @@ -402,57 +433,83 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj menuTab = self.altMenuTab if menuTab == "General": + if is_game_oot(): + global_obj_prop_name = "globalObject" + skybox_prop_name = "skyboxID" + skybox_cfg_prop_name = "skyboxCloudiness" + seq_id_prop_name = "musicSeq" + ambience_prop_name = "nightSeq" + op_name = OOT_SearchMusicSeqEnumOperator.bl_idname + else: + global_obj_prop_name = "mm_global_obj" + skybox_prop_name = "mm_skybox_id" + skybox_cfg_prop_name = "mm_skybox_config" + seq_id_prop_name = "mm_seq_id" + ambience_prop_name = "mm_ambience_id" + op_name = MM_SearchMusicSeqEnumOperator.bl_idname + general = layout.column() general.box().label(text="General") - drawEnumWithCustom(general, self, "globalObject", "Global Object", "") + drawEnumWithCustom(general, self, global_obj_prop_name, "Global Object", "") + drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: self.sceneTableEntry.draw_props(general) - general.prop(self, "set_region_visited") + + if not is_game_oot(): + general.prop(self, "set_region_visited") + general.prop(self, "appendNullEntrance") skyboxAndSound = layout.column() skyboxAndSound.box().label(text="Skybox And Sound") - drawEnumWithCustom(skyboxAndSound, self, "skybox_texture_id", "Skybox Texture ID", "") - drawEnumWithCustom(skyboxAndSound, self, "skyboxID", "Skybox", "") - drawEnumWithCustom(skyboxAndSound, self, "skyboxCloudiness", "Cloudiness", "") - drawEnumWithCustom(skyboxAndSound, self, "musicSeq", "Music Sequence", "") - musicSearch = skyboxAndSound.operator(MM_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") + + drawEnumWithCustom(skyboxAndSound, self, skybox_prop_name, "Skybox", "") + drawEnumWithCustom(skyboxAndSound, self, skybox_cfg_prop_name, "Cloudiness", "") + drawEnumWithCustom(skyboxAndSound, self, seq_id_prop_name, "Music Sequence", "") + + musicSearch = skyboxAndSound.operator(op_name, icon="VIEWZOOM") musicSearch.objName = objName musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 - drawEnumWithCustom(skyboxAndSound, self, "nightSeq", "Nighttime SFX", "") + drawEnumWithCustom(skyboxAndSound, self, ambience_prop_name, "Nighttime SFX", "") drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") - minimap = layout.column() - minimap.box().label(text="Minimap Settings") - prop_split(minimap, self, "minimap_scale", "Minimap Scale") - - map_room_box = minimap.column().box() - list_length = len(self.minimap_room_list) - item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" - map_room_box.prop( - self, - "minimap_room_expand", - text=f"Minimap Room List ({item_count})", - icon="TRIA_DOWN" if self.minimap_room_expand else "TRIA_RIGHT", - ) - if self.minimap_room_expand: - for i in range(list_length): - self.minimap_room_list[i].draw_props(map_room_box, i, headerIndex, objName) - drawAddButton(map_room_box, list_length, "Minimap Room", headerIndex, objName) - - chest_box = minimap.column().box() - list_length = len(self.minimap_chest_list) - item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" - chest_box.prop( - self, - "minimap_chest_expand", - text=f"Minimap Chest List ({item_count})", - icon="TRIA_DOWN" if self.minimap_chest_expand else "TRIA_RIGHT", - ) - if self.minimap_chest_expand: - for i in range(list_length): - self.minimap_chest_list[i].draw_props(chest_box, i, headerIndex, objName) - drawAddButton(chest_box, list_length, "Minimap Chest", headerIndex, objName) + if is_game_oot(): + cameraAndWorldMap = layout.column() + cameraAndWorldMap.box().label(text="Camera And World Map") + drawEnumWithCustom(cameraAndWorldMap, self, "mapLocation", "Map Location", "") + drawEnumWithCustom(cameraAndWorldMap, self, "cameraMode", "Camera Mode", "") + else: + minimap = layout.column() + minimap.box().label(text="Minimap Settings") + prop_split(minimap, self, "minimap_scale", "Minimap Scale") + + map_room_box = minimap.column().box() + list_length = len(self.minimap_room_list) + item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" + map_room_box.prop( + self, + "minimap_room_expand", + text=f"Minimap Room List ({item_count})", + icon="TRIA_DOWN" if self.minimap_room_expand else "TRIA_RIGHT", + ) + if self.minimap_room_expand: + for i in range(list_length): + self.minimap_room_list[i].draw_props(map_room_box, i, headerIndex, objName) + drawAddButton(map_room_box, list_length, "Minimap Room", headerIndex, objName) + + chest_box = minimap.column().box() + list_length = len(self.minimap_chest_list) + item_count = "Empty" if list_length == 0 else f"{list_length} item{'s' if list_length > 1 else ''}" + chest_box.prop( + self, + "minimap_chest_expand", + text=f"Minimap Chest List ({item_count})", + icon="TRIA_DOWN" if self.minimap_chest_expand else "TRIA_RIGHT", + ) + if self.minimap_chest_expand: + for i in range(list_length): + self.minimap_chest_list[i].draw_props(chest_box, i, headerIndex, objName) + drawAddButton(chest_box, list_length, "Minimap Chest", headerIndex, objName) elif menuTab == "Lighting": lighting = layout.column() @@ -466,10 +523,10 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawAddButton(lighting, len(self.lightList), "Light", headerIndex, objName) elif menuTab == "Cutscene": - layout.label(text="Cutscenes aren't implemented yet.") cutscene = layout.column() - cutscene.enabled = False + if not is_game_oot(): + cutscene.enabled = False r = cutscene.row() r.prop(self, "writeCutscene", text="Write Cutscene") @@ -498,23 +555,54 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawAddButton(exitBox, len(self.exitList), "Exit", headerIndex, objName) -class MM_AlternateSceneHeaderProperty(PropertyGroup): - cutsceneHeaders: CollectionProperty(type=MM_SceneHeaderProperty) - currentCutsceneIndex: IntProperty(min=1, default=1, update=onHeaderMenuTabChange) +def update_cutscene_index(self: "Z64_AlternateSceneHeaderProperty", context: Context): + cs_index_start = get_cs_index_start() + + if self.currentCutsceneIndex < cs_index_start: + self.currentCutsceneIndex = cs_index_start + + onHeaderMenuTabChange(self, context) + + +class Z64_AlternateSceneHeaderProperty(PropertyGroup): + cutsceneHeaders: CollectionProperty(type=Z64_SceneHeaderProperty) + currentCutsceneIndex: IntProperty(update=update_cutscene_index) + + # OoT exclusive + childNightHeader: PointerProperty(name="Child Night Header", type=Z64_SceneHeaderProperty) + adultDayHeader: PointerProperty(name="Adult Day Header", type=Z64_SceneHeaderProperty) + adultNightHeader: PointerProperty(name="Adult Night Header", type=Z64_SceneHeaderProperty) + headerMenuTab: EnumProperty(name="Header Menu", items=ootEnumHeaderMenu, update=onHeaderMenuTabChange) def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - - prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") - drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) - index = self.currentCutsceneIndex - if index - 1 < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - 1].draw_props(headerSetup, None, index, objName) - else: - headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") + cs_index_start = get_cs_index_start() + can_draw_cs_header = not is_game_oot() + + if not can_draw_cs_header: + headerSetupBox = headerSetup.column() + headerSetupBox.row().prop(self, "headerMenuTab", expand=True) + + if self.headerMenuTab == "Child Night": + self.childNightHeader.draw_props(headerSetupBox, None, 1, objName) + elif self.headerMenuTab == "Adult Day": + self.adultDayHeader.draw_props(headerSetupBox, None, 2, objName) + elif self.headerMenuTab == "Adult Night": + self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) + elif self.headerMenuTab == "Cutscene": + can_draw_cs_header = True + + if can_draw_cs_header: + prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") + drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) + index = self.currentCutsceneIndex + if index - cs_index_start < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - cs_index_start].draw_props(headerSetup, None, index, objName) + else: + headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") -class OOTBootupSceneOptions(PropertyGroup): +class OOT_BootupSceneOptions(PropertyGroup): bootToScene: BoolProperty(default=False, name="Boot To Scene") overrideHeader: BoolProperty(default=False, name="Override Header") headerOption: EnumProperty(items=ootEnumHeaderMenuComplete, name="Header", default="Child Day") @@ -546,19 +634,20 @@ def draw_props(self, layout: UILayout): prop_split(layout, self, "cutsceneIndex", "Cutscene Index") -class MM_RemoveSceneSettingsProperty(PropertyGroup): +class Z64_RemoveSceneSettingsProperty(PropertyGroup): name: StringProperty(name="Name", default="spot03") subFolder: StringProperty(name="Subfolder", default="overworld") customExport: BoolProperty(name="Custom Export Path") - option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") + mm_option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") def draw_props(self, layout: UILayout): - if self.option == "Custom": + if is_game_oot() and self.option == "Custom" or self.mm_option == "Custom": prop_split(layout, self, "subFolder", "Subfolder") prop_split(layout, self, "name", "Name") -class MM_ExportSceneSettingsProperty(PropertyGroup): +class Z64_ExportSceneSettingsProperty(PropertyGroup): name: StringProperty(name="Name", default="spot03") subFolder: StringProperty(name="Subfolder", default="overworld") exportPath: StringProperty(name="Directory", subtype="FILE_PATH") @@ -568,7 +657,8 @@ class MM_ExportSceneSettingsProperty(PropertyGroup): default=False, description="Does not split the scene and rooms into multiple files.", ) - option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") + mm_option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") def draw_props(self, layout: UILayout): if self.customExport: @@ -576,7 +666,7 @@ def draw_props(self, layout: UILayout): prop_split(layout, self, "name", "Name") customExportWarning(layout) else: - if self.option == "Custom": + if is_game_oot() and self.option == "Custom" or self.mm_option == "Custom": prop_split(layout, self, "subFolder", "Subfolder") prop_split(layout, self, "name", "Name") @@ -586,7 +676,7 @@ def draw_props(self, layout: UILayout): layout.prop(self, "customExport") -class MM_ImportSceneSettingsProperty(PropertyGroup): +class Z64_ImportSceneSettingsProperty(PropertyGroup): name: StringProperty(name="Name", default="spot03") subFolder: StringProperty(name="Subfolder", default="overworld") destPath: StringProperty(name="Directory", subtype="FILE_PATH") @@ -600,7 +690,8 @@ class MM_ImportSceneSettingsProperty(PropertyGroup): includePaths: BoolProperty(name="Paths", default=True) includeWaterBoxes: BoolProperty(name="Water Boxes", default=True) includeCutscenes: BoolProperty(name="Cutscenes", default=False) - option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") + option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") + mm_option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") def draw_props(self, layout: UILayout, sceneOption: str): col = layout.column() @@ -617,55 +708,64 @@ def draw_props(self, layout: UILayout, sceneOption: str): includeButtons3 = col.row(align=True) includeButtons3.prop(self, "includePaths", toggle=1) includeButtons3.prop(self, "includeWaterBoxes", toggle=1) - # TODO: implement cutscenes - # includeButtons3.prop(self, "includeCutscenes", toggle=1) + + # TODO: implement cutscenes for MM + if is_game_oot(): + includeButtons3.prop(self, "includeCutscenes", toggle=1) + col.prop(self, "isCustomDest") if self.isCustomDest: prop_split(col, self, "destPath", "Directory") prop_split(col, self, "name", "Name") else: - if self.option == "Custom": + if is_game_oot() and self.option == "Custom" or self.mm_option == "Custom": prop_split(col, self, "subFolder", "Subfolder") prop_split(col, self, "name", "Name") + if is_game_oot() and "SCENE_JABU_JABU" in sceneOption: + col.label(text="Pulsing wall effect won't be imported.", icon="ERROR") + classes = ( - MM_ExitProperty, - OOTLightProperty, - OOTLightGroupProperty, - MM_SceneTableEntryProperty, - OOTExtraCutsceneProperty, + # OoT exclusive + OOT_BootupSceneOptions, + # MM exclusive MM_MinimapChestProperty, MM_MinimapRoomProperty, - MM_SceneHeaderProperty, - MM_AlternateSceneHeaderProperty, - OOTBootupSceneOptions, - MM_RemoveSceneSettingsProperty, - MM_ExportSceneSettingsProperty, - MM_ImportSceneSettingsProperty, + # Common + Z64_ExitProperty, + Z64_LightProperty, + Z64_LightGroupProperty, + Z64_SceneTableEntryProperty, + Z64_ExtraCutsceneProperty, + Z64_SceneHeaderProperty, + Z64_AlternateSceneHeaderProperty, + Z64_RemoveSceneSettingsProperty, + Z64_ExportSceneSettingsProperty, + Z64_ImportSceneSettingsProperty, ) -def mm_scene_props_register(): +def scene_props_register(): for cls in classes: register_class(cls) - Object.mm_scene_header = PointerProperty(type=MM_SceneHeaderProperty) - Object.mm_alternate_scene_headers = PointerProperty(type=MM_AlternateSceneHeaderProperty) - Scene.mm_scene_export_obj = PointerProperty(type=Object, poll=OOTSceneCommon.isSceneObj) - Scene.mm_scene_export_settings = PointerProperty(type=MM_ExportSceneSettingsProperty) - Scene.mm_scene_import_settings = PointerProperty(type=MM_ImportSceneSettingsProperty) - Scene.mm_scene_remove_settings = PointerProperty(type=MM_RemoveSceneSettingsProperty) - - -def mm_scene_props_unregister(): - del Object.mm_scene_header - del Object.mm_alternate_scene_headers - del Scene.mm_scene_export_obj - del Scene.mm_scene_export_settings - del Scene.mm_scene_import_settings - del Scene.mm_scene_remove_settings + Object.ootSceneHeader = PointerProperty(type=Z64_SceneHeaderProperty) + Object.ootAlternateSceneHeaders = PointerProperty(type=Z64_AlternateSceneHeaderProperty) + Scene.ootSceneExportObj = PointerProperty(type=Object, poll=OOTSceneCommon.isSceneObj) + Scene.ootSceneExportSettings = PointerProperty(type=Z64_ExportSceneSettingsProperty) + Scene.ootSceneImportSettings = PointerProperty(type=Z64_ImportSceneSettingsProperty) + Scene.ootSceneRemoveSettings = PointerProperty(type=Z64_RemoveSceneSettingsProperty) + + +def scene_props_unregister(): + del Object.ootSceneHeader + del Object.ootAlternateSceneHeaders + del Scene.ootSceneExportObj + del Scene.ootSceneExportSettings + del Scene.ootSceneImportSettings + del Scene.ootSceneRemoveSettings for cls in reversed(classes): unregister_class(cls) diff --git a/fast64_internal/z64/scene/properties/__init__.py b/fast64_internal/z64/scene/properties/__init__.py deleted file mode 100644 index c81be385d..000000000 --- a/fast64_internal/z64/scene/properties/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from .oot_props import ( - OOTSceneHeaderProperty, - OOTBootupSceneOptions, - OOTSceneProperties, - OOTAlternateSceneHeaderProperty, - OOTLightProperty, - OOTExportSceneSettingsProperty, - OOTImportSceneSettingsProperty, - OOTRemoveSceneSettingsProperty, - scene_props_register, - scene_props_unregister, -) - -from .mm_props import ( - MM_MinimapChestProperty, - MM_MinimapRoomProperty, - MM_SceneHeaderProperty, - MM_AlternateSceneHeaderProperty, - MM_ExportSceneSettingsProperty, - MM_ImportSceneSettingsProperty, - MM_RemoveSceneSettingsProperty, - mm_scene_props_register, - mm_scene_props_unregister, -) diff --git a/fast64_internal/z64/scene/properties/oot_props.py b/fast64_internal/z64/scene/properties/oot_props.py deleted file mode 100644 index dde74b1f3..000000000 --- a/fast64_internal/z64/scene/properties/oot_props.py +++ /dev/null @@ -1,593 +0,0 @@ -import bpy -from bpy.types import PropertyGroup, Object, Light, UILayout, Scene -from bpy.props import ( - EnumProperty, - IntProperty, - StringProperty, - CollectionProperty, - PointerProperty, - BoolProperty, - FloatVectorProperty, -) -from bpy.utils import register_class, unregister_class -from ....render_settings import on_update_oot_render_settings -from ....utility import prop_split, customExportWarning -from ...cutscene.constants import ootEnumCSWriteType - -from ...utility import ( - onMenuTabChange, - onHeaderMenuTabChange, - drawCollectionOps, - drawEnumWithCustom, - drawAddButton, -) - -from ...constants import ( - oot_data, - ootEnumSceneID, - ootEnumGlobalObject, - ootEnumNaviHints, - ootEnumSkybox, - ootEnumCloudiness, - ootEnumSkyboxLighting, - ootEnumMapLocation, - ootEnumCameraMode, - ootEnumAudioSessionPreset, - ootEnumHeaderMenu, - ootEnumDrawConfig, - ootEnumHeaderMenuComplete, -) - -ootEnumSceneMenuAlternate = [ - ("General", "General", "General"), - ("Lighting", "Lighting", "Lighting"), - ("Cutscene", "Cutscene", "Cutscene"), - ("Exits", "Exits", "Exits"), -] -ootEnumSceneMenu = ootEnumSceneMenuAlternate + [ - ("Alternate", "Alternate", "Alternate"), -] - -ootEnumLightGroupMenu = [ - ("Dawn", "Dawn", "Dawn"), - ("Day", "Day", "Day"), - ("Dusk", "Dusk", "Dusk"), - ("Night", "Night", "Night"), -] - -ootEnumTransitionAnims = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Spiky", "Spiky"), - ("0x01", "Triforce", "Triforce"), - ("0x02", "Slow Black Fade", "Slow Black Fade"), - ("0x03", "Slow Day/White, Slow Night/Black Fade", "Slow Day/White, Slow Night/Black Fade"), - ("0x04", "Fast Day/Black, Slow Night/Black Fade", "Fast Day/Black, Slow Night/Black Fade"), - ("0x05", "Fast Day/White, Slow Night/Black Fade", "Fast Day/White, Slow Night/Black Fade"), - ("0x06", "Very Slow Day/White, Slow Night/Black Fade", "Very Slow Day/White, Slow Night/Black Fade"), - ("0x07", "Very Slow Day/White, Slow Night/Black Fade", "Very Slow Day/White, Slow Night/Black Fade"), - ("0x0E", "Slow Sandstorm Fade", "Slow Sandstorm Fade"), - ("0x0F", "Fast Sandstorm Fade", "Fast Sandstorm Fade"), - ("0x20", "Iris Fade", "Iris Fade"), - ("0x2C", "Shortcut Transition", "Shortcut Transition"), -] - -ootEnumExitIndex = [ - ("Custom", "Custom", "Custom"), - ("Default", "Default", "Default"), -] - - -class OOTSceneCommon: - ootEnumBootMode = [ - ("Play", "Play", "Play"), - ("Map Select", "Map Select", "Map Select"), - ("File Select", "File Select", "File Select"), - ] - - def isSceneObj(self, obj): - return obj.type == "EMPTY" and obj.ootEmptyType == "Scene" - - -class OOTSceneProperties(PropertyGroup): - write_dummy_room_list: BoolProperty( - name="Dummy Room List", - default=False, - description=( - "When exporting the scene to C, use NULL for the pointers to room " - "start/end offsets, instead of the appropriate symbols" - ), - ) - - -class OOTExitProperty(PropertyGroup): - expandTab: BoolProperty(name="Expand Tab") - - exitIndex: EnumProperty(items=ootEnumExitIndex, default="Default") - exitIndexCustom: StringProperty(default="0x0000") - - # These are used when adding an entry to gEntranceTable - scene: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") - sceneCustom: StringProperty(default="SCENE_DEKU_TREE") - - # These are used when adding an entry to gEntranceTable - continueBGM: BoolProperty(default=False) - displayTitleCard: BoolProperty(default=True) - fadeInAnim: EnumProperty(items=ootEnumTransitionAnims, default="0x02") - fadeInAnimCustom: StringProperty(default="0x02") - fadeOutAnim: EnumProperty(items=ootEnumTransitionAnims, default="0x02") - fadeOutAnimCustom: StringProperty(default="0x02") - - def draw_props(self, layout: UILayout, index: int, headerIndex: int, objName: str): - box = layout.box() - box.prop(self, "expandTab", text="Exit " + str(index + 1), icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") - if self.expandTab: - drawCollectionOps(box, index, "Exit", headerIndex, objName) - drawEnumWithCustom(box, self, "exitIndex", "Exit Index", "") - if self.exitIndex != "Custom": - box.label(text='This is unfinished, use "Custom".') - exitGroup = box.column() - exitGroup.enabled = False - drawEnumWithCustom(exitGroup, self, "scene", "Scene", "") - exitGroup.prop(self, "continueBGM", text="Continue BGM") - exitGroup.prop(self, "displayTitleCard", text="Display Title Card") - drawEnumWithCustom(exitGroup, self, "fadeInAnim", "Fade In Animation", "") - drawEnumWithCustom(exitGroup, self, "fadeOutAnim", "Fade Out Animation", "") - - -class OOTLightProperty(PropertyGroup): - ambient: FloatVectorProperty( - name="Ambient Color", - size=4, - min=0, - max=1, - default=(70 / 255, 40 / 255, 57 / 255, 1), - subtype="COLOR", - update=on_update_oot_render_settings, - ) - useCustomDiffuse0: BoolProperty(name="Use Custom Diffuse 0 Light Object", update=on_update_oot_render_settings) - useCustomDiffuse1: BoolProperty(name="Use Custom Diffuse 1 Light Object", update=on_update_oot_render_settings) - diffuse0: FloatVectorProperty( - name="", - size=4, - min=0, - max=1, - default=(180 / 255, 154 / 255, 138 / 255, 1), - subtype="COLOR", - update=on_update_oot_render_settings, - ) - diffuse1: FloatVectorProperty( - name="", - size=4, - min=0, - max=1, - default=(20 / 255, 20 / 255, 60 / 255, 1), - subtype="COLOR", - update=on_update_oot_render_settings, - ) - diffuse0Custom: PointerProperty(name="Diffuse 0", type=Light, update=on_update_oot_render_settings) - diffuse1Custom: PointerProperty(name="Diffuse 1", type=Light, update=on_update_oot_render_settings) - fogColor: FloatVectorProperty( - name="", - size=4, - min=0, - max=1, - default=(140 / 255, 120 / 255, 110 / 255, 1), - subtype="COLOR", - update=on_update_oot_render_settings, - ) - fogNear: IntProperty(name="", default=993, min=0, max=2**10 - 1, update=on_update_oot_render_settings) - transitionSpeed: IntProperty(name="", default=1, min=0, max=63, update=on_update_oot_render_settings) - z_far: IntProperty(name="", default=0x3200, min=0, max=2**15 - 1, update=on_update_oot_render_settings) - expandTab: BoolProperty(name="Expand Tab") - - def draw_props( - self, layout: UILayout, name: str, showExpandTab: bool, index: int, sceneHeaderIndex: int, objName: str - ): - if showExpandTab: - box = layout.box().column() - box.prop(self, "expandTab", text=name, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") - expandTab = self.expandTab - else: - box = layout - expandTab = True - - if expandTab: - if index is not None: - drawCollectionOps(box, index, "Light", sceneHeaderIndex, objName) - prop_split(box, self, "ambient", "Ambient Color") - - if self.useCustomDiffuse0: - prop_split(box, self, "diffuse0Custom", "Diffuse 0") - box.label(text="Make sure light is not part of scene hierarchy.", icon="FILE_PARENT") - else: - prop_split(box, self, "diffuse0", "Diffuse 0") - box.prop(self, "useCustomDiffuse0") - - if self.useCustomDiffuse1: - prop_split(box, self, "diffuse1Custom", "Diffuse 1") - box.label(text="Make sure light is not part of scene hierarchy.", icon="FILE_PARENT") - else: - prop_split(box, self, "diffuse1", "Diffuse 1") - box.prop(self, "useCustomDiffuse1") - - prop_split(box, self, "fogColor", "Fog Color") - prop_split(box, self, "fogNear", "Fog Near (Fog Far=1000)") - prop_split(box, self, "z_far", "Z Far (Draw Distance)") - prop_split(box, self, "transitionSpeed", "Transition Speed") - - -class OOTLightGroupProperty(PropertyGroup): - expandTab: BoolProperty() - menuTab: EnumProperty(items=ootEnumLightGroupMenu) - dawn: PointerProperty(type=OOTLightProperty) - day: PointerProperty(type=OOTLightProperty) - dusk: PointerProperty(type=OOTLightProperty) - night: PointerProperty(type=OOTLightProperty) - defaultsSet: BoolProperty() - - def draw_props(self, layout: UILayout): - box = layout.column() - box.row().prop(self, "menuTab", expand=True) - if self.menuTab == "Dawn": - self.dawn.draw_props(box, "Dawn", False, None, None, None) - if self.menuTab == "Day": - self.day.draw_props(box, "Day", False, None, None, None) - if self.menuTab == "Dusk": - self.dusk.draw_props(box, "Dusk", False, None, None, None) - if self.menuTab == "Night": - self.night.draw_props(box, "Night", False, None, None, None) - - -class OOTSceneTableEntryProperty(PropertyGroup): - drawConfig: EnumProperty(items=ootEnumDrawConfig, name="Scene Draw Config", default="SDC_DEFAULT") - drawConfigCustom: StringProperty(name="Scene Draw Config Custom") - hasTitle: BoolProperty(default=True) - - def draw_props(self, layout: UILayout): - drawEnumWithCustom(layout, self, "drawConfig", "Draw Config", "") - - -class OOTExtraCutsceneProperty(PropertyGroup): - csObject: PointerProperty( - name="Cutscene Object", - type=Object, - poll=lambda self, object: object.type == "EMPTY" and object.ootEmptyType == "Cutscene", - ) - - -class OOTSceneHeaderProperty(PropertyGroup): - expandTab: BoolProperty(name="Expand Tab") - usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) - - globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) - globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") - naviCup: EnumProperty(name="Navi Hints", default="NAVI_QUEST_HINTS_NONE", items=ootEnumNaviHints) - naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") - - skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") - skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=ootEnumCloudiness, default="0x00") - skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") - skyboxLighting: EnumProperty( - name="Skybox Lighting", - items=ootEnumSkyboxLighting, - default="LIGHT_MODE_TIME", - update=on_update_oot_render_settings, - ) - skyboxLightingCustom: StringProperty( - name="Skybox Lighting Custom", default="0x00", update=on_update_oot_render_settings - ) - - mapLocation: EnumProperty(name="Map Location", items=ootEnumMapLocation, default="0x00") - mapLocationCustom: StringProperty(name="Skybox Lighting Custom", default="0x00") - cameraMode: EnumProperty(name="Camera Mode", items=ootEnumCameraMode, default="0x00") - cameraModeCustom: StringProperty(name="Camera Mode Custom", default="0x00") - - musicSeq: EnumProperty(name="Music Sequence", items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") - musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=oot_data.ootEnumNightSeq, default="0x00") - nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") - audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") - audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") - - timeOfDayLights: PointerProperty(type=OOTLightGroupProperty, name="Time Of Day Lighting") - lightList: CollectionProperty(type=OOTLightProperty, name="Lighting List") - exitList: CollectionProperty(type=OOTExitProperty, name="Exit List") - - writeCutscene: BoolProperty(name="Write Cutscene") - csWriteType: EnumProperty(name="Cutscene Data Type", items=ootEnumCSWriteType, default="Object") - csWriteCustom: StringProperty(name="CS hdr var:", default="") - csWriteObject: PointerProperty( - name="Cutscene Object", - type=Object, - poll=lambda self, object: object.type == "EMPTY" and object.ootEmptyType == "Cutscene", - ) - - extraCutscenes: CollectionProperty(type=OOTExtraCutsceneProperty, name="Extra Cutscenes") - sceneTableEntry: PointerProperty(type=OOTSceneTableEntryProperty) - menuTab: EnumProperty(name="Menu", items=ootEnumSceneMenu, update=onMenuTabChange) - altMenuTab: EnumProperty(name="Menu", items=ootEnumSceneMenuAlternate) - - appendNullEntrance: BoolProperty( - name="Append Null Entrance", - description="Add an additional {0, 0} to the end of the EntranceEntry list.", - default=False, - ) - - def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from ..operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix - - if dropdownLabel is not None: - layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") - if not self.expandTab: - return - if headerIndex is not None and headerIndex > 3: - drawCollectionOps(layout, headerIndex - 4, "Scene", None, objName) - - if headerIndex is not None and headerIndex > 0 and headerIndex < 4: - layout.prop(self, "usePreviousHeader", text="Use Previous Header") - if self.usePreviousHeader: - return - - if headerIndex is None or headerIndex == 0: - layout.row().prop(self, "menuTab", expand=True) - menuTab = self.menuTab - else: - layout.row().prop(self, "altMenuTab", expand=True) - menuTab = self.altMenuTab - - if menuTab == "General": - general = layout.column() - general.box().label(text="General") - drawEnumWithCustom(general, self, "globalObject", "Global Object", "") - drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") - if headerIndex is None or headerIndex == 0: - self.sceneTableEntry.draw_props(general) - general.prop(self, "appendNullEntrance") - - skyboxAndSound = layout.column() - skyboxAndSound.box().label(text="Skybox And Sound") - drawEnumWithCustom(skyboxAndSound, self, "skyboxID", "Skybox", "") - drawEnumWithCustom(skyboxAndSound, self, "skyboxCloudiness", "Cloudiness", "") - drawEnumWithCustom(skyboxAndSound, self, "musicSeq", "Music Sequence", "") - musicSearch = skyboxAndSound.operator(OOT_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") - musicSearch.objName = objName - musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 - drawEnumWithCustom(skyboxAndSound, self, "nightSeq", "Nighttime SFX", "") - drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") - - cameraAndWorldMap = layout.column() - cameraAndWorldMap.box().label(text="Camera And World Map") - drawEnumWithCustom(cameraAndWorldMap, self, "mapLocation", "Map Location", "") - drawEnumWithCustom(cameraAndWorldMap, self, "cameraMode", "Camera Mode", "") - - elif menuTab == "Lighting": - lighting = layout.column() - lighting.box().label(text="Lighting List") - drawEnumWithCustom(lighting, self, "skyboxLighting", "Lighting Mode", "") - if self.skyboxLighting == "LIGHT_MODE_TIME": # Time of Day - self.timeOfDayLights.draw_props(lighting) - else: - for i in range(len(self.lightList)): - self.lightList[i].draw_props(lighting, "Lighting " + str(i), True, i, headerIndex, objName) - drawAddButton(lighting, len(self.lightList), "Light", headerIndex, objName) - - elif menuTab == "Cutscene": - cutscene = layout.column() - r = cutscene.row() - r.prop(self, "writeCutscene", text="Write Cutscene") - if self.writeCutscene: - r.prop(self, "csWriteType", text="Data") - if self.csWriteType == "Custom": - cutscene.prop(self, "csWriteCustom") - else: - cutscene.prop(self, "csWriteObject") - - if headerIndex is None or headerIndex == 0: - cutscene.label(text="Extra cutscenes (not in any header):") - for i in range(len(self.extraCutscenes)): - box = cutscene.box().column() - drawCollectionOps(box, i, "extraCutscenes", None, objName, True) - box.prop(self.extraCutscenes[i], "csObject", text="CS obj") - if len(self.extraCutscenes) == 0: - drawAddButton(cutscene, 0, "extraCutscenes", 0, objName) - - elif menuTab == "Exits": - exitBox = layout.column() - exitBox.box().label(text="Exit List") - for i in range(len(self.exitList)): - self.exitList[i].draw_props(exitBox, i, headerIndex, objName) - - drawAddButton(exitBox, len(self.exitList), "Exit", headerIndex, objName) - - -class OOTAlternateSceneHeaderProperty(PropertyGroup): - childNightHeader: PointerProperty(name="Child Night Header", type=OOTSceneHeaderProperty) - adultDayHeader: PointerProperty(name="Adult Day Header", type=OOTSceneHeaderProperty) - adultNightHeader: PointerProperty(name="Adult Night Header", type=OOTSceneHeaderProperty) - cutsceneHeaders: CollectionProperty(type=OOTSceneHeaderProperty) - - headerMenuTab: EnumProperty(name="Header Menu", items=ootEnumHeaderMenu, update=onHeaderMenuTabChange) - currentCutsceneIndex: IntProperty(min=4, default=4, update=onHeaderMenuTabChange) - - def draw_props(self, layout: UILayout, objName: str): - headerSetup = layout.column() - # headerSetup.box().label(text = "Alternate Headers") - headerSetupBox = headerSetup.column() - - headerSetupBox.row().prop(self, "headerMenuTab", expand=True) - if self.headerMenuTab == "Child Night": - self.childNightHeader.draw_props(headerSetupBox, None, 1, objName) - elif self.headerMenuTab == "Adult Day": - self.adultDayHeader.draw_props(headerSetupBox, None, 2, objName) - elif self.headerMenuTab == "Adult Night": - self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) - elif self.headerMenuTab == "Cutscene": - prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") - drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) - index = self.currentCutsceneIndex - if index - 4 < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - 4].draw_props(headerSetup, None, index, objName) - else: - headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") - - -class OOTBootupSceneOptions(PropertyGroup): - bootToScene: BoolProperty(default=False, name="Boot To Scene") - overrideHeader: BoolProperty(default=False, name="Override Header") - headerOption: EnumProperty(items=ootEnumHeaderMenuComplete, name="Header", default="Child Day") - spawnIndex: IntProperty(name="Spawn", min=0) - newGameOnly: BoolProperty( - default=False, - name="Override Scene On New Game Only", - description="Only use this starting scene after loading a new save file", - ) - newGameName: StringProperty(default="Link", name="New Game Name") - bootMode: EnumProperty(default="Play", name="Boot Mode", items=OOTSceneCommon.ootEnumBootMode) - - # see src/code/z_play.c:Play_Init() - can't access more than 16 cutscenes? - cutsceneIndex: IntProperty(min=4, max=19, default=4, name="Cutscene Index") - - def draw_props(self, layout: UILayout): - layout.prop(self, "bootToScene", text="Boot To Scene (HackerOOT)") - if self.bootToScene: - layout.prop(self, "newGameOnly") - prop_split(layout, self, "bootMode", "Boot Mode") - if self.bootMode == "Play": - prop_split(layout, self, "newGameName", "New Game Name") - if self.bootMode != "Map Select": - prop_split(layout, self, "spawnIndex", "Spawn") - layout.prop(self, "overrideHeader") - if self.overrideHeader: - prop_split(layout, self, "headerOption", "Header Option") - if self.headerOption == "Cutscene": - prop_split(layout, self, "cutsceneIndex", "Cutscene Index") - - -class OOTRemoveSceneSettingsProperty(PropertyGroup): - name: StringProperty(name="Name", default="spot03") - subFolder: StringProperty(name="Subfolder", default="overworld") - customExport: BoolProperty(name="Custom Export Path") - option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") - - def draw_props(self, layout: UILayout): - if self.option == "Custom": - prop_split(layout, self, "subFolder", "Subfolder") - prop_split(layout, self, "name", "Name") - - -class OOTExportSceneSettingsProperty(PropertyGroup): - name: StringProperty(name="Name", default="spot03") - subFolder: StringProperty(name="Subfolder", default="overworld") - exportPath: StringProperty(name="Directory", subtype="FILE_PATH") - customExport: BoolProperty(name="Custom Export Path") - singleFile: BoolProperty( - name="Export as Single File", - default=False, - description="Does not split the scene and rooms into multiple files.", - ) - option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") - - # keeping this on purpose, will be removed once old code is cleaned-up - useNewExporter: BoolProperty(name="Use New Exporter", default=True) - - def draw_props(self, layout: UILayout): - if self.customExport: - prop_split(layout, self, "exportPath", "Directory") - prop_split(layout, self, "name", "Name") - customExportWarning(layout) - else: - if self.option == "Custom": - prop_split(layout, self, "subFolder", "Subfolder") - prop_split(layout, self, "name", "Name") - - prop_split(layout, bpy.context.scene, "ootSceneExportObj", "Scene Object") - - layout.prop(self, "singleFile") - layout.prop(self, "customExport") - # layout.prop(self, "useNewExporter") - - -class OOTImportSceneSettingsProperty(PropertyGroup): - name: StringProperty(name="Name", default="spot03") - subFolder: StringProperty(name="Subfolder", default="overworld") - destPath: StringProperty(name="Directory", subtype="FILE_PATH") - isCustomDest: BoolProperty(name="Custom Path") - includeMesh: BoolProperty(name="Mesh", default=True) - includeCollision: BoolProperty(name="Collision", default=True) - includeActors: BoolProperty(name="Actors", default=True) - includeCullGroups: BoolProperty(name="Cull Groups", default=True) - includeLights: BoolProperty(name="Lights", default=True) - includeCameras: BoolProperty(name="Cameras", default=True) - includePaths: BoolProperty(name="Paths", default=True) - includeWaterBoxes: BoolProperty(name="Water Boxes", default=True) - includeCutscenes: BoolProperty(name="Cutscenes", default=False) - option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") - - def draw_props(self, layout: UILayout, sceneOption: str): - col = layout.column() - includeButtons1 = col.row(align=True) - includeButtons1.prop(self, "includeMesh", toggle=1) - includeButtons1.prop(self, "includeCollision", toggle=1) - includeButtons1.prop(self, "includeActors", toggle=1) - - includeButtons2 = col.row(align=True) - includeButtons2.prop(self, "includeCullGroups", toggle=1) - includeButtons2.prop(self, "includeLights", toggle=1) - includeButtons2.prop(self, "includeCameras", toggle=1) - - includeButtons3 = col.row(align=True) - includeButtons3.prop(self, "includePaths", toggle=1) - includeButtons3.prop(self, "includeWaterBoxes", toggle=1) - includeButtons3.prop(self, "includeCutscenes", toggle=1) - col.prop(self, "isCustomDest") - - if self.isCustomDest: - prop_split(col, self, "destPath", "Directory") - prop_split(col, self, "name", "Name") - else: - if self.option == "Custom": - prop_split(col, self, "subFolder", "Subfolder") - prop_split(col, self, "name", "Name") - - if "SCENE_JABU_JABU" in sceneOption: - col.label(text="Pulsing wall effect won't be imported.", icon="ERROR") - - -classes = ( - OOTExitProperty, - OOTLightProperty, - OOTLightGroupProperty, - OOTSceneTableEntryProperty, - OOTExtraCutsceneProperty, - OOTSceneHeaderProperty, - OOTAlternateSceneHeaderProperty, - OOTBootupSceneOptions, - OOTRemoveSceneSettingsProperty, - OOTExportSceneSettingsProperty, - OOTImportSceneSettingsProperty, -) - - -def scene_props_register(): - for cls in classes: - register_class(cls) - - Object.ootSceneHeader = PointerProperty(type=OOTSceneHeaderProperty) - Object.ootAlternateSceneHeaders = PointerProperty(type=OOTAlternateSceneHeaderProperty) - Scene.ootSceneExportObj = PointerProperty(type=Object, poll=OOTSceneCommon.isSceneObj) - Scene.ootSceneExportSettings = PointerProperty(type=OOTExportSceneSettingsProperty) - Scene.ootSceneImportSettings = PointerProperty(type=OOTImportSceneSettingsProperty) - Scene.ootSceneRemoveSettings = PointerProperty(type=OOTRemoveSceneSettingsProperty) - - -def scene_props_unregister(): - del Object.ootSceneHeader - del Object.ootAlternateSceneHeaders - del Scene.ootSceneExportObj - del Scene.ootSceneExportSettings - del Scene.ootSceneImportSettings - del Scene.ootSceneRemoveSettings - - for cls in reversed(classes): - unregister_class(cls) diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index 47824e5f3..f507d69dc 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -7,7 +7,7 @@ from ..utility import drawEnumWithCustom, is_game_oot, get_game_props from ..collision.constants import enum_camera_crawlspace_stype from ..actor.properties import OOTActorHeaderProperty, MM_ActorHeaderProperty -from ..scene.properties import OOTAlternateSceneHeaderProperty, MM_AlternateSceneHeaderProperty +from ..scene.properties import Z64_AlternateSceneHeaderProperty enum_spline = [("Path", "Path", "Path"), ("Crawlspace", "Crawlspace", "Crawlspace")] @@ -27,7 +27,7 @@ class Z64_SplineProperty(PropertyGroup): def draw_props( self, layout: UILayout, - altSceneProp: OOTAlternateSceneHeaderProperty | MM_AlternateSceneHeaderProperty, + altSceneProp: Z64_AlternateSceneHeaderProperty, objName: str, ): camIndexName = "Path Index" if self.splineType == "Path" else "Camera Index" diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 4d33e6022..521fb6349 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -46,7 +46,7 @@ ) if TYPE_CHECKING: - from .scene.properties import OOTBootupSceneOptions, OOTSceneHeaderProperty, MM_SceneHeaderProperty + from .scene.properties import OOT_BootupSceneOptions, Z64_SceneHeaderProperty def get_game_enum(enum_type: str): @@ -88,8 +88,8 @@ def get_game_props(obj: Object, header_type: str): "path_header_settings": obj.ootSplineProperty.headerSettings, }, "MM": { - "scene": obj.mm_scene_header, - "alt_scene": obj.mm_alternate_scene_headers, + "scene": obj.ootSceneHeader, + "alt_scene": obj.ootAlternateSceneHeaders, "room": obj.mm_room_header, "alt_room": obj.mm_alternate_room_headers, "actor": obj.mm_actor_property, @@ -104,7 +104,7 @@ def get_game_props(obj: Object, header_type: str): "export_settings": bpy.context.scene.ootSceneExportSettings, }, "MM": { - "export_settings": bpy.context.scene.mm_scene_export_settings, + "export_settings": bpy.context.scene.ootSceneExportSettings, }, } @@ -391,7 +391,7 @@ class ExportInfo: useMacros: bool """ Whether to use macros or numeric/binary representations of certain values.""" - hackerootBootOption: "OOTBootupSceneOptions" + hackerootBootOption: "OOT_BootupSceneOptions" """ Options for setting the bootup scene in HackerOoT.""" From 56c13e9425d9b8418249e51bb6473b02adf9be0c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 01:12:16 +0100 Subject: [PATCH 021/126] merge OoT and MM for scene properties (2/2) --- fast64_internal/z64/constants.py | 67 ++++++++++--------- fast64_internal/z64/cutscene/classes.py | 14 ++-- .../z64/cutscene/exporter/classes.py | 6 +- fast64_internal/z64/data/oot/enum_data.py | 12 ++-- .../z64/exporter/cutscene/actor_cue.py | 2 +- .../z64/exporter/cutscene/common.py | 4 +- fast64_internal/z64/exporter/cutscene/data.py | 6 +- fast64_internal/z64/importer/scene.py | 3 +- fast64_internal/z64/importer/scene_header.py | 31 +++++++-- fast64_internal/z64/scene/properties.py | 56 +++++++++------- fast64_internal/z64/upgrade.py | 4 +- fast64_internal/z64/utility.py | 32 ++++++++- 12 files changed, 144 insertions(+), 93 deletions(-) diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index 63cf7846c..71ae7a5bc 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -53,34 +53,34 @@ mm_enum_skybox_config = [ ("Custom", "Custom", "Custom"), - ("0x00", "SKYBOX_CONFIG_0", "SKYBOX_CONFIG_0"), - ("0x01", "SKYBOX_CONFIG_1", "SKYBOX_CONFIG_1"), - ("0x02", "SKYBOX_CONFIG_2", "SKYBOX_CONFIG_2"), - ("0x03", "SKYBOX_CONFIG_3", "SKYBOX_CONFIG_3"), - ("0x04", "SKYBOX_CONFIG_4", "SKYBOX_CONFIG_4"), - ("0x05", "SKYBOX_CONFIG_5", "SKYBOX_CONFIG_5"), - ("0x06", "SKYBOX_CONFIG_6", "SKYBOX_CONFIG_6"), - ("0x07", "SKYBOX_CONFIG_7", "SKYBOX_CONFIG_7"), - ("0x08", "SKYBOX_CONFIG_8", "SKYBOX_CONFIG_8"), - ("0x09", "SKYBOX_CONFIG_9", "SKYBOX_CONFIG_9"), - ("0x0A", "SKYBOX_CONFIG_10", "SKYBOX_CONFIG_10"), - ("0x0B", "SKYBOX_CONFIG_11", "SKYBOX_CONFIG_11"), - ("0x0C", "SKYBOX_CONFIG_12", "SKYBOX_CONFIG_12"), - ("0x0D", "SKYBOX_CONFIG_13", "SKYBOX_CONFIG_13"), - ("0x0E", "SKYBOX_CONFIG_14", "SKYBOX_CONFIG_14"), - ("0x0F", "SKYBOX_CONFIG_15", "SKYBOX_CONFIG_15"), - ("0x10", "SKYBOX_CONFIG_16", "SKYBOX_CONFIG_16"), - ("0x11", "SKYBOX_CONFIG_17", "SKYBOX_CONFIG_17"), - ("0x12", "SKYBOX_CONFIG_18", "SKYBOX_CONFIG_18"), - ("0x13", "SKYBOX_CONFIG_19", "SKYBOX_CONFIG_19"), - ("0x14", "SKYBOX_CONFIG_20", "SKYBOX_CONFIG_20"), - ("0x15", "SKYBOX_CONFIG_21", "SKYBOX_CONFIG_21"), - ("0x16", "SKYBOX_CONFIG_22", "SKYBOX_CONFIG_22"), - ("0x17", "SKYBOX_CONFIG_23", "SKYBOX_CONFIG_23"), - ("0x18", "SKYBOX_CONFIG_24", "SKYBOX_CONFIG_24"), - ("0x19", "SKYBOX_CONFIG_25", "SKYBOX_CONFIG_25"), - ("0x1A", "SKYBOX_CONFIG_26", "SKYBOX_CONFIG_26"), - ("0x1B", "SKYBOX_CONFIG_27", "SKYBOX_CONFIG_27"), + ("SKYBOX_CONFIG_0", "SKYBOX_CONFIG_0", "0x00"), + ("SKYBOX_CONFIG_1", "SKYBOX_CONFIG_1", "0x01"), + ("SKYBOX_CONFIG_2", "SKYBOX_CONFIG_2", "0x02"), + ("SKYBOX_CONFIG_3", "SKYBOX_CONFIG_3", "0x03"), + ("SKYBOX_CONFIG_4", "SKYBOX_CONFIG_4", "0x04"), + ("SKYBOX_CONFIG_5", "SKYBOX_CONFIG_5", "0x05"), + ("SKYBOX_CONFIG_6", "SKYBOX_CONFIG_6", "0x06"), + ("SKYBOX_CONFIG_7", "SKYBOX_CONFIG_7", "0x07"), + ("SKYBOX_CONFIG_8", "SKYBOX_CONFIG_8", "0x08"), + ("SKYBOX_CONFIG_9", "SKYBOX_CONFIG_9", "0x09"), + ("SKYBOX_CONFIG_10", "SKYBOX_CONFIG_10", "0x0A"), + ("SKYBOX_CONFIG_11", "SKYBOX_CONFIG_11", "0x0B"), + ("SKYBOX_CONFIG_12", "SKYBOX_CONFIG_12", "0x0C"), + ("SKYBOX_CONFIG_13", "SKYBOX_CONFIG_13", "0x0D"), + ("SKYBOX_CONFIG_14", "SKYBOX_CONFIG_14", "0x0E"), + ("SKYBOX_CONFIG_15", "SKYBOX_CONFIG_15", "0x0F"), + ("SKYBOX_CONFIG_16", "SKYBOX_CONFIG_16", "0x10"), + ("SKYBOX_CONFIG_17", "SKYBOX_CONFIG_17", "0x11"), + ("SKYBOX_CONFIG_18", "SKYBOX_CONFIG_18", "0x12"), + ("SKYBOX_CONFIG_19", "SKYBOX_CONFIG_19", "0x13"), + ("SKYBOX_CONFIG_20", "SKYBOX_CONFIG_20", "0x14"), + ("SKYBOX_CONFIG_21", "SKYBOX_CONFIG_21", "0x15"), + ("SKYBOX_CONFIG_22", "SKYBOX_CONFIG_22", "0x16"), + ("SKYBOX_CONFIG_23", "SKYBOX_CONFIG_23", "0x17"), + ("SKYBOX_CONFIG_24", "SKYBOX_CONFIG_24", "0x18"), + ("SKYBOX_CONFIG_25", "SKYBOX_CONFIG_25", "0x19"), + ("SKYBOX_CONFIG_26", "SKYBOX_CONFIG_26", "0x1A"), + ("SKYBOX_CONFIG_27", "SKYBOX_CONFIG_27", "0x1B"), ] ootEnumCameraMode = [ @@ -153,11 +153,11 @@ mm_enum_skybox = [ ("Custom", "Custom", "Custom"), - ("0x00", "None", "SKYBOX_NONE"), - ("0x01", "Standard Sky", "SKYBOX_NORMAL_SKY"), - ("0x02", "SKYBOX_2", "SKYBOX_2"), - ("0x03", "SKYBOX_3", "SKYBOX_3"), - ("0x05", "Cutscene Map", "SKYBOX_CUTSCENE_MAP"), + ("SKYBOX_NONE", "None", "0x00"), + ("SKYBOX_NORMAL_SKY", "Standard Sky", "0x01"), + ("SKYBOX_2", "SKYBOX_2", "0x02"), + ("SKYBOX_3", "SKYBOX_3", "0x03"), + ("SKYBOX_CUTSCENE_MAP", "Cutscene Map", "0x05"), ] ootEnumSkyboxLighting = [ @@ -661,6 +661,7 @@ ] mm_enum_room_type = [ + ("Custom", "Custom", "Custom"), ("0x00", "Normal", "ROOM_TYPE_NORMAL"), ("0x01", "Dungeon", "ROOM_TYPE_DUNGEON"), ("0x02", "Indoors", "ROOM_TYPE_INDOORS"), diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index ac7d2b560..cf7395aa8 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -26,12 +26,12 @@ class CutsceneCmdBase: def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): enum = oot_data.enumData.enumByKey[enumKey] - item = enum.itemById.get(self.params[index]) + item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) if isSeqLegacy: setting -= 1 - item = enum.itemByIndex.get(setting) + item = enum.item_by_index.get(setting) return item.key if item is not None else self.params[index] @@ -101,7 +101,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = oot_data.enumData.enumByKey["csCmd"].itemById[self.commandType].key + self.commandType = oot_data.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -532,8 +532,8 @@ def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Objec if commandType == "Player": commandType = "player_cue" - index = cmdEnum.itemByKey[commandType].index if commandType in cmdEnum.itemByKey else int(commandType, base=16) - item = cmdEnum.itemByIndex.get(index) + index = cmdEnum.item_by_key[commandType].index if commandType in cmdEnum.item_by_key else int(commandType, base=16) + item = cmdEnum.item_by_index.get(index) if item is not None: newActorCueListObj.ootCSMotionProperty.actorCueListProp.commandType = item.key @@ -568,9 +568,9 @@ def getNewActorCueObject( if isPlayer: playerEnum = oot_data.enumData.enumByKey["csPlayerCueId"] if isinstance(actionID, int): - item = playerEnum.itemByIndex.get(actionID) + item = playerEnum.item_by_index.get(actionID) else: - item = playerEnum.itemByKey.get(actionID) + item = playerEnum.item_by_key.get(actionID) if item is not None: newActorCueObj.ootCSMotionProperty.actorCueProp.playerCueID = item.key diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index fc8d0bf98..a0c7215f7 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -40,7 +40,7 @@ class CutsceneCmdToC: """This class contains functions to create the cutscene commands""" def getEnumValue(self, enumKey: str, owner, propName: str): - item = oot_data.enumData.enumByKey[enumKey].itemByKey.get(getattr(owner, propName)) + item = oot_data.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def getGenericListCmd(self, cmdName: str, entryTotal: int): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = oot_data.enumData.enumByKey["csCmd"].itemByKey[commandType].id + commandType = oot_data.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = oot_data.enumData.enumByKey["csPlayerCueId"].itemByKey[cueID].id + actionID = oot_data.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/data/oot/enum_data.py b/fast64_internal/z64/data/oot/enum_data.py index d970f93b3..3552f9850 100644 --- a/fast64_internal/z64/data/oot/enum_data.py +++ b/fast64_internal/z64/data/oot/enum_data.py @@ -41,14 +41,14 @@ def __post_init__(self): @dataclass class OoT_EnumElement(OoT_BaseElement): items: list[OoT_ItemElement] - itemByKey: dict[str, OoT_ItemElement] = field(default_factory=dict) - itemByIndex: dict[int, OoT_ItemElement] = field(default_factory=dict) - itemById: dict[int, OoT_ItemElement] = field(default_factory=dict) + item_by_key: dict[str, OoT_ItemElement] = field(default_factory=dict) + item_by_index: dict[int, OoT_ItemElement] = field(default_factory=dict) + item_by_id: dict[int, OoT_ItemElement] = field(default_factory=dict) def __post_init__(self): - self.itemByKey = {item.key: item for item in self.items} - self.itemByIndex = {item.index: item for item in self.items} - self.itemById = {item.id: item for item in self.items} + self.item_by_key = {item.key: item for item in self.items} + self.item_by_index = {item.index: item for item in self.items} + self.item_by_id = {item.id: item for item in self.items} class OoT_EnumData: diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index c1909d1b9..c60c813a0 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = oot_data.enumData.enumByKey["csCmd"].itemById[commandType].key + commandType = oot_data.enumData.enumByKey["csCmd"].item_by_id[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index a913cce88..e51039226 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -21,12 +21,12 @@ def validateFrames(self, checkEndFrame: bool = True): @staticmethod def getEnumValue(enumKey: str, value: str, isSeqLegacy: bool = False): enum = oot_data.enumData.enumByKey[enumKey] - item = enum.itemById.get(value) + item = enum.item_by_id.get(value) if item is None: setting = getInteger(value) if isSeqLegacy: setting -= 1 - item = enum.itemByIndex.get(setting) + item = enum.item_by_index.get(setting) return item.key if item is not None else value def getGenericListCmd(self, cmdName: str, entryTotal: int): diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index f57273526..53d11c468 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -142,7 +142,7 @@ def getOoTPosition(self, pos): return [x, y, z] def getEnumValueFromProp(self, enumKey: str, owner, propName: str): - item = oot_data.enumData.enumByKey[enumKey].itemByKey.get(getattr(owner, propName)) + item = oot_data.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): @@ -169,7 +169,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = oot_data.enumData.enumByKey["csCmd"].itemByKey[commandType].id + commandType = oot_data.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +183,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = oot_data.enumData.enumByKey["csPlayerCueId"].itemByKey[cueID].id + actionID = oot_data.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index cf855136c..0fbe21690 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -23,6 +23,7 @@ setAllActorsVisibility, is_game_oot, get_game_props, + get_game_prop_name, ) @@ -172,7 +173,7 @@ def parseScene( if not settings.isCustomDest: setCustomProperty( get_game_props(sceneObj, "scene").sceneTableEntry, - "drawConfig", + get_game_prop_name("draw_config"), SceneTableUtility.get_draw_config(sceneName), ootEnumDrawConfig if is_game_oot() else mm_enum_draw_config, ) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 7fdd032b4..a43ace54b 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -15,6 +15,7 @@ get_game_props, is_game_oot, get_cs_index_start, + get_game_prop_name, ) from .constants import headerNames from .utility import getDataMatch, stripName @@ -281,7 +282,7 @@ def parse_mm_minimap_info(scene_header, scene_data: str, list_name: str): def get_enum_id_from_index(enum_key: str, index: int): if is_game_oot(): - return oot_data.enumData.enumByKey[enum_key].itemByIndex[index].id + return oot_data.enumData.enumByKey[enum_key].item_by_index[index].id else: return mm_data.enum_data.enum_by_key[enum_key].item_by_index[index].id @@ -323,8 +324,19 @@ def parseSceneCommands( if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) setCustomProperty(sceneHeader, "nightSeq", args[1], get_game_enum("enum_ambiance_id")) + + if args[2].startswith("NA_BGM_"): + enum_id = args[2] + else: + if is_game_oot(): + enum_seq_id = oot_data.enumData.enumByKey["seqId"] + else: + enum_seq_id = mm_data.enum_data.enum_by_key["seqId"] + + enum_id = enum_seq_id.item_by_index[int(args[2])].id + setCustomProperty( - sceneHeader, "musicSeq", get_enum_id_from_index("seqId", int(args[2])), get_game_enum("enum_seq_id") + sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id") ) elif command == "SCENE_CMD_ROOM_LIST": # Assumption that all scenes use the same room list. @@ -352,8 +364,9 @@ def parseSceneCommands( entranceListName = stripName(args[0]) entranceList = parseEntranceList(sceneHeader, roomObjs, sceneData, entranceListName) elif command == "SCENE_CMD_SPECIAL_FILES": - setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) - setCustomProperty(sceneHeader, "globalObject", args[1], get_game_enum("enum_global_object")) + if is_game_oot(): + setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) + setCustomProperty(sceneHeader, get_game_prop_name("global_obj"), args[1], get_game_enum("enum_global_object")) elif command == "SCENE_CMD_PATH_LIST" and sharedSceneData.includePaths: pathListName = stripName(args[0]) parsePathList(sceneObj, sceneData, pathListName, headerIndex, sharedSceneData) @@ -368,9 +381,13 @@ def parseSceneCommands( entranceList = None elif command == "SCENE_CMD_SKYBOX_SETTINGS": - setCustomProperty(sceneHeader, "skyboxID", args[0], get_game_enum("enum_skybox")) - setCustomProperty(sceneHeader, "skyboxCloudiness", args[1], ootEnumCloudiness) - setCustomProperty(sceneHeader, "skyboxLighting", args[2], ootEnumSkyboxLighting) + args_index = 0 + if not is_game_oot(): + sceneHeader.skybox_texture_id = args[args_index] + args_index += 1 + setCustomProperty(sceneHeader, get_game_prop_name("skybox_id"), args[args_index], get_game_enum("enum_skybox")) + setCustomProperty(sceneHeader, get_game_prop_name("skybox_config"), args[args_index + 1], get_game_enum("enum_skybox_config")) + setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) elif command == "SCENE_CMD_EXIT_LIST": exitListName = stripName(args[0]) parseExitList(sceneHeader, sceneData, exitListName) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index ebd8a971c..d2c5ad8b5 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -22,6 +22,7 @@ drawAddButton, is_game_oot, get_cs_index_start, + get_game_prop_name, ) from ..constants import ( @@ -252,8 +253,7 @@ class Z64_SceneTableEntryProperty(PropertyGroup): drawConfigCustom: StringProperty(name="Scene Draw Config Custom") def draw_props(self, layout: UILayout): - prop_name = "drawConfig" if is_game_oot() else "mm_draw_config" - drawEnumWithCustom(layout, self, prop_name, "Draw Config", "") + drawEnumWithCustom(layout, self, get_game_prop_name("draw_config"), "Draw Config", "") class Z64_ExtraCutsceneProperty(PropertyGroup): @@ -325,15 +325,17 @@ class Z64_SceneHeaderProperty(PropertyGroup): globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) mm_global_obj: EnumProperty(name="Global Object", default="GAMEPLAY_DANGEON_KEEP", items=mm_enum_global_object) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") + + # OoT exclusive naviCup: EnumProperty(name="Navi Hints", default="NAVI_QUEST_HINTS_NONE", items=ootEnumNaviHints) naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") - mm_skybox_id: EnumProperty(name="Skybox", items=mm_enum_skybox, default="0x01") + mm_skybox_id: EnumProperty(name="Skybox", items=mm_enum_skybox, default="SKYBOX_NORMAL_SKY") skyboxIDCustom: StringProperty(name="Skybox ID", default="0") skyboxCloudiness: EnumProperty(name="Cloudiness", items=ootEnumCloudiness, default="0x00") - mm_skybox_config: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="0x00") + mm_skybox_config: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="SKYBOX_CONFIG_0") skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", @@ -345,6 +347,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): name="Skybox Lighting Custom", default="0x00", update=on_update_oot_render_settings ) + # MM exclusive + skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") + # SCENE_CMD_SOUND_SETTINGS musicSeq: EnumProperty(name="Music Sequence", items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") mm_seq_id: EnumProperty(name="Music Sequence", items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") @@ -433,24 +438,11 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj menuTab = self.altMenuTab if menuTab == "General": - if is_game_oot(): - global_obj_prop_name = "globalObject" - skybox_prop_name = "skyboxID" - skybox_cfg_prop_name = "skyboxCloudiness" - seq_id_prop_name = "musicSeq" - ambience_prop_name = "nightSeq" - op_name = OOT_SearchMusicSeqEnumOperator.bl_idname - else: - global_obj_prop_name = "mm_global_obj" - skybox_prop_name = "mm_skybox_id" - skybox_cfg_prop_name = "mm_skybox_config" - seq_id_prop_name = "mm_seq_id" - ambience_prop_name = "mm_ambience_id" - op_name = MM_SearchMusicSeqEnumOperator.bl_idname - general = layout.column() general.box().label(text="General") - drawEnumWithCustom(general, self, global_obj_prop_name, "Global Object", "") + + # General + drawEnumWithCustom(general, self, get_game_prop_name("global_obj"), "Global Object", "") drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: self.sceneTableEntry.draw_props(general) @@ -460,19 +452,27 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general.prop(self, "appendNullEntrance") + # Skybox And Sound skyboxAndSound = layout.column() skyboxAndSound.box().label(text="Skybox And Sound") - drawEnumWithCustom(skyboxAndSound, self, skybox_prop_name, "Skybox", "") - drawEnumWithCustom(skyboxAndSound, self, skybox_cfg_prop_name, "Cloudiness", "") - drawEnumWithCustom(skyboxAndSound, self, seq_id_prop_name, "Music Sequence", "") + prop_split(skyboxAndSound, self, "skybox_texture_id", "Skybox Texture ID") + drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("skybox_id"), "Skybox", "", "skyboxIDCustom") + drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("skybox_config"), "Skybox Config", "", "skyboxCloudinessCustom") + drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("seq_id"), "Music Sequence", "") + + if is_game_oot(): + op_name = OOT_SearchMusicSeqEnumOperator.bl_idname + else: + op_name = MM_SearchMusicSeqEnumOperator.bl_idname musicSearch = skyboxAndSound.operator(op_name, icon="VIEWZOOM") musicSearch.objName = objName musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 - drawEnumWithCustom(skyboxAndSound, self, ambience_prop_name, "Nighttime SFX", "") + drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("ambience_id"), "Nighttime SFX", "") drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") + # Camera And World Map | Minimap Settings if is_game_oot(): cameraAndWorldMap = layout.column() cameraAndWorldMap.box().label(text="Camera And World Map") @@ -723,8 +723,12 @@ def draw_props(self, layout: UILayout, sceneOption: str): prop_split(col, self, "subFolder", "Subfolder") prop_split(col, self, "name", "Name") - if is_game_oot() and "SCENE_JABU_JABU" in sceneOption: - col.label(text="Pulsing wall effect won't be imported.", icon="ERROR") + if is_game_oot(): + if "SCENE_JABU_JABU" in sceneOption: + col.label(text="Pulsing wall effect won't be imported.", icon="ERROR") + else: + if not self.includeActors: + col.label(text="MapDataChest won't be imported.", icon="ERROR") classes = ( diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index f15be1feb..5291a8e06 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -243,7 +243,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): index = legacyData["actor_id"] if index >= 0: cmdEnum = oot_data.enumData.enumByKey["csCmd"] - cmdType = cmdEnum.itemByIndex.get(index) + cmdType = cmdEnum.item_by_index.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key else: @@ -266,7 +266,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): playerEnum = oot_data.enumData.enumByKey["csPlayerCueId"] item = None if isPlayer: - item = playerEnum.itemByIndex.get(int(legacyData["action_id"], base=16)) + item = playerEnum.item_by_index.get(int(legacyData["action_id"], base=16)) if isPlayer and item is not None: csMotionProp.actorCueProp.playerCueID = item.key diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 521fb6349..4fb69c3c9 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -23,6 +23,7 @@ ootEnumSkybox, mm_enum_skybox, ootEnumCloudiness, + mm_enum_skybox_config, ootEnumSkyboxLighting, ootEnumLinkIdle, ootEnumRoomBehaviour, @@ -54,6 +55,7 @@ def get_game_enum(enum_type: str): "OOT": { "enum_global_object": ootEnumGlobalObject, "enum_skybox": ootEnumSkybox, + "enum_skybox_config": ootEnumCloudiness, "enum_seq_id": oot_data.ootEnumMusicSeq, "enum_ambiance_id": oot_data.ootEnumNightSeq, # TODO: generate this from xml (not for enumproperties) "enum_env_type": ootEnumLinkIdle, @@ -63,6 +65,7 @@ def get_game_enum(enum_type: str): "MM": { "enum_global_object": mm_enum_global_object, "enum_skybox": mm_enum_skybox, + "enum_skybox_config": mm_enum_skybox_config, "enum_seq_id": mm_data.enum_seq_id, "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above "enum_env_type": mm_enum_environvment_type, @@ -74,6 +77,29 @@ def get_game_enum(enum_type: str): return game_enum_map[bpy.context.scene.gameEditorMode][enum_type] +def get_game_prop_name(prop_type: str): + game_prop_name_map = { + "OOT": { + "global_obj": "globalObject", + "skybox_id": "skyboxID", + "skybox_config": "skyboxCloudiness", + "seq_id": "musicSeq", + "ambience_id": "nightSeq", + "draw_config": "drawConfig", + }, + "MM": { + "global_obj": "mm_global_obj", + "skybox_id": "mm_skybox_id", + "skybox_config": "mm_skybox_config", + "seq_id": "mm_seq_id", + "ambience_id": "mm_ambience_id", + "draw_config": "mm_draw_config", + }, + } + + return game_prop_name_map[bpy.context.scene.gameEditorMode][prop_type] + + def get_game_props(obj: Object, header_type: str): if obj is not None: game_header_map = { @@ -697,10 +723,12 @@ def convertIntTo2sComplement(value: int, length: int, signed: bool): return int.from_bytes(int(round(value)).to_bytes(length, "big", signed=signed), "big") -def drawEnumWithCustom(panel, data, attribute, name, customName): +def drawEnumWithCustom(panel, data, attribute, name, customName, custom_prop_name: Optional[str] = None): prop_split(panel, data, attribute, name) if getattr(data, attribute) == "Custom": - prop_split(panel, data, attribute + "Custom", customName) + if custom_prop_name is None: + custom_prop_name = attribute + "Custom" + prop_split(panel, data, custom_prop_name, customName) def getEnumName(enumItems, value): From 4051c36a5dba688fd5664f6abaefab5b305ec585 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 01:46:54 +0100 Subject: [PATCH 022/126] merge OoT and MM for room properties (1/2) --- fast64_internal/z64/__init__.py | 4 - .../z64/actor/properties/mm_props.py | 8 +- .../z64/actor/properties/oot_props.py | 8 +- fast64_internal/z64/constants.py | 2 +- fast64_internal/z64/data/oot/object_data.py | 6 +- fast64_internal/z64/exporter/room/__init__.py | 4 +- fast64_internal/z64/exporter/room/header.py | 10 +- fast64_internal/z64/exporter/room/shape.py | 6 +- fast64_internal/z64/exporter/scene/general.py | 2 +- fast64_internal/z64/importer/room_header.py | 6 +- fast64_internal/z64/importer/room_shape.py | 6 +- fast64_internal/z64/object.py | 2 +- fast64_internal/z64/props_panel_main.py | 8 +- .../oot_props.py => properties.py} | 191 ++++++++----- .../z64/room/properties/__init__.py | 14 - .../z64/room/properties/mm_props.py | 261 ------------------ fast64_internal/z64/scene/properties.py | 2 +- fast64_internal/z64/upgrade.py | 2 +- fast64_internal/z64/utility.py | 14 +- 19 files changed, 168 insertions(+), 388 deletions(-) rename fast64_internal/z64/room/{properties/oot_props.py => properties.py} (62%) delete mode 100644 fast64_internal/z64/room/properties/__init__.py delete mode 100644 fast64_internal/z64/room/properties/mm_props.py diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index b98410871..9b43f1707 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -19,8 +19,6 @@ from .room.properties import ( room_props_register, room_props_unregister, - mm_room_props_register, - mm_room_props_unregister, ) from .actor.operators import actor_ops_register, actor_ops_unregister @@ -175,7 +173,6 @@ def oot_register(registerPanels): scene_props_register() room_ops_register() room_props_register() - mm_room_props_register() actor_ops_register() actor_props_register() mm_actor_props_register() @@ -217,7 +214,6 @@ def oot_unregister(unregisterPanels): scene_props_unregister() room_ops_unregister() room_props_unregister() - mm_room_props_unregister() actor_ops_unregister() actor_props_unregister() mm_actor_props_unregister() diff --git a/fast64_internal/z64/actor/properties/mm_props.py b/fast64_internal/z64/actor/properties/mm_props.py index c575793d3..bc471df7c 100644 --- a/fast64_internal/z64/actor/properties/mm_props.py +++ b/fast64_internal/z64/actor/properties/mm_props.py @@ -4,7 +4,7 @@ from ....utility import prop_split, label_split from ...constants import mm_data, ootEnumCamTransition from ...upgrade import upgradeActors -from ...room.properties import MM_AlternateRoomHeaderProperty +from ...room.properties import Z64_AlternateRoomHeaderProperty from ..operators import MM_SearchActorIDEnumOperator from ...utility import ( @@ -24,7 +24,7 @@ def draw_props( layout: UILayout, propUser: str, index: int, - altProp: MM_AlternateRoomHeaderProperty, + altProp: Z64_AlternateRoomHeaderProperty, objName: str, ): box = layout.column() @@ -53,7 +53,7 @@ def draw_props( self, layout: UILayout, propUser: str, - altProp: MM_AlternateRoomHeaderProperty, + altProp: Z64_AlternateRoomHeaderProperty, objName: str, ): headerSetup = layout.column() @@ -95,7 +95,7 @@ class MM_ActorProperty(PropertyGroup): rotOverrideZ: StringProperty(name="Rot Z", default="0") headerSettings: PointerProperty(type=MM_ActorHeaderProperty) - def draw_props(self, layout: UILayout, altRoomProp: MM_AlternateRoomHeaderProperty, objName: str): + def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderProperty, objName: str): actorIDBox = layout.column() searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") searchOp.actorUser = "Actor" diff --git a/fast64_internal/z64/actor/properties/oot_props.py b/fast64_internal/z64/actor/properties/oot_props.py index 937219c50..75d8a556e 100644 --- a/fast64_internal/z64/actor/properties/oot_props.py +++ b/fast64_internal/z64/actor/properties/oot_props.py @@ -5,7 +5,7 @@ from ...constants import oot_data, ootEnumCamTransition from ...upgrade import upgradeActors from ...scene.properties import Z64_AlternateSceneHeaderProperty -from ...room.properties import OOTAlternateRoomHeaderProperty +from ...room.properties import Z64_AlternateRoomHeaderProperty from ..operators import OOT_SearchActorIDEnumOperator from ...utility import ( @@ -31,7 +31,7 @@ def draw_props( layout: UILayout, propUser: str, index: int, - altProp: Z64_AlternateSceneHeaderProperty | OOTAlternateRoomHeaderProperty, + altProp: Z64_AlternateSceneHeaderProperty | Z64_AlternateRoomHeaderProperty, objName: str, ): box = layout.column() @@ -66,7 +66,7 @@ def draw_props( self, layout: UILayout, propUser: str, - altProp: Z64_AlternateSceneHeaderProperty | OOTAlternateRoomHeaderProperty, + altProp: Z64_AlternateSceneHeaderProperty | Z64_AlternateRoomHeaderProperty, objName: str, ): headerSetup = layout.column() @@ -121,7 +121,7 @@ def upgrade_object(obj: Object): print(f"Processing '{obj.name}'...") upgradeActors(obj) - def draw_props(self, layout: UILayout, altRoomProp: OOTAlternateRoomHeaderProperty, objName: str): + def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderProperty, objName: str): # prop_split(layout, actorProp, 'actorID', 'Actor') actorIDBox = layout.column() # actorIDBox.box().label(text = "Settings") diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index 71ae7a5bc..27818eb97 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -34,7 +34,7 @@ ("0xFF", "Hops On Epona", "Hops On Epona"), ] -mm_enum_environvment_type = [ +mm_enum_environment_type = [ ("Custom", "Custom", "Custom"), ("0x00", "Default", "ROOM_ENV_DEFAULT"), ("0x01", "Cold", "ROOM_ENV_COLD"), diff --git a/fast64_internal/z64/data/oot/object_data.py b/fast64_internal/z64/data/oot/object_data.py index 69339d7c4..5b51e3e87 100644 --- a/fast64_internal/z64/data/oot/object_data.py +++ b/fast64_internal/z64/data/oot/object_data.py @@ -29,8 +29,8 @@ def __init__(self): OoT_ObjectElement(obj.attrib["ID"], obj.attrib["Key"], objName, int(obj.attrib["Index"])) ) - self.objectsByID = {obj.id: obj for obj in self.objectList} - self.objectsByKey = {obj.key: obj for obj in self.objectList} + self.objects_by_id = {obj.id: obj for obj in self.objectList} + self.objects_by_key = {obj.key: obj for obj in self.objectList} # list of tuples used by Blender's enum properties self.deletedEntry = ("None", "(Deleted from the XML)", "None") @@ -38,7 +38,7 @@ def __init__(self): self.ootEnumObjectKey = self.getObjectIDList(lastIndex + 1, False) # create the legacy object list for old blends - self.ootEnumObjectIDLegacy = self.getObjectIDList(self.objectsByKey["obj_timeblock"].index + 1, True) + self.ootEnumObjectIDLegacy = self.getObjectIDList(self.objects_by_key["obj_timeblock"].index + 1, True) # validate the legacy list, if there's any None element then something's wrong if self.deletedEntry in self.ootEnumObjectIDLegacy: diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index a4a733f9f..5515927f7 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -5,7 +5,7 @@ from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings from ...utility import get_game_props, is_game_oot -from ...room.properties import OOTRoomHeaderProperty +from ...room.properties import Z64_RoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter from ..file import RoomFile @@ -60,7 +60,7 @@ def new( if is_game_oot(): for i, header in enumerate(altHeaderList, 1): - altP: OOTRoomHeaderProperty = getattr(altProp, f"{header}Header") + altP: Z64_RoomHeaderProperty = getattr(altProp, f"{header}Header") if not altP.usePreviousHeader: hasAlternateHeaders = True newRoomHeader = RoomHeader.new( diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index e8fcfa1b6..448eaf001 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -5,7 +5,7 @@ from ....utility import CData, indent from ...utility import getObjectList, get_game_props, is_game_oot, getEvalParams from ...constants import oot_data -from ...room.properties import OOTRoomHeaderProperty, MM_RoomHeaderProperty +from ...room.properties import Z64_RoomHeaderProperty from ..utility import Utility from ..actor import Actor @@ -48,7 +48,7 @@ class RoomInfos: strength: int @staticmethod - def new(props: Optional[OOTRoomHeaderProperty | MM_RoomHeaderProperty]): + def new(props: Optional[Z64_RoomHeaderProperty]): disableWarpSongs = False enable_pos_lights = False enable_storm = False @@ -116,13 +116,13 @@ class RoomObjects: objectList: list[str] @staticmethod - def new(name: str, props: Optional[OOTRoomHeaderProperty]): + def new(name: str, props: Optional[Z64_RoomHeaderProperty]): objectList: list[str] = [] for objProp in props.objectList: if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objectList.append(oot_data.objectData.objectsByKey[objProp.objectKey].id) + objectList.append(oot_data.objectData.objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -276,7 +276,7 @@ class RoomHeader: @staticmethod def new( name: str, - props: Optional[OOTRoomHeaderProperty], + props: Optional[Z64_RoomHeaderProperty], sceneObj: Optional[Object], roomObj: Optional[Object], transform: Matrix, diff --git a/fast64_internal/z64/exporter/room/shape.py b/fast64_internal/z64/exporter/room/shape.py index e1fd0f37f..0e377452e 100644 --- a/fast64_internal/z64/exporter/room/shape.py +++ b/fast64_internal/z64/exporter/room/shape.py @@ -7,7 +7,7 @@ from ....utility import PluginError, CData, toAlnum, indent from ....f3d.f3d_gbi import SPDisplayList, SPEndDisplayList, GfxListTag, GfxList, DLFormat from ....f3d.f3d_writer import TriangleConverterInfo, saveStaticModel, getInfoDict -from ...room.properties import OOTRoomHeaderProperty, OOTBGProperty +from ...room.properties import Z64_RoomHeaderProperty, Z64_BGProperty from ...model_classes import OOTModel from ..utility import Utility from bpy.types import Object @@ -211,7 +211,7 @@ def get_height(self) -> int: return self.image.size[1] if self.image else 0 @staticmethod - def new(name: str, prop: OOTBGProperty): + def new(name: str, prop: Z64_BGProperty): if prop.image is None: raise PluginError( 'A room is has room shape "Image" but does not have an image set in one of its BG images.' @@ -521,7 +521,7 @@ def create_shape( sceneObj: Object, roomObj: Object, saveTexturesAsPNG: bool, - props: OOTRoomHeaderProperty, + props: Z64_RoomHeaderProperty, ): name = f"{room_name}_shapeHeader" dl_name = f"{room_name}_shapeDListsEntry" diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 495082b9f..7490d5017 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -294,7 +294,7 @@ def get_room_index(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object) for room_obj in room_obj_list: if chest_prop.chest_obj in room_obj.children_recursive: - return room_obj.mm_room_header.roomIndex + return room_obj.ootRoomHeader.roomIndex raise PluginError(f"ERROR: Can't find the room associated with '{chest_prop.chest_obj.name}'") diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index a8eb93f0c..738af3e48 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -4,7 +4,7 @@ from ...utility import hexOrDecInt from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum, get_cs_index_start from ..model_classes import OOTF3DContext -from ..room.properties import OOTRoomHeaderProperty +from ..room.properties import Z64_RoomHeaderProperty from ..constants import oot_data, mm_data from .utility import getDataMatch, stripName from .classes import SharedSceneData @@ -15,12 +15,12 @@ def get_object_from_id(object: str): if is_game_oot(): - return oot_data.objectData.objectsByID.get(object) + return oot_data.objectData.objects_by_id.get(object) else: return mm_data.object_data.objects_by_id.get(object) -def parseObjectList(roomHeader: OOTRoomHeaderProperty, sceneData: str, objectListName: str): +def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectListName: str): objectData = getDataMatch(sceneData, objectListName, "s16", "object list") objects = [value.strip() for value in objectData.split(",") if value.strip() != ""] diff --git a/fast64_internal/z64/importer/room_shape.py b/fast64_internal/z64/importer/room_shape.py index c46a6a51b..0f5c9971c 100644 --- a/fast64_internal/z64/importer/room_shape.py +++ b/fast64_internal/z64/importer/room_shape.py @@ -6,7 +6,7 @@ from ...utility import parentObject, hexOrDecInt, yUpToZUp from ...f3d.f3d_parser import importMeshC from ..model_classes import OOTF3DContext -from ..room.properties import OOTRoomHeaderProperty +from ..room.properties import Z64_RoomHeaderProperty from ..constants import ootEnumRoomShapeType from ..utility import get_game_props from .classes import SharedSceneData @@ -46,7 +46,7 @@ def parseMeshHeader( parseBGImageList(roomHeader, sceneData, bgListName, sharedSceneData) -def parseBGImage(roomHeader: OOTRoomHeaderProperty, params: list[str], sharedSceneData: SharedSceneData): +def parseBGImage(roomHeader: Z64_RoomHeaderProperty, params: list[str], sharedSceneData: SharedSceneData): bgImage = roomHeader.bgImageList.add() bgImage.otherModeFlags = params[10] bgName = f"{params[3]}.jpg" @@ -55,7 +55,7 @@ def parseBGImage(roomHeader: OOTRoomHeaderProperty, params: list[str], sharedSce def parseBGImageList( - roomHeader: OOTRoomHeaderProperty, sceneData: str, bgListName: str, sharedSceneData: SharedSceneData + roomHeader: Z64_RoomHeaderProperty, sceneData: str, bgListName: str, sharedSceneData: SharedSceneData ): bgData = getDataMatch(sceneData, bgListName, "", "bg list") bgList = [value.replace("{", "").strip() for value in bgData.split("},") if value.strip() != ""] diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index e8e8bf768..a07205654 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -22,7 +22,7 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: if objKey not in ["obj_gameplay_keep", "obj_gameplay_field_keep", "obj_gameplay_dangeon_keep"]: - objID = oot_data.objectData.objectsByKey[objKey].id + objID = oot_data.objectData.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) addMissingObjectToProp(roomObj, headerIndex, objKey) diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index bfd9c810e..52e45d4b4 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -3,7 +3,7 @@ from ..utility import prop_split, gammaInverse from .utility import getSceneObj, getRoomObj, get_game_props, is_game_oot from .scene.properties import OOTSceneProperties -from .room.properties import OOTObjectProperty, OOTRoomHeaderProperty, OOTAlternateRoomHeaderProperty +from .room.properties import Z64_ObjectProperty, Z64_RoomHeaderProperty, Z64_AlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty from .cutscene.properties import OOTCutsceneProperty from .cutscene.motion.properties import ( @@ -155,10 +155,10 @@ def draw(self, context): drawSceneHeader(box, obj) elif obj.ootEmptyType == "Room": - roomProp: OOTRoomHeaderProperty = get_game_props(obj, "room") + roomProp: Z64_RoomHeaderProperty = get_game_props(obj, "room") roomProp.draw_props(box, None, None, objName) if get_game_props(obj, "room").menuTab == "Alternate": - roomAltProp: OOTAlternateRoomHeaderProperty = get_game_props(obj, "alt_room") + roomAltProp: Z64_AlternateRoomHeaderProperty = get_game_props(obj, "alt_room") roomAltProp.draw_props(box, objName) elif obj.ootEmptyType == "Entrance": @@ -203,7 +203,7 @@ def upgrade_changed_props(): for obj in bpy.data.objects: if obj.type == "EMPTY" and is_game_oot(): if obj.ootEmptyType == "Room": - OOTObjectProperty.upgrade_object(obj) + Z64_ObjectProperty.upgrade_object(obj) if obj.ootEmptyType in {"Entrance", "Transition Actor"}: OOTActorProperty.upgrade_object(obj) if obj.ootEmptyType == "Cutscene": diff --git a/fast64_internal/z64/room/properties/oot_props.py b/fast64_internal/z64/room/properties.py similarity index 62% rename from fast64_internal/z64/room/properties/oot_props.py rename to fast64_internal/z64/room/properties.py index 5117f8681..f4075a067 100644 --- a/fast64_internal/z64/room/properties/oot_props.py +++ b/fast64_internal/z64/room/properties.py @@ -1,17 +1,19 @@ import bpy -from bpy.types import PropertyGroup, UILayout, Image, Object +from bpy.types import PropertyGroup, UILayout, Image, Object, Context from bpy.utils import register_class, unregister_class -from ....utility import prop_split -from ...utility import ( +from ...utility import prop_split +from ..utility import ( drawCollectionOps, onMenuTabChange, onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton, is_game_oot, + get_game_prop_name, + get_cs_index_start, ) -from ...upgrade import upgradeRoomHeaders -from ..operators import OOT_SearchObjectEnumOperator +from ..upgrade import upgradeRoomHeaders +from .operators import OOT_SearchObjectEnumOperator, MM_SearchObjectEnumOperator from bpy.props import ( EnumProperty, @@ -24,12 +26,15 @@ IntVectorProperty, ) -from ...constants import ( +from ..constants import ( oot_data, ootEnumRoomBehaviour, ootEnumLinkIdle, ootEnumRoomShapeType, ootEnumHeaderMenu, + mm_data, + mm_enum_room_type, + mm_enum_environment_type, ) ootEnumRoomMenuAlternate = [ @@ -41,41 +46,51 @@ ] -class OOTObjectProperty(PropertyGroup): +class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") + mm_object_key: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod def upgrade_object(obj: Object): - print(f"Processing '{obj.name}'...") - upgradeRoomHeaders(obj, oot_data.objectData) + if is_game_oot(): + print(f"Processing '{obj.name}'...") + upgradeRoomHeaders(obj, oot_data.objectData) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): - isLegacy = True if "objectID" in self else False + is_legacy = True if "objectID" in self else False + obj_key: str = getattr(self, get_game_prop_name("object_key")) - if isLegacy: - objectName = oot_data.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] - elif self.objectKey != "Custom": - objectName = oot_data.objectData.objectsByKey[self.objectKey].name + if is_game_oot(): + objects_by_key = oot_data.objectData.objects_by_key + op_name = OOT_SearchObjectEnumOperator.bl_idname else: - objectName = self.objectIDCustom + objects_by_key = mm_data.object_data.objects_by_key + op_name = MM_SearchObjectEnumOperator.bl_idname + + if is_game_oot() and is_legacy: + obj_name = oot_data.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + elif obj_key != "Custom": + obj_name = objects_by_key[obj_key].name + else: + obj_name = self.objectIDCustom objItemBox = layout.column() row = objItemBox.row() - row.label(text=f"{objectName}") + row.label(text=f"{obj_name}") buttons = row.row(align=True) - objSearch = buttons.operator(OOT_SearchObjectEnumOperator.bl_idname, icon="VIEWZOOM", text="Select") + objSearch = buttons.operator(op_name, icon="VIEWZOOM", text="Select") drawCollectionOps(buttons, index, "Object", headerIndex, objName, compact=True) objSearch.objName = objName objSearch.headerIndex = headerIndex if headerIndex is not None else 0 objSearch.index = index - if self.objectKey == "Custom": + if obj_key == "Custom": prop_split(objItemBox, self, "objectIDCustom", "Object ID Custom") -class OOTBGProperty(PropertyGroup): +class Z64_BGProperty(PropertyGroup): image: PointerProperty(type=Image) # camera: IntProperty(name="Camera Index", min=0) otherModeFlags: StringProperty( @@ -92,39 +107,56 @@ def draw_props(self, layout: UILayout, index: int, objName: str, isMulti: bool): drawCollectionOps(box, index, "BgImage", None, objName) -class OOTRoomHeaderProperty(PropertyGroup): +class Z64_RoomHeaderProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") menuTab: EnumProperty(items=ootEnumRoomMenu, update=onMenuTabChange) altMenuTab: EnumProperty(items=ootEnumRoomMenuAlternate) + + # OoT exclusive usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) + # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) roomBehaviour: EnumProperty(items=ootEnumRoomBehaviour, default="0x00") + mm_room_type: EnumProperty(items=mm_enum_room_type, default="0x00") roomBehaviourCustom: StringProperty(default="0x00") - disableWarpSongs: BoolProperty(name="Disable Warp Songs") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Link Idle Mode", items=ootEnumLinkIdle, default="0x00") - linkIdleModeCustom: StringProperty(name="Link Idle Mode Custom", default="0x00") + linkIdleMode: EnumProperty(name="Environment Type", items=ootEnumLinkIdle, default="0x00") + mm_environment_type: EnumProperty(name="Environment Type", items=mm_enum_environment_type, default="0x00") + linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") + + # OoT exclusive + disableWarpSongs: BoolProperty(name="Disable Warp Songs") + + # MM exclusive + enable_pos_lights: BoolProperty(name="Enable Pos Lights") + enable_storm: BoolProperty(name="Enable Storm") + # SCENE_CMD_WIND_SETTINGS setWind: BoolProperty(name="Set Wind") windVector: IntVectorProperty(name="Wind Vector", size=3, min=-127, max=127) windStrength: IntProperty(name="Wind Strength", min=0, max=255) + # SCENE_CMD_TIME_SETTINGS leaveTimeUnchanged: BoolProperty(name="Leave Time Unchanged", default=True) timeHours: IntProperty(name="Hours", default=0, min=0, max=23) # 0xFFFE timeMinutes: IntProperty(name="Minutes", default=0, min=0, max=59) timeSpeed: FloatProperty(name="Time Speed", default=1, min=-13, max=13) # 0xA + # SCENE_CMD_SKYBOX_DISABLES disableSkybox: BoolProperty(name="Disable Skybox") disableSunMoon: BoolProperty(name="Disable Sun/Moon") + # SCENE_CMD_ECHO_SETTINGS echo: StringProperty(name="Echo", default="0x00") - objectList: CollectionProperty(type=OOTObjectProperty) + # SCENE_CMD_OBJECT_LIST + objectList: CollectionProperty(type=Z64_ObjectProperty) + # SCENE_CMD_ROOM_SHAPE roomShape: EnumProperty(items=ootEnumRoomShapeType, default="ROOM_SHAPE_TYPE_NORMAL") defaultCullDistance: IntProperty(name="Default Cull Distance", min=1, default=100) - bgImageList: CollectionProperty(type=OOTBGProperty) + bgImageList: CollectionProperty(type=Z64_BGProperty) bgImageTab: BoolProperty(name="BG Images") def drawBGImageList(self, layout: UILayout, objName: str): @@ -144,16 +176,18 @@ def drawBGImageList(self, layout: UILayout, objName: str): drawAddButton(box, len(self.bgImageList), "BgImage", None, objName) def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from ...props_panel_main import OOT_ManualUpgrade + from ..props_panel_main import OOT_ManualUpgrade + + cs_index_start = get_cs_index_start() if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") if not self.expandTab: return - if headerIndex is not None and headerIndex > 3: - drawCollectionOps(layout, headerIndex - 4, "Room", None, objName) + if headerIndex is not None and headerIndex > (cs_index_start - 1): + drawCollectionOps(layout, headerIndex - cs_index_start, "Room", None, objName) - if headerIndex is not None and headerIndex > 0 and headerIndex < 4: + if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < cs_index_start: layout.prop(self, "usePreviousHeader", text="Use Previous Header") if self.usePreviousHeader: return @@ -166,6 +200,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj menuTab = self.altMenuTab if menuTab == "General": + # General if headerIndex is None or headerIndex == 0: general = layout.column() general.box().label(text="General") @@ -180,13 +215,17 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_game_oot(): general.label(text="This shape type is only implemented on MM", icon="INFO") - # Behaviour - behaviourBox = layout.column() - behaviourBox.box().label(text="Behaviour") - drawEnumWithCustom(behaviourBox, self, "roomBehaviour", "Room Behaviour", "") - drawEnumWithCustom(behaviourBox, self, "linkIdleMode", "Link Idle Mode", "") - behaviourBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") - behaviourBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") + + # Behavior + behaviorBox = layout.column() + behaviorBox.box().label(text="Behavior") + drawEnumWithCustom(behaviorBox, self, get_game_prop_name("room_type"), "Room Type", "", "roomBehaviourCustom") + drawEnumWithCustom(behaviorBox, self, get_game_prop_name("environment_type"), "Environment Type", "", "linkIdleModeCustom") + behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") + behaviorBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") + if not is_game_oot(): + behaviorBox.prop(self, "enable_pos_lights") + behaviorBox.prop(self, "enable_storm") # Time skyboxAndTime = layout.column() @@ -201,7 +240,6 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj timeRow = skyboxAndTime.row() timeRow.prop(self, "timeHours", text="Hours") timeRow.prop(self, "timeMinutes", text="Minutes") - # prop_split(skyboxAndTime, self, "timeValue", "Time Of Day") prop_split(skyboxAndTime, self, "timeSpeed", "Time Speed") # Echo @@ -215,68 +253,83 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj windBoxRow = windBox.row() windBoxRow.prop(self, "windVector", text="") windBox.prop(self, "windStrength", text="Strength") - # prop_split(windBox, self, "windVector", "Wind Vector") elif menuTab == "Objects": upgradeLayout = layout.column() objBox = layout.column() objBox.box().label(text="Objects") - if len(self.objectList) > 16: + if is_game_oot() and len(self.objectList) > 16: objBox.label(text="You are over the 16 object limit.", icon="ERROR") objBox.label(text="You must allocate more memory in code.") - isLegacy = False + is_legacy = False for i, objProp in enumerate(self.objectList): objProp.draw_props(objBox, headerIndex, i, objName) - if "objectID" in objProp: - isLegacy = True + if is_game_oot() and "objectID" in objProp: + is_legacy = True - if isLegacy: + if is_game_oot() and is_legacy: upgradeLayout.label(text="Legacy data has not been upgraded!") upgradeLayout.operator(OOT_ManualUpgrade.bl_idname, text="Upgrade Data Now!") - objBox.enabled = False if isLegacy else True + objBox.enabled = False if is_legacy else True drawAddButton(objBox, len(self.objectList), "Object", headerIndex, objName) -class OOTAlternateRoomHeaderProperty(PropertyGroup): - childNightHeader: PointerProperty(name="Child Night Header", type=OOTRoomHeaderProperty) - adultDayHeader: PointerProperty(name="Adult Day Header", type=OOTRoomHeaderProperty) - adultNightHeader: PointerProperty(name="Adult Night Header", type=OOTRoomHeaderProperty) - cutsceneHeaders: CollectionProperty(type=OOTRoomHeaderProperty) +def update_cutscene_index(self: "Z64_AlternateRoomHeaderProperty", context: Context): + cs_index_start = get_cs_index_start() + + if self.currentCutsceneIndex < cs_index_start: + self.currentCutsceneIndex = cs_index_start + + onHeaderMenuTabChange(self, context) + + +class Z64_AlternateRoomHeaderProperty(PropertyGroup): + cutsceneHeaders: CollectionProperty(type=Z64_RoomHeaderProperty) + currentCutsceneIndex: IntProperty(update=update_cutscene_index) + # OoT exclusive + childNightHeader: PointerProperty(name="Child Night Header", type=Z64_RoomHeaderProperty) + adultDayHeader: PointerProperty(name="Adult Day Header", type=Z64_RoomHeaderProperty) + adultNightHeader: PointerProperty(name="Adult Night Header", type=Z64_RoomHeaderProperty) headerMenuTab: EnumProperty(name="Header Menu", items=ootEnumHeaderMenu, update=onHeaderMenuTabChange) - currentCutsceneIndex: IntProperty(min=4, default=4, update=onHeaderMenuTabChange) def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - # headerSetup.box().label(text = "Alternate Headers") - headerSetupBox = headerSetup.column() - - headerSetupBox.row().prop(self, "headerMenuTab", expand=True) - if self.headerMenuTab == "Child Night": - self.childNightHeader.draw_props(headerSetupBox, None, 1, objName) - elif self.headerMenuTab == "Adult Day": - self.adultDayHeader.draw_props(headerSetupBox, None, 2, objName) - elif self.headerMenuTab == "Adult Night": - self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) - elif self.headerMenuTab == "Cutscene": + cs_index_start = get_cs_index_start() + can_draw_cs_header = not is_game_oot() + + if not can_draw_cs_header: + headerSetupBox = headerSetup.column() + headerSetupBox.row().prop(self, "headerMenuTab", expand=True) + + if self.headerMenuTab == "Child Night": + self.childNightHeader.draw_props(headerSetupBox, None, 1, objName) + elif self.headerMenuTab == "Adult Day": + self.adultDayHeader.draw_props(headerSetupBox, None, 2, objName) + elif self.headerMenuTab == "Adult Night": + self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) + elif self.headerMenuTab == "Cutscene": + can_draw_cs_header = True + + if can_draw_cs_header: prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") drawAddButton(headerSetup, len(self.cutsceneHeaders), "Room", None, objName) index = self.currentCutsceneIndex - if index - 4 < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - 4].draw_props(headerSetup, None, index, objName) + if index - cs_index_start < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - cs_index_start].draw_props(headerSetup, None, index, objName) else: headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") classes = ( - OOTObjectProperty, - OOTBGProperty, - OOTRoomHeaderProperty, - OOTAlternateRoomHeaderProperty, + Z64_ObjectProperty, + Z64_BGProperty, + Z64_RoomHeaderProperty, + Z64_AlternateRoomHeaderProperty, ) @@ -284,8 +337,8 @@ def room_props_register(): for cls in classes: register_class(cls) - Object.ootRoomHeader = PointerProperty(type=OOTRoomHeaderProperty) - Object.ootAlternateRoomHeaders = PointerProperty(type=OOTAlternateRoomHeaderProperty) + Object.ootRoomHeader = PointerProperty(type=Z64_RoomHeaderProperty) + Object.ootAlternateRoomHeaders = PointerProperty(type=Z64_AlternateRoomHeaderProperty) def room_props_unregister(): diff --git a/fast64_internal/z64/room/properties/__init__.py b/fast64_internal/z64/room/properties/__init__.py deleted file mode 100644 index cdf320ae9..000000000 --- a/fast64_internal/z64/room/properties/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -from .oot_props import ( - OOTRoomHeaderProperty, - OOTBGProperty, - OOTAlternateRoomHeaderProperty, - OOTObjectProperty, - room_props_register, - room_props_unregister, -) -from .mm_props import ( - MM_RoomHeaderProperty, - MM_AlternateRoomHeaderProperty, - mm_room_props_register, - mm_room_props_unregister, -) diff --git a/fast64_internal/z64/room/properties/mm_props.py b/fast64_internal/z64/room/properties/mm_props.py deleted file mode 100644 index 6a8352790..000000000 --- a/fast64_internal/z64/room/properties/mm_props.py +++ /dev/null @@ -1,261 +0,0 @@ -import bpy -from bpy.types import PropertyGroup, UILayout, Image, Object -from bpy.utils import register_class, unregister_class -from ....utility import prop_split -from ...utility import ( - drawCollectionOps, - onMenuTabChange, - onHeaderMenuTabChange, - drawEnumWithCustom, - drawAddButton, - is_game_oot, -) -from ..operators import MM_SearchObjectEnumOperator - -from bpy.props import ( - EnumProperty, - IntProperty, - StringProperty, - FloatProperty, - CollectionProperty, - PointerProperty, - BoolProperty, - IntVectorProperty, -) - -from ...constants import ( - mm_data, - mm_enum_room_type, - mm_enum_environvment_type, - ootEnumRoomShapeType, -) - -ootEnumRoomMenuAlternate = [ - ("General", "General", "General"), - ("Objects", "Objects", "Objects"), -] -ootEnumRoomMenu = ootEnumRoomMenuAlternate + [ - ("Alternate", "Alternate", "Alternate"), -] - - -class MM_ObjectProperty(PropertyGroup): - expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") - objectIDCustom: StringProperty(default="OBJECT_CUSTOM") - - def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): - if self.objectKey != "Custom": - objectName = mm_data.object_data.objects_by_key[self.objectKey].name - else: - objectName = self.objectIDCustom - - objItemBox = layout.column() - row = objItemBox.row() - row.label(text=f"{objectName}") - buttons = row.row(align=True) - objSearch = buttons.operator(MM_SearchObjectEnumOperator.bl_idname, icon="VIEWZOOM", text="Select") - drawCollectionOps(buttons, index, "Object", headerIndex, objName, compact=True) - objSearch.obj_name = objName - objSearch.header_index = headerIndex if headerIndex is not None else 0 - objSearch.index = index - - if self.objectKey == "Custom": - prop_split(objItemBox, self, "objectIDCustom", "Object ID Custom") - - -class MM_BGProperty(PropertyGroup): - image: PointerProperty(type=Image) - # camera: IntProperty(name="Camera Index", min=0) - otherModeFlags: StringProperty( - name="DPSetOtherMode Flags", default="0x0000", description="See src/code/z_room.c:func_8009638C()" - ) - - def draw_props(self, layout: UILayout, index: int, objName: str, isMulti: bool): - box = layout.box().column() - - box.template_ID(self, "image", new="image.new", open="image.open") - # if isMulti: - # prop_split(box, self, "camera", "Camera") - prop_split(box, self, "otherModeFlags", "Other Mode Flags") - drawCollectionOps(box, index, "BgImage", None, objName) - - -class MM_RoomHeaderProperty(PropertyGroup): - expandTab: BoolProperty(name="Expand Tab") - menuTab: EnumProperty(items=ootEnumRoomMenu, update=onMenuTabChange) - altMenuTab: EnumProperty(items=ootEnumRoomMenuAlternate) - - roomIndex: IntProperty(name="Room Index", default=0, min=0) - - # SCENE_CMD_ROOM_BEHAVIOR - roomBehaviour: EnumProperty(items=mm_enum_room_type, default="0x00") - roomBehaviourCustom: StringProperty(default="0x00") - showInvisibleActors: BoolProperty(name="Show Invisible Actors") - enable_pos_lights: BoolProperty(name="Enable Pos Lights") - enable_storm: BoolProperty(name="Enable Storm") - linkIdleMode: EnumProperty(name="Environment Type", items=mm_enum_environvment_type, default="0x00") - linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") - - # SCENE_CMD_WIND_SETTINGS - setWind: BoolProperty(name="Set Wind") - windVector: IntVectorProperty(name="Wind Vector", size=3, min=-127, max=127) - windStrength: IntProperty(name="Wind Strength", min=0, max=255) - - # SCENE_CMD_TIME_SETTINGS - leaveTimeUnchanged: BoolProperty(name="Leave Time Unchanged", default=True) - timeHours: IntProperty(name="Hours", default=0, min=0, max=23) # 0xFFFE - timeMinutes: IntProperty(name="Minutes", default=0, min=0, max=59) - timeSpeed: FloatProperty(name="Time Speed", default=1, min=-13, max=13) # 0xA - - # SCENE_CMD_SKYBOX_DISABLES - disableSkybox: BoolProperty(name="Disable Skybox") - disableSunMoon: BoolProperty(name="Disable Sun/Moon") - - # SCENE_CMD_ECHO_SETTINGS - echo: StringProperty(name="Echo", default="0x00") - - # SCENE_CMD_OBJECT_LIST - objectList: CollectionProperty(type=MM_ObjectProperty) - - # SCENE_CMD_ROOM_SHAPE - roomShape: EnumProperty(items=ootEnumRoomShapeType, default="ROOM_SHAPE_TYPE_NORMAL") - defaultCullDistance: IntProperty(name="Default Cull Distance", min=1, default=100) - bgImageList: CollectionProperty(type=MM_BGProperty) - bgImageTab: BoolProperty(name="BG Images") - - def drawBGImageList(self, layout: UILayout, objName: str): - box = layout.column() - box.label(text="BG images do not work currently.", icon="ERROR") - box.prop(self, "bgImageTab", text="BG Images", icon="TRIA_DOWN" if self.bgImageTab else "TRIA_RIGHT") - if self.bgImageTab: - box.label(text="Only one room allowed per scene.", icon="INFO") - box.label(text="Must be framebuffer sized (320x240).", icon="INFO") - box.label(text="Must be jpg file with file marker.", icon="INFO") - box.label(text="Ex. MsPaint compatible, Photoshop not.") - box.label(text="Can't use files generated in Blender.") - imageCount = len(self.bgImageList) - for i in range(imageCount): - self.bgImageList[i].draw_props(box, i, objName, imageCount > 1) - - drawAddButton(box, len(self.bgImageList), "BgImage", None, objName) - - def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from ...props_panel_main import OOT_ManualUpgrade - - if dropdownLabel is not None: - layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") - if not self.expandTab: - return - if headerIndex is not None and headerIndex > 0: - drawCollectionOps(layout, headerIndex - 1, "Room", None, objName) - - if headerIndex is None or headerIndex == 0: - layout.row().prop(self, "menuTab", expand=True) - menuTab = self.menuTab - else: - layout.row().prop(self, "altMenuTab", expand=True) - menuTab = self.altMenuTab - - if menuTab == "General": - if headerIndex is None or headerIndex == 0: - general = layout.column() - general.box().label(text="General") - prop_split(general, self, "roomIndex", "Room Index") - prop_split(general, self, "roomShape", "Room Shape") - if self.roomShape == "ROOM_SHAPE_TYPE_IMAGE": - self.drawBGImageList(general, objName) - if self.roomShape == "ROOM_SHAPE_TYPE_CULLABLE": - general.label(text="The 'Cullable' room shape type is for CPU culling,", icon="INFO") - general.label(text="and requires meshes to be parented to Custom Cull Group empties.") - general.label(text="RSP culling is done automatically regardless of room shape.") - prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") - if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_game_oot(): - general.label(text="This shape type is only implemented on MM", icon="INFO") - - # Behaviour - behaviourBox = layout.column() - behaviourBox.box().label(text="Behaviour") - drawEnumWithCustom(behaviourBox, self, "roomBehaviour", "Room Type", "") - drawEnumWithCustom(behaviourBox, self, "linkIdleMode", "Environment Type", "") - behaviourBox.prop(self, "showInvisibleActors") - behaviourBox.prop(self, "enable_pos_lights") - behaviourBox.prop(self, "enable_storm") - - # Time - skyboxAndTime = layout.column() - skyboxAndTime.box().label(text="Skybox And Time") - - # Skybox - skyboxAndTime.prop(self, "disableSkybox", text="Disable Skybox") - skyboxAndTime.prop(self, "disableSunMoon", text="Disable Sun/Moon") - skyboxAndTime.prop(self, "leaveTimeUnchanged", text="Leave Time Unchanged") - if not self.leaveTimeUnchanged: - skyboxAndTime.label(text="Time") - timeRow = skyboxAndTime.row() - timeRow.prop(self, "timeHours", text="Hours") - timeRow.prop(self, "timeMinutes", text="Minutes") - # prop_split(skyboxAndTime, self, "timeValue", "Time Of Day") - prop_split(skyboxAndTime, self, "timeSpeed", "Time Speed") - - # Echo - prop_split(skyboxAndTime, self, "echo", "Echo") - - # Wind - windBox = layout.column() - windBox.box().label(text="Wind") - windBox.prop(self, "setWind", text="Set Wind") - if self.setWind: - windBoxRow = windBox.row() - windBoxRow.prop(self, "windVector", text="") - windBox.prop(self, "windStrength", text="Strength") - # prop_split(windBox, self, "windVector", "Wind Vector") - - elif menuTab == "Objects": - objBox = layout.column() - objBox.box().label(text="Objects") - - for i, objProp in enumerate(self.objectList): - objProp.draw_props(objBox, headerIndex, i, objName) - - drawAddButton(objBox, len(self.objectList), "Object", headerIndex, objName) - - -class MM_AlternateRoomHeaderProperty(PropertyGroup): - cutsceneHeaders: CollectionProperty(type=MM_RoomHeaderProperty) - currentCutsceneIndex: IntProperty(min=1, default=1, update=onHeaderMenuTabChange) - - def draw_props(self, layout: UILayout, objName: str): - headerSetup = layout.column() - - prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") - drawAddButton(headerSetup, len(self.cutsceneHeaders), "Room", None, objName) - index = self.currentCutsceneIndex - if index - 1 < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - 1].draw_props(headerSetup, None, index, objName) - else: - headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") - - -classes = ( - MM_ObjectProperty, - MM_BGProperty, - MM_RoomHeaderProperty, - MM_AlternateRoomHeaderProperty, -) - - -def mm_room_props_register(): - for cls in classes: - register_class(cls) - - Object.mm_room_header = PointerProperty(type=MM_RoomHeaderProperty) - Object.mm_alternate_room_headers = PointerProperty(type=MM_AlternateRoomHeaderProperty) - - -def mm_room_props_unregister(): - del bpy.types.Object.mm_room_header - del bpy.types.Object.mm_alternate_room_headers - - for cls in reversed(classes): - unregister_class(cls) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index d2c5ad8b5..aa8123106 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -404,7 +404,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): description="Sets a flag that indicates the region has been visited. Scene indices are mapped to their region in `gSceneIdsPerRegion` from `z_inventory.c`", ) - # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `MM_RoomHeaderProperty`) + # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `Z64_RoomHeaderProperty`) minimap_room_expand: BoolProperty(name="Expand Tab") minimap_room_list: CollectionProperty(type=MM_MinimapRoomProperty, name="Minimap Room List") minimap_scale: IntProperty(name="Minimap Scale", default=0) diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 5291a8e06..c1583187a 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -31,7 +31,7 @@ def upgradeObjectList(objList: CollectionProperty, objData: OoT_ObjectData): if objectID == "Custom": obj.objectKey = objectID else: - obj.objectKey = objData.objectsByID[objectID].key + obj.objectKey = objData.objects_by_id[objectID].key del obj["objectID"] diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 4fb69c3c9..addf150a1 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -28,7 +28,7 @@ ootEnumLinkIdle, ootEnumRoomBehaviour, mm_enum_room_type, - mm_enum_environvment_type, + mm_enum_environment_type, ) from dataclasses import dataclass @@ -68,7 +68,7 @@ def get_game_enum(enum_type: str): "enum_skybox_config": mm_enum_skybox_config, "enum_seq_id": mm_data.enum_seq_id, "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above - "enum_env_type": mm_enum_environvment_type, + "enum_env_type": mm_enum_environment_type, "enum_room_type": mm_enum_room_type, "enum_actor_id": mm_data.actor_data.enum_actor_id, }, @@ -86,6 +86,9 @@ def get_game_prop_name(prop_type: str): "seq_id": "musicSeq", "ambience_id": "nightSeq", "draw_config": "drawConfig", + "object_key": "objectKey", + "room_type": "roomBehaviour", + "environment_type": "linkIdleMode", }, "MM": { "global_obj": "mm_global_obj", @@ -94,6 +97,9 @@ def get_game_prop_name(prop_type: str): "seq_id": "mm_seq_id", "ambience_id": "mm_ambience_id", "draw_config": "mm_draw_config", + "object_key": "mm_object_key", + "room_type": "mm_room_type", + "environment_type": "mm_environment_type", }, } @@ -116,8 +122,8 @@ def get_game_props(obj: Object, header_type: str): "MM": { "scene": obj.ootSceneHeader, "alt_scene": obj.ootAlternateSceneHeaders, - "room": obj.mm_room_header, - "alt_room": obj.mm_alternate_room_headers, + "room": obj.ootRoomHeader, + "alt_room": obj.ootAlternateRoomHeaders, "actor": obj.mm_actor_property, "transition_actor": obj.mm_transition_actor_property, "entrance_actor": obj.mm_entrance_property, From 3ca26b02a56ffccfd27a0c6a89bcc6623cc6adc9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 02:21:13 +0100 Subject: [PATCH 023/126] merge OoT and MM for room properties (2/2) --- __init__.py | 14 +++++++++++ fast64_internal/z64/constants.py | 26 +++++++++---------- fast64_internal/z64/importer/room_header.py | 8 +++--- fast64_internal/z64/room/operators.py | 6 ++--- fast64_internal/z64/room/properties.py | 6 ++--- fast64_internal/z64/scene/properties.py | 28 +++++++++++++-------- 6 files changed, 54 insertions(+), 34 deletions(-) diff --git a/__init__.py b/__init__.py index 655acbd2a..a1186ce55 100644 --- a/__init__.py +++ b/__init__.py @@ -22,6 +22,7 @@ from .fast64_internal.z64 import OOT_Properties, oot_register, oot_unregister from .fast64_internal.z64.constants import oot_world_defaults from .fast64_internal.z64.props_panel_main import OOT_ObjectProperties +from .fast64_internal.z64.utility import getObjectList from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister @@ -409,6 +410,19 @@ def set_game_defaults(scene: bpy.types.Scene, set_ucode=True): def gameEditorUpdate(scene: bpy.types.Scene, _context): set_game_defaults(scene) + # reset `currentCutsceneIndex` when switching games + if scene.gameEditorMode in {"OOT", "MM"}: + cs_index_start = 4 if scene.gameEditorMode == "OOT" else 1 + + for scene_obj in bpy.data.objects: + scene_obj.ootAlternateSceneHeaders.currentCutsceneIndex = cs_index_start + + if scene_obj.type == "EMPTY" and scene_obj.ootEmptyType == "Scene": + room_obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Room") + + for room_obj in room_obj_list: + room_obj.ootAlternateRoomHeaders.currentCutsceneIndex = cs_index_start + # called on add-on enabling # register operators and panels here diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index 27818eb97..a15be1dc0 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -36,13 +36,13 @@ mm_enum_environment_type = [ ("Custom", "Custom", "Custom"), - ("0x00", "Default", "ROOM_ENV_DEFAULT"), - ("0x01", "Cold", "ROOM_ENV_COLD"), - ("0x02", "Warm", "ROOM_ENV_WARM"), - ("0x03", "Hot", "ROOM_ENV_HOT"), - ("0x04", "Unknown Stretch 1", "ROOM_ENV_UNK_STRETCH_1"), - ("0x05", "Unknown Stretch 2", "ROOM_ENV_UNK_STRETCH_2"), - ("0x06", "Unknown Stretch 3", "ROOM_ENV_UNK_STRETCH_3"), + ("ROOM_ENV_DEFAULT", "Default", "0x00"), + ("ROOM_ENV_COLD", "Cold", "0x01"), + ("ROOM_ENV_WARM", "Warm", "0x02"), + ("ROOM_ENV_HOT", "Hot", "0x03"), + ("ROOM_ENV_UNK_STRETCH_1", "Unknown Stretch 1", "0x04"), + ("ROOM_ENV_UNK_STRETCH_2", "Unknown Stretch 2", "0x05"), + ("ROOM_ENV_UNK_STRETCH_3", "Unknown Stretch 3", "0x06"), ] ootEnumCloudiness = [ @@ -662,12 +662,12 @@ mm_enum_room_type = [ ("Custom", "Custom", "Custom"), - ("0x00", "Normal", "ROOM_TYPE_NORMAL"), - ("0x01", "Dungeon", "ROOM_TYPE_DUNGEON"), - ("0x02", "Indoors", "ROOM_TYPE_INDOORS"), - ("0x03", "Type 3", "ROOM_TYPE_3"), - ("0x04", "Type 4 (Horse related)", "ROOM_TYPE_4"), - ("0x05", "Boss", "ROOM_TYPE_BOSS"), + ("ROOM_TYPE_NORMAL", "Normal", "0x00"), + ("ROOM_TYPE_DUNGEON", "Dungeon", "0x01"), + ("ROOM_TYPE_INDOORS", "Indoors", "0x02"), + ("ROOM_TYPE_3", "Type 3", "0x03"), + ("ROOM_TYPE_4", "Type 4 (Horse related)", "0x04"), + ("ROOM_TYPE_BOSS", "Boss", "0x05"), ] ootEnumDrawConfig = [ diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 738af3e48..a7a06b008 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,7 @@ import re from ...utility import hexOrDecInt -from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum, get_cs_index_start +from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum, get_cs_index_start, get_game_prop_name from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty from ..constants import oot_data, mm_data @@ -29,7 +29,7 @@ def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectLi objByID = get_object_from_id(object) if objByID is not None: - objectProp.objectKey = objByID.key + setattr(objectProp, get_game_prop_name("object_key"), objByID.key) else: objectProp.objectIDCustom = object @@ -75,8 +75,8 @@ def parseRoomCommands( elif command == "SCENE_CMD_ECHO_SETTINGS": roomHeader.echo = args[0] elif command == "SCENE_CMD_ROOM_BEHAVIOR": - setCustomProperty(roomHeader, "roomBehaviour", args[0], get_game_enum("enum_room_type")) - setCustomProperty(roomHeader, "linkIdleMode", args[1], get_game_enum("enum_env_type")) + setCustomProperty(roomHeader, get_game_prop_name("room_type"), args[0], get_game_enum("enum_room_type")) + setCustomProperty(roomHeader, get_game_prop_name("environment_type"), args[1], get_game_enum("enum_env_type")) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" if is_game_oot(): diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index 8f686c15e..d0a8b665a 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -36,12 +36,12 @@ class MM_SearchObjectEnumOperator(Operator): bl_options = {"REGISTER", "UNDO"} object_key: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") - header_index: IntProperty(default=0, min=0) + headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) - obj_name: StringProperty() + objName: StringProperty() def execute(self, context): - roomHeader = ootGetSceneOrRoomHeader(bpy.data.objects[self.obj_name], self.header_index, True) + roomHeader = ootGetSceneOrRoomHeader(bpy.data.objects[self.objName], self.headerIndex, True) roomHeader.objectList[self.index].object_key = self.object_key context.region.tag_redraw() self.report({"INFO"}, "Selected: " + self.object_key) diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index f4075a067..6b907cb01 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -118,11 +118,11 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) roomBehaviour: EnumProperty(items=ootEnumRoomBehaviour, default="0x00") - mm_room_type: EnumProperty(items=mm_enum_room_type, default="0x00") + mm_room_type: EnumProperty(items=mm_enum_room_type, default="ROOM_TYPE_NORMAL") roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") linkIdleMode: EnumProperty(name="Environment Type", items=ootEnumLinkIdle, default="0x00") - mm_environment_type: EnumProperty(name="Environment Type", items=mm_enum_environment_type, default="0x00") + mm_environment_type: EnumProperty(name="Environment Type", items=mm_enum_environment_type, default="ROOM_ENV_DEFAULT") linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") # OoT exclusive @@ -289,7 +289,7 @@ def update_cutscene_index(self: "Z64_AlternateRoomHeaderProperty", context: Cont class Z64_AlternateRoomHeaderProperty(PropertyGroup): cutsceneHeaders: CollectionProperty(type=Z64_RoomHeaderProperty) - currentCutsceneIndex: IntProperty(update=update_cutscene_index) + currentCutsceneIndex: IntProperty(default=1, update=update_cutscene_index) # OoT exclusive childNightHeader: PointerProperty(name="Child Night Header", type=Z64_RoomHeaderProperty) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index aa8123106..c4ccb66d4 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -129,18 +129,24 @@ class Z64_ExitProperty(PropertyGroup): def draw_props(self, layout: UILayout, index: int, headerIndex: int, objName: str): box = layout.box() box.prop(self, "expandTab", text="Exit " + str(index + 1), icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") + if self.expandTab: drawCollectionOps(box, index, "Exit", headerIndex, objName) - drawEnumWithCustom(box, self, "exitIndex", "Exit Index", "") - if is_game_oot() and self.exitIndex != "Custom": - box.label(text='This is unfinished, use "Custom".') - exitGroup = box.column() - exitGroup.enabled = False - drawEnumWithCustom(exitGroup, self, "scene", "Scene", "") - exitGroup.prop(self, "continueBGM", text="Continue BGM") - exitGroup.prop(self, "displayTitleCard", text="Display Title Card") - drawEnumWithCustom(exitGroup, self, "fadeInAnim", "Fade In Animation", "") - drawEnumWithCustom(exitGroup, self, "fadeOutAnim", "Fade Out Animation", "") + + if is_game_oot(): + drawEnumWithCustom(box, self, "exitIndex", "Exit Index", "") + + if self.exitIndex != "Custom": + box.label(text='This is unfinished, use "Custom".') + exitGroup = box.column() + exitGroup.enabled = False + drawEnumWithCustom(exitGroup, self, "scene", "Scene", "") + exitGroup.prop(self, "continueBGM", text="Continue BGM") + exitGroup.prop(self, "displayTitleCard", text="Display Title Card") + drawEnumWithCustom(exitGroup, self, "fadeInAnim", "Fade In Animation", "") + drawEnumWithCustom(exitGroup, self, "fadeOutAnim", "Fade Out Animation", "") + else: + prop_split(box, self, "exitIndexCustom", "Exit Index") class Z64_LightProperty(PropertyGroup): @@ -566,7 +572,7 @@ def update_cutscene_index(self: "Z64_AlternateSceneHeaderProperty", context: Con class Z64_AlternateSceneHeaderProperty(PropertyGroup): cutsceneHeaders: CollectionProperty(type=Z64_SceneHeaderProperty) - currentCutsceneIndex: IntProperty(update=update_cutscene_index) + currentCutsceneIndex: IntProperty(default=1, update=update_cutscene_index) # OoT exclusive childNightHeader: PointerProperty(name="Child Night Header", type=Z64_SceneHeaderProperty) From f1758e5bf9b2f72f7bc94f85207cfd7dc9f5ab93 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 02:21:25 +0100 Subject: [PATCH 024/126] format --- fast64_internal/z64/cutscene/classes.py | 4 +++- fast64_internal/z64/importer/room_header.py | 13 +++++++++++-- fast64_internal/z64/importer/scene_header.py | 19 +++++++++++++------ fast64_internal/z64/room/properties.py | 12 +++++++++--- fast64_internal/z64/scene/properties.py | 4 +++- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index cf7395aa8..b7a236f77 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -532,7 +532,9 @@ def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Objec if commandType == "Player": commandType = "player_cue" - index = cmdEnum.item_by_key[commandType].index if commandType in cmdEnum.item_by_key else int(commandType, base=16) + index = ( + cmdEnum.item_by_key[commandType].index if commandType in cmdEnum.item_by_key else int(commandType, base=16) + ) item = cmdEnum.item_by_index.get(index) if item is not None: diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index a7a06b008..2d1a7d16c 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,14 @@ import re from ...utility import hexOrDecInt -from ..utility import setCustomProperty, get_game_props, is_game_oot, get_game_enum, get_cs_index_start, get_game_prop_name +from ..utility import ( + setCustomProperty, + get_game_props, + is_game_oot, + get_game_enum, + get_cs_index_start, + get_game_prop_name, +) from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty from ..constants import oot_data, mm_data @@ -76,7 +83,9 @@ def parseRoomCommands( roomHeader.echo = args[0] elif command == "SCENE_CMD_ROOM_BEHAVIOR": setCustomProperty(roomHeader, get_game_prop_name("room_type"), args[0], get_game_enum("enum_room_type")) - setCustomProperty(roomHeader, get_game_prop_name("environment_type"), args[1], get_game_enum("enum_env_type")) + setCustomProperty( + roomHeader, get_game_prop_name("environment_type"), args[1], get_game_enum("enum_env_type") + ) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" if is_game_oot(): diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index a43ace54b..8628fdcb5 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -335,9 +335,7 @@ def parseSceneCommands( enum_id = enum_seq_id.item_by_index[int(args[2])].id - setCustomProperty( - sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id") - ) + setCustomProperty(sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id")) elif command == "SCENE_CMD_ROOM_LIST": # Assumption that all scenes use the same room list. if headerIndex == 0: @@ -366,7 +364,9 @@ def parseSceneCommands( elif command == "SCENE_CMD_SPECIAL_FILES": if is_game_oot(): setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) - setCustomProperty(sceneHeader, get_game_prop_name("global_obj"), args[1], get_game_enum("enum_global_object")) + setCustomProperty( + sceneHeader, get_game_prop_name("global_obj"), args[1], get_game_enum("enum_global_object") + ) elif command == "SCENE_CMD_PATH_LIST" and sharedSceneData.includePaths: pathListName = stripName(args[0]) parsePathList(sceneObj, sceneData, pathListName, headerIndex, sharedSceneData) @@ -385,8 +385,15 @@ def parseSceneCommands( if not is_game_oot(): sceneHeader.skybox_texture_id = args[args_index] args_index += 1 - setCustomProperty(sceneHeader, get_game_prop_name("skybox_id"), args[args_index], get_game_enum("enum_skybox")) - setCustomProperty(sceneHeader, get_game_prop_name("skybox_config"), args[args_index + 1], get_game_enum("enum_skybox_config")) + setCustomProperty( + sceneHeader, get_game_prop_name("skybox_id"), args[args_index], get_game_enum("enum_skybox") + ) + setCustomProperty( + sceneHeader, + get_game_prop_name("skybox_config"), + args[args_index + 1], + get_game_enum("enum_skybox_config"), + ) setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) elif command == "SCENE_CMD_EXIT_LIST": exitListName = stripName(args[0]) diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 6b907cb01..0bb768e01 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -122,7 +122,9 @@ class Z64_RoomHeaderProperty(PropertyGroup): roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") linkIdleMode: EnumProperty(name="Environment Type", items=ootEnumLinkIdle, default="0x00") - mm_environment_type: EnumProperty(name="Environment Type", items=mm_enum_environment_type, default="ROOM_ENV_DEFAULT") + mm_environment_type: EnumProperty( + name="Environment Type", items=mm_enum_environment_type, default="ROOM_ENV_DEFAULT" + ) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") # OoT exclusive @@ -219,8 +221,12 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj # Behavior behaviorBox = layout.column() behaviorBox.box().label(text="Behavior") - drawEnumWithCustom(behaviorBox, self, get_game_prop_name("room_type"), "Room Type", "", "roomBehaviourCustom") - drawEnumWithCustom(behaviorBox, self, get_game_prop_name("environment_type"), "Environment Type", "", "linkIdleModeCustom") + drawEnumWithCustom( + behaviorBox, self, get_game_prop_name("room_type"), "Room Type", "", "roomBehaviourCustom" + ) + drawEnumWithCustom( + behaviorBox, self, get_game_prop_name("environment_type"), "Environment Type", "", "linkIdleModeCustom" + ) behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") behaviorBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") if not is_game_oot(): diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index c4ccb66d4..bb18275fb 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -464,7 +464,9 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj prop_split(skyboxAndSound, self, "skybox_texture_id", "Skybox Texture ID") drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("skybox_id"), "Skybox", "", "skyboxIDCustom") - drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("skybox_config"), "Skybox Config", "", "skyboxCloudinessCustom") + drawEnumWithCustom( + skyboxAndSound, self, get_game_prop_name("skybox_config"), "Skybox Config", "", "skyboxCloudinessCustom" + ) drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("seq_id"), "Music Sequence", "") if is_game_oot(): From f640829086d8abd0ce2fd94d1c9c906f890c4d6e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 02:58:52 +0100 Subject: [PATCH 025/126] merge OoT and MM for actor properties (1/2) --- fast64_internal/z64/__init__.py | 20 +- fast64_internal/z64/actor/operators.py | 6 +- fast64_internal/z64/actor/properties.py | 330 ++++++++++++++++++ .../z64/actor/properties/__init__.py | 17 - .../z64/actor/properties/mm_props.py | 239 ------------- .../z64/actor/properties/oot_props.py | 265 -------------- fast64_internal/z64/exporter/scene/general.py | 2 +- fast64_internal/z64/exporter/utility.py | 4 +- .../z64/importer/scene_pathways.py | 4 +- fast64_internal/z64/importer/utility.py | 6 +- fast64_internal/z64/props_panel_main.py | 14 +- fast64_internal/z64/scene/properties.py | 2 +- fast64_internal/z64/spline/properties.py | 18 +- fast64_internal/z64/utility.py | 10 +- 14 files changed, 366 insertions(+), 571 deletions(-) create mode 100644 fast64_internal/z64/actor/properties.py delete mode 100644 fast64_internal/z64/actor/properties/__init__.py delete mode 100644 fast64_internal/z64/actor/properties/mm_props.py delete mode 100644 fast64_internal/z64/actor/properties/oot_props.py diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 9b43f1707..64e2a4dca 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -2,11 +2,7 @@ from bpy.utils import register_class, unregister_class from .scene.operators import scene_ops_register, scene_ops_unregister -from .scene.properties import ( - OOT_BootupSceneOptions, - scene_props_register, - scene_props_unregister, -) +from .scene.properties import OOT_BootupSceneOptions, scene_props_register, scene_props_unregister from .scene.panels import scene_panels_register, scene_panels_unregister from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister @@ -16,18 +12,10 @@ from .collision.properties import OOTCollisionExportSettings from .room.operators import room_ops_register, room_ops_unregister -from .room.properties import ( - room_props_register, - room_props_unregister, -) +from .room.properties import room_props_register, room_props_unregister from .actor.operators import actor_ops_register, actor_ops_unregister -from .actor.properties import ( - actor_props_register, - actor_props_unregister, - mm_actor_props_register, - mm_actor_props_unregister, -) +from .actor.properties import actor_props_register, actor_props_unregister from .f3d.operators import f3d_ops_register, f3d_ops_unregister from .f3d.properties import OOTDLExportSettings, OOTDLImportSettings, f3d_props_register, f3d_props_unregister @@ -175,7 +163,6 @@ def oot_register(registerPanels): room_props_register() actor_ops_register() actor_props_register() - mm_actor_props_register() oot_obj_register() spline_props_register() f3d_props_register() @@ -216,7 +203,6 @@ def oot_unregister(unregisterPanels): room_props_unregister() actor_ops_unregister() actor_props_unregister() - mm_actor_props_unregister() spline_props_unregister() f3d_props_unregister() anim_ops_unregister() diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 0f1cef187..15562ad4a 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -49,11 +49,11 @@ class MM_SearchActorIDEnumOperator(Operator): def execute(self, context): obj = bpy.data.objects[self.objName] if self.actorUser == "Transition Actor": - obj.mm_transition_actor_property.actor.actorID = self.actorID + obj.ootTransitionActorProperty.actor.actorID = self.actorID elif self.actorUser == "Actor": - obj.mm_actor_property.actorID = self.actorID + obj.ootActorProperty.actorID = self.actorID elif self.actorUser == "Entrance": - obj.ootEntrmm_entrance_propertyanceProperty.actor.actorID = self.actorID + obj.ootEntranceProperty.actor.actorID = self.actorID else: raise PluginError("Invalid actor user for search: " + str(self.actorUser)) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py new file mode 100644 index 000000000..6b715cfd1 --- /dev/null +++ b/fast64_internal/z64/actor/properties.py @@ -0,0 +1,330 @@ +from bpy.types import Object, PropertyGroup, UILayout, Context +from bpy.utils import register_class, unregister_class +from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty +from ...utility import prop_split, label_split +from ..constants import oot_data, ootEnumCamTransition, mm_data +from ..upgrade import upgradeActors +from ..scene.properties import Z64_AlternateSceneHeaderProperty +from ..room.properties import Z64_AlternateRoomHeaderProperty +from .operators import OOT_SearchActorIDEnumOperator, MM_SearchActorIDEnumOperator + +from ..utility import ( + getRoomObj, + getEnumName, + drawAddButton, + drawCollectionOps, + drawEnumWithCustom, + get_game_prop_name, + get_cs_index_start, + is_game_oot, + get_game_enum, +) + +ootEnumSceneSetupPreset = [ + ("Custom", "Custom", "Custom"), + ("All Scene Setups", "All Scene Setups", "All Scene Setups"), + ("All Non-Cutscene Scene Setups", "All Non-Cutscene Scene Setups", "All Non-Cutscene Scene Setups"), +] + + +def update_cutscene_index(self, context: Context): + cs_index_start = get_cs_index_start() + + if self.headerIndex < cs_index_start: + self.headerIndex = cs_index_start + + +class Z64_ActorHeaderItemProperty(PropertyGroup): + headerIndex: IntProperty(name="Scene Setup", min=1, update=update_cutscene_index) + + def draw_props( + self, + layout: UILayout, + propUser: str, + index: int, + altProp: Z64_AlternateSceneHeaderProperty | Z64_AlternateRoomHeaderProperty, + objName: str, + ): + box = layout.column() + row = box.row() + row.prop(self, "headerIndex", text="") + + drawCollectionOps(row.row(align=True), index, propUser, None, objName, compact=True) + + if altProp is not None and self.headerIndex >= len(altProp.cutsceneHeaders) + get_cs_index_start(): + box.label(text="Above header does not exist.", icon="QUESTION") + + +class Z64_ActorHeaderProperty(PropertyGroup): + childDayHeader: BoolProperty(name="Child Day Header", default=True) + cutsceneHeaders: CollectionProperty(type=Z64_ActorHeaderItemProperty) + + # OoT exclusive + sceneSetupPreset: EnumProperty(name="Scene Setup Preset", items=ootEnumSceneSetupPreset, default="All Scene Setups") + childNightHeader: BoolProperty(name="Child Night Header", default=True) + adultDayHeader: BoolProperty(name="Adult Day Header", default=True) + adultNightHeader: BoolProperty(name="Adult Night Header", default=True) + + # MM exclusive + include_in_all_setups: BoolProperty(name="Include in all scene setups") + expand_tab: BoolProperty(name="Expand Tab") + + def checkHeader(self, index: int) -> bool: + if index == 0: + return self.childDayHeader + elif is_game_oot(): + if index == 1: + return self.childNightHeader + elif index == 2: + return self.adultDayHeader + elif index == 3: + return self.adultNightHeader + + return index in [value.headerIndex for value in self.cutsceneHeaders] + + def draw_props( + self, + layout: UILayout, + propUser: str, + altProp: Z64_AlternateSceneHeaderProperty | Z64_AlternateRoomHeaderProperty, + objName: str, + ): + headerSetup = layout.column() + + if is_game_oot(): + prop_split(headerSetup, self, "sceneSetupPreset", "Scene Setup Preset") + + if self.sceneSetupPreset == "Custom": + headerSetupBox = headerSetup.column() + headerSetupBox.prop(self, "childDayHeader", text="Child Day") + prevHeaderName = "childDayHeader" + childNightRow = headerSetupBox.row() + if altProp is None or altProp.childNightHeader.usePreviousHeader: + # Draw previous header checkbox (so get previous state), but labeled + # as current one and grayed out + childNightRow.prop(self, prevHeaderName, text="Child Night") + childNightRow.enabled = False + else: + childNightRow.prop(self, "childNightHeader", text="Child Night") + prevHeaderName = "childNightHeader" + adultDayRow = headerSetupBox.row() + if altProp is None or altProp.adultDayHeader.usePreviousHeader: + adultDayRow.prop(self, prevHeaderName, text="Adult Day") + adultDayRow.enabled = False + else: + adultDayRow.prop(self, "adultDayHeader", text="Adult Day") + prevHeaderName = "adultDayHeader" + adultNightRow = headerSetupBox.row() + if altProp is None or altProp.adultNightHeader.usePreviousHeader: + adultNightRow.prop(self, prevHeaderName, text="Adult Night") + adultNightRow.enabled = False + else: + adultNightRow.prop(self, "adultNightHeader", text="Adult Night") + + headerSetupBox.row().label(text="Cutscene headers to include this actor in:") + for i in range(len(self.cutsceneHeaders)): + headerItemProps: Z64_ActorHeaderItemProperty = self.cutsceneHeaders[i] + headerItemProps.draw_props(headerSetup, propUser, i, altProp, objName) + drawAddButton(headerSetup, len(self.cutsceneHeaders), propUser, None, objName) + else: + header_settings_box = headerSetup.column().box() + + header_settings_box.label(text="Header Settings") + header_settings_box.prop(self, "include_in_all_setups") + + if not self.include_in_all_setups: + header_settings_box.prop(self, "childDayHeader", text="Default Header") + + cs_header_box = header_settings_box.box() + cs_header_box.row().prop( + self, + "expand_tab", + text="Cutscene Headers", + icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT", + ) + + if self.expand_tab: + for i in range(len(self.cutsceneHeaders)): + headerItemProps: Z64_ActorHeaderItemProperty = self.cutsceneHeaders[i] + headerItemProps.draw_props(cs_header_box, propUser, i, altProp, objName) + + drawAddButton(cs_header_box, len(self.cutsceneHeaders), propUser, None, objName) + + +class Z64_ActorProperty(PropertyGroup): + actorID: EnumProperty(name="Actor", items=oot_data.actorData.ootEnumActorID, default="ACTOR_PLAYER") + mm_actor_id: EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") + actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") + actorParam: StringProperty(name="Actor Parameter", default="0x0000") + rotOverride: BoolProperty( + name="Override Rotation", + default=False, + description="For MM, non-zero values means the rotation is used as additional flags and will set the matching flag in the actor ID automatically", + ) + rotOverrideX: StringProperty(name="Rot X", default="0") + rotOverrideY: StringProperty(name="Rot Y", default="0") + rotOverrideZ: StringProperty(name="Rot Z", default="0") + headerSettings: PointerProperty(type=Z64_ActorHeaderProperty) + + @staticmethod + def upgrade_object(obj: Object): + if is_game_oot(): + print(f"Processing '{obj.name}'...") + upgradeActors(obj) + + def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderProperty, objName: str): + actorIDBox = layout.column() + actor_id: str = getattr(self, get_game_prop_name("actor_id")) + + if is_game_oot(): + op_name = OOT_SearchActorIDEnumOperator.bl_idname + else: + op_name = MM_SearchActorIDEnumOperator.bl_idname + + searchOp = actorIDBox.operator(op_name, icon="VIEWZOOM") + searchOp.actorUser = "Actor" + searchOp.objName = objName + + split = actorIDBox.split(factor=0.5) + + if actor_id == "None": + actorIDBox.box().label(text="This Actor was deleted from the XML file.") + return + + split.label(text="Actor ID") + split.label(text=getEnumName(get_game_enum("enum_actor_id"), actor_id)) + + if actor_id == "Custom": + prop_split(actorIDBox, self, "actorIDCustom", "") + + prop_split(actorIDBox, self, "actorParam", "Actor Parameter") + + rot_box = actorIDBox.box() + prop_text = "Override Rotation (ignore Blender rot)" if is_game_oot() else "Use Rotation Flags" + rot_box.prop(self, "rotOverride", text=prop_text) + if self.rotOverride: + prop_split(rot_box, self, "rotOverrideX", "Rot X") + prop_split(rot_box, self, "rotOverrideY", "Rot Y") + prop_split(rot_box, self, "rotOverrideZ", "Rot Z") + + headerProp: Z64_ActorHeaderProperty = self.headerSettings + headerProp.draw_props(actorIDBox, "Actor", altRoomProp, objName) + + +class Z64_TransitionActorProperty(PropertyGroup): + fromRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) + toRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) + cameraTransitionFront: EnumProperty(items=ootEnumCamTransition, default="0x00") + cameraTransitionFrontCustom: StringProperty(default="0x00") + cameraTransitionBack: EnumProperty(items=ootEnumCamTransition, default="0x00") + cameraTransitionBackCustom: StringProperty(default="0x00") + isRoomTransition: BoolProperty(name="Is Room Transition", default=True) + + actor: PointerProperty(type=Z64_ActorProperty) + + # MM exclusive + cutscene_id: StringProperty( + name="Cutscene ID", default="CS_ID_GLOBAL_END", description="See the `CutsceneId` enum for more values" + ) + + def isRoomEmptyObject(self, obj: Object): + return obj.type == "EMPTY" and obj.ootEmptyType == "Room" + + def draw_props( + self, layout: UILayout, altSceneProp: Z64_AlternateSceneHeaderProperty, roomObj: Object, objName: str + ): + actorIDBox = layout.column() + searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") + searchOp.actorUser = "Transition Actor" + searchOp.objName = objName + + split = actorIDBox.split(factor=0.5) + split.label(text="Actor ID") + split.label(text=getEnumName(oot_data.actorData.ootEnumActorID, self.actor.actorID)) + + if self.actor.actorID == "Custom": + prop_split(actorIDBox, self.actor, "actorIDCustom", "") + + if not is_game_oot(): + prop_split(actorIDBox, self, "cutscene_id", "Cutscene ID") + + prop_split(actorIDBox, self.actor, "actorParam", "Actor Parameter") + + if roomObj is None: + actorIDBox.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") + else: + actorIDBox.prop(self, "isRoomTransition") + if self.isRoomTransition: + prop_split(actorIDBox, self, "fromRoom", "Room To Transition From") + prop_split(actorIDBox, self, "toRoom", "Room To Transition To") + if self.fromRoom == self.toRoom: + actorIDBox.label(text="Warning: You selected the same room!", icon="ERROR") + actorIDBox.label(text='Y+ side of door faces toward the "from" room.', icon="ORIENTATION_NORMAL") + drawEnumWithCustom(actorIDBox, self, "cameraTransitionFront", "Camera Transition Front", "") + drawEnumWithCustom(actorIDBox, self, "cameraTransitionBack", "Camera Transition Back", "") + + headerProps: Z64_ActorHeaderProperty = self.actor.headerSettings + headerProps.draw_props(actorIDBox, "Transition Actor", altSceneProp, objName) + + +class Z64_EntranceProperty(PropertyGroup): + # This is also used in entrance list. + spawnIndex: IntProperty(min=0) + customActor: BoolProperty(name="Use Custom Actor") + actor: PointerProperty(type=Z64_ActorProperty) + + tiedRoom: PointerProperty( + type=Object, + poll=lambda self, object: self.isRoomEmptyObject(object), + description="Used to set the room index", + ) + + def isRoomEmptyObject(self, obj: Object): + return obj.type == "EMPTY" and obj.ootEmptyType == "Room" + + def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateSceneHeaderProperty, objName: str): + box = layout.column() + + roomObj = getRoomObj(obj) + if roomObj is None: + box.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") + + entranceProp = obj.ootEntranceProperty + box.prop(entranceProp, "customActor") + + if entranceProp.customActor: + prop_split(box, entranceProp.actor, "actorIDCustom", "Actor ID Custom") + + prop_split(box, entranceProp, "tiedRoom", "Room") + prop_split(box, entranceProp, "spawnIndex", "Spawn Index") + prop_split(box, entranceProp.actor, "actorParam", "Actor Param") + + headerProps: Z64_ActorHeaderProperty = entranceProp.actor.headerSettings + headerProps.draw_props(box, "Entrance", altSceneProp, objName) + + +classes = ( + Z64_ActorHeaderItemProperty, + Z64_ActorHeaderProperty, + Z64_ActorProperty, + Z64_TransitionActorProperty, + Z64_EntranceProperty, +) + + +def actor_props_register(): + for cls in classes: + register_class(cls) + + Object.ootActorProperty = PointerProperty(type=Z64_ActorProperty) + Object.ootTransitionActorProperty = PointerProperty(type=Z64_TransitionActorProperty) + Object.ootEntranceProperty = PointerProperty(type=Z64_EntranceProperty) + + +def actor_props_unregister(): + del Object.ootActorProperty + del Object.ootTransitionActorProperty + del Object.ootEntranceProperty + + for cls in reversed(classes): + unregister_class(cls) diff --git a/fast64_internal/z64/actor/properties/__init__.py b/fast64_internal/z64/actor/properties/__init__.py deleted file mode 100644 index 0f47efeaf..000000000 --- a/fast64_internal/z64/actor/properties/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -from .oot_props import ( - OOTActorProperty, - OOTTransitionActorProperty, - OOTEntranceProperty, - OOTActorHeaderProperty, - actor_props_register, - actor_props_unregister, -) - -from .mm_props import ( - MM_ActorProperty, - MM_TransitionActorProperty, - MM_EntranceProperty, - MM_ActorHeaderProperty, - mm_actor_props_register, - mm_actor_props_unregister, -) diff --git a/fast64_internal/z64/actor/properties/mm_props.py b/fast64_internal/z64/actor/properties/mm_props.py deleted file mode 100644 index bc471df7c..000000000 --- a/fast64_internal/z64/actor/properties/mm_props.py +++ /dev/null @@ -1,239 +0,0 @@ -from bpy.types import Object, PropertyGroup, UILayout -from bpy.utils import register_class, unregister_class -from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty -from ....utility import prop_split, label_split -from ...constants import mm_data, ootEnumCamTransition -from ...upgrade import upgradeActors -from ...room.properties import Z64_AlternateRoomHeaderProperty -from ..operators import MM_SearchActorIDEnumOperator - -from ...utility import ( - getRoomObj, - getEnumName, - drawAddButton, - drawCollectionOps, - drawEnumWithCustom, -) - - -class MM_ActorHeaderItemProperty(PropertyGroup): - headerIndex: IntProperty(name="Scene Setup", min=1, default=1) - - def draw_props( - self, - layout: UILayout, - propUser: str, - index: int, - altProp: Z64_AlternateRoomHeaderProperty, - objName: str, - ): - box = layout.column() - row = box.row() - row.prop(self, "headerIndex", text="") - - drawCollectionOps(row.row(align=True), index, propUser, None, objName, compact=True) - - if altProp is not None and self.headerIndex >= len(altProp.cutsceneHeaders) + 1: - box.label(text="Above header does not exist.", icon="QUESTION") - - -class MM_ActorHeaderProperty(PropertyGroup): - include_in_all_setups: BoolProperty(name="Include in all scene setups") - childDayHeader: BoolProperty(name="Child Day Header", default=True) - cutsceneHeaders: CollectionProperty(type=MM_ActorHeaderItemProperty) - expand_tab: BoolProperty(name="Expand Tab") - - def checkHeader(self, index: int) -> bool: - if index == 0: - return self.childDayHeader - else: - return index in [value.headerIndex for value in self.cutsceneHeaders] - - def draw_props( - self, - layout: UILayout, - propUser: str, - altProp: Z64_AlternateRoomHeaderProperty, - objName: str, - ): - headerSetup = layout.column() - - header_settings_box = headerSetup.column().box() - header_settings_box.label(text="Header Settings") - header_settings_box.prop(self, "include_in_all_setups") - - if not self.include_in_all_setups: - header_settings_box.prop(self, "childDayHeader", text="Default Header") - - cs_header_box = header_settings_box.box() - cs_header_box.row().prop( - self, - "expand_tab", - text="Cutscene Headers", - icon="TRIA_DOWN" if self.expand_tab else "TRIA_RIGHT", - ) - - if self.expand_tab: - for i in range(len(self.cutsceneHeaders)): - headerItemProps: MM_ActorHeaderItemProperty = self.cutsceneHeaders[i] - headerItemProps.draw_props(cs_header_box, propUser, i, altProp, objName) - - drawAddButton(cs_header_box, len(self.cutsceneHeaders), propUser, None, objName) - - -class MM_ActorProperty(PropertyGroup): - actorID: EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") - actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") - actorParam: StringProperty(name="Actor Parameter", default="0x0000") - rotOverride: BoolProperty( - name="Override Rotation", - default=False, - description="Non-zero values means the rotation is used as additional flags and will set the matching flag in the actor ID automatically", - ) - rotOverrideX: StringProperty(name="Rot X", default="0") - rotOverrideY: StringProperty(name="Rot Y", default="0") - rotOverrideZ: StringProperty(name="Rot Z", default="0") - headerSettings: PointerProperty(type=MM_ActorHeaderProperty) - - def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderProperty, objName: str): - actorIDBox = layout.column() - searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") - searchOp.actorUser = "Actor" - searchOp.objName = objName - - split = actorIDBox.split(factor=0.5) - - if self.actorID == "None": - actorIDBox.box().label(text="This Actor was deleted from the XML file.") - return - - split.label(text="Actor ID") - split.label(text=getEnumName(mm_data.actor_data.enum_actor_id, self.actorID)) - - if self.actorID == "Custom": - prop_split(actorIDBox, self, "actorIDCustom", "") - - prop_split(actorIDBox, self, "actorParam", "Actor Parameter") - - rot_box = actorIDBox.box() - rot_box.prop(self, "rotOverride", text="Use Rotation Flags") - if self.rotOverride: - prop_split(rot_box, self, "rotOverrideX", "Rot X") - prop_split(rot_box, self, "rotOverrideY", "Rot Y") - prop_split(rot_box, self, "rotOverrideZ", "Rot Z") - - headerProp: MM_ActorHeaderProperty = self.headerSettings - headerProp.draw_props(actorIDBox, "Actor", altRoomProp, objName) - - -class MM_TransitionActorProperty(PropertyGroup): - fromRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) - toRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) - cameraTransitionFront: EnumProperty(items=ootEnumCamTransition, default="0x00") - cameraTransitionFrontCustom: StringProperty(default="0x00") - cameraTransitionBack: EnumProperty(items=ootEnumCamTransition, default="0x00") - cameraTransitionBackCustom: StringProperty(default="0x00") - isRoomTransition: BoolProperty(name="Is Room Transition", default=True) - cutscene_id: StringProperty( - name="Cutscene ID", default="CS_ID_GLOBAL_END", description="See the `CutsceneId` enum for more values" - ) - - actor: PointerProperty(type=MM_ActorProperty) - - def isRoomEmptyObject(self, obj: Object): - return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - - def draw_props(self, layout: UILayout, altSceneProp, roomObj: Object, objName: str): - actorIDBox = layout.column() - searchOp = actorIDBox.operator(MM_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") - searchOp.actorUser = "Transition Actor" - searchOp.objName = objName - - split = actorIDBox.split(factor=0.5) - split.label(text="Actor ID") - split.label(text=getEnumName(mm_data.actor_data.enum_actor_id, self.actor.actorID)) - - if self.actor.actorID == "Custom": - prop_split(actorIDBox, self.actor, "actorIDCustom", "") - - prop_split(actorIDBox, self, "cutscene_id", "Cutscene ID") - prop_split(actorIDBox, self.actor, "actorParam", "Actor Parameter") - - if roomObj is None: - actorIDBox.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") - else: - actorIDBox.prop(self, "isRoomTransition") - if self.isRoomTransition: - prop_split(actorIDBox, self, "fromRoom", "Room To Transition From") - prop_split(actorIDBox, self, "toRoom", "Room To Transition To") - if self.fromRoom == self.toRoom: - actorIDBox.label(text="Warning: You selected the same room!", icon="ERROR") - actorIDBox.label(text='Y+ side of door faces toward the "from" room.', icon="ORIENTATION_NORMAL") - drawEnumWithCustom(actorIDBox, self, "cameraTransitionFront", "Camera Transition Front", "") - drawEnumWithCustom(actorIDBox, self, "cameraTransitionBack", "Camera Transition Back", "") - - headerProps: MM_ActorHeaderProperty = self.actor.headerSettings - headerProps.draw_props(actorIDBox, "Transition Actor", altSceneProp, objName) - - -class MM_EntranceProperty(PropertyGroup): - # This is also used in entrance list. - spawnIndex: IntProperty(min=0) - customActor: BoolProperty(name="Use Custom Actor") - actor: PointerProperty(type=MM_ActorProperty) - - tiedRoom: PointerProperty( - type=Object, - poll=lambda self, object: self.isRoomEmptyObject(object), - description="Used to set the room index", - ) - - def isRoomEmptyObject(self, obj: Object): - return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - - def draw_props(self, layout: UILayout, obj: Object, altSceneProp, objName: str): - box = layout.column() - - roomObj = getRoomObj(obj) - if roomObj is None: - box.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") - - entranceProp = obj.mm_entrance_property - box.prop(entranceProp, "customActor") - - if entranceProp.customActor: - prop_split(box, entranceProp.actor, "actorIDCustom", "Actor ID Custom") - - prop_split(box, entranceProp, "tiedRoom", "Room") - prop_split(box, entranceProp, "spawnIndex", "Spawn Index") - prop_split(box, self, "actorParam", "Actor Parameter") - - headerProps: MM_ActorHeaderProperty = entranceProp.actor.headerSettings - headerProps.draw_props(box, "Entrance", altSceneProp, objName) - - -classes = ( - MM_ActorHeaderItemProperty, - MM_ActorHeaderProperty, - MM_ActorProperty, - MM_TransitionActorProperty, - MM_EntranceProperty, -) - - -def mm_actor_props_register(): - for cls in classes: - register_class(cls) - - Object.mm_actor_property = PointerProperty(type=MM_ActorProperty) - Object.mm_transition_actor_property = PointerProperty(type=MM_TransitionActorProperty) - Object.mm_entrance_property = PointerProperty(type=MM_EntranceProperty) - - -def mm_actor_props_unregister(): - del Object.mm_actor_property - del Object.mm_transition_actor_property - del Object.mm_entrance_property - - for cls in reversed(classes): - unregister_class(cls) diff --git a/fast64_internal/z64/actor/properties/oot_props.py b/fast64_internal/z64/actor/properties/oot_props.py deleted file mode 100644 index 75d8a556e..000000000 --- a/fast64_internal/z64/actor/properties/oot_props.py +++ /dev/null @@ -1,265 +0,0 @@ -from bpy.types import Object, PropertyGroup, UILayout -from bpy.utils import register_class, unregister_class -from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty -from ....utility import prop_split, label_split -from ...constants import oot_data, ootEnumCamTransition -from ...upgrade import upgradeActors -from ...scene.properties import Z64_AlternateSceneHeaderProperty -from ...room.properties import Z64_AlternateRoomHeaderProperty -from ..operators import OOT_SearchActorIDEnumOperator - -from ...utility import ( - getRoomObj, - getEnumName, - drawAddButton, - drawCollectionOps, - drawEnumWithCustom, -) - -ootEnumSceneSetupPreset = [ - ("Custom", "Custom", "Custom"), - ("All Scene Setups", "All Scene Setups", "All Scene Setups"), - ("All Non-Cutscene Scene Setups", "All Non-Cutscene Scene Setups", "All Non-Cutscene Scene Setups"), -] - - -class OOTActorHeaderItemProperty(PropertyGroup): - headerIndex: IntProperty(name="Scene Setup", min=4, default=4) - - def draw_props( - self, - layout: UILayout, - propUser: str, - index: int, - altProp: Z64_AlternateSceneHeaderProperty | Z64_AlternateRoomHeaderProperty, - objName: str, - ): - box = layout.column() - row = box.row() - row.prop(self, "headerIndex", text="") - drawCollectionOps(row.row(align=True), index, propUser, None, objName, compact=True) - if altProp is not None and self.headerIndex >= len(altProp.cutsceneHeaders) + 4: - box.label(text="Above header does not exist.", icon="QUESTION") - - -class OOTActorHeaderProperty(PropertyGroup): - sceneSetupPreset: EnumProperty(name="Scene Setup Preset", items=ootEnumSceneSetupPreset, default="All Scene Setups") - childDayHeader: BoolProperty(name="Child Day Header", default=True) - childNightHeader: BoolProperty(name="Child Night Header", default=True) - adultDayHeader: BoolProperty(name="Adult Day Header", default=True) - adultNightHeader: BoolProperty(name="Adult Night Header", default=True) - cutsceneHeaders: CollectionProperty(type=OOTActorHeaderItemProperty) - - def checkHeader(self, index: int) -> bool: - if index == 0: - return self.childDayHeader - elif index == 1: - return self.childNightHeader - elif index == 2: - return self.adultDayHeader - elif index == 3: - return self.adultNightHeader - else: - return index in [value.headerIndex for value in self.cutsceneHeaders] - - def draw_props( - self, - layout: UILayout, - propUser: str, - altProp: Z64_AlternateSceneHeaderProperty | Z64_AlternateRoomHeaderProperty, - objName: str, - ): - headerSetup = layout.column() - # headerSetup.box().label(text = "Alternate Headers") - prop_split(headerSetup, self, "sceneSetupPreset", "Scene Setup Preset") - if self.sceneSetupPreset == "Custom": - headerSetupBox = headerSetup.column() - headerSetupBox.prop(self, "childDayHeader", text="Child Day") - prevHeaderName = "childDayHeader" - childNightRow = headerSetupBox.row() - if altProp is None or altProp.childNightHeader.usePreviousHeader: - # Draw previous header checkbox (so get previous state), but labeled - # as current one and grayed out - childNightRow.prop(self, prevHeaderName, text="Child Night") - childNightRow.enabled = False - else: - childNightRow.prop(self, "childNightHeader", text="Child Night") - prevHeaderName = "childNightHeader" - adultDayRow = headerSetupBox.row() - if altProp is None or altProp.adultDayHeader.usePreviousHeader: - adultDayRow.prop(self, prevHeaderName, text="Adult Day") - adultDayRow.enabled = False - else: - adultDayRow.prop(self, "adultDayHeader", text="Adult Day") - prevHeaderName = "adultDayHeader" - adultNightRow = headerSetupBox.row() - if altProp is None or altProp.adultNightHeader.usePreviousHeader: - adultNightRow.prop(self, prevHeaderName, text="Adult Night") - adultNightRow.enabled = False - else: - adultNightRow.prop(self, "adultNightHeader", text="Adult Night") - - headerSetupBox.row().label(text="Cutscene headers to include this actor in:") - for i in range(len(self.cutsceneHeaders)): - headerItemProps: OOTActorHeaderItemProperty = self.cutsceneHeaders[i] - headerItemProps.draw_props(headerSetup, propUser, i, altProp, objName) - drawAddButton(headerSetup, len(self.cutsceneHeaders), propUser, None, objName) - - -class OOTActorProperty(PropertyGroup): - actorID: EnumProperty(name="Actor", items=oot_data.actorData.ootEnumActorID, default="ACTOR_PLAYER") - actorIDCustom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") - actorParam: StringProperty(name="Actor Parameter", default="0x0000") - rotOverride: BoolProperty(name="Override Rotation", default=False) - rotOverrideX: StringProperty(name="Rot X", default="0") - rotOverrideY: StringProperty(name="Rot Y", default="0") - rotOverrideZ: StringProperty(name="Rot Z", default="0") - headerSettings: PointerProperty(type=OOTActorHeaderProperty) - - @staticmethod - def upgrade_object(obj: Object): - print(f"Processing '{obj.name}'...") - upgradeActors(obj) - - def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderProperty, objName: str): - # prop_split(layout, actorProp, 'actorID', 'Actor') - actorIDBox = layout.column() - # actorIDBox.box().label(text = "Settings") - searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") - searchOp.actorUser = "Actor" - searchOp.objName = objName - - split = actorIDBox.split(factor=0.5) - - if self.actorID == "None": - actorIDBox.box().label(text="This Actor was deleted from the XML file.") - return - - split.label(text="Actor ID") - split.label(text=getEnumName(oot_data.actorData.ootEnumActorID, self.actorID)) - - if self.actorID == "Custom": - # actorIDBox.prop(actorProp, 'actorIDCustom', text = 'Actor ID') - prop_split(actorIDBox, self, "actorIDCustom", "") - - # layout.box().label(text = 'Actor IDs defined in include/z64actors.h.') - prop_split(actorIDBox, self, "actorParam", "Actor Parameter") - - actorIDBox.prop(self, "rotOverride", text="Override Rotation (ignore Blender rot)") - if self.rotOverride: - prop_split(actorIDBox, self, "rotOverrideX", "Rot X") - prop_split(actorIDBox, self, "rotOverrideY", "Rot Y") - prop_split(actorIDBox, self, "rotOverrideZ", "Rot Z") - - headerProp: OOTActorHeaderProperty = self.headerSettings - headerProp.draw_props(actorIDBox, "Actor", altRoomProp, objName) - - -class OOTTransitionActorProperty(PropertyGroup): - fromRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) - toRoom: PointerProperty(type=Object, poll=lambda self, object: self.isRoomEmptyObject(object)) - cameraTransitionFront: EnumProperty(items=ootEnumCamTransition, default="0x00") - cameraTransitionFrontCustom: StringProperty(default="0x00") - cameraTransitionBack: EnumProperty(items=ootEnumCamTransition, default="0x00") - cameraTransitionBackCustom: StringProperty(default="0x00") - isRoomTransition: BoolProperty(name="Is Room Transition", default=True) - - actor: PointerProperty(type=OOTActorProperty) - - def isRoomEmptyObject(self, obj: Object): - return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - - def draw_props( - self, layout: UILayout, altSceneProp: Z64_AlternateSceneHeaderProperty, roomObj: Object, objName: str - ): - actorIDBox = layout.column() - searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") - searchOp.actorUser = "Transition Actor" - searchOp.objName = objName - - split = actorIDBox.split(factor=0.5) - split.label(text="Actor ID") - split.label(text=getEnumName(oot_data.actorData.ootEnumActorID, self.actor.actorID)) - - if self.actor.actorID == "Custom": - prop_split(actorIDBox, self.actor, "actorIDCustom", "") - - # layout.box().label(text = 'Actor IDs defined in include/z64actors.h.') - prop_split(actorIDBox, self.actor, "actorParam", "Actor Parameter") - - if roomObj is None: - actorIDBox.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") - else: - actorIDBox.prop(self, "isRoomTransition") - if self.isRoomTransition: - prop_split(actorIDBox, self, "fromRoom", "Room To Transition From") - prop_split(actorIDBox, self, "toRoom", "Room To Transition To") - if self.fromRoom == self.toRoom: - actorIDBox.label(text="Warning: You selected the same room!", icon="ERROR") - actorIDBox.label(text='Y+ side of door faces toward the "from" room.', icon="ORIENTATION_NORMAL") - drawEnumWithCustom(actorIDBox, self, "cameraTransitionFront", "Camera Transition Front", "") - drawEnumWithCustom(actorIDBox, self, "cameraTransitionBack", "Camera Transition Back", "") - - headerProps: OOTActorHeaderProperty = self.actor.headerSettings - headerProps.draw_props(actorIDBox, "Transition Actor", altSceneProp, objName) - - -class OOTEntranceProperty(PropertyGroup): - # This is also used in entrance list. - spawnIndex: IntProperty(min=0) - customActor: BoolProperty(name="Use Custom Actor") - actor: PointerProperty(type=OOTActorProperty) - - tiedRoom: PointerProperty( - type=Object, - poll=lambda self, object: self.isRoomEmptyObject(object), - description="Used to set the room index", - ) - - def isRoomEmptyObject(self, obj: Object): - return obj.type == "EMPTY" and obj.ootEmptyType == "Room" - - def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateSceneHeaderProperty, objName: str): - box = layout.column() - # box.box().label(text = "Properties") - roomObj = getRoomObj(obj) - if roomObj is None: - box.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") - - entranceProp = obj.ootEntranceProperty - prop_split(box, entranceProp, "tiedRoom", "Room") - prop_split(box, entranceProp, "spawnIndex", "Spawn Index") - prop_split(box, entranceProp.actor, "actorParam", "Actor Param") - box.prop(entranceProp, "customActor") - if entranceProp.customActor: - prop_split(box, entranceProp.actor, "actorIDCustom", "Actor ID Custom") - - headerProps: OOTActorHeaderProperty = entranceProp.actor.headerSettings - headerProps.draw_props(box, "Entrance", altSceneProp, objName) - - -classes = ( - OOTActorHeaderItemProperty, - OOTActorHeaderProperty, - OOTActorProperty, - OOTTransitionActorProperty, - OOTEntranceProperty, -) - - -def actor_props_register(): - for cls in classes: - register_class(cls) - - Object.ootActorProperty = PointerProperty(type=OOTActorProperty) - Object.ootTransitionActorProperty = PointerProperty(type=OOTTransitionActorProperty) - Object.ootEntranceProperty = PointerProperty(type=OOTEntranceProperty) - - -def actor_props_unregister(): - del Object.ootActorProperty - del Object.ootTransitionActorProperty - del Object.ootEntranceProperty - - for cls in reversed(classes): - unregister_class(cls) diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 7490d5017..5bc6e7367 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -286,7 +286,7 @@ def __init__(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object, trans pos, _, _, _ = Utility.getConvertedTransform(transform, scene_obj, chest_prop.chest_obj, True) self.room_idx = self.get_room_index(chest_prop, scene_obj) - self.chest_flag = int(getEvalParams(chest_prop.chest_obj.mm_actor_property.actorParam), base=0) & 0x1F + self.chest_flag = int(getEvalParams(chest_prop.chest_obj.ootActorProperty.actorParam), base=0) & 0x1F self.pos = pos def get_room_index(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object) -> int: diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index 560c74e1b..b4a7a2171 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -3,7 +3,7 @@ from bpy.types import Object from ...utility import PluginError, indent from ..utility import ootConvertTranslation, ootConvertRotation, is_game_oot -from ..actor.properties import OOTActorHeaderProperty, MM_ActorHeaderProperty +from ..actor.properties import Z64_ActorHeaderProperty altHeaderList = ["childNight", "adultDay", "adultNight"] @@ -34,7 +34,7 @@ def roundPosition(position) -> tuple[int, int, int]: return (round(position[0]), round(position[1]), round(position[2])) @staticmethod - def isCurrentHeaderValid(headerSettings: OOTActorHeaderProperty | MM_ActorHeaderProperty, headerIndex: int): + def isCurrentHeaderValid(headerSettings: Z64_ActorHeaderProperty, headerIndex: int): """Checks if the an alternate header can be used""" if is_game_oot(): diff --git a/fast64_internal/z64/importer/scene_pathways.py b/fast64_internal/z64/importer/scene_pathways.py index 0852b66d7..3546ba97d 100644 --- a/fast64_internal/z64/importer/scene_pathways.py +++ b/fast64_internal/z64/importer/scene_pathways.py @@ -32,8 +32,8 @@ def parsePath( splineProp.index = orderIndex if not is_game_oot() and opt_path_idx is not None and custom_value is not None: - splineProp.mm_opt_path_index = int(opt_path_idx) - splineProp.mm_custom_value = int(custom_value) + splineProp.opt_path_index = int(opt_path_idx) + splineProp.custom_value = int(custom_value) unsetAllHeadersExceptSpecified(get_game_props(curveObj, "path_header_settings"), headerIndex) sharedSceneData.pathDict[pathPoints] = curveObj diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index 781c4709f..af5014009 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -3,7 +3,7 @@ import mathutils from ...utility import PluginError, hexOrDecInt, removeComments, yUpToZUp -from ..actor.properties import OOTActorProperty, OOTActorHeaderProperty, MM_ActorHeaderProperty +from ..actor.properties import Z64_ActorProperty, Z64_ActorHeaderProperty from ..utility import ootParseRotation, is_game_oot, get_cs_index_start from .constants import headerNames, actorsWithRotAsParam @@ -16,7 +16,7 @@ def getBits(value: int, index: int, size: int) -> int: return ((1 << size) - 1) & (value >> index) -def unsetAllHeadersExceptSpecified(headerSettings: OOTActorHeaderProperty | MM_ActorHeaderProperty, headerIndex: int): +def unsetAllHeadersExceptSpecified(headerSettings: Z64_ActorHeaderProperty, headerIndex: int): if is_game_oot(): headerSettings.sceneSetupPreset = "Custom" @@ -50,7 +50,7 @@ def getDisplayNameFromActorID(actorID: str): return " ".join([word.lower().capitalize() for word in actorID.split("_") if word != "ACTOR"]) -def handleActorWithRotAsParam(actorProp: OOTActorProperty, actorID: str, rotation: list[int]): +def handleActorWithRotAsParam(actorProp: Z64_ActorProperty, actorID: str, rotation: list[int]): if is_game_oot(): if actorID in actorsWithRotAsParam: actorProp.rotOverride = True diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 52e45d4b4..870620e87 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -13,9 +13,9 @@ ) from .actor.properties import ( - OOTActorProperty, - OOTTransitionActorProperty, - OOTEntranceProperty, + Z64_ActorProperty, + Z64_TransitionActorProperty, + Z64_EntranceProperty, ) # Make sure to add exceptions in utility.py - selectMeshChildrenOnly @@ -140,11 +140,11 @@ def draw(self, context): altRoomProp = get_game_props(roomObj, "alt_room") if roomObj is not None else None if obj.ootEmptyType == "Actor": - actorProp: OOTActorProperty = get_game_props(obj, "actor") + actorProp: Z64_ActorProperty = get_game_props(obj, "actor") actorProp.draw_props(box, altRoomProp, objName) elif obj.ootEmptyType == "Transition Actor": - transActorProp: OOTTransitionActorProperty = get_game_props(obj, "transition_actor") + transActorProp: Z64_TransitionActorProperty = get_game_props(obj, "transition_actor") transActorProp.draw_props(box, altSceneProp, roomObj, objName) elif obj.ootEmptyType == "Water Box": @@ -162,7 +162,7 @@ def draw(self, context): roomAltProp.draw_props(box, objName) elif obj.ootEmptyType == "Entrance": - entranceProp: OOTEntranceProperty = get_game_props(obj, "entrance_actor") + entranceProp: Z64_EntranceProperty = get_game_props(obj, "entrance_actor") entranceProp.draw_props(box, obj, altSceneProp, objName) elif obj.ootEmptyType == "Cull Group": @@ -205,7 +205,7 @@ def upgrade_changed_props(): if obj.ootEmptyType == "Room": Z64_ObjectProperty.upgrade_object(obj) if obj.ootEmptyType in {"Entrance", "Transition Actor"}: - OOTActorProperty.upgrade_object(obj) + Z64_ActorProperty.upgrade_object(obj) if obj.ootEmptyType == "Cutscene": OOTCutsceneProperty.upgrade_object(obj) if any(obj.name.startswith(elem) for elem in ["ActionList.", "Point.", "Preview."]): diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index bb18275fb..07dedd009 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -272,7 +272,7 @@ class Z64_ExtraCutsceneProperty(PropertyGroup): def minimap_chest_poll(self: "MM_MinimapChestProperty", object: Object): return ( - object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.mm_actor_property.actorID == "ACTOR_EN_BOX" + object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" ) diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index f507d69dc..3de4cbb89 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -6,7 +6,7 @@ from ...utility import prop_split from ..utility import drawEnumWithCustom, is_game_oot, get_game_props from ..collision.constants import enum_camera_crawlspace_stype -from ..actor.properties import OOTActorHeaderProperty, MM_ActorHeaderProperty +from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -16,13 +16,13 @@ class Z64_SplineProperty(PropertyGroup): splineType: EnumProperty(items=enum_spline, default="Path") index: IntProperty(min=0) # only used for crawlspace, not path - headerSettings: PointerProperty(type=OOTActorHeaderProperty) + headerSettings: PointerProperty(type=Z64_ActorHeaderProperty) camSType: EnumProperty(items=enum_camera_crawlspace_stype, default="CAM_SET_CRAWLSPACE") camSTypeCustom: StringProperty(default="CAM_SET_CRAWLSPACE") - mm_header_settings: PointerProperty(type=MM_ActorHeaderProperty) - mm_opt_path_index: IntProperty(name="Additional Path Index", min=-1, default=-1) - mm_custom_value: IntProperty(name="Custom Value", min=-1, default=-1) + # MM exclusive + opt_path_index: IntProperty(name="Additional Path Index", min=-1, default=-1) + custom_value: IntProperty(name="Custom Value", min=-1, default=-1) def draw_props( self, @@ -35,13 +35,11 @@ def draw_props( prop_split(layout, self, "index", camIndexName) if not is_game_oot(): - prop_split(layout, self, "mm_opt_path_index", "Additional Path Index") - prop_split(layout, self, "mm_custom_value", "Custom Value") + prop_split(layout, self, "opt_path_index", "Additional Path Index") + prop_split(layout, self, "custom_value", "Custom Value") if self.splineType == "Path": - headerProp: OOTActorHeaderProperty | MM_ActorHeaderProperty = get_game_props( - bpy.data.objects[objName], "path_header_settings" - ) + headerProp: Z64_ActorHeaderProperty = get_game_props(bpy.data.objects[objName], "path_header_settings") headerProp.draw_props(layout, "Curve", altSceneProp, objName) elif self.splineType == "Crawlspace": layout.label(text="This counts as a camera for index purposes.", icon="INFO") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index addf150a1..f323cfd40 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -89,6 +89,7 @@ def get_game_prop_name(prop_type: str): "object_key": "objectKey", "room_type": "roomBehaviour", "environment_type": "linkIdleMode", + "actor_id": "actorID", }, "MM": { "global_obj": "mm_global_obj", @@ -100,6 +101,7 @@ def get_game_prop_name(prop_type: str): "object_key": "mm_object_key", "room_type": "mm_room_type", "environment_type": "mm_environment_type", + "actor_id": "mm_actor_id", }, } @@ -124,10 +126,10 @@ def get_game_props(obj: Object, header_type: str): "alt_scene": obj.ootAlternateSceneHeaders, "room": obj.ootRoomHeader, "alt_room": obj.ootAlternateRoomHeaders, - "actor": obj.mm_actor_property, - "transition_actor": obj.mm_transition_actor_property, - "entrance_actor": obj.mm_entrance_property, - "path_header_settings": obj.ootSplineProperty.mm_header_settings, + "actor": obj.ootActorProperty, + "transition_actor": obj.ootTransitionActorProperty, + "entrance_actor": obj.ootEntranceProperty, + "path_header_settings": obj.ootSplineProperty.headerSettings, }, } else: From 848496b613246f31b044c7bf28ed4a53a208d8ff Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:14:00 +0100 Subject: [PATCH 026/126] merge OoT and MM for actor properties (2/2) --- fast64_internal/z64/actor/properties.py | 3 +- .../z64/exporter/collision/waterbox.py | 4 +- .../z64/exporter/decomp_edit/spec.py | 4 +- fast64_internal/z64/exporter/room/__init__.py | 6 +- fast64_internal/z64/exporter/room/header.py | 4 +- fast64_internal/z64/exporter/room/shape.py | 3 +- .../z64/exporter/scene/__init__.py | 8 +- fast64_internal/z64/exporter/scene/actors.py | 16 ++-- .../z64/exporter/scene/pathways.py | 4 +- fast64_internal/z64/exporter/scene/rooms.py | 4 +- fast64_internal/z64/importer/actor.py | 16 ++-- fast64_internal/z64/importer/room_header.py | 9 +- fast64_internal/z64/importer/room_shape.py | 5 +- fast64_internal/z64/importer/scene.py | 3 +- fast64_internal/z64/importer/scene_header.py | 7 +- .../z64/importer/scene_pathways.py | 4 +- fast64_internal/z64/props_panel_main.py | 24 +++--- fast64_internal/z64/scene/operators.py | 4 +- fast64_internal/z64/spline/panels.py | 4 +- fast64_internal/z64/spline/properties.py | 4 +- fast64_internal/z64/tools/operators.py | 14 ++-- fast64_internal/z64/upgrade.py | 12 +-- fast64_internal/z64/utility.py | 83 +++++-------------- 23 files changed, 99 insertions(+), 146 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 6b715cfd1..ffe9217e0 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -27,6 +27,7 @@ ] +# TODO: remove def update_cutscene_index(self, context: Context): cs_index_start = get_cs_index_start() @@ -35,7 +36,7 @@ def update_cutscene_index(self, context: Context): class Z64_ActorHeaderItemProperty(PropertyGroup): - headerIndex: IntProperty(name="Scene Setup", min=1, update=update_cutscene_index) + headerIndex: IntProperty(name="Scene Setup", min=1, default=1, update=update_cutscene_index) def draw_props( self, diff --git a/fast64_internal/z64/exporter/collision/waterbox.py b/fast64_internal/z64/exporter/collision/waterbox.py index b23f208e6..1267fecf0 100644 --- a/fast64_internal/z64/exporter/collision/waterbox.py +++ b/fast64_internal/z64/exporter/collision/waterbox.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from mathutils import Matrix from bpy.types import Object -from ...utility import getObjectList, get_game_props +from ...utility import getObjectList from ....utility import CData, checkIdentityRotation, indent from ..utility import Utility @@ -121,7 +121,7 @@ def new(name: str, dataHolder: Object, transform: Matrix, useMacros: bool): emptyScale, wboxProp.camera, wboxProp.lighting, - get_game_props(roomObj, "room").roomIndex if roomObj is not None else 0x3F, + roomObj.ootRoomHeader.roomIndex if roomObj is not None else 0x3F, wboxProp.flag19, useMacros, ) diff --git a/fast64_internal/z64/exporter/decomp_edit/spec.py b/fast64_internal/z64/exporter/decomp_edit/spec.py index 835ba0c7d..5029ff21d 100644 --- a/fast64_internal/z64/exporter/decomp_edit/spec.py +++ b/fast64_internal/z64/exporter/decomp_edit/spec.py @@ -5,7 +5,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile, indent -from ...utility import ExportInfo, getSceneDirFromLevelName, get_game_props +from ...utility import ExportInfo, getSceneDirFromLevelName from ..scene import Scene from ..file import SceneFile @@ -238,7 +238,7 @@ def add_segments(exportInfo: "ExportInfo", scene: "Scene", sceneFile: "SceneFile SpecUtility.remove_segments_from_spec(specFile, exportInfo.name) assert build_directory is not None - isSingleFile = get_game_props(None, "export_settings").singleFile + isSingleFile = bpy.context.scene.ootSceneExportSettings.singleFile includeDir = f"{build_directory}/" if exportInfo.customSubPath is not None: includeDir += f"{exportInfo.customSubPath + sceneName}" diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index 5515927f7..08453ed91 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings -from ...utility import get_game_props, is_game_oot +from ...utility import is_game_oot from ...room.properties import Z64_RoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -38,9 +38,9 @@ def new( saveTexturesAsPNG: bool, ): i = 0 - mainHeaderProps = get_game_props(roomObj, "room") + mainHeaderProps = roomObj.ootRoomHeader altHeader = RoomAlternateHeader(f"{name}_alternateHeaders") - altProp = get_game_props(roomObj, "alt_room") + altProp = roomObj.ootAlternateRoomHeaders if mainHeaderProps.roomShape == "ROOM_SHAPE_TYPE_IMAGE" and len(mainHeaderProps.bgImageList) == 0: raise PluginError(f'Room {roomObj.name} uses room shape "Image" but doesn\'t have any BG images.') diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 448eaf001..2ad7c927b 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData, indent -from ...utility import getObjectList, get_game_props, is_game_oot, getEvalParams +from ...utility import getObjectList, is_game_oot, getEvalParams from ...constants import oot_data from ...room.properties import Z64_RoomHeaderProperty from ..utility import Utility @@ -174,7 +174,7 @@ def new( actorList: list[Actor] = [] actorObjList = getObjectList(sceneObj.children, "EMPTY", "Actor", parentObj=roomObj, room_index=room_index) for obj in actorObjList: - actorProp = get_game_props(obj, "actor") + actorProp = obj.ootActorProperty if not Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex): continue diff --git a/fast64_internal/z64/exporter/room/shape.py b/fast64_internal/z64/exporter/room/shape.py index 0e377452e..04ae3c82d 100644 --- a/fast64_internal/z64/exporter/room/shape.py +++ b/fast64_internal/z64/exporter/room/shape.py @@ -18,7 +18,6 @@ CullGroup, checkUniformScale, ootConvertTranslation, - get_game_props, ) @@ -545,7 +544,7 @@ def create_shape( room_shape.bg_entries.append(RoomShapeImageEntry.new(scene_name, bg_image)) pos, _, scale, _ = Utility.getConvertedTransform(transform, sceneObj, roomObj, True) - cull_group = CullGroup(pos, scale, get_game_props(roomObj, "room").defaultCullDistance) + cull_group = CullGroup(pos, scale, roomObj.ootRoomHeader.defaultCullDistance) dl_entry = room_shape.add_dl_entry(cull_group) boundingBox = BoundingBox() ootProcessMesh( diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index dd90b5da6..d5da88a68 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -6,7 +6,7 @@ from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import Z64_SceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter -from ...utility import get_game_props, is_game_oot, get_cs_index_start +from ...utility import is_game_oot, get_cs_index_start from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -42,12 +42,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex True, ) - mainHeader = SceneHeader.new( - f"{name}_header{i:02}", get_game_props(sceneObj, "scene"), sceneObj, transform, i, useMacros - ) + mainHeader = SceneHeader.new(f"{name}_header{i:02}", sceneObj.ootSceneHeader, sceneObj, transform, i, useMacros) hasAlternateHeaders = False altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") - altProp = get_game_props(sceneObj, "alt_scene") + altProp = sceneObj.ootAlternateSceneHeaders if is_game_oot(): for i, header in enumerate(altHeaderList, 1): diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index bbba05dc4..fc42f3f76 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, get_game_props, is_game_oot, getEvalParams +from ...utility import getObjectList, is_game_oot from ...constants import oot_data from ..utility import Utility from ..actor import Actor @@ -54,11 +54,11 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): actorToRoom[childObj] = obj actorObjList = getObjectList(sceneObj.children_recursive, "EMPTY", "Transition Actor") - actorObjList.sort(key=lambda obj: get_game_props(actorToRoom[obj], "room").roomIndex) + actorObjList.sort(key=lambda obj: actorToRoom[obj].ootRoomHeader.roomIndex) entries: list[TransitionActor] = [] for obj in actorObjList: - transActorProp = get_game_props(obj, "transition_actor") + transActorProp = obj.ootTransitionActorProperty if ( Utility.isCurrentHeaderValid(transActorProp.actor.headerSettings, headerIndex) and transActorProp.actor.actorID != "None" @@ -69,10 +69,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if transActorProp.isRoomTransition: if transActorProp.fromRoom is None or transActorProp.toRoom is None: raise PluginError("ERROR: Missing room empty object assigned to transition.") - fromIndex = get_game_props(transActorProp.fromRoom, "room").roomIndex - toIndex = get_game_props(transActorProp.toRoom, "room").roomIndex + fromIndex = transActorProp.fromRoom.ootRoomHeader.roomIndex + toIndex = transActorProp.toRoom.ootRoomHeader.roomIndex else: - fromIndex = toIndex = get_game_props(actorToRoom[obj], "room").roomIndex + fromIndex = toIndex = actorToRoom[obj].ootRoomHeader.roomIndex front = (fromIndex, Utility.getPropValue(transActorProp, "cameraTransitionFront")) back = (toIndex, Utility.getPropValue(transActorProp, "cameraTransitionBack")) @@ -150,7 +150,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActorFromIndex: dict[int, EntranceActor] = {} actorObjList = getObjectList(sceneObj.children_recursive, "EMPTY", "Entrance") for obj in actorObjList: - entranceProp = get_game_props(obj, "entrance_actor") + entranceProp = obj.ootEntranceProperty if ( Utility.isCurrentHeaderValid(entranceProp.actor.headerSettings, headerIndex) and entranceProp.actor.actorID != "None" @@ -178,7 +178,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.params = entranceProp.actor.actorParam if entranceProp.tiedRoom is not None: - entranceActor.roomIndex = get_game_props(entranceProp.tiedRoom, "room").roomIndex + entranceActor.roomIndex = entranceProp.tiedRoom.ootRoomHeader.roomIndex else: raise PluginError("ERROR: Missing room empty object assigned to the entrance.") entranceActor.spawnIndex = entranceProp.spawnIndex diff --git a/fast64_internal/z64/exporter/scene/pathways.py b/fast64_internal/z64/exporter/scene/pathways.py index 64e322633..2936132c4 100644 --- a/fast64_internal/z64/exporter/scene/pathways.py +++ b/fast64_internal/z64/exporter/scene/pathways.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, get_game_props +from ...utility import getObjectList from ..utility import Utility @@ -50,7 +50,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in pathObjList: relativeTransform = transform @ sceneObj.matrix_world.inverted() @ obj.matrix_world pathProps = obj.ootSplineProperty - isHeaderValid = Utility.isCurrentHeaderValid(get_game_props(obj, "path_header_settings"), headerIndex) + isHeaderValid = Utility.isCurrentHeaderValid(obj.ootSplineProperty.headerSettings, headerIndex) if isHeaderValid and Utility.validateCurveData(obj): if pathProps.index not in pathFromIndex: pathFromIndex[pathProps.index] = Path( diff --git a/fast64_internal/z64/exporter/scene/rooms.py b/fast64_internal/z64/exporter/scene/rooms.py index d2b78047a..9efb03b81 100644 --- a/fast64_internal/z64/exporter/scene/rooms.py +++ b/fast64_internal/z64/exporter/scene/rooms.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, get_game_props +from ...utility import getObjectList from ...model_classes import OOTModel from ..room import Room @@ -23,7 +23,7 @@ def new(name: str, sceneName: str, model: OOTModel, sceneObj: Object, transform: raise PluginError("ERROR: The scene has no child empties with the 'Room' empty type.") for roomObj in roomObjs: - roomHeader = get_game_props(roomObj, "room") + roomHeader = roomObj.ootRoomHeader roomIndex = roomHeader.roomIndex if roomIndex in roomDict: diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 1a63f5c96..4e2e81a85 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,7 +3,7 @@ from ...utility import parentObject, hexOrDecInt from ..scene.properties import Z64_SceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams, get_game_props, is_game_oot, get_game_enum +from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_enum, get_game_prop_name from ..constants import ootEnumCamTransition from .classes import SharedSceneData from .constants import actorsWithRotAsParam @@ -66,7 +66,7 @@ def parseTransActorList( actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) actorObj.ootEmptyType = "Transition Actor" actorObj.name = "Transition " + getDisplayNameFromActorID(params[4]) - transActorProp = get_game_props(actorObj, "transition_actor") + transActorProp = actorObj.ootTransitionActorProperty sharedSceneData.transDict[actorHash] = actorObj @@ -88,7 +88,7 @@ def parseTransActorList( setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition) actorProp = transActorProp.actor - setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) + setCustomProperty(actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -183,12 +183,12 @@ def parseSpawnList( spawnObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) spawnObj.ootEmptyType = "Entrance" spawnObj.name = "Entrance" - spawnProp = get_game_props(spawnObj, "entrance_actor") + spawnProp = spawnObj.ootEntranceProperty spawnProp.tiedRoom = roomObjs[roomIndex] spawnProp.spawnIndex = spawnIndex spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor - setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) + setCustomProperty(actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -216,7 +216,7 @@ def parseActorList( regex, nestedBrackets = getActorRegex(actorList) for actorMatch in re.finditer(regex, actorList, flags=re.DOTALL): - actorHash = parseActorInfo(actorMatch, nestedBrackets) + (get_game_props(roomObj, "room").roomIndex,) + actorHash = parseActorInfo(actorMatch, nestedBrackets) + (roomObj.ootRoomHeader.roomIndex,) if not sharedSceneData.addHeaderIfItemExists(actorHash, "Actor", headerIndex): actorID, actor_id_flags, position, rotation, spawn_flags, actorParam, roomIndex = actorHash @@ -224,8 +224,8 @@ def parseActorList( actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) actorObj.ootEmptyType = "Actor" actorObj.name = getDisplayNameFromActorID(actorID) - actorProp = get_game_props(actorObj, "actor") - setCustomProperty(actorProp, "actorID", actorID, get_game_enum("enum_actor_id")) + actorProp = actorObj.ootActorProperty + setCustomProperty(actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id")) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 2d1a7d16c..fa104c060 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -4,7 +4,6 @@ from ...utility import hexOrDecInt from ..utility import ( setCustomProperty, - get_game_props, is_game_oot, get_game_enum, get_cs_index_start, @@ -58,16 +57,16 @@ def parseRoomCommands( roomObj.empty_display_type = "SPHERE" roomObj.location = [0, 0, (roomIndex + 1) * -2] roomObj.ootEmptyType = "Room" - get_game_props(roomObj, "room").roomIndex = roomIndex + roomObj.ootRoomHeader.roomIndex = roomIndex roomObj.name = roomName if headerIndex == 0: - roomHeader = get_game_props(roomObj, "room") + roomHeader = roomObj.ootRoomHeader elif is_game_oot() and headerIndex < get_cs_index_start(): - roomHeader = getattr(get_game_props(roomObj, "alt_room"), headerNames[headerIndex]) + roomHeader = getattr(roomObj.ootAlternateRoomHeaders, headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: - cutsceneHeaders = get_game_props(roomObj, "alt_room").cutsceneHeaders + cutsceneHeaders = roomObj.ootAlternateRoomHeaders.cutsceneHeaders while len(cutsceneHeaders) < headerIndex - (get_cs_index_start() - 1): cutsceneHeaders.add() roomHeader = cutsceneHeaders[headerIndex - get_cs_index_start()] diff --git a/fast64_internal/z64/importer/room_shape.py b/fast64_internal/z64/importer/room_shape.py index 0f5c9971c..c0b35ccc7 100644 --- a/fast64_internal/z64/importer/room_shape.py +++ b/fast64_internal/z64/importer/room_shape.py @@ -8,7 +8,6 @@ from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty from ..constants import ootEnumRoomShapeType -from ..utility import get_game_props from .classes import SharedSceneData from .utility import getDataMatch, stripName @@ -20,7 +19,7 @@ def parseMeshHeader( f3dContext: OOTF3DContext, sharedSceneData: SharedSceneData, ): - roomHeader = get_game_props(roomObj, "room") + roomHeader = roomObj.ootRoomHeader meshData = getDataMatch(sceneData, meshHeaderName, "", "mesh header", False) meshData = meshData.replace("{", "").replace("}", "") @@ -79,7 +78,7 @@ def parseMeshList( f3dContext: OOTF3DContext, sharedSceneData: SharedSceneData, ): - roomHeader = get_game_props(roomObj, "room") + roomHeader = roomObj.ootRoomHeader meshEntryData = getDataMatch(sceneData, meshListName, "", "mesh list", roomShape != 1) if roomShape == 2: diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 0fbe21690..182f71d4f 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -22,7 +22,6 @@ ootGetPath, setAllActorsVisibility, is_game_oot, - get_game_props, get_game_prop_name, ) @@ -172,7 +171,7 @@ def parseScene( if not settings.isCustomDest: setCustomProperty( - get_game_props(sceneObj, "scene").sceneTableEntry, + sceneObj.ootSceneHeader.sceneTableEntry, get_game_prop_name("draw_config"), SceneTableUtility.get_draw_config(sceneName), ootEnumDrawConfig if is_game_oot() else mm_enum_draw_config, diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 8628fdcb5..81fee9b56 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -12,7 +12,6 @@ getEvalParams, setCustomProperty, get_game_enum, - get_game_props, is_game_oot, get_cs_index_start, get_game_prop_name, @@ -305,12 +304,12 @@ def parseSceneCommands( sceneObj.name = sceneName if headerIndex == 0: - sceneHeader = get_game_props(sceneObj, "scene") + sceneHeader = sceneObj.ootSceneHeader elif is_game_oot() and headerIndex < get_cs_index_start(): - sceneHeader = getattr(get_game_props(sceneObj, "alt_scene"), headerNames[headerIndex]) + sceneHeader = getattr(sceneObj.ootAlternateSceneHeaders, headerNames[headerIndex]) sceneHeader.usePreviousHeader = False else: - cutsceneHeaders = get_game_props(sceneObj, "alt_scene").cutsceneHeaders + cutsceneHeaders = sceneObj.ootAlternateSceneHeaders.cutsceneHeaders while len(cutsceneHeaders) < headerIndex - (get_cs_index_start() - 1): cutsceneHeaders.add() sceneHeader = cutsceneHeaders[headerIndex - get_cs_index_start()] diff --git a/fast64_internal/z64/importer/scene_pathways.py b/fast64_internal/z64/importer/scene_pathways.py index 3546ba97d..b76b80638 100644 --- a/fast64_internal/z64/importer/scene_pathways.py +++ b/fast64_internal/z64/importer/scene_pathways.py @@ -2,7 +2,7 @@ from typing import Optional from ...utility import hexOrDecInt, parentObject -from ..utility import is_game_oot, get_game_props +from ..utility import is_game_oot from .utility import getDataMatch, createCurveFromPoints, unsetAllHeadersExceptSpecified from .classes import SharedSceneData @@ -35,7 +35,7 @@ def parsePath( splineProp.opt_path_index = int(opt_path_idx) splineProp.custom_value = int(custom_value) - unsetAllHeadersExceptSpecified(get_game_props(curveObj, "path_header_settings"), headerIndex) + unsetAllHeadersExceptSpecified(curveObj.ootSplineProperty.headerSettings, headerIndex) sharedSceneData.pathDict[pathPoints] = curveObj parentObject(sceneObj, curveObj) diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 870620e87..8e854fe00 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj, get_game_props, is_game_oot +from .utility import getSceneObj, getRoomObj, is_game_oot from .scene.properties import OOTSceneProperties from .room.properties import Z64_ObjectProperty, Z64_RoomHeaderProperty, Z64_AlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -43,10 +43,10 @@ def drawSceneHeader(box: bpy.types.UILayout, obj: bpy.types.Object): objName = obj.name - props = get_game_props(obj, "scene") + props = obj.ootSceneHeader props.draw_props(box, None, None, objName) if props.menuTab == "Alternate": - alt_props = get_game_props(obj, "alt_scene") + alt_props = obj.ootAlternateSceneHeaders alt_props.draw_props(box, objName) box.prop(obj.fast64.oot.scene, "write_dummy_room_list") @@ -81,7 +81,7 @@ def onUpdateOOTEmptyType(self, context): if isSphereEmpty: self.empty_display_type = "SPHERE" - header_props = get_game_props(self, "scene") + header_props = self.ootSceneHeader if self.ootEmptyType == "Scene": if len(header_props.lightList) == 0: @@ -136,15 +136,15 @@ def draw(self, context): sceneObj = getSceneObj(obj) roomObj = getRoomObj(obj) - altSceneProp = get_game_props(sceneObj, "alt_scene") if sceneObj is not None else None - altRoomProp = get_game_props(roomObj, "alt_room") if roomObj is not None else None + altSceneProp = sceneObj.ootAlternateSceneHeaders if sceneObj is not None else None + altRoomProp = roomObj.ootAlternateRoomHeaders if roomObj is not None else None if obj.ootEmptyType == "Actor": - actorProp: Z64_ActorProperty = get_game_props(obj, "actor") + actorProp: Z64_ActorProperty = obj.ootActorProperty actorProp.draw_props(box, altRoomProp, objName) elif obj.ootEmptyType == "Transition Actor": - transActorProp: Z64_TransitionActorProperty = get_game_props(obj, "transition_actor") + transActorProp: Z64_TransitionActorProperty = obj.ootTransitionActorProperty transActorProp.draw_props(box, altSceneProp, roomObj, objName) elif obj.ootEmptyType == "Water Box": @@ -155,14 +155,14 @@ def draw(self, context): drawSceneHeader(box, obj) elif obj.ootEmptyType == "Room": - roomProp: Z64_RoomHeaderProperty = get_game_props(obj, "room") + roomProp: Z64_RoomHeaderProperty = obj.ootRoomHeader roomProp.draw_props(box, None, None, objName) - if get_game_props(obj, "room").menuTab == "Alternate": - roomAltProp: Z64_AlternateRoomHeaderProperty = get_game_props(obj, "alt_room") + if obj.ootRoomHeader.menuTab == "Alternate": + roomAltProp: Z64_AlternateRoomHeaderProperty = obj.ootAlternateRoomHeaders roomAltProp.draw_props(box, objName) elif obj.ootEmptyType == "Entrance": - entranceProp: Z64_EntranceProperty = get_game_props(obj, "entrance_actor") + entranceProp: Z64_EntranceProperty = obj.ootEntranceProperty entranceProp.draw_props(box, obj, altSceneProp, objName) elif obj.ootEmptyType == "Cull Group": diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 61809a747..2da3b6d8d 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -9,7 +9,7 @@ from mathutils import Matrix, Vector from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader -from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot, get_game_props +from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot from ..constants import oot_data, mm_data, ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config @@ -200,7 +200,7 @@ def execute(self, context): raisePluginError(self, e) return {"CANCELLED"} try: - settings = get_game_props(None, "export_settings") + settings = context.scene.ootSceneExportSettings levelName = settings.name option = settings.option if is_game_oot() else settings.mm_option hackerFeaturesEnabled = False diff --git a/fast64_internal/z64/spline/panels.py b/fast64_internal/z64/spline/panels.py index b2fb5d520..2ed982327 100644 --- a/fast64_internal/z64/spline/panels.py +++ b/fast64_internal/z64/spline/panels.py @@ -1,6 +1,6 @@ from bpy.types import Panel, Curve from bpy.utils import register_class, unregister_class -from ..utility import getSceneObj, get_game_props +from ..utility import getSceneObj from .properties import Z64_SplineProperty @@ -26,7 +26,7 @@ def draw(self, context): box.label(text="Only NURBS curves are compatible.") else: sceneObj = getSceneObj(context.object) - altSceneProp = get_game_props(sceneObj, "alt_scene") if sceneObj is not None else None + altSceneProp = sceneObj.ootAlternateSceneHeaders if sceneObj is not None else None splineProp: Z64_SplineProperty = context.object.ootSplineProperty splineProp.draw_props(box, altSceneProp, context.object.name) diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index 3de4cbb89..f5d603329 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -4,7 +4,7 @@ from bpy.props import EnumProperty, PointerProperty, StringProperty, IntProperty from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom, is_game_oot, get_game_props +from ..utility import drawEnumWithCustom, is_game_oot from ..collision.constants import enum_camera_crawlspace_stype from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -39,7 +39,7 @@ def draw_props( prop_split(layout, self, "custom_value", "Custom Value") if self.splineType == "Path": - headerProp: Z64_ActorHeaderProperty = get_game_props(bpy.data.objects[objName], "path_header_settings") + headerProp: Z64_ActorHeaderProperty = bpy.data.objects[objName].ootSplineProperty.headerSettings headerProp.draw_props(layout, "Curve", altSceneProp, objName) elif self.splineType == "Crawlspace": layout.label(text="This counts as a camera for index purposes.", icon="INFO") diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 365637b9a..4b5090a70 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -7,7 +7,7 @@ from ...operators import AddWaterBox, addMaterialByName from ...utility import parentObject, setOrigin from ..cutscene.motion.utility import setupCutscene, createNewCameraShot -from ..utility import getNewPath, get_game_props +from ..utility import getNewPath from .quick_import import QuickImportAborted, quick_import_exec @@ -54,8 +54,8 @@ def execute(self, context): emptyObj = context.view_layer.objects.active emptyObj.ootEmptyType = "Transition Actor" emptyObj.name = "Door Actor" - get_game_props(emptyObj, "transition_actor").actor.actorID = "ACTOR_DOOR_SHUTTER" - get_game_props(emptyObj, "transition_actor").actor.actorParam = "0x0000" + emptyObj.ootTransitionActorProperty.actor.actorID = "ACTOR_DOOR_SHUTTER" + emptyObj.ootTransitionActorProperty.actor.actorParam = "0x0000" parentObject(cubeObj, emptyObj) @@ -89,7 +89,7 @@ def execute(self, context): entranceObj = context.view_layer.objects.active entranceObj.ootEmptyType = "Entrance" entranceObj.name = "Entrance" - get_game_props(entranceObj, "entrance_actor").actor.actorParam = "0x0FFF" + entranceObj.ootEntranceProperty.actor.actorParam = "0x0FFF" parentObject(planeObj, entranceObj) location += Vector([0, 0, 10]) @@ -97,7 +97,7 @@ def execute(self, context): roomObj = context.view_layer.objects.active roomObj.ootEmptyType = "Room" roomObj.name = "Room" - get_game_props(entranceObj, "entrance_actor").tiedRoom = roomObj + entranceObj.ootEntranceProperty.tiedRoom = roomObj parentObject(roomObj, planeObj) location += Vector([0, 0, 2]) @@ -133,11 +133,11 @@ def execute(self, context): indices = [] for sceneChild in sceneObj.children: if sceneChild.ootEmptyType == "Room": - indices.append(get_game_props(sceneChild, "room").roomIndex) + indices.append(sceneChild.ootRoomHeader.roomIndex) nextIndex = 0 while nextIndex in indices: nextIndex += 1 - get_game_props(roomObj, "room").roomIndex = nextIndex + roomObj.ootRoomHeader.roomIndex = nextIndex parentObject(sceneObj, roomObj) object.select_all(action="DESELECT") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index c1583187a..95bcb4118 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,7 +6,7 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from .data import OoT_ObjectData -from .utility import getEvalParams, get_game_props +from .utility import getEvalParams from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode @@ -38,9 +38,9 @@ def upgradeObjectList(objList: CollectionProperty, objData: OoT_ObjectData): def upgradeRoomHeaders(roomObj: Object, objData: OoT_ObjectData): """Main upgrade logic for room headers""" - altHeaders = get_game_props(roomObj, "alt_room") + altHeaders = roomObj.ootAlternateRoomHeaders for sceneLayer in [ - get_game_props(roomObj, "room"), + roomObj.ootRoomHeader, altHeaders.childNightHeader, altHeaders.adultDayHeader, altHeaders.adultNightHeader, @@ -308,7 +308,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): ##################################### def upgradeActors(actorObj: Object): if actorObj.ootEmptyType == "Entrance": - entranceProp = get_game_props(actorObj, "entrance_actor") + entranceProp = actorObj.ootEntranceProperty for obj in bpy.data.objects: if obj.type == "EMPTY" and obj.ootEmptyType == "Room": @@ -328,7 +328,7 @@ def upgradeActors(actorObj: Object): print("WARNING: Ignoring Door Actor not parented to a room") return - transActorProp = get_game_props(actorObj, "transition_actor") + transActorProp = actorObj.ootTransitionActorProperty if "dontTransition" in transActorProp or "roomIndex" in transActorProp: # look for old data since we don't want to overwrite newer existing data transActorProp.fromRoom = roomParent @@ -344,7 +344,7 @@ def upgradeActors(actorObj: Object): obj != transActorProp.fromRoom and obj.type == "EMPTY" and obj.ootEmptyType == "Room" - and get_game_props(obj, "room").roomIndex == transActorProp["roomIndex"] + and obj.ootRoomHeader.roomIndex == transActorProp["roomIndex"] ): transActorProp.toRoom = obj del transActorProp["roomIndex"] diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index f323cfd40..a0f147b97 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -108,43 +108,6 @@ def get_game_prop_name(prop_type: str): return game_prop_name_map[bpy.context.scene.gameEditorMode][prop_type] -def get_game_props(obj: Object, header_type: str): - if obj is not None: - game_header_map = { - "OOT": { - "scene": obj.ootSceneHeader, - "alt_scene": obj.ootAlternateSceneHeaders, - "room": obj.ootRoomHeader, - "alt_room": obj.ootAlternateRoomHeaders, - "actor": obj.ootActorProperty, - "transition_actor": obj.ootTransitionActorProperty, - "entrance_actor": obj.ootEntranceProperty, - "path_header_settings": obj.ootSplineProperty.headerSettings, - }, - "MM": { - "scene": obj.ootSceneHeader, - "alt_scene": obj.ootAlternateSceneHeaders, - "room": obj.ootRoomHeader, - "alt_room": obj.ootAlternateRoomHeaders, - "actor": obj.ootActorProperty, - "transition_actor": obj.ootTransitionActorProperty, - "entrance_actor": obj.ootEntranceProperty, - "path_header_settings": obj.ootSplineProperty.headerSettings, - }, - } - else: - game_header_map = { - "OOT": { - "export_settings": bpy.context.scene.ootSceneExportSettings, - }, - "MM": { - "export_settings": bpy.context.scene.ootSceneExportSettings, - }, - } - - return game_header_map[bpy.context.scene.gameEditorMode][header_type] - - def is_game_oot(): return bpy.context.scene.gameEditorMode == "OOT" @@ -791,15 +754,15 @@ def getCollectionFromIndex(obj, prop, subIndex, isRoom): def getCollection(objName, collectionType, subIndex): obj = bpy.data.objects[objName] if collectionType == "Actor": - collection = get_game_props(obj, "actor").headerSettings.cutsceneHeaders + collection = obj.ootActorProperty.headerSettings.cutsceneHeaders elif collectionType == "Transition Actor": - collection = get_game_props(obj, "transition_actor").actor.headerSettings.cutsceneHeaders + collection = obj.ootTransitionActorProperty.actor.headerSettings.cutsceneHeaders elif collectionType == "Entrance": - collection = get_game_props(obj, "entrance_actor").actor.headerSettings.cutsceneHeaders + collection = obj.ootEntranceProperty.actor.headerSettings.cutsceneHeaders elif collectionType == "Room": - collection = get_game_props(obj, "alt_room").cutsceneHeaders + collection = obj.ootAlternateRoomHeaders.cutsceneHeaders elif collectionType == "Scene": - collection = get_game_props(obj, "alt_scene").cutsceneHeaders + collection = obj.ootAlternateSceneHeaders.cutsceneHeaders elif collectionType == "Light": collection = getCollectionFromIndex(obj, "lightList", subIndex, False) elif collectionType == "Exit": @@ -811,7 +774,7 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Object": collection = getCollectionFromIndex(obj, "objectList", subIndex, True) elif collectionType == "Curve": - collection = get_game_props(obj, "path_header_settings").cutsceneHeaders + collection = obj.ootSplineProperty.headerSettings.cutsceneHeaders elif collectionType.startswith("CSHdr."): # CSHdr.HeaderNumber[.ListType] # Specifying ListType means uses subIndex @@ -830,9 +793,9 @@ def getCollection(objName, collectionType, subIndex): elif collectionType == "Cutscene": collection = obj.ootCutsceneProperty.csLists elif collectionType == "extraCutscenes": - collection = get_game_props(obj, "scene").extraCutscenes + collection = obj.ootSceneHeader.extraCutscenes elif collectionType == "BgImage": - collection = get_game_props(obj, "room").bgImageList + collection = obj.ootRoomHeader.bgImageList else: raise PluginError("Invalid collection type: " + collectionType) @@ -942,15 +905,15 @@ def getHeaderSettings(actorObj: bpy.types.Object): itemType = actorObj.ootEmptyType if actorObj.type == "EMPTY": if itemType == "Actor": - headerSettings = get_game_props(actorObj, "actor").headerSettings + headerSettings = actorObj.ootActorProperty.headerSettings elif itemType == "Entrance": - headerSettings = get_game_props(actorObj, "transition_actor").actor.headerSettings + headerSettings = actorObj.ootTransitionActorProperty.actor.headerSettings elif itemType == "Transition Actor": - headerSettings = get_game_props(actorObj, "entrance_actor").actor.headerSettings + headerSettings = actorObj.ootEntranceProperty.actor.headerSettings else: headerSettings = None elif isPathObject(actorObj): - headerSettings = get_game_props(actorObj, "path_header_settings") + headerSettings = actorObj.ootSplineProperty.headerSettings else: headerSettings = None @@ -983,11 +946,11 @@ def getActiveHeaderIndex() -> int: headerObj = headerObjs[0] if headerObj.ootEmptyType == "Scene": - header = get_game_props(headerObj, "scene") - altHeader = get_game_props(headerObj, "alt_scene") + header = headerObj.ootSceneHeader + altHeader = headerObj.ootAlternateSceneHeaders else: - header = get_game_props(headerObj, "room") - altHeader = get_game_props(headerObj, "alt_room") + header = headerObj.ootRoomHeader + altHeader = headerObj.ootAlternateRoomHeaders if header.menuTab != "Alternate": headerIndex = 0 @@ -1064,9 +1027,9 @@ def setActorVisibility( def onMenuTabChange(self, context: bpy.types.Context): def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": - header = get_game_props(otherObj, "scene") + header = otherObj.ootSceneHeader else: - header = get_game_props(otherObj, "room") + header = otherObj.ootRoomHeader if thisHeader.menuTab != "Alternate" and header.menuTab == "Alternate": header.menuTab = "General" @@ -1079,9 +1042,9 @@ def callback(thisHeader, otherObj: bpy.types.Object): def onHeaderMenuTabChange(self, context: bpy.types.Context): def callback(thisHeader, otherObj: bpy.types.Object): if otherObj.ootEmptyType == "Scene": - header = get_game_props(otherObj, "alt_scene") + header = otherObj.ootAlternateSceneHeaders else: - header = get_game_props(otherObj, "alt_room") + header = otherObj.ootAlternateRoomHeaders header.headerMenuTab = thisHeader.headerMenuTab header.currentCutsceneIndex = thisHeader.currentCutsceneIndex @@ -1247,11 +1210,7 @@ def getObjectList( cond = obj.ootSplineProperty.splineType == splineType if parentObj is not None: - if ( - emptyType == "Actor" - and obj.ootEmptyType == "Room" - and get_game_props(obj, "room").roomIndex == room_index - ): + if emptyType == "Actor" and obj.ootEmptyType == "Room" and obj.ootRoomHeader.roomIndex == room_index: for o in obj.children_recursive: if o.type == objType and o.ootEmptyType == emptyType and o not in ret: ret.append(o) From 8acb13e0816b9639e041854bc67516c78a39cb96 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:42:25 +0100 Subject: [PATCH 027/126] added macros header for mm, fixed missing prop_name getter, hide warp song for mm --- fast64_internal/z64/exporter/room/header.py | 6 +++--- .../z64/exporter/scene/__init__.py | 20 +++++++++---------- fast64_internal/z64/exporter/scene/general.py | 14 ++++++------- fast64_internal/z64/importer/scene_header.py | 2 +- fast64_internal/z64/room/properties.py | 9 ++++++--- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 2ad7c927b..9c9b52969 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData, indent -from ...utility import getObjectList, is_game_oot, getEvalParams +from ...utility import getObjectList, is_game_oot, getEvalParams, get_game_prop_name from ...constants import oot_data from ...room.properties import Z64_RoomHeaderProperty from ..utility import Utility @@ -62,8 +62,8 @@ def new(props: Optional[Z64_RoomHeaderProperty]): return RoomInfos( props.roomIndex, props.roomShape, - Utility.getPropValue(props, "roomBehaviour"), - Utility.getPropValue(props, "linkIdleMode"), + Utility.getPropValue(props, get_game_prop_name("room_type")), + Utility.getPropValue(props, get_game_prop_name("environment_type")), props.showInvisibleActors, disableWarpSongs, enable_pos_lights, diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index d5da88a68..6abe472ef 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -218,16 +218,16 @@ def getNewSceneFile(self, path: str, isSingleFile: bool, textureExportSettings: sceneCutsceneData = self.getSceneCutscenesC() sceneTexturesData = self.getSceneTexturesC(textureExportSettings) - includes = ( - "\n".join( - [ - '#include "ultra64.h"', - '#include "macros.h"', - '#include "z64.h"', - ] - ) - + "\n\n\n" - ) + include_list = [ + '#include "ultra64.h"', + '#include "macros.h"', + '#include "z64.h"', + ] + + if not is_game_oot(): + include_list.append('#include "command_macros_base.h"') + + includes = "\n".join(include_list) + "\n\n\n" return SceneFile( self.name, diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 5bc6e7367..2b4395f30 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, exportColor, ootGetBaseOrCustomLight, indent -from ...utility import is_game_oot, getObjectList, getEvalParams +from ...utility import is_game_oot, getObjectList, getEvalParams, get_game_prop_name from ...scene.properties import ( Z64_SceneHeaderProperty, Z64_LightProperty, @@ -194,16 +194,16 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): skybox_texture_id = Utility.getPropValue(props, "skybox_texture_id") return SceneInfos( - Utility.getPropValue(props, "globalObject"), + Utility.getPropValue(props, get_game_prop_name("global_obj")), Utility.getPropValue(props, "naviCup") if is_game_oot() else "NAVI_QUEST_HINTS_NONE", - Utility.getPropValue(props.sceneTableEntry, "drawConfig"), + Utility.getPropValue(props.sceneTableEntry, get_game_prop_name("draw_config")), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, - Utility.getPropValue(props, "skyboxID"), - Utility.getPropValue(props, "skyboxCloudiness"), + Utility.getPropValue(props, get_game_prop_name("skybox_id")), + Utility.getPropValue(props, get_game_prop_name("skybox_config")), skybox_texture_id, - Utility.getPropValue(props, "musicSeq"), - Utility.getPropValue(props, "nightSeq"), + Utility.getPropValue(props, get_game_prop_name("seq_id")), + Utility.getPropValue(props, get_game_prop_name("ambience_id")), Utility.getPropValue(props, "audioSessionPreset"), Utility.getPropValue(props, "mapLocation") if is_game_oot() else "", Utility.getPropValue(props, "cameraMode") if is_game_oot() else "", diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 81fee9b56..aa368b771 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -322,7 +322,7 @@ def parseSceneCommands( args = [arg.strip() for arg in commandMatch.group(2).split(",")] if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) - setCustomProperty(sceneHeader, "nightSeq", args[1], get_game_enum("enum_ambiance_id")) + setCustomProperty(sceneHeader, get_game_prop_name("ambience_id"), args[1], get_game_enum("enum_ambiance_id")) if args[2].startswith("NA_BGM_"): enum_id = args[2] diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 0bb768e01..5033b86e1 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -227,12 +227,15 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawEnumWithCustom( behaviorBox, self, get_game_prop_name("environment_type"), "Environment Type", "", "linkIdleModeCustom" ) - behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") - behaviorBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") - if not is_game_oot(): + + if is_game_oot(): + behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") + else: behaviorBox.prop(self, "enable_pos_lights") behaviorBox.prop(self, "enable_storm") + behaviorBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") + # Time skyboxAndTime = layout.column() skyboxAndTime.box().label(text="Skybox And Time") From d1ebe9d4144296e3d1fad8bf5d3df28179c38630 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:42:38 +0100 Subject: [PATCH 028/126] format --- fast64_internal/z64/importer/scene_header.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index aa368b771..a82475069 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -322,7 +322,9 @@ def parseSceneCommands( args = [arg.strip() for arg in commandMatch.group(2).split(",")] if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) - setCustomProperty(sceneHeader, get_game_prop_name("ambience_id"), args[1], get_game_enum("enum_ambiance_id")) + setCustomProperty( + sceneHeader, get_game_prop_name("ambience_id"), args[1], get_game_enum("enum_ambiance_id") + ) if args[2].startswith("NA_BGM_"): enum_id = args[2] From 27edbeaad340c6e3b7c3f00bb804723395da7d65 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:48:31 +0100 Subject: [PATCH 029/126] missed `ootGetSceneOrRoomHeader` --- fast64_internal/utility.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index 4c48a41ec..ebbf360c3 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -1674,28 +1674,25 @@ def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): raise PluginError("Alternate scene/room header index too low: " + str(idx)) target = "Room" if isRoom else "Scene" - - if bpy.context.scene.gameEditorMode == "OOT": - header = getattr(parent, "oot" + target + "Header") - altHeaders = getattr(parent, "ootAlternate" + target + "Headers") - else: - header = getattr(parent, f"mm_{target.lower()}_header") - altHeaders = getattr(parent, f"mm_alternate_{target.lower()}_headers") + altHeaders = getattr(parent, "ootAlternate" + target + "Headers") + is_game_oot = bpy.context.scene.gameEditorMode == "OOT" + cs_index_start = 4 if is_game_oot else 1 if idx == 0: - return header - elif 1 <= idx <= 3: - if idx == 1: - ret = altHeaders.childNightHeader - elif idx == 2: - ret = altHeaders.adultDayHeader - else: - ret = altHeaders.adultNightHeader - return None if ret.usePreviousHeader else ret - else: - if idx - 4 >= len(altHeaders.cutsceneHeaders): - return None - return altHeaders.cutsceneHeaders[idx - 4] + return getattr(parent, "oot" + target + "Header") + elif is_game_oot: + if 1 <= idx <= (cs_index_start - 1): + if idx == 1: + ret = altHeaders.childNightHeader + elif idx == 2: + ret = altHeaders.adultDayHeader + else: + ret = altHeaders.adultNightHeader + return None if ret.usePreviousHeader else ret + + if idx - cs_index_start >= len(altHeaders.cutsceneHeaders): + return None + return altHeaders.cutsceneHeaders[idx - cs_index_start] def ootGetBaseOrCustomLight(prop, idx, toExport: bool, errIfMissing: bool): From 9ed6a9555eb41eee8ef554dfa4c80ced758165aa Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:42:19 +0100 Subject: [PATCH 030/126] update collision enums --- fast64_internal/z64/collision/constants.py | 129 +++++++++++++----- .../z64/collision/exporter/classes.py | 10 +- fast64_internal/z64/collision/properties.py | 53 ++++--- .../z64/exporter/collision/__init__.py | 10 +- .../z64/importer/scene_collision.py | 16 ++- fast64_internal/z64/utility.py | 8 ++ 6 files changed, 156 insertions(+), 70 deletions(-) diff --git a/fast64_internal/z64/collision/constants.py b/fast64_internal/z64/collision/constants.py index 7642699e6..ef2394372 100644 --- a/fast64_internal/z64/collision/constants.py +++ b/fast64_internal/z64/collision/constants.py @@ -7,66 +7,127 @@ ootEnumFloorSetting = [ ("Custom", "Custom", "Custom"), ("0x00", "Default", "Default"), - ("0x05", "Void (Small)", "Void (Small)"), + ("0x05", "Trigger Respawn", "Trigger Respawn"), ("0x06", "Grab Wall", "Grab Wall"), ("0x08", "Stop Air Momentum", "Stop Air Momentum"), ("0x09", "Fall Instead Of Jumping", "Fall Instead Of Jumping"), - ("0x0B", "Dive", "Dive"), - ("0x0C", "Void (Large)", "Void (Large)"), + ("0x0B", "Dive Animation", "Dive Animation"), + ("0x0C", "Trigger Void", "Trigger Void"), +] + +mm_enum_floor_property = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "FLOOR_PROPERTY_0"), + ("0x01", "Frontflip Jump Animation", "FLOOR_PROPERTY_1"), + ("0x02", "Sideflip Jump Animation", "FLOOR_PROPERTY_2"), + ("0x05", "Trigger Respawn (sets human no mask)", "FLOOR_PROPERTY_5"), + ("0x06", "Grab Wall", "FLOOR_PROPERTY_6"), + ("0x07", "Unknown (sets speed to 0)", "FLOOR_PROPERTY_7"), + ("0x08", "Stop Air Momentum", "FLOOR_PROPERTY_8"), + ("0x09", "Fall Instead Of Jumping", "FLOOR_PROPERTY_9"), + ("0x0B", "Dive Animation", "FLOOR_PROPERTY_11"), + ("0x0C", "Trigger Void", "FLOOR_PROPERTY_12"), + ("0x0D", "Trigger Void (runs `Player_Action_1`)", "FLOOR_PROPERTY_13"), ] ootEnumWallSetting = [ ("Custom", "Custom", "Custom"), - ("0x00", "None", "None"), - ("0x01", "No Ledge Grab", "No Ledge Grab"), - ("0x02", "Ladder", "Ladder"), + ("0x00", "Default", "Default"), + ("0x01", "No Ledge Climb", "No Ledge Climb"), + ("0x02", "Ladder Bottom", "Ladder Bottom"), ("0x03", "Ladder Top", "Ladder Top"), ("0x04", "Vines", "Vines"), - ("0x05", "Crawl Space", "Crawl Space"), + ("0x05", "Crawl Space 1", "Crawl Space 1"), ("0x06", "Crawl Space 2", "Crawl Space 2"), ("0x07", "Push Block", "Push Block"), ] ootEnumFloorProperty = [ ("Custom", "Custom", "Custom"), - ("0x00", "None", "None"), + ("0x00", "Default", "Default"), ("0x01", "Haunted Wasteland Camera", "Haunted Wasteland Camera"), - ("0x02", "Hurt Floor (Spikes)", "Hurt Floor (Spikes)"), - ("0x03", "Hurt Floor (Lava)", "Hurt Floor (Lava)"), + ("0x02", "Fire (damages every 6s)", "Fire (damages every 6s)"), + ("0x03", "Fire (damages every 3s)", "Fire (damages every 3s)"), ("0x04", "Shallow Sand", "Shallow Sand"), ("0x05", "Slippery", "Slippery"), - ("0x06", "No Fall Damage", "No Fall Damage"), - ("0x07", "Quicksand Crossing (Epona Uncrossable)", "Quicksand Crossing (Epona Uncrossable)"), - ("0x08", "Jabu Jabu's Belly", "Jabu Jabu's Belly"), - ("0x09", "Void", "Void"), - ("0x0A", "Link Looks Up", "Link Looks Up"), - ("0x0B", "Quicksand Crossing (Epona Crossable)", "Quicksand Crossing (Epona Crossable)"), + ("0x06", "Ignore Fall Damage", "Ignore Fall Damage"), + ("0x07", "Quicksand Crossing (Blocks Epona)", "Quicksand Crossing (Epona Uncrossable)"), + ("0x08", "Jabu Jabu's Belly Floor", "Jabu Jabu's Belly Floor"), + ("0x09", "Trigger Void", "Trigger Void"), + ("0x0A", "Stops Air Momentum", "Stops Air Momentum"), + ("0x0B", "Grotto Exit Animation", "Link Looks Up"), + ("0x0C", "Quicksand Crossing (Epona Crossable)", "Quicksand Crossing (Epona Crossable)"), +] + +mm_enum_floor_type = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "FLOOR_TYPE_0"), + ("0x01", "Unused (?)", "FLOOR_TYPE_1"), + ("0x02", "Fire Damages (burns Player every second)", "FLOOR_TYPE_2"), + ("0x03", "Fire Damages 2 (burns Player every second)", "FLOOR_TYPE_3"), + ("0x04", "Shallow Sand", "FLOOR_TYPE_4"), + ("0x05", "Ice (Slippery)", "FLOOR_TYPE_5"), + ("0x06", "Ignore Fall Damages", "FLOOR_TYPE_6"), + ("0x07", "Quicksand (blocks Epona)", "FLOOR_TYPE_7"), + ("0x08", "Jabu Jabu's Belly Floor (Unused)", "FLOOR_TYPE_8"), + ("0x09", "Triggers Void", "FLOOR_TYPE_9"), + ("0x0A", "Stops Air Momentum", "FLOOR_TYPE_10"), + ("0x0B", "Grotto Exit Animation", "FLOOR_TYPE_11"), + ("0x0C", "Quicksand (doesn't block Epona)", "FLOOR_TYPE_12"), + ("0x0D", "Deeper Shallow Sand", "FLOOR_TYPE_13"), + ("0x0E", "Shallow Snow", "FLOOR_TYPE_14"), + ("0x0F", "Deeper Shallow Snow", "FLOOR_TYPE_15"), ] ootEnumCollisionTerrain = [ ("Custom", "Custom", "Custom"), - ("0x00", "Walkable", "Walkable"), - ("0x01", "Steep", "Steep"), - ("0x02", "Walkable (Preserves Exit Flags)", "Walkable (Preserves Exit Flags)"), - ("0x03", "Walkable (?)", "Walkable (?)"), + ("0x00", "Walkable", "FLOOR_EFFECT_0"), + ("0x01", "Steep", "FLOOR_EFFECT_1"), + ("0x02", "Walkable (Preserves Exit Flags)", "FLOOR_EFFECT_2"), +] + +mm_enum_floor_effect = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "FLOOR_EFFECT_0"), + ("0x01", "Steep/Slippery Slope", "FLOOR_EFFECT_1"), + ("0x02", "Walkable (Preserves Exit Flags)", "FLOOR_EFFECT_2"), ] ootEnumCollisionSound = [ ("Custom", "Custom", "Custom"), - ("0x00", "Dirt", "Dirt (aka Earth)"), - ("0x01", "Sand", "Sand"), - ("0x02", "Stone", "Stone"), - ("0x03", "Jabu", "Jabu-Jabu flesh (aka Wet Stone)"), - ("0x04", "Shallow Water", "Shallow Water"), - ("0x05", "Deep Water", "Deep Water"), - ("0x06", "Tall Grass", "Tall Grass"), - ("0x07", "Lava", "Lava (aka Goo)"), - ("0x08", "Grass", "Grass (aka Earth 2)"), - ("0x09", "Bridge", "Bridge (aka Wooden Plank)"), - ("0x0A", "Wood", "Wood (aka Packed Earth)"), - ("0x0B", "Soft Dirt", "Soft Dirt (aka Earth 3)"), - ("0x0C", "Ice", "Ice (aka Ceramic)"), - ("0x0D", "Carpet", "Carpet (aka Loose Earth)"), + ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), + ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), + ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), + ("SURFACE_MATERIAL_JABU", "Jabu", "Jabu-Jabu flesh (aka Wet Stone)"), + ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), + ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), + ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), + ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), + ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), + ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), + ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), + ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), + ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), + ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), +] + +mm_enum_surface_material = [ + ("Custom", "Custom", "Custom"), + ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), + ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), + ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), + ("SURFACE_MATERIAL_DIRT_SHALLOW", "Shallow Dirt", "Shallow Dirt"), + ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), + ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), + ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), + ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), + ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), + ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), + ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), + ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), + ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), + ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), + ("SURFACE_MATERIAL_SNOW", "Snow", "Snow"), ] ootEnumConveyorSpeed = [ diff --git a/fast64_internal/z64/collision/exporter/classes.py b/fast64_internal/z64/collision/exporter/classes.py index 295d2d056..447fe6b58 100644 --- a/fast64_internal/z64/collision/exporter/classes.py +++ b/fast64_internal/z64/collision/exporter/classes.py @@ -1,6 +1,6 @@ import math from ....utility import PluginError -from ...utility import BoxEmpty, convertIntTo2sComplement, getCustomProperty +from ...utility import BoxEmpty, convertIntTo2sComplement, getCustomProperty, get_game_prop_name class OOTCollisionVertex: @@ -193,9 +193,9 @@ def getPolygonType(collisionProp): polygonType.ignoreProjectileCollision = collisionProp.ignoreProjectileCollision polygonType.eponaBlock = collisionProp.eponaBlock polygonType.decreaseHeight = collisionProp.decreaseHeight - polygonType.floorSetting = getCustomProperty(collisionProp, "floorSetting") + polygonType.floorSetting = getCustomProperty(collisionProp, get_game_prop_name("floor_property")) polygonType.wallSetting = getCustomProperty(collisionProp, "wallSetting") - polygonType.floorProperty = getCustomProperty(collisionProp, "floorProperty") + polygonType.floorProperty = getCustomProperty(collisionProp, get_game_prop_name("floor_type")) polygonType.exitID = collisionProp.exitID polygonType.cameraID = collisionProp.cameraID polygonType.isWallDamage = collisionProp.isWallDamage @@ -212,8 +212,8 @@ def getPolygonType(collisionProp): polygonType.hookshotable = collisionProp.hookshotable polygonType.echo = collisionProp.echo polygonType.lightingSetting = collisionProp.lightingSetting - polygonType.terrain = getCustomProperty(collisionProp, "terrain") - polygonType.sound = getCustomProperty(collisionProp, "sound") + polygonType.terrain = getCustomProperty(collisionProp, get_game_prop_name("floor_effect")) + polygonType.sound = getCustomProperty(collisionProp, get_game_prop_name("surface_material")) return polygonType diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 691fc02f3..85b1d640a 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -3,7 +3,7 @@ from bpy.types import PropertyGroup, Camera, Object, Material, UILayout from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom +from ..utility import drawEnumWithCustom, is_game_oot, get_game_prop_name from ..constants import ootEnumSceneID from .constants import ( ootEnumFloorSetting, @@ -14,6 +14,10 @@ ootEnumCollisionTerrain, ootEnumCollisionSound, ootEnumCameraSType, + mm_enum_floor_property, + mm_enum_floor_type, + mm_enum_floor_effect, + mm_enum_surface_material, ) @@ -68,26 +72,30 @@ class OOTMaterialCollisionProperty(PropertyGroup): eponaBlock: BoolProperty() decreaseHeight: BoolProperty() floorSettingCustom: StringProperty(default="0x00") - floorSetting: EnumProperty(items=ootEnumFloorSetting, default="0x00") + floorSetting: EnumProperty(items=ootEnumFloorSetting, default=1) + mm_floor_property: EnumProperty(items=mm_enum_floor_property, default=1) wallSettingCustom: StringProperty(default="0x00") - wallSetting: EnumProperty(items=ootEnumWallSetting, default="0x00") + wallSetting: EnumProperty(items=ootEnumWallSetting, default=1) floorPropertyCustom: StringProperty(default="0x00") - floorProperty: EnumProperty(items=ootEnumFloorProperty, default="0x00") + floorProperty: EnumProperty(items=ootEnumFloorProperty, default=1) + mm_floor_type: EnumProperty(items=mm_enum_floor_type, default=1) exitID: IntProperty(default=0, min=0) cameraID: IntProperty(default=0, min=0) isWallDamage: BoolProperty() conveyorOption: EnumProperty(items=ootEnumConveyer) conveyorRotation: FloatProperty(min=0, max=2 * math.pi, subtype="ANGLE") - conveyorSpeed: EnumProperty(items=ootEnumConveyorSpeed, default="0x00") + conveyorSpeed: EnumProperty(items=ootEnumConveyorSpeed, default=1) conveyorSpeedCustom: StringProperty(default="0x00") conveyorKeepMomentum: BoolProperty() hookshotable: BoolProperty() echo: StringProperty(default="0x00") lightingSetting: IntProperty(default=0, min=0) terrainCustom: StringProperty(default="0x00") - terrain: EnumProperty(items=ootEnumCollisionTerrain, default="0x00") + terrain: EnumProperty(items=ootEnumCollisionTerrain, default=1) + mm_floor_effect: EnumProperty(items=mm_enum_floor_effect, default=1) soundCustom: StringProperty(default="0x00") - sound: EnumProperty(items=ootEnumCollisionSound, default="0x00") + sound: EnumProperty(items=ootEnumCollisionSound, default=1) + mm_surface_material: EnumProperty(items=mm_enum_surface_material, default=1) def draw_props(self, layout: UILayout): layout.prop( @@ -97,31 +105,34 @@ def draw_props(self, layout: UILayout): icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT", ) if self.expandTab: - prop_split(layout, self, "exitID", "Exit ID") - prop_split(layout, self, "cameraID", "Camera ID") + prop_split(layout, self, "exitID", "Exit Index") + prop_split(layout, self, "cameraID", "Camera Index") + prop_split(layout, self, "lightingSetting", "Lighting Index") prop_split(layout, self, "echo", "Echo") - prop_split(layout, self, "lightingSetting", "Lighting") - drawEnumWithCustom(layout, self, "terrain", "Terrain", "") - drawEnumWithCustom(layout, self, "sound", "Sound", "") + + enum_box = layout.box().column() + enum_box.label(text="Surface Settings") + drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_type"), "Floor Type", "") + drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_property"), "Floor Property", "") + drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_effect"), "Floor Effect", "") + drawEnumWithCustom(enum_box, self, get_game_prop_name("surface_material"), "Surface Material", "") + drawEnumWithCustom(enum_box, self, "wallSetting", "Wall Type", "") layout.prop(self, "eponaBlock", text="Blocks Epona") layout.prop(self, "decreaseHeight", text="Decrease Height 1 Unit") layout.prop(self, "isWallDamage", text="Is Wall Damage") layout.prop(self, "hookshotable", text="Hookshotable") - - drawEnumWithCustom(layout, self, "floorSetting", "Floor Setting", "") - drawEnumWithCustom(layout, self, "wallSetting", "Wall Setting", "") - drawEnumWithCustom(layout, self, "floorProperty", "Floor Property", "") - layout.prop(self, "ignoreCameraCollision", text="Ignore Camera Collision") layout.prop(self, "ignoreActorCollision", text="Ignore Actor Collision") layout.prop(self, "ignoreProjectileCollision", text="Ignore Projectile Collision") - prop_split(layout, self, "conveyorOption", "Conveyor Option") + + conveyor_box = layout.box().column() + prop_split(conveyor_box, self, "conveyorOption", "Conveyor Option") if self.conveyorOption != "None": - prop_split(layout, self, "conveyorRotation", "Conveyor Rotation") - drawEnumWithCustom(layout, self, "conveyorSpeed", "Conveyor Speed", "") + prop_split(conveyor_box, self, "conveyorRotation", "Conveyor Rotation") + drawEnumWithCustom(conveyor_box, self, "conveyorSpeed", "Conveyor Speed", "") if self.conveyorSpeed != "Custom": - layout.prop(self, "conveyorKeepMomentum", text="Keep Momentum") + conveyor_box.prop(self, "conveyorKeepMomentum", text="Keep Momentum") class OOTWaterBoxProperty(PropertyGroup): diff --git a/fast64_internal/z64/exporter/collision/__init__.py b/fast64_internal/z64/exporter/collision/__init__.py index b101bfe0b..4c2462a21 100644 --- a/fast64_internal/z64/exporter/collision/__init__.py +++ b/fast64_internal/z64/exporter/collision/__init__.py @@ -6,7 +6,7 @@ from bpy.ops import object from typing import Optional from ....utility import PluginError, CData, indent -from ...utility import convertIntTo2sComplement +from ...utility import convertIntTo2sComplement, get_game_prop_name from ..utility import Utility from .polygons import CollisionPoly, CollisionPolygons from .surface import SurfaceType, SurfaceTypes @@ -156,14 +156,14 @@ def getCollisionData(dataHolder: Optional[Object], transform: Matrix, useMacros: surfaceType = SurfaceType( colProp.cameraID, colProp.exitID, - Utility.getPropValue(colProp, "floorProperty"), + Utility.getPropValue(colProp, get_game_prop_name("floor_type")), 0, # unused? Utility.getPropValue(colProp, "wallSetting"), - Utility.getPropValue(colProp, "floorSetting"), + Utility.getPropValue(colProp, get_game_prop_name("floor_property")), colProp.decreaseHeight, colProp.eponaBlock, - Utility.getPropValue(colProp, "sound"), - Utility.getPropValue(colProp, "terrain"), + Utility.getPropValue(colProp, get_game_prop_name("surface_material")), + Utility.getPropValue(colProp, get_game_prop_name("floor_effect")), colProp.lightingSetting, int(colProp.echo, base=16), colProp.hookshotable, diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index fb8149db9..0f22f107b 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -8,7 +8,7 @@ from ...utility import PluginError, parentObject, hexOrDecInt, yUpToZUp from ..collision.properties import OOTMaterialCollisionProperty from ..f3d_writer import getColliderMat -from ..utility import setCustomProperty, ootParseRotation +from ..utility import setCustomProperty, ootParseRotation, get_game_prop_name from .utility import getDataMatch, getBits, checkBit, createCurveFromPoints, stripName from .classes import SharedSceneData @@ -176,9 +176,11 @@ def parseSurfaceParams( collision.eponaBlock = checkBit(params[0], 31) collision.decreaseHeight = checkBit(params[0], 30) - setCustomProperty(collision, "floorSetting", str(getBits(params[0], 26, 4)), ootEnumFloorSetting) + setCustomProperty( + collision, get_game_prop_name("floor_property"), str(getBits(params[0], 26, 4)), ootEnumFloorSetting + ) setCustomProperty(collision, "wallSetting", str(getBits(params[0], 21, 5)), ootEnumWallSetting) - setCustomProperty(collision, "floorProperty", str(getBits(params[0], 13, 8)), ootEnumFloorProperty) + setCustomProperty(collision, get_game_prop_name("floor_type"), str(getBits(params[0], 13, 8)), ootEnumFloorProperty) collision.exitID = getBits(params[0], 8, 5) collision.cameraID = getBits(params[0], 0, 8) collision.isWallDamage = checkBit(params[1], 27) @@ -197,8 +199,12 @@ def parseSurfaceParams( collision.hookshotable = checkBit(params[1], 17) collision.echo = str(getBits(params[1], 11, 6)) collision.lightingSetting = getBits(params[1], 6, 5) - setCustomProperty(collision, "terrain", str(getBits(params[1], 4, 2)), ootEnumCollisionTerrain) - setCustomProperty(collision, "sound", str(getBits(params[1], 0, 4)), ootEnumCollisionSound) + setCustomProperty( + collision, get_game_prop_name("floor_effect"), str(getBits(params[1], 4, 2)), ootEnumCollisionTerrain + ) + setCustomProperty( + collision, get_game_prop_name("surface_material"), str(getBits(params[1], 0, 4)), ootEnumCollisionSound + ) collision.ignoreCameraCollision = ignoreCamera collision.ignoreActorCollision = ignoreActor diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index a0f147b97..7173db2e1 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -90,6 +90,10 @@ def get_game_prop_name(prop_type: str): "room_type": "roomBehaviour", "environment_type": "linkIdleMode", "actor_id": "actorID", + "floor_property": "floorSetting", + "floor_type": "floorProperty", + "floor_effect": "terrain", + "surface_material": "sound", }, "MM": { "global_obj": "mm_global_obj", @@ -102,6 +106,10 @@ def get_game_prop_name(prop_type: str): "room_type": "mm_room_type", "environment_type": "mm_environment_type", "actor_id": "mm_actor_id", + "floor_property": "mm_floor_property", + "floor_type": "mm_floor_type", + "floor_effect": "mm_floor_effect", + "surface_material": "mm_surface_material", }, } From 869681eff6422410dc8a3018686a3bc86bec3e69 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sat, 28 Dec 2024 16:29:22 +0100 Subject: [PATCH 031/126] mm camera setting type enum --- fast64_internal/z64/collision/constants.py | 179 ++++++++++++++++++ fast64_internal/z64/collision/properties.py | 8 +- .../z64/importer/scene_collision.py | 6 +- fast64_internal/z64/spline/properties.py | 6 +- fast64_internal/z64/utility.py | 2 + 5 files changed, 194 insertions(+), 7 deletions(-) diff --git a/fast64_internal/z64/collision/constants.py b/fast64_internal/z64/collision/constants.py index ef2394372..c7e94f7d0 100644 --- a/fast64_internal/z64/collision/constants.py +++ b/fast64_internal/z64/collision/constants.py @@ -213,6 +213,185 @@ ("CAM_SET_NORMAL4", "Normal4", "Normal4"), ] +mm_enum_camera_setting_type = [ + ("Custom", "Custom", "Custom"), + ("CAM_SET_NONE", "None", "None"), + ("CAM_SET_NORMAL0", "Normal0", "Generic camera 0, used in various places 'NORMAL0'"), + ("CAM_SET_NORMAL3", "Normal3", "Generic camera 3, used in various places 'NORMAL3'"), + ( + "CAM_SET_PIVOT_DIVING", + "Pivot_Diving", + "Player diving from the surface of the water to underwater not as zora 'CIRCLE5'", + ), + ("CAM_SET_HORSE", "Horse", "Reiding a horse 'HORSE0'"), + ( + "CAM_SET_ZORA_DIVING", + "Zora_Diving", + "Parallel's Pivot Diving, but as Zora. However, Zora does not dive like a human. So this setting appears to not be used 'ZORA0'", + ), + ( + "CAM_SET_PREREND_FIXED", + "Prerend_Fixed", + "Unused remnant of OoT: camera is fixed in position and rotation 'PREREND0'", + ), + ( + "CAM_SET_PREREND_PIVOT", + "Prerend_Pivot", + "Unused remnant of OoT: Camera is fixed in position with fixed pitch, but is free to rotate in the yaw direction 360 degrees 'PREREND1'", + ), + ( + "CAM_SET_DOORC", + "Doorc", + "Generic room door transitions, camera moves and follows player as the door is open and closed 'DOORC'", + ), + ("CAM_SET_DEMO0", "Demo0", "Unknown, possibly related to treasure chest game as goron? 'DEMO0'"), + ("CAM_SET_FREE0", "Free0", "Free Camera, manual control is given, no auto-updating eye or at 'FREE0'"), + ("CAM_SET_BIRDS_EYE_VIEW_0", "Birds_Eye_View_0", "Appears unused. Camera is a top-down view 'FUKAN0'"), + ("CAM_SET_NORMAL1", "Normal1", "Generic camera 1, used in various places 'NORMAL1'"), + ( + "CAM_SET_NANAME", + "Naname", + "Unknown, slanted or tilted. Behaves identical to Normal0 except with added roll 'NANAME'", + ), + ("CAM_SET_CIRCLE0", "Circle0", "Used in Curiosity Shop, Pirates Fortress, Mayor's Residence 'CIRCLE0'"), + ("CAM_SET_FIXED0", "Fixed0", "Used in Sakon's Hideout puzzle rooms, milk bar stage 'FIXED0'"), + ("CAM_SET_SPIRAL_DOOR", "Spiral_Door", "Exiting a Spiral Staircase 'SPIRAL'"), + ("CAM_SET_DUNGEON0", "Dungeon0", "Generic dungeon camera 0, used in various places 'DUNGEON0'"), + ( + "CAM_SET_ITEM0", + "Item0", + "Getting an item and holding it above Player's head (from small chest, freestanding, npc, ...) 'ITEM0'", + ), + ("CAM_SET_ITEM1", "Item1", "Looking at player while playing the ocarina 'ITEM1'"), + ("CAM_SET_ITEM2", "Item2", "Bottles: drinking, releasing fairy, dropping fish 'ITEM2'"), + ("CAM_SET_ITEM3", "Item3", "Bottles: catching fish or bugs, showing an item 'ITEM3'"), + ("CAM_SET_NAVI", "Navi", "Song of Soaring, variations of playing Song of Time 'NAVI'"), + ("CAM_SET_WARP_PAD_MOON", "Warp_Pad_Moon", "Warp circles from Goron Trial on the moon 'WARP0'"), + ("CAM_SET_DEATH", "Death", "Player death animation when health goes to 0 'DEATH'"), + ("CAM_SET_REBIRTH", "Rebirth", "Unknown set with camDataId = -9 (it's not being revived by a fairy) 'REBIRTH'"), + ( + "CAM_SET_LONG_CHEST_OPENING", + "Long_Chest_Opening", + "Long cutscene when opening a big chest with a major item 'TREASURE'", + ), + ("CAM_SET_MASK_TRANSFORMATION", "Mask_Transformation", "Putting on a transformation mask 'TRANSFORM'"), + ("CAM_SET_ATTENTION", "Attention", "Unknown, set with camDataId = -15 'ATTENTION'"), + ("CAM_SET_WARP_PAD_ENTRANCE", "Warp_Pad_Entrance", "Warp pad from start of a dungeon to the boss-room 'WARP1'"), + ("CAM_SET_DUNGEON1", "Dungeon1", "Generic dungeon camera 1, used in various places 'DUNGEON1'"), + ( + "CAM_SET_FIXED1", + "Fixed1", + "Fixes camera in place, used in various places eg. entering Stock Pot Inn, hiting a switch, giving witch a red potion, shop browsing 'FIXED1'", + ), + ( + "CAM_SET_FIXED2", + "Fixed2", + "Used in Pinnacle Rock after defeating Sea Monsters, and by Tatl in Fortress 'FIXED2'", + ), + ("CAM_SET_MAZE", "Maze", "Unused. Set to use Camera_Parallel2(), which is only Camera_Noop() 'MAZE'"), + ( + "CAM_SET_REMOTEBOMB", + "Remotebomb", + "Unused. Set to use Camera_Parallel2(), which is only Camera_Noop(). But also related to Play_ChangeCameraSetting? 'REMOTEBOMB'", + ), + ("CAM_SET_CIRCLE1", "Circle1", "Unknown 'CIRCLE1'"), + ( + "CAM_SET_CIRCLE2", + "Circle2", + "Looking at far-away NPCs eg. Garo in Road to Ikana, Hungry Goron, Tingle 'CIRCLE2'", + ), + ( + "CAM_SET_CIRCLE3", + "Circle3", + "Used in curiosity shop, goron racetrack, final room in Sakon's hideout, other places 'CIRCLE3'", + ), + ("CAM_SET_CIRCLE4", "Circle4", "Used during the races on the doggy racetrack 'CIRCLE4'"), + ("CAM_SET_FIXED3", "Fixed3", "Used in Stock Pot Inn Toilet and Tatl cutscene after woodfall 'FIXED3'"), + ( + "CAM_SET_TOWER_ASCENT", + "Tower_Ascent", + "Various climbing structures (Snowhead climb to the temple entrance) 'TOWER0'", + ), + ("CAM_SET_PARALLEL0", "Parallel0", "Unknown 'PARALLEL0'"), + ("CAM_SET_NORMALD", "Normald", "Unknown, set with camDataId = -20 'NORMALD'"), + ("CAM_SET_SUBJECTD", "Subjectd", "Unknown, set with camDataId = -21 'SUBJECTD'"), + ( + "CAM_SET_START0", + "Start0", + "Entering a room, either Dawn of a New Day reload, or entering a door where the camera is fixed on the other end 'START0'", + ), + ( + "CAM_SET_START2", + "Start2", + "Entering a scene, camera is put at a low angle eg. Grottos, Deku Palace, Stock Pot Inn 'START2'", + ), + ("CAM_SET_STOP0", "Stop0", "Called in z_play 'STOP0'"), + ("CAM_SET_BOAT_CRUISE", "Boat_Cruise", " Koume's boat cruise 'JCRUISING'"), + ( + "CAM_SET_VERTICAL_CLIMB", + "Vertical_Climb", + "Large vertical climbs, such as Mountain Village wall or Pirates Fortress ladder. 'CLIMBMAZE'", + ), + ("CAM_SET_SIDED", "Sided", "Unknown, set with camDataId = -24 'SIDED'"), + ("CAM_SET_DUNGEON2", "Dungeon2", "Generic dungeon camera 2, used in various places 'DUNGEON2'"), + ("CAM_SET_BOSS_ODOLWA", "Boss_Odolwa", "Odolwa's Lair, also used in GBT entrance: 'BOSS_SHIGE'"), + ("CAM_SET_KEEPBACK", "Keepback", "Unknown. Possibly related to climbing something? 'KEEPBACK'"), + ("CAM_SET_CIRCLE6", "Circle6", "Used in select regions from Ikana 'CIRCLE6'"), + ("CAM_SET_CIRCLE7", "Circle7", "Unknown 'CIRCLE7'"), + ("CAM_SET_MINI_BOSS", "Mini_Boss", "Used during the various minibosses of the 'CHUBOSS'"), + ("CAM_SET_RFIXED1", "Rfixed1", "Talking to Koume stuck on the floor in woods of mystery 'RFIXED1'"), + ( + "CAM_SET_TREASURE_CHEST_MINIGAME", + "Treasure_Chest_Minigame", + "Treasure Chest Shop in East Clock Town, minigame location 'TRESURE1'", + ), + ("CAM_SET_HONEY_AND_DARLING_1", "Honey_And_Darling_1", "Honey and Darling Minigames 'BOMBBASKET'"), + ( + "CAM_SET_CIRCLE8", + "Circle8", + "Used by Stone Tower moving platforms, Falling eggs in Marine Lab, Bugs into soilpatch cutscene 'CIRCLE8'", + ), + ( + "CAM_SET_BIRDS_EYE_VIEW_1", + "Birds_Eye_View_1", + "Camera is a top-down view. Used in Fisherman's minigame and Deku Palace 'FUKAN1'", + ), + ("CAM_SET_DUNGEON3", "Dungeon3", "Generic dungeon camera 3, used in various places 'DUNGEON3'"), + ("CAM_SET_TELESCOPE", "Telescope", "Observatory telescope and Curiosity Shop Peep-Hole 'TELESCOPE'"), + ("CAM_SET_ROOM0", "Room0", "Certain rooms eg. inside the clock tower 'ROOM0'"), + ("CAM_SET_RCIRC0", "Rcirc0", "Used by a few NPC cutscenes, focus close on the NPC 'RCIRC0'"), + ("CAM_SET_CIRCLE9", "Circle9", "Used by Sakon Hideout entrance and Deku Palace Maze 'CIRCLE9'"), + ("CAM_SET_ONTHEPOLE", "Onthepole", "Somewhere in Snowhead Temple and Woodfall Temple 'ONTHEPOLE'"), + ( + "CAM_SET_INBUSH", + "Inbush", + "Various bush environments eg. grottos, Swamp Spider House, Termina Field grass bushes, Deku Palace near bean 'INBUSH'", + ), + ("CAM_SET_BOSS_MAJORA", "Boss_Majora", "Majora's Lair: 'BOSS_LAST'"), + ("CAM_SET_BOSS_TWINMOLD", "Boss_Twinmold", "Twinmold's Lair: 'BOSS_INI'"), + ("CAM_SET_BOSS_GOHT", "Boss_Goht", "Goht's Lair: 'BOSS_HAK'"), + ("CAM_SET_BOSS_GYORG", "Boss_Gyorg", "Gyorg's Lair: 'BOSS_KON'"), + ("CAM_SET_CONNECT0", "Connect0", "Smoothly and gradually return camera to Player after a cutscene 'CONNECT0'"), + ("CAM_SET_PINNACLE_ROCK", "Pinnacle_Rock", "Pinnacle Rock pit 'MORAY'"), + ("CAM_SET_NORMAL2", "Normal2", "Generic camera 2, used in various places 'NORMAL2'"), + ("CAM_SET_HONEY_AND_DARLING_2", "Honey_And_Darling_2", "'BOMBBOWL'"), + ("CAM_SET_CIRCLEA", "Circlea", "Unknown, Circle 10 'CIRCLEA'"), + ("CAM_SET_WHIRLPOOL", "Whirlpool", "Great Bay Temple Central Room Whirlpool 'WHIRLPOOL'"), + ("CAM_SET_CUCCO_SHACK", "Cucco_Shack", "'KOKKOGAME'"), + ("CAM_SET_GIANT", "Giant", "Giants Mask in Twinmold's Lair 'GIANT'"), + ("CAM_SET_SCENE0", "Scene0", "Entering doors to a new scene 'SCENE0'"), + ("CAM_SET_ROOM1", "Room1", "Certain rooms eg. some rooms in Stock Pot Inn 'ROOM1'"), + ("CAM_SET_WATER2", "Water2", "Swimming as Zora in Great Bay Temple 'WATER2'"), + ("CAM_SET_WOODFALL_SWAMP", "Woodfall_Swamp", "Woodfall inside the swamp, but not on the platforms, 'SOKONASI'"), + ("CAM_SET_FORCEKEEP", "Forcekeep", "Unknown 'FORCEKEEP'"), + ("CAM_SET_PARALLEL1", "Parallel1", "Unknown 'PARALLEL1'"), + ("CAM_SET_START1", "Start1", "Used when entering the lens cave 'START1'"), + ("CAM_SET_ROOM2", "Room2", "Certain rooms eg. Deku King's Chamber, Ocean Spider House 'ROOM2'"), + ("CAM_SET_NORMAL4", "Normal4", "Generic camera 4, used in Ikana Graveyard 'NORMAL4'"), + ("CAM_SET_ELEGY_SHELL", "Elegy_Shell", "cutscene after playing elegy of emptyness and spawning a shell 'SHELL'"), + ("CAM_SET_DUNGEON4", "Dungeon4", "Used in Pirates Fortress Interior, hidden room near hookshot 'DUNGEON4'"), +] + decomp_compat_map_CameraSType = { "CAM_SET_HORSE0": "CAM_SET_HORSE", "CAM_SET_BOSS_GOMA": "CAM_SET_BOSS_GOHMA", diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 85b1d640a..621e39b8f 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -18,6 +18,7 @@ mm_enum_floor_type, mm_enum_floor_effect, mm_enum_surface_material, + mm_enum_camera_setting_type, ) @@ -49,12 +50,13 @@ def draw_props(self, layout: UILayout): class OOTCameraPositionProperty(PropertyGroup): index: IntProperty(min=0) bgImageOverrideIndex: IntProperty(default=-1, min=-1) - camSType: EnumProperty(items=ootEnumCameraSType, default="CAM_SET_NONE") - camSTypeCustom: StringProperty(default="CAM_SET_NONE") + camSType: EnumProperty(items=ootEnumCameraSType, default=2) + mm_cam_setting_type: EnumProperty(items=mm_enum_camera_setting_type, default=2) + camSTypeCustom: StringProperty(default="CAM_SET_NORMAL0") hasPositionData: BoolProperty(default=True, name="Has Position Data") def draw_props(self, layout: UILayout, cameraObj: Object): - drawEnumWithCustom(layout, self, "camSType", "Camera S Type", "") + drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "") prop_split(layout, self, "index", "Camera Index") layout.prop(self, "hasPositionData") if self.hasPositionData: diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index 0f22f107b..d176e0bd1 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -40,7 +40,9 @@ def parseCrawlSpaceData( crawlProp = curveObj.ootSplineProperty crawlProp.splineType = "Crawlspace" crawlProp.index = orderIndex - setCustomProperty(crawlProp, "camSType", "CAM_SET_CRAWLSPACE", enum_camera_crawlspace_stype) + setCustomProperty( + crawlProp, get_game_prop_name("cam_setting_type"), "CAM_SET_CRAWLSPACE", enum_camera_crawlspace_stype + ) return curveObj @@ -75,7 +77,7 @@ def parseCamPosData(setting: str, sceneData: str, posDataName: str, index: int, camObj = bpy.data.objects.new(objName, camera) bpy.context.scene.collection.objects.link(camObj) camProp = camObj.ootCameraPositionProperty - setCustomProperty(camProp, "camSType", setting, ootEnumCameraSType) + setCustomProperty(camProp, get_game_prop_name("cam_setting_type"), setting, ootEnumCameraSType) camProp.hasPositionData = posDataName != "NULL" and posDataName != "0" camProp.index = orderIndex diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index f5d603329..9e77f82f2 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -4,7 +4,7 @@ from bpy.props import EnumProperty, PointerProperty, StringProperty, IntProperty from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom, is_game_oot +from ..utility import drawEnumWithCustom, is_game_oot, get_game_prop_name from ..collision.constants import enum_camera_crawlspace_stype from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -42,8 +42,10 @@ def draw_props( headerProp: Z64_ActorHeaderProperty = bpy.data.objects[objName].ootSplineProperty.headerSettings headerProp.draw_props(layout, "Curve", altSceneProp, objName) elif self.splineType == "Crawlspace": + if not is_game_oot(): + layout.label(text="Warning: MM doesn't have crawlspaces implemented.", icon="ERROR") layout.label(text="This counts as a camera for index purposes.", icon="INFO") - drawEnumWithCustom(layout, self, "camSType", "Camera S Type", "") + drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "") oot_spline_classes = (Z64_SplineProperty,) diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 7173db2e1..004d89a45 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -94,6 +94,7 @@ def get_game_prop_name(prop_type: str): "floor_type": "floorProperty", "floor_effect": "terrain", "surface_material": "sound", + "cam_setting_type": "camSType", }, "MM": { "global_obj": "mm_global_obj", @@ -110,6 +111,7 @@ def get_game_prop_name(prop_type: str): "floor_type": "mm_floor_type", "floor_effect": "mm_floor_effect", "surface_material": "mm_surface_material", + "cam_setting_type": "mm_cam_setting_type", }, } From 70f013a40ff304f01bc1da3fa22bcca4e5a593af Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sat, 28 Dec 2024 17:03:09 +0100 Subject: [PATCH 032/126] fix "custom" issues --- .../z64/collision/exporter/classes.py | 12 ++++--- fast64_internal/z64/collision/properties.py | 16 +++++++--- .../z64/exporter/collision/__init__.py | 8 ++--- fast64_internal/z64/exporter/room/header.py | 4 +-- fast64_internal/z64/exporter/scene/general.py | 12 +++---- fast64_internal/z64/exporter/utility.py | 13 ++++++-- fast64_internal/z64/importer/actor.py | 12 +++++-- fast64_internal/z64/importer/room_header.py | 14 ++++++-- fast64_internal/z64/importer/scene.py | 1 + .../z64/importer/scene_collision.py | 32 ++++++++++++++----- fast64_internal/z64/importer/scene_header.py | 23 ++++++++++--- fast64_internal/z64/scene/properties.py | 14 +++++--- fast64_internal/z64/spline/properties.py | 2 +- fast64_internal/z64/utility.py | 18 ++++++++--- 14 files changed, 131 insertions(+), 50 deletions(-) diff --git a/fast64_internal/z64/collision/exporter/classes.py b/fast64_internal/z64/collision/exporter/classes.py index 447fe6b58..5c6823254 100644 --- a/fast64_internal/z64/collision/exporter/classes.py +++ b/fast64_internal/z64/collision/exporter/classes.py @@ -193,9 +193,13 @@ def getPolygonType(collisionProp): polygonType.ignoreProjectileCollision = collisionProp.ignoreProjectileCollision polygonType.eponaBlock = collisionProp.eponaBlock polygonType.decreaseHeight = collisionProp.decreaseHeight - polygonType.floorSetting = getCustomProperty(collisionProp, get_game_prop_name("floor_property")) + polygonType.floorSetting = getCustomProperty( + collisionProp, get_game_prop_name("floor_property"), "floorSettingCustom" + ) polygonType.wallSetting = getCustomProperty(collisionProp, "wallSetting") - polygonType.floorProperty = getCustomProperty(collisionProp, get_game_prop_name("floor_type")) + polygonType.floorProperty = getCustomProperty( + collisionProp, get_game_prop_name("floor_type"), "floorPropertyCustom" + ) polygonType.exitID = collisionProp.exitID polygonType.cameraID = collisionProp.cameraID polygonType.isWallDamage = collisionProp.isWallDamage @@ -212,8 +216,8 @@ def getPolygonType(collisionProp): polygonType.hookshotable = collisionProp.hookshotable polygonType.echo = collisionProp.echo polygonType.lightingSetting = collisionProp.lightingSetting - polygonType.terrain = getCustomProperty(collisionProp, get_game_prop_name("floor_effect")) - polygonType.sound = getCustomProperty(collisionProp, get_game_prop_name("surface_material")) + polygonType.terrain = getCustomProperty(collisionProp, get_game_prop_name("floor_effect", "terrainCustom")) + polygonType.sound = getCustomProperty(collisionProp, get_game_prop_name("surface_material", "soundCustom")) return polygonType diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 621e39b8f..cb912467e 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -56,7 +56,7 @@ class OOTCameraPositionProperty(PropertyGroup): hasPositionData: BoolProperty(default=True, name="Has Position Data") def draw_props(self, layout: UILayout, cameraObj: Object): - drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "") + drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "", "camSTypeCustom") prop_split(layout, self, "index", "Camera Index") layout.prop(self, "hasPositionData") if self.hasPositionData: @@ -114,10 +114,16 @@ def draw_props(self, layout: UILayout): enum_box = layout.box().column() enum_box.label(text="Surface Settings") - drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_type"), "Floor Type", "") - drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_property"), "Floor Property", "") - drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_effect"), "Floor Effect", "") - drawEnumWithCustom(enum_box, self, get_game_prop_name("surface_material"), "Surface Material", "") + drawEnumWithCustom( + enum_box, self, get_game_prop_name("floor_type"), "Floor Type", "", "floorPropertyCustom" + ) + drawEnumWithCustom( + enum_box, self, get_game_prop_name("floor_property"), "Floor Property", "", "floorSettingCustom" + ) + drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_effect"), "Floor Effect", "", "terrainCustom") + drawEnumWithCustom( + enum_box, self, get_game_prop_name("surface_material"), "Surface Material", "", "soundCustom" + ) drawEnumWithCustom(enum_box, self, "wallSetting", "Wall Type", "") layout.prop(self, "eponaBlock", text="Blocks Epona") diff --git a/fast64_internal/z64/exporter/collision/__init__.py b/fast64_internal/z64/exporter/collision/__init__.py index 4c2462a21..6506518c6 100644 --- a/fast64_internal/z64/exporter/collision/__init__.py +++ b/fast64_internal/z64/exporter/collision/__init__.py @@ -156,14 +156,14 @@ def getCollisionData(dataHolder: Optional[Object], transform: Matrix, useMacros: surfaceType = SurfaceType( colProp.cameraID, colProp.exitID, - Utility.getPropValue(colProp, get_game_prop_name("floor_type")), + Utility.getPropValue(colProp, get_game_prop_name("floor_type"), "floorPropertyCustom"), 0, # unused? Utility.getPropValue(colProp, "wallSetting"), - Utility.getPropValue(colProp, get_game_prop_name("floor_property")), + Utility.getPropValue(colProp, get_game_prop_name("floor_property"), "floorSettingCustom"), colProp.decreaseHeight, colProp.eponaBlock, - Utility.getPropValue(colProp, get_game_prop_name("surface_material")), - Utility.getPropValue(colProp, get_game_prop_name("floor_effect")), + Utility.getPropValue(colProp, get_game_prop_name("surface_material"), "soundCustom"), + Utility.getPropValue(colProp, get_game_prop_name("floor_effect"), "terrainCustom"), colProp.lightingSetting, int(colProp.echo, base=16), colProp.hookshotable, diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 9c9b52969..c40464060 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -62,8 +62,8 @@ def new(props: Optional[Z64_RoomHeaderProperty]): return RoomInfos( props.roomIndex, props.roomShape, - Utility.getPropValue(props, get_game_prop_name("room_type")), - Utility.getPropValue(props, get_game_prop_name("environment_type")), + Utility.getPropValue(props, get_game_prop_name("room_type"), "roomBehaviourCustom"), + Utility.getPropValue(props, get_game_prop_name("environment_type"), "linkIdleModeCustom"), props.showInvisibleActors, disableWarpSongs, enable_pos_lights, diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 2b4395f30..4541990c5 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -194,16 +194,16 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): skybox_texture_id = Utility.getPropValue(props, "skybox_texture_id") return SceneInfos( - Utility.getPropValue(props, get_game_prop_name("global_obj")), + Utility.getPropValue(props, get_game_prop_name("global_obj"), "globalObjectCustom"), Utility.getPropValue(props, "naviCup") if is_game_oot() else "NAVI_QUEST_HINTS_NONE", - Utility.getPropValue(props.sceneTableEntry, get_game_prop_name("draw_config")), + Utility.getPropValue(props.sceneTableEntry, get_game_prop_name("draw_config"), "drawConfigCustom"), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, - Utility.getPropValue(props, get_game_prop_name("skybox_id")), - Utility.getPropValue(props, get_game_prop_name("skybox_config")), + Utility.getPropValue(props, get_game_prop_name("skybox_id"), "skyboxIDCustom"), + Utility.getPropValue(props, get_game_prop_name("skybox_config"), "skyboxCloudinessCustom"), skybox_texture_id, - Utility.getPropValue(props, get_game_prop_name("seq_id")), - Utility.getPropValue(props, get_game_prop_name("ambience_id")), + Utility.getPropValue(props, get_game_prop_name("seq_id"), "musicSeqCustom"), + Utility.getPropValue(props, get_game_prop_name("ambience_id"), "nightSeqCustom"), Utility.getPropValue(props, "audioSessionPreset"), Utility.getPropValue(props, "mapLocation") if is_game_oot() else "", Utility.getPropValue(props, "cameraMode") if is_game_oot() else "", diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index b4a7a2171..798a73b0a 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -1,3 +1,4 @@ +from typing import Optional from math import radians from mathutils import Quaternion, Matrix from bpy.types import Object @@ -58,11 +59,17 @@ def isCurrentHeaderValid(headerSettings: Z64_ActorHeaderProperty, headerIndex: i return False @staticmethod - def getPropValue(data, propName: str): + def getPropValue(data, prop_name: str, custom_name: Optional[str] = None): """Returns a property's value based on if the value is 'Custom'""" - value = getattr(data, propName) - return value if value != "Custom" else getattr(data, f"{propName}Custom") + value = getattr(data, prop_name) + + if value != "Custom": + return value + elif custom_name is not None: + return getattr(data, custom_name) + + return getattr(data, f"{prop_name}Custom") @staticmethod def getConvertedTransformWithOrientation( diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 4e2e81a85..95c2f81a7 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -88,7 +88,9 @@ def parseTransActorList( setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition) actorProp = transActorProp.actor - setCustomProperty(actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id")) + setCustomProperty( + actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actorIDCustom" + ) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -188,7 +190,9 @@ def parseSpawnList( spawnProp.spawnIndex = spawnIndex spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor - setCustomProperty(actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id")) + setCustomProperty( + actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actorIDCustom" + ) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) @@ -225,7 +229,9 @@ def parseActorList( actorObj.ootEmptyType = "Actor" actorObj.name = getDisplayNameFromActorID(actorID) actorProp = actorObj.ootActorProperty - setCustomProperty(actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id")) + setCustomProperty( + actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actorIDCustom" + ) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index fa104c060..4ee0fa088 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -81,9 +81,19 @@ def parseRoomCommands( elif command == "SCENE_CMD_ECHO_SETTINGS": roomHeader.echo = args[0] elif command == "SCENE_CMD_ROOM_BEHAVIOR": - setCustomProperty(roomHeader, get_game_prop_name("room_type"), args[0], get_game_enum("enum_room_type")) setCustomProperty( - roomHeader, get_game_prop_name("environment_type"), args[1], get_game_enum("enum_env_type") + roomHeader, + get_game_prop_name("room_type"), + args[0], + get_game_enum("enum_room_type"), + "roomBehaviourCustom", + ) + setCustomProperty( + roomHeader, + get_game_prop_name("environment_type"), + args[1], + get_game_enum("enum_env_type"), + "linkIdleModeCustom", ) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 182f71d4f..d22c919ab 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -175,6 +175,7 @@ def parseScene( get_game_prop_name("draw_config"), SceneTableUtility.get_draw_config(sceneName), ootEnumDrawConfig if is_game_oot() else mm_enum_draw_config, + "drawConfigCustom", ) if bpy.context.scene.fast64.oot.headerTabAffectsVisibility: diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index d176e0bd1..def4aeb93 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -40,9 +40,7 @@ def parseCrawlSpaceData( crawlProp = curveObj.ootSplineProperty crawlProp.splineType = "Crawlspace" crawlProp.index = orderIndex - setCustomProperty( - crawlProp, get_game_prop_name("cam_setting_type"), "CAM_SET_CRAWLSPACE", enum_camera_crawlspace_stype - ) + setCustomProperty(crawlProp, "camSType", "CAM_SET_CRAWLSPACE", enum_camera_crawlspace_stype) return curveObj @@ -77,7 +75,7 @@ def parseCamPosData(setting: str, sceneData: str, posDataName: str, index: int, camObj = bpy.data.objects.new(objName, camera) bpy.context.scene.collection.objects.link(camObj) camProp = camObj.ootCameraPositionProperty - setCustomProperty(camProp, get_game_prop_name("cam_setting_type"), setting, ootEnumCameraSType) + setCustomProperty(camProp, get_game_prop_name("cam_setting_type"), setting, ootEnumCameraSType, "camSTypeCustom") camProp.hasPositionData = posDataName != "NULL" and posDataName != "0" camProp.index = orderIndex @@ -179,10 +177,20 @@ def parseSurfaceParams( collision.eponaBlock = checkBit(params[0], 31) collision.decreaseHeight = checkBit(params[0], 30) setCustomProperty( - collision, get_game_prop_name("floor_property"), str(getBits(params[0], 26, 4)), ootEnumFloorSetting + collision, + get_game_prop_name("floor_property"), + str(getBits(params[0], 26, 4)), + ootEnumFloorSetting, + "floorSettingCustom", ) setCustomProperty(collision, "wallSetting", str(getBits(params[0], 21, 5)), ootEnumWallSetting) - setCustomProperty(collision, get_game_prop_name("floor_type"), str(getBits(params[0], 13, 8)), ootEnumFloorProperty) + setCustomProperty( + collision, + get_game_prop_name("floor_type"), + str(getBits(params[0], 13, 8)), + ootEnumFloorProperty, + "floorPropertyCustom", + ) collision.exitID = getBits(params[0], 8, 5) collision.cameraID = getBits(params[0], 0, 8) collision.isWallDamage = checkBit(params[1], 27) @@ -202,10 +210,18 @@ def parseSurfaceParams( collision.echo = str(getBits(params[1], 11, 6)) collision.lightingSetting = getBits(params[1], 6, 5) setCustomProperty( - collision, get_game_prop_name("floor_effect"), str(getBits(params[1], 4, 2)), ootEnumCollisionTerrain + collision, + get_game_prop_name("floor_effect"), + str(getBits(params[1], 4, 2)), + ootEnumCollisionTerrain, + "terrainCustom", ) setCustomProperty( - collision, get_game_prop_name("surface_material"), str(getBits(params[1], 0, 4)), ootEnumCollisionSound + collision, + get_game_prop_name("surface_material"), + str(getBits(params[1], 0, 4)), + ootEnumCollisionSound, + "soundCustom", ) collision.ignoreCameraCollision = ignoreCamera diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index a82475069..da5092b2c 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -323,7 +323,11 @@ def parseSceneCommands( if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) setCustomProperty( - sceneHeader, get_game_prop_name("ambience_id"), args[1], get_game_enum("enum_ambiance_id") + sceneHeader, + get_game_prop_name("ambience_id"), + args[1], + get_game_enum("enum_ambiance_id"), + "nightSeqCustom", ) if args[2].startswith("NA_BGM_"): @@ -336,7 +340,9 @@ def parseSceneCommands( enum_id = enum_seq_id.item_by_index[int(args[2])].id - setCustomProperty(sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id")) + setCustomProperty( + sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id"), "musicSeqCustom" + ) elif command == "SCENE_CMD_ROOM_LIST": # Assumption that all scenes use the same room list. if headerIndex == 0: @@ -366,7 +372,11 @@ def parseSceneCommands( if is_game_oot(): setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) setCustomProperty( - sceneHeader, get_game_prop_name("global_obj"), args[1], get_game_enum("enum_global_object") + sceneHeader, + get_game_prop_name("global_obj"), + args[1], + get_game_enum("enum_global_object"), + "globalObjectCustom", ) elif command == "SCENE_CMD_PATH_LIST" and sharedSceneData.includePaths: pathListName = stripName(args[0]) @@ -387,13 +397,18 @@ def parseSceneCommands( sceneHeader.skybox_texture_id = args[args_index] args_index += 1 setCustomProperty( - sceneHeader, get_game_prop_name("skybox_id"), args[args_index], get_game_enum("enum_skybox") + sceneHeader, + get_game_prop_name("skybox_id"), + args[args_index], + get_game_enum("enum_skybox"), + "skyboxIDCustom", ) setCustomProperty( sceneHeader, get_game_prop_name("skybox_config"), args[args_index + 1], get_game_enum("enum_skybox_config"), + "skyboxCloudinessCustom", ) setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) elif command == "SCENE_CMD_EXIT_LIST": diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 07dedd009..22f8a791b 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -259,7 +259,7 @@ class Z64_SceneTableEntryProperty(PropertyGroup): drawConfigCustom: StringProperty(name="Scene Draw Config Custom") def draw_props(self, layout: UILayout): - drawEnumWithCustom(layout, self, get_game_prop_name("draw_config"), "Draw Config", "") + drawEnumWithCustom(layout, self, get_game_prop_name("draw_config"), "Draw Config", "", "drawConfigCustom") class Z64_ExtraCutsceneProperty(PropertyGroup): @@ -448,7 +448,9 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general.box().label(text="General") # General - drawEnumWithCustom(general, self, get_game_prop_name("global_obj"), "Global Object", "") + drawEnumWithCustom( + general, self, get_game_prop_name("global_obj"), "Global Object", "", "globalObjectCustom" + ) drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: self.sceneTableEntry.draw_props(general) @@ -467,7 +469,9 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawEnumWithCustom( skyboxAndSound, self, get_game_prop_name("skybox_config"), "Skybox Config", "", "skyboxCloudinessCustom" ) - drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("seq_id"), "Music Sequence", "") + drawEnumWithCustom( + skyboxAndSound, self, get_game_prop_name("seq_id"), "Music Sequence", "", "musicSeqCustom" + ) if is_game_oot(): op_name = OOT_SearchMusicSeqEnumOperator.bl_idname @@ -477,7 +481,9 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj musicSearch = skyboxAndSound.operator(op_name, icon="VIEWZOOM") musicSearch.objName = objName musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 - drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("ambience_id"), "Nighttime SFX", "") + drawEnumWithCustom( + skyboxAndSound, self, get_game_prop_name("ambience_id"), "Nighttime SFX", "", "nightSeqCustom" + ) drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") # Camera And World Map | Minimap Settings diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index 9e77f82f2..b2116e5fb 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -45,7 +45,7 @@ def draw_props( if not is_game_oot(): layout.label(text="Warning: MM doesn't have crawlspaces implemented.", icon="ERROR") layout.label(text="This counts as a camera for index purposes.", icon="INFO") - drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "") + drawEnumWithCustom(layout, self, "camSType", "Camera S Type", "") oot_spline_classes = (Z64_SplineProperty,) diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 004d89a45..cfcfdc470 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -676,7 +676,9 @@ def __init__(self, position, scale, emptyScale): self.cullDepth = abs(int(round(scale[0] * emptyScale))) -def setCustomProperty(data: any, prop: str, value: str, enumList: list[tuple[str, str, str]] | None): +def setCustomProperty( + data: any, prop: str, value: str, enumList: list[tuple[str, str, str]] | None, custom_name: Optional[str] = None +): if enumList is not None: if value in [enumItem[0] for enumItem in enumList]: setattr(data, prop, value) @@ -692,12 +694,19 @@ def setCustomProperty(data: any, prop: str, value: str, enumList: list[tuple[str pass setattr(data, prop, "Custom") - setattr(data, prop + str("Custom"), value) + setattr(data, custom_name if custom_name is not None else f"{prop}Custom", value) -def getCustomProperty(data, prop): +def getCustomProperty(data, prop, custom_prop_name: Optional[str] = None): + # TODO: cleanup prop names and remove `custom_prop_name` value = getattr(data, prop) - return value if value != "Custom" else getattr(data, prop + str("Custom")) + + if value != "Custom": + return value + elif custom_prop_name is not None: + return getattr(data, custom_prop_name) + + return getattr(data, prop + str("Custom")) def convertIntTo2sComplement(value: int, length: int, signed: bool): @@ -705,6 +714,7 @@ def convertIntTo2sComplement(value: int, length: int, signed: bool): def drawEnumWithCustom(panel, data, attribute, name, customName, custom_prop_name: Optional[str] = None): + # TODO: cleanup prop names and remove `custom_prop_name` prop_split(panel, data, attribute, name) if getattr(data, attribute) == "Custom": if custom_prop_name is None: From b17a8b3f7977f434421bce5a43d92b7dee6085bb Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sat, 28 Dec 2024 17:50:03 +0100 Subject: [PATCH 033/126] implement MapDataChest import --- fast64_internal/z64/importer/scene_header.py | 67 ++++++++++++++++++-- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index da5092b2c..fa9146050 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -4,6 +4,7 @@ import bpy import mathutils +from bpy.types import Object from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext @@ -256,7 +257,7 @@ def twos_complement(hexstr: str, bits: int): return value -def parse_mm_minimap_info(scene_header, scene_data: str, list_name: str): +def parse_mm_map_data(scene_header, scene_data: str, list_name: str): data_match = getDataMatch(scene_data, list_name, ["MapDataScene", "MinimapList"], "minimap scene", False) scene_map_data = data_match.strip().split(", ") scene_header.minimap_scale = int(scene_map_data[1], base=0) @@ -272,11 +273,53 @@ def parse_mm_minimap_info(scene_header, scene_data: str, list_name: str): new_prop.center_z = twos_complement(map_data[3], 16) new_prop.flags = map_data[4] - # TODO: complete chest map data import when actors are handled - # data_match = getDataMatch(scene_data, scene_map_data[0], ["MapDataChest", "MinimapChest"], "minimap chest") - # chest_map_data = data_match.strip().split("\n") - # for data in chest_map_data: - # map_data = data.strip().removeprefix("{ ").removesuffix(" },").split(", ") + +def parse_mm_map_data_chest( + room_obj_list: list[Object], scene_header, scene_data: str, chest_count: int, list_name: str +): + data_match = getDataMatch(scene_data, list_name, ["MapDataChest", "MinimapChest"], "minimap chest") + chest_map_data = data_match.strip().split("\n") + + if len(chest_map_data) != chest_count: + print( + f"WARNING: chest count ({chest_count}) is different than parsed chest data length ({len(chest_map_data)})" + ) + + if room_obj_list is None or len(room_obj_list) == 0: + raise PluginError("ERROR: The room list doesn't exist or is empty!") + + for data in chest_map_data: + map_data = data.strip().removeprefix("{ ").removesuffix(" },").split(", ") + chest_room_id, chest_flag, chest_pos_x, chest_pos_y, chest_pos_z = map_data + + # fetch room + chest_room = None + for room in room_obj_list: + if getattr(room.ootRoomHeader, "roomIndex") == int(chest_room_id, base=0): + chest_room = room + break + + # fetch chest actor (based on the chest flag and room index, maybe we should check for the coordinates too?) + chest_actor_obj = None + if chest_room is not None: + for child_obj in chest_room.children_recursive: + if child_obj.type == "EMPTY" and child_obj.ootEmptyType == "Actor": + actor_id: str = getattr(child_obj.ootActorProperty, get_game_prop_name("actor_id")) + actor_params = int(getEvalParams(child_obj.ootActorProperty.actorParam), base=0) + + if actor_id in {"ACTOR_EN_BOX"}: + actor_chest_flag = actor_params & 0x1F + if actor_chest_flag == int(chest_flag, base=0): + chest_actor_obj = child_obj + break + else: + raise PluginError("ERROR: Chest's Room not found!") + + if chest_actor_obj is not None: + new_prop = scene_header.minimap_chest_list.add() + new_prop.chest_obj = chest_actor_obj + else: + raise PluginError("ERROR: Chest Object not found!") def get_enum_id_from_index(enum_key: str, index: int): @@ -317,6 +360,8 @@ def parseSceneCommands( commands = getDataMatch(sceneData, sceneCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") entranceList = None altHeadersListName = None + chest_map_data_args = None + for commandMatch in re.finditer(rf"(SCENE\_CMD\_[a-zA-Z0-9\_]*)\s*\((.*?)\)\s*,", commands, flags=re.DOTALL): command = commandMatch.group(1) args = [arg.strip() for arg in commandMatch.group(2).split(",")] @@ -435,7 +480,15 @@ def parseSceneCommands( if command == "SCENE_CMD_SET_REGION_VISITED": sceneHeader.set_region_visited = True elif command in {"SCENE_CMD_MINIMAP_INFO", "SCENE_CMD_MAP_DATA"}: - parse_mm_minimap_info(sceneHeader, sceneData, stripName(args[0])) + parse_mm_map_data(sceneHeader, sceneData, stripName(args[0])) + elif command in {"SCENE_CMD_MINIMAP_COMPASS_ICON_INFO", "SCENE_CMD_MAP_DATA_CHESTS"}: + # Delay until rooms and actors are processed + chest_map_data_args = args + + if sharedSceneData.includeActors and chest_map_data_args is not None: + parse_mm_map_data_chest( + roomObjs, sceneHeader, sceneData, int(chest_map_data_args[0], base=0), stripName(chest_map_data_args[1]) + ) if altHeadersListName is not None: parseAlternateSceneHeaders(sceneObj, roomObjs, sceneData, altHeadersListName, f3dContext, sharedSceneData) From badf507848f3016ec715b1b2507187b805e30808 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sat, 28 Dec 2024 19:48:07 +0100 Subject: [PATCH 034/126] document en_door --- fast64_internal/z64/data/mm/xml/ActorList.xml | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/fast64_internal/z64/data/mm/xml/ActorList.xml b/fast64_internal/z64/data/mm/xml/ActorList.xml index ec1670321..132dc9539 100644 --- a/fast64_internal/z64/data/mm/xml/ActorList.xml +++ b/fast64_internal/z64/data/mm/xml/ActorList.xml @@ -71,8 +71,59 @@ for each sub element (of ) mentioned below: - - + + + Whole Day ('ENDOOR_TYPE_WHOLE_DAY') + Locked ('ENDOOR_TYPE_LOCKED') + Day ('ENDOOR_TYPE_DAY') + Night ('ENDOOR_TYPE_NIGHT') + Ajar ('ENDOOR_TYPE_AJAR') + Schedule ('ENDOOR_TYPE_SCHEDULE') + Unknown ('ENDOOR_TYPE_6') + Framed ('ENDOOR_TYPE_FRAMED') + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Golden From c5291fb9bd107f116c1bea4956c2fbd86efa5d7a Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 30 Dec 2024 00:36:49 +0100 Subject: [PATCH 035/126] animated materials support (import and export) --- fast64_internal/f3d/f3d_material.py | 11 +- fast64_internal/z64/__init__.py | 8 +- .../z64/animated_mats/properties.py | 282 +++++++++++++++++ .../z64/exporter/scene/__init__.py | 1 + .../z64/exporter/scene/animated_mats.py | 293 ++++++++++++++++++ fast64_internal/z64/exporter/scene/header.py | 7 + fast64_internal/z64/importer/classes.py | 2 + fast64_internal/z64/importer/scene.py | 1 + fast64_internal/z64/importer/scene_header.py | 108 ++++++- fast64_internal/z64/importer/utility.py | 32 +- fast64_internal/z64/props_panel_main.py | 11 + fast64_internal/z64/scene/properties.py | 4 + fast64_internal/z64/utility.py | 32 +- 13 files changed, 771 insertions(+), 21 deletions(-) create mode 100644 fast64_internal/z64/animated_mats/properties.py create mode 100644 fast64_internal/z64/exporter/scene/animated_mats.py diff --git a/fast64_internal/f3d/f3d_material.py b/fast64_internal/f3d/f3d_material.py index fcc13d661..2fc241025 100644 --- a/fast64_internal/f3d/f3d_material.py +++ b/fast64_internal/f3d/f3d_material.py @@ -253,7 +253,7 @@ def get_world_layer_defaults(scene, game_mode: str, layer: str): getattr(world, f"draw_layer_{layer}_cycle_1", ""), getattr(world, f"draw_layer_{layer}_cycle_2", ""), ) - elif game_mode == "OOT": + elif game_mode in {"OOT", "MM"}: return ( getattr(world.ootDefaultRenderModes, f"{layer.lower()}Cycle1", ""), getattr(world.ootDefaultRenderModes, f"{layer.lower()}Cycle2", ""), @@ -3962,7 +3962,10 @@ def execute(self, context): def getCurrentPresetDir(): - return "f3d/" + bpy.context.scene.gameEditorMode.lower() + if bpy.context.scene.gameEditorMode in {"OOT", "MM"}: + return f"f3d/oot" + else: + return f"f3d/{bpy.context.scene.gameEditorMode.lower()}" class ApplyMaterialPresetOperator(Operator): @@ -3976,10 +3979,6 @@ def execute(self, context: Context): return {"FINISHED"} -def getCurrentPresetDir(): - return "f3d/" + bpy.context.scene.gameEditorMode.lower() - - # modules/bpy_types.py -> Menu class MATERIAL_MT_f3d_presets(Menu): bl_label = "F3D Material Presets" diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 64e2a4dca..6b62a0fb7 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -51,6 +51,8 @@ from .spline.properties import spline_props_register, spline_props_unregister from .spline.panels import spline_panels_register, spline_panels_unregister +from .animated_mats.properties import animated_mats_register, animated_mats_unregister + from .tools import ( oot_operator_panel_register, oot_operator_panel_unregister, @@ -151,7 +153,7 @@ def oot_panel_unregister(): skeleton_panels_unregister() -def oot_register(registerPanels): +def oot_register(registerPanels: bool): oot_operator_register() oot_utility_register() collision_ops_register() # register first, so panel goes above mat panel @@ -173,6 +175,7 @@ def oot_register(registerPanels): f3d_ops_register() file_register() anim_props_register() + animated_mats_register() csMotion_ops_register() csMotion_props_register() @@ -187,10 +190,11 @@ def oot_register(registerPanels): oot_panel_register() -def oot_unregister(unregisterPanels): +def oot_unregister(unregisterPanels: bool): for cls in reversed(oot_classes): unregister_class(cls) + animated_mats_unregister() oot_operator_unregister() oot_utility_unregister() collision_ops_unregister() # register first, so panel goes above mat panel diff --git a/fast64_internal/z64/animated_mats/properties.py b/fast64_internal/z64/animated_mats/properties.py new file mode 100644 index 000000000..0b23e08c7 --- /dev/null +++ b/fast64_internal/z64/animated_mats/properties.py @@ -0,0 +1,282 @@ +from bpy.props import ( + IntProperty, + PointerProperty, + BoolProperty, + EnumProperty, + StringProperty, + CollectionProperty, + FloatVectorProperty, +) +from bpy.utils import register_class, unregister_class +from bpy.types import PropertyGroup, UILayout, Object +from ...utility import prop_split +from ..utility import drawCollectionOps, drawAddButton + + +# no custom since we only need to know where to export the data +enum_mode = [ + ("Scene", "Scene", "Scene"), + ("Actor", "Actor", "Actor"), +] + +# see `sMatAnimDrawHandlers` in `z_scene_proc.c` +enum_anim_mat_type = [ + ("Custom", "Custom", "Custom"), + ("tex_scroll", "Draw Texture Scroll", "Draw Texture Scroll"), + ("two_tex_scroll", "Draw Two Texture Scroll", "Draw Two Texture Scroll"), + ("color", "Draw Color", "Draw Color"), + ("color_lerp", "Draw Color Lerp", "Draw Color Lerp"), + ("color_nonlinear_interp", "Draw Color Non-Linear Interp", "Draw Color Non-Linear Interp"), + ("tex_cycle", "Draw Texture Cycle", "Draw Texture Cycle"), +] + + +def get_list_tab_text(base_text: str, list_length: int): + if list_length > 0: + items_amount = f"{list_length} Item{'s' if list_length > 1 else ''}" + else: + items_amount = "Empty" + + return f"{base_text} ({items_amount})" + + +class Z64_AnimatedMatColorKeyFrame(PropertyGroup): + frame_num: IntProperty(name="Frame No.", min=0) + + prim_lod_frac: IntProperty(name="Primitive LOD Frac", min=0, max=255) + prim_color: FloatVectorProperty( + name="Primitive Color", + subtype="COLOR", + size=4, + min=0, + max=1, + default=(1, 1, 1, 1), + ) + + env_color: FloatVectorProperty( + name="Environment Color", + subtype="COLOR", + size=4, + min=0, + max=1, + default=(1, 1, 1, 1), + ) + + def draw_props(self, layout: UILayout, owner: Object, parent_index: int, index: int): + drawCollectionOps(layout, index, "Animated Mat. Color", None, owner.name, collection_index=parent_index) + prop_split(layout, self, "frame_num", "Frame No.") + prop_split(layout, self, "prim_lod_frac", "Primitive LOD Frac") + prop_split(layout, self, "prim_color", "Primitive Color") + prop_split(layout, self, "env_color", "Environment Color") + + +class Z64_AnimatedMatColorParams(PropertyGroup): + frame_count: IntProperty(name="Frame Count", min=0) + keyframes: CollectionProperty(type=Z64_AnimatedMatColorKeyFrame) + + # ui only props + show_entries: BoolProperty(default=False) + + def draw_props(self, layout: UILayout, owner: Object, parent_index: int): + prop_split(layout, self, "frame_count", "Frame Count") + + prop_text = get_list_tab_text("Keyframes", len(self.keyframes)) + layout.prop(self, "show_entries", text=prop_text, icon="TRIA_DOWN" if self.show_entries else "TRIA_RIGHT") + + if self.show_entries: + for i, keyframe in enumerate(self.keyframes): + keyframe.draw_props(layout, owner, parent_index, i) + + drawAddButton(layout, len(self.keyframes), "Animated Mat. Color", None, owner.name, parent_index) + + +class Z64_AnimatedMatTexScrollItem(PropertyGroup): + step_x: IntProperty(default=0) + step_y: IntProperty(default=0) + width: IntProperty(min=0) + height: IntProperty(min=0) + + def draw_props(self, layout: UILayout, owner: Object, parent_index: int, index: int): + drawCollectionOps(layout, index, "Animated Mat. Scroll", None, owner.name, collection_index=parent_index) + prop_split(layout, self, "step_x", "Step X") + prop_split(layout, self, "step_y", "Step Y") + prop_split(layout, self, "width", "Texture Width") + prop_split(layout, self, "height", "Texture Height") + + +class Z64_AnimatedMatTexScrollParams(PropertyGroup): + entries: CollectionProperty(type=Z64_AnimatedMatTexScrollItem) + + # ui only props + show_entries: BoolProperty(default=False) + + def draw_props(self, layout: UILayout, owner: Object, parent_index: int): + prop_text = get_list_tab_text("Tex. Scroll", len(self.entries)) + layout.prop(self, "show_entries", text=prop_text, icon="TRIA_DOWN" if self.show_entries else "TRIA_RIGHT") + + if self.show_entries: + for i, item in enumerate(self.entries): + item.draw_props(layout, owner, parent_index, i) + + drawAddButton(layout, len(self.entries), "Animated Mat. Scroll", None, owner.name, parent_index) + + +class Z64_AnimatedMatTexCycleKeyFrame(PropertyGroup): + frame_num: IntProperty(name="Frame No.", min=0) + texture: StringProperty(name="Texture Symbol") + + def draw_props(self, layout: UILayout, owner: Object, parent_index: int, index: int): + drawCollectionOps(layout, index, "Animated Mat. Cycle", None, owner.name, collection_index=parent_index) + prop_split(layout, self, "frame_num", "Frame No.") + prop_split(layout, self, "texture", "Texture Symbol") + + +class Z64_AnimatedMatTexCycleParams(PropertyGroup): + frame_count: IntProperty(name="Frame Count", min=0) + keyframes: CollectionProperty(type=Z64_AnimatedMatTexCycleKeyFrame) + + # ui only props + show_entries: BoolProperty(default=False) + + def draw_props(self, layout: UILayout, owner: Object, parent_index: int): + prop_split(layout, self, "frame_count", "Frame Count") + + prop_text = get_list_tab_text("Keyframes", len(self.keyframes)) + layout.prop(self, "show_entries", text=prop_text, icon="TRIA_DOWN" if self.show_entries else "TRIA_RIGHT") + + if self.show_entries: + for i, keyframe in enumerate(self.keyframes): + keyframe.draw_props(layout, owner, parent_index, i) + + drawAddButton(layout, len(self.keyframes), "Animated Mat. Cycle", None, owner.name, parent_index) + + +class Z64_AnimatedMaterialItem(PropertyGroup): + """see the `AnimatedMaterial` struct from `z64scene.h`""" + + segment_num: IntProperty(name="Segment Number", min=8, max=13, default=8) + type: EnumProperty( + name="Draw Handler Type", items=enum_anim_mat_type, default=2, description="Index to `sMatAnimDrawHandlers`" + ) + type_custom: StringProperty(name="Custom Draw Handler Index", default="2") + + color_params: PointerProperty(type=Z64_AnimatedMatColorParams) + tex_scroll_params: PointerProperty(type=Z64_AnimatedMatTexScrollParams) + tex_cycle_params: PointerProperty(type=Z64_AnimatedMatTexCycleParams) + + # ui only props + show_item: BoolProperty(default=False) + + def draw_props(self, layout: UILayout, owner: Object, index: int): + layout.prop( + self, "show_item", text=f"Item No.{index + 1}", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT" + ) + + if self.show_item: + drawCollectionOps(layout, index, "Animated Mat.", None, owner.name) + + prop_split(layout, self, "segment_num", "Segment Number") + + layout_type = layout.column() + prop_split(layout_type, self, "type", "Draw Handler Type") + + if self.type == "Custom": + layout_type.label( + text="This only allows you to choose a custom index for the function handler.", icon="ERROR" + ) + prop_split(layout_type, self, "type_custom", "Custom Draw Handler Index") + elif self.type in {"tex_scroll", "two_tex_scroll"}: + self.tex_scroll_params.draw_props(layout_type, owner, index) + elif self.type in {"color", "color_lerp", "color_nonlinear_interp"}: + self.color_params.draw_props(layout_type, owner, index) + elif self.type == "tex_cycle": + self.tex_cycle_params.draw_props(layout_type, owner, index) + + +class Z64_AnimatedMaterial(PropertyGroup): + """Defines an Animated Material array""" + + header_index: IntProperty(name="Header Index", min=-1, default=-1, description="Header Index, -1 means all headers") + entries: CollectionProperty(type=Z64_AnimatedMaterialItem) + + # ui only props + show_list: BoolProperty(default=True) + show_entries: BoolProperty(default=True) + + def draw_props(self, layout: UILayout, owner: Object, index: int): + layout.prop( + self, "show_list", text=f"List No.{index + 1}", icon="TRIA_DOWN" if self.show_list else "TRIA_RIGHT" + ) + + if self.show_list: + drawCollectionOps(layout, index, "Animated Mat. List", None, owner.name) + prop_split(layout, self, "header_index", "Header Index") + + prop_text = get_list_tab_text("Animated Materials", len(self.entries)) + layout_entries = layout.column() + layout_entries.prop( + self, "show_entries", text=prop_text, icon="TRIA_DOWN" if self.show_entries else "TRIA_RIGHT" + ) + + if self.show_entries: + for i, item in enumerate(self.entries): + item.draw_props(layout_entries.box().column(), owner, i) + + drawAddButton(layout_entries, len(self.entries), "Animated Mat.", None, owner.name) + + +class Z64_AnimatedMaterialProperty(PropertyGroup): + """List of Animated Material arrays""" + + mode: EnumProperty(name="Export To", items=enum_mode) + + # this is probably useless since usually you wouldn't use different animated materials + # on different headers but it's better to give users the choice + items: CollectionProperty(type=Z64_AnimatedMaterial) + + # ui only props + show_entries: BoolProperty(default=True) + + def draw_props(self, layout: UILayout, owner: Object): + layout = layout.column() + + prop_split(layout, self, "mode", "Export To") + + prop_text = get_list_tab_text("Animated Materials List", len(self.items)) + layout_entries = layout.box().column() + layout_entries.prop( + self, "show_entries", text=prop_text, icon="TRIA_DOWN" if self.show_entries else "TRIA_RIGHT" + ) + + if self.show_entries: + for i, item in enumerate(self.items): + item.draw_props(layout_entries.box().column(), owner, i) + + drawAddButton(layout_entries, len(self.items), "Animated Mat. List", None, owner.name) + + +classes = ( + Z64_AnimatedMatColorKeyFrame, + Z64_AnimatedMatColorParams, + Z64_AnimatedMatTexScrollItem, + Z64_AnimatedMatTexScrollParams, + Z64_AnimatedMatTexCycleKeyFrame, + Z64_AnimatedMatTexCycleParams, + Z64_AnimatedMaterialItem, + Z64_AnimatedMaterial, + Z64_AnimatedMaterialProperty, +) + + +def animated_mats_register(): + for cls in classes: + register_class(cls) + + Object.z64_anim_mats_property = PointerProperty(type=Z64_AnimatedMaterialProperty) + + +def animated_mats_unregister(): + del Object.z64_anim_mats_property + + for cls in reversed(classes): + unregister_class(cls) diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 6abe472ef..00a5c2dc1 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -124,6 +124,7 @@ def getCmdList(self, curHeader: SceneHeader, hasAltHeaders: bool): + (curHeader.exits.getCmd() if len(curHeader.exits.exitList) > 0 else "") + (curHeader.cutscene.getCmd() if len(curHeader.cutscene.entries) > 0 else "") + (curHeader.map_data.get_cmds() if not is_game_oot() and curHeader.map_data is not None else "") + + (curHeader.anim_mat.get_cmd() if not is_game_oot() and curHeader.anim_mat is not None else "") + Utility.getEndCmd() + "};\n\n" ) diff --git a/fast64_internal/z64/exporter/scene/animated_mats.py b/fast64_internal/z64/exporter/scene/animated_mats.py new file mode 100644 index 000000000..0b79ae5bd --- /dev/null +++ b/fast64_internal/z64/exporter/scene/animated_mats.py @@ -0,0 +1,293 @@ +from dataclasses import dataclass +from bpy.types import Object +from ....utility import CData, PluginError, exportColor, scaleToU8, indent +from ...utility import getObjectList +from ...animated_mats.properties import ( + Z64_AnimatedMatColorParams, + Z64_AnimatedMatTexScrollParams, + Z64_AnimatedMatTexCycleParams, + Z64_AnimatedMaterial, +) + + +class AnimatedMatColorParams: + def __init__( + self, + props: Z64_AnimatedMatColorParams, + segment_num: int, + type_num: int, + base_name: str, + header_index: int, + index: int, + ): + # the code adds back 7 when processing animated materials + self.segment_num = segment_num - 7 + self.type_num = type_num + self.base_name = base_name + self.header_index = header_index + self.header_suffix = f"_{index:02}" + self.name = f"{self.base_name}ColorParams{self.header_suffix}" + self.frame_length = props.frame_count + self.prim_colors: list[tuple[int, int, int, int]] = [] + self.env_colors: list[tuple[int, int, int]] = [] + self.frames: list[int] = [] + + for keyframe in props.keyframes: + prim = exportColor(keyframe.prim_color[0:3]) + [scaleToU8(keyframe.prim_color[3])] + self.prim_colors.append((prim[0], prim[1], prim[2], prim[3], keyframe.prim_lod_frac)) + self.env_colors.append(tuple(exportColor(keyframe.env_color[0:3]) + [scaleToU8(keyframe.env_color[3])])) + self.frames.append(keyframe.frame_num) + + self.frame_count = len(self.frames) + assert len(self.frames) == len(self.prim_colors) == len(self.env_colors) + + def to_c(self): + data = CData() + prim_array_name = f"{self.base_name}ColorPrimColor{self.header_suffix}" + env_array_name = f"{self.base_name}ColorEnvColor{self.header_suffix}" + frames_array_name = f"{self.base_name}ColorKeyFrames{self.header_suffix}" + params_name = f"AnimatedMatColorParams {self.name}" + + # .h + data.header = ( + f"extern F3DPrimColor {prim_array_name}[];\n" + + f"extern F3DEnvColor {env_array_name}[];\n" + + f"extern u16 {frames_array_name}[];\n" + + f"extern {params_name};\n" + ) + + # .c + data.source = ( + ( + (f"F3DPrimColor {prim_array_name}[]" + " = {\n" + indent) + + f",\n{indent}".join( + "{ " + f"{entry[0]}, {entry[1]}, {entry[2]}, {entry[3]}, {entry[4]}" + " }" + for entry in self.prim_colors + ) + + "\n};\n\n" + ) + + ( + (f"F3DEnvColor {env_array_name}[]" + " = {\n" + indent) + + f",\n{indent}".join( + "{ " + f"{entry[0]}, {entry[1]}, {entry[2]}, {entry[3]}" + " }" for entry in self.env_colors + ) + + "\n};\n\n" + ) + + ( + (f"u16 {frames_array_name}[]" + " = {\n" + indent) + + f",\n{indent}".join(f"{entry}" for entry in self.frames) + + "\n};\n\n" + ) + + ( + (params_name + " = {\n") + + (indent + f"{self.frame_length},\n") + + (indent + f"{self.frame_count},\n") + + (indent + f"{prim_array_name},\n") + + (indent + f"{env_array_name},\n") + + (indent + f"{frames_array_name},\n") + + "};\n\n" + ) + ) + + return data + + +class AnimatedMatTexScrollParams: + def __init__( + self, + props: Z64_AnimatedMatTexScrollParams, + segment_num: int, + type_num: int, + base_name: str, + header_index: int, + index: int, + ): + # the code adds back 7 when processing animated materials + self.segment_num = segment_num - 7 + self.type_num = type_num + self.base_name = base_name + self.header_index = header_index + self.header_suffix = f"_{index:02}" + self.name = f"{self.base_name}TexScrollParams{self.header_suffix}" + self.entries: list[str] = [] + + for item in props.entries: + self.entries.append("{ " + f"{item.step_x}, {item.step_y}, {item.width}, {item.height}" + " }") + + def to_c(self): + data = CData() + params_name = f"AnimatedMatTexScrollParams {self.name}[]" + + # .h + data.header = f"extern {params_name};\n" + + # .c + data.source = ( + f"{params_name}" + " = {\n" + indent + f",\n{indent}".join(entry for entry in self.entries) + "\n};\n\n" + ) + + return data + + +class AnimatedMatTexCycleParams: + def __init__( + self, + props: Z64_AnimatedMatTexCycleParams, + segment_num: int, + type_num: int, + base_name: str, + header_index: int, + index: int, + ): + # the code adds back 7 when processing animated materials + self.segment_num = segment_num - 7 + self.type_num = type_num + self.base_name = base_name + self.header_index = header_index + self.header_suffix = f"_{index:02}" + self.name = f"{self.base_name}TexCycleParams{self.header_suffix}" + self.textures: list[str] = [] + self.frames: list[int] = [] + + for keyframe in props.keyframes: + self.textures.append(keyframe.texture) + self.frames.append(keyframe.frame_num) + + def to_c(self): + data = CData() + texture_array_name = f"{self.base_name}CycleTextures{self.header_suffix}" + frame_array_name = f"{self.base_name}CycleKeyFrames{self.header_suffix}" + params_name = f"AnimatedMatTexCycleParams {self.name}" + + # .h + data.header = ( + f"extern TexturePtr {texture_array_name}[];\n" + + f"extern u8 {frame_array_name}[];\n" + + f"extern {params_name};\n" + ) + + # .c + data.source = ( + ( + (f"TexturePtr {texture_array_name}[]" + " = {\n") + + indent + + f",\n{indent}".join(texture for texture in self.textures) + + "\n};\n\n" + ) + + ( + (f"u8 {frame_array_name}[]" + " = {\n") + + indent + + ", ".join(f"{frame}" for frame in self.frames) + + "\n};\n\n" + ) + + ( + (params_name + " = {\n") + + indent + + f"{len(self.frames)}, {texture_array_name}, {frame_array_name}," + + "\n};\n\n" + ) + ) + + return data + + +class AnimatedMaterial: + def __init__(self, props: Z64_AnimatedMaterial, base_name: str, scene_header_index: int): + self.name = base_name + self.scene_header_index = scene_header_index + self.header_index = props.header_index + self.entries: list[AnimatedMatColorParams | AnimatedMatTexScrollParams | AnimatedMatTexCycleParams] = [] + + type_list_map: dict[ + str, tuple[AnimatedMatColorParams | AnimatedMatTexScrollParams | AnimatedMatTexCycleParams, str, int] + ] = { + "tex_scroll": (AnimatedMatTexScrollParams, "tex_scroll_params", 0), + "two_tex_scroll": (AnimatedMatTexScrollParams, "tex_scroll_params", 1), + "color": (AnimatedMatColorParams, "color_params", 2), + "color_lerp": (AnimatedMatColorParams, "color_params", 3), + "color_nonlinear_interp": (AnimatedMatColorParams, "color_params", 4), + "tex_cycle": (AnimatedMatTexCycleParams, "tex_cycle_params", 5), + } + + for i, item in enumerate(props.entries): + if item.type != "Custom": + class_def, prop_name, type_num = type_list_map[item.type] + # example: `self.tex_scroll_entries.append(AnimatedMatTexScrollParams(item.tex_scroll_params, base_name, header_index))` + self.entries.append( + class_def(getattr(item, prop_name), item.segment_num, type_num, base_name, self.header_index, i) + ) + + # the last entry's segment need to be negative + if len(self.entries) > 0 and self.entries[-1].segment_num > 0: + self.entries[-1].segment_num = -self.entries[-1].segment_num + + def to_c(self): + data = CData() + + for entry in self.entries: + if entry.header_index == -1 or entry.header_index == self.scene_header_index: + data.append(entry.to_c()) + + if len(self.entries) > 0: + array_name = f"AnimatedMaterial {self.name}[]" + + # .h + data.header += f"extern {array_name};" + + # .c + data.source += ( + (array_name + " = {\n" + indent) + + f",\n{indent}".join( + "{ " + + f"{entry.segment_num} /* {abs(entry.segment_num) + 7} */, " + + f"{entry.type_num}, " + + f"{'&' if entry.type_num in {2, 3, 4, 5} else ''}{entry.name}" + + " }" + for entry in self.entries + ) + + "\n};\n\n" + ) + else: + raise PluginError("ERROR: Trying to export animated materials with empty entries!") + + return data + + +@dataclass +class SceneAnimatedMaterial: + """This class hosts exit data""" + + name: str + header_index: int + entries: list[AnimatedMaterial] + + @staticmethod + def new(name: str, scene_obj: Object, header_index: int): + obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Animated Materials") + entries: list[AnimatedMaterial] = [] + + for obj in obj_list: + entries.extend([AnimatedMaterial(item, name, header_index) for item in obj.z64_anim_mats_property.items]) + + last_index = -1 + for entry in entries: + if entry.header_index >= 0: + if entry.header_index > last_index: + last_index = entry.header_index + else: + raise PluginError("ERROR: Animated Materials header indices are not consecutives!") + + return SceneAnimatedMaterial(name, header_index, entries) + + def get_cmd(self): + """Returns the sound settings, misc settings, special files and skybox settings scene commands""" + + return indent + f"SCENE_CMD_ANIMATED_MATERIAL_LIST({self.name}),\n" + + def to_c(self): + data = CData() + + for entry in self.entries: + data.append(entry.to_c()) + + return data diff --git a/fast64_internal/z64/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py index ade72636b..b74fce18c 100644 --- a/fast64_internal/z64/exporter/scene/header.py +++ b/fast64_internal/z64/exporter/scene/header.py @@ -9,6 +9,7 @@ from .general import SceneLighting, SceneInfos, SceneExits, SceneMapData from .actors import SceneTransitionActors, SceneEntranceActors, SceneSpawns from .pathways import ScenePathways +from .animated_mats import SceneAnimatedMaterial @dataclass @@ -27,6 +28,7 @@ class SceneHeader: # MM map_data: Optional[SceneMapData] + anim_mat: Optional[SceneAnimatedMaterial] @staticmethod def new( @@ -49,6 +51,7 @@ def new( SceneSpawns(f"{name}_entranceList", entranceActors.entries), ScenePathways.new(f"{name}_pathway", sceneObj, transform, headerIndex), SceneMapData.new(f"{name}_mapData", props, sceneObj, transform) if not is_game_oot() else None, + SceneAnimatedMaterial.new(f"{name}_AnimatedMaterial", sceneObj, headerIndex) if not is_game_oot() else None, ) def getC(self): @@ -73,6 +76,7 @@ def getC(self): if len(self.lighting.settings) > 0: headerData.append(self.lighting.getC()) + # Write the map data if not is_game_oot() and self.map_data is not None: headerData.append(self.map_data.to_c()) @@ -80,6 +84,9 @@ def getC(self): if len(self.path.pathList) > 0: headerData.append(self.path.getC()) + if not is_game_oot() and self.anim_mat is not None: + headerData.append(self.anim_mat.to_c()) + return headerData diff --git a/fast64_internal/z64/importer/classes.py b/fast64_internal/z64/importer/classes.py index f099d541c..4437cdae6 100644 --- a/fast64_internal/z64/importer/classes.py +++ b/fast64_internal/z64/importer/classes.py @@ -16,6 +16,7 @@ def __init__( includePaths: bool, includeWaterBoxes: bool, includeCutscenes: bool, + includeAnimatedMats: bool, ): self.actorDict = {} # actor hash : blender object self.entranceDict = {} # actor hash : blender object @@ -32,6 +33,7 @@ def __init__( self.includePaths = includePaths self.includeWaterBoxes = includeWaterBoxes self.includeCutscenes = includeCutscenes + self.includeAnimatedMats = includeAnimatedMats def addHeaderIfItemExists(self, hash, itemType: str, headerIndex: int): if itemType == "Actor": diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index d22c919ab..5eacb15fa 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -161,6 +161,7 @@ def parseScene( settings.includePaths, settings.includeWaterBoxes, settings.includeCutscenes, + settings.includeAnimatedMats, ) if settings.includeCutscenes: diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index fa9146050..be5312bb4 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -9,6 +9,7 @@ from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext from ..scene.properties import Z64_SceneHeaderProperty, Z64_LightProperty +from ..animated_mats.properties import enum_anim_mat_type from ..utility import ( getEvalParams, setCustomProperty, @@ -16,9 +17,10 @@ is_game_oot, get_cs_index_start, get_game_prop_name, + getObjectList, ) from .constants import headerNames -from .utility import getDataMatch, stripName +from .utility import getDataMatch, stripName, get_new_empty_object from .classes import SharedSceneData from .room_header import parseRoomCommands from .actor import parseTransActorList, parseSpawnList, parseEntranceList @@ -322,6 +324,108 @@ def parse_mm_map_data_chest( raise PluginError("ERROR: Chest Object not found!") +animated_material_first_list_name = "" + + +def parse_animated_material(scene_obj: Object, header_index: int, scene_data: str, list_name: str): + global animated_material_first_list_name + + data_match = getDataMatch(scene_data, list_name, "AnimatedMaterial", "animated material") + anim_mat_data = data_match.strip().split("\n") + + if header_index == 0: + animated_material_first_list_name = list_name + anim_mat_obj = get_new_empty_object("Animated Material") + anim_mat_obj.ootEmptyType = "Animated Materials" + parentObject(scene_obj, anim_mat_obj) + else: + obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Animated Materials") + anim_mat_obj = obj_list[0] + + # if the alternate header is using the first header's data then don't do anything + if header_index > 0 and list_name == animated_material_first_list_name: + return + + anim_mat_props = anim_mat_obj.z64_anim_mats_property + anim_mat_item = anim_mat_props.items.add() + anim_mat_item.header_index = header_index + + for data in anim_mat_data: + data = data.replace("{", "").replace("}", "").removesuffix(",").strip() + + split = data.split(", ") + segment = int(split[0], base=0) + type_num = int(split[1], base=0) + data_ptr = split[2].removeprefix("&") + + is_array = type_num in {0, 1} + struct_name, data_match = getDataMatch( + scene_data, data_ptr, r"(AnimatedMat[a-zA-Z]*Params)", "animated params", is_array, False + ) + + if is_array: + params_data = data_match.replace("{", "").replace("}", "").replace(" ", "").split("\n") + else: + params_data = data_match.replace("\n", "").replace(" ", "").split(",") + + entry = anim_mat_item.entries.add() + entry.segment_num = abs(segment) + 7 + entry.type = enum_anim_mat_type[type_num + 1][0] + + if struct_name == "AnimatedMatTexScrollParams": + for params in params_data: + if len(params) > 0: + split = params.split(",") + scroll_entry = entry.tex_scroll_params.entries.add() + scroll_entry.step_x = int(split[0], base=0) + scroll_entry.step_y = int(split[1], base=0) + scroll_entry.width = int(split[2], base=0) + scroll_entry.height = int(split[3], base=0) + elif struct_name == "AnimatedMatColorParams": + entry.color_params.frame_count = int(params_data[0], base=0) + + prim_match = getDataMatch(scene_data, params_data[2], "F3DPrimColor", "animated material prim color", True) + prim_data = prim_match.strip().replace(" ", "").replace("}", "").replace("{", "").split("\n") + + env_match = getDataMatch(scene_data, params_data[3], "F3DEnvColor", "animated material env color", True) + env_data = env_match.strip().replace(" ", "").replace("}", "").replace("{", "").split("\n") + + frame_match = getDataMatch(scene_data, params_data[4], "u16", "animated material color frame data", True) + frame_data = frame_match.strip().replace(" ", "").removesuffix(",").replace(",", "\n").split("\n") + + assert len(prim_data) == len(env_data) == len(frame_data) + + for prim_color_raw, env_color_raw, frame in zip(prim_data, env_data, frame_data): + prim_color = prim_color_raw.split(",") + env_color = env_color_raw.split(",") + + color_entry = entry.color_params.keyframes.add() + color_entry.frame_num = int(frame, base=0) + color_entry.prim_lod_frac = int(prim_color[4].strip(), base=0) + color_entry.prim_color = parseColor(prim_color[0:3]) + (1,) + color_entry.env_color = parseColor(env_color[0:3]) + (1,) + elif struct_name == "AnimatedMatTexCycleParams": + entry.tex_cycle_params.frame_count = int(params_data[0], base=0) + textures: list[str] = [] + frames: list[int] = [] + + data_match = getDataMatch(scene_data, params_data[1], "TexturePtr", "animated material texture ptr", True) + for texture_ptr in data_match.replace(",", "\n").strip().split("\n"): + textures.append(texture_ptr.strip()) + + data_match = getDataMatch(scene_data, params_data[2], "u8", "animated material frame data", True) + for frame_num in data_match.replace(",", "\n").strip().split("\n"): + frames.append(int(frame_num.strip(), base=0)) + + while len(textures) < len(frames): + textures.append("") + + for texture_ptr, frame_num in zip(textures, frames): + cycle_entry = entry.tex_cycle_params.keyframes.add() + cycle_entry.frame_num = frame_num + cycle_entry.texture = texture_ptr + + def get_enum_id_from_index(enum_key: str, index: int): if is_game_oot(): return oot_data.enumData.enumByKey[enum_key].item_by_index[index].id @@ -484,6 +588,8 @@ def parseSceneCommands( elif command in {"SCENE_CMD_MINIMAP_COMPASS_ICON_INFO", "SCENE_CMD_MAP_DATA_CHESTS"}: # Delay until rooms and actors are processed chest_map_data_args = args + elif sharedSceneData.includeAnimatedMats and command == "SCENE_CMD_ANIMATED_MATERIAL_LIST": + parse_animated_material(sceneObj, headerIndex, sceneData, stripName(args[0])) if sharedSceneData.includeActors and chest_map_data_args is not None: parse_mm_map_data_chest( diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index af5014009..ccf5a6ebe 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -46,6 +46,15 @@ def createEmptyWithTransform(positionValues: list[float], rotationValues: list[f return obj +def get_new_empty_object(name: str): + new_obj = bpy.data.objects.new(name, None) + bpy.context.scene.collection.objects.link(new_obj) + new_obj.location = [0.0, 0.0, 0.0] + new_obj.rotation_euler = [0.0, 0.0, 0.0] + new_obj.scale = [1.0, 1.0, 1.0] + return new_obj + + def getDisplayNameFromActorID(actorID: str): return " ".join([word.lower().capitalize() for word in actorID.split("_") if word != "ACTOR"]) @@ -64,25 +73,36 @@ def handleActorWithRotAsParam(actorProp: Z64_ActorProperty, actorID: str, rotati def getDataMatch( - sceneData: str, name: str, dataType: str | list[str], errorMessageID: str, isArray: bool = True -) -> str: + sceneData: str, + name: str, + dataType: str | list[str], + errorMessageID: str, + isArray: bool = True, + is_type_known: bool = True, +): arrayText = rf"\[[\s0-9A-Za-z_]*\]\s*" if isArray else "" + dataTypeRegex = dataType if isinstance(dataType, list): dataTypeRegex = "(?:" for i in dataType: dataTypeRegex += f"(?:{re.escape(i)})|" dataTypeRegex = dataTypeRegex[:-1] + ")" - else: + elif is_type_known: dataTypeRegex = re.escape(dataType) regex = rf"{dataTypeRegex}\s*{re.escape(name)}\s*{arrayText}=\s*\{{(.*?)\}}\s*;" match = re.search(regex, sceneData, flags=re.DOTALL) - if not match: + if match is None: raise PluginError(f"Could not find {errorMessageID} {name}.") - # return the match with comments removed - return removeComments(match.group(1)) + if is_type_known: + # return the match with comments removed + return removeComments(match.group(1)) + else: + f = match.groups() + # return the struct name and the match + return removeComments(match.group(1)), removeComments(match.group(2)) def stripName(name: str): diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 8e854fe00..5e3f8785d 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -6,6 +6,7 @@ from .room.properties import Z64_ObjectProperty, Z64_RoomHeaderProperty, Z64_AlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty from .cutscene.properties import OOTCutsceneProperty +from .animated_mats.properties import Z64_AnimatedMaterialProperty from .cutscene.motion.properties import ( OOTCutsceneMotionProperty, CutsceneCmdActorCueListProperty, @@ -37,6 +38,7 @@ ("CS Actor Cue Preview", "CS Actor Cue Preview", "CS Actor Cue Preview"), ("CS Player Cue Preview", "CS Player Cue Preview", "CS Player Cue Preview"), ("CS Dummy Cue", "CS Dummy Cue", "CS Dummy Cue"), + ("Animated Materials", "Animated Materials", "Animated Materials"), # ('Camera Volume', 'Camera Volume', 'Camera Volume'), ] @@ -69,6 +71,11 @@ def setLightPropertyValues(lightProp, ambient, diffuse0, diffuse1, fogColor, fog def onUpdateOOTEmptyType(self, context): + # OoT doesn't have this feature + if is_game_oot() and self.ootEmptyType == "Animated Materials": + self.ootEmptyType = "None" + print("INFO: Ocarina of Time doesn't support that feature.") + isNoneEmpty = self.ootEmptyType == "None" isBoxEmpty = self.ootEmptyType == "Water Box" isSphereEmpty = self.ootEmptyType == "Cull Group" @@ -176,6 +183,10 @@ def draw(self, context): csProp: OOTCutsceneProperty = obj.ootCutsceneProperty csProp.draw_props(box, obj) + elif obj.ootEmptyType == "Animated Materials": + anim_props: Z64_AnimatedMaterialProperty = obj.z64_anim_mats_property + anim_props.draw_props(box, obj) + elif obj.ootEmptyType in [ "CS Actor Cue List", "CS Player Cue List", diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 22f8a791b..85569571d 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -704,6 +704,7 @@ class Z64_ImportSceneSettingsProperty(PropertyGroup): includePaths: BoolProperty(name="Paths", default=True) includeWaterBoxes: BoolProperty(name="Water Boxes", default=True) includeCutscenes: BoolProperty(name="Cutscenes", default=False) + includeAnimatedMats: BoolProperty(name="Animated Materials", default=False) option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") mm_option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") @@ -727,6 +728,9 @@ def draw_props(self, layout: UILayout, sceneOption: str): if is_game_oot(): includeButtons3.prop(self, "includeCutscenes", toggle=1) + includeButtons4 = col.row(align=True) + includeButtons4.prop(self, "includeAnimatedMats", toggle=1) + col.prop(self, "isCustomDest") if self.isCustomDest: diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index cfcfdc470..d9bea9929 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -771,7 +771,7 @@ def getCollectionFromIndex(obj, prop, subIndex, isRoom): # Operators cannot store mutable references (?), so to reuse PropertyCollection modification code we do this. # Save a string identifier in the operator, then choose the member variable based on that. # subIndex is for a collection within a collection element -def getCollection(objName, collectionType, subIndex): +def getCollection(objName, collectionType, subIndex: int, collection_index: int = 0): obj = bpy.data.objects[objName] if collectionType == "Actor": collection = obj.ootActorProperty.headerSettings.cutsceneHeaders @@ -793,6 +793,16 @@ def getCollection(objName, collectionType, subIndex): collection = getCollectionFromIndex(obj, "minimap_room_list", subIndex, False) elif collectionType == "Object": collection = getCollectionFromIndex(obj, "objectList", subIndex, True) + elif collectionType == "Animated Mat. List": + collection = obj.z64_anim_mats_property.items + elif collectionType == "Animated Mat.": + collection = obj.z64_anim_mats_property.items[subIndex].entries + elif collectionType == "Animated Mat. Color": + collection = obj.z64_anim_mats_property.items[subIndex].entries[collection_index].color_params.keyframes + elif collectionType == "Animated Mat. Scroll": + collection = obj.z64_anim_mats_property.items[subIndex].entries[collection_index].tex_scroll_params.entries + elif collectionType == "Animated Mat. Cycle": + collection = obj.z64_anim_mats_property.items[subIndex].entries[collection_index].tex_cycle_params.keyframes elif collectionType == "Curve": collection = obj.ootSplineProperty.headerSettings.cutsceneHeaders elif collectionType.startswith("CSHdr."): @@ -822,7 +832,7 @@ def getCollection(objName, collectionType, subIndex): return collection -def drawAddButton(layout, index, collectionType, subIndex, objName): +def drawAddButton(layout, index, collectionType, subIndex, objName, collection_index: int = 0): if subIndex is None: subIndex = 0 addOp = layout.operator(OOTCollectionAdd.bl_idname) @@ -830,9 +840,12 @@ def drawAddButton(layout, index, collectionType, subIndex, objName): addOp.collectionType = collectionType addOp.subIndex = subIndex addOp.objName = objName + addOp.collection_index = collection_index -def drawCollectionOps(layout, index, collectionType, subIndex, objName, allowAdd=True, compact=False): +def drawCollectionOps( + layout, index, collectionType, subIndex, objName, allowAdd=True, compact=False, collection_index: int = 0 +): if subIndex is None: subIndex = 0 @@ -847,12 +860,14 @@ def drawCollectionOps(layout, index, collectionType, subIndex, objName, allowAdd addOp.collectionType = collectionType addOp.subIndex = subIndex addOp.objName = objName + addOp.collection_index = collection_index removeOp = buttons.operator(OOTCollectionRemove.bl_idname, text="Delete" if not compact else "", icon="REMOVE") removeOp.option = index removeOp.collectionType = collectionType removeOp.subIndex = subIndex removeOp.objName = objName + removeOp.collection_index = collection_index moveUp = buttons.operator(OOTCollectionMove.bl_idname, text="Up" if not compact else "", icon="TRIA_UP") moveUp.option = index @@ -860,6 +875,7 @@ def drawCollectionOps(layout, index, collectionType, subIndex, objName, allowAdd moveUp.collectionType = collectionType moveUp.subIndex = subIndex moveUp.objName = objName + moveUp.collection_index = collection_index moveDown = buttons.operator(OOTCollectionMove.bl_idname, text="Down" if not compact else "", icon="TRIA_DOWN") moveDown.option = index @@ -867,6 +883,7 @@ def drawCollectionOps(layout, index, collectionType, subIndex, objName, allowAdd moveDown.collectionType = collectionType moveDown.subIndex = subIndex moveDown.objName = objName + moveDown.collection_index = collection_index class OOTCollectionAdd(bpy.types.Operator): @@ -877,10 +894,11 @@ class OOTCollectionAdd(bpy.types.Operator): option: bpy.props.IntProperty() collectionType: bpy.props.StringProperty(default="Actor") subIndex: bpy.props.IntProperty(default=0) + collection_index: bpy.props.IntProperty(default=0) objName: bpy.props.StringProperty() def execute(self, context): - collection = getCollection(self.objName, self.collectionType, self.subIndex) + collection = getCollection(self.objName, self.collectionType, self.subIndex, self.collection_index) collection.add() collection.move(len(collection) - 1, self.option) @@ -895,10 +913,11 @@ class OOTCollectionRemove(bpy.types.Operator): option: bpy.props.IntProperty() collectionType: bpy.props.StringProperty(default="Actor") subIndex: bpy.props.IntProperty(default=0) + collection_index: bpy.props.IntProperty(default=0) objName: bpy.props.StringProperty() def execute(self, context): - collection = getCollection(self.objName, self.collectionType, self.subIndex) + collection = getCollection(self.objName, self.collectionType, self.subIndex, self.collection_index) collection.remove(self.option) return {"FINISHED"} @@ -911,12 +930,13 @@ class OOTCollectionMove(bpy.types.Operator): option: bpy.props.IntProperty() offset: bpy.props.IntProperty() subIndex: bpy.props.IntProperty(default=0) + collection_index: bpy.props.IntProperty(default=0) objName: bpy.props.StringProperty() collectionType: bpy.props.StringProperty(default="Actor") def execute(self, context): - collection = getCollection(self.objName, self.collectionType, self.subIndex) + collection = getCollection(self.objName, self.collectionType, self.subIndex, self.collection_index) collection.move(self.option, self.option + self.offset) return {"FINISHED"} From b5f26a6a68812177c7b0d63bddcf795fb80c05c9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 31 Dec 2024 03:50:42 +0100 Subject: [PATCH 036/126] fixed actor issues and started actor cutscene support --- fast64_internal/z64/__init__.py | 3 + fast64_internal/z64/actor/operators.py | 6 +- fast64_internal/z64/actor/properties.py | 13 +- .../z64/actor_cutscene/properties.py | 187 +++++++++++++++++ .../z64/animated_mats/properties.py | 11 +- fast64_internal/z64/collision/properties.py | 7 +- .../z64/exporter/collision/camera.py | 76 ++++--- fast64_internal/z64/exporter/room/header.py | 22 +- .../z64/exporter/scene/__init__.py | 1 + .../z64/exporter/scene/actor_cutscene.py | 192 ++++++++++++++++++ fast64_internal/z64/exporter/scene/actors.py | 32 ++- fast64_internal/z64/exporter/scene/header.py | 8 + fast64_internal/z64/importer/classes.py | 2 + fast64_internal/z64/importer/scene.py | 1 + .../z64/importer/scene_collision.py | 28 ++- fast64_internal/z64/importer/scene_header.py | 78 ++++++- fast64_internal/z64/props_panel_main.py | 6 + fast64_internal/z64/scene/properties.py | 2 + fast64_internal/z64/utility.py | 13 ++ 19 files changed, 607 insertions(+), 81 deletions(-) create mode 100644 fast64_internal/z64/actor_cutscene/properties.py create mode 100644 fast64_internal/z64/exporter/scene/actor_cutscene.py diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 6b62a0fb7..39afd0428 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -52,6 +52,7 @@ from .spline.panels import spline_panels_register, spline_panels_unregister from .animated_mats.properties import animated_mats_register, animated_mats_unregister +from .actor_cutscene.properties import actor_cs_register, actor_cs_unregister from .tools import ( oot_operator_panel_register, @@ -176,6 +177,7 @@ def oot_register(registerPanels: bool): file_register() anim_props_register() animated_mats_register() + actor_cs_register() csMotion_ops_register() csMotion_props_register() @@ -194,6 +196,7 @@ def oot_unregister(unregisterPanels: bool): for cls in reversed(oot_classes): unregister_class(cls) + actor_cs_unregister() animated_mats_unregister() oot_operator_unregister() oot_utility_unregister() diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 15562ad4a..623d160e4 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -49,11 +49,11 @@ class MM_SearchActorIDEnumOperator(Operator): def execute(self, context): obj = bpy.data.objects[self.objName] if self.actorUser == "Transition Actor": - obj.ootTransitionActorProperty.actor.actorID = self.actorID + obj.ootTransitionActorProperty.actor.mm_actor_id = self.actorID elif self.actorUser == "Actor": - obj.ootActorProperty.actorID = self.actorID + obj.ootActorProperty.mm_actor_id = self.actorID elif self.actorUser == "Entrance": - obj.ootEntranceProperty.actor.actorID = self.actorID + obj.ootEntranceProperty.actor.mm_actor_id = self.actorID else: raise PluginError("Invalid actor user for search: " + str(self.actorUser)) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index ffe9217e0..fc97e383c 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -235,15 +235,22 @@ def draw_props( self, layout: UILayout, altSceneProp: Z64_AlternateSceneHeaderProperty, roomObj: Object, objName: str ): actorIDBox = layout.column() - searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") + + if is_game_oot(): + op_name = OOT_SearchActorIDEnumOperator.bl_idname + else: + op_name = MM_SearchActorIDEnumOperator.bl_idname + + searchOp = actorIDBox.operator(op_name, icon="VIEWZOOM") searchOp.actorUser = "Transition Actor" searchOp.objName = objName split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - split.label(text=getEnumName(oot_data.actorData.ootEnumActorID, self.actor.actorID)) + actor_id = getattr(self.actor, get_game_prop_name("actor_id")) + split.label(text=getEnumName(get_game_enum("enum_actor_id"), actor_id)) - if self.actor.actorID == "Custom": + if actor_id == "Custom": prop_split(actorIDBox, self.actor, "actorIDCustom", "") if not is_game_oot(): diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py new file mode 100644 index 000000000..6f4b0f5c2 --- /dev/null +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -0,0 +1,187 @@ +from bpy.props import ( + IntProperty, + PointerProperty, + BoolProperty, + EnumProperty, + StringProperty, + CollectionProperty, + FloatVectorProperty, +) +from bpy.utils import register_class, unregister_class +from bpy.types import PropertyGroup, UILayout, Object +from ...utility import prop_split +from ..utility import drawCollectionOps, drawAddButton, get_list_tab_text +from ..actor.properties import Z64_ActorHeaderProperty +from ..scene.properties import Z64_AlternateSceneHeaderProperty + + +enum_cs_cam_id = [ + ("Custom", "Custom", "Custom"), + ("Camera", "Camera Object", "Camera Object"), + ("CS_CAM_ID_GLOBAL_ELEGY", "Elegy of Emptiness", "-25 (CAM_SET_ELEGY_SHELL)"), + ("CS_CAM_ID_GLOBAL_SIDED", "Sided", "-24 (CAM_SET_SIDED)"), + ("CS_CAM_ID_GLOBAL_BOAT_CRUISE", "Boat Cruise", "-23 (CAM_SET_BOAT_CRUISE)"), + ("CS_CAM_ID_GLOBAL_N16", "N16", "-22 (CAM_SET_NONE)"), + ("CS_CAM_ID_GLOBAL_SUBJECTD", "Subjectd", "-21 (CAM_SET_SUBJECTD)"), + ("CS_CAM_ID_GLOBAL_NORMALD", "Normald", "-20 (CAM_SET_NORMALD)"), + ("CS_CAM_ID_GLOBAL_N13", "N13", "-19 (CAM_SET_NONE)"), + ("CS_CAM_ID_GLOBAL_N12", "N12", "-18 (CAM_SET_NONE)"), + ("CS_CAM_ID_GLOBAL_N11", "N11", "-17 (CAM_SET_NONE)"), + ("CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE", "Warp Pad Entrance", "-16 (CAM_SET_WARP_PAD_ENTRANCE)"), + ("CS_CAM_ID_GLOBAL_ATTENTION", "Attention", "-15 (CAM_SET_ATTENTION)"), + ("CS_CAM_ID_GLOBAL_CONNECT", "Connect", "-14 (CAM_SET_CONNECT0)"), + ("CS_CAM_ID_GLOBAL_REMOTE_BOMB", "Remote Bomb", "-13 (CAM_SET_REMOTEBOMB)"), + ("CS_CAM_ID_GLOBAL_N0C", "N0C", "-12 (CAM_SET_NONE)"), + ("CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION", "Mask Transformation", "-11 (CAM_SET_MASK_TRANSFORMATION)"), + ("CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING", "Long Chest Opening", "-10 (CAM_SET_LONG_CHEST_OPENING)"), + ("CS_CAM_ID_GLOBAL_REVIVE", "Revive", "-9 (CAM_SET_REBIRTH)"), + ("CS_CAM_ID_GLOBAL_DEATH", "Death", "-8 (CAM_SET_DEATH)"), + ("CS_CAM_ID_GLOBAL_WARP_PAD_MOON", "Warp Pad Moon", "-7 (CAM_SET_WARP_PAD_MOON)"), + ("CS_CAM_ID_GLOBAL_SONG_WARP", "Song Warp", "-6 (CAM_SET_NAVI)"), + ("CS_CAM_ID_GLOBAL_ITEM_SHOW", "Item Show", "-5 (CAM_SET_ITEM3)"), + ("CS_CAM_ID_GLOBAL_ITEM_BOTTLE", "Item Bottle", "-4 (CAM_SET_ITEM2)"), + ("CS_CAM_ID_GLOBAL_ITEM_OCARINA", "Item Ocarina", "-3 (CAM_SET_ITEM1)"), + ("CS_CAM_ID_GLOBAL_ITEM_GET", "Item Get", "-2 (CAM_SET_ITEM0)"), + ("CS_CAM_ID_NONE", "None", "-1"), +] + +enum_end_sfx = [ + ("Custom", "Custom", "Custom"), + ("CS_END_SFX_NONE", "None", "0"), + ("CS_END_SFX_TRE_BOX_APPEAR", "Chest Appear", "1"), + ("CS_END_SFX_CORRECT_CHIME", "Correct Chime", "2"), + ("CS_END_SFX_NONE_ALT", "None Alt", "255"), +] + +enum_hud_visibility = [ + ("Custom", "Custom", "Custom"), + ("CS_HUD_VISIBILITY_NONE", "None", "0"), + ("CS_HUD_VISIBILITY_ALL", "All", "1"), + ("CS_HUD_VISIBILITY_A_HEARTS_MAGIC", "Only A Button, Hearts and Magic Meter", "2"), + ("CS_HUD_VISIBILITY_C_HEARTS_MAGIC", "Only C Buttons, Hearts and Magic Meter", "3"), + ("CS_HUD_VISIBILITY_ALL_NO_MINIMAP", "All without Minimap", "4"), + ("CS_HUD_VISIBILITY_A_B_C", "Only A Button, B Button and C Buttons", "5"), + ("CS_HUD_VISIBILITY_B_MINIMAP", "Only B Button and Minimap", "6"), + ("CS_HUD_VISIBILITY_A", "Only A Button", "7"), + ("CS_HUD_VISIBILITY_ALL_ALT", "All 2", "-1"), +] + +enum_end_cam = [ + ("Custom", "Custom", "Custom"), + ("CS_END_CAM_0", "Cam 0", "0"), + ("CS_END_CAM_1", "Cam 1", "1"), + ("CS_END_CAM_SMOOTH", "Cam Smooth", "2"), +] + + +def poll_camera_obj(self, obj: Object): + return obj.type == "CAMERA" and obj.ootCameraPositionProperty.is_actor_cs_cam + + +class Z64_ActorCutscene(PropertyGroup): + priority: IntProperty(name="Priority", default=700, description="Lower number means higher priority") + length: IntProperty(name="Length", min=-1, default=-1) + cs_cam_id: EnumProperty( + name="CS Cam ID", + items=enum_cs_cam_id, + default=2, + description="Index of `CsCameraEntry` to use. Negative indices use `sGlobalCamDataSettings`. Indices 0 and above use `CsCameraEntry` from a sceneLayer", + ) + cs_cam_id_custom: StringProperty(name="CS Cam ID Custom", default="CS_CAM_ID_NONE") + cs_cam_obj: PointerProperty(type=Object, poll=poll_camera_obj) + script_index: IntProperty(name="Script Index", min=-1, default=-1, description="Gets the priority over 'CS Cam ID'") + additional_cs_id: IntProperty(name="Additional CS ID", min=-1, default=-1) + end_sfx: EnumProperty(name="End Sound Effect", items=enum_end_sfx, default=1) + end_sfx_custom: StringProperty(name="End Sound Effect Custom") + custom_value: StringProperty( + name="Custom Value", default="255", description="0 - 99: actor-specific custom value. 100+: spawn. 255: none" + ) + hud_visibility: EnumProperty(name="HUD Visibility", items=enum_hud_visibility, default=1) + hud_visibility_custom: StringProperty(name="HUD Visibility Custom") + end_cam: EnumProperty(name="End Cam", items=enum_end_cam, default=1) + end_cam_custom: StringProperty(name="End Cam Custom") + letterbox_size: IntProperty(name="Letterbox Size", min=0, max=255, default=30) + + # ui only props + show_item: BoolProperty() + + def draw_props(self, layout: UILayout, owner: Object, index: int): + layout = layout.column() + layout.prop( + self, "show_item", text=f"Entry No. {index + 1}", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT" + ) + + if self.show_item: + drawCollectionOps(layout, index, "Actor CS", None, owner.name) + + prop_split(layout, self, "priority", "Priority") + prop_split(layout, self, "length", "Length") + + prop_split(layout, self, "cs_cam_id", "CS Cam ID") + if self.cs_cam_id == "Custom": + prop_split(layout, self, "cs_cam_id_custom", "CS Cam ID Custom") + elif self.cs_cam_id == "Camera": + prop_split(layout, self, "cs_cam_obj", "Camera Object") + + prop_split(layout, self, "script_index", "Script Index") + prop_split(layout, self, "additional_cs_id", "Additional CS ID") + + prop_split(layout, self, "end_sfx", "End Sound Effect") + if self.end_sfx == "Custom": + prop_split(layout, self, "end_sfx_custom", "End Sound Effect Custom") + + prop_split(layout, self, "custom_value", "Custom Value") + + prop_split(layout, self, "hud_visibility", "HUD Visibility") + if self.hud_visibility == "Custom": + prop_split(layout, self, "hud_visibility_custom", "HUD Visibility Custom") + + prop_split(layout, self, "end_cam", "End Cam") + if self.end_cam == "Custom": + prop_split(layout, self, "end_cam_custom", "End Cam Custom") + + prop_split(layout, self, "letterbox_size", "Letterbox Size") + + +class Z64_ActorCutsceneProperty(PropertyGroup): + entries: CollectionProperty(type=Z64_ActorCutscene) + header_settings: PointerProperty(type=Z64_ActorHeaderProperty) + + # ui only props + show_entries: BoolProperty(default=True) + + def draw_props(self, layout: UILayout, owner: Object, alt_header_props: Z64_AlternateSceneHeaderProperty): + layout_entries = layout.box().column() + + prop_text = get_list_tab_text("Entries", len(self.entries)) + layout_entries.prop( + self, "show_entries", text=prop_text, icon="TRIA_DOWN" if self.show_entries else "TRIA_RIGHT" + ) + + if self.show_entries: + for i, actor_cs in enumerate(self.entries): + actor_cs.draw_props(layout_entries.box(), owner, i) + + drawAddButton(layout_entries, len(self.entries), "Actor CS", None, owner.name) + + self.header_settings.draw_props(layout, "Actor CS Headers", alt_header_props, owner.name) + + +classes = ( + Z64_ActorCutscene, + Z64_ActorCutsceneProperty, +) + + +def actor_cs_register(): + for cls in classes: + register_class(cls) + + Object.z64_actor_cs_property = PointerProperty(type=Z64_ActorCutsceneProperty) + + +def actor_cs_unregister(): + del Object.z64_actor_cs_property + + for cls in reversed(classes): + unregister_class(cls) diff --git a/fast64_internal/z64/animated_mats/properties.py b/fast64_internal/z64/animated_mats/properties.py index 0b23e08c7..5c4edff49 100644 --- a/fast64_internal/z64/animated_mats/properties.py +++ b/fast64_internal/z64/animated_mats/properties.py @@ -10,7 +10,7 @@ from bpy.utils import register_class, unregister_class from bpy.types import PropertyGroup, UILayout, Object from ...utility import prop_split -from ..utility import drawCollectionOps, drawAddButton +from ..utility import drawCollectionOps, drawAddButton, get_list_tab_text # no custom since we only need to know where to export the data @@ -31,15 +31,6 @@ ] -def get_list_tab_text(base_text: str, list_length: int): - if list_length > 0: - items_amount = f"{list_length} Item{'s' if list_length > 1 else ''}" - else: - items_amount = "Empty" - - return f"{base_text} ({items_amount})" - - class Z64_AnimatedMatColorKeyFrame(PropertyGroup): frame_num: IntProperty(name="Frame No.", min=0) diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index cb912467e..e0331b5b0 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -54,11 +54,16 @@ class OOTCameraPositionProperty(PropertyGroup): mm_cam_setting_type: EnumProperty(items=mm_enum_camera_setting_type, default=2) camSTypeCustom: StringProperty(default="CAM_SET_NORMAL0") hasPositionData: BoolProperty(default=True, name="Has Position Data") + is_actor_cs_cam: BoolProperty(default=False, name="Is Actor CS Camera") def draw_props(self, layout: UILayout, cameraObj: Object): drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "", "camSTypeCustom") prop_split(layout, self, "index", "Camera Index") - layout.prop(self, "hasPositionData") + layout.prop(self, "is_actor_cs_cam") + + if not self.is_actor_cs_cam: + layout.prop(self, "hasPositionData") + if self.hasPositionData: prop_split(layout, cameraObj.data, "angle", "Field Of View") prop_split(layout, self, "bgImageOverrideIndex", "BG Index Override") diff --git a/fast64_internal/z64/exporter/collision/camera.py b/fast64_internal/z64/exporter/collision/camera.py index f4f2eccfb..8acc8d669 100644 --- a/fast64_internal/z64/exporter/collision/camera.py +++ b/fast64_internal/z64/exporter/collision/camera.py @@ -3,8 +3,9 @@ from dataclasses import dataclass, field from mathutils import Quaternion, Matrix from bpy.types import Object +from typing import Optional from ....utility import PluginError, CData, indent -from ...utility import getObjectList +from ...utility import getObjectList, is_game_oot from ...collision.constants import decomp_compat_map_CameraSType from ...collision.properties import OOTCameraPositionProperty from ..utility import Utility @@ -102,6 +103,47 @@ def getCrawlspacePosList(dataHolder: Object, transform: Matrix): ) return crawlspacePosList + @staticmethod + def get_camera_info( + data_holder: Object, cam_obj: Object, transform: Matrix, cam_pos_data: Optional[dict[int, CameraData]] + ): + camProp: OOTCameraPositionProperty = cam_obj.ootCameraPositionProperty + cam_setting = camProp.camSType if is_game_oot() else camProp.mm_cam_setting_type + + if cam_pos_data is None: + cam_pos_data = {} + + if cam_setting == "Custom": + setting = camProp.camSTypeCustom + else: + setting = decomp_compat_map_CameraSType.get(cam_setting, cam_setting) if is_game_oot() else cam_setting + + if camProp.hasPositionData or camProp.is_actor_cs_cam: + if camProp.index in cam_pos_data: + raise PluginError(f"ERROR: Repeated camera position index: {camProp.index} for {cam_obj.name}") + + # Camera faces opposite direction + pos, rot, _, _ = Utility.getConvertedTransformWithOrientation( + transform, data_holder, cam_obj, Quaternion((0, 1, 0), math.radians(180.0)) + ) + + fov = math.degrees(cam_obj.data.angle) + cam_pos_data[camProp.index] = CameraData( + pos, + rot, + round(fov * 100 if fov > 3.6 else fov), # see CAM_DATA_SCALED() macro + cam_obj.ootCameraPositionProperty.bgImageOverrideIndex, + ) + + return CameraInfo( + setting, + 3 + if camProp.hasPositionData or camProp.is_actor_cs_cam + else 0, # cameras are using 3 entries in the data array + cam_pos_data[camProp.index] if camProp.hasPositionData or camProp.is_actor_cs_cam else None, + camProp.index, + ) + @staticmethod def getBgCamInfoList(dataHolder: Object, transform: Matrix): """Returns a list of camera informations from camera objects""" @@ -113,37 +155,15 @@ def getBgCamInfoList(dataHolder: Object, transform: Matrix): for camObj in camObjList: camProp: OOTCameraPositionProperty = camObj.ootCameraPositionProperty - if camProp.camSType == "Custom": - setting = camProp.camSTypeCustom - else: - setting = decomp_compat_map_CameraSType.get(camProp.camSType, camProp.camSType) - - if camProp.hasPositionData: - if camProp.index in camPosData: - raise PluginError(f"ERROR: Repeated camera position index: {camProp.index} for {camObj.name}") - - # Camera faces opposite direction - pos, rot, _, _ = Utility.getConvertedTransformWithOrientation( - transform, dataHolder, camObj, Quaternion((0, 1, 0), math.radians(180.0)) - ) - - fov = math.degrees(camObj.data.angle) - camPosData[camProp.index] = CameraData( - pos, - rot, - round(fov * 100 if fov > 3.6 else fov), # see CAM_DATA_SCALED() macro - camObj.ootCameraPositionProperty.bgImageOverrideIndex, - ) + # ignore non-scene cameras + if camProp.is_actor_cs_cam: + continue if camProp.index in camInfoData: raise PluginError(f"ERROR: Repeated camera entry: {camProp.index} for {camObj.name}") - camInfoData[camProp.index] = CameraInfo( - setting, - 3 if camProp.hasPositionData else 0, # cameras are using 3 entries in the data array - camPosData[camProp.index] if camProp.hasPositionData else None, - camProp.index, - ) + camInfoData[camProp.index] = BgCamInformations.get_camera_info(dataHolder, camObj, transform, camPosData) + return list(camInfoData.values()) @staticmethod diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index c40464060..2d424e5f4 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import CData, indent from ...utility import getObjectList, is_game_oot, getEvalParams, get_game_prop_name -from ...constants import oot_data +from ...constants import oot_data, mm_data from ...room.properties import Z64_RoomHeaderProperty from ..utility import Utility from ..actor import Actor @@ -122,7 +122,10 @@ def new(name: str, props: Optional[Z64_RoomHeaderProperty]): if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objectList.append(oot_data.objectData.objects_by_key[objProp.objectKey].id) + objects_by_key = ( + oot_data.objectData.objects_by_key if is_game_oot() else mm_data.object_data.objects_by_key + ) + objectList.append(objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -178,19 +181,21 @@ def new( if not Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex): continue + actor_id: str = actorProp.actorID if is_game_oot() else actorProp.mm_actor_id + # The Actor list is filled with ``("None", f"{i} (Deleted from the XML)", "None")`` for # the total number of actors defined in the XML. If the user deletes one, this will prevent # any data loss as Blender saves the index of the element in the Actor list used for the EnumProperty # and not the identifier as defined by the first element of the tuple. Therefore, we need to check if # the current Actor has the ID `None` to avoid export issues. - if actorProp.actorID != "None": + if actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) actor = Actor() - if actorProp.actorID == "Custom": + if actor_id == "Custom": actor.id = actorProp.actorIDCustom else: - actor.id = actorProp.actorID + actor.id = actor_id if is_game_oot(): if actorProp.rotOverride: @@ -222,11 +227,10 @@ def new( spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) + actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id actor.name = ( - oot_data.actorData.actorsByID[actorProp.actorID].name.replace( - f" - {actorProp.actorID.removeprefix('ACTOR_')}", "" - ) - if actorProp.actorID != "Custom" + actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") + if actor_id != "Custom" else "Custom Actor" ) diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 00a5c2dc1..9e9d847ae 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -125,6 +125,7 @@ def getCmdList(self, curHeader: SceneHeader, hasAltHeaders: bool): + (curHeader.cutscene.getCmd() if len(curHeader.cutscene.entries) > 0 else "") + (curHeader.map_data.get_cmds() if not is_game_oot() and curHeader.map_data is not None else "") + (curHeader.anim_mat.get_cmd() if not is_game_oot() and curHeader.anim_mat is not None else "") + + (curHeader.actor_cs.get_cmds() if not is_game_oot() and curHeader.actor_cs is not None else "") + Utility.getEndCmd() + "};\n\n" ) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py new file mode 100644 index 000000000..736b0d301 --- /dev/null +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -0,0 +1,192 @@ +from dataclasses import dataclass +from bpy.types import Object +from mathutils import Matrix +from typing import Optional +from ....utility import CData, PluginError, exportColor, scaleToU8, indent +from ...utility import getObjectList +from ...actor_cutscene.properties import Z64_ActorCutsceneProperty, Z64_ActorCutscene +from ..utility import Utility +from ..collision.camera import BgCamInformations, CameraInfo + + +class ActorCutscene: + def __init__(self, scene_obj: Object, transform: Matrix, props: Z64_ActorCutscene, name: str, index: int): + self.name = name + self.priority: int = props.priority + self.length: int = props.length + self.index = index + self.cam_info: Optional[CameraInfo] = None + + if props.cs_cam_id == "Custom": + self.cs_cam_id: str = props.cs_cam_id_custom + elif props.cs_cam_id == "Camera": + if props.cs_cam_obj is None: + raise PluginError("ERROR: The Actor Cutscene Camera object is unset!") + + cam_props = props.cs_cam_obj.ootCameraPositionProperty + self.cs_cam_id: str = f"{cam_props.index}" + + # since it's literally the same thing we can just use `BgCamInformations` + self.cam_info = BgCamInformations.get_camera_info(scene_obj, props.cs_cam_obj, transform, None) + self.cam_info.arrayIndex = cam_props.index * 3 + else: + self.cs_cam_id: str = props.cs_cam_id + + self.script_index: int = props.script_index + self.additional_cs_id: int = props.additional_cs_id + self.end_sfx: str = Utility.getPropValue(props, "end_sfx", "end_sfx_custom") + self.custom_value: str = props.custom_value + self.hud_visibility: str = Utility.getPropValue(props, "hud_visibility", "hud_visibility_custom") + self.end_cam: str = Utility.getPropValue(props, "end_cam", "end_cam_custom") + self.letterbox_size: int = props.letterbox_size + + if self.script_index != -1 and self.cs_cam_id not in {"CS_CAM_ID_NONE", "-1"}: + print( + "WARNING: this actor cutscene entry won't use the camera cutscene since the script takes the priority." + ) + + def cutscene_entry_to_c(self): + values = [ + self.priority, + self.length, + self.cs_cam_id, + self.script_index, + self.additional_cs_id, + self.end_sfx, + self.custom_value, + self.hud_visibility, + self.end_cam, + self.letterbox_size, + ] + + return "{ " + ", ".join(f"{value}" for value in values) + " }" + + +@dataclass +class SceneActorCutscene: + """This class hosts actor cutscene data""" + + name: str + cam_info_array_name: str + cam_data_array_name: str + header_index: int + entries: list[ActorCutscene] + + @staticmethod + def new(name: str, scene_obj: Object, transform: Matrix, header_index: int): + obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Actor Cutscene") + entries: list[ActorCutscene] = [] + + for i, obj in enumerate(obj_list): + entries.extend( + [ + ActorCutscene(scene_obj, transform, item, name, i) + for item in obj.z64_actor_cs_property.entries + if Utility.isCurrentHeaderValid(obj.z64_actor_cs_property.header_settings, header_index) + ] + ) + + # validate camera indices + last_cam_index = -1 + for entry in entries: + if entry.cam_info is not None: + if entry.cam_info.camIndex > last_cam_index: + last_cam_index = entry.cam_info.camIndex + else: + raise PluginError("ERROR: the actor cs camera indices are not consecutives!") + + return SceneActorCutscene(name, f"{name}CameraInfo", f"{name}CameraData", header_index, entries) + + def is_cs_cam_used(self): + for entry in self.entries: + if entry.cam_info is not None: + return True + return False + + def get_cs_cam_list_length(self): + length = 0 + for entry in self.entries: + if entry.cam_info is not None: + length += 1 + return length + + def get_cmds(self): + """Returns the actor cutscene commands""" + + commands = [ + f"SCENE_CMD_ACTOR_CUTSCENE_LIST({len(self.entries)}, {self.name}List)", + ] + + if self.is_cs_cam_used(): + commands.append( + f"SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST({self.get_cs_cam_list_length()}, {self.cam_info_array_name})" + ) + + return indent + f",\n{indent}".join(commands) + ",\n" + + def cam_data_to_c(self): + """Returns the camera data positions array""" + + data = CData() + array_name = f"Vec3s {self.cam_data_array_name}[]" + + # .h + data.header = f"extern {array_name};\n" + + # .c + data.source = array_name + " = {\n" + + for entry in self.entries: + if entry.cam_info is not None: + data.source += entry.cam_info.data.getEntryC() + "\n" + + data.source = data.source[:-1] # remove extra newline + data.source += "};\n\n" + + return data + + def cam_info_to_c(self): + """Returns the array containing the informations of each cameras""" + + data = CData() + array_name = f"ActorCsCamInfo {self.cam_info_array_name}[]" + + # .h + data.header = f"extern {array_name};\n" + + # .c + data.source = ( + (array_name + " = {\n") + + "".join( + entry.cam_info.getInfoEntryC(self.cam_data_array_name) + for i, entry in enumerate(self.entries) + if entry.cam_info is not None + ) + + "};\n\n" + ) + + return data + + def to_c(self): + data = CData() + array_name = f"CutsceneEntry {self.name}List[]" + + if self.is_cs_cam_used(): + data.append(self.cam_data_to_c()) + data.append(self.cam_info_to_c()) + + # .h + data.header += f"extern {array_name};\n" + + # .c + data.source += ( + (array_name + " = {\n") + + ( + ",\n".join( + indent + f"/* {i:02} */ " + entry.cutscene_entry_to_c() for i, entry in enumerate(self.entries) + ) + ) + + "\n};\n\n" + ) + + return data diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index fc42f3f76..1289ca6fa 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_game_oot -from ...constants import oot_data +from ...constants import oot_data, mm_data from ..utility import Utility from ..actor import Actor @@ -59,10 +59,8 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entries: list[TransitionActor] = [] for obj in actorObjList: transActorProp = obj.ootTransitionActorProperty - if ( - Utility.isCurrentHeaderValid(transActorProp.actor.headerSettings, headerIndex) - and transActorProp.actor.actorID != "None" - ): + actor_id: str = transActorProp.actor.actorID if is_game_oot() else transActorProp.actor.mm_actor_id + if Utility.isCurrentHeaderValid(transActorProp.actor.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) transActor = TransitionActor() @@ -76,16 +74,15 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): front = (fromIndex, Utility.getPropValue(transActorProp, "cameraTransitionFront")) back = (toIndex, Utility.getPropValue(transActorProp, "cameraTransitionBack")) - if transActorProp.actor.actorID == "Custom": + if actor_id == "Custom": transActor.id = transActorProp.actor.actorIDCustom else: - transActor.id = transActorProp.actor.actorID + transActor.id = actor_id + actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id transActor.name = ( - oot_data.actorData.actorsByID[transActorProp.actor.actorID].name.replace( - f" - {transActorProp.actor.actorID.removeprefix('ACTOR_')}", "" - ) - if transActorProp.actor.actorID != "Custom" + actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") + if actor_id != "Custom" else "Custom Actor" ) @@ -151,18 +148,15 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): actorObjList = getObjectList(sceneObj.children_recursive, "EMPTY", "Entrance") for obj in actorObjList: entranceProp = obj.ootEntranceProperty - if ( - Utility.isCurrentHeaderValid(entranceProp.actor.headerSettings, headerIndex) - and entranceProp.actor.actorID != "None" - ): + actor_id: str = entranceProp.actor.actorID if is_game_oot() else entranceProp.actor.mm_actor_id + if Utility.isCurrentHeaderValid(entranceProp.actor.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) entranceActor = EntranceActor() + actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id entranceActor.name = ( - oot_data.actorData.actorsByID[entranceProp.actor.actorID].name.replace( - f" - {entranceProp.actor.actorID.removeprefix('ACTOR_')}", "" - ) - if entranceProp.actor.actorID != "Custom" + actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") + if actor_id != "Custom" else "Custom Actor" ) diff --git a/fast64_internal/z64/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py index b74fce18c..92b4b2394 100644 --- a/fast64_internal/z64/exporter/scene/header.py +++ b/fast64_internal/z64/exporter/scene/header.py @@ -10,6 +10,7 @@ from .actors import SceneTransitionActors, SceneEntranceActors, SceneSpawns from .pathways import ScenePathways from .animated_mats import SceneAnimatedMaterial +from .actor_cutscene import SceneActorCutscene @dataclass @@ -29,6 +30,7 @@ class SceneHeader: # MM map_data: Optional[SceneMapData] anim_mat: Optional[SceneAnimatedMaterial] + actor_cs: Optional[SceneActorCutscene] @staticmethod def new( @@ -52,6 +54,9 @@ def new( ScenePathways.new(f"{name}_pathway", sceneObj, transform, headerIndex), SceneMapData.new(f"{name}_mapData", props, sceneObj, transform) if not is_game_oot() else None, SceneAnimatedMaterial.new(f"{name}_AnimatedMaterial", sceneObj, headerIndex) if not is_game_oot() else None, + SceneActorCutscene.new(f"{name}_ActorCutscene", sceneObj, transform, headerIndex) + if not is_game_oot() + else None, ) def getC(self): @@ -87,6 +92,9 @@ def getC(self): if not is_game_oot() and self.anim_mat is not None: headerData.append(self.anim_mat.to_c()) + if not is_game_oot() and self.actor_cs is not None: + headerData.append(self.actor_cs.to_c()) + return headerData diff --git a/fast64_internal/z64/importer/classes.py b/fast64_internal/z64/importer/classes.py index 4437cdae6..a181fb657 100644 --- a/fast64_internal/z64/importer/classes.py +++ b/fast64_internal/z64/importer/classes.py @@ -17,6 +17,7 @@ def __init__( includeWaterBoxes: bool, includeCutscenes: bool, includeAnimatedMats: bool, + includeActorCs: bool, ): self.actorDict = {} # actor hash : blender object self.entranceDict = {} # actor hash : blender object @@ -34,6 +35,7 @@ def __init__( self.includeWaterBoxes = includeWaterBoxes self.includeCutscenes = includeCutscenes self.includeAnimatedMats = includeAnimatedMats + self.includeActorCs = includeActorCs def addHeaderIfItemExists(self, hash, itemType: str, headerIndex: int): if itemType == "Actor": diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 5eacb15fa..fb1150992 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -162,6 +162,7 @@ def parseScene( settings.includeWaterBoxes, settings.includeCutscenes, settings.includeAnimatedMats, + settings.includeActorCs, ) if settings.includeCutscenes: diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index def4aeb93..e7808a8dc 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -45,8 +45,9 @@ def parseCrawlSpaceData( return curveObj -def parseCamDataList(sceneObj: bpy.types.Object, camDataListName: str, sceneData: str): - camMatchData = getDataMatch(sceneData, camDataListName, ["CamData", "BgCamInfo"], "camera data list") +def parseCamDataList(sceneObj: bpy.types.Object, camDataListName: str, sceneData: str, is_actor_cs: bool = False): + type_names = "ActorCsCamInfo" if is_actor_cs else ["CamData", "BgCamInfo"] + camMatchData = getDataMatch(sceneData, camDataListName, type_names, "camera data list") camDataList = [value.replace("{", "").strip() for value in camMatchData.split("},") if value.strip() != ""] # orderIndex used for naming cameras in alphabetical order @@ -55,28 +56,39 @@ def parseCamDataList(sceneObj: bpy.types.Object, camDataListName: str, sceneData setting, count, posDataName = [value.strip() for value in camEntry.split(",")] index = None - objName = f"{sceneObj.name}_camPos_{format(orderIndex, '03')}" + objName = ( + f"{sceneObj.name}_ActorCsCam_{format(orderIndex, '03')}" + if is_actor_cs + else f"{sceneObj.name}_camPos_{format(orderIndex, '03')}" + ) if posDataName != "NULL" and posDataName != "0": index = hexOrDecInt(posDataName[posDataName.index("[") + 1 : -1]) posDataName = posDataName[1 : posDataName.index("[")] # remove '&' and '[n]' - if setting == "CAM_SET_CRAWLSPACE" or setting == "0x001E": + if not is_actor_cs and setting == "CAM_SET_CRAWLSPACE" or setting == "0x001E": obj = parseCrawlSpaceData(setting, sceneData, posDataName, index, hexOrDecInt(count), objName, orderIndex) else: - obj = parseCamPosData(setting, sceneData, posDataName, index, objName, orderIndex) + obj = parseCamPosData(setting, sceneData, posDataName, index, objName, orderIndex, is_actor_cs) parentObject(sceneObj, obj) orderIndex += 1 -def parseCamPosData(setting: str, sceneData: str, posDataName: str, index: int, objName: str, orderIndex: str): +def parseCamPosData( + setting: str, sceneData: str, posDataName: str, index: int, objName: str, orderIndex: str, is_actor_cs: bool +): camera = bpy.data.cameras.new("Camera") camObj = bpy.data.objects.new(objName, camera) bpy.context.scene.collection.objects.link(camObj) camProp = camObj.ootCameraPositionProperty setCustomProperty(camProp, get_game_prop_name("cam_setting_type"), setting, ootEnumCameraSType, "camSTypeCustom") - camProp.hasPositionData = posDataName != "NULL" and posDataName != "0" + + if is_actor_cs: + camProp.is_actor_cs_cam = camProp.hasPositionData = True + else: + camProp.hasPositionData = posDataName != "NULL" and posDataName != "0" + camProp.index = orderIndex # name is important for alphabetical ordering @@ -116,6 +128,8 @@ def parseCamPosData(setting: str, sceneData: str, posDataName: str, index: int, fovValue = int.from_bytes(fovValue.to_bytes(2, "big", signed=fovValue < 0x8000), "big", signed=True) if fovValue > 360: fovValue *= 0.01 # see CAM_DATA_SCALED() macro + elif fovValue == -1: + fovValue = 60 # TODO: set the fov value depending on each camera setting camObj.data.angle = math.radians(fovValue) return camObj diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index be5312bb4..e437f423e 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -10,6 +10,7 @@ from ..model_classes import OOTF3DContext from ..scene.properties import Z64_SceneHeaderProperty, Z64_LightProperty from ..animated_mats.properties import enum_anim_mat_type +from ..actor_cutscene.properties import enum_cs_cam_id, enum_end_cam, enum_end_sfx, enum_hud_visibility from ..utility import ( getEvalParams, setCustomProperty, @@ -18,13 +19,14 @@ get_cs_index_start, get_game_prop_name, getObjectList, + getEnumIndex, ) from .constants import headerNames from .utility import getDataMatch, stripName, get_new_empty_object from .classes import SharedSceneData from .room_header import parseRoomCommands from .actor import parseTransActorList, parseSpawnList, parseEntranceList -from .scene_collision import parseCollisionHeader +from .scene_collision import parseCollisionHeader, parseCamDataList from .scene_pathways import parsePathList from ..constants import ( @@ -426,6 +428,67 @@ def parse_animated_material(scene_obj: Object, header_index: int, scene_data: st cycle_entry.texture = texture_ptr +def set_actor_cs_property(value: str, enum: tuple[str, str, str], data, prop_name: str, is_cam: bool = False): + enum_index = None + + try: + if is_cam: + # since the value is negative it will simply go backwards in the list + enum_index = int(value, base=0) + + # use camera obj pointer mode if the value is not negative + if enum_index >= 0: + enum_index = 1 + else: + # accounting for custom value + enum_index = int(value, base=0) + 1 + except: + enum_index = getEnumIndex(enum, value) + + if enum_index is not None: + setattr(data, prop_name, enum[enum_index][0]) + else: + setattr(data, prop_name, "Custom") + setattr(data, f"{prop_name}_custom", value) + + +def parse_actor_cs(scene_obj: Object, header_index: int, scene_data: str, list_name: str): + data_match = getDataMatch(scene_data, list_name, "CutsceneEntry", "actor cs") + actor_cs_data = data_match.strip().replace(" ", "").replace("{", "").replace("}", "").split("\n") + + # TODO: implement alt headers + if header_index != 0: + return + + actor_cs_obj = get_new_empty_object("Actor Cutscene") + actor_cs_obj.ootEmptyType = "Actor Cutscene" + parentObject(scene_obj, actor_cs_obj) + + props = actor_cs_obj.z64_actor_cs_property + + for data in actor_cs_data: + split = data.removesuffix(",").split(",") + + new_entry = props.entries.add() + new_entry.priority = int(split[0], base=0) + new_entry.length = int(split[1], base=0) + set_actor_cs_property(split[2], enum_cs_cam_id, new_entry, "cs_cam_id", True) + new_entry.script_index = int(split[3], base=0) + new_entry.additional_cs_id = int(split[4], base=0) + set_actor_cs_property(split[5], enum_end_sfx, new_entry, "end_sfx") + new_entry.custom_value = split[6] + set_actor_cs_property(split[7], enum_hud_visibility, new_entry, "hud_visibility") + set_actor_cs_property(split[8], enum_end_cam, new_entry, "end_cam") + new_entry.letterbox_size = int(split[9], base=0) + + if new_entry.cs_cam_id == "Camera": + for obj in bpy.data.objects: + cam_props = obj.ootCameraPositionProperty + if obj.type == "CAMERA" and cam_props.is_actor_cs_cam and cam_props.index == int(split[2], base=0): + new_entry.cs_cam_obj = obj + break + + def get_enum_id_from_index(enum_key: str, index: int): if is_game_oot(): return oot_data.enumData.enumByKey[enum_key].item_by_index[index].id @@ -465,6 +528,7 @@ def parseSceneCommands( entranceList = None altHeadersListName = None chest_map_data_args = None + actor_cs_data_args = None for commandMatch in re.finditer(rf"(SCENE\_CMD\_[a-zA-Z0-9\_]*)\s*\((.*?)\)\s*,", commands, flags=re.DOTALL): command = commandMatch.group(1) @@ -590,12 +654,24 @@ def parseSceneCommands( chest_map_data_args = args elif sharedSceneData.includeAnimatedMats and command == "SCENE_CMD_ANIMATED_MATERIAL_LIST": parse_animated_material(sceneObj, headerIndex, sceneData, stripName(args[0])) + elif sharedSceneData.includeActorCs: + if command in {"SCENE_CMD_ACTOR_CUTSCENE_LIST", "SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST"}: + if command == "SCENE_CMD_ACTOR_CUTSCENE_LIST": + # Delay until cameras are processed, if used + actor_cs_data_args = args + else: + # TODO: implement alt headers + if headerIndex == 0: + parseCamDataList(sceneObj, stripName(args[1]), sceneData, True) if sharedSceneData.includeActors and chest_map_data_args is not None: parse_mm_map_data_chest( roomObjs, sceneHeader, sceneData, int(chest_map_data_args[0], base=0), stripName(chest_map_data_args[1]) ) + if sharedSceneData.includeActorCs and actor_cs_data_args is not None: + parse_actor_cs(sceneObj, headerIndex, sceneData, stripName(actor_cs_data_args[1])) + if altHeadersListName is not None: parseAlternateSceneHeaders(sceneObj, roomObjs, sceneData, altHeadersListName, f3dContext, sharedSceneData) diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 5e3f8785d..2516b8361 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -7,6 +7,7 @@ from .collision.properties import OOTWaterBoxProperty from .cutscene.properties import OOTCutsceneProperty from .animated_mats.properties import Z64_AnimatedMaterialProperty +from .actor_cutscene.properties import Z64_ActorCutsceneProperty from .cutscene.motion.properties import ( OOTCutsceneMotionProperty, CutsceneCmdActorCueListProperty, @@ -39,6 +40,7 @@ ("CS Player Cue Preview", "CS Player Cue Preview", "CS Player Cue Preview"), ("CS Dummy Cue", "CS Dummy Cue", "CS Dummy Cue"), ("Animated Materials", "Animated Materials", "Animated Materials"), + ("Actor Cutscene", "Actor Cutscene", "Actor Cutscene"), # ('Camera Volume', 'Camera Volume', 'Camera Volume'), ] @@ -187,6 +189,10 @@ def draw(self, context): anim_props: Z64_AnimatedMaterialProperty = obj.z64_anim_mats_property anim_props.draw_props(box, obj) + elif obj.ootEmptyType == "Actor Cutscene": + actor_cs_props: Z64_ActorCutsceneProperty = obj.z64_actor_cs_property + actor_cs_props.draw_props(box, obj, altSceneProp) + elif obj.ootEmptyType in [ "CS Actor Cue List", "CS Player Cue List", diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 85569571d..6f6a6a6ac 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -705,6 +705,7 @@ class Z64_ImportSceneSettingsProperty(PropertyGroup): includeWaterBoxes: BoolProperty(name="Water Boxes", default=True) includeCutscenes: BoolProperty(name="Cutscenes", default=False) includeAnimatedMats: BoolProperty(name="Animated Materials", default=False) + includeActorCs: BoolProperty(name="Actor Cutscenes", default=False) option: EnumProperty(items=ootEnumSceneID, default="SCENE_DEKU_TREE") mm_option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") @@ -730,6 +731,7 @@ def draw_props(self, layout: UILayout, sceneOption: str): includeButtons4 = col.row(align=True) includeButtons4.prop(self, "includeAnimatedMats", toggle=1) + includeButtons4.prop(self, "includeActorCs", toggle=1) col.prop(self, "isCustomDest") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index d9bea9929..3187a1040 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -803,6 +803,10 @@ def getCollection(objName, collectionType, subIndex: int, collection_index: int collection = obj.z64_anim_mats_property.items[subIndex].entries[collection_index].tex_scroll_params.entries elif collectionType == "Animated Mat. Cycle": collection = obj.z64_anim_mats_property.items[subIndex].entries[collection_index].tex_cycle_params.keyframes + elif collectionType == "Actor CS": + collection = obj.z64_actor_cs_property.entries + elif collectionType == "Actor CS Headers": + collection = obj.z64_actor_cs_property.header_settings.cutsceneHeaders elif collectionType == "Curve": collection = obj.ootSplineProperty.headerSettings.cutsceneHeaders elif collectionType.startswith("CSHdr."): @@ -1262,3 +1266,12 @@ def getObjectList( ret.append(obj) ret.sort(key=lambda o: o.name) return ret + + +def get_list_tab_text(base_text: str, list_length: int): + if list_length > 0: + items_amount = f"{list_length} Item{'s' if list_length > 1 else ''}" + else: + items_amount = "Empty" + + return f"{base_text} ({items_amount})" From f92a47bbfc9437c4548d1bd566baab4e07afc80a Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:09:37 +0100 Subject: [PATCH 037/126] update readme and introduce "mm features" checkbox for oot --- __init__.py | 4 +- fast64_internal/utility.py | 8 +- fast64_internal/z64/README.md | 119 +++++++++++------- fast64_internal/z64/__init__.py | 5 +- fast64_internal/z64/actor/properties.py | 5 +- fast64_internal/z64/collision/properties.py | 7 +- fast64_internal/z64/cutscene/panels.py | 6 +- .../z64/exporter/collision/camera.py | 4 +- .../z64/exporter/decomp_edit/scene_table.py | 6 +- fast64_internal/z64/exporter/room/__init__.py | 4 +- fast64_internal/z64/exporter/room/header.py | 15 ++- .../z64/exporter/scene/__init__.py | 12 +- fast64_internal/z64/exporter/scene/actors.py | 6 +- .../z64/exporter/scene/animated_mats.py | 8 +- fast64_internal/z64/exporter/scene/general.py | 22 ++-- fast64_internal/z64/exporter/scene/header.py | 16 +-- fast64_internal/z64/file_settings.py | 5 +- .../z64/importer/scene_collision.py | 3 +- fast64_internal/z64/props_panel_main.py | 4 +- fast64_internal/z64/room/properties.py | 8 +- fast64_internal/z64/scene/properties.py | 37 +++--- fast64_internal/z64/spline/properties.py | 4 +- fast64_internal/z64/utility.py | 9 +- 23 files changed, 190 insertions(+), 127 deletions(-) diff --git a/__init__.py b/__init__.py index a1186ce55..c57ad1954 100644 --- a/__init__.py +++ b/__init__.py @@ -22,7 +22,7 @@ from .fast64_internal.z64 import OOT_Properties, oot_register, oot_unregister from .fast64_internal.z64.constants import oot_world_defaults from .fast64_internal.z64.props_panel_main import OOT_ObjectProperties -from .fast64_internal.z64.utility import getObjectList +from .fast64_internal.z64.utility import getObjectList, get_cs_index_start from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister @@ -412,7 +412,7 @@ def gameEditorUpdate(scene: bpy.types.Scene, _context): # reset `currentCutsceneIndex` when switching games if scene.gameEditorMode in {"OOT", "MM"}: - cs_index_start = 4 if scene.gameEditorMode == "OOT" else 1 + cs_index_start = get_cs_index_start() for scene_obj in bpy.data.objects: scene_obj.ootAlternateSceneHeaders.currentCutsceneIndex = cs_index_start diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index ebbf360c3..cae829241 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -1666,6 +1666,9 @@ def lightDataToObj(lightData): def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): + # circular import fix + from .z64.utility import get_cs_index_start, is_game_oot + # This should be in oot_utility.py, but it is needed in f3d_material.py # which creates a circular import. The real problem is that the F3D render # settings stuff should be in a place which can import both SM64 and OoT @@ -1675,12 +1678,11 @@ def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): target = "Room" if isRoom else "Scene" altHeaders = getattr(parent, "ootAlternate" + target + "Headers") - is_game_oot = bpy.context.scene.gameEditorMode == "OOT" - cs_index_start = 4 if is_game_oot else 1 + cs_index_start = get_cs_index_start() if idx == 0: return getattr(parent, "oot" + target + "Header") - elif is_game_oot: + elif is_game_oot(): if 1 <= idx <= (cs_index_start - 1): if idx == 1: ret = altHeaders.childNightHeader diff --git a/fast64_internal/z64/README.md b/fast64_internal/z64/README.md index abc3f3386..2c1223322 100644 --- a/fast64_internal/z64/README.md +++ b/fast64_internal/z64/README.md @@ -1,4 +1,4 @@ -# Ocarina Of Time +# Ocarina Of Time and Majora's Mask ## Table of Contents 1. [Getting Started](#getting-started) @@ -12,20 +12,23 @@ 9. [Custom Link Process](#custom-link-process) 10. [Custom Skeleton Mesh Process](#custom-skeleton-mesh-process) 11. [Cutscenes](#cutscenes) +12. [Actor Cutscenes](#actor-cutscenes) ### Getting Started -1. In the 3D view properties sidebar (default hotkey to show this is `n` in the viewport), go to the ``Fast64`` tab, then ``Fast64 Global Settings`` and set ``Game`` to ``OOT``. -2. Switch to the ``OOT`` tab. In ``OOT File Settings``, set your decomp path to the path of your [HackerOoT (recommended)](https://github.com/HackerN64/HackerOoT) or [OoT Decomp](https://github.com/zeldaret/oot/) repository on disk. Check `Enable HackerOoT Features` if using HackerOoT. -3. In ``OOT Tools``, click `Add Scene` to create a basic scene. +1. In the 3D view properties sidebar (default hotkey to show this is `n` in the viewport), go to the `Fast64` tab, then `Fast64 Global Settings` and set `Game` to `OOT` or `MM`. +2. Switch to the `OOT/MM` tab. In `Workspace Settings`, set your decomp path to the path of your [HackerOoT (recommended)](https://github.com/HackerN64/HackerOoT), [OoT Decomp](https://github.com/zeldaret/oot/) or [MM](https://github.com/zeldaret/mm) repository on disk. Check `Enable HackerOoT Features` if using HackerOoT. +3. In `Tools`, click `Add Scene` to create a basic scene. 4. Press `a` so that everything is selected, then click `Clear Transform`. -5. In ``OOT Scene Exporter`` you can choose the scene to replace or add. Some scenes have some hardcoded things that will cause them to break, so choose something like ``Market Entrance (Child Day) (Entra)``. -- To add a custom scene choose ``Custom`` in the scene search box, then choose in which folder you want to export the scene and which name you want it to be (note that Fast64 will force the scene name to be lower-case). -- Enable ``Export as Single File`` if you want to have your scene in the same format as the other ones in decomp. -6. Make sure you selected the right scene in ``Scene Object`` then click "Export Scene" to export it. When you click ``Add Scene`` this is set automatically. +5. In `Scenes` you can choose the scene to replace or add. Some scenes have some hardcoded things that will cause them to break, so choose something like `Market Entrance (Child Day) (Entra)`. +- To add a custom scene choose `Custom` in the scene search box, then choose in which folder you want to export the scene and which name you want it to be (note that Fast64 will force the scene name to be lower-case). +- Enable `Export as Single File` if you want to have your scene in the same format as the other ones in decomp. +6. Make sure you selected the right scene in `Scene Object` then click "Export Scene" to export it. When you click `Add Scene` this is set automatically. 7. Compile and run the game. -8. (Optional) In the ``View`` tab you may want to increase the ``Clip End`` value. +8. (Optional) In the `View` tab you may want to increase the `Clip End` value. 9. Note: You can read [this code](https://github.com/Dragorn421/oot/tree/mod_base_for_mods) to take a glance at what you can do for quality of life for testing. +Note: You can use features from MM with OoT by enabling the MM features (see workspace settings when the game is set to `OOT`). + ### Scene Overview In Blender, the "empty" object type is used to define different types of OOT data, including scenes and rooms. For scenes, there must be a specific parenting hierarchy: @@ -43,30 +46,42 @@ Read the "Getting Started" section for information on scene exporting. ### Actors To add an actor you need to create a new empty object in Blender, the shape doesn't matter. -When the empty object is created you can set the ``Actor`` object type in the ``Object Properties`` panel. +When the empty object is created you can set the `Actor` object type in the `Object Properties` panel. -To add actors to a scene, create a new Empty and parent it to a Room, otherwise they will not be exported in the room C code. Then in the Object Properties panel select ``Actor`` as the Object Type. Use the ``Select Actor ID`` button to choose an actor, and then set the Actor Parameter value as desired (see the list of Actor Parameters below). +To add actors to a scene, create a new Empty and parent it to a Room, otherwise they will not be exported in the room C code. Then in the Object Properties panel select `Actor` as the Object Type. Use the `Select Actor ID` button to choose an actor, and then set the Actor Parameter value as desired (see the list of Actor Parameters below). Finally, every actors you are using needs their assets. In OoT they're called "Objects", if an actor is missing an object the code will not spawn the actor. To do this select the Room that your actor is parented to, select the "Objects" tab in its Object Properties window, and click "Add Item". Then "Search Object ID" to find the actor object you need. For example, if adding a Deku Baba actor (EN_DEKUBABA) you need to add the "Dekubaba" object to the Room's object dependencies. Note that the object list must not contain more than 15 items. #### Actor Parameters -Actor parameters can be found at https://wiki.cloudmodding.com/oot/Actor_List_(Variables). This documentation is NOT 100% accurate, you can get more informations with the OoT Decomp. Look for ``rot.z`` and ``params`` in the actor you want, some actors may use ``rot.x`` and ``rot.y``. +Actor parameters can be found at https://wiki.cloudmodding.com/oot/Actor_List_(Variables). This documentation is NOT 100% accurate, you can get more informations with the OoT Decomp. Look for `rot.z` and `params` in the actor you want, some actors may use `rot.x` and `rot.y`. ### Exits -The debug menu scene select can be found at ``SceneSelectEntry sScenes[]`` in ``src/overlays/gamestates/ovl_select/z_select.c``. -The last field of a ``SceneSelectEntry`` is the index into ``gEntranceTable`` (found in ``src/code/z_scene_table.c``). +The entrance table can be found in `tables/entrance_table.h`. For MM search `EntranceSceneId` in `include/z64scene.h`. All exits are basically an index into this table. Due to the way it works it makes it difficult to add/remove entries without breaking everything. For now the user will have to manually manage this table. For more info check out https://wiki.cloudmodding.com/oot/Entrance_Table. ### Scene Draw Configuration And Dynamic Material Properties -The scene object has a property called ``Draw Config``. This is an index into ``sSceneDrawHandlers`` in ``src/code/z_scene_table.c``. -Each function in this table will load certain Gfx commands such as scrolling textures or setting color registers into the beginning of a RAM segment using ``gsSPSegment()``. In Blender, in the material properties window you can choose which commands are called at the beginning of the material drawing. For example, to get animated water you need to use segment 9 with the draw config 19 (0x13). +The scene object has a property called `Draw Config`. This is an index into `sSceneDrawHandlers` in `src/code/z_scene_table.c`. +Each function in this table will load certain Gfx commands such as scrolling textures or setting color registers into the beginning of a RAM segment using `gsSPSegment()`. In Blender, in the material properties window you can choose which commands are called at the beginning of the material drawing. For example, to get animated water you need to use segment 9 with the draw config 19 (0x13). ![](/images/oot_dynamic_material.png) Note that there are different segments loaded between the OPA (opaque) and XLU (transparent) draw layers. -Additionally, for functions like ``Gfx_TexScroll()``, the x,y inputs are pre-shifted by <<2. For example, a % 128 means a repeat of the texture every 32 pixels. +Additionally, for functions like `Gfx_TexScroll()`, the x,y inputs are pre-shifted by <<2. For example, a % 128 means a repeat of the texture every 32 pixels. + +## Animated Materials + +On Majora's Mask the draw config system changed. Now you only have a few configs available. To use animated materials, you need to change the draw config to "material animated" and add an empty object with the type "Animated Materials". + +The "Animated Materials List" element represents one `AnimatedMaterial` array. You can set the header index at this level. Then you can add elements in the first sub-list ("Animated Materials ([item count])"). You need to select the segment number corresponding to the one your material is using, for instance for a water-like material, if you pick segment 0x0A/10 in the dynamic material properties, you'll need to choose 10 for the "Segment Number" value (and choose "Draw Two Texture Scroll" for the draw handler type). + +Each Draw Handler Type requires elements in a list of the current "Animated Materials" item: +- For texture scroll types, each element represent one texture scroll. This means for "Draw Two Texture Scroll" you will need two entries here. To create a water effect, you need to set two segments and add two items, one for each segment, with two "tex scroll" elements for each items. The width and height must match the width and height of the texture you picked on the material. +- For "color" types, you need to set the total frame count and add keyframes. Each keyframe requires a primitive color and an environment color (and the "LOD Fraction"). This is also where you set the frame where this entry starts, this value must not exceed the total frame count. +- For "cycle" types, it's very similar to color types, except you need to choose a texture symbol instead of a color. Note: this is a GIF-like system. + +You can choose between exporting with the scene or exporting with an actor with the "Export To" enum. (Default: "Scene") ### Collision Collision properties are found underneath the material properties. Water boxes and collision properties will have references the properties "Camera", "Lighting", and "Exit", which reference the indices of the scene cameras, scene light list, and scene exit list respectively. If you want separate visual/collision geometry, you can set per mesh object "Ignore Collision" or "Ignore Render" in object inspector window. @@ -142,12 +157,12 @@ For more informations about cutscenes [click here](cutscene_docs.md) **Creating the cutscene itself:** -1. Start with using the ``Add Cutscene`` button from the OOT Panel. Name it ``Cutscene.YOUR_CS_NAME``, ``YOUR_CS_NAME`` being the name of your choice, it can be something like: ``Cutscene.fireTempleIntroCS``. Note that this object can't be parented to any object, also this will automatically create a new camera and it will also set the Blender scene's active camera to this one. -2. Select the scene where you want to add the cutscene, and in the object properties go in the ``Cutscene`` tab then enable ``Write Cutscene``. In ``Data`` select ``Object`` and in ``Cutscene Object`` select the cutscene empty object you just created. -3. Now you can create the camera shot. The ``Create Camera Shot`` button from the cutscene object's properties panel will add a basic shot with 4 bones that you can edit. To have a better idea of the position/angle of one point of the shot, you can change the display of the armature in the ``Object Data Properties`` panel (select the shot object first), choose ``Octahedral`` in ``Viewport Display`` then ``Display As``. -4. The first and last bone of the shot won't be actual camera points, it defines the start and the end of a camera shot, this means a basic shot will only have 2 actual camera points. Either duplicate (``SHIFT+D``) or add a new bone to add more camera points. Note that these points will be exported in the order you can see in the view layer. -5. You can edit the position and rotation of each bone in the ``Edit Mode`` after selecting the shot object. The "tail" (less large point) of a bone is the direction (the "look-at", or AT), and "head" (larger point) is the origin (the "eye"). -7. When you're done with your cutscene, exporting the scene will also export the camera shot and actor cue data. If you don't want to re-export the scene everytime, select the cutscene object you want to export and use ``Export Cutscene`` from ``OOT Cutscene Exporter`` in the OOT panel. In the ``File`` field, you can choose the scene of your choice (note that it can export into actors too). You can toggle the usage of decomp's names and macros with the ``Use Decomp for Export`` checkbox, you can also choose to insert the motion data in an existing cutscene (it will create a new array if it can't find it, it's based on the name of the object you selected). This is done by toggling the ``Export Motion Data Only`` checkbox. +1. Start with using the `Add Cutscene` button from the OOT Panel. Name it `Cutscene.YOUR_CS_NAME`, `YOUR_CS_NAME` being the name of your choice, it can be something like: `Cutscene.fireTempleIntroCS`. Note that this object can't be parented to any object, also this will automatically create a new camera and it will also set the Blender scene's active camera to this one. +2. Select the scene where you want to add the cutscene, and in the object properties go in the `Cutscene` tab then enable `Write Cutscene`. In `Data` select `Object` and in `Cutscene Object` select the cutscene empty object you just created. +3. Now you can create the camera shot. The `Create Camera Shot` button from the cutscene object's properties panel will add a basic shot with 4 bones that you can edit. To have a better idea of the position/angle of one point of the shot, you can change the display of the armature in the `Object Data Properties` panel (select the shot object first), choose `Octahedral` in `Viewport Display` then `Display As`. +4. The first and last bone of the shot won't be actual camera points, it defines the start and the end of a camera shot, this means a basic shot will only have 2 actual camera points. Either duplicate (`SHIFT+D`) or add a new bone to add more camera points. Note that these points will be exported in the order you can see in the view layer. +5. You can edit the position and rotation of each bone in the `Edit Mode` after selecting the shot object. The "tail" (less large point) of a bone is the direction (the "look-at", or AT), and "head" (larger point) is the origin (the "eye"). +7. When you're done with your cutscene, exporting the scene will also export the camera shot and actor cue data. If you don't want to re-export the scene everytime, select the cutscene object you want to export and use `Export Cutscene` from `OOT Cutscene Exporter` in the OOT panel. In the `File` field, you can choose the scene of your choice (note that it can export into actors too). You can toggle the usage of decomp's names and macros with the `Use Decomp for Export` checkbox, you can also choose to insert the motion data in an existing cutscene (it will create a new array if it can't find it, it's based on the name of the object you selected). This is done by toggling the `Export Motion Data Only` checkbox. 8. Compile the game.
@@ -160,30 +175,30 @@ For more informations about cutscenes [click here](cutscene_docs.md) To be able to actually watch your cutscene you need to have a way to trigger it, this can be done by an actor (for instance) or using the entrance cutscene table. This guide will be explaining how to use an entrance. -1. Open ``src/code/z_demo.c`` and add an ``#include`` with the path of the file containing your cutscene. -2. Add an entry at the end of ``EntranceCutscene sEntranceCutsceneTable[]``, the format is: -``{ ENTRANCE_NUMBER, AGE_RESTRICTION, FLAG, SEGMENT_ADDRESS }`` -- ``ENTRANCE_NUMBER`` is the entrance index in ``gEntranceTable`` -- ``AGE_RESTRICTION`` defines if you want to play your cutscene only as child (set it to 1), as adult (set it to 0) or both (set it to 2) -- ``FLAG`` is the ``event_chk_inf`` flag that will prevent playing the cutscene everytime, you can use something unused like ``0x0F`` (https://wiki.cloudmodding.com/oot/Save_Format#event_chk_inf for more informations) -- ``SEGMENT_ADDRESS`` is the important part. This is the memory address where your cutscene is located. Using the ``#include`` will allow you to use the name of the array containing the cutscene commands in the file you exported you're cutscene, if you named the cutscene object ``Cutscene.YOUR_CS_NAME`` then this array will be named ``YOUR_CS_NAME``, use that name for the segment address. -3. Example with: ``{ ENTR_SPOT00_3, 2, EVENTCHKINF_A0, gHyruleFieldIntroCs },`` -- ``ENTR_SPOT00_3`` is the Hyrule Field entrance from Lost Woods, see ``entrance_table.h`` to view/add entrances -- ``2`` means this cutscene can be watched as child AND as adult -- ``EVENTCHKINF_A0`` is the flag set in the ``event_chk_inf`` table, this is a macro but you can use raw hex: ``0xA0`` -- ``gHyruleFieldIntroCs`` is the name of the array with the cutscene commands, as defined in ``extracted/VERSION/assets/scenes/overworld/spot00_scene.c``, ``CutsceneData gHyruleFieldIntroCs[]`` -4. Compile the game again and use the entrance you chose for ``sEntranceCutsceneTable`` and your cutscene should play. +1. Open `src/code/z_demo.c` and add an `#include` with the path of the file containing your cutscene. +2. Add an entry at the end of `EntranceCutscene sEntranceCutsceneTable[]`, the format is: +`{ ENTRANCE_NUMBER, AGE_RESTRICTION, FLAG, SEGMENT_ADDRESS }` +- `ENTRANCE_NUMBER` is the entrance index in `gEntranceTable` +- `AGE_RESTRICTION` defines if you want to play your cutscene only as child (set it to 1), as adult (set it to 0) or both (set it to 2) +- `FLAG` is the `event_chk_inf` flag that will prevent playing the cutscene everytime, you can use something unused like `0x0F` (https://wiki.cloudmodding.com/oot/Save_Format#event_chk_inf for more informations) +- `SEGMENT_ADDRESS` is the important part. This is the memory address where your cutscene is located. Using the `#include` will allow you to use the name of the array containing the cutscene commands in the file you exported you're cutscene, if you named the cutscene object `Cutscene.YOUR_CS_NAME` then this array will be named `YOUR_CS_NAME`, use that name for the segment address. +3. Example with: `{ ENTR_SPOT00_3, 2, EVENTCHKINF_A0, gHyruleFieldIntroCs },` +- `ENTR_SPOT00_3` is the Hyrule Field entrance from Lost Woods, see `entrance_table.h` to view/add entrances +- `2` means this cutscene can be watched as child AND as adult +- `EVENTCHKINF_A0` is the flag set in the `event_chk_inf` table, this is a macro but you can use raw hex: `0xA0` +- `gHyruleFieldIntroCs` is the name of the array with the cutscene commands, as defined in `extracted/VERSION/assets/scenes/overworld/spot00_scene.c`, `CutsceneData gHyruleFieldIntroCs[]` +4. Compile the game again and use the entrance you chose for `sEntranceCutsceneTable` and your cutscene should play. Alternatively, you can use the map select to watch your cutscene, though note that this won't make it watchable during normal gameplay: -1. Open ``src/overlays/gamestates/ovl_select/z_select.c`` -2. Either edit or add an entry inside ``SceneSelectEntry sScenes[]``, for instance: ``{ "My Scene", MapSelect_LoadGame, ENTR_MYSCENE_0 },`` (note that the entrance used is the first of the block you need to have for the scene) -3. Compile the game, you may or may not need to run ``make clean`` first if you edited the entrance table -4. Get on the map select then scroll until you see your new entry (in the previous example is will be called "My Scene") then press R to change the header, on the vanilla map select the first cutscene header will be called ``デモ00``, on HackerOoT it will be ``Cutscene 0`` then press A to start the cutscene. +1. Open `src/overlays/gamestates/ovl_select/z_select.c` +2. Either edit or add an entry inside `SceneSelectEntry sScenes[]`, for instance: `{ "My Scene", MapSelect_LoadGame, ENTR_MYSCENE_0 },` (note that the entrance used is the first of the block you need to have for the scene) +3. Compile the game, you may or may not need to run `make clean` first if you edited the entrance table +4. Get on the map select then scroll until you see your new entry (in the previous example is will be called "My Scene") then press R to change the header, on the vanilla map select the first cutscene header will be called `デモ00`, on HackerOoT it will be `Cutscene 0` then press A to start the cutscene. -Note that you can have the actual address of your cutscene if you use ``sym_info.py`` from decomp. Example with ``gHyruleFieldIntroCs``: -- Command: ``./sym_info.py gHyruleFieldIntroCs`` -- Result: ``Symbol gHyruleFieldIntroCs (RAM: 0x02013AA0, ROM: 0x27E9AA0, build/assets/scenes/overworld/spot00/spot00_scene.o)`` +Note that you can have the actual address of your cutscene if you use `sym_info.py` from decomp. Example with `gHyruleFieldIntroCs`: +- Command: `./sym_info.py gHyruleFieldIntroCs` +- Result: `Symbol gHyruleFieldIntroCs (RAM: 0x02013AA0, ROM: 0x27E9AA0, build/assets/scenes/overworld/spot00/spot00_scene.o)` If you have a softlock in-game then you probably did something wrong when creating the cutscene. Make sure you set up the bones properly. The softlock means the game is playing a cutscene but it's probably reading wrong data. Make sure the cutscene is exported, if it's not export it again. @@ -194,3 +209,21 @@ If the camera preview in Blender isn't following where you have the bones or if 2. If you moved / rotated / etc. one of the camera shots / armatures in object mode, this transformation will be ignored. You can fix this by selecting the shot / armature in object mode and clicking Object > Apply > All Transforms. That will convert the transform to actual changed positions for each bone. If the game crashes check the transitions if you use the transition command (check both the ones from the entrance table and your cutscene script), also it will crash if you try to use the map select without having a 5th entrance (or more depending on the number of cutscenes you have) in the group for your scene. + +### Actor Cutscenes + +To get started, add an empty object with the "Actor Cutscene" type then add entries in the list. + +The informations required are the following: +- `Priority`: how important the cutscene is, lower value means higher priority. +- `Length`: the length of the cutscene, only useful when you're not using a cutscene script. Can be -1 if using a script. +- `CS Cam ID`: the cutscene camera type. **IMPORTANT**: because of how `Play_AssignPlayerCsIdsFromScene` works, you need to match the order of the `PlayerCsId` enum (see `include/z64cutscene.h`) otherwise it won't work properly. Can be -1 if using a script. +- `Script Index`: the index into the `CutsceneScriptEntry` array. **IMPORTANT**: this takes the priority over `CS Cam ID`, it's very important you leave this value to -1 if you don't want to use a script. +- `Additional CS ID`: another index into `CutsceneEntry`, some actors might require using this (the actor responsible for "dawn/night of the X day", `en_test4`, requires this for instance). +- `End Sound Effect`: the sound effect to play when the cutscene ends. +- `Custom Value`: 0 - 99: actor-specific custom value. 100+: spawn. 255: none +- `HUD Visibility`: which elements of the HUD to hide. +- `End Cam`: the camera's behavior when the cutscene ends. +- `Letterbox Size`: the size of the letterbox (the two black rectangles at the top and the bottom of the screen) + +If you want to use your own camera, add a camera object and enable "Is Actor CS Camera". Set the index, this is NOT the same order as normal scene cameras so choose 0 for the first actor cutscene camera you add. Finally, back in the actor cutscene entry, choose "Camera Object" as the value of `CS Cam ID` and select the camera you've just created. For the camera setting simply change that from the camera object you added. diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 39afd0428..916f72171 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -103,7 +103,8 @@ class OOT_Properties(bpy.types.PropertyGroup): collisionExportSettings: bpy.props.PointerProperty(type=OOTCollisionExportSettings) oot_version: bpy.props.EnumProperty(name="OoT Version", items=oot_versions_items, default="gc-eu-mq-dbg") mm_version: bpy.props.EnumProperty(name="OoT Version", items=mm_versions_items, default="n64-us") - oot_version_custom: bpy.props.StringProperty(name="Custom Version") + version_custom: bpy.props.StringProperty(name="Custom Version") + mm_features: bpy.props.BoolProperty(name="Enable MM Features", default=False) def get_extracted_path(self): version = self.oot_version if is_game_oot() else self.mm_version @@ -111,7 +112,7 @@ def get_extracted_path(self): if version == "legacy": return "." else: - return f"extracted/{version if version != 'Custom' else self.oot_version_custom}" + return f"extracted/{version if version != 'Custom' else self.version_custom}" useDecompFeatures: bpy.props.BoolProperty( name="Use decomp for export", description="Use names and macros from decomp when exporting", default=True diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index fc97e383c..d7a3f301b 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -16,6 +16,7 @@ drawEnumWithCustom, get_game_prop_name, get_cs_index_start, + is_oot_features, is_game_oot, get_game_enum, ) @@ -201,7 +202,7 @@ def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderPrope prop_split(actorIDBox, self, "actorParam", "Actor Parameter") rot_box = actorIDBox.box() - prop_text = "Override Rotation (ignore Blender rot)" if is_game_oot() else "Use Rotation Flags" + prop_text = "Override Rotation (ignore Blender rot)" if is_oot_features() else "Use Rotation Flags" rot_box.prop(self, "rotOverride", text=prop_text) if self.rotOverride: prop_split(rot_box, self, "rotOverrideX", "Rot X") @@ -253,7 +254,7 @@ def draw_props( if actor_id == "Custom": prop_split(actorIDBox, self.actor, "actorIDCustom", "") - if not is_game_oot(): + if not is_oot_features(): prop_split(actorIDBox, self, "cutscene_id", "Cutscene ID") prop_split(actorIDBox, self.actor, "actorParam", "Actor Parameter") diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index e0331b5b0..11511a9bc 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -3,7 +3,7 @@ from bpy.types import PropertyGroup, Camera, Object, Material, UILayout from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom, is_game_oot, get_game_prop_name +from ..utility import drawEnumWithCustom, get_game_prop_name from ..constants import ootEnumSceneID from .constants import ( ootEnumFloorSetting, @@ -55,6 +55,7 @@ class OOTCameraPositionProperty(PropertyGroup): camSTypeCustom: StringProperty(default="CAM_SET_NORMAL0") hasPositionData: BoolProperty(default=True, name="Has Position Data") is_actor_cs_cam: BoolProperty(default=False, name="Is Actor CS Camera") + use_setting_default_fov: BoolProperty(name="Use the default FoV from the camera setting", default=False) def draw_props(self, layout: UILayout, cameraObj: Object): drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "", "camSTypeCustom") @@ -64,8 +65,10 @@ def draw_props(self, layout: UILayout, cameraObj: Object): if not self.is_actor_cs_cam: layout.prop(self, "hasPositionData") + layout.prop(self, "use_setting_default_fov") if self.hasPositionData: - prop_split(layout, cameraObj.data, "angle", "Field Of View") + if not self.use_setting_default_fov: + prop_split(layout, cameraObj.data, "angle", "Field Of View") prop_split(layout, self, "bgImageOverrideIndex", "BG Index Override") diff --git a/fast64_internal/z64/cutscene/panels.py b/fast64_internal/z64/cutscene/panels.py index 40f37535e..522e737d3 100644 --- a/fast64_internal/z64/cutscene/panels.py +++ b/fast64_internal/z64/cutscene/panels.py @@ -3,7 +3,7 @@ from bpy.props import BoolProperty from ...utility import prop_split from ...panels import Z64_Panel -from ..utility import is_game_oot +from ..utility import is_oot_features from .operators import OOT_ExportCutscene, OOT_ExportAllCutscenes, OOT_ImportCutscene @@ -27,7 +27,7 @@ def draw(self, context): exportBox = layout.box() exportBox.label(text="Cutscene Exporter") - exportBox.enabled = is_game_oot() + exportBox.enabled = is_oot_features() if not exportBox.enabled: layout.label(text="Export not implemented yet.") @@ -53,7 +53,7 @@ def draw(self, context): importBox = layout.box() importBox.label(text="Cutscene Importer") - importBox.enabled = is_game_oot() + importBox.enabled = is_oot_features() if not importBox.enabled: layout.label(text="Import not implemented yet.") diff --git a/fast64_internal/z64/exporter/collision/camera.py b/fast64_internal/z64/exporter/collision/camera.py index 8acc8d669..f034388be 100644 --- a/fast64_internal/z64/exporter/collision/camera.py +++ b/fast64_internal/z64/exporter/collision/camera.py @@ -131,7 +131,9 @@ def get_camera_info( cam_pos_data[camProp.index] = CameraData( pos, rot, - round(fov * 100 if fov > 3.6 else fov), # see CAM_DATA_SCALED() macro + -1 + if camProp.use_setting_default_fov + else round(fov * 100 if fov > 3.6 else fov), # see CAM_DATA_SCALED() macro cam_obj.ootCameraPositionProperty.bgImageOverrideIndex, ) diff --git a/fast64_internal/z64/exporter/decomp_edit/scene_table.py b/fast64_internal/z64/exporter/decomp_edit/scene_table.py index 2aa6fd0d9..0c818a6f7 100644 --- a/fast64_internal/z64/exporter/decomp_edit/scene_table.py +++ b/fast64_internal/z64/exporter/decomp_edit/scene_table.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile -from ...utility import is_game_oot +from ...utility import is_oot_features, is_game_oot from ...constants import ootEnumSceneID, ootSceneNameToID, mm_enum_scene_id, mm_scene_name_to_id ADDED_SCENES_COMMENT = "// Added scenes" @@ -55,7 +55,7 @@ def from_line(original_line: str): index = original_line.index(macro_start) + len(macro_start) parsed = original_line[index:].removesuffix(")") - if is_game_oot(): + if is_oot_features(): params = parsed.split(", ") assert len(params) == 6 return SceneTableEntry(*params) @@ -88,7 +88,7 @@ def from_scene(scene_name: str, draw_config: str): def to_c(self, index: int): """Returns the entry as C code""" - if is_game_oot(): + if is_oot_features(): return ( f"/* 0x{index:02X} */ " f"DEFINE_SCENE({self.spec_name}, {self.title_card_name}, {self.enum_value}, " diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index 08453ed91..ee55b4ee8 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings -from ...utility import is_game_oot +from ...utility import is_game_oot, get_cs_index_start from ...room.properties import Z64_RoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -82,7 +82,7 @@ def new( transform, i, ) - for i, csHeader in enumerate(altProp.cutsceneHeaders, 4 if is_game_oot() else 1) + for i, csHeader in enumerate(altProp.cutsceneHeaders, get_cs_index_start()) ] hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 2d424e5f4..5252cf661 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData, indent -from ...utility import getObjectList, is_game_oot, getEvalParams, get_game_prop_name +from ...utility import getObjectList, is_oot_features, getEvalParams, get_game_prop_name, is_game_oot from ...constants import oot_data, mm_data from ...room.properties import Z64_RoomHeaderProperty from ..utility import Utility @@ -55,7 +55,8 @@ def new(props: Optional[Z64_RoomHeaderProperty]): if is_game_oot(): disableWarpSongs = props.disableWarpSongs - else: + + if not is_oot_features(): enable_pos_lights = props.enable_pos_lights enable_storm = props.enable_storm @@ -84,16 +85,14 @@ def getCmds(self): showInvisActors = "true" if self.showInvisActors else "false" disableSkybox = "true" if self.disableSky else "false" disableSunMoon = "true" if self.disableSunMoon else "false" + disableWarpSongs = "true" if self.disableWarpSongs else "false" - if is_game_oot(): - disableWarpSongs = "true" if self.disableWarpSongs else "false" + if is_oot_features(): roomBehaviorArgs = f"{self.roomBehavior}, {self.playerIdleType}, {showInvisActors}, {disableWarpSongs}" else: enable_pos_lights = "true" if self.enable_pos_lights else "false" enable_storm = "true" if self.enable_storm else "false" - roomBehaviorArgs = ( - f"{self.roomBehavior}, {self.playerIdleType}, {showInvisActors}, 0, {enable_pos_lights}, {enable_storm}" - ) + roomBehaviorArgs = f"{self.roomBehavior}, {self.playerIdleType}, {showInvisActors}, {disableWarpSongs}, {enable_pos_lights}, {enable_storm}" cmdList = [ f"SCENE_CMD_ECHO_SETTINGS({self.echo})", @@ -197,7 +196,7 @@ def new( else: actor.id = actor_id - if is_game_oot(): + if is_oot_features(): if actorProp.rotOverride: actor.rot = ", ".join([actorProp.rotOverrideX, actorProp.rotOverrideY, actorProp.rotOverrideZ]) else: diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 9e9d847ae..e09a5e330 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -6,7 +6,7 @@ from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import Z64_SceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter -from ...utility import is_game_oot, get_cs_index_start +from ...utility import is_oot_features, get_cs_index_start, is_game_oot from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -60,7 +60,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex altHeader.cutscenes = [ SceneHeader.new(f"{name}_header{i:02}", csHeader, sceneObj, transform, i, useMacros) - for i, csHeader in enumerate(altProp.cutsceneHeaders, 4 if is_game_oot() else 1) + for i, csHeader in enumerate(altProp.cutsceneHeaders, get_cs_index_start()) ] hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders @@ -123,9 +123,9 @@ def getCmdList(self, curHeader: SceneHeader, hasAltHeaders: bool): + curHeader.entranceActors.getCmd() + (curHeader.exits.getCmd() if len(curHeader.exits.exitList) > 0 else "") + (curHeader.cutscene.getCmd() if len(curHeader.cutscene.entries) > 0 else "") - + (curHeader.map_data.get_cmds() if not is_game_oot() and curHeader.map_data is not None else "") - + (curHeader.anim_mat.get_cmd() if not is_game_oot() and curHeader.anim_mat is not None else "") - + (curHeader.actor_cs.get_cmds() if not is_game_oot() and curHeader.actor_cs is not None else "") + + (curHeader.map_data.get_cmds() if not is_oot_features() and curHeader.map_data is not None else "") + + (curHeader.anim_mat.get_cmd() if not is_oot_features() and curHeader.anim_mat is not None else "") + + (curHeader.actor_cs.get_cmds() if not is_oot_features() and curHeader.actor_cs is not None else "") + Utility.getEndCmd() + "};\n\n" ) @@ -159,7 +159,7 @@ def getSceneMainC(self): for i, (curHeader, _) in enumerate(headers, 1) ) - header_name = "Child Day (Default)" if is_game_oot() else "Default" + header_name = "Child Day (Default)" if is_oot_features() else "Default" headers.insert(0, (self.mainHeader, header_name)) for i, (curHeader, headerDesc) in enumerate(headers): if curHeader is not None: diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 1289ca6fa..6bc59c128 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, is_game_oot +from ...utility import getObjectList, is_oot_features, is_game_oot from ...constants import oot_data, mm_data from ..utility import Utility from ..actor import Actor @@ -89,7 +89,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.pos = pos rot_deg = rot[1] * (180 / 0x8000) - if is_game_oot(): + if is_oot_features(): transActor.rot = f"DEG_TO_BINANG({rot_deg:.3f})" # TODO: Correct axis? else: transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({transActorProp.cutscene_id} & 0x7F)" @@ -163,7 +163,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.id = "ACTOR_PLAYER" if not entranceProp.customActor else entranceProp.actor.actorIDCustom entranceActor.pos = pos - if is_game_oot(): + if is_oot_features(): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: entranceActor.rot = ", ".join( diff --git a/fast64_internal/z64/exporter/scene/animated_mats.py b/fast64_internal/z64/exporter/scene/animated_mats.py index 0b79ae5bd..1a718adde 100644 --- a/fast64_internal/z64/exporter/scene/animated_mats.py +++ b/fast64_internal/z64/exporter/scene/animated_mats.py @@ -38,6 +38,9 @@ def __init__( self.env_colors.append(tuple(exportColor(keyframe.env_color[0:3]) + [scaleToU8(keyframe.env_color[3])])) self.frames.append(keyframe.frame_num) + if keyframe.frame_num > self.frame_length: + raise PluginError("ERROR: the frame number cannot be higher than the total frame count!") + self.frame_count = len(self.frames) assert len(self.frames) == len(self.prim_colors) == len(self.env_colors) @@ -267,7 +270,10 @@ def new(name: str, scene_obj: Object, header_index: int): entries: list[AnimatedMaterial] = [] for obj in obj_list: - entries.extend([AnimatedMaterial(item, name, header_index) for item in obj.z64_anim_mats_property.items]) + if obj.z64_anim_mats_property.mode == "Scene": + entries.extend( + [AnimatedMaterial(item, name, header_index) for item in obj.z64_anim_mats_property.items] + ) last_index = -1 for entry in entries: diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 4541990c5..3e1907a05 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -2,12 +2,12 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, exportColor, ootGetBaseOrCustomLight, indent -from ...utility import is_game_oot, getObjectList, getEvalParams, get_game_prop_name +from ...utility import is_oot_features, getObjectList, getEvalParams, get_game_prop_name, is_game_oot from ...scene.properties import ( Z64_SceneHeaderProperty, Z64_LightProperty, - MM_MinimapChestProperty, - MM_MinimapRoomProperty, + Z64_MapDataChestProperty, + Z64_MapDataRoomProperty, ) from ..utility import Utility @@ -188,7 +188,7 @@ class SceneInfos: @staticmethod def new(props: Z64_SceneHeaderProperty, sceneObj: Object): - if is_game_oot(): + if is_oot_features(): skybox_texture_id = "" else: skybox_texture_id = Utility.getPropValue(props, "skybox_texture_id") @@ -205,9 +205,9 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): Utility.getPropValue(props, get_game_prop_name("seq_id"), "musicSeqCustom"), Utility.getPropValue(props, get_game_prop_name("ambience_id"), "nightSeqCustom"), Utility.getPropValue(props, "audioSessionPreset"), - Utility.getPropValue(props, "mapLocation") if is_game_oot() else "", - Utility.getPropValue(props, "cameraMode") if is_game_oot() else "", - props.set_region_visited if not is_game_oot() else False, + Utility.getPropValue(props, "mapLocation") if is_oot_features() else "", + Utility.getPropValue(props, "cameraMode") if is_oot_features() else "", + props.set_region_visited if not is_oot_features() else False, ) def getCmds(self, lights: SceneLighting): @@ -217,7 +217,7 @@ def getCmds(self, lights: SceneLighting): f"SCENE_CMD_SPECIAL_FILES({self.naviHintType}, {self.keepObjectID})", ] - if is_game_oot(): + if is_oot_features(): commands.extend( [ f"SCENE_CMD_MISC_SETTINGS({self.sceneCamType}, {self.worldMapLocation})", @@ -279,7 +279,7 @@ def getC(self): class MapDataChest: - def __init__(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object, transform: Matrix): + def __init__(self, chest_prop: Z64_MapDataChestProperty, scene_obj: Object, transform: Matrix): if chest_prop.chest_obj is None: raise PluginError("ERROR: The chest empty object is unset.") @@ -289,7 +289,7 @@ def __init__(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object, trans self.chest_flag = int(getEvalParams(chest_prop.chest_obj.ootActorProperty.actorParam), base=0) & 0x1F self.pos = pos - def get_room_index(self, chest_prop: MM_MinimapChestProperty, scene_obj: Object) -> int: + def get_room_index(self, chest_prop: Z64_MapDataChestProperty, scene_obj: Object) -> int: room_obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Room") for room_obj in room_obj_list: @@ -303,7 +303,7 @@ def to_c(self): class MapDataRoom: - def __init__(self, room_prop: MM_MinimapRoomProperty): + def __init__(self, room_prop: Z64_MapDataRoomProperty): self.map_id: str = room_prop.map_id self.center_x: int = room_prop.center_x self.floor_y: int = room_prop.floor_y diff --git a/fast64_internal/z64/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py index 92b4b2394..02c4a2570 100644 --- a/fast64_internal/z64/exporter/scene/header.py +++ b/fast64_internal/z64/exporter/scene/header.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import CData -from ...utility import is_game_oot +from ...utility import is_oot_features from ...scene.properties import Z64_SceneHeaderProperty from ..cutscene import SceneCutscene from .general import SceneLighting, SceneInfos, SceneExits, SceneMapData @@ -52,10 +52,12 @@ def new( entranceActors, SceneSpawns(f"{name}_entranceList", entranceActors.entries), ScenePathways.new(f"{name}_pathway", sceneObj, transform, headerIndex), - SceneMapData.new(f"{name}_mapData", props, sceneObj, transform) if not is_game_oot() else None, - SceneAnimatedMaterial.new(f"{name}_AnimatedMaterial", sceneObj, headerIndex) if not is_game_oot() else None, + SceneMapData.new(f"{name}_mapData", props, sceneObj, transform) if not is_oot_features() else None, + SceneAnimatedMaterial.new(f"{name}_AnimatedMaterial", sceneObj, headerIndex) + if not is_oot_features() + else None, SceneActorCutscene.new(f"{name}_ActorCutscene", sceneObj, transform, headerIndex) - if not is_game_oot() + if not is_oot_features() else None, ) @@ -82,17 +84,17 @@ def getC(self): headerData.append(self.lighting.getC()) # Write the map data - if not is_game_oot() and self.map_data is not None: + if not is_oot_features() and self.map_data is not None: headerData.append(self.map_data.to_c()) # Write the path data, if used if len(self.path.pathList) > 0: headerData.append(self.path.getC()) - if not is_game_oot() and self.anim_mat is not None: + if not is_oot_features() and self.anim_mat is not None: headerData.append(self.anim_mat.to_c()) - if not is_game_oot() and self.actor_cs is not None: + if not is_oot_features() and self.actor_cs is not None: headerData.append(self.actor_cs.to_c()) return headerData diff --git a/fast64_internal/z64/file_settings.py b/fast64_internal/z64/file_settings.py index 486c6d152..ad6f73cc2 100644 --- a/fast64_internal/z64/file_settings.py +++ b/fast64_internal/z64/file_settings.py @@ -27,7 +27,7 @@ def draw(self, context): prop_split(col, context.scene.fast64.oot, version, "Version") if getattr(context.scene.fast64.oot, version) == "Custom": - prop_split(col, context.scene.fast64.oot, "oot_version_custom", "Custom Version") + prop_split(col, context.scene.fast64.oot, "version_custom", "Custom Version") col.prop(context.scene.fast64.oot, "headerTabAffectsVisibility") col.prop(context.scene.fast64.oot, "hackerFeaturesEnabled") @@ -36,6 +36,9 @@ def draw(self, context): col.prop(context.scene.fast64.oot, "useDecompFeatures") col.prop(context.scene.fast64.oot, "exportMotionOnly") + if context.scene.gameEditorMode == "OOT": + col.prop(context.scene.fast64.oot, "mm_features") + oot_classes = (OOT_FileSettingsPanel,) diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index e7808a8dc..88c56d88c 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -126,9 +126,10 @@ def parseCamPosData( fovValue = hexOrDecInt(fov) fovValue = int.from_bytes(fovValue.to_bytes(2, "big", signed=fovValue < 0x8000), "big", signed=True) + camProp.use_setting_default_fov = fovValue == -1 if fovValue > 360: fovValue *= 0.01 # see CAM_DATA_SCALED() macro - elif fovValue == -1: + elif camProp.use_setting_default_fov: fovValue = 60 # TODO: set the fov value depending on each camera setting camObj.data.angle = math.radians(fovValue) diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 2516b8361..06e0e4cd5 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,7 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj, is_game_oot +from .utility import getSceneObj, getRoomObj, is_oot_features, is_game_oot from .scene.properties import OOTSceneProperties from .room.properties import Z64_ObjectProperty, Z64_RoomHeaderProperty, Z64_AlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -74,7 +74,7 @@ def setLightPropertyValues(lightProp, ambient, diffuse0, diffuse1, fogColor, fog def onUpdateOOTEmptyType(self, context): # OoT doesn't have this feature - if is_game_oot() and self.ootEmptyType == "Animated Materials": + if is_oot_features() and self.ootEmptyType == "Animated Materials": self.ootEmptyType = "None" print("INFO: Ocarina of Time doesn't support that feature.") diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 5033b86e1..94398e7c0 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -8,6 +8,7 @@ onHeaderMenuTabChange, drawEnumWithCustom, drawAddButton, + is_oot_features, is_game_oot, get_game_prop_name, get_cs_index_start, @@ -215,7 +216,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general.label(text="and requires meshes to be parented to Custom Cull Group empties.") general.label(text="RSP culling is done automatically regardless of room shape.") prop_split(general, self, "defaultCullDistance", "Default Cull (Blender Units)") - if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_game_oot(): + if self.roomShape == "ROOM_SHAPE_TYPE_NONE" and is_oot_features(): general.label(text="This shape type is only implemented on MM", icon="INFO") # Behavior @@ -230,7 +231,8 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj if is_game_oot(): behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") - else: + + if not is_oot_features(): behaviorBox.prop(self, "enable_pos_lights") behaviorBox.prop(self, "enable_storm") @@ -268,7 +270,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj objBox = layout.column() objBox.box().label(text="Objects") - if is_game_oot() and len(self.objectList) > 16: + if is_oot_features() and len(self.objectList) > 16: objBox.label(text="You are over the 16 object limit.", icon="ERROR") objBox.label(text="You must allocate more memory in code.") diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 6f6a6a6ac..0b69313a4 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -20,6 +20,7 @@ drawCollectionOps, drawEnumWithCustom, drawAddButton, + is_oot_features, is_game_oot, get_cs_index_start, get_game_prop_name, @@ -270,13 +271,13 @@ class Z64_ExtraCutsceneProperty(PropertyGroup): ) -def minimap_chest_poll(self: "MM_MinimapChestProperty", object: Object): +def minimap_chest_poll(self: "Z64_MapDataChestProperty", object: Object): return ( object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" ) -class MM_MinimapChestProperty(PropertyGroup): +class Z64_MapDataChestProperty(PropertyGroup): expand_tab: BoolProperty(name="Expand Tab") # used to get the room index, the coordinates and the chest flag @@ -296,7 +297,7 @@ def draw_props(self, layout: UILayout, index: int, header_index: int, obj_name: box.prop(self, "chest_obj") -class MM_MinimapRoomProperty(PropertyGroup): +class Z64_MapDataRoomProperty(PropertyGroup): expand_tab: BoolProperty(name="Expand Tab") map_id: StringProperty(name="Minimap ID", default="MAP_DATA_NO_MAP") @@ -412,12 +413,12 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_MINIMAP_INFO (note: room informations are defined in `Z64_RoomHeaderProperty`) minimap_room_expand: BoolProperty(name="Expand Tab") - minimap_room_list: CollectionProperty(type=MM_MinimapRoomProperty, name="Minimap Room List") + minimap_room_list: CollectionProperty(type=Z64_MapDataRoomProperty, name="Minimap Room List") minimap_scale: IntProperty(name="Minimap Scale", default=0) # SCENE_CMD_MINIMAP_COMPASS_ICON_INFO minimap_chest_expand: BoolProperty(name="Expand Tab") - minimap_chest_list: CollectionProperty(type=MM_MinimapChestProperty, name="Minimap Chest List") + minimap_chest_list: CollectionProperty(type=Z64_MapDataChestProperty, name="Minimap Chest List") def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): from .operators import OOT_SearchMusicSeqEnumOperator, MM_SearchMusicSeqEnumOperator # temp circular import fix @@ -451,11 +452,12 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawEnumWithCustom( general, self, get_game_prop_name("global_obj"), "Global Object", "", "globalObjectCustom" ) - drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") + if is_game_oot(): + drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: self.sceneTableEntry.draw_props(general) - if not is_game_oot(): + if not is_oot_features(): general.prop(self, "set_region_visited") general.prop(self, "appendNullEntrance") @@ -487,7 +489,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") # Camera And World Map | Minimap Settings - if is_game_oot(): + if is_oot_features(): cameraAndWorldMap = layout.column() cameraAndWorldMap.box().label(text="Camera And World Map") drawEnumWithCustom(cameraAndWorldMap, self, "mapLocation", "Map Location", "") @@ -539,8 +541,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj elif menuTab == "Cutscene": cutscene = layout.column() - if not is_game_oot(): - cutscene.enabled = False + cutscene.enabled = is_oot_features() r = cutscene.row() r.prop(self, "writeCutscene", text="Write Cutscene") @@ -725,13 +726,14 @@ def draw_props(self, layout: UILayout, sceneOption: str): includeButtons3.prop(self, "includePaths", toggle=1) includeButtons3.prop(self, "includeWaterBoxes", toggle=1) - # TODO: implement cutscenes for MM - if is_game_oot(): + # TODO: implement cutscenes for MM features + if is_oot_features(): includeButtons3.prop(self, "includeCutscenes", toggle=1) includeButtons4 = col.row(align=True) - includeButtons4.prop(self, "includeAnimatedMats", toggle=1) - includeButtons4.prop(self, "includeActorCs", toggle=1) + if not is_oot_features(): + includeButtons4.prop(self, "includeAnimatedMats", toggle=1) + includeButtons4.prop(self, "includeActorCs", toggle=1) col.prop(self, "isCustomDest") @@ -746,7 +748,8 @@ def draw_props(self, layout: UILayout, sceneOption: str): if is_game_oot(): if "SCENE_JABU_JABU" in sceneOption: col.label(text="Pulsing wall effect won't be imported.", icon="ERROR") - else: + + if not is_oot_features(): if not self.includeActors: col.label(text="MapDataChest won't be imported.", icon="ERROR") @@ -755,8 +758,8 @@ def draw_props(self, layout: UILayout, sceneOption: str): # OoT exclusive OOT_BootupSceneOptions, # MM exclusive - MM_MinimapChestProperty, - MM_MinimapRoomProperty, + Z64_MapDataChestProperty, + Z64_MapDataRoomProperty, # Common Z64_ExitProperty, Z64_LightProperty, diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index b2116e5fb..3b0f89d75 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -4,7 +4,7 @@ from bpy.props import EnumProperty, PointerProperty, StringProperty, IntProperty from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom, is_game_oot, get_game_prop_name +from ..utility import drawEnumWithCustom, is_oot_features, is_game_oot from ..collision.constants import enum_camera_crawlspace_stype from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -34,7 +34,7 @@ def draw_props( prop_split(layout, self, "splineType", "Type") prop_split(layout, self, "index", camIndexName) - if not is_game_oot(): + if not is_oot_features(): prop_split(layout, self, "opt_path_index", "Additional Path Index") prop_split(layout, self, "custom_value", "Custom Value") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 3187a1040..ef59740bd 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -122,14 +122,19 @@ def is_game_oot(): return bpy.context.scene.gameEditorMode == "OOT" -def isPathObject(obj: bpy.types.Object) -> bool: - return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" +def is_oot_features(): + return is_game_oot() and not bpy.context.scene.fast64.oot.mm_features def get_cs_index_start(): + # not using `is_oot_features()` because we're assuming people won't change the header system return 4 if is_game_oot() else 1 +def isPathObject(obj: bpy.types.Object) -> bool: + return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" + + ootSceneDungeons = [ "bdan", "bdan_boss", From c2cec063955032270e5b3317b14da440169144db Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:51:06 +0100 Subject: [PATCH 038/126] add button to add a default actor cs --- fast64_internal/z64/importer/scene_header.py | 3 +- fast64_internal/z64/importer/utility.py | 9 ---- fast64_internal/z64/tools/operators.py | 55 +++++++++++++++++++- fast64_internal/z64/tools/panel.py | 13 ++++- fast64_internal/z64/utility.py | 9 ++++ 5 files changed, 77 insertions(+), 12 deletions(-) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index e437f423e..9011f2335 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -20,9 +20,10 @@ get_game_prop_name, getObjectList, getEnumIndex, + get_new_empty_object, ) from .constants import headerNames -from .utility import getDataMatch, stripName, get_new_empty_object +from .utility import getDataMatch, stripName from .classes import SharedSceneData from .room_header import parseRoomCommands from .actor import parseTransActorList, parseSpawnList, parseEntranceList diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index ccf5a6ebe..d07aa1d79 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -46,15 +46,6 @@ def createEmptyWithTransform(positionValues: list[float], rotationValues: list[f return obj -def get_new_empty_object(name: str): - new_obj = bpy.data.objects.new(name, None) - bpy.context.scene.collection.objects.link(new_obj) - new_obj.location = [0.0, 0.0, 0.0] - new_obj.rotation_euler = [0.0, 0.0, 0.0] - new_obj.scale = [1.0, 1.0, 1.0] - return new_obj - - def getDisplayNameFromActorID(actorID: str): return " ".join([word.lower().capitalize() for word in actorID.split("_") if word != "ACTOR"]) diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 4b5090a70..9a0166fa4 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -7,8 +7,9 @@ from ...operators import AddWaterBox, addMaterialByName from ...utility import parentObject, setOrigin from ..cutscene.motion.utility import setupCutscene, createNewCameraShot -from ..utility import getNewPath +from ..utility import getNewPath, get_new_empty_object, is_oot_features from .quick_import import QuickImportAborted, quick_import_exec +from ..actor_cutscene.properties import enum_end_cam, enum_end_sfx, enum_hud_visibility class OOT_AddWaterBox(AddWaterBox): @@ -293,3 +294,55 @@ def execute(self, context: Context): self.report({"ERROR"}, e.message) return {"CANCELLED"} return {"FINISHED"} + + +class Z64_AddActorCutscenes(Operator): + bl_idname = "object.z64_add_actor_cs" + bl_label = "Add Actor CS" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Adds a basic actor cutscene with the necessary entries for a scene" + + obj_name: StringProperty(name="Object Name", default="Actor Cutscene") + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + def draw(self, context): + self.layout.prop(self, "obj_name") + + if is_oot_features(): + self.layout.label(text="Warning: This is only useful when using MM features.", icon="ERROR") + + def execute(self, context: Context): + actor_cs_obj = get_new_empty_object(self.obj_name) + actor_cs_obj.ootEmptyType = "Actor Cutscene" + + entry_data_map = { + # CS Cam ID: [Priority, Length, Script Index, Additional CS ID, End SFX, Custom Value, HUD visibility, End Cam, Letterbox Size] + "CS_CAM_ID_GLOBAL_ITEM_OCARINA": [550, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_GET": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_BOTTLE": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_SHOW": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_WARP_PAD_MOON": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_DEATH": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_REVIVE": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_SONG_WARP": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING": [700, -1, -1, -1, 1, "255", 1, 1, 30], + } + + for cs_cam_id, data in entry_data_map.items(): + new_entry = actor_cs_obj.z64_actor_cs_property.entries.add() + new_entry.cs_cam_id = cs_cam_id + new_entry.priority = data[0] + new_entry.length = data[1] + new_entry.script_index = data[2] + new_entry.additional_cs_id = data[3] + new_entry.end_sfx = enum_end_sfx[data[4]][0] + new_entry.custom_value = data[5] + new_entry.hud_visibility = enum_hud_visibility[data[6]][0] + new_entry.end_cam = enum_end_cam[data[7]][0] + new_entry.letterbox_size = data[8] + + return {"FINISHED"} diff --git a/fast64_internal/z64/tools/panel.py b/fast64_internal/z64/tools/panel.py index d77004b89..ab4140327 100644 --- a/fast64_internal/z64/tools/panel.py +++ b/fast64_internal/z64/tools/panel.py @@ -9,6 +9,7 @@ OOT_AddPath, OOTClearTransformAndLock, OOTQuickImport, + Z64_AddActorCutscenes, ) @@ -17,16 +18,25 @@ class OoT_ToolsPanel(Z64_Panel): bl_label = "Tools" def draw(self, context): - col = self.layout.column() + col = self.layout.row(align=True) col.operator(OOT_AddWaterBox.bl_idname) col.operator(OOT_AddDoor.bl_idname) + + col = self.layout.row(align=True) col.operator(OOT_AddScene.bl_idname) col.operator(OOT_AddRoom.bl_idname) + + col = self.layout.row(align=True) col.operator(OOT_AddCutscene.bl_idname) col.operator(OOT_AddPath.bl_idname) + + col = self.layout.row(align=True) col.operator(OOTClearTransformAndLock.bl_idname) col.operator(OOTQuickImport.bl_idname) + col = self.layout.row(align=True) + col.operator(Z64_AddActorCutscenes.bl_idname) + oot_operator_panel_classes = [ OoT_ToolsPanel, @@ -41,6 +51,7 @@ def draw(self, context): OOT_AddPath, OOTClearTransformAndLock, OOTQuickImport, + Z64_AddActorCutscenes, ] diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index ef59740bd..cb117caba 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -1280,3 +1280,12 @@ def get_list_tab_text(base_text: str, list_length: int): items_amount = "Empty" return f"{base_text} ({items_amount})" + + +def get_new_empty_object(name: str): + new_obj = bpy.data.objects.new(name, None) + bpy.context.scene.collection.objects.link(new_obj) + new_obj.location = [0.0, 0.0, 0.0] + new_obj.rotation_euler = [0.0, 0.0, 0.0] + new_obj.scale = [1.0, 1.0, 1.0] + return new_obj From f04388a44a97cc28d4fcf5f284235f3ac3d2186e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 1 Jan 2025 15:44:14 +0100 Subject: [PATCH 039/126] actors: halfday bits and embedded actor cs --- fast64_internal/z64/actor/properties.py | 132 +++++++++--- .../z64/actor_cutscene/properties.py | 11 +- fast64_internal/z64/constants.py | 55 +++++ fast64_internal/z64/exporter/room/header.py | 70 +++--- .../z64/exporter/scene/__init__.py | 8 +- .../z64/exporter/scene/actor_cutscene.py | 29 ++- fast64_internal/z64/importer/actor.py | 71 ++++++- fast64_internal/z64/importer/scene_header.py | 201 +++++++++++------- fast64_internal/z64/importer/utility.py | 7 +- fast64_internal/z64/props_panel_main.py | 2 +- fast64_internal/z64/room/properties.py | 8 + fast64_internal/z64/utility.py | 2 + 12 files changed, 453 insertions(+), 143 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index d7a3f301b..37fe7b476 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -19,6 +19,7 @@ is_oot_features, is_game_oot, get_game_enum, + get_list_tab_text, ) ootEnumSceneSetupPreset = [ @@ -27,6 +28,38 @@ ("All Non-Cutscene Scene Setups", "All Non-Cutscene Scene Setups", "All Non-Cutscene Scene Setups"), ] +enum_actor_menu = [ + ("General", "General", "General"), + ("Actor Cutscene", "Actor Cutscene", "Actor Cutscene"), +] + +enum_half_day = [ + ("Custom", "Custom", "Custom"), + ("0-Dawn", "Day 0 (Intro) - Dawn", "Day 0 - Dawn"), + ("0-Night", "Day 0 (Intro) - Night", "Day 0 - Night"), + ("1-Dawn", "Day 1 - Dawn", "Day 1 - Dawn"), + ("1-Night", "Day 1 - Night", "Day 1 - Night"), + ("2-Dawn", "Day 2 - Dawn", "Day 2 - Dawn"), + ("2-Night", "Day 2 - Night", "Day 2 - Night"), + ("3-Dawn", "Day 3 - Dawn", "Day 3 - Dawn"), + ("3-Night", "Day 3 - Night", "Day 3 - Night"), + ("4-Dawn", "Day 4 (Credits) - Dawn", "Day 4 - Dawn"), + ("4-Night", "Day 4 (Credits) - Night", "Day 4 - Night"), +] + + +class Z64_HalfdayItem(PropertyGroup): + value: EnumProperty(items=enum_half_day, default=1) + value_custom: StringProperty() + + def draw_props(self, layout: UILayout, owner: Object, index: int): + layout = layout.column() + row = layout.row() + row.prop(self, "value", text="") + if self.value == "Custom": + row.prop(self, "value_custom", text="") + drawCollectionOps(row.row(align=True), index, "Actor Halfday", None, owner.name, compact=True) + # TODO: remove def update_cutscene_index(self, context: Context): @@ -167,6 +200,15 @@ class Z64_ActorProperty(PropertyGroup): rotOverrideY: StringProperty(name="Rot Y", default="0") rotOverrideZ: StringProperty(name="Rot Z", default="0") headerSettings: PointerProperty(type=Z64_ActorHeaderProperty) + menu_tab: EnumProperty(items=enum_actor_menu) + halfday_show_entries: BoolProperty(default=True) + halfday_all: BoolProperty(default=True) + halfday_all_dawns: BoolProperty(default=False) + halfday_all_nights: BoolProperty(default=False) + halfday_bits: CollectionProperty(type=Z64_HalfdayItem) + + # internal + actor_cs_index: IntProperty(default=0x7F) @staticmethod def upgrade_object(obj: Object): @@ -174,43 +216,80 @@ def upgrade_object(obj: Object): print(f"Processing '{obj.name}'...") upgradeActors(obj) - def draw_props(self, layout: UILayout, altRoomProp: Z64_AlternateRoomHeaderProperty, objName: str): + def draw_props( + self, + layout: UILayout, + owner: Object, + alt_scene_props: Z64_AlternateSceneHeaderProperty, + altRoomProp: Z64_AlternateRoomHeaderProperty, + ): actorIDBox = layout.column() - actor_id: str = getattr(self, get_game_prop_name("actor_id")) - if is_game_oot(): - op_name = OOT_SearchActorIDEnumOperator.bl_idname - else: - op_name = MM_SearchActorIDEnumOperator.bl_idname + actorIDBox.row().prop(self, "menu_tab", expand=True) + actor_cs_props = owner.z64_actor_cs_property - searchOp = actorIDBox.operator(op_name, icon="VIEWZOOM") - searchOp.actorUser = "Actor" - searchOp.objName = objName + if self.menu_tab == "General": + actor_id: str = getattr(self, get_game_prop_name("actor_id")) - split = actorIDBox.split(factor=0.5) + if is_game_oot(): + op_name = OOT_SearchActorIDEnumOperator.bl_idname + else: + op_name = MM_SearchActorIDEnumOperator.bl_idname - if actor_id == "None": - actorIDBox.box().label(text="This Actor was deleted from the XML file.") - return + searchOp = actorIDBox.operator(op_name, icon="VIEWZOOM") + searchOp.actorUser = "Actor" + searchOp.objName = owner.name - split.label(text="Actor ID") - split.label(text=getEnumName(get_game_enum("enum_actor_id"), actor_id)) + split = actorIDBox.split(factor=0.5) - if actor_id == "Custom": - prop_split(actorIDBox, self, "actorIDCustom", "") + if actor_id == "None": + actorIDBox.box().label(text="This Actor was deleted from the XML file.") + return + + split.label(text="Actor ID") + split.label(text=getEnumName(get_game_enum("enum_actor_id"), actor_id)) + + if actor_id == "Custom": + prop_split(actorIDBox, self, "actorIDCustom", "") + + prop_split(actorIDBox, self, "actorParam", "Actor Parameter") + + rot_box = actorIDBox.box().column() + rot_box.prop(self, "rotOverride", text="Override Rotation (ignore Blender rot)") + if self.rotOverride: + prop_split(rot_box, self, "rotOverrideX", "Rot X") + prop_split(rot_box, self, "rotOverrideY", "Rot Y") + prop_split(rot_box, self, "rotOverrideZ", "Rot Z") + + if not is_oot_features(): + layout_halfday = actorIDBox.box().column() + layout_halfday.label(text="Spawn Schedule") + row = layout_halfday.row(align=True) + row.prop(self, "halfday_all", text="Always Spawn") + + if not self.halfday_all: + row.prop(self, "halfday_all_dawns", text="All Dawns") + row.prop(self, "halfday_all_nights", text="All Nights") + + if not self.halfday_all_dawns and not self.halfday_all_nights: + prop_text = get_list_tab_text("Entries", len(self.halfday_bits)) + layout_halfday.prop( + self, + "halfday_show_entries", + text=prop_text, + icon="TRIA_DOWN" if self.halfday_show_entries else "TRIA_RIGHT", + ) - prop_split(actorIDBox, self, "actorParam", "Actor Parameter") + if self.halfday_show_entries: + for i, item in enumerate(self.halfday_bits): + item.draw_props(layout_halfday, owner, i) + drawAddButton(layout_halfday, len(self.halfday_bits), "Actor Halfday", None, owner.name) - rot_box = actorIDBox.box() - prop_text = "Override Rotation (ignore Blender rot)" if is_oot_features() else "Use Rotation Flags" - rot_box.prop(self, "rotOverride", text=prop_text) - if self.rotOverride: - prop_split(rot_box, self, "rotOverrideX", "Rot X") - prop_split(rot_box, self, "rotOverrideY", "Rot Y") - prop_split(rot_box, self, "rotOverrideZ", "Rot Z") + elif self.menu_tab == "Actor Cutscene": + actor_cs_props.draw_props(actorIDBox, owner, alt_scene_props, False) headerProp: Z64_ActorHeaderProperty = self.headerSettings - headerProp.draw_props(actorIDBox, "Actor", altRoomProp, objName) + headerProp.draw_props(actorIDBox, "Actor", altRoomProp, owner.name) class Z64_TransitionActorProperty(PropertyGroup): @@ -313,6 +392,7 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateS classes = ( + Z64_HalfdayItem, Z64_ActorHeaderItemProperty, Z64_ActorHeaderProperty, Z64_ActorProperty, diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py index 6f4b0f5c2..d559df939 100644 --- a/fast64_internal/z64/actor_cutscene/properties.py +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -150,7 +150,13 @@ class Z64_ActorCutsceneProperty(PropertyGroup): # ui only props show_entries: BoolProperty(default=True) - def draw_props(self, layout: UILayout, owner: Object, alt_header_props: Z64_AlternateSceneHeaderProperty): + def draw_props( + self, + layout: UILayout, + owner: Object, + alt_header_props: Z64_AlternateSceneHeaderProperty, + draw_header: bool = True, + ): layout_entries = layout.box().column() prop_text = get_list_tab_text("Entries", len(self.entries)) @@ -164,7 +170,8 @@ def draw_props(self, layout: UILayout, owner: Object, alt_header_props: Z64_Alte drawAddButton(layout_entries, len(self.entries), "Actor CS", None, owner.name) - self.header_settings.draw_props(layout, "Actor CS Headers", alt_header_props, owner.name) + if draw_header: + self.header_settings.draw_props(layout, "Actor CS Headers", alt_header_props, owner.name) classes = ( diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index a15be1dc0..3bf2ea078 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -756,3 +756,58 @@ "cycleType": "G_CYC_2CYCLE", }, } + +halfday_bits_day0_dawn = 1 << 9 +halfday_bits_day0_night = 1 << 8 +halfday_bits_day1_dawn = 1 << 7 +halfday_bits_day1_night = 1 << 6 +halfday_bits_day2_dawn = 1 << 5 +halfday_bits_day2_night = 1 << 4 +halfday_bits_day3_dawn = 1 << 3 +halfday_bits_day3_night = 1 << 2 +halfday_bits_day4_dawn = 1 << 1 +halfday_bits_day4_night = 1 << 0 + +halfday_bits_values = [ + halfday_bits_day0_dawn, + halfday_bits_day0_night, + halfday_bits_day1_dawn, + halfday_bits_day1_night, + halfday_bits_day2_dawn, + halfday_bits_day2_night, + halfday_bits_day3_dawn, + halfday_bits_day3_night, + halfday_bits_day4_dawn, + halfday_bits_day4_night, +] + +halfday_bits_all_dawns = ( + halfday_bits_day0_dawn + | halfday_bits_day1_dawn + | halfday_bits_day2_dawn + | halfday_bits_day3_dawn + | halfday_bits_day4_dawn +) + +halfday_bits_all_nights = ( + halfday_bits_day0_night + | halfday_bits_day1_night + | halfday_bits_day2_night + | halfday_bits_day3_night + | halfday_bits_day4_night +) + + +enum_to_halfday_bits = { + "0-Dawn": halfday_bits_day0_dawn, + "0-Night": halfday_bits_day0_night, + "1-Dawn": halfday_bits_day1_dawn, + "1-Night": halfday_bits_day1_night, + "2-Dawn": halfday_bits_day2_dawn, + "2-Night": halfday_bits_day2_night, + "3-Dawn": halfday_bits_day3_dawn, + "3-Night": halfday_bits_day3_night, + "4-Dawn": halfday_bits_day4_dawn, + "4-Night": halfday_bits_day4_night, +} +halfday_bits_to_enum = {val: key for key, val in enum_to_halfday_bits.items()} diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 5252cf661..e638d7235 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -2,9 +2,9 @@ from typing import Optional from mathutils import Matrix from bpy.types import Object -from ....utility import CData, indent +from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, getEvalParams, get_game_prop_name, is_game_oot -from ...constants import oot_data, mm_data +from ...constants import oot_data, mm_data, halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits from ...room.properties import Z64_RoomHeaderProperty from ..utility import Utility from ..actor import Actor @@ -196,34 +196,50 @@ def new( else: actor.id = actor_id + if actorProp.rotOverride: + rotation: list[str] = [actorProp.rotOverrideX, actorProp.rotOverrideY, actorProp.rotOverrideZ] + else: + rotation: list[str] = [f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] + if is_oot_features(): - if actorProp.rotOverride: - actor.rot = ", ".join([actorProp.rotOverrideX, actorProp.rotOverrideY, actorProp.rotOverrideZ]) - else: - actor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) + actor.rot = ", ".join(rotation) else: - if actorProp.rotOverride: - actor_flags = [0x4000, 0x8000, 0x2000] - actor_flag_masks = [] - spawn_flags = [ - f"0x{int(getEvalParams(actorProp.rotOverrideX), base=0):02X}", - f"0x{int(getEvalParams(actorProp.rotOverrideY), base=0):02X}", - f"0x{int(getEvalParams(actorProp.rotOverrideZ), base=0):02X}", - ] - - for i, rot_flag in enumerate(spawn_flags): - if int(rot_flag, base=0) > 0: - actor_flag_masks.append(actor_flags[i]) - - if len(actor_flag_masks) > 0: - mask = 0 - for val in actor_flag_masks: - mask |= val - actor.id = f"{actor.id} | 0x{mask:04X}" - else: - spawn_flags = ["0x00"] * 3 + halfday_bits = 0 - spawn_rot = [f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot] + if actorProp.halfday_all: + halfday_bits |= halfday_bits_all_dawns | halfday_bits_all_nights + else: + if actorProp.halfday_all_dawns: + halfday_bits |= halfday_bits_all_dawns + + if actorProp.halfday_all_nights: + halfday_bits |= halfday_bits_all_nights + + # if the value is 0 it means it's not all nor all dawns nor all nights + if halfday_bits == 0: + for item in actorProp.halfday_bits: + custom_value = 0 + + try: + if item.value == "Custom": + custom_value = int(getEvalParams(item.value_custom), base=0) + except: + raise PluginError( + f"ERROR: custom spawn schedule values don't support non-evaluable characters! ({repr(obj.name)})" + ) + + halfday_bits |= enum_to_halfday_bits.get(item.value, custom_value) + + # rot.x stores a part of the halfday bits value + # rot.y stores a cutscene index + # rot.z stores the other part of the halfday bits + cs_index = actorProp.actor_cs_index & 0x7F + spawn_flags = [ + f"0x{(halfday_bits >> 7) & 0x07:02X}", + "CS_ID_GLOBAL_END" if cs_index == 0x7F else cs_index, + f"0x{halfday_bits & 0x7F:02X}", + ] + spawn_rot = [f"SPAWN_ROT_FLAGS({r}" for r in rotation] actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index e09a5e330..b54f19ab1 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -29,9 +29,6 @@ class Scene: @staticmethod def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTexturesAsPNG: bool, model: OOTModel): i = 0 - rooms = RoomEntries.new( - f"{name}_roomList", name.removesuffix("_scene"), model, sceneObj, transform, saveTexturesAsPNG - ) colHeader = CollisionHeader.new( f"{name}_collisionHeader", @@ -63,6 +60,11 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex for i, csHeader in enumerate(altProp.cutsceneHeaders, get_cs_index_start()) ] + # process room after scene because of actor cutscenes requiring to be processed before actors + rooms = RoomEntries.new( + f"{name}_roomList", name.removesuffix("_scene"), model, sceneObj, transform, saveTexturesAsPNG + ) + hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders altHeader = altHeader if hasAlternateHeaders else None return Scene(name, model, mainHeader, altHeader, rooms, colHeader, hasAlternateHeaders) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index 736b0d301..bb7e35f51 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -10,13 +10,18 @@ class ActorCutscene: - def __init__(self, scene_obj: Object, transform: Matrix, props: Z64_ActorCutscene, name: str, index: int): + def __init__( + self, scene_obj: Object, transform: Matrix, props: Z64_ActorCutscene, name: str, index: int, obj: Object + ): self.name = name self.priority: int = props.priority self.length: int = props.length self.index = index self.cam_info: Optional[CameraInfo] = None + if obj.ootEmptyType == "Actor": + obj.ootActorProperty.actor_cs_index = index + if props.cs_cam_id == "Custom": self.cs_cam_id: str = props.cs_cam_id_custom elif props.cs_cam_id == "Camera": @@ -73,19 +78,31 @@ class SceneActorCutscene: entries: list[ActorCutscene] @staticmethod - def new(name: str, scene_obj: Object, transform: Matrix, header_index: int): - obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Actor Cutscene") + def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: int, empty_type: str, start: int): entries: list[ActorCutscene] = [] + obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", empty_type) + + for i, obj in enumerate(obj_list, start): + if empty_type == "Actor": + header_settings = obj.ootActorProperty.headerSettings + else: + header_settings = obj.z64_actor_cs_property.header_settings - for i, obj in enumerate(obj_list): entries.extend( [ - ActorCutscene(scene_obj, transform, item, name, i) + ActorCutscene(scene_obj, transform, item, name, i, obj) for item in obj.z64_actor_cs_property.entries - if Utility.isCurrentHeaderValid(obj.z64_actor_cs_property.header_settings, header_index) + if Utility.isCurrentHeaderValid(header_settings, header_index) ] ) + return entries + + @staticmethod + def new(name: str, scene_obj: Object, transform: Matrix, header_index: int): + entries = SceneActorCutscene.get_entries(name, scene_obj, transform, header_index, "Actor Cutscene", 0) + entries.extend(SceneActorCutscene.get_entries(name, scene_obj, transform, header_index, "Actor", len(entries))) + # validate camera indices last_cam_index = -1 for entry in entries: diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 95c2f81a7..8eefd8a03 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -1,10 +1,17 @@ import re import bpy +from bpy.types import Object from ...utility import parentObject, hexOrDecInt from ..scene.properties import Z64_SceneHeaderProperty from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_enum, get_game_prop_name -from ..constants import ootEnumCamTransition +from ..constants import ( + ootEnumCamTransition, + halfday_bits_all_dawns, + halfday_bits_all_nights, + halfday_bits_to_enum, + halfday_bits_values, +) from .classes import SharedSceneData from .constants import actorsWithRotAsParam @@ -213,6 +220,36 @@ def getActorRegex(actorList: list[str]): return regex, nestedBrackets +def move_actor_cs_entry(global_cs_obj: Object, actor_obj: Object, index: int, default_entry): + index &= 0x7F + if index >= 0x78: + return default_entry + + global_cs_props = global_cs_obj.z64_actor_cs_property + actor_cs_props = actor_obj.z64_actor_cs_property + entry = global_cs_props.entries[index] + additional_cs_id = entry.additional_cs_id + + new_entry = actor_cs_props.entries.add() + new_entry.priority = entry.priority + new_entry.length = entry.length + new_entry.cs_cam_id = entry.cs_cam_id + new_entry.cs_cam_id_custom = entry.cs_cam_id_custom + new_entry.cs_cam_obj = entry.cs_cam_obj + new_entry.script_index = entry.script_index + new_entry.additional_cs_id = additional_cs_id + new_entry.end_sfx = entry.end_sfx + new_entry.end_sfx_custom = entry.end_sfx_custom + new_entry.custom_value = entry.custom_value + new_entry.hud_visibility = entry.hud_visibility + new_entry.hud_visibility_custom = entry.hud_visibility_custom + new_entry.end_cam = entry.end_cam + new_entry.end_cam_custom = entry.end_cam_custom + new_entry.letterbox_size = entry.letterbox_size + + return new_entry + + def parseActorList( roomObj: bpy.types.Object, sceneData: str, actorListName: str, sharedSceneData: SharedSceneData, headerIndex: int ): @@ -233,9 +270,39 @@ def parseActorList( actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actorIDCustom" ) actorProp.actorParam = actorParam - handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) + handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) + actor_cs_obj = None + for obj in bpy.data.objects: + if obj.type == "EMPTY" and obj.ootEmptyType == "Actor Cutscene": + actor_cs_obj = obj + break + + if sharedSceneData.includeActorCs and actor_cs_obj is not None: + # move any actor cs entry to the actor object embedded list based on the cs index of rot.y + # also move any other entries as defined by the additional cs id + new_entry = move_actor_cs_entry(actor_cs_obj, actorObj, spawn_flags[1], None) + if new_entry is not None: + while new_entry.additional_cs_id != -1: + new_entry = move_actor_cs_entry(actor_cs_obj, actorObj, new_entry.additional_cs_id, new_entry) + + # see `Actor_SpawnEntry()` + halfday_bits = ((spawn_flags[0] & 7) << 7) | (spawn_flags[2] & 0x7F) + actorProp.halfday_all = halfday_bits == halfday_bits_all_dawns | halfday_bits_all_nights + + if not actorProp.halfday_all: + actorProp.halfday_all_dawns = halfday_bits == halfday_bits_all_dawns + actorProp.halfday_all_nights = halfday_bits == halfday_bits_all_nights + + if not actorProp.halfday_all and not actorProp.halfday_all_dawns and not actorProp.halfday_all_nights: + for bits in halfday_bits_values: + value = halfday_bits & bits + + if value > 0: + new_entry = actorProp.halfday_bits.add() + new_entry.value = halfday_bits_to_enum[value] + sharedSceneData.actorDict[actorHash] = actorObj parentObject(roomObj, actorObj) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 9011f2335..1e4797913 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -527,13 +527,19 @@ def parseSceneCommands( commands = getDataMatch(sceneData, sceneCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") entranceList = None - altHeadersListName = None - chest_map_data_args = None - actor_cs_data_args = None + # command to delay: command args + delayed_commands: dict[str, list[str]] = {} + command_map: dict[str, list[str]] = {} + # store the commands to process with the corresponding args for commandMatch in re.finditer(rf"(SCENE\_CMD\_[a-zA-Z0-9\_]*)\s*\((.*?)\)\s*,", commands, flags=re.DOTALL): command = commandMatch.group(1) args = [arg.strip() for arg in commandMatch.group(2).split(",")] + command_map[command] = args + + command_list = list(command_map.keys()) + + for command, args in command_map.items(): if command == "SCENE_CMD_SOUND_SETTINGS": setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) setCustomProperty( @@ -557,31 +563,29 @@ def parseSceneCommands( setCustomProperty( sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id"), "musicSeqCustom" ) + command_list.remove(command) elif command == "SCENE_CMD_ROOM_LIST": - # Assumption that all scenes use the same room list. - if headerIndex == 0: - if roomObjs is not None: - raise PluginError("Attempting to parse a room list while room objs already loaded.") - roomListName = stripName(args[1]) - roomObjs = parseRoomList(sceneObj, sceneData, roomListName, f3dContext, sharedSceneData, headerIndex) - - # This must be handled after rooms, so that room objs can be referenced - elif command == "SCENE_CMD_TRANSITION_ACTOR_LIST" and sharedSceneData.includeActors: - transActorListName = stripName(args[1]) - parseTransActorList(roomObjs, sceneData, transActorListName, sharedSceneData, headerIndex) - + # Delay until actor cutscenes are processed + delayed_commands[command] = args + command_list.remove(command) + elif command == "SCENE_CMD_TRANSITION_ACTOR_LIST": + if sharedSceneData.includeActors: + # This must be handled after rooms, so that room objs can be referenced + delayed_commands[command] = args + command_list.remove(command) elif is_game_oot() and command == "SCENE_CMD_MISC_SETTINGS": setCustomProperty(sceneHeader, "cameraMode", args[0], ootEnumCameraMode) setCustomProperty(sceneHeader, "mapLocation", args[1], ootEnumMapLocation) + command_list.remove(command) elif command == "SCENE_CMD_COL_HEADER": - # Assumption that all scenes use the same collision. - if headerIndex == 0: - collisionHeaderName = args[0][1:] # remove '&' - parseCollisionHeader(sceneObj, roomObjs, sceneData, collisionHeaderName, sharedSceneData) - elif command == "SCENE_CMD_ENTRANCE_LIST" and sharedSceneData.includeActors: - if not (args[0] == "NULL" or args[0] == "0" or args[0] == "0x00"): - entranceListName = stripName(args[0]) - entranceList = parseEntranceList(sceneHeader, roomObjs, sceneData, entranceListName) + # Delay until after rooms are processed + delayed_commands[command] = args + command_list.remove(command) + elif command == "SCENE_CMD_ENTRANCE_LIST": + if sharedSceneData.includeActors: + # Delay until after rooms are processed + delayed_commands[command] = args + command_list.remove(command) elif command == "SCENE_CMD_SPECIAL_FILES": if is_game_oot(): setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) @@ -592,19 +596,17 @@ def parseSceneCommands( get_game_enum("enum_global_object"), "globalObjectCustom", ) - elif command == "SCENE_CMD_PATH_LIST" and sharedSceneData.includePaths: - pathListName = stripName(args[0]) - parsePathList(sceneObj, sceneData, pathListName, headerIndex, sharedSceneData) - - # This must be handled after entrance list, so that entrance list can be referenced - elif command == "SCENE_CMD_SPAWN_LIST" and sharedSceneData.includeActors: - if not (args[1] == "NULL" or args[1] == "0" or args[1] == "0x00"): - spawnListName = stripName(args[1]) - parseSpawnList(roomObjs, sceneData, spawnListName, entranceList, sharedSceneData, headerIndex) - - # Clear entrance list - entranceList = None - + command_list.remove(command) + elif command == "SCENE_CMD_PATH_LIST": + if sharedSceneData.includePaths: + pathListName = stripName(args[0]) + parsePathList(sceneObj, sceneData, pathListName, headerIndex, sharedSceneData) + command_list.remove(command) + elif command == "SCENE_CMD_SPAWN_LIST": + if sharedSceneData.includeActors: + # This must be handled after entrance list, so that entrance list and room list can be referenced + delayed_commands[command] = args + command_list.remove(command) elif command == "SCENE_CMD_SKYBOX_SETTINGS": args_index = 0 if not is_game_oot(): @@ -625,55 +627,112 @@ def parseSceneCommands( "skyboxCloudinessCustom", ) setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) + command_list.remove(command) elif command == "SCENE_CMD_EXIT_LIST": exitListName = stripName(args[0]) parseExitList(sceneHeader, sceneData, exitListName) - elif command == "SCENE_CMD_ENV_LIGHT_SETTINGS" and sharedSceneData.includeLights: - if not (args[1] == "NULL" or args[1] == "0" or args[1] == "0x00"): - lightsListName = stripName(args[1]) - parseLightList(sceneObj, sceneHeader, sceneData, lightsListName, headerIndex) - elif command == "SCENE_CMD_CUTSCENE_DATA" and sharedSceneData.includeCutscenes: - sceneHeader.writeCutscene = True - sceneHeader.csWriteType = "Object" - csObjName = f"Cutscene.{args[0]}" - try: - sceneHeader.csWriteObject = bpy.data.objects[csObjName] - except: - print(f"ERROR: Cutscene ``{csObjName}`` do not exist!") + command_list.remove(command) + elif command == "SCENE_CMD_ENV_LIGHT_SETTINGS": + if sharedSceneData.includeLights: + if not (args[1] == "NULL" or args[1] == "0" or args[1] == "0x00"): + lightsListName = stripName(args[1]) + parseLightList(sceneObj, sceneHeader, sceneData, lightsListName, headerIndex) + command_list.remove(command) + elif command == "SCENE_CMD_CUTSCENE_DATA": + if sharedSceneData.includeCutscenes: + sceneHeader.writeCutscene = True + sceneHeader.csWriteType = "Object" + csObjName = f"Cutscene.{args[0]}" + try: + sceneHeader.csWriteObject = bpy.data.objects[csObjName] + except: + print(f"ERROR: Cutscene ``{csObjName}`` do not exist!") + command_list.remove(command) elif command == "SCENE_CMD_ALTERNATE_HEADER_LIST": - # Delay until after rooms are parsed - altHeadersListName = stripName(args[0]) + # Delay until after rooms are processed + delayed_commands[command] = args + command_list.remove(command) + elif command == "SCENE_CMD_END": + command_list.remove(command) # handle Majora's Mask exclusive commands elif not is_game_oot(): if command == "SCENE_CMD_SET_REGION_VISITED": sceneHeader.set_region_visited = True + command_list.remove(command) elif command in {"SCENE_CMD_MINIMAP_INFO", "SCENE_CMD_MAP_DATA"}: parse_mm_map_data(sceneHeader, sceneData, stripName(args[0])) + command_list.remove(command) elif command in {"SCENE_CMD_MINIMAP_COMPASS_ICON_INFO", "SCENE_CMD_MAP_DATA_CHESTS"}: # Delay until rooms and actors are processed - chest_map_data_args = args - elif sharedSceneData.includeAnimatedMats and command == "SCENE_CMD_ANIMATED_MATERIAL_LIST": - parse_animated_material(sceneObj, headerIndex, sceneData, stripName(args[0])) - elif sharedSceneData.includeActorCs: - if command in {"SCENE_CMD_ACTOR_CUTSCENE_LIST", "SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST"}: - if command == "SCENE_CMD_ACTOR_CUTSCENE_LIST": - # Delay until cameras are processed, if used - actor_cs_data_args = args - else: - # TODO: implement alt headers - if headerIndex == 0: - parseCamDataList(sceneObj, stripName(args[1]), sceneData, True) - - if sharedSceneData.includeActors and chest_map_data_args is not None: - parse_mm_map_data_chest( - roomObjs, sceneHeader, sceneData, int(chest_map_data_args[0], base=0), stripName(chest_map_data_args[1]) - ) + delayed_commands[command] = args + command_list.remove(command) + elif command == "SCENE_CMD_ANIMATED_MATERIAL_LIST": + if sharedSceneData.includeAnimatedMats: + parse_animated_material(sceneObj, headerIndex, sceneData, stripName(args[0])) + command_list.remove(command) + elif command == "SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST": + if sharedSceneData.includeActorCs: + # TODO: implement alt headers + if headerIndex == 0: + parseCamDataList(sceneObj, stripName(args[1]), sceneData, True) + command_list.remove(command) + elif command == "SCENE_CMD_ACTOR_CUTSCENE_LIST": + if sharedSceneData.includeActorCs: + # Delay until cameras are processed, if used + delayed_commands[command] = args + command_list.remove(command) + + # requires `SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST` + if "SCENE_CMD_ACTOR_CUTSCENE_LIST" in delayed_commands: + if sharedSceneData.includeActorCs: + args = delayed_commands["SCENE_CMD_ACTOR_CUTSCENE_LIST"] + parse_actor_cs(sceneObj, headerIndex, sceneData, stripName(args[1])) + delayed_commands.pop("SCENE_CMD_ACTOR_CUTSCENE_LIST") + + # requires `SCENE_CMD_ACTOR_CUTSCENE_LIST` + if "SCENE_CMD_ROOM_LIST" in delayed_commands: + args = delayed_commands["SCENE_CMD_ROOM_LIST"] + # Assumption that all scenes use the same room list. + if headerIndex == 0: + if roomObjs is not None: + raise PluginError("Attempting to parse a room list while room objs already loaded.") + roomListName = stripName(args[1]) + roomObjs = parseRoomList(sceneObj, sceneData, roomListName, f3dContext, sharedSceneData, headerIndex) + delayed_commands.pop("SCENE_CMD_ROOM_LIST") + else: + raise PluginError("ERROR: no room command found for this scene!") - if sharedSceneData.includeActorCs and actor_cs_data_args is not None: - parse_actor_cs(sceneObj, headerIndex, sceneData, stripName(actor_cs_data_args[1])) + # any other delayed command requires rooms to be processed + for command, args in delayed_commands.items(): + if command == "SCENE_CMD_TRANSITION_ACTOR_LIST" and sharedSceneData.includeActors: + transActorListName = stripName(args[1]) + parseTransActorList(roomObjs, sceneData, transActorListName, sharedSceneData, headerIndex) + elif command == "SCENE_CMD_COL_HEADER": + # Assumption that all scenes use the same collision. + if headerIndex == 0: + collisionHeaderName = args[0][1:] # remove '&' + parseCollisionHeader(sceneObj, roomObjs, sceneData, collisionHeaderName, sharedSceneData) + elif command == "SCENE_CMD_ENTRANCE_LIST" and sharedSceneData.includeActors: + if not (args[0] == "NULL" or args[0] == "0" or args[0] == "0x00"): + entranceListName = stripName(args[0]) + entranceList = parseEntranceList(sceneHeader, roomObjs, sceneData, entranceListName) + elif command == "SCENE_CMD_SPAWN_LIST" and sharedSceneData.includeActors: + if not (args[1] == "NULL" or args[1] == "0" or args[1] == "0x00"): + spawnListName = stripName(args[1]) + parseSpawnList(roomObjs, sceneData, spawnListName, entranceList, sharedSceneData, headerIndex) - if altHeadersListName is not None: - parseAlternateSceneHeaders(sceneObj, roomObjs, sceneData, altHeadersListName, f3dContext, sharedSceneData) + # Clear entrance list + entranceList = None + elif command == "SCENE_CMD_ALTERNATE_HEADER_LIST": + parseAlternateSceneHeaders(sceneObj, roomObjs, sceneData, stripName(args[0]), f3dContext, sharedSceneData) + elif command in {"SCENE_CMD_MINIMAP_COMPASS_ICON_INFO", "SCENE_CMD_MAP_DATA_CHESTS"}: + if sharedSceneData.includeActors: + parse_mm_map_data_chest(roomObjs, sceneHeader, sceneData, int(args[0], base=0), stripName(args[1])) + + if len(command_list) > 0: + print(f"INFO: The following scene commands weren't processed for header {headerIndex}:") + for command in command_list: + print(f"- {repr(command)}") return sceneObj diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index d07aa1d79..0643fd22d 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -51,11 +51,8 @@ def getDisplayNameFromActorID(actorID: str): def handleActorWithRotAsParam(actorProp: Z64_ActorProperty, actorID: str, rotation: list[int]): - if is_game_oot(): - if actorID in actorsWithRotAsParam: - actorProp.rotOverride = True - else: - actorProp.rotOverride = rotation[0] != 0 or rotation[1] != 0 or rotation[2] != 0 + if actorID in actorsWithRotAsParam: + actorProp.rotOverride = True if actorProp.rotOverride: actorProp.rotOverrideX = f"0x{rotation[0]:04X}" diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 06e0e4cd5..2ce2d2632 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -150,7 +150,7 @@ def draw(self, context): if obj.ootEmptyType == "Actor": actorProp: Z64_ActorProperty = obj.ootActorProperty - actorProp.draw_props(box, altRoomProp, objName) + actorProp.draw_props(box, obj, altSceneProp, altRoomProp) elif obj.ootEmptyType == "Transition Actor": transActorProp: Z64_TransitionActorProperty = obj.ootTransitionActorProperty diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 94398e7c0..90620205f 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -238,6 +238,14 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj behaviorBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") + if not is_oot_features(): + if self.mm_room_type in {"ROOM_TYPE_DUNGEON", "ROOM_TYPE_BOSS"}: + behaviorBox.label(text="The Three-Day Events actor will be automatically", icon="INFO") + behaviorBox.label(text="spawned by `Play_Init` (see 'ACTOR_EN_TEST4' usage).") + else: + behaviorBox.label(text="You will need to add the Three-Day Events actor", icon="INFO") + behaviorBox.label(text="to that room (see 'ACTOR_EN_TEST4' usage).") + # Time skyboxAndTime = layout.column() skyboxAndTime.box().label(text="Skybox And Time") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index cb117caba..3fb53d08e 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -812,6 +812,8 @@ def getCollection(objName, collectionType, subIndex: int, collection_index: int collection = obj.z64_actor_cs_property.entries elif collectionType == "Actor CS Headers": collection = obj.z64_actor_cs_property.header_settings.cutsceneHeaders + elif collectionType == "Actor Halfday": + collection = obj.ootActorProperty.halfday_bits elif collectionType == "Curve": collection = obj.ootSplineProperty.headerSettings.cutsceneHeaders elif collectionType.startswith("CSHdr."): From 16ea747f2d14e4c64f3593cc2bd627eef1f6391d Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 1 Jan 2025 16:34:14 +0100 Subject: [PATCH 040/126] post-merge fixes --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index ddec5b196..c3dfe95a3 100644 --- a/__init__.py +++ b/__init__.py @@ -23,7 +23,7 @@ from .fast64_internal.z64.constants import oot_world_defaults from .fast64_internal.z64.props_panel_main import OOT_ObjectProperties from .fast64_internal.z64.utility import getObjectList, get_cs_index_start -from .fast64_internal.oot.actor.properties import initOOTActorProperties +from .fast64_internal.z64.actor.properties import initOOTActorProperties from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister From 7c72bb66fa4b2c7d29379eebf2a1e268c79fd7ac Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 1 Jan 2025 16:37:27 +0100 Subject: [PATCH 041/126] forgot something to fix --- fast64_internal/z64/actor/operators.py | 30 +++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 7017e0564..67cb6993c 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -30,26 +30,26 @@ def invoke(self, context, event): class MM_SearchActorIDEnumOperator(Operator): bl_idname = "object.mm_search_actor_id_enum_operator" bl_label = "Select Actor ID" - bl_property = "actorID" + bl_property = "actor_id" bl_options = {"REGISTER", "UNDO"} - actorID: EnumProperty(items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") - actorUser: StringProperty(default="Actor") - objName: StringProperty() + actor_id: EnumProperty(items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") + actor_user: StringProperty(default="Actor") + obj_name: StringProperty() def execute(self, context): - obj = bpy.data.objects[self.objName] - if self.actorUser == "Transition Actor": - obj.ootTransitionActorProperty.actor.mm_actor_id = self.actorID - elif self.actorUser == "Actor": - obj.ootActorProperty.mm_actor_id = self.actorID - elif self.actorUser == "Entrance": - obj.ootEntranceProperty.actor.mm_actor_id = self.actorID + obj = bpy.data.objects[self.obj_name] + if self.actor_user == "Transition Actor": + obj.ootTransitionActorProperty.actor.mm_actor_id = self.actor_id + elif self.actor_user == "Actor": + obj.ootActorProperty.mm_actor_id = self.actor_id + elif self.actor_user == "Entrance": + obj.ootEntranceProperty.actor.mm_actor_id = self.actor_id else: - raise PluginError("Invalid actor user for search: " + str(self.actorUser)) + raise PluginError("Invalid actor user for search: " + str(self.actor_user)) context.region.tag_redraw() - self.report({"INFO"}, "Selected: " + self.actorID) + self.report({"INFO"}, "Selected: " + self.actor_id) class OOT_SearchNaviMsgIDEnumOperator(Operator): @@ -83,10 +83,6 @@ class OOT_SearchActorIDEnumOperator(Operator): actor_user: StringProperty(default="Actor") obj_name: StringProperty() - actorID: EnumProperty(items=oot_data.actorData.ootEnumActorID, default="ACTOR_PLAYER") - actorUser: StringProperty(default="Actor") - objName: StringProperty() - def execute(self, context): obj = bpy.data.objects[self.obj_name] From 2981aeba4ae291cb7f328dee874faf031b4172d7 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 01:40:15 +0100 Subject: [PATCH 042/126] update cutscene parser to handle MM commands --- fast64_internal/z64/cutscene/classes.py | 322 +++++++++++++++++- fast64_internal/z64/cutscene/constants.py | 68 ++++ .../z64/cutscene/importer/classes.py | 90 ++++- .../z64/cutscene/importer/functions.py | 3 +- fast64_internal/z64/scene/properties.py | 5 +- 5 files changed, 472 insertions(+), 16 deletions(-) diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index b7a236f77..c48f9529b 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -3,7 +3,8 @@ from dataclasses import dataclass, field from bpy.types import Object from typing import Optional -from ..constants import oot_data +from ..utility import is_oot_features, is_game_oot +from ..constants import oot_data, mm_data from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger @@ -24,8 +25,15 @@ class CutsceneCmdBase: startFrame: Optional[int] = None endFrame: Optional[int] = None + # MM doesn't have startFrame and endFrame, instead it's just the framecount + duration: Optional[int] = None + def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): - enum = oot_data.enumData.enumByKey[enumKey] + if not is_game_oot() and enumKey not in {"seqId", "destinationType", "ocarinaSongActionId", "motionBlurType", "modifySeqType", "chooseCreditsSceneType", "transitionGeneralType"}: + # remove `cs` and lowercase first letter + enumKey = enumKey[2].lower() + enumKey[3:] + + enum = oot_data.enumData.enumByKey[enumKey] if is_game_oot() else mm_data.enum_data.enum_by_key[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -55,6 +63,81 @@ def __post_init__(self): self.pos = [getInteger(self.params[4]), getInteger(self.params[5]), getInteger(self.params[6])] +# MM's new camera commands + +@dataclass +class CutsceneCmdNewCamPoint(CutsceneCmdBase): + """This class contains a single Camera Point command data (the newer version)""" + + interp_type: Optional[str] = None + weight: Optional[int] = None + pos: list[int] = field(default_factory=list) + relative_to: Optional[str] = None + paramNumber: int = 7 + size: int = 0xC + + def __post_init__(self): + if self.params is not None: + self.interp_type = self.params[0] + self.weight = getInteger(self.params[1]) + self.duration = getInteger(self.params[2]) + self.pos = [getInteger(self.params[3]), getInteger(self.params[4]), getInteger(self.params[5])] + self.relative_to = self.params[6] + + +@dataclass +class CutsceneCmdCamMisc(CutsceneCmdBase): + """This class contains the Camera Misc data""" + + camRoll: Optional[int] = None + viewAngle: Optional[float] = None + paramNumber: int = 4 + size: int = 0x8 + + def __post_init__(self): + if self.params is not None: + self.camRoll = getInteger(self.params[1]) + self.viewAngle = getInteger(self.params[2]) + + +@dataclass +class CutsceneSplinePoint: + # this is not a real command but it helps as each camera point is made of one at, one eye and one misc + at: Optional[CutsceneCmdNewCamPoint] = None + eye: Optional[CutsceneCmdNewCamPoint] = None + misc: Optional[CutsceneCmdCamMisc] = None + + +@dataclass +class CutsceneCmdCamSpline(CutsceneCmdBase): + """This class contains the Camera Spline data""" + + num_entries: Optional[int] = None + entries: list[CutsceneSplinePoint] = field(default_factory=list) + paramNumber: int = 4 + size: int = 0x8 + + def __post_init__(self): + if self.params is not None: + self.num_entries = getInteger(self.params[0]) + self.duration = getInteger(self.params[3]) + + +@dataclass +class CutsceneCmdCamSplineList(CutsceneCmdBase): + """This class contains the Camera Spline list data""" + + num_bytes: Optional[int] = None + entries: list[CutsceneCmdCamSpline] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "camSplineListNew" + size: int = 0x8 + + def __post_init__(self): + if self.params is not None: + self.num_bytes = getInteger(self.params[0]) + + @dataclass class CutsceneCmdActorCue(CutsceneCmdBase): """This class contains a single Actor Cue command data""" @@ -101,7 +184,10 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = oot_data.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key + if is_game_oot(): + self.commandType = oot_data.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key + else: + self.commandType = mm_data.enum_data.enum_by_key["cmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -195,7 +281,7 @@ def __post_init__(self): class CutsceneCmdMisc(CutsceneCmdBase): """This class contains a single misc command entry""" - type: Optional[str] = None # see ``CutsceneMiscType`` in decomp + type: Optional[str] = None # see `CutsceneMiscType` in decomp paramNumber: int = 14 def __post_init__(self): @@ -234,6 +320,20 @@ def __post_init__(self): self.type = self.getEnumValue("csTransitionType", 0) +@dataclass +class CutsceneCmdTransitionList(CutsceneCmdBase): + """This class contains Transition list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdTransition] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "transitionListNew" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) + + @dataclass class CutsceneCmdText(CutsceneCmdBase): """This class contains Text command data""" @@ -251,8 +351,8 @@ def __post_init__(self): self.endFrame = getInteger(self.params[2]) self.textId = getInteger(self.params[0]) self.type = self.getEnumValue("csTextType", 3) - self.altTextId1 = (getInteger(self.params[4]),) - self.altTextId2 = (getInteger(self.params[5]),) + self.altTextId1 = getInteger(self.params[4]) + self.altTextId2 = getInteger(self.params[5]) @dataclass @@ -285,12 +385,48 @@ def __post_init__(self): self.messageId = getInteger(self.params[3]) +@dataclass +class CutsceneCmdTextGeneric(CutsceneCmdBase): + """This class contains generic text command data""" + + textId: Optional[int] = None + topOptionBranch: Optional[int] = None + bottomOptionBranch: Optional[int] = None + paramNumber: int = 5 + id: str = "Generic" + + def __post_init__(self): + if self.params is not None: + self.textId = getInteger(self.params[0]) + self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + self.topOptionBranch = getInteger(self.params[3]) + self.bottomOptionBranch = getInteger(self.params[4]) + + +@dataclass +class CutsceneCmdTextMask(CutsceneCmdBase): + """This class contains mask/remains text command data""" + + defaultTextId: Optional[int] = None + alternativeTextId: Optional[int] = None + paramNumber: int = 4 + id: str = "Mask" + + def __post_init__(self): + if self.params is not None: + self.defaultTextId = getInteger(self.params[0]) + self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + self.alternativeTextId = getInteger(self.params[3]) + + @dataclass class CutsceneCmdTextList(CutsceneCmdBase): """This class contains Text List command data""" entryTotal: Optional[int] = None - entries: list[CutsceneCmdText | CutsceneCmdTextNone | CutsceneCmdTextOcarinaAction] = field(default_factory=list) + entries: list[CutsceneCmdText | CutsceneCmdTextNone | CutsceneCmdTextOcarinaAction | CutsceneCmdTextGeneric | CutsceneCmdTextMask] = field(default_factory=list) paramNumber: int = 1 listName: str = "textList" @@ -455,14 +591,170 @@ def __post_init__(self): class CutsceneCmdDestination(CutsceneCmdBase): """This class contains Destination command data""" - id: Optional[str] = None + type: Optional[str] = None paramNumber: int = 3 listName: str = "destination" def __post_init__(self): if self.params is not None: - self.id = self.getEnumValue("csDestination", 0) + self.type = self.getEnumValue("csDestination" if is_game_oot() else "destinationType", 0) + self.startFrame = getInteger(self.params[1]) + + +@dataclass +class CutsceneCmdDestinationList(CutsceneCmdBase): + """This class contains Destination list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdDestination] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "destinationListNew" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) + + +@dataclass +class CutsceneCmdMotionBlur(CutsceneCmdBase): + """This class contains motion blur command data""" + + type: Optional[str] = None + paramNumber: int = 3 + + def __post_init__(self): + if self.params is not None: + self.type = self.getEnumValue("motionBlurType", 0) self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + + +@dataclass +class CutsceneCmdMotionBlurList(CutsceneCmdBase): + """This class contains motion blur list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdDestination] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "motionBlurList" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) + + +@dataclass +class CutsceneCmdModifySeq(CutsceneCmdBase): + """This class contains modify seq command data""" + + type: Optional[str] = None + paramNumber: int = 3 + + def __post_init__(self): + if self.params is not None: + self.type = self.getEnumValue("modifySeqType", 0) + self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + + +@dataclass +class CutsceneCmdModifySeqList(CutsceneCmdBase): + """This class contains modify seq list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdModifySeq] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "modifySeqList" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) + + +@dataclass +class CutsceneCmdChooseCreditsScenes(CutsceneCmdBase): + """This class contains choose credits scenes command data""" + + type: Optional[str] = None + paramNumber: int = 3 + + def __post_init__(self): + if self.params is not None: + self.type = self.getEnumValue("chooseCreditsSceneType", 0) + self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + + +@dataclass +class CutsceneCmdChooseCreditsScenesList(CutsceneCmdBase): + """This class contains choose credits scenes list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdChooseCreditsScenes] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "creditsSceneList" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) + + +@dataclass +class CutsceneCmdTransitionGeneral(CutsceneCmdBase): + """This class contains transition general command data""" + + type: Optional[str] = None + rgb: list[int] = field(default_factory=list) + paramNumber: int = 6 + + def __post_init__(self): + if self.params is not None: + self.type = self.getEnumValue("transitionGeneralType", 0) + self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + self.rgb = [getInteger(self.params[3]), getInteger(self.params[4]), getInteger(self.params[5])] + + +@dataclass +class CutsceneCmdTransitionGeneralList(CutsceneCmdBase): + """This class contains transition general list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdTransitionGeneral] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "transitionGeneralList" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) + + +@dataclass +class CutsceneCmdGiveTatl(CutsceneCmdBase): + """This class contains give tatl command data""" + + giveTatl: Optional[bool] = None + paramNumber: int = 3 + + def __post_init__(self): + if self.params is not None: + self.giveTatl = self.params[0] in {"true", "1"} + self.startFrame = getInteger(self.params[1]) + self.endFrame = getInteger(self.params[2]) + + +@dataclass +class CutsceneCmdGiveTatlList(CutsceneCmdBase): + """This class contains give tatl list command data""" + + entryTotal: Optional[int] = None + entries: list[CutsceneCmdGiveTatl] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "giveTatlList" + + def __post_init__(self): + if self.params is not None: + self.entryTotal = getInteger(self.params[0]) @dataclass @@ -486,12 +778,22 @@ class Cutscene: textList: list[CutsceneCmdTextList] = field(default_factory=list) miscList: list[CutsceneCmdMiscList] = field(default_factory=list) rumbleList: list[CutsceneCmdRumbleControllerList] = field(default_factory=list) - transitionList: list[CutsceneCmdTransition] = field(default_factory=list) + transitionList: list[CutsceneCmdTransition] = field(default_factory=list) lightSettingsList: list[CutsceneCmdLightSettingList] = field(default_factory=list) timeList: list[CutsceneCmdTimeList] = field(default_factory=list) seqList: list[CutsceneCmdStartStopSeqList] = field(default_factory=list) fadeSeqList: list[CutsceneCmdFadeSeqList] = field(default_factory=list) + # lists from the new cutscene system + camSplineListNew: list[CutsceneCmdCamSplineList] = field(default_factory=list) + transitionListNew: list[CutsceneCmdTransitionList] = field(default_factory=list) + destinationListNew: list[CutsceneCmdDestinationList] = field(default_factory=list) + motionBlurList: list[CutsceneCmdMotionBlurList] = field(default_factory=list) + modifySeqList: list[CutsceneCmdModifySeqList] = field(default_factory=list) + creditsSceneList: list[CutsceneCmdChooseCreditsScenesList] = field(default_factory=list) + transitionGeneralList: list[CutsceneCmdTransitionGeneralList] = field(default_factory=list) + giveTatlList: list[CutsceneCmdGiveTatlList] = field(default_factory=list) + class CutsceneObjectFactory: """This class contains functions to create new Blender objects""" diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index b310fc075..9152ef922 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -27,6 +27,24 @@ CutsceneCmdRumbleController, CutsceneCmdRumbleControllerList, CutsceneCmdDestination, + CutsceneCmdCamSplineList, + CutsceneCmdTransitionList, + CutsceneCmdDestinationList, + CutsceneCmdMotionBlurList, + CutsceneCmdModifySeqList, + CutsceneCmdChooseCreditsScenesList, + CutsceneCmdTransitionGeneralList, + CutsceneCmdGiveTatlList, + CutsceneCmdCamSpline, + CutsceneCmdNewCamPoint, + CutsceneCmdCamMisc, + CutsceneCmdTextGeneric, + CutsceneCmdTextMask, + CutsceneCmdMotionBlur, + CutsceneCmdModifySeq, + CutsceneCmdChooseCreditsScenes, + CutsceneCmdTransitionGeneral, + CutsceneCmdGiveTatl, ) @@ -157,6 +175,8 @@ "CS_PLAY_BGM": "L_CS_START_SEQ", "CS_STOP_BGM_LIST": "CS_STOP_SEQ_LIST", "CS_STOP_BGM": "L_CS_STOP_SEQ", + "CS_BEGIN_CUTSCENE": "CS_HEADER", + "CS_END": "CS_END_OF_SCRIPT", } ootCSListCommands = [ @@ -180,6 +200,15 @@ "CS_PLAY_BGM_LIST", "CS_STOP_BGM_LIST", "CS_LIGHTING_LIST", + # from new system + "CS_CAM_SPLINE_LIST", + "CS_TRANSITION_LIST", + "CS_DESTINATION_LIST", + "CS_MOTION_BLUR_LIST", + "CS_MODIFY_SEQ_LIST", + "CS_CHOOSE_CREDITS_SCENES_LIST", + "CS_TRANSITION_GENERAL_LIST", + "CS_GIVE_TATL_LIST", ] ootCSListEntryCommands = [ @@ -204,15 +233,32 @@ "L_CS_LIGHT_SETTING", "L_CS_START_SEQ", "L_CS_STOP_SEQ", + # from new system + "CS_CAM_POINT_NEW", + "CS_CAM_MISC", + "CS_CAM_END", + "CS_CAM_SPLINE", # technically a list but treating it as an entry + "CS_TEXT_DEFAULT", + "CS_TEXT_TYPE_1", + "CS_TEXT_TYPE_3", + "CS_TEXT_BOSSES_REMAINS", + "CS_TEXT_ALL_NORMAL_MASKS", + "CS_MOTION_BLUR", + "CS_MODIFY_SEQ", + "CS_CHOOSE_CREDITS_SCENES", + "CS_TRANSITION_GENERAL", + "CS_GIVE_TATL", ] ootCSSingleCommands = [ "CS_HEADER", "CS_END_OF_SCRIPT", + # note: `CutsceneImport.correct_command_lists()` can move these ones in `ootCSListEntryCommands` "CS_TRANSITION", "CS_DESTINATION", ] + ootCSListAndSingleCommands = ootCSSingleCommands + ootCSListCommands ootCSListAndSingleCommands.remove("CS_HEADER") ootCutsceneCommandsC = ootCSSingleCommands + ootCSListCommands + ootCSListEntryCommands @@ -249,4 +295,26 @@ "CS_ACTOR_CUE_LIST": CutsceneCmdActorCueList, "CS_PLAYER_CUE_LIST": CutsceneCmdActorCueList, "CS_DESTINATION": CutsceneCmdDestination, + # from new system + "CS_CAM_SPLINE_LIST": CutsceneCmdCamSplineList, + "CS_CAM_SPLINE": CutsceneCmdCamSpline, + "CS_CAM_POINT_NEW": CutsceneCmdNewCamPoint, + "CS_CAM_MISC": CutsceneCmdCamMisc, + "CS_TRANSITION_LIST": CutsceneCmdTransitionList, + "CS_DESTINATION_LIST": CutsceneCmdDestinationList, + "CS_TEXT_DEFAULT": CutsceneCmdTextGeneric, + "CS_TEXT_TYPE_1": CutsceneCmdTextGeneric, + "CS_TEXT_TYPE_3": CutsceneCmdTextGeneric, + "CS_TEXT_BOSSES_REMAINS": CutsceneCmdTextMask, + "CS_TEXT_ALL_NORMAL_MASKS": CutsceneCmdTextMask, + "CS_MOTION_BLUR_LIST": CutsceneCmdMotionBlurList, + "CS_MOTION_BLUR": CutsceneCmdMotionBlur, + "CS_MODIFY_SEQ_LIST": CutsceneCmdModifySeqList, + "CS_MODIFY_SEQ": CutsceneCmdModifySeq, + "CS_CHOOSE_CREDITS_SCENES_LIST": CutsceneCmdChooseCreditsScenesList, + "CS_CHOOSE_CREDITS_SCENES": CutsceneCmdChooseCreditsScenes, + "CS_TRANSITION_GENERAL_LIST": CutsceneCmdTransitionGeneralList, + "CS_TRANSITION_GENERAL": CutsceneCmdTransitionGeneral, + "CS_GIVE_TATL_LIST": CutsceneCmdGiveTatlList, + "CS_GIVE_TATL": CutsceneCmdGiveTatl, } diff --git a/fast64_internal/z64/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py index 46e9df3eb..224b78f97 100644 --- a/fast64_internal/z64/cutscene/importer/classes.py +++ b/fast64_internal/z64/cutscene/importer/classes.py @@ -23,6 +23,10 @@ from ..classes import ( CutsceneCmdActorCueList, CutsceneCmdCamPoint, + CutsceneCmdNewCamPoint, + CutsceneCmdCamMisc, + CutsceneCmdCamSpline, + CutsceneSplinePoint, Cutscene, CutsceneObjectFactory, ) @@ -50,10 +54,20 @@ class CutsceneImport(CutsceneObjectFactory): filePath: Optional[str] # used when importing from the panel fileData: Optional[str] # used when importing the cutscenes when importing a scene csName: Optional[str] # used when import a specific cutscene + new_cs_system: bool def getCmdParams(self, data: str, cmdName: str, paramNumber: int): """Returns the list of every parameter of the given command""" + # kinda hacky but better than duplicating the classes + if self.new_cs_system: + if cmdName in {"CS_START_SEQ", "CS_FADE_OUT_SEQ", "CS_LIGHT_SETTING"}: + paramNumber = 3 + elif cmdName in {"CS_MISC", "CS_STOP_SEQ"}: + paramNumber = 4 + elif cmdName in {"CS_RUMBLE_CONTROLLER"}: + paramNumber = 6 + parenthesis = "(" if not cmdName.endswith("(") else "" data = data.strip().removeprefix(f"{cmdName}{parenthesis}").replace(" ", "").removesuffix(")") if "CS_FLOAT" in data: @@ -71,6 +85,16 @@ def getCmdParams(self, data: str, cmdName: str, paramNumber: int): def getNewCutscene(self, csData: str, name: str): params = self.getCmdParams(csData, "CS_HEADER", Cutscene.paramNumber) return Cutscene(name, getInteger(params[0]), getInteger(params[1])) + + def correct_command_lists(self, command: str): + """If using the new cs system, moves standalone commands to the proper lists""" + if self.new_cs_system: + if command in ootCSSingleCommands: + ootCSSingleCommands.remove(command) + if command in ootCSListAndSingleCommands: + ootCSListAndSingleCommands.remove(command) + if command not in ootCSListEntryCommands: + ootCSListEntryCommands.append(command) def getParsedCutscenes(self): """Returns the parsed commands read from every cutscene we can find""" @@ -85,6 +109,9 @@ def getParsedCutscenes(self): else: raise PluginError("ERROR: File data can't be found!") + self.correct_command_lists("CS_TRANSITION") + self.correct_command_lists("CS_DESTINATION") + # replace old names oldNames = list(ootCSLegacyToNewCmdNames.keys()) fileData = fileData.replace("CS_CMD_CONTINUE", "CS_CAM_CONTINUE") @@ -92,6 +119,11 @@ def getParsedCutscenes(self): for oldName in oldNames: fileData = fileData.replace(f"{oldName}(", f"{ootCSLegacyToNewCmdNames[oldName]}(") + # handle conflicts between the cs system of OoT and MM + if self.new_cs_system: + fileData = fileData.replace("CS_CAM_POINT", "CS_CAM_POINT_NEW") + fileData = fileData.replace("CS_RUMBLE", "CS_RUMBLE_CONTROLLER") + # make a list of existing cutscene names, to skip importing them if found existingCutsceneNames = [ csObj.name.removeprefix("Cutscene.") @@ -235,7 +267,63 @@ def getCutsceneList(self): else: commandData = cmd(params) - if cmdListName != "CS_TRANSITION" and cmdListName != "CS_DESTINATION": + # treating camera commands separately if using the new cs commands + # as it became more complex to parse since it's basically a list in a list in a list + if self.new_cs_system and "CAM" in cmdListName: + foundEndCmd = False + cur_point = 0 + at_list: list[CutsceneCmdNewCamPoint] = [] + eye_list: list[CutsceneCmdNewCamPoint] = [] + misc_list: list[CutsceneCmdCamMisc] = [] + cur_spline_entry: Optional[CutsceneCmdCamSpline] = None + for d in cmdData: + cmdEntryName = d.strip().split("(")[0] + + if foundEndCmd: + raise ValueError("ERROR: More camera commands after last one!") + + if "CS_CAM_END" in d: + foundEndCmd = True + continue + + entryCmd = cmdToClass[cmdEntryName] + params = self.getCmdParams(d, cmdEntryName, entryCmd.paramNumber) + listEntry = entryCmd(params) + + if cmdEntryName == "CS_CAM_SPLINE": + cur_spline_entry = listEntry + elif cur_spline_entry is not None: + sub_list_entry = cmdToClass[cmdEntryName] + sub_params = self.getCmdParams(d, cmdEntryName, sub_list_entry.paramNumber) + + if cur_point < cur_spline_entry.num_entries: + at_list.append(sub_list_entry(sub_params)) + cur_point += 1 + elif cur_point < cur_spline_entry.num_entries * 2: + eye_list.append(sub_list_entry(sub_params)) + cur_point += 1 + elif cur_point < cur_spline_entry.num_entries * 3: + misc_list.append(sub_list_entry(sub_params)) + cur_point += 1 + + if cur_point == cur_spline_entry.num_entries * 3: + assert len(at_list) == len(eye_list) == len(misc_list) + + for at, eye, misc in zip(at_list, eye_list, misc_list): + cur_spline_entry.entries.append(CutsceneSplinePoint(at, eye, misc)) + + commandData.entries.append(cur_spline_entry) + cur_point = 0 + at_list.clear() + eye_list.clear() + misc_list.clear() + cur_spline_entry = None + else: + raise ValueError("ERROR: Invalid number of entries.") + elif cmdListName != "CS_TRANSITION" and cmdListName != "CS_DESTINATION": + # this condition still works for both versions since the list name actually ends with "_LIST", + # same thing in the next if/else block when it adds the data to the `Cutscene` class + foundEndCmd = False for d in cmdData: cmdEntryName = d.strip().split("(")[0] diff --git a/fast64_internal/z64/cutscene/importer/functions.py b/fast64_internal/z64/cutscene/importer/functions.py index 20e562f76..6ca73d7bd 100644 --- a/fast64_internal/z64/cutscene/importer/functions.py +++ b/fast64_internal/z64/cutscene/importer/functions.py @@ -2,10 +2,11 @@ from typing import Optional from .classes import CutsceneImport +from ...utility import is_oot_features def importCutsceneData(filePath: Optional[str], sceneData: Optional[str], csName: Optional[str] = None): """Initialises and imports the cutscene data from either a file or the scene data""" # NOTE: ``sceneData`` is the data read when importing a scene - csMotionImport = CutsceneImport(filePath, sceneData, csName) + csMotionImport = CutsceneImport(filePath, sceneData, csName, not is_oot_features()) return csMotionImport.setCutsceneData(bpy.context.scene.ootCSNumber) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 0b69313a4..5f5f2f874 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -725,10 +725,7 @@ def draw_props(self, layout: UILayout, sceneOption: str): includeButtons3 = col.row(align=True) includeButtons3.prop(self, "includePaths", toggle=1) includeButtons3.prop(self, "includeWaterBoxes", toggle=1) - - # TODO: implement cutscenes for MM features - if is_oot_features(): - includeButtons3.prop(self, "includeCutscenes", toggle=1) + includeButtons3.prop(self, "includeCutscenes", toggle=1) includeButtons4 = col.row(align=True) if not is_oot_features(): From e4fbb1ca881cfe02d41b16655ea56837dad2ab27 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 01:44:17 +0100 Subject: [PATCH 043/126] add note about size --- fast64_internal/z64/cutscene/classes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index c48f9529b..28d39e705 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -14,6 +14,9 @@ def cs_import_float(v_str: str): # NOTE: ``paramNumber`` is the expected number of parameters inside the parsed commands, # this account for the unused parameters. Every classes are based on the commands arguments from ``z64cutscene_commands.h`` +# +# some commands have a `size` attribute, it's purpose is for the exporter as +# MM's camera command requires the size of the camera data in bytes @dataclass From 0e2b27ef80c8b59ebc908bbd2c93057051dcc6c6 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:21:15 +0100 Subject: [PATCH 044/126] checkpoint --- __init__.py | 74 ++++++++++++++++++++++----------- fast64_internal/__init__.py | 5 --- fast64_internal/constants.py | 11 +++++ fast64_internal/oot/__init__.py | 30 +++++++------ fast64_internal/utility.py | 5 ++- 5 files changed, 82 insertions(+), 43 deletions(-) delete mode 100644 fast64_internal/__init__.py create mode 100644 fast64_internal/constants.py diff --git a/__init__.py b/__init__.py index 1a67b172b..fd443d14f 100644 --- a/__init__.py +++ b/__init__.py @@ -5,6 +5,7 @@ from . import addon_updater_ops from .fast64_internal.utility import prop_split, multilineLabel, set_prop_if_in_data +from .fast64_internal.constants import GameData, game_data from .fast64_internal.repo_settings import ( draw_repo_settings, @@ -19,10 +20,9 @@ from .fast64_internal.sm64.sm64_geolayout_bone import SM64_BoneProperties from .fast64_internal.sm64.sm64_objects import SM64_ObjectProperties -from .fast64_internal.oot import OOT_Properties, oot_register, oot_unregister +from .fast64_internal.oot import OOT_Properties, oot_register, oot_unregister, z64_register_on_enable from .fast64_internal.oot.oot_constants import oot_world_defaults from .fast64_internal.oot.props_panel_main import OOT_ObjectProperties -from .fast64_internal.oot.actor.properties import initOOTActorProperties from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister @@ -298,24 +298,6 @@ def execute(self, context: "bpy.types.Context"): return {"FINISHED"} -# def updateGameEditor(scene, context): -# if scene.currentGameEditorMode == 'SM64': -# sm64_panel_unregister() -# elif scene.currentGameEditorMode == 'Z64': -# oot_panel_unregister() -# else: -# raise PluginError("Unhandled game editor mode " + str(scene.currentGameEditorMode)) -# -# if scene.gameEditorMode == 'SM64': -# sm64_panel_register() -# elif scene.gameEditorMode == 'Z64': -# oot_panel_register() -# else: -# raise PluginError("Unhandled game editor mode " + str(scene.gameEditorMode)) -# -# scene.currentGameEditorMode = scene.gameEditorMode - - class ExampleAddonPreferences(bpy.types.AddonPreferences, addon_updater_ops.AddonUpdaterPreferences): bl_idname = __package__ @@ -368,8 +350,46 @@ def upgrade_scene_props_node(): bpy.ops.dialog.upgrade_f3d_materials("INVOKE_DEFAULT") +def update_game_data(): + """This function should be called on blend load or game editor update""" + + def init_game_data(): + global game_data + game_data = GameData(bpy.context.scene.gameEditorMode) + + match bpy.context.scene.gameEditorMode: + case "OOT": + from .fast64_internal.oot.actor.properties import initOOTActorProperties + + initOOTActorProperties() + oot_register(True) + case _: + print(f"[init_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") + return + + print(f"[init_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") + + def destroy_game_data(): + match bpy.context.scene.gameEditorMode: + case "OOT": + oot_unregister(True) + case _: + print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") + return + + print(f"[destroy_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") + + try: + init_game_data() + except ValueError: + destroy_game_data() + init_game_data() + + @bpy.app.handlers.persistent def after_load(_a, _b): + update_game_data() + settings = bpy.context.scene.fast64.settings if any(mat.is_f3d for mat in bpy.data.materials): check_or_ask_color_management(bpy.context) @@ -402,11 +422,12 @@ def set_game_defaults(scene: bpy.types.Scene, set_ucode=True): world_defaults = {} # This will set some pretty bad defaults, but trust the user if set_ucode: scene.f3d_type = f3d_type - if scene.world is not None: + if scene.world is not None and world_defaults is not None: scene.world.rdp_defaults.from_dict(world_defaults) def gameEditorUpdate(scene: bpy.types.Scene, _context): + update_game_data() set_game_defaults(scene) @@ -431,17 +452,18 @@ def register(): register_class(ExampleAddonPreferences) addon_updater_ops.register(bl_info) - initOOTActorProperties() utility_anim_register() mat_register() render_engine_register() bsdf_conv_register() sm64_register(True) - oot_register(True) mk64_register(True) repo_settings_operators_register() + for cls in z64_register_on_enable: + register_class(cls) + for cls in classes: register_class(cls) @@ -484,7 +506,6 @@ def unregister(): f3d_writer_unregister() f3d_parser_unregister() sm64_unregister(True) - oot_unregister(True) mk64_unregister(True) mat_unregister() bsdf_conv_unregister() @@ -504,7 +525,10 @@ def unregister(): repo_settings_operators_unregister() - for cls in classes: + for cls in reversed(classes): + unregister_class(cls) + + for cls in reversed(z64_register_on_enable): unregister_class(cls) bpy.app.handlers.load_post.remove(after_load) diff --git a/fast64_internal/__init__.py b/fast64_internal/__init__.py deleted file mode 100644 index 6bb605c2a..000000000 --- a/fast64_internal/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .f3d_material_converter import * -from .f3d import * -from .sm64 import * -from .oot import * # is this really needed? -from .panels import * diff --git a/fast64_internal/constants.py b/fast64_internal/constants.py new file mode 100644 index 000000000..36114e1c1 --- /dev/null +++ b/fast64_internal/constants.py @@ -0,0 +1,11 @@ +from typing import Optional + + +class GameData: + def __init__(self, game_editor_mode: Optional[str] = None): + from .oot.data import OoT_Data + + self.z64 = OoT_Data() + + +game_data = GameData() diff --git a/fast64_internal/oot/__init__.py b/fast64_internal/oot/__init__.py index 5c4bd90a8..7dfb36f3a 100644 --- a/fast64_internal/oot/__init__.py +++ b/fast64_internal/oot/__init__.py @@ -5,7 +5,7 @@ from .scene.properties import OOTBootupSceneOptions, scene_props_register, scene_props_unregister from .scene.panels import scene_panels_register, scene_panels_unregister -from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister +from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister, OOT_ObjectProperties, OOTSceneProperties from .skeleton.properties import OOTSkeletonImportSettings, OOTSkeletonExportSettings from .oot_utility import oot_utility_register, oot_utility_unregister, setAllActorsVisibility from .file_settings import file_register, file_unregister @@ -112,7 +112,19 @@ def get_extracted_path(self): ) -oot_classes = (OOT_Properties,) +z64_register_on_enable = ( + OOTBootupSceneOptions, + OOTDLExportSettings, + OOTDLImportSettings, + OOTSkeletonExportSettings, + OOTSkeletonImportSettings, + OOTAnimExportSettingsProperty, + OOTAnimImportSettingsProperty, + OOTCollisionExportSettings, + OOT_Properties, + OOTSceneProperties, + OOT_ObjectProperties, +) def oot_panel_register(): @@ -139,7 +151,7 @@ def oot_panel_unregister(): skeleton_panels_unregister() -def oot_register(registerPanels): +def oot_register(registerPanels: bool): oot_operator_register() oot_utility_register() collision_ops_register() # register first, so panel goes above mat panel @@ -168,16 +180,13 @@ def oot_register(registerPanels): csMotion_preview_register() cutscene_preview_register() - for cls in oot_classes: - register_class(cls) - if registerPanels: oot_panel_register() -def oot_unregister(unregisterPanels): - for cls in reversed(oot_classes): - unregister_class(cls) +def oot_unregister(unregisterPanels: bool): + if unregisterPanels: + oot_panel_unregister() oot_operator_unregister() oot_utility_unregister() @@ -206,6 +215,3 @@ def oot_unregister(unregisterPanels): csMotion_panels_unregister() csMotion_props_unregister() csMotion_ops_unregister() - - if unregisterPanels: - oot_panel_unregister() diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index fceff5450..b72694a94 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -3,9 +3,12 @@ from math import pi, ceil, degrees, radians, copysign from mathutils import * from .utility_anim import * -from typing import Callable, Iterable, Any, Optional, Tuple, TypeVar, Union +from typing import Callable, Iterable, Any, Optional, Tuple, TypeVar, Union, TYPE_CHECKING from bpy.types import UILayout, Scene, World +if TYPE_CHECKING: + from .f3d.f3d_material import F3DMaterialProperty + CollectionProperty = Any # collection prop as defined by using bpy.props.CollectionProperty From a210c0c0b22ed1b99bcbcf77f589c18bf2d284bc Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:23:24 +0100 Subject: [PATCH 045/126] checkpoint 2 --- fast64_internal/oot/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fast64_internal/oot/__init__.py b/fast64_internal/oot/__init__.py index 7dfb36f3a..79e9d86df 100644 --- a/fast64_internal/oot/__init__.py +++ b/fast64_internal/oot/__init__.py @@ -14,9 +14,6 @@ from .room.operators import room_ops_register, room_ops_unregister from .room.properties import room_props_register, room_props_unregister -from .actor.operators import actor_ops_register, actor_ops_unregister -from .actor.properties import actor_props_register, actor_props_unregister - from .f3d.operators import f3d_ops_register, f3d_ops_unregister from .f3d.properties import OOTDLExportSettings, OOTDLImportSettings, f3d_props_register, f3d_props_unregister from .f3d.panels import f3d_panels_register, f3d_panels_unregister @@ -152,6 +149,9 @@ def oot_panel_unregister(): def oot_register(registerPanels: bool): + from .actor.operators import actor_ops_register + from .actor.properties import actor_props_register + oot_operator_register() oot_utility_register() collision_ops_register() # register first, so panel goes above mat panel @@ -185,6 +185,9 @@ def oot_register(registerPanels: bool): def oot_unregister(unregisterPanels: bool): + from .actor.operators import actor_ops_unregister + from .actor.properties import actor_props_unregister + if unregisterPanels: oot_panel_unregister() From 9bcc368966a9b836faf8d6f2ece7d2d2f448b8bc Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:25:13 +0100 Subject: [PATCH 046/126] checkpoint 3 --- fast64_internal/oot/animation/properties.py | 2 -- fast64_internal/oot/collision/properties.py | 1 - fast64_internal/oot/f3d/properties.py | 2 -- fast64_internal/oot/scene/properties.py | 1 - fast64_internal/oot/skeleton/properties.py | 2 -- 5 files changed, 8 deletions(-) diff --git a/fast64_internal/oot/animation/properties.py b/fast64_internal/oot/animation/properties.py index ab3a641c9..46234c999 100644 --- a/fast64_internal/oot/animation/properties.py +++ b/fast64_internal/oot/animation/properties.py @@ -69,8 +69,6 @@ def draw_props(self, layout: UILayout): classes = ( - OOTAnimExportSettingsProperty, - OOTAnimImportSettingsProperty, OOTLinkTextureAnimProperty, ) diff --git a/fast64_internal/oot/collision/properties.py b/fast64_internal/oot/collision/properties.py index 2b2373773..ad20ff830 100644 --- a/fast64_internal/oot/collision/properties.py +++ b/fast64_internal/oot/collision/properties.py @@ -139,7 +139,6 @@ def draw_props(self, layout: UILayout): oot_col_classes = ( - OOTCollisionExportSettings, OOTCameraPositionProperty, OOTMaterialCollisionProperty, OOTWaterBoxProperty, diff --git a/fast64_internal/oot/f3d/properties.py b/fast64_internal/oot/f3d/properties.py index d4c0e4772..970e2371d 100644 --- a/fast64_internal/oot/f3d/properties.py +++ b/fast64_internal/oot/f3d/properties.py @@ -177,8 +177,6 @@ def draw_props(self, layout: UILayout): oot_dl_writer_classes = ( - OOTDLExportSettings, - OOTDLImportSettings, OOTDynamicMaterialDrawLayerProperty, OOTDynamicMaterialProperty, OOTDefaultRenderModesProperty, diff --git a/fast64_internal/oot/scene/properties.py b/fast64_internal/oot/scene/properties.py index b48948e06..247521ea5 100644 --- a/fast64_internal/oot/scene/properties.py +++ b/fast64_internal/oot/scene/properties.py @@ -563,7 +563,6 @@ def draw_props(self, layout: UILayout, sceneOption: str): OOTExtraCutsceneProperty, OOTSceneHeaderProperty, OOTAlternateSceneHeaderProperty, - OOTBootupSceneOptions, OOTRemoveSceneSettingsProperty, OOTExportSceneSettingsProperty, OOTImportSceneSettingsProperty, diff --git a/fast64_internal/oot/skeleton/properties.py b/fast64_internal/oot/skeleton/properties.py index daa0e9c43..e886ac990 100644 --- a/fast64_internal/oot/skeleton/properties.py +++ b/fast64_internal/oot/skeleton/properties.py @@ -163,8 +163,6 @@ def draw_props(self, layout: UILayout): OOTDynamicTransformProperty, OOTBoneProperty, OOTSkeletonProperty, - OOTSkeletonExportSettings, - OOTSkeletonImportSettings, ) From 883d14e91cbd3c82e0120a97272c992f70715481 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:26:04 +0100 Subject: [PATCH 047/126] checkpoint 4 --- fast64_internal/oot/props_panel_main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/fast64_internal/oot/props_panel_main.py b/fast64_internal/oot/props_panel_main.py index 331a54d04..5963cd363 100644 --- a/fast64_internal/oot/props_panel_main.py +++ b/fast64_internal/oot/props_panel_main.py @@ -236,8 +236,6 @@ def draw_props(self, layout: bpy.types.UILayout): oot_obj_classes = ( - OOTSceneProperties, - OOT_ObjectProperties, OOTCullGroupProperty, OOT_ManualUpgrade, ) From 179596fe1628a811dab14eee2a58fece422f19a4 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:54:48 +0100 Subject: [PATCH 048/126] checkpoint 5 --- __init__.py | 3 -- fast64_internal/oot/actor/properties.py | 57 +++++++++++++------------ fast64_internal/utility.py | 10 +++++ 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/__init__.py b/__init__.py index fd443d14f..4f4572947 100644 --- a/__init__.py +++ b/__init__.py @@ -359,9 +359,6 @@ def init_game_data(): match bpy.context.scene.gameEditorMode: case "OOT": - from .fast64_internal.oot.actor.properties import initOOTActorProperties - - initOOTActorProperties() oot_register(True) case _: print(f"[init_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") diff --git a/fast64_internal/oot/actor/properties.py b/fast64_internal/oot/actor/properties.py index 8236b078e..52b44aa7b 100644 --- a/fast64_internal/oot/actor/properties.py +++ b/fast64_internal/oot/actor/properties.py @@ -1,8 +1,9 @@ from bpy.types import Object, PropertyGroup, UILayout from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty -from ...utility import PluginError, prop_split, label_split -from ..oot_constants import ootData, ootEnumCamTransition +from ...utility import PluginError, prop_split, label_split, get_prop_annotations +from ...constants import game_data +from ..oot_constants import ootEnumCamTransition from ..oot_upgrade import upgradeActors from ..scene.properties import OOTAlternateSceneHeaderProperty from ..room.properties import OOTAlternateRoomHeaderProperty @@ -49,18 +50,17 @@ def get_prop_name(actor_key: str, param_type: str, param_subtype: str, param_ind def initOOTActorProperties(): """This function is used to edit the OOTActorProperty class""" - prop_annotations = getattr(OOTActorProperty, "__annotations__", None) + prop_ats = get_prop_annotations(OOTActorProperty) - if prop_annotations is None: - OOTActorProperty.__annotations__ = prop_annotations = {} + prop_ats["actor_id"] = EnumProperty(name="Actor", items=game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER") param_type_to_enum_items = { - "ChestContent": ootData.actorData.ootEnumChestContent, - "Collectible": ootData.actorData.ootEnumCollectibleItems, - "Message": ootData.actorData.ootEnumNaviMessageData, + "ChestContent": game_data.z64.actorData.ootEnumChestContent, + "Collectible": game_data.z64.actorData.ootEnumCollectibleItems, + "Message": game_data.z64.actorData.ootEnumNaviMessageData, } - for actor in ootData.actorData.actorList: + for actor in game_data.z64.actorData.actorList: for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) enum_items = None @@ -72,14 +72,14 @@ def initOOTActorProperties(): enum_items = param_type_to_enum_items[param.type] if param.type in {"Property", "Flag"}: - prop_annotations[prop_name] = StringProperty(name="", default="0x0") + prop_ats[prop_name] = StringProperty(name="", default="0x0") elif param.type == "Bool": - prop_annotations[prop_name] = BoolProperty(name="", default=False) + prop_ats[prop_name] = BoolProperty(name="", default=False) elif param.type in {"Type", "Enum", "ChestContent", "Collectible", "Message"} and enum_items is not None: - prop_annotations[prop_name] = EnumProperty(name="", items=enum_items, default=enum_items[1][0]) + prop_ats[prop_name] = EnumProperty(name="", items=enum_items, default=enum_items[1][0]) if param.type in {"Type", "Enum", "ChestContent", "Collectible", "Message"}: - prop_annotations[f"{prop_name}_custom"] = StringProperty(name="", default="0x0") + prop_ats[f"{prop_name}_custom"] = StringProperty(name="", default="0x0") class OOTActorHeaderItemProperty(PropertyGroup): @@ -167,7 +167,6 @@ def draw_props( class OOTActorProperty(PropertyGroup): - actor_id: EnumProperty(name="Actor", items=ootData.actorData.ootEnumActorID, default="ACTOR_PLAYER") actor_id_custom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") # only used for actors with the id "Custom" @@ -214,7 +213,7 @@ def upgrade_object(obj: Object): upgradeActors(obj) def is_rotation_used(self, target: str): - actor = ootData.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: @@ -242,7 +241,7 @@ def is_value_in_range(self, value: int, min: int, max: int): return True def set_param_value(self, base_value: str | bool, target: str): - actor = ootData.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] base_value = getEvalParamsInt(base_value) found_type = None @@ -266,11 +265,11 @@ def set_param_value(self, base_value: str | bool, target: str): prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) if param.type == "ChestContent": - prop_value = ootData.actorData.chestItemByValue[value].key + prop_value = game_data.z64.actorData.chestItemByValue[value].key elif param.type == "Collectible": - prop_value = ootData.actorData.collectibleItemsByValue[value].key + prop_value = game_data.z64.actorData.collectibleItemsByValue[value].key elif param.type == "Message": - prop_value = ootData.actorData.messageItemsByValue[value].key + prop_value = game_data.z64.actorData.messageItemsByValue[value].key elif param.type == "Bool": prop_value = bool(value) else: @@ -288,7 +287,7 @@ def set_param_value(self, base_value: str | bool, target: str): ) def get_param_value(self, target: str): - actor = ootData.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] param_list = [] type_value = None have_custom_value = False @@ -325,11 +324,11 @@ def get_param_value(self, target: str): param_val = 0 if param.type == "ChestContent": - param_val = ootData.actorData.chestItemByKey[cur_prop_value].value + param_val = game_data.z64.actorData.chestItemByKey[cur_prop_value].value elif param.type == "Collectible": - param_val = ootData.actorData.collectibleItemsByKey[cur_prop_value].value + param_val = game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value elif param.type == "Message": - param_val = ootData.actorData.messageItemsByKey[cur_prop_value].value + param_val = game_data.z64.actorData.messageItemsByKey[cur_prop_value].value if "Rot" in target: type_value = getEvalParamsInt(getattr(self, get_prop_name(actor.key, "Type", None, 1))) @@ -382,7 +381,7 @@ def get_param_value(self, target: str): return param_str def draw_params(self, layout: UILayout, obj: Object): - actor = ootData.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: @@ -407,11 +406,11 @@ def draw_params(self, layout: UILayout, obj: Object): if param.type == "ChestContent": search_op = layout.operator(OOT_SearchChestContentEnumOperator.bl_idname) label_name = "Chest Content" - item_map = ootData.actorData.chestItemByKey + item_map = game_data.z64.actorData.chestItemByKey else: search_op = layout.operator(OOT_SearchNaviMsgIDEnumOperator.bl_idname) label_name = "Navi Message ID" - item_map = ootData.actorData.messageItemsByKey + item_map = game_data.z64.actorData.messageItemsByKey search_op.obj_name = obj.name search_op.prop_name = prop_name @@ -440,7 +439,7 @@ def draw_props(self, layout: UILayout, altRoomProp: OOTAlternateRoomHeaderProper return split.label(text="Actor ID") - split.label(text=getEnumName(ootData.actorData.ootEnumActorID, self.actor_id)) + split.label(text=getEnumName(game_data.z64.actorData.ootEnumActorID, self.actor_id)) if self.actor_id != "Custom": self.draw_params(actorIDBox, obj) @@ -502,7 +501,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - split.label(text=getEnumName(ootData.actorData.ootEnumActorID, self.actor.actor_id)) + split.label(text=getEnumName(game_data.z64.actorData.ootEnumActorID, self.actor.actor_id)) if self.actor.actor_id == "Custom": prop_split(actorIDBox, self.actor, "actor_id_custom", "") @@ -588,6 +587,8 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: OOTAlternateSc def actor_props_register(): + initOOTActorProperties() + for cls in classes: register_class(cls) diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index b72694a94..2e0280f7e 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -1912,3 +1912,13 @@ def set_if_different(owner: object, prop: str, value): def set_prop_if_in_data(owner: object, prop_name: str, data: dict, data_name: str): if data_name in data: set_if_different(owner, prop_name, data[data_name]) + + +def get_prop_annotations(cls): + prop_annotations = getattr(cls, "__annotations__", None) + + if prop_annotations is None: + setattr(cls, "__annotations__", dict()) + prop_annotations = getattr(cls, "__annotations__") + + return prop_annotations From bd4bc84bb0be59171439ede70f64efc421d5d226 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:58:20 +0100 Subject: [PATCH 049/126] move data outside oot submodule --- fast64_internal/constants.py | 2 +- fast64_internal/{oot/data => data/oot}/__init__.py | 0 fast64_internal/{oot/data => data/oot}/oot_actor_data.py | 0 fast64_internal/{oot/data => data/oot}/oot_data.py | 0 fast64_internal/{oot/data => data/oot}/oot_enum_data.py | 0 fast64_internal/{oot/data => data/oot}/oot_getters.py | 0 fast64_internal/{oot/data => data/oot}/oot_object_data.py | 0 fast64_internal/{oot/data => data/oot}/xml/ActorList.xml | 0 fast64_internal/{oot/data => data/oot}/xml/EnumData.xml | 0 fast64_internal/{oot/data => data/oot}/xml/ObjectList.xml | 0 fast64_internal/oot/oot_constants.py | 2 +- fast64_internal/oot/oot_upgrade.py | 2 +- 12 files changed, 3 insertions(+), 3 deletions(-) rename fast64_internal/{oot/data => data/oot}/__init__.py (100%) rename fast64_internal/{oot/data => data/oot}/oot_actor_data.py (100%) rename fast64_internal/{oot/data => data/oot}/oot_data.py (100%) rename fast64_internal/{oot/data => data/oot}/oot_enum_data.py (100%) rename fast64_internal/{oot/data => data/oot}/oot_getters.py (100%) rename fast64_internal/{oot/data => data/oot}/oot_object_data.py (100%) rename fast64_internal/{oot/data => data/oot}/xml/ActorList.xml (100%) rename fast64_internal/{oot/data => data/oot}/xml/EnumData.xml (100%) rename fast64_internal/{oot/data => data/oot}/xml/ObjectList.xml (100%) diff --git a/fast64_internal/constants.py b/fast64_internal/constants.py index 36114e1c1..0786ae3e4 100644 --- a/fast64_internal/constants.py +++ b/fast64_internal/constants.py @@ -3,7 +3,7 @@ class GameData: def __init__(self, game_editor_mode: Optional[str] = None): - from .oot.data import OoT_Data + from .data.oot import OoT_Data self.z64 = OoT_Data() diff --git a/fast64_internal/oot/data/__init__.py b/fast64_internal/data/oot/__init__.py similarity index 100% rename from fast64_internal/oot/data/__init__.py rename to fast64_internal/data/oot/__init__.py diff --git a/fast64_internal/oot/data/oot_actor_data.py b/fast64_internal/data/oot/oot_actor_data.py similarity index 100% rename from fast64_internal/oot/data/oot_actor_data.py rename to fast64_internal/data/oot/oot_actor_data.py diff --git a/fast64_internal/oot/data/oot_data.py b/fast64_internal/data/oot/oot_data.py similarity index 100% rename from fast64_internal/oot/data/oot_data.py rename to fast64_internal/data/oot/oot_data.py diff --git a/fast64_internal/oot/data/oot_enum_data.py b/fast64_internal/data/oot/oot_enum_data.py similarity index 100% rename from fast64_internal/oot/data/oot_enum_data.py rename to fast64_internal/data/oot/oot_enum_data.py diff --git a/fast64_internal/oot/data/oot_getters.py b/fast64_internal/data/oot/oot_getters.py similarity index 100% rename from fast64_internal/oot/data/oot_getters.py rename to fast64_internal/data/oot/oot_getters.py diff --git a/fast64_internal/oot/data/oot_object_data.py b/fast64_internal/data/oot/oot_object_data.py similarity index 100% rename from fast64_internal/oot/data/oot_object_data.py rename to fast64_internal/data/oot/oot_object_data.py diff --git a/fast64_internal/oot/data/xml/ActorList.xml b/fast64_internal/data/oot/xml/ActorList.xml similarity index 100% rename from fast64_internal/oot/data/xml/ActorList.xml rename to fast64_internal/data/oot/xml/ActorList.xml diff --git a/fast64_internal/oot/data/xml/EnumData.xml b/fast64_internal/data/oot/xml/EnumData.xml similarity index 100% rename from fast64_internal/oot/data/xml/EnumData.xml rename to fast64_internal/data/oot/xml/EnumData.xml diff --git a/fast64_internal/oot/data/xml/ObjectList.xml b/fast64_internal/data/oot/xml/ObjectList.xml similarity index 100% rename from fast64_internal/oot/data/xml/ObjectList.xml rename to fast64_internal/data/oot/xml/ObjectList.xml diff --git a/fast64_internal/oot/oot_constants.py b/fast64_internal/oot/oot_constants.py index a0b33813c..31403665f 100644 --- a/fast64_internal/oot/oot_constants.py +++ b/fast64_internal/oot/oot_constants.py @@ -1,4 +1,4 @@ -from .data import OoT_Data +from ..data.oot import OoT_Data ootData = OoT_Data() diff --git a/fast64_internal/oot/oot_upgrade.py b/fast64_internal/oot/oot_upgrade.py index d575615c0..802f81bff 100644 --- a/fast64_internal/oot/oot_upgrade.py +++ b/fast64_internal/oot/oot_upgrade.py @@ -5,7 +5,7 @@ import bpy from bpy.types import Object, CollectionProperty from ..utility import PluginError -from .data import OoT_ObjectData +from ..data.oot import OoT_ObjectData from .oot_utility import getEvalParams, get_actor_prop_from_obj from .oot_constants import ootData from .cutscene.constants import ootEnumCSMotionCamMode From 8dae77a4d7e932792c44b75cde8b045e7b8aa0eb Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:05:34 +0100 Subject: [PATCH 050/126] use game in detailed actor props --- fast64_internal/oot/actor/properties.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fast64_internal/oot/actor/properties.py b/fast64_internal/oot/actor/properties.py index 52b44aa7b..6fc31ec8c 100644 --- a/fast64_internal/oot/actor/properties.py +++ b/fast64_internal/oot/actor/properties.py @@ -1,3 +1,5 @@ +import bpy + from bpy.types import Object, PropertyGroup, UILayout from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty @@ -44,7 +46,7 @@ def get_prop_name(actor_key: str, param_type: str, param_subtype: str, param_ind "Message": "naviMsg", } suffix = param_to_prop_suffix[param_type] if param_type != "Flag" else flag_to_prop_suffix[param_subtype] - return f"{actor_key}.{suffix}{param_index}" # e.g.: ``en_test.props1`` + return f"{bpy.context.scene.gameEditorMode.lower()}.{actor_key}.{suffix}{param_index}" # e.g.: ``en_test.props1`` def initOOTActorProperties(): From ac9ded661ac1867500a582d2601c1dabe355a60a Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:55:19 +0100 Subject: [PATCH 051/126] format --- __init__.py | 2 +- fast64_internal/oot/__init__.py | 9 ++++++++- fast64_internal/oot/actor/properties.py | 4 +++- fast64_internal/oot/animation/properties.py | 4 +--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/__init__.py b/__init__.py index 4f4572947..759a3fbf9 100644 --- a/__init__.py +++ b/__init__.py @@ -373,7 +373,7 @@ def destroy_game_data(): case _: print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") return - + print(f"[destroy_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") try: diff --git a/fast64_internal/oot/__init__.py b/fast64_internal/oot/__init__.py index 79e9d86df..0b859dfcc 100644 --- a/fast64_internal/oot/__init__.py +++ b/fast64_internal/oot/__init__.py @@ -5,7 +5,14 @@ from .scene.properties import OOTBootupSceneOptions, scene_props_register, scene_props_unregister from .scene.panels import scene_panels_register, scene_panels_unregister -from .props_panel_main import oot_obj_panel_register, oot_obj_panel_unregister, oot_obj_register, oot_obj_unregister, OOT_ObjectProperties, OOTSceneProperties +from .props_panel_main import ( + oot_obj_panel_register, + oot_obj_panel_unregister, + oot_obj_register, + oot_obj_unregister, + OOT_ObjectProperties, + OOTSceneProperties, +) from .skeleton.properties import OOTSkeletonImportSettings, OOTSkeletonExportSettings from .oot_utility import oot_utility_register, oot_utility_unregister, setAllActorsVisibility from .file_settings import file_register, file_unregister diff --git a/fast64_internal/oot/actor/properties.py b/fast64_internal/oot/actor/properties.py index 6fc31ec8c..ba71245a0 100644 --- a/fast64_internal/oot/actor/properties.py +++ b/fast64_internal/oot/actor/properties.py @@ -54,7 +54,9 @@ def initOOTActorProperties(): prop_ats = get_prop_annotations(OOTActorProperty) - prop_ats["actor_id"] = EnumProperty(name="Actor", items=game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER") + prop_ats["actor_id"] = EnumProperty( + name="Actor", items=game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER" + ) param_type_to_enum_items = { "ChestContent": game_data.z64.actorData.ootEnumChestContent, diff --git a/fast64_internal/oot/animation/properties.py b/fast64_internal/oot/animation/properties.py index 46234c999..97a510128 100644 --- a/fast64_internal/oot/animation/properties.py +++ b/fast64_internal/oot/animation/properties.py @@ -68,9 +68,7 @@ def draw_props(self, layout: UILayout): prop_split(layout, self, "mouth", "Mouth") -classes = ( - OOTLinkTextureAnimProperty, -) +classes = (OOTLinkTextureAnimProperty,) def anim_props_register(): From f3315c155dc587630ed1db153653946fcc663c9f Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 18:04:28 +0100 Subject: [PATCH 052/126] move success print --- __init__.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/__init__.py b/__init__.py index 759a3fbf9..f08f99b5f 100644 --- a/__init__.py +++ b/__init__.py @@ -364,17 +364,12 @@ def init_game_data(): print(f"[init_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") return - print(f"[init_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") - def destroy_game_data(): match bpy.context.scene.gameEditorMode: case "OOT": oot_unregister(True) case _: print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") - return - - print(f"[destroy_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") try: init_game_data() @@ -382,6 +377,8 @@ def destroy_game_data(): destroy_game_data() init_game_data() + print(f"[update_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") + @bpy.app.handlers.persistent def after_load(_a, _b): From 96541a67b2b38c111ff7903ebe2a762045bee09e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 18:10:48 +0100 Subject: [PATCH 053/126] move data outside z64 --- fast64_internal/{z64 => }/data/__init__.py | 0 fast64_internal/{z64 => }/data/mm/actor_data.py | 0 fast64_internal/{z64 => }/data/mm/data.py | 0 fast64_internal/{z64 => }/data/mm/enum_data.py | 0 fast64_internal/{z64 => }/data/mm/getters.py | 2 +- fast64_internal/{z64 => }/data/mm/object_data.py | 0 fast64_internal/{z64 => }/data/mm/xml/ActorList.xml | 0 fast64_internal/{z64 => }/data/mm/xml/EnumData.xml | 0 fast64_internal/{z64 => }/data/mm/xml/ObjectList.xml | 0 fast64_internal/{z64 => }/data/oot/actor_data.py | 0 fast64_internal/{z64 => }/data/oot/data.py | 0 fast64_internal/{z64 => }/data/oot/enum_data.py | 0 fast64_internal/{z64 => }/data/oot/getters.py | 2 +- fast64_internal/{z64 => }/data/oot/object_data.py | 2 +- fast64_internal/{z64 => }/data/oot/xml/ActorList.xml | 0 fast64_internal/{z64 => }/data/oot/xml/EnumData.xml | 0 fast64_internal/{z64 => }/data/oot/xml/ObjectList.xml | 0 fast64_internal/z64/constants.py | 2 +- fast64_internal/z64/upgrade.py | 2 +- 19 files changed, 5 insertions(+), 5 deletions(-) rename fast64_internal/{z64 => }/data/__init__.py (100%) rename fast64_internal/{z64 => }/data/mm/actor_data.py (100%) rename fast64_internal/{z64 => }/data/mm/data.py (100%) rename fast64_internal/{z64 => }/data/mm/enum_data.py (100%) rename fast64_internal/{z64 => }/data/mm/getters.py (88%) rename fast64_internal/{z64 => }/data/mm/object_data.py (100%) rename fast64_internal/{z64 => }/data/mm/xml/ActorList.xml (100%) rename fast64_internal/{z64 => }/data/mm/xml/EnumData.xml (100%) rename fast64_internal/{z64 => }/data/mm/xml/ObjectList.xml (100%) rename fast64_internal/{z64 => }/data/oot/actor_data.py (100%) rename fast64_internal/{z64 => }/data/oot/data.py (100%) rename fast64_internal/{z64 => }/data/oot/enum_data.py (100%) rename fast64_internal/{z64 => }/data/oot/getters.py (87%) rename fast64_internal/{z64 => }/data/oot/object_data.py (98%) rename fast64_internal/{z64 => }/data/oot/xml/ActorList.xml (100%) rename fast64_internal/{z64 => }/data/oot/xml/EnumData.xml (100%) rename fast64_internal/{z64 => }/data/oot/xml/ObjectList.xml (100%) diff --git a/fast64_internal/z64/data/__init__.py b/fast64_internal/data/__init__.py similarity index 100% rename from fast64_internal/z64/data/__init__.py rename to fast64_internal/data/__init__.py diff --git a/fast64_internal/z64/data/mm/actor_data.py b/fast64_internal/data/mm/actor_data.py similarity index 100% rename from fast64_internal/z64/data/mm/actor_data.py rename to fast64_internal/data/mm/actor_data.py diff --git a/fast64_internal/z64/data/mm/data.py b/fast64_internal/data/mm/data.py similarity index 100% rename from fast64_internal/z64/data/mm/data.py rename to fast64_internal/data/mm/data.py diff --git a/fast64_internal/z64/data/mm/enum_data.py b/fast64_internal/data/mm/enum_data.py similarity index 100% rename from fast64_internal/z64/data/mm/enum_data.py rename to fast64_internal/data/mm/enum_data.py diff --git a/fast64_internal/z64/data/mm/getters.py b/fast64_internal/data/mm/getters.py similarity index 88% rename from fast64_internal/z64/data/mm/getters.py rename to fast64_internal/data/mm/getters.py index 538818462..26378f38d 100644 --- a/fast64_internal/z64/data/mm/getters.py +++ b/fast64_internal/data/mm/getters.py @@ -7,6 +7,6 @@ def get_xml_root(xml_path: Path) -> Element: try: return parse_xml(xml_path.resolve()).getroot() except: - from ....utility import PluginError + from ...utility import PluginError raise PluginError(f"ERROR: File '{xml_path}' is missing or malformed.") diff --git a/fast64_internal/z64/data/mm/object_data.py b/fast64_internal/data/mm/object_data.py similarity index 100% rename from fast64_internal/z64/data/mm/object_data.py rename to fast64_internal/data/mm/object_data.py diff --git a/fast64_internal/z64/data/mm/xml/ActorList.xml b/fast64_internal/data/mm/xml/ActorList.xml similarity index 100% rename from fast64_internal/z64/data/mm/xml/ActorList.xml rename to fast64_internal/data/mm/xml/ActorList.xml diff --git a/fast64_internal/z64/data/mm/xml/EnumData.xml b/fast64_internal/data/mm/xml/EnumData.xml similarity index 100% rename from fast64_internal/z64/data/mm/xml/EnumData.xml rename to fast64_internal/data/mm/xml/EnumData.xml diff --git a/fast64_internal/z64/data/mm/xml/ObjectList.xml b/fast64_internal/data/mm/xml/ObjectList.xml similarity index 100% rename from fast64_internal/z64/data/mm/xml/ObjectList.xml rename to fast64_internal/data/mm/xml/ObjectList.xml diff --git a/fast64_internal/z64/data/oot/actor_data.py b/fast64_internal/data/oot/actor_data.py similarity index 100% rename from fast64_internal/z64/data/oot/actor_data.py rename to fast64_internal/data/oot/actor_data.py diff --git a/fast64_internal/z64/data/oot/data.py b/fast64_internal/data/oot/data.py similarity index 100% rename from fast64_internal/z64/data/oot/data.py rename to fast64_internal/data/oot/data.py diff --git a/fast64_internal/z64/data/oot/enum_data.py b/fast64_internal/data/oot/enum_data.py similarity index 100% rename from fast64_internal/z64/data/oot/enum_data.py rename to fast64_internal/data/oot/enum_data.py diff --git a/fast64_internal/z64/data/oot/getters.py b/fast64_internal/data/oot/getters.py similarity index 87% rename from fast64_internal/z64/data/oot/getters.py rename to fast64_internal/data/oot/getters.py index a5e2d9237..fb4fbfe09 100644 --- a/fast64_internal/z64/data/oot/getters.py +++ b/fast64_internal/data/oot/getters.py @@ -6,6 +6,6 @@ def getXMLRoot(xmlPath: str) -> Element: try: return parseXML(xmlPath).getroot() except: - from ....utility import PluginError + from ...utility import PluginError raise PluginError(f"ERROR: File '{xmlPath}' is missing or malformed.") diff --git a/fast64_internal/z64/data/oot/object_data.py b/fast64_internal/data/oot/object_data.py similarity index 98% rename from fast64_internal/z64/data/oot/object_data.py rename to fast64_internal/data/oot/object_data.py index 5b51e3e87..d588a07dd 100644 --- a/fast64_internal/z64/data/oot/object_data.py +++ b/fast64_internal/data/oot/object_data.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from os import path -from ....utility import PluginError +from ...utility import PluginError from .getters import getXMLRoot from .data import OoT_BaseElement diff --git a/fast64_internal/z64/data/oot/xml/ActorList.xml b/fast64_internal/data/oot/xml/ActorList.xml similarity index 100% rename from fast64_internal/z64/data/oot/xml/ActorList.xml rename to fast64_internal/data/oot/xml/ActorList.xml diff --git a/fast64_internal/z64/data/oot/xml/EnumData.xml b/fast64_internal/data/oot/xml/EnumData.xml similarity index 100% rename from fast64_internal/z64/data/oot/xml/EnumData.xml rename to fast64_internal/data/oot/xml/EnumData.xml diff --git a/fast64_internal/z64/data/oot/xml/ObjectList.xml b/fast64_internal/data/oot/xml/ObjectList.xml similarity index 100% rename from fast64_internal/z64/data/oot/xml/ObjectList.xml rename to fast64_internal/data/oot/xml/ObjectList.xml diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index 3bf2ea078..cdbb67a44 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -1,4 +1,4 @@ -from .data import OoT_Data, MM_Data +from ..data import OoT_Data, MM_Data oot_data = OoT_Data() diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 0e22ce004..d70c28e35 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -5,7 +5,7 @@ import bpy from bpy.types import Object, CollectionProperty from ..utility import PluginError -from .data import OoT_ObjectData +from ..data import OoT_ObjectData from .utility import getEvalParams, get_actor_prop_from_obj from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode From 95b4504266a2d48a698194a1af11e228ce157a8e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 18:34:08 +0100 Subject: [PATCH 054/126] fix merge oopsie --- fast64_internal/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast64_internal/constants.py b/fast64_internal/constants.py index 0786ae3e4..a88d695c1 100644 --- a/fast64_internal/constants.py +++ b/fast64_internal/constants.py @@ -3,7 +3,7 @@ class GameData: def __init__(self, game_editor_mode: Optional[str] = None): - from .data.oot import OoT_Data + from .data import OoT_Data self.z64 = OoT_Data() From 7f031fdf6f9cfa22648e44341cdb8701f77ae121 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:07:40 +0100 Subject: [PATCH 055/126] create z64 data folder --- fast64_internal/data/oot/data.py | 186 - fast64_internal/data/oot/enum_data.py | 123 - .../data/{oot => z64}/actor_data.py | 41 +- fast64_internal/data/z64/data.py | 352 ++ fast64_internal/data/z64/enum_data.py | 180 + fast64_internal/data/{oot => z64}/getters.py | 2 +- .../data/{oot => z64}/object_data.py | 23 +- .../data/z64/xml/mm_actor_list.xml | 979 +++++ fast64_internal/data/z64/xml/mm_enum_data.xml | 719 ++++ .../data/z64/xml/mm_object_list.xml | 653 +++ .../data/z64/xml/oot_actor_list.xml | 3695 +++++++++++++++++ .../data/z64/xml/oot_enum_data.xml | 601 +++ .../data/z64/xml/oot_object_list.xml | 389 ++ 13 files changed, 7602 insertions(+), 341 deletions(-) delete mode 100644 fast64_internal/data/oot/data.py delete mode 100644 fast64_internal/data/oot/enum_data.py rename fast64_internal/data/{oot => z64}/actor_data.py (86%) create mode 100644 fast64_internal/data/z64/data.py create mode 100644 fast64_internal/data/z64/enum_data.py rename fast64_internal/data/{oot => z64}/getters.py (87%) rename fast64_internal/data/{oot => z64}/object_data.py (74%) create mode 100644 fast64_internal/data/z64/xml/mm_actor_list.xml create mode 100644 fast64_internal/data/z64/xml/mm_enum_data.xml create mode 100644 fast64_internal/data/z64/xml/mm_object_list.xml create mode 100644 fast64_internal/data/z64/xml/oot_actor_list.xml create mode 100644 fast64_internal/data/z64/xml/oot_enum_data.xml create mode 100644 fast64_internal/data/z64/xml/oot_object_list.xml diff --git a/fast64_internal/data/oot/data.py b/fast64_internal/data/oot/data.py deleted file mode 100644 index 01123572e..000000000 --- a/fast64_internal/data/oot/data.py +++ /dev/null @@ -1,186 +0,0 @@ -from dataclasses import dataclass - - -@dataclass -class OoT_BaseElement: - id: str - key: str - name: str - index: int - - -@dataclass -class OoT_Data: - """Contains data related to OoT, like actors or objects""" - - def __init__(self): - from .enum_data import OoT_EnumData - from .object_data import OoT_ObjectData - from .actor_data import OoT_ActorData - - self.enumData = OoT_EnumData() - self.objectData = OoT_ObjectData() - self.actorData = OoT_ActorData() - - # `EnumProperty` requires fixed values - self.ootEnumMusicSeq = [ - # see https://github.com/zeldaret/oot/blob/9f09505d34619883748a7dab05071883281c14fd/include/sequence.h#L4-L118 - ("Custom", "Custom", "Custom"), - ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), - ("NA_BGM_NATURE_AMBIENCE", "Nature Ambiance", "Nature Ambiance"), - ("NA_BGM_FIELD_LOGIC", "Hyrule Field", "Hyrule Field"), - ( - "NA_BGM_FIELD_INIT", - "Hyrule Field (Initial Segment From Loading Area)", - "Hyrule Field (Initial Segment From Loading Area)", - ), - ("NA_BGM_FIELD_DEFAULT_1", "Hyrule Field (Moving Segment 1)", "Hyrule Field (Moving Segment 1)"), - ("NA_BGM_FIELD_DEFAULT_2", "Hyrule Field (Moving Segment 2)", "Hyrule Field (Moving Segment 2)"), - ("NA_BGM_FIELD_DEFAULT_3", "Hyrule Field (Moving Segment 3)", "Hyrule Field (Moving Segment 3)"), - ("NA_BGM_FIELD_DEFAULT_4", "Hyrule Field (Moving Segment 4)", "Hyrule Field (Moving Segment 4)"), - ("NA_BGM_FIELD_DEFAULT_5", "Hyrule Field (Moving Segment 5)", "Hyrule Field (Moving Segment 5)"), - ("NA_BGM_FIELD_DEFAULT_6", "Hyrule Field (Moving Segment 6)", "Hyrule Field (Moving Segment 6)"), - ("NA_BGM_FIELD_DEFAULT_7", "Hyrule Field (Moving Segment 7)", "Hyrule Field (Moving Segment 7)"), - ("NA_BGM_FIELD_DEFAULT_8", "Hyrule Field (Moving Segment 8)", "Hyrule Field (Moving Segment 8)"), - ("NA_BGM_FIELD_DEFAULT_9", "Hyrule Field (Moving Segment 9)", "Hyrule Field (Moving Segment 9)"), - ("NA_BGM_FIELD_DEFAULT_A", "Hyrule Field (Moving Segment 10)", "Hyrule Field (Moving Segment 10)"), - ("NA_BGM_FIELD_DEFAULT_B", "Hyrule Field (Moving Segment 11)", "Hyrule Field (Moving Segment 11)"), - ("NA_BGM_FIELD_ENEMY_INIT", "Hyrule Field (Enemy Approaches)", "Hyrule Field (Enemy Approaches)"), - ("NA_BGM_FIELD_ENEMY_1", "Hyrule Field (Enemy Near Segment 1)", "Hyrule Field (Enemy Near Segment 1)"), - ("NA_BGM_FIELD_ENEMY_2", "Hyrule Field (Enemy Near Segment 2)", "Hyrule Field (Enemy Near Segment 2)"), - ("NA_BGM_FIELD_ENEMY_3", "Hyrule Field (Enemy Near Segment 3)", "Hyrule Field (Enemy Near Segment 3)"), - ("NA_BGM_FIELD_ENEMY_4", "Hyrule Field (Enemy Near Segment 4)", "Hyrule Field (Enemy Near Segment 4)"), - ( - "NA_BGM_FIELD_STILL_1", - "Hyrule Field (Standing Still Segment 1)", - "Hyrule Field (Standing Still Segment 1)", - ), - ( - "NA_BGM_FIELD_STILL_2", - "Hyrule Field (Standing Still Segment 2)", - "Hyrule Field (Standing Still Segment 2)", - ), - ( - "NA_BGM_FIELD_STILL_3", - "Hyrule Field (Standing Still Segment 3)", - "Hyrule Field (Standing Still Segment 3)", - ), - ( - "NA_BGM_FIELD_STILL_4", - "Hyrule Field (Standing Still Segment 4)", - "Hyrule Field (Standing Still Segment 4)", - ), - ("NA_BGM_DUNGEON", "Dodongo's Cavern", "Dodongo's Cavern"), - ("NA_BGM_KAKARIKO_ADULT", "Kakariko Village (Adult)", "Kakariko Village (Adult)"), - ("NA_BGM_ENEMY", "Enemy Battle", "Enemy Battle"), - ("NA_BGM_BOSS", "Boss Battle 00", "Boss Battle 00"), - ("NA_BGM_INSIDE_DEKU_TREE", "Inside the Deku Tree", "Inside the Deku Tree"), - ("NA_BGM_MARKET", "Market", "Market"), - ("NA_BGM_TITLE", "Title Theme", "Title Theme"), - ("NA_BGM_LINK_HOUSE", "Link's House", "Link's House"), - ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), - ("NA_BGM_BOSS_CLEAR", "Boss Clear", "Boss Clear"), - ("NA_BGM_ITEM_GET", "Item Get", "Item Get"), - ("NA_BGM_OPENING_GANON", "Opening Ganon", "Opening Ganon"), - ("NA_BGM_HEART_GET", "Heart Get", "Heart Get"), - ("NA_BGM_OCA_LIGHT", "Prelude Of Light", "Prelude Of Light"), - ("NA_BGM_JABU_JABU", "Inside Jabu-Jabu's Belly", "Inside Jabu-Jabu's Belly"), - ("NA_BGM_KAKARIKO_KID", "Kakariko Village (Child)", "Kakariko Village (Child)"), - ("NA_BGM_GREAT_FAIRY", "Great Fairy's Fountain", "Great Fairy's Fountain"), - ("NA_BGM_ZELDA_THEME", "Zelda's Theme", "Zelda's Theme"), - ("NA_BGM_FIRE_TEMPLE", "Fire Temple", "Fire Temple"), - ("NA_BGM_OPEN_TRE_BOX", "Open Treasure Chest", "Open Treasure Chest"), - ("NA_BGM_FOREST_TEMPLE", "Forest Temple", "Forest Temple"), - ("NA_BGM_COURTYARD", "Hyrule Castle Courtyard", "Hyrule Castle Courtyard"), - ("NA_BGM_GANON_TOWER", "Ganondorf's Theme", "Ganondorf's Theme"), - ("NA_BGM_LONLON", "Lon Lon Ranch", "Lon Lon Ranch"), - ("NA_BGM_GORON_CITY", "Goron City", "Goron City"), - ("NA_BGM_FIELD_MORNING", "Hyrule Field Morning Theme", "Hyrule Field Morning Theme"), - ("NA_BGM_SPIRITUAL_STONE", "Spiritual Stone Get", "Spiritual Stone Get"), - ("NA_BGM_OCA_BOLERO", "Bolero of Fire", "Bolero of Fire"), - ("NA_BGM_OCA_MINUET", "Minuet of Woods", "Minuet of Woods"), - ("NA_BGM_OCA_SERENADE", "Serenade of Water", "Serenade of Water"), - ("NA_BGM_OCA_REQUIEM", "Requiem of Spirit", "Requiem of Spirit"), - ("NA_BGM_OCA_NOCTURNE", "Nocturne of Shadow", "Nocturne of Shadow"), - ("NA_BGM_MINI_BOSS", "Mini-Boss Battle", "Mini-Boss Battle"), - ("NA_BGM_SMALL_ITEM_GET", "Obtain Small Item", "Obtain Small Item"), - ("NA_BGM_TEMPLE_OF_TIME", "Temple of Time", "Temple of Time"), - ("NA_BGM_EVENT_CLEAR", "Escape from Lon Lon Ranch", "Escape from Lon Lon Ranch"), - ("NA_BGM_KOKIRI", "Kokiri Forest", "Kokiri Forest"), - ("NA_BGM_OCA_FAIRY_GET", "Obtain Fairy Ocarina", "Obtain Fairy Ocarina"), - ("NA_BGM_SARIA_THEME", "Lost Woods", "Lost Woods"), - ("NA_BGM_SPIRIT_TEMPLE", "Spirit Temple", "Spirit Temple"), - ("NA_BGM_HORSE", "Horse Race", "Horse Race"), - ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), - ("NA_BGM_INGO", "Ingo's Theme", "Ingo's Theme"), - ("NA_BGM_MEDALLION_GET", "Obtain Medallion", "Obtain Medallion"), - ("NA_BGM_OCA_SARIA", "Ocarina Saria's Song", "Ocarina Saria's Song"), - ("NA_BGM_OCA_EPONA", "Ocarina Epona's Song", "Ocarina Epona's Song"), - ("NA_BGM_OCA_ZELDA", "Ocarina Zelda's Lullaby", "Ocarina Zelda's Lullaby"), - ("NA_BGM_OCA_SUNS", "Sun's Song", "Sun's Song"), - ("NA_BGM_OCA_TIME", "Song of Time", "Song of Time"), - ("NA_BGM_OCA_STORM", "Song of Storms", "Song of Storms"), - ("NA_BGM_NAVI_OPENING", "Fairy Flying", "Fairy Flying"), - ("NA_BGM_DEKU_TREE_CS", "Deku Tree", "Deku Tree"), - ("NA_BGM_WINDMILL", "Windmill Hut", "Windmill Hut"), - ("NA_BGM_HYRULE_CS", "Legend of Hyrule", "Legend of Hyrule"), - ("NA_BGM_MINI_GAME", "Shooting Gallery", "Shooting Gallery"), - ("NA_BGM_SHEIK", "Sheik's Theme", "Sheik's Theme"), - ("NA_BGM_ZORA_DOMAIN", "Zora's Domain", "Zora's Domain"), - ("NA_BGM_APPEAR", "Enter Zelda", "Enter Zelda"), - ("NA_BGM_ADULT_LINK", "Goodbye to Zelda", "Goodbye to Zelda"), - ("NA_BGM_MASTER_SWORD", "Master Sword", "Master Sword"), - ("NA_BGM_INTRO_GANON", "Ganon Intro", "Ganon Intro"), - ("NA_BGM_SHOP", "Shop", "Shop"), - ("NA_BGM_CHAMBER_OF_SAGES", "Chamber of the Sages", "Chamber of the Sages"), - ("NA_BGM_FILE_SELECT", "File Select", "File Select"), - ("NA_BGM_ICE_CAVERN", "Ice Cavern", "Ice Cavern"), - ("NA_BGM_DOOR_OF_TIME", "Open Door of Temple of Time", "Open Door of Temple of Time"), - ("NA_BGM_OWL", "Kaepora Gaebora's Theme", "Kaepora Gaebora's Theme"), - ("NA_BGM_SHADOW_TEMPLE", "Shadow Temple", "Shadow Temple"), - ("NA_BGM_WATER_TEMPLE", "Water Temple", "Water Temple"), - ("NA_BGM_BRIDGE_TO_GANONS", "Ganon's Castle Bridge", "Ganon's Castle Bridge"), - ("NA_BGM_OCARINA_OF_TIME", "Ocarina of Time", "Ocarina of Time"), - ("NA_BGM_GERUDO_VALLEY", "Gerudo Valley", "Gerudo Valley"), - ("NA_BGM_POTION_SHOP", "Potion Shop", "Potion Shop"), - ("NA_BGM_KOTAKE_KOUME", "Kotake & Koume's Theme", "Kotake & Koume's Theme"), - ("NA_BGM_ESCAPE", "Escape from Ganon's Castle", "Escape from Ganon's Castle"), - ("NA_BGM_UNDERGROUND", "Ganon's Castle Under Ground", "Ganon's Castle Under Ground"), - ("NA_BGM_GANONDORF_BOSS", "Ganondorf Battle", "Ganondorf Battle"), - ("NA_BGM_GANON_BOSS", "Ganon Battle", "Ganon Battle"), - ("NA_BGM_END_DEMO", "Seal of Six Sages", "Seal of Six Sages"), - ("NA_BGM_STAFF_1", "End Credits I", "End Credits I"), - ("NA_BGM_STAFF_2", "End Credits II", "End Credits II"), - ("NA_BGM_STAFF_3", "End Credits III", "End Credits III"), - ("NA_BGM_STAFF_4", "End Credits IV", "End Credits IV"), - ("NA_BGM_FIRE_BOSS", "King Dodongo & Volvagia Boss Battle", "King Dodongo & Volvagia Boss Battle"), - ("NA_BGM_TIMED_MINI_GAME", "Mini-Game", "Mini-Game"), - ("NA_BGM_CUTSCENE_EFFECTS", "Various Cutscene Sounds", "Various Cutscene Sounds"), - ("NA_BGM_NO_MUSIC", "No Music", "No Music"), - ("NA_BGM_NATURE_SFX_RAIN", "Nature Ambiance: Rain", "Nature Ambiance: Rain"), - ] - - self.ootEnumNightSeq = [ - ("Custom", "Custom", "Custom"), - ("0x00", "General Night", "NATURE_ID_GENERAL_NIGHT"), - ("0x01", "Market Entrance", "NATURE_ID_MARKET_ENTRANCE"), - ("0x02", "Kakariko Region", "NATURE_ID_KAKARIKO_REGION"), - ("0x03", "Market Ruins", "NATURE_ID_MARKET_RUINS"), - ("0x04", "Kokiri Region", "NATURE_ID_KOKIRI_REGION"), - ("0x05", "Market Night", "NATURE_ID_MARKET_NIGHT"), - ("0x06", "NATURE_ID_06", "NATURE_ID_06"), - ("0x07", "Ganon's Lair", "NATURE_ID_GANONS_LAIR"), - ("0x08", "NATURE_ID_08", "NATURE_ID_08"), - ("0x09", "NATURE_ID_09", "NATURE_ID_09"), - ("0x0A", "Wasteland", "NATURE_ID_WASTELAND"), - ("0x0B", "Colossus", "NATURE_ID_COLOSSUS"), - ("0x0C", "Nature DMT", "NATURE_ID_DEATH_MOUNTAIN_TRAIL"), - ("0x0D", "NATURE_ID_0D", "NATURE_ID_0D"), - ("0x0E", "NATURE_ID_0E", "NATURE_ID_0E"), - ("0x0F", "NATURE_ID_0F", "NATURE_ID_0F"), - ("0x10", "NATURE_ID_10", "NATURE_ID_10"), - ("0x11", "NATURE_ID_11", "NATURE_ID_11"), - ("0x12", "NATURE_ID_12", "NATURE_ID_12"), - ("0x13", "None", "NATURE_ID_NONE"), - ("0xFF", "Disabled", "NATURE_ID_DISABLED"), - ] diff --git a/fast64_internal/data/oot/enum_data.py b/fast64_internal/data/oot/enum_data.py deleted file mode 100644 index 3552f9850..000000000 --- a/fast64_internal/data/oot/enum_data.py +++ /dev/null @@ -1,123 +0,0 @@ -from dataclasses import dataclass, field -from os import path -from .getters import getXMLRoot -from .data import OoT_BaseElement - -# Note: "enumData" in this context refers to an OoT Object file (like ``gameplay_keep``) - - -@dataclass -class OoT_ItemElement(OoT_BaseElement): - parentKey: str - - def __post_init__(self): - # generate the name from the id - - if self.name is None: - keyToPrefix = { - "csCmd": "CS_CMD", - "csMiscType": "CS_MISC", - "csTextType": "CS_TEXT", - "csFadeOutSeqPlayer": "CS_FADE_OUT", - "csTransitionType": "CS_TRANS", - "csDestination": "CS_DEST", - "csPlayerCueId": "PLAYER_CUEID", - "naviQuestHintType": "NAVI_QUEST_HINTS", - "ocarinaSongActionId": "OCARINA_ACTION", - } - - self.name = self.id.removeprefix(f"{keyToPrefix[self.parentKey]}_") - - if self.parentKey in ["csCmd", "csPlayerCueId"]: - split = self.name.split("_") - if self.parentKey == "csCmd" and "ACTOR_CUE" in self.id: - self.name = f"Actor Cue {split[-2]}_{split[-1]}" - else: - self.name = f"Player Cue Id {split[-1]}" - else: - self.name = self.name.replace("_", " ").title() - - -@dataclass -class OoT_EnumElement(OoT_BaseElement): - items: list[OoT_ItemElement] - item_by_key: dict[str, OoT_ItemElement] = field(default_factory=dict) - item_by_index: dict[int, OoT_ItemElement] = field(default_factory=dict) - item_by_id: dict[int, OoT_ItemElement] = field(default_factory=dict) - - def __post_init__(self): - self.item_by_key = {item.key: item for item in self.items} - self.item_by_index = {item.index: item for item in self.items} - self.item_by_id = {item.id: item for item in self.items} - - -class OoT_EnumData: - """Cutscene and misc enum data""" - - def __init__(self): - # general enumData list - self.enumDataList: list[OoT_EnumElement] = [] - - # Path to the ``EnumData.xml`` file - enumDataXML = path.dirname(path.abspath(__file__)) + "/xml/EnumData.xml" - enumDataRoot = getXMLRoot(enumDataXML) - - for enum in enumDataRoot.iterfind("Enum"): - self.enumDataList.append( - OoT_EnumElement( - enum.attrib["ID"], - enum.attrib["Key"], - None, - None, - [ - OoT_ItemElement( - item.attrib["ID"], - item.attrib["Key"], - # note: the name sets automatically after the init if None - item.attrib["Name"] if enum.attrib["Key"] == "seqId" else None, - int(item.attrib["Index"]), - enum.attrib["Key"], - ) - for item in enum - ], - ) - ) - - # create list of tuples used by Blender's enum properties - self.deletedEntry = ("None", "(Deleted from the XML)", "None") - - self.ootEnumCsCmd: list[tuple[str, str, str]] = [] - self.ootEnumCsMiscType: list[tuple[str, str, str]] = [] - self.ootEnumCsTextType: list[tuple[str, str, str]] = [] - self.ootEnumCsFadeOutSeqPlayer: list[tuple[str, str, str]] = [] - self.ootEnumCsTransitionType: list[tuple[str, str, str]] = [] - self.ootEnumCsDestination: list[tuple[str, str, str]] = [] - self.ootEnumCsPlayerCueId: list[tuple[str, str, str]] = [] - self.ootEnumNaviQuestHintType: list[tuple[str, str, str]] = [] - self.ootEnumOcarinaSongActionId: list[tuple[str, str, str]] = [] - self.ootEnumSeqId: list[tuple[str, str, str]] = [] - - self.enumByID = {enum.id: enum for enum in self.enumDataList} - self.enumByKey = {enum.key: enum for enum in self.enumDataList} - - for key in self.enumByKey.keys(): - setattr(self, "ootEnum" + key[0].upper() + key[1:], self.getOoTEnumData(key)) - - def getOoTEnumData(self, enumKey: str): - enum = self.enumByKey[enumKey] - firstIndex = min(1, *(item.index for item in enum.items)) - lastIndex = max(1, *(item.index for item in enum.items)) + 1 - enumData = [self.deletedEntry] * lastIndex - custom = ("Custom", "Custom", "Custom") - - for item in enum.items: - if item.index < lastIndex: - identifier = item.key - enumData[item.index] = (identifier, item.name, item.id) - - if firstIndex > 0: - enumData[0] = custom - else: - enumData.insert(0, custom) - - return enumData diff --git a/fast64_internal/data/oot/actor_data.py b/fast64_internal/data/z64/actor_data.py similarity index 86% rename from fast64_internal/data/oot/actor_data.py rename to fast64_internal/data/z64/actor_data.py index 325f1d14e..12fedb58d 100644 --- a/fast64_internal/data/oot/actor_data.py +++ b/fast64_internal/data/z64/actor_data.py @@ -1,11 +1,12 @@ from os import path from dataclasses import dataclass -from .getters import getXMLRoot -from .data import OoT_BaseElement +from pathlib import Path +from .getters import get_xml_root +from .data import Z64_BaseElement @dataclass -class OoT_ParameterElement: +class Z64_ParameterElement: type: str # bool, enum, type, property, etc... index: int mask: int @@ -18,34 +19,34 @@ class OoT_ParameterElement: @dataclass -class OoT_ListElement: +class Z64_ListElement: key: str name: str value: int @dataclass -class OoT_ActorElement(OoT_BaseElement): +class Z64_ActorElement(Z64_BaseElement): category: str tiedObjects: list[str] - params: list[OoT_ParameterElement] + params: list[Z64_ParameterElement] -class OoT_ActorData: +class Z64_ActorData: """Everything related to OoT Actors""" - def __init__(self): + def __init__(self, game: str): # Path to the ``ActorList.xml`` file - actorXML = path.dirname(path.abspath(__file__)) + "/xml/ActorList.xml" - actorRoot = getXMLRoot(actorXML) + xml_path = Path(f"{path.dirname(path.abspath(__file__))}/xml/{game.lower()}_actor_list.xml") + actor_root = get_xml_root(xml_path.resolve()) # general actor list - self.actorList: list[OoT_ActorElement] = [] + self.actorList: list[Z64_ActorElement] = [] # list elements - self.chestItems: list[OoT_ListElement] = [] - self.collectibleItems: list[OoT_ListElement] = [] - self.messageItems: list[OoT_ListElement] = [] + self.chestItems: list[Z64_ListElement] = [] + self.collectibleItems: list[Z64_ListElement] = [] + self.messageItems: list[Z64_ListElement] = [] listNameToList = { "Chest Content": self.chestItems, @@ -53,15 +54,15 @@ def __init__(self): "Elf_Msg Message ID": self.messageItems, } - for elem in actorRoot.iterfind("List"): + for elem in actor_root.iterfind("List"): listName = elem.get("Name") if listName is not None: for item in elem: listNameToList[listName].append( - OoT_ListElement(item.get("Key"), item.get("Name"), int(item.get("Value"), base=16)) + Z64_ListElement(item.get("Key"), item.get("Name"), int(item.get("Value"), base=16)) ) - for actor in actorRoot.iterfind("Actor"): + for actor in actor_root.iterfind("Actor"): tiedObjects = [] objKey = actor.get("ObjectKey") actorName = f"{actor.attrib['Name']} - {actor.attrib['ID'].removeprefix('ACTOR_')}" @@ -70,7 +71,7 @@ def __init__(self): tiedObjects = objKey.split(",") # parameters - params: list[OoT_ParameterElement] = [] + params: list[Z64_ParameterElement] = [] for elem in actor: elemType = elem.tag if elemType != "Notes": @@ -91,7 +92,7 @@ def __init__(self): defaultName = f"{elem.get('Type')} {elemType}" valueRange = elem.get("ValueRange") params.append( - OoT_ParameterElement( + Z64_ParameterElement( elemType, int(elem.get("Index", "1")), int(elem.get("Mask", "0xFFFF"), base=16), @@ -105,7 +106,7 @@ def __init__(self): ) self.actorList.append( - OoT_ActorElement( + Z64_ActorElement( actor.attrib["ID"], actor.attrib["Key"], actorName, diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py new file mode 100644 index 000000000..cb5678fa4 --- /dev/null +++ b/fast64_internal/data/z64/data.py @@ -0,0 +1,352 @@ +from dataclasses import dataclass + + +@dataclass +class Z64_BaseElement: + id: str + key: str + name: str + index: int + + +ootEnumMusicSeq = [ + # see https://github.com/zeldaret/oot/blob/9f09505d34619883748a7dab05071883281c14fd/include/sequence.h#L4-L118 + ("Custom", "Custom", "Custom"), + ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), + ("NA_BGM_NATURE_AMBIENCE", "Nature Ambiance", "Nature Ambiance"), + ("NA_BGM_FIELD_LOGIC", "Hyrule Field", "Hyrule Field"), + ( + "NA_BGM_FIELD_INIT", + "Hyrule Field (Initial Segment From Loading Area)", + "Hyrule Field (Initial Segment From Loading Area)", + ), + ("NA_BGM_FIELD_DEFAULT_1", "Hyrule Field (Moving Segment 1)", "Hyrule Field (Moving Segment 1)"), + ("NA_BGM_FIELD_DEFAULT_2", "Hyrule Field (Moving Segment 2)", "Hyrule Field (Moving Segment 2)"), + ("NA_BGM_FIELD_DEFAULT_3", "Hyrule Field (Moving Segment 3)", "Hyrule Field (Moving Segment 3)"), + ("NA_BGM_FIELD_DEFAULT_4", "Hyrule Field (Moving Segment 4)", "Hyrule Field (Moving Segment 4)"), + ("NA_BGM_FIELD_DEFAULT_5", "Hyrule Field (Moving Segment 5)", "Hyrule Field (Moving Segment 5)"), + ("NA_BGM_FIELD_DEFAULT_6", "Hyrule Field (Moving Segment 6)", "Hyrule Field (Moving Segment 6)"), + ("NA_BGM_FIELD_DEFAULT_7", "Hyrule Field (Moving Segment 7)", "Hyrule Field (Moving Segment 7)"), + ("NA_BGM_FIELD_DEFAULT_8", "Hyrule Field (Moving Segment 8)", "Hyrule Field (Moving Segment 8)"), + ("NA_BGM_FIELD_DEFAULT_9", "Hyrule Field (Moving Segment 9)", "Hyrule Field (Moving Segment 9)"), + ("NA_BGM_FIELD_DEFAULT_A", "Hyrule Field (Moving Segment 10)", "Hyrule Field (Moving Segment 10)"), + ("NA_BGM_FIELD_DEFAULT_B", "Hyrule Field (Moving Segment 11)", "Hyrule Field (Moving Segment 11)"), + ("NA_BGM_FIELD_ENEMY_INIT", "Hyrule Field (Enemy Approaches)", "Hyrule Field (Enemy Approaches)"), + ("NA_BGM_FIELD_ENEMY_1", "Hyrule Field (Enemy Near Segment 1)", "Hyrule Field (Enemy Near Segment 1)"), + ("NA_BGM_FIELD_ENEMY_2", "Hyrule Field (Enemy Near Segment 2)", "Hyrule Field (Enemy Near Segment 2)"), + ("NA_BGM_FIELD_ENEMY_3", "Hyrule Field (Enemy Near Segment 3)", "Hyrule Field (Enemy Near Segment 3)"), + ("NA_BGM_FIELD_ENEMY_4", "Hyrule Field (Enemy Near Segment 4)", "Hyrule Field (Enemy Near Segment 4)"), + ( + "NA_BGM_FIELD_STILL_1", + "Hyrule Field (Standing Still Segment 1)", + "Hyrule Field (Standing Still Segment 1)", + ), + ( + "NA_BGM_FIELD_STILL_2", + "Hyrule Field (Standing Still Segment 2)", + "Hyrule Field (Standing Still Segment 2)", + ), + ( + "NA_BGM_FIELD_STILL_3", + "Hyrule Field (Standing Still Segment 3)", + "Hyrule Field (Standing Still Segment 3)", + ), + ( + "NA_BGM_FIELD_STILL_4", + "Hyrule Field (Standing Still Segment 4)", + "Hyrule Field (Standing Still Segment 4)", + ), + ("NA_BGM_DUNGEON", "Dodongo's Cavern", "Dodongo's Cavern"), + ("NA_BGM_KAKARIKO_ADULT", "Kakariko Village (Adult)", "Kakariko Village (Adult)"), + ("NA_BGM_ENEMY", "Enemy Battle", "Enemy Battle"), + ("NA_BGM_BOSS", "Boss Battle 00", "Boss Battle 00"), + ("NA_BGM_INSIDE_DEKU_TREE", "Inside the Deku Tree", "Inside the Deku Tree"), + ("NA_BGM_MARKET", "Market", "Market"), + ("NA_BGM_TITLE", "Title Theme", "Title Theme"), + ("NA_BGM_LINK_HOUSE", "Link's House", "Link's House"), + ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), + ("NA_BGM_BOSS_CLEAR", "Boss Clear", "Boss Clear"), + ("NA_BGM_ITEM_GET", "Item Get", "Item Get"), + ("NA_BGM_OPENING_GANON", "Opening Ganon", "Opening Ganon"), + ("NA_BGM_HEART_GET", "Heart Get", "Heart Get"), + ("NA_BGM_OCA_LIGHT", "Prelude Of Light", "Prelude Of Light"), + ("NA_BGM_JABU_JABU", "Inside Jabu-Jabu's Belly", "Inside Jabu-Jabu's Belly"), + ("NA_BGM_KAKARIKO_KID", "Kakariko Village (Child)", "Kakariko Village (Child)"), + ("NA_BGM_GREAT_FAIRY", "Great Fairy's Fountain", "Great Fairy's Fountain"), + ("NA_BGM_ZELDA_THEME", "Zelda's Theme", "Zelda's Theme"), + ("NA_BGM_FIRE_TEMPLE", "Fire Temple", "Fire Temple"), + ("NA_BGM_OPEN_TRE_BOX", "Open Treasure Chest", "Open Treasure Chest"), + ("NA_BGM_FOREST_TEMPLE", "Forest Temple", "Forest Temple"), + ("NA_BGM_COURTYARD", "Hyrule Castle Courtyard", "Hyrule Castle Courtyard"), + ("NA_BGM_GANON_TOWER", "Ganondorf's Theme", "Ganondorf's Theme"), + ("NA_BGM_LONLON", "Lon Lon Ranch", "Lon Lon Ranch"), + ("NA_BGM_GORON_CITY", "Goron City", "Goron City"), + ("NA_BGM_FIELD_MORNING", "Hyrule Field Morning Theme", "Hyrule Field Morning Theme"), + ("NA_BGM_SPIRITUAL_STONE", "Spiritual Stone Get", "Spiritual Stone Get"), + ("NA_BGM_OCA_BOLERO", "Bolero of Fire", "Bolero of Fire"), + ("NA_BGM_OCA_MINUET", "Minuet of Woods", "Minuet of Woods"), + ("NA_BGM_OCA_SERENADE", "Serenade of Water", "Serenade of Water"), + ("NA_BGM_OCA_REQUIEM", "Requiem of Spirit", "Requiem of Spirit"), + ("NA_BGM_OCA_NOCTURNE", "Nocturne of Shadow", "Nocturne of Shadow"), + ("NA_BGM_MINI_BOSS", "Mini-Boss Battle", "Mini-Boss Battle"), + ("NA_BGM_SMALL_ITEM_GET", "Obtain Small Item", "Obtain Small Item"), + ("NA_BGM_TEMPLE_OF_TIME", "Temple of Time", "Temple of Time"), + ("NA_BGM_EVENT_CLEAR", "Escape from Lon Lon Ranch", "Escape from Lon Lon Ranch"), + ("NA_BGM_KOKIRI", "Kokiri Forest", "Kokiri Forest"), + ("NA_BGM_OCA_FAIRY_GET", "Obtain Fairy Ocarina", "Obtain Fairy Ocarina"), + ("NA_BGM_SARIA_THEME", "Lost Woods", "Lost Woods"), + ("NA_BGM_SPIRIT_TEMPLE", "Spirit Temple", "Spirit Temple"), + ("NA_BGM_HORSE", "Horse Race", "Horse Race"), + ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), + ("NA_BGM_INGO", "Ingo's Theme", "Ingo's Theme"), + ("NA_BGM_MEDALLION_GET", "Obtain Medallion", "Obtain Medallion"), + ("NA_BGM_OCA_SARIA", "Ocarina Saria's Song", "Ocarina Saria's Song"), + ("NA_BGM_OCA_EPONA", "Ocarina Epona's Song", "Ocarina Epona's Song"), + ("NA_BGM_OCA_ZELDA", "Ocarina Zelda's Lullaby", "Ocarina Zelda's Lullaby"), + ("NA_BGM_OCA_SUNS", "Sun's Song", "Sun's Song"), + ("NA_BGM_OCA_TIME", "Song of Time", "Song of Time"), + ("NA_BGM_OCA_STORM", "Song of Storms", "Song of Storms"), + ("NA_BGM_NAVI_OPENING", "Fairy Flying", "Fairy Flying"), + ("NA_BGM_DEKU_TREE_CS", "Deku Tree", "Deku Tree"), + ("NA_BGM_WINDMILL", "Windmill Hut", "Windmill Hut"), + ("NA_BGM_HYRULE_CS", "Legend of Hyrule", "Legend of Hyrule"), + ("NA_BGM_MINI_GAME", "Shooting Gallery", "Shooting Gallery"), + ("NA_BGM_SHEIK", "Sheik's Theme", "Sheik's Theme"), + ("NA_BGM_ZORA_DOMAIN", "Zora's Domain", "Zora's Domain"), + ("NA_BGM_APPEAR", "Enter Zelda", "Enter Zelda"), + ("NA_BGM_ADULT_LINK", "Goodbye to Zelda", "Goodbye to Zelda"), + ("NA_BGM_MASTER_SWORD", "Master Sword", "Master Sword"), + ("NA_BGM_INTRO_GANON", "Ganon Intro", "Ganon Intro"), + ("NA_BGM_SHOP", "Shop", "Shop"), + ("NA_BGM_CHAMBER_OF_SAGES", "Chamber of the Sages", "Chamber of the Sages"), + ("NA_BGM_FILE_SELECT", "File Select", "File Select"), + ("NA_BGM_ICE_CAVERN", "Ice Cavern", "Ice Cavern"), + ("NA_BGM_DOOR_OF_TIME", "Open Door of Temple of Time", "Open Door of Temple of Time"), + ("NA_BGM_OWL", "Kaepora Gaebora's Theme", "Kaepora Gaebora's Theme"), + ("NA_BGM_SHADOW_TEMPLE", "Shadow Temple", "Shadow Temple"), + ("NA_BGM_WATER_TEMPLE", "Water Temple", "Water Temple"), + ("NA_BGM_BRIDGE_TO_GANONS", "Ganon's Castle Bridge", "Ganon's Castle Bridge"), + ("NA_BGM_OCARINA_OF_TIME", "Ocarina of Time", "Ocarina of Time"), + ("NA_BGM_GERUDO_VALLEY", "Gerudo Valley", "Gerudo Valley"), + ("NA_BGM_POTION_SHOP", "Potion Shop", "Potion Shop"), + ("NA_BGM_KOTAKE_KOUME", "Kotake & Koume's Theme", "Kotake & Koume's Theme"), + ("NA_BGM_ESCAPE", "Escape from Ganon's Castle", "Escape from Ganon's Castle"), + ("NA_BGM_UNDERGROUND", "Ganon's Castle Under Ground", "Ganon's Castle Under Ground"), + ("NA_BGM_GANONDORF_BOSS", "Ganondorf Battle", "Ganondorf Battle"), + ("NA_BGM_GANON_BOSS", "Ganon Battle", "Ganon Battle"), + ("NA_BGM_END_DEMO", "Seal of Six Sages", "Seal of Six Sages"), + ("NA_BGM_STAFF_1", "End Credits I", "End Credits I"), + ("NA_BGM_STAFF_2", "End Credits II", "End Credits II"), + ("NA_BGM_STAFF_3", "End Credits III", "End Credits III"), + ("NA_BGM_STAFF_4", "End Credits IV", "End Credits IV"), + ("NA_BGM_FIRE_BOSS", "King Dodongo & Volvagia Boss Battle", "King Dodongo & Volvagia Boss Battle"), + ("NA_BGM_TIMED_MINI_GAME", "Mini-Game", "Mini-Game"), + ("NA_BGM_CUTSCENE_EFFECTS", "Various Cutscene Sounds", "Various Cutscene Sounds"), + ("NA_BGM_NO_MUSIC", "No Music", "No Music"), + ("NA_BGM_NATURE_SFX_RAIN", "Nature Ambiance: Rain", "Nature Ambiance: Rain"), +] + +ootEnumNightSeq = [ + ("Custom", "Custom", "Custom"), + ("0x00", "General Night", "NATURE_ID_GENERAL_NIGHT"), + ("0x01", "Market Entrance", "NATURE_ID_MARKET_ENTRANCE"), + ("0x02", "Kakariko Region", "NATURE_ID_KAKARIKO_REGION"), + ("0x03", "Market Ruins", "NATURE_ID_MARKET_RUINS"), + ("0x04", "Kokiri Region", "NATURE_ID_KOKIRI_REGION"), + ("0x05", "Market Night", "NATURE_ID_MARKET_NIGHT"), + ("0x06", "NATURE_ID_06", "NATURE_ID_06"), + ("0x07", "Ganon's Lair", "NATURE_ID_GANONS_LAIR"), + ("0x08", "NATURE_ID_08", "NATURE_ID_08"), + ("0x09", "NATURE_ID_09", "NATURE_ID_09"), + ("0x0A", "Wasteland", "NATURE_ID_WASTELAND"), + ("0x0B", "Colossus", "NATURE_ID_COLOSSUS"), + ("0x0C", "Nature DMT", "NATURE_ID_DEATH_MOUNTAIN_TRAIL"), + ("0x0D", "NATURE_ID_0D", "NATURE_ID_0D"), + ("0x0E", "NATURE_ID_0E", "NATURE_ID_0E"), + ("0x0F", "NATURE_ID_0F", "NATURE_ID_0F"), + ("0x10", "NATURE_ID_10", "NATURE_ID_10"), + ("0x11", "NATURE_ID_11", "NATURE_ID_11"), + ("0x12", "NATURE_ID_12", "NATURE_ID_12"), + ("0x13", "None", "NATURE_ID_NONE"), + ("0xFF", "Disabled", "NATURE_ID_DISABLED"), +] + +enum_seq_id = [ + ("Custom", "Custom", "Custom"), + ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), + ("NA_BGM_AMBIENCE", "Ambient background noises", "Ambient background noises"), + ("NA_BGM_TERMINA_FIELD", "Termina Field", "Termina Field"), + ("NA_BGM_CHASE", "Chase", "Chase"), + ("NA_BGM_MAJORAS_THEME", "Majora's Theme", "Majora's Theme"), + ("NA_BGM_CLOCK_TOWER", "Clock Tower", "Clock Tower"), + ("NA_BGM_STONE_TOWER_TEMPLE", "Stone Tower Temple", "Stone Tower Temple"), + ("NA_BGM_INV_STONE_TOWER_TEMPLE", "Stone Tower Temple Upside-down", "Stone Tower Temple Upside-down"), + ("NA_BGM_FAILURE_0", "Missed Event 1", "Missed Event 1"), + ("NA_BGM_FAILURE_1", "Missed Event 2", "Missed Event 2"), + ("NA_BGM_HAPPY_MASK_SALESMAN", "Happy Mask Saleman's Theme", "Happy Mask Saleman's Theme"), + ("NA_BGM_SONG_OF_HEALING", "Song Of Healing", "Song Of Healing"), + ("NA_BGM_SWAMP_REGION", "Southern Swamp", "Southern Swamp"), + ("NA_BGM_ALIEN_INVASION", "Ghost Attack", "Ghost Attack"), + ("NA_BGM_SWAMP_CRUISE", "Boat Cruise", "Boat Cruise"), + ("NA_BGM_SHARPS_CURSE", "Sharp's Curse", "Sharp's Curse"), + ("NA_BGM_GREAT_BAY_REGION", "Great Bay Coast", "Great Bay Coast"), + ("NA_BGM_IKANA_REGION", "Ikana Valley", "Ikana Valley"), + ("NA_BGM_DEKU_PALACE", "Deku Palace", "Deku Palace"), + ("NA_BGM_MOUNTAIN_REGION", "Mountain Village", "Mountain Village"), + ("NA_BGM_PIRATES_FORTRESS", "Pirates' Fortress", "Pirates' Fortress"), + ("NA_BGM_CLOCK_TOWN_DAY_1", "Clock Town, First Day", "Clock Town, First Day"), + ("NA_BGM_CLOCK_TOWN_DAY_2", "Clock Town, Second Day", "Clock Town, Second Day"), + ("NA_BGM_CLOCK_TOWN_DAY_3", "Clock Town, Third Day", "Clock Town, Third Day"), + ("NA_BGM_FILE_SELECT", "File Select", "File Select"), + ("NA_BGM_CLEAR_EVENT", "Event Clear", "Event Clear"), + ("NA_BGM_ENEMY", "Battle", "Battle"), + ("NA_BGM_BOSS", "Boss Battle", "Boss Battle"), + ("NA_BGM_WOODFALL_TEMPLE", "Woodfall Temple", "Woodfall Temple"), + ("NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE"), + ("NA_BGM_OPENING", "Opening", "Opening"), + ("NA_BGM_INSIDE_A_HOUSE", "House", "House"), + ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), + ("NA_BGM_CLEAR_BOSS", "Boss Clear", "Boss Clear"), + ("NA_BGM_GET_ITEM", "Item Catch", "Item Catch"), + ("NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR"), + ("NA_BGM_GET_HEART", "Get A Heart Container", "Get A Heart Container"), + ("NA_BGM_TIMED_MINI_GAME", "Mini Game", "Mini Game"), + ("NA_BGM_GORON_RACE", "Goron Race", "Goron Race"), + ("NA_BGM_MUSIC_BOX_HOUSE", "Music Box House", "Music Box House"), + ("NA_BGM_FAIRY_FOUNTAIN", "Fairy's Fountain", "Fairy's Fountain"), + ("NA_BGM_ZELDAS_LULLABY", "Zelda's Theme", "Zelda's Theme"), + ("NA_BGM_ROSA_SISTERS", "Rosa Sisters", "Rosa Sisters"), + ("NA_BGM_OPEN_CHEST", "Open Treasure Box", "Open Treasure Box"), + ("NA_BGM_MARINE_RESEARCH_LAB", "Marine Research Laboratory", "Marine Research Laboratory"), + ("NA_BGM_GIANTS_THEME", "Giants' Theme", "Giants' Theme"), + ("NA_BGM_SONG_OF_STORMS", "Guru-Guru's Song", "Guru-Guru's Song"), + ("NA_BGM_ROMANI_RANCH", "Romani Ranch", "Romani Ranch"), + ("NA_BGM_GORON_VILLAGE", "Goron Village", "Goron Village"), + ("NA_BGM_MAYORS_OFFICE", "Mayor's Meeting", "Mayor's Meeting"), + ("NA_BGM_OCARINA_EPONA", "Ocarina “Epona's Song”", "Ocarina “Epona's Song”"), + ("NA_BGM_OCARINA_SUNS", "Ocarina “Sun's Song”", "Ocarina “Sun's Song”"), + ("NA_BGM_OCARINA_TIME", "Ocarina “Song Of Time”", "Ocarina “Song Of Time”"), + ("NA_BGM_OCARINA_STORM", "Ocarina “Song Of Storms”", "Ocarina “Song Of Storms”"), + ("NA_BGM_ZORA_HALL", "Zora Hall", "Zora Hall"), + ("NA_BGM_GET_NEW_MASK", "Get A Mask", "Get A Mask"), + ("NA_BGM_MINI_BOSS", "Middle Boss Battle", "Middle Boss Battle"), + ("NA_BGM_GET_SMALL_ITEM", "Small Item Catch", "Small Item Catch"), + ("NA_BGM_ASTRAL_OBSERVATORY", "Astral Observatory", "Astral Observatory"), + ("NA_BGM_CAVERN", "Cavern", "Cavern"), + ("NA_BGM_MILK_BAR", "Milk Bar", "Milk Bar"), + ("NA_BGM_ZELDA_APPEAR", "Enter Zelda", "Enter Zelda"), + ("NA_BGM_SARIAS_SONG", "Woods Of Mystery", "Woods Of Mystery"), + ("NA_BGM_GORON_GOAL", "Goron Race Goal", "Goron Race Goal"), + ("NA_BGM_HORSE", "Horse Race", "Horse Race"), + ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), + ("NA_BGM_INGO", "Gorman Track", "Gorman Track"), + ("NA_BGM_KOTAKE_POTION_SHOP", "Magic Hags' Potion Shop", "Magic Hags' Potion Shop"), + ("NA_BGM_SHOP", "Shop", "Shop"), + ("NA_BGM_OWL", "Owl", "Owl"), + ("NA_BGM_SHOOTING_GALLERY", "Shooting Gallery", "Shooting Gallery"), + ("NA_BGM_OCARINA_SOARING", "Ocarina “Song Of Soaring”", "Ocarina “Song Of Soaring”"), + ("NA_BGM_OCARINA_HEALING", "Ocarina “Song Of Healing”", "Ocarina “Song Of Healing”"), + ("NA_BGM_INVERTED_SONG_OF_TIME", "Ocarina “Inverted Song Of Time”", "Ocarina “Inverted Song Of Time”"), + ("NA_BGM_SONG_OF_DOUBLE_TIME", "Ocarina “Song Of Double Time”", "Ocarina “Song Of Double Time”"), + ("NA_BGM_SONATA_OF_AWAKENING", "Sonata of Awakening", "Sonata of Awakening"), + ("NA_BGM_GORON_LULLABY", "Goron Lullaby", "Goron Lullaby"), + ("NA_BGM_NEW_WAVE_BOSSA_NOVA", "New Wave Bossa Nova", "New Wave Bossa Nova"), + ("NA_BGM_ELEGY_OF_EMPTINESS", "Elegy Of Emptiness", "Elegy Of Emptiness"), + ("NA_BGM_OATH_TO_ORDER", "Oath To Order", "Oath To Order"), + ("NA_BGM_SWORD_TRAINING_HALL", "Swordsman's School", "Swordsman's School"), + ("NA_BGM_OCARINA_LULLABY_INTRO", "Ocarina “Goron Lullaby Intro”", "Ocarina “Goron Lullaby Intro”"), + ("NA_BGM_LEARNED_NEW_SONG", "Get The Ocarina", "Get The Ocarina"), + ("NA_BGM_BREMEN_MARCH", "Bremen March", "Bremen March"), + ("NA_BGM_BALLAD_OF_THE_WIND_FISH", "Ballad Of The Wind Fish", "Ballad Of The Wind Fish"), + ("NA_BGM_SONG_OF_SOARING", "Song Of Soaring", "Song Of Soaring"), + ("NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE"), + ("NA_BGM_FINAL_HOURS", "Last Day", "Last Day"), + ("NA_BGM_MIKAU_RIFF", "Mikau", "Mikau"), + ("NA_BGM_MIKAU_FINALE", "Mikau", "Mikau"), + ("NA_BGM_FROG_SONG", "Frog Song", "Frog Song"), + ("NA_BGM_OCARINA_SONATA", "Ocarina “Sonata Of Awakening”", "Ocarina “Sonata Of Awakening”"), + ("NA_BGM_OCARINA_LULLABY", "Ocarina “Goron Lullaby”", "Ocarina “Goron Lullaby”"), + ("NA_BGM_OCARINA_NEW_WAVE", "Ocarina “New Wave Bossa Nova”", "Ocarina “New Wave Bossa Nova”"), + ("NA_BGM_OCARINA_ELEGY", "Ocarina “Elegy of Emptiness”", "Ocarina “Elegy of Emptiness”"), + ("NA_BGM_OCARINA_OATH", "Ocarina “Oath To Order”", "Ocarina “Oath To Order”"), + ("NA_BGM_MAJORAS_LAIR", "Majora Boss Room", "Majora Boss Room"), + ("NA_BGM_OCARINA_LULLABY_INTRO_PTR", "NA_BGM_OCARINA_LULLABY_INTRO", "NA_BGM_OCARINA_LULLABY_INTRO"), + ("NA_BGM_OCARINA_GUITAR_BASS_SESSION", "Bass and Guitar Session", "Bass and Guitar Session"), + ("NA_BGM_PIANO_SESSION", "Piano Solo", "Piano Solo"), + ("NA_BGM_INDIGO_GO_SESSION", "The Indigo-Go's", "The Indigo-Go's"), + ("NA_BGM_SNOWHEAD_TEMPLE", "Snowhead Temple", "Snowhead Temple"), + ("NA_BGM_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), + ("NA_BGM_NEW_WAVE_SAXOPHONE", "New Wave Bossa Nova", "New Wave Bossa Nova"), + ("NA_BGM_NEW_WAVE_VOCAL", "New Wave Bossa Nova", "New Wave Bossa Nova"), + ("NA_BGM_MAJORAS_WRATH", "Majora's Wrath Battle", "Majora's Wrath Battle"), + ("NA_BGM_MAJORAS_INCARNATION", "Majora's Incarnate Battle", "Majora's Incarnate Battle"), + ("NA_BGM_MAJORAS_MASK", "Majora's Mask Battle", "Majora's Mask Battle"), + ("NA_BGM_BASS_PLAY", "Bass Practice", "Bass Practice"), + ("NA_BGM_DRUMS_PLAY", "Drums Practice", "Drums Practice"), + ("NA_BGM_PIANO_PLAY", "Piano Practice", "Piano Practice"), + ("NA_BGM_IKANA_CASTLE", "Ikana Castle", "Ikana Castle"), + ("NA_BGM_GATHERING_GIANTS", "Calling The Four Giants", "Calling The Four Giants"), + ("NA_BGM_KAMARO_DANCE", "Kamaro's Dance", "Kamaro's Dance"), + ("NA_BGM_CREMIA_CARRIAGE", "Cremia's Carriage", "Cremia's Carriage"), + ("NA_BGM_KEATON_QUIZ", "Keaton's Quiz", "Keaton's Quiz"), + ("NA_BGM_END_CREDITS", "The End / Credits", "The End / Credits"), + ("NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP"), + ("NA_BGM_TITLE_THEME", "Title Theme", "Title Theme"), + ("NA_BGM_DUNGEON_APPEAR", "Woodfall Rises", "Woodfall Rises"), + ("NA_BGM_WOODFALL_CLEAR", "Southern Swamp Clears", "Southern Swamp Clears"), + ("NA_BGM_SNOWHEAD_CLEAR", "Snowhead Clear", "Snowhead Clear"), + ("NA_BGM_INTO_THE_MOON", "To The Moon", "To The Moon"), + ("NA_BGM_GOODBYE_GIANT", "The Giants' Exit", "The Giants' Exit"), + ("NA_BGM_TATL_AND_TAEL", "Tatl and Tael", "Tatl and Tael"), + ("NA_BGM_MOONS_DESTRUCTION", "Moon's Destruction", "Moon's Destruction"), + ("NA_BGM_END_CREDITS_SECOND_HALF", "The End / Credits (Half 2)", "The End / Credits (Half 2)"), +] + +enum_ambiance_id = [ + ("Custom", "Custom", "Custom"), + ("0x00", "AMBIENCE_ID_00", "AMBIENCE_ID_00"), + ("0x01", "AMBIENCE_ID_01", "AMBIENCE_ID_01"), + ("0x02", "AMBIENCE_ID_02", "AMBIENCE_ID_02"), + ("0x03", "AMBIENCE_ID_03", "AMBIENCE_ID_03"), + ("0x04", "AMBIENCE_ID_04", "AMBIENCE_ID_04"), + ("0x05", "AMBIENCE_ID_05", "AMBIENCE_ID_05"), + ("0x06", "AMBIENCE_ID_06", "AMBIENCE_ID_06"), + ("0x07", "AMBIENCE_ID_07", "AMBIENCE_ID_07"), + ("0x08", "AMBIENCE_ID_08", "AMBIENCE_ID_08"), + ("0x09", "AMBIENCE_ID_09", "AMBIENCE_ID_09"), + ("0x0A", "AMBIENCE_ID_0A", "AMBIENCE_ID_0A"), + ("0x0B", "AMBIENCE_ID_0B", "AMBIENCE_ID_0B"), + ("0x0C", "AMBIENCE_ID_0C", "AMBIENCE_ID_0C"), + ("0x0D", "AMBIENCE_ID_0D", "AMBIENCE_ID_0D"), + ("0x0E", "AMBIENCE_ID_0E", "AMBIENCE_ID_0E"), + ("0x0F", "AMBIENCE_ID_0F", "AMBIENCE_ID_0F"), + ("0x10", "AMBIENCE_ID_10", "AMBIENCE_ID_10"), + ("0x11", "AMBIENCE_ID_11", "AMBIENCE_ID_11"), + ("0x12", "AMBIENCE_ID_12", "AMBIENCE_ID_12"), + ("0x13", "AMBIENCE_ID_13", "AMBIENCE_ID_13"), + ("0xFF", "AMBIENCE_ID_DISABLED", "AMBIENCE_ID_DISABLED"), +] + + +@dataclass +class Z64_Data: + """Contains data related to OoT, like actors or objects""" + + def __init__(self, game: str = "OOT"): + from .enum_data import Z64_EnumData + from .object_data import Z64_ObjectData + from .actor_data import Z64_ActorData + + self.enumData = Z64_EnumData(game) + self.objectData = Z64_ObjectData(game) + self.actorData = Z64_ActorData(game) + + # `EnumProperty` requires fixed values + if game == "OOT": + self.ootEnumMusicSeq = ootEnumMusicSeq + self.ootEnumNightSeq = ootEnumNightSeq + else: + self.ootEnumMusicSeq = enum_seq_id + self.ootEnumNightSeq = enum_ambiance_id + + pass diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py new file mode 100644 index 000000000..cce2d101a --- /dev/null +++ b/fast64_internal/data/z64/enum_data.py @@ -0,0 +1,180 @@ +from dataclasses import dataclass, field +from os import path +from pathlib import Path +from .getters import get_xml_root +from .data import Z64_BaseElement + +# Note: "enumData" in this context refers to an OoT Object file (like ``gameplay_keep``) + + +@dataclass +class Z64_ItemElement(Z64_BaseElement): + parentKey: str + game: str + + def __post_init__(self): + # generate the name from the id + + if self.name is None: + if self.game == "OOT": + keyToPrefix = { + "csCmd": "CS_CMD", + "csMiscType": "CS_MISC", + "csTextType": "CS_TEXT", + "csFadeOutSeqPlayer": "CS_FADE_OUT", + "csTransitionType": "CS_TRANS", + "csDestination": "CS_DEST", + "csPlayerCueId": "PLAYER_CUEID", + "naviQuestHintType": "NAVI_QUEST_HINTS", + "ocarinaSongActionId": "OCARINA_ACTION", + } + else: + keyToPrefix = { + "cmd": "CS_CMD", + "miscType": "CS_MISC", + "textType": "CS_TEXT", + "fadeOutSeqPlayer": "CS_FADE_OUT", + "modifySeqType": "CS_MOD", + "transitionType": "CS_TRANS", + "destinationType": "CS_DESTINATION", + "chooseCreditsSceneType": "CS_CREDITS", + "motionBlurType": "CS_MOTION_BLUR", + "rumbleType": "CS_RUMBLE", + "transitionGeneralType": "CS_TRANS_GENERAL", + "spawnFlag": "CS_SPAWN_FLAG", + "endSfx": "CS_END_SFX", + "csSplineInterpType": "CS_CAM_INTERP", + "csSplineRelTo": "CS_CAM_REL", + "playerCueId": "PLAYER_CUEID", + "naviQuestHintType": "NAVI_QUEST_HINTS", + "ocarinaSongActionId": "OCARINA_ACTION", + } + + self.name = self.id.removeprefix(f"{keyToPrefix[self.parentKey]}_") + + if self.parentKey in ["csCmd", "csPlayerCueId"]: + split = self.name.split("_") + if self.parentKey == "csCmd" and "ACTOR_CUE" in self.id: + self.name = f"Actor Cue {split[-2]}_{split[-1]}" + else: + self.name = f"Player Cue Id {split[-1]}" + else: + self.name = self.name.replace("_", " ").title() + + +@dataclass +class Z64_EnumElement(Z64_BaseElement): + items: list[Z64_ItemElement] + item_by_key: dict[str, Z64_ItemElement] = field(default_factory=dict) + item_by_index: dict[int, Z64_ItemElement] = field(default_factory=dict) + item_by_id: dict[int, Z64_ItemElement] = field(default_factory=dict) + + def __post_init__(self): + self.item_by_key = {item.key: item for item in self.items} + self.item_by_index = {item.index: item for item in self.items} + self.item_by_id = {item.id: item for item in self.items} + + +class Z64_EnumData: + """Cutscene and misc enum data""" + + def __init__(self, game: str): + # general enumData list + self.enumDataList: list[Z64_EnumElement] = [] + + # Path to the ``EnumData.xml`` file + xml_path = Path(f"{path.dirname(path.abspath(__file__))}/xml/{game.lower()}_enum_data.xml") + enum_data_root = get_xml_root(xml_path.resolve()) + + for enum in enum_data_root.iterfind("Enum"): + self.enumDataList.append( + Z64_EnumElement( + enum.attrib["ID"], + enum.attrib["Key"], + None, + None, + [ + Z64_ItemElement( + item.attrib["ID"], + item.attrib["Key"], + # note: the name sets automatically after the init if None + item.attrib["Name"] if enum.attrib["Key"] == "seqId" else None, + int(item.attrib["Index"]), + enum.attrib["Key"], + ) + for item in enum + ], + ) + ) + + # create list of tuples used by Blender's enum properties + self.deletedEntry = ("None", "(Deleted from the XML)", "None") + + self.ootEnumCsCmd: list[tuple[str, str, str]] = [] + self.ootEnumCsMiscType: list[tuple[str, str, str]] = [] + self.ootEnumCsTextType: list[tuple[str, str, str]] = [] + self.ootEnumCsFadeOutSeqPlayer: list[tuple[str, str, str]] = [] + self.ootEnumCsTransitionType: list[tuple[str, str, str]] = [] + self.ootEnumCsDestination: list[tuple[str, str, str]] = [] + self.ootEnumCsPlayerCueId: list[tuple[str, str, str]] = [] + self.ootEnumNaviQuestHintType: list[tuple[str, str, str]] = [] + self.ootEnumOcarinaSongActionId: list[tuple[str, str, str]] = [] + self.ootEnumSeqId: list[tuple[str, str, str]] = [] + + self.enum_modify_seq_type: list[tuple[str, str, str]] = [] + self.enum_credits_scene_type: list[tuple[str, str, str]] = [] + self.enum_motion_blur_type: list[tuple[str, str, str]] = [] + self.enum_rumble_type: list[tuple[str, str, str]] = [] + self.enum_transition_general_type: list[tuple[str, str, str]] = [] + self.enum_spawn_flag: list[tuple[str, str, str]] = [] + self.enum_end_sfx: list[tuple[str, str, str]] = [] + self.enum_split_interp_type: list[tuple[str, str, str]] = [] + self.enum_spline_rel_to: list[tuple[str, str, str]] = [] + + self.enumByID = {enum.id: enum for enum in self.enumDataList} + self.enumByKey = {enum.key: enum for enum in self.enumDataList} + + key_to_enum = { + "cmd": "ootEnumCsCmd", + "miscType": "ootEnumCsMiscType", + "textType": "ootEnumCsTextType", + "fadeOutSeqPlayer": "ootEnumCsFadeOutSeqPlayer", + "modifySeqType": "enum_cs_modify_seq_type", + "transitionType": "ootEnumCsTransitionType", + "destinationType": "ootEnumCsDestination", + "chooseCreditsSceneType": "enum_cs_credits_scene_type", + "motionBlurType": "enum_cs_motion_blur_type", + "rumbleType": "enum_cs_rumble_type", + "transitionGeneralType": "enum_cs_transition_general_type", + "spawnFlag": "enum_cs_spawn_flag", + "endSfx": "enum_cs_end_sfx", + "csSplineInterpType": "enum_cs_split_interp_type", + "csSplineRelTo": "enum_cs_spline_rel_to", + "playerCueId": "ootEnumCsPlayerCueId", + "naviQuestHintType": "ootEnumNaviQuestHintType", + "ocarinaSongActionId": "ootEnumOcarinaSongActionId", + "seqId": "ootEnumSeqId", + } + + for key in self.enumByKey.keys(): + name = ("ootEnum" + key[0].upper() + key[1:]) if game == "OOT" else key_to_enum[key] + setattr(self, name, self.get_enum_data(key)) + + def get_enum_data(self, enumKey: str): + enum = self.enumByKey[enumKey] + firstIndex = min(1, *(item.index for item in enum.items)) + lastIndex = max(1, *(item.index for item in enum.items)) + 1 + enumData = [self.deletedEntry] * lastIndex + custom = ("Custom", "Custom", "Custom") + + for item in enum.items: + if item.index < lastIndex: + identifier = item.key + enumData[item.index] = (identifier, item.name, item.id) + + if firstIndex > 0: + enumData[0] = custom + else: + enumData.insert(0, custom) + + return enumData diff --git a/fast64_internal/data/oot/getters.py b/fast64_internal/data/z64/getters.py similarity index 87% rename from fast64_internal/data/oot/getters.py rename to fast64_internal/data/z64/getters.py index fb4fbfe09..d0b76ce74 100644 --- a/fast64_internal/data/oot/getters.py +++ b/fast64_internal/data/z64/getters.py @@ -1,7 +1,7 @@ from xml.etree.ElementTree import parse as parseXML, Element -def getXMLRoot(xmlPath: str) -> Element: +def get_xml_root(xmlPath: str) -> Element: """Parse an XML file and return its root element""" try: return parseXML(xmlPath).getroot() diff --git a/fast64_internal/data/oot/object_data.py b/fast64_internal/data/z64/object_data.py similarity index 74% rename from fast64_internal/data/oot/object_data.py rename to fast64_internal/data/z64/object_data.py index d588a07dd..db3a663de 100644 --- a/fast64_internal/data/oot/object_data.py +++ b/fast64_internal/data/z64/object_data.py @@ -1,32 +1,33 @@ from dataclasses import dataclass from os import path +from pathlib import Path from ...utility import PluginError -from .getters import getXMLRoot -from .data import OoT_BaseElement +from .getters import get_xml_root +from .data import Z64_BaseElement # Note: "object" in this context refers to an OoT Object file (like ``gameplay_keep``) @dataclass -class OoT_ObjectElement(OoT_BaseElement): +class Z64_ObjectElement(Z64_BaseElement): pass -class OoT_ObjectData: +class Z64_ObjectData: """Everything related to OoT objects""" - def __init__(self): + def __init__(self, game: str): # general object list - self.objectList: list[OoT_ObjectElement] = [] + self.objectList: list[Z64_ObjectElement] = [] # Path to the ``ObjectList.xml`` file - objectXML = path.dirname(path.abspath(__file__)) + "/xml/ObjectList.xml" - objectRoot = getXMLRoot(objectXML) + xml_path = Path(f"{path.dirname(path.abspath(__file__))}/xml/{game.lower()}_object_list.xml") + object_root = get_xml_root(xml_path.resolve()) - for obj in objectRoot.iterfind("Object"): + for obj in object_root.iterfind("Object"): objName = f"{obj.attrib['Name']} - {obj.attrib['ID'].removeprefix('OBJECT_')}" self.objectList.append( - OoT_ObjectElement(obj.attrib["ID"], obj.attrib["Key"], objName, int(obj.attrib["Index"])) + Z64_ObjectElement(obj.attrib["ID"], obj.attrib["Key"], objName, int(obj.attrib["Index"])) ) self.objects_by_id = {obj.id: obj for obj in self.objectList} @@ -41,7 +42,7 @@ def __init__(self): self.ootEnumObjectIDLegacy = self.getObjectIDList(self.objects_by_key["obj_timeblock"].index + 1, True) # validate the legacy list, if there's any None element then something's wrong - if self.deletedEntry in self.ootEnumObjectIDLegacy: + if game == "OOT" and self.deletedEntry in self.ootEnumObjectIDLegacy: raise PluginError("ERROR: Legacy Object List doesn't match!") def getObjectIDList(self, max: int, isLegacy: bool): diff --git a/fast64_internal/data/z64/xml/mm_actor_list.xml b/fast64_internal/data/z64/xml/mm_actor_list.xml new file mode 100644 index 000000000..132dc9539 --- /dev/null +++ b/fast64_internal/data/z64/xml/mm_actor_list.xml @@ -0,0 +1,979 @@ + + + + + + + + + + + + Large Orange Flame + Large Orange Flame + Large Blue Flame + Large Green Flame + Small Orange Flame + Large Orange Flame + Large Green Flame + Large Blue Flame + Large Magenta Flame + Large Pale Orange Flame + Large Pale Yellow Flame + Large Pale Green Flame + Large Pale Pink Flame + Large Pale Purple Flame + Large Pale Indigo Flame + Large Pale Blue Flame + + + + + + + + Whole Day ('ENDOOR_TYPE_WHOLE_DAY') + Locked ('ENDOOR_TYPE_LOCKED') + Day ('ENDOOR_TYPE_DAY') + Night ('ENDOOR_TYPE_NIGHT') + Ajar ('ENDOOR_TYPE_AJAR') + Schedule ('ENDOOR_TYPE_SCHEDULE') + Unknown ('ENDOOR_TYPE_6') + Framed ('ENDOOR_TYPE_FRAMED') + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Golden + Golden - Appears - Clear Flag + Boss Key Chest + Golden - Falls - Switch Flag + Golden - Invisible + Wooden + Wooden - Invisible + Wooden - Clear Flag + Wooden - Falls - Switch Flag + Crash + Crash + Golden - Appears - Switch Flag + + + + + + + + + + + + + + + Regular + Large + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + Invisible + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/data/z64/xml/mm_enum_data.xml b/fast64_internal/data/z64/xml/mm_enum_data.xml new file mode 100644 index 000000000..f7321efa5 --- /dev/null +++ b/fast64_internal/data/z64/xml/mm_enum_data.xml @@ -0,0 +1,719 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/data/z64/xml/mm_object_list.xml b/fast64_internal/data/z64/xml/mm_object_list.xml new file mode 100644 index 000000000..71706d83c --- /dev/null +++ b/fast64_internal/data/z64/xml/mm_object_list.xml @@ -0,0 +1,653 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/data/z64/xml/oot_actor_list.xml b/fast64_internal/data/z64/xml/oot_actor_list.xml new file mode 100644 index 000000000..f3303de70 --- /dev/null +++ b/fast64_internal/data/z64/xml/oot_actor_list.xml @@ -0,0 +1,3695 @@ + + + + + + + + Invisible, Can't Control //Used for cutscenes without Link + Master Sword Pull and Drop Animation //Overwrites coordinates + Spawn: Blue Warp //used when returning from a blue warp + Spawn: Immobile + Spawn: Exit via Grotto //Y velocity = 12 + Spawn: Warp Song + Spawn: Farore's Wind + Spawn: Thrown Out + Stand + Slow Walk Forward + Retain Previous Velocity //Walk speed set by last exit + + + Last 2 digits = Camera Initial Focus //Data defined by scene Link spawns in ++00FF No Special Positioning + + + + Invisible (Lens of Truth), Mini-Boss Theme + Rises from Ground, Mini-Boss Theme + Rises from Ground //Pair with 0001 + Drops From Sky on Approach + Rises from Ground, Mini-Boss Theme + Unknown + + + + + Intended to be spawned by the Shopkeeper actor + + + + Green Flame + Purple Flame + Red Bubbles + Invisible Hovering Object w/Shadow, bursts into purple flames + Green Flame + Green Flame + Purple Flame + Green Flame + + + + + Large Orange Flame + Large Orange Flame + Large Blue Flame + Large Green Flame + Small Orange Flame + Large Orange Flame + Large Green Flame + Large Blue Flame + Large Magenta Flame + Large Pale Orange Flame + Large Pale Yellow Flame + Large Pale Green Flame + Large Pale Pink Flame + Large Pale Purple Flame + Large Pale Indigo Flame + Large Pale Blue Flame + + + + + + + + + Loads Room + Small Key Locked Door + Loads Room + Scene Transition + Ajar (slams on approach) + Displays Textbox + Time Locked (Unlocked between 18:00 and 21:00) + Loads Room + + + + + Model depends on the scene + + + + Large + Large, Appears, Clear Flag + Boss Key's Chest + Large, Falling, Switch Flag + Large, Invisible + Small + Small, Invisible + Small, Appears, Clear Flag + Small, Falls, Switch Flag + Large, Appears, Zelda's Lullaby + Large, Appears, Sun's Song Triggered + Large, Appears, Switch Flag + + + + + + + + Default + + Hardcoded cutscene camera points to -19, -2 ,-1000 + + + Missing variables + + + + Graveyard Poe + Graveyard Poe //Leaves a Blue Rupee at its spawn point + (006E) Sharp (Composer Brothers) //Sets Permanent Switch Flag 0B when spoken to, use object 006E + (006E) Flat (Composer Brothers) //Sets Permanent Switch Flag 0A when talked to, use object 006E + Graveyard Poe + + May need another object + + + + + First 2 digits: Rocks fired per volley + + + + Web-Covered Hole + Vertical Web Wall + Web-Covered Hole //When burned, web becomes inverse-conical and extends upwards + + + + +0x3F00 = Switch Flag (Set when destroyed) + +0x0FC0 = Switch Flag (Web burns when set) + + + + Bomb + Bomb Shadow + + + + + Timer Spawn (every 6 seconds) + Proximity Spawn + Spawn on Switch Flag + + + + 0x3F00 = Switch Flag (Flag to spawn on. Used by type 02 only) + + + + Default + Two-Foot Dodongo //Emits fire and smoke from mouth upon death + Two-Foot Dodongo //Doesn't emit fire and smoke from mouth upon death + + + + + Fire Keese + Aggressive Keese + Roosting Keese + Ice Keese + + + +8000 = Invisible + + + + Epona + No Epona + Default + + + + + Green Rupee + Blue Rupee + Red Rupee + Recovery Heart + Bomb + Arrow (1) //Used for collecting arrows stuck in walls + Heart Piece + Deku Seeds (5) or Arrows (5) + Deku Seeds (5) or Arrows (10) + Deku Seeds (5) or Arrows (30) + Bombs (5) + Deku Nut + Deku Stick + Large Magic Jar + Small Magic Jar + Deku Seeds (5) or Arrows (5) + Small Key + Flexible Drop //Used for randomized drops, see comments. Will spawn as an invisible Recovery Heart in some situations + Giant Orange Rupee + Large Purple Rupee + Deku Shield //May require Child Link's object + Hylian Shield + Zora Tunic + Goron Tunic + Bombs (5) + Invisible Item + + + +0x3F00 = Collectible Flag + + + + Fire Arrow + Wooden Arrow + + + + + Navi + Bottled Healing Fairy + Roaming Healing Fairy + Group of Healing Fairies + Fairy Healing You + Roaming Large Healing Fairy + + + + + Flees when approached //Cucco hidden in the box in Kakariko + Doesn't Flee + Non-Targetable //The non-super cuccos in the Ranch house + Default + + + + + Red Tektite + Blue Tektite + Normal Tektite + Dies Instantly + + + + + Clear flag ignores this monster + + + + Flying Peahat //Spawns Larva + Peahat Larva + Burrowed Peahat + + + + + + + + Large Bug + Three Small Bugs + Small Bug + + + + + Flopping + Swimming, Doesn't Flee //Used for very small pools of water + Swimming, Reacts to Link + Swimming, Flees + + + + + Vertical, two way, fades black when approached + Up/Down, one-way, fades black when approached + Up/Down, two-way, no fade + Vertical, enabled on switch flag, fades black when approached + Vertical, two-way, no fade + Up/Down, two-way, fades black when approached + + + + + + + + Lizalfos mini-boss, drops from ceiling //Partner to 01, in order to be killed + Lizalfos mini-boss, no mini-boss music //Partner to 00, in order to be killed + Lizalfos, no mini-boss music + Dinolfos, no mini-boss music + Lizalfos, no mini-boss music, drops from ceiling + + + +0xFF00 = Nullable Switch Flag Lizalfos miniboss spawns when entering room from door bound to this switch flag +The Lizalfos miniboss (Type 00 and 01) has special behavior to it. +Type 00 and 01 actors must be spawned together for the miniboss to be defeated. +To differentiate the two encounters (as both are in room 3), the switch flag is used. This flag matches the switch flag of the door used to enter the room + + + + Default + + + + + Default + + + + + Default + + + + + Default + + + + + Impa's Horse + Impa on Horse + Zelda + Ganondorf on Horse (Stationary) + Ganondorf's Horse (Stationary) + Ganondorf on Horse (Riding) + Flames + Ganondorf's Horse (Galloping) + Ganondorf hands crossed //use object 009B + Ganondorf Bowing to King + Ganondorf floating (Curse You) //use object 00E1 + + They need their respective objects to load + + + + Spawned by Gohma Boss, falls on ground, hatches quickly + Spawned by Gohma Boss (unknown 1) + Spawned by Gohma Boss (unknown 2) + Ground Gohma Egg (increase spawn count) + Ground Gohma Egg + Ceiling Gohma Egg (increase spawn count, invisible?) + Ceiling Gohma Egg (invisible?) + + + + Unused + + + + Default + + + + + Lifting door + Front side attached to Room Clear + Front side attached to Switch + Back side permanently locked + Boss door //needs object 00B0 + Front side attached to Switch, Back to Room Clear + Key Locked door + + + +003F = Switch Flag //Used by switch flag iron bar and locked doors +Depending on the scene ID, they need certain objects loaded as the first one in the object list. Scene IDs: +00: needs object 0036 +01: needs object 002B +02: needs object 0096 +04: needs object 002C +05: needs object 0059 +06: needs object 016D +07-08: needs object 0187 +09: needs object 006B +0A: needs object 0139 +0B: needs object 004D +0D: needs object 0179 + + + + + Default + + + + + + + + + Default + + + + + Default + + + + + Default + + + + + Normal + Big + Invisible + + Normal + + + + + Default + + + + + Small grey stone block + Large grey stone block + Huge grey stone block + Small grey stone block, rotates when you stand on it + Large grey stone block, rotates when you stand on it + Small grey stone cube + Crashes + Grass clump + Small tree stump + Oblong Signpost (unbreakable) + Arrow Signpost + Black knobby thing + + + +0xFF00 = Message ID (+0300) + + + + Four spinning a circle, but once you kill one, the rest are gone as well + Three in formation, sink under floor and do not activate + Two in formation, sink under floor and do not activate + One in formation, sink under floor and do not activate + Single + + + + + River (Multi-Point) + Stream + Magma + Waterfall + Small Stream + Stream + Fire Temple's Lower Ambient Noise + Fire Temple's Higher Ambient Noise + Water Dripping (Well) + River + Market gibberish + Decrease current BGM volume + Proximity Saria's Song + Howling wind + Gurgling + Temple of Light's dripping sounds + Low booming-likish sound + Quake/Collapse + Fairy Fountain + Torches + Cows + Outside of the ambient noise domain + + + +0xFF00 = Path ID (Used for sound sources, Type 00, 04 and 05 only) + + + + Tan, Runs Around + Tan, Runs Around + Tan, Runs Away + Tan, Runs Around + + + + + Kokiri Shopkeeper, Objects 0x0FC, 0x101, 0x102 + Kakariko Potion Shopkeeper, Object 0x159 + Bombchu Shopkeeper, spawn when King Dodongo is beaten, Object 0x165 + Market Potion Shopkeeper, Object 0x159 + Bazaar Shopkeeper, Object 0x05B + Unused? Shopkeeper, Object 0x05B + Unused? Shopkeeper, Object 0x05B + Zora Shopkeeper, Object 0x0FE + Goron Shopkeeper, Object 0x05B + Unused? Shopkeeper, Object 0x05B + Happy Mask Shopkeeper, Object 0x13E + + + + + Default + + + + + +0x3F = Switch Flag + Spawns when a specific switch flag is set +Out-of-bounds Plane (typ.) + + + + Lower Part (Flame decal) + Top Part (Face decal) + + + +0xFF00 = Switch Flag + + + + Huge + Big + Small + + + ++0x00FF = Switch Flag + + + + + + + Large Face Cube //Pushable + Squat Cube //Shakes and flies into the air when you land on it + + + + + + + + 2-way diagonal + 4-way plus + + + + + Sinking + Sliding + + + + + + + Idle + Unknown + Unknown + Unknown + Transformation into Zelda + Nocturne CS + Minuet CS + Bolero CS + Serenade CS + First Meeting at ToT + + + + +0x0FC0 = Chest Flag + + Large, turns off with room clear. + Large, plays cutscene, switches off for long time with ticking sound. Turns off permanently with chest flag. + Small, switches off for long time silently. + Large, plays cutscene, switches off for short time with ticking sound. + Disabled, small, switches on for short time. + Disabled, large, can be switched on and off. + Large, switches off permanently, won't spawn if room is cleared. + Nothing + + + + +0x003F = Switch Flag + + + + Chains + Drawbridge + + + + + Club Moblin //Pounds the ground + Spear Moblin + + + +0xFF00 = path Id (Spear Moblins only) + + + + Bomb + Invisible Bomb + Default + + + + + Light Arrows CS + Pre-Credits + Post Castle Collapse + + + + + + + + + Floating Platform + Water Plane + 3 Raising platforms + + + + + + Rotating Spike Cylinder + Deku tree ladder falling when hit by slingshot (switchflag?) + + + + + + + + Statue + Enemy + + + + + Small + Big + + + + + + + + + +0x3F = Switch Flag to make the platform rise more, hardcoded cutscene camera points to 420,-180 ,-1180 + + + + Bombable Wall, triggers intro cutscene + Bombable Wall + Bombable Floor + Lava Cover + + + + +0x3F = Switch Flag + + + + Lord Jabu-Jabu + + The actor spawns the collision data + + + + + + + + + Normal (adult Link) + Spawning in from crystal //Combine with Link's gentle fall spawn in + Normal + Nothing + Blue warp, disappears + Giant purple crystal/magic enclosure + Yellow warp, disappears + Blue warp, doesn't warp you + Spawn in from child blue warp //Combine with Link's gentle fall + Blue warp, warping animation + Tan warp, disappears + Green warp, disappears + Red warp, disappears + Area fails to load + + + + + Golden Torch + Puzzle Torch + Wooden Torch + + + + + +0x3C0 = Torches to light to solve puzzle (Timed Torch) + +0x3F = Switch Flag + + + + + + + + + + + + +0x3F = Switch Flag + Requires 4 actors of this id to work + + + + + + Floating Square platform, sloped bottom //Used in first room, on center column + Floating Square platform + Floating Square platform, tapered on bottom //Center Room floating block + Dragon Head Statue //Main Room + Dragon Head Statue //Skulltula Room + Dragon Head Statue //before Dark Link + Dragon Head Statue + Moving Square Platform with Hookshot Target + + + + + + ++0x0F00 = Path to follow //Type 7 only ++0x00F0 = Speed //Type 7 only ++0x000F = Start Point on Path //Type 7 only + + + + + Switches to lowest (Triforce seems to activate itself for some reason in the ToT) + Stays at ground level (Triforce isn't affected in ToT) + Water Temple Map 3, Standard Quest + Water Temple Map 6, Standard Quest + Water Temple Map 14, Standard Quest + Water Temple (most rooms), Standard Quest + + + + + + + + + + + + + + + Large Green Bubble //requires movement path + Green Bubble //requires movement path + White Bubble //requires movement path + Fire Bubble //Proximity activated, bounces on solid surfaces, hides in lava + Blue Bubble + + + +0xFF00 = Path Id + + + + Normal + Invisible + + + + + ++0x00FF = Time until tile rises +Variable is first incremented by 1, then time until tile rises is calculated as T * 0x10 + 0x14 frames. For example: +-FFFF = 0x14 frames +-0000 = 0x24 frames +-0001 = 0x34 frames etc. + + + + +Use with actors 008C and 008B for the cutscene to work + + + + + + + (0068) Ocarina //Unused + (0062) Light Medallion + (0063) Shadow Medallion + (0064) Fire Medallion + (0065) Water Medallion + (0066) Spirit Medallion + (0067) Forest Medallion + + Add the object in brackets for it to work + + + + Yellow with corner removed + Green and rectangular + Yellow/green and rectangular, looks rusty + Crashes, but not without drawing a huge black thing that I can only assume is a gate... + Crashes before it can even light the area... + + Crashes, no sign of a gate + + + +0x3F00 = Switch Flag + + + Spawned by actor 008C + + + + Hammer-triggered Stone Steps + Platform, one sided + + + +0x3F00 = Switch Flag + + + Unused + + + + Large Conical Tree + Medium Conical Tree + Small Conical Tree + Conical Tree Spawner + Conical Tree Spawned + Oval Green Tree + Oval Yellow Tree Spawner + Oval Yellow Tree Spawned + Oval Green Tree Spawner + Oval Green Tree Spawned + Adult Kakariko Tree + Small Bush + Large Bush + Small Bush Spawner + Small Bush Spawned + Large Bush Spawner + Large Bush Spawned + Small Black Bush + Large Black Bush + Small Black Bush Spawner + Small Black Bush Spawned + Large Black Bush Spawner + Large Black Bush Spawned + Green leaf + Yellow leaf + + + + + + +0xFF00 = Controls item(s) dropped (trees only) +-0000 Random +-0800 Deku seeds +-0900 Magic jars +-0A00 Bombs +-0B00 Three Hearts +-0C00 Three Blue Rupees +-0D00 Random +-0E00 Random +-0F00 Nothing ++0xFF00 = Gold Skulltula spawn var low byte if rz != 0 +ZROT 0x00FF = Gold Skulltula spawn var high byte (See Gold Skulltula Actor 0095) + + + + + Normal, flashes blue when struck with sword + Frickin' huge, doesn't flash when struck + Even bigger? + Ridiculously huge? + Small size, flashes blue when struck + + Unused + + + + Stone cube, side struck with sword flashes blue + Slightly larger + + + + + + 4-Way Attack + Line Loop + Circle Loop + + + + + + + + + + + + + + Text ID when he sleeps: 702A + + + + + + Lowers when a clear flag and the switch flag are set + + + + + + + + + + + Attacking Beamos (2 health) + Attacking Beamos (1 health) + + + XX00: 05 in dodongo's cavern, 08 in ganon's castle entrance + + + + Crystal Light, used by Triforce in Hyrule Creation CS + Flame, used by Din in Hyrule Creation CS + Blue Orb, used by Din in Hyrule Creation CS + Large Green Cone, used by Farore in Hyrule Creation CS + Din + Nayru + Farore + Blue Light Ring, used by Din and Farore in Hyrule Creation CS + Triforce + Fire Medallion + Water Medallion + Forest Medallion + Spirit Medallion + Shadow Medallion + Light Medallion + Time Warp Effect from Temple of Time + Blue Light Ring that shrinks, used by Din in Hyrule Creation CS + Vertical Light Effect used by Triforce + Light Ball from the 6 Sages when sealing Ganondorf + Kokiri Emerald + Goron Ruby + Zora Sapphire + Dust, used in Light Arrow CS + Light Ball, used by Zelda + Large Block of Time Time Warp Effect + Small Block of Time Time Warp Effect + + + + + + + + + + + + + + + Blue Rain Effect, used by Goddesses/Triforce CS + Blue Rain Effect, used in the Master Sword CS + Giant Rock 1 + Giant Rock 2 + Giant Rock 3 + Giant Rock 4 + Giant Rock 5 + Fluffy Clouds + Bolero 3D Note (not implemented) + Serenade 3D Note (not implemented) + Requiem 3D Note (not implemented) + ? 3D Note (not implemented) + ? 3D Note (not implemented) + Door of Time + Yellow Light, used in Master Sword's chamber + Warp Song leaving effect + Warp Song arriving effect + Orange Sparkly Effect, used by appearing chests + + + + + Stationary with switch and hardcoded camera cutscene + Follows Player + + + + + + + + + Slow Patrolling Guard + Fast Patrolling Guard + Slow Patrolling Guard, can skip some waypoints + Fast Patrolling Guard, can skip some waypoints + Nighttime Standing Guard + + + Rupees circle spawned if Path ID == 3 + + + + Rising Gibdo + Gibdo + Redead, doesn't mourn + Redead, doesn't mourn if walking + Redead + Crying Redead + Invisible Redead + + + + + + + Meg, Purple Poe + Joelle, Red Poe + Beth, Blue Poe + Amy, Green Poe + + + + + + + + Sinks into the ground + Breaks on impact + + + ++0x3F00 = Switch Flag + + + + + ??? Amy + ??? Amy + Joelle Painting Puzzle + Beth Painting Puzzle + ??? Amy + + + +0x3F = Switch Flag + + + + Fish + Bug + Butterfly + + + + +0xF000 -> 0 to 15 ++0x0700 Spawn Count (0 or 8 or 9 or 12) ++0000 12 spawns ++0100 9 spawns ++0200 8 spawns ++1000 1 spawn + + + + + Skullwalltula + Gold Skulltula + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Flying Fairies, Dustmotes + Lightning + Snow + Electric Spark Effect, object 0x0A1 + Ganon's Castle Barrier Colored Light Beams, object 0x179 + + + + + + + + + + + Visible + Appears on Song of Storms + Appears on explosion or Megaton Hammer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Shadow Temple's Eye of Truth Door + Small Square Patch of Ground, child only, blocks entrance to Dampe's Grave + Royal Tomb Grave, despawn if the Royal Tomb CS is watched and the scene is the graveyard + Thunderbolt used with the electric spark effect + Light Aura, appears when Royal Tomb Grave explodes + + + +0xFF00 = Switch Flag + + + + Default + Plays discovery sfx when pulled back + Typical + + + + + Normal (no sphere) + Dissipating (no sphere) + + + + + + + Blue Warp and Ruto + Leaning Ruto //no collision data, targetable + Ruto, First Encounter //Plays cutscene from Jabu-Jabu's Belly when you first meet her + Ruto, after falling down the hole in Jabu-Jabu + + + + + + + Flies, lands, dies in a bit //try not to run into it, Link'll catch on fire + Flies, lands, creeps towards Link, dies in a bit //it's blue, but it's still fire + + + + does not appear unless his hands exist + + + + + + Light Medallion and post-Spirit/Shadow Medallions + Ganon's Castle and post-Ganon + + + + + Leever //Use object 0017, spawn on sand (max defined by code) + Red Tektite //Use object 0016 (max defined by code) + Stalchildren //Use object 0184, spawn on dirt + Wolfos //Use object 0183 + + + + + ++0xFF = Enemies to Spawn +-0088 When spawning Leevers, 88 is used in Haunted Wasteland +-00A4 When spawning Stalchildren, loads two at a time. Used in Hyrule Field +-00F2 When spawning Leevers, F2 is used in Desert Colossus + + + + + Fire Medallion (Default) + Goron Ruby + Chamber After Ganon + Credits + + + + + Shadow Medallion + Chamber After Ganon/Ganon's Castle + Escort + Hyrule Field after ZL + First Time Escort + Credits + + + + + + + No damage + One-Hit Kill + + + + Spawned by volvagia + + + Spawned by volvagia + + + + Rock Wall with Skull //style that sometimes has glowy eyes + Black square with large skull face + Shadow Temple Boss Room platforms + Wall of Skulls + Shadow Temple Floor //bluish? texture + Massive Platform + Wall with bluish?, fat bricks texture (one sided) + Shadow Temple Diamond Room (before big key) Fake Walls + Wall with purplish?, fat brick texture (both side) + Room 11's invisible spikes, invisible hookshot point. + + Need Object 0x69 + + + + Moving stone platforms + Rising and falling stone platforms + Spinning black platform + Metal grate + Same as 0001, but graphics are glitched + + + +0xFF00 = Switch Flag //Type 03 Only + + + + +0x3F00 = Switch Flag for Zelda's Lullaby spot + Camera cutscene points to X 4738 Y -1395 Z -2006 + + + + Shadow Temple Scythes (Visible) //Use object 0069 + Shadow Temple Scythes (Invisible) //Use object 0069 + Ice Cavern Spinning Blade //Use object 0069 + + May require additional object + + + + Hyrule Castle guard + Death Mountain gate guard + Ceremonial guard + + + + + + + Large + Medium + Small + Large + + + + + + + + + Spirit Temple's Sun-Block Room + Spirit Temple's Single Cobra-Mirror Room + Spirit Temple's Four Armos Room + Spirit Temple's Topmost Room + + + + + Bridge Sides + Broken Bridge + Bridge as Child + Tent + Repaired Bridge + + + + + Statue, no spear, movable with Adult Link + Spear only, climbable + + + + + + Barinade + + + + + Drops a small key if the room isn't 12, if room is 12 it'll act like the 3 spinning pot room before Bongo-Bongo + + + + Guillotine Blade (Slow) + Spiked Box on Chain + Spiked Wooden Wall, moving //FIXME: moves in wrong direction? + Opposite Spiked Wooden Wall, moving //FIXME: moves in wrong direction? + Propeller, blows wind + Guillotine Blade (Fast) + + Graphical glitches, same as 2 or 3 (unsure) + + + + + Spawns gibdo //(needs object 0098) + Spawns 2 keese //(needs object 000D) + + + +0x3F = Switch Flag + + + + Giant Bird Statue, bombing it will make it fall + Bombable Wall of Skulls + Bombable Rubble (Object 0x8D) + + + +0x3F00 = Switch Flag + + + + + + + + + + Wooden (Default) + Stone (Zora) + Granite (Goron) + + + + + Spirit Medallion + Chamber After Ganon/Ganon's Castle + Kidnapping CS + Iron Knuckle + Credits + Crawlspace + + + + + + + + + Sits there, mini-boss music starts, slice it to make it move (no teleport), green target + Already running around, yellow target this time, no music + + Slicing it in the back will make it jump to the y location of its room, which is typically below most floors + + + + Normal Deku Baba + Straight Deku Baba + + + + + Giant Octo's Platform + Elevator Platform + Water Square //Rises when Switch Flag is set + Lowering Platform //Lowers into place when stepped on, sets Switch Flag + + + +0xFF00 = Nullable Switch Flag + + + + Chamber of Sages, gives Forest Medallion + Chamber After Ganon/Ganon's Castle //Use with actor 01A7 + Credits, Death Mountain Trail + Fairy Ocarina Cutscene + + + + + Unknown + Unknown + Unknown + + + + + Unknown + Unknown + Unknown + Default + + + + + Koume + Kotake + + + + + Default + Debris + Debris + Debris + Debris + Debris + + + + + + Cracked stone floor + Bombable stone wall + Large bombable stone wall + + + +0x3F00 = Switch Flag + + + + + + + + Iceberg + Ice Ramp + + + + + + + + + + + + + + + + + Water Medallion + Chamber After Ganon/Ganon's Castle + Credits + Water Temple Meeting + + + + + + + + + + Temple Gate + Gate lock + Water plane + Ice Block blocking Zora's Domain Entrance (Adult only) + + + +0xFF = Nullable Switch Flag + + + + + + +0x3F = Switch Flag //If set, water level is lowered + + + + + + + + Ingo Race + Gerudo Archery + Unused? + Malon Race + + + + + + + + + Reddish brown + Green + Grayish blue with some red + Already dead + + + + + Reddish brown + Green + Grayish blue with some red + Corrupt textures, still visible and works + Dark brownish + Blackish gray + + + + + + + + + Default + + + + + Rotating platforms + Metal Gate + + + + + + + + + Gray + Expanding, gray //Unused? + Expanding, gray //Unused? + Default + + + + + Floor Blue Switch, release when not stood on + Floor Heavy Switch (Need Ruto to press it) + Standard Floor Yellow Switch + Standard Tall Yellow Switch + On/Off Toggle Tall Yellow Switch + + + +0x3F00 = Switch Flag + + + + + + Default + Begins battle + Ganondorf death sequence + + + + + Default + + + + + Normal + Does not open //possibly waiting for some trap to spring? + + + + + Frog Game Ocarina Spot + Yellow Frog + Blue Frog + Red Frog + Purple Frog + White Frog + + + + + Collectible Deku Shield + Burning Deku shield + + + + + Large crystal + Smaller crystal + Crystal platform + Meltable ice sheet + Giant crystal + + + 0xFF = Nullable Switch Flag + + + + Group of small blue flames, disappear + Blue flame, disappears + Blue flame, targetable + + + + + Ocarina of Time being tossed higher in air + Ocarina of Time being tossed in air + Ocarina of Time + Collectible Ocarina of Time + + + + + Normal + No bright sphere, first one dies off quickly + + + + + Rain of multi-colored light balls, used in Rainbow Bridge CS + Lots of small particles, used with the White 'Black Hole' + White 'Black Hole' Effect, used in the Ganondorf's Sealing CS + Red Light Ball, used in Ganon's Castle + Green Light Ball, used in Ganon's Castle + Yellow Light Ball, used in Ganon's Castle + Purple Light Ball, used in Ganon's Castle + Orange Light Ball, used in Ganon's Castle + Blue Light Ball, used in Ganon's Castle + Koume/Kotake Red Light Ball Attack + Koume/Kotake Blue Light Ball Attack + 'Nabooru Disappearing' Orange Particles + Ganondorf's Light Ball Attack Purple Loading Effect + Ganondorf's Light Ball Attack, used in Zelda Fleeing CS + Red Light Ball with particles, used in the LLR/DMT part of the credits + Green Light Ball with particles, used in the LLR/DMT part of the credits + Yellow Light Ball with particles, used in ToT Cutscenes + Purple Light Ball with particles, used in the LLR/DMT part of the credits + Orange Light Ball with particles, used in the LLR/DMT part of the credits + Blue Light Ball with particles, used in the LLR/DMT part of the credits + + + + + + + + Rotatable Bird Statue + Circular Trap Door Platform //Opens when wrong skull is chosen + Gate //Only blocks one-way + Skull Top + Glitchy graphics, can't see object, behaves like the gate + + + +0x3F00 = Switch Flag + + + + Default + + Not market town gate + + + + Normal + Follow patch faster and repeat it + + + + + + + Large shadow //looks like it's reproduced, well-done though + Small Shadow //CRASH? + No shadow //CRASH? + + + +The sun switch has to be between 252 and 308 units from the cobra mirror to be activated ++0x3F = Switch Flag + + + + + + + + Wearing red vest over blue shirt, no hat + Normal fish + Hylian Loach + Huge Hylian Loach + Pond stuff, still no hat + + + + + Small Push Block + Medium Push Block + Large Push Block + Huge Push Block + + + + + + + + + + + + + + + + + + Default + + + + + Rushing white particles //Jabu-Jabu, when he opens his mouth + Rushing white particles to one point (???) + + + + + + + + + Default + + + + + Purple (Meg) + Red (Joelle) + Blue (Beth) + Green (Amy) + + + +0x3F = Switch Flag + + + + + + + + + Fence + Nothing //Possibly waypoint for the Ingo Race? + Fence + + + + + + + + + + + Bottle //Use group 00C6 + Bottle with Ruto's Letter //Use group 010B + Hylian shield //Use group 00DC + Quiver //Use group 00BE + Silver Scale //Use group 00DB + Golden Scale //Use group 00DB + Small Key //Use group 00AA + Fire Arrow //Use group 0158 + + + + + + Set to 0xFFFF to spawn nothing + + + + + + + + + Collectible gave if each tag points are reached (no order) + Tag Point (no order) + Gives collectible if in range + Invisible Collectible + Collectible gave if each tag points are reached in order + Tag Point (sets order) + Sets Switch Flag if in range (no collectible) + Bomberman Soldier + Collectible gave if player rolls + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nabooru Knuckle //May Crash + White, sitting //Stone Chair + Black, standing + White, standing + White, no armor falls off when at low health + + + +0xFF00 = Nullable Switch Flag + + + + Unknown + Unknown + Unknown + Unknown + Unknown + Unknown + + + + + Saria's Song HP Skull Kid + Ocarina Game Left Skull Kid + Ocarina Game Right Skull Kid + Saria's Song HP Ocarina Spot + Memory Game Ocarina Spot + Enemy Skull Kid + + + + + + + Silver Rupee Tracker (handles puzzle resolution) + Silver Rupee (the puzzle itself) + Horseback Archery Pot + + + + You need to use one tracker if using silver rupees + + + Used when Koume and Kotake kidnap Nabooru + + + + + + Deku Nuts + Deku Sticks + Piece of Heart (10 rupees) + Deku Seeds + Deku Shield + Bombs + Deku Seeds + Red Potion + Green Potion + Deku Stick Upgrade + Deku Nut Upgrade + Never speaks, and Link is sadly very patient... + Pocket Egg? + + + + + Talk when in range + C-Up Prompt + + + + + + + Stone Eye + Heat-Seeking flame + Immobile flame, dies + Flame sound effect + + + + + Heart or Green Rupee + Bombs + Deku Seeds + Deku Nuts + Deku Seeds + Giant Purple Rupee + Goron Tunic + Nothing + + + +0x3F = Collectible Flag + + + + + + + + + + Waterfall and Pool //Room 1 + King's Chamber Water //Room 0 + + + + + Immobile + Mobile //Hidden When Spawned + + + + + + + + Rotating platform + Dampé Race Stone Door + + + +0xFF = Nullable Switch Flag + + + Hardcoded cutscene camera: -149, 943, -1020 + + + + Normal shrub. Random drops. //Use object 0002 + Cut-able, regenerating grass //Use object 012B, Drops: Heart, Arrows or Deku Seeds + Cut-able grass //Use object 012B, Set drop table via Random Drop Table param + + + + +0x0010 = Spawns set of 3 bugs ++0xFF00 = Random Drop Table +-FF00 No Table + + + + + + ++0x1F00 = Path Id //1F00 = null ++0x003F = Switch Flag +ZROT +0x0003 = Speed, Acceleration +-0000 3.0, 0.3 +-0001 10.0, 0.5 +-0002 30.0, 0.5 +-0003 3.0, 0.3 + + + + + + +0x8000 = Play Puzzle Solved When Destroyed ++0x3F = Switch Flag + + + + Floor + Rusted Floor + Eye + Crystal + Targetable Crystal + + + + + + + + + + + Large + Small + + + + 0xF000 = Rise Height //80 unit increments +0x0F00 = Platform Travel Speed + + + + + + + + + Hookshot Target Tower + Hookshot Target Tower, lifts up on Switch Flag + Square Hookshot Target + + + + + + + Zora River, Zelda's Lullaby Spot (no cutscene) + Windmill, Song of Storms spot (cutscene) + Temple of Time, Song of Time spot (cutscene) + Learn Sun's Song spot + Royal Family Tomb, Zelda's Lullaby spot + Puzzle Spot + + + + + + + + + + + + + + + End Targets + Mounted Target (Small) + Mounted Target (Big) //Center one + + + + + Follows path, disappears, reappears at first waypoint //simulates falling into a hole + Follows path, breaks into pieces, reappears at first waypoint //As in adult Death Mountain Trail + Follows path, treating it as a closed loop + Follows path, halts, reverses, repeat //As in Fire Temple boulder maze + + + + + +0xFF = Path Id +ROTZ 0x0001 = Behavior after colliding with Link +-0000 Reverse path +-0001 Follow path + + + + + Sparkling blue rupee + Huge Magenta Rupee, explodes when touched //Unused + Blue, red, and orange rupees, explode when touched //Unused + Random-colored rupees, collectible + Green rupees underground, not collectible //Unused + + + + + + + Ichiro //Red/Purple Pants, "normal" hair + Sabooro //Light-Blue Pants + Jiro //Green Pants + Shiro //Pink/Purple Pants, two-spiked hair + + + + + Talking softlocks if outside of intended scene numbers + + + + + + + + + + + + Shoos you away //Calls you a kid regardless of your actual age + Gate Manager (Gerudo Fortress) + Generic Guard (Gerudo Fortress) + Stands By Cow (Gerudo Valley) + Horseback Archery + Gerudo Training Grounds Guard + + + +0x3F00 = Switch Flag + + + + +0x3F = Switch Flag //Sets flag when block is placed on top of actor + + + Unused. Works on Link and Signs. Check in Spirit Temple under light, works for all values except 1 + + + + Cutscene start + No cutscene //required if you spawn more than four or five of these + + + + Text ID 503E as adult, gives you an egg + + + + +0x3F = Switch Flag //Won't say his normal dialog unless the flag Medigoron is bound to is set + + + + Default + + + + + Default + + Text ID 10B1 when sleeping + + + + Standard + Cutscene Gate, Left Part + Cutscene Gate, Right Part + + + + + X + Hyrule Field + Hyrule Castle Town + The Temple of Time + Dead End + Kakariko Village / Death Mountain Trail / Starting Point + Kakariko Village Graveyard + Dark! Narrow! Scary! / Well of Three Features + Death Mountain / No passage without a / Royal Decree! + Death Mountain Trail + Dodongo's Cavern / Don't enter without permission! + Land of the Gorons / Goron City + Zora's River / Watch out for swift current / and strong undertow. + The Shadow will yield only to one / with the eye of truth, handed / down in Kakariko Village. + Zora's Domain + Zora's Fountain / Don't disturb Lord Jabu-Jabu! / –King Zora XVI + Forest Training Center / Don't recklessly cut signs– / read them carefully! + All those reckless enough to / venture into the desert–please drop by our shop. / Carpet Merchant + Just ahead: / Great Deku Tree's Meadow + Forest Temple + The Lost Woods + Talon and Malon's / Lon Lon Ranch + The Great Ingo's / Ingo Ranch + Lake Hylia + Lakeside Laboratory / Daily trying to get to the bottom / of the mysteries of Lake Hylia! / –Lake Scientist + Gerudo Valley + Horseback Archery Range / Skilled players are welcome! / Current record: # Points + Gerudo Training Ground / Only registered members are / allowed! + Haunted Wasteland / If you chase a mirage, the / desert will swallow you. / Only one path is true! + Spirit Temple + Kokiri Shop / We have original forest goods! + LINK's House + Forest folk shall not leave these woods. + Follow the trail along the edge of / the cliff and you will reach / Goron City, home of the Gorons. + Natural Wonder / Bomb Flower / Danger! Do not uproot! + Death Mountain Summit / Entrance to the crater ahead / Beware of intense heat! + King Zora's Throne Room / To hear the King's royal / proclamations, stand on the / platform and speak to him. + If you can stop my wild rolling, you might get something great. / –Hot Rodder Goron + Only one with the eye of truth / will find the stone umbrella / that protects against the / rain of blades. + Only one who has sacred feet / can cross the valley of the dead. + The record time of those / who raced against me was: / ##"##" / –Dampé the Gravekeeper + Shooting Gallery / etc. + Treasure Chest Shop / We don't necessarily sell them... + High Dive Practice Spot / Are you confident / in your diving skill? + 032c + Mountain Summit / Danger Ahead - Keep Out + Happy Mask Shop! / Now hiring happiness / delivery men! + Bombchu Bowling Alley / You can experience the / latest in Bomb technology! + Bazaar / We have a little bit of everything! + Potion Shop / We have the best quality / potions! + Goron Shop / Mountaineering supplies! + Zora Shop / We have fresh fish! + Heart-Pounding Gravedigging Tour! / From 18:00 to 21:00 Hyrule Time / –Dampé the Gravekeeper + Heart-Pounding Gravedigging Tour! / Tours are cancelled until a new / gravekeeper is found. We / apologize for any inconvenience. + Thrust Attack Signs! / To thrust with your sword, press / CS toward your target while / Z Targeting, then press B. + Hole of “Z” / Let's go through this small / hole! / Stand in front of the hole and / push CS towards it. When the / Action Icon shows “Enter,” press / A to crawl into the hole. / Pay attention to what the Action / Icon says! + Cut Grass With Your Sword / If you just swing with B, you'll / cut horizontally. If you hold Z as / you swing, you'll cut vertically. + Hyrule Castle / Lon Lon Ranch + You are here: Hyrule Castle / This way to Lon Lon Ranch + Just Ahead / King Zora's Chamber / Show the proper respect! + House of the Great Mido / Boss of the Kokiri + House of the Know-It-All Brothers + House of Twins + Saria's House + View Point with Z Targeting / When you have no object to look / at, you can just look forward / with Z. / Stop moving and then change the / direction you are facing, or hold / down Z for a little while. / This can help you get oriented in / the direction you want to face. / It's quite convenient! / If you hold down Z, you can / walk sideways while facing / straight ahead. / Walking sideways can be a very / important technique in dungeon / corridors. Turn around and try doing this right now. + Stepping Stones in the Pond / If you boldly go in the direction / you want to jump, you will leap / automatically. / If you hop around on the stones, / you'll become happier! + No Diving Allowed / –It won't do you any good! + Switch Targeting / If you see a \/ icon above an / object, you can target it with Z. / ... / You can target the stones next to this sign for practice! + Forest Stage / We are waiting to see your / beautiful face! / Win fabulous prizes! + Visit the / House of the Know-It-All Brothers / to get answers to all your / item-related questions! + Pocket Egg + + Message ID //Value + 0x0300 + + + + Whistleblower + Stands there, does nothing + + + + + Non-solid cucco, hops oddly every once in awhile and only goes in one direction + Invisible, solid cucco, doesn't move, can be attacked but will only smoke and molt + Invisible cucco, cannot be attacked it seems, no idea what it does, but you can hear it + + + + + + + Default + + + + + Default + + + + + Temple of Time stone altar dialog + Gravekeeper's diary dialog //Navi hovers higher than normal + Royal Composer Sharp's grave dialog //Use Object 006E, Sets Temporary Switch Flag 09, spawns Sharp + "Royal Family Tomb" dialog + Royal Composer Flat's grave dialog //Use Object 006E, Sets Temporary Switch Flag 08, spawns Flat + + + +0x3F = Switch Flag //Spot deactivates when flag is set + + + + + + + + + + + + + + Does nothing + Outside of Kokiri Forest exit, auto talks + Near Hyrule Castle, auto talks + In front of Kakariko Village, auto talks + Between Lake Hylia and Gerudo Valley, auto talks + In front of Lake Hylia, auto talks + Nothing + Lake Hylia, manual talk, talon grab shortcut + Death Mountain summit, manual talk, talon grab shortcut + Death Mountain summit, manual talk, talon grab shortcut + Desert Colossus, auto talks + Lost Woods, before meeting Saria, auto talks + Lost Woods, after meeting Saria, auto talks + Outside of Kokiri Forest exit, auto talks, Head position alternates? + + + +0x3F = Switch Flag + + + + Small rock, random drops + Large light-gray rock, can't pick up as Young Link, no drop + + + + + + +0x10 = Spawns Bugs +-0000 No +-0010 Yes ++0x0F00 = Drop Table //0-12, anything higher becomes drop table 0 ++0xF000 = Switch Flag (High Bits) ++0xC0 = Switch Flag (Low Bits) + + + + Flower for grave + Non-liftable small rock + Uncuttable small shrub + Erratic collision data + + + + + Stays On + On/Off Toggle + Activated while enlightened + Burns + + + + +0x3F00 switch flag + + + + Circle of shrubs with one in the middle + Scattered shrubs + Circle of rocks + + + +0xFF00 = Random Drop Table + + + + Link the Goron + Fire Temple Generic + DMT DC Entrance + DMT Rolling + DMT Near Bomb Flower + Goron City Entrance + Goron City Island + Goron City Lost Woods + Unused + Biggoron + + + + + + + 5034 as adult, 5035 when playing ocarina in front of him as adult, crash if no cutscene ? + + + + + + + + + + + + + + + + Bombable, targetable + +0x3F00 = Switch Flag + hardcoded cutscene position at -1160, 686, -880 + spawn light at -946, 477, -894 + + + + Hookable, automatically rises as you approach it + + + + + + + + +0x3F00 = Switch Flag //Lid disappears, starts spinning on floor ++0x003F = Collectible Flag //Heart Piece + + + + + + Rising + Lowering + + + + + + + + + + Tall and narrow + Short and wide + + + + + + + + Standing boy lifting a rock + Standing girl near Fado + Boxing boy + Blocking boy + Backflipping boy + Sitting girl on Shop + Standing girl near Mido's House + Know-It-All Bro teaching about HUD icons + Know-It-All Bro teaching about map and items + Sitting girl in house + Standing girl in Shop + Know-It-All Bro teaching about C-Up + Fado + + + + + + + + + Cloudy Market + Cloudy Ranch + Snowy Zora's Domain + Rainy Lake Hylia + Cloudy Death Mountain + Thunderstrorm Kakariko + Sandstorm Intensity + Thunderstrorm Graveyard + + + + + + + Text ID 5052 as adult + + + + Bomb Bag (Bombchu Bowling given prize) + Heart Piece (Bombchu Bowling given prize) + Bombchus (Bombchu Bowling given prize) + Bombs (Bombchu Bowling given prize) + Purple Rupee (Bombchu Bowling given prize) + Bomb Bag (Bombchu Bowing prize preview) + Heart Piece (Bombchu Bowing prize preview) + Bombchus (Bombchu Bowing prize preview) + Bombs (Bombchu Bowing prize preview) + Purple Rupee (Bombchu Bowing prize preview) + Green Rupee (Chest Game) + Blue Rupee (Chest Game) + Red Rupee (Chest Game) + Purple Rupee (Unused Chest Game Rupee) + Small Key (Chest Game) + Din's Fire + Farore's Wind + Nayru's Love + Bullet Bag + + Each type needs its own object to load + + + + Brick pillar + Brick throne + + + + + + + + + +0xFF = Path Id + + + + Blocking Deku Tree + + + + + Richard's Owner // Use object 0105, text ID 079D + Woman in white, blues and yellow near Apothicary // Use object 018C, text ID 7016 first, then 7017 + Bearded man in white and green near Bazaar // Use object 0107, text ID 701A + Sakon (Jogging Man) // Use object 0111, needs pathway, text ID 7002 + Staunch man in black and green // Use object 0107, text ID 7023 first, then 7024 + Begging man // Use object 0111 // Use object 0111, buy things in bottles, text ID 70ED and followings + Old woman in white // Use object 010D, text ID 7021 first, then 7022 + Old man in blue near Bombchu Bowling // Use object 010C, text ID 7027 first, then 7028 + Woman in lilac near Bombchu Bowling // Use object 0108, text ID 701D first, then 701E + Laughing man in red and white // Use object 0111, text ID 701F first, then 7020 + Explaining man in blue and white // Use object 0111, text ID 7018 first, then 7019 + 'Dancing' woman in blue and yellow near Archery Game // Use object 0108, text ID 7014 + Watchtower man in crimson // Use object 0111, text ID 7015 + Red haired man in green and lilac // Use object 0107, text ID 7055 + Bearded, red haired man in green and white // Use object 0111, text ID 7089 + Old bald man in brown // Use object 010C, text ID 708A + Man in white // Use object 0111, text ID 700E + Man from Impa's House // Use object 0107, text ID 505B first, then 505C + Old bald man in purple // Use object 010C + Man in two shades of green // Use object 0107 + + + +0x780 = Path Id //NPCs 03 and 07 only + + + + + + + + + + + + + + + + + + See actor 11B for variables + + + + Unknown + Unknown + Unknown + Unknown + Unknown + Unknown + Unknown + Unknown + Unknown + Unknown + + + + + + + + + + +0x3F00 = Switch Flag + + + + Time teller + Stands by Impa's House, tells time + Dying guard in Market Town + Stands in Market Town at night + + Text ID 5063, then 5064 + + + + Zelda in Ganondorf Fight (used by game engine) + Zelda in Ganon Fight (used by game engine) + Zelda in Castle Collapse + + + + + + + + + + + + + + + + + Requires Goron Bracelet or better to move as child or adult + + + + + + + + Contents determined by the grotto (actor 009B) variable + + + + Drunken Ingo // Use Object 00C0 + Drunken Talon // Use Object 0088 + Windmill man breakdancing // Use Object 0133 + Encouraging Kokiri Boy // Use Object 00FC + Encouraging Kokiri Girl // Use Object 00FD + White-haired man in blue // Use Object 010C + Black-bearded man in white and green // Use Object 0107 + Bushy-haired woman in red and black // Use Object 0115 + Little old lady // Use Object 010D + Carpenter Boss, Singing // Use Object 0121 + Carpenter, Singing // Use Object 0122 + Carpenter, Singing // Use Object 0122 + Carpenter, Singing // Use Object 0122 + Carpenter, Singing // Use Object 0122 + Kokiri Boy, Dancing // Use Object 00FC + Kokiri Girl, Dancing // Use Object 00FD + Gerudo, Line-dancing 1 // Use Object 0116 + Gerudo, Line-dancing 2 // Use Object 0116 + Gerudo, spikey-haired, Line-dancing // Use Object 0116 + Dancing Zora // Use Object 00FE + King Zora // Use Object 00FF + Mido, sitting // Use Object 00FB + Floating cucco // Use Object 0013 + Floating cucco 2 // Use Object 0013 + Walking cucco // Use Object 0013 + Cucco Lady // Use Object 0110 + Potion Shopkeeper // Use Object 0159 + Happy Mask Salesman // Use Object 013E + Fisherman // Use Object 015B + Bombchu Shopkeeper // Use Object 0165 + Dancing Goron // Use Object 00C9 + Belly slapping Goron // Use Object 00C9 + Biggoron, dancing // Use Object 00C9 + Medigoron, lying down // Use Object 00C9 + Singing Malon // Use Object 00D0 + + Each variable requires it's own object + + + + Lake Hylia's Sun Hitbox + Big Fairy, spawns with Sun's Song + Big Fairy, spawns with Song of Storms + + + + + Pink spiral beam + Green spiral beam + Purple spiral beam + Blue spiral beam + + Black spiral beam + Black and green spiral beam + Gray and green spiral beam + Light blue spiral beam + Light purple spiral beam + + + + + Checkable, Sets Switch + Instant Text + Checkable, Disappears on Switch + Z-Target, No Text + + + + +0x3FC0 = Message ID //0x0200 + Value +-0000 Hi! I'm a talking door! //Unused +-0040 Strange... this door doesn't open... +-0080 Strong iron bars are blocking the door. You can't open them with your hands! +-00C0 You need a Key to open a door that is locked or chained. +-0100 You need a special key to open this door. +-0140 Be quiet! It's only time! I, Dampé the Gravekeeper, am in bed now! Go away and play! Maybe you can find a ghost in the daytime? +-0180 It's time now. The Gravedigging Tour is over now! I, Dampé the gravekeeper, am in bed! Go away and play! Maybe you'll find a ghost! +-01C0 Happy Mask Shop / Please read this sign before you use this shop... +-0200 Shadow Temple... here is gathered Hyrule's bloody history of greed and hatred... +-0240 What is hidden in the darkness... Tricks full of ill will... You can't see the way forward... +-0280 One who gains the eye of truth will be able to see what is hidden in the darkness. +-02C0 Something strange is covering the entrance. You must solve the puzzle in this room to make the entrance open. +-0300 Giant dead Dodongo... when it sees red, a new way to go will be open. +-0340 Treasure Chest Contest / Temporarily Closed / Open Tonight! +-0380 Medicine Shop / Closed until morning... +-03C0 Shooting Gallery / Open only during the day +-0400 Happy Mask Shop / Now hiring part-time / Apply during the day +-0440 Bazaar / Open only during the day +-0480 Show me the light! +-04C0 One with the eye of truth shall be guided to the Spirit Temple by an inviting ghost. +-0500 Those who wish to open the path sleeping at the bottom of the lake must play the song passed down by the Royal Family. +-0540 Those who wish to open the gate on the far heights, play the song passed down by the Royal Family. +-0580 Those who find a Small Key can advance to the next room. Those who don't can go home! //Unused +-05C0 If you wish to speak to me, do so from the platform. +-0600 Hi, LINK! Look this way! Look over here with Z, and talk to me with A. +-0640 The current time is: time. +-0680 Shine light on the living dead... +-06C0 Those who break into the Royal Tomb will be obstructed by the lurkers in the dark. +-0700 Hey, you! Young man, over there! Look over here, inside the cell! +-0740 My little boy isn't here right now... I think he went to play in the graveyard... +-0780 Oh, my boy is asleep right now. Please come back some other time to play with him! +-07C0 When water fills the lake, shoot for the morning light. +-0800 If you want to travel to the future, you should return here with the power of silver from the past. +-0840 If you want to proceed to the past, you should return here with the pure heart of a child. +-0880 This door is currently being refurbished. //Unused +-08C0 It looks like something used to be set in this stand... +-0900 Make my beak face the skull of truth. The alternative is descent into the deep darkness. +-0940 This is not the correct key... the door won't open! +-0980 Granny's Potion Shop / Closed / Gone for Field Study / Please come again! –Granny +-09C0 Who's there? What a bad kid, trying to enter from the rear door! Such a bad kid... I have to tell you some juicy gossip! The boss carpenter has a son... He's the guy who sits under the tree every night... Don't tell the boss I told you that! +-0A00 Look at this! +-0A40 Malon's gone to sleep! I'm goin' to sleep now, too. Come back again when it's light out! +-0A80 LINK's Records! / Spiders squished: 0 / Largest fish caught: 0 pounds / Marathon time: 00"00" / Horse race time: 00"00" / Horseback archery: 0 points +-0AC0 The crest of the Royal Family is inscribed here. +-0B00 R.I.P. / Here lie the souls of those who swore fealty to the Royal Family of Hyrule / The Sheikah, guardians of the Royal Family and founders of Kakariko, watch over these spirits in their eternal slumber. +-0B40 Sleepless Waterfall / The flow of this waterfall serves the King of Hyrule. When the king slumbers, so too do these falls. +-0B80 Some frogs are looking at you from underwater... +-0BC0 You're standing on a soft carpet for guests... it feels so plush under your feet! +-0C00 If you can overcome the trials in the chambers ahead, then and only then will you be qualified to hold our secret treasure! +-0C40 If you desire to acquire our hidden treasure, you must strive to obtain the keys hidden in each chamber! +-0C80 Defeat all the enemies in a limited time! +-0CC0 Collect the underwater gems! +-0D00 Cross the sea of fire! +-0D40 Find a secret passage in this room! +-0D80 Blind the eyes of the statue! +-0DC0 One with silver hands shall move a giant block! +-0E00 Without the necessary items, one will be confounded by impossible mysteries. +-0E40 Gather the jewels of white, while avoiding traps and danger! +-0E80 Fishing Pond / The fish are really biting today! +-0EC0 ...??? +-0F00 The Shadow will yield only to one with the eye of truth, handed down in Kakariko Village. +-0F40 You borrowed a Pocket Egg! ... ++0x3F = Switch Flag + + + + Turns around, can't move, whistle-blower + Won't turn around, can't move, whistle-blower + Purple Gerudo, acts like the one that gives you the membership card + + + + + + + +0xFC00 = Switch Flag //Set on room clear ++ 0x3FF = Timer in seconds (capped to 10 minutes) +-03FF No Timer + + + + Main Hyliantula //(gold skulltulas lower than 100) + Hyliantula without an arm //(gold skulltulas lower than 10) + Hyliantula without an arm //(gold skulltulas lower than 20) + Hyliantula without an arm //(gold skulltulas lower than 30) + Hyliantula without an arm //(gold skulltulas lower than 40) + Hyliantula without an arm //(gold skulltulas lower than 50) + Hyliantula without an arm //(gold skulltulas lower than 60) + Hyliantula without an arm //(gold skulltulas lower than 70) + Hyliantula without an arm //(gold skulltulas lower than 80) + Hyliantula without an arm //(gold skulltulas lower than 90) + Hyliantula without an arm //(gold skulltulas lower than 100) + Hyliantula without an arm //(gold skulltulas lower than 110) + + + + + Main Hyliantula //(gold skulltulas lower than 100) + Hyliantula without an arm //(gold skulltulas lower than 10) + Hyliantula without an arm //(gold skulltulas lower than 20) + Hyliantula without an arm //(gold skulltulas lower than 30) + Hyliantula without an arm //(gold skulltulas lower than 40) + Hyliantula without an arm //(gold skulltulas lower than 50) + Hyliantula without an arm //(gold skulltulas lower than 60) + Hyliantula without an arm //(gold skulltulas lower than 70) + Hyliantula without an arm //(gold skulltulas lower than 80) + Hyliantula without an arm //(gold skulltulas lower than 90) + Hyliantula without an arm //(gold skulltulas lower than 100) + Hyliantula without an arm //(gold skulltulas lower than 110) + + + + + Purple wormhole + Blue wormhole + + + + + Regular effects, storm begins + Texture-spanning effect only, no storm, music isn't affected, effect does not dissipate + + + + + Default + + + + + Large flat square floor tile, makes water noises when walking on it + Large vertical gate + + + +0x3F00 = Switch Flag //Type 01 only + + + + +0x3F = Switch Flag + + + + Chair Crumble + Pillar Crumble + Round stone thing, explodes as soon as area loads + + + + + +0xFF = Nullable Switch Flag, has cutscene with absolute position + Hardcoded cutscene camera: -1134, 112, -3075 + + + + +0xFF = Nullable Switch Flag + Camera cutscene points to X 38 Y 333 Z -1097 + + + + (Invalid) + Scrub on path to Deku Slingshot + 231/312 Hint scrub + Final Deku Scrub + + + ++0xFF = used to set up 231/312 puzzle +-00 Normal, talks when caught +-01 First scrub to hit //0001 for no dialog? +-02 Second scrub to hit //0002 for no dialog? +-03 Third scrub to hit, talks when caught + + + + Mad Scrubs + Hint Scrubs + Business Scrubs + Forest Stage Judge + Forest Stage Patron + + + + + Broken Drawbridge + Fences (Hyrule Field) + + + + + Deku Nuts + Deku Sticks + Piece of Heart + Deku Seeds + Deku Shield + Bombs + Deku Seeds + Red Potion + Green Potion + Deku Stick Upgrade + Deku Nut Upgrade + + + + + + + + + +0x3F00 = switch flag when you defeat her AND collectible flag for her key + (if the collectible flag XX is already set she will not give you a key) + ZRot = switch to make her spawn + + + + + + + + + + + + Dirty blond dog + Chocolate brown dog + Red dog + Multicolored, flashing dog + Red dog + Multicolored, flashing dog + Dark dog (black fur) + Green dog + Red dog + Purple dog + Red dog + Green dog + Green dog + Black dog + Black dog + Purple dog + + + + ++0x0FF0 = Direction it runs //Orientation relative to the object. Also, if you befriend a dog and return to the place with the dog and change this value, another dog will spawn +-0000 SEE +-0010 NNW +-0020 N +-0030 First NNW, then SE +-0040 First NNW, then SE +-0050 First NNW, then SE +-0060 N +-0070 First NNW, then S +-0080 First NNW, then SE +-0090 N +-00A0 First NNW, then SE +-00B0 NW +-00C0 NW +-00D0 NW +-00E0 NW +-00F0+ First NNW, then SEE +-0F00+ No dog + + + + + + + + Potion Shop Poster + Shooting Gallery Poster + Bazaar Poster + Shooting Gallery (Partially Complete) //Spawns Carpenter Sabooro (Kakariko) during the day + Shooting Gallery (Complete) + + + + + + + graphics very glitchy in certain areas + + + + + + + + + 0xFFFF = Spawned Skulltula Variable (see actor 0095) +-FFFF No Skulltula +X ROTATION +0xFF = Collectible Item Dropped (see actor 0015) +Z ROTATION +0x3F = Collectible Flag + + + + Default + + + + Spawned by Deku Panel + + + + Default + + Yields deku seed upgrade + + + may cause crashes in some areas + + + + + + + + Magic Barrier + Blue Magic Core //Use with actor 00D2 (Adult Ruto), var 0002 + Yellow Magic Core //Use with actor 00A6 (Rauru), var 0002 + Red Magic Core //Use with actor 00A8 (Cutscene Darunia), var 0002 + Purple Magic Core //Use with actor 00A9 (Impa), var 0002 + Orange Magic Core //Use with actor 00C3 (Nabooru), var 0002 + Green Magic Core //Use with actor 00C9 (Cutscene Saria), var 0002 + + + + + Graphics may glitch when it's destroyed, but will fix after it disappears ++0x3F = Switch Flag + + + + Graphics may glitch when it's destroyed, but will fix after it disappears + + + + Five Blue Rupees stacked vertically + Five Green Rupees in a row + Six Green Rupees in a circle with a Red Rupee in the center + + + + + Text ID 7025, then 7026 then 7025…. + + + + Blue/green textures + Green/brown textures + Green/red textures + Purple/red textures + Orange/red textures + Purple/black textures + Flashing purple/blue textures + Flashing purple/cyan/green textures, depends on movement of camera + Purple/red textures + + + + + Big Rollin' Goron + Link the Goron + Biggoron + Generic Fire Temple Goron + Goron from DMT near a bomb flower + Rolling Goron from DMT + Goron near Dodongo's Cavern Entrance + Goron at the entrance of Goron City + Goron on the island from Goron City + Goron near Darunia's room + Goron in the stairwell in Goron City + Goron near Lost Woods + Goron talking about the Great Fairy in DMT + Goron in Market's Bazaar + + + + + + + + Normal + White Wolfos, mini-boss music starts + + + +0xFF00 = Nullable Switch Flag + + + + //0000 to 1098 controls the size, where 0000 is normal size and 1098 is as large as is possible for the machine to handle (may vary depending on the level). +//From F02F to FFFF, the Stalchild will appear but will somehow invert everything. In other words, it walks upside-down underneath the ground. +//Really weird. FFFF is smallest, F02F is supposedly largest (I haven't been able to see it, though). + + + + Around Arena, indestructible rubble + Rubble Pile 1 (where Ganondorf rises) + Rubble Pile 2 (where Ganondorf rises) + Rubble Pile 3 (where Ganondorf rises) + Rubble Pile 4 (where Ganondorf rises) + Rubble Pile 5 (where Ganondorf rises) + Rubble Pile 6 (where Ganondorf rises) + Rubble Pile 7 (where Ganondorf rises) + 'Sun' destructible rubble, drops collectible (draw depends on Ganon) + 'Wall' destructible rubble, drops collectible (draw depends on Ganon) + Tall destructible rubble, drops collectible (draw depends on Ganon) + + + + + + + Large chunk + Medium chunk + Small chunk + Large chunk + Medium chunk + Small chunk + Large chunk + Medium chunk + Small chunk + Small chunk + + non-solid, possibly Ganon's Tower rubble + + + Narrow, maze-like platform (sinks) + + + + Invisible Path + Glass Block, appears on Switch Flag + Invisible Timer + + + +0xFF00 = Nullable Switch Flag //If null, Enabled and ignoring switch flag input +//The timer works as such: +//The clear block's invisible timer actor manipulates the value of three switch flags: +//The Switch Flag (FlagA), Flag + 1 (FlagB), Flag + 2 (FlagC) +//FlagA is set to 0 if FlagB and FlagC are 0 +//FlagA is set to 1 and timer started if either FlagB or FlagC are 1 +//Before timer ends, FlagA is set to 0 +//Aprox. 1 second later, FlagB and FlagC are zeroed +//Clear Block actors disappear ~2 seconds after the Switch Flag is zeroed to account for +//FlagA being zeroed before the timer runs out + + + + Ceiling Web + Light Source (draws when web burned) + Light Floor (draws when web burned) + + + + + + Square Stone + Stone Brick + Similar to 1, but looks like a different texture + + Graphics glitchy + + + + + //Actor 00D6 is used in Ice Cavern + + + + + + This is a Gossip Stone! + They say you can swim faster by continuously pressing B. + They say there is a secret near the lone tree which is not far from the river in the northwest part of Hyrule Field. + They say that there is a secret on the road that leads to Lake Hylia. + They say that Biggoron's Sword is super sharp and will never break. + They say that Medigoron didn't really think about his own size, so his store is really cramped. + They say that Malon set the original record in the obstacle course of Lon Lon Ranch. + They say that Malon of Lon Lon Ranch hopes a knight in shining armor will come and sweep her off her feet someday. + They say that Ruto, the Zora princess who is known for her selfish nature, likes a certain boy... + They say that players who select the “HOLD” option for “Z TARGETING” are the real “Zelda players!” + They say that there is a secret near a tree in Kakariko Village. + They say that, contrary to her elegant image, Princess Zelda of Hyrule Castle is, in fact, a tomboy! + They say that Princess Zelda's nanny is actually one of the Sheikah, who many thought had died out. + They say there is a man who can always be found running around in Hyrule Field. + They say that it is against the rules to use glasses at the Treasure Chest Shop in Hyrule Castle Town Market. + They say that the chicken lady goes to the Lakeside Laboratory to study how to breed pocket-sized Cuccos. + They say that Gerudos sometimes come to Hyrule Castle Town to look for boyfriends. + They say that the thief named Nabooru, who haunts this area, is a Gerudo. + They say that if you get close to a butterfly while holding a Deku Stick in your hands, something good will happen. + They say that you may find something new in dungeons that you have already finished. + They say that Gerudos worship Ganondorf almost like a god. + They say that there is a secret around the entrance to Gerudo Valley. + They say that the owl named Kaepora Gaebora is the reincarnation of an ancient Sage. + They say that strange owl, Kaepora Gaebora, may look big and heavy, but its character is rather lighthearted. + They say that the horse Ganondorf rides is a solid black Gerudo stallion. + They say that Ganondorf is not satisfied with ruling only the Gerudo and aims to conquer all of Hyrule! + They say that the treasure you can earn in the Gerudo's Training Ground is not as great as you would expect, given its difficulty! + They say that there is a switch that you can activate only by using the Spin Attack. + They say that it's possible to find a total of 100 Gold Skulltulas throughout Hyrule. + They say that when non-fairy folk enter the Lost Woods, they become monsters! + They say that the small holes in the ground that you can find all over Hyrule make perfect breeding ground for bugs. + They say that the Kokiri are always followed by small fairies. + They say that one Kokiri has left the forest, but he is still alive! + + + +0xFF00 Collectible Flag (fairy) + + + + Floor + Cracked Wall + Unused + Stinger Room 1 + Stinger Room 2 + + + + + + Vertical + Horizontal + + Invalid + + + + 0x0FC0 = Timer (Seconds) ++0x3F = Switch Flag + + + + Ichiro //Red/Purple Pants, "normal" hair + Sabooro //Light-blue Pants + Jiro //Green Pants + Shiro //Pink/Purple Pants, Two-Spiked Hair + + + +0xFF00 = Path +-FF None + + + + First Wall + Second Wall + + + + + First Wall + Second Wall + + + + + + +0xFF00 path ID + + + + + + + Fake door + Debris + Debris + Debris + Debris + + + + + + + + + + + + + + + + Cow + Tail only + + + + + Stalagmite (floor) + Stalactite (ceiling) //falls when Link is underneath + Regrowing Stalactite (ceiling) //falls when Link is underneath + + + + + vertical, clear flag + vertical, switch softlock + horizontal, clear flag + + + +0x3F00 switchflag + + + + + + + + + + + + + + Scarecrow song effect? + purple + + + + + + + Circular piece of false stone wall //Visible, invisible with Lens of Truth + Square piece of false stone wall //Oriented horizontally + + + + + Zora near the ladder/grotto + Zora near the shop + Zora near the fishes + Zora near the Lake Hylia exit + Zora near the grotto platform + Zora between ladder and grotto platform + Zora near the Lakeside Laboratory + Zora near the Domain exit + Zora from Zora Shop + + + + + + + + See Actor 0095 for variable + + + + + + Child Visible + Adult Visible + + + + + + + + + + + + + + + + Tent, starts the race + Waiting in Lost Woods, ends the race + + + + + + + + Invisible + Visible + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/data/z64/xml/oot_enum_data.xml b/fast64_internal/data/z64/xml/oot_enum_data.xml new file mode 100644 index 000000000..c379af7a4 --- /dev/null +++ b/fast64_internal/data/z64/xml/oot_enum_data.xml @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/data/z64/xml/oot_object_list.xml b/fast64_internal/data/z64/xml/oot_object_list.xml new file mode 100644 index 000000000..d303038c5 --- /dev/null +++ b/fast64_internal/data/z64/xml/oot_object_list.xml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
From 8c267430800c7f1a30e5b675e8755016719fd797 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:16:38 +0100 Subject: [PATCH 056/126] merge oot and mm for xml data --- fast64_internal/constants.py | 4 +- fast64_internal/data/__init__.py | 5 +- fast64_internal/data/mm/actor_data.py | 51 - fast64_internal/data/mm/data.py | 179 - fast64_internal/data/mm/enum_data.py | 162 - fast64_internal/data/mm/getters.py | 12 - fast64_internal/data/mm/object_data.py | 47 - fast64_internal/data/mm/xml/ActorList.xml | 979 ----- fast64_internal/data/mm/xml/EnumData.xml | 719 ---- fast64_internal/data/mm/xml/ObjectList.xml | 653 ---- fast64_internal/data/oot/xml/ActorList.xml | 3695 ------------------- fast64_internal/data/oot/xml/EnumData.xml | 601 --- fast64_internal/data/oot/xml/ObjectList.xml | 389 -- fast64_internal/data/z64/data.py | 4 +- fast64_internal/data/z64/enum_data.py | 1 + fast64_internal/data/z64/object_data.py | 13 +- fast64_internal/z64/constants.py | 6 - fast64_internal/z64/upgrade.py | 6 +- 18 files changed, 17 insertions(+), 7509 deletions(-) delete mode 100644 fast64_internal/data/mm/actor_data.py delete mode 100644 fast64_internal/data/mm/data.py delete mode 100644 fast64_internal/data/mm/enum_data.py delete mode 100644 fast64_internal/data/mm/getters.py delete mode 100644 fast64_internal/data/mm/object_data.py delete mode 100644 fast64_internal/data/mm/xml/ActorList.xml delete mode 100644 fast64_internal/data/mm/xml/EnumData.xml delete mode 100644 fast64_internal/data/mm/xml/ObjectList.xml delete mode 100644 fast64_internal/data/oot/xml/ActorList.xml delete mode 100644 fast64_internal/data/oot/xml/EnumData.xml delete mode 100644 fast64_internal/data/oot/xml/ObjectList.xml diff --git a/fast64_internal/constants.py b/fast64_internal/constants.py index a88d695c1..0d6658b70 100644 --- a/fast64_internal/constants.py +++ b/fast64_internal/constants.py @@ -3,9 +3,9 @@ class GameData: def __init__(self, game_editor_mode: Optional[str] = None): - from .data import OoT_Data + from .data import Z64_Data - self.z64 = OoT_Data() + self.z64 = Z64_Data(game_editor_mode if game_editor_mode is not None else "MM") game_data = GameData() diff --git a/fast64_internal/data/__init__.py b/fast64_internal/data/__init__.py index a9d9375c3..514ce8cf3 100644 --- a/fast64_internal/data/__init__.py +++ b/fast64_internal/data/__init__.py @@ -1,3 +1,2 @@ -from .oot.data import OoT_Data -from .mm.data import MM_Data -from .oot.object_data import OoT_ObjectData +from .z64.data import Z64_Data +from .z64.object_data import Z64_ObjectData diff --git a/fast64_internal/data/mm/actor_data.py b/fast64_internal/data/mm/actor_data.py deleted file mode 100644 index a7929521c..000000000 --- a/fast64_internal/data/mm/actor_data.py +++ /dev/null @@ -1,51 +0,0 @@ -from os import path -from dataclasses import dataclass -from pathlib import Path -from .getters import get_xml_root -from .data import MM_BaseElement - - -@dataclass -class MM_ActorElement(MM_BaseElement): - category: str - tied_objects: list[str] - - -class MM_ActorData: - """Everything related to MM Actors""" - - def __init__(self): - # Path to the ``ActorList.xml`` file - actor_root = get_xml_root(Path(f"{path.dirname(path.abspath(__file__))}/xml/ActorList.xml").resolve()) - - # general actor list - self.actor_list: list[MM_ActorElement] = [] - - for actor in actor_root.iterfind("Actor"): - tied_objects = [] - obj_key = actor.get("ObjectKey") - actorName = f"{actor.attrib['Name']} - {actor.attrib['ID'].removeprefix('ACTOR_')}" - - if obj_key is not None: # actors don't always use an object - tied_objects = obj_key.split(",") - - self.actor_list.append( - MM_ActorElement( - actor.attrib["ID"], - actor.attrib["Key"], - actorName, - int(actor.attrib["Index"]), - actor.attrib["Category"], - tied_objects, - ) - ) - - self.actors_by_key = {actor.key: actor for actor in self.actor_list} - self.actors_by_id = {actor.id: actor for actor in self.actor_list} - - # list of tuples used by Blender's enum properties - last_index = max(1, *(actor.index for actor in self.actor_list)) - self.enum_actor_id = [("None", f"{i} (Deleted from the XML)", "None") for i in range(last_index)] - self.enum_actor_id.insert(0, ("Custom", "Custom Actor", "Custom")) - for actor in self.actor_list: - self.enum_actor_id[actor.index] = (actor.id, actor.name, actor.id) diff --git a/fast64_internal/data/mm/data.py b/fast64_internal/data/mm/data.py deleted file mode 100644 index 0530df442..000000000 --- a/fast64_internal/data/mm/data.py +++ /dev/null @@ -1,179 +0,0 @@ -from dataclasses import dataclass - - -@dataclass -class MM_BaseElement: - id: str - key: str - name: str - index: int - - -@dataclass -class MM_Data: - """Contains data related to MM, like actors or objects""" - - def __init__(self): - from .enum_data import MM_EnumData - from .actor_data import MM_ActorData - from .object_data import MM_ObjectData - - self.enum_data = MM_EnumData() - self.actor_data = MM_ActorData() - self.object_data = MM_ObjectData() - - self.enum_seq_id = [ - ("Custom", "Custom", "Custom"), - ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), - ("NA_BGM_AMBIENCE", "Ambient background noises", "Ambient background noises"), - ("NA_BGM_TERMINA_FIELD", "Termina Field", "Termina Field"), - ("NA_BGM_CHASE", "Chase", "Chase"), - ("NA_BGM_MAJORAS_THEME", "Majora's Theme", "Majora's Theme"), - ("NA_BGM_CLOCK_TOWER", "Clock Tower", "Clock Tower"), - ("NA_BGM_STONE_TOWER_TEMPLE", "Stone Tower Temple", "Stone Tower Temple"), - ("NA_BGM_INV_STONE_TOWER_TEMPLE", "Stone Tower Temple Upside-down", "Stone Tower Temple Upside-down"), - ("NA_BGM_FAILURE_0", "Missed Event 1", "Missed Event 1"), - ("NA_BGM_FAILURE_1", "Missed Event 2", "Missed Event 2"), - ("NA_BGM_HAPPY_MASK_SALESMAN", "Happy Mask Saleman's Theme", "Happy Mask Saleman's Theme"), - ("NA_BGM_SONG_OF_HEALING", "Song Of Healing", "Song Of Healing"), - ("NA_BGM_SWAMP_REGION", "Southern Swamp", "Southern Swamp"), - ("NA_BGM_ALIEN_INVASION", "Ghost Attack", "Ghost Attack"), - ("NA_BGM_SWAMP_CRUISE", "Boat Cruise", "Boat Cruise"), - ("NA_BGM_SHARPS_CURSE", "Sharp's Curse", "Sharp's Curse"), - ("NA_BGM_GREAT_BAY_REGION", "Great Bay Coast", "Great Bay Coast"), - ("NA_BGM_IKANA_REGION", "Ikana Valley", "Ikana Valley"), - ("NA_BGM_DEKU_PALACE", "Deku Palace", "Deku Palace"), - ("NA_BGM_MOUNTAIN_REGION", "Mountain Village", "Mountain Village"), - ("NA_BGM_PIRATES_FORTRESS", "Pirates' Fortress", "Pirates' Fortress"), - ("NA_BGM_CLOCK_TOWN_DAY_1", "Clock Town, First Day", "Clock Town, First Day"), - ("NA_BGM_CLOCK_TOWN_DAY_2", "Clock Town, Second Day", "Clock Town, Second Day"), - ("NA_BGM_CLOCK_TOWN_DAY_3", "Clock Town, Third Day", "Clock Town, Third Day"), - ("NA_BGM_FILE_SELECT", "File Select", "File Select"), - ("NA_BGM_CLEAR_EVENT", "Event Clear", "Event Clear"), - ("NA_BGM_ENEMY", "Battle", "Battle"), - ("NA_BGM_BOSS", "Boss Battle", "Boss Battle"), - ("NA_BGM_WOODFALL_TEMPLE", "Woodfall Temple", "Woodfall Temple"), - ("NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE"), - ("NA_BGM_OPENING", "Opening", "Opening"), - ("NA_BGM_INSIDE_A_HOUSE", "House", "House"), - ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), - ("NA_BGM_CLEAR_BOSS", "Boss Clear", "Boss Clear"), - ("NA_BGM_GET_ITEM", "Item Catch", "Item Catch"), - ("NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR"), - ("NA_BGM_GET_HEART", "Get A Heart Container", "Get A Heart Container"), - ("NA_BGM_TIMED_MINI_GAME", "Mini Game", "Mini Game"), - ("NA_BGM_GORON_RACE", "Goron Race", "Goron Race"), - ("NA_BGM_MUSIC_BOX_HOUSE", "Music Box House", "Music Box House"), - ("NA_BGM_FAIRY_FOUNTAIN", "Fairy's Fountain", "Fairy's Fountain"), - ("NA_BGM_ZELDAS_LULLABY", "Zelda's Theme", "Zelda's Theme"), - ("NA_BGM_ROSA_SISTERS", "Rosa Sisters", "Rosa Sisters"), - ("NA_BGM_OPEN_CHEST", "Open Treasure Box", "Open Treasure Box"), - ("NA_BGM_MARINE_RESEARCH_LAB", "Marine Research Laboratory", "Marine Research Laboratory"), - ("NA_BGM_GIANTS_THEME", "Giants' Theme", "Giants' Theme"), - ("NA_BGM_SONG_OF_STORMS", "Guru-Guru's Song", "Guru-Guru's Song"), - ("NA_BGM_ROMANI_RANCH", "Romani Ranch", "Romani Ranch"), - ("NA_BGM_GORON_VILLAGE", "Goron Village", "Goron Village"), - ("NA_BGM_MAYORS_OFFICE", "Mayor's Meeting", "Mayor's Meeting"), - ("NA_BGM_OCARINA_EPONA", "Ocarina “Epona's Song”", "Ocarina “Epona's Song”"), - ("NA_BGM_OCARINA_SUNS", "Ocarina “Sun's Song”", "Ocarina “Sun's Song”"), - ("NA_BGM_OCARINA_TIME", "Ocarina “Song Of Time”", "Ocarina “Song Of Time”"), - ("NA_BGM_OCARINA_STORM", "Ocarina “Song Of Storms”", "Ocarina “Song Of Storms”"), - ("NA_BGM_ZORA_HALL", "Zora Hall", "Zora Hall"), - ("NA_BGM_GET_NEW_MASK", "Get A Mask", "Get A Mask"), - ("NA_BGM_MINI_BOSS", "Middle Boss Battle", "Middle Boss Battle"), - ("NA_BGM_GET_SMALL_ITEM", "Small Item Catch", "Small Item Catch"), - ("NA_BGM_ASTRAL_OBSERVATORY", "Astral Observatory", "Astral Observatory"), - ("NA_BGM_CAVERN", "Cavern", "Cavern"), - ("NA_BGM_MILK_BAR", "Milk Bar", "Milk Bar"), - ("NA_BGM_ZELDA_APPEAR", "Enter Zelda", "Enter Zelda"), - ("NA_BGM_SARIAS_SONG", "Woods Of Mystery", "Woods Of Mystery"), - ("NA_BGM_GORON_GOAL", "Goron Race Goal", "Goron Race Goal"), - ("NA_BGM_HORSE", "Horse Race", "Horse Race"), - ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), - ("NA_BGM_INGO", "Gorman Track", "Gorman Track"), - ("NA_BGM_KOTAKE_POTION_SHOP", "Magic Hags' Potion Shop", "Magic Hags' Potion Shop"), - ("NA_BGM_SHOP", "Shop", "Shop"), - ("NA_BGM_OWL", "Owl", "Owl"), - ("NA_BGM_SHOOTING_GALLERY", "Shooting Gallery", "Shooting Gallery"), - ("NA_BGM_OCARINA_SOARING", "Ocarina “Song Of Soaring”", "Ocarina “Song Of Soaring”"), - ("NA_BGM_OCARINA_HEALING", "Ocarina “Song Of Healing”", "Ocarina “Song Of Healing”"), - ("NA_BGM_INVERTED_SONG_OF_TIME", "Ocarina “Inverted Song Of Time”", "Ocarina “Inverted Song Of Time”"), - ("NA_BGM_SONG_OF_DOUBLE_TIME", "Ocarina “Song Of Double Time”", "Ocarina “Song Of Double Time”"), - ("NA_BGM_SONATA_OF_AWAKENING", "Sonata of Awakening", "Sonata of Awakening"), - ("NA_BGM_GORON_LULLABY", "Goron Lullaby", "Goron Lullaby"), - ("NA_BGM_NEW_WAVE_BOSSA_NOVA", "New Wave Bossa Nova", "New Wave Bossa Nova"), - ("NA_BGM_ELEGY_OF_EMPTINESS", "Elegy Of Emptiness", "Elegy Of Emptiness"), - ("NA_BGM_OATH_TO_ORDER", "Oath To Order", "Oath To Order"), - ("NA_BGM_SWORD_TRAINING_HALL", "Swordsman's School", "Swordsman's School"), - ("NA_BGM_OCARINA_LULLABY_INTRO", "Ocarina “Goron Lullaby Intro”", "Ocarina “Goron Lullaby Intro”"), - ("NA_BGM_LEARNED_NEW_SONG", "Get The Ocarina", "Get The Ocarina"), - ("NA_BGM_BREMEN_MARCH", "Bremen March", "Bremen March"), - ("NA_BGM_BALLAD_OF_THE_WIND_FISH", "Ballad Of The Wind Fish", "Ballad Of The Wind Fish"), - ("NA_BGM_SONG_OF_SOARING", "Song Of Soaring", "Song Of Soaring"), - ("NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE"), - ("NA_BGM_FINAL_HOURS", "Last Day", "Last Day"), - ("NA_BGM_MIKAU_RIFF", "Mikau", "Mikau"), - ("NA_BGM_MIKAU_FINALE", "Mikau", "Mikau"), - ("NA_BGM_FROG_SONG", "Frog Song", "Frog Song"), - ("NA_BGM_OCARINA_SONATA", "Ocarina “Sonata Of Awakening”", "Ocarina “Sonata Of Awakening”"), - ("NA_BGM_OCARINA_LULLABY", "Ocarina “Goron Lullaby”", "Ocarina “Goron Lullaby”"), - ("NA_BGM_OCARINA_NEW_WAVE", "Ocarina “New Wave Bossa Nova”", "Ocarina “New Wave Bossa Nova”"), - ("NA_BGM_OCARINA_ELEGY", "Ocarina “Elegy of Emptiness”", "Ocarina “Elegy of Emptiness”"), - ("NA_BGM_OCARINA_OATH", "Ocarina “Oath To Order”", "Ocarina “Oath To Order”"), - ("NA_BGM_MAJORAS_LAIR", "Majora Boss Room", "Majora Boss Room"), - ("NA_BGM_OCARINA_LULLABY_INTRO_PTR", "NA_BGM_OCARINA_LULLABY_INTRO", "NA_BGM_OCARINA_LULLABY_INTRO"), - ("NA_BGM_OCARINA_GUITAR_BASS_SESSION", "Bass and Guitar Session", "Bass and Guitar Session"), - ("NA_BGM_PIANO_SESSION", "Piano Solo", "Piano Solo"), - ("NA_BGM_INDIGO_GO_SESSION", "The Indigo-Go's", "The Indigo-Go's"), - ("NA_BGM_SNOWHEAD_TEMPLE", "Snowhead Temple", "Snowhead Temple"), - ("NA_BGM_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), - ("NA_BGM_NEW_WAVE_SAXOPHONE", "New Wave Bossa Nova", "New Wave Bossa Nova"), - ("NA_BGM_NEW_WAVE_VOCAL", "New Wave Bossa Nova", "New Wave Bossa Nova"), - ("NA_BGM_MAJORAS_WRATH", "Majora's Wrath Battle", "Majora's Wrath Battle"), - ("NA_BGM_MAJORAS_INCARNATION", "Majora's Incarnate Battle", "Majora's Incarnate Battle"), - ("NA_BGM_MAJORAS_MASK", "Majora's Mask Battle", "Majora's Mask Battle"), - ("NA_BGM_BASS_PLAY", "Bass Practice", "Bass Practice"), - ("NA_BGM_DRUMS_PLAY", "Drums Practice", "Drums Practice"), - ("NA_BGM_PIANO_PLAY", "Piano Practice", "Piano Practice"), - ("NA_BGM_IKANA_CASTLE", "Ikana Castle", "Ikana Castle"), - ("NA_BGM_GATHERING_GIANTS", "Calling The Four Giants", "Calling The Four Giants"), - ("NA_BGM_KAMARO_DANCE", "Kamaro's Dance", "Kamaro's Dance"), - ("NA_BGM_CREMIA_CARRIAGE", "Cremia's Carriage", "Cremia's Carriage"), - ("NA_BGM_KEATON_QUIZ", "Keaton's Quiz", "Keaton's Quiz"), - ("NA_BGM_END_CREDITS", "The End / Credits", "The End / Credits"), - ("NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP"), - ("NA_BGM_TITLE_THEME", "Title Theme", "Title Theme"), - ("NA_BGM_DUNGEON_APPEAR", "Woodfall Rises", "Woodfall Rises"), - ("NA_BGM_WOODFALL_CLEAR", "Southern Swamp Clears", "Southern Swamp Clears"), - ("NA_BGM_SNOWHEAD_CLEAR", "Snowhead Clear", "Snowhead Clear"), - ("NA_BGM_INTO_THE_MOON", "To The Moon", "To The Moon"), - ("NA_BGM_GOODBYE_GIANT", "The Giants' Exit", "The Giants' Exit"), - ("NA_BGM_TATL_AND_TAEL", "Tatl and Tael", "Tatl and Tael"), - ("NA_BGM_MOONS_DESTRUCTION", "Moon's Destruction", "Moon's Destruction"), - ("NA_BGM_END_CREDITS_SECOND_HALF", "The End / Credits (Half 2)", "The End / Credits (Half 2)"), - ] - - self.enum_ambiance_id = [ - ("Custom", "Custom", "Custom"), - ("0x00", "AMBIENCE_ID_00", "AMBIENCE_ID_00"), - ("0x01", "AMBIENCE_ID_01", "AMBIENCE_ID_01"), - ("0x02", "AMBIENCE_ID_02", "AMBIENCE_ID_02"), - ("0x03", "AMBIENCE_ID_03", "AMBIENCE_ID_03"), - ("0x04", "AMBIENCE_ID_04", "AMBIENCE_ID_04"), - ("0x05", "AMBIENCE_ID_05", "AMBIENCE_ID_05"), - ("0x06", "AMBIENCE_ID_06", "AMBIENCE_ID_06"), - ("0x07", "AMBIENCE_ID_07", "AMBIENCE_ID_07"), - ("0x08", "AMBIENCE_ID_08", "AMBIENCE_ID_08"), - ("0x09", "AMBIENCE_ID_09", "AMBIENCE_ID_09"), - ("0x0A", "AMBIENCE_ID_0A", "AMBIENCE_ID_0A"), - ("0x0B", "AMBIENCE_ID_0B", "AMBIENCE_ID_0B"), - ("0x0C", "AMBIENCE_ID_0C", "AMBIENCE_ID_0C"), - ("0x0D", "AMBIENCE_ID_0D", "AMBIENCE_ID_0D"), - ("0x0E", "AMBIENCE_ID_0E", "AMBIENCE_ID_0E"), - ("0x0F", "AMBIENCE_ID_0F", "AMBIENCE_ID_0F"), - ("0x10", "AMBIENCE_ID_10", "AMBIENCE_ID_10"), - ("0x11", "AMBIENCE_ID_11", "AMBIENCE_ID_11"), - ("0x12", "AMBIENCE_ID_12", "AMBIENCE_ID_12"), - ("0x13", "AMBIENCE_ID_13", "AMBIENCE_ID_13"), - ("0xFF", "AMBIENCE_ID_DISABLED", "AMBIENCE_ID_DISABLED"), - ] diff --git a/fast64_internal/data/mm/enum_data.py b/fast64_internal/data/mm/enum_data.py deleted file mode 100644 index 54b3336f5..000000000 --- a/fast64_internal/data/mm/enum_data.py +++ /dev/null @@ -1,162 +0,0 @@ -from dataclasses import dataclass, field -from os import path -from pathlib import Path -from .getters import get_xml_root -from .data import MM_BaseElement - -# Note: "enumData" in this context refers to an MM Object file (like ``gameplay_keep``) - - -@dataclass -class MM_ItemElement(MM_BaseElement): - parent_key: str - - def __post_init__(self): - # generate the name from the id - if self.name is None: - key_to_prefix = { - "cmd": "CS_CMD", - "miscType": "CS_MISC", - "textType": "CS_TEXT", - "fadeOutSeqPlayer": "CS_FADE_OUT", - "modifySeqType": "CS_MOD", - "transitionType": "CS_TRANS", - "destinationType": "CS_DESTINATION", - "chooseCreditsSceneType": "CS_CREDITS", - "motionBlurType": "CS_MOTION_BLUR", - "rumbleType": "CS_RUMBLE", - "transitionGeneralType": "CS_TRANS_GENERAL", - "spawnFlag": "CS_SPAWN_FLAG", - "endSfx": "CS_END_SFX", - "csSplineInterpType": "CS_CAM_INTERP", - "csSplineRelTo": "CS_CAM_REL", - "playerCueId": "PLAYER_CUEID", - "naviQuestHintType": "NAVI_QUEST_HINTS", - "ocarinaSongActionId": "OCARINA_ACTION", - } - - self.name = self.id.removeprefix(f"{key_to_prefix[self.parent_key]}_") - - if self.parent_key in ["csCmd", "csPlayerCueId"]: - split = self.name.split("_") - if self.parent_key == "csCmd" and "ACTOR_CUE" in self.id: - self.name = f"Actor Cue {split[-2]}_{split[-1]}" - else: - self.name = f"Player Cue Id {split[-1]}" - else: - self.name = self.name.replace("_", " ").title() - - -@dataclass -class MM_EnumElement(MM_BaseElement): - items: list[MM_ItemElement] - item_by_key: dict[str, MM_ItemElement] = field(default_factory=dict) - item_by_index: dict[int, MM_ItemElement] = field(default_factory=dict) - item_by_id: dict[int, MM_ItemElement] = field(default_factory=dict) - - def __post_init__(self): - self.item_by_key = {item.key: item for item in self.items} - self.item_by_index = {item.index: item for item in self.items} - self.item_by_id = {item.id: item for item in self.items} - - -class MM_EnumData: - """Cutscene and misc enum data""" - - def __init__(self): - # general enumData list - self.enum_data_list: list[MM_EnumElement] = [] - - # Path to the ``EnumData.xml`` file - enum_data_root = get_xml_root(Path(f"{path.dirname(path.abspath(__file__))}/xml/EnumData.xml").resolve()) - - for enum in enum_data_root.iterfind("Enum"): - self.enum_data_list.append( - MM_EnumElement( - enum.attrib["ID"], - enum.attrib["Key"], - None, - None, - [ - MM_ItemElement( - item.attrib["ID"], - item.attrib["Key"], - # note: the name sets automatically after the init if None - item.attrib["Name"] if enum.attrib["Key"] == "seqId" else None, - int(item.attrib["Index"]), - enum.attrib["Key"], - ) - for item in enum - ], - ) - ) - - # create list of tuples used by Blender's enum properties - self.deleted_entry = ("None", "(Deleted from the XML)", "None") - - self.enum_cs_cmd: list[tuple[str, str, str]] = [] - self.enum_cs_misc_type: list[tuple[str, str, str]] = [] - self.enum_cs_text_type: list[tuple[str, str, str]] = [] - self.enum_cs_fade_out_seq_player: list[tuple[str, str, str]] = [] - self.enum_cs_modify_seq_type: list[tuple[str, str, str]] = [] - self.enum_cs_transition_type: list[tuple[str, str, str]] = [] - self.enum_cs_destination_type: list[tuple[str, str, str]] = [] - self.enum_cs_credits_scene_type: list[tuple[str, str, str]] = [] - self.enum_cs_motion_blur_type: list[tuple[str, str, str]] = [] - self.enum_cs_rumble_type: list[tuple[str, str, str]] = [] - self.enum_cs_transition_general_type: list[tuple[str, str, str]] = [] - self.enum_cs_spawn_flag: list[tuple[str, str, str]] = [] - self.enum_cs_end_sfx: list[tuple[str, str, str]] = [] - self.enum_cs_split_interp_type: list[tuple[str, str, str]] = [] - self.enum_cs_spline_rel_to: list[tuple[str, str, str]] = [] - self.enum_cs_player_cue_id: list[tuple[str, str, str]] = [] - self.enum_navi_quest_hint_type: list[tuple[str, str, str]] = [] - self.enum_ocarina_song_action_id: list[tuple[str, str, str]] = [] - self.enum_seq_id: list[tuple[str, str, str]] = [] - - self.enum_by_id = {enum.id: enum for enum in self.enum_data_list} - self.enum_by_key = {enum.key: enum for enum in self.enum_data_list} - - key_to_enum = { - "cmd": "enum_cs_cmd", - "miscType": "enum_cs_misc_type", - "textType": "enum_cs_text_type", - "fadeOutSeqPlayer": "enum_cs_fade_out_seq_player", - "modifySeqType": "enum_cs_modify_seq_type", - "transitionType": "enum_cs_transition_type", - "destinationType": "enum_cs_destination_type", - "chooseCreditsSceneType": "enum_cs_credits_scene_type", - "motionBlurType": "enum_cs_motion_blur_type", - "rumbleType": "enum_cs_rumble_type", - "transitionGeneralType": "enum_cs_transition_general_type", - "spawnFlag": "enum_cs_spawn_flag", - "endSfx": "enum_cs_end_sfx", - "csSplineInterpType": "enum_cs_split_interp_type", - "csSplineRelTo": "enum_cs_spline_rel_to", - "playerCueId": "enum_cs_player_cue_id", - "naviQuestHintType": "enum_navi_quest_hint_type", - "ocarinaSongActionId": "enum_ocarina_song_action_id", - "seqId": "enum_seq_id", - } - - for key in self.enum_by_key.keys(): - setattr(self, key_to_enum[key], self.get_enum_data(key)) - - def get_enum_data(self, enum_key: str): - enum = self.enum_by_key[enum_key] - first_index = min(1, *(item.index for item in enum.items)) - last_index = max(1, *(item.index for item in enum.items)) + 1 - enum_data = [self.deleted_entry] * last_index - custom = ("Custom", "Custom", "Custom") - - for item in enum.items: - if item.index < last_index: - identifier = item.key - enum_data[item.index] = (identifier, item.name, item.id) - - if first_index > 0: - enum_data[0] = custom - else: - enum_data.insert(0, custom) - - return enum_data diff --git a/fast64_internal/data/mm/getters.py b/fast64_internal/data/mm/getters.py deleted file mode 100644 index 26378f38d..000000000 --- a/fast64_internal/data/mm/getters.py +++ /dev/null @@ -1,12 +0,0 @@ -from xml.etree.ElementTree import parse as parse_xml, Element -from pathlib import Path - - -def get_xml_root(xml_path: Path) -> Element: - """Parse an XML file and return its root element""" - try: - return parse_xml(xml_path.resolve()).getroot() - except: - from ...utility import PluginError - - raise PluginError(f"ERROR: File '{xml_path}' is missing or malformed.") diff --git a/fast64_internal/data/mm/object_data.py b/fast64_internal/data/mm/object_data.py deleted file mode 100644 index 60eded1e6..000000000 --- a/fast64_internal/data/mm/object_data.py +++ /dev/null @@ -1,47 +0,0 @@ -from dataclasses import dataclass -from os import path -from pathlib import Path -from .getters import get_xml_root -from .data import MM_BaseElement - -# Note: "object" in this context refers to an MM Object file (like `gameplay_keep`) - - -@dataclass -class MM_ObjectElement(MM_BaseElement): - pass - - -class MM_ObjectData: - """Everything related to MM objects""" - - def __init__(self): - # general object list - self.object_list: list[MM_ObjectElement] = [] - - # Path to the ``ObjectList.xml`` file - object_root = get_xml_root(Path(f"{path.dirname(path.abspath(__file__))}/xml/ObjectList.xml")) - - for obj in object_root.iterfind("Object"): - obj_name = f"{obj.attrib['Name']} - {obj.attrib['ID'].removeprefix('OBJECT_')}" - self.object_list.append( - MM_ObjectElement(obj.attrib["ID"], obj.attrib["Key"], obj_name, int(obj.attrib["Index"])) - ) - - self.objects_by_id = {obj.id: obj for obj in self.object_list} - self.objects_by_key = {obj.key: obj for obj in self.object_list} - - # list of tuples used by Blender's enum properties - self.deleted_entry = ("None", "(Deleted from the XML)", "None") - last_index = max(1, *(obj.index for obj in self.object_list)) - self.enum_object_key = self.get_object_id_list(last_index + 1) - - def get_object_id_list(self, max: int): - """Generates and returns the object list in the right order""" - objList = [self.deleted_entry] * max - for obj in self.object_list: - if obj.index < max: - identifier = obj.key - objList[obj.index] = (identifier, obj.name, obj.id) - objList[0] = ("Custom", "Custom Object", "Custom") - return objList diff --git a/fast64_internal/data/mm/xml/ActorList.xml b/fast64_internal/data/mm/xml/ActorList.xml deleted file mode 100644 index 132dc9539..000000000 --- a/fast64_internal/data/mm/xml/ActorList.xml +++ /dev/null @@ -1,979 +0,0 @@ - - - - - - - - - - - - Large Orange Flame - Large Orange Flame - Large Blue Flame - Large Green Flame - Small Orange Flame - Large Orange Flame - Large Green Flame - Large Blue Flame - Large Magenta Flame - Large Pale Orange Flame - Large Pale Yellow Flame - Large Pale Green Flame - Large Pale Pink Flame - Large Pale Purple Flame - Large Pale Indigo Flame - Large Pale Blue Flame - - - - - - - - Whole Day ('ENDOOR_TYPE_WHOLE_DAY') - Locked ('ENDOOR_TYPE_LOCKED') - Day ('ENDOOR_TYPE_DAY') - Night ('ENDOOR_TYPE_NIGHT') - Ajar ('ENDOOR_TYPE_AJAR') - Schedule ('ENDOOR_TYPE_SCHEDULE') - Unknown ('ENDOOR_TYPE_6') - Framed ('ENDOOR_TYPE_FRAMED') - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Golden - Golden - Appears - Clear Flag - Boss Key Chest - Golden - Falls - Switch Flag - Golden - Invisible - Wooden - Wooden - Invisible - Wooden - Clear Flag - Wooden - Falls - Switch Flag - Crash - Crash - Golden - Appears - Switch Flag - - - - - - - - - - - - - - - Regular - Large - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - Invisible - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/data/mm/xml/EnumData.xml b/fast64_internal/data/mm/xml/EnumData.xml deleted file mode 100644 index f7321efa5..000000000 --- a/fast64_internal/data/mm/xml/EnumData.xml +++ /dev/null @@ -1,719 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/data/mm/xml/ObjectList.xml b/fast64_internal/data/mm/xml/ObjectList.xml deleted file mode 100644 index 71706d83c..000000000 --- a/fast64_internal/data/mm/xml/ObjectList.xml +++ /dev/null @@ -1,653 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/data/oot/xml/ActorList.xml b/fast64_internal/data/oot/xml/ActorList.xml deleted file mode 100644 index f3303de70..000000000 --- a/fast64_internal/data/oot/xml/ActorList.xml +++ /dev/null @@ -1,3695 +0,0 @@ - - - - - - - - Invisible, Can't Control //Used for cutscenes without Link - Master Sword Pull and Drop Animation //Overwrites coordinates - Spawn: Blue Warp //used when returning from a blue warp - Spawn: Immobile - Spawn: Exit via Grotto //Y velocity = 12 - Spawn: Warp Song - Spawn: Farore's Wind - Spawn: Thrown Out - Stand - Slow Walk Forward - Retain Previous Velocity //Walk speed set by last exit - - - Last 2 digits = Camera Initial Focus //Data defined by scene Link spawns in -+00FF No Special Positioning - - - - Invisible (Lens of Truth), Mini-Boss Theme - Rises from Ground, Mini-Boss Theme - Rises from Ground //Pair with 0001 - Drops From Sky on Approach - Rises from Ground, Mini-Boss Theme - Unknown - - - - - Intended to be spawned by the Shopkeeper actor - - - - Green Flame - Purple Flame - Red Bubbles - Invisible Hovering Object w/Shadow, bursts into purple flames - Green Flame - Green Flame - Purple Flame - Green Flame - - - - - Large Orange Flame - Large Orange Flame - Large Blue Flame - Large Green Flame - Small Orange Flame - Large Orange Flame - Large Green Flame - Large Blue Flame - Large Magenta Flame - Large Pale Orange Flame - Large Pale Yellow Flame - Large Pale Green Flame - Large Pale Pink Flame - Large Pale Purple Flame - Large Pale Indigo Flame - Large Pale Blue Flame - - - - - - - - - Loads Room - Small Key Locked Door - Loads Room - Scene Transition - Ajar (slams on approach) - Displays Textbox - Time Locked (Unlocked between 18:00 and 21:00) - Loads Room - - - - - Model depends on the scene - - - - Large - Large, Appears, Clear Flag - Boss Key's Chest - Large, Falling, Switch Flag - Large, Invisible - Small - Small, Invisible - Small, Appears, Clear Flag - Small, Falls, Switch Flag - Large, Appears, Zelda's Lullaby - Large, Appears, Sun's Song Triggered - Large, Appears, Switch Flag - - - - - - - - Default - - Hardcoded cutscene camera points to -19, -2 ,-1000 - - - Missing variables - - - - Graveyard Poe - Graveyard Poe //Leaves a Blue Rupee at its spawn point - (006E) Sharp (Composer Brothers) //Sets Permanent Switch Flag 0B when spoken to, use object 006E - (006E) Flat (Composer Brothers) //Sets Permanent Switch Flag 0A when talked to, use object 006E - Graveyard Poe - - May need another object - - - - - First 2 digits: Rocks fired per volley - - - - Web-Covered Hole - Vertical Web Wall - Web-Covered Hole //When burned, web becomes inverse-conical and extends upwards - - - - +0x3F00 = Switch Flag (Set when destroyed) - +0x0FC0 = Switch Flag (Web burns when set) - - - - Bomb - Bomb Shadow - - - - - Timer Spawn (every 6 seconds) - Proximity Spawn - Spawn on Switch Flag - - - + 0x3F00 = Switch Flag (Flag to spawn on. Used by type 02 only) - - - - Default - Two-Foot Dodongo //Emits fire and smoke from mouth upon death - Two-Foot Dodongo //Doesn't emit fire and smoke from mouth upon death - - - - - Fire Keese - Aggressive Keese - Roosting Keese - Ice Keese - - - +8000 = Invisible - - - - Epona - No Epona - Default - - - - - Green Rupee - Blue Rupee - Red Rupee - Recovery Heart - Bomb - Arrow (1) //Used for collecting arrows stuck in walls - Heart Piece - Deku Seeds (5) or Arrows (5) - Deku Seeds (5) or Arrows (10) - Deku Seeds (5) or Arrows (30) - Bombs (5) - Deku Nut - Deku Stick - Large Magic Jar - Small Magic Jar - Deku Seeds (5) or Arrows (5) - Small Key - Flexible Drop //Used for randomized drops, see comments. Will spawn as an invisible Recovery Heart in some situations - Giant Orange Rupee - Large Purple Rupee - Deku Shield //May require Child Link's object - Hylian Shield - Zora Tunic - Goron Tunic - Bombs (5) - Invisible Item - - - +0x3F00 = Collectible Flag - - - - Fire Arrow - Wooden Arrow - - - - - Navi - Bottled Healing Fairy - Roaming Healing Fairy - Group of Healing Fairies - Fairy Healing You - Roaming Large Healing Fairy - - - - - Flees when approached //Cucco hidden in the box in Kakariko - Doesn't Flee - Non-Targetable //The non-super cuccos in the Ranch house - Default - - - - - Red Tektite - Blue Tektite - Normal Tektite - Dies Instantly - - - - - Clear flag ignores this monster - - - - Flying Peahat //Spawns Larva - Peahat Larva - Burrowed Peahat - - - - - - - - Large Bug - Three Small Bugs - Small Bug - - - - - Flopping - Swimming, Doesn't Flee //Used for very small pools of water - Swimming, Reacts to Link - Swimming, Flees - - - - - Vertical, two way, fades black when approached - Up/Down, one-way, fades black when approached - Up/Down, two-way, no fade - Vertical, enabled on switch flag, fades black when approached - Vertical, two-way, no fade - Up/Down, two-way, fades black when approached - - - - - - - - Lizalfos mini-boss, drops from ceiling //Partner to 01, in order to be killed - Lizalfos mini-boss, no mini-boss music //Partner to 00, in order to be killed - Lizalfos, no mini-boss music - Dinolfos, no mini-boss music - Lizalfos, no mini-boss music, drops from ceiling - - - +0xFF00 = Nullable Switch Flag Lizalfos miniboss spawns when entering room from door bound to this switch flag -The Lizalfos miniboss (Type 00 and 01) has special behavior to it. -Type 00 and 01 actors must be spawned together for the miniboss to be defeated. -To differentiate the two encounters (as both are in room 3), the switch flag is used. This flag matches the switch flag of the door used to enter the room - - - - Default - - - - - Default - - - - - Default - - - - - Default - - - - - Impa's Horse - Impa on Horse - Zelda - Ganondorf on Horse (Stationary) - Ganondorf's Horse (Stationary) - Ganondorf on Horse (Riding) + Flames - Ganondorf's Horse (Galloping) - Ganondorf hands crossed //use object 009B - Ganondorf Bowing to King - Ganondorf floating (Curse You) //use object 00E1 - - They need their respective objects to load - - - - Spawned by Gohma Boss, falls on ground, hatches quickly - Spawned by Gohma Boss (unknown 1) - Spawned by Gohma Boss (unknown 2) - Ground Gohma Egg (increase spawn count) - Ground Gohma Egg - Ceiling Gohma Egg (increase spawn count, invisible?) - Ceiling Gohma Egg (invisible?) - - - - Unused - - - - Default - - - - - Lifting door - Front side attached to Room Clear - Front side attached to Switch - Back side permanently locked - Boss door //needs object 00B0 - Front side attached to Switch, Back to Room Clear - Key Locked door - - - +003F = Switch Flag //Used by switch flag iron bar and locked doors -Depending on the scene ID, they need certain objects loaded as the first one in the object list. Scene IDs: -00: needs object 0036 -01: needs object 002B -02: needs object 0096 -04: needs object 002C -05: needs object 0059 -06: needs object 016D -07-08: needs object 0187 -09: needs object 006B -0A: needs object 0139 -0B: needs object 004D -0D: needs object 0179 - - - - - Default - - - - - - - - - Default - - - - - Default - - - - - Default - - - - - Normal - Big - Invisible - + Normal - - - - - Default - - - - - Small grey stone block - Large grey stone block - Huge grey stone block - Small grey stone block, rotates when you stand on it - Large grey stone block, rotates when you stand on it - Small grey stone cube - Crashes - Grass clump - Small tree stump - Oblong Signpost (unbreakable) - Arrow Signpost - Black knobby thing - - - +0xFF00 = Message ID (+0300) - - - - Four spinning a circle, but once you kill one, the rest are gone as well - Three in formation, sink under floor and do not activate - Two in formation, sink under floor and do not activate - One in formation, sink under floor and do not activate - Single - - - - - River (Multi-Point) - Stream - Magma - Waterfall - Small Stream - Stream - Fire Temple's Lower Ambient Noise - Fire Temple's Higher Ambient Noise - Water Dripping (Well) - River - Market gibberish - Decrease current BGM volume - Proximity Saria's Song - Howling wind - Gurgling - Temple of Light's dripping sounds - Low booming-likish sound - Quake/Collapse - Fairy Fountain - Torches - Cows - Outside of the ambient noise domain - - - +0xFF00 = Path ID (Used for sound sources, Type 00, 04 and 05 only) - - - - Tan, Runs Around - Tan, Runs Around - Tan, Runs Away - Tan, Runs Around - - - - - Kokiri Shopkeeper, Objects 0x0FC, 0x101, 0x102 - Kakariko Potion Shopkeeper, Object 0x159 - Bombchu Shopkeeper, spawn when King Dodongo is beaten, Object 0x165 - Market Potion Shopkeeper, Object 0x159 - Bazaar Shopkeeper, Object 0x05B - Unused? Shopkeeper, Object 0x05B - Unused? Shopkeeper, Object 0x05B - Zora Shopkeeper, Object 0x0FE - Goron Shopkeeper, Object 0x05B - Unused? Shopkeeper, Object 0x05B - Happy Mask Shopkeeper, Object 0x13E - - - - - Default - - - - - +0x3F = Switch Flag - Spawns when a specific switch flag is set -Out-of-bounds Plane (typ.) - - - - Lower Part (Flame decal) - Top Part (Face decal) - - - +0xFF00 = Switch Flag - - - - Huge - Big - Small - - - -+0x00FF = Switch Flag - - - - - - - Large Face Cube //Pushable - Squat Cube //Shakes and flies into the air when you land on it - - - - - - - - 2-way diagonal - 4-way plus - - - - - Sinking - Sliding - - - - - - - Idle - Unknown - Unknown - Unknown - Transformation into Zelda - Nocturne CS - Minuet CS - Bolero CS - Serenade CS - First Meeting at ToT - - - - +0x0FC0 = Chest Flag - - Large, turns off with room clear. - Large, plays cutscene, switches off for long time with ticking sound. Turns off permanently with chest flag. - Small, switches off for long time silently. - Large, plays cutscene, switches off for short time with ticking sound. - Disabled, small, switches on for short time. - Disabled, large, can be switched on and off. - Large, switches off permanently, won't spawn if room is cleared. - Nothing - - - - +0x003F = Switch Flag - - - - Chains - Drawbridge - - - - - Club Moblin //Pounds the ground - Spear Moblin - - - +0xFF00 = path Id (Spear Moblins only) - - - - Bomb - Invisible Bomb - Default - - - - - Light Arrows CS - Pre-Credits - Post Castle Collapse - - - - - - - - - Floating Platform - Water Plane - 3 Raising platforms - - - - - - Rotating Spike Cylinder - Deku tree ladder falling when hit by slingshot (switchflag?) - - - - - - - - Statue - Enemy - - - - - Small - Big - - - - - - - - - +0x3F = Switch Flag to make the platform rise more, hardcoded cutscene camera points to 420,-180 ,-1180 - - - - Bombable Wall, triggers intro cutscene - Bombable Wall - Bombable Floor - Lava Cover - - - - +0x3F = Switch Flag - - - - Lord Jabu-Jabu - - The actor spawns the collision data - - - - - - - - - Normal (adult Link) - Spawning in from crystal //Combine with Link's gentle fall spawn in - Normal - Nothing - Blue warp, disappears - Giant purple crystal/magic enclosure - Yellow warp, disappears - Blue warp, doesn't warp you - Spawn in from child blue warp //Combine with Link's gentle fall - Blue warp, warping animation - Tan warp, disappears - Green warp, disappears - Red warp, disappears - Area fails to load - - - - - Golden Torch - Puzzle Torch - Wooden Torch - - - - - +0x3C0 = Torches to light to solve puzzle (Timed Torch) - +0x3F = Switch Flag - - - - - - - - - - - - +0x3F = Switch Flag - Requires 4 actors of this id to work - - - - - - Floating Square platform, sloped bottom //Used in first room, on center column - Floating Square platform - Floating Square platform, tapered on bottom //Center Room floating block - Dragon Head Statue //Main Room - Dragon Head Statue //Skulltula Room - Dragon Head Statue //before Dark Link - Dragon Head Statue - Moving Square Platform with Hookshot Target - - - - - - -+0x0F00 = Path to follow //Type 7 only -+0x00F0 = Speed //Type 7 only -+0x000F = Start Point on Path //Type 7 only - - - - - Switches to lowest (Triforce seems to activate itself for some reason in the ToT) - Stays at ground level (Triforce isn't affected in ToT) - Water Temple Map 3, Standard Quest - Water Temple Map 6, Standard Quest - Water Temple Map 14, Standard Quest - Water Temple (most rooms), Standard Quest - - - - - - - - - - - - - - - Large Green Bubble //requires movement path - Green Bubble //requires movement path - White Bubble //requires movement path - Fire Bubble //Proximity activated, bounces on solid surfaces, hides in lava - Blue Bubble - - - +0xFF00 = Path Id - - - - Normal - Invisible - - - - - -+0x00FF = Time until tile rises -Variable is first incremented by 1, then time until tile rises is calculated as T * 0x10 + 0x14 frames. For example: --FFFF = 0x14 frames --0000 = 0x24 frames --0001 = 0x34 frames etc. - - - - -Use with actors 008C and 008B for the cutscene to work - - - - - - - (0068) Ocarina //Unused - (0062) Light Medallion - (0063) Shadow Medallion - (0064) Fire Medallion - (0065) Water Medallion - (0066) Spirit Medallion - (0067) Forest Medallion - - Add the object in brackets for it to work - - - - Yellow with corner removed - Green and rectangular - Yellow/green and rectangular, looks rusty - Crashes, but not without drawing a huge black thing that I can only assume is a gate... - Crashes before it can even light the area... - + Crashes, no sign of a gate - - - +0x3F00 = Switch Flag - - - Spawned by actor 008C - - - - Hammer-triggered Stone Steps - Platform, one sided - - - +0x3F00 = Switch Flag - - - Unused - - - - Large Conical Tree - Medium Conical Tree - Small Conical Tree - Conical Tree Spawner - Conical Tree Spawned - Oval Green Tree - Oval Yellow Tree Spawner - Oval Yellow Tree Spawned - Oval Green Tree Spawner - Oval Green Tree Spawned - Adult Kakariko Tree - Small Bush - Large Bush - Small Bush Spawner - Small Bush Spawned - Large Bush Spawner - Large Bush Spawned - Small Black Bush - Large Black Bush - Small Black Bush Spawner - Small Black Bush Spawned - Large Black Bush Spawner - Large Black Bush Spawned - Green leaf - Yellow leaf - - - - - - +0xFF00 = Controls item(s) dropped (trees only) --0000 Random --0800 Deku seeds --0900 Magic jars --0A00 Bombs --0B00 Three Hearts --0C00 Three Blue Rupees --0D00 Random --0E00 Random --0F00 Nothing -+0xFF00 = Gold Skulltula spawn var low byte if rz != 0 -ZROT 0x00FF = Gold Skulltula spawn var high byte (See Gold Skulltula Actor 0095) - - - - - Normal, flashes blue when struck with sword - Frickin' huge, doesn't flash when struck - Even bigger? - Ridiculously huge? - Small size, flashes blue when struck - - Unused - - - - Stone cube, side struck with sword flashes blue - Slightly larger - - - - - - 4-Way Attack - Line Loop - Circle Loop - - - - - - - - - - - - - - Text ID when he sleeps: 702A - - - - - - Lowers when a clear flag and the switch flag are set - - - - - - - - - - - Attacking Beamos (2 health) - Attacking Beamos (1 health) - - - XX00: 05 in dodongo's cavern, 08 in ganon's castle entrance - - - - Crystal Light, used by Triforce in Hyrule Creation CS - Flame, used by Din in Hyrule Creation CS - Blue Orb, used by Din in Hyrule Creation CS - Large Green Cone, used by Farore in Hyrule Creation CS - Din - Nayru - Farore - Blue Light Ring, used by Din and Farore in Hyrule Creation CS - Triforce - Fire Medallion - Water Medallion - Forest Medallion - Spirit Medallion - Shadow Medallion - Light Medallion - Time Warp Effect from Temple of Time - Blue Light Ring that shrinks, used by Din in Hyrule Creation CS - Vertical Light Effect used by Triforce - Light Ball from the 6 Sages when sealing Ganondorf - Kokiri Emerald - Goron Ruby - Zora Sapphire - Dust, used in Light Arrow CS - Light Ball, used by Zelda - Large Block of Time Time Warp Effect - Small Block of Time Time Warp Effect - - - - - - - - - - - - - - - Blue Rain Effect, used by Goddesses/Triforce CS - Blue Rain Effect, used in the Master Sword CS - Giant Rock 1 - Giant Rock 2 - Giant Rock 3 - Giant Rock 4 - Giant Rock 5 - Fluffy Clouds - Bolero 3D Note (not implemented) - Serenade 3D Note (not implemented) - Requiem 3D Note (not implemented) - ? 3D Note (not implemented) - ? 3D Note (not implemented) - Door of Time - Yellow Light, used in Master Sword's chamber - Warp Song leaving effect - Warp Song arriving effect - Orange Sparkly Effect, used by appearing chests - - - - - Stationary with switch and hardcoded camera cutscene - Follows Player - - - - - - - - - Slow Patrolling Guard - Fast Patrolling Guard - Slow Patrolling Guard, can skip some waypoints - Fast Patrolling Guard, can skip some waypoints - Nighttime Standing Guard - - - Rupees circle spawned if Path ID == 3 - - - - Rising Gibdo - Gibdo - Redead, doesn't mourn - Redead, doesn't mourn if walking - Redead - Crying Redead - Invisible Redead - - - - - - - Meg, Purple Poe - Joelle, Red Poe - Beth, Blue Poe - Amy, Green Poe - - - - - - - - Sinks into the ground - Breaks on impact - - - -+0x3F00 = Switch Flag - - - - - ??? Amy - ??? Amy - Joelle Painting Puzzle - Beth Painting Puzzle - ??? Amy - - - +0x3F = Switch Flag - - - - Fish - Bug - Butterfly - - - - -0xF000 -> 0 to 15 -+0x0700 Spawn Count (0 or 8 or 9 or 12) -+0000 12 spawns -+0100 9 spawns -+0200 8 spawns -+1000 1 spawn - - - - - Skullwalltula - Gold Skulltula - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Flying Fairies, Dustmotes - Lightning - Snow - Electric Spark Effect, object 0x0A1 - Ganon's Castle Barrier Colored Light Beams, object 0x179 - - - - - - - - - - - Visible - Appears on Song of Storms - Appears on explosion or Megaton Hammer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Shadow Temple's Eye of Truth Door - Small Square Patch of Ground, child only, blocks entrance to Dampe's Grave - Royal Tomb Grave, despawn if the Royal Tomb CS is watched and the scene is the graveyard - Thunderbolt used with the electric spark effect - Light Aura, appears when Royal Tomb Grave explodes - - - +0xFF00 = Switch Flag - - - - Default - Plays discovery sfx when pulled back - Typical - - - - - Normal (no sphere) - Dissipating (no sphere) - - - - - - - Blue Warp and Ruto - Leaning Ruto //no collision data, targetable - Ruto, First Encounter //Plays cutscene from Jabu-Jabu's Belly when you first meet her - Ruto, after falling down the hole in Jabu-Jabu - - - - - - - Flies, lands, dies in a bit //try not to run into it, Link'll catch on fire - Flies, lands, creeps towards Link, dies in a bit //it's blue, but it's still fire - - - - does not appear unless his hands exist - - - - - - Light Medallion and post-Spirit/Shadow Medallions - Ganon's Castle and post-Ganon - - - - - Leever //Use object 0017, spawn on sand (max defined by code) - Red Tektite //Use object 0016 (max defined by code) - Stalchildren //Use object 0184, spawn on dirt - Wolfos //Use object 0183 - - - - - -+0xFF = Enemies to Spawn --0088 When spawning Leevers, 88 is used in Haunted Wasteland --00A4 When spawning Stalchildren, loads two at a time. Used in Hyrule Field --00F2 When spawning Leevers, F2 is used in Desert Colossus - - - - - Fire Medallion (Default) - Goron Ruby - Chamber After Ganon - Credits - - - - - Shadow Medallion - Chamber After Ganon/Ganon's Castle - Escort - Hyrule Field after ZL - First Time Escort - Credits - - - - - - - No damage - One-Hit Kill - - - - Spawned by volvagia - - - Spawned by volvagia - - - - Rock Wall with Skull //style that sometimes has glowy eyes - Black square with large skull face - Shadow Temple Boss Room platforms - Wall of Skulls - Shadow Temple Floor //bluish? texture - Massive Platform - Wall with bluish?, fat bricks texture (one sided) - Shadow Temple Diamond Room (before big key) Fake Walls - Wall with purplish?, fat brick texture (both side) - Room 11's invisible spikes, invisible hookshot point. - - Need Object 0x69 - - - - Moving stone platforms - Rising and falling stone platforms - Spinning black platform - Metal grate - Same as 0001, but graphics are glitched - - - +0xFF00 = Switch Flag //Type 03 Only - - - - +0x3F00 = Switch Flag for Zelda's Lullaby spot - Camera cutscene points to X 4738 Y -1395 Z -2006 - - - - Shadow Temple Scythes (Visible) //Use object 0069 - Shadow Temple Scythes (Invisible) //Use object 0069 - Ice Cavern Spinning Blade //Use object 0069 - - May require additional object - - - - Hyrule Castle guard - Death Mountain gate guard - Ceremonial guard - - - - - - - Large - Medium - Small - Large - - - - - - - - - Spirit Temple's Sun-Block Room - Spirit Temple's Single Cobra-Mirror Room - Spirit Temple's Four Armos Room - Spirit Temple's Topmost Room - - - - - Bridge Sides - Broken Bridge - Bridge as Child - Tent - Repaired Bridge - - - - - Statue, no spear, movable with Adult Link - Spear only, climbable - - - - - - Barinade - - - - - Drops a small key if the room isn't 12, if room is 12 it'll act like the 3 spinning pot room before Bongo-Bongo - - - - Guillotine Blade (Slow) - Spiked Box on Chain - Spiked Wooden Wall, moving //FIXME: moves in wrong direction? - Opposite Spiked Wooden Wall, moving //FIXME: moves in wrong direction? - Propeller, blows wind - Guillotine Blade (Fast) - + Graphical glitches, same as 2 or 3 (unsure) - - - - - Spawns gibdo //(needs object 0098) - Spawns 2 keese //(needs object 000D) - - - +0x3F = Switch Flag - - - - Giant Bird Statue, bombing it will make it fall - Bombable Wall of Skulls - Bombable Rubble (Object 0x8D) - - - +0x3F00 = Switch Flag - - - - - - - - - - Wooden (Default) - Stone (Zora) - Granite (Goron) - - - - - Spirit Medallion - Chamber After Ganon/Ganon's Castle - Kidnapping CS - Iron Knuckle - Credits - Crawlspace - - - - - - - - - Sits there, mini-boss music starts, slice it to make it move (no teleport), green target - Already running around, yellow target this time, no music - - Slicing it in the back will make it jump to the y location of its room, which is typically below most floors - - - - Normal Deku Baba - Straight Deku Baba - - - - - Giant Octo's Platform - Elevator Platform - Water Square //Rises when Switch Flag is set - Lowering Platform //Lowers into place when stepped on, sets Switch Flag - - - +0xFF00 = Nullable Switch Flag - - - - Chamber of Sages, gives Forest Medallion - Chamber After Ganon/Ganon's Castle //Use with actor 01A7 - Credits, Death Mountain Trail - Fairy Ocarina Cutscene - - - - - Unknown - Unknown - Unknown - - - - - Unknown - Unknown - Unknown - Default - - - - - Koume - Kotake - - - - - Default - Debris - Debris - Debris - Debris - Debris - - - - - - Cracked stone floor - Bombable stone wall - Large bombable stone wall - - - +0x3F00 = Switch Flag - - - - - - - - Iceberg - Ice Ramp - - - - - - - - - - - - - - - - - Water Medallion - Chamber After Ganon/Ganon's Castle - Credits - Water Temple Meeting - - - - - - - - - - Temple Gate - Gate lock - Water plane - Ice Block blocking Zora's Domain Entrance (Adult only) - - - +0xFF = Nullable Switch Flag - - - - - - +0x3F = Switch Flag //If set, water level is lowered - - - - - - - - Ingo Race - Gerudo Archery - Unused? - Malon Race - - - - - - - - - Reddish brown - Green - Grayish blue with some red - Already dead - - - - - Reddish brown - Green - Grayish blue with some red - Corrupt textures, still visible and works - Dark brownish - Blackish gray - - - - - - - - - Default - - - - - Rotating platforms - Metal Gate - - - - - - - - - Gray - Expanding, gray //Unused? - Expanding, gray //Unused? - Default - - - - - Floor Blue Switch, release when not stood on - Floor Heavy Switch (Need Ruto to press it) - Standard Floor Yellow Switch - Standard Tall Yellow Switch - On/Off Toggle Tall Yellow Switch - - - +0x3F00 = Switch Flag - - - - - - Default - Begins battle - Ganondorf death sequence - - - - - Default - - - - - Normal - Does not open //possibly waiting for some trap to spring? - - - - - Frog Game Ocarina Spot - Yellow Frog - Blue Frog - Red Frog - Purple Frog - White Frog - - - - - Collectible Deku Shield - Burning Deku shield - - - - - Large crystal - Smaller crystal - Crystal platform - Meltable ice sheet - Giant crystal - - - 0xFF = Nullable Switch Flag - - - - Group of small blue flames, disappear - Blue flame, disappears - Blue flame, targetable - - - - - Ocarina of Time being tossed higher in air - Ocarina of Time being tossed in air - Ocarina of Time - Collectible Ocarina of Time - - - - - Normal - No bright sphere, first one dies off quickly - - - - - Rain of multi-colored light balls, used in Rainbow Bridge CS - Lots of small particles, used with the White 'Black Hole' - White 'Black Hole' Effect, used in the Ganondorf's Sealing CS - Red Light Ball, used in Ganon's Castle - Green Light Ball, used in Ganon's Castle - Yellow Light Ball, used in Ganon's Castle - Purple Light Ball, used in Ganon's Castle - Orange Light Ball, used in Ganon's Castle - Blue Light Ball, used in Ganon's Castle - Koume/Kotake Red Light Ball Attack - Koume/Kotake Blue Light Ball Attack - 'Nabooru Disappearing' Orange Particles - Ganondorf's Light Ball Attack Purple Loading Effect - Ganondorf's Light Ball Attack, used in Zelda Fleeing CS - Red Light Ball with particles, used in the LLR/DMT part of the credits - Green Light Ball with particles, used in the LLR/DMT part of the credits - Yellow Light Ball with particles, used in ToT Cutscenes - Purple Light Ball with particles, used in the LLR/DMT part of the credits - Orange Light Ball with particles, used in the LLR/DMT part of the credits - Blue Light Ball with particles, used in the LLR/DMT part of the credits - - - - - - - - Rotatable Bird Statue - Circular Trap Door Platform //Opens when wrong skull is chosen - Gate //Only blocks one-way - Skull Top - Glitchy graphics, can't see object, behaves like the gate - - - +0x3F00 = Switch Flag - - - - Default - - Not market town gate - - - - Normal - Follow patch faster and repeat it - - - - - - - Large shadow //looks like it's reproduced, well-done though - Small Shadow //CRASH? - No shadow //CRASH? - - - -The sun switch has to be between 252 and 308 units from the cobra mirror to be activated -+0x3F = Switch Flag - - - - - - - - Wearing red vest over blue shirt, no hat - Normal fish - Hylian Loach - Huge Hylian Loach - Pond stuff, still no hat - - - - - Small Push Block - Medium Push Block - Large Push Block - Huge Push Block - - - - - - - - - - - - - - - - - - Default - - - - - Rushing white particles //Jabu-Jabu, when he opens his mouth - Rushing white particles to one point (???) - - - - - - - - - Default - - - - - Purple (Meg) - Red (Joelle) - Blue (Beth) - Green (Amy) - - - +0x3F = Switch Flag - - - - - - - - - Fence - Nothing //Possibly waypoint for the Ingo Race? - Fence - - - - - - - - - - - Bottle //Use group 00C6 - Bottle with Ruto's Letter //Use group 010B - Hylian shield //Use group 00DC - Quiver //Use group 00BE - Silver Scale //Use group 00DB - Golden Scale //Use group 00DB - Small Key //Use group 00AA - Fire Arrow //Use group 0158 - - - - - - Set to 0xFFFF to spawn nothing - - - - - - - - - Collectible gave if each tag points are reached (no order) - Tag Point (no order) - Gives collectible if in range - Invisible Collectible - Collectible gave if each tag points are reached in order - Tag Point (sets order) - Sets Switch Flag if in range (no collectible) - Bomberman Soldier - Collectible gave if player rolls - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Nabooru Knuckle //May Crash - White, sitting //Stone Chair - Black, standing - White, standing - White, no armor falls off when at low health - - - +0xFF00 = Nullable Switch Flag - - - - Unknown - Unknown - Unknown - Unknown - Unknown - Unknown - - - - - Saria's Song HP Skull Kid - Ocarina Game Left Skull Kid - Ocarina Game Right Skull Kid - Saria's Song HP Ocarina Spot - Memory Game Ocarina Spot - Enemy Skull Kid - - - - - - - Silver Rupee Tracker (handles puzzle resolution) - Silver Rupee (the puzzle itself) - Horseback Archery Pot - - - - You need to use one tracker if using silver rupees - - - Used when Koume and Kotake kidnap Nabooru - - - - - - Deku Nuts - Deku Sticks - Piece of Heart (10 rupees) - Deku Seeds - Deku Shield - Bombs - Deku Seeds - Red Potion - Green Potion - Deku Stick Upgrade - Deku Nut Upgrade - Never speaks, and Link is sadly very patient... - Pocket Egg? - - - - - Talk when in range - C-Up Prompt - - - - - - - Stone Eye - Heat-Seeking flame - Immobile flame, dies - Flame sound effect - - - - - Heart or Green Rupee - Bombs - Deku Seeds - Deku Nuts - Deku Seeds - Giant Purple Rupee - Goron Tunic - Nothing - - - +0x3F = Collectible Flag - - - - - - - - - - Waterfall and Pool //Room 1 - King's Chamber Water //Room 0 - - - - - Immobile - Mobile //Hidden When Spawned - - - - - - - - Rotating platform - Dampé Race Stone Door - - - +0xFF = Nullable Switch Flag - - - Hardcoded cutscene camera: -149, 943, -1020 - - - - Normal shrub. Random drops. //Use object 0002 - Cut-able, regenerating grass //Use object 012B, Drops: Heart, Arrows or Deku Seeds - Cut-able grass //Use object 012B, Set drop table via Random Drop Table param - - - - +0x0010 = Spawns set of 3 bugs -+0xFF00 = Random Drop Table --FF00 No Table - - - - - - -+0x1F00 = Path Id //1F00 = null -+0x003F = Switch Flag -ZROT +0x0003 = Speed, Acceleration --0000 3.0, 0.3 --0001 10.0, 0.5 --0002 30.0, 0.5 --0003 3.0, 0.3 - - - - - - +0x8000 = Play Puzzle Solved When Destroyed -+0x3F = Switch Flag - - - - Floor - Rusted Floor - Eye - Crystal - Targetable Crystal - - - - - - - - - - - Large - Small - - - - 0xF000 = Rise Height //80 unit increments -0x0F00 = Platform Travel Speed - - - - - - - - - Hookshot Target Tower - Hookshot Target Tower, lifts up on Switch Flag - Square Hookshot Target - - - - - - - Zora River, Zelda's Lullaby Spot (no cutscene) - Windmill, Song of Storms spot (cutscene) - Temple of Time, Song of Time spot (cutscene) - Learn Sun's Song spot - Royal Family Tomb, Zelda's Lullaby spot - Puzzle Spot - - - - - - - - - - - - - - - End Targets - Mounted Target (Small) - Mounted Target (Big) //Center one - - - - - Follows path, disappears, reappears at first waypoint //simulates falling into a hole - Follows path, breaks into pieces, reappears at first waypoint //As in adult Death Mountain Trail - Follows path, treating it as a closed loop - Follows path, halts, reverses, repeat //As in Fire Temple boulder maze - - - - - +0xFF = Path Id -ROTZ 0x0001 = Behavior after colliding with Link --0000 Reverse path --0001 Follow path - - - - - Sparkling blue rupee - Huge Magenta Rupee, explodes when touched //Unused - Blue, red, and orange rupees, explode when touched //Unused - Random-colored rupees, collectible - Green rupees underground, not collectible //Unused - - - - - - - Ichiro //Red/Purple Pants, "normal" hair - Sabooro //Light-Blue Pants - Jiro //Green Pants - Shiro //Pink/Purple Pants, two-spiked hair - - - - - Talking softlocks if outside of intended scene numbers - - - - - - - - - - - - Shoos you away //Calls you a kid regardless of your actual age - Gate Manager (Gerudo Fortress) - Generic Guard (Gerudo Fortress) - Stands By Cow (Gerudo Valley) - Horseback Archery - Gerudo Training Grounds Guard - - - +0x3F00 = Switch Flag - - - - +0x3F = Switch Flag //Sets flag when block is placed on top of actor - - - Unused. Works on Link and Signs. Check in Spirit Temple under light, works for all values except 1 - - - - Cutscene start - No cutscene //required if you spawn more than four or five of these - - - - Text ID 503E as adult, gives you an egg - - - - +0x3F = Switch Flag //Won't say his normal dialog unless the flag Medigoron is bound to is set - - - - Default - - - - - Default - - Text ID 10B1 when sleeping - - - - Standard - Cutscene Gate, Left Part - Cutscene Gate, Right Part - - - - - X - Hyrule Field - Hyrule Castle Town - The Temple of Time - Dead End - Kakariko Village / Death Mountain Trail / Starting Point - Kakariko Village Graveyard - Dark! Narrow! Scary! / Well of Three Features - Death Mountain / No passage without a / Royal Decree! - Death Mountain Trail - Dodongo's Cavern / Don't enter without permission! - Land of the Gorons / Goron City - Zora's River / Watch out for swift current / and strong undertow. - The Shadow will yield only to one / with the eye of truth, handed / down in Kakariko Village. - Zora's Domain - Zora's Fountain / Don't disturb Lord Jabu-Jabu! / –King Zora XVI - Forest Training Center / Don't recklessly cut signs– / read them carefully! - All those reckless enough to / venture into the desert–please drop by our shop. / Carpet Merchant - Just ahead: / Great Deku Tree's Meadow - Forest Temple - The Lost Woods - Talon and Malon's / Lon Lon Ranch - The Great Ingo's / Ingo Ranch - Lake Hylia - Lakeside Laboratory / Daily trying to get to the bottom / of the mysteries of Lake Hylia! / –Lake Scientist - Gerudo Valley - Horseback Archery Range / Skilled players are welcome! / Current record: # Points - Gerudo Training Ground / Only registered members are / allowed! - Haunted Wasteland / If you chase a mirage, the / desert will swallow you. / Only one path is true! - Spirit Temple - Kokiri Shop / We have original forest goods! - LINK's House - Forest folk shall not leave these woods. - Follow the trail along the edge of / the cliff and you will reach / Goron City, home of the Gorons. - Natural Wonder / Bomb Flower / Danger! Do not uproot! - Death Mountain Summit / Entrance to the crater ahead / Beware of intense heat! - King Zora's Throne Room / To hear the King's royal / proclamations, stand on the / platform and speak to him. - If you can stop my wild rolling, you might get something great. / –Hot Rodder Goron - Only one with the eye of truth / will find the stone umbrella / that protects against the / rain of blades. - Only one who has sacred feet / can cross the valley of the dead. - The record time of those / who raced against me was: / ##"##" / –Dampé the Gravekeeper - Shooting Gallery / etc. - Treasure Chest Shop / We don't necessarily sell them... - High Dive Practice Spot / Are you confident / in your diving skill? - 032c - Mountain Summit / Danger Ahead - Keep Out - Happy Mask Shop! / Now hiring happiness / delivery men! - Bombchu Bowling Alley / You can experience the / latest in Bomb technology! - Bazaar / We have a little bit of everything! - Potion Shop / We have the best quality / potions! - Goron Shop / Mountaineering supplies! - Zora Shop / We have fresh fish! - Heart-Pounding Gravedigging Tour! / From 18:00 to 21:00 Hyrule Time / –Dampé the Gravekeeper - Heart-Pounding Gravedigging Tour! / Tours are cancelled until a new / gravekeeper is found. We / apologize for any inconvenience. - Thrust Attack Signs! / To thrust with your sword, press / CS toward your target while / Z Targeting, then press B. - Hole of “Z” / Let's go through this small / hole! / Stand in front of the hole and / push CS towards it. When the / Action Icon shows “Enter,” press / A to crawl into the hole. / Pay attention to what the Action / Icon says! - Cut Grass With Your Sword / If you just swing with B, you'll / cut horizontally. If you hold Z as / you swing, you'll cut vertically. - Hyrule Castle / Lon Lon Ranch - You are here: Hyrule Castle / This way to Lon Lon Ranch - Just Ahead / King Zora's Chamber / Show the proper respect! - House of the Great Mido / Boss of the Kokiri - House of the Know-It-All Brothers - House of Twins - Saria's House - View Point with Z Targeting / When you have no object to look / at, you can just look forward / with Z. / Stop moving and then change the / direction you are facing, or hold / down Z for a little while. / This can help you get oriented in / the direction you want to face. / It's quite convenient! / If you hold down Z, you can / walk sideways while facing / straight ahead. / Walking sideways can be a very / important technique in dungeon / corridors. Turn around and try doing this right now. - Stepping Stones in the Pond / If you boldly go in the direction / you want to jump, you will leap / automatically. / If you hop around on the stones, / you'll become happier! - No Diving Allowed / –It won't do you any good! - Switch Targeting / If you see a \/ icon above an / object, you can target it with Z. / ... / You can target the stones next to this sign for practice! - Forest Stage / We are waiting to see your / beautiful face! / Win fabulous prizes! - Visit the / House of the Know-It-All Brothers / to get answers to all your / item-related questions! - Pocket Egg - - Message ID //Value + 0x0300 - - - - Whistleblower - Stands there, does nothing - - - - - Non-solid cucco, hops oddly every once in awhile and only goes in one direction - Invisible, solid cucco, doesn't move, can be attacked but will only smoke and molt - Invisible cucco, cannot be attacked it seems, no idea what it does, but you can hear it - - - - - - - Default - - - - - Default - - - - - Temple of Time stone altar dialog - Gravekeeper's diary dialog //Navi hovers higher than normal - Royal Composer Sharp's grave dialog //Use Object 006E, Sets Temporary Switch Flag 09, spawns Sharp - "Royal Family Tomb" dialog - Royal Composer Flat's grave dialog //Use Object 006E, Sets Temporary Switch Flag 08, spawns Flat - - - +0x3F = Switch Flag //Spot deactivates when flag is set - - - - - - - - - - - - - - Does nothing - Outside of Kokiri Forest exit, auto talks - Near Hyrule Castle, auto talks - In front of Kakariko Village, auto talks - Between Lake Hylia and Gerudo Valley, auto talks - In front of Lake Hylia, auto talks - Nothing - Lake Hylia, manual talk, talon grab shortcut - Death Mountain summit, manual talk, talon grab shortcut - Death Mountain summit, manual talk, talon grab shortcut - Desert Colossus, auto talks - Lost Woods, before meeting Saria, auto talks - Lost Woods, after meeting Saria, auto talks - Outside of Kokiri Forest exit, auto talks, Head position alternates? - - - +0x3F = Switch Flag - - - - Small rock, random drops - Large light-gray rock, can't pick up as Young Link, no drop - - - - - - +0x10 = Spawns Bugs --0000 No --0010 Yes -+0x0F00 = Drop Table //0-12, anything higher becomes drop table 0 -+0xF000 = Switch Flag (High Bits) -+0xC0 = Switch Flag (Low Bits) - - - - Flower for grave - Non-liftable small rock - Uncuttable small shrub - Erratic collision data - - - - - Stays On - On/Off Toggle - Activated while enlightened - Burns - - - - +0x3F00 switch flag - - - - Circle of shrubs with one in the middle - Scattered shrubs - Circle of rocks - - - +0xFF00 = Random Drop Table - - - - Link the Goron - Fire Temple Generic - DMT DC Entrance - DMT Rolling - DMT Near Bomb Flower - Goron City Entrance - Goron City Island - Goron City Lost Woods - Unused - Biggoron - - - - - - - 5034 as adult, 5035 when playing ocarina in front of him as adult, crash if no cutscene ? - - - - - - - - - - - - - - - - Bombable, targetable - +0x3F00 = Switch Flag - hardcoded cutscene position at -1160, 686, -880 - spawn light at -946, 477, -894 - - - - Hookable, automatically rises as you approach it - - - - - - - - +0x3F00 = Switch Flag //Lid disappears, starts spinning on floor -+0x003F = Collectible Flag //Heart Piece - - - - - - Rising - Lowering - - - - - - - - - - Tall and narrow - Short and wide - - - - - - - - Standing boy lifting a rock - Standing girl near Fado - Boxing boy - Blocking boy - Backflipping boy - Sitting girl on Shop - Standing girl near Mido's House - Know-It-All Bro teaching about HUD icons - Know-It-All Bro teaching about map and items - Sitting girl in house - Standing girl in Shop - Know-It-All Bro teaching about C-Up - Fado - - - - - - - - - Cloudy Market - Cloudy Ranch - Snowy Zora's Domain - Rainy Lake Hylia - Cloudy Death Mountain - Thunderstrorm Kakariko - Sandstorm Intensity - Thunderstrorm Graveyard - - - - - - - Text ID 5052 as adult - - - - Bomb Bag (Bombchu Bowling given prize) - Heart Piece (Bombchu Bowling given prize) - Bombchus (Bombchu Bowling given prize) - Bombs (Bombchu Bowling given prize) - Purple Rupee (Bombchu Bowling given prize) - Bomb Bag (Bombchu Bowing prize preview) - Heart Piece (Bombchu Bowing prize preview) - Bombchus (Bombchu Bowing prize preview) - Bombs (Bombchu Bowing prize preview) - Purple Rupee (Bombchu Bowing prize preview) - Green Rupee (Chest Game) - Blue Rupee (Chest Game) - Red Rupee (Chest Game) - Purple Rupee (Unused Chest Game Rupee) - Small Key (Chest Game) - Din's Fire - Farore's Wind - Nayru's Love - Bullet Bag - - Each type needs its own object to load - - - - Brick pillar - Brick throne - - - - - - - - - +0xFF = Path Id - - - - Blocking Deku Tree - - - - - Richard's Owner // Use object 0105, text ID 079D - Woman in white, blues and yellow near Apothicary // Use object 018C, text ID 7016 first, then 7017 - Bearded man in white and green near Bazaar // Use object 0107, text ID 701A - Sakon (Jogging Man) // Use object 0111, needs pathway, text ID 7002 - Staunch man in black and green // Use object 0107, text ID 7023 first, then 7024 - Begging man // Use object 0111 // Use object 0111, buy things in bottles, text ID 70ED and followings - Old woman in white // Use object 010D, text ID 7021 first, then 7022 - Old man in blue near Bombchu Bowling // Use object 010C, text ID 7027 first, then 7028 - Woman in lilac near Bombchu Bowling // Use object 0108, text ID 701D first, then 701E - Laughing man in red and white // Use object 0111, text ID 701F first, then 7020 - Explaining man in blue and white // Use object 0111, text ID 7018 first, then 7019 - 'Dancing' woman in blue and yellow near Archery Game // Use object 0108, text ID 7014 - Watchtower man in crimson // Use object 0111, text ID 7015 - Red haired man in green and lilac // Use object 0107, text ID 7055 - Bearded, red haired man in green and white // Use object 0111, text ID 7089 - Old bald man in brown // Use object 010C, text ID 708A - Man in white // Use object 0111, text ID 700E - Man from Impa's House // Use object 0107, text ID 505B first, then 505C - Old bald man in purple // Use object 010C - Man in two shades of green // Use object 0107 - - - +0x780 = Path Id //NPCs 03 and 07 only - - - - - - - - - - - - - - - - - - See actor 11B for variables - - - - Unknown - Unknown - Unknown - Unknown - Unknown - Unknown - Unknown - Unknown - Unknown - Unknown - - - - - - - - - - +0x3F00 = Switch Flag - - - - Time teller - Stands by Impa's House, tells time - Dying guard in Market Town - Stands in Market Town at night - - Text ID 5063, then 5064 - - - - Zelda in Ganondorf Fight (used by game engine) - Zelda in Ganon Fight (used by game engine) - Zelda in Castle Collapse - - - - - - - - - - - - - - - - - Requires Goron Bracelet or better to move as child or adult - - - - - - - - Contents determined by the grotto (actor 009B) variable - - - - Drunken Ingo // Use Object 00C0 - Drunken Talon // Use Object 0088 - Windmill man breakdancing // Use Object 0133 - Encouraging Kokiri Boy // Use Object 00FC - Encouraging Kokiri Girl // Use Object 00FD - White-haired man in blue // Use Object 010C - Black-bearded man in white and green // Use Object 0107 - Bushy-haired woman in red and black // Use Object 0115 - Little old lady // Use Object 010D - Carpenter Boss, Singing // Use Object 0121 - Carpenter, Singing // Use Object 0122 - Carpenter, Singing // Use Object 0122 - Carpenter, Singing // Use Object 0122 - Carpenter, Singing // Use Object 0122 - Kokiri Boy, Dancing // Use Object 00FC - Kokiri Girl, Dancing // Use Object 00FD - Gerudo, Line-dancing 1 // Use Object 0116 - Gerudo, Line-dancing 2 // Use Object 0116 - Gerudo, spikey-haired, Line-dancing // Use Object 0116 - Dancing Zora // Use Object 00FE - King Zora // Use Object 00FF - Mido, sitting // Use Object 00FB - Floating cucco // Use Object 0013 - Floating cucco 2 // Use Object 0013 - Walking cucco // Use Object 0013 - Cucco Lady // Use Object 0110 - Potion Shopkeeper // Use Object 0159 - Happy Mask Salesman // Use Object 013E - Fisherman // Use Object 015B - Bombchu Shopkeeper // Use Object 0165 - Dancing Goron // Use Object 00C9 - Belly slapping Goron // Use Object 00C9 - Biggoron, dancing // Use Object 00C9 - Medigoron, lying down // Use Object 00C9 - Singing Malon // Use Object 00D0 - - Each variable requires it's own object - - - - Lake Hylia's Sun Hitbox - Big Fairy, spawns with Sun's Song - Big Fairy, spawns with Song of Storms - - - - - Pink spiral beam - Green spiral beam - Purple spiral beam - Blue spiral beam - + Black spiral beam - Black and green spiral beam - Gray and green spiral beam - Light blue spiral beam - Light purple spiral beam - - - - - Checkable, Sets Switch - Instant Text - Checkable, Disappears on Switch - Z-Target, No Text - - - - +0x3FC0 = Message ID //0x0200 + Value --0000 Hi! I'm a talking door! //Unused --0040 Strange... this door doesn't open... --0080 Strong iron bars are blocking the door. You can't open them with your hands! --00C0 You need a Key to open a door that is locked or chained. --0100 You need a special key to open this door. --0140 Be quiet! It's only time! I, Dampé the Gravekeeper, am in bed now! Go away and play! Maybe you can find a ghost in the daytime? --0180 It's time now. The Gravedigging Tour is over now! I, Dampé the gravekeeper, am in bed! Go away and play! Maybe you'll find a ghost! --01C0 Happy Mask Shop / Please read this sign before you use this shop... --0200 Shadow Temple... here is gathered Hyrule's bloody history of greed and hatred... --0240 What is hidden in the darkness... Tricks full of ill will... You can't see the way forward... --0280 One who gains the eye of truth will be able to see what is hidden in the darkness. --02C0 Something strange is covering the entrance. You must solve the puzzle in this room to make the entrance open. --0300 Giant dead Dodongo... when it sees red, a new way to go will be open. --0340 Treasure Chest Contest / Temporarily Closed / Open Tonight! --0380 Medicine Shop / Closed until morning... --03C0 Shooting Gallery / Open only during the day --0400 Happy Mask Shop / Now hiring part-time / Apply during the day --0440 Bazaar / Open only during the day --0480 Show me the light! --04C0 One with the eye of truth shall be guided to the Spirit Temple by an inviting ghost. --0500 Those who wish to open the path sleeping at the bottom of the lake must play the song passed down by the Royal Family. --0540 Those who wish to open the gate on the far heights, play the song passed down by the Royal Family. --0580 Those who find a Small Key can advance to the next room. Those who don't can go home! //Unused --05C0 If you wish to speak to me, do so from the platform. --0600 Hi, LINK! Look this way! Look over here with Z, and talk to me with A. --0640 The current time is: time. --0680 Shine light on the living dead... --06C0 Those who break into the Royal Tomb will be obstructed by the lurkers in the dark. --0700 Hey, you! Young man, over there! Look over here, inside the cell! --0740 My little boy isn't here right now... I think he went to play in the graveyard... --0780 Oh, my boy is asleep right now. Please come back some other time to play with him! --07C0 When water fills the lake, shoot for the morning light. --0800 If you want to travel to the future, you should return here with the power of silver from the past. --0840 If you want to proceed to the past, you should return here with the pure heart of a child. --0880 This door is currently being refurbished. //Unused --08C0 It looks like something used to be set in this stand... --0900 Make my beak face the skull of truth. The alternative is descent into the deep darkness. --0940 This is not the correct key... the door won't open! --0980 Granny's Potion Shop / Closed / Gone for Field Study / Please come again! –Granny --09C0 Who's there? What a bad kid, trying to enter from the rear door! Such a bad kid... I have to tell you some juicy gossip! The boss carpenter has a son... He's the guy who sits under the tree every night... Don't tell the boss I told you that! --0A00 Look at this! --0A40 Malon's gone to sleep! I'm goin' to sleep now, too. Come back again when it's light out! --0A80 LINK's Records! / Spiders squished: 0 / Largest fish caught: 0 pounds / Marathon time: 00"00" / Horse race time: 00"00" / Horseback archery: 0 points --0AC0 The crest of the Royal Family is inscribed here. --0B00 R.I.P. / Here lie the souls of those who swore fealty to the Royal Family of Hyrule / The Sheikah, guardians of the Royal Family and founders of Kakariko, watch over these spirits in their eternal slumber. --0B40 Sleepless Waterfall / The flow of this waterfall serves the King of Hyrule. When the king slumbers, so too do these falls. --0B80 Some frogs are looking at you from underwater... --0BC0 You're standing on a soft carpet for guests... it feels so plush under your feet! --0C00 If you can overcome the trials in the chambers ahead, then and only then will you be qualified to hold our secret treasure! --0C40 If you desire to acquire our hidden treasure, you must strive to obtain the keys hidden in each chamber! --0C80 Defeat all the enemies in a limited time! --0CC0 Collect the underwater gems! --0D00 Cross the sea of fire! --0D40 Find a secret passage in this room! --0D80 Blind the eyes of the statue! --0DC0 One with silver hands shall move a giant block! --0E00 Without the necessary items, one will be confounded by impossible mysteries. --0E40 Gather the jewels of white, while avoiding traps and danger! --0E80 Fishing Pond / The fish are really biting today! --0EC0 ...??? --0F00 The Shadow will yield only to one with the eye of truth, handed down in Kakariko Village. --0F40 You borrowed a Pocket Egg! ... -+0x3F = Switch Flag - - - - Turns around, can't move, whistle-blower - Won't turn around, can't move, whistle-blower - Purple Gerudo, acts like the one that gives you the membership card - - - - - - - +0xFC00 = Switch Flag //Set on room clear -+ 0x3FF = Timer in seconds (capped to 10 minutes) --03FF No Timer - - - - Main Hyliantula //(gold skulltulas lower than 100) - Hyliantula without an arm //(gold skulltulas lower than 10) - Hyliantula without an arm //(gold skulltulas lower than 20) - Hyliantula without an arm //(gold skulltulas lower than 30) - Hyliantula without an arm //(gold skulltulas lower than 40) - Hyliantula without an arm //(gold skulltulas lower than 50) - Hyliantula without an arm //(gold skulltulas lower than 60) - Hyliantula without an arm //(gold skulltulas lower than 70) - Hyliantula without an arm //(gold skulltulas lower than 80) - Hyliantula without an arm //(gold skulltulas lower than 90) - Hyliantula without an arm //(gold skulltulas lower than 100) - Hyliantula without an arm //(gold skulltulas lower than 110) - - - - - Main Hyliantula //(gold skulltulas lower than 100) - Hyliantula without an arm //(gold skulltulas lower than 10) - Hyliantula without an arm //(gold skulltulas lower than 20) - Hyliantula without an arm //(gold skulltulas lower than 30) - Hyliantula without an arm //(gold skulltulas lower than 40) - Hyliantula without an arm //(gold skulltulas lower than 50) - Hyliantula without an arm //(gold skulltulas lower than 60) - Hyliantula without an arm //(gold skulltulas lower than 70) - Hyliantula without an arm //(gold skulltulas lower than 80) - Hyliantula without an arm //(gold skulltulas lower than 90) - Hyliantula without an arm //(gold skulltulas lower than 100) - Hyliantula without an arm //(gold skulltulas lower than 110) - - - - - Purple wormhole - Blue wormhole - - - - - Regular effects, storm begins - Texture-spanning effect only, no storm, music isn't affected, effect does not dissipate - - - - - Default - - - - - Large flat square floor tile, makes water noises when walking on it - Large vertical gate - - - +0x3F00 = Switch Flag //Type 01 only - - - - +0x3F = Switch Flag - - - - Chair Crumble - Pillar Crumble - Round stone thing, explodes as soon as area loads - - - - - +0xFF = Nullable Switch Flag, has cutscene with absolute position - Hardcoded cutscene camera: -1134, 112, -3075 - - - - +0xFF = Nullable Switch Flag - Camera cutscene points to X 38 Y 333 Z -1097 - - - - (Invalid) - Scrub on path to Deku Slingshot - 231/312 Hint scrub - Final Deku Scrub - - - -+0xFF = used to set up 231/312 puzzle --00 Normal, talks when caught --01 First scrub to hit //0001 for no dialog? --02 Second scrub to hit //0002 for no dialog? --03 Third scrub to hit, talks when caught - - - - Mad Scrubs - Hint Scrubs - Business Scrubs - Forest Stage Judge - Forest Stage Patron - - - - - Broken Drawbridge - Fences (Hyrule Field) - - - - - Deku Nuts - Deku Sticks - Piece of Heart - Deku Seeds - Deku Shield - Bombs - Deku Seeds - Red Potion - Green Potion - Deku Stick Upgrade - Deku Nut Upgrade - - - - - - - - - +0x3F00 = switch flag when you defeat her AND collectible flag for her key - (if the collectible flag XX is already set she will not give you a key) - ZRot = switch to make her spawn - - - - - - - - - - - - Dirty blond dog - Chocolate brown dog - Red dog - Multicolored, flashing dog - Red dog - Multicolored, flashing dog - Dark dog (black fur) - Green dog - Red dog - Purple dog - Red dog - Green dog - Green dog - Black dog - Black dog - Purple dog - - - - -+0x0FF0 = Direction it runs //Orientation relative to the object. Also, if you befriend a dog and return to the place with the dog and change this value, another dog will spawn --0000 SEE --0010 NNW --0020 N --0030 First NNW, then SE --0040 First NNW, then SE --0050 First NNW, then SE --0060 N --0070 First NNW, then S --0080 First NNW, then SE --0090 N --00A0 First NNW, then SE --00B0 NW --00C0 NW --00D0 NW --00E0 NW --00F0+ First NNW, then SEE --0F00+ No dog - - - - - - - - Potion Shop Poster - Shooting Gallery Poster - Bazaar Poster - Shooting Gallery (Partially Complete) //Spawns Carpenter Sabooro (Kakariko) during the day - Shooting Gallery (Complete) - - - - - - - graphics very glitchy in certain areas - - - - - - - - - 0xFFFF = Spawned Skulltula Variable (see actor 0095) --FFFF No Skulltula -X ROTATION +0xFF = Collectible Item Dropped (see actor 0015) -Z ROTATION +0x3F = Collectible Flag - - - - Default - - - - Spawned by Deku Panel - - - - Default - - Yields deku seed upgrade - - - may cause crashes in some areas - - - - - - - - Magic Barrier - Blue Magic Core //Use with actor 00D2 (Adult Ruto), var 0002 - Yellow Magic Core //Use with actor 00A6 (Rauru), var 0002 - Red Magic Core //Use with actor 00A8 (Cutscene Darunia), var 0002 - Purple Magic Core //Use with actor 00A9 (Impa), var 0002 - Orange Magic Core //Use with actor 00C3 (Nabooru), var 0002 - Green Magic Core //Use with actor 00C9 (Cutscene Saria), var 0002 - - - - - Graphics may glitch when it's destroyed, but will fix after it disappears -+0x3F = Switch Flag - - - - Graphics may glitch when it's destroyed, but will fix after it disappears - - - - Five Blue Rupees stacked vertically - Five Green Rupees in a row - Six Green Rupees in a circle with a Red Rupee in the center - - - - - Text ID 7025, then 7026 then 7025…. - - - - Blue/green textures - Green/brown textures - Green/red textures - Purple/red textures - Orange/red textures - Purple/black textures - Flashing purple/blue textures - Flashing purple/cyan/green textures, depends on movement of camera - Purple/red textures - - - - - Big Rollin' Goron - Link the Goron - Biggoron - Generic Fire Temple Goron - Goron from DMT near a bomb flower - Rolling Goron from DMT - Goron near Dodongo's Cavern Entrance - Goron at the entrance of Goron City - Goron on the island from Goron City - Goron near Darunia's room - Goron in the stairwell in Goron City - Goron near Lost Woods - Goron talking about the Great Fairy in DMT - Goron in Market's Bazaar - - - - - - - - Normal - White Wolfos, mini-boss music starts - - - +0xFF00 = Nullable Switch Flag - - - - //0000 to 1098 controls the size, where 0000 is normal size and 1098 is as large as is possible for the machine to handle (may vary depending on the level). -//From F02F to FFFF, the Stalchild will appear but will somehow invert everything. In other words, it walks upside-down underneath the ground. -//Really weird. FFFF is smallest, F02F is supposedly largest (I haven't been able to see it, though). - - - - Around Arena, indestructible rubble - Rubble Pile 1 (where Ganondorf rises) - Rubble Pile 2 (where Ganondorf rises) - Rubble Pile 3 (where Ganondorf rises) - Rubble Pile 4 (where Ganondorf rises) - Rubble Pile 5 (where Ganondorf rises) - Rubble Pile 6 (where Ganondorf rises) - Rubble Pile 7 (where Ganondorf rises) - 'Sun' destructible rubble, drops collectible (draw depends on Ganon) - 'Wall' destructible rubble, drops collectible (draw depends on Ganon) - Tall destructible rubble, drops collectible (draw depends on Ganon) - - - - - - - Large chunk - Medium chunk - Small chunk - Large chunk - Medium chunk - Small chunk - Large chunk - Medium chunk - Small chunk - Small chunk - - non-solid, possibly Ganon's Tower rubble - - - Narrow, maze-like platform (sinks) - - - - Invisible Path - Glass Block, appears on Switch Flag - Invisible Timer - - - +0xFF00 = Nullable Switch Flag //If null, Enabled and ignoring switch flag input -//The timer works as such: -//The clear block's invisible timer actor manipulates the value of three switch flags: -//The Switch Flag (FlagA), Flag + 1 (FlagB), Flag + 2 (FlagC) -//FlagA is set to 0 if FlagB and FlagC are 0 -//FlagA is set to 1 and timer started if either FlagB or FlagC are 1 -//Before timer ends, FlagA is set to 0 -//Aprox. 1 second later, FlagB and FlagC are zeroed -//Clear Block actors disappear ~2 seconds after the Switch Flag is zeroed to account for -//FlagA being zeroed before the timer runs out - - - - Ceiling Web - Light Source (draws when web burned) - Light Floor (draws when web burned) - - - - - - Square Stone - Stone Brick - Similar to 1, but looks like a different texture - + Graphics glitchy - - - - - //Actor 00D6 is used in Ice Cavern - - - - - - This is a Gossip Stone! - They say you can swim faster by continuously pressing B. - They say there is a secret near the lone tree which is not far from the river in the northwest part of Hyrule Field. - They say that there is a secret on the road that leads to Lake Hylia. - They say that Biggoron's Sword is super sharp and will never break. - They say that Medigoron didn't really think about his own size, so his store is really cramped. - They say that Malon set the original record in the obstacle course of Lon Lon Ranch. - They say that Malon of Lon Lon Ranch hopes a knight in shining armor will come and sweep her off her feet someday. - They say that Ruto, the Zora princess who is known for her selfish nature, likes a certain boy... - They say that players who select the “HOLD” option for “Z TARGETING” are the real “Zelda players!” - They say that there is a secret near a tree in Kakariko Village. - They say that, contrary to her elegant image, Princess Zelda of Hyrule Castle is, in fact, a tomboy! - They say that Princess Zelda's nanny is actually one of the Sheikah, who many thought had died out. - They say there is a man who can always be found running around in Hyrule Field. - They say that it is against the rules to use glasses at the Treasure Chest Shop in Hyrule Castle Town Market. - They say that the chicken lady goes to the Lakeside Laboratory to study how to breed pocket-sized Cuccos. - They say that Gerudos sometimes come to Hyrule Castle Town to look for boyfriends. - They say that the thief named Nabooru, who haunts this area, is a Gerudo. - They say that if you get close to a butterfly while holding a Deku Stick in your hands, something good will happen. - They say that you may find something new in dungeons that you have already finished. - They say that Gerudos worship Ganondorf almost like a god. - They say that there is a secret around the entrance to Gerudo Valley. - They say that the owl named Kaepora Gaebora is the reincarnation of an ancient Sage. - They say that strange owl, Kaepora Gaebora, may look big and heavy, but its character is rather lighthearted. - They say that the horse Ganondorf rides is a solid black Gerudo stallion. - They say that Ganondorf is not satisfied with ruling only the Gerudo and aims to conquer all of Hyrule! - They say that the treasure you can earn in the Gerudo's Training Ground is not as great as you would expect, given its difficulty! - They say that there is a switch that you can activate only by using the Spin Attack. - They say that it's possible to find a total of 100 Gold Skulltulas throughout Hyrule. - They say that when non-fairy folk enter the Lost Woods, they become monsters! - They say that the small holes in the ground that you can find all over Hyrule make perfect breeding ground for bugs. - They say that the Kokiri are always followed by small fairies. - They say that one Kokiri has left the forest, but he is still alive! - - - +0xFF00 Collectible Flag (fairy) - - - - Floor - Cracked Wall - Unused - Stinger Room 1 - Stinger Room 2 - - - - - - Vertical - Horizontal - + Invalid - - - - 0x0FC0 = Timer (Seconds) -+0x3F = Switch Flag - - - - Ichiro //Red/Purple Pants, "normal" hair - Sabooro //Light-blue Pants - Jiro //Green Pants - Shiro //Pink/Purple Pants, Two-Spiked Hair - - - +0xFF00 = Path --FF None - - - - First Wall - Second Wall - - - - - First Wall - Second Wall - - - - - - +0xFF00 path ID - - - - - - - Fake door - Debris - Debris - Debris - Debris - - - - - - - - - - - - - - - - Cow - Tail only - - - - - Stalagmite (floor) - Stalactite (ceiling) //falls when Link is underneath - Regrowing Stalactite (ceiling) //falls when Link is underneath - - - - - vertical, clear flag - vertical, switch softlock - horizontal, clear flag - - - +0x3F00 switchflag - - - - - - - - - - - - - - Scarecrow song effect? - purple - - - - - - - Circular piece of false stone wall //Visible, invisible with Lens of Truth - Square piece of false stone wall //Oriented horizontally - - - - - Zora near the ladder/grotto - Zora near the shop - Zora near the fishes - Zora near the Lake Hylia exit - Zora near the grotto platform - Zora between ladder and grotto platform - Zora near the Lakeside Laboratory - Zora near the Domain exit - Zora from Zora Shop - - - - - - - - See Actor 0095 for variable - - - - - - Child Visible - Adult Visible - - - - - - - - - - - - - - - - Tent, starts the race - Waiting in Lost Woods, ends the race - - - - - - - - Invisible - Visible - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/data/oot/xml/EnumData.xml b/fast64_internal/data/oot/xml/EnumData.xml deleted file mode 100644 index c379af7a4..000000000 --- a/fast64_internal/data/oot/xml/EnumData.xml +++ /dev/null @@ -1,601 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/data/oot/xml/ObjectList.xml b/fast64_internal/data/oot/xml/ObjectList.xml deleted file mode 100644 index d303038c5..000000000 --- a/fast64_internal/data/oot/xml/ObjectList.xml +++ /dev/null @@ -1,389 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index cb5678fa4..1ed1a610d 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -332,7 +332,7 @@ class Z64_BaseElement: class Z64_Data: """Contains data related to OoT, like actors or objects""" - def __init__(self, game: str = "OOT"): + def __init__(self, game: str): from .enum_data import Z64_EnumData from .object_data import Z64_ObjectData from .actor_data import Z64_ActorData @@ -348,5 +348,3 @@ def __init__(self, game: str = "OOT"): else: self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id - - pass diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py index cce2d101a..a8b9c1517 100644 --- a/fast64_internal/data/z64/enum_data.py +++ b/fast64_internal/data/z64/enum_data.py @@ -101,6 +101,7 @@ def __init__(self, game: str): item.attrib["Name"] if enum.attrib["Key"] == "seqId" else None, int(item.attrib["Index"]), enum.attrib["Key"], + game, ) for item in enum ], diff --git a/fast64_internal/data/z64/object_data.py b/fast64_internal/data/z64/object_data.py index db3a663de..50d45b1ff 100644 --- a/fast64_internal/data/z64/object_data.py +++ b/fast64_internal/data/z64/object_data.py @@ -39,11 +39,14 @@ def __init__(self, game: str): self.ootEnumObjectKey = self.getObjectIDList(lastIndex + 1, False) # create the legacy object list for old blends - self.ootEnumObjectIDLegacy = self.getObjectIDList(self.objects_by_key["obj_timeblock"].index + 1, True) - - # validate the legacy list, if there's any None element then something's wrong - if game == "OOT" and self.deletedEntry in self.ootEnumObjectIDLegacy: - raise PluginError("ERROR: Legacy Object List doesn't match!") + if game == "OOT": + self.ootEnumObjectIDLegacy = self.getObjectIDList(self.objects_by_key["obj_timeblock"].index + 1, True) + + # validate the legacy list, if there's any None element then something's wrong + if self.deletedEntry in self.ootEnumObjectIDLegacy: + raise PluginError("ERROR: Legacy Object List doesn't match!") + else: + self.ootEnumObjectIDLegacy = [] def getObjectIDList(self, max: int, isLegacy: bool): """Generates and returns the object list in the right order""" diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index cdbb67a44..fddae8bd9 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -1,9 +1,3 @@ -from ..data import OoT_Data, MM_Data - - -oot_data = OoT_Data() -mm_data = MM_Data() - ootEnumRoomShapeType = [ # ("Custom", "Custom", "Custom"), ("ROOM_SHAPE_TYPE_NORMAL", "Normal", "Normal"), diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index d70c28e35..c30ad7a3c 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -5,7 +5,7 @@ import bpy from bpy.types import Object, CollectionProperty from ..utility import PluginError -from ..data import OoT_ObjectData +from ..data import Z64_ObjectData from .utility import getEvalParams, get_actor_prop_from_obj from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode @@ -17,7 +17,7 @@ ##################################### # Room Header ##################################### -def upgradeObjectList(objList: CollectionProperty, objData: OoT_ObjectData): +def upgradeObjectList(objList: CollectionProperty, objData: Z64_ObjectData): """Transition to the XML object system""" for obj in objList: # In order to check whether the data in the current blend needs to be updated, @@ -36,7 +36,7 @@ def upgradeObjectList(objList: CollectionProperty, objData: OoT_ObjectData): del obj["objectID"] -def upgradeRoomHeaders(roomObj: Object, objData: OoT_ObjectData): +def upgradeRoomHeaders(roomObj: Object, objData: Z64_ObjectData): """Main upgrade logic for room headers""" altHeaders = roomObj.ootAlternateRoomHeaders for sceneLayer in [ From e49b0423edcb7dad252fea010a2fe943a97cb2d7 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:16:49 +0100 Subject: [PATCH 057/126] format --- fast64_internal/data/z64/data.py | 2 +- fast64_internal/z64/cutscene/classes.py | 21 ++++++++++++++++--- fast64_internal/z64/cutscene/constants.py | 2 +- .../z64/cutscene/importer/classes.py | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 1ed1a610d..55bbcd821 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -345,6 +345,6 @@ def __init__(self, game: str): if game == "OOT": self.ootEnumMusicSeq = ootEnumMusicSeq self.ootEnumNightSeq = ootEnumNightSeq - else: + else: self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 28d39e705..278db12bc 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -32,7 +32,15 @@ class CutsceneCmdBase: duration: Optional[int] = None def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): - if not is_game_oot() and enumKey not in {"seqId", "destinationType", "ocarinaSongActionId", "motionBlurType", "modifySeqType", "chooseCreditsSceneType", "transitionGeneralType"}: + if not is_game_oot() and enumKey not in { + "seqId", + "destinationType", + "ocarinaSongActionId", + "motionBlurType", + "modifySeqType", + "chooseCreditsSceneType", + "transitionGeneralType", + }: # remove `cs` and lowercase first letter enumKey = enumKey[2].lower() + enumKey[3:] @@ -68,6 +76,7 @@ def __post_init__(self): # MM's new camera commands + @dataclass class CutsceneCmdNewCamPoint(CutsceneCmdBase): """This class contains a single Camera Point command data (the newer version)""" @@ -429,7 +438,13 @@ class CutsceneCmdTextList(CutsceneCmdBase): """This class contains Text List command data""" entryTotal: Optional[int] = None - entries: list[CutsceneCmdText | CutsceneCmdTextNone | CutsceneCmdTextOcarinaAction | CutsceneCmdTextGeneric | CutsceneCmdTextMask] = field(default_factory=list) + entries: list[ + CutsceneCmdText + | CutsceneCmdTextNone + | CutsceneCmdTextOcarinaAction + | CutsceneCmdTextGeneric + | CutsceneCmdTextMask + ] = field(default_factory=list) paramNumber: int = 1 listName: str = "textList" @@ -781,7 +796,7 @@ class Cutscene: textList: list[CutsceneCmdTextList] = field(default_factory=list) miscList: list[CutsceneCmdMiscList] = field(default_factory=list) rumbleList: list[CutsceneCmdRumbleControllerList] = field(default_factory=list) - transitionList: list[CutsceneCmdTransition] = field(default_factory=list) + transitionList: list[CutsceneCmdTransition] = field(default_factory=list) lightSettingsList: list[CutsceneCmdLightSettingList] = field(default_factory=list) timeList: list[CutsceneCmdTimeList] = field(default_factory=list) seqList: list[CutsceneCmdStartStopSeqList] = field(default_factory=list) diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 9152ef922..7e2e4e1b7 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -237,7 +237,7 @@ "CS_CAM_POINT_NEW", "CS_CAM_MISC", "CS_CAM_END", - "CS_CAM_SPLINE", # technically a list but treating it as an entry + "CS_CAM_SPLINE", # technically a list but treating it as an entry "CS_TEXT_DEFAULT", "CS_TEXT_TYPE_1", "CS_TEXT_TYPE_3", diff --git a/fast64_internal/z64/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py index 224b78f97..c589d9bec 100644 --- a/fast64_internal/z64/cutscene/importer/classes.py +++ b/fast64_internal/z64/cutscene/importer/classes.py @@ -85,7 +85,7 @@ def getCmdParams(self, data: str, cmdName: str, paramNumber: int): def getNewCutscene(self, csData: str, name: str): params = self.getCmdParams(csData, "CS_HEADER", Cutscene.paramNumber) return Cutscene(name, getInteger(params[0]), getInteger(params[1])) - + def correct_command_lists(self, command: str): """If using the new cs system, moves standalone commands to the proper lists""" if self.new_cs_system: From 468d70735a244dff3a0fec00d03be4ed3973e56c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:31:36 +0100 Subject: [PATCH 058/126] remove get_game_enum --- fast64_internal/data/z64/data.py | 153 ++++++++++++++++++- fast64_internal/z64/actor/properties.py | 6 +- fast64_internal/z64/constants.py | 131 ---------------- fast64_internal/z64/importer/actor.py | 9 +- fast64_internal/z64/importer/room_header.py | 6 +- fast64_internal/z64/importer/scene_header.py | 12 +- fast64_internal/z64/utility.py | 44 ------ 7 files changed, 169 insertions(+), 192 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 55bbcd821..b6e74bd06 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -8,6 +8,9 @@ class Z64_BaseElement: name: str index: int +# --- + +# TODO: get this from XML ootEnumMusicSeq = [ # see https://github.com/zeldaret/oot/blob/9f09505d34619883748a7dab05071883281c14fd/include/sequence.h#L4-L118 @@ -328,6 +331,145 @@ class Z64_BaseElement: ] +ootEnumGlobalObject = [ + ("Custom", "Custom", "Custom"), + ("OBJECT_INVALID", "None", "None"), + ("OBJECT_GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), + ("OBJECT_GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), +] + +mm_enum_global_object = [ + ("Custom", "Custom", "Custom"), + ("GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), + ("GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), +] + +# --- + +ootEnumSkybox = [ + ("Custom", "Custom", "Custom"), + ("0x00", "None", "None"), + ("0x01", "Standard Sky", "Standard Sky"), + ("0x02", "Hylian Bazaar", "Hylian Bazaar"), + ("0x03", "Brown Cloudy Sky", "Brown Cloudy Sky"), + ("0x04", "Market Ruins", "Market Ruins"), + ("0x05", "Black Cloudy Night", "Black Cloudy Night"), + ("0x07", "Link's House", "Link's House"), + ("0x09", "Market (Main Square, Day)", "Market (Main Square, Day)"), + ("0x0A", "Market (Main Square, Night)", "Market (Main Square, Night)"), + ("0x0B", "Happy Mask Shop", "Happy Mask Shop"), + ("0x0C", "Know-It-All Brothers' House", "Know-It-All Brothers' House"), + ("0x0E", "Kokiri Twins' House", "Kokiri Twins' House"), + ("0x0F", "Stable", "Stable"), + ("0x10", "Stew Lady's House", "Stew Lady's House"), + ("0x11", "Kokiri Shop", "Kokiri Shop"), + ("0x13", "Goron Shop", "Goron Shop"), + ("0x14", "Zora Shop", "Zora Shop"), + ("0x16", "Kakariko Potions Shop", "Kakariko Potions Shop"), + ("0x17", "Hylian Potions Shop", "Hylian Potions Shop"), + ("0x18", "Bomb Shop", "Bomb Shop"), + ("0x1A", "Dog Lady's House", "Dog Lady's House"), + ("0x1B", "Impa's House", "Impa's House"), + ("0x1C", "Gerudo Tent", "Gerudo Tent"), + ("0x1D", "Environment Color", "Environment Color"), + ("0x20", "Mido's House", "Mido's House"), + ("0x21", "Saria's House", "Saria's House"), + ("0x22", "Dog Guy's House", "Dog Guy's House"), +] + +mm_enum_skybox = [ + ("Custom", "Custom", "Custom"), + ("SKYBOX_NONE", "None", "0x00"), + ("SKYBOX_NORMAL_SKY", "Standard Sky", "0x01"), + ("SKYBOX_2", "SKYBOX_2", "0x02"), + ("SKYBOX_3", "SKYBOX_3", "0x03"), + ("SKYBOX_CUTSCENE_MAP", "Cutscene Map", "0x05"), +] + +ootEnumCloudiness = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Sunny", "Sunny"), + ("0x01", "Cloudy", "Cloudy"), +] + +mm_enum_skybox_config = [ + ("Custom", "Custom", "Custom"), + ("SKYBOX_CONFIG_0", "SKYBOX_CONFIG_0", "0x00"), + ("SKYBOX_CONFIG_1", "SKYBOX_CONFIG_1", "0x01"), + ("SKYBOX_CONFIG_2", "SKYBOX_CONFIG_2", "0x02"), + ("SKYBOX_CONFIG_3", "SKYBOX_CONFIG_3", "0x03"), + ("SKYBOX_CONFIG_4", "SKYBOX_CONFIG_4", "0x04"), + ("SKYBOX_CONFIG_5", "SKYBOX_CONFIG_5", "0x05"), + ("SKYBOX_CONFIG_6", "SKYBOX_CONFIG_6", "0x06"), + ("SKYBOX_CONFIG_7", "SKYBOX_CONFIG_7", "0x07"), + ("SKYBOX_CONFIG_8", "SKYBOX_CONFIG_8", "0x08"), + ("SKYBOX_CONFIG_9", "SKYBOX_CONFIG_9", "0x09"), + ("SKYBOX_CONFIG_10", "SKYBOX_CONFIG_10", "0x0A"), + ("SKYBOX_CONFIG_11", "SKYBOX_CONFIG_11", "0x0B"), + ("SKYBOX_CONFIG_12", "SKYBOX_CONFIG_12", "0x0C"), + ("SKYBOX_CONFIG_13", "SKYBOX_CONFIG_13", "0x0D"), + ("SKYBOX_CONFIG_14", "SKYBOX_CONFIG_14", "0x0E"), + ("SKYBOX_CONFIG_15", "SKYBOX_CONFIG_15", "0x0F"), + ("SKYBOX_CONFIG_16", "SKYBOX_CONFIG_16", "0x10"), + ("SKYBOX_CONFIG_17", "SKYBOX_CONFIG_17", "0x11"), + ("SKYBOX_CONFIG_18", "SKYBOX_CONFIG_18", "0x12"), + ("SKYBOX_CONFIG_19", "SKYBOX_CONFIG_19", "0x13"), + ("SKYBOX_CONFIG_20", "SKYBOX_CONFIG_20", "0x14"), + ("SKYBOX_CONFIG_21", "SKYBOX_CONFIG_21", "0x15"), + ("SKYBOX_CONFIG_22", "SKYBOX_CONFIG_22", "0x16"), + ("SKYBOX_CONFIG_23", "SKYBOX_CONFIG_23", "0x17"), + ("SKYBOX_CONFIG_24", "SKYBOX_CONFIG_24", "0x18"), + ("SKYBOX_CONFIG_25", "SKYBOX_CONFIG_25", "0x19"), + ("SKYBOX_CONFIG_26", "SKYBOX_CONFIG_26", "0x1A"), + ("SKYBOX_CONFIG_27", "SKYBOX_CONFIG_27", "0x1B"), +] + +ootEnumLinkIdle = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "Default"), + ("0x01", "Sneezing", "Sneezing"), + ("0x02", "Wiping Forehead", "Wiping Forehead"), + ("0x04", "Yawning", "Yawning"), + ("0x07", "Gasping For Breath", "Gasping For Breath"), + ("0x09", "Brandish Sword", "Brandish Sword"), + ("0x0A", "Adjust Tunic", "Adjust Tunic"), + ("0xFF", "Hops On Epona", "Hops On Epona"), +] + +mm_enum_environment_type = [ + ("Custom", "Custom", "Custom"), + ("ROOM_ENV_DEFAULT", "Default", "0x00"), + ("ROOM_ENV_COLD", "Cold", "0x01"), + ("ROOM_ENV_WARM", "Warm", "0x02"), + ("ROOM_ENV_HOT", "Hot", "0x03"), + ("ROOM_ENV_UNK_STRETCH_1", "Unknown Stretch 1", "0x04"), + ("ROOM_ENV_UNK_STRETCH_2", "Unknown Stretch 2", "0x05"), + ("ROOM_ENV_UNK_STRETCH_3", "Unknown Stretch 3", "0x06"), +] + +# see RoomType enum +ootEnumRoomBehaviour = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "Default"), + ("0x01", "Dungeon Behavior (Z-Target, Sun's Song)", "Dungeon Behavior (Z-Target, Sun's Song)"), + ("0x02", "Disable Backflips/Sidehops", "Disable Backflips/Sidehops"), + ("0x03", "Disable Color Dither", "Disable Color Dither"), + ("0x04", "(?) Horse Camera Related", "(?) Horse Camera Related"), + ("0x05", "Disable Darker Screen Effect (NL/Spins)", "Disable Darker Screen Effect (NL/Spins)"), +] + +mm_enum_room_type = [ + ("Custom", "Custom", "Custom"), + ("ROOM_TYPE_NORMAL", "Normal", "0x00"), + ("ROOM_TYPE_DUNGEON", "Dungeon", "0x01"), + ("ROOM_TYPE_INDOORS", "Indoors", "0x02"), + ("ROOM_TYPE_3", "Type 3", "0x03"), + ("ROOM_TYPE_4", "Type 4 (Horse related)", "0x04"), + ("ROOM_TYPE_BOSS", "Boss", "0x05"), +] + +# --- + @dataclass class Z64_Data: """Contains data related to OoT, like actors or objects""" @@ -341,10 +483,19 @@ def __init__(self, game: str): self.objectData = Z64_ObjectData(game) self.actorData = Z64_ActorData(game) - # `EnumProperty` requires fixed values if game == "OOT": self.ootEnumMusicSeq = ootEnumMusicSeq self.ootEnumNightSeq = ootEnumNightSeq + self.ootEnumGlobalObject = ootEnumGlobalObject + self.ootEnumSkybox = ootEnumSkybox + self.ootEnumCloudiness = ootEnumCloudiness + self.ootEnumLinkIdle = ootEnumLinkIdle + self.ootEnumRoomBehaviour = ootEnumRoomBehaviour else: self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id + self.ootEnumGlobalObject = mm_enum_global_object + self.ootEnumSkybox = mm_enum_skybox + self.ootEnumCloudiness = mm_enum_skybox_config + self.ootEnumLinkIdle = mm_enum_environment_type + self.ootEnumRoomBehaviour = mm_enum_room_type diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 3056e0f22..778c82f26 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -4,6 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from ...utility import PluginError, prop_split, label_split, get_prop_annotations +from ...constants import game_data from ..constants import oot_data, ootEnumCamTransition, mm_data from ..upgrade import upgradeActors from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -25,7 +26,6 @@ get_cs_index_start, is_oot_features, is_game_oot, - get_game_enum, get_list_tab_text, getEvalParams, getEvalParamsInt, @@ -508,7 +508,7 @@ def draw_props( return split.label(text="Actor ID") - split.label(text=getEnumName(get_game_enum("enum_actor_id"), actor_id)) + split.label(text=getEnumName(game_data.z64.actorData.ootEnumActorID, actor_id)) if self.actor_id != "Custom": self.draw_params(actorIDBox, owner) @@ -609,7 +609,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") actor_id = getattr(self.actor, get_game_prop_name("actor_id")) - split.label(text=getEnumName(get_game_enum("enum_actor_id"), actor_id)) + split.label(text=getEnumName(game_data.z64.actorData.ootEnumActorID, actor_id)) if self.actor.actor_id == "Custom": prop_split(actorIDBox, self.actor, "actor_id_custom", "") diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index fddae8bd9..b5e42cdca 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -16,66 +16,9 @@ ("Child Day", "Child Day", "Child Day"), ] + ootEnumHeaderMenu -ootEnumLinkIdle = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "Default"), - ("0x01", "Sneezing", "Sneezing"), - ("0x02", "Wiping Forehead", "Wiping Forehead"), - ("0x04", "Yawning", "Yawning"), - ("0x07", "Gasping For Breath", "Gasping For Breath"), - ("0x09", "Brandish Sword", "Brandish Sword"), - ("0x0A", "Adjust Tunic", "Adjust Tunic"), - ("0xFF", "Hops On Epona", "Hops On Epona"), -] -mm_enum_environment_type = [ - ("Custom", "Custom", "Custom"), - ("ROOM_ENV_DEFAULT", "Default", "0x00"), - ("ROOM_ENV_COLD", "Cold", "0x01"), - ("ROOM_ENV_WARM", "Warm", "0x02"), - ("ROOM_ENV_HOT", "Hot", "0x03"), - ("ROOM_ENV_UNK_STRETCH_1", "Unknown Stretch 1", "0x04"), - ("ROOM_ENV_UNK_STRETCH_2", "Unknown Stretch 2", "0x05"), - ("ROOM_ENV_UNK_STRETCH_3", "Unknown Stretch 3", "0x06"), -] -ootEnumCloudiness = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Sunny", "Sunny"), - ("0x01", "Cloudy", "Cloudy"), -] -mm_enum_skybox_config = [ - ("Custom", "Custom", "Custom"), - ("SKYBOX_CONFIG_0", "SKYBOX_CONFIG_0", "0x00"), - ("SKYBOX_CONFIG_1", "SKYBOX_CONFIG_1", "0x01"), - ("SKYBOX_CONFIG_2", "SKYBOX_CONFIG_2", "0x02"), - ("SKYBOX_CONFIG_3", "SKYBOX_CONFIG_3", "0x03"), - ("SKYBOX_CONFIG_4", "SKYBOX_CONFIG_4", "0x04"), - ("SKYBOX_CONFIG_5", "SKYBOX_CONFIG_5", "0x05"), - ("SKYBOX_CONFIG_6", "SKYBOX_CONFIG_6", "0x06"), - ("SKYBOX_CONFIG_7", "SKYBOX_CONFIG_7", "0x07"), - ("SKYBOX_CONFIG_8", "SKYBOX_CONFIG_8", "0x08"), - ("SKYBOX_CONFIG_9", "SKYBOX_CONFIG_9", "0x09"), - ("SKYBOX_CONFIG_10", "SKYBOX_CONFIG_10", "0x0A"), - ("SKYBOX_CONFIG_11", "SKYBOX_CONFIG_11", "0x0B"), - ("SKYBOX_CONFIG_12", "SKYBOX_CONFIG_12", "0x0C"), - ("SKYBOX_CONFIG_13", "SKYBOX_CONFIG_13", "0x0D"), - ("SKYBOX_CONFIG_14", "SKYBOX_CONFIG_14", "0x0E"), - ("SKYBOX_CONFIG_15", "SKYBOX_CONFIG_15", "0x0F"), - ("SKYBOX_CONFIG_16", "SKYBOX_CONFIG_16", "0x10"), - ("SKYBOX_CONFIG_17", "SKYBOX_CONFIG_17", "0x11"), - ("SKYBOX_CONFIG_18", "SKYBOX_CONFIG_18", "0x12"), - ("SKYBOX_CONFIG_19", "SKYBOX_CONFIG_19", "0x13"), - ("SKYBOX_CONFIG_20", "SKYBOX_CONFIG_20", "0x14"), - ("SKYBOX_CONFIG_21", "SKYBOX_CONFIG_21", "0x15"), - ("SKYBOX_CONFIG_22", "SKYBOX_CONFIG_22", "0x16"), - ("SKYBOX_CONFIG_23", "SKYBOX_CONFIG_23", "0x17"), - ("SKYBOX_CONFIG_24", "SKYBOX_CONFIG_24", "0x18"), - ("SKYBOX_CONFIG_25", "SKYBOX_CONFIG_25", "0x19"), - ("SKYBOX_CONFIG_26", "SKYBOX_CONFIG_26", "0x1A"), - ("SKYBOX_CONFIG_27", "SKYBOX_CONFIG_27", "0x1B"), -] ootEnumCameraMode = [ ("Custom", "Custom", "Custom"), @@ -114,46 +57,6 @@ ("0x16", "Grottos & Fairy Fountains", "Grottos & Fairy Fountains"), ] -ootEnumSkybox = [ - ("Custom", "Custom", "Custom"), - ("0x00", "None", "None"), - ("0x01", "Standard Sky", "Standard Sky"), - ("0x02", "Hylian Bazaar", "Hylian Bazaar"), - ("0x03", "Brown Cloudy Sky", "Brown Cloudy Sky"), - ("0x04", "Market Ruins", "Market Ruins"), - ("0x05", "Black Cloudy Night", "Black Cloudy Night"), - ("0x07", "Link's House", "Link's House"), - ("0x09", "Market (Main Square, Day)", "Market (Main Square, Day)"), - ("0x0A", "Market (Main Square, Night)", "Market (Main Square, Night)"), - ("0x0B", "Happy Mask Shop", "Happy Mask Shop"), - ("0x0C", "Know-It-All Brothers' House", "Know-It-All Brothers' House"), - ("0x0E", "Kokiri Twins' House", "Kokiri Twins' House"), - ("0x0F", "Stable", "Stable"), - ("0x10", "Stew Lady's House", "Stew Lady's House"), - ("0x11", "Kokiri Shop", "Kokiri Shop"), - ("0x13", "Goron Shop", "Goron Shop"), - ("0x14", "Zora Shop", "Zora Shop"), - ("0x16", "Kakariko Potions Shop", "Kakariko Potions Shop"), - ("0x17", "Hylian Potions Shop", "Hylian Potions Shop"), - ("0x18", "Bomb Shop", "Bomb Shop"), - ("0x1A", "Dog Lady's House", "Dog Lady's House"), - ("0x1B", "Impa's House", "Impa's House"), - ("0x1C", "Gerudo Tent", "Gerudo Tent"), - ("0x1D", "Environment Color", "Environment Color"), - ("0x20", "Mido's House", "Mido's House"), - ("0x21", "Saria's House", "Saria's House"), - ("0x22", "Dog Guy's House", "Dog Guy's House"), -] - -mm_enum_skybox = [ - ("Custom", "Custom", "Custom"), - ("SKYBOX_NONE", "None", "0x00"), - ("SKYBOX_NORMAL_SKY", "Standard Sky", "0x01"), - ("SKYBOX_2", "SKYBOX_2", "0x02"), - ("SKYBOX_3", "SKYBOX_3", "0x03"), - ("SKYBOX_CUTSCENE_MAP", "Cutscene Map", "0x05"), -] - ootEnumSkyboxLighting = [ # see ``LightMode`` enum in ``z64environment.h`` ("Custom", "Custom", "Custom"), @@ -166,19 +69,6 @@ ("0x00", "0x00", "0x00"), ] -ootEnumGlobalObject = [ - ("Custom", "Custom", "Custom"), - ("OBJECT_INVALID", "None", "None"), - ("OBJECT_GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), - ("OBJECT_GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), -] - -mm_enum_global_object = [ - ("Custom", "Custom", "Custom"), - ("GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), - ("GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), -] - ootEnumNaviHints = [ ("Custom", "Custom", "Custom"), ("NAVI_QUEST_HINTS_NONE", "None", "None"), @@ -643,27 +533,6 @@ # ("0xFF", "0xFF", "0xFF"), ] -# see RoomType enum -ootEnumRoomBehaviour = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "Default"), - ("0x01", "Dungeon Behavior (Z-Target, Sun's Song)", "Dungeon Behavior (Z-Target, Sun's Song)"), - ("0x02", "Disable Backflips/Sidehops", "Disable Backflips/Sidehops"), - ("0x03", "Disable Color Dither", "Disable Color Dither"), - ("0x04", "(?) Horse Camera Related", "(?) Horse Camera Related"), - ("0x05", "Disable Darker Screen Effect (NL/Spins)", "Disable Darker Screen Effect (NL/Spins)"), -] - -mm_enum_room_type = [ - ("Custom", "Custom", "Custom"), - ("ROOM_TYPE_NORMAL", "Normal", "0x00"), - ("ROOM_TYPE_DUNGEON", "Dungeon", "0x01"), - ("ROOM_TYPE_INDOORS", "Indoors", "0x02"), - ("ROOM_TYPE_3", "Type 3", "0x03"), - ("ROOM_TYPE_4", "Type 4 (Horse related)", "0x04"), - ("ROOM_TYPE_BOSS", "Boss", "0x05"), -] - ootEnumDrawConfig = [ ("Custom", "Custom", "Custom"), ("SDC_DEFAULT", "Default", "Default"), diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 027ac90b1..99be9b8cc 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,8 +3,9 @@ from bpy.types import Object from ...utility import parentObject, hexOrDecInt +from ...constants import game_data from ..scene.properties import Z64_SceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_enum, get_game_prop_name +from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_prop_name from ..constants import ( ootEnumCamTransition, halfday_bits_all_dawns, @@ -96,7 +97,7 @@ def parseTransActorList( actorProp = transActorProp.actor setCustomProperty( - actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actorIDCustom" + actorProp, get_game_prop_name("actor_id"), actorID, game_data.z64.actorData.ootEnumActorID, "actorIDCustom" ) if actorProp.actor_id != "Custom": actorProp.params = actorParam @@ -201,7 +202,7 @@ def parseSpawnList( spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor setCustomProperty( - actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actor_id_custom" + actorProp, get_game_prop_name("actor_id"), actorID, game_data.z64.actorData.ootEnumActorID, "actor_id_custom" ) if actorProp.actor_id != "Custom": actorProp.params = actorParam @@ -273,7 +274,7 @@ def parseActorList( actorObj.name = getDisplayNameFromActorID(actorID) actorProp = actorObj.ootActorProperty setCustomProperty( - actorProp, get_game_prop_name("actor_id"), actorID, get_game_enum("enum_actor_id"), "actor_id_custom" + actorProp, get_game_prop_name("actor_id"), actorID, game_data.z64.actorData.ootEnumActorID, "actor_id_custom" ) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 4ee0fa088..d4fab15e7 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,10 +2,10 @@ import re from ...utility import hexOrDecInt +from ...constants import game_data from ..utility import ( setCustomProperty, is_game_oot, - get_game_enum, get_cs_index_start, get_game_prop_name, ) @@ -85,14 +85,14 @@ def parseRoomCommands( roomHeader, get_game_prop_name("room_type"), args[0], - get_game_enum("enum_room_type"), + game_data.z64.ootEnumRoomBehaviour, "roomBehaviourCustom", ) setCustomProperty( roomHeader, get_game_prop_name("environment_type"), args[1], - get_game_enum("enum_env_type"), + game_data.z64.ootEnumLinkIdle, "linkIdleModeCustom", ) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 1e4797913..870098136 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -6,6 +6,7 @@ from bpy.types import Object from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse +from ...constants import game_data from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext from ..scene.properties import Z64_SceneHeaderProperty, Z64_LightProperty @@ -14,7 +15,6 @@ from ..utility import ( getEvalParams, setCustomProperty, - get_game_enum, is_game_oot, get_cs_index_start, get_game_prop_name, @@ -546,7 +546,7 @@ def parseSceneCommands( sceneHeader, get_game_prop_name("ambience_id"), args[1], - get_game_enum("enum_ambiance_id"), + game_data.z64.ootEnumNightSeq, "nightSeqCustom", ) @@ -561,7 +561,7 @@ def parseSceneCommands( enum_id = enum_seq_id.item_by_index[int(args[2])].id setCustomProperty( - sceneHeader, get_game_prop_name("seq_id"), enum_id, get_game_enum("enum_seq_id"), "musicSeqCustom" + sceneHeader, get_game_prop_name("seq_id"), enum_id, game_data.z64.ootEnumMusicSeq, "musicSeqCustom" ) command_list.remove(command) elif command == "SCENE_CMD_ROOM_LIST": @@ -593,7 +593,7 @@ def parseSceneCommands( sceneHeader, get_game_prop_name("global_obj"), args[1], - get_game_enum("enum_global_object"), + game_data.z64.ootEnumGlobalObject, "globalObjectCustom", ) command_list.remove(command) @@ -616,14 +616,14 @@ def parseSceneCommands( sceneHeader, get_game_prop_name("skybox_id"), args[args_index], - get_game_enum("enum_skybox"), + game_data.z64.ootEnumSkybox, "skyboxIDCustom", ) setCustomProperty( sceneHeader, get_game_prop_name("skybox_config"), args[args_index + 1], - get_game_enum("enum_skybox_config"), + game_data.z64.ootEnumCloudiness, "skyboxCloudinessCustom", ) setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 31b28c787..e00269687 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -12,23 +12,6 @@ from .constants import ( ootSceneIDToName, mm_scene_id_to_name, - oot_data, - mm_data, - ootEnumAudioSessionPreset, - ootEnumCameraMode, - ootEnumMapLocation, - ootEnumNaviHints, - ootEnumGlobalObject, - mm_enum_global_object, - ootEnumSkybox, - mm_enum_skybox, - ootEnumCloudiness, - mm_enum_skybox_config, - ootEnumSkyboxLighting, - ootEnumLinkIdle, - ootEnumRoomBehaviour, - mm_enum_room_type, - mm_enum_environment_type, ) from dataclasses import dataclass @@ -51,33 +34,6 @@ from .actor.properties import OOTActorProperty -def get_game_enum(enum_type: str): - game_enum_map = { - "OOT": { - "enum_global_object": ootEnumGlobalObject, - "enum_skybox": ootEnumSkybox, - "enum_skybox_config": ootEnumCloudiness, - "enum_seq_id": oot_data.ootEnumMusicSeq, - "enum_ambiance_id": oot_data.ootEnumNightSeq, # TODO: generate this from xml (not for enumproperties) - "enum_env_type": ootEnumLinkIdle, - "enum_room_type": ootEnumRoomBehaviour, - "enum_actor_id": oot_data.actorData.ootEnumActorID, - }, - "MM": { - "enum_global_object": mm_enum_global_object, - "enum_skybox": mm_enum_skybox, - "enum_skybox_config": mm_enum_skybox_config, - "enum_seq_id": mm_data.enum_seq_id, - "enum_ambiance_id": mm_data.enum_ambiance_id, # TODO: same as above - "enum_env_type": mm_enum_environment_type, - "enum_room_type": mm_enum_room_type, - "enum_actor_id": mm_data.actor_data.enum_actor_id, - }, - } - - return game_enum_map[bpy.context.scene.gameEditorMode][enum_type] - - def get_game_prop_name(prop_type: str): game_prop_name_map = { "OOT": { From fe94c9d3d954f85b90d42d3e8ebbdccef3a08e91 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:43:17 +0100 Subject: [PATCH 059/126] remove oot_data --- fast64_internal/data/z64/data.py | 2 + fast64_internal/z64/actor/operators.py | 8 ++-- fast64_internal/z64/actor/properties.py | 38 ++++++++++--------- fast64_internal/z64/constants.py | 3 -- fast64_internal/z64/cutscene/classes.py | 10 ++--- fast64_internal/z64/cutscene/constants.py | 4 +- .../z64/cutscene/exporter/classes.py | 8 ++-- .../z64/cutscene/motion/operators.py | 4 +- .../z64/cutscene/motion/properties.py | 6 +-- fast64_internal/z64/cutscene/operators.py | 6 +-- fast64_internal/z64/cutscene/properties.py | 18 ++++----- .../z64/exporter/cutscene/actor_cue.py | 4 +- .../z64/exporter/cutscene/common.py | 4 +- fast64_internal/z64/exporter/cutscene/data.py | 8 ++-- fast64_internal/z64/exporter/room/header.py | 7 ++-- fast64_internal/z64/exporter/scene/actors.py | 6 +-- fast64_internal/z64/importer/actor.py | 18 +++++++-- fast64_internal/z64/importer/room_header.py | 3 +- fast64_internal/z64/importer/scene_header.py | 11 +----- fast64_internal/z64/object.py | 6 +-- fast64_internal/z64/room/operators.py | 4 +- fast64_internal/z64/room/properties.py | 19 ++++------ fast64_internal/z64/scene/operators.py | 5 ++- fast64_internal/z64/scene/properties.py | 21 ++++------ fast64_internal/z64/upgrade.py | 20 +++++----- 25 files changed, 120 insertions(+), 123 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index b6e74bd06..74c3da05a 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -8,6 +8,7 @@ class Z64_BaseElement: name: str index: int + # --- # TODO: get this from XML @@ -470,6 +471,7 @@ class Z64_BaseElement: # --- + @dataclass class Z64_Data: """Contains data related to OoT, like actors or objects""" diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 67cb6993c..90fe7b449 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -3,7 +3,7 @@ from bpy.props import EnumProperty, StringProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError -from ..constants import oot_data, mm_data +from ...constants import game_data class OOT_SearchChestContentEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_property = "chest_content" bl_options = {"REGISTER", "UNDO"} - chest_content: EnumProperty(items=oot_data.actorData.ootEnumChestContent, default="item_heart") + chest_content: EnumProperty(items=game_data.z64.actorData.ootEnumChestContent, default="item_heart") obj_name: StringProperty() prop_name: StringProperty() @@ -58,7 +58,7 @@ class OOT_SearchNaviMsgIDEnumOperator(Operator): bl_property = "navi_msg_id" bl_options = {"REGISTER", "UNDO"} - navi_msg_id: EnumProperty(items=oot_data.actorData.ootEnumNaviMessageData, default="msg_00") + navi_msg_id: EnumProperty(items=game_data.z64.actorData.ootEnumNaviMessageData, default="msg_00") obj_name: StringProperty() prop_name: StringProperty() @@ -79,7 +79,7 @@ class OOT_SearchActorIDEnumOperator(Operator): bl_property = "actor_id" bl_options = {"REGISTER", "UNDO"} - actor_id: EnumProperty(items=lambda self, context: oot_data.actorData.getItems(self.actor_user)) + actor_id: EnumProperty(items=lambda self, context: game_data.z64.actorData.getItems(self.actor_user)) actor_user: StringProperty(default="Actor") obj_name: StringProperty() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 778c82f26..2db6affd9 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -5,7 +5,7 @@ from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from ...utility import PluginError, prop_split, label_split, get_prop_annotations from ...constants import game_data -from ..constants import oot_data, ootEnumCamTransition, mm_data +from ..constants import ootEnumCamTransition from ..upgrade import upgradeActors from ..scene.properties import Z64_AlternateSceneHeaderProperty from ..room.properties import Z64_AlternateRoomHeaderProperty @@ -78,16 +78,18 @@ def initOOTActorProperties(): """This function is used to edit the Z64_ActorProperty class""" prop_ats = get_prop_annotations(Z64_ActorProperty) - prop_ats["actor_id"] = EnumProperty(name="Actor", items=oot_data.actorData.ootEnumActorID, default="ACTOR_PLAYER") + prop_ats["actor_id"] = EnumProperty( + name="Actor", items=game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER" + ) prop_ats["mm_actor_id"] = EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") param_type_to_enum_items = { - "ChestContent": oot_data.actorData.ootEnumChestContent, - "Collectible": oot_data.actorData.ootEnumCollectibleItems, - "Message": oot_data.actorData.ootEnumNaviMessageData, + "ChestContent": game_data.z64.actorData.ootEnumChestContent, + "Collectible": game_data.z64.actorData.ootEnumCollectibleItems, + "Message": game_data.z64.actorData.ootEnumNaviMessageData, } - for actor in oot_data.actorData.actorList: + for actor in game_data.z64.actorData.actorList: for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) enum_items = None @@ -301,7 +303,7 @@ def upgrade_object(obj: Object): upgradeActors(obj) def is_rotation_used(self, target: str): - actor = oot_data.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: if param.type == "Type": @@ -324,7 +326,7 @@ def is_value_in_range(self, value: int, min: int, max: int): return True def set_param_value(self, base_value: str | bool, target: str): - actor = oot_data.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] base_value = getEvalParamsInt(base_value) found_type = None for param in actor.params: @@ -343,11 +345,11 @@ def set_param_value(self, base_value: str | bool, target: str): if is_in_range and (found_type_in_tied_types or len(param.tiedTypes) == 0): prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) if param.type == "ChestContent": - prop_value = oot_data.actorData.chestItemByValue[value].key + prop_value = game_data.z64.actorData.chestItemByValue[value].key elif param.type == "Collectible": - prop_value = oot_data.actorData.collectibleItemsByValue[value].key + prop_value = game_data.z64.actorData.collectibleItemsByValue[value].key elif param.type == "Message": - prop_value = oot_data.actorData.messageItemsByValue[value].key + prop_value = game_data.z64.actorData.messageItemsByValue[value].key elif param.type == "Bool": prop_value = bool(value) else: @@ -364,7 +366,7 @@ def set_param_value(self, base_value: str | bool, target: str): ) def get_param_value(self, target: str): - actor = oot_data.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] param_list = [] type_value = None have_custom_value = False @@ -395,11 +397,11 @@ def get_param_value(self, target: str): else: param_val = 0 if param.type == "ChestContent": - param_val = oot_data.actorData.chestItemByKey[cur_prop_value].value + param_val = game_data.z64.actorData.chestItemByKey[cur_prop_value].value elif param.type == "Collectible": - param_val = oot_data.actorData.collectibleItemsByKey[cur_prop_value].value + param_val = game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value elif param.type == "Message": - param_val = oot_data.actorData.messageItemsByKey[cur_prop_value].value + param_val = game_data.z64.actorData.messageItemsByKey[cur_prop_value].value if "Rot" in target: type_value = getEvalParamsInt(getattr(self, get_prop_name(actor.key, "Type", None, 1))) if type_value is not None and type_value in param.tiedTypes or len(param.tiedTypes) == 0: @@ -441,7 +443,7 @@ def get_param_value(self, target: str): return param_str def draw_params(self, layout: UILayout, obj: Object): - actor = oot_data.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) @@ -460,11 +462,11 @@ def draw_params(self, layout: UILayout, obj: Object): if param.type == "ChestContent": search_op = layout.operator(OOT_SearchChestContentEnumOperator.bl_idname) label_name = "Chest Content" - item_map = oot_data.actorData.chestItemByKey + item_map = game_data.z64.actorData.chestItemByKey else: search_op = layout.operator(OOT_SearchNaviMsgIDEnumOperator.bl_idname) label_name = "Navi Message ID" - item_map = oot_data.actorData.messageItemsByKey + item_map = game_data.z64.actorData.messageItemsByKey search_op.obj_name = obj.name search_op.prop_name = prop_name if key != "Custom": diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index b5e42cdca..a06dc2060 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -17,9 +17,6 @@ ] + ootEnumHeaderMenu - - - ootEnumCameraMode = [ ("Custom", "Custom", "Custom"), ("0x00", "Default", "Default"), diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 278db12bc..1b487ac97 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -3,8 +3,8 @@ from dataclasses import dataclass, field from bpy.types import Object from typing import Optional +from ...constants import game_data from ..utility import is_oot_features, is_game_oot -from ..constants import oot_data, mm_data from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger @@ -44,7 +44,7 @@ def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): # remove `cs` and lowercase first letter enumKey = enumKey[2].lower() + enumKey[3:] - enum = oot_data.enumData.enumByKey[enumKey] if is_game_oot() else mm_data.enum_data.enum_by_key[enumKey] + enum = game_data.z64.enumData.enumByKey[enumKey] if is_game_oot() else mm_data.enum_data.enum_by_key[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -197,7 +197,7 @@ def __post_init__(self): self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: if is_game_oot(): - self.commandType = oot_data.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key + self.commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key else: self.commandType = mm_data.enum_data.enum_by_key["cmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -847,7 +847,7 @@ def getNewCutsceneObject(self, name: str, frameCount: int, parentObj: Object): def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Object): newActorCueListObj = self.getNewEmptyObject(name, False, parentObj) newActorCueListObj.ootEmptyType = f"CS {'Player' if 'Player' in name else 'Actor'} Cue List" - cmdEnum = oot_data.enumData.enumByKey["csCmd"] + cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] if commandType == "Player": commandType = "player_cue" @@ -888,7 +888,7 @@ def getNewActorCueObject( item = None if isPlayer: - playerEnum = oot_data.enumData.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] if isinstance(actionID, int): item = playerEnum.item_by_index.get(actionID) else: diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 7e2e4e1b7..2a4ba176b 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -1,4 +1,4 @@ -from ..constants import oot_data +from ...constants import game_data from .classes import ( CutsceneCmdActorCueList, CutsceneCmdActorCue, @@ -141,7 +141,7 @@ ] ootEnumCSActorCueListCommandType = [ - item for item in oot_data.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] + item for item in game_data.z64.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] ] ootEnumCSActorCueListCommandType.sort() ootEnumCSActorCueListCommandType.insert(0, ("Custom", "Custom", "Custom")) diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index a0c7215f7..9bc4bc954 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object from ....utility import PluginError, indent -from ...constants import oot_data +from ....constants import game_data from ..constants import ootEnumCSListTypeListC if TYPE_CHECKING: @@ -40,7 +40,7 @@ class CutsceneCmdToC: """This class contains functions to create the cutscene commands""" def getEnumValue(self, enumKey: str, owner, propName: str): - item = oot_data.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def getGenericListCmd(self, cmdName: str, entryTotal: int): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = oot_data.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = oot_data.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index f01d4e5a8..dcd78639f 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty from ....utility import PluginError -from ...constants import oot_data +from ....constants import game_data from ..classes import CutsceneObjectFactory from ..constants import ootEnumCSActorCueListCommandType from ..preview import initFirstFrame, setupCompositorNodes @@ -318,7 +318,7 @@ class OOT_SearchPlayerCueIdEnumOperator(Operator): bl_property = "playerCueID" bl_options = {"REGISTER", "UNDO"} - playerCueID: EnumProperty(items=oot_data.enumData.ootEnumCsPlayerCueId, default="cueid_none") + playerCueID: EnumProperty(items=game_data.z64.enumData.ootEnumCsPlayerCueId, default="cueid_none") objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 80758099b..5e0ef3f99 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...upgrade import upgradeCutsceneMotion from ...utility import getEnumName -from ...constants import oot_data +from ....constants import game_data from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType from .operators import ( @@ -86,7 +86,7 @@ class CutsceneCmdActorCueProperty(PropertyGroup): get=lambda self: getNextCuesStartFrame(self), ) - playerCueID: EnumProperty(items=oot_data.enumData.ootEnumCsPlayerCueId, default="cueid_none") + playerCueID: EnumProperty(items=game_data.z64.enumData.ootEnumCsPlayerCueId, default="cueid_none") cueActionID: StringProperty( name="Action ID", default="0x0001", description="Actor action. Meaning is unique for each different actor." ) @@ -116,7 +116,7 @@ def draw_props(self, layout: UILayout, labelPrefix: str, isDummy: bool, objName: split = box.split(factor=0.5) searchOp = split.operator(OOT_SearchPlayerCueIdEnumOperator.bl_idname, icon="VIEWZOOM", text=label) searchOp.objName = objName - split.label(text=getEnumName(oot_data.enumData.ootEnumCsPlayerCueId, self.playerCueID)) + split.label(text=getEnumName(game_data.z64.enumData.ootEnumCsPlayerCueId, self.playerCueID)) if not isPlayer or self.playerCueID == "Custom": split = box.split(factor=0.5) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index c5719ab2c..904b077a0 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -9,7 +9,7 @@ from bpy.utils import register_class, unregister_class from ...utility import CData, PluginError, writeCData, raisePluginError from ..utility import getCollection -from ..constants import oot_data +from ...constants import game_data from .constants import ootEnumCSTextboxType, ootEnumCSListType from .importer import importCutsceneData from .exporter import getNewCutsceneExport @@ -238,7 +238,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty(items=oot_data.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse") + csDestination: EnumProperty(items=game_data.z64.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse") objName: StringProperty() def execute(self, context): @@ -260,7 +260,7 @@ class OOT_SearchCSSeqOperator(Operator): bl_property = "seqId" bl_options = {"REGISTER", "UNDO"} - seqId: EnumProperty(items=oot_data.enumData.ootEnumSeqId, default="general_sfx") + seqId: EnumProperty(items=game_data.z64.enumData.ootEnumSeqId, default="general_sfx") itemIndex: IntProperty() listType: StringProperty() diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index e2b6f902e..dc9f03367 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName -from ..constants import oot_data +from ...constants import game_data from ..upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty from .operators import OOTCSTextAdd, OOT_SearchCSDestinationEnumOperator, OOTCSListAdd, OOT_SearchCSSeqOperator from .motion.preview import previewFrameHandler @@ -113,13 +113,13 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): # subprops textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( - name="Ocarina Action", items=oot_data.enumData.ootEnumOcarinaSongActionId, default="teach_minuet" + name="Ocarina Action", items=game_data.z64.enumData.ootEnumOcarinaSongActionId, default="teach_minuet" ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") topOptionTextID: StringProperty(name="", default="0x0000") bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") - csTextType: EnumProperty(name="Text Type", items=oot_data.enumData.ootEnumCsTextType, default="normal") + csTextType: EnumProperty(name="Text Type", items=game_data.z64.enumData.ootEnumCsTextType, default="normal") csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") def getName(self): @@ -152,10 +152,10 @@ class OOTCSTimeProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] - csSeqID: EnumProperty(name="Seq ID", items=oot_data.enumData.ootEnumSeqId, default="general_sfx") + csSeqID: EnumProperty(name="Seq ID", items=game_data.z64.enumData.ootEnumSeqId, default="general_sfx") csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") csSeqPlayer: EnumProperty( - name="Seq Player", items=oot_data.enumData.ootEnumCsFadeOutSeqPlayer, default="fade_out_fanfare" + name="Seq Player", items=game_data.z64.enumData.ootEnumCsFadeOutSeqPlayer, default="fade_out_fanfare" ) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") @@ -171,7 +171,7 @@ def filterName(self, name, listProp): class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] - csMiscType: EnumProperty(name="Type", items=oot_data.enumData.ootEnumCsMiscType, default="rain") + csMiscType: EnumProperty(name="Type", items=game_data.z64.enumData.ootEnumCsMiscType, default="rain") csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -197,7 +197,7 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - transitionType: EnumProperty(items=oot_data.enumData.ootEnumCsTransitionType, default="gray_fill_in") + transitionType: EnumProperty(items=game_data.z64.enumData.ootEnumCsTransitionType, default="gray_fill_in") transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) transitionEndFrame: IntProperty(name="", default=1, min=0) @@ -356,7 +356,7 @@ class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") csDestination: EnumProperty( - name="Destination", items=oot_data.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse" + name="Destination", items=game_data.z64.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse" ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) @@ -407,7 +407,7 @@ def draw_props(self, layout: UILayout, obj: Object): boxRow = searchBox.row() searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") searchOp.objName = obj.name - boxRow.label(text=getEnumName(oot_data.enumData.ootEnumCsDestination, self.csDestination)) + boxRow.label(text=getEnumName(game_data.z64.enumData.ootEnumCsDestination, self.csDestination)) if self.csDestination == "Custom": prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index c60c813a0..fc27b6b8c 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field from ....utility import PluginError, indent -from ...constants import oot_data +from ....constants import game_data from ...cutscene.motion.utility import getRotation, getInteger from .common import CutsceneCmdBase @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = oot_data.enumData.enumByKey["csCmd"].item_by_id[commandType].key + commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index e51039226..fe5146ad8 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional from ....utility import PluginError, indent -from ...constants import oot_data +from ....constants import game_data from ...cutscene.motion.utility import getInteger @@ -20,7 +20,7 @@ def validateFrames(self, checkEndFrame: bool = True): @staticmethod def getEnumValue(enumKey: str, value: str, isSeqLegacy: bool = False): - enum = oot_data.enumData.enumByKey[enumKey] + enum = game_data.z64.enumData.enumByKey[enumKey] item = enum.item_by_id.get(value) if item is None: setting = getInteger(value) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 53d11c468..b752eb7e9 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError -from ...constants import oot_data +from ....constants import game_data from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction @@ -142,7 +142,7 @@ def getOoTPosition(self, pos): return [x, y, z] def getEnumValueFromProp(self, enumKey: str, owner, propName: str): - item = oot_data.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): @@ -169,7 +169,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = oot_data.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +183,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = oot_data.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index a70833cb2..3fb785af6 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -4,7 +4,8 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, getEvalParams, get_game_prop_name, is_game_oot -from ...constants import oot_data, mm_data, halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits +from ....constants import game_data +from ...constants import halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits from ...room.properties import Z64_RoomHeaderProperty from ...actor.properties import Z64_ActorProperty from ..utility import Utility @@ -123,7 +124,7 @@ def new(name: str, props: Optional[Z64_RoomHeaderProperty]): objectList.append(objProp.objectIDCustom) else: objects_by_key = ( - oot_data.objectData.objects_by_key if is_game_oot() else mm_data.object_data.objects_by_key + game_data.z64.objectData.objects_by_key if is_game_oot() else mm_data.object_data.objects_by_key ) objectList.append(objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) @@ -257,7 +258,7 @@ def new( spawn_rot = [f"SPAWN_ROT_FLAGS({r}" for r in rotation] actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) - actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id + actors_by_id = game_data.z64.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id actor.name = ( actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") if actor_id != "Custom" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 31fa01d32..4b2e3ab0e 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, is_game_oot -from ...constants import oot_data, mm_data +from ....constants import game_data from ...actor.properties import Z64_ActorProperty from ..utility import Utility from ..actor import Actor @@ -81,7 +81,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): else: transActor.id = actor_id - actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id + actors_by_id = game_data.z64.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id transActor.name = ( actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") if actor_id != "Custom" @@ -156,7 +156,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) entranceActor = EntranceActor() - actors_by_id = oot_data.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id + actors_by_id = game_data.z64.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id entranceActor.name = ( actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") if actor_id != "Custom" diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 99be9b8cc..510f405df 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -97,7 +97,11 @@ def parseTransActorList( actorProp = transActorProp.actor setCustomProperty( - actorProp, get_game_prop_name("actor_id"), actorID, game_data.z64.actorData.ootEnumActorID, "actorIDCustom" + actorProp, + get_game_prop_name("actor_id"), + actorID, + game_data.z64.actorData.ootEnumActorID, + "actorIDCustom", ) if actorProp.actor_id != "Custom": actorProp.params = actorParam @@ -202,7 +206,11 @@ def parseSpawnList( spawnProp.customActor = actorID != "ACTOR_PLAYER" actorProp = spawnProp.actor setCustomProperty( - actorProp, get_game_prop_name("actor_id"), actorID, game_data.z64.actorData.ootEnumActorID, "actor_id_custom" + actorProp, + get_game_prop_name("actor_id"), + actorID, + game_data.z64.actorData.ootEnumActorID, + "actor_id_custom", ) if actorProp.actor_id != "Custom": actorProp.params = actorParam @@ -274,7 +282,11 @@ def parseActorList( actorObj.name = getDisplayNameFromActorID(actorID) actorProp = actorObj.ootActorProperty setCustomProperty( - actorProp, get_game_prop_name("actor_id"), actorID, game_data.z64.actorData.ootEnumActorID, "actor_id_custom" + actorProp, + get_game_prop_name("actor_id"), + actorID, + game_data.z64.actorData.ootEnumActorID, + "actor_id_custom", ) actorProp.actorParam = actorParam handleActorWithRotAsParam(actorProp, actorID, rotation) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index d4fab15e7..768a279ba 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -11,7 +11,6 @@ ) from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty -from ..constants import oot_data, mm_data from .utility import getDataMatch, stripName from .classes import SharedSceneData from .constants import headerNames @@ -21,7 +20,7 @@ def get_object_from_id(object: str): if is_game_oot(): - return oot_data.objectData.objects_by_id.get(object) + return game_data.z64.objectData.objects_by_id.get(object) else: return mm_data.object_data.objects_by_id.get(object) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 870098136..946547c95 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -31,17 +31,10 @@ from .scene_pathways import parsePathList from ..constants import ( - oot_data, - mm_data, ootEnumAudioSessionPreset, ootEnumCameraMode, ootEnumMapLocation, ootEnumNaviHints, - ootEnumGlobalObject, - mm_enum_global_object, - ootEnumSkybox, - mm_enum_skybox, - ootEnumCloudiness, ootEnumSkyboxLighting, ) @@ -492,7 +485,7 @@ def parse_actor_cs(scene_obj: Object, header_index: int, scene_data: str, list_n def get_enum_id_from_index(enum_key: str, index: int): if is_game_oot(): - return oot_data.enumData.enumByKey[enum_key].item_by_index[index].id + return game_data.z64.enumData.enumByKey[enum_key].item_by_index[index].id else: return mm_data.enum_data.enum_by_key[enum_key].item_by_index[index].id @@ -554,7 +547,7 @@ def parseSceneCommands( enum_id = args[2] else: if is_game_oot(): - enum_seq_id = oot_data.enumData.enumByKey["seqId"] + enum_seq_id = game_data.z64.enumData.enumByKey["seqId"] else: enum_seq_id = mm_data.enum_data.enum_by_key["seqId"] diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index a07205654..caa251fb4 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -1,6 +1,6 @@ from bpy.types import Object from ..utility import ootGetSceneOrRoomHeader -from .constants import oot_data +from ..constants import game_data from .exporter.room.header import RoomHeader @@ -18,11 +18,11 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header """Adds missing objects to the object list""" if len(curHeader.actors.actorList) > 0: for roomActor in curHeader.actors.actorList: - actor = oot_data.actorData.actorsByID.get(roomActor.id) + actor = game_data.z64.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: if objKey not in ["obj_gameplay_keep", "obj_gameplay_field_keep", "obj_gameplay_dangeon_keep"]: - objID = oot_data.objectData.objects_by_key[objKey].id + objID = game_data.z64.objectData.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) addMissingObjectToProp(roomObj, headerIndex, objKey) diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index d0a8b665a..9fc8372d4 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, IntProperty, StringProperty from ...utility import ootGetSceneOrRoomHeader -from ..constants import oot_data, mm_data +from ...constants import game_data class OOT_SearchObjectEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") + objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default="obj_human") headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 90620205f..d66bd99d1 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -2,6 +2,7 @@ from bpy.types import PropertyGroup, UILayout, Image, Object, Context from bpy.utils import register_class, unregister_class from ...utility import prop_split +from ...constants import game_data from ..utility import ( drawCollectionOps, onMenuTabChange, @@ -28,14 +29,8 @@ ) from ..constants import ( - oot_data, - ootEnumRoomBehaviour, - ootEnumLinkIdle, ootEnumRoomShapeType, ootEnumHeaderMenu, - mm_data, - mm_enum_room_type, - mm_enum_environment_type, ) ootEnumRoomMenuAlternate = [ @@ -49,7 +44,7 @@ class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=oot_data.objectData.ootEnumObjectKey, default="obj_human") + objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default="obj_human") mm_object_key: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @@ -57,21 +52,21 @@ class Z64_ObjectProperty(PropertyGroup): def upgrade_object(obj: Object): if is_game_oot(): print(f"Processing '{obj.name}'...") - upgradeRoomHeaders(obj, oot_data.objectData) + upgradeRoomHeaders(obj, game_data.z64.objectData) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): is_legacy = True if "objectID" in self else False obj_key: str = getattr(self, get_game_prop_name("object_key")) if is_game_oot(): - objects_by_key = oot_data.objectData.objects_by_key + objects_by_key = game_data.z64.objectData.objects_by_key op_name = OOT_SearchObjectEnumOperator.bl_idname else: objects_by_key = mm_data.object_data.objects_by_key op_name = MM_SearchObjectEnumOperator.bl_idname if is_game_oot() and is_legacy: - obj_name = oot_data.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + obj_name = game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] elif obj_key != "Custom": obj_name = objects_by_key[obj_key].name else: @@ -118,11 +113,11 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=ootEnumRoomBehaviour, default="0x00") + roomBehaviour: EnumProperty(items=game_data.z64.ootEnumRoomBehaviour, default="0x00") mm_room_type: EnumProperty(items=mm_enum_room_type, default="ROOM_TYPE_NORMAL") roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Environment Type", items=ootEnumLinkIdle, default="0x00") + linkIdleMode: EnumProperty(name="Environment Type", items=game_data.z64.ootEnumLinkIdle, default="0x00") mm_environment_type: EnumProperty( name="Environment Type", items=mm_enum_environment_type, default="ROOM_ENV_DEFAULT" ) diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 2da3b6d8d..bcafd0808 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -10,7 +10,8 @@ from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot -from ..constants import oot_data, mm_data, ootEnumSceneID, mm_enum_scene_id +from ...constants import game_data +from ..constants import ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config from ..exporter import SceneExport, Files @@ -99,7 +100,7 @@ class OOT_SearchMusicSeqEnumOperator(Operator): bl_property = "ootMusicSeq" bl_options = {"REGISTER", "UNDO"} - ootMusicSeq: EnumProperty(items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + ootMusicSeq: EnumProperty(items=game_data.z64.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") headerIndex: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index f80cca579..2b698ec99 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -12,6 +12,7 @@ from bpy.utils import register_class, unregister_class from ...render_settings import on_update_oot_render_settings from ...utility import prop_split, customExportWarning +from ...constants import game_data from ..cutscene.constants import ootEnumCSWriteType from ..utility import ( @@ -27,12 +28,8 @@ ) from ..constants import ( - oot_data, ootEnumSceneID, - ootEnumGlobalObject, ootEnumNaviHints, - ootEnumSkybox, - ootEnumCloudiness, ootEnumSkyboxLighting, ootEnumMapLocation, ootEnumCameraMode, @@ -40,11 +37,7 @@ ootEnumHeaderMenu, ootEnumDrawConfig, ootEnumHeaderMenuComplete, - mm_data, mm_enum_scene_id, - mm_enum_global_object, - mm_enum_skybox, - mm_enum_skybox_config, mm_enum_draw_config, ) @@ -329,7 +322,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty(name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=ootEnumGlobalObject) + globalObject: EnumProperty( + name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=game_data.z64.ootEnumGlobalObject + ) mm_global_obj: EnumProperty(name="Global Object", default="GAMEPLAY_DANGEON_KEEP", items=mm_enum_global_object) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") @@ -338,10 +333,10 @@ class Z64_SceneHeaderProperty(PropertyGroup): naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skyboxID: EnumProperty(name="Skybox", items=ootEnumSkybox, default="0x01") + skyboxID: EnumProperty(name="Skybox", items=game_data.z64.ootEnumSkybox, default="0x01") mm_skybox_id: EnumProperty(name="Skybox", items=mm_enum_skybox, default="SKYBOX_NORMAL_SKY") skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=ootEnumCloudiness, default="0x00") + skyboxCloudiness: EnumProperty(name="Cloudiness", items=game_data.z64.ootEnumCloudiness, default="0x00") mm_skybox_config: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="SKYBOX_CONFIG_0") skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( @@ -358,10 +353,10 @@ class Z64_SceneHeaderProperty(PropertyGroup): skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") # SCENE_CMD_SOUND_SETTINGS - musicSeq: EnumProperty(name="Music Sequence", items=oot_data.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + musicSeq: EnumProperty(name="Music Sequence", items=game_data.z64.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") mm_seq_id: EnumProperty(name="Music Sequence", items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=oot_data.ootEnumNightSeq, default="0x00") + nightSeq: EnumProperty(name="Nighttime SFX", items=game_data.z64.ootEnumNightSeq, default="0x00") mm_ambience_id: EnumProperty(name="Nighttime SFX", items=mm_data.enum_ambiance_id, default="0x00") nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index c30ad7a3c..f055c596d 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,8 +6,8 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from ..data import Z64_ObjectData +from ..constants import game_data from .utility import getEvalParams, get_actor_prop_from_obj -from .constants import oot_data from .cutscene.constants import ootEnumCSMotionCamMode if TYPE_CHECKING: @@ -180,12 +180,12 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox - Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", oot_data.enumData.ootEnumOcarinaSongActionId), - Cutscene_UpgradeData("type", "csTextType", oot_data.enumData.ootEnumCsTextType), + Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", game_data.z64.enumData.ootEnumOcarinaSongActionId), + Cutscene_UpgradeData("type", "csTextType", game_data.z64.enumData.ootEnumCsTextType), # Seq - Cutscene_UpgradeData("value", "csSeqID", oot_data.enumData.ootEnumSeqId), + Cutscene_UpgradeData("value", "csSeqID", game_data.z64.enumData.ootEnumSeqId), # Misc - Cutscene_UpgradeData("operation", "csMiscType", oot_data.enumData.ootEnumCsMiscType), + Cutscene_UpgradeData("operation", "csMiscType", game_data.z64.enumData.ootEnumCsMiscType), ] transferOldDataToNew(csListSubProp, subPropsOldToNew) @@ -210,7 +210,7 @@ def upgradeCSListProps(csListProp): # both are enums but the item list is different (the old one doesn't have a "custom" entry) convertOldDataToEnumData( - csListProp, [Cutscene_UpgradeData("fxType", "transitionType", oot_data.enumData.ootEnumCsTransitionType)] + csListProp, [Cutscene_UpgradeData("fxType", "transitionType", game_data.z64.enumData.ootEnumCsTransitionType)] ) @@ -223,7 +223,7 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): transferOldDataToNew(csProp, csPropOldToNew) convertOldDataToEnumData( - csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", oot_data.enumData.ootEnumCsDestination)] + csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", game_data.z64.enumData.ootEnumCsDestination)] ) @@ -242,7 +242,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): if "actor_id" in legacyData: index = legacyData["actor_id"] if index >= 0: - cmdEnum = oot_data.enumData.enumByKey["csCmd"] + cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] cmdType = cmdEnum.item_by_index.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key @@ -263,7 +263,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): del legacyData["start_frame"] if "action_id" in legacyData: - playerEnum = oot_data.enumData.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] item = None if isPlayer: item = playerEnum.item_by_index.get(int(legacyData["action_id"], base=16)) @@ -315,7 +315,7 @@ def upgradeActors(actorObj: Object): isCustom = actorObj.ootEntranceProperty.customActor else: if "actorID" in actorProp: - actorProp.actor_id = oot_data.actorData.ootEnumActorID[actorProp["actorID"]][0] + actorProp.actor_id = game_data.z64.actorData.ootEnumActorID[actorProp["actorID"]][0] del actorProp["actorID"] if "actorIDCustom" in actorProp: From e38bddbef3f5922e55687baa81d871028fd1fb42 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:51:19 +0100 Subject: [PATCH 060/126] remove mm_data --- fast64_internal/z64/actor/operators.py | 26 ----------------- fast64_internal/z64/actor/properties.py | 16 ++--------- fast64_internal/z64/cutscene/classes.py | 7 ++--- fast64_internal/z64/exporter/room/header.py | 10 +++---- fast64_internal/z64/exporter/scene/actors.py | 10 ++++--- fast64_internal/z64/importer/room_header.py | 9 +----- fast64_internal/z64/importer/scene_header.py | 14 +-------- fast64_internal/z64/room/operators.py | 30 ++------------------ fast64_internal/z64/room/properties.py | 22 ++++---------- fast64_internal/z64/scene/operators.py | 23 --------------- fast64_internal/z64/scene/properties.py | 17 ++++------- 11 files changed, 28 insertions(+), 156 deletions(-) diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 90fe7b449..4b7fe407d 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -27,31 +27,6 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} -class MM_SearchActorIDEnumOperator(Operator): - bl_idname = "object.mm_search_actor_id_enum_operator" - bl_label = "Select Actor ID" - bl_property = "actor_id" - bl_options = {"REGISTER", "UNDO"} - - actor_id: EnumProperty(items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") - actor_user: StringProperty(default="Actor") - obj_name: StringProperty() - - def execute(self, context): - obj = bpy.data.objects[self.obj_name] - if self.actor_user == "Transition Actor": - obj.ootTransitionActorProperty.actor.mm_actor_id = self.actor_id - elif self.actor_user == "Actor": - obj.ootActorProperty.mm_actor_id = self.actor_id - elif self.actor_user == "Entrance": - obj.ootEntranceProperty.actor.mm_actor_id = self.actor_id - else: - raise PluginError("Invalid actor user for search: " + str(self.actor_user)) - - context.region.tag_redraw() - self.report({"INFO"}, "Selected: " + self.actor_id) - - class OOT_SearchNaviMsgIDEnumOperator(Operator): bl_idname = "object.oot_search_navi_msg_id_enum_operator" bl_label = "Select Message ID" @@ -103,7 +78,6 @@ def invoke(self, context, event): classes = ( - MM_SearchActorIDEnumOperator, OOT_SearchActorIDEnumOperator, OOT_SearchChestContentEnumOperator, OOT_SearchNaviMsgIDEnumOperator, diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 2db6affd9..64abf57a6 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -11,7 +11,6 @@ from ..room.properties import Z64_AlternateRoomHeaderProperty from .operators import ( OOT_SearchActorIDEnumOperator, - MM_SearchActorIDEnumOperator, OOT_SearchChestContentEnumOperator, OOT_SearchNaviMsgIDEnumOperator, ) @@ -81,7 +80,6 @@ def initOOTActorProperties(): prop_ats["actor_id"] = EnumProperty( name="Actor", items=game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER" ) - prop_ats["mm_actor_id"] = EnumProperty(name="Actor", items=mm_data.actor_data.enum_actor_id, default="ACTOR_PLAYER") param_type_to_enum_items = { "ChestContent": game_data.z64.actorData.ootEnumChestContent, @@ -494,12 +492,7 @@ def draw_props( if self.menu_tab == "General": actor_id: str = getattr(self, get_game_prop_name("actor_id")) - if is_game_oot(): - op_name = OOT_SearchActorIDEnumOperator.bl_idname - else: - op_name = MM_SearchActorIDEnumOperator.bl_idname - - searchOp = actorIDBox.operator(op_name, icon="VIEWZOOM") + searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") searchOp.actor_user = "Actor" searchOp.obj_name = owner.name @@ -599,12 +592,7 @@ def draw_props( ): actorIDBox = layout.column() - if is_game_oot(): - op_name = OOT_SearchActorIDEnumOperator.bl_idname - else: - op_name = MM_SearchActorIDEnumOperator.bl_idname - - searchOp = actorIDBox.operator(op_name, icon="VIEWZOOM") + searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") searchOp.actor_user = "Transition Actor" searchOp.obj_name = objName diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 1b487ac97..dd5d97b62 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -44,7 +44,7 @@ def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): # remove `cs` and lowercase first letter enumKey = enumKey[2].lower() + enumKey[3:] - enum = game_data.z64.enumData.enumByKey[enumKey] if is_game_oot() else mm_data.enum_data.enum_by_key[enumKey] + enum = game_data.z64.enumData.enumByKey[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -196,10 +196,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - if is_game_oot(): - self.commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key - else: - self.commandType = mm_data.enum_data.enum_by_key["cmd"].item_by_id[self.commandType].key + self.commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 3fb785af6..460ead0d5 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -123,10 +123,7 @@ def new(name: str, props: Optional[Z64_RoomHeaderProperty]): if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objects_by_key = ( - game_data.z64.objectData.objects_by_key if is_game_oot() else mm_data.object_data.objects_by_key - ) - objectList.append(objects_by_key[objProp.objectKey].id) + objectList.append(game_data.z64.objectData.objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -258,9 +255,10 @@ def new( spawn_rot = [f"SPAWN_ROT_FLAGS({r}" for r in rotation] actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) - actors_by_id = game_data.z64.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id actor.name = ( - actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") + game_data.z64.actorData.actorsByID[actor_id].name.replace( + f" - {actor_id.removeprefix('ACTOR_')}", "" + ) if actor_id != "Custom" else "Custom Actor" ) diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 4b2e3ab0e..2cf335569 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -81,9 +81,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): else: transActor.id = actor_id - actors_by_id = game_data.z64.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id transActor.name = ( - actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") + game_data.z64.actorData.actorsByID[actor_id].name.replace( + f" - {actor_id.removeprefix('ACTOR_')}", "" + ) if actor_id != "Custom" else "Custom Actor" ) @@ -156,9 +157,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) entranceActor = EntranceActor() - actors_by_id = game_data.z64.actorData.actorsByID if is_game_oot() else mm_data.actor_data.actors_by_id entranceActor.name = ( - actors_by_id[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") + game_data.z64.actorData.actorsByID[actor_id].name.replace( + f" - {actor_id.removeprefix('ACTOR_')}", "" + ) if actor_id != "Custom" else "Custom Actor" ) diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 768a279ba..4e8a7a50d 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -18,20 +18,13 @@ from .room_shape import parseMeshHeader -def get_object_from_id(object: str): - if is_game_oot(): - return game_data.z64.objectData.objects_by_id.get(object) - else: - return mm_data.object_data.objects_by_id.get(object) - - def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectListName: str): objectData = getDataMatch(sceneData, objectListName, "s16", "object list") objects = [value.strip() for value in objectData.split(",") if value.strip() != ""] for object in objects: objectProp = roomHeader.objectList.add() - objByID = get_object_from_id(object) + objByID = game_data.z64.objectData.objects_by_id.get(object) if objByID is not None: setattr(objectProp, get_game_prop_name("object_key"), objByID.key) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 946547c95..4a65e0a8d 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -483,13 +483,6 @@ def parse_actor_cs(scene_obj: Object, header_index: int, scene_data: str, list_n break -def get_enum_id_from_index(enum_key: str, index: int): - if is_game_oot(): - return game_data.z64.enumData.enumByKey[enum_key].item_by_index[index].id - else: - return mm_data.enum_data.enum_by_key[enum_key].item_by_index[index].id - - def parseSceneCommands( sceneName: str | None, sceneObj: bpy.types.Object | None, @@ -546,12 +539,7 @@ def parseSceneCommands( if args[2].startswith("NA_BGM_"): enum_id = args[2] else: - if is_game_oot(): - enum_seq_id = game_data.z64.enumData.enumByKey["seqId"] - else: - enum_seq_id = mm_data.enum_data.enum_by_key["seqId"] - - enum_id = enum_seq_id.item_by_index[int(args[2])].id + enum_id = game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id setCustomProperty( sceneHeader, get_game_prop_name("seq_id"), enum_id, game_data.z64.ootEnumMusicSeq, "musicSeqCustom" diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index 9fc8372d4..558858296 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default="obj_human") + objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default=1) headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() @@ -29,33 +29,7 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} -class MM_SearchObjectEnumOperator(Operator): - bl_idname = "object.mm_search_object_enum_operator" - bl_label = "Search Object ID" - bl_property = "object_key" - bl_options = {"REGISTER", "UNDO"} - - object_key: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") - headerIndex: IntProperty(default=0, min=0) - index: IntProperty(default=0, min=0) - objName: StringProperty() - - def execute(self, context): - roomHeader = ootGetSceneOrRoomHeader(bpy.data.objects[self.objName], self.headerIndex, True) - roomHeader.objectList[self.index].object_key = self.object_key - context.region.tag_redraw() - self.report({"INFO"}, "Selected: " + self.object_key) - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.invoke_search_popup(self) - return {"RUNNING_MODAL"} - - -classes = ( - OOT_SearchObjectEnumOperator, - MM_SearchObjectEnumOperator, -) +classes = (OOT_SearchObjectEnumOperator,) def room_ops_register(): diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index d66bd99d1..9dfcd97f0 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -44,8 +44,7 @@ class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default="obj_human") - mm_object_key: EnumProperty(items=mm_data.object_data.enum_object_key, default="gameplay_keep") + objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default=1) objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod @@ -58,17 +57,10 @@ def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: st is_legacy = True if "objectID" in self else False obj_key: str = getattr(self, get_game_prop_name("object_key")) - if is_game_oot(): - objects_by_key = game_data.z64.objectData.objects_by_key - op_name = OOT_SearchObjectEnumOperator.bl_idname - else: - objects_by_key = mm_data.object_data.objects_by_key - op_name = MM_SearchObjectEnumOperator.bl_idname - if is_game_oot() and is_legacy: obj_name = game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] elif obj_key != "Custom": - obj_name = objects_by_key[obj_key].name + obj_name = game_data.z64.objectData.objects_by_key[obj_key].name else: obj_name = self.objectIDCustom @@ -76,7 +68,7 @@ def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: st row = objItemBox.row() row.label(text=f"{obj_name}") buttons = row.row(align=True) - objSearch = buttons.operator(op_name, icon="VIEWZOOM", text="Select") + objSearch = buttons.operator(OOT_SearchObjectEnumOperator.bl_idname, icon="VIEWZOOM", text="Select") drawCollectionOps(buttons, index, "Object", headerIndex, objName, compact=True) objSearch.objName = objName objSearch.headerIndex = headerIndex if headerIndex is not None else 0 @@ -113,14 +105,10 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=game_data.z64.ootEnumRoomBehaviour, default="0x00") - mm_room_type: EnumProperty(items=mm_enum_room_type, default="ROOM_TYPE_NORMAL") + roomBehaviour: EnumProperty(items=game_data.z64.ootEnumRoomBehaviour, default=1) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Environment Type", items=game_data.z64.ootEnumLinkIdle, default="0x00") - mm_environment_type: EnumProperty( - name="Environment Type", items=mm_enum_environment_type, default="ROOM_ENV_DEFAULT" - ) + linkIdleMode: EnumProperty(name="Environment Type", items=game_data.z64.ootEnumLinkIdle, default=1) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") # OoT exclusive diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index bcafd0808..86446a5fd 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -116,28 +116,6 @@ def invoke(self, context, event): return {"RUNNING_MODAL"} -class MM_SearchMusicSeqEnumOperator(Operator): - bl_idname = "object.mm_search_music_seq_enum_operator" - bl_label = "Search Music Sequence" - bl_property = "seq_id" - bl_options = {"REGISTER", "UNDO"} - - seq_id: EnumProperty(items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") - headerIndex: IntProperty(default=0, min=0) - objName: StringProperty() - - def execute(self, context): - sceneHeader = ootGetSceneOrRoomHeader(bpy.data.objects[self.objName], self.headerIndex, False) - sceneHeader.musicSeq = self.seq_id - context.region.tag_redraw() - self.report({"INFO"}, "Selected: " + self.seq_id) - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.invoke_search_popup(self) - return {"RUNNING_MODAL"} - - class OOT_ClearBootupScene(Operator): bl_idname = "object.oot_clear_bootup_scene" bl_label = "Undo Boot To Scene" @@ -310,7 +288,6 @@ def draw(self, context): OOT_ExportScene, OOT_RemoveScene, MM_SearchSceneEnumOperator, - MM_SearchMusicSeqEnumOperator, ) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 2b698ec99..bb58659b5 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -322,10 +322,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty( - name="Global Object", default="OBJECT_GAMEPLAY_DANGEON_KEEP", items=game_data.z64.ootEnumGlobalObject - ) - mm_global_obj: EnumProperty(name="Global Object", default="GAMEPLAY_DANGEON_KEEP", items=mm_enum_global_object) + globalObject: EnumProperty(name="Global Object", default=1, items=game_data.z64.ootEnumGlobalObject) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") # OoT exclusive @@ -333,11 +330,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skyboxID: EnumProperty(name="Skybox", items=game_data.z64.ootEnumSkybox, default="0x01") - mm_skybox_id: EnumProperty(name="Skybox", items=mm_enum_skybox, default="SKYBOX_NORMAL_SKY") + skyboxID: EnumProperty(name="Skybox", items=game_data.z64.ootEnumSkybox, default=1) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=game_data.z64.ootEnumCloudiness, default="0x00") - mm_skybox_config: EnumProperty(name="Skybox Config", items=mm_enum_skybox_config, default="SKYBOX_CONFIG_0") + skyboxCloudiness: EnumProperty(name="Cloudiness", items=game_data.z64.ootEnumCloudiness, default=1) skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", @@ -353,11 +348,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") # SCENE_CMD_SOUND_SETTINGS - musicSeq: EnumProperty(name="Music Sequence", items=game_data.z64.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") - mm_seq_id: EnumProperty(name="Music Sequence", items=mm_data.enum_seq_id, default="NA_BGM_TERMINA_FIELD") + musicSeq: EnumProperty(name="Music Sequence", items=game_data.z64.ootEnumMusicSeq, default=1) musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=game_data.z64.ootEnumNightSeq, default="0x00") - mm_ambience_id: EnumProperty(name="Nighttime SFX", items=mm_data.enum_ambiance_id, default="0x00") + nightSeq: EnumProperty(name="Nighttime SFX", items=game_data.z64.ootEnumNightSeq, default=1) nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") From eda100daffa7737960a8b4a6d8facff730f4483c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:32:00 +0100 Subject: [PATCH 061/126] fixed data not updating properly --- __init__.py | 11 ++--- fast64_internal/constants.py | 11 ----- fast64_internal/data/z64/data.py | 1 + fast64_internal/data/z64/xml/mm_enum_data.xml | 9 ++++ fast64_internal/game_data.py | 15 +++++++ fast64_internal/z64/actor/operators.py | 8 ++-- fast64_internal/z64/actor/properties.py | 45 +++++++++---------- fast64_internal/z64/cutscene/classes.py | 10 ++--- fast64_internal/z64/cutscene/constants.py | 4 +- .../z64/cutscene/exporter/classes.py | 8 ++-- .../z64/cutscene/motion/operators.py | 6 +-- .../z64/cutscene/motion/properties.py | 8 ++-- fast64_internal/z64/cutscene/operators.py | 6 +-- fast64_internal/z64/cutscene/properties.py | 18 ++++---- .../z64/exporter/cutscene/actor_cue.py | 4 +- .../z64/exporter/cutscene/common.py | 4 +- fast64_internal/z64/exporter/cutscene/data.py | 8 ++-- fast64_internal/z64/exporter/room/header.py | 12 ++--- fast64_internal/z64/exporter/scene/actors.py | 10 ++--- fast64_internal/z64/exporter/scene/general.py | 10 ++--- fast64_internal/z64/importer/actor.py | 14 +++--- fast64_internal/z64/importer/room_header.py | 12 ++--- fast64_internal/z64/importer/scene_header.py | 24 +++++----- fast64_internal/z64/object.py | 6 +-- fast64_internal/z64/room/operators.py | 4 +- fast64_internal/z64/room/properties.py | 20 ++++----- fast64_internal/z64/scene/operators.py | 4 +- fast64_internal/z64/scene/properties.py | 31 ++++++------- fast64_internal/z64/upgrade.py | 20 ++++----- fast64_internal/z64/utility.py | 22 ++------- 30 files changed, 178 insertions(+), 187 deletions(-) delete mode 100644 fast64_internal/constants.py create mode 100644 fast64_internal/game_data.py diff --git a/__init__.py b/__init__.py index 715d02ed4..7480a241d 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +1,13 @@ import bpy +import fast64_internal.game_data as GD + + from bpy.utils import register_class, unregister_class from bpy.path import abspath from . import addon_updater_ops from .fast64_internal.utility import prop_split, multilineLabel, set_prop_if_in_data -from .fast64_internal.constants import GameData, game_data from .fast64_internal.repo_settings import ( draw_repo_settings, @@ -356,11 +358,10 @@ def update_game_data(): """This function should be called on blend load or game editor update""" def init_game_data(): - global game_data - game_data = GameData(bpy.context.scene.gameEditorMode) + GD.game_data = GD.GameData(bpy.context.scene.gameEditorMode) match bpy.context.scene.gameEditorMode: - case "OOT": + case "OOT" | "MM": oot_register(True) case _: print(f"[init_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") @@ -368,7 +369,7 @@ def init_game_data(): def destroy_game_data(): match bpy.context.scene.gameEditorMode: - case "OOT": + case "OOT" | "MM": oot_unregister(True) case _: print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") diff --git a/fast64_internal/constants.py b/fast64_internal/constants.py deleted file mode 100644 index 0d6658b70..000000000 --- a/fast64_internal/constants.py +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Optional - - -class GameData: - def __init__(self, game_editor_mode: Optional[str] = None): - from .data import Z64_Data - - self.z64 = Z64_Data(game_editor_mode if game_editor_mode is not None else "MM") - - -game_data = GameData() diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 74c3da05a..a91c15ffe 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -481,6 +481,7 @@ def __init__(self, game: str): from .object_data import Z64_ObjectData from .actor_data import Z64_ActorData + self.game = game self.enumData = Z64_EnumData(game) self.objectData = Z64_ObjectData(game) self.actorData = Z64_ActorData(game) diff --git a/fast64_internal/data/z64/xml/mm_enum_data.xml b/fast64_internal/data/z64/xml/mm_enum_data.xml index f7321efa5..92e5b437d 100644 --- a/fast64_internal/data/z64/xml/mm_enum_data.xml +++ b/fast64_internal/data/z64/xml/mm_enum_data.xml @@ -500,6 +500,15 @@ + + + + + + + + + diff --git a/fast64_internal/game_data.py b/fast64_internal/game_data.py new file mode 100644 index 000000000..e421c1253 --- /dev/null +++ b/fast64_internal/game_data.py @@ -0,0 +1,15 @@ +from typing import Optional + + +class GameData: + def __init__(self, game_editor_mode: Optional[str] = None): + from .data import Z64_Data + + if game_editor_mode is not None and game_editor_mode in {"OOT", "MM"}: + self.z64 = Z64_Data(game_editor_mode) + else: + # default value to avoid issues + self.z64 = Z64_Data("OOT") + + +game_data = GameData() diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 4b7fe407d..ee0d7001c 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -3,7 +3,7 @@ from bpy.props import EnumProperty, StringProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError -from ...constants import game_data +import fast64_internal.game_data as GD class OOT_SearchChestContentEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_property = "chest_content" bl_options = {"REGISTER", "UNDO"} - chest_content: EnumProperty(items=game_data.z64.actorData.ootEnumChestContent, default="item_heart") + chest_content: EnumProperty(items=GD.game_data.z64.actorData.ootEnumChestContent, default="item_heart") obj_name: StringProperty() prop_name: StringProperty() @@ -33,7 +33,7 @@ class OOT_SearchNaviMsgIDEnumOperator(Operator): bl_property = "navi_msg_id" bl_options = {"REGISTER", "UNDO"} - navi_msg_id: EnumProperty(items=game_data.z64.actorData.ootEnumNaviMessageData, default="msg_00") + navi_msg_id: EnumProperty(items=GD.game_data.z64.actorData.ootEnumNaviMessageData, default=1) obj_name: StringProperty() prop_name: StringProperty() @@ -54,7 +54,7 @@ class OOT_SearchActorIDEnumOperator(Operator): bl_property = "actor_id" bl_options = {"REGISTER", "UNDO"} - actor_id: EnumProperty(items=lambda self, context: game_data.z64.actorData.getItems(self.actor_user)) + actor_id: EnumProperty(items=lambda self, context: GD.game_data.z64.actorData.getItems(self.actor_user)) actor_user: StringProperty(default="Actor") obj_name: StringProperty() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 64abf57a6..541608dd8 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from ...utility import PluginError, prop_split, label_split, get_prop_annotations -from ...constants import game_data +import fast64_internal.game_data as GD from ..constants import ootEnumCamTransition from ..upgrade import upgradeActors from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -78,16 +78,16 @@ def initOOTActorProperties(): prop_ats = get_prop_annotations(Z64_ActorProperty) prop_ats["actor_id"] = EnumProperty( - name="Actor", items=game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER" + name="Actor", items=GD.game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER" ) param_type_to_enum_items = { - "ChestContent": game_data.z64.actorData.ootEnumChestContent, - "Collectible": game_data.z64.actorData.ootEnumCollectibleItems, - "Message": game_data.z64.actorData.ootEnumNaviMessageData, + "ChestContent": GD.game_data.z64.actorData.ootEnumChestContent, + "Collectible": GD.game_data.z64.actorData.ootEnumCollectibleItems, + "Message": GD.game_data.z64.actorData.ootEnumNaviMessageData, } - for actor in game_data.z64.actorData.actorList: + for actor in GD.game_data.z64.actorData.actorList: for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) enum_items = None @@ -301,7 +301,7 @@ def upgrade_object(obj: Object): upgradeActors(obj) def is_rotation_used(self, target: str): - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: if param.type == "Type": @@ -324,7 +324,7 @@ def is_value_in_range(self, value: int, min: int, max: int): return True def set_param_value(self, base_value: str | bool, target: str): - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] base_value = getEvalParamsInt(base_value) found_type = None for param in actor.params: @@ -343,11 +343,11 @@ def set_param_value(self, base_value: str | bool, target: str): if is_in_range and (found_type_in_tied_types or len(param.tiedTypes) == 0): prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) if param.type == "ChestContent": - prop_value = game_data.z64.actorData.chestItemByValue[value].key + prop_value = GD.game_data.z64.actorData.chestItemByValue[value].key elif param.type == "Collectible": - prop_value = game_data.z64.actorData.collectibleItemsByValue[value].key + prop_value = GD.game_data.z64.actorData.collectibleItemsByValue[value].key elif param.type == "Message": - prop_value = game_data.z64.actorData.messageItemsByValue[value].key + prop_value = GD.game_data.z64.actorData.messageItemsByValue[value].key elif param.type == "Bool": prop_value = bool(value) else: @@ -364,7 +364,7 @@ def set_param_value(self, base_value: str | bool, target: str): ) def get_param_value(self, target: str): - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] param_list = [] type_value = None have_custom_value = False @@ -395,11 +395,11 @@ def get_param_value(self, target: str): else: param_val = 0 if param.type == "ChestContent": - param_val = game_data.z64.actorData.chestItemByKey[cur_prop_value].value + param_val = GD.game_data.z64.actorData.chestItemByKey[cur_prop_value].value elif param.type == "Collectible": - param_val = game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value + param_val = GD.game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value elif param.type == "Message": - param_val = game_data.z64.actorData.messageItemsByKey[cur_prop_value].value + param_val = GD.game_data.z64.actorData.messageItemsByKey[cur_prop_value].value if "Rot" in target: type_value = getEvalParamsInt(getattr(self, get_prop_name(actor.key, "Type", None, 1))) if type_value is not None and type_value in param.tiedTypes or len(param.tiedTypes) == 0: @@ -441,7 +441,7 @@ def get_param_value(self, target: str): return param_str def draw_params(self, layout: UILayout, obj: Object): - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) @@ -460,11 +460,11 @@ def draw_params(self, layout: UILayout, obj: Object): if param.type == "ChestContent": search_op = layout.operator(OOT_SearchChestContentEnumOperator.bl_idname) label_name = "Chest Content" - item_map = game_data.z64.actorData.chestItemByKey + item_map = GD.game_data.z64.actorData.chestItemByKey else: search_op = layout.operator(OOT_SearchNaviMsgIDEnumOperator.bl_idname) label_name = "Navi Message ID" - item_map = game_data.z64.actorData.messageItemsByKey + item_map = GD.game_data.z64.actorData.messageItemsByKey search_op.obj_name = obj.name search_op.prop_name = prop_name if key != "Custom": @@ -490,20 +490,18 @@ def draw_props( actor_cs_props = owner.z64_actor_cs_property if self.menu_tab == "General": - actor_id: str = getattr(self, get_game_prop_name("actor_id")) - searchOp = actorIDBox.operator(OOT_SearchActorIDEnumOperator.bl_idname, icon="VIEWZOOM") searchOp.actor_user = "Actor" searchOp.obj_name = owner.name split = actorIDBox.split(factor=0.5) - if actor_id == "None": + if self.actor_id == "None": actorIDBox.box().label(text="This Actor was deleted from the XML file.") return split.label(text="Actor ID") - split.label(text=getEnumName(game_data.z64.actorData.ootEnumActorID, actor_id)) + split.label(text=getEnumName(GD.game_data.z64.actorData.ootEnumActorID, self.actor_id)) if self.actor_id != "Custom": self.draw_params(actorIDBox, owner) @@ -598,8 +596,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - actor_id = getattr(self.actor, get_game_prop_name("actor_id")) - split.label(text=getEnumName(game_data.z64.actorData.ootEnumActorID, actor_id)) + split.label(text=getEnumName(GD.game_data.z64.actorData.ootEnumActorID, self.actor.actor_id)) if self.actor.actor_id == "Custom": prop_split(actorIDBox, self.actor, "actor_id_custom", "") diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index dd5d97b62..4c17f19ef 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from bpy.types import Object from typing import Optional -from ...constants import game_data +import fast64_internal.game_data as GD from ..utility import is_oot_features, is_game_oot from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger @@ -44,7 +44,7 @@ def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): # remove `cs` and lowercase first letter enumKey = enumKey[2].lower() + enumKey[3:] - enum = game_data.z64.enumData.enumByKey[enumKey] + enum = GD.game_data.z64.enumData.enumByKey[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -196,7 +196,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key + self.commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -844,7 +844,7 @@ def getNewCutsceneObject(self, name: str, frameCount: int, parentObj: Object): def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Object): newActorCueListObj = self.getNewEmptyObject(name, False, parentObj) newActorCueListObj.ootEmptyType = f"CS {'Player' if 'Player' in name else 'Actor'} Cue List" - cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] + cmdEnum = GD.game_data.z64.enumData.enumByKey["csCmd"] if commandType == "Player": commandType = "player_cue" @@ -885,7 +885,7 @@ def getNewActorCueObject( item = None if isPlayer: - playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] + playerEnum = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"] if isinstance(actionID, int): item = playerEnum.item_by_index.get(actionID) else: diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 2a4ba176b..21c7d5de2 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -1,4 +1,4 @@ -from ...constants import game_data +import fast64_internal.game_data as GD from .classes import ( CutsceneCmdActorCueList, CutsceneCmdActorCue, @@ -141,7 +141,7 @@ ] ootEnumCSActorCueListCommandType = [ - item for item in game_data.z64.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] + item for item in GD.game_data.z64.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] ] ootEnumCSActorCueListCommandType.sort() ootEnumCSActorCueListCommandType.insert(0, ("Custom", "Custom", "Custom")) diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index 9bc4bc954..713c67082 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object from ....utility import PluginError, indent -from ....constants import game_data +import fast64_internal.game_data as GD from ..constants import ootEnumCSListTypeListC if TYPE_CHECKING: @@ -40,7 +40,7 @@ class CutsceneCmdToC: """This class contains functions to create the cutscene commands""" def getEnumValue(self, enumKey: str, owner, propName: str): - item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = GD.game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def getGenericListCmd(self, cmdName: str, entryTotal: int): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index dcd78639f..179220d60 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty from ....utility import PluginError -from ....constants import game_data +import fast64_internal.game_data as GD from ..classes import CutsceneObjectFactory from ..constants import ootEnumCSActorCueListCommandType from ..preview import initFirstFrame, setupCompositorNodes @@ -296,7 +296,7 @@ class OOT_SearchActorCueCmdTypeEnumOperator(Operator): bl_property = "commandType" bl_options = {"REGISTER", "UNDO"} - commandType: EnumProperty(items=ootEnumCSActorCueListCommandType, default="actor_cue_0_0") + commandType: EnumProperty(items=ootEnumCSActorCueListCommandType, default=1) objName: StringProperty() def execute(self, context): @@ -318,7 +318,7 @@ class OOT_SearchPlayerCueIdEnumOperator(Operator): bl_property = "playerCueID" bl_options = {"REGISTER", "UNDO"} - playerCueID: EnumProperty(items=game_data.z64.enumData.ootEnumCsPlayerCueId, default="cueid_none") + playerCueID: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsPlayerCueId, default=1) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 5e0ef3f99..19cb0d9c6 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...upgrade import upgradeCutsceneMotion from ...utility import getEnumName -from ....constants import game_data +import fast64_internal.game_data as GD from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType from .operators import ( @@ -32,7 +32,7 @@ def getNextCuesStartFrame(self): class CutsceneCmdActorCueListProperty(PropertyGroup): commandType: EnumProperty( - items=ootEnumCSActorCueListCommandType, name="CS Actor Cue Command Type", default="actor_cue_0_0" + items=ootEnumCSActorCueListCommandType, name="CS Actor Cue Command Type", default=1 ) commandTypeCustom: StringProperty(name="CS Actor Cue Command Type Custom") actorCueListToPreview: PointerProperty( @@ -86,7 +86,7 @@ class CutsceneCmdActorCueProperty(PropertyGroup): get=lambda self: getNextCuesStartFrame(self), ) - playerCueID: EnumProperty(items=game_data.z64.enumData.ootEnumCsPlayerCueId, default="cueid_none") + playerCueID: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsPlayerCueId, default=1) cueActionID: StringProperty( name="Action ID", default="0x0001", description="Actor action. Meaning is unique for each different actor." ) @@ -116,7 +116,7 @@ def draw_props(self, layout: UILayout, labelPrefix: str, isDummy: bool, objName: split = box.split(factor=0.5) searchOp = split.operator(OOT_SearchPlayerCueIdEnumOperator.bl_idname, icon="VIEWZOOM", text=label) searchOp.objName = objName - split.label(text=getEnumName(game_data.z64.enumData.ootEnumCsPlayerCueId, self.playerCueID)) + split.label(text=getEnumName(GD.game_data.z64.enumData.ootEnumCsPlayerCueId, self.playerCueID)) if not isPlayer or self.playerCueID == "Custom": split = box.split(factor=0.5) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index 904b077a0..bb3747a7d 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -9,7 +9,7 @@ from bpy.utils import register_class, unregister_class from ...utility import CData, PluginError, writeCData, raisePluginError from ..utility import getCollection -from ...constants import game_data +import fast64_internal.game_data as GD from .constants import ootEnumCSTextboxType, ootEnumCSListType from .importer import importCutsceneData from .exporter import getNewCutsceneExport @@ -238,7 +238,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty(items=game_data.z64.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse") + csDestination: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsDestination, default=1) objName: StringProperty() def execute(self, context): @@ -260,7 +260,7 @@ class OOT_SearchCSSeqOperator(Operator): bl_property = "seqId" bl_options = {"REGISTER", "UNDO"} - seqId: EnumProperty(items=game_data.z64.enumData.ootEnumSeqId, default="general_sfx") + seqId: EnumProperty(items=GD.game_data.z64.enumData.ootEnumSeqId, default=1) itemIndex: IntProperty() listType: StringProperty() diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index dc9f03367..6dc393afc 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName -from ...constants import game_data +import fast64_internal.game_data as GD from ..upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty from .operators import OOTCSTextAdd, OOT_SearchCSDestinationEnumOperator, OOTCSListAdd, OOT_SearchCSSeqOperator from .motion.preview import previewFrameHandler @@ -113,13 +113,13 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): # subprops textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( - name="Ocarina Action", items=game_data.z64.enumData.ootEnumOcarinaSongActionId, default="teach_minuet" + name="Ocarina Action", items=GD.game_data.z64.enumData.ootEnumOcarinaSongActionId, default=1 ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") topOptionTextID: StringProperty(name="", default="0x0000") bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") - csTextType: EnumProperty(name="Text Type", items=game_data.z64.enumData.ootEnumCsTextType, default="normal") + csTextType: EnumProperty(name="Text Type", items=GD.game_data.z64.enumData.ootEnumCsTextType, default=1) csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") def getName(self): @@ -152,10 +152,10 @@ class OOTCSTimeProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] - csSeqID: EnumProperty(name="Seq ID", items=game_data.z64.enumData.ootEnumSeqId, default="general_sfx") + csSeqID: EnumProperty(name="Seq ID", items=GD.game_data.z64.enumData.ootEnumSeqId, default=1) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") csSeqPlayer: EnumProperty( - name="Seq Player", items=game_data.z64.enumData.ootEnumCsFadeOutSeqPlayer, default="fade_out_fanfare" + name="Seq Player", items=GD.game_data.z64.enumData.ootEnumCsFadeOutSeqPlayer, default=1 ) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") @@ -171,7 +171,7 @@ def filterName(self, name, listProp): class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] - csMiscType: EnumProperty(name="Type", items=game_data.z64.enumData.ootEnumCsMiscType, default="rain") + csMiscType: EnumProperty(name="Type", items=GD.game_data.z64.enumData.ootEnumCsMiscType, default=1) csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -197,7 +197,7 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - transitionType: EnumProperty(items=game_data.z64.enumData.ootEnumCsTransitionType, default="gray_fill_in") + transitionType: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsTransitionType, default=1) transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) transitionEndFrame: IntProperty(name="", default=1, min=0) @@ -356,7 +356,7 @@ class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") csDestination: EnumProperty( - name="Destination", items=game_data.z64.enumData.ootEnumCsDestination, default="cutscene_map_ganon_horse" + name="Destination", items=GD.game_data.z64.enumData.ootEnumCsDestination, default=1 ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) @@ -407,7 +407,7 @@ def draw_props(self, layout: UILayout, obj: Object): boxRow = searchBox.row() searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") searchOp.objName = obj.name - boxRow.label(text=getEnumName(game_data.z64.enumData.ootEnumCsDestination, self.csDestination)) + boxRow.label(text=getEnumName(GD.game_data.z64.enumData.ootEnumCsDestination, self.csDestination)) if self.csDestination == "Custom": prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index fc27b6b8c..80063598e 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field from ....utility import PluginError, indent -from ....constants import game_data +import fast64_internal.game_data as GD from ...cutscene.motion.utility import getRotation, getInteger from .common import CutsceneCmdBase @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[commandType].key + commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_id[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index fe5146ad8..fa0778d91 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional from ....utility import PluginError, indent -from ....constants import game_data +import fast64_internal.game_data as GD from ...cutscene.motion.utility import getInteger @@ -20,7 +20,7 @@ def validateFrames(self, checkEndFrame: bool = True): @staticmethod def getEnumValue(enumKey: str, value: str, isSeqLegacy: bool = False): - enum = game_data.z64.enumData.enumByKey[enumKey] + enum = GD.game_data.z64.enumData.enumByKey[enumKey] item = enum.item_by_id.get(value) if item is None: setting = getInteger(value) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index b752eb7e9..76eb047d8 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError -from ....constants import game_data +import fast64_internal.game_data as GD from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction @@ -142,7 +142,7 @@ def getOoTPosition(self, pos): return [x, y, z] def getEnumValueFromProp(self, enumKey: str, owner, propName: str): - item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = GD.game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): @@ -169,7 +169,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +183,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 460ead0d5..42a14b1d2 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, getEvalParams, get_game_prop_name, is_game_oot -from ....constants import game_data +import fast64_internal.game_data as GD from ...constants import halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits from ...room.properties import Z64_RoomHeaderProperty from ...actor.properties import Z64_ActorProperty @@ -65,8 +65,8 @@ def new(props: Optional[Z64_RoomHeaderProperty]): return RoomInfos( props.roomIndex, props.roomShape, - Utility.getPropValue(props, get_game_prop_name("room_type"), "roomBehaviourCustom"), - Utility.getPropValue(props, get_game_prop_name("environment_type"), "linkIdleModeCustom"), + Utility.getPropValue(props, "roomBehaviour", "roomBehaviourCustom"), + Utility.getPropValue(props, "linkIdleMode", "linkIdleModeCustom"), props.showInvisibleActors, disableWarpSongs, enable_pos_lights, @@ -123,7 +123,7 @@ def new(name: str, props: Optional[Z64_RoomHeaderProperty]): if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objectList.append(game_data.z64.objectData.objects_by_key[objProp.objectKey].id) + objectList.append(GD.game_data.z64.objectData.objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -196,7 +196,7 @@ def new( if not Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex): continue - actor_id: str = actorProp.actorID if is_game_oot() else actorProp.mm_actor_id + actor_id: str = actorProp.actorID if is_game_oot() else actorProp.actor_id # The Actor list is filled with ``("None", f"{i} (Deleted from the XML)", "None")`` for # the total number of actors defined in the XML. If the user deletes one, this will prevent @@ -256,7 +256,7 @@ def new( actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actor.name = ( - game_data.z64.actorData.actorsByID[actor_id].name.replace( + GD.game_data.z64.actorData.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 2cf335569..f685be4b2 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, is_game_oot -from ....constants import game_data +import fast64_internal.game_data as GD from ...actor.properties import Z64_ActorProperty from ..utility import Utility from ..actor import Actor @@ -61,7 +61,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in actorObjList: transActorProp = obj.ootTransitionActorProperty actorProp: Z64_ActorProperty = transActorProp.actor - actor_id: str = actorProp.actorID if is_game_oot() else actorProp.mm_actor_id + actor_id: str = actorProp.actorID if is_game_oot() else actorProp.actor_id if Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) transActor = TransitionActor() @@ -82,7 +82,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.id = actor_id transActor.name = ( - game_data.z64.actorData.actorsByID[actor_id].name.replace( + GD.game_data.z64.actorData.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" @@ -152,13 +152,13 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in actorObjList: entranceProp = obj.ootEntranceProperty actorProp: Z64_ActorProperty = entranceProp.actor - actor_id: str = actorProp.actorID if is_game_oot() else actorProp.mm_actor_id + actor_id: str = actorProp.actorID if is_game_oot() else actorProp.actor_id if Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) entranceActor = EntranceActor() entranceActor.name = ( - game_data.z64.actorData.actorsByID[actor_id].name.replace( + GD.game_data.z64.actorData.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 3e1907a05..e487eada5 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -194,16 +194,16 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): skybox_texture_id = Utility.getPropValue(props, "skybox_texture_id") return SceneInfos( - Utility.getPropValue(props, get_game_prop_name("global_obj"), "globalObjectCustom"), + Utility.getPropValue(props, "globalObject", "globalObjectCustom"), Utility.getPropValue(props, "naviCup") if is_game_oot() else "NAVI_QUEST_HINTS_NONE", Utility.getPropValue(props.sceneTableEntry, get_game_prop_name("draw_config"), "drawConfigCustom"), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, - Utility.getPropValue(props, get_game_prop_name("skybox_id"), "skyboxIDCustom"), - Utility.getPropValue(props, get_game_prop_name("skybox_config"), "skyboxCloudinessCustom"), + Utility.getPropValue(props, "skyboxID", "skyboxIDCustom"), + Utility.getPropValue(props, "skyboxCloudiness", "skyboxCloudinessCustom"), skybox_texture_id, - Utility.getPropValue(props, get_game_prop_name("seq_id"), "musicSeqCustom"), - Utility.getPropValue(props, get_game_prop_name("ambience_id"), "nightSeqCustom"), + Utility.getPropValue(props, "musicSeq", "musicSeqCustom"), + Utility.getPropValue(props, "nightSeq", "nightSeqCustom"), Utility.getPropValue(props, "audioSessionPreset"), Utility.getPropValue(props, "mapLocation") if is_oot_features() else "", Utility.getPropValue(props, "cameraMode") if is_oot_features() else "", diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 510f405df..5581ec862 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,7 +3,7 @@ from bpy.types import Object from ...utility import parentObject, hexOrDecInt -from ...constants import game_data +import fast64_internal.game_data as GD from ..scene.properties import Z64_SceneHeaderProperty from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_prop_name from ..constants import ( @@ -98,9 +98,9 @@ def parseTransActorList( actorProp = transActorProp.actor setCustomProperty( actorProp, - get_game_prop_name("actor_id"), + "actor_id", actorID, - game_data.z64.actorData.ootEnumActorID, + GD.game_data.z64.actorData.ootEnumActorID, "actorIDCustom", ) if actorProp.actor_id != "Custom": @@ -207,9 +207,9 @@ def parseSpawnList( actorProp = spawnProp.actor setCustomProperty( actorProp, - get_game_prop_name("actor_id"), + "actor_id", actorID, - game_data.z64.actorData.ootEnumActorID, + GD.game_data.z64.actorData.ootEnumActorID, "actor_id_custom", ) if actorProp.actor_id != "Custom": @@ -283,9 +283,9 @@ def parseActorList( actorProp = actorObj.ootActorProperty setCustomProperty( actorProp, - get_game_prop_name("actor_id"), + "actor_id", actorID, - game_data.z64.actorData.ootEnumActorID, + GD.game_data.z64.actorData.ootEnumActorID, "actor_id_custom", ) actorProp.actorParam = actorParam diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 4e8a7a50d..543384e4c 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,7 @@ import re from ...utility import hexOrDecInt -from ...constants import game_data +import fast64_internal.game_data as GD from ..utility import ( setCustomProperty, is_game_oot, @@ -24,7 +24,7 @@ def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectLi for object in objects: objectProp = roomHeader.objectList.add() - objByID = game_data.z64.objectData.objects_by_id.get(object) + objByID = GD.game_data.z64.objectData.objects_by_id.get(object) if objByID is not None: setattr(objectProp, get_game_prop_name("object_key"), objByID.key) @@ -75,16 +75,16 @@ def parseRoomCommands( elif command == "SCENE_CMD_ROOM_BEHAVIOR": setCustomProperty( roomHeader, - get_game_prop_name("room_type"), + "roomBehaviour", args[0], - game_data.z64.ootEnumRoomBehaviour, + GD.game_data.z64.ootEnumRoomBehaviour, "roomBehaviourCustom", ) setCustomProperty( roomHeader, - get_game_prop_name("environment_type"), + "linkIdleMode", args[1], - game_data.z64.ootEnumLinkIdle, + GD.game_data.z64.ootEnumLinkIdle, "linkIdleModeCustom", ) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 4a65e0a8d..2ba1c67ea 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -6,7 +6,7 @@ from bpy.types import Object from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse -from ...constants import game_data +import fast64_internal.game_data as GD from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext from ..scene.properties import Z64_SceneHeaderProperty, Z64_LightProperty @@ -302,7 +302,7 @@ def parse_mm_map_data_chest( if chest_room is not None: for child_obj in chest_room.children_recursive: if child_obj.type == "EMPTY" and child_obj.ootEmptyType == "Actor": - actor_id: str = getattr(child_obj.ootActorProperty, get_game_prop_name("actor_id")) + actor_id: str = getattr(child_obj.ootActorProperty, "actor_id") actor_params = int(getEvalParams(child_obj.ootActorProperty.actorParam), base=0) if actor_id in {"ACTOR_EN_BOX"}: @@ -530,19 +530,19 @@ def parseSceneCommands( setCustomProperty(sceneHeader, "audioSessionPreset", args[0], ootEnumAudioSessionPreset) setCustomProperty( sceneHeader, - get_game_prop_name("ambience_id"), + "nightSeq", args[1], - game_data.z64.ootEnumNightSeq, + GD.game_data.z64.ootEnumNightSeq, "nightSeqCustom", ) if args[2].startswith("NA_BGM_"): enum_id = args[2] else: - enum_id = game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id + enum_id = GD.game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id setCustomProperty( - sceneHeader, get_game_prop_name("seq_id"), enum_id, game_data.z64.ootEnumMusicSeq, "musicSeqCustom" + sceneHeader, "musicSeq", enum_id, GD.game_data.z64.ootEnumMusicSeq, "musicSeqCustom" ) command_list.remove(command) elif command == "SCENE_CMD_ROOM_LIST": @@ -572,9 +572,9 @@ def parseSceneCommands( setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) setCustomProperty( sceneHeader, - get_game_prop_name("global_obj"), + "globalObject", args[1], - game_data.z64.ootEnumGlobalObject, + GD.game_data.z64.ootEnumGlobalObject, "globalObjectCustom", ) command_list.remove(command) @@ -595,16 +595,16 @@ def parseSceneCommands( args_index += 1 setCustomProperty( sceneHeader, - get_game_prop_name("skybox_id"), + "skyboxID", args[args_index], - game_data.z64.ootEnumSkybox, + GD.game_data.z64.ootEnumSkybox, "skyboxIDCustom", ) setCustomProperty( sceneHeader, - get_game_prop_name("skybox_config"), + "skyboxCloudiness", args[args_index + 1], - game_data.z64.ootEnumCloudiness, + GD.game_data.z64.ootEnumCloudiness, "skyboxCloudinessCustom", ) setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index caa251fb4..9cf5dea4f 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -1,6 +1,6 @@ from bpy.types import Object from ..utility import ootGetSceneOrRoomHeader -from ..constants import game_data +import fast64_internal.game_data as GD from .exporter.room.header import RoomHeader @@ -18,11 +18,11 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header """Adds missing objects to the object list""" if len(curHeader.actors.actorList) > 0: for roomActor in curHeader.actors.actorList: - actor = game_data.z64.actorData.actorsByID.get(roomActor.id) + actor = GD.game_data.z64.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: if objKey not in ["obj_gameplay_keep", "obj_gameplay_field_keep", "obj_gameplay_dangeon_keep"]: - objID = game_data.z64.objectData.objects_by_key[objKey].id + objID = GD.game_data.z64.objectData.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) addMissingObjectToProp(roomObj, headerIndex, objKey) diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index 558858296..c0f8d8fd9 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, IntProperty, StringProperty from ...utility import ootGetSceneOrRoomHeader -from ...constants import game_data +import fast64_internal.game_data as GD class OOT_SearchObjectEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default=1) + objectKey: EnumProperty(items=GD.game_data.z64.objectData.ootEnumObjectKey, default=1) headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 9dfcd97f0..59a0e2765 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -2,7 +2,7 @@ from bpy.types import PropertyGroup, UILayout, Image, Object, Context from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ...constants import game_data +import fast64_internal.game_data as GD from ..utility import ( drawCollectionOps, onMenuTabChange, @@ -15,7 +15,7 @@ get_cs_index_start, ) from ..upgrade import upgradeRoomHeaders -from .operators import OOT_SearchObjectEnumOperator, MM_SearchObjectEnumOperator +from .operators import OOT_SearchObjectEnumOperator from bpy.props import ( EnumProperty, @@ -44,23 +44,23 @@ class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=game_data.z64.objectData.ootEnumObjectKey, default=1) + objectKey: EnumProperty(items=GD.game_data.z64.objectData.ootEnumObjectKey, default=1) objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod def upgrade_object(obj: Object): if is_game_oot(): print(f"Processing '{obj.name}'...") - upgradeRoomHeaders(obj, game_data.z64.objectData) + upgradeRoomHeaders(obj, GD.game_data.z64.objectData) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): is_legacy = True if "objectID" in self else False obj_key: str = getattr(self, get_game_prop_name("object_key")) if is_game_oot() and is_legacy: - obj_name = game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + obj_name = GD.game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] elif obj_key != "Custom": - obj_name = game_data.z64.objectData.objects_by_key[obj_key].name + obj_name = GD.game_data.z64.objectData.objects_by_key[obj_key].name else: obj_name = self.objectIDCustom @@ -105,10 +105,10 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=game_data.z64.ootEnumRoomBehaviour, default=1) + roomBehaviour: EnumProperty(items=GD.game_data.z64.ootEnumRoomBehaviour, default=1) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Environment Type", items=game_data.z64.ootEnumLinkIdle, default=1) + linkIdleMode: EnumProperty(name="Environment Type", items=GD.game_data.z64.ootEnumLinkIdle, default=1) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") # OoT exclusive @@ -206,10 +206,10 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj behaviorBox = layout.column() behaviorBox.box().label(text="Behavior") drawEnumWithCustom( - behaviorBox, self, get_game_prop_name("room_type"), "Room Type", "", "roomBehaviourCustom" + behaviorBox, self, "roomBehaviour", "Room Type", "", "roomBehaviourCustom" ) drawEnumWithCustom( - behaviorBox, self, get_game_prop_name("environment_type"), "Environment Type", "", "linkIdleModeCustom" + behaviorBox, self, "linkIdleMode", "Environment Type", "", "linkIdleModeCustom" ) if is_game_oot(): diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 86446a5fd..99e8672d7 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -10,7 +10,7 @@ from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot -from ...constants import game_data +import fast64_internal.game_data as GD from ..constants import ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config @@ -100,7 +100,7 @@ class OOT_SearchMusicSeqEnumOperator(Operator): bl_property = "ootMusicSeq" bl_options = {"REGISTER", "UNDO"} - ootMusicSeq: EnumProperty(items=game_data.z64.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + ootMusicSeq: EnumProperty(items=GD.game_data.z64.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") headerIndex: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index bb58659b5..dede59fe1 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -12,7 +12,7 @@ from bpy.utils import register_class, unregister_class from ...render_settings import on_update_oot_render_settings from ...utility import prop_split, customExportWarning -from ...constants import game_data +import fast64_internal.game_data as GD from ..cutscene.constants import ootEnumCSWriteType from ..utility import ( @@ -322,7 +322,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty(name="Global Object", default=1, items=game_data.z64.ootEnumGlobalObject) + globalObject: EnumProperty(name="Global Object", default=1, items=GD.game_data.z64.ootEnumGlobalObject) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") # OoT exclusive @@ -330,9 +330,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skyboxID: EnumProperty(name="Skybox", items=game_data.z64.ootEnumSkybox, default=1) + skyboxID: EnumProperty(name="Skybox", items=GD.game_data.z64.ootEnumSkybox, default=1) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=game_data.z64.ootEnumCloudiness, default=1) + skyboxCloudiness: EnumProperty(name="Cloudiness", items=GD.game_data.z64.ootEnumCloudiness, default=1) skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", @@ -348,9 +348,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") # SCENE_CMD_SOUND_SETTINGS - musicSeq: EnumProperty(name="Music Sequence", items=game_data.z64.ootEnumMusicSeq, default=1) + musicSeq: EnumProperty(name="Music Sequence", items=GD.game_data.z64.ootEnumMusicSeq, default=1) musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=game_data.z64.ootEnumNightSeq, default=1) + nightSeq: EnumProperty(name="Nighttime SFX", items=GD.game_data.z64.ootEnumNightSeq, default=1) nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") @@ -409,7 +409,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): minimap_chest_list: CollectionProperty(type=Z64_MapDataChestProperty, name="Minimap Chest List") def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): - from .operators import OOT_SearchMusicSeqEnumOperator, MM_SearchMusicSeqEnumOperator # temp circular import fix + from .operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix cs_index_start = get_cs_index_start() @@ -438,7 +438,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj # General drawEnumWithCustom( - general, self, get_game_prop_name("global_obj"), "Global Object", "", "globalObjectCustom" + general, self, "globalObject", "Global Object", "", "globalObjectCustom" ) if is_game_oot(): drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") @@ -455,24 +455,19 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj skyboxAndSound.box().label(text="Skybox And Sound") prop_split(skyboxAndSound, self, "skybox_texture_id", "Skybox Texture ID") - drawEnumWithCustom(skyboxAndSound, self, get_game_prop_name("skybox_id"), "Skybox", "", "skyboxIDCustom") + drawEnumWithCustom(skyboxAndSound, self, "skyboxID", "Skybox", "", "skyboxIDCustom") drawEnumWithCustom( - skyboxAndSound, self, get_game_prop_name("skybox_config"), "Skybox Config", "", "skyboxCloudinessCustom" + skyboxAndSound, self, "skyboxCloudiness", "Skybox Config", "", "skyboxCloudinessCustom" ) drawEnumWithCustom( - skyboxAndSound, self, get_game_prop_name("seq_id"), "Music Sequence", "", "musicSeqCustom" + skyboxAndSound, self, "musicSeq", "Music Sequence", "", "musicSeqCustom" ) - if is_game_oot(): - op_name = OOT_SearchMusicSeqEnumOperator.bl_idname - else: - op_name = MM_SearchMusicSeqEnumOperator.bl_idname - - musicSearch = skyboxAndSound.operator(op_name, icon="VIEWZOOM") + musicSearch = skyboxAndSound.operator(OOT_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") musicSearch.objName = objName musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 drawEnumWithCustom( - skyboxAndSound, self, get_game_prop_name("ambience_id"), "Nighttime SFX", "", "nightSeqCustom" + skyboxAndSound, self, "nightSeq", "Nighttime SFX", "", "nightSeqCustom" ) drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index f055c596d..0f0538948 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,7 +6,7 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from ..data import Z64_ObjectData -from ..constants import game_data +import fast64_internal.game_data as GD from .utility import getEvalParams, get_actor_prop_from_obj from .cutscene.constants import ootEnumCSMotionCamMode @@ -180,12 +180,12 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox - Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", game_data.z64.enumData.ootEnumOcarinaSongActionId), - Cutscene_UpgradeData("type", "csTextType", game_data.z64.enumData.ootEnumCsTextType), + Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", GD.game_data.z64.enumData.ootEnumOcarinaSongActionId), + Cutscene_UpgradeData("type", "csTextType", GD.game_data.z64.enumData.ootEnumCsTextType), # Seq - Cutscene_UpgradeData("value", "csSeqID", game_data.z64.enumData.ootEnumSeqId), + Cutscene_UpgradeData("value", "csSeqID", GD.game_data.z64.enumData.ootEnumSeqId), # Misc - Cutscene_UpgradeData("operation", "csMiscType", game_data.z64.enumData.ootEnumCsMiscType), + Cutscene_UpgradeData("operation", "csMiscType", GD.game_data.z64.enumData.ootEnumCsMiscType), ] transferOldDataToNew(csListSubProp, subPropsOldToNew) @@ -210,7 +210,7 @@ def upgradeCSListProps(csListProp): # both are enums but the item list is different (the old one doesn't have a "custom" entry) convertOldDataToEnumData( - csListProp, [Cutscene_UpgradeData("fxType", "transitionType", game_data.z64.enumData.ootEnumCsTransitionType)] + csListProp, [Cutscene_UpgradeData("fxType", "transitionType", GD.game_data.z64.enumData.ootEnumCsTransitionType)] ) @@ -223,7 +223,7 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): transferOldDataToNew(csProp, csPropOldToNew) convertOldDataToEnumData( - csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", game_data.z64.enumData.ootEnumCsDestination)] + csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", GD.game_data.z64.enumData.ootEnumCsDestination)] ) @@ -242,7 +242,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): if "actor_id" in legacyData: index = legacyData["actor_id"] if index >= 0: - cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] + cmdEnum = GD.game_data.z64.enumData.enumByKey["csCmd"] cmdType = cmdEnum.item_by_index.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key @@ -263,7 +263,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): del legacyData["start_frame"] if "action_id" in legacyData: - playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] + playerEnum = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"] item = None if isPlayer: item = playerEnum.item_by_index.get(int(legacyData["action_id"], base=16)) @@ -315,7 +315,7 @@ def upgradeActors(actorObj: Object): isCustom = actorObj.ootEntranceProperty.customActor else: if "actorID" in actorProp: - actorProp.actor_id = game_data.z64.actorData.ootEnumActorID[actorProp["actorID"]][0] + actorProp.actor_id = GD.game_data.z64.actorData.ootEnumActorID[actorProp["actorID"]][0] del actorProp["actorID"] if "actorIDCustom" in actorProp: diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index e00269687..5294d497f 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -31,22 +31,14 @@ if TYPE_CHECKING: from .scene.properties import OOT_BootupSceneOptions, Z64_SceneHeaderProperty - from .actor.properties import OOTActorProperty + from .actor.properties import Z64_ActorProperty def get_game_prop_name(prop_type: str): game_prop_name_map = { "OOT": { - "global_obj": "globalObject", - "skybox_id": "skyboxID", - "skybox_config": "skyboxCloudiness", - "seq_id": "musicSeq", - "ambience_id": "nightSeq", "draw_config": "drawConfig", "object_key": "objectKey", - "room_type": "roomBehaviour", - "environment_type": "linkIdleMode", - "actor_id": "actor_id", "floor_property": "floorSetting", "floor_type": "floorProperty", "floor_effect": "terrain", @@ -54,16 +46,8 @@ def get_game_prop_name(prop_type: str): "cam_setting_type": "camSType", }, "MM": { - "global_obj": "mm_global_obj", - "skybox_id": "mm_skybox_id", - "skybox_config": "mm_skybox_config", - "seq_id": "mm_seq_id", - "ambience_id": "mm_ambience_id", "draw_config": "mm_draw_config", "object_key": "mm_object_key", - "room_type": "mm_room_type", - "environment_type": "mm_environment_type", - "actor_id": "mm_actor_id", "floor_property": "mm_floor_property", "floor_type": "mm_floor_type", "floor_effect": "mm_floor_effect", @@ -1283,9 +1267,9 @@ def get_new_empty_object(name: str): return new_obj -def get_actor_prop_from_obj(actor_obj: Object) -> "OOTActorProperty": +def get_actor_prop_from_obj(actor_obj: Object) -> "Z64_ActorProperty": """ - Returns the reference to `OOTActorProperty` + Returns the reference to `Z64_ActorProperty` Parameters: - `actor_obj`: the Blender object to use to find the actor properties From 84fac6796ffcc7745e8ba1f4ff6fdd0b571e7304 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:32:12 +0100 Subject: [PATCH 062/126] format --- .../z64/cutscene/motion/properties.py | 4 +--- fast64_internal/z64/cutscene/properties.py | 8 ++------ fast64_internal/z64/importer/scene_header.py | 4 +--- fast64_internal/z64/room/properties.py | 8 ++------ fast64_internal/z64/scene/properties.py | 16 ++++------------ fast64_internal/z64/upgrade.py | 7 +++++-- 6 files changed, 15 insertions(+), 32 deletions(-) diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 19cb0d9c6..dadd80e11 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -31,9 +31,7 @@ def getNextCuesStartFrame(self): class CutsceneCmdActorCueListProperty(PropertyGroup): - commandType: EnumProperty( - items=ootEnumCSActorCueListCommandType, name="CS Actor Cue Command Type", default=1 - ) + commandType: EnumProperty(items=ootEnumCSActorCueListCommandType, name="CS Actor Cue Command Type", default=1) commandTypeCustom: StringProperty(name="CS Actor Cue Command Type Custom") actorCueListToPreview: PointerProperty( type=Object, name="", poll=lambda self, object: self.isActorCueListObj(object, "CS Actor Cue List") diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 6dc393afc..19e563375 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -154,9 +154,7 @@ class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): subprops = ["csSeqID", "startFrame", "endFrame"] csSeqID: EnumProperty(name="Seq ID", items=GD.game_data.z64.enumData.ootEnumSeqId, default=1) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") - csSeqPlayer: EnumProperty( - name="Seq Player", items=GD.game_data.z64.enumData.ootEnumCsFadeOutSeqPlayer, default=1 - ) + csSeqPlayer: EnumProperty(name="Seq Player", items=GD.game_data.z64.enumData.ootEnumCsFadeOutSeqPlayer, default=1) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") def filterProp(self, name, listProp): @@ -355,9 +353,7 @@ def draw_props(self, layout: UILayout): class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") - csDestination: EnumProperty( - name="Destination", items=GD.game_data.z64.enumData.ootEnumCsDestination, default=1 - ) + csDestination: EnumProperty(name="Destination", items=GD.game_data.z64.enumData.ootEnumCsDestination, default=1) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) csLists: CollectionProperty(type=OOTCSListProperty, name="Cutscene Lists") diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 2ba1c67ea..251a045d3 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -541,9 +541,7 @@ def parseSceneCommands( else: enum_id = GD.game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id - setCustomProperty( - sceneHeader, "musicSeq", enum_id, GD.game_data.z64.ootEnumMusicSeq, "musicSeqCustom" - ) + setCustomProperty(sceneHeader, "musicSeq", enum_id, GD.game_data.z64.ootEnumMusicSeq, "musicSeqCustom") command_list.remove(command) elif command == "SCENE_CMD_ROOM_LIST": # Delay until actor cutscenes are processed diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 59a0e2765..a23a77ab8 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -205,12 +205,8 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj # Behavior behaviorBox = layout.column() behaviorBox.box().label(text="Behavior") - drawEnumWithCustom( - behaviorBox, self, "roomBehaviour", "Room Type", "", "roomBehaviourCustom" - ) - drawEnumWithCustom( - behaviorBox, self, "linkIdleMode", "Environment Type", "", "linkIdleModeCustom" - ) + drawEnumWithCustom(behaviorBox, self, "roomBehaviour", "Room Type", "", "roomBehaviourCustom") + drawEnumWithCustom(behaviorBox, self, "linkIdleMode", "Environment Type", "", "linkIdleModeCustom") if is_game_oot(): behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index dede59fe1..427968987 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -437,9 +437,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj general.box().label(text="General") # General - drawEnumWithCustom( - general, self, "globalObject", "Global Object", "", "globalObjectCustom" - ) + drawEnumWithCustom(general, self, "globalObject", "Global Object", "", "globalObjectCustom") if is_game_oot(): drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: @@ -456,19 +454,13 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj prop_split(skyboxAndSound, self, "skybox_texture_id", "Skybox Texture ID") drawEnumWithCustom(skyboxAndSound, self, "skyboxID", "Skybox", "", "skyboxIDCustom") - drawEnumWithCustom( - skyboxAndSound, self, "skyboxCloudiness", "Skybox Config", "", "skyboxCloudinessCustom" - ) - drawEnumWithCustom( - skyboxAndSound, self, "musicSeq", "Music Sequence", "", "musicSeqCustom" - ) + drawEnumWithCustom(skyboxAndSound, self, "skyboxCloudiness", "Skybox Config", "", "skyboxCloudinessCustom") + drawEnumWithCustom(skyboxAndSound, self, "musicSeq", "Music Sequence", "", "musicSeqCustom") musicSearch = skyboxAndSound.operator(OOT_SearchMusicSeqEnumOperator.bl_idname, icon="VIEWZOOM") musicSearch.objName = objName musicSearch.headerIndex = headerIndex if headerIndex is not None else 0 - drawEnumWithCustom( - skyboxAndSound, self, "nightSeq", "Nighttime SFX", "", "nightSeqCustom" - ) + drawEnumWithCustom(skyboxAndSound, self, "nightSeq", "Nighttime SFX", "", "nightSeqCustom") drawEnumWithCustom(skyboxAndSound, self, "audioSessionPreset", "Audio Session Preset", "") # Camera And World Map | Minimap Settings diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 0f0538948..3b758a5c5 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -180,7 +180,9 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox - Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", GD.game_data.z64.enumData.ootEnumOcarinaSongActionId), + Cutscene_UpgradeData( + "ocarinaSongAction", "ocarinaAction", GD.game_data.z64.enumData.ootEnumOcarinaSongActionId + ), Cutscene_UpgradeData("type", "csTextType", GD.game_data.z64.enumData.ootEnumCsTextType), # Seq Cutscene_UpgradeData("value", "csSeqID", GD.game_data.z64.enumData.ootEnumSeqId), @@ -210,7 +212,8 @@ def upgradeCSListProps(csListProp): # both are enums but the item list is different (the old one doesn't have a "custom" entry) convertOldDataToEnumData( - csListProp, [Cutscene_UpgradeData("fxType", "transitionType", GD.game_data.z64.enumData.ootEnumCsTransitionType)] + csListProp, + [Cutscene_UpgradeData("fxType", "transitionType", GD.game_data.z64.enumData.ootEnumCsTransitionType)], ) From 3e645e4eeaa4d2f60204c3f85723311ebdf48430 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:03:21 +0100 Subject: [PATCH 063/126] fix enum issues --- __init__.py | 23 +++++- fast64_internal/data/z64/data.py | 78 +++++++++++++++++-- fast64_internal/z64/actor/operators.py | 4 +- fast64_internal/z64/actor/properties.py | 34 ++++---- .../z64/cutscene/motion/operators.py | 2 +- .../z64/cutscene/motion/properties.py | 4 +- fast64_internal/z64/cutscene/operators.py | 4 +- fast64_internal/z64/cutscene/properties.py | 18 +++-- fast64_internal/z64/exporter/__init__.py | 3 + fast64_internal/z64/object.py | 6 +- fast64_internal/z64/room/operators.py | 2 +- fast64_internal/z64/room/properties.py | 8 +- fast64_internal/z64/scene/operators.py | 3 +- fast64_internal/z64/scene/properties.py | 10 +-- fast64_internal/z64/upgrade.py | 9 +++ 15 files changed, 158 insertions(+), 50 deletions(-) diff --git a/__init__.py b/__init__.py index 7480a241d..d610c58d3 100644 --- a/__init__.py +++ b/__init__.py @@ -362,7 +362,11 @@ def init_game_data(): match bpy.context.scene.gameEditorMode: case "OOT" | "MM": - oot_register(True) + if GD.game_data.z64.status != "registered": + oot_register(True) + GD.game_data.z64.status = "registered" + else: + print("[init_game_data:Info]: Already Registered.") case _: print(f"[init_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") return @@ -370,15 +374,26 @@ def init_game_data(): def destroy_game_data(): match bpy.context.scene.gameEditorMode: case "OOT" | "MM": - oot_unregister(True) + if GD.game_data.z64.status != "unregistered": + oot_unregister(True) + GD.game_data.z64.status = "unregistered" + else: + print("[destroy_game_data:Info]: Already Unregistered.") case _: print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") - try: + if GD.game_data.z64.status == "waiting": init_game_data() - except ValueError: + elif GD.game_data.z64.status == "registered": destroy_game_data() init_game_data() + elif GD.game_data.z64.status == "unregistered": + init_game_data() + else: + raise ValueError(f"ERROR: Unknown operating mode {repr(GD.game_data.z64.status)}") + + if bpy.context.scene.gameEditorMode in {"OOT", "MM"} and GD.game_data.z64.game != bpy.context.scene.gameEditorMode: + raise ValueError("ERROR: Z64 game mismatch.") print(f"[update_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index a91c15ffe..e2b4ca592 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -1,4 +1,6 @@ from dataclasses import dataclass +from typing import Optional +from bpy.types import Context @dataclass @@ -477,16 +479,31 @@ class Z64_Data: """Contains data related to OoT, like actors or objects""" def __init__(self, game: str): + self.status = "waiting" + self.game = game + self.update(None, game, True) # forcing the update as we're in the init function + + def update(self, context: Optional[Context], game: Optional[str], force: bool = False): from .enum_data import Z64_EnumData from .object_data import Z64_ObjectData from .actor_data import Z64_ActorData - self.game = game - self.enumData = Z64_EnumData(game) - self.objectData = Z64_ObjectData(game) - self.actorData = Z64_ActorData(game) + if context is not None: + next_game = context.scene.gameEditorMode + elif game is not None: + next_game = game + else: + raise ValueError("ERROR: invalid values for context and game") + + # don't update if the game is the same (or we don't want to force one) + if not force and next_game == self.game: + return - if game == "OOT": + self.enumData = Z64_EnumData(self.game) + self.objectData = Z64_ObjectData(self.game) + self.actorData = Z64_ActorData(self.game) + + if self.game == "OOT": self.ootEnumMusicSeq = ootEnumMusicSeq self.ootEnumNightSeq = ootEnumNightSeq self.ootEnumGlobalObject = ootEnumGlobalObject @@ -494,7 +511,7 @@ def __init__(self, game: str): self.ootEnumCloudiness = ootEnumCloudiness self.ootEnumLinkIdle = ootEnumLinkIdle self.ootEnumRoomBehaviour = ootEnumRoomBehaviour - else: + elif self.game == "MM": self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id self.ootEnumGlobalObject = mm_enum_global_object @@ -502,3 +519,52 @@ def __init__(self, game: str): self.ootEnumCloudiness = mm_enum_skybox_config self.ootEnumLinkIdle = mm_enum_environment_type self.ootEnumRoomBehaviour = mm_enum_room_type + else: + raise ValueError(f"ERROR: unsupported game {repr(self.game)}") + + def get_enum(self, context, prop_name: str): + self.update(context, None) + + match prop_name: + case "globalObject": + return self.ootEnumGlobalObject + case "skyboxID": + return self.ootEnumSkybox + case "skyboxCloudiness": + return self.ootEnumCloudiness + case "musicSeq": + return self.ootEnumMusicSeq + case "nightSeq": + return self.ootEnumNightSeq + case "roomBehaviour": + return self.ootEnumRoomBehaviour + case "linkIdleMode": + return self.ootEnumLinkIdle + case "actor_id": + return self.actorData.ootEnumActorID + case "chest_content": + return self.actorData.ootEnumChestContent + case "navi_msg_id": + return self.actorData.ootEnumNaviMessageData + case "collectibles": + return self.actorData.ootEnumCollectibleItems + case "objectKey": + return self.objectData.ootEnumObjectKey + case "csDestination": + return self.enumData.ootEnumCsDestination + case "seqId": + return self.enumData.ootEnumSeqId + case "playerCueID": + return self.enumData.ootEnumCsPlayerCueId + case "ocarinaAction": + return self.enumData.ootEnumOcarinaSongActionId + case "csTextType": + return self.enumData.ootEnumCsTextType + case "csSeqPlayer": + return self.enumData.ootEnumCsFadeOutSeqPlayer + case "csMiscType": + return self.enumData.ootEnumCsMiscType + case "transitionType": + return self.enumData.ootEnumCsTransitionType + case _: + raise ValueError(f"ERROR: unknown value {repr(prop_name)}") diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index ee0d7001c..7702a7cfb 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -12,7 +12,7 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_property = "chest_content" bl_options = {"REGISTER", "UNDO"} - chest_content: EnumProperty(items=GD.game_data.z64.actorData.ootEnumChestContent, default="item_heart") + chest_content: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "chest_content"), default=1) obj_name: StringProperty() prop_name: StringProperty() @@ -33,7 +33,7 @@ class OOT_SearchNaviMsgIDEnumOperator(Operator): bl_property = "navi_msg_id" bl_options = {"REGISTER", "UNDO"} - navi_msg_id: EnumProperty(items=GD.game_data.z64.actorData.ootEnumNaviMessageData, default=1) + navi_msg_id: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "navi_msg_id"), default=1) obj_name: StringProperty() prop_name: StringProperty() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 541608dd8..5cf770a44 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -77,25 +77,23 @@ def initOOTActorProperties(): """This function is used to edit the Z64_ActorProperty class""" prop_ats = get_prop_annotations(Z64_ActorProperty) - prop_ats["actor_id"] = EnumProperty( - name="Actor", items=GD.game_data.z64.actorData.ootEnumActorID, default="ACTOR_PLAYER" - ) - param_type_to_enum_items = { - "ChestContent": GD.game_data.z64.actorData.ootEnumChestContent, - "Collectible": GD.game_data.z64.actorData.ootEnumCollectibleItems, - "Message": GD.game_data.z64.actorData.ootEnumNaviMessageData, + "ChestContent": GD.game_data.z64.get_enum(bpy.context, "chest_content"), + "Collectible": GD.game_data.z64.get_enum(bpy.context, "collectibles"), + "Message": GD.game_data.z64.get_enum(bpy.context, "navi_msg_id"), } for actor in GD.game_data.z64.actorData.actorList: for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) enum_items = None + if len(param.items) > 0: enum_items = [(f"0x{val:04X}", name, f"0x{val:04X}") for val, name in param.items] enum_items.insert(0, ("Custom", "Custom Value", "Custom")) elif param.type in {"ChestContent", "Collectible", "Message"}: enum_items = param_type_to_enum_items[param.type] + if param.type in {"Property", "Flag"}: prop_ats[prop_name] = StringProperty(name="", default="0x0") elif param.type == "Bool": @@ -246,6 +244,9 @@ def draw_props( class Z64_ActorProperty(PropertyGroup): + actor_id: EnumProperty( + name="Actor", items=lambda self, context: GD.game_data.z64.get_enum(context, "actor_id"), default="ACTOR_PLAYER" + ) actor_id_custom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") # only used for actors with the id "Custom" @@ -301,6 +302,7 @@ def upgrade_object(obj: Object): upgradeActors(obj) def is_rotation_used(self, target: str): + GD.game_data.z64.update(bpy.context, None) actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: @@ -324,6 +326,7 @@ def is_value_in_range(self, value: int, min: int, max: int): return True def set_param_value(self, base_value: str | bool, target: str): + GD.game_data.z64.update(bpy.context, None) actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] base_value = getEvalParamsInt(base_value) found_type = None @@ -364,6 +367,7 @@ def set_param_value(self, base_value: str | bool, target: str): ) def get_param_value(self, target: str): + GD.game_data.z64.update(bpy.context, None) actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] param_list = [] type_value = None @@ -441,6 +445,7 @@ def get_param_value(self, target: str): return param_str def draw_params(self, layout: UILayout, obj: Object): + GD.game_data.z64.update(bpy.context, None) actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: @@ -501,17 +506,18 @@ def draw_props( return split.label(text="Actor ID") - split.label(text=getEnumName(GD.game_data.z64.actorData.ootEnumActorID, self.actor_id)) + split.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "actor_id"), self.actor_id)) - if self.actor_id != "Custom": - self.draw_params(actorIDBox, owner) - else: - prop_split(actorIDBox, self, "actor_id_custom", "") + if is_game_oot(): + if self.actor_id != "Custom": + self.draw_params(actorIDBox, owner) + else: + prop_split(actorIDBox, self, "actor_id_custom", "") paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if self.actor_id != "Custom": + if is_game_oot() and self.actor_id != "Custom": paramBox.prop(self, "eval_params") paramBox.prop(self, "params", text="") else: @@ -596,7 +602,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - split.label(text=getEnumName(GD.game_data.z64.actorData.ootEnumActorID, self.actor.actor_id)) + split.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "actor_id"), self.actor.actor_id)) if self.actor.actor_id == "Custom": prop_split(actorIDBox, self.actor, "actor_id_custom", "") diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index 179220d60..068bb676a 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -318,7 +318,7 @@ class OOT_SearchPlayerCueIdEnumOperator(Operator): bl_property = "playerCueID" bl_options = {"REGISTER", "UNDO"} - playerCueID: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsPlayerCueId, default=1) + playerCueID: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "playerCueID"), default=1) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index dadd80e11..223f6a0df 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -84,7 +84,7 @@ class CutsceneCmdActorCueProperty(PropertyGroup): get=lambda self: getNextCuesStartFrame(self), ) - playerCueID: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsPlayerCueId, default=1) + playerCueID: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "playerCueID"), default=1) cueActionID: StringProperty( name="Action ID", default="0x0001", description="Actor action. Meaning is unique for each different actor." ) @@ -114,7 +114,7 @@ def draw_props(self, layout: UILayout, labelPrefix: str, isDummy: bool, objName: split = box.split(factor=0.5) searchOp = split.operator(OOT_SearchPlayerCueIdEnumOperator.bl_idname, icon="VIEWZOOM", text=label) searchOp.objName = objName - split.label(text=getEnumName(GD.game_data.z64.enumData.ootEnumCsPlayerCueId, self.playerCueID)) + split.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "playerCueID"), self.playerCueID)) if not isPlayer or self.playerCueID == "Custom": split = box.split(factor=0.5) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index bb3747a7d..b08162b22 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -238,7 +238,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsDestination, default=1) + csDestination: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1) objName: StringProperty() def execute(self, context): @@ -260,7 +260,7 @@ class OOT_SearchCSSeqOperator(Operator): bl_property = "seqId" bl_options = {"REGISTER", "UNDO"} - seqId: EnumProperty(items=GD.game_data.z64.enumData.ootEnumSeqId, default=1) + seqId: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "seqId"), default=1) itemIndex: IntProperty() listType: StringProperty() diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 19e563375..dca44778f 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -1,3 +1,5 @@ +import bpy + from bpy.types import PropertyGroup, Object, UILayout, Scene, Context from bpy.props import StringProperty, EnumProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from bpy.utils import register_class, unregister_class @@ -113,13 +115,13 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): # subprops textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( - name="Ocarina Action", items=GD.game_data.z64.enumData.ootEnumOcarinaSongActionId, default=1 + name="Ocarina Action", items=lambda self, context: GD.game_data.z64.get_enum(context, "ocarinaAction"), default=1 ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") topOptionTextID: StringProperty(name="", default="0x0000") bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") - csTextType: EnumProperty(name="Text Type", items=GD.game_data.z64.enumData.ootEnumCsTextType, default=1) + csTextType: EnumProperty(name="Text Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csTextType"), default=1) csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") def getName(self): @@ -152,9 +154,9 @@ class OOTCSTimeProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] - csSeqID: EnumProperty(name="Seq ID", items=GD.game_data.z64.enumData.ootEnumSeqId, default=1) + csSeqID: EnumProperty(name="Seq ID", items=lambda self, context: GD.game_data.z64.get_enum(context, "seqId"), default=1) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") - csSeqPlayer: EnumProperty(name="Seq Player", items=GD.game_data.z64.enumData.ootEnumCsFadeOutSeqPlayer, default=1) + csSeqPlayer: EnumProperty(name="Seq Player", items=lambda self, context: GD.game_data.z64.get_enum(context, "csSeqPlayer"), default=1) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") def filterProp(self, name, listProp): @@ -169,7 +171,7 @@ def filterName(self, name, listProp): class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] - csMiscType: EnumProperty(name="Type", items=GD.game_data.z64.enumData.ootEnumCsMiscType, default=1) + csMiscType: EnumProperty(name="Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csMiscType"), default=1) csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -195,7 +197,7 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - transitionType: EnumProperty(items=GD.game_data.z64.enumData.ootEnumCsTransitionType, default=1) + transitionType: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "transitionType"), default=1) transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) transitionEndFrame: IntProperty(name="", default=1, min=0) @@ -353,7 +355,7 @@ def draw_props(self, layout: UILayout): class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") - csDestination: EnumProperty(name="Destination", items=GD.game_data.z64.enumData.ootEnumCsDestination, default=1) + csDestination: EnumProperty(name="Destination", items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) csLists: CollectionProperty(type=OOTCSListProperty, name="Cutscene Lists") @@ -403,7 +405,7 @@ def draw_props(self, layout: UILayout, obj: Object): boxRow = searchBox.row() searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") searchOp.objName = obj.name - boxRow.label(text=getEnumName(GD.game_data.z64.enumData.ootEnumCsDestination, self.csDestination)) + boxRow.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "csDestination"), self.csDestination)) if self.csDestination == "Custom": prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") diff --git a/fast64_internal/z64/exporter/__init__.py b/fast64_internal/z64/exporter/__init__.py index d0fec594f..e01c8f310 100644 --- a/fast64_internal/z64/exporter/__init__.py +++ b/fast64_internal/z64/exporter/__init__.py @@ -1,5 +1,6 @@ import bpy import os +import fast64_internal.game_data as GD from mathutils import Matrix from bpy.types import Object @@ -93,6 +94,8 @@ def export(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo): # circular import fixes from .decomp_edit.config import Config + GD.game_data.z64.update(bpy.context, None) + checkObjectReference(originalSceneObj, "Scene object") scene = SceneExport.create_scene(originalSceneObj, transform, exportInfo) diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index 9cf5dea4f..f2378d4a1 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -1,6 +1,8 @@ +import bpy +import fast64_internal.game_data as GD + from bpy.types import Object from ..utility import ootGetSceneOrRoomHeader -import fast64_internal.game_data as GD from .exporter.room.header import RoomHeader @@ -17,6 +19,8 @@ def addMissingObjectToProp(roomObj: Object, headerIndex: int, objectKey: str): def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, headerIndex: int): """Adds missing objects to the object list""" if len(curHeader.actors.actorList) > 0: + GD.game_data.z64.update(bpy.context, None) + for roomActor in curHeader.actors.actorList: actor = GD.game_data.z64.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index c0f8d8fd9..7d7b5864f 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=GD.game_data.z64.objectData.ootEnumObjectKey, default=1) + objectKey: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "objectKey"), default=1) headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index a23a77ab8..7d3d9e6df 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -44,18 +44,20 @@ class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=GD.game_data.z64.objectData.ootEnumObjectKey, default=1) + objectKey: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "objectKey"), default=1) objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod def upgrade_object(obj: Object): if is_game_oot(): print(f"Processing '{obj.name}'...") + GD.game_data.z64.update(bpy.context, None) upgradeRoomHeaders(obj, GD.game_data.z64.objectData) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): is_legacy = True if "objectID" in self else False obj_key: str = getattr(self, get_game_prop_name("object_key")) + GD.game_data.z64.update(bpy.context, None) if is_game_oot() and is_legacy: obj_name = GD.game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] @@ -105,10 +107,10 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=GD.game_data.z64.ootEnumRoomBehaviour, default=1) + roomBehaviour: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "roomBehaviour"), default=1) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Environment Type", items=GD.game_data.z64.ootEnumLinkIdle, default=1) + linkIdleMode: EnumProperty(name="Environment Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "linkIdleMode"), default=1) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") # OoT exclusive diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 99e8672d7..2bba23ef1 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -34,6 +34,7 @@ def dummy_view_layer_update(context): def parseSceneFunc(): + GD.game_data.z64.update(bpy.context, None) settings = bpy.context.scene.ootSceneImportSettings parseScene(settings, settings.option if is_game_oot() else settings.mm_option) @@ -100,7 +101,7 @@ class OOT_SearchMusicSeqEnumOperator(Operator): bl_property = "ootMusicSeq" bl_options = {"REGISTER", "UNDO"} - ootMusicSeq: EnumProperty(items=GD.game_data.z64.ootEnumMusicSeq, default="NA_BGM_FIELD_LOGIC") + ootMusicSeq: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "musicSeq"), default=1) headerIndex: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 427968987..923d11095 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -322,7 +322,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty(name="Global Object", default=1, items=GD.game_data.z64.ootEnumGlobalObject) + globalObject: EnumProperty(name="Global Object", default=1, items=lambda self, context: GD.game_data.z64.get_enum(context, "globalObject")) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") # OoT exclusive @@ -330,9 +330,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skyboxID: EnumProperty(name="Skybox", items=GD.game_data.z64.ootEnumSkybox, default=1) + skyboxID: EnumProperty(name="Skybox", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxID"), default=1) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=GD.game_data.z64.ootEnumCloudiness, default=1) + skyboxCloudiness: EnumProperty(name="Cloudiness", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxCloudiness"), default=1) skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", @@ -348,9 +348,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") # SCENE_CMD_SOUND_SETTINGS - musicSeq: EnumProperty(name="Music Sequence", items=GD.game_data.z64.ootEnumMusicSeq, default=1) + musicSeq: EnumProperty(name="Music Sequence", items=lambda self, context: GD.game_data.z64.get_enum(context, "musicSeq"), default=1) musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=GD.game_data.z64.ootEnumNightSeq, default=1) + nightSeq: EnumProperty(name="Nighttime SFX", items=lambda self, context: GD.game_data.z64.get_enum(context, "nightSeq"), default=1) nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 3b758a5c5..81104e4b1 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -150,6 +150,8 @@ def upgradeCutsceneSubProps(csListSubProp): # ``csListSubProp`` types: OOTCSTextProperty | OOTCSSeqProperty | OOTCSMiscProperty | OOTCSRumbleProperty # based on ``upgradeObjectList`` + GD.game_data.z64.update(bpy.context, None) + subPropsOldToNew = { # TextBox "messageId": "textID", @@ -197,6 +199,8 @@ def upgradeCutsceneSubProps(csListSubProp): def upgradeCSListProps(csListProp): # ``csListProp`` type: ``OOTCSListProperty`` + GD.game_data.z64.update(bpy.context, None) + csListPropOldToNew = { "textbox": "textList", "lighting": "lightSettingsList", @@ -218,6 +222,8 @@ def upgradeCSListProps(csListProp): def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): + GD.game_data.z64.update(bpy.context, None) + csPropOldToNew = { "csWriteTerminator": "csUseDestination", "csTermStart": "csDestinationStartFrame", @@ -233,6 +239,7 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): def upgradeCutsceneMotion(csMotionObj: Object): """Main upgrade logic for Cutscene Motion data from zcamedit""" objName = csMotionObj.name + GD.game_data.z64.update(bpy.context, None) if csMotionObj.type == "EMPTY": csMotionProp = csMotionObj.ootCSMotionProperty @@ -310,6 +317,8 @@ def upgradeCutsceneMotion(csMotionObj: Object): # Actors ##################################### def upgradeActors(actorObj: Object): + GD.game_data.z64.update(bpy.context, None) + # parameters actorProp = get_actor_prop_from_obj(actorObj) isCustom = False From 6348e9e1040440348ef65db3bcde8aeeb0c47ed1 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:03:32 +0100 Subject: [PATCH 064/126] format --- fast64_internal/data/z64/data.py | 2 +- fast64_internal/z64/actor/operators.py | 4 +++- fast64_internal/z64/cutscene/operators.py | 4 +++- fast64_internal/z64/cutscene/properties.py | 28 ++++++++++++++++------ fast64_internal/z64/room/properties.py | 10 ++++++-- fast64_internal/z64/scene/properties.py | 20 ++++++++++++---- 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index e2b4ca592..6551d62a8 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -481,7 +481,7 @@ class Z64_Data: def __init__(self, game: str): self.status = "waiting" self.game = game - self.update(None, game, True) # forcing the update as we're in the init function + self.update(None, game, True) # forcing the update as we're in the init function def update(self, context: Optional[Context], game: Optional[str], force: bool = False): from .enum_data import Z64_EnumData diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 7702a7cfb..19e0c1ee5 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -12,7 +12,9 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_property = "chest_content" bl_options = {"REGISTER", "UNDO"} - chest_content: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "chest_content"), default=1) + chest_content: EnumProperty( + items=lambda self, context: GD.game_data.z64.get_enum(context, "chest_content"), default=1 + ) obj_name: StringProperty() prop_name: StringProperty() diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index b08162b22..a34c69519 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -238,7 +238,9 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1) + csDestination: EnumProperty( + items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1 + ) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index dca44778f..bc61f63ee 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -115,13 +115,17 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): # subprops textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( - name="Ocarina Action", items=lambda self, context: GD.game_data.z64.get_enum(context, "ocarinaAction"), default=1 + name="Ocarina Action", + items=lambda self, context: GD.game_data.z64.get_enum(context, "ocarinaAction"), + default=1, ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") topOptionTextID: StringProperty(name="", default="0x0000") bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") - csTextType: EnumProperty(name="Text Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csTextType"), default=1) + csTextType: EnumProperty( + name="Text Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csTextType"), default=1 + ) csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") def getName(self): @@ -154,9 +158,13 @@ class OOTCSTimeProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] - csSeqID: EnumProperty(name="Seq ID", items=lambda self, context: GD.game_data.z64.get_enum(context, "seqId"), default=1) + csSeqID: EnumProperty( + name="Seq ID", items=lambda self, context: GD.game_data.z64.get_enum(context, "seqId"), default=1 + ) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") - csSeqPlayer: EnumProperty(name="Seq Player", items=lambda self, context: GD.game_data.z64.get_enum(context, "csSeqPlayer"), default=1) + csSeqPlayer: EnumProperty( + name="Seq Player", items=lambda self, context: GD.game_data.z64.get_enum(context, "csSeqPlayer"), default=1 + ) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") def filterProp(self, name, listProp): @@ -171,7 +179,9 @@ def filterName(self, name, listProp): class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] - csMiscType: EnumProperty(name="Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csMiscType"), default=1) + csMiscType: EnumProperty( + name="Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csMiscType"), default=1 + ) csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -197,7 +207,9 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - transitionType: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "transitionType"), default=1) + transitionType: EnumProperty( + items=lambda self, context: GD.game_data.z64.get_enum(context, "transitionType"), default=1 + ) transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) transitionEndFrame: IntProperty(name="", default=1, min=0) @@ -355,7 +367,9 @@ def draw_props(self, layout: UILayout): class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") - csDestination: EnumProperty(name="Destination", items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1) + csDestination: EnumProperty( + name="Destination", items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1 + ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) csLists: CollectionProperty(type=OOTCSListProperty, name="Cutscene Lists") diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 7d3d9e6df..0a9ba013f 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -107,10 +107,16 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "roomBehaviour"), default=1) + roomBehaviour: EnumProperty( + items=lambda self, context: GD.game_data.z64.get_enum(context, "roomBehaviour"), default=1 + ) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") - linkIdleMode: EnumProperty(name="Environment Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "linkIdleMode"), default=1) + linkIdleMode: EnumProperty( + name="Environment Type", + items=lambda self, context: GD.game_data.z64.get_enum(context, "linkIdleMode"), + default=1, + ) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") # OoT exclusive diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 923d11095..d052a779e 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -322,7 +322,9 @@ class Z64_SceneHeaderProperty(PropertyGroup): usePreviousHeader: BoolProperty(name="Use Previous Header", default=True) # SCENE_CMD_SPECIAL_FILES - globalObject: EnumProperty(name="Global Object", default=1, items=lambda self, context: GD.game_data.z64.get_enum(context, "globalObject")) + globalObject: EnumProperty( + name="Global Object", default=1, items=lambda self, context: GD.game_data.z64.get_enum(context, "globalObject") + ) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") # OoT exclusive @@ -330,9 +332,13 @@ class Z64_SceneHeaderProperty(PropertyGroup): naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skyboxID: EnumProperty(name="Skybox", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxID"), default=1) + skyboxID: EnumProperty( + name="Skybox", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxID"), default=1 + ) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") - skyboxCloudiness: EnumProperty(name="Cloudiness", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxCloudiness"), default=1) + skyboxCloudiness: EnumProperty( + name="Cloudiness", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxCloudiness"), default=1 + ) skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( name="Skybox Lighting", @@ -348,9 +354,13 @@ class Z64_SceneHeaderProperty(PropertyGroup): skybox_texture_id: StringProperty(name="Skybox Texture ID", default="0x00") # SCENE_CMD_SOUND_SETTINGS - musicSeq: EnumProperty(name="Music Sequence", items=lambda self, context: GD.game_data.z64.get_enum(context, "musicSeq"), default=1) + musicSeq: EnumProperty( + name="Music Sequence", items=lambda self, context: GD.game_data.z64.get_enum(context, "musicSeq"), default=1 + ) musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") - nightSeq: EnumProperty(name="Nighttime SFX", items=lambda self, context: GD.game_data.z64.get_enum(context, "nightSeq"), default=1) + nightSeq: EnumProperty( + name="Nighttime SFX", items=lambda self, context: GD.game_data.z64.get_enum(context, "nightSeq"), default=1 + ) nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") audioSessionPresetCustom: StringProperty(name="Audio Session Preset", default="0x00") From 86b25fffda311294ddf72b60155c20056d8ec21c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:30:49 +0100 Subject: [PATCH 065/126] get rid of GD. --- __init__.py | 23 +++++---- fast64_internal/game_data.py | 11 +++-- fast64_internal/z64/actor/operators.py | 8 ++-- fast64_internal/z64/actor/properties.py | 48 +++++++++---------- fast64_internal/z64/cutscene/classes.py | 10 ++-- fast64_internal/z64/cutscene/constants.py | 4 +- .../z64/cutscene/exporter/classes.py | 8 ++-- .../z64/cutscene/motion/operators.py | 4 +- .../z64/cutscene/motion/properties.py | 6 +-- fast64_internal/z64/cutscene/operators.py | 6 +-- fast64_internal/z64/cutscene/properties.py | 18 +++---- fast64_internal/z64/exporter/__init__.py | 4 +- .../z64/exporter/cutscene/actor_cue.py | 4 +- .../z64/exporter/cutscene/common.py | 4 +- fast64_internal/z64/exporter/cutscene/data.py | 8 ++-- fast64_internal/z64/exporter/room/header.py | 6 +-- fast64_internal/z64/exporter/scene/actors.py | 6 +-- fast64_internal/z64/importer/actor.py | 8 ++-- fast64_internal/z64/importer/room_header.py | 8 ++-- fast64_internal/z64/importer/scene_header.py | 14 +++--- fast64_internal/z64/object.py | 8 ++-- fast64_internal/z64/room/operators.py | 4 +- fast64_internal/z64/room/properties.py | 18 +++---- fast64_internal/z64/scene/operators.py | 6 +-- fast64_internal/z64/scene/properties.py | 12 ++--- fast64_internal/z64/upgrade.py | 30 ++++++------ 26 files changed, 144 insertions(+), 142 deletions(-) diff --git a/__init__.py b/__init__.py index d610c58d3..f7c3b8031 100644 --- a/__init__.py +++ b/__init__.py @@ -1,6 +1,5 @@ import bpy -import fast64_internal.game_data as GD - +from .fast64_internal.game_data import game_data from bpy.utils import register_class, unregister_class from bpy.path import abspath @@ -358,13 +357,13 @@ def update_game_data(): """This function should be called on blend load or game editor update""" def init_game_data(): - GD.game_data = GD.GameData(bpy.context.scene.gameEditorMode) + game_data.update(bpy.context.scene.gameEditorMode) match bpy.context.scene.gameEditorMode: case "OOT" | "MM": - if GD.game_data.z64.status != "registered": + if game_data.z64.status != "registered": oot_register(True) - GD.game_data.z64.status = "registered" + game_data.z64.status = "registered" else: print("[init_game_data:Info]: Already Registered.") case _: @@ -374,25 +373,25 @@ def init_game_data(): def destroy_game_data(): match bpy.context.scene.gameEditorMode: case "OOT" | "MM": - if GD.game_data.z64.status != "unregistered": + if game_data.z64.status != "unregistered": oot_unregister(True) - GD.game_data.z64.status = "unregistered" + game_data.z64.status = "unregistered" else: print("[destroy_game_data:Info]: Already Unregistered.") case _: print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") - if GD.game_data.z64.status == "waiting": + if game_data.z64.status == "waiting": init_game_data() - elif GD.game_data.z64.status == "registered": + elif game_data.z64.status == "registered": destroy_game_data() init_game_data() - elif GD.game_data.z64.status == "unregistered": + elif game_data.z64.status == "unregistered": init_game_data() else: - raise ValueError(f"ERROR: Unknown operating mode {repr(GD.game_data.z64.status)}") + raise ValueError(f"ERROR: Unknown operating mode {repr(game_data.z64.status)}") - if bpy.context.scene.gameEditorMode in {"OOT", "MM"} and GD.game_data.z64.game != bpy.context.scene.gameEditorMode: + if bpy.context.scene.gameEditorMode in {"OOT", "MM"} and game_data.z64.game != bpy.context.scene.gameEditorMode: raise ValueError("ERROR: Z64 game mismatch.") print(f"[update_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") diff --git a/fast64_internal/game_data.py b/fast64_internal/game_data.py index e421c1253..ff3086a3c 100644 --- a/fast64_internal/game_data.py +++ b/fast64_internal/game_data.py @@ -5,11 +5,14 @@ class GameData: def __init__(self, game_editor_mode: Optional[str] = None): from .data import Z64_Data + self.z64 = Z64_Data("OOT") + + if game_editor_mode is not None: + self.update(game_editor_mode) + + def update(self, game_editor_mode: str): if game_editor_mode is not None and game_editor_mode in {"OOT", "MM"}: - self.z64 = Z64_Data(game_editor_mode) - else: - # default value to avoid issues - self.z64 = Z64_Data("OOT") + self.z64.update(None, game_editor_mode, True) game_data = GameData() diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 19e0c1ee5..4b30d5975 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -3,7 +3,7 @@ from bpy.props import EnumProperty, StringProperty from bpy.utils import register_class, unregister_class from ...utility import PluginError -import fast64_internal.game_data as GD +from ...game_data import game_data class OOT_SearchChestContentEnumOperator(Operator): @@ -13,7 +13,7 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_options = {"REGISTER", "UNDO"} chest_content: EnumProperty( - items=lambda self, context: GD.game_data.z64.get_enum(context, "chest_content"), default=1 + items=lambda self, context: game_data.z64.get_enum(context, "chest_content"), default=1 ) obj_name: StringProperty() prop_name: StringProperty() @@ -35,7 +35,7 @@ class OOT_SearchNaviMsgIDEnumOperator(Operator): bl_property = "navi_msg_id" bl_options = {"REGISTER", "UNDO"} - navi_msg_id: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "navi_msg_id"), default=1) + navi_msg_id: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "navi_msg_id"), default=1) obj_name: StringProperty() prop_name: StringProperty() @@ -56,7 +56,7 @@ class OOT_SearchActorIDEnumOperator(Operator): bl_property = "actor_id" bl_options = {"REGISTER", "UNDO"} - actor_id: EnumProperty(items=lambda self, context: GD.game_data.z64.actorData.getItems(self.actor_user)) + actor_id: EnumProperty(items=lambda self, context: game_data.z64.actorData.getItems(self.actor_user)) actor_user: StringProperty(default="Actor") obj_name: StringProperty() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 5cf770a44..e032f65f6 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, StringProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty from ...utility import PluginError, prop_split, label_split, get_prop_annotations -import fast64_internal.game_data as GD +from ...game_data import game_data from ..constants import ootEnumCamTransition from ..upgrade import upgradeActors from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -78,12 +78,12 @@ def initOOTActorProperties(): prop_ats = get_prop_annotations(Z64_ActorProperty) param_type_to_enum_items = { - "ChestContent": GD.game_data.z64.get_enum(bpy.context, "chest_content"), - "Collectible": GD.game_data.z64.get_enum(bpy.context, "collectibles"), - "Message": GD.game_data.z64.get_enum(bpy.context, "navi_msg_id"), + "ChestContent": game_data.z64.get_enum(bpy.context, "chest_content"), + "Collectible": game_data.z64.get_enum(bpy.context, "collectibles"), + "Message": game_data.z64.get_enum(bpy.context, "navi_msg_id"), } - for actor in GD.game_data.z64.actorData.actorList: + for actor in game_data.z64.actorData.actorList: for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) enum_items = None @@ -245,7 +245,7 @@ def draw_props( class Z64_ActorProperty(PropertyGroup): actor_id: EnumProperty( - name="Actor", items=lambda self, context: GD.game_data.z64.get_enum(context, "actor_id"), default="ACTOR_PLAYER" + name="Actor", items=lambda self, context: game_data.z64.get_enum(context, "actor_id"), default=1 ) actor_id_custom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") @@ -302,8 +302,8 @@ def upgrade_object(obj: Object): upgradeActors(obj) def is_rotation_used(self, target: str): - GD.game_data.z64.update(bpy.context, None) - actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] + game_data.z64.update(bpy.context, None) + actor = game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: if param.type == "Type": @@ -326,8 +326,8 @@ def is_value_in_range(self, value: int, min: int, max: int): return True def set_param_value(self, base_value: str | bool, target: str): - GD.game_data.z64.update(bpy.context, None) - actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] + game_data.z64.update(bpy.context, None) + actor = game_data.z64.actorData.actorsByID[self.actor_id] base_value = getEvalParamsInt(base_value) found_type = None for param in actor.params: @@ -346,11 +346,11 @@ def set_param_value(self, base_value: str | bool, target: str): if is_in_range and (found_type_in_tied_types or len(param.tiedTypes) == 0): prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) if param.type == "ChestContent": - prop_value = GD.game_data.z64.actorData.chestItemByValue[value].key + prop_value = game_data.z64.actorData.chestItemByValue[value].key elif param.type == "Collectible": - prop_value = GD.game_data.z64.actorData.collectibleItemsByValue[value].key + prop_value = game_data.z64.actorData.collectibleItemsByValue[value].key elif param.type == "Message": - prop_value = GD.game_data.z64.actorData.messageItemsByValue[value].key + prop_value = game_data.z64.actorData.messageItemsByValue[value].key elif param.type == "Bool": prop_value = bool(value) else: @@ -367,8 +367,8 @@ def set_param_value(self, base_value: str | bool, target: str): ) def get_param_value(self, target: str): - GD.game_data.z64.update(bpy.context, None) - actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] + game_data.z64.update(bpy.context, None) + actor = game_data.z64.actorData.actorsByID[self.actor_id] param_list = [] type_value = None have_custom_value = False @@ -399,11 +399,11 @@ def get_param_value(self, target: str): else: param_val = 0 if param.type == "ChestContent": - param_val = GD.game_data.z64.actorData.chestItemByKey[cur_prop_value].value + param_val = game_data.z64.actorData.chestItemByKey[cur_prop_value].value elif param.type == "Collectible": - param_val = GD.game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value + param_val = game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value elif param.type == "Message": - param_val = GD.game_data.z64.actorData.messageItemsByKey[cur_prop_value].value + param_val = game_data.z64.actorData.messageItemsByKey[cur_prop_value].value if "Rot" in target: type_value = getEvalParamsInt(getattr(self, get_prop_name(actor.key, "Type", None, 1))) if type_value is not None and type_value in param.tiedTypes or len(param.tiedTypes) == 0: @@ -445,8 +445,8 @@ def get_param_value(self, target: str): return param_str def draw_params(self, layout: UILayout, obj: Object): - GD.game_data.z64.update(bpy.context, None) - actor = GD.game_data.z64.actorData.actorsByID[self.actor_id] + game_data.z64.update(bpy.context, None) + actor = game_data.z64.actorData.actorsByID[self.actor_id] selected_type = None for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) @@ -465,11 +465,11 @@ def draw_params(self, layout: UILayout, obj: Object): if param.type == "ChestContent": search_op = layout.operator(OOT_SearchChestContentEnumOperator.bl_idname) label_name = "Chest Content" - item_map = GD.game_data.z64.actorData.chestItemByKey + item_map = game_data.z64.actorData.chestItemByKey else: search_op = layout.operator(OOT_SearchNaviMsgIDEnumOperator.bl_idname) label_name = "Navi Message ID" - item_map = GD.game_data.z64.actorData.messageItemsByKey + item_map = game_data.z64.actorData.messageItemsByKey search_op.obj_name = obj.name search_op.prop_name = prop_name if key != "Custom": @@ -506,7 +506,7 @@ def draw_props( return split.label(text="Actor ID") - split.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "actor_id"), self.actor_id)) + split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "actor_id"), self.actor_id)) if is_game_oot(): if self.actor_id != "Custom": @@ -602,7 +602,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - split.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "actor_id"), self.actor.actor_id)) + split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "actor_id"), self.actor.actor_id)) if self.actor.actor_id == "Custom": prop_split(actorIDBox, self.actor, "actor_id_custom", "") diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 4c17f19ef..65a475246 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from bpy.types import Object from typing import Optional -import fast64_internal.game_data as GD +from ...game_data import game_data from ..utility import is_oot_features, is_game_oot from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger @@ -44,7 +44,7 @@ def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): # remove `cs` and lowercase first letter enumKey = enumKey[2].lower() + enumKey[3:] - enum = GD.game_data.z64.enumData.enumByKey[enumKey] + enum = game_data.z64.enumData.enumByKey[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -196,7 +196,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key + self.commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -844,7 +844,7 @@ def getNewCutsceneObject(self, name: str, frameCount: int, parentObj: Object): def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Object): newActorCueListObj = self.getNewEmptyObject(name, False, parentObj) newActorCueListObj.ootEmptyType = f"CS {'Player' if 'Player' in name else 'Actor'} Cue List" - cmdEnum = GD.game_data.z64.enumData.enumByKey["csCmd"] + cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] if commandType == "Player": commandType = "player_cue" @@ -885,7 +885,7 @@ def getNewActorCueObject( item = None if isPlayer: - playerEnum = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] if isinstance(actionID, int): item = playerEnum.item_by_index.get(actionID) else: diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 21c7d5de2..f48b06502 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -1,4 +1,4 @@ -import fast64_internal.game_data as GD +from ...game_data import game_data from .classes import ( CutsceneCmdActorCueList, CutsceneCmdActorCue, @@ -141,7 +141,7 @@ ] ootEnumCSActorCueListCommandType = [ - item for item in GD.game_data.z64.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] + item for item in game_data.z64.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] ] ootEnumCSActorCueListCommandType.sort() ootEnumCSActorCueListCommandType.insert(0, ("Custom", "Custom", "Custom")) diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index 713c67082..7f8125420 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object from ....utility import PluginError, indent -import fast64_internal.game_data as GD +from ....game_data import game_data from ..constants import ootEnumCSListTypeListC if TYPE_CHECKING: @@ -40,7 +40,7 @@ class CutsceneCmdToC: """This class contains functions to create the cutscene commands""" def getEnumValue(self, enumKey: str, owner, propName: str): - item = GD.game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def getGenericListCmd(self, cmdName: str, entryTotal: int): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index 068bb676a..4b49e2cc8 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -4,7 +4,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty from ....utility import PluginError -import fast64_internal.game_data as GD +from ....game_data import game_data from ..classes import CutsceneObjectFactory from ..constants import ootEnumCSActorCueListCommandType from ..preview import initFirstFrame, setupCompositorNodes @@ -318,7 +318,7 @@ class OOT_SearchPlayerCueIdEnumOperator(Operator): bl_property = "playerCueID" bl_options = {"REGISTER", "UNDO"} - playerCueID: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "playerCueID"), default=1) + playerCueID: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "playerCueID"), default=1) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 223f6a0df..7b01d4ddf 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...upgrade import upgradeCutsceneMotion from ...utility import getEnumName -import fast64_internal.game_data as GD +from ....game_data import game_data from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType from .operators import ( @@ -84,7 +84,7 @@ class CutsceneCmdActorCueProperty(PropertyGroup): get=lambda self: getNextCuesStartFrame(self), ) - playerCueID: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "playerCueID"), default=1) + playerCueID: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "playerCueID"), default=1) cueActionID: StringProperty( name="Action ID", default="0x0001", description="Actor action. Meaning is unique for each different actor." ) @@ -114,7 +114,7 @@ def draw_props(self, layout: UILayout, labelPrefix: str, isDummy: bool, objName: split = box.split(factor=0.5) searchOp = split.operator(OOT_SearchPlayerCueIdEnumOperator.bl_idname, icon="VIEWZOOM", text=label) searchOp.objName = objName - split.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "playerCueID"), self.playerCueID)) + split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "playerCueID"), self.playerCueID)) if not isPlayer or self.playerCueID == "Custom": split = box.split(factor=0.5) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index a34c69519..69af63d64 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -9,7 +9,7 @@ from bpy.utils import register_class, unregister_class from ...utility import CData, PluginError, writeCData, raisePluginError from ..utility import getCollection -import fast64_internal.game_data as GD +from ...game_data import game_data from .constants import ootEnumCSTextboxType, ootEnumCSListType from .importer import importCutsceneData from .exporter import getNewCutsceneExport @@ -239,7 +239,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_options = {"REGISTER", "UNDO"} csDestination: EnumProperty( - items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1 + items=lambda self, context: game_data.z64.get_enum(context, "csDestination"), default=1 ) objName: StringProperty() @@ -262,7 +262,7 @@ class OOT_SearchCSSeqOperator(Operator): bl_property = "seqId" bl_options = {"REGISTER", "UNDO"} - seqId: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "seqId"), default=1) + seqId: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "seqId"), default=1) itemIndex: IntProperty() listType: StringProperty() diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index bc61f63ee..e6194546d 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName -import fast64_internal.game_data as GD +from ...game_data import game_data from ..upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty from .operators import OOTCSTextAdd, OOT_SearchCSDestinationEnumOperator, OOTCSListAdd, OOT_SearchCSSeqOperator from .motion.preview import previewFrameHandler @@ -116,7 +116,7 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( name="Ocarina Action", - items=lambda self, context: GD.game_data.z64.get_enum(context, "ocarinaAction"), + items=lambda self, context: game_data.z64.get_enum(context, "ocarinaAction"), default=1, ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") @@ -124,7 +124,7 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") csTextType: EnumProperty( - name="Text Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csTextType"), default=1 + name="Text Type", items=lambda self, context: game_data.z64.get_enum(context, "csTextType"), default=1 ) csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") @@ -159,11 +159,11 @@ class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] csSeqID: EnumProperty( - name="Seq ID", items=lambda self, context: GD.game_data.z64.get_enum(context, "seqId"), default=1 + name="Seq ID", items=lambda self, context: game_data.z64.get_enum(context, "seqId"), default=1 ) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") csSeqPlayer: EnumProperty( - name="Seq Player", items=lambda self, context: GD.game_data.z64.get_enum(context, "csSeqPlayer"), default=1 + name="Seq Player", items=lambda self, context: game_data.z64.get_enum(context, "csSeqPlayer"), default=1 ) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") @@ -180,7 +180,7 @@ class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] csMiscType: EnumProperty( - name="Type", items=lambda self, context: GD.game_data.z64.get_enum(context, "csMiscType"), default=1 + name="Type", items=lambda self, context: game_data.z64.get_enum(context, "csMiscType"), default=1 ) csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -208,7 +208,7 @@ class OOTCSListProperty(PropertyGroup): rumbleList: CollectionProperty(type=OOTCSRumbleProperty) transitionType: EnumProperty( - items=lambda self, context: GD.game_data.z64.get_enum(context, "transitionType"), default=1 + items=lambda self, context: game_data.z64.get_enum(context, "transitionType"), default=1 ) transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) @@ -368,7 +368,7 @@ class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") csDestination: EnumProperty( - name="Destination", items=lambda self, context: GD.game_data.z64.get_enum(context, "csDestination"), default=1 + name="Destination", items=lambda self, context: game_data.z64.get_enum(context, "csDestination"), default=1 ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) @@ -419,7 +419,7 @@ def draw_props(self, layout: UILayout, obj: Object): boxRow = searchBox.row() searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") searchOp.objName = obj.name - boxRow.label(text=getEnumName(GD.game_data.z64.get_enum(bpy.context, "csDestination"), self.csDestination)) + boxRow.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "csDestination"), self.csDestination)) if self.csDestination == "Custom": prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") diff --git a/fast64_internal/z64/exporter/__init__.py b/fast64_internal/z64/exporter/__init__.py index e01c8f310..e9ed576c6 100644 --- a/fast64_internal/z64/exporter/__init__.py +++ b/fast64_internal/z64/exporter/__init__.py @@ -1,6 +1,6 @@ import bpy import os -import fast64_internal.game_data as GD +from ...game_data import game_data from mathutils import Matrix from bpy.types import Object @@ -94,7 +94,7 @@ def export(originalSceneObj: Object, transform: Matrix, exportInfo: ExportInfo): # circular import fixes from .decomp_edit.config import Config - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) checkObjectReference(originalSceneObj, "Scene object") scene = SceneExport.create_scene(originalSceneObj, transform, exportInfo) diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index 80063598e..695a7c19a 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field from ....utility import PluginError, indent -import fast64_internal.game_data as GD +from ....game_data import game_data from ...cutscene.motion.utility import getRotation, getInteger from .common import CutsceneCmdBase @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_id[commandType].key + commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index fa0778d91..02c4f6836 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional from ....utility import PluginError, indent -import fast64_internal.game_data as GD +from ....game_data import game_data from ...cutscene.motion.utility import getInteger @@ -20,7 +20,7 @@ def validateFrames(self, checkEndFrame: bool = True): @staticmethod def getEnumValue(enumKey: str, value: str, isSeqLegacy: bool = False): - enum = GD.game_data.z64.enumData.enumByKey[enumKey] + enum = game_data.z64.enumData.enumByKey[enumKey] item = enum.item_by_id.get(value) if item is None: setting = getInteger(value) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 76eb047d8..080d0b9f5 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError -import fast64_internal.game_data as GD +from ....game_data import game_data from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction @@ -142,7 +142,7 @@ def getOoTPosition(self, pos): return [x, y, z] def getEnumValueFromProp(self, enumKey: str, owner, propName: str): - item = GD.game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): @@ -169,7 +169,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = GD.game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +183,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 42a14b1d2..cba99e199 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, getEvalParams, get_game_prop_name, is_game_oot -import fast64_internal.game_data as GD +from ....game_data import game_data from ...constants import halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits from ...room.properties import Z64_RoomHeaderProperty from ...actor.properties import Z64_ActorProperty @@ -123,7 +123,7 @@ def new(name: str, props: Optional[Z64_RoomHeaderProperty]): if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objectList.append(GD.game_data.z64.objectData.objects_by_key[objProp.objectKey].id) + objectList.append(game_data.z64.objectData.objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -256,7 +256,7 @@ def new( actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actor.name = ( - GD.game_data.z64.actorData.actorsByID[actor_id].name.replace( + game_data.z64.actorData.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index f685be4b2..14149d981 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -4,7 +4,7 @@ from bpy.types import Object from ....utility import PluginError, CData, indent from ...utility import getObjectList, is_oot_features, is_game_oot -import fast64_internal.game_data as GD +from ....game_data import game_data from ...actor.properties import Z64_ActorProperty from ..utility import Utility from ..actor import Actor @@ -82,7 +82,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.id = actor_id transActor.name = ( - GD.game_data.z64.actorData.actorsByID[actor_id].name.replace( + game_data.z64.actorData.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" @@ -158,7 +158,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor = EntranceActor() entranceActor.name = ( - GD.game_data.z64.actorData.actorsByID[actor_id].name.replace( + game_data.z64.actorData.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 5581ec862..bbc09067d 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -3,7 +3,7 @@ from bpy.types import Object from ...utility import parentObject, hexOrDecInt -import fast64_internal.game_data as GD +from ...game_data import game_data from ..scene.properties import Z64_SceneHeaderProperty from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_prop_name from ..constants import ( @@ -100,7 +100,7 @@ def parseTransActorList( actorProp, "actor_id", actorID, - GD.game_data.z64.actorData.ootEnumActorID, + game_data.z64.actorData.ootEnumActorID, "actorIDCustom", ) if actorProp.actor_id != "Custom": @@ -209,7 +209,7 @@ def parseSpawnList( actorProp, "actor_id", actorID, - GD.game_data.z64.actorData.ootEnumActorID, + game_data.z64.actorData.ootEnumActorID, "actor_id_custom", ) if actorProp.actor_id != "Custom": @@ -285,7 +285,7 @@ def parseActorList( actorProp, "actor_id", actorID, - GD.game_data.z64.actorData.ootEnumActorID, + game_data.z64.actorData.ootEnumActorID, "actor_id_custom", ) actorProp.actorParam = actorParam diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 543384e4c..ca11459ef 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -2,7 +2,7 @@ import re from ...utility import hexOrDecInt -import fast64_internal.game_data as GD +from ...game_data import game_data from ..utility import ( setCustomProperty, is_game_oot, @@ -24,7 +24,7 @@ def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectLi for object in objects: objectProp = roomHeader.objectList.add() - objByID = GD.game_data.z64.objectData.objects_by_id.get(object) + objByID = game_data.z64.objectData.objects_by_id.get(object) if objByID is not None: setattr(objectProp, get_game_prop_name("object_key"), objByID.key) @@ -77,14 +77,14 @@ def parseRoomCommands( roomHeader, "roomBehaviour", args[0], - GD.game_data.z64.ootEnumRoomBehaviour, + game_data.z64.ootEnumRoomBehaviour, "roomBehaviourCustom", ) setCustomProperty( roomHeader, "linkIdleMode", args[1], - GD.game_data.z64.ootEnumLinkIdle, + game_data.z64.ootEnumLinkIdle, "linkIdleModeCustom", ) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 251a045d3..a7c11d198 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -6,7 +6,7 @@ from bpy.types import Object from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse -import fast64_internal.game_data as GD +from ...game_data import game_data from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext from ..scene.properties import Z64_SceneHeaderProperty, Z64_LightProperty @@ -532,16 +532,16 @@ def parseSceneCommands( sceneHeader, "nightSeq", args[1], - GD.game_data.z64.ootEnumNightSeq, + game_data.z64.ootEnumNightSeq, "nightSeqCustom", ) if args[2].startswith("NA_BGM_"): enum_id = args[2] else: - enum_id = GD.game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id + enum_id = game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id - setCustomProperty(sceneHeader, "musicSeq", enum_id, GD.game_data.z64.ootEnumMusicSeq, "musicSeqCustom") + setCustomProperty(sceneHeader, "musicSeq", enum_id, game_data.z64.ootEnumMusicSeq, "musicSeqCustom") command_list.remove(command) elif command == "SCENE_CMD_ROOM_LIST": # Delay until actor cutscenes are processed @@ -572,7 +572,7 @@ def parseSceneCommands( sceneHeader, "globalObject", args[1], - GD.game_data.z64.ootEnumGlobalObject, + game_data.z64.ootEnumGlobalObject, "globalObjectCustom", ) command_list.remove(command) @@ -595,14 +595,14 @@ def parseSceneCommands( sceneHeader, "skyboxID", args[args_index], - GD.game_data.z64.ootEnumSkybox, + game_data.z64.ootEnumSkybox, "skyboxIDCustom", ) setCustomProperty( sceneHeader, "skyboxCloudiness", args[args_index + 1], - GD.game_data.z64.ootEnumCloudiness, + game_data.z64.ootEnumCloudiness, "skyboxCloudinessCustom", ) setCustomProperty(sceneHeader, "skyboxLighting", args[args_index + 2], ootEnumSkyboxLighting) diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index f2378d4a1..e42811fd8 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -1,5 +1,5 @@ import bpy -import fast64_internal.game_data as GD +from ..game_data import game_data from bpy.types import Object from ..utility import ootGetSceneOrRoomHeader @@ -19,14 +19,14 @@ def addMissingObjectToProp(roomObj: Object, headerIndex: int, objectKey: str): def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, headerIndex: int): """Adds missing objects to the object list""" if len(curHeader.actors.actorList) > 0: - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) for roomActor in curHeader.actors.actorList: - actor = GD.game_data.z64.actorData.actorsByID.get(roomActor.id) + actor = game_data.z64.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: if objKey not in ["obj_gameplay_keep", "obj_gameplay_field_keep", "obj_gameplay_dangeon_keep"]: - objID = GD.game_data.z64.objectData.objects_by_key[objKey].id + objID = game_data.z64.objectData.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) addMissingObjectToProp(roomObj, headerIndex, objKey) diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index 7d7b5864f..b16c5c299 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -3,7 +3,7 @@ from bpy.utils import register_class, unregister_class from bpy.props import EnumProperty, IntProperty, StringProperty from ...utility import ootGetSceneOrRoomHeader -import fast64_internal.game_data as GD +from ...game_data import game_data class OOT_SearchObjectEnumOperator(Operator): @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "objectKey"), default=1) + objectKey: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "objectKey"), default=1) headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 0a9ba013f..67a057488 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -2,7 +2,7 @@ from bpy.types import PropertyGroup, UILayout, Image, Object, Context from bpy.utils import register_class, unregister_class from ...utility import prop_split -import fast64_internal.game_data as GD +from ...game_data import game_data from ..utility import ( drawCollectionOps, onMenuTabChange, @@ -44,25 +44,25 @@ class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "objectKey"), default=1) + objectKey: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "objectKey"), default=1) objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod def upgrade_object(obj: Object): if is_game_oot(): print(f"Processing '{obj.name}'...") - GD.game_data.z64.update(bpy.context, None) - upgradeRoomHeaders(obj, GD.game_data.z64.objectData) + game_data.z64.update(bpy.context, None) + upgradeRoomHeaders(obj, game_data.z64.objectData) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): is_legacy = True if "objectID" in self else False obj_key: str = getattr(self, get_game_prop_name("object_key")) - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) if is_game_oot() and is_legacy: - obj_name = GD.game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + obj_name = game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] elif obj_key != "Custom": - obj_name = GD.game_data.z64.objectData.objects_by_key[obj_key].name + obj_name = game_data.z64.objectData.objects_by_key[obj_key].name else: obj_name = self.objectIDCustom @@ -108,13 +108,13 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) roomBehaviour: EnumProperty( - items=lambda self, context: GD.game_data.z64.get_enum(context, "roomBehaviour"), default=1 + items=lambda self, context: game_data.z64.get_enum(context, "roomBehaviour"), default=1 ) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") linkIdleMode: EnumProperty( name="Environment Type", - items=lambda self, context: GD.game_data.z64.get_enum(context, "linkIdleMode"), + items=lambda self, context: game_data.z64.get_enum(context, "linkIdleMode"), default=1, ) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 2bba23ef1..07ab149ce 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -10,7 +10,7 @@ from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot -import fast64_internal.game_data as GD +from ...game_data import game_data from ..constants import ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene from ..exporter.decomp_edit.config import Config @@ -34,7 +34,7 @@ def dummy_view_layer_update(context): def parseSceneFunc(): - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) settings = bpy.context.scene.ootSceneImportSettings parseScene(settings, settings.option if is_game_oot() else settings.mm_option) @@ -101,7 +101,7 @@ class OOT_SearchMusicSeqEnumOperator(Operator): bl_property = "ootMusicSeq" bl_options = {"REGISTER", "UNDO"} - ootMusicSeq: EnumProperty(items=lambda self, context: GD.game_data.z64.get_enum(context, "musicSeq"), default=1) + ootMusicSeq: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "musicSeq"), default=1) headerIndex: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index d052a779e..611e2bdd1 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -12,7 +12,7 @@ from bpy.utils import register_class, unregister_class from ...render_settings import on_update_oot_render_settings from ...utility import prop_split, customExportWarning -import fast64_internal.game_data as GD +from ...game_data import game_data from ..cutscene.constants import ootEnumCSWriteType from ..utility import ( @@ -323,7 +323,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_SPECIAL_FILES globalObject: EnumProperty( - name="Global Object", default=1, items=lambda self, context: GD.game_data.z64.get_enum(context, "globalObject") + name="Global Object", default=1, items=lambda self, context: game_data.z64.get_enum(context, "globalObject") ) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") @@ -333,11 +333,11 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_SKYBOX_SETTINGS skyboxID: EnumProperty( - name="Skybox", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxID"), default=1 + name="Skybox", items=lambda self, context: game_data.z64.get_enum(context, "skyboxID"), default=1 ) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") skyboxCloudiness: EnumProperty( - name="Cloudiness", items=lambda self, context: GD.game_data.z64.get_enum(context, "skyboxCloudiness"), default=1 + name="Cloudiness", items=lambda self, context: game_data.z64.get_enum(context, "skyboxCloudiness"), default=1 ) skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( @@ -355,11 +355,11 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_SOUND_SETTINGS musicSeq: EnumProperty( - name="Music Sequence", items=lambda self, context: GD.game_data.z64.get_enum(context, "musicSeq"), default=1 + name="Music Sequence", items=lambda self, context: game_data.z64.get_enum(context, "musicSeq"), default=1 ) musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") nightSeq: EnumProperty( - name="Nighttime SFX", items=lambda self, context: GD.game_data.z64.get_enum(context, "nightSeq"), default=1 + name="Nighttime SFX", items=lambda self, context: game_data.z64.get_enum(context, "nightSeq"), default=1 ) nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 81104e4b1..48fce99b8 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -6,7 +6,7 @@ from bpy.types import Object, CollectionProperty from ..utility import PluginError from ..data import Z64_ObjectData -import fast64_internal.game_data as GD +from ..game_data import game_data from .utility import getEvalParams, get_actor_prop_from_obj from .cutscene.constants import ootEnumCSMotionCamMode @@ -150,7 +150,7 @@ def upgradeCutsceneSubProps(csListSubProp): # ``csListSubProp`` types: OOTCSTextProperty | OOTCSSeqProperty | OOTCSMiscProperty | OOTCSRumbleProperty # based on ``upgradeObjectList`` - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) subPropsOldToNew = { # TextBox @@ -183,13 +183,13 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox Cutscene_UpgradeData( - "ocarinaSongAction", "ocarinaAction", GD.game_data.z64.enumData.ootEnumOcarinaSongActionId + "ocarinaSongAction", "ocarinaAction", game_data.z64.enumData.ootEnumOcarinaSongActionId ), - Cutscene_UpgradeData("type", "csTextType", GD.game_data.z64.enumData.ootEnumCsTextType), + Cutscene_UpgradeData("type", "csTextType", game_data.z64.enumData.ootEnumCsTextType), # Seq - Cutscene_UpgradeData("value", "csSeqID", GD.game_data.z64.enumData.ootEnumSeqId), + Cutscene_UpgradeData("value", "csSeqID", game_data.z64.enumData.ootEnumSeqId), # Misc - Cutscene_UpgradeData("operation", "csMiscType", GD.game_data.z64.enumData.ootEnumCsMiscType), + Cutscene_UpgradeData("operation", "csMiscType", game_data.z64.enumData.ootEnumCsMiscType), ] transferOldDataToNew(csListSubProp, subPropsOldToNew) @@ -199,7 +199,7 @@ def upgradeCutsceneSubProps(csListSubProp): def upgradeCSListProps(csListProp): # ``csListProp`` type: ``OOTCSListProperty`` - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) csListPropOldToNew = { "textbox": "textList", @@ -217,12 +217,12 @@ def upgradeCSListProps(csListProp): # both are enums but the item list is different (the old one doesn't have a "custom" entry) convertOldDataToEnumData( csListProp, - [Cutscene_UpgradeData("fxType", "transitionType", GD.game_data.z64.enumData.ootEnumCsTransitionType)], + [Cutscene_UpgradeData("fxType", "transitionType", game_data.z64.enumData.ootEnumCsTransitionType)], ) def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) csPropOldToNew = { "csWriteTerminator": "csUseDestination", @@ -232,14 +232,14 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): transferOldDataToNew(csProp, csPropOldToNew) convertOldDataToEnumData( - csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", GD.game_data.z64.enumData.ootEnumCsDestination)] + csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", game_data.z64.enumData.ootEnumCsDestination)] ) def upgradeCutsceneMotion(csMotionObj: Object): """Main upgrade logic for Cutscene Motion data from zcamedit""" objName = csMotionObj.name - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) if csMotionObj.type == "EMPTY": csMotionProp = csMotionObj.ootCSMotionProperty @@ -252,7 +252,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): if "actor_id" in legacyData: index = legacyData["actor_id"] if index >= 0: - cmdEnum = GD.game_data.z64.enumData.enumByKey["csCmd"] + cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] cmdType = cmdEnum.item_by_index.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key @@ -273,7 +273,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): del legacyData["start_frame"] if "action_id" in legacyData: - playerEnum = GD.game_data.z64.enumData.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] item = None if isPlayer: item = playerEnum.item_by_index.get(int(legacyData["action_id"], base=16)) @@ -317,7 +317,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): # Actors ##################################### def upgradeActors(actorObj: Object): - GD.game_data.z64.update(bpy.context, None) + game_data.z64.update(bpy.context, None) # parameters actorProp = get_actor_prop_from_obj(actorObj) @@ -327,7 +327,7 @@ def upgradeActors(actorObj: Object): isCustom = actorObj.ootEntranceProperty.customActor else: if "actorID" in actorProp: - actorProp.actor_id = GD.game_data.z64.actorData.ootEnumActorID[actorProp["actorID"]][0] + actorProp.actor_id = game_data.z64.actorData.ootEnumActorID[actorProp["actorID"]][0] del actorProp["actorID"] if "actorIDCustom" in actorProp: From 53f7f1764ce84e74fa6d89164960264e52a23d6f Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:59:26 +0100 Subject: [PATCH 066/126] cleanup --- __init__.py | 53 +++------------------ fast64_internal/data/z64/data.py | 2 +- fast64_internal/game_data.py | 4 ++ fast64_internal/z64/__init__.py | 56 ++++++++++++++--------- fast64_internal/z64/actor/operators.py | 4 +- fast64_internal/z64/cutscene/operators.py | 4 +- fast64_internal/z64/room/properties.py | 4 +- fast64_internal/z64/upgrade.py | 4 +- 8 files changed, 51 insertions(+), 80 deletions(-) diff --git a/__init__.py b/__init__.py index f7c3b8031..d4ced3860 100644 --- a/__init__.py +++ b/__init__.py @@ -353,53 +353,13 @@ def upgrade_scene_props_node(): bpy.ops.dialog.upgrade_f3d_materials("INVOKE_DEFAULT") -def update_game_data(): - """This function should be called on blend load or game editor update""" - - def init_game_data(): - game_data.update(bpy.context.scene.gameEditorMode) - - match bpy.context.scene.gameEditorMode: - case "OOT" | "MM": - if game_data.z64.status != "registered": - oot_register(True) - game_data.z64.status = "registered" - else: - print("[init_game_data:Info]: Already Registered.") - case _: - print(f"[init_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") - return - - def destroy_game_data(): - match bpy.context.scene.gameEditorMode: - case "OOT" | "MM": - if game_data.z64.status != "unregistered": - oot_unregister(True) - game_data.z64.status = "unregistered" - else: - print("[destroy_game_data:Info]: Already Unregistered.") - case _: - print(f"[destroy_game_data:Info]: Nothing to do for {bpy.context.scene.gameEditorMode}") - - if game_data.z64.status == "waiting": - init_game_data() - elif game_data.z64.status == "registered": - destroy_game_data() - init_game_data() - elif game_data.z64.status == "unregistered": - init_game_data() - else: - raise ValueError(f"ERROR: Unknown operating mode {repr(game_data.z64.status)}") - - if bpy.context.scene.gameEditorMode in {"OOT", "MM"} and game_data.z64.game != bpy.context.scene.gameEditorMode: - raise ValueError("ERROR: Z64 game mismatch.") - - print(f"[update_game_data:Info]: Success! ({bpy.context.scene.gameEditorMode})") - - @bpy.app.handlers.persistent def after_load(_a, _b): - update_game_data() + game_data.update(bpy.context.scene.gameEditorMode) + + if game_data.status != "ready": + oot_register(True, True) + game_data.status = "ready" settings = bpy.context.scene.fast64.settings if any(mat.is_f3d for mat in bpy.data.materials): @@ -438,7 +398,7 @@ def set_game_defaults(scene: bpy.types.Scene, set_ucode=True): def gameEditorUpdate(scene: bpy.types.Scene, _context): - update_game_data() + game_data.update(scene.gameEditorMode) set_game_defaults(scene) # reset `currentCutsceneIndex` when switching games @@ -530,6 +490,7 @@ def unregister(): f3d_writer_unregister() f3d_parser_unregister() sm64_unregister(True) + oot_unregister(True, True) mk64_unregister(True) mat_unregister() bsdf_conv_unregister() diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 6551d62a8..ab1d686e9 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -479,7 +479,6 @@ class Z64_Data: """Contains data related to OoT, like actors or objects""" def __init__(self, game: str): - self.status = "waiting" self.game = game self.update(None, game, True) # forcing the update as we're in the init function @@ -499,6 +498,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = if not force and next_game == self.game: return + self.game = next_game self.enumData = Z64_EnumData(self.game) self.objectData = Z64_ObjectData(self.game) self.actorData = Z64_ActorData(self.game) diff --git a/fast64_internal/game_data.py b/fast64_internal/game_data.py index ff3086a3c..23e33978c 100644 --- a/fast64_internal/game_data.py +++ b/fast64_internal/game_data.py @@ -6,6 +6,7 @@ def __init__(self, game_editor_mode: Optional[str] = None): from .data import Z64_Data self.z64 = Z64_Data("OOT") + self.status = "not ready" if game_editor_mode is not None: self.update(game_editor_mode) @@ -14,5 +15,8 @@ def update(self, game_editor_mode: str): if game_editor_mode is not None and game_editor_mode in {"OOT", "MM"}: self.z64.update(None, game_editor_mode, True) + if game_editor_mode in {"OOT", "MM"} and game_editor_mode != self.z64.game: + raise ValueError(f"ERROR: Z64 game mismatch: {game_editor_mode}, {game_data.z64.game}") + game_data = GameData() diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index abb34b417..264780ec5 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -172,72 +172,87 @@ def oot_panel_unregister(): skeleton_panels_unregister() -def oot_register(registerPanels: bool): +def z64_register_ops(): from .actor.operators import actor_ops_register + + collision_ops_register() + scene_ops_register() + room_ops_register() + actor_ops_register() + anim_ops_register() + skeleton_ops_register() + cutscene_ops_register() + f3d_ops_register() + csMotion_ops_register() + + +def oot_register(registerPanels: bool, register_ops: bool = True): from .actor.properties import actor_props_register oot_operator_register() oot_utility_register() - collision_ops_register() # register first, so panel goes above mat panel - collision_props_register() + collision_props_register() # register first, so panel goes above mat panel cutscene_props_register() - scene_ops_register() scene_props_register() - room_ops_register() room_props_register() - actor_ops_register() actor_props_register() oot_obj_register() spline_props_register() f3d_props_register() - anim_ops_register() - skeleton_ops_register() skeleton_props_register() - cutscene_ops_register() - f3d_ops_register() file_register() anim_props_register() animated_mats_register() actor_cs_register() - csMotion_ops_register() csMotion_props_register() csMotion_panels_register() csMotion_preview_register() cutscene_preview_register() + if register_ops: + z64_register_ops() + if registerPanels: oot_panel_register() -def oot_unregister(unregisterPanels: bool): +def z64_unregister_ops(): from .actor.operators import actor_ops_unregister + + collision_ops_unregister() + scene_ops_unregister() + room_ops_unregister() + actor_ops_unregister() + anim_ops_unregister() + skeleton_ops_unregister() + cutscene_ops_unregister() + f3d_ops_unregister() + csMotion_ops_unregister() + + +def oot_unregister(unregisterPanels: bool, unregister_ops: bool = True): from .actor.properties import actor_props_unregister if unregisterPanels: oot_panel_unregister() + if unregister_ops: + z64_unregister_ops() + actor_cs_unregister() animated_mats_unregister() oot_operator_unregister() oot_utility_unregister() - collision_ops_unregister() # register first, so panel goes above mat panel collision_props_unregister() oot_obj_unregister() cutscene_props_unregister() - scene_ops_unregister() scene_props_unregister() - room_ops_unregister() room_props_unregister() - actor_ops_unregister() actor_props_unregister() spline_props_unregister() f3d_props_unregister() - anim_ops_unregister() - skeleton_ops_unregister() skeleton_props_unregister() - cutscene_ops_unregister() - f3d_ops_unregister() file_unregister() anim_props_unregister() @@ -245,4 +260,3 @@ def oot_unregister(unregisterPanels: bool): csMotion_preview_unregister() csMotion_panels_unregister() csMotion_props_unregister() - csMotion_ops_unregister() diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 4b30d5975..5dcf5f49e 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -12,9 +12,7 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_property = "chest_content" bl_options = {"REGISTER", "UNDO"} - chest_content: EnumProperty( - items=lambda self, context: game_data.z64.get_enum(context, "chest_content"), default=1 - ) + chest_content: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "chest_content"), default=1) obj_name: StringProperty() prop_name: StringProperty() diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index 69af63d64..68bf57d56 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -238,9 +238,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty( - items=lambda self, context: game_data.z64.get_enum(context, "csDestination"), default=1 - ) + csDestination: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "csDestination"), default=1) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 67a057488..85eba1ec5 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -107,9 +107,7 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty( - items=lambda self, context: game_data.z64.get_enum(context, "roomBehaviour"), default=1 - ) + roomBehaviour: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "roomBehaviour"), default=1) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") linkIdleMode: EnumProperty( diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 48fce99b8..253937cef 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -182,9 +182,7 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox - Cutscene_UpgradeData( - "ocarinaSongAction", "ocarinaAction", game_data.z64.enumData.ootEnumOcarinaSongActionId - ), + Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", game_data.z64.enumData.ootEnumOcarinaSongActionId), Cutscene_UpgradeData("type", "csTextType", game_data.z64.enumData.ootEnumCsTextType), # Seq Cutscene_UpgradeData("value", "csSeqID", game_data.z64.enumData.ootEnumSeqId), From 303806667f43c6e73330223b828e9664cce802d0 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 02:24:14 +0100 Subject: [PATCH 067/126] more fixes --- __init__.py | 3 +++ fast64_internal/z64/actor/properties.py | 27 +++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/__init__.py b/__init__.py index d4ced3860..aebf43268 100644 --- a/__init__.py +++ b/__init__.py @@ -361,6 +361,9 @@ def after_load(_a, _b): oot_register(True, True) game_data.status = "ready" + if game_data.status != "ready": + raise ValueError("ERROR: game data is not ready") + settings = bpy.context.scene.fast64.settings if any(mat.is_f3d for mat in bpy.data.materials): check_or_ask_color_management(bpy.context) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index e032f65f6..483232b11 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -58,7 +58,9 @@ ] -def get_prop_name(actor_key: str, param_type: str, param_subtype: str, param_index: int): +def get_prop_name(actor_key: str, param_type: str, param_subtype: str, param_index: int, update: bool = True): + if update: + game_data.z64.update(bpy.context, None) flag_to_prop_suffix = {"Chest": "chestFlag", "Collectible": "collectibleFlag", "Switch": "switchFlag"} param_to_prop_suffix = { "Type": "type", @@ -70,22 +72,22 @@ def get_prop_name(actor_key: str, param_type: str, param_subtype: str, param_ind "Message": "naviMsg", } suffix = param_to_prop_suffix[param_type] if param_type != "Flag" else flag_to_prop_suffix[param_subtype] - return f"{bpy.context.scene.gameEditorMode.lower()}.{actor_key}.{suffix}{param_index}" # e.g.: ``en_test.props1`` + return f"{game_data.z64.game.lower()}.{actor_key}.{suffix}{param_index}" # e.g.: `oot.en_test.props1` -def initOOTActorProperties(): +def create_game_props(): """This function is used to edit the Z64_ActorProperty class""" prop_ats = get_prop_annotations(Z64_ActorProperty) param_type_to_enum_items = { - "ChestContent": game_data.z64.get_enum(bpy.context, "chest_content"), - "Collectible": game_data.z64.get_enum(bpy.context, "collectibles"), - "Message": game_data.z64.get_enum(bpy.context, "navi_msg_id"), + "ChestContent": game_data.z64.actorData.ootEnumChestContent, + "Collectible": game_data.z64.actorData.ootEnumCollectibleItems, + "Message": game_data.z64.actorData.ootEnumNaviMessageData, } for actor in game_data.z64.actorData.actorList: for param in actor.params: - prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) + prop_name = get_prop_name(actor.key, param.type, param.subType, param.index, update=False) enum_items = None if len(param.items) > 0: @@ -696,7 +698,16 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateS def actor_props_register(): - initOOTActorProperties() + # generate props for OoT + game_data.z64.update(None, "OOT", True) + create_game_props() + + # generate props for MM + game_data.z64.update(None, "MM", True) + create_game_props() + + # restore the data for the current game + game_data.z64.update(bpy.context, None, True) for cls in classes: register_class(cls) From 66591b2fab158c57aa9913eccd76fff9b29cebed Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 02:32:31 +0100 Subject: [PATCH 068/126] update the updater (temp) --- addon_updater_ops.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addon_updater_ops.py b/addon_updater_ops.py index 381b02dcc..8f6098ab8 100644 --- a/addon_updater_ops.py +++ b/addon_updater_ops.py @@ -1376,7 +1376,7 @@ def register(bl_info): # https://github.com/Fast-64/fast64 updater.engine = "Github" - updater.user = "Fast-64" + updater.user = "Yanis002" updater.repo = "fast64" # updater.addon = # define at top of module, MUST be done first @@ -1455,7 +1455,7 @@ def register(bl_info): # Note: updater.include_branch_list defaults to ['master'] branch if set to # none. Example targeting another multiple branches allowed to pull from: # updater.include_branch_list = ['master', 'dev'] - updater.include_branch_list = ["main"] + updater.include_branch_list = ["main", "mm_dev"] # Only allow manual install, thus prompting the user to open # the addon's web page to download, specifically: updater.website From c2f29b2a02df18994ad138d533dad0787af1c37e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:00:28 +0100 Subject: [PATCH 069/126] actor cutscene fixes and fix export issues --- .../data/z64/xml/mm_actor_list.xml | 1154 ++++++++--------- fast64_internal/z64/exporter/scene/actors.py | 2 +- fast64_internal/z64/exporter/scene/general.py | 2 +- fast64_internal/z64/importer/scene_header.py | 2 +- fast64_internal/z64/object.py | 2 +- fast64_internal/z64/tools/operators.py | 20 +- 6 files changed, 591 insertions(+), 591 deletions(-) diff --git a/fast64_internal/data/z64/xml/mm_actor_list.xml b/fast64_internal/data/z64/xml/mm_actor_list.xml index 132dc9539..aa0ff6462 100644 --- a/fast64_internal/data/z64/xml/mm_actor_list.xml +++ b/fast64_internal/data/z64/xml/mm_actor_list.xml @@ -43,12 +43,12 @@ for each sub element (of ) mentioned below: - -> used to draw the collectible drop item --> - - - - + + + + - + Large Orange Flame Large Orange Flame @@ -71,7 +71,7 @@ for each sub element (of ) mentioned below: - + Whole Day ('ENDOOR_TYPE_WHOLE_DAY') Locked ('ENDOOR_TYPE_LOCKED') @@ -124,7 +124,7 @@ for each sub element (of ) mentioned below: - + Golden Golden - Appears - Clear Flag @@ -145,47 +145,47 @@ for each sub element (of ) mentioned below: - - - - + + + + - + Regular Large - - + + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + Default Invisible @@ -193,549 +193,549 @@ for each sub element (of ) mentioned below: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 14149d981..938343d84 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -97,7 +97,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): else: transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({transActorProp.cutscene_id} & 0x7F)" - transActor.params = actorProp.actorParam if actorProp.actor_id != "Custom" else actorProp.params_custom + transActor.params = actorProp.params if is_game_oot() and actorProp.actor_id != "Custom" else actorProp.params_custom transActor.roomFrom, transActor.cameraFront = front transActor.roomTo, transActor.cameraBack = back entries.append(transActor) diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index e487eada5..518e396e5 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -286,7 +286,7 @@ def __init__(self, chest_prop: Z64_MapDataChestProperty, scene_obj: Object, tran pos, _, _, _ = Utility.getConvertedTransform(transform, scene_obj, chest_prop.chest_obj, True) self.room_idx = self.get_room_index(chest_prop, scene_obj) - self.chest_flag = int(getEvalParams(chest_prop.chest_obj.ootActorProperty.actorParam), base=0) & 0x1F + self.chest_flag = int(getEvalParams(chest_prop.chest_obj.ootActorProperty.params_custom), base=0) & 0x1F self.pos = pos def get_room_index(self, chest_prop: Z64_MapDataChestProperty, scene_obj: Object) -> int: diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index a7c11d198..c21603b93 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -303,7 +303,7 @@ def parse_mm_map_data_chest( for child_obj in chest_room.children_recursive: if child_obj.type == "EMPTY" and child_obj.ootEmptyType == "Actor": actor_id: str = getattr(child_obj.ootActorProperty, "actor_id") - actor_params = int(getEvalParams(child_obj.ootActorProperty.actorParam), base=0) + actor_params = int(getEvalParams(child_obj.ootActorProperty.params_custom), base=0) if actor_id in {"ACTOR_EN_BOX"}: actor_chest_flag = actor_params & 0x1F diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index e42811fd8..5d01375ad 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -25,7 +25,7 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header actor = game_data.z64.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: - if objKey not in ["obj_gameplay_keep", "obj_gameplay_field_keep", "obj_gameplay_dangeon_keep"]: + if objKey.replace("obj_", "") not in {"gameplay_keep", "gameplay_field_keep", "gameplay_dangeon_keep"}: objID = game_data.z64.objectData.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 38302c68d..1334bafae 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -319,16 +319,16 @@ def execute(self, context: Context): entry_data_map = { # CS Cam ID: [Priority, Length, Script Index, Additional CS ID, End SFX, Custom Value, HUD visibility, End Cam, Letterbox Size] - "CS_CAM_ID_GLOBAL_ITEM_OCARINA": [550, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_ITEM_GET": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_ITEM_BOTTLE": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_ITEM_SHOW": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_WARP_PAD_MOON": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_DEATH": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_REVIVE": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_SONG_WARP": [700, -1, -1, -1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_OCARINA": [550, -1, -1, 1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_GET": [600, -1, -1, 2, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_BOTTLE": [700, -1, -1, 3, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_SHOW": [700, -1, -1, 4, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_WARP_PAD_MOON": [500, -1, -1, 5, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION": [400, -1, -1, 6, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_DEATH": [100, -1, -1, 7, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_REVIVE": [200, -1, -1, 8, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_SONG_WARP": [700, -1, -1, 9, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE": [700, -1, -1, 10, 1, "255", 1, 1, 30], "CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING": [700, -1, -1, -1, 1, "255", 1, 1, 30], } From 076f49f7ecc2572ce408d3fc6da613431a1e84ca Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:19:35 +0100 Subject: [PATCH 070/126] more actor cs export fixes --- .../z64/exporter/scene/actor_cutscene.py | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index bb7e35f51..2b2a6ed1e 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -81,20 +81,26 @@ class SceneActorCutscene: def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: int, empty_type: str, start: int): entries: list[ActorCutscene] = [] obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", empty_type) + processed = [] - for i, obj in enumerate(obj_list, start): + for obj in obj_list: if empty_type == "Actor": header_settings = obj.ootActorProperty.headerSettings else: header_settings = obj.z64_actor_cs_property.header_settings - entries.extend( - [ - ActorCutscene(scene_obj, transform, item, name, i, obj) - for item in obj.z64_actor_cs_property.entries - if Utility.isCurrentHeaderValid(header_settings, header_index) - ] - ) + for i, item in enumerate(obj.z64_actor_cs_property.entries, start): + if Utility.isCurrentHeaderValid(header_settings, header_index): + new_entry = ActorCutscene(scene_obj, transform, item, name, i, obj) + + if new_entry.cs_cam_id not in {"Custom", "Camera", "CS_CAM_ID_NONE"}: + if new_entry.cs_cam_id not in processed: + entries.append(new_entry) + processed.append(new_entry.cs_cam_id) + else: + raise PluginError(f"ERROR: reapeated actor cutscene camera id {repr(new_entry.cs_cam_id)}") + + start += i return entries From 5809867ed95f9d76e17c49f832493224ca43d610 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:55:21 +0100 Subject: [PATCH 071/126] remove get_game_prop_name --- fast64_internal/data/z64/data.py | 448 ++++++++++++++++++ fast64_internal/z64/actor/properties.py | 1 - fast64_internal/z64/collision/constants.py | 363 -------------- .../z64/collision/exporter/classes.py | 10 +- fast64_internal/z64/collision/properties.py | 43 +- fast64_internal/z64/constants.py | 70 --- .../z64/exporter/collision/__init__.py | 10 +- .../z64/exporter/collision/camera.py | 2 +- fast64_internal/z64/exporter/room/header.py | 2 +- fast64_internal/z64/exporter/scene/general.py | 4 +- fast64_internal/z64/importer/actor.py | 2 +- fast64_internal/z64/importer/room_header.py | 3 +- fast64_internal/z64/importer/scene.py | 7 +- .../z64/importer/scene_collision.py | 26 +- fast64_internal/z64/importer/scene_header.py | 1 - fast64_internal/z64/room/properties.py | 3 +- fast64_internal/z64/scene/properties.py | 8 +- fast64_internal/z64/utility.py | 25 - 18 files changed, 496 insertions(+), 532 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index ab1d686e9..955d30e27 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -347,6 +347,113 @@ class Z64_BaseElement: ("GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), ] +ootEnumDrawConfig = [ + ("Custom", "Custom", "Custom"), + ("SDC_DEFAULT", "Default", "Default"), + ("SDC_HYRULE_FIELD", "Hyrule Field (Spot00)", "Spot00"), + ("SDC_KAKARIKO_VILLAGE", "Kakariko Village (Spot01)", "Spot01"), + ("SDC_ZORAS_RIVER", "Zora's River (Spot03)", "Spot03"), + ("SDC_KOKIRI_FOREST", "Kokiri Forest (Spot04)", "Spot04"), + ("SDC_LAKE_HYLIA", "Lake Hylia (Spot06)", "Spot06"), + ("SDC_ZORAS_DOMAIN", "Zora's Domain (Spot07)", "Spot07"), + ("SDC_ZORAS_FOUNTAIN", "Zora's Fountain (Spot08)", "Spot08"), + ("SDC_GERUDO_VALLEY", "Gerudo Valley (Spot09)", "Spot09"), + ("SDC_LOST_WOODS", "Lost Woods (Spot10)", "Spot10"), + ("SDC_DESERT_COLOSSUS", "Desert Colossus (Spot11)", "Spot11"), + ("SDC_GERUDOS_FORTRESS", "Gerudo's Fortress (Spot12)", "Spot12"), + ("SDC_HAUNTED_WASTELAND", "Haunted Wasteland (Spot13)", "Spot13"), + ("SDC_HYRULE_CASTLE", "Hyrule Castle (Spot15)", "Spot15"), + ("SDC_DEATH_MOUNTAIN_TRAIL", "Death Mountain Trail (Spot16)", "Spot16"), + ("SDC_DEATH_MOUNTAIN_CRATER", "Death Mountain Crater (Spot17)", "Spot17"), + ("SDC_GORON_CITY", "Goron City (Spot18)", "Spot18"), + ("SDC_LON_LON_RANCH", "Lon Lon Ranch (Spot20)", "Spot20"), + ("SDC_FIRE_TEMPLE", "Fire Temple (Hidan)", "Hidan"), + ("SDC_DEKU_TREE", "Inside the Deku Tree (Ydan)", "Ydan"), + ("SDC_DODONGOS_CAVERN", "Dodongo's Cavern (Ddan)", "Ddan"), + ("SDC_JABU_JABU", "Inside Jabu Jabu's Belly (Bdan)", "Bdan"), + ("SDC_FOREST_TEMPLE", "Forest Temple (Bmori1)", "Bmori1"), + ("SDC_WATER_TEMPLE", "Water Temple (Mizusin)", "Mizusin"), + ("SDC_SHADOW_TEMPLE_AND_WELL", "Shadow Temple (Hakadan)", "Hakadan"), + ("SDC_SPIRIT_TEMPLE", "Spirit Temple (Jyasinzou)", "Jyasinzou"), + ("SDC_INSIDE_GANONS_CASTLE", "Inside Ganon's Castle (Ganontika)", "Ganontika"), + ("SDC_GERUDO_TRAINING_GROUND", "Gerudo Training Ground (Men)", "Men"), + ("SDC_DEKU_TREE_BOSS", "Gohma's Lair (Ydan Boss)", "Ydan Boss"), + ("SDC_WATER_TEMPLE_BOSS", "Morpha's Lair (Mizusin Bs)", "Mizusin Bs"), + ("SDC_TEMPLE_OF_TIME", "Temple of Time (Tokinoma)", "Tokinoma"), + ("SDC_GROTTOS", "Grottos (Kakusiana)", "Kakusiana"), + ("SDC_CHAMBER_OF_THE_SAGES", "Chamber of the Sages (Kenjyanoma)", "Kenjyanoma"), + ("SDC_GREAT_FAIRYS_FOUNTAIN", "Great Fairy Fountain", "Great Fairy Fountain"), + ("SDC_SHOOTING_GALLERY", "Shooting Gallery (Syatekijyou)", "Syatekijyou"), + ("SDC_CASTLE_COURTYARD_GUARDS", "Castle Hedge Maze (Day) (Hairal Niwa)", "Hairal Niwa"), + ("SDC_OUTSIDE_GANONS_CASTLE", "Ganon's Castle Exterior (Ganon Tou)", "Ganon Tou"), + ("SDC_ICE_CAVERN", "Ice Cavern (Ice Doukuto)", "Ice Doukuto"), + ( + "SDC_GANONS_TOWER_COLLAPSE_EXTERIOR", + "Ganondorf's Death Scene (Tower Escape Exterior) (Ganon Final)", + "Ganon Final", + ), + ("SDC_FAIRYS_FOUNTAIN", "Fairy Fountain", "Fairy Fountain"), + ("SDC_THIEVES_HIDEOUT", "Thieves' Hideout (Gerudoway)", "Gerudoway"), + ("SDC_BOMBCHU_BOWLING_ALLEY", "Bombchu Bowling Alley (Bowling)", "Bowling"), + ("SDC_ROYAL_FAMILYS_TOMB", "Royal Family's Tomb (Hakaana Ouke)", "Hakaana Ouke"), + ("SDC_LAKESIDE_LABORATORY", "Lakeside Laboratory (Hylia Labo)", "Hylia Labo"), + ("SDC_LON_LON_BUILDINGS", "Lon Lon Ranch House & Tower (Souko)", "Souko"), + ("SDC_MARKET_GUARD_HOUSE", "Guard House (Miharigoya)", "Miharigoya"), + ("SDC_POTION_SHOP_GRANNY", "Granny's Potion Shop (Mahouya)", "Mahouya"), + ("SDC_CALM_WATER", "Calm Water", "Calm Water"), + ("SDC_GRAVE_EXIT_LIGHT_SHINING", "Grave Exit Light Shining", "Grave Exit Light Shining"), + ("SDC_BESITU", "Ganondorf Test Room (Besitu)", "Besitu"), + ("SDC_FISHING_POND", "Fishing Pond (Turibori)", "Turibori"), + ("SDC_GANONS_TOWER_COLLAPSE_INTERIOR", "Ganon's Tower (Collapsing) (Ganon Sonogo)", "Ganon Sonogo"), + ("SDC_INSIDE_GANONS_CASTLE_COLLAPSE", "Inside Ganon's Castle (Collapsing) (Ganontika Sonogo)", "Ganontika Sonogo"), +] + +mm_enum_draw_config = [ + ("Custom", "Custom", "Custom"), + ("SCENE_DRAW_CFG_DEFAULT", "Default", "Default"), + ("SCENE_DRAW_CFG_MAT_ANIM", "Material Animated", "Material Animated"), + ("SCENE_DRAW_CFG_NOTHING", "Nothing", "Nothing"), + ("SCENE_DRAW_CFG_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), + ("SCENE_DRAW_CFG_MAT_ANIM_MANUAL_STEP", "Material Animated (manual step)", "Material Animated (manual step)"), +] + +ootEnumCollisionSound = [ + ("Custom", "Custom", "Custom"), + ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), + ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), + ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), + ("SURFACE_MATERIAL_JABU", "Jabu", "Jabu-Jabu flesh (aka Wet Stone)"), + ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), + ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), + ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), + ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), + ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), + ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), + ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), + ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), + ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), + ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), +] + +mm_enum_surface_material = [ + ("Custom", "Custom", "Custom"), + ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), + ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), + ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), + ("SURFACE_MATERIAL_DIRT_SHALLOW", "Shallow Dirt", "Shallow Dirt"), + ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), + ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), + ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), + ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), + ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), + ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), + ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), + ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), + ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), + ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), + ("SURFACE_MATERIAL_SNOW", "Snow", "Snow"), +] + # --- ootEnumSkybox = [ @@ -471,6 +578,325 @@ class Z64_BaseElement: ("ROOM_TYPE_BOSS", "Boss", "0x05"), ] +ootEnumFloorSetting = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "Default"), + ("0x05", "Trigger Respawn", "Trigger Respawn"), + ("0x06", "Grab Wall", "Grab Wall"), + ("0x08", "Stop Air Momentum", "Stop Air Momentum"), + ("0x09", "Fall Instead Of Jumping", "Fall Instead Of Jumping"), + ("0x0B", "Dive Animation", "Dive Animation"), + ("0x0C", "Trigger Void", "Trigger Void"), +] + +mm_enum_floor_property = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "FLOOR_PROPERTY_0"), + ("0x01", "Frontflip Jump Animation", "FLOOR_PROPERTY_1"), + ("0x02", "Sideflip Jump Animation", "FLOOR_PROPERTY_2"), + ("0x05", "Trigger Respawn (sets human no mask)", "FLOOR_PROPERTY_5"), + ("0x06", "Grab Wall", "FLOOR_PROPERTY_6"), + ("0x07", "Unknown (sets speed to 0)", "FLOOR_PROPERTY_7"), + ("0x08", "Stop Air Momentum", "FLOOR_PROPERTY_8"), + ("0x09", "Fall Instead Of Jumping", "FLOOR_PROPERTY_9"), + ("0x0B", "Dive Animation", "FLOOR_PROPERTY_11"), + ("0x0C", "Trigger Void", "FLOOR_PROPERTY_12"), + ("0x0D", "Trigger Void (runs `Player_Action_1`)", "FLOOR_PROPERTY_13"), +] + +ootEnumFloorProperty = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "Default"), + ("0x01", "Haunted Wasteland Camera", "Haunted Wasteland Camera"), + ("0x02", "Fire (damages every 6s)", "Fire (damages every 6s)"), + ("0x03", "Fire (damages every 3s)", "Fire (damages every 3s)"), + ("0x04", "Shallow Sand", "Shallow Sand"), + ("0x05", "Slippery", "Slippery"), + ("0x06", "Ignore Fall Damage", "Ignore Fall Damage"), + ("0x07", "Quicksand Crossing (Blocks Epona)", "Quicksand Crossing (Epona Uncrossable)"), + ("0x08", "Jabu Jabu's Belly Floor", "Jabu Jabu's Belly Floor"), + ("0x09", "Trigger Void", "Trigger Void"), + ("0x0A", "Stops Air Momentum", "Stops Air Momentum"), + ("0x0B", "Grotto Exit Animation", "Link Looks Up"), + ("0x0C", "Quicksand Crossing (Epona Crossable)", "Quicksand Crossing (Epona Crossable)"), +] + +mm_enum_floor_type = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "FLOOR_TYPE_0"), + ("0x01", "Unused (?)", "FLOOR_TYPE_1"), + ("0x02", "Fire Damages (burns Player every second)", "FLOOR_TYPE_2"), + ("0x03", "Fire Damages 2 (burns Player every second)", "FLOOR_TYPE_3"), + ("0x04", "Shallow Sand", "FLOOR_TYPE_4"), + ("0x05", "Ice (Slippery)", "FLOOR_TYPE_5"), + ("0x06", "Ignore Fall Damages", "FLOOR_TYPE_6"), + ("0x07", "Quicksand (blocks Epona)", "FLOOR_TYPE_7"), + ("0x08", "Jabu Jabu's Belly Floor (Unused)", "FLOOR_TYPE_8"), + ("0x09", "Triggers Void", "FLOOR_TYPE_9"), + ("0x0A", "Stops Air Momentum", "FLOOR_TYPE_10"), + ("0x0B", "Grotto Exit Animation", "FLOOR_TYPE_11"), + ("0x0C", "Quicksand (doesn't block Epona)", "FLOOR_TYPE_12"), + ("0x0D", "Deeper Shallow Sand", "FLOOR_TYPE_13"), + ("0x0E", "Shallow Snow", "FLOOR_TYPE_14"), + ("0x0F", "Deeper Shallow Snow", "FLOOR_TYPE_15"), +] + +enum_floor_effect = [ + ("Custom", "Custom", "Custom"), + ("0x00", "Default", "FLOOR_EFFECT_0"), + ("0x01", "Steep/Slippery Slope", "FLOOR_EFFECT_1"), + ("0x02", "Walkable (Preserves Exit Flags)", "FLOOR_EFFECT_2"), +] + +ootEnumCameraSType = [ + ("Custom", "Custom", "Custom"), + ("CAM_SET_NONE", "None", "None"), + ("CAM_SET_NORMAL0", "Normal0", "Normal0"), + ("CAM_SET_NORMAL1", "Normal1", "Normal1"), + ("CAM_SET_DUNGEON0", "Dungeon0", "Dungeon0"), + ("CAM_SET_DUNGEON1", "Dungeon1", "Dungeon1"), + ("CAM_SET_NORMAL3", "Normal3", "Normal3"), + ("CAM_SET_HORSE0", "Horse", "Horse"), + ("CAM_SET_BOSS_GOMA", "Boss_gohma", "Boss_gohma"), + ("CAM_SET_BOSS_DODO", "Boss_dodongo", "Boss_dodongo"), + ("CAM_SET_BOSS_BARI", "Boss_barinade", "Boss_barinade"), + ("CAM_SET_BOSS_FGANON", "Boss_phantom_ganon", "Boss_phantom_ganon"), + ("CAM_SET_BOSS_BAL", "Boss_volvagia", "Boss_volvagia"), + ("CAM_SET_BOSS_SHADES", "Boss_bongo", "Boss_bongo"), + ("CAM_SET_BOSS_MOFA", "Boss_morpha", "Boss_morpha"), + ("CAM_SET_TWIN0", "Twinrova_platform", "Twinrova_platform"), + ("CAM_SET_TWIN1", "Twinrova_floor", "Twinrova_floor"), + ("CAM_SET_BOSS_GANON1", "Boss_ganondorf", "Boss_ganondorf"), + ("CAM_SET_BOSS_GANON2", "Boss_ganon", "Boss_ganon"), + ("CAM_SET_TOWER0", "Tower_climb", "Tower_climb"), + ("CAM_SET_TOWER1", "Tower_unused", "Tower_unused"), + ("CAM_SET_FIXED0", "Market_balcony", "Market_balcony"), + ("CAM_SET_FIXED1", "Chu_bowling", "Chu_bowling"), + ("CAM_SET_CIRCLE0", "Pivot_crawlspace", "Pivot_crawlspace"), + ("CAM_SET_CIRCLE2", "Pivot_shop_browsing", "Pivot_shop_browsing"), + ("CAM_SET_CIRCLE3", "Pivot_in_front", "Pivot_in_front"), + ("CAM_SET_PREREND0", "Prerend_fixed", "Prerend_fixed"), + ("CAM_SET_PREREND1", "Prerend_pivot", "Prerend_pivot"), + ("CAM_SET_PREREND3", "Prerend_side_scroll", "Prerend_side_scroll"), + ("CAM_SET_DOOR0", "Door0", "Door0"), + ("CAM_SET_DOORC", "Doorc", "Doorc"), + ("CAM_SET_RAIL3", "Crawlspace", "Crawlspace"), + ("CAM_SET_START0", "Start0", "Start0"), + ("CAM_SET_START1", "Start1", "Start1"), + ("CAM_SET_FREE0", "Free0", "Free0"), + ("CAM_SET_FREE2", "Free2", "Free2"), + ("CAM_SET_CIRCLE4", "Pivot_corner", "Pivot_corner"), + ("CAM_SET_CIRCLE5", "Pivot_water_surface", "Pivot_water_surface"), + ("CAM_SET_DEMO0", "Cs_0", "Cs_0"), + ("CAM_SET_DEMO1", "Twisted_Hallway", "Twisted_Hallway"), + ("CAM_SET_MORI1", "Forest_birds_eye", "Forest_birds_eye"), + ("CAM_SET_ITEM0", "Slow_chest_cs", "Slow_chest_cs"), + ("CAM_SET_ITEM1", "Item_unused", "Item_unused"), + ("CAM_SET_DEMO3", "Cs_3", "Cs_3"), + ("CAM_SET_DEMO4", "Cs_attention", "Cs_attention"), + ("CAM_SET_UFOBEAN", "Bean_generic", "Bean_generic"), + ("CAM_SET_LIFTBEAN", "Bean_lost_woods", "Bean_lost_woods"), + ("CAM_SET_SCENE0", "Scene_unused", "Scene_unused"), + ("CAM_SET_SCENE1", "Scene_transition", "Scene_transition"), + ("CAM_SET_HIDAN1", "Fire_platform", "Fire_platform"), + ("CAM_SET_HIDAN2", "Fire_staircase", "Fire_staircase"), + ("CAM_SET_MORI2", "Forest_unused", "Forest_unused"), + ("CAM_SET_MORI3", "Defeat_poe", "Defeat_poe"), + ("CAM_SET_TAKO", "Big_octo", "Big_octo"), + ("CAM_SET_SPOT05A", "Meadow_birds_eye", "Meadow_birds_eye"), + ("CAM_SET_SPOT05B", "Meadow_unused", "Meadow_unused"), + ("CAM_SET_HIDAN3", "Fire_birds_eye", "Fire_birds_eye"), + ("CAM_SET_ITEM2", "Turn_around", "Turn_around"), + ("CAM_SET_CIRCLE6", "Pivot_vertical", "Pivot_vertical"), + ("CAM_SET_NORMAL2", "Normal2", "Normal2"), + ("CAM_SET_FISHING", "Fishing", "Fishing"), + ("CAM_SET_DEMOC", "Cs_c", "Cs_c"), + ("CAM_SET_UO_FIBER", "Jabu_tentacle", "Jabu_tentacle"), + ("CAM_SET_DUNGEON2", "Dungeon2", "Dungeon2"), + ("CAM_SET_TEPPEN", "Directed_yaw", "Directed_yaw"), + ("CAM_SET_CIRCLE7", "Pivot_from_side", "Pivot_from_side"), + ("CAM_SET_NORMAL4", "Normal4", "Normal4"), +] + +mm_enum_camera_setting_type = [ + ("Custom", "Custom", "Custom"), + ("CAM_SET_NONE", "None", "None"), + ("CAM_SET_NORMAL0", "Normal0", "Generic camera 0, used in various places 'NORMAL0'"), + ("CAM_SET_NORMAL3", "Normal3", "Generic camera 3, used in various places 'NORMAL3'"), + ( + "CAM_SET_PIVOT_DIVING", + "Pivot_Diving", + "Player diving from the surface of the water to underwater not as zora 'CIRCLE5'", + ), + ("CAM_SET_HORSE", "Horse", "Reiding a horse 'HORSE0'"), + ( + "CAM_SET_ZORA_DIVING", + "Zora_Diving", + "Parallel's Pivot Diving, but as Zora. However, Zora does not dive like a human. So this setting appears to not be used 'ZORA0'", + ), + ( + "CAM_SET_PREREND_FIXED", + "Prerend_Fixed", + "Unused remnant of OoT: camera is fixed in position and rotation 'PREREND0'", + ), + ( + "CAM_SET_PREREND_PIVOT", + "Prerend_Pivot", + "Unused remnant of OoT: Camera is fixed in position with fixed pitch, but is free to rotate in the yaw direction 360 degrees 'PREREND1'", + ), + ( + "CAM_SET_DOORC", + "Doorc", + "Generic room door transitions, camera moves and follows player as the door is open and closed 'DOORC'", + ), + ("CAM_SET_DEMO0", "Demo0", "Unknown, possibly related to treasure chest game as goron? 'DEMO0'"), + ("CAM_SET_FREE0", "Free0", "Free Camera, manual control is given, no auto-updating eye or at 'FREE0'"), + ("CAM_SET_BIRDS_EYE_VIEW_0", "Birds_Eye_View_0", "Appears unused. Camera is a top-down view 'FUKAN0'"), + ("CAM_SET_NORMAL1", "Normal1", "Generic camera 1, used in various places 'NORMAL1'"), + ( + "CAM_SET_NANAME", + "Naname", + "Unknown, slanted or tilted. Behaves identical to Normal0 except with added roll 'NANAME'", + ), + ("CAM_SET_CIRCLE0", "Circle0", "Used in Curiosity Shop, Pirates Fortress, Mayor's Residence 'CIRCLE0'"), + ("CAM_SET_FIXED0", "Fixed0", "Used in Sakon's Hideout puzzle rooms, milk bar stage 'FIXED0'"), + ("CAM_SET_SPIRAL_DOOR", "Spiral_Door", "Exiting a Spiral Staircase 'SPIRAL'"), + ("CAM_SET_DUNGEON0", "Dungeon0", "Generic dungeon camera 0, used in various places 'DUNGEON0'"), + ( + "CAM_SET_ITEM0", + "Item0", + "Getting an item and holding it above Player's head (from small chest, freestanding, npc, ...) 'ITEM0'", + ), + ("CAM_SET_ITEM1", "Item1", "Looking at player while playing the ocarina 'ITEM1'"), + ("CAM_SET_ITEM2", "Item2", "Bottles: drinking, releasing fairy, dropping fish 'ITEM2'"), + ("CAM_SET_ITEM3", "Item3", "Bottles: catching fish or bugs, showing an item 'ITEM3'"), + ("CAM_SET_NAVI", "Navi", "Song of Soaring, variations of playing Song of Time 'NAVI'"), + ("CAM_SET_WARP_PAD_MOON", "Warp_Pad_Moon", "Warp circles from Goron Trial on the moon 'WARP0'"), + ("CAM_SET_DEATH", "Death", "Player death animation when health goes to 0 'DEATH'"), + ("CAM_SET_REBIRTH", "Rebirth", "Unknown set with camDataId = -9 (it's not being revived by a fairy) 'REBIRTH'"), + ( + "CAM_SET_LONG_CHEST_OPENING", + "Long_Chest_Opening", + "Long cutscene when opening a big chest with a major item 'TREASURE'", + ), + ("CAM_SET_MASK_TRANSFORMATION", "Mask_Transformation", "Putting on a transformation mask 'TRANSFORM'"), + ("CAM_SET_ATTENTION", "Attention", "Unknown, set with camDataId = -15 'ATTENTION'"), + ("CAM_SET_WARP_PAD_ENTRANCE", "Warp_Pad_Entrance", "Warp pad from start of a dungeon to the boss-room 'WARP1'"), + ("CAM_SET_DUNGEON1", "Dungeon1", "Generic dungeon camera 1, used in various places 'DUNGEON1'"), + ( + "CAM_SET_FIXED1", + "Fixed1", + "Fixes camera in place, used in various places eg. entering Stock Pot Inn, hiting a switch, giving witch a red potion, shop browsing 'FIXED1'", + ), + ( + "CAM_SET_FIXED2", + "Fixed2", + "Used in Pinnacle Rock after defeating Sea Monsters, and by Tatl in Fortress 'FIXED2'", + ), + ("CAM_SET_MAZE", "Maze", "Unused. Set to use Camera_Parallel2(), which is only Camera_Noop() 'MAZE'"), + ( + "CAM_SET_REMOTEBOMB", + "Remotebomb", + "Unused. Set to use Camera_Parallel2(), which is only Camera_Noop(). But also related to Play_ChangeCameraSetting? 'REMOTEBOMB'", + ), + ("CAM_SET_CIRCLE1", "Circle1", "Unknown 'CIRCLE1'"), + ( + "CAM_SET_CIRCLE2", + "Circle2", + "Looking at far-away NPCs eg. Garo in Road to Ikana, Hungry Goron, Tingle 'CIRCLE2'", + ), + ( + "CAM_SET_CIRCLE3", + "Circle3", + "Used in curiosity shop, goron racetrack, final room in Sakon's hideout, other places 'CIRCLE3'", + ), + ("CAM_SET_CIRCLE4", "Circle4", "Used during the races on the doggy racetrack 'CIRCLE4'"), + ("CAM_SET_FIXED3", "Fixed3", "Used in Stock Pot Inn Toilet and Tatl cutscene after woodfall 'FIXED3'"), + ( + "CAM_SET_TOWER_ASCENT", + "Tower_Ascent", + "Various climbing structures (Snowhead climb to the temple entrance) 'TOWER0'", + ), + ("CAM_SET_PARALLEL0", "Parallel0", "Unknown 'PARALLEL0'"), + ("CAM_SET_NORMALD", "Normald", "Unknown, set with camDataId = -20 'NORMALD'"), + ("CAM_SET_SUBJECTD", "Subjectd", "Unknown, set with camDataId = -21 'SUBJECTD'"), + ( + "CAM_SET_START0", + "Start0", + "Entering a room, either Dawn of a New Day reload, or entering a door where the camera is fixed on the other end 'START0'", + ), + ( + "CAM_SET_START2", + "Start2", + "Entering a scene, camera is put at a low angle eg. Grottos, Deku Palace, Stock Pot Inn 'START2'", + ), + ("CAM_SET_STOP0", "Stop0", "Called in z_play 'STOP0'"), + ("CAM_SET_BOAT_CRUISE", "Boat_Cruise", " Koume's boat cruise 'JCRUISING'"), + ( + "CAM_SET_VERTICAL_CLIMB", + "Vertical_Climb", + "Large vertical climbs, such as Mountain Village wall or Pirates Fortress ladder. 'CLIMBMAZE'", + ), + ("CAM_SET_SIDED", "Sided", "Unknown, set with camDataId = -24 'SIDED'"), + ("CAM_SET_DUNGEON2", "Dungeon2", "Generic dungeon camera 2, used in various places 'DUNGEON2'"), + ("CAM_SET_BOSS_ODOLWA", "Boss_Odolwa", "Odolwa's Lair, also used in GBT entrance: 'BOSS_SHIGE'"), + ("CAM_SET_KEEPBACK", "Keepback", "Unknown. Possibly related to climbing something? 'KEEPBACK'"), + ("CAM_SET_CIRCLE6", "Circle6", "Used in select regions from Ikana 'CIRCLE6'"), + ("CAM_SET_CIRCLE7", "Circle7", "Unknown 'CIRCLE7'"), + ("CAM_SET_MINI_BOSS", "Mini_Boss", "Used during the various minibosses of the 'CHUBOSS'"), + ("CAM_SET_RFIXED1", "Rfixed1", "Talking to Koume stuck on the floor in woods of mystery 'RFIXED1'"), + ( + "CAM_SET_TREASURE_CHEST_MINIGAME", + "Treasure_Chest_Minigame", + "Treasure Chest Shop in East Clock Town, minigame location 'TRESURE1'", + ), + ("CAM_SET_HONEY_AND_DARLING_1", "Honey_And_Darling_1", "Honey and Darling Minigames 'BOMBBASKET'"), + ( + "CAM_SET_CIRCLE8", + "Circle8", + "Used by Stone Tower moving platforms, Falling eggs in Marine Lab, Bugs into soilpatch cutscene 'CIRCLE8'", + ), + ( + "CAM_SET_BIRDS_EYE_VIEW_1", + "Birds_Eye_View_1", + "Camera is a top-down view. Used in Fisherman's minigame and Deku Palace 'FUKAN1'", + ), + ("CAM_SET_DUNGEON3", "Dungeon3", "Generic dungeon camera 3, used in various places 'DUNGEON3'"), + ("CAM_SET_TELESCOPE", "Telescope", "Observatory telescope and Curiosity Shop Peep-Hole 'TELESCOPE'"), + ("CAM_SET_ROOM0", "Room0", "Certain rooms eg. inside the clock tower 'ROOM0'"), + ("CAM_SET_RCIRC0", "Rcirc0", "Used by a few NPC cutscenes, focus close on the NPC 'RCIRC0'"), + ("CAM_SET_CIRCLE9", "Circle9", "Used by Sakon Hideout entrance and Deku Palace Maze 'CIRCLE9'"), + ("CAM_SET_ONTHEPOLE", "Onthepole", "Somewhere in Snowhead Temple and Woodfall Temple 'ONTHEPOLE'"), + ( + "CAM_SET_INBUSH", + "Inbush", + "Various bush environments eg. grottos, Swamp Spider House, Termina Field grass bushes, Deku Palace near bean 'INBUSH'", + ), + ("CAM_SET_BOSS_MAJORA", "Boss_Majora", "Majora's Lair: 'BOSS_LAST'"), + ("CAM_SET_BOSS_TWINMOLD", "Boss_Twinmold", "Twinmold's Lair: 'BOSS_INI'"), + ("CAM_SET_BOSS_GOHT", "Boss_Goht", "Goht's Lair: 'BOSS_HAK'"), + ("CAM_SET_BOSS_GYORG", "Boss_Gyorg", "Gyorg's Lair: 'BOSS_KON'"), + ("CAM_SET_CONNECT0", "Connect0", "Smoothly and gradually return camera to Player after a cutscene 'CONNECT0'"), + ("CAM_SET_PINNACLE_ROCK", "Pinnacle_Rock", "Pinnacle Rock pit 'MORAY'"), + ("CAM_SET_NORMAL2", "Normal2", "Generic camera 2, used in various places 'NORMAL2'"), + ("CAM_SET_HONEY_AND_DARLING_2", "Honey_And_Darling_2", "'BOMBBOWL'"), + ("CAM_SET_CIRCLEA", "Circlea", "Unknown, Circle 10 'CIRCLEA'"), + ("CAM_SET_WHIRLPOOL", "Whirlpool", "Great Bay Temple Central Room Whirlpool 'WHIRLPOOL'"), + ("CAM_SET_CUCCO_SHACK", "Cucco_Shack", "'KOKKOGAME'"), + ("CAM_SET_GIANT", "Giant", "Giants Mask in Twinmold's Lair 'GIANT'"), + ("CAM_SET_SCENE0", "Scene0", "Entering doors to a new scene 'SCENE0'"), + ("CAM_SET_ROOM1", "Room1", "Certain rooms eg. some rooms in Stock Pot Inn 'ROOM1'"), + ("CAM_SET_WATER2", "Water2", "Swimming as Zora in Great Bay Temple 'WATER2'"), + ("CAM_SET_WOODFALL_SWAMP", "Woodfall_Swamp", "Woodfall inside the swamp, but not on the platforms, 'SOKONASI'"), + ("CAM_SET_FORCEKEEP", "Forcekeep", "Unknown 'FORCEKEEP'"), + ("CAM_SET_PARALLEL1", "Parallel1", "Unknown 'PARALLEL1'"), + ("CAM_SET_START1", "Start1", "Used when entering the lens cave 'START1'"), + ("CAM_SET_ROOM2", "Room2", "Certain rooms eg. Deku King's Chamber, Ocean Spider House 'ROOM2'"), + ("CAM_SET_NORMAL4", "Normal4", "Generic camera 4, used in Ikana Graveyard 'NORMAL4'"), + ("CAM_SET_ELEGY_SHELL", "Elegy_Shell", "cutscene after playing elegy of emptyness and spawning a shell 'SHELL'"), + ("CAM_SET_DUNGEON4", "Dungeon4", "Used in Pirates Fortress Interior, hidden room near hookshot 'DUNGEON4'"), +] + # --- @@ -482,6 +908,8 @@ def __init__(self, game: str): self.game = game self.update(None, game, True) # forcing the update as we're in the init function + self.enum_floor_effect = enum_floor_effect + def update(self, context: Optional[Context], game: Optional[str], force: bool = False): from .enum_data import Z64_EnumData from .object_data import Z64_ObjectData @@ -511,6 +939,11 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumCloudiness = ootEnumCloudiness self.ootEnumLinkIdle = ootEnumLinkIdle self.ootEnumRoomBehaviour = ootEnumRoomBehaviour + self.ootEnumDrawConfig = ootEnumDrawConfig + self.ootEnumFloorSetting = ootEnumFloorSetting + self.ootEnumFloorProperty = ootEnumFloorProperty + self.ootEnumCollisionSound = ootEnumCollisionSound + self.ootEnumCameraSType = ootEnumCameraSType elif self.game == "MM": self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id @@ -519,6 +952,11 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumCloudiness = mm_enum_skybox_config self.ootEnumLinkIdle = mm_enum_environment_type self.ootEnumRoomBehaviour = mm_enum_room_type + self.ootEnumDrawConfig = mm_enum_draw_config + self.ootEnumFloorSetting = mm_enum_floor_property + self.ootEnumFloorProperty = mm_enum_floor_type + self.ootEnumCollisionSound = mm_enum_surface_material + self.ootEnumCameraSType = mm_enum_camera_setting_type else: raise ValueError(f"ERROR: unsupported game {repr(self.game)}") @@ -540,6 +978,16 @@ def get_enum(self, context, prop_name: str): return self.ootEnumRoomBehaviour case "linkIdleMode": return self.ootEnumLinkIdle + case "drawConfig": + return self.ootEnumDrawConfig + case "floorSetting": + return self.ootEnumFloorSetting + case "floorProperty": + return self.ootEnumFloorProperty + case "sound": + return self.ootEnumCollisionSound + case "camSType": + return self.ootEnumCameraSType case "actor_id": return self.actorData.ootEnumActorID case "chest_content": diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 483232b11..be4a9bc36 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -21,7 +21,6 @@ drawAddButton, drawCollectionOps, drawEnumWithCustom, - get_game_prop_name, get_cs_index_start, is_oot_features, is_game_oot, diff --git a/fast64_internal/z64/collision/constants.py b/fast64_internal/z64/collision/constants.py index c7e94f7d0..88d33de28 100644 --- a/fast64_internal/z64/collision/constants.py +++ b/fast64_internal/z64/collision/constants.py @@ -4,32 +4,6 @@ ("Water", "Water", "Water"), ] -ootEnumFloorSetting = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "Default"), - ("0x05", "Trigger Respawn", "Trigger Respawn"), - ("0x06", "Grab Wall", "Grab Wall"), - ("0x08", "Stop Air Momentum", "Stop Air Momentum"), - ("0x09", "Fall Instead Of Jumping", "Fall Instead Of Jumping"), - ("0x0B", "Dive Animation", "Dive Animation"), - ("0x0C", "Trigger Void", "Trigger Void"), -] - -mm_enum_floor_property = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "FLOOR_PROPERTY_0"), - ("0x01", "Frontflip Jump Animation", "FLOOR_PROPERTY_1"), - ("0x02", "Sideflip Jump Animation", "FLOOR_PROPERTY_2"), - ("0x05", "Trigger Respawn (sets human no mask)", "FLOOR_PROPERTY_5"), - ("0x06", "Grab Wall", "FLOOR_PROPERTY_6"), - ("0x07", "Unknown (sets speed to 0)", "FLOOR_PROPERTY_7"), - ("0x08", "Stop Air Momentum", "FLOOR_PROPERTY_8"), - ("0x09", "Fall Instead Of Jumping", "FLOOR_PROPERTY_9"), - ("0x0B", "Dive Animation", "FLOOR_PROPERTY_11"), - ("0x0C", "Trigger Void", "FLOOR_PROPERTY_12"), - ("0x0D", "Trigger Void (runs `Player_Action_1`)", "FLOOR_PROPERTY_13"), -] - ootEnumWallSetting = [ ("Custom", "Custom", "Custom"), ("0x00", "Default", "Default"), @@ -42,94 +16,6 @@ ("0x07", "Push Block", "Push Block"), ] -ootEnumFloorProperty = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "Default"), - ("0x01", "Haunted Wasteland Camera", "Haunted Wasteland Camera"), - ("0x02", "Fire (damages every 6s)", "Fire (damages every 6s)"), - ("0x03", "Fire (damages every 3s)", "Fire (damages every 3s)"), - ("0x04", "Shallow Sand", "Shallow Sand"), - ("0x05", "Slippery", "Slippery"), - ("0x06", "Ignore Fall Damage", "Ignore Fall Damage"), - ("0x07", "Quicksand Crossing (Blocks Epona)", "Quicksand Crossing (Epona Uncrossable)"), - ("0x08", "Jabu Jabu's Belly Floor", "Jabu Jabu's Belly Floor"), - ("0x09", "Trigger Void", "Trigger Void"), - ("0x0A", "Stops Air Momentum", "Stops Air Momentum"), - ("0x0B", "Grotto Exit Animation", "Link Looks Up"), - ("0x0C", "Quicksand Crossing (Epona Crossable)", "Quicksand Crossing (Epona Crossable)"), -] - -mm_enum_floor_type = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "FLOOR_TYPE_0"), - ("0x01", "Unused (?)", "FLOOR_TYPE_1"), - ("0x02", "Fire Damages (burns Player every second)", "FLOOR_TYPE_2"), - ("0x03", "Fire Damages 2 (burns Player every second)", "FLOOR_TYPE_3"), - ("0x04", "Shallow Sand", "FLOOR_TYPE_4"), - ("0x05", "Ice (Slippery)", "FLOOR_TYPE_5"), - ("0x06", "Ignore Fall Damages", "FLOOR_TYPE_6"), - ("0x07", "Quicksand (blocks Epona)", "FLOOR_TYPE_7"), - ("0x08", "Jabu Jabu's Belly Floor (Unused)", "FLOOR_TYPE_8"), - ("0x09", "Triggers Void", "FLOOR_TYPE_9"), - ("0x0A", "Stops Air Momentum", "FLOOR_TYPE_10"), - ("0x0B", "Grotto Exit Animation", "FLOOR_TYPE_11"), - ("0x0C", "Quicksand (doesn't block Epona)", "FLOOR_TYPE_12"), - ("0x0D", "Deeper Shallow Sand", "FLOOR_TYPE_13"), - ("0x0E", "Shallow Snow", "FLOOR_TYPE_14"), - ("0x0F", "Deeper Shallow Snow", "FLOOR_TYPE_15"), -] - -ootEnumCollisionTerrain = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Walkable", "FLOOR_EFFECT_0"), - ("0x01", "Steep", "FLOOR_EFFECT_1"), - ("0x02", "Walkable (Preserves Exit Flags)", "FLOOR_EFFECT_2"), -] - -mm_enum_floor_effect = [ - ("Custom", "Custom", "Custom"), - ("0x00", "Default", "FLOOR_EFFECT_0"), - ("0x01", "Steep/Slippery Slope", "FLOOR_EFFECT_1"), - ("0x02", "Walkable (Preserves Exit Flags)", "FLOOR_EFFECT_2"), -] - -ootEnumCollisionSound = [ - ("Custom", "Custom", "Custom"), - ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), - ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), - ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), - ("SURFACE_MATERIAL_JABU", "Jabu", "Jabu-Jabu flesh (aka Wet Stone)"), - ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), - ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), - ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), - ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), - ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), - ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), - ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), - ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), - ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), - ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), -] - -mm_enum_surface_material = [ - ("Custom", "Custom", "Custom"), - ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), - ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), - ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), - ("SURFACE_MATERIAL_DIRT_SHALLOW", "Shallow Dirt", "Shallow Dirt"), - ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), - ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), - ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), - ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), - ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), - ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), - ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), - ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), - ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), - ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), - ("SURFACE_MATERIAL_SNOW", "Snow", "Snow"), -] - ootEnumConveyorSpeed = [ ("Custom", "Custom", "Custom"), ("0x00", "None", "None"), @@ -143,255 +29,6 @@ ("CAM_SET_CRAWLSPACE", "Crawlspace", "Crawlspace"), ] -ootEnumCameraSType = [ - ("Custom", "Custom", "Custom"), - ("CAM_SET_NONE", "None", "None"), - ("CAM_SET_NORMAL0", "Normal0", "Normal0"), - ("CAM_SET_NORMAL1", "Normal1", "Normal1"), - ("CAM_SET_DUNGEON0", "Dungeon0", "Dungeon0"), - ("CAM_SET_DUNGEON1", "Dungeon1", "Dungeon1"), - ("CAM_SET_NORMAL3", "Normal3", "Normal3"), - ("CAM_SET_HORSE0", "Horse", "Horse"), - ("CAM_SET_BOSS_GOMA", "Boss_gohma", "Boss_gohma"), - ("CAM_SET_BOSS_DODO", "Boss_dodongo", "Boss_dodongo"), - ("CAM_SET_BOSS_BARI", "Boss_barinade", "Boss_barinade"), - ("CAM_SET_BOSS_FGANON", "Boss_phantom_ganon", "Boss_phantom_ganon"), - ("CAM_SET_BOSS_BAL", "Boss_volvagia", "Boss_volvagia"), - ("CAM_SET_BOSS_SHADES", "Boss_bongo", "Boss_bongo"), - ("CAM_SET_BOSS_MOFA", "Boss_morpha", "Boss_morpha"), - ("CAM_SET_TWIN0", "Twinrova_platform", "Twinrova_platform"), - ("CAM_SET_TWIN1", "Twinrova_floor", "Twinrova_floor"), - ("CAM_SET_BOSS_GANON1", "Boss_ganondorf", "Boss_ganondorf"), - ("CAM_SET_BOSS_GANON2", "Boss_ganon", "Boss_ganon"), - ("CAM_SET_TOWER0", "Tower_climb", "Tower_climb"), - ("CAM_SET_TOWER1", "Tower_unused", "Tower_unused"), - ("CAM_SET_FIXED0", "Market_balcony", "Market_balcony"), - ("CAM_SET_FIXED1", "Chu_bowling", "Chu_bowling"), - ("CAM_SET_CIRCLE0", "Pivot_crawlspace", "Pivot_crawlspace"), - ("CAM_SET_CIRCLE2", "Pivot_shop_browsing", "Pivot_shop_browsing"), - ("CAM_SET_CIRCLE3", "Pivot_in_front", "Pivot_in_front"), - ("CAM_SET_PREREND0", "Prerend_fixed", "Prerend_fixed"), - ("CAM_SET_PREREND1", "Prerend_pivot", "Prerend_pivot"), - ("CAM_SET_PREREND3", "Prerend_side_scroll", "Prerend_side_scroll"), - ("CAM_SET_DOOR0", "Door0", "Door0"), - ("CAM_SET_DOORC", "Doorc", "Doorc"), - ("CAM_SET_RAIL3", "Crawlspace", "Crawlspace"), - ("CAM_SET_START0", "Start0", "Start0"), - ("CAM_SET_START1", "Start1", "Start1"), - ("CAM_SET_FREE0", "Free0", "Free0"), - ("CAM_SET_FREE2", "Free2", "Free2"), - ("CAM_SET_CIRCLE4", "Pivot_corner", "Pivot_corner"), - ("CAM_SET_CIRCLE5", "Pivot_water_surface", "Pivot_water_surface"), - ("CAM_SET_DEMO0", "Cs_0", "Cs_0"), - ("CAM_SET_DEMO1", "Twisted_Hallway", "Twisted_Hallway"), - ("CAM_SET_MORI1", "Forest_birds_eye", "Forest_birds_eye"), - ("CAM_SET_ITEM0", "Slow_chest_cs", "Slow_chest_cs"), - ("CAM_SET_ITEM1", "Item_unused", "Item_unused"), - ("CAM_SET_DEMO3", "Cs_3", "Cs_3"), - ("CAM_SET_DEMO4", "Cs_attention", "Cs_attention"), - ("CAM_SET_UFOBEAN", "Bean_generic", "Bean_generic"), - ("CAM_SET_LIFTBEAN", "Bean_lost_woods", "Bean_lost_woods"), - ("CAM_SET_SCENE0", "Scene_unused", "Scene_unused"), - ("CAM_SET_SCENE1", "Scene_transition", "Scene_transition"), - ("CAM_SET_HIDAN1", "Fire_platform", "Fire_platform"), - ("CAM_SET_HIDAN2", "Fire_staircase", "Fire_staircase"), - ("CAM_SET_MORI2", "Forest_unused", "Forest_unused"), - ("CAM_SET_MORI3", "Defeat_poe", "Defeat_poe"), - ("CAM_SET_TAKO", "Big_octo", "Big_octo"), - ("CAM_SET_SPOT05A", "Meadow_birds_eye", "Meadow_birds_eye"), - ("CAM_SET_SPOT05B", "Meadow_unused", "Meadow_unused"), - ("CAM_SET_HIDAN3", "Fire_birds_eye", "Fire_birds_eye"), - ("CAM_SET_ITEM2", "Turn_around", "Turn_around"), - ("CAM_SET_CIRCLE6", "Pivot_vertical", "Pivot_vertical"), - ("CAM_SET_NORMAL2", "Normal2", "Normal2"), - ("CAM_SET_FISHING", "Fishing", "Fishing"), - ("CAM_SET_DEMOC", "Cs_c", "Cs_c"), - ("CAM_SET_UO_FIBER", "Jabu_tentacle", "Jabu_tentacle"), - ("CAM_SET_DUNGEON2", "Dungeon2", "Dungeon2"), - ("CAM_SET_TEPPEN", "Directed_yaw", "Directed_yaw"), - ("CAM_SET_CIRCLE7", "Pivot_from_side", "Pivot_from_side"), - ("CAM_SET_NORMAL4", "Normal4", "Normal4"), -] - -mm_enum_camera_setting_type = [ - ("Custom", "Custom", "Custom"), - ("CAM_SET_NONE", "None", "None"), - ("CAM_SET_NORMAL0", "Normal0", "Generic camera 0, used in various places 'NORMAL0'"), - ("CAM_SET_NORMAL3", "Normal3", "Generic camera 3, used in various places 'NORMAL3'"), - ( - "CAM_SET_PIVOT_DIVING", - "Pivot_Diving", - "Player diving from the surface of the water to underwater not as zora 'CIRCLE5'", - ), - ("CAM_SET_HORSE", "Horse", "Reiding a horse 'HORSE0'"), - ( - "CAM_SET_ZORA_DIVING", - "Zora_Diving", - "Parallel's Pivot Diving, but as Zora. However, Zora does not dive like a human. So this setting appears to not be used 'ZORA0'", - ), - ( - "CAM_SET_PREREND_FIXED", - "Prerend_Fixed", - "Unused remnant of OoT: camera is fixed in position and rotation 'PREREND0'", - ), - ( - "CAM_SET_PREREND_PIVOT", - "Prerend_Pivot", - "Unused remnant of OoT: Camera is fixed in position with fixed pitch, but is free to rotate in the yaw direction 360 degrees 'PREREND1'", - ), - ( - "CAM_SET_DOORC", - "Doorc", - "Generic room door transitions, camera moves and follows player as the door is open and closed 'DOORC'", - ), - ("CAM_SET_DEMO0", "Demo0", "Unknown, possibly related to treasure chest game as goron? 'DEMO0'"), - ("CAM_SET_FREE0", "Free0", "Free Camera, manual control is given, no auto-updating eye or at 'FREE0'"), - ("CAM_SET_BIRDS_EYE_VIEW_0", "Birds_Eye_View_0", "Appears unused. Camera is a top-down view 'FUKAN0'"), - ("CAM_SET_NORMAL1", "Normal1", "Generic camera 1, used in various places 'NORMAL1'"), - ( - "CAM_SET_NANAME", - "Naname", - "Unknown, slanted or tilted. Behaves identical to Normal0 except with added roll 'NANAME'", - ), - ("CAM_SET_CIRCLE0", "Circle0", "Used in Curiosity Shop, Pirates Fortress, Mayor's Residence 'CIRCLE0'"), - ("CAM_SET_FIXED0", "Fixed0", "Used in Sakon's Hideout puzzle rooms, milk bar stage 'FIXED0'"), - ("CAM_SET_SPIRAL_DOOR", "Spiral_Door", "Exiting a Spiral Staircase 'SPIRAL'"), - ("CAM_SET_DUNGEON0", "Dungeon0", "Generic dungeon camera 0, used in various places 'DUNGEON0'"), - ( - "CAM_SET_ITEM0", - "Item0", - "Getting an item and holding it above Player's head (from small chest, freestanding, npc, ...) 'ITEM0'", - ), - ("CAM_SET_ITEM1", "Item1", "Looking at player while playing the ocarina 'ITEM1'"), - ("CAM_SET_ITEM2", "Item2", "Bottles: drinking, releasing fairy, dropping fish 'ITEM2'"), - ("CAM_SET_ITEM3", "Item3", "Bottles: catching fish or bugs, showing an item 'ITEM3'"), - ("CAM_SET_NAVI", "Navi", "Song of Soaring, variations of playing Song of Time 'NAVI'"), - ("CAM_SET_WARP_PAD_MOON", "Warp_Pad_Moon", "Warp circles from Goron Trial on the moon 'WARP0'"), - ("CAM_SET_DEATH", "Death", "Player death animation when health goes to 0 'DEATH'"), - ("CAM_SET_REBIRTH", "Rebirth", "Unknown set with camDataId = -9 (it's not being revived by a fairy) 'REBIRTH'"), - ( - "CAM_SET_LONG_CHEST_OPENING", - "Long_Chest_Opening", - "Long cutscene when opening a big chest with a major item 'TREASURE'", - ), - ("CAM_SET_MASK_TRANSFORMATION", "Mask_Transformation", "Putting on a transformation mask 'TRANSFORM'"), - ("CAM_SET_ATTENTION", "Attention", "Unknown, set with camDataId = -15 'ATTENTION'"), - ("CAM_SET_WARP_PAD_ENTRANCE", "Warp_Pad_Entrance", "Warp pad from start of a dungeon to the boss-room 'WARP1'"), - ("CAM_SET_DUNGEON1", "Dungeon1", "Generic dungeon camera 1, used in various places 'DUNGEON1'"), - ( - "CAM_SET_FIXED1", - "Fixed1", - "Fixes camera in place, used in various places eg. entering Stock Pot Inn, hiting a switch, giving witch a red potion, shop browsing 'FIXED1'", - ), - ( - "CAM_SET_FIXED2", - "Fixed2", - "Used in Pinnacle Rock after defeating Sea Monsters, and by Tatl in Fortress 'FIXED2'", - ), - ("CAM_SET_MAZE", "Maze", "Unused. Set to use Camera_Parallel2(), which is only Camera_Noop() 'MAZE'"), - ( - "CAM_SET_REMOTEBOMB", - "Remotebomb", - "Unused. Set to use Camera_Parallel2(), which is only Camera_Noop(). But also related to Play_ChangeCameraSetting? 'REMOTEBOMB'", - ), - ("CAM_SET_CIRCLE1", "Circle1", "Unknown 'CIRCLE1'"), - ( - "CAM_SET_CIRCLE2", - "Circle2", - "Looking at far-away NPCs eg. Garo in Road to Ikana, Hungry Goron, Tingle 'CIRCLE2'", - ), - ( - "CAM_SET_CIRCLE3", - "Circle3", - "Used in curiosity shop, goron racetrack, final room in Sakon's hideout, other places 'CIRCLE3'", - ), - ("CAM_SET_CIRCLE4", "Circle4", "Used during the races on the doggy racetrack 'CIRCLE4'"), - ("CAM_SET_FIXED3", "Fixed3", "Used in Stock Pot Inn Toilet and Tatl cutscene after woodfall 'FIXED3'"), - ( - "CAM_SET_TOWER_ASCENT", - "Tower_Ascent", - "Various climbing structures (Snowhead climb to the temple entrance) 'TOWER0'", - ), - ("CAM_SET_PARALLEL0", "Parallel0", "Unknown 'PARALLEL0'"), - ("CAM_SET_NORMALD", "Normald", "Unknown, set with camDataId = -20 'NORMALD'"), - ("CAM_SET_SUBJECTD", "Subjectd", "Unknown, set with camDataId = -21 'SUBJECTD'"), - ( - "CAM_SET_START0", - "Start0", - "Entering a room, either Dawn of a New Day reload, or entering a door where the camera is fixed on the other end 'START0'", - ), - ( - "CAM_SET_START2", - "Start2", - "Entering a scene, camera is put at a low angle eg. Grottos, Deku Palace, Stock Pot Inn 'START2'", - ), - ("CAM_SET_STOP0", "Stop0", "Called in z_play 'STOP0'"), - ("CAM_SET_BOAT_CRUISE", "Boat_Cruise", " Koume's boat cruise 'JCRUISING'"), - ( - "CAM_SET_VERTICAL_CLIMB", - "Vertical_Climb", - "Large vertical climbs, such as Mountain Village wall or Pirates Fortress ladder. 'CLIMBMAZE'", - ), - ("CAM_SET_SIDED", "Sided", "Unknown, set with camDataId = -24 'SIDED'"), - ("CAM_SET_DUNGEON2", "Dungeon2", "Generic dungeon camera 2, used in various places 'DUNGEON2'"), - ("CAM_SET_BOSS_ODOLWA", "Boss_Odolwa", "Odolwa's Lair, also used in GBT entrance: 'BOSS_SHIGE'"), - ("CAM_SET_KEEPBACK", "Keepback", "Unknown. Possibly related to climbing something? 'KEEPBACK'"), - ("CAM_SET_CIRCLE6", "Circle6", "Used in select regions from Ikana 'CIRCLE6'"), - ("CAM_SET_CIRCLE7", "Circle7", "Unknown 'CIRCLE7'"), - ("CAM_SET_MINI_BOSS", "Mini_Boss", "Used during the various minibosses of the 'CHUBOSS'"), - ("CAM_SET_RFIXED1", "Rfixed1", "Talking to Koume stuck on the floor in woods of mystery 'RFIXED1'"), - ( - "CAM_SET_TREASURE_CHEST_MINIGAME", - "Treasure_Chest_Minigame", - "Treasure Chest Shop in East Clock Town, minigame location 'TRESURE1'", - ), - ("CAM_SET_HONEY_AND_DARLING_1", "Honey_And_Darling_1", "Honey and Darling Minigames 'BOMBBASKET'"), - ( - "CAM_SET_CIRCLE8", - "Circle8", - "Used by Stone Tower moving platforms, Falling eggs in Marine Lab, Bugs into soilpatch cutscene 'CIRCLE8'", - ), - ( - "CAM_SET_BIRDS_EYE_VIEW_1", - "Birds_Eye_View_1", - "Camera is a top-down view. Used in Fisherman's minigame and Deku Palace 'FUKAN1'", - ), - ("CAM_SET_DUNGEON3", "Dungeon3", "Generic dungeon camera 3, used in various places 'DUNGEON3'"), - ("CAM_SET_TELESCOPE", "Telescope", "Observatory telescope and Curiosity Shop Peep-Hole 'TELESCOPE'"), - ("CAM_SET_ROOM0", "Room0", "Certain rooms eg. inside the clock tower 'ROOM0'"), - ("CAM_SET_RCIRC0", "Rcirc0", "Used by a few NPC cutscenes, focus close on the NPC 'RCIRC0'"), - ("CAM_SET_CIRCLE9", "Circle9", "Used by Sakon Hideout entrance and Deku Palace Maze 'CIRCLE9'"), - ("CAM_SET_ONTHEPOLE", "Onthepole", "Somewhere in Snowhead Temple and Woodfall Temple 'ONTHEPOLE'"), - ( - "CAM_SET_INBUSH", - "Inbush", - "Various bush environments eg. grottos, Swamp Spider House, Termina Field grass bushes, Deku Palace near bean 'INBUSH'", - ), - ("CAM_SET_BOSS_MAJORA", "Boss_Majora", "Majora's Lair: 'BOSS_LAST'"), - ("CAM_SET_BOSS_TWINMOLD", "Boss_Twinmold", "Twinmold's Lair: 'BOSS_INI'"), - ("CAM_SET_BOSS_GOHT", "Boss_Goht", "Goht's Lair: 'BOSS_HAK'"), - ("CAM_SET_BOSS_GYORG", "Boss_Gyorg", "Gyorg's Lair: 'BOSS_KON'"), - ("CAM_SET_CONNECT0", "Connect0", "Smoothly and gradually return camera to Player after a cutscene 'CONNECT0'"), - ("CAM_SET_PINNACLE_ROCK", "Pinnacle_Rock", "Pinnacle Rock pit 'MORAY'"), - ("CAM_SET_NORMAL2", "Normal2", "Generic camera 2, used in various places 'NORMAL2'"), - ("CAM_SET_HONEY_AND_DARLING_2", "Honey_And_Darling_2", "'BOMBBOWL'"), - ("CAM_SET_CIRCLEA", "Circlea", "Unknown, Circle 10 'CIRCLEA'"), - ("CAM_SET_WHIRLPOOL", "Whirlpool", "Great Bay Temple Central Room Whirlpool 'WHIRLPOOL'"), - ("CAM_SET_CUCCO_SHACK", "Cucco_Shack", "'KOKKOGAME'"), - ("CAM_SET_GIANT", "Giant", "Giants Mask in Twinmold's Lair 'GIANT'"), - ("CAM_SET_SCENE0", "Scene0", "Entering doors to a new scene 'SCENE0'"), - ("CAM_SET_ROOM1", "Room1", "Certain rooms eg. some rooms in Stock Pot Inn 'ROOM1'"), - ("CAM_SET_WATER2", "Water2", "Swimming as Zora in Great Bay Temple 'WATER2'"), - ("CAM_SET_WOODFALL_SWAMP", "Woodfall_Swamp", "Woodfall inside the swamp, but not on the platforms, 'SOKONASI'"), - ("CAM_SET_FORCEKEEP", "Forcekeep", "Unknown 'FORCEKEEP'"), - ("CAM_SET_PARALLEL1", "Parallel1", "Unknown 'PARALLEL1'"), - ("CAM_SET_START1", "Start1", "Used when entering the lens cave 'START1'"), - ("CAM_SET_ROOM2", "Room2", "Certain rooms eg. Deku King's Chamber, Ocean Spider House 'ROOM2'"), - ("CAM_SET_NORMAL4", "Normal4", "Generic camera 4, used in Ikana Graveyard 'NORMAL4'"), - ("CAM_SET_ELEGY_SHELL", "Elegy_Shell", "cutscene after playing elegy of emptyness and spawning a shell 'SHELL'"), - ("CAM_SET_DUNGEON4", "Dungeon4", "Used in Pirates Fortress Interior, hidden room near hookshot 'DUNGEON4'"), -] - decomp_compat_map_CameraSType = { "CAM_SET_HORSE0": "CAM_SET_HORSE", "CAM_SET_BOSS_GOMA": "CAM_SET_BOSS_GOHMA", diff --git a/fast64_internal/z64/collision/exporter/classes.py b/fast64_internal/z64/collision/exporter/classes.py index 5c6823254..749833e1a 100644 --- a/fast64_internal/z64/collision/exporter/classes.py +++ b/fast64_internal/z64/collision/exporter/classes.py @@ -1,6 +1,6 @@ import math from ....utility import PluginError -from ...utility import BoxEmpty, convertIntTo2sComplement, getCustomProperty, get_game_prop_name +from ...utility import BoxEmpty, convertIntTo2sComplement, getCustomProperty class OOTCollisionVertex: @@ -194,11 +194,11 @@ def getPolygonType(collisionProp): polygonType.eponaBlock = collisionProp.eponaBlock polygonType.decreaseHeight = collisionProp.decreaseHeight polygonType.floorSetting = getCustomProperty( - collisionProp, get_game_prop_name("floor_property"), "floorSettingCustom" + collisionProp, "floorSetting", "floorSettingCustom" ) polygonType.wallSetting = getCustomProperty(collisionProp, "wallSetting") polygonType.floorProperty = getCustomProperty( - collisionProp, get_game_prop_name("floor_type"), "floorPropertyCustom" + collisionProp, "floorProperty", "floorPropertyCustom" ) polygonType.exitID = collisionProp.exitID polygonType.cameraID = collisionProp.cameraID @@ -216,8 +216,8 @@ def getPolygonType(collisionProp): polygonType.hookshotable = collisionProp.hookshotable polygonType.echo = collisionProp.echo polygonType.lightingSetting = collisionProp.lightingSetting - polygonType.terrain = getCustomProperty(collisionProp, get_game_prop_name("floor_effect", "terrainCustom")) - polygonType.sound = getCustomProperty(collisionProp, get_game_prop_name("surface_material", "soundCustom")) + polygonType.terrain = getCustomProperty(collisionProp, "terrain") + polygonType.sound = getCustomProperty(collisionProp, "sound") return polygonType diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index bf294e0e1..723616c9c 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -1,24 +1,16 @@ import math + from bpy.props import StringProperty, PointerProperty, IntProperty, EnumProperty, BoolProperty, FloatProperty -from bpy.types import PropertyGroup, Camera, Object, Material, UILayout +from bpy.types import PropertyGroup, Object, Material, UILayout from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom, get_game_prop_name -from ..constants import ootEnumSceneID +from ...game_data import game_data +from ..utility import drawEnumWithCustom + from .constants import ( - ootEnumFloorSetting, ootEnumWallSetting, - ootEnumFloorProperty, ootEnumConveyer, ootEnumConveyorSpeed, - ootEnumCollisionTerrain, - ootEnumCollisionSound, - ootEnumCameraSType, - mm_enum_floor_property, - mm_enum_floor_type, - mm_enum_floor_effect, - mm_enum_surface_material, - mm_enum_camera_setting_type, ) @@ -50,15 +42,14 @@ def draw_props(self, layout: UILayout): class OOTCameraPositionProperty(PropertyGroup): index: IntProperty(min=0) bgImageOverrideIndex: IntProperty(default=-1, min=-1) - camSType: EnumProperty(items=ootEnumCameraSType, default=2) - mm_cam_setting_type: EnumProperty(items=mm_enum_camera_setting_type, default=2) + camSType: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "camSType"), default=2) camSTypeCustom: StringProperty(default="CAM_SET_NORMAL0") hasPositionData: BoolProperty(default=True, name="Has Position Data") is_actor_cs_cam: BoolProperty(default=False, name="Is Actor CS Camera") use_setting_default_fov: BoolProperty(name="Use the default FoV from the camera setting", default=False) def draw_props(self, layout: UILayout, cameraObj: Object): - drawEnumWithCustom(layout, self, get_game_prop_name("cam_setting_type"), "Camera S Type", "", "camSTypeCustom") + drawEnumWithCustom(layout, self, "camSType", "Camera S Type", "", "camSTypeCustom") prop_split(layout, self, "index", "Camera Index") layout.prop(self, "is_actor_cs_cam") @@ -82,13 +73,11 @@ class OOTMaterialCollisionProperty(PropertyGroup): eponaBlock: BoolProperty() decreaseHeight: BoolProperty() floorSettingCustom: StringProperty(default="0x00") - floorSetting: EnumProperty(items=ootEnumFloorSetting, default=1) - mm_floor_property: EnumProperty(items=mm_enum_floor_property, default=1) + floorSetting: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "floorSetting"), default=1) wallSettingCustom: StringProperty(default="0x00") wallSetting: EnumProperty(items=ootEnumWallSetting, default=1) floorPropertyCustom: StringProperty(default="0x00") - floorProperty: EnumProperty(items=ootEnumFloorProperty, default=1) - mm_floor_type: EnumProperty(items=mm_enum_floor_type, default=1) + floorProperty: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "floorProperty"), default=1) exitID: IntProperty(default=0, min=0) cameraID: IntProperty(default=0, min=0) isWallDamage: BoolProperty() @@ -101,11 +90,9 @@ class OOTMaterialCollisionProperty(PropertyGroup): echo: StringProperty(default="0x00") lightingSetting: IntProperty(default=0, min=0) terrainCustom: StringProperty(default="0x00") - terrain: EnumProperty(items=ootEnumCollisionTerrain, default=1) - mm_floor_effect: EnumProperty(items=mm_enum_floor_effect, default=1) + terrain: EnumProperty(items=game_data.z64.enum_floor_effect, default=1) soundCustom: StringProperty(default="0x00") - sound: EnumProperty(items=ootEnumCollisionSound, default=1) - mm_surface_material: EnumProperty(items=mm_enum_surface_material, default=1) + sound: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "sound"), default=1) def draw_props(self, layout: UILayout): layout.prop( @@ -123,14 +110,14 @@ def draw_props(self, layout: UILayout): enum_box = layout.box().column() enum_box.label(text="Surface Settings") drawEnumWithCustom( - enum_box, self, get_game_prop_name("floor_type"), "Floor Type", "", "floorPropertyCustom" + enum_box, self, "floorProperty", "Floor Type", "", "floorPropertyCustom" ) drawEnumWithCustom( - enum_box, self, get_game_prop_name("floor_property"), "Floor Property", "", "floorSettingCustom" + enum_box, self, "floorSetting", "Floor Property", "", "floorSettingCustom" ) - drawEnumWithCustom(enum_box, self, get_game_prop_name("floor_effect"), "Floor Effect", "", "terrainCustom") + drawEnumWithCustom(enum_box, self, "terrain", "Floor Effect", "", "terrainCustom") drawEnumWithCustom( - enum_box, self, get_game_prop_name("surface_material"), "Surface Material", "", "soundCustom" + enum_box, self, "sound", "Surface Material", "", "soundCustom" ) drawEnumWithCustom(enum_box, self, "wallSetting", "Wall Type", "") diff --git a/fast64_internal/z64/constants.py b/fast64_internal/z64/constants.py index a06dc2060..793d62e51 100644 --- a/fast64_internal/z64/constants.py +++ b/fast64_internal/z64/constants.py @@ -530,76 +530,6 @@ # ("0xFF", "0xFF", "0xFF"), ] -ootEnumDrawConfig = [ - ("Custom", "Custom", "Custom"), - ("SDC_DEFAULT", "Default", "Default"), - ("SDC_HYRULE_FIELD", "Hyrule Field (Spot00)", "Spot00"), - ("SDC_KAKARIKO_VILLAGE", "Kakariko Village (Spot01)", "Spot01"), - ("SDC_ZORAS_RIVER", "Zora's River (Spot03)", "Spot03"), - ("SDC_KOKIRI_FOREST", "Kokiri Forest (Spot04)", "Spot04"), - ("SDC_LAKE_HYLIA", "Lake Hylia (Spot06)", "Spot06"), - ("SDC_ZORAS_DOMAIN", "Zora's Domain (Spot07)", "Spot07"), - ("SDC_ZORAS_FOUNTAIN", "Zora's Fountain (Spot08)", "Spot08"), - ("SDC_GERUDO_VALLEY", "Gerudo Valley (Spot09)", "Spot09"), - ("SDC_LOST_WOODS", "Lost Woods (Spot10)", "Spot10"), - ("SDC_DESERT_COLOSSUS", "Desert Colossus (Spot11)", "Spot11"), - ("SDC_GERUDOS_FORTRESS", "Gerudo's Fortress (Spot12)", "Spot12"), - ("SDC_HAUNTED_WASTELAND", "Haunted Wasteland (Spot13)", "Spot13"), - ("SDC_HYRULE_CASTLE", "Hyrule Castle (Spot15)", "Spot15"), - ("SDC_DEATH_MOUNTAIN_TRAIL", "Death Mountain Trail (Spot16)", "Spot16"), - ("SDC_DEATH_MOUNTAIN_CRATER", "Death Mountain Crater (Spot17)", "Spot17"), - ("SDC_GORON_CITY", "Goron City (Spot18)", "Spot18"), - ("SDC_LON_LON_RANCH", "Lon Lon Ranch (Spot20)", "Spot20"), - ("SDC_FIRE_TEMPLE", "Fire Temple (Hidan)", "Hidan"), - ("SDC_DEKU_TREE", "Inside the Deku Tree (Ydan)", "Ydan"), - ("SDC_DODONGOS_CAVERN", "Dodongo's Cavern (Ddan)", "Ddan"), - ("SDC_JABU_JABU", "Inside Jabu Jabu's Belly (Bdan)", "Bdan"), - ("SDC_FOREST_TEMPLE", "Forest Temple (Bmori1)", "Bmori1"), - ("SDC_WATER_TEMPLE", "Water Temple (Mizusin)", "Mizusin"), - ("SDC_SHADOW_TEMPLE_AND_WELL", "Shadow Temple (Hakadan)", "Hakadan"), - ("SDC_SPIRIT_TEMPLE", "Spirit Temple (Jyasinzou)", "Jyasinzou"), - ("SDC_INSIDE_GANONS_CASTLE", "Inside Ganon's Castle (Ganontika)", "Ganontika"), - ("SDC_GERUDO_TRAINING_GROUND", "Gerudo Training Ground (Men)", "Men"), - ("SDC_DEKU_TREE_BOSS", "Gohma's Lair (Ydan Boss)", "Ydan Boss"), - ("SDC_WATER_TEMPLE_BOSS", "Morpha's Lair (Mizusin Bs)", "Mizusin Bs"), - ("SDC_TEMPLE_OF_TIME", "Temple of Time (Tokinoma)", "Tokinoma"), - ("SDC_GROTTOS", "Grottos (Kakusiana)", "Kakusiana"), - ("SDC_CHAMBER_OF_THE_SAGES", "Chamber of the Sages (Kenjyanoma)", "Kenjyanoma"), - ("SDC_GREAT_FAIRYS_FOUNTAIN", "Great Fairy Fountain", "Great Fairy Fountain"), - ("SDC_SHOOTING_GALLERY", "Shooting Gallery (Syatekijyou)", "Syatekijyou"), - ("SDC_CASTLE_COURTYARD_GUARDS", "Castle Hedge Maze (Day) (Hairal Niwa)", "Hairal Niwa"), - ("SDC_OUTSIDE_GANONS_CASTLE", "Ganon's Castle Exterior (Ganon Tou)", "Ganon Tou"), - ("SDC_ICE_CAVERN", "Ice Cavern (Ice Doukuto)", "Ice Doukuto"), - ( - "SDC_GANONS_TOWER_COLLAPSE_EXTERIOR", - "Ganondorf's Death Scene (Tower Escape Exterior) (Ganon Final)", - "Ganon Final", - ), - ("SDC_FAIRYS_FOUNTAIN", "Fairy Fountain", "Fairy Fountain"), - ("SDC_THIEVES_HIDEOUT", "Thieves' Hideout (Gerudoway)", "Gerudoway"), - ("SDC_BOMBCHU_BOWLING_ALLEY", "Bombchu Bowling Alley (Bowling)", "Bowling"), - ("SDC_ROYAL_FAMILYS_TOMB", "Royal Family's Tomb (Hakaana Ouke)", "Hakaana Ouke"), - ("SDC_LAKESIDE_LABORATORY", "Lakeside Laboratory (Hylia Labo)", "Hylia Labo"), - ("SDC_LON_LON_BUILDINGS", "Lon Lon Ranch House & Tower (Souko)", "Souko"), - ("SDC_MARKET_GUARD_HOUSE", "Guard House (Miharigoya)", "Miharigoya"), - ("SDC_POTION_SHOP_GRANNY", "Granny's Potion Shop (Mahouya)", "Mahouya"), - ("SDC_CALM_WATER", "Calm Water", "Calm Water"), - ("SDC_GRAVE_EXIT_LIGHT_SHINING", "Grave Exit Light Shining", "Grave Exit Light Shining"), - ("SDC_BESITU", "Ganondorf Test Room (Besitu)", "Besitu"), - ("SDC_FISHING_POND", "Fishing Pond (Turibori)", "Turibori"), - ("SDC_GANONS_TOWER_COLLAPSE_INTERIOR", "Ganon's Tower (Collapsing) (Ganon Sonogo)", "Ganon Sonogo"), - ("SDC_INSIDE_GANONS_CASTLE_COLLAPSE", "Inside Ganon's Castle (Collapsing) (Ganontika Sonogo)", "Ganontika Sonogo"), -] - -mm_enum_draw_config = [ - ("Custom", "Custom", "Custom"), - ("SCENE_DRAW_CFG_DEFAULT", "Default", "Default"), - ("SCENE_DRAW_CFG_MAT_ANIM", "Material Animated", "Material Animated"), - ("SCENE_DRAW_CFG_NOTHING", "Nothing", "Nothing"), - ("SCENE_DRAW_CFG_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), - ("SCENE_DRAW_CFG_MAT_ANIM_MANUAL_STEP", "Material Animated (manual step)", "Material Animated (manual step)"), -] - oot_world_defaults = { "geometryMode": { "zBuffer": True, diff --git a/fast64_internal/z64/exporter/collision/__init__.py b/fast64_internal/z64/exporter/collision/__init__.py index 6506518c6..d6a384297 100644 --- a/fast64_internal/z64/exporter/collision/__init__.py +++ b/fast64_internal/z64/exporter/collision/__init__.py @@ -6,7 +6,7 @@ from bpy.ops import object from typing import Optional from ....utility import PluginError, CData, indent -from ...utility import convertIntTo2sComplement, get_game_prop_name +from ...utility import convertIntTo2sComplement from ..utility import Utility from .polygons import CollisionPoly, CollisionPolygons from .surface import SurfaceType, SurfaceTypes @@ -156,14 +156,14 @@ def getCollisionData(dataHolder: Optional[Object], transform: Matrix, useMacros: surfaceType = SurfaceType( colProp.cameraID, colProp.exitID, - Utility.getPropValue(colProp, get_game_prop_name("floor_type"), "floorPropertyCustom"), + Utility.getPropValue(colProp, "floorProperty", "floorPropertyCustom"), 0, # unused? Utility.getPropValue(colProp, "wallSetting"), - Utility.getPropValue(colProp, get_game_prop_name("floor_property"), "floorSettingCustom"), + Utility.getPropValue(colProp, "floorSetting", "floorSettingCustom"), colProp.decreaseHeight, colProp.eponaBlock, - Utility.getPropValue(colProp, get_game_prop_name("surface_material"), "soundCustom"), - Utility.getPropValue(colProp, get_game_prop_name("floor_effect"), "terrainCustom"), + Utility.getPropValue(colProp, "sound", "soundCustom"), + Utility.getPropValue(colProp, "terrain", "terrainCustom"), colProp.lightingSetting, int(colProp.echo, base=16), colProp.hookshotable, diff --git a/fast64_internal/z64/exporter/collision/camera.py b/fast64_internal/z64/exporter/collision/camera.py index f034388be..b0c449d9d 100644 --- a/fast64_internal/z64/exporter/collision/camera.py +++ b/fast64_internal/z64/exporter/collision/camera.py @@ -108,7 +108,7 @@ def get_camera_info( data_holder: Object, cam_obj: Object, transform: Matrix, cam_pos_data: Optional[dict[int, CameraData]] ): camProp: OOTCameraPositionProperty = cam_obj.ootCameraPositionProperty - cam_setting = camProp.camSType if is_game_oot() else camProp.mm_cam_setting_type + cam_setting = camProp.camSType if cam_pos_data is None: cam_pos_data = {} diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index cba99e199..4dac4f563 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,7 +3,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, is_oot_features, getEvalParams, get_game_prop_name, is_game_oot +from ...utility import getObjectList, is_oot_features, getEvalParams, is_game_oot from ....game_data import game_data from ...constants import halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits from ...room.properties import Z64_RoomHeaderProperty diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 518e396e5..586ad34e7 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -2,7 +2,7 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, exportColor, ootGetBaseOrCustomLight, indent -from ...utility import is_oot_features, getObjectList, getEvalParams, get_game_prop_name, is_game_oot +from ...utility import is_oot_features, getObjectList, getEvalParams, is_game_oot from ...scene.properties import ( Z64_SceneHeaderProperty, Z64_LightProperty, @@ -196,7 +196,7 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): return SceneInfos( Utility.getPropValue(props, "globalObject", "globalObjectCustom"), Utility.getPropValue(props, "naviCup") if is_game_oot() else "NAVI_QUEST_HINTS_NONE", - Utility.getPropValue(props.sceneTableEntry, get_game_prop_name("draw_config"), "drawConfigCustom"), + Utility.getPropValue(props.sceneTableEntry, "drawConfig", "drawConfigCustom"), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, Utility.getPropValue(props, "skyboxID", "skyboxIDCustom"), diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index bbc09067d..e5aa8c385 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -5,7 +5,7 @@ from ...utility import parentObject, hexOrDecInt from ...game_data import game_data from ..scene.properties import Z64_SceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams, is_game_oot, get_game_prop_name +from ..utility import setCustomProperty, getEvalParams, is_game_oot from ..constants import ( ootEnumCamTransition, halfday_bits_all_dawns, diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index ca11459ef..081e7b12f 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -7,7 +7,6 @@ setCustomProperty, is_game_oot, get_cs_index_start, - get_game_prop_name, ) from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty @@ -27,7 +26,7 @@ def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectLi objByID = game_data.z64.objectData.objects_by_id.get(object) if objByID is not None: - setattr(objectProp, get_game_prop_name("object_key"), objByID.key) + setattr(objectProp, "objectKey", objByID.key) else: objectProp.objectIDCustom = object diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index fb1150992..2c89677e6 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -3,6 +3,7 @@ import bpy import mathutils +from ...game_data import game_data from ...utility import readFile, hexOrDecInt from ...f3d.f3d_parser import parseMatrices from ...f3d.f3d_gbi import get_F3D_GBI @@ -10,7 +11,6 @@ from ..model_classes import OOTF3DContext from ..exporter.decomp_edit.scene_table import SceneTableUtility from ..scene.properties import Z64_ImportSceneSettingsProperty -from ..constants import ootEnumDrawConfig, mm_enum_draw_config from .scene_header import parseSceneCommands from .classes import SharedSceneData from ..cutscene.importer import importCutsceneData @@ -22,7 +22,6 @@ ootGetPath, setAllActorsVisibility, is_game_oot, - get_game_prop_name, ) @@ -174,9 +173,9 @@ def parseScene( if not settings.isCustomDest: setCustomProperty( sceneObj.ootSceneHeader.sceneTableEntry, - get_game_prop_name("draw_config"), + "drawConfig", SceneTableUtility.get_draw_config(sceneName), - ootEnumDrawConfig if is_game_oot() else mm_enum_draw_config, + game_data.z64.get_enum(bpy.context, "drawConfig"), "drawConfigCustom", ) diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index 88c56d88c..7be8477f8 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -5,20 +5,16 @@ from random import random from collections import OrderedDict +from ...game_data import game_data from ...utility import PluginError, parentObject, hexOrDecInt, yUpToZUp from ..collision.properties import OOTMaterialCollisionProperty from ..f3d_writer import getColliderMat -from ..utility import setCustomProperty, ootParseRotation, get_game_prop_name +from ..utility import setCustomProperty, ootParseRotation from .utility import getDataMatch, getBits, checkBit, createCurveFromPoints, stripName from .classes import SharedSceneData from ..collision.constants import ( - ootEnumFloorSetting, ootEnumWallSetting, - ootEnumFloorProperty, - ootEnumCollisionTerrain, - ootEnumCollisionSound, - ootEnumCameraSType, enum_camera_crawlspace_stype, ) @@ -82,7 +78,7 @@ def parseCamPosData( camObj = bpy.data.objects.new(objName, camera) bpy.context.scene.collection.objects.link(camObj) camProp = camObj.ootCameraPositionProperty - setCustomProperty(camProp, get_game_prop_name("cam_setting_type"), setting, ootEnumCameraSType, "camSTypeCustom") + setCustomProperty(camProp, "camSType", setting, game_data.z64.get_enum(bpy.context, "camSType"), "camSTypeCustom") if is_actor_cs: camProp.is_actor_cs_cam = camProp.hasPositionData = True @@ -193,17 +189,17 @@ def parseSurfaceParams( collision.decreaseHeight = checkBit(params[0], 30) setCustomProperty( collision, - get_game_prop_name("floor_property"), + "floorSetting", str(getBits(params[0], 26, 4)), - ootEnumFloorSetting, + game_data.z64.get_enum(bpy.context, "floorSetting"), "floorSettingCustom", ) setCustomProperty(collision, "wallSetting", str(getBits(params[0], 21, 5)), ootEnumWallSetting) setCustomProperty( collision, - get_game_prop_name("floor_type"), + "floorProperty", str(getBits(params[0], 13, 8)), - ootEnumFloorProperty, + game_data.z64.get_enum(bpy.context, "floorProperty"), "floorPropertyCustom", ) collision.exitID = getBits(params[0], 8, 5) @@ -226,16 +222,16 @@ def parseSurfaceParams( collision.lightingSetting = getBits(params[1], 6, 5) setCustomProperty( collision, - get_game_prop_name("floor_effect"), + "terrain", str(getBits(params[1], 4, 2)), - ootEnumCollisionTerrain, + game_data.z64.enum_floor_effect, "terrainCustom", ) setCustomProperty( collision, - get_game_prop_name("surface_material"), + "sound", str(getBits(params[1], 0, 4)), - ootEnumCollisionSound, + game_data.z64.get_enum(bpy.context, "sound"), "soundCustom", ) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index c21603b93..871753c7f 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -17,7 +17,6 @@ setCustomProperty, is_game_oot, get_cs_index_start, - get_game_prop_name, getObjectList, getEnumIndex, get_new_empty_object, diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 85eba1ec5..e6da08466 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -11,7 +11,6 @@ drawAddButton, is_oot_features, is_game_oot, - get_game_prop_name, get_cs_index_start, ) from ..upgrade import upgradeRoomHeaders @@ -56,7 +55,7 @@ def upgrade_object(obj: Object): def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): is_legacy = True if "objectID" in self else False - obj_key: str = getattr(self, get_game_prop_name("object_key")) + obj_key: str = getattr(self, "objectKey") game_data.z64.update(bpy.context, None) if is_game_oot() and is_legacy: diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 611e2bdd1..dc7536a66 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -24,7 +24,6 @@ is_oot_features, is_game_oot, get_cs_index_start, - get_game_prop_name, ) from ..constants import ( @@ -35,10 +34,8 @@ ootEnumCameraMode, ootEnumAudioSessionPreset, ootEnumHeaderMenu, - ootEnumDrawConfig, ootEnumHeaderMenuComplete, mm_enum_scene_id, - mm_enum_draw_config, ) ootEnumSceneMenuAlternate = [ @@ -248,12 +245,11 @@ def draw_props(self, layout: UILayout): class Z64_SceneTableEntryProperty(PropertyGroup): - drawConfig: EnumProperty(items=ootEnumDrawConfig, name="Scene Draw Config", default="SDC_DEFAULT") - mm_draw_config: EnumProperty(items=mm_enum_draw_config, name="Scene Draw Config", default="SCENE_DRAW_CFG_DEFAULT") + drawConfig: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "drawConfig"), name="Scene Draw Config", default=1) drawConfigCustom: StringProperty(name="Scene Draw Config Custom") def draw_props(self, layout: UILayout): - drawEnumWithCustom(layout, self, get_game_prop_name("draw_config"), "Draw Config", "", "drawConfigCustom") + drawEnumWithCustom(layout, self, "drawConfig", "Draw Config", "", "drawConfigCustom") class Z64_ExtraCutsceneProperty(PropertyGroup): diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index 5294d497f..bd6700c44 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -34,31 +34,6 @@ from .actor.properties import Z64_ActorProperty -def get_game_prop_name(prop_type: str): - game_prop_name_map = { - "OOT": { - "draw_config": "drawConfig", - "object_key": "objectKey", - "floor_property": "floorSetting", - "floor_type": "floorProperty", - "floor_effect": "terrain", - "surface_material": "sound", - "cam_setting_type": "camSType", - }, - "MM": { - "draw_config": "mm_draw_config", - "object_key": "mm_object_key", - "floor_property": "mm_floor_property", - "floor_type": "mm_floor_type", - "floor_effect": "mm_floor_effect", - "surface_material": "mm_surface_material", - "cam_setting_type": "mm_cam_setting_type", - }, - } - - return game_prop_name_map[bpy.context.scene.gameEditorMode][prop_type] - - def is_game_oot(): return bpy.context.scene.gameEditorMode == "OOT" From bd80b33a326d9d41403178ce8b832c5b5161e215 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:55:30 +0100 Subject: [PATCH 072/126] format --- fast64_internal/z64/collision/exporter/classes.py | 8 ++------ fast64_internal/z64/collision/properties.py | 12 +++--------- fast64_internal/z64/exporter/scene/actors.py | 4 +++- fast64_internal/z64/object.py | 6 +++++- fast64_internal/z64/scene/properties.py | 4 +++- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/fast64_internal/z64/collision/exporter/classes.py b/fast64_internal/z64/collision/exporter/classes.py index 749833e1a..25898b3c9 100644 --- a/fast64_internal/z64/collision/exporter/classes.py +++ b/fast64_internal/z64/collision/exporter/classes.py @@ -193,13 +193,9 @@ def getPolygonType(collisionProp): polygonType.ignoreProjectileCollision = collisionProp.ignoreProjectileCollision polygonType.eponaBlock = collisionProp.eponaBlock polygonType.decreaseHeight = collisionProp.decreaseHeight - polygonType.floorSetting = getCustomProperty( - collisionProp, "floorSetting", "floorSettingCustom" - ) + polygonType.floorSetting = getCustomProperty(collisionProp, "floorSetting", "floorSettingCustom") polygonType.wallSetting = getCustomProperty(collisionProp, "wallSetting") - polygonType.floorProperty = getCustomProperty( - collisionProp, "floorProperty", "floorPropertyCustom" - ) + polygonType.floorProperty = getCustomProperty(collisionProp, "floorProperty", "floorPropertyCustom") polygonType.exitID = collisionProp.exitID polygonType.cameraID = collisionProp.cameraID polygonType.isWallDamage = collisionProp.isWallDamage diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 723616c9c..35711b9d7 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -109,16 +109,10 @@ def draw_props(self, layout: UILayout): enum_box = layout.box().column() enum_box.label(text="Surface Settings") - drawEnumWithCustom( - enum_box, self, "floorProperty", "Floor Type", "", "floorPropertyCustom" - ) - drawEnumWithCustom( - enum_box, self, "floorSetting", "Floor Property", "", "floorSettingCustom" - ) + drawEnumWithCustom(enum_box, self, "floorProperty", "Floor Type", "", "floorPropertyCustom") + drawEnumWithCustom(enum_box, self, "floorSetting", "Floor Property", "", "floorSettingCustom") drawEnumWithCustom(enum_box, self, "terrain", "Floor Effect", "", "terrainCustom") - drawEnumWithCustom( - enum_box, self, "sound", "Surface Material", "", "soundCustom" - ) + drawEnumWithCustom(enum_box, self, "sound", "Surface Material", "", "soundCustom") drawEnumWithCustom(enum_box, self, "wallSetting", "Wall Type", "") layout.prop(self, "eponaBlock", text="Blocks Epona") diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 938343d84..755f769d4 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -97,7 +97,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): else: transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({transActorProp.cutscene_id} & 0x7F)" - transActor.params = actorProp.params if is_game_oot() and actorProp.actor_id != "Custom" else actorProp.params_custom + transActor.params = ( + actorProp.params if is_game_oot() and actorProp.actor_id != "Custom" else actorProp.params_custom + ) transActor.roomFrom, transActor.cameraFront = front transActor.roomTo, transActor.cameraBack = back entries.append(transActor) diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index 5d01375ad..7208ab775 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -25,7 +25,11 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header actor = game_data.z64.actorData.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: - if objKey.replace("obj_", "") not in {"gameplay_keep", "gameplay_field_keep", "gameplay_dangeon_keep"}: + if objKey.replace("obj_", "") not in { + "gameplay_keep", + "gameplay_field_keep", + "gameplay_dangeon_keep", + }: objID = game_data.z64.objectData.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index dc7536a66..236f2d315 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -245,7 +245,9 @@ def draw_props(self, layout: UILayout): class Z64_SceneTableEntryProperty(PropertyGroup): - drawConfig: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "drawConfig"), name="Scene Draw Config", default=1) + drawConfig: EnumProperty( + items=lambda self, context: game_data.z64.get_enum(context, "drawConfig"), name="Scene Draw Config", default=1 + ) drawConfigCustom: StringProperty(name="Scene Draw Config Custom") def draw_props(self, layout: UILayout): From 98ef097bd2e3ab32c67c3b4c75bc9309389d46c9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:10:16 +0100 Subject: [PATCH 073/126] remove get_cs_index_start --- __init__.py | 8 +++----- fast64_internal/data/z64/data.py | 2 ++ fast64_internal/utility.py | 10 +++++----- fast64_internal/z64/actor/properties.py | 9 +++------ fast64_internal/z64/exporter/room/__init__.py | 5 +++-- .../z64/exporter/scene/__init__.py | 7 ++++--- fast64_internal/z64/importer/classes.py | 5 +++-- fast64_internal/z64/importer/room_header.py | 7 +++---- fast64_internal/z64/importer/scene_header.py | 7 +++---- fast64_internal/z64/importer/utility.py | 5 +++-- fast64_internal/z64/room/properties.py | 20 +++++++------------ fast64_internal/z64/scene/properties.py | 20 +++++++------------ fast64_internal/z64/utility.py | 5 ----- 13 files changed, 46 insertions(+), 64 deletions(-) diff --git a/__init__.py b/__init__.py index aebf43268..8012845c9 100644 --- a/__init__.py +++ b/__init__.py @@ -24,7 +24,7 @@ from .fast64_internal.z64 import OOT_Properties, oot_register, oot_unregister, z64_register_on_enable from .fast64_internal.z64.constants import oot_world_defaults from .fast64_internal.z64.props_panel_main import OOT_ObjectProperties -from .fast64_internal.z64.utility import getObjectList, get_cs_index_start +from .fast64_internal.z64.utility import getObjectList from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister @@ -406,16 +406,14 @@ def gameEditorUpdate(scene: bpy.types.Scene, _context): # reset `currentCutsceneIndex` when switching games if scene.gameEditorMode in {"OOT", "MM"}: - cs_index_start = get_cs_index_start() - for scene_obj in bpy.data.objects: - scene_obj.ootAlternateSceneHeaders.currentCutsceneIndex = cs_index_start + scene_obj.ootAlternateSceneHeaders.currentCutsceneIndex = game_data.z64.cs_index_start if scene_obj.type == "EMPTY" and scene_obj.ootEmptyType == "Scene": room_obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", "Room") for room_obj in room_obj_list: - room_obj.ootAlternateRoomHeaders.currentCutsceneIndex = cs_index_start + room_obj.ootAlternateRoomHeaders.currentCutsceneIndex = game_data.z64.cs_index_start # called on add-on enabling diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 955d30e27..133d4400a 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -932,6 +932,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.actorData = Z64_ActorData(self.game) if self.game == "OOT": + self.cs_index_start = 4 self.ootEnumMusicSeq = ootEnumMusicSeq self.ootEnumNightSeq = ootEnumNightSeq self.ootEnumGlobalObject = ootEnumGlobalObject @@ -945,6 +946,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumCollisionSound = ootEnumCollisionSound self.ootEnumCameraSType = ootEnumCameraSType elif self.game == "MM": + self.cs_index_start = 1 self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id self.ootEnumGlobalObject = mm_enum_global_object diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index 9b077892a..cdd5dbbdb 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -3,6 +3,7 @@ from math import pi, ceil, degrees, radians, copysign from mathutils import * from .utility_anim import * +from .game_data import game_data from typing import Callable, Iterable, Any, Optional, Tuple, TypeVar, Union, TYPE_CHECKING from bpy.types import UILayout, Scene, World @@ -1670,7 +1671,7 @@ def lightDataToObj(lightData): def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): # circular import fix - from .z64.utility import get_cs_index_start, is_game_oot + from .z64.utility import is_game_oot # This should be in oot_utility.py, but it is needed in f3d_material.py # which creates a circular import. The real problem is that the F3D render @@ -1681,12 +1682,11 @@ def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): target = "Room" if isRoom else "Scene" altHeaders = getattr(parent, "ootAlternate" + target + "Headers") - cs_index_start = get_cs_index_start() if idx == 0: return getattr(parent, "oot" + target + "Header") elif is_game_oot(): - if 1 <= idx <= (cs_index_start - 1): + if 1 <= idx <= (game_data.z64.cs_index_start - 1): if idx == 1: ret = altHeaders.childNightHeader elif idx == 2: @@ -1695,9 +1695,9 @@ def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): ret = altHeaders.adultNightHeader return None if ret.usePreviousHeader else ret - if idx - cs_index_start >= len(altHeaders.cutsceneHeaders): + if idx - game_data.z64.cs_index_start >= len(altHeaders.cutsceneHeaders): return None - return altHeaders.cutsceneHeaders[idx - cs_index_start] + return altHeaders.cutsceneHeaders[idx - game_data.z64.cs_index_start] def ootGetBaseOrCustomLight(prop, idx, toExport: bool, errIfMissing: bool): diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index be4a9bc36..ed5b02ea3 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -21,7 +21,6 @@ drawAddButton, drawCollectionOps, drawEnumWithCustom, - get_cs_index_start, is_oot_features, is_game_oot, get_list_tab_text, @@ -121,10 +120,8 @@ def draw_props(self, layout: UILayout, owner: Object, index: int): # TODO: remove def update_cutscene_index(self, context: Context): - cs_index_start = get_cs_index_start() - - if self.headerIndex < cs_index_start: - self.headerIndex = cs_index_start + if self.headerIndex < game_data.z64.cs_index_start: + self.headerIndex = game_data.z64.cs_index_start class Z64_ActorHeaderItemProperty(PropertyGroup): @@ -144,7 +141,7 @@ def draw_props( drawCollectionOps(row.row(align=True), index, propUser, None, objName, compact=True) - if altProp is not None and self.headerIndex >= len(altProp.cutsceneHeaders) + get_cs_index_start(): + if altProp is not None and self.headerIndex >= len(altProp.cutsceneHeaders) + game_data.z64.cs_index_start: box.label(text="Above header does not exist.", icon="QUESTION") diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index ee55b4ee8..d5790553c 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -3,8 +3,9 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent +from ....game_data import game_data from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings -from ...utility import is_game_oot, get_cs_index_start +from ...utility import is_game_oot from ...room.properties import Z64_RoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -82,7 +83,7 @@ def new( transform, i, ) - for i, csHeader in enumerate(altProp.cutsceneHeaders, get_cs_index_start()) + for i, csHeader in enumerate(altProp.cutsceneHeaders, game_data.z64.cs_index_start) ] hasAlternateHeaders = True if len(altHeader.cutscenes) > 0 else hasAlternateHeaders diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index b54f19ab1..8d237189b 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -3,10 +3,11 @@ from bpy.types import Object from typing import Optional from ....utility import PluginError, CData, indent +from ....game_data import game_data from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import Z64_SceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter -from ...utility import is_oot_features, get_cs_index_start, is_game_oot +from ...utility import is_oot_features, is_game_oot from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -57,7 +58,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex altHeader.cutscenes = [ SceneHeader.new(f"{name}_header{i:02}", csHeader, sceneObj, transform, i, useMacros) - for i, csHeader in enumerate(altProp.cutsceneHeaders, get_cs_index_start()) + for i, csHeader in enumerate(altProp.cutsceneHeaders, game_data.z64.cs_index_start) ] # process room after scene because of actor cutscenes requiring to be processed before actors @@ -156,7 +157,7 @@ def getSceneMainC(self): indent + curHeader.name + "," if curHeader is not None else indent + "NULL," - if i < get_cs_index_start() + if i < game_data.z64.cs_index_start else "" for i, (curHeader, _) in enumerate(headers, 1) ) diff --git a/fast64_internal/z64/importer/classes.py b/fast64_internal/z64/importer/classes.py index a181fb657..0949caab1 100644 --- a/fast64_internal/z64/importer/classes.py +++ b/fast64_internal/z64/importer/classes.py @@ -1,5 +1,6 @@ from ...utility import PluginError -from ..utility import getHeaderSettings, get_cs_index_start +from ...game_data import game_data +from ..utility import getHeaderSettings from .constants import headerNames @@ -55,7 +56,7 @@ def addHeaderIfItemExists(self, hash, itemType: str, headerIndex: int): actorObj = dictToAdd[hash] headerSettings = getHeaderSettings(actorObj) - if headerIndex < get_cs_index_start(): + if headerIndex < game_data.z64.cs_index_start: setattr(headerSettings, headerNames[headerIndex], True) else: cutsceneHeaders = headerSettings.cutsceneHeaders diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index 081e7b12f..a14e65843 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -6,7 +6,6 @@ from ..utility import ( setCustomProperty, is_game_oot, - get_cs_index_start, ) from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty @@ -53,14 +52,14 @@ def parseRoomCommands( if headerIndex == 0: roomHeader = roomObj.ootRoomHeader - elif is_game_oot() and headerIndex < get_cs_index_start(): + elif is_game_oot() and headerIndex < game_data.z64.cs_index_start: roomHeader = getattr(roomObj.ootAlternateRoomHeaders, headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: cutsceneHeaders = roomObj.ootAlternateRoomHeaders.cutsceneHeaders - while len(cutsceneHeaders) < headerIndex - (get_cs_index_start() - 1): + while len(cutsceneHeaders) < headerIndex - (game_data.z64.cs_index_start - 1): cutsceneHeaders.add() - roomHeader = cutsceneHeaders[headerIndex - get_cs_index_start()] + roomHeader = cutsceneHeaders[headerIndex - game_data.z64.cs_index_start] commands = getDataMatch(sceneData, roomCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") for commandMatch in re.finditer(rf"(SCENE\_CMD\_[a-zA-Z0-9\_]*)\s*\((.*?)\)\s*,", commands, flags=re.DOTALL): diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 871753c7f..a1113c4bd 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -16,7 +16,6 @@ getEvalParams, setCustomProperty, is_game_oot, - get_cs_index_start, getObjectList, getEnumIndex, get_new_empty_object, @@ -501,14 +500,14 @@ def parseSceneCommands( if headerIndex == 0: sceneHeader = sceneObj.ootSceneHeader - elif is_game_oot() and headerIndex < get_cs_index_start(): + elif is_game_oot() and headerIndex < game_data.z64.cs_index_start: sceneHeader = getattr(sceneObj.ootAlternateSceneHeaders, headerNames[headerIndex]) sceneHeader.usePreviousHeader = False else: cutsceneHeaders = sceneObj.ootAlternateSceneHeaders.cutsceneHeaders - while len(cutsceneHeaders) < headerIndex - (get_cs_index_start() - 1): + while len(cutsceneHeaders) < headerIndex - (game_data.z64.cs_index_start - 1): cutsceneHeaders.add() - sceneHeader = cutsceneHeaders[headerIndex - get_cs_index_start()] + sceneHeader = cutsceneHeaders[headerIndex - game_data.z64.cs_index_start] commands = getDataMatch(sceneData, sceneCommandsName, ["SceneCmd", "SCmdBase"], "scene commands") entranceList = None diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index 1071c92b3..47a93adb2 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -2,9 +2,10 @@ import bpy import mathutils +from ...game_data import game_data from ...utility import PluginError, hexOrDecInt, removeComments, yUpToZUp from ..actor.properties import Z64_ActorProperty, Z64_ActorHeaderProperty -from ..utility import ootParseRotation, is_game_oot, get_cs_index_start +from ..utility import ootParseRotation, is_game_oot from .constants import headerNames, actorsWithRotAsParam @@ -26,7 +27,7 @@ def unsetAllHeadersExceptSpecified(headerSettings: Z64_ActorHeaderProperty, head headerSettings.include_in_all_setups = False headerSettings.childDayHeader = headerIndex == 0 - if headerIndex >= get_cs_index_start(): + if headerIndex >= game_data.z64.cs_index_start: headerSettings.cutsceneHeaders.add().headerIndex = headerIndex diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index e6da08466..b2e9850df 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -11,7 +11,6 @@ drawAddButton, is_oot_features, is_game_oot, - get_cs_index_start, ) from ..upgrade import upgradeRoomHeaders from .operators import OOT_SearchObjectEnumOperator @@ -169,16 +168,14 @@ def drawBGImageList(self, layout: UILayout, objName: str): def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): from ..props_panel_main import OOT_ManualUpgrade - cs_index_start = get_cs_index_start() - if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") if not self.expandTab: return - if headerIndex is not None and headerIndex > (cs_index_start - 1): - drawCollectionOps(layout, headerIndex - cs_index_start, "Room", None, objName) + if headerIndex is not None and headerIndex > (game_data.z64.cs_index_start - 1): + drawCollectionOps(layout, headerIndex - game_data.z64.cs_index_start, "Room", None, objName) - if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < cs_index_start: + if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < game_data.z64.cs_index_start: layout.prop(self, "usePreviousHeader", text="Use Previous Header") if self.usePreviousHeader: return @@ -282,10 +279,8 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj def update_cutscene_index(self: "Z64_AlternateRoomHeaderProperty", context: Context): - cs_index_start = get_cs_index_start() - - if self.currentCutsceneIndex < cs_index_start: - self.currentCutsceneIndex = cs_index_start + if self.currentCutsceneIndex < game_data.z64.cs_index_start: + self.currentCutsceneIndex = game_data.z64.cs_index_start onHeaderMenuTabChange(self, context) @@ -302,7 +297,6 @@ class Z64_AlternateRoomHeaderProperty(PropertyGroup): def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - cs_index_start = get_cs_index_start() can_draw_cs_header = not is_game_oot() if not can_draw_cs_header: @@ -322,8 +316,8 @@ def draw_props(self, layout: UILayout, objName: str): prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") drawAddButton(headerSetup, len(self.cutsceneHeaders), "Room", None, objName) index = self.currentCutsceneIndex - if index - cs_index_start < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - cs_index_start].draw_props(headerSetup, None, index, objName) + if index - game_data.z64.cs_index_start < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - game_data.z64.cs_index_start].draw_props(headerSetup, None, index, objName) else: headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 236f2d315..2885fc40d 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -23,7 +23,6 @@ drawAddButton, is_oot_features, is_game_oot, - get_cs_index_start, ) from ..constants import ( @@ -419,16 +418,14 @@ class Z64_SceneHeaderProperty(PropertyGroup): def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, objName: str): from .operators import OOT_SearchMusicSeqEnumOperator # temp circular import fix - cs_index_start = get_cs_index_start() - if dropdownLabel is not None: layout.prop(self, "expandTab", text=dropdownLabel, icon="TRIA_DOWN" if self.expandTab else "TRIA_RIGHT") if not self.expandTab: return - if headerIndex is not None and headerIndex > (cs_index_start - 1): - drawCollectionOps(layout, headerIndex - cs_index_start, "Scene", None, objName) + if headerIndex is not None and headerIndex > (game_data.z64.cs_index_start - 1): + drawCollectionOps(layout, headerIndex - game_data.z64.cs_index_start, "Scene", None, objName) - if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < cs_index_start: + if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < game_data.z64.cs_index_start: layout.prop(self, "usePreviousHeader", text="Use Previous Header") if self.usePreviousHeader: return @@ -554,10 +551,8 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj def update_cutscene_index(self: "Z64_AlternateSceneHeaderProperty", context: Context): - cs_index_start = get_cs_index_start() - - if self.currentCutsceneIndex < cs_index_start: - self.currentCutsceneIndex = cs_index_start + if self.currentCutsceneIndex < game_data.z64.cs_index_start: + self.currentCutsceneIndex = game_data.z64.cs_index_start onHeaderMenuTabChange(self, context) @@ -574,7 +569,6 @@ class Z64_AlternateSceneHeaderProperty(PropertyGroup): def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - cs_index_start = get_cs_index_start() can_draw_cs_header = not is_game_oot() if not can_draw_cs_header: @@ -594,8 +588,8 @@ def draw_props(self, layout: UILayout, objName: str): prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) index = self.currentCutsceneIndex - if index - cs_index_start < len(self.cutsceneHeaders): - self.cutsceneHeaders[index - cs_index_start].draw_props(headerSetup, None, index, objName) + if index - game_data.z64.cs_index_start < len(self.cutsceneHeaders): + self.cutsceneHeaders[index - game_data.z64.cs_index_start].draw_props(headerSetup, None, index, objName) else: headerSetup.label(text="No cutscene header for this index.", icon="QUESTION") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index bd6700c44..cb159e291 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -42,11 +42,6 @@ def is_oot_features(): return is_game_oot() and not bpy.context.scene.fast64.oot.mm_features -def get_cs_index_start(): - # not using `is_oot_features()` because we're assuming people won't change the header system - return 4 if is_game_oot() else 1 - - def isPathObject(obj: bpy.types.Object) -> bool: return obj.type == "CURVE" and obj.ootSplineProperty.splineType == "Path" From 7d5e256b653b5c7d34db07af896a273adfbdc768 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:26:37 +0100 Subject: [PATCH 074/126] remove is_game_oot --- fast64_internal/data/z64/data.py | 6 ++++ fast64_internal/utility.py | 5 +--- fast64_internal/z64/__init__.py | 6 ++-- fast64_internal/z64/actor/properties.py | 11 ++++---- fast64_internal/z64/cutscene/classes.py | 5 ++-- .../z64/exporter/collision/camera.py | 7 +++-- .../z64/exporter/decomp_edit/scene_table.py | 11 ++++---- fast64_internal/z64/exporter/room/__init__.py | 5 ++-- fast64_internal/z64/exporter/room/header.py | 6 ++-- .../z64/exporter/scene/__init__.py | 8 +++--- fast64_internal/z64/exporter/scene/actors.py | 12 ++++---- fast64_internal/z64/exporter/scene/general.py | 5 ++-- fast64_internal/z64/exporter/utility.py | 5 ++-- fast64_internal/z64/importer/actor.py | 10 +++---- fast64_internal/z64/importer/room_header.py | 9 ++---- fast64_internal/z64/importer/scene.py | 7 ++--- fast64_internal/z64/importer/scene_header.py | 11 ++++---- .../z64/importer/scene_pathways.py | 6 ++-- fast64_internal/z64/importer/utility.py | 4 +-- fast64_internal/z64/props_panel_main.py | 7 +++-- fast64_internal/z64/room/properties.py | 27 ++++++++++-------- fast64_internal/z64/scene/operators.py | 11 ++++---- fast64_internal/z64/scene/panels.py | 16 +++++------ fast64_internal/z64/scene/properties.py | 28 +++++++++++-------- fast64_internal/z64/spline/properties.py | 5 ++-- fast64_internal/z64/utility.py | 21 ++++++-------- 26 files changed, 131 insertions(+), 123 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 133d4400a..668cec812 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -910,6 +910,12 @@ def __init__(self, game: str): self.enum_floor_effect = enum_floor_effect + def is_oot(self): + return self.game == "OOT" + + def is_mm(self): + return self.game == "MM" + def update(self, context: Optional[Context], game: Optional[str], force: bool = False): from .enum_data import Z64_EnumData from .object_data import Z64_ObjectData diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index cdd5dbbdb..f51aee1ca 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -1670,9 +1670,6 @@ def lightDataToObj(lightData): def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): - # circular import fix - from .z64.utility import is_game_oot - # This should be in oot_utility.py, but it is needed in f3d_material.py # which creates a circular import. The real problem is that the F3D render # settings stuff should be in a place which can import both SM64 and OoT @@ -1685,7 +1682,7 @@ def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): if idx == 0: return getattr(parent, "oot" + target + "Header") - elif is_game_oot(): + elif game_data.z64.is_oot(): if 1 <= idx <= (game_data.z64.cs_index_start - 1): if idx == 1: ret = altHeaders.childNightHeader diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 264780ec5..93a6282b4 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -1,6 +1,6 @@ import bpy -from bpy.utils import register_class, unregister_class +from ..game_data import game_data from .scene.operators import scene_ops_register, scene_ops_unregister from .scene.properties import OOT_BootupSceneOptions, scene_props_register, scene_props_unregister @@ -66,8 +66,6 @@ oot_operator_unregister, ) -from .utility import is_game_oot - oot_versions_items = [ ("Custom", "Custom", "Custom"), @@ -112,7 +110,7 @@ class OOT_Properties(bpy.types.PropertyGroup): mm_features: bpy.props.BoolProperty(name="Enable MM Features", default=False) def get_extracted_path(self): - version = self.oot_version if is_game_oot() else self.mm_version + version = self.oot_version if game_data.z64.is_oot() else self.mm_version if version == "legacy": return "." diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index ed5b02ea3..1baff56d9 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -22,7 +22,6 @@ drawCollectionOps, drawEnumWithCustom, is_oot_features, - is_game_oot, get_list_tab_text, getEvalParams, getEvalParamsInt, @@ -162,7 +161,7 @@ class Z64_ActorHeaderProperty(PropertyGroup): def checkHeader(self, index: int) -> bool: if index == 0: return self.childDayHeader - elif is_game_oot(): + elif game_data.z64.is_oot(): if index == 1: return self.childNightHeader elif index == 2: @@ -181,7 +180,7 @@ def draw_props( ): headerSetup = layout.column() - if is_game_oot(): + if game_data.z64.is_oot(): prop_split(headerSetup, self, "sceneSetupPreset", "Scene Setup Preset") if self.sceneSetupPreset == "Custom": @@ -295,7 +294,7 @@ class Z64_ActorProperty(PropertyGroup): @staticmethod def upgrade_object(obj: Object): - if is_game_oot(): + if game_data.z64.is_oot(): print(f"Processing '{obj.name}'...") upgradeActors(obj) @@ -506,7 +505,7 @@ def draw_props( split.label(text="Actor ID") split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "actor_id"), self.actor_id)) - if is_game_oot(): + if game_data.z64.is_oot(): if self.actor_id != "Custom": self.draw_params(actorIDBox, owner) else: @@ -515,7 +514,7 @@ def draw_props( paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if is_game_oot() and self.actor_id != "Custom": + if game_data.z64.is_oot() and self.actor_id != "Custom": paramBox.prop(self, "eval_params") paramBox.prop(self, "params", text="") else: diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 65a475246..1ad2dece7 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -4,7 +4,6 @@ from bpy.types import Object from typing import Optional from ...game_data import game_data -from ..utility import is_oot_features, is_game_oot from .motion.utility import getBlenderPosition, getBlenderRotation, getRotation, getInteger @@ -32,7 +31,7 @@ class CutsceneCmdBase: duration: Optional[int] = None def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): - if not is_game_oot() and enumKey not in { + if game_data.z64.is_mm() and enumKey not in { "seqId", "destinationType", "ocarinaSongActionId", @@ -612,7 +611,7 @@ class CutsceneCmdDestination(CutsceneCmdBase): def __post_init__(self): if self.params is not None: - self.type = self.getEnumValue("csDestination" if is_game_oot() else "destinationType", 0) + self.type = self.getEnumValue("csDestination" if game_data.z64.is_oot() else "destinationType", 0) self.startFrame = getInteger(self.params[1]) diff --git a/fast64_internal/z64/exporter/collision/camera.py b/fast64_internal/z64/exporter/collision/camera.py index b0c449d9d..aec40e985 100644 --- a/fast64_internal/z64/exporter/collision/camera.py +++ b/fast64_internal/z64/exporter/collision/camera.py @@ -5,7 +5,8 @@ from bpy.types import Object from typing import Optional from ....utility import PluginError, CData, indent -from ...utility import getObjectList, is_game_oot +from ....game_data import game_data +from ...utility import getObjectList from ...collision.constants import decomp_compat_map_CameraSType from ...collision.properties import OOTCameraPositionProperty from ..utility import Utility @@ -116,7 +117,9 @@ def get_camera_info( if cam_setting == "Custom": setting = camProp.camSTypeCustom else: - setting = decomp_compat_map_CameraSType.get(cam_setting, cam_setting) if is_game_oot() else cam_setting + setting = ( + decomp_compat_map_CameraSType.get(cam_setting, cam_setting) if game_data.z64.is_oot() else cam_setting + ) if camProp.hasPositionData or camProp.is_actor_cs_cam: if camProp.index in cam_pos_data: diff --git a/fast64_internal/z64/exporter/decomp_edit/scene_table.py b/fast64_internal/z64/exporter/decomp_edit/scene_table.py index 0c818a6f7..5ea32d3ce 100644 --- a/fast64_internal/z64/exporter/decomp_edit/scene_table.py +++ b/fast64_internal/z64/exporter/decomp_edit/scene_table.py @@ -4,7 +4,8 @@ from dataclasses import dataclass, field from typing import Optional from ....utility import PluginError, writeFile -from ...utility import is_oot_features, is_game_oot +from ....game_data import game_data +from ...utility import is_oot_features from ...constants import ootEnumSceneID, ootSceneNameToID, mm_enum_scene_id, mm_scene_name_to_id ADDED_SCENES_COMMENT = "// Added scenes" @@ -14,7 +15,7 @@ def get_original_index(enum_value: str) -> Optional[int]: """ Returns the original index of a specific scene """ - if is_game_oot(): + if game_data.z64.is_oot(): enum_scene_id = ootEnumSceneID else: enum_scene_id = mm_enum_scene_id @@ -28,7 +29,7 @@ def get_original_index(enum_value: str) -> Optional[int]: def get_scene_enum_from_name(scene_name: str): - if is_game_oot(): + if game_data.z64.is_oot(): return ootSceneNameToID.get(scene_name, f"SCENE_{scene_name.upper()}") else: return mm_scene_name_to_id.get(scene_name, f"SCENE_{scene_name.upper()}") @@ -115,7 +116,7 @@ def to_c(self, index: int): entry_string = "\n".join(entry.to_c(index + i) for i, entry in enumerate(self.entries)) section_c = f"{directive}{entry_string}{terminator}\n" - if is_game_oot(): + if game_data.z64.is_oot(): section_c += "\n" return section_c @@ -285,7 +286,7 @@ class SceneTableUtility: @staticmethod def get_draw_config(scene_name: str): """Read draw config from scene table""" - if is_game_oot(): + if game_data.z64.is_oot(): scene_name = f"{scene_name}_scene" scene_table = SceneTable.new( diff --git a/fast64_internal/z64/exporter/room/__init__.py b/fast64_internal/z64/exporter/room/__init__.py index d5790553c..340a02240 100644 --- a/fast64_internal/z64/exporter/room/__init__.py +++ b/fast64_internal/z64/exporter/room/__init__.py @@ -5,7 +5,6 @@ from ....utility import PluginError, CData, indent from ....game_data import game_data from ....f3d.f3d_gbi import ScrollMethod, TextureExportSettings -from ...utility import is_game_oot from ...room.properties import Z64_RoomHeaderProperty from ...object import addMissingObjectsToAllRoomHeaders from ...model_classes import OOTModel, OOTGfxFormatter @@ -59,7 +58,7 @@ def new( ) hasAlternateHeaders = False - if is_game_oot(): + if game_data.z64.is_oot(): for i, header in enumerate(altHeaderList, 1): altP: Z64_RoomHeaderProperty = getattr(altProp, f"{header}Header") if not altP.usePreviousHeader: @@ -172,7 +171,7 @@ def getRoomMainC(self): + "\n};\n\n" ) - header_name = "Child Day (Default)" if is_game_oot() else "Default" + header_name = "Child Day (Default)" if game_data.z64.is_oot() else "Default" roomHeaders.insert(0, (self.mainHeader, header_name)) for i, (curHeader, headerDesc) in enumerate(roomHeaders): if curHeader is not None: diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 4dac4f563..f9229813f 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -3,8 +3,8 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, is_oot_features, getEvalParams, is_game_oot from ....game_data import game_data +from ...utility import getObjectList, is_oot_features, getEvalParams from ...constants import halfday_bits_all_dawns, halfday_bits_all_nights, enum_to_halfday_bits from ...room.properties import Z64_RoomHeaderProperty from ...actor.properties import Z64_ActorProperty @@ -55,7 +55,7 @@ def new(props: Optional[Z64_RoomHeaderProperty]): enable_pos_lights = False enable_storm = False - if is_game_oot(): + if game_data.z64.is_oot(): disableWarpSongs = props.disableWarpSongs if not is_oot_features(): @@ -196,7 +196,7 @@ def new( if not Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex): continue - actor_id: str = actorProp.actorID if is_game_oot() else actorProp.actor_id + actor_id: str = actorProp.actorID if game_data.z64.is_oot() else actorProp.actor_id # The Actor list is filled with ``("None", f"{i} (Deleted from the XML)", "None")`` for # the total number of actors defined in the XML. If the user deletes one, this will prevent diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index 8d237189b..e3c47a9eb 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -7,7 +7,7 @@ from ....f3d.f3d_gbi import TextureExportSettings, ScrollMethod from ...scene.properties import Z64_SceneHeaderProperty from ...model_classes import OOTModel, OOTGfxFormatter -from ...utility import is_oot_features, is_game_oot +from ...utility import is_oot_features from ..file import SceneFile from ..utility import Utility, altHeaderList from ..collision import CollisionHeader @@ -45,7 +45,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex altHeader = SceneAlternateHeader(f"{name}_alternateHeaders") altProp = sceneObj.ootAlternateSceneHeaders - if is_game_oot(): + if game_data.z64.is_oot(): for i, header in enumerate(altHeaderList, 1): altP: Z64_SceneHeaderProperty = getattr(altProp, f"{header}Header") if not altP.usePreviousHeader: @@ -143,7 +143,7 @@ def getSceneMainC(self): altHeaderPtrs = None if self.hasAlternateHeaders: - if is_game_oot(): + if game_data.z64.is_oot(): headers = [ (self.altHeader.childNight, "Child Night"), (self.altHeader.adultDay, "Adult Day"), @@ -229,7 +229,7 @@ def getNewSceneFile(self, path: str, isSingleFile: bool, textureExportSettings: '#include "z64.h"', ] - if not is_game_oot(): + if game_data.z64.is_mm(): include_list.append('#include "command_macros_base.h"') includes = "\n".join(include_list) + "\n\n\n" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 755f769d4..236008fdf 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -3,8 +3,8 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, indent -from ...utility import getObjectList, is_oot_features, is_game_oot from ....game_data import game_data +from ...utility import getObjectList, is_oot_features from ...actor.properties import Z64_ActorProperty from ..utility import Utility from ..actor import Actor @@ -61,7 +61,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in actorObjList: transActorProp = obj.ootTransitionActorProperty actorProp: Z64_ActorProperty = transActorProp.actor - actor_id: str = actorProp.actorID if is_game_oot() else actorProp.actor_id + actor_id: str = actorProp.actorID if game_data.z64.is_oot() else actorProp.actor_id if Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) transActor = TransitionActor() @@ -98,7 +98,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({transActorProp.cutscene_id} & 0x7F)" transActor.params = ( - actorProp.params if is_game_oot() and actorProp.actor_id != "Custom" else actorProp.params_custom + actorProp.params + if game_data.z64.is_oot() and actorProp.actor_id != "Custom" + else actorProp.params_custom ) transActor.roomFrom, transActor.cameraFront = front transActor.roomTo, transActor.cameraBack = back @@ -154,7 +156,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in actorObjList: entranceProp = obj.ootEntranceProperty actorProp: Z64_ActorProperty = entranceProp.actor - actor_id: str = actorProp.actorID if is_game_oot() else actorProp.actor_id + actor_id: str = actorProp.actorID if game_data.z64.is_oot() else actorProp.actor_id if Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) entranceActor = EntranceActor() @@ -234,7 +236,7 @@ def getC(self): """Returns the spawn array""" spawnList = CData() - listName = f"Spawn {self.name}" if is_game_oot() else f"EntranceEntry {self.name}" + listName = f"Spawn {self.name}" if game_data.z64.is_oot() else f"EntranceEntry {self.name}" # .h spawnList.header = f"extern {listName}[];\n" diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 586ad34e7..a72324e6b 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -2,7 +2,8 @@ from mathutils import Matrix from bpy.types import Object from ....utility import PluginError, CData, exportColor, ootGetBaseOrCustomLight, indent -from ...utility import is_oot_features, getObjectList, getEvalParams, is_game_oot +from ....game_data import game_data +from ...utility import is_oot_features, getObjectList, getEvalParams from ...scene.properties import ( Z64_SceneHeaderProperty, Z64_LightProperty, @@ -195,7 +196,7 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): return SceneInfos( Utility.getPropValue(props, "globalObject", "globalObjectCustom"), - Utility.getPropValue(props, "naviCup") if is_game_oot() else "NAVI_QUEST_HINTS_NONE", + Utility.getPropValue(props, "naviCup") if game_data.z64.is_oot() else "NAVI_QUEST_HINTS_NONE", Utility.getPropValue(props.sceneTableEntry, "drawConfig", "drawConfigCustom"), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index 798a73b0a..d592cf85d 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -3,7 +3,8 @@ from mathutils import Quaternion, Matrix from bpy.types import Object from ...utility import PluginError, indent -from ..utility import ootConvertTranslation, ootConvertRotation, is_game_oot +from ...game_data import game_data +from ..utility import ootConvertTranslation, ootConvertRotation from ..actor.properties import Z64_ActorHeaderProperty @@ -38,7 +39,7 @@ def roundPosition(position) -> tuple[int, int, int]: def isCurrentHeaderValid(headerSettings: Z64_ActorHeaderProperty, headerIndex: int): """Checks if the an alternate header can be used""" - if is_game_oot(): + if game_data.z64.is_oot(): preset = headerSettings.sceneSetupPreset if preset == "All Scene Setups" or (preset == "All Non-Cutscene Scene Setups" and headerIndex < 4): diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index e5aa8c385..0490f8f85 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -5,7 +5,7 @@ from ...utility import parentObject, hexOrDecInt from ...game_data import game_data from ..scene.properties import Z64_SceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams, is_game_oot +from ..utility import setCustomProperty, getEvalParams from ..constants import ( ootEnumCamTransition, halfday_bits_all_dawns, @@ -45,7 +45,7 @@ def parseTransActorList( rot_y = getEvalParams(params[8]) if "DEG_TO_BINANG" in params[8] else params[8] cutscene_id = "CS_ID_GLOBAL_END" - if not is_game_oot(): + if game_data.z64.is_mm(): rotY_int = int(rot_y, base=0) rot_y = f"0x{(rotY_int >> 7) & 0x1FF:04X}" cutscene_id = f"0x{rotY_int & 0x7F:02X}" @@ -89,7 +89,7 @@ def parseTransActorList( transActorProp.isRoomTransition = False parentObject(toRoom, actorObj) - if not is_game_oot(): + if game_data.z64.is_mm(): transActorProp.cutscene_id = cutscene_id setCustomProperty(transActorProp, "cameraTransitionFront", camFront, ootEnumCamTransition) @@ -144,7 +144,7 @@ def parseActorInfo( [hexOrDecInt(value.strip()) for value in actorMatch.group(2).split(",") if value.strip() != ""] ) - if is_game_oot(): + if game_data.z64.is_oot(): spawn_rotation = tuple( [ hexOrDecInt(getEvalParams(value.strip())) @@ -216,7 +216,7 @@ def parseSpawnList( actorProp.params = actorParam else: actorProp.params_custom = actorParam - handleActorWithRotAsParam(actorProp, actorID, rotation if is_game_oot() else spawn_flags) + handleActorWithRotAsParam(actorProp, actorID, rotation if game_data.z64.is_oot() else spawn_flags) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) sharedSceneData.entranceDict[actorHash] = spawnObj diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index a14e65843..e91ad1816 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -3,10 +3,7 @@ from ...utility import hexOrDecInt from ...game_data import game_data -from ..utility import ( - setCustomProperty, - is_game_oot, -) +from ..utility import setCustomProperty from ..model_classes import OOTF3DContext from ..room.properties import Z64_RoomHeaderProperty from .utility import getDataMatch, stripName @@ -52,7 +49,7 @@ def parseRoomCommands( if headerIndex == 0: roomHeader = roomObj.ootRoomHeader - elif is_game_oot() and headerIndex < game_data.z64.cs_index_start: + elif game_data.z64.is_oot() and headerIndex < game_data.z64.cs_index_start: roomHeader = getattr(roomObj.ootAlternateRoomHeaders, headerNames[headerIndex]) roomHeader.usePreviousHeader = False else: @@ -87,7 +84,7 @@ def parseRoomCommands( ) roomHeader.showInvisibleActors = args[2] == "true" or args[2] == "1" - if is_game_oot(): + if game_data.z64.is_oot(): roomHeader.disableWarpSongs = args[3] == "true" or args[3] == "1" else: roomHeader.enable_pos_lights = args[4] == "true" or args[4] == "1" diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 2c89677e6..f80085a0c 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -21,12 +21,11 @@ sceneNameFromID, ootGetPath, setAllActorsVisibility, - is_game_oot, ) def parseDrawConfig(drawConfigName: str, sceneData: str, drawConfigData: str, f3dContext: OOTF3DContext): - if is_game_oot(): + if game_data.z64.is_oot(): drawFunctionName = "Scene_DrawConfig" + "".join( [value.strip().lower().capitalize() for value in drawConfigName.replace("SDC_", "").split("_")] ) @@ -105,7 +104,7 @@ def parseScene( subfolder = None importPath = bpy.path.abspath(bpy.context.scene.ootDecompPath) - if is_game_oot(): + if game_data.z64.is_oot(): sceneName = f"{sceneName}_scene" importSubdir = "" @@ -138,7 +137,7 @@ def parseScene( if not settings.isCustomDest: drawConfigName = SceneTableUtility.get_draw_config(sceneName) - filename = "z_scene_table" if is_game_oot() else "z_scene_proc" + filename = "z_scene_table" if game_data.z64.is_oot() else "z_scene_proc" drawConfigData = readFile(os.path.join(importPath, f"src/code/{filename}.c")) parseDrawConfig(drawConfigName, sceneData, drawConfigData, f3dContext) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index a1113c4bd..f68c1d70e 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -15,7 +15,6 @@ from ..utility import ( getEvalParams, setCustomProperty, - is_game_oot, getObjectList, getEnumIndex, get_new_empty_object, @@ -500,7 +499,7 @@ def parseSceneCommands( if headerIndex == 0: sceneHeader = sceneObj.ootSceneHeader - elif is_game_oot() and headerIndex < game_data.z64.cs_index_start: + elif game_data.z64.is_oot() and headerIndex < game_data.z64.cs_index_start: sceneHeader = getattr(sceneObj.ootAlternateSceneHeaders, headerNames[headerIndex]) sceneHeader.usePreviousHeader = False else: @@ -550,7 +549,7 @@ def parseSceneCommands( # This must be handled after rooms, so that room objs can be referenced delayed_commands[command] = args command_list.remove(command) - elif is_game_oot() and command == "SCENE_CMD_MISC_SETTINGS": + elif game_data.z64.is_oot() and command == "SCENE_CMD_MISC_SETTINGS": setCustomProperty(sceneHeader, "cameraMode", args[0], ootEnumCameraMode) setCustomProperty(sceneHeader, "mapLocation", args[1], ootEnumMapLocation) command_list.remove(command) @@ -564,7 +563,7 @@ def parseSceneCommands( delayed_commands[command] = args command_list.remove(command) elif command == "SCENE_CMD_SPECIAL_FILES": - if is_game_oot(): + if game_data.z64.is_oot(): setCustomProperty(sceneHeader, "naviCup", args[0], ootEnumNaviHints) setCustomProperty( sceneHeader, @@ -586,7 +585,7 @@ def parseSceneCommands( command_list.remove(command) elif command == "SCENE_CMD_SKYBOX_SETTINGS": args_index = 0 - if not is_game_oot(): + if game_data.z64.is_mm(): sceneHeader.skybox_texture_id = args[args_index] args_index += 1 setCustomProperty( @@ -633,7 +632,7 @@ def parseSceneCommands( command_list.remove(command) # handle Majora's Mask exclusive commands - elif not is_game_oot(): + elif game_data.z64.is_mm(): if command == "SCENE_CMD_SET_REGION_VISITED": sceneHeader.set_region_visited = True command_list.remove(command) diff --git a/fast64_internal/z64/importer/scene_pathways.py b/fast64_internal/z64/importer/scene_pathways.py index b76b80638..e09042631 100644 --- a/fast64_internal/z64/importer/scene_pathways.py +++ b/fast64_internal/z64/importer/scene_pathways.py @@ -2,7 +2,7 @@ from typing import Optional from ...utility import hexOrDecInt, parentObject -from ..utility import is_game_oot +from ...game_data import game_data from .utility import getDataMatch, createCurveFromPoints, unsetAllHeadersExceptSpecified from .classes import SharedSceneData @@ -31,7 +31,7 @@ def parsePath( splineProp = curveObj.ootSplineProperty splineProp.index = orderIndex - if not is_game_oot() and opt_path_idx is not None and custom_value is not None: + if game_data.z64.is_mm() and opt_path_idx is not None and custom_value is not None: splineProp.opt_path_index = int(opt_path_idx) splineProp.custom_value = int(custom_value) @@ -51,7 +51,7 @@ def parsePathList( pathData = getDataMatch(sceneData, pathListName, "Path", "path list") pathList = [value.replace("{", "").strip() for value in pathData.split("},") if value.strip() != ""] for i, pathEntry in enumerate(pathList): - if is_game_oot(): + if game_data.z64.is_oot(): count, points_ptr = [value.strip() for value in pathEntry.split(",")] opt_path_idx = custom_value = None else: diff --git a/fast64_internal/z64/importer/utility.py b/fast64_internal/z64/importer/utility.py index 47a93adb2..bd599c184 100644 --- a/fast64_internal/z64/importer/utility.py +++ b/fast64_internal/z64/importer/utility.py @@ -5,7 +5,7 @@ from ...game_data import game_data from ...utility import PluginError, hexOrDecInt, removeComments, yUpToZUp from ..actor.properties import Z64_ActorProperty, Z64_ActorHeaderProperty -from ..utility import ootParseRotation, is_game_oot +from ..utility import ootParseRotation from .constants import headerNames, actorsWithRotAsParam @@ -18,7 +18,7 @@ def getBits(value: int, index: int, size: int) -> int: def unsetAllHeadersExceptSpecified(headerSettings: Z64_ActorHeaderProperty, headerIndex: int): - if is_game_oot(): + if game_data.z64.is_oot(): headerSettings.sceneSetupPreset = "Custom" for i in range(len(headerNames)): diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index b5d4601f4..32aa047ea 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,7 +1,8 @@ import bpy from bpy.utils import register_class, unregister_class from ..utility import prop_split, gammaInverse -from .utility import getSceneObj, getRoomObj, is_oot_features, is_game_oot +from ..game_data import game_data +from .utility import getSceneObj, getRoomObj, is_oot_features from .scene.properties import OOTSceneProperties from .room.properties import Z64_ObjectProperty, Z64_RoomHeaderProperty, Z64_AlternateRoomHeaderProperty from .collision.properties import OOTWaterBoxProperty @@ -218,7 +219,7 @@ class OOT_ObjectProperties(bpy.types.PropertyGroup): @staticmethod def upgrade_changed_props(): for obj in bpy.data.objects: - if obj.type == "EMPTY" and is_game_oot(): + if obj.type == "EMPTY" and game_data.z64.is_oot(): if obj.ootEmptyType == "Room": Z64_ObjectProperty.upgrade_object(obj) if obj.ootEmptyType in {"Actor", "Entrance", "Transition Actor"}: @@ -235,7 +236,7 @@ def upgrade_changed_props(): obj.ootEmptyType = "CS Dummy Cue" else: print("WARNING: An Actor Cue has been detected outside an Actor Cue List: " + obj.name) - elif obj.type == "ARMATURE" and is_game_oot(): + elif obj.type == "ARMATURE" and game_data.z64.is_oot(): parentObj = obj.parent if parentObj is not None and ( parentObj.name.startswith("Cutscene.") or parentObj.ootEmptyType == "Cutscene" diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index b2e9850df..b6c6da803 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -1,4 +1,5 @@ import bpy + from bpy.types import PropertyGroup, UILayout, Image, Object, Context from bpy.utils import register_class, unregister_class from ...utility import prop_split @@ -10,7 +11,6 @@ drawEnumWithCustom, drawAddButton, is_oot_features, - is_game_oot, ) from ..upgrade import upgradeRoomHeaders from .operators import OOT_SearchObjectEnumOperator @@ -47,7 +47,7 @@ class Z64_ObjectProperty(PropertyGroup): @staticmethod def upgrade_object(obj: Object): - if is_game_oot(): + if game_data.z64.is_oot(): print(f"Processing '{obj.name}'...") game_data.z64.update(bpy.context, None) upgradeRoomHeaders(obj, game_data.z64.objectData) @@ -57,7 +57,7 @@ def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: st obj_key: str = getattr(self, "objectKey") game_data.z64.update(bpy.context, None) - if is_game_oot() and is_legacy: + if game_data.z64.is_oot() and is_legacy: obj_name = game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] elif obj_key != "Custom": obj_name = game_data.z64.objectData.objects_by_key[obj_key].name @@ -175,7 +175,12 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj if headerIndex is not None and headerIndex > (game_data.z64.cs_index_start - 1): drawCollectionOps(layout, headerIndex - game_data.z64.cs_index_start, "Room", None, objName) - if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < game_data.z64.cs_index_start: + if ( + game_data.z64.is_oot() + and headerIndex is not None + and headerIndex > 0 + and headerIndex < game_data.z64.cs_index_start + ): layout.prop(self, "usePreviousHeader", text="Use Previous Header") if self.usePreviousHeader: return @@ -210,7 +215,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj drawEnumWithCustom(behaviorBox, self, "roomBehaviour", "Room Type", "", "roomBehaviourCustom") drawEnumWithCustom(behaviorBox, self, "linkIdleMode", "Environment Type", "", "linkIdleModeCustom") - if is_game_oot(): + if game_data.z64.is_oot(): behaviorBox.prop(self, "disableWarpSongs", text="Disable Warp Songs") if not is_oot_features(): @@ -267,10 +272,10 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj for i, objProp in enumerate(self.objectList): objProp.draw_props(objBox, headerIndex, i, objName) - if is_game_oot() and "objectID" in objProp: + if game_data.z64.is_oot() and "objectID" in objProp: is_legacy = True - if is_game_oot() and is_legacy: + if game_data.z64.is_oot() and is_legacy: upgradeLayout.label(text="Legacy data has not been upgraded!") upgradeLayout.operator(OOT_ManualUpgrade.bl_idname, text="Upgrade Data Now!") objBox.enabled = False if is_legacy else True @@ -297,9 +302,9 @@ class Z64_AlternateRoomHeaderProperty(PropertyGroup): def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - can_draw_cs_header = not is_game_oot() + oot_can_draw_cs_header = False - if not can_draw_cs_header: + if game_data.z64.is_oot(): headerSetupBox = headerSetup.column() headerSetupBox.row().prop(self, "headerMenuTab", expand=True) @@ -310,9 +315,9 @@ def draw_props(self, layout: UILayout, objName: str): elif self.headerMenuTab == "Adult Night": self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) elif self.headerMenuTab == "Cutscene": - can_draw_cs_header = True + oot_can_draw_cs_header = True - if can_draw_cs_header: + if game_data.z64.is_mm() or oot_can_draw_cs_header: prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") drawAddButton(headerSetup, len(self.cutsceneHeaders), "Room", None, objName) index = self.currentCutsceneIndex diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 07ab149ce..6ec38379d 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -7,9 +7,8 @@ from bpy.utils import register_class, unregister_class from bpy.ops import object from mathutils import Matrix, Vector -from ...f3d.f3d_gbi import TextureExportSettings, DLFormat from ...utility import PluginError, raisePluginError, ootGetSceneOrRoomHeader -from ..utility import ExportInfo, RemoveInfo, sceneNameFromID, is_game_oot +from ..utility import ExportInfo, RemoveInfo, sceneNameFromID from ...game_data import game_data from ..constants import ootEnumSceneID, mm_enum_scene_id from ..importer import parseScene @@ -36,7 +35,7 @@ def dummy_view_layer_update(context): def parseSceneFunc(): game_data.z64.update(bpy.context, None) settings = bpy.context.scene.ootSceneImportSettings - parseScene(settings, settings.option if is_game_oot() else settings.mm_option) + parseScene(settings, settings.option if game_data.z64.is_oot() else settings.mm_option) class OOT_SearchSceneEnumOperator(Operator): @@ -182,10 +181,10 @@ def execute(self, context): try: settings = context.scene.ootSceneExportSettings levelName = settings.name - option = settings.option if is_game_oot() else settings.mm_option + option = settings.option if game_data.z64.is_oot() else settings.mm_option hackerFeaturesEnabled = False - if is_game_oot(): + if game_data.z64.is_oot(): bootOptions = context.scene.fast64.oot.bootupSceneOptions hackerFeaturesEnabled = context.scene.fast64.oot.hackerFeaturesEnabled @@ -254,7 +253,7 @@ class OOT_RemoveScene(Operator): def execute(self, context): settings = context.scene.ootSceneRemoveSettings # Type: Z64_RemoveSceneSettingsProperty - option = settings.option if is_game_oot() else settings.mm_option + option = settings.option if game_data.z64.is_oot() else settings.mm_option if settings.customExport: self.report({"ERROR"}, "You can only remove scenes from your decomp path.") diff --git a/fast64_internal/z64/scene/panels.py b/fast64_internal/z64/scene/panels.py index 7cbf32a49..d12ff54c4 100644 --- a/fast64_internal/z64/scene/panels.py +++ b/fast64_internal/z64/scene/panels.py @@ -1,11 +1,9 @@ -import bpy -import os - from bpy.types import UILayout from bpy.utils import register_class, unregister_class +from ...game_data import game_data from ...panels import Z64_Panel from ..constants import ootEnumSceneID, mm_enum_scene_id -from ..utility import getEnumName, is_game_oot +from ..utility import getEnumName from .properties import ( Z64_ExportSceneSettingsProperty, Z64_ImportSceneSettingsProperty, @@ -30,7 +28,7 @@ class OOT_ExportScenePanel(Z64_Panel): def drawSceneSearchOp(self, layout: UILayout, enumValue: str, opName: str): searchBox = layout.box().row() - if is_game_oot(): + if game_data.z64.is_oot(): searchBox.operator(OOT_SearchSceneEnumOperator.bl_idname, icon="VIEWZOOM", text="").opName = opName searchBox.label(text=getEnumName(ootEnumSceneID, enumValue)) else: @@ -46,7 +44,9 @@ def draw(self, context): settings: Z64_ExportSceneSettingsProperty = context.scene.ootSceneExportSettings if not settings.customExport: - self.drawSceneSearchOp(exportBox, settings.option if is_game_oot() else settings.mm_option, "Export") + self.drawSceneSearchOp( + exportBox, settings.option if game_data.z64.is_oot() else settings.mm_option, "Export" + ) settings.draw_props(exportBox) if context.scene.fast64.oot.hackerFeaturesEnabled: @@ -68,7 +68,7 @@ def draw(self, context): importBox.label(text="Scene Importer") importSettings: Z64_ImportSceneSettingsProperty = context.scene.ootSceneImportSettings - option = importSettings.option if is_game_oot() else importSettings.mm_option + option = importSettings.option if game_data.z64.is_oot() else importSettings.mm_option if not importSettings.isCustomDest: self.drawSceneSearchOp(importBox, option, "Import") @@ -81,7 +81,7 @@ def draw(self, context): removeBox.label(text="Remove Scene") removeSettings: Z64_RemoveSceneSettingsProperty = context.scene.ootSceneRemoveSettings - option = removeSettings.option if is_game_oot() else removeSettings.mm_option + option = removeSettings.option if game_data.z64.is_oot() else removeSettings.mm_option self.drawSceneSearchOp(removeBox, option, "Remove") removeSettings.draw_props(removeBox) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 2885fc40d..96c037ef5 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -22,7 +22,6 @@ drawEnumWithCustom, drawAddButton, is_oot_features, - is_game_oot, ) from ..constants import ( @@ -123,7 +122,7 @@ def draw_props(self, layout: UILayout, index: int, headerIndex: int, objName: st if self.expandTab: drawCollectionOps(box, index, "Exit", headerIndex, objName) - if is_game_oot(): + if game_data.z64.is_oot(): drawEnumWithCustom(box, self, "exitIndex", "Exit Index", "") if self.exitIndex != "Custom": @@ -425,7 +424,12 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj if headerIndex is not None and headerIndex > (game_data.z64.cs_index_start - 1): drawCollectionOps(layout, headerIndex - game_data.z64.cs_index_start, "Scene", None, objName) - if is_game_oot() and headerIndex is not None and headerIndex > 0 and headerIndex < game_data.z64.cs_index_start: + if ( + game_data.z64.is_oot() + and headerIndex is not None + and headerIndex > 0 + and headerIndex < game_data.z64.cs_index_start + ): layout.prop(self, "usePreviousHeader", text="Use Previous Header") if self.usePreviousHeader: return @@ -443,7 +447,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj # General drawEnumWithCustom(general, self, "globalObject", "Global Object", "", "globalObjectCustom") - if is_game_oot(): + if game_data.z64.is_oot(): drawEnumWithCustom(general, self, "naviCup", "Navi Hints", "") if headerIndex is None or headerIndex == 0: self.sceneTableEntry.draw_props(general) @@ -569,9 +573,9 @@ class Z64_AlternateSceneHeaderProperty(PropertyGroup): def draw_props(self, layout: UILayout, objName: str): headerSetup = layout.column() - can_draw_cs_header = not is_game_oot() + oot_can_draw_cs_header = False - if not can_draw_cs_header: + if game_data.z64.is_oot(): headerSetupBox = headerSetup.column() headerSetupBox.row().prop(self, "headerMenuTab", expand=True) @@ -582,9 +586,9 @@ def draw_props(self, layout: UILayout, objName: str): elif self.headerMenuTab == "Adult Night": self.adultNightHeader.draw_props(headerSetupBox, None, 3, objName) elif self.headerMenuTab == "Cutscene": - can_draw_cs_header = True + oot_can_draw_cs_header = True - if can_draw_cs_header: + if game_data.z64.is_mm() or oot_can_draw_cs_header: prop_split(headerSetup, self, "currentCutsceneIndex", "Cutscene Index") drawAddButton(headerSetup, len(self.cutsceneHeaders), "Scene", None, objName) index = self.currentCutsceneIndex @@ -634,7 +638,7 @@ class Z64_RemoveSceneSettingsProperty(PropertyGroup): mm_option: EnumProperty(items=mm_enum_scene_id, default="SCENE_20SICHITAI2") def draw_props(self, layout: UILayout): - if is_game_oot() and self.option == "Custom" or self.mm_option == "Custom": + if game_data.z64.is_oot() and self.option == "Custom" or self.mm_option == "Custom": prop_split(layout, self, "subFolder", "Subfolder") prop_split(layout, self, "name", "Name") @@ -658,7 +662,7 @@ def draw_props(self, layout: UILayout): prop_split(layout, self, "name", "Name") customExportWarning(layout) else: - if is_game_oot() and self.option == "Custom" or self.mm_option == "Custom": + if game_data.z64.is_oot() and self.option == "Custom" or self.mm_option == "Custom": prop_split(layout, self, "subFolder", "Subfolder") prop_split(layout, self, "name", "Name") @@ -715,11 +719,11 @@ def draw_props(self, layout: UILayout, sceneOption: str): prop_split(col, self, "destPath", "Directory") prop_split(col, self, "name", "Name") else: - if is_game_oot() and self.option == "Custom" or self.mm_option == "Custom": + if game_data.z64.is_oot() and self.option == "Custom" or self.mm_option == "Custom": prop_split(col, self, "subFolder", "Subfolder") prop_split(col, self, "name", "Name") - if is_game_oot(): + if game_data.z64.is_oot(): if "SCENE_JABU_JABU" in sceneOption: col.label(text="Pulsing wall effect won't be imported.", icon="ERROR") diff --git a/fast64_internal/z64/spline/properties.py b/fast64_internal/z64/spline/properties.py index 3b0f89d75..05aca7d65 100644 --- a/fast64_internal/z64/spline/properties.py +++ b/fast64_internal/z64/spline/properties.py @@ -4,7 +4,8 @@ from bpy.props import EnumProperty, PointerProperty, StringProperty, IntProperty from bpy.utils import register_class, unregister_class from ...utility import prop_split -from ..utility import drawEnumWithCustom, is_oot_features, is_game_oot +from ...game_data import game_data +from ..utility import drawEnumWithCustom, is_oot_features from ..collision.constants import enum_camera_crawlspace_stype from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -42,7 +43,7 @@ def draw_props( headerProp: Z64_ActorHeaderProperty = bpy.data.objects[objName].ootSplineProperty.headerSettings headerProp.draw_props(layout, "Curve", altSceneProp, objName) elif self.splineType == "Crawlspace": - if not is_game_oot(): + if game_data.z64.is_mm(): layout.label(text="Warning: MM doesn't have crawlspaces implemented.", icon="ERROR") layout.label(text="This counts as a camera for index purposes.", icon="INFO") drawEnumWithCustom(layout, self, "camSType", "Camera S Type", "") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index cb159e291..d9e5b6d97 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -3,17 +3,18 @@ import os import re +from dataclasses import dataclass from ast import parse, Expression, Constant, UnaryOp, USub, Invert, BinOp from mathutils import Vector from bpy.types import Object from bpy.utils import register_class, unregister_class from bpy.types import Object from typing import Callable, Optional, TYPE_CHECKING, List +from ..game_data import game_data from .constants import ( ootSceneIDToName, mm_scene_id_to_name, ) -from dataclasses import dataclass from ..utility import ( PluginError, @@ -34,12 +35,8 @@ from .actor.properties import Z64_ActorProperty -def is_game_oot(): - return bpy.context.scene.gameEditorMode == "OOT" - - def is_oot_features(): - return is_game_oot() and not bpy.context.scene.fast64.oot.mm_features + return game_data.z64.is_oot() and not bpy.context.scene.fast64.oot.mm_features def isPathObject(obj: bpy.types.Object) -> bool: @@ -186,7 +183,7 @@ def isPathObject(obj: bpy.types.Object) -> bool: def sceneNameFromID(scene_id: str): - if is_game_oot(): + if game_data.z64.is_oot(): scene_id_to_name = ootSceneIDToName else: scene_id_to_name = mm_scene_id_to_name @@ -268,7 +265,7 @@ def addIncludeFilesExtension(objectName, objectPath, assetName, extension): def getSceneDirFromLevelName(name: str, include_extracted: bool = False): extracted = bpy.context.scene.fast64.oot.get_extracted_path() if include_extracted else "." - if is_game_oot(): + if game_data.z64.is_oot(): for sceneDir, dirLevels in ootSceneDirs.items(): if name in dirLevels: return f"{extracted}/" + sceneDir + name @@ -917,7 +914,7 @@ def getActiveHeaderIndex() -> int: if header.menuTab != "Alternate": headerIndex = 0 else: - if is_game_oot(): + if game_data.z64.is_oot(): if altHeader.headerMenuTab == "Child Night": headerIndex = 1 elif altHeader.headerMenuTab == "Adult Day": @@ -929,7 +926,7 @@ def getActiveHeaderIndex() -> int: else: headerIndex = altHeader.currentCutsceneIndex - if is_game_oot(): + if game_data.z64.is_oot(): return ( headerIndex, altHeader.childNightHeader.usePreviousHeader, @@ -958,7 +955,7 @@ def setActorVisibility( ): headerIndex, childNightHeader, adultDayHeader, adultNightHeader = activeHeaderInfo - if is_game_oot(): + if game_data.z64.is_oot(): usePreviousHeader = [False, childNightHeader, adultDayHeader, adultNightHeader] if headerIndex < 4: @@ -970,7 +967,7 @@ def setActorVisibility( if headerSettings is None: return - if is_game_oot(): + if game_data.z64.is_oot(): if headerSettings.sceneSetupPreset == "All Scene Setups": actorObj.hide_set(False) elif headerSettings.sceneSetupPreset == "All Non-Cutscene Scene Setups": From b8277c71c534c4f42f5ee05641df2d5151d86f9c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:56:28 +0100 Subject: [PATCH 075/126] implement pathway export and some fixes --- .../data/z64/xml/mm_actor_list.xml | 854 +++++++++--------- fast64_internal/utility.py | 3 +- fast64_internal/z64/exporter/room/header.py | 2 +- fast64_internal/z64/exporter/scene/actors.py | 4 +- .../z64/exporter/scene/pathways.py | 25 +- fast64_internal/z64/room/properties.py | 2 +- fast64_internal/z64/scene/properties.py | 2 +- 7 files changed, 453 insertions(+), 439 deletions(-) diff --git a/fast64_internal/data/z64/xml/mm_actor_list.xml b/fast64_internal/data/z64/xml/mm_actor_list.xml index aa0ff6462..3593921e6 100644 --- a/fast64_internal/data/z64/xml/mm_actor_list.xml +++ b/fast64_internal/data/z64/xml/mm_actor_list.xml @@ -43,7 +43,7 @@ for each sub element (of ) mentioned below: - -> used to draw the collectible drop item -->
- + @@ -124,7 +124,7 @@ for each sub element (of ) mentioned below: - + Golden Golden - Appears - Clear Flag @@ -145,22 +145,22 @@ for each sub element (of ) mentioned below: - - + + - + - + Regular Large - + - + @@ -168,24 +168,24 @@ for each sub element (of ) mentioned below: - - - + + + - - - + + + - + - + - + Default Invisible @@ -193,56 +193,56 @@ for each sub element (of ) mentioned below: - + - - - - + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - + + + + - + - + - - - - - - - - - - + + + + + + + + + + - - + + - + @@ -252,489 +252,489 @@ for each sub element (of ) mentioned below: - - - + + + - + - - + + - - + + - - - + + + - + - - - - - - - - + + + + + + + + - - + + - - + + - - + + - + - - + + - + - + - - - - + + + + - - - - + + + + - - + + - + - + - + - - - - + + + + - + - - - - + + + + - + - - - - + + + + - - + + - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - + - + - - - + + + - + - - + + - - + + - - - - - - + + + + + + - - - - - - - - + + + + + + + + - - - - - - + + + + + + - - + + - - + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - + + - - - - - + + + + + - + - - - - + + + + - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - + - - - - - - - - - - - + + + + + + + + + + + - + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + - + - + diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index f51aee1ca..e33ca044b 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -3,7 +3,6 @@ from math import pi, ceil, degrees, radians, copysign from mathutils import * from .utility_anim import * -from .game_data import game_data from typing import Callable, Iterable, Any, Optional, Tuple, TypeVar, Union, TYPE_CHECKING from bpy.types import UILayout, Scene, World @@ -1670,6 +1669,8 @@ def lightDataToObj(lightData): def ootGetSceneOrRoomHeader(parent: bpy.types.Object, idx: int, isRoom: bool): + from .game_data import game_data # circular import fix + # This should be in oot_utility.py, but it is needed in f3d_material.py # which creates a circular import. The real problem is that the F3D render # settings stuff should be in a place which can import both SM64 and OoT diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index f9229813f..dea886cd5 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -196,7 +196,7 @@ def new( if not Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex): continue - actor_id: str = actorProp.actorID if game_data.z64.is_oot() else actorProp.actor_id + actor_id: str = actorProp.actor_id # The Actor list is filled with ``("None", f"{i} (Deleted from the XML)", "None")`` for # the total number of actors defined in the XML. If the user deletes one, this will prevent diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 236008fdf..77a10f283 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -61,7 +61,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in actorObjList: transActorProp = obj.ootTransitionActorProperty actorProp: Z64_ActorProperty = transActorProp.actor - actor_id: str = actorProp.actorID if game_data.z64.is_oot() else actorProp.actor_id + actor_id: str = actorProp.actor_id if Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) transActor = TransitionActor() @@ -156,7 +156,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): for obj in actorObjList: entranceProp = obj.ootEntranceProperty actorProp: Z64_ActorProperty = entranceProp.actor - actor_id: str = actorProp.actorID if game_data.z64.is_oot() else actorProp.actor_id + actor_id: str = actorProp.actor_id if Utility.isCurrentHeaderValid(actorProp.headerSettings, headerIndex) and actor_id != "None": pos, rot, _, _ = Utility.getConvertedTransform(transform, sceneObj, obj, True) entranceActor = EntranceActor() diff --git a/fast64_internal/z64/exporter/scene/pathways.py b/fast64_internal/z64/exporter/scene/pathways.py index 2936132c4..ca3777fce 100644 --- a/fast64_internal/z64/exporter/scene/pathways.py +++ b/fast64_internal/z64/exporter/scene/pathways.py @@ -1,17 +1,21 @@ from dataclasses import dataclass, field +from typing import Optional from mathutils import Matrix from bpy.types import Object +from ....game_data import game_data from ....utility import PluginError, CData, indent from ...utility import getObjectList from ..utility import Utility @dataclass -class Path: +class ScenePath: """This class defines a pathway""" name: str - points: list[tuple[int, int, int]] = field(default_factory=list) + additional_path_index: Optional[int] + custom_value: Optional[int] + points: list[tuple[int, int, int]] def getC(self): """Returns the pathway position array""" @@ -40,11 +44,11 @@ class ScenePathways: """This class hosts pathways array data""" name: str - pathList: list[Path] + pathList: list[ScenePath] @staticmethod def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): - pathFromIndex: dict[int, Path] = {} + pathFromIndex: dict[int, ScenePath] = {} pathObjList = getObjectList(sceneObj.children_recursive, "CURVE", splineType="Path") for obj in pathObjList: @@ -53,8 +57,10 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): isHeaderValid = Utility.isCurrentHeaderValid(obj.ootSplineProperty.headerSettings, headerIndex) if isHeaderValid and Utility.validateCurveData(obj): if pathProps.index not in pathFromIndex: - pathFromIndex[pathProps.index] = Path( + pathFromIndex[pathProps.index] = ScenePath( f"{name}List{pathProps.index:02}", + pathProps.opt_path_index if game_data.z64.is_mm() else None, + pathProps.custom_value if game_data.z64.is_mm() else None, [relativeTransform @ point.co.xyz for point in obj.data.splines[0].points], ) else: @@ -85,7 +91,14 @@ def getC(self): pathListData.source = listName + " = {\n" for path in self.pathList: - pathListData.source += indent + "{ " + f"ARRAY_COUNTU({path.name}), {path.name}" + " },\n" + pathListData.source += ( + (indent + "{ ") + + f"ARRAY_COUNTU({path.name}), " + + (f"{path.additional_path_index}, " if game_data.z64.is_mm() else "") + + (f"{path.custom_value}, " if game_data.z64.is_mm() else "") + + f"{path.name}" + + " },\n" + ) pathData.append(path.getC()) pathListData.source += "};\n\n" diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index b6c6da803..8be5f2ddb 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -225,7 +225,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj behaviorBox.prop(self, "showInvisibleActors", text="Show Invisible Actors") if not is_oot_features(): - if self.mm_room_type in {"ROOM_TYPE_DUNGEON", "ROOM_TYPE_BOSS"}: + if self.roomBehaviour in {"ROOM_TYPE_DUNGEON", "ROOM_TYPE_BOSS"}: behaviorBox.label(text="The Three-Day Events actor will be automatically", icon="INFO") behaviorBox.label(text="spawned by `Play_Init` (see 'ACTOR_EN_TEST4' usage).") else: diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 96c037ef5..4344b27e0 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -262,7 +262,7 @@ class Z64_ExtraCutsceneProperty(PropertyGroup): def minimap_chest_poll(self: "Z64_MapDataChestProperty", object: Object): return ( - object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actorID == "ACTOR_EN_BOX" + object.type == "EMPTY" and object.ootEmptyType == "Actor" and object.ootActorProperty.actor_id == "ACTOR_EN_BOX" ) From 9ac2043209cb4bd4f336da9645956639c87df404 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:02:41 +0100 Subject: [PATCH 076/126] data cleanup --- fast64_internal/data/z64/actor_data.py | 3 +- fast64_internal/data/z64/data.py | 507 ++---------------- fast64_internal/data/z64/enum_data.py | 133 ++--- fast64_internal/data/z64/getters.py | 9 + fast64_internal/data/z64/object_data.py | 3 +- fast64_internal/data/z64/xml/mm_enum_data.xml | 74 ++- .../data/z64/xml/oot_enum_data.xml | 96 +++- fast64_internal/z64/actor/operators.py | 6 +- fast64_internal/z64/actor/properties.py | 38 +- fast64_internal/z64/collision/properties.py | 8 +- fast64_internal/z64/cutscene/classes.py | 8 +- fast64_internal/z64/cutscene/constants.py | 2 +- .../z64/cutscene/exporter/classes.py | 6 +- .../z64/cutscene/motion/operators.py | 2 +- .../z64/cutscene/motion/properties.py | 4 +- fast64_internal/z64/cutscene/operators.py | 4 +- fast64_internal/z64/cutscene/properties.py | 16 +- .../z64/exporter/cutscene/actor_cue.py | 2 +- .../z64/exporter/cutscene/common.py | 2 +- fast64_internal/z64/exporter/cutscene/data.py | 6 +- fast64_internal/z64/exporter/room/header.py | 4 +- fast64_internal/z64/exporter/scene/actors.py | 4 +- fast64_internal/z64/importer/actor.py | 6 +- fast64_internal/z64/importer/room_header.py | 2 +- fast64_internal/z64/importer/scene.py | 2 +- .../z64/importer/scene_collision.py | 8 +- fast64_internal/z64/importer/scene_header.py | 6 +- fast64_internal/z64/object.py | 4 +- fast64_internal/z64/room/operators.py | 2 +- fast64_internal/z64/room/properties.py | 12 +- fast64_internal/z64/scene/operators.py | 2 +- fast64_internal/z64/scene/properties.py | 12 +- fast64_internal/z64/upgrade.py | 22 +- 33 files changed, 332 insertions(+), 683 deletions(-) diff --git a/fast64_internal/data/z64/actor_data.py b/fast64_internal/data/z64/actor_data.py index 12fedb58d..04c59855b 100644 --- a/fast64_internal/data/z64/actor_data.py +++ b/fast64_internal/data/z64/actor_data.py @@ -1,8 +1,7 @@ from os import path from dataclasses import dataclass from pathlib import Path -from .getters import get_xml_root -from .data import Z64_BaseElement +from .getters import Z64_BaseElement, get_xml_root @dataclass diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 668cec812..60ba57e27 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -1,157 +1,17 @@ +import bpy + from dataclasses import dataclass from typing import Optional from bpy.types import Context - - -@dataclass -class Z64_BaseElement: - id: str - key: str - name: str - index: int +from .enum_data import Z64_EnumData +from .object_data import Z64_ObjectData +from .actor_data import Z64_ActorData # --- # TODO: get this from XML -ootEnumMusicSeq = [ - # see https://github.com/zeldaret/oot/blob/9f09505d34619883748a7dab05071883281c14fd/include/sequence.h#L4-L118 - ("Custom", "Custom", "Custom"), - ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), - ("NA_BGM_NATURE_AMBIENCE", "Nature Ambiance", "Nature Ambiance"), - ("NA_BGM_FIELD_LOGIC", "Hyrule Field", "Hyrule Field"), - ( - "NA_BGM_FIELD_INIT", - "Hyrule Field (Initial Segment From Loading Area)", - "Hyrule Field (Initial Segment From Loading Area)", - ), - ("NA_BGM_FIELD_DEFAULT_1", "Hyrule Field (Moving Segment 1)", "Hyrule Field (Moving Segment 1)"), - ("NA_BGM_FIELD_DEFAULT_2", "Hyrule Field (Moving Segment 2)", "Hyrule Field (Moving Segment 2)"), - ("NA_BGM_FIELD_DEFAULT_3", "Hyrule Field (Moving Segment 3)", "Hyrule Field (Moving Segment 3)"), - ("NA_BGM_FIELD_DEFAULT_4", "Hyrule Field (Moving Segment 4)", "Hyrule Field (Moving Segment 4)"), - ("NA_BGM_FIELD_DEFAULT_5", "Hyrule Field (Moving Segment 5)", "Hyrule Field (Moving Segment 5)"), - ("NA_BGM_FIELD_DEFAULT_6", "Hyrule Field (Moving Segment 6)", "Hyrule Field (Moving Segment 6)"), - ("NA_BGM_FIELD_DEFAULT_7", "Hyrule Field (Moving Segment 7)", "Hyrule Field (Moving Segment 7)"), - ("NA_BGM_FIELD_DEFAULT_8", "Hyrule Field (Moving Segment 8)", "Hyrule Field (Moving Segment 8)"), - ("NA_BGM_FIELD_DEFAULT_9", "Hyrule Field (Moving Segment 9)", "Hyrule Field (Moving Segment 9)"), - ("NA_BGM_FIELD_DEFAULT_A", "Hyrule Field (Moving Segment 10)", "Hyrule Field (Moving Segment 10)"), - ("NA_BGM_FIELD_DEFAULT_B", "Hyrule Field (Moving Segment 11)", "Hyrule Field (Moving Segment 11)"), - ("NA_BGM_FIELD_ENEMY_INIT", "Hyrule Field (Enemy Approaches)", "Hyrule Field (Enemy Approaches)"), - ("NA_BGM_FIELD_ENEMY_1", "Hyrule Field (Enemy Near Segment 1)", "Hyrule Field (Enemy Near Segment 1)"), - ("NA_BGM_FIELD_ENEMY_2", "Hyrule Field (Enemy Near Segment 2)", "Hyrule Field (Enemy Near Segment 2)"), - ("NA_BGM_FIELD_ENEMY_3", "Hyrule Field (Enemy Near Segment 3)", "Hyrule Field (Enemy Near Segment 3)"), - ("NA_BGM_FIELD_ENEMY_4", "Hyrule Field (Enemy Near Segment 4)", "Hyrule Field (Enemy Near Segment 4)"), - ( - "NA_BGM_FIELD_STILL_1", - "Hyrule Field (Standing Still Segment 1)", - "Hyrule Field (Standing Still Segment 1)", - ), - ( - "NA_BGM_FIELD_STILL_2", - "Hyrule Field (Standing Still Segment 2)", - "Hyrule Field (Standing Still Segment 2)", - ), - ( - "NA_BGM_FIELD_STILL_3", - "Hyrule Field (Standing Still Segment 3)", - "Hyrule Field (Standing Still Segment 3)", - ), - ( - "NA_BGM_FIELD_STILL_4", - "Hyrule Field (Standing Still Segment 4)", - "Hyrule Field (Standing Still Segment 4)", - ), - ("NA_BGM_DUNGEON", "Dodongo's Cavern", "Dodongo's Cavern"), - ("NA_BGM_KAKARIKO_ADULT", "Kakariko Village (Adult)", "Kakariko Village (Adult)"), - ("NA_BGM_ENEMY", "Enemy Battle", "Enemy Battle"), - ("NA_BGM_BOSS", "Boss Battle 00", "Boss Battle 00"), - ("NA_BGM_INSIDE_DEKU_TREE", "Inside the Deku Tree", "Inside the Deku Tree"), - ("NA_BGM_MARKET", "Market", "Market"), - ("NA_BGM_TITLE", "Title Theme", "Title Theme"), - ("NA_BGM_LINK_HOUSE", "Link's House", "Link's House"), - ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), - ("NA_BGM_BOSS_CLEAR", "Boss Clear", "Boss Clear"), - ("NA_BGM_ITEM_GET", "Item Get", "Item Get"), - ("NA_BGM_OPENING_GANON", "Opening Ganon", "Opening Ganon"), - ("NA_BGM_HEART_GET", "Heart Get", "Heart Get"), - ("NA_BGM_OCA_LIGHT", "Prelude Of Light", "Prelude Of Light"), - ("NA_BGM_JABU_JABU", "Inside Jabu-Jabu's Belly", "Inside Jabu-Jabu's Belly"), - ("NA_BGM_KAKARIKO_KID", "Kakariko Village (Child)", "Kakariko Village (Child)"), - ("NA_BGM_GREAT_FAIRY", "Great Fairy's Fountain", "Great Fairy's Fountain"), - ("NA_BGM_ZELDA_THEME", "Zelda's Theme", "Zelda's Theme"), - ("NA_BGM_FIRE_TEMPLE", "Fire Temple", "Fire Temple"), - ("NA_BGM_OPEN_TRE_BOX", "Open Treasure Chest", "Open Treasure Chest"), - ("NA_BGM_FOREST_TEMPLE", "Forest Temple", "Forest Temple"), - ("NA_BGM_COURTYARD", "Hyrule Castle Courtyard", "Hyrule Castle Courtyard"), - ("NA_BGM_GANON_TOWER", "Ganondorf's Theme", "Ganondorf's Theme"), - ("NA_BGM_LONLON", "Lon Lon Ranch", "Lon Lon Ranch"), - ("NA_BGM_GORON_CITY", "Goron City", "Goron City"), - ("NA_BGM_FIELD_MORNING", "Hyrule Field Morning Theme", "Hyrule Field Morning Theme"), - ("NA_BGM_SPIRITUAL_STONE", "Spiritual Stone Get", "Spiritual Stone Get"), - ("NA_BGM_OCA_BOLERO", "Bolero of Fire", "Bolero of Fire"), - ("NA_BGM_OCA_MINUET", "Minuet of Woods", "Minuet of Woods"), - ("NA_BGM_OCA_SERENADE", "Serenade of Water", "Serenade of Water"), - ("NA_BGM_OCA_REQUIEM", "Requiem of Spirit", "Requiem of Spirit"), - ("NA_BGM_OCA_NOCTURNE", "Nocturne of Shadow", "Nocturne of Shadow"), - ("NA_BGM_MINI_BOSS", "Mini-Boss Battle", "Mini-Boss Battle"), - ("NA_BGM_SMALL_ITEM_GET", "Obtain Small Item", "Obtain Small Item"), - ("NA_BGM_TEMPLE_OF_TIME", "Temple of Time", "Temple of Time"), - ("NA_BGM_EVENT_CLEAR", "Escape from Lon Lon Ranch", "Escape from Lon Lon Ranch"), - ("NA_BGM_KOKIRI", "Kokiri Forest", "Kokiri Forest"), - ("NA_BGM_OCA_FAIRY_GET", "Obtain Fairy Ocarina", "Obtain Fairy Ocarina"), - ("NA_BGM_SARIA_THEME", "Lost Woods", "Lost Woods"), - ("NA_BGM_SPIRIT_TEMPLE", "Spirit Temple", "Spirit Temple"), - ("NA_BGM_HORSE", "Horse Race", "Horse Race"), - ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), - ("NA_BGM_INGO", "Ingo's Theme", "Ingo's Theme"), - ("NA_BGM_MEDALLION_GET", "Obtain Medallion", "Obtain Medallion"), - ("NA_BGM_OCA_SARIA", "Ocarina Saria's Song", "Ocarina Saria's Song"), - ("NA_BGM_OCA_EPONA", "Ocarina Epona's Song", "Ocarina Epona's Song"), - ("NA_BGM_OCA_ZELDA", "Ocarina Zelda's Lullaby", "Ocarina Zelda's Lullaby"), - ("NA_BGM_OCA_SUNS", "Sun's Song", "Sun's Song"), - ("NA_BGM_OCA_TIME", "Song of Time", "Song of Time"), - ("NA_BGM_OCA_STORM", "Song of Storms", "Song of Storms"), - ("NA_BGM_NAVI_OPENING", "Fairy Flying", "Fairy Flying"), - ("NA_BGM_DEKU_TREE_CS", "Deku Tree", "Deku Tree"), - ("NA_BGM_WINDMILL", "Windmill Hut", "Windmill Hut"), - ("NA_BGM_HYRULE_CS", "Legend of Hyrule", "Legend of Hyrule"), - ("NA_BGM_MINI_GAME", "Shooting Gallery", "Shooting Gallery"), - ("NA_BGM_SHEIK", "Sheik's Theme", "Sheik's Theme"), - ("NA_BGM_ZORA_DOMAIN", "Zora's Domain", "Zora's Domain"), - ("NA_BGM_APPEAR", "Enter Zelda", "Enter Zelda"), - ("NA_BGM_ADULT_LINK", "Goodbye to Zelda", "Goodbye to Zelda"), - ("NA_BGM_MASTER_SWORD", "Master Sword", "Master Sword"), - ("NA_BGM_INTRO_GANON", "Ganon Intro", "Ganon Intro"), - ("NA_BGM_SHOP", "Shop", "Shop"), - ("NA_BGM_CHAMBER_OF_SAGES", "Chamber of the Sages", "Chamber of the Sages"), - ("NA_BGM_FILE_SELECT", "File Select", "File Select"), - ("NA_BGM_ICE_CAVERN", "Ice Cavern", "Ice Cavern"), - ("NA_BGM_DOOR_OF_TIME", "Open Door of Temple of Time", "Open Door of Temple of Time"), - ("NA_BGM_OWL", "Kaepora Gaebora's Theme", "Kaepora Gaebora's Theme"), - ("NA_BGM_SHADOW_TEMPLE", "Shadow Temple", "Shadow Temple"), - ("NA_BGM_WATER_TEMPLE", "Water Temple", "Water Temple"), - ("NA_BGM_BRIDGE_TO_GANONS", "Ganon's Castle Bridge", "Ganon's Castle Bridge"), - ("NA_BGM_OCARINA_OF_TIME", "Ocarina of Time", "Ocarina of Time"), - ("NA_BGM_GERUDO_VALLEY", "Gerudo Valley", "Gerudo Valley"), - ("NA_BGM_POTION_SHOP", "Potion Shop", "Potion Shop"), - ("NA_BGM_KOTAKE_KOUME", "Kotake & Koume's Theme", "Kotake & Koume's Theme"), - ("NA_BGM_ESCAPE", "Escape from Ganon's Castle", "Escape from Ganon's Castle"), - ("NA_BGM_UNDERGROUND", "Ganon's Castle Under Ground", "Ganon's Castle Under Ground"), - ("NA_BGM_GANONDORF_BOSS", "Ganondorf Battle", "Ganondorf Battle"), - ("NA_BGM_GANON_BOSS", "Ganon Battle", "Ganon Battle"), - ("NA_BGM_END_DEMO", "Seal of Six Sages", "Seal of Six Sages"), - ("NA_BGM_STAFF_1", "End Credits I", "End Credits I"), - ("NA_BGM_STAFF_2", "End Credits II", "End Credits II"), - ("NA_BGM_STAFF_3", "End Credits III", "End Credits III"), - ("NA_BGM_STAFF_4", "End Credits IV", "End Credits IV"), - ("NA_BGM_FIRE_BOSS", "King Dodongo & Volvagia Boss Battle", "King Dodongo & Volvagia Boss Battle"), - ("NA_BGM_TIMED_MINI_GAME", "Mini-Game", "Mini-Game"), - ("NA_BGM_CUTSCENE_EFFECTS", "Various Cutscene Sounds", "Various Cutscene Sounds"), - ("NA_BGM_NO_MUSIC", "No Music", "No Music"), - ("NA_BGM_NATURE_SFX_RAIN", "Nature Ambiance: Rain", "Nature Ambiance: Rain"), -] - ootEnumNightSeq = [ ("Custom", "Custom", "Custom"), ("0x00", "General Night", "NATURE_ID_GENERAL_NIGHT"), @@ -177,137 +37,6 @@ class Z64_BaseElement: ("0xFF", "Disabled", "NATURE_ID_DISABLED"), ] -enum_seq_id = [ - ("Custom", "Custom", "Custom"), - ("NA_BGM_GENERAL_SFX", "General Sound Effects", "General Sound Effects"), - ("NA_BGM_AMBIENCE", "Ambient background noises", "Ambient background noises"), - ("NA_BGM_TERMINA_FIELD", "Termina Field", "Termina Field"), - ("NA_BGM_CHASE", "Chase", "Chase"), - ("NA_BGM_MAJORAS_THEME", "Majora's Theme", "Majora's Theme"), - ("NA_BGM_CLOCK_TOWER", "Clock Tower", "Clock Tower"), - ("NA_BGM_STONE_TOWER_TEMPLE", "Stone Tower Temple", "Stone Tower Temple"), - ("NA_BGM_INV_STONE_TOWER_TEMPLE", "Stone Tower Temple Upside-down", "Stone Tower Temple Upside-down"), - ("NA_BGM_FAILURE_0", "Missed Event 1", "Missed Event 1"), - ("NA_BGM_FAILURE_1", "Missed Event 2", "Missed Event 2"), - ("NA_BGM_HAPPY_MASK_SALESMAN", "Happy Mask Saleman's Theme", "Happy Mask Saleman's Theme"), - ("NA_BGM_SONG_OF_HEALING", "Song Of Healing", "Song Of Healing"), - ("NA_BGM_SWAMP_REGION", "Southern Swamp", "Southern Swamp"), - ("NA_BGM_ALIEN_INVASION", "Ghost Attack", "Ghost Attack"), - ("NA_BGM_SWAMP_CRUISE", "Boat Cruise", "Boat Cruise"), - ("NA_BGM_SHARPS_CURSE", "Sharp's Curse", "Sharp's Curse"), - ("NA_BGM_GREAT_BAY_REGION", "Great Bay Coast", "Great Bay Coast"), - ("NA_BGM_IKANA_REGION", "Ikana Valley", "Ikana Valley"), - ("NA_BGM_DEKU_PALACE", "Deku Palace", "Deku Palace"), - ("NA_BGM_MOUNTAIN_REGION", "Mountain Village", "Mountain Village"), - ("NA_BGM_PIRATES_FORTRESS", "Pirates' Fortress", "Pirates' Fortress"), - ("NA_BGM_CLOCK_TOWN_DAY_1", "Clock Town, First Day", "Clock Town, First Day"), - ("NA_BGM_CLOCK_TOWN_DAY_2", "Clock Town, Second Day", "Clock Town, Second Day"), - ("NA_BGM_CLOCK_TOWN_DAY_3", "Clock Town, Third Day", "Clock Town, Third Day"), - ("NA_BGM_FILE_SELECT", "File Select", "File Select"), - ("NA_BGM_CLEAR_EVENT", "Event Clear", "Event Clear"), - ("NA_BGM_ENEMY", "Battle", "Battle"), - ("NA_BGM_BOSS", "Boss Battle", "Boss Battle"), - ("NA_BGM_WOODFALL_TEMPLE", "Woodfall Temple", "Woodfall Temple"), - ("NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE"), - ("NA_BGM_OPENING", "Opening", "Opening"), - ("NA_BGM_INSIDE_A_HOUSE", "House", "House"), - ("NA_BGM_GAME_OVER", "Game Over", "Game Over"), - ("NA_BGM_CLEAR_BOSS", "Boss Clear", "Boss Clear"), - ("NA_BGM_GET_ITEM", "Item Catch", "Item Catch"), - ("NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_CLOCK_TOWN_DAY_2_PTR"), - ("NA_BGM_GET_HEART", "Get A Heart Container", "Get A Heart Container"), - ("NA_BGM_TIMED_MINI_GAME", "Mini Game", "Mini Game"), - ("NA_BGM_GORON_RACE", "Goron Race", "Goron Race"), - ("NA_BGM_MUSIC_BOX_HOUSE", "Music Box House", "Music Box House"), - ("NA_BGM_FAIRY_FOUNTAIN", "Fairy's Fountain", "Fairy's Fountain"), - ("NA_BGM_ZELDAS_LULLABY", "Zelda's Theme", "Zelda's Theme"), - ("NA_BGM_ROSA_SISTERS", "Rosa Sisters", "Rosa Sisters"), - ("NA_BGM_OPEN_CHEST", "Open Treasure Box", "Open Treasure Box"), - ("NA_BGM_MARINE_RESEARCH_LAB", "Marine Research Laboratory", "Marine Research Laboratory"), - ("NA_BGM_GIANTS_THEME", "Giants' Theme", "Giants' Theme"), - ("NA_BGM_SONG_OF_STORMS", "Guru-Guru's Song", "Guru-Guru's Song"), - ("NA_BGM_ROMANI_RANCH", "Romani Ranch", "Romani Ranch"), - ("NA_BGM_GORON_VILLAGE", "Goron Village", "Goron Village"), - ("NA_BGM_MAYORS_OFFICE", "Mayor's Meeting", "Mayor's Meeting"), - ("NA_BGM_OCARINA_EPONA", "Ocarina “Epona's Song”", "Ocarina “Epona's Song”"), - ("NA_BGM_OCARINA_SUNS", "Ocarina “Sun's Song”", "Ocarina “Sun's Song”"), - ("NA_BGM_OCARINA_TIME", "Ocarina “Song Of Time”", "Ocarina “Song Of Time”"), - ("NA_BGM_OCARINA_STORM", "Ocarina “Song Of Storms”", "Ocarina “Song Of Storms”"), - ("NA_BGM_ZORA_HALL", "Zora Hall", "Zora Hall"), - ("NA_BGM_GET_NEW_MASK", "Get A Mask", "Get A Mask"), - ("NA_BGM_MINI_BOSS", "Middle Boss Battle", "Middle Boss Battle"), - ("NA_BGM_GET_SMALL_ITEM", "Small Item Catch", "Small Item Catch"), - ("NA_BGM_ASTRAL_OBSERVATORY", "Astral Observatory", "Astral Observatory"), - ("NA_BGM_CAVERN", "Cavern", "Cavern"), - ("NA_BGM_MILK_BAR", "Milk Bar", "Milk Bar"), - ("NA_BGM_ZELDA_APPEAR", "Enter Zelda", "Enter Zelda"), - ("NA_BGM_SARIAS_SONG", "Woods Of Mystery", "Woods Of Mystery"), - ("NA_BGM_GORON_GOAL", "Goron Race Goal", "Goron Race Goal"), - ("NA_BGM_HORSE", "Horse Race", "Horse Race"), - ("NA_BGM_HORSE_GOAL", "Horse Race Goal", "Horse Race Goal"), - ("NA_BGM_INGO", "Gorman Track", "Gorman Track"), - ("NA_BGM_KOTAKE_POTION_SHOP", "Magic Hags' Potion Shop", "Magic Hags' Potion Shop"), - ("NA_BGM_SHOP", "Shop", "Shop"), - ("NA_BGM_OWL", "Owl", "Owl"), - ("NA_BGM_SHOOTING_GALLERY", "Shooting Gallery", "Shooting Gallery"), - ("NA_BGM_OCARINA_SOARING", "Ocarina “Song Of Soaring”", "Ocarina “Song Of Soaring”"), - ("NA_BGM_OCARINA_HEALING", "Ocarina “Song Of Healing”", "Ocarina “Song Of Healing”"), - ("NA_BGM_INVERTED_SONG_OF_TIME", "Ocarina “Inverted Song Of Time”", "Ocarina “Inverted Song Of Time”"), - ("NA_BGM_SONG_OF_DOUBLE_TIME", "Ocarina “Song Of Double Time”", "Ocarina “Song Of Double Time”"), - ("NA_BGM_SONATA_OF_AWAKENING", "Sonata of Awakening", "Sonata of Awakening"), - ("NA_BGM_GORON_LULLABY", "Goron Lullaby", "Goron Lullaby"), - ("NA_BGM_NEW_WAVE_BOSSA_NOVA", "New Wave Bossa Nova", "New Wave Bossa Nova"), - ("NA_BGM_ELEGY_OF_EMPTINESS", "Elegy Of Emptiness", "Elegy Of Emptiness"), - ("NA_BGM_OATH_TO_ORDER", "Oath To Order", "Oath To Order"), - ("NA_BGM_SWORD_TRAINING_HALL", "Swordsman's School", "Swordsman's School"), - ("NA_BGM_OCARINA_LULLABY_INTRO", "Ocarina “Goron Lullaby Intro”", "Ocarina “Goron Lullaby Intro”"), - ("NA_BGM_LEARNED_NEW_SONG", "Get The Ocarina", "Get The Ocarina"), - ("NA_BGM_BREMEN_MARCH", "Bremen March", "Bremen March"), - ("NA_BGM_BALLAD_OF_THE_WIND_FISH", "Ballad Of The Wind Fish", "Ballad Of The Wind Fish"), - ("NA_BGM_SONG_OF_SOARING", "Song Of Soaring", "Song Of Soaring"), - ("NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_MILK_BAR_DUPLICATE"), - ("NA_BGM_FINAL_HOURS", "Last Day", "Last Day"), - ("NA_BGM_MIKAU_RIFF", "Mikau", "Mikau"), - ("NA_BGM_MIKAU_FINALE", "Mikau", "Mikau"), - ("NA_BGM_FROG_SONG", "Frog Song", "Frog Song"), - ("NA_BGM_OCARINA_SONATA", "Ocarina “Sonata Of Awakening”", "Ocarina “Sonata Of Awakening”"), - ("NA_BGM_OCARINA_LULLABY", "Ocarina “Goron Lullaby”", "Ocarina “Goron Lullaby”"), - ("NA_BGM_OCARINA_NEW_WAVE", "Ocarina “New Wave Bossa Nova”", "Ocarina “New Wave Bossa Nova”"), - ("NA_BGM_OCARINA_ELEGY", "Ocarina “Elegy of Emptiness”", "Ocarina “Elegy of Emptiness”"), - ("NA_BGM_OCARINA_OATH", "Ocarina “Oath To Order”", "Ocarina “Oath To Order”"), - ("NA_BGM_MAJORAS_LAIR", "Majora Boss Room", "Majora Boss Room"), - ("NA_BGM_OCARINA_LULLABY_INTRO_PTR", "NA_BGM_OCARINA_LULLABY_INTRO", "NA_BGM_OCARINA_LULLABY_INTRO"), - ("NA_BGM_OCARINA_GUITAR_BASS_SESSION", "Bass and Guitar Session", "Bass and Guitar Session"), - ("NA_BGM_PIANO_SESSION", "Piano Solo", "Piano Solo"), - ("NA_BGM_INDIGO_GO_SESSION", "The Indigo-Go's", "The Indigo-Go's"), - ("NA_BGM_SNOWHEAD_TEMPLE", "Snowhead Temple", "Snowhead Temple"), - ("NA_BGM_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), - ("NA_BGM_NEW_WAVE_SAXOPHONE", "New Wave Bossa Nova", "New Wave Bossa Nova"), - ("NA_BGM_NEW_WAVE_VOCAL", "New Wave Bossa Nova", "New Wave Bossa Nova"), - ("NA_BGM_MAJORAS_WRATH", "Majora's Wrath Battle", "Majora's Wrath Battle"), - ("NA_BGM_MAJORAS_INCARNATION", "Majora's Incarnate Battle", "Majora's Incarnate Battle"), - ("NA_BGM_MAJORAS_MASK", "Majora's Mask Battle", "Majora's Mask Battle"), - ("NA_BGM_BASS_PLAY", "Bass Practice", "Bass Practice"), - ("NA_BGM_DRUMS_PLAY", "Drums Practice", "Drums Practice"), - ("NA_BGM_PIANO_PLAY", "Piano Practice", "Piano Practice"), - ("NA_BGM_IKANA_CASTLE", "Ikana Castle", "Ikana Castle"), - ("NA_BGM_GATHERING_GIANTS", "Calling The Four Giants", "Calling The Four Giants"), - ("NA_BGM_KAMARO_DANCE", "Kamaro's Dance", "Kamaro's Dance"), - ("NA_BGM_CREMIA_CARRIAGE", "Cremia's Carriage", "Cremia's Carriage"), - ("NA_BGM_KEATON_QUIZ", "Keaton's Quiz", "Keaton's Quiz"), - ("NA_BGM_END_CREDITS", "The End / Credits", "The End / Credits"), - ("NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP", "NA_BGM_OPENING_LOOP"), - ("NA_BGM_TITLE_THEME", "Title Theme", "Title Theme"), - ("NA_BGM_DUNGEON_APPEAR", "Woodfall Rises", "Woodfall Rises"), - ("NA_BGM_WOODFALL_CLEAR", "Southern Swamp Clears", "Southern Swamp Clears"), - ("NA_BGM_SNOWHEAD_CLEAR", "Snowhead Clear", "Snowhead Clear"), - ("NA_BGM_INTO_THE_MOON", "To The Moon", "To The Moon"), - ("NA_BGM_GOODBYE_GIANT", "The Giants' Exit", "The Giants' Exit"), - ("NA_BGM_TATL_AND_TAEL", "Tatl and Tael", "Tatl and Tael"), - ("NA_BGM_MOONS_DESTRUCTION", "Moon's Destruction", "Moon's Destruction"), - ("NA_BGM_END_CREDITS_SECOND_HALF", "The End / Credits (Half 2)", "The End / Credits (Half 2)"), -] - enum_ambiance_id = [ ("Custom", "Custom", "Custom"), ("0x00", "AMBIENCE_ID_00", "AMBIENCE_ID_00"), @@ -333,127 +62,6 @@ class Z64_BaseElement: ("0xFF", "AMBIENCE_ID_DISABLED", "AMBIENCE_ID_DISABLED"), ] - -ootEnumGlobalObject = [ - ("Custom", "Custom", "Custom"), - ("OBJECT_INVALID", "None", "None"), - ("OBJECT_GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), - ("OBJECT_GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), -] - -mm_enum_global_object = [ - ("Custom", "Custom", "Custom"), - ("GAMEPLAY_FIELD_KEEP", "Overworld", "gameplay_field_keep"), - ("GAMEPLAY_DANGEON_KEEP", "Dungeon", "gameplay_dangeon_keep"), -] - -ootEnumDrawConfig = [ - ("Custom", "Custom", "Custom"), - ("SDC_DEFAULT", "Default", "Default"), - ("SDC_HYRULE_FIELD", "Hyrule Field (Spot00)", "Spot00"), - ("SDC_KAKARIKO_VILLAGE", "Kakariko Village (Spot01)", "Spot01"), - ("SDC_ZORAS_RIVER", "Zora's River (Spot03)", "Spot03"), - ("SDC_KOKIRI_FOREST", "Kokiri Forest (Spot04)", "Spot04"), - ("SDC_LAKE_HYLIA", "Lake Hylia (Spot06)", "Spot06"), - ("SDC_ZORAS_DOMAIN", "Zora's Domain (Spot07)", "Spot07"), - ("SDC_ZORAS_FOUNTAIN", "Zora's Fountain (Spot08)", "Spot08"), - ("SDC_GERUDO_VALLEY", "Gerudo Valley (Spot09)", "Spot09"), - ("SDC_LOST_WOODS", "Lost Woods (Spot10)", "Spot10"), - ("SDC_DESERT_COLOSSUS", "Desert Colossus (Spot11)", "Spot11"), - ("SDC_GERUDOS_FORTRESS", "Gerudo's Fortress (Spot12)", "Spot12"), - ("SDC_HAUNTED_WASTELAND", "Haunted Wasteland (Spot13)", "Spot13"), - ("SDC_HYRULE_CASTLE", "Hyrule Castle (Spot15)", "Spot15"), - ("SDC_DEATH_MOUNTAIN_TRAIL", "Death Mountain Trail (Spot16)", "Spot16"), - ("SDC_DEATH_MOUNTAIN_CRATER", "Death Mountain Crater (Spot17)", "Spot17"), - ("SDC_GORON_CITY", "Goron City (Spot18)", "Spot18"), - ("SDC_LON_LON_RANCH", "Lon Lon Ranch (Spot20)", "Spot20"), - ("SDC_FIRE_TEMPLE", "Fire Temple (Hidan)", "Hidan"), - ("SDC_DEKU_TREE", "Inside the Deku Tree (Ydan)", "Ydan"), - ("SDC_DODONGOS_CAVERN", "Dodongo's Cavern (Ddan)", "Ddan"), - ("SDC_JABU_JABU", "Inside Jabu Jabu's Belly (Bdan)", "Bdan"), - ("SDC_FOREST_TEMPLE", "Forest Temple (Bmori1)", "Bmori1"), - ("SDC_WATER_TEMPLE", "Water Temple (Mizusin)", "Mizusin"), - ("SDC_SHADOW_TEMPLE_AND_WELL", "Shadow Temple (Hakadan)", "Hakadan"), - ("SDC_SPIRIT_TEMPLE", "Spirit Temple (Jyasinzou)", "Jyasinzou"), - ("SDC_INSIDE_GANONS_CASTLE", "Inside Ganon's Castle (Ganontika)", "Ganontika"), - ("SDC_GERUDO_TRAINING_GROUND", "Gerudo Training Ground (Men)", "Men"), - ("SDC_DEKU_TREE_BOSS", "Gohma's Lair (Ydan Boss)", "Ydan Boss"), - ("SDC_WATER_TEMPLE_BOSS", "Morpha's Lair (Mizusin Bs)", "Mizusin Bs"), - ("SDC_TEMPLE_OF_TIME", "Temple of Time (Tokinoma)", "Tokinoma"), - ("SDC_GROTTOS", "Grottos (Kakusiana)", "Kakusiana"), - ("SDC_CHAMBER_OF_THE_SAGES", "Chamber of the Sages (Kenjyanoma)", "Kenjyanoma"), - ("SDC_GREAT_FAIRYS_FOUNTAIN", "Great Fairy Fountain", "Great Fairy Fountain"), - ("SDC_SHOOTING_GALLERY", "Shooting Gallery (Syatekijyou)", "Syatekijyou"), - ("SDC_CASTLE_COURTYARD_GUARDS", "Castle Hedge Maze (Day) (Hairal Niwa)", "Hairal Niwa"), - ("SDC_OUTSIDE_GANONS_CASTLE", "Ganon's Castle Exterior (Ganon Tou)", "Ganon Tou"), - ("SDC_ICE_CAVERN", "Ice Cavern (Ice Doukuto)", "Ice Doukuto"), - ( - "SDC_GANONS_TOWER_COLLAPSE_EXTERIOR", - "Ganondorf's Death Scene (Tower Escape Exterior) (Ganon Final)", - "Ganon Final", - ), - ("SDC_FAIRYS_FOUNTAIN", "Fairy Fountain", "Fairy Fountain"), - ("SDC_THIEVES_HIDEOUT", "Thieves' Hideout (Gerudoway)", "Gerudoway"), - ("SDC_BOMBCHU_BOWLING_ALLEY", "Bombchu Bowling Alley (Bowling)", "Bowling"), - ("SDC_ROYAL_FAMILYS_TOMB", "Royal Family's Tomb (Hakaana Ouke)", "Hakaana Ouke"), - ("SDC_LAKESIDE_LABORATORY", "Lakeside Laboratory (Hylia Labo)", "Hylia Labo"), - ("SDC_LON_LON_BUILDINGS", "Lon Lon Ranch House & Tower (Souko)", "Souko"), - ("SDC_MARKET_GUARD_HOUSE", "Guard House (Miharigoya)", "Miharigoya"), - ("SDC_POTION_SHOP_GRANNY", "Granny's Potion Shop (Mahouya)", "Mahouya"), - ("SDC_CALM_WATER", "Calm Water", "Calm Water"), - ("SDC_GRAVE_EXIT_LIGHT_SHINING", "Grave Exit Light Shining", "Grave Exit Light Shining"), - ("SDC_BESITU", "Ganondorf Test Room (Besitu)", "Besitu"), - ("SDC_FISHING_POND", "Fishing Pond (Turibori)", "Turibori"), - ("SDC_GANONS_TOWER_COLLAPSE_INTERIOR", "Ganon's Tower (Collapsing) (Ganon Sonogo)", "Ganon Sonogo"), - ("SDC_INSIDE_GANONS_CASTLE_COLLAPSE", "Inside Ganon's Castle (Collapsing) (Ganontika Sonogo)", "Ganontika Sonogo"), -] - -mm_enum_draw_config = [ - ("Custom", "Custom", "Custom"), - ("SCENE_DRAW_CFG_DEFAULT", "Default", "Default"), - ("SCENE_DRAW_CFG_MAT_ANIM", "Material Animated", "Material Animated"), - ("SCENE_DRAW_CFG_NOTHING", "Nothing", "Nothing"), - ("SCENE_DRAW_CFG_GREAT_BAY_TEMPLE", "Great Bay Temple", "Great Bay Temple"), - ("SCENE_DRAW_CFG_MAT_ANIM_MANUAL_STEP", "Material Animated (manual step)", "Material Animated (manual step)"), -] - -ootEnumCollisionSound = [ - ("Custom", "Custom", "Custom"), - ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), - ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), - ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), - ("SURFACE_MATERIAL_JABU", "Jabu", "Jabu-Jabu flesh (aka Wet Stone)"), - ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), - ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), - ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), - ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), - ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), - ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), - ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), - ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), - ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), - ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), -] - -mm_enum_surface_material = [ - ("Custom", "Custom", "Custom"), - ("SURFACE_MATERIAL_DIRT", "Dirt", "Dirt (aka Earth)"), - ("SURFACE_MATERIAL_SAND", "Sand", "Sand"), - ("SURFACE_MATERIAL_STONE", "Stone", "Stone"), - ("SURFACE_MATERIAL_DIRT_SHALLOW", "Shallow Dirt", "Shallow Dirt"), - ("SURFACE_MATERIAL_WATER_SHALLOW", "Shallow Water", "Shallow Water"), - ("SURFACE_MATERIAL_WATER_DEEP", "Deep Water", "Deep Water"), - ("SURFACE_MATERIAL_TALL_GRASS", "Tall Grass", "Tall Grass"), - ("SURFACE_MATERIAL_LAVA", "Lava", "Lava (aka Goo)"), - ("SURFACE_MATERIAL_GRASS", "Grass", "Grass (aka Earth 2)"), - ("SURFACE_MATERIAL_BRIDGE", "Bridge", "Bridge (aka Wooden Plank)"), - ("SURFACE_MATERIAL_WOOD", "Wood", "Wood (aka Packed Earth)"), - ("SURFACE_MATERIAL_DIRT_SOFT", "Soft Dirt", "Soft Dirt (aka Earth 3)"), - ("SURFACE_MATERIAL_ICE", "Ice", "Ice (aka Ceramic)"), - ("SURFACE_MATERIAL_CARPET", "Carpet", "Carpet (aka Loose Earth)"), - ("SURFACE_MATERIAL_SNOW", "Snow", "Snow"), -] - # --- ootEnumSkybox = [ @@ -917,10 +525,6 @@ def is_mm(self): return self.game == "MM" def update(self, context: Optional[Context], game: Optional[str], force: bool = False): - from .enum_data import Z64_EnumData - from .object_data import Z64_ObjectData - from .actor_data import Z64_ActorData - if context is not None: next_game = context.scene.gameEditorMode elif game is not None: @@ -933,94 +537,61 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = return self.game = next_game - self.enumData = Z64_EnumData(self.game) - self.objectData = Z64_ObjectData(self.game) - self.actorData = Z64_ActorData(self.game) + self.enums = Z64_EnumData(self.game) + self.objects = Z64_ObjectData(self.game) + self.actors = Z64_ActorData(self.game) if self.game == "OOT": self.cs_index_start = 4 - self.ootEnumMusicSeq = ootEnumMusicSeq self.ootEnumNightSeq = ootEnumNightSeq - self.ootEnumGlobalObject = ootEnumGlobalObject self.ootEnumSkybox = ootEnumSkybox self.ootEnumCloudiness = ootEnumCloudiness self.ootEnumLinkIdle = ootEnumLinkIdle self.ootEnumRoomBehaviour = ootEnumRoomBehaviour - self.ootEnumDrawConfig = ootEnumDrawConfig self.ootEnumFloorSetting = ootEnumFloorSetting self.ootEnumFloorProperty = ootEnumFloorProperty - self.ootEnumCollisionSound = ootEnumCollisionSound self.ootEnumCameraSType = ootEnumCameraSType elif self.game == "MM": self.cs_index_start = 1 - self.ootEnumMusicSeq = enum_seq_id self.ootEnumNightSeq = enum_ambiance_id - self.ootEnumGlobalObject = mm_enum_global_object self.ootEnumSkybox = mm_enum_skybox self.ootEnumCloudiness = mm_enum_skybox_config self.ootEnumLinkIdle = mm_enum_environment_type self.ootEnumRoomBehaviour = mm_enum_room_type - self.ootEnumDrawConfig = mm_enum_draw_config self.ootEnumFloorSetting = mm_enum_floor_property self.ootEnumFloorProperty = mm_enum_floor_type - self.ootEnumCollisionSound = mm_enum_surface_material self.ootEnumCameraSType = mm_enum_camera_setting_type else: raise ValueError(f"ERROR: unsupported game {repr(self.game)}") - def get_enum(self, context, prop_name: str): - self.update(context, None) - - match prop_name: - case "globalObject": - return self.ootEnumGlobalObject - case "skyboxID": - return self.ootEnumSkybox - case "skyboxCloudiness": - return self.ootEnumCloudiness - case "musicSeq": - return self.ootEnumMusicSeq - case "nightSeq": - return self.ootEnumNightSeq - case "roomBehaviour": - return self.ootEnumRoomBehaviour - case "linkIdleMode": - return self.ootEnumLinkIdle - case "drawConfig": - return self.ootEnumDrawConfig - case "floorSetting": - return self.ootEnumFloorSetting - case "floorProperty": - return self.ootEnumFloorProperty - case "sound": - return self.ootEnumCollisionSound - case "camSType": - return self.ootEnumCameraSType - case "actor_id": - return self.actorData.ootEnumActorID - case "chest_content": - return self.actorData.ootEnumChestContent - case "navi_msg_id": - return self.actorData.ootEnumNaviMessageData - case "collectibles": - return self.actorData.ootEnumCollectibleItems - case "objectKey": - return self.objectData.ootEnumObjectKey - case "csDestination": - return self.enumData.ootEnumCsDestination - case "seqId": - return self.enumData.ootEnumSeqId - case "playerCueID": - return self.enumData.ootEnumCsPlayerCueId - case "ocarinaAction": - return self.enumData.ootEnumOcarinaSongActionId - case "csTextType": - return self.enumData.ootEnumCsTextType - case "csSeqPlayer": - return self.enumData.ootEnumCsFadeOutSeqPlayer - case "csMiscType": - return self.enumData.ootEnumCsMiscType - case "transitionType": - return self.enumData.ootEnumCsTransitionType - case _: - raise ValueError(f"ERROR: unknown value {repr(prop_name)}") + self.enum_map: dict[str, list[tuple[str, str, str]]] = { + "globalObject": self.enums.enum_global_object, + "musicSeq": self.enums.enum_seq_id, + "drawConfig": self.enums.enum_draw_config, + "sound": self.enums.enum_surface_material, + "csDestination": self.enums.enum_cs_destination, + "seqId": self.enums.enum_seq_id, + "playerCueID": self.enums.enum_cs_player_cue_id, + "ocarinaAction": self.enums.enum_ocarina_song_action_id, + "csTextType": self.enums.enum_cs_text_type, + "csSeqPlayer": self.enums.enum_cs_fade_out_seq_player, + "csMiscType": self.enums.enum_cs_misc_type, + "transitionType": self.enums.enum_cs_transition_type, + "objectKey": self.objects.ootEnumObjectKey, + "actor_id": self.actors.ootEnumActorID, + "chest_content": self.actors.ootEnumChestContent, + "navi_msg_id": self.actors.ootEnumNaviMessageData, + "collectibles": self.actors.ootEnumCollectibleItems, + "skyboxID": self.ootEnumSkybox, + "skyboxCloudiness": self.ootEnumCloudiness, + "nightSeq": self.ootEnumNightSeq, + "roomBehaviour": self.ootEnumRoomBehaviour, + "linkIdleMode": self.ootEnumLinkIdle, + "floorSetting": self.ootEnumFloorSetting, + "floorProperty": self.ootEnumFloorProperty, + "camSType": self.ootEnumCameraSType, + } + + def get_enum(self, prop_name: str): + self.update(bpy.context, None) + return self.enum_map[prop_name] diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py index a8b9c1517..12a912ad0 100644 --- a/fast64_internal/data/z64/enum_data.py +++ b/fast64_internal/data/z64/enum_data.py @@ -1,10 +1,7 @@ from dataclasses import dataclass, field from os import path from pathlib import Path -from .getters import get_xml_root -from .data import Z64_BaseElement - -# Note: "enumData" in this context refers to an OoT Object file (like ``gameplay_keep``) +from .getters import Z64_BaseElement, get_xml_root @dataclass @@ -16,45 +13,36 @@ def __post_init__(self): # generate the name from the id if self.name is None: - if self.game == "OOT": - keyToPrefix = { - "csCmd": "CS_CMD", - "csMiscType": "CS_MISC", - "csTextType": "CS_TEXT", - "csFadeOutSeqPlayer": "CS_FADE_OUT", - "csTransitionType": "CS_TRANS", - "csDestination": "CS_DEST", - "csPlayerCueId": "PLAYER_CUEID", - "naviQuestHintType": "NAVI_QUEST_HINTS", - "ocarinaSongActionId": "OCARINA_ACTION", - } - else: - keyToPrefix = { - "cmd": "CS_CMD", - "miscType": "CS_MISC", - "textType": "CS_TEXT", - "fadeOutSeqPlayer": "CS_FADE_OUT", - "modifySeqType": "CS_MOD", - "transitionType": "CS_TRANS", - "destinationType": "CS_DESTINATION", - "chooseCreditsSceneType": "CS_CREDITS", - "motionBlurType": "CS_MOTION_BLUR", - "rumbleType": "CS_RUMBLE", - "transitionGeneralType": "CS_TRANS_GENERAL", - "spawnFlag": "CS_SPAWN_FLAG", - "endSfx": "CS_END_SFX", - "csSplineInterpType": "CS_CAM_INTERP", - "csSplineRelTo": "CS_CAM_REL", - "playerCueId": "PLAYER_CUEID", - "naviQuestHintType": "NAVI_QUEST_HINTS", - "ocarinaSongActionId": "OCARINA_ACTION", - } + keyToPrefix = { + "cs_cmd": "CS_CMD", + "cs_misc_type": "CS_MISC", + "cs_text_type": "CS_TEXT", + "cs_fade_out_seq_player": "CS_FADE_OUT", + "cs_transition_type": "CS_TRANS", + "cs_destination": "CS_DEST", + "cs_player_cue_id": "PLAYER_CUEID", + "cs_modify_seq_type": "CS_MOD", + "cs_credits_scene_type": "CS_CREDITS", + "cs_motion_blur_type": "CS_MOTION_BLUR", + "cs_rumble_type": "CS_RUMBLE", + "cs_transition_general": "CS_TRANS_GENERAL", + "cs_spline_interp_type": "CS_CAM_INTERP", + "cs_spline_rel": "CS_CAM_REL", + "cs_spawn_flag": "CS_SPAWN_FLAG", + "actor_cs_end_sfx": "CS_END_SFX", + "navi_quest_hint_type": "NAVI_QUEST_HINTS", + "ocarina_song_action_id": "OCARINA_ACTION", + "seq_id": "NA_BGM", + "draw_config": ("SCENE_DRAW_CFG" if self.game == "MM" else "SDC"), + "surface_material": "SURFACE_MATERIAL", + "global_object": "OBJECT_", + } self.name = self.id.removeprefix(f"{keyToPrefix[self.parentKey]}_") - if self.parentKey in ["csCmd", "csPlayerCueId"]: + if self.parentKey in ["cs_cmd", "cs_player_cue_id"]: split = self.name.split("_") - if self.parentKey == "csCmd" and "ACTOR_CUE" in self.id: + if self.parentKey == "cs_cmd" and "ACTOR_CUE" in self.id: self.name = f"Actor Cue {split[-2]}_{split[-1]}" else: self.name = f"Player Cue Id {split[-1]}" @@ -111,55 +99,34 @@ def __init__(self, game: str): # create list of tuples used by Blender's enum properties self.deletedEntry = ("None", "(Deleted from the XML)", "None") - self.ootEnumCsCmd: list[tuple[str, str, str]] = [] - self.ootEnumCsMiscType: list[tuple[str, str, str]] = [] - self.ootEnumCsTextType: list[tuple[str, str, str]] = [] - self.ootEnumCsFadeOutSeqPlayer: list[tuple[str, str, str]] = [] - self.ootEnumCsTransitionType: list[tuple[str, str, str]] = [] - self.ootEnumCsDestination: list[tuple[str, str, str]] = [] - self.ootEnumCsPlayerCueId: list[tuple[str, str, str]] = [] - self.ootEnumNaviQuestHintType: list[tuple[str, str, str]] = [] - self.ootEnumOcarinaSongActionId: list[tuple[str, str, str]] = [] - self.ootEnumSeqId: list[tuple[str, str, str]] = [] - - self.enum_modify_seq_type: list[tuple[str, str, str]] = [] - self.enum_credits_scene_type: list[tuple[str, str, str]] = [] - self.enum_motion_blur_type: list[tuple[str, str, str]] = [] - self.enum_rumble_type: list[tuple[str, str, str]] = [] - self.enum_transition_general_type: list[tuple[str, str, str]] = [] - self.enum_spawn_flag: list[tuple[str, str, str]] = [] - self.enum_end_sfx: list[tuple[str, str, str]] = [] - self.enum_split_interp_type: list[tuple[str, str, str]] = [] - self.enum_spline_rel_to: list[tuple[str, str, str]] = [] + self.enum_cs_cmd: list[tuple[str, str, str]] = [] + self.enum_cs_misc_type: list[tuple[str, str, str]] = [] + self.enum_cs_text_type: list[tuple[str, str, str]] = [] + self.enum_cs_fade_out_seq_player: list[tuple[str, str, str]] = [] + self.enum_cs_transition_type: list[tuple[str, str, str]] = [] + self.enum_cs_destination: list[tuple[str, str, str]] = [] + self.enum_cs_player_cue_id: list[tuple[str, str, str]] = [] + self.enum_cs_modify_seq_type: list[tuple[str, str, str]] = [] + self.enum_cs_credits_scene_type: list[tuple[str, str, str]] = [] + self.enum_cs_motion_blur_type: list[tuple[str, str, str]] = [] + self.enum_cs_rumble_type: list[tuple[str, str, str]] = [] + self.enum_cs_transition_general: list[tuple[str, str, str]] = [] + self.enum_cs_spline_interp_type: list[tuple[str, str, str]] = [] + self.enum_cs_spline_rel: list[tuple[str, str, str]] = [] + self.enum_cs_spawn_flag: list[tuple[str, str, str]] = [] + self.enum_actor_cs_end_sfx: list[tuple[str, str, str]] = [] + self.enum_navi_quest_hint_type: list[tuple[str, str, str]] = [] + self.enum_ocarina_song_action_id: list[tuple[str, str, str]] = [] + self.enum_seq_id: list[tuple[str, str, str]] = [] + self.enum_draw_config: list[tuple[str, str, str]] = [] + self.enum_surface_material: list[tuple[str, str, str]] = [] + self.enum_global_object: list[tuple[str, str, str]] = [] self.enumByID = {enum.id: enum for enum in self.enumDataList} self.enumByKey = {enum.key: enum for enum in self.enumDataList} - key_to_enum = { - "cmd": "ootEnumCsCmd", - "miscType": "ootEnumCsMiscType", - "textType": "ootEnumCsTextType", - "fadeOutSeqPlayer": "ootEnumCsFadeOutSeqPlayer", - "modifySeqType": "enum_cs_modify_seq_type", - "transitionType": "ootEnumCsTransitionType", - "destinationType": "ootEnumCsDestination", - "chooseCreditsSceneType": "enum_cs_credits_scene_type", - "motionBlurType": "enum_cs_motion_blur_type", - "rumbleType": "enum_cs_rumble_type", - "transitionGeneralType": "enum_cs_transition_general_type", - "spawnFlag": "enum_cs_spawn_flag", - "endSfx": "enum_cs_end_sfx", - "csSplineInterpType": "enum_cs_split_interp_type", - "csSplineRelTo": "enum_cs_spline_rel_to", - "playerCueId": "ootEnumCsPlayerCueId", - "naviQuestHintType": "ootEnumNaviQuestHintType", - "ocarinaSongActionId": "ootEnumOcarinaSongActionId", - "seqId": "ootEnumSeqId", - } - for key in self.enumByKey.keys(): - name = ("ootEnum" + key[0].upper() + key[1:]) if game == "OOT" else key_to_enum[key] - setattr(self, name, self.get_enum_data(key)) + setattr(self, f"enum_{key}", self.get_enum_data(key)) def get_enum_data(self, enumKey: str): enum = self.enumByKey[enumKey] diff --git a/fast64_internal/data/z64/getters.py b/fast64_internal/data/z64/getters.py index d0b76ce74..7cd3b5159 100644 --- a/fast64_internal/data/z64/getters.py +++ b/fast64_internal/data/z64/getters.py @@ -1,4 +1,13 @@ from xml.etree.ElementTree import parse as parseXML, Element +from dataclasses import dataclass + + +@dataclass +class Z64_BaseElement: + id: str + key: str + name: str + index: int def get_xml_root(xmlPath: str) -> Element: diff --git a/fast64_internal/data/z64/object_data.py b/fast64_internal/data/z64/object_data.py index 50d45b1ff..e9301bd92 100644 --- a/fast64_internal/data/z64/object_data.py +++ b/fast64_internal/data/z64/object_data.py @@ -2,8 +2,7 @@ from os import path from pathlib import Path from ...utility import PluginError -from .getters import get_xml_root -from .data import Z64_BaseElement +from .getters import Z64_BaseElement, get_xml_root # Note: "object" in this context refers to an OoT Object file (like ``gameplay_keep``) diff --git a/fast64_internal/data/z64/xml/mm_enum_data.xml b/fast64_internal/data/z64/xml/mm_enum_data.xml index 92e5b437d..8265a6b6e 100644 --- a/fast64_internal/data/z64/xml/mm_enum_data.xml +++ b/fast64_internal/data/z64/xml/mm_enum_data.xml @@ -20,12 +20,12 @@ - Player Cue Ids got their own enum but not regular Actor Cues. This is because Actor Cues are among cutscene commands (``csCmd``) --> - + - + @@ -36,12 +36,12 @@ - + - + @@ -55,12 +55,12 @@ - + - + @@ -76,17 +76,17 @@ - + - + - + @@ -324,7 +324,7 @@ - + @@ -368,25 +368,25 @@ - + - + - + - + @@ -481,18 +481,18 @@ - - - - - + + + + + - + @@ -501,7 +501,7 @@ - + @@ -510,7 +510,7 @@ - + @@ -595,7 +595,7 @@ - + @@ -725,4 +725,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fast64_internal/data/z64/xml/oot_enum_data.xml b/fast64_internal/data/z64/xml/oot_enum_data.xml index c379af7a4..0e067ce26 100644 --- a/fast64_internal/data/z64/xml/oot_enum_data.xml +++ b/fast64_internal/data/z64/xml/oot_enum_data.xml @@ -20,7 +20,7 @@ - Player Cue Ids got their own enum but not regular Actor Cues. This is because Actor Cues are among cutscene commands (``csCmd``) --> - + @@ -152,7 +152,7 @@ - + @@ -191,7 +191,7 @@ - + @@ -199,12 +199,12 @@ - + - + @@ -220,7 +220,7 @@ - + @@ -343,7 +343,7 @@ - + @@ -424,13 +424,13 @@ - + - + @@ -483,7 +483,7 @@ - + @@ -598,4 +598,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fast64_internal/z64/actor/operators.py b/fast64_internal/z64/actor/operators.py index 5dcf5f49e..6d5cfddee 100644 --- a/fast64_internal/z64/actor/operators.py +++ b/fast64_internal/z64/actor/operators.py @@ -12,7 +12,7 @@ class OOT_SearchChestContentEnumOperator(Operator): bl_property = "chest_content" bl_options = {"REGISTER", "UNDO"} - chest_content: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "chest_content"), default=1) + chest_content: EnumProperty(items=lambda self, context: game_data.z64.get_enum("chest_content"), default=1) obj_name: StringProperty() prop_name: StringProperty() @@ -33,7 +33,7 @@ class OOT_SearchNaviMsgIDEnumOperator(Operator): bl_property = "navi_msg_id" bl_options = {"REGISTER", "UNDO"} - navi_msg_id: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "navi_msg_id"), default=1) + navi_msg_id: EnumProperty(items=lambda self, context: game_data.z64.get_enum("navi_msg_id"), default=1) obj_name: StringProperty() prop_name: StringProperty() @@ -54,7 +54,7 @@ class OOT_SearchActorIDEnumOperator(Operator): bl_property = "actor_id" bl_options = {"REGISTER", "UNDO"} - actor_id: EnumProperty(items=lambda self, context: game_data.z64.actorData.getItems(self.actor_user)) + actor_id: EnumProperty(items=lambda self, context: game_data.z64.actors.getItems(self.actor_user)) actor_user: StringProperty(default="Actor") obj_name: StringProperty() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 1baff56d9..a64432e23 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -77,12 +77,12 @@ def create_game_props(): prop_ats = get_prop_annotations(Z64_ActorProperty) param_type_to_enum_items = { - "ChestContent": game_data.z64.actorData.ootEnumChestContent, - "Collectible": game_data.z64.actorData.ootEnumCollectibleItems, - "Message": game_data.z64.actorData.ootEnumNaviMessageData, + "ChestContent": game_data.z64.actors.ootEnumChestContent, + "Collectible": game_data.z64.actors.ootEnumCollectibleItems, + "Message": game_data.z64.actors.ootEnumNaviMessageData, } - for actor in game_data.z64.actorData.actorList: + for actor in game_data.z64.actors.actorList: for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index, update=False) enum_items = None @@ -242,7 +242,7 @@ def draw_props( class Z64_ActorProperty(PropertyGroup): actor_id: EnumProperty( - name="Actor", items=lambda self, context: game_data.z64.get_enum(context, "actor_id"), default=1 + name="Actor", items=lambda self, context: game_data.z64.get_enum("actor_id"), default=1 ) actor_id_custom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") @@ -300,7 +300,7 @@ def upgrade_object(obj: Object): def is_rotation_used(self, target: str): game_data.z64.update(bpy.context, None) - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actors.actorsByID[self.actor_id] selected_type = None for param in actor.params: if param.type == "Type": @@ -324,7 +324,7 @@ def is_value_in_range(self, value: int, min: int, max: int): def set_param_value(self, base_value: str | bool, target: str): game_data.z64.update(bpy.context, None) - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actors.actorsByID[self.actor_id] base_value = getEvalParamsInt(base_value) found_type = None for param in actor.params: @@ -343,11 +343,11 @@ def set_param_value(self, base_value: str | bool, target: str): if is_in_range and (found_type_in_tied_types or len(param.tiedTypes) == 0): prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) if param.type == "ChestContent": - prop_value = game_data.z64.actorData.chestItemByValue[value].key + prop_value = game_data.z64.actors.chestItemByValue[value].key elif param.type == "Collectible": - prop_value = game_data.z64.actorData.collectibleItemsByValue[value].key + prop_value = game_data.z64.actors.collectibleItemsByValue[value].key elif param.type == "Message": - prop_value = game_data.z64.actorData.messageItemsByValue[value].key + prop_value = game_data.z64.actors.messageItemsByValue[value].key elif param.type == "Bool": prop_value = bool(value) else: @@ -365,7 +365,7 @@ def set_param_value(self, base_value: str | bool, target: str): def get_param_value(self, target: str): game_data.z64.update(bpy.context, None) - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actors.actorsByID[self.actor_id] param_list = [] type_value = None have_custom_value = False @@ -396,11 +396,11 @@ def get_param_value(self, target: str): else: param_val = 0 if param.type == "ChestContent": - param_val = game_data.z64.actorData.chestItemByKey[cur_prop_value].value + param_val = game_data.z64.actors.chestItemByKey[cur_prop_value].value elif param.type == "Collectible": - param_val = game_data.z64.actorData.collectibleItemsByKey[cur_prop_value].value + param_val = game_data.z64.actors.collectibleItemsByKey[cur_prop_value].value elif param.type == "Message": - param_val = game_data.z64.actorData.messageItemsByKey[cur_prop_value].value + param_val = game_data.z64.actors.messageItemsByKey[cur_prop_value].value if "Rot" in target: type_value = getEvalParamsInt(getattr(self, get_prop_name(actor.key, "Type", None, 1))) if type_value is not None and type_value in param.tiedTypes or len(param.tiedTypes) == 0: @@ -443,7 +443,7 @@ def get_param_value(self, target: str): def draw_params(self, layout: UILayout, obj: Object): game_data.z64.update(bpy.context, None) - actor = game_data.z64.actorData.actorsByID[self.actor_id] + actor = game_data.z64.actors.actorsByID[self.actor_id] selected_type = None for param in actor.params: prop_name = get_prop_name(actor.key, param.type, param.subType, param.index) @@ -462,11 +462,11 @@ def draw_params(self, layout: UILayout, obj: Object): if param.type == "ChestContent": search_op = layout.operator(OOT_SearchChestContentEnumOperator.bl_idname) label_name = "Chest Content" - item_map = game_data.z64.actorData.chestItemByKey + item_map = game_data.z64.actors.chestItemByKey else: search_op = layout.operator(OOT_SearchNaviMsgIDEnumOperator.bl_idname) label_name = "Navi Message ID" - item_map = game_data.z64.actorData.messageItemsByKey + item_map = game_data.z64.actors.messageItemsByKey search_op.obj_name = obj.name search_op.prop_name = prop_name if key != "Custom": @@ -503,7 +503,7 @@ def draw_props( return split.label(text="Actor ID") - split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "actor_id"), self.actor_id)) + split.label(text=getEnumName(game_data.z64.get_enum("actor_id"), self.actor_id)) if game_data.z64.is_oot(): if self.actor_id != "Custom": @@ -599,7 +599,7 @@ def draw_props( split = actorIDBox.split(factor=0.5) split.label(text="Actor ID") - split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "actor_id"), self.actor.actor_id)) + split.label(text=getEnumName(game_data.z64.get_enum("actor_id"), self.actor.actor_id)) if self.actor.actor_id == "Custom": prop_split(actorIDBox, self.actor, "actor_id_custom", "") diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 35711b9d7..422c4c467 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -42,7 +42,7 @@ def draw_props(self, layout: UILayout): class OOTCameraPositionProperty(PropertyGroup): index: IntProperty(min=0) bgImageOverrideIndex: IntProperty(default=-1, min=-1) - camSType: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "camSType"), default=2) + camSType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("camSType"), default=2) camSTypeCustom: StringProperty(default="CAM_SET_NORMAL0") hasPositionData: BoolProperty(default=True, name="Has Position Data") is_actor_cs_cam: BoolProperty(default=False, name="Is Actor CS Camera") @@ -73,11 +73,11 @@ class OOTMaterialCollisionProperty(PropertyGroup): eponaBlock: BoolProperty() decreaseHeight: BoolProperty() floorSettingCustom: StringProperty(default="0x00") - floorSetting: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "floorSetting"), default=1) + floorSetting: EnumProperty(items=lambda self, context: game_data.z64.get_enum("floorSetting"), default=1) wallSettingCustom: StringProperty(default="0x00") wallSetting: EnumProperty(items=ootEnumWallSetting, default=1) floorPropertyCustom: StringProperty(default="0x00") - floorProperty: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "floorProperty"), default=1) + floorProperty: EnumProperty(items=lambda self, context: game_data.z64.get_enum("floorProperty"), default=1) exitID: IntProperty(default=0, min=0) cameraID: IntProperty(default=0, min=0) isWallDamage: BoolProperty() @@ -92,7 +92,7 @@ class OOTMaterialCollisionProperty(PropertyGroup): terrainCustom: StringProperty(default="0x00") terrain: EnumProperty(items=game_data.z64.enum_floor_effect, default=1) soundCustom: StringProperty(default="0x00") - sound: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "sound"), default=1) + sound: EnumProperty(items=lambda self, context: game_data.z64.get_enum("sound"), default=1) def draw_props(self, layout: UILayout): layout.prop( diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 1ad2dece7..4c596b699 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -43,7 +43,7 @@ def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): # remove `cs` and lowercase first letter enumKey = enumKey[2].lower() + enumKey[3:] - enum = game_data.z64.enumData.enumByKey[enumKey] + enum = game_data.z64.enums.enumByKey[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: setting = getInteger(self.params[index]) @@ -195,7 +195,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[self.commandType].key + self.commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -843,7 +843,7 @@ def getNewCutsceneObject(self, name: str, frameCount: int, parentObj: Object): def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Object): newActorCueListObj = self.getNewEmptyObject(name, False, parentObj) newActorCueListObj.ootEmptyType = f"CS {'Player' if 'Player' in name else 'Actor'} Cue List" - cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] + cmdEnum = game_data.z64.enums.enumByKey["csCmd"] if commandType == "Player": commandType = "player_cue" @@ -884,7 +884,7 @@ def getNewActorCueObject( item = None if isPlayer: - playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enums.enumByKey["csPlayerCueId"] if isinstance(actionID, int): item = playerEnum.item_by_index.get(actionID) else: diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index f48b06502..e381a54bc 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -141,7 +141,7 @@ ] ootEnumCSActorCueListCommandType = [ - item for item in game_data.z64.enumData.ootEnumCsCmd if "actor_cue" in item[0] or "player_cue" in item[0] + item for item in game_data.z64.enums.enum_cs_cmd if "actor_cue" in item[0] or "player_cue" in item[0] ] ootEnumCSActorCueListCommandType.sort() ootEnumCSActorCueListCommandType.insert(0, ("Custom", "Custom", "Custom")) diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index 7f8125420..3cbe4d70b 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -40,7 +40,7 @@ class CutsceneCmdToC: """This class contains functions to create the cutscene commands""" def getEnumValue(self, enumKey: str, owner, propName: str): - item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = game_data.z64.enums.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def getGenericListCmd(self, cmdName: str, entryTotal: int): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enums.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index 4b49e2cc8..d242181f9 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -318,7 +318,7 @@ class OOT_SearchPlayerCueIdEnumOperator(Operator): bl_property = "playerCueID" bl_options = {"REGISTER", "UNDO"} - playerCueID: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "playerCueID"), default=1) + playerCueID: EnumProperty(items=lambda self, context: game_data.z64.get_enum("playerCueID"), default=1) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 7b01d4ddf..842852e3b 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -84,7 +84,7 @@ class CutsceneCmdActorCueProperty(PropertyGroup): get=lambda self: getNextCuesStartFrame(self), ) - playerCueID: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "playerCueID"), default=1) + playerCueID: EnumProperty(items=lambda self, context: game_data.z64.get_enum("playerCueID"), default=1) cueActionID: StringProperty( name="Action ID", default="0x0001", description="Actor action. Meaning is unique for each different actor." ) @@ -114,7 +114,7 @@ def draw_props(self, layout: UILayout, labelPrefix: str, isDummy: bool, objName: split = box.split(factor=0.5) searchOp = split.operator(OOT_SearchPlayerCueIdEnumOperator.bl_idname, icon="VIEWZOOM", text=label) searchOp.objName = objName - split.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "playerCueID"), self.playerCueID)) + split.label(text=getEnumName(game_data.z64.get_enum("playerCueID"), self.playerCueID)) if not isPlayer or self.playerCueID == "Custom": split = box.split(factor=0.5) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index 68bf57d56..98858f759 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -238,7 +238,7 @@ class OOT_SearchCSDestinationEnumOperator(Operator): bl_property = "csDestination" bl_options = {"REGISTER", "UNDO"} - csDestination: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "csDestination"), default=1) + csDestination: EnumProperty(items=lambda self, context: game_data.z64.get_enum("csDestination"), default=1) objName: StringProperty() def execute(self, context): @@ -260,7 +260,7 @@ class OOT_SearchCSSeqOperator(Operator): bl_property = "seqId" bl_options = {"REGISTER", "UNDO"} - seqId: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "seqId"), default=1) + seqId: EnumProperty(items=lambda self, context: game_data.z64.get_enum("seqId"), default=1) itemIndex: IntProperty() listType: StringProperty() diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index e6194546d..7fb8e3ce0 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -116,7 +116,7 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): textID: StringProperty(name="", default="0x0000") ocarinaAction: EnumProperty( name="Ocarina Action", - items=lambda self, context: game_data.z64.get_enum(context, "ocarinaAction"), + items=lambda self, context: game_data.z64.get_enum("ocarinaAction"), default=1, ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") @@ -124,7 +124,7 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): bottomOptionTextID: StringProperty(name="", default="0x0000") ocarinaMessageId: StringProperty(name="", default="0x0000") csTextType: EnumProperty( - name="Text Type", items=lambda self, context: game_data.z64.get_enum(context, "csTextType"), default=1 + name="Text Type", items=lambda self, context: game_data.z64.get_enum("csTextType"), default=1 ) csTextTypeCustom: StringProperty(default="CS_TEXT_CUSTOM") @@ -159,11 +159,11 @@ class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] csSeqID: EnumProperty( - name="Seq ID", items=lambda self, context: game_data.z64.get_enum(context, "seqId"), default=1 + name="Seq ID", items=lambda self, context: game_data.z64.get_enum("seqId"), default=1 ) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") csSeqPlayer: EnumProperty( - name="Seq Player", items=lambda self, context: game_data.z64.get_enum(context, "csSeqPlayer"), default=1 + name="Seq Player", items=lambda self, context: game_data.z64.get_enum("csSeqPlayer"), default=1 ) csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") @@ -180,7 +180,7 @@ class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] csMiscType: EnumProperty( - name="Type", items=lambda self, context: game_data.z64.get_enum(context, "csMiscType"), default=1 + name="Type", items=lambda self, context: game_data.z64.get_enum("csMiscType"), default=1 ) csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -208,7 +208,7 @@ class OOTCSListProperty(PropertyGroup): rumbleList: CollectionProperty(type=OOTCSRumbleProperty) transitionType: EnumProperty( - items=lambda self, context: game_data.z64.get_enum(context, "transitionType"), default=1 + items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1 ) transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) @@ -368,7 +368,7 @@ class OOTCutsceneProperty(PropertyGroup): csEndFrame: IntProperty(name="End Frame", min=0, default=100) csUseDestination: BoolProperty(name="Cutscene Destination (Scene Change)") csDestination: EnumProperty( - name="Destination", items=lambda self, context: game_data.z64.get_enum(context, "csDestination"), default=1 + name="Destination", items=lambda self, context: game_data.z64.get_enum("csDestination"), default=1 ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) @@ -419,7 +419,7 @@ def draw_props(self, layout: UILayout, obj: Object): boxRow = searchBox.row() searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") searchOp.objName = obj.name - boxRow.label(text=getEnumName(game_data.z64.get_enum(bpy.context, "csDestination"), self.csDestination)) + boxRow.label(text=getEnumName(game_data.z64.get_enum("csDestination"), self.csDestination)) if self.csDestination == "Custom": prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index 695a7c19a..1e50a8e94 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_id[commandType].key + commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_id[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index 02c4f6836..4811f803e 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -20,7 +20,7 @@ def validateFrames(self, checkEndFrame: bool = True): @staticmethod def getEnumValue(enumKey: str, value: str, isSeqLegacy: bool = False): - enum = game_data.z64.enumData.enumByKey[enumKey] + enum = game_data.z64.enums.enumByKey[enumKey] item = enum.item_by_id.get(value) if item is None: setting = getInteger(value) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 080d0b9f5..587820e06 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -142,7 +142,7 @@ def getOoTPosition(self, pos): return [x, y, z] def getEnumValueFromProp(self, enumKey: str, owner, propName: str): - item = game_data.z64.enumData.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) + item = game_data.z64.enums.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) return item.id if item is not None else getattr(owner, f"{propName}Custom") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): @@ -169,7 +169,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = game_data.z64.enumData.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_key[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +183,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = game_data.z64.enumData.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enums.enumByKey["csPlayerCueId"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index dea886cd5..604c64888 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -123,7 +123,7 @@ def new(name: str, props: Optional[Z64_RoomHeaderProperty]): if objProp.objectKey == "Custom": objectList.append(objProp.objectIDCustom) else: - objectList.append(game_data.z64.objectData.objects_by_key[objProp.objectKey].id) + objectList.append(game_data.z64.objects.objects_by_key[objProp.objectKey].id) return RoomObjects(name, objectList) def getDefineName(self): @@ -256,7 +256,7 @@ def new( actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actor.name = ( - game_data.z64.actorData.actorsByID[actor_id].name.replace( + game_data.z64.actors.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 77a10f283..352a50112 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -82,7 +82,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.id = actor_id transActor.name = ( - game_data.z64.actorData.actorsByID[actor_id].name.replace( + game_data.z64.actors.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" @@ -162,7 +162,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor = EntranceActor() entranceActor.name = ( - game_data.z64.actorData.actorsByID[actor_id].name.replace( + game_data.z64.actors.actorsByID[actor_id].name.replace( f" - {actor_id.removeprefix('ACTOR_')}", "" ) if actor_id != "Custom" diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 0490f8f85..9a8269663 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -100,7 +100,7 @@ def parseTransActorList( actorProp, "actor_id", actorID, - game_data.z64.actorData.ootEnumActorID, + game_data.z64.actors.ootEnumActorID, "actorIDCustom", ) if actorProp.actor_id != "Custom": @@ -209,7 +209,7 @@ def parseSpawnList( actorProp, "actor_id", actorID, - game_data.z64.actorData.ootEnumActorID, + game_data.z64.actors.ootEnumActorID, "actor_id_custom", ) if actorProp.actor_id != "Custom": @@ -285,7 +285,7 @@ def parseActorList( actorProp, "actor_id", actorID, - game_data.z64.actorData.ootEnumActorID, + game_data.z64.actors.ootEnumActorID, "actor_id_custom", ) actorProp.actorParam = actorParam diff --git a/fast64_internal/z64/importer/room_header.py b/fast64_internal/z64/importer/room_header.py index e91ad1816..61aaba050 100644 --- a/fast64_internal/z64/importer/room_header.py +++ b/fast64_internal/z64/importer/room_header.py @@ -19,7 +19,7 @@ def parseObjectList(roomHeader: Z64_RoomHeaderProperty, sceneData: str, objectLi for object in objects: objectProp = roomHeader.objectList.add() - objByID = game_data.z64.objectData.objects_by_id.get(object) + objByID = game_data.z64.objects.objects_by_id.get(object) if objByID is not None: setattr(objectProp, "objectKey", objByID.key) diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index f80085a0c..710420fec 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -174,7 +174,7 @@ def parseScene( sceneObj.ootSceneHeader.sceneTableEntry, "drawConfig", SceneTableUtility.get_draw_config(sceneName), - game_data.z64.get_enum(bpy.context, "drawConfig"), + game_data.z64.get_enum("drawConfig"), "drawConfigCustom", ) diff --git a/fast64_internal/z64/importer/scene_collision.py b/fast64_internal/z64/importer/scene_collision.py index 7be8477f8..f3bdb7358 100644 --- a/fast64_internal/z64/importer/scene_collision.py +++ b/fast64_internal/z64/importer/scene_collision.py @@ -78,7 +78,7 @@ def parseCamPosData( camObj = bpy.data.objects.new(objName, camera) bpy.context.scene.collection.objects.link(camObj) camProp = camObj.ootCameraPositionProperty - setCustomProperty(camProp, "camSType", setting, game_data.z64.get_enum(bpy.context, "camSType"), "camSTypeCustom") + setCustomProperty(camProp, "camSType", setting, game_data.z64.get_enum("camSType"), "camSTypeCustom") if is_actor_cs: camProp.is_actor_cs_cam = camProp.hasPositionData = True @@ -191,7 +191,7 @@ def parseSurfaceParams( collision, "floorSetting", str(getBits(params[0], 26, 4)), - game_data.z64.get_enum(bpy.context, "floorSetting"), + game_data.z64.get_enum("floorSetting"), "floorSettingCustom", ) setCustomProperty(collision, "wallSetting", str(getBits(params[0], 21, 5)), ootEnumWallSetting) @@ -199,7 +199,7 @@ def parseSurfaceParams( collision, "floorProperty", str(getBits(params[0], 13, 8)), - game_data.z64.get_enum(bpy.context, "floorProperty"), + game_data.z64.get_enum("floorProperty"), "floorPropertyCustom", ) collision.exitID = getBits(params[0], 8, 5) @@ -231,7 +231,7 @@ def parseSurfaceParams( collision, "sound", str(getBits(params[1], 0, 4)), - game_data.z64.get_enum(bpy.context, "sound"), + game_data.z64.get_enum("sound"), "soundCustom", ) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index f68c1d70e..17d71e667 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -536,9 +536,9 @@ def parseSceneCommands( if args[2].startswith("NA_BGM_"): enum_id = args[2] else: - enum_id = game_data.z64.enumData.enumByKey["seqId"].item_by_index[int(args[2])].id + enum_id = game_data.z64.enums.enumByKey["seqId"].item_by_index[int(args[2])].id - setCustomProperty(sceneHeader, "musicSeq", enum_id, game_data.z64.ootEnumMusicSeq, "musicSeqCustom") + setCustomProperty(sceneHeader, "musicSeq", enum_id, game_data.z64.get_enum("musicSeq"), "musicSeqCustom") command_list.remove(command) elif command == "SCENE_CMD_ROOM_LIST": # Delay until actor cutscenes are processed @@ -569,7 +569,7 @@ def parseSceneCommands( sceneHeader, "globalObject", args[1], - game_data.z64.ootEnumGlobalObject, + game_data.z64.get_enum("globalObject"), "globalObjectCustom", ) command_list.remove(command) diff --git a/fast64_internal/z64/object.py b/fast64_internal/z64/object.py index 7208ab775..e42d388eb 100644 --- a/fast64_internal/z64/object.py +++ b/fast64_internal/z64/object.py @@ -22,7 +22,7 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header game_data.z64.update(bpy.context, None) for roomActor in curHeader.actors.actorList: - actor = game_data.z64.actorData.actorsByID.get(roomActor.id) + actor = game_data.z64.actors.actorsByID.get(roomActor.id) if actor is not None and actor.key != "player" and len(actor.tiedObjects) > 0: for objKey in actor.tiedObjects: if objKey.replace("obj_", "") not in { @@ -30,7 +30,7 @@ def addMissingObjectsToRoomHeader(roomObj: Object, curHeader: RoomHeader, header "gameplay_field_keep", "gameplay_dangeon_keep", }: - objID = game_data.z64.objectData.objects_by_key[objKey].id + objID = game_data.z64.objects.objects_by_key[objKey].id if not (objID in curHeader.objects.objectList): curHeader.objects.objectList.append(objID) addMissingObjectToProp(roomObj, headerIndex, objKey) diff --git a/fast64_internal/z64/room/operators.py b/fast64_internal/z64/room/operators.py index b16c5c299..f71e2133b 100644 --- a/fast64_internal/z64/room/operators.py +++ b/fast64_internal/z64/room/operators.py @@ -12,7 +12,7 @@ class OOT_SearchObjectEnumOperator(Operator): bl_property = "objectKey" bl_options = {"REGISTER", "UNDO"} - objectKey: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "objectKey"), default=1) + objectKey: EnumProperty(items=lambda self, context: game_data.z64.get_enum("objectKey"), default=1) headerIndex: IntProperty(default=0, min=0) index: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 8be5f2ddb..984075389 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -42,7 +42,7 @@ class Z64_ObjectProperty(PropertyGroup): expandTab: BoolProperty(name="Expand Tab") - objectKey: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "objectKey"), default=1) + objectKey: EnumProperty(items=lambda self, context: game_data.z64.get_enum("objectKey"), default=1) objectIDCustom: StringProperty(default="OBJECT_CUSTOM") @staticmethod @@ -50,7 +50,7 @@ def upgrade_object(obj: Object): if game_data.z64.is_oot(): print(f"Processing '{obj.name}'...") game_data.z64.update(bpy.context, None) - upgradeRoomHeaders(obj, game_data.z64.objectData) + upgradeRoomHeaders(obj, game_data.z64.objects) def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: str): is_legacy = True if "objectID" in self else False @@ -58,9 +58,9 @@ def draw_props(self, layout: UILayout, headerIndex: int, index: int, objName: st game_data.z64.update(bpy.context, None) if game_data.z64.is_oot() and is_legacy: - obj_name = game_data.z64.objectData.ootEnumObjectIDLegacy[self["objectID"]][1] + obj_name = game_data.z64.objects.ootEnumObjectIDLegacy[self["objectID"]][1] elif obj_key != "Custom": - obj_name = game_data.z64.objectData.objects_by_key[obj_key].name + obj_name = game_data.z64.objects.objects_by_key[obj_key].name else: obj_name = self.objectIDCustom @@ -105,12 +105,12 @@ class Z64_RoomHeaderProperty(PropertyGroup): # SCENE_CMD_ROOM_BEHAVIOR roomIndex: IntProperty(name="Room Index", default=0, min=0) - roomBehaviour: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "roomBehaviour"), default=1) + roomBehaviour: EnumProperty(items=lambda self, context: game_data.z64.get_enum("roomBehaviour"), default=1) roomBehaviourCustom: StringProperty(default="0x00") showInvisibleActors: BoolProperty(name="Show Invisible Actors") linkIdleMode: EnumProperty( name="Environment Type", - items=lambda self, context: game_data.z64.get_enum(context, "linkIdleMode"), + items=lambda self, context: game_data.z64.get_enum("linkIdleMode"), default=1, ) linkIdleModeCustom: StringProperty(name="Environment Type Custom", default="0x00") diff --git a/fast64_internal/z64/scene/operators.py b/fast64_internal/z64/scene/operators.py index 6ec38379d..bfcb5e9da 100644 --- a/fast64_internal/z64/scene/operators.py +++ b/fast64_internal/z64/scene/operators.py @@ -100,7 +100,7 @@ class OOT_SearchMusicSeqEnumOperator(Operator): bl_property = "ootMusicSeq" bl_options = {"REGISTER", "UNDO"} - ootMusicSeq: EnumProperty(items=lambda self, context: game_data.z64.get_enum(context, "musicSeq"), default=1) + ootMusicSeq: EnumProperty(items=lambda self, context: game_data.z64.get_enum("musicSeq"), default=1) headerIndex: IntProperty(default=0, min=0) objName: StringProperty() diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 4344b27e0..6709ea638 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -244,7 +244,7 @@ def draw_props(self, layout: UILayout): class Z64_SceneTableEntryProperty(PropertyGroup): drawConfig: EnumProperty( - items=lambda self, context: game_data.z64.get_enum(context, "drawConfig"), name="Scene Draw Config", default=1 + items=lambda self, context: game_data.z64.get_enum("drawConfig"), name="Scene Draw Config", default=1 ) drawConfigCustom: StringProperty(name="Scene Draw Config Custom") @@ -319,7 +319,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_SPECIAL_FILES globalObject: EnumProperty( - name="Global Object", default=1, items=lambda self, context: game_data.z64.get_enum(context, "globalObject") + name="Global Object", default=1, items=lambda self, context: game_data.z64.get_enum("globalObject") ) globalObjectCustom: StringProperty(name="Global Object Custom", default="0x00") @@ -329,11 +329,11 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_SKYBOX_SETTINGS skyboxID: EnumProperty( - name="Skybox", items=lambda self, context: game_data.z64.get_enum(context, "skyboxID"), default=1 + name="Skybox", items=lambda self, context: game_data.z64.get_enum("skyboxID"), default=1 ) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") skyboxCloudiness: EnumProperty( - name="Cloudiness", items=lambda self, context: game_data.z64.get_enum(context, "skyboxCloudiness"), default=1 + name="Cloudiness", items=lambda self, context: game_data.z64.get_enum("skyboxCloudiness"), default=1 ) skyboxCloudinessCustom: StringProperty(name="Cloudiness ID", default="0x00") skyboxLighting: EnumProperty( @@ -351,11 +351,11 @@ class Z64_SceneHeaderProperty(PropertyGroup): # SCENE_CMD_SOUND_SETTINGS musicSeq: EnumProperty( - name="Music Sequence", items=lambda self, context: game_data.z64.get_enum(context, "musicSeq"), default=1 + name="Music Sequence", items=lambda self, context: game_data.z64.get_enum("musicSeq"), default=1 ) musicSeqCustom: StringProperty(name="Music Sequence ID", default="0x00") nightSeq: EnumProperty( - name="Nighttime SFX", items=lambda self, context: game_data.z64.get_enum(context, "nightSeq"), default=1 + name="Nighttime SFX", items=lambda self, context: game_data.z64.get_enum("nightSeq"), default=1 ) nightSeqCustom: StringProperty(name="Nighttime SFX ID", default="0x00") audioSessionPreset: EnumProperty(name="Audio Session Preset", items=ootEnumAudioSessionPreset, default="0x00") diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 253937cef..8baf464fa 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -124,8 +124,8 @@ def convertOldDataToEnumData(data, oldDataToEnumData: list[Cutscene_UpgradeData] raise NotImplementedError # if the value is in the list find the identifier - if value < len(csUpgradeData.enumData): - setattr(data, csUpgradeData.newPropName, csUpgradeData.enumData[value][0]) + if value < len(csUpgradeData.enums): + setattr(data, csUpgradeData.newPropName, csUpgradeData.enums[value][0]) isUpgraded = True else: # else raise an error to default to custom @@ -182,12 +182,12 @@ def upgradeCutsceneSubProps(csListSubProp): subPropsToEnum = [ # TextBox - Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", game_data.z64.enumData.ootEnumOcarinaSongActionId), - Cutscene_UpgradeData("type", "csTextType", game_data.z64.enumData.ootEnumCsTextType), + Cutscene_UpgradeData("ocarinaSongAction", "ocarinaAction", game_data.z64.enums.enum_ocarina_song_action_id), + Cutscene_UpgradeData("type", "csTextType", game_data.z64.enums.enum_cs_text_type), # Seq - Cutscene_UpgradeData("value", "csSeqID", game_data.z64.enumData.ootEnumSeqId), + Cutscene_UpgradeData("value", "csSeqID", game_data.z64.enums.enum_seq_id), # Misc - Cutscene_UpgradeData("operation", "csMiscType", game_data.z64.enumData.ootEnumCsMiscType), + Cutscene_UpgradeData("operation", "csMiscType", game_data.z64.enums.enum_cs_misc_type), ] transferOldDataToNew(csListSubProp, subPropsOldToNew) @@ -215,7 +215,7 @@ def upgradeCSListProps(csListProp): # both are enums but the item list is different (the old one doesn't have a "custom" entry) convertOldDataToEnumData( csListProp, - [Cutscene_UpgradeData("fxType", "transitionType", game_data.z64.enumData.ootEnumCsTransitionType)], + [Cutscene_UpgradeData("fxType", "transitionType", game_data.z64.enums.enum_cs_transition_type)], ) @@ -230,7 +230,7 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): transferOldDataToNew(csProp, csPropOldToNew) convertOldDataToEnumData( - csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", game_data.z64.enumData.ootEnumCsDestination)] + csProp, [Cutscene_UpgradeData("csTermIdx", "csDestination", game_data.z64.enums.enum_cs_destination)] ) @@ -250,7 +250,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): if "actor_id" in legacyData: index = legacyData["actor_id"] if index >= 0: - cmdEnum = game_data.z64.enumData.enumByKey["csCmd"] + cmdEnum = game_data.z64.enums.enumByKey["csCmd"] cmdType = cmdEnum.item_by_index.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key @@ -271,7 +271,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): del legacyData["start_frame"] if "action_id" in legacyData: - playerEnum = game_data.z64.enumData.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enums.enumByKey["csPlayerCueId"] item = None if isPlayer: item = playerEnum.item_by_index.get(int(legacyData["action_id"], base=16)) @@ -325,7 +325,7 @@ def upgradeActors(actorObj: Object): isCustom = actorObj.ootEntranceProperty.customActor else: if "actorID" in actorProp: - actorProp.actor_id = game_data.z64.actorData.ootEnumActorID[actorProp["actorID"]][0] + actorProp.actor_id = game_data.z64.actors.ootEnumActorID[actorProp["actorID"]][0] del actorProp["actorID"] if "actorIDCustom" in actorProp: From d3515f197de955261d86d646d1a2368c32e98530 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:02:53 +0100 Subject: [PATCH 077/126] format --- fast64_internal/z64/actor/properties.py | 4 +--- fast64_internal/z64/cutscene/properties.py | 12 +++--------- fast64_internal/z64/exporter/room/header.py | 4 +--- fast64_internal/z64/exporter/scene/actors.py | 8 ++------ fast64_internal/z64/scene/properties.py | 4 +--- 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index a64432e23..906dedd99 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -241,9 +241,7 @@ def draw_props( class Z64_ActorProperty(PropertyGroup): - actor_id: EnumProperty( - name="Actor", items=lambda self, context: game_data.z64.get_enum("actor_id"), default=1 - ) + actor_id: EnumProperty(name="Actor", items=lambda self, context: game_data.z64.get_enum("actor_id"), default=1) actor_id_custom: StringProperty(name="Actor ID", default="ACTOR_PLAYER") # only used for actors with the id "Custom" diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 7fb8e3ce0..75a0b6a5d 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -158,9 +158,7 @@ class OOTCSTimeProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): attrName = "seqList" subprops = ["csSeqID", "startFrame", "endFrame"] - csSeqID: EnumProperty( - name="Seq ID", items=lambda self, context: game_data.z64.get_enum("seqId"), default=1 - ) + csSeqID: EnumProperty(name="Seq ID", items=lambda self, context: game_data.z64.get_enum("seqId"), default=1) csSeqIDCustom: StringProperty(default="NA_BGM_CUSTOM") csSeqPlayer: EnumProperty( name="Seq Player", items=lambda self, context: game_data.z64.get_enum("csSeqPlayer"), default=1 @@ -179,9 +177,7 @@ def filterName(self, name, listProp): class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): attrName = "miscList" subprops = ["csMiscType", "startFrame", "endFrame"] - csMiscType: EnumProperty( - name="Type", items=lambda self, context: game_data.z64.get_enum("csMiscType"), default=1 - ) + csMiscType: EnumProperty(name="Type", items=lambda self, context: game_data.z64.get_enum("csMiscType"), default=1) csMiscTypeCustom: StringProperty(default="CS_MISC_CUSTOM") @@ -207,9 +203,7 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - transitionType: EnumProperty( - items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1 - ) + transitionType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1) transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") transitionStartFrame: IntProperty(name="", default=0, min=0) transitionEndFrame: IntProperty(name="", default=1, min=0) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 604c64888..6d4f71fe5 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -256,9 +256,7 @@ def new( actor.rot = ", ".join(f"{rot}, {flag})" for rot, flag in zip(spawn_rot, spawn_flags)) actor.name = ( - game_data.z64.actors.actorsByID[actor_id].name.replace( - f" - {actor_id.removeprefix('ACTOR_')}", "" - ) + game_data.z64.actors.actorsByID[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") if actor_id != "Custom" else "Custom Actor" ) diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 352a50112..c7cc18a97 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -82,9 +82,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.id = actor_id transActor.name = ( - game_data.z64.actors.actorsByID[actor_id].name.replace( - f" - {actor_id.removeprefix('ACTOR_')}", "" - ) + game_data.z64.actors.actorsByID[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") if actor_id != "Custom" else "Custom Actor" ) @@ -162,9 +160,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor = EntranceActor() entranceActor.name = ( - game_data.z64.actors.actorsByID[actor_id].name.replace( - f" - {actor_id.removeprefix('ACTOR_')}", "" - ) + game_data.z64.actors.actorsByID[actor_id].name.replace(f" - {actor_id.removeprefix('ACTOR_')}", "") if actor_id != "Custom" else "Custom Actor" ) diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 6709ea638..5a92e939c 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -328,9 +328,7 @@ class Z64_SceneHeaderProperty(PropertyGroup): naviCupCustom: StringProperty(name="Navi Hints Custom", default="0x00") # SCENE_CMD_SKYBOX_SETTINGS - skyboxID: EnumProperty( - name="Skybox", items=lambda self, context: game_data.z64.get_enum("skyboxID"), default=1 - ) + skyboxID: EnumProperty(name="Skybox", items=lambda self, context: game_data.z64.get_enum("skyboxID"), default=1) skyboxIDCustom: StringProperty(name="Skybox ID", default="0") skyboxCloudiness: EnumProperty( name="Cloudiness", items=lambda self, context: game_data.z64.get_enum("skyboxCloudiness"), default=1 From b0fb457c948fe253dd184555b6106c0ab658843b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:05:03 +0100 Subject: [PATCH 078/126] rename getters --- fast64_internal/data/z64/actor_data.py | 2 +- fast64_internal/data/z64/{getters.py => common.py} | 0 fast64_internal/data/z64/enum_data.py | 2 +- fast64_internal/data/z64/object_data.py | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename fast64_internal/data/z64/{getters.py => common.py} (100%) diff --git a/fast64_internal/data/z64/actor_data.py b/fast64_internal/data/z64/actor_data.py index 04c59855b..ca6f71183 100644 --- a/fast64_internal/data/z64/actor_data.py +++ b/fast64_internal/data/z64/actor_data.py @@ -1,7 +1,7 @@ from os import path from dataclasses import dataclass from pathlib import Path -from .getters import Z64_BaseElement, get_xml_root +from .common import Z64_BaseElement, get_xml_root @dataclass diff --git a/fast64_internal/data/z64/getters.py b/fast64_internal/data/z64/common.py similarity index 100% rename from fast64_internal/data/z64/getters.py rename to fast64_internal/data/z64/common.py diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py index 12a912ad0..cb83ae977 100644 --- a/fast64_internal/data/z64/enum_data.py +++ b/fast64_internal/data/z64/enum_data.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field from os import path from pathlib import Path -from .getters import Z64_BaseElement, get_xml_root +from .common import Z64_BaseElement, get_xml_root @dataclass diff --git a/fast64_internal/data/z64/object_data.py b/fast64_internal/data/z64/object_data.py index e9301bd92..f4dccb109 100644 --- a/fast64_internal/data/z64/object_data.py +++ b/fast64_internal/data/z64/object_data.py @@ -2,7 +2,7 @@ from os import path from pathlib import Path from ...utility import PluginError -from .getters import Z64_BaseElement, get_xml_root +from .common import Z64_BaseElement, get_xml_root # Note: "object" in this context refers to an OoT Object file (like ``gameplay_keep``) From 1cee54231aad85fffc49d15a01582a6e641b863d Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:57:47 +0100 Subject: [PATCH 079/126] fix registration oddities --- __init__.py | 8 +------- fast64_internal/data/z64/data.py | 7 ++++++- fast64_internal/game_data.py | 4 +++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/__init__.py b/__init__.py index 8012845c9..591512572 100644 --- a/__init__.py +++ b/__init__.py @@ -357,13 +357,6 @@ def upgrade_scene_props_node(): def after_load(_a, _b): game_data.update(bpy.context.scene.gameEditorMode) - if game_data.status != "ready": - oot_register(True, True) - game_data.status = "ready" - - if game_data.status != "ready": - raise ValueError("ERROR: game data is not ready") - settings = bpy.context.scene.fast64.settings if any(mat.is_f3d for mat in bpy.data.materials): check_or_ask_color_management(bpy.context) @@ -442,6 +435,7 @@ def register(): render_engine_register() bsdf_conv_register() sm64_register(True) + oot_register(True, True) mk64_register(True) repo_settings_operators_register() diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 60ba57e27..5bf26cd16 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -514,6 +514,7 @@ class Z64_Data: def __init__(self, game: str): self.game = game + self.is_registering = True self.update(None, game, True) # forcing the update as we're in the init function self.enum_floor_effect = enum_floor_effect @@ -525,7 +526,11 @@ def is_mm(self): return self.game == "MM" def update(self, context: Optional[Context], game: Optional[str], force: bool = False): - if context is not None: + if self.is_registering: + # it doesn't matter to force the game since it will be updated during the post-load handler + # is_registering becomes false as soon as an update with context passed is done + next_game = "OOT" + elif context is not None: next_game = context.scene.gameEditorMode elif game is not None: next_game = game diff --git a/fast64_internal/game_data.py b/fast64_internal/game_data.py index 23e33978c..4b0db82c4 100644 --- a/fast64_internal/game_data.py +++ b/fast64_internal/game_data.py @@ -6,13 +6,15 @@ def __init__(self, game_editor_mode: Optional[str] = None): from .data import Z64_Data self.z64 = Z64_Data("OOT") - self.status = "not ready" if game_editor_mode is not None: self.update(game_editor_mode) def update(self, game_editor_mode: str): if game_editor_mode is not None and game_editor_mode in {"OOT", "MM"}: + if game_data.z64.is_registering: + game_data.z64.is_registering = False + self.z64.update(None, game_editor_mode, True) if game_editor_mode in {"OOT", "MM"} and game_editor_mode != self.z64.game: From d166c14da078cad4bb67b502ad23a10091332147 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 9 Jan 2025 00:13:08 +0100 Subject: [PATCH 080/126] progress on cutscenes --- __init__.py | 5 +- fast64_internal/data/z64/data.py | 5 +- fast64_internal/data/z64/enum_data.py | 6 +- fast64_internal/data/z64/xml/mm_enum_data.xml | 14 ++-- .../data/z64/xml/oot_enum_data.xml | 62 +++++++++++++++ fast64_internal/game_data.py | 3 - fast64_internal/z64/actor/properties.py | 3 - fast64_internal/z64/cutscene/classes.py | 40 ++++------ fast64_internal/z64/cutscene/constants.py | 7 +- .../z64/cutscene/exporter/classes.py | 30 ++++---- .../z64/cutscene/importer/classes.py | 6 +- .../z64/cutscene/motion/operators.py | 3 +- .../z64/cutscene/motion/properties.py | 15 +++- fast64_internal/z64/cutscene/properties.py | 76 +++++++++++++------ .../z64/exporter/cutscene/actor_cue.py | 2 +- fast64_internal/z64/exporter/cutscene/data.py | 33 ++++---- fast64_internal/z64/exporter/cutscene/misc.py | 6 +- fast64_internal/z64/exporter/cutscene/seq.py | 2 +- fast64_internal/z64/exporter/cutscene/text.py | 4 +- fast64_internal/z64/importer/scene_header.py | 2 +- fast64_internal/z64/props_panel_main.py | 5 +- fast64_internal/z64/upgrade.py | 14 ++-- 22 files changed, 218 insertions(+), 125 deletions(-) diff --git a/__init__.py b/__init__.py index 591512572..e04b30de3 100644 --- a/__init__.py +++ b/__init__.py @@ -60,7 +60,7 @@ # info about add on bl_info = { "name": "Fast64", - "version": (2, 3, 0), + "version": (2, 3, 1), "author": "kurethedead", "location": "3DView", "description": "Plugin for exporting F3D display lists and other game data related to Nintendo 64 games.", @@ -243,6 +243,9 @@ class Fast64_Properties(bpy.types.PropertyGroup): settings: bpy.props.PointerProperty(type=Fast64Settings_Properties, name="Fast64 Settings") renderSettings: bpy.props.PointerProperty(type=Fast64RenderSettings_Properties, name="Fast64 Render Settings") + def get_addon_version(self): + return bl_info["version"] + class Fast64_BoneProperties(bpy.types.PropertyGroup): """ diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 5bf26cd16..49e38dca5 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -526,9 +526,10 @@ def is_mm(self): return self.game == "MM" def update(self, context: Optional[Context], game: Optional[str], force: bool = False): + if context is not None and self.is_registering: + self.is_registering = False + if self.is_registering: - # it doesn't matter to force the game since it will be updated during the post-load handler - # is_registering becomes false as soon as an update with context passed is done next_game = "OOT" elif context is not None: next_game = context.scene.gameEditorMode diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py index cb83ae977..8bd598407 100644 --- a/fast64_internal/data/z64/enum_data.py +++ b/fast64_internal/data/z64/enum_data.py @@ -19,7 +19,7 @@ def __post_init__(self): "cs_text_type": "CS_TEXT", "cs_fade_out_seq_player": "CS_FADE_OUT", "cs_transition_type": "CS_TRANS", - "cs_destination": "CS_DEST", + "cs_destination": ("CS_DESTINATION" if self.game == "MM" else "CS_DEST"), "cs_player_cue_id": "PLAYER_CUEID", "cs_modify_seq_type": "CS_MOD", "cs_credits_scene_type": "CS_CREDITS", @@ -27,7 +27,7 @@ def __post_init__(self): "cs_rumble_type": "CS_RUMBLE", "cs_transition_general": "CS_TRANS_GENERAL", "cs_spline_interp_type": "CS_CAM_INTERP", - "cs_spline_rel": "CS_CAM_REL", + "cs_spline_rel": "", # TODO: set the value to `CS_CAM_REL` once this is documented "cs_spawn_flag": "CS_SPAWN_FLAG", "actor_cs_end_sfx": "CS_END_SFX", "navi_quest_hint_type": "NAVI_QUEST_HINTS", @@ -35,7 +35,7 @@ def __post_init__(self): "seq_id": "NA_BGM", "draw_config": ("SCENE_DRAW_CFG" if self.game == "MM" else "SDC"), "surface_material": "SURFACE_MATERIAL", - "global_object": "OBJECT_", + "global_object": "OBJECT", } self.name = self.id.removeprefix(f"{keyToPrefix[self.parentKey]}_") diff --git a/fast64_internal/data/z64/xml/mm_enum_data.xml b/fast64_internal/data/z64/xml/mm_enum_data.xml index 8265a6b6e..bccb116df 100644 --- a/fast64_internal/data/z64/xml/mm_enum_data.xml +++ b/fast64_internal/data/z64/xml/mm_enum_data.xml @@ -502,13 +502,13 @@ - - - - - - - + + + + + + + diff --git a/fast64_internal/data/z64/xml/oot_enum_data.xml b/fast64_internal/data/z64/xml/oot_enum_data.xml index 0e067ce26..bafc62fc8 100644 --- a/fast64_internal/data/z64/xml/oot_enum_data.xml +++ b/fast64_internal/data/z64/xml/oot_enum_data.xml @@ -674,4 +674,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fast64_internal/game_data.py b/fast64_internal/game_data.py index 4b0db82c4..1c8222c29 100644 --- a/fast64_internal/game_data.py +++ b/fast64_internal/game_data.py @@ -12,9 +12,6 @@ def __init__(self, game_editor_mode: Optional[str] = None): def update(self, game_editor_mode: str): if game_editor_mode is not None and game_editor_mode in {"OOT", "MM"}: - if game_data.z64.is_registering: - game_data.z64.is_registering = False - self.z64.update(None, game_editor_mode, True) if game_editor_mode in {"OOT", "MM"} and game_editor_mode != self.z64.game: diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 906dedd99..a8de3ac6d 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -699,9 +699,6 @@ def actor_props_register(): game_data.z64.update(None, "MM", True) create_game_props() - # restore the data for the current game - game_data.z64.update(bpy.context, None, True) - for cls in classes: register_class(cls) diff --git a/fast64_internal/z64/cutscene/classes.py b/fast64_internal/z64/cutscene/classes.py index 4c596b699..549034672 100644 --- a/fast64_internal/z64/cutscene/classes.py +++ b/fast64_internal/z64/cutscene/classes.py @@ -31,18 +31,6 @@ class CutsceneCmdBase: duration: Optional[int] = None def getEnumValue(self, enumKey: str, index: int, isSeqLegacy: bool = False): - if game_data.z64.is_mm() and enumKey not in { - "seqId", - "destinationType", - "ocarinaSongActionId", - "motionBlurType", - "modifySeqType", - "chooseCreditsSceneType", - "transitionGeneralType", - }: - # remove `cs` and lowercase first letter - enumKey = enumKey[2].lower() + enumKey[3:] - enum = game_data.z64.enums.enumByKey[enumKey] item = enum.item_by_id.get(self.params[index]) if item is None: @@ -195,7 +183,7 @@ def __post_init__(self): self.commandType = self.commandType.removeprefix("0x") self.commandType = "0x" + "0" * (4 - len(self.commandType)) + self.commandType else: - self.commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_id[self.commandType].key + self.commandType = game_data.z64.enums.enumByKey["cs_cmd"].item_by_id[self.commandType].key self.entryTotal = getInteger(self.params[1].strip()) @@ -296,7 +284,7 @@ def __post_init__(self): if self.params is not None: self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) - self.type = self.getEnumValue("csMiscType", 0) + self.type = self.getEnumValue("cs_misc_type", 0) @dataclass @@ -325,7 +313,7 @@ def __post_init__(self): if self.params is not None: self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) - self.type = self.getEnumValue("csTransitionType", 0) + self.type = self.getEnumValue("cs_transition_type", 0) @dataclass @@ -358,7 +346,7 @@ def __post_init__(self): self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) self.textId = getInteger(self.params[0]) - self.type = self.getEnumValue("csTextType", 3) + self.type = self.getEnumValue("cs_text_type", 3) self.altTextId1 = getInteger(self.params[4]) self.altTextId2 = getInteger(self.params[5]) @@ -389,7 +377,7 @@ def __post_init__(self): if self.params is not None: self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) - self.ocarinaActionId = self.getEnumValue("ocarinaSongActionId", 0) + self.ocarinaActionId = self.getEnumValue("ocarina_song_action_id", 0) self.messageId = getInteger(self.params[3]) @@ -522,7 +510,7 @@ def __post_init__(self): if self.params is not None: self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) - self.seqId = self.getEnumValue("seqId", 0, self.isLegacy) + self.seqId = self.getEnumValue("seq_id", 0, self.isLegacy) @dataclass @@ -552,7 +540,7 @@ def __post_init__(self): if self.params is not None: self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) - self.seqPlayer = self.getEnumValue("csFadeOutSeqPlayer", 0) + self.seqPlayer = self.getEnumValue("cs_fade_out_seq_player", 0) @dataclass @@ -611,7 +599,7 @@ class CutsceneCmdDestination(CutsceneCmdBase): def __post_init__(self): if self.params is not None: - self.type = self.getEnumValue("csDestination" if game_data.z64.is_oot() else "destinationType", 0) + self.type = self.getEnumValue("cs_destination" if game_data.z64.is_oot() else "destinationType", 0) self.startFrame = getInteger(self.params[1]) @@ -638,7 +626,7 @@ class CutsceneCmdMotionBlur(CutsceneCmdBase): def __post_init__(self): if self.params is not None: - self.type = self.getEnumValue("motionBlurType", 0) + self.type = self.getEnumValue("cs_motion_blur_type", 0) self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) @@ -666,7 +654,7 @@ class CutsceneCmdModifySeq(CutsceneCmdBase): def __post_init__(self): if self.params is not None: - self.type = self.getEnumValue("modifySeqType", 0) + self.type = self.getEnumValue("cs_modify_seq_type", 0) self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) @@ -694,7 +682,7 @@ class CutsceneCmdChooseCreditsScenes(CutsceneCmdBase): def __post_init__(self): if self.params is not None: - self.type = self.getEnumValue("chooseCreditsSceneType", 0) + self.type = self.getEnumValue("cs_credits_scene_type", 0) self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) @@ -723,7 +711,7 @@ class CutsceneCmdTransitionGeneral(CutsceneCmdBase): def __post_init__(self): if self.params is not None: - self.type = self.getEnumValue("transitionGeneralType", 0) + self.type = self.getEnumValue("cs_transition_general", 0) self.startFrame = getInteger(self.params[1]) self.endFrame = getInteger(self.params[2]) self.rgb = [getInteger(self.params[3]), getInteger(self.params[4]), getInteger(self.params[5])] @@ -843,7 +831,7 @@ def getNewCutsceneObject(self, name: str, frameCount: int, parentObj: Object): def getNewActorCueListObject(self, name: str, commandType: str, parentObj: Object): newActorCueListObj = self.getNewEmptyObject(name, False, parentObj) newActorCueListObj.ootEmptyType = f"CS {'Player' if 'Player' in name else 'Actor'} Cue List" - cmdEnum = game_data.z64.enums.enumByKey["csCmd"] + cmdEnum = game_data.z64.enums.enumByKey["cs_cmd"] if commandType == "Player": commandType = "player_cue" @@ -884,7 +872,7 @@ def getNewActorCueObject( item = None if isPlayer: - playerEnum = game_data.z64.enums.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enums.enumByKey["cs_player_cue_id"] if isinstance(actionID, int): item = playerEnum.item_by_index.get(actionID) else: diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index e381a54bc..ddd2d443d 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -70,7 +70,7 @@ ("TextList", "Text List", "Textbox", "ALIGN_BOTTOM", 0), ("MiscList", "Misc List", "Misc", "OPTIONS", 7), ("RumbleList", "Rumble List", "Rumble Controller", "OUTLINER_OB_FORCE_FIELD", 8), - ("Transition", "Transition", "Transition", "COLORSET_10_VEC", 1), + ("Transition", "Transition List", "Transition List", "COLORSET_10_VEC", 1), ("LightSettingsList", "Light Settings List", "Lighting", "LIGHT_SUN", 2), ("TimeList", "Time List", "Time", "TIME", 3), ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), @@ -122,11 +122,14 @@ "rumbleSourceStrength": "Source Strength", "rumbleDuration": "Duration", "rumbleDecreaseRate": "Decrease Rate", + "rumble_type": "Rumble Type", + # Transition + "transition_type": "Transition Type", # Lists "TextList": "Text List", "TimeList": "Time List", "FadeOutSeqList": "Fade-Out Seq List", - "Transition": "Transition", + "Transition": "Transition List", "StartSeqList": "Start Seq List", "MiscList": "Misc List", "LightSettingsList": "Light Settings List", diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index 3cbe4d70b..c68b26ee0 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -89,7 +89,7 @@ def getTextOcarinaActionCmd(self, ocarinaAction: CutsceneCmdTextOcarinaAction): ) def getDestinationCmd(self, csProp: "OOTCutsceneProperty"): - dest = self.getEnumValue("csDestination", csProp, "csDestination") + dest = self.getEnumValue("cs_destination", csProp, "csDestination") return indent * 2 + f"CS_DESTINATION({dest}, {csProp.csDestinationStartFrame}, 0),\n" def getActorCueListCmd(self, actorCueList: CutsceneCmdActorCueList, isPlayerActor: bool): @@ -212,7 +212,7 @@ def getActorCueListData(self, isPlayer: bool): if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useDecomp: - commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enums.enumByKey["cs_cmd"].item_by_key[commandType].id # ignoring dummy cue actorCueList = CutsceneCmdActorCueList(None, entryTotal=entryTotal - 1, commandType=commandType) @@ -227,7 +227,7 @@ def getActorCueListData(self, isPlayer: bool): if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = game_data.z64.enums.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enums.enumByKey["cs_player_cue_id"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID @@ -348,7 +348,7 @@ def getTextListData(self, textEntry: "OOTCSTextProperty"): textEntry.startFrame, textEntry.endFrame, textEntry.textID, - self.getEnumValue("csTextType", textEntry, "csTextType"), + self.getEnumValue("cs_text_type", textEntry, "csTextType"), textEntry.topOptionTextID, textEntry.bottomOptionTextID, ) @@ -361,7 +361,7 @@ def getTextListData(self, textEntry: "OOTCSTextProperty"): None, textEntry.startFrame, textEntry.endFrame, - self.getEnumValue("ocarinaSongActionId", textEntry, "ocarinaAction"), + self.getEnumValue("ocarina_song_action_id", textEntry, "ocarinaAction"), textEntry.ocarinaMessageId, ) ) @@ -391,20 +391,20 @@ def getCutsceneData(self): elem.startFrame, elem.endFrame, ) - case "Transition": - subData += self.getTransitionCmd( - CutsceneCmdTransition( - None, - entry.transitionStartFrame, - entry.transitionEndFrame, - self.getEnumValue("csTransitionType", entry, "transitionType"), - ) - ) case _: curList = getattr(entry, (entry.listType[0].lower() + entry.listType[1:])) entryTotal = len(curList) for elem in curList: match entry.listType: + case "Transition": + subData += self.getTransitionCmd( + CutsceneCmdTransition( + None, + elem.startFrame, + elem.endFrame, + self.getEnumValue("cs_transition_type", elem, "transition_type"), + ) + ) case "TextList": subData += self.getTextListData(elem) case "LightSettingsList": @@ -423,7 +423,7 @@ def getCutsceneData(self): None, elem.startFrame, elem.endFrame, - self.getEnumValue("csMiscType", elem, "csMiscType"), + self.getEnumValue("cs_misc_type", elem, "csMiscType"), ) ) case "RumbleList": diff --git a/fast64_internal/z64/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py index c589d9bec..a711d7554 100644 --- a/fast64_internal/z64/cutscene/importer/classes.py +++ b/fast64_internal/z64/cutscene/importer/classes.py @@ -503,14 +503,14 @@ def setPropOrCustom(self, prop, propName: str, value): setattr(prop, propName, value) except TypeError: setattr(prop, propName, "Custom") - setattr(prop, f"{propName}Custom", value) + setattr(prop, f"{propName}_custom" if "_" in propName else f"{propName}Custom", value) def setSubPropertyData(self, subPropsData: dict[str, str], newSubElem, entry): customNames = [ "csMiscType", "csTextType", "ocarinaAction", - "transitionType", + "transition_type", "csSeqID", "csSeqPlayer", "transition", @@ -613,7 +613,7 @@ def setCutsceneData(self, csNumber): propDataList = [ PropertyData("Text", {"textboxType": "id"}, True), PropertyData("Misc", {"csMiscType": "type"}, True), - PropertyData("Transition", {"transitionType": "type"}, True), + PropertyData("Transition", {"transition_type": "type"}, True), PropertyData("LightSettings", {"lightSettingsIndex": "lightSetting"}, False), PropertyData("Time", {"hour": "hour", "minute": "minute"}, False), PropertyData("Seq", {"csSeqID": "seqId"}, False), diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index d242181f9..8fb72df5e 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -24,9 +24,8 @@ def createNewActorCueList(csObj: Object, isPlayer: bool): """Creates a new Actor or Player Cue List and adds one basic cue and the dummy one""" objFactory = CutsceneObjectFactory() playerOrActor = "Player" if isPlayer else "Actor" - newActorCueListObj = objFactory.getNewActorCueListObject(f"New {playerOrActor} Cue List", "actor_cue_0_0", None) index, csPrefix = getNameInformations(csObj, f"{playerOrActor} Cue List", None) - newActorCueListObj.name = f"{csPrefix}.{playerOrActor} Cue List {index:02}" + newActorCueListObj = objFactory.getNewActorCueListObject(f"{csPrefix}.{playerOrActor} Cue List {index:02}", "actor_cue_0_0", None) # add a basic actor cue and the dummy one for i in range(2): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 842852e3b..ea19b0a3c 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -4,7 +4,7 @@ from bpy.props import IntProperty, StringProperty, PointerProperty, EnumProperty, FloatProperty from bpy.utils import register_class, unregister_class from ...upgrade import upgradeCutsceneMotion -from ...utility import getEnumName +from ...utility import getEnumName, prop_split from ....game_data import game_data from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType @@ -144,6 +144,9 @@ class CutsceneCmdCameraShotProperty(PropertyGroup): default="splineEyeOrAT", ) + shot_spline_rel_to: EnumProperty(items=game_data.z64.enums.enum_cs_spline_rel, default=1) + shot_spline_rel_to_custom: StringProperty(default="CS_CAM_REL_CUSTOM") + def getEndFrame(self, camShotObj: Object = None): if camShotObj is None: camShotObj = bpy.context.view_layer.objects.active @@ -155,12 +158,20 @@ def getEndFrame(self, camShotObj: Object = None): return -1 def draw_props(self, layout: UILayout, label: str): + # update manually since we don't use shared enum mode + game_data.z64.update(bpy.context, None) + box = layout.box() box.label(text=label) split = box.split(factor=0.5) split.prop(self, "shotStartFrame") split.prop(self, "shotEndFrame") - box.row().prop(self, "shotCamMode", expand=True) + if game_data.z64.is_oot(): + box.row().prop(self, "shotCamMode", expand=True) + else: + prop_split(box.row(), self, "shot_spline_rel_to", "Spline Relative To") + if self.shot_spline_rel_to == "Custom": + prop_split(box.row(), self, "shot_spline_rel_to_custom", "") box.operator(CutsceneCmdAddBone.bl_idname) diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 75a0b6a5d..fd51031df 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -68,6 +68,9 @@ def draw_props( drawCollectionOps(box, cmdIndex, collectionType + "." + self.attrName, listIndex, objName) for p in self.subprops: + if game_data.z64.is_oot() and p == "rumble_type" and not bpy.context.scene.fast64.oot.mm_features: + continue + if self.filterProp(p, listProp): name = self.filterName(p, listProp) displayName = ootCSSubPropToName[name] @@ -89,10 +92,12 @@ def draw_props( "ocarinaAction", "csSeqID", "csSeqPlayer", + "rumble_type", + "transition_type", ] value = getattr(self, p) if name in customValues and value == "Custom": - prop_split(box, self, f"{name}Custom", f"{displayName} Custom") + prop_split(box, self, f"{name}_custom" if "_" in p else f"{name}Custom", f"{displayName} Custom") if name == "csTextType" and value != "choice": break @@ -166,7 +171,8 @@ class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") def filterProp(self, name, listProp): - return name != "endFrame" or listProp.listType == "FadeOutSeqList" + types = {"FadeOutSeqList", "StopSeqList"} if game_data.z64.is_mm() else {"FadeOutSeqList"} + return name != "endFrame" or listProp.listType in types def filterName(self, name, listProp): if name == "csSeqID" and listProp.listType == "FadeOutSeqList": @@ -183,13 +189,23 @@ class OOTCSMiscProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSRumbleProperty(OOTCutsceneCommon, PropertyGroup): attrName = "rumbleList" - subprops = ["startFrame", "rumbleSourceStrength", "rumbleDuration", "rumbleDecreaseRate"] + subprops = ["rumble_type", "startFrame", "rumbleSourceStrength", "rumbleDuration", "rumbleDecreaseRate"] # those variables are unsigned chars in decomp # see https://github.com/zeldaret/oot/blob/542012efa68d110d6b631f9d149f6e5f4e68cc8e/src/code/z_rumble.c#L58-L77 rumbleSourceStrength: IntProperty(name="", default=0, min=0, max=255) rumbleDuration: IntProperty(name="", default=0, min=0, max=255) rumbleDecreaseRate: IntProperty(name="", default=0, min=0, max=255) + rumble_type: EnumProperty(name="", items=game_data.z64.enums.enum_cs_rumble_type, default=1) + rumble_type_custom: StringProperty() + + +class OOTCSTransitionProperty(OOTCutsceneCommon, PropertyGroup): + attrName = "transition_list" + subprops = ["transition_type", "startFrame", "endFrame"] + + transition_type: EnumProperty(name="", items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1) + transition_type_custom: StringProperty("CS_TRANS_CUSTOM") class OOTCSListProperty(PropertyGroup): @@ -202,14 +218,11 @@ class OOTCSListProperty(PropertyGroup): seqList: CollectionProperty(type=OOTCSSeqProperty) miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) - - transitionType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1) - transitionTypeCustom: StringProperty(default="CS_TRANS_CUSTOM") - transitionStartFrame: IntProperty(name="", default=0, min=0) - transitionEndFrame: IntProperty(name="", default=1, min=0) + transition_list: CollectionProperty(type=OOTCSTransitionProperty) def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionType: str): box = layout.box().column() + game_data.z64.update(bpy.context, None) enumName = getEnumName(ootEnumCSListType, self.listType) # Draw current command tab @@ -229,13 +242,7 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT if self.listType == "TextList": attrName = "textList" elif self.listType == "Transition": - prop_split(box, self, "transitionType", "Transition Type") - if self.transitionType == "Custom": - prop_split(box, self, "transitionTypeCustom", "Transition Type Custom") - - prop_split(box, self, "transitionStartFrame", "Start Frame") - prop_split(box, self, "transitionEndFrame", "End Frame") - return + attrName = "transition_list" elif self.listType == "LightSettingsList": attrName = "lightSettingsList" elif self.listType == "TimeList": @@ -279,7 +286,7 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT for i, p in enumerate(data): # ``p`` type: # OOTCSTextProperty | OOTCSLightSettingsProperty | OOTCSTimeProperty | - # OOTCSSeqProperty | OOTCSMiscProperty | OOTCSRumbleProperty + # OOTCSSeqProperty | OOTCSMiscProperty | OOTCSRumbleProperty | OOTCSTransitionProperty p.draw_props(box, self, listIndex, i, objName, collectionType, enumName.removesuffix(" List")) if len(data) == 0: @@ -388,6 +395,22 @@ def upgrade_object(obj): for csListSubProp in getattr(csListProp, listName): upgradeCutsceneSubProps(csListSubProp) + if csListProp.listType == "Transition": + new_entry = csListProp.transition_list.add() + + if "transitionType" in csListProp: + new_entry.transition_type = csListProp.transitionType + del csListProp["transitionType"] + if "transitionTypeCustom" in csListProp: + new_entry.transition_type_custom = csListProp.transitionTypeCustom + del csListProp["transitionTypeCustom"] + if "transitionStartFrame" in csListProp: + new_entry.startFrame = csListProp.transitionStartFrame + del csListProp["transitionStartFrame"] + if "transitionEndFrame" in csListProp: + new_entry.endFrame = csListProp.transitionEndFrame + del csListProp["transitionEndFrame"] + def draw_props(self, layout: UILayout, obj: Object): split = layout.split(factor=0.5) split.operator(CutsceneCmdCreateCameraShot.bl_idname, icon="VIEW_CAMERA") @@ -409,13 +432,19 @@ def draw_props(self, layout: UILayout, obj: Object): if self.csUseDestination: b.prop(self, "csDestinationStartFrame") - searchBox = b.box() - boxRow = searchBox.row() - searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") - searchOp.objName = obj.name - boxRow.label(text=getEnumName(game_data.z64.get_enum("csDestination"), self.csDestination)) + if game_data.z64.is_oot(): + searchBox = b.box() + boxRow = searchBox.row() + searchOp = boxRow.operator(OOT_SearchCSDestinationEnumOperator.bl_idname, icon="VIEWZOOM", text="") + searchOp.objName = obj.name + boxRow.label(text=getEnumName(game_data.z64.get_enum("csDestination"), self.csDestination)) + layout_custom = searchBox + else: + layout_custom = b + prop_split(b, self, "csDestination", "Cutscene Destination Type") + if self.csDestination == "Custom": - prop_split(searchBox.column(), self, "csDestinationCustom", "Cutscene Destination Custom") + prop_split(layout_custom.column(), self, "csDestinationCustom", "Cutscene Destination Custom") commandsBox.column_flow(columns=3, align=True).prop(self, "menuTab", expand=True) label = f"Add New {ootCSSubPropToName[self.menuTab]}" @@ -437,6 +466,7 @@ def draw_props(self, layout: UILayout, obj: Object): OOTCSSeqProperty, OOTCSMiscProperty, OOTCSRumbleProperty, + OOTCSTransitionProperty, OOTCSListProperty, OOTCutsceneTransitionProperty, OOTCutsceneMiscProperty, @@ -447,6 +477,8 @@ def draw_props(self, layout: UILayout, obj: Object): def cutscene_props_register(): + game_data.z64.update(None, "OOT", True) + for cls in classes: register_class(cls) diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index 1e50a8e94..2208266fd 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -74,7 +74,7 @@ def from_params(params: list[str], isPlayer: bool): commandType = commandType.removeprefix("0x") commandType = "0x" + "0" * (4 - len(commandType)) + commandType else: - commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_id[commandType].key + commandType = game_data.z64.enums.enumByKey["cs_cmd"].item_by_id[commandType].key entryTotal = getInteger(params[1].strip()) return CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 587820e06..560a03d01 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -49,6 +49,7 @@ "StartSeq": CutsceneCmdStartStopSeq, "StopSeq": CutsceneCmdStartStopSeq, "FadeOutSeq": CutsceneCmdFadeSeq, + "Transition": CutsceneCmdTransition, } cmdToList = { @@ -169,7 +170,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if commandType == "Custom": commandType = obj.ootCSMotionProperty.actorCueListProp.commandTypeCustom elif self.useMacros: - commandType = game_data.z64.enums.enumByKey["csCmd"].item_by_key[commandType].id + commandType = game_data.z64.enums.enumByKey["cs_cmd"].item_by_key[commandType].id # ignoring dummy cue newActorCueList = CutsceneCmdActorCueList(None, None, isPlayer, commandType, entryTotal - 1) @@ -183,7 +184,7 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if isPlayer: cueID = childObj.ootCSMotionProperty.actorCueProp.playerCueID if cueID != "Custom": - actionID = game_data.z64.enums.enumByKey["csPlayerCueId"].item_by_key[cueID].id + actionID = game_data.z64.enums.enumByKey["cs_player_cue_id"].item_by_key[cueID].id if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID @@ -309,7 +310,7 @@ def getNewTextCmd(self, textEntry: "OOTCSTextProperty"): textEntry.startFrame, textEntry.endFrame, textEntry.textID, - self.getEnumValueFromProp("csTextType", textEntry, "csTextType"), + self.getEnumValueFromProp("cs_text_type", textEntry, "csTextType"), textEntry.topOptionTextID, textEntry.bottomOptionTextID, ) @@ -319,7 +320,7 @@ def getNewTextCmd(self, textEntry: "OOTCSTextProperty"): return CutsceneCmdTextOcarinaAction( textEntry.startFrame, textEntry.endFrame, - self.getEnumValueFromProp("ocarinaSongActionId", textEntry, "ocarinaAction"), + self.getEnumValueFromProp("ocarina_song_action_id", textEntry, "ocarinaAction"), textEntry.ocarinaMessageId, ) raise PluginError("ERROR: Unknown text type!") @@ -337,7 +338,7 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce self.destination = CutsceneCmdDestination( csProp.csDestinationStartFrame, None, - self.getEnumValueFromProp("csDestination", csProp, "csDestination"), + self.getEnumValueFromProp("cs_destination", csProp, "csDestination"), ) self.totalEntries += 1 @@ -355,29 +356,29 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce for elem in entry.seqList: data = cmdToClass[entry.listType.removesuffix("List")](elem.startFrame, elem.endFrame) if isFadeOutSeq: - data.seqPlayer = self.getEnumValueFromProp("csFadeOutSeqPlayer", elem, "csSeqPlayer") + data.seqPlayer = self.getEnumValueFromProp("cs_fade_out_seq_player", elem, "csSeqPlayer") else: data.type = cmdList.type - data.seqId = self.getEnumValueFromProp("seqId", elem, "csSeqID") + data.seqId = self.getEnumValueFromProp("seq_id", elem, "csSeqID") cmdList.entries.append(data) if isFadeOutSeq: self.fadeSeqList.append(cmdList) else: self.seqList.append(cmdList) - case "Transition": - self.transitionList.append( - CutsceneCmdTransition( - entry.transitionStartFrame, - entry.transitionEndFrame, - self.getEnumValueFromProp("csTransitionType", entry, "transitionType"), - ) - ) case _: curList = getattr(entry, (entry.listType[0].lower() + entry.listType[1:])) cmdList = cmdToClass[entry.listType](None, None) cmdList.entryTotal = len(curList) for elem in curList: match entry.listType: + case "Transition": + cmdList.entries.append( + CutsceneCmdTransition( + elem.startFrame, + elem.endFrame, + self.getEnumValueFromProp("cs_transition_type", elem, "transition_type"), + ) + ) case "TextList": cmdList.entries.append(self.getNewTextCmd(elem)) case "LightSettingsList": @@ -395,7 +396,7 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce CutsceneCmdMisc( elem.startFrame, elem.endFrame, - self.getEnumValueFromProp("csMiscType", elem, "csMiscType"), + self.getEnumValueFromProp("cs_misc_type", elem, "csMiscType"), ) ) case "RumbleList": diff --git a/fast64_internal/z64/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py index a332dbf6c..be628616e 100644 --- a/fast64_internal/z64/exporter/cutscene/misc.py +++ b/fast64_internal/z64/exporter/cutscene/misc.py @@ -16,7 +16,7 @@ class CutsceneCmdMisc(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): return CutsceneCmdMisc( - getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("csMiscType", params[0]) + getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_misc_type", params[0]) ) def getCmd(self): @@ -200,7 +200,7 @@ class CutsceneCmdDestination(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): return CutsceneCmdDestination( - getInteger(params[1]), None, CutsceneCmdBase.getEnumValue("csDestination", params[0]) + getInteger(params[1]), None, CutsceneCmdBase.getEnumValue("cs_destination", params[0]) ) def getCmd(self): @@ -220,7 +220,7 @@ class CutsceneCmdTransition(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): return CutsceneCmdTransition( - getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("csTransitionType", params[0]) + getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_transition_type", params[0]) ) def getCmd(self): diff --git a/fast64_internal/z64/exporter/cutscene/seq.py b/fast64_internal/z64/exporter/cutscene/seq.py index f8afeb78b..bb4155c70 100644 --- a/fast64_internal/z64/exporter/cutscene/seq.py +++ b/fast64_internal/z64/exporter/cutscene/seq.py @@ -17,7 +17,7 @@ class CutsceneCmdStartStopSeq(CutsceneCmdBase): @staticmethod def from_params(params: list[str], isLegacy: bool): return CutsceneCmdFadeSeq( - getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("seqId", params[0], isLegacy) + getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("seq_id", params[0], isLegacy) ) def getCmd(self): diff --git a/fast64_internal/z64/exporter/cutscene/text.py b/fast64_internal/z64/exporter/cutscene/text.py index a19efb96e..ffe532a7f 100644 --- a/fast64_internal/z64/exporter/cutscene/text.py +++ b/fast64_internal/z64/exporter/cutscene/text.py @@ -22,7 +22,7 @@ def from_params(params: list[str]): getInteger(params[1]), getInteger(params[2]), getInteger(params[0]), - CutsceneCmdBase.getEnumValue("csTextType", params[3]), + CutsceneCmdBase.getEnumValue("cs_text_type", params[3]), getInteger(params[4]), getInteger(params[5]), ) @@ -67,7 +67,7 @@ def from_params(params: list[str]): return CutsceneCmdTextOcarinaAction( getInteger(params[1]), getInteger(params[2]), - CutsceneCmdBase.getEnumValue("ocarinaSongActionId", params[0]), + CutsceneCmdBase.getEnumValue("ocarina_song_action_id", params[0]), getInteger(params[3]), ) diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index 17d71e667..a854a03bb 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -536,7 +536,7 @@ def parseSceneCommands( if args[2].startswith("NA_BGM_"): enum_id = args[2] else: - enum_id = game_data.z64.enums.enumByKey["seqId"].item_by_index[int(args[2])].id + enum_id = game_data.z64.enums.enumByKey["seq_id"].item_by_index[int(args[2])].id setCustomProperty(sceneHeader, "musicSeq", enum_id, game_data.z64.get_enum("musicSeq"), "musicSeqCustom") command_list.remove(command) diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 32aa047ea..6a38d17a2 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -1,6 +1,6 @@ import bpy from bpy.utils import register_class, unregister_class -from ..utility import prop_split, gammaInverse +from ..utility import PluginError, prop_split, gammaInverse from ..game_data import game_data from .utility import getSceneObj, getRoomObj, is_oot_features from .scene.properties import OOTSceneProperties @@ -218,6 +218,9 @@ class OOT_ObjectProperties(bpy.types.PropertyGroup): @staticmethod def upgrade_changed_props(): + if bpy.context.scene.fast64.get_addon_version() < (2, 3, 1): + raise PluginError("ERROR: Upgrading on this version is deprecated. Please update to an older version and update again to this one.") + for obj in bpy.data.objects: if obj.type == "EMPTY" and game_data.z64.is_oot(): if obj.ootEmptyType == "Room": diff --git a/fast64_internal/z64/upgrade.py b/fast64_internal/z64/upgrade.py index 8baf464fa..fd680634a 100644 --- a/fast64_internal/z64/upgrade.py +++ b/fast64_internal/z64/upgrade.py @@ -212,12 +212,6 @@ def upgradeCSListProps(csListProp): transferOldDataToNew(csListProp, csListPropOldToNew) - # both are enums but the item list is different (the old one doesn't have a "custom" entry) - convertOldDataToEnumData( - csListProp, - [Cutscene_UpgradeData("fxType", "transitionType", game_data.z64.enums.enum_cs_transition_type)], - ) - def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): game_data.z64.update(bpy.context, None) @@ -237,7 +231,7 @@ def upgradeCutsceneProperty(csProp: "OOTCutsceneProperty"): def upgradeCutsceneMotion(csMotionObj: Object): """Main upgrade logic for Cutscene Motion data from zcamedit""" objName = csMotionObj.name - game_data.z64.update(bpy.context, None) + game_data.z64.update(None, "OOT", True) if csMotionObj.type == "EMPTY": csMotionProp = csMotionObj.ootCSMotionProperty @@ -250,7 +244,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): if "actor_id" in legacyData: index = legacyData["actor_id"] if index >= 0: - cmdEnum = game_data.z64.enums.enumByKey["csCmd"] + cmdEnum = game_data.z64.enums.enumByKey["cs_cmd"] cmdType = cmdEnum.item_by_index.get(index) if cmdType is not None: csMotionProp.actorCueListProp.commandType = cmdType.key @@ -271,7 +265,7 @@ def upgradeCutsceneMotion(csMotionObj: Object): del legacyData["start_frame"] if "action_id" in legacyData: - playerEnum = game_data.z64.enums.enumByKey["csPlayerCueId"] + playerEnum = game_data.z64.enums.enumByKey["cs_player_cue_id"] item = None if isPlayer: item = playerEnum.item_by_index.get(int(legacyData["action_id"], base=16)) @@ -310,6 +304,8 @@ def upgradeCutsceneMotion(csMotionObj: Object): camShotPointProp.shotPointRoll = bone["camroll"] del bone["camroll"] + game_data.z64.update(bpy.context, None, True) + ##################################### # Actors From 696d46bccb253d20751c12bf2b99005fd4af77ca Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 9 Jan 2025 00:17:28 +0100 Subject: [PATCH 081/126] format --- fast64_internal/data/z64/enum_data.py | 2 +- fast64_internal/z64/cutscene/motion/operators.py | 4 +++- fast64_internal/z64/cutscene/properties.py | 4 +++- fast64_internal/z64/props_panel_main.py | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py index 8bd598407..2885a7c34 100644 --- a/fast64_internal/data/z64/enum_data.py +++ b/fast64_internal/data/z64/enum_data.py @@ -27,7 +27,7 @@ def __post_init__(self): "cs_rumble_type": "CS_RUMBLE", "cs_transition_general": "CS_TRANS_GENERAL", "cs_spline_interp_type": "CS_CAM_INTERP", - "cs_spline_rel": "", # TODO: set the value to `CS_CAM_REL` once this is documented + "cs_spline_rel": "", # TODO: set the value to `CS_CAM_REL` once this is documented "cs_spawn_flag": "CS_SPAWN_FLAG", "actor_cs_end_sfx": "CS_END_SFX", "navi_quest_hint_type": "NAVI_QUEST_HINTS", diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index 8fb72df5e..0dcb028e2 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -25,7 +25,9 @@ def createNewActorCueList(csObj: Object, isPlayer: bool): objFactory = CutsceneObjectFactory() playerOrActor = "Player" if isPlayer else "Actor" index, csPrefix = getNameInformations(csObj, f"{playerOrActor} Cue List", None) - newActorCueListObj = objFactory.getNewActorCueListObject(f"{csPrefix}.{playerOrActor} Cue List {index:02}", "actor_cue_0_0", None) + newActorCueListObj = objFactory.getNewActorCueListObject( + f"{csPrefix}.{playerOrActor} Cue List {index:02}", "actor_cue_0_0", None + ) # add a basic actor cue and the dummy one for i in range(2): diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index fd51031df..fd7fdc15f 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -204,7 +204,9 @@ class OOTCSTransitionProperty(OOTCutsceneCommon, PropertyGroup): attrName = "transition_list" subprops = ["transition_type", "startFrame", "endFrame"] - transition_type: EnumProperty(name="", items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1) + transition_type: EnumProperty( + name="", items=lambda self, context: game_data.z64.get_enum("transitionType"), default=1 + ) transition_type_custom: StringProperty("CS_TRANS_CUSTOM") diff --git a/fast64_internal/z64/props_panel_main.py b/fast64_internal/z64/props_panel_main.py index 6a38d17a2..be394d941 100644 --- a/fast64_internal/z64/props_panel_main.py +++ b/fast64_internal/z64/props_panel_main.py @@ -219,7 +219,9 @@ class OOT_ObjectProperties(bpy.types.PropertyGroup): @staticmethod def upgrade_changed_props(): if bpy.context.scene.fast64.get_addon_version() < (2, 3, 1): - raise PluginError("ERROR: Upgrading on this version is deprecated. Please update to an older version and update again to this one.") + raise PluginError( + "ERROR: Upgrading on this version is deprecated. Please update to an older version and update again to this one." + ) for obj in bpy.data.objects: if obj.type == "EMPTY" and game_data.z64.is_oot(): From 7ab487fadca204a39b4c9f09b03dbef124a2a5d2 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 9 Jan 2025 03:01:23 +0100 Subject: [PATCH 082/126] more progress on cutscenes + exporter fixes --- fast64_internal/data/z64/data.py | 62 ++++++++++++++++++- fast64_internal/data/z64/enum_data.py | 8 +++ fast64_internal/data/z64/xml/mm_enum_data.xml | 28 ++++----- fast64_internal/z64/actor/properties.py | 10 +-- fast64_internal/z64/cutscene/constants.py | 54 +++++++--------- .../z64/cutscene/exporter/classes.py | 5 +- .../z64/cutscene/motion/operators.py | 5 +- .../z64/cutscene/motion/properties.py | 21 +++++-- fast64_internal/z64/cutscene/operators.py | 4 +- fast64_internal/z64/cutscene/properties.py | 15 +++-- .../z64/exporter/collision/__init__.py | 8 +-- fast64_internal/z64/exporter/scene/general.py | 12 ++-- fast64_internal/z64/exporter/utility.py | 12 +++- 13 files changed, 158 insertions(+), 86 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 49e38dca5..0d4ec5cd7 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -505,6 +505,37 @@ ("CAM_SET_DUNGEON4", "Dungeon4", "Used in Pirates Fortress Interior, hidden room near hookshot 'DUNGEON4'"), ] +# order here sets order on the UI +ootEnumCSListType = [ + ("TextList", "Text List", "Textbox", "ALIGN_BOTTOM", 0), + ("MiscList", "Misc List", "Misc", "OPTIONS", 7), + ("RumbleList", "Rumble List", "Rumble Controller", "OUTLINER_OB_FORCE_FIELD", 8), + ("Transition", "Transition List", "Transition List", "COLORSET_10_VEC", 1), + ("LightSettingsList", "Light Settings List", "Lighting", "LIGHT_SUN", 2), + ("TimeList", "Time List", "Time", "TIME", 3), + ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), + ("StopSeqList", "Stop Seq List", "Stop BGM", "SNAP_FACE", 5), + ("FadeOutSeqList", "Fade-Out Seq List", "Fade BGM", "IPO_EASE_IN_OUT", 6), +] + +mm_enum_cs_list_type = [ + ("TextList", "Text List", "Textbox", "ALIGN_BOTTOM", 0), + ("MiscList", "Misc List", "Misc", "OPTIONS", 7), + ("RumbleList", "Rumble List", "Rumble Controller", "OUTLINER_OB_FORCE_FIELD", 8), + ("Transition", "Transition", "Transition", "COLORSET_10_VEC", 1), + ("LightSettingsList", "Light Settings List", "Lighting", "LIGHT_SUN", 2), + ("TimeList", "Time List", "Time", "TIME", 3), + ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), + ("StopSeqList", "Stop Seq List", "Stop BGM", "SNAP_FACE", 5), + ("FadeOutSeqList", "Fade-Out Seq List", "Fade BGM", "IPO_EASE_IN_OUT", 6), + ("DestinationList", "Destination List", "Destination", "EVENT_D", 9), + ("MotionBlurList", "Motion Blur List", "Motion Blur", "ONIONSKIN_ON", 10), + ("ModifySeqList", "Modify Seq List", "Modify Seq", "IPO_CONSTANT", 11), + ("CreditsSceneList", "Choose Credits Scene List", "Choose Credits Scene", "WORLD", 12), + ("TransitionGeneralList", "Transition General List", "Transition General", "COLORSET_06_VEC", 13), + ("GiveTatlList", "Give Tatl List", "Give Tatl", "EVENT_T", 14), +] + # --- @@ -529,18 +560,34 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = if context is not None and self.is_registering: self.is_registering = False - if self.is_registering: + if not force and self.is_registering: next_game = "OOT" - elif context is not None: - next_game = context.scene.gameEditorMode elif game is not None: next_game = game + elif context is not None: + next_game = context.scene.gameEditorMode else: raise ValueError("ERROR: invalid values for context and game") # don't update if the game is the same (or we don't want to force one) if not force and next_game == self.game: return + + self.cs_list_type_to_cmd = { + "TextList": "CS_TEXT_LIST", + "LightSettingsList": "CS_LIGHT_SETTING_LIST", + "TimeList": "CS_TIME_LIST", + "StartSeqList": "CS_START_SEQ_LIST", + "StopSeqList": "CS_STOP_SEQ_LIST", + "FadeOutSeqList": "CS_FADE_OUT_SEQ_LIST", + "MiscList": "CS_MISC_LIST", + "DestinationList": "CS_DESTINATION_LIST", + "MotionBlurList": "CS_MOTION_BLUR_LIST", + "ModifySeqList": "CS_MODIFY_SEQ_LIST", + "CreditsSceneList": "CS_CHOOSE_CREDITS_SCENES_LIST", + "TransitionGeneralList": "CS_TRANSITION_GENERAL_LIST", + "GiveTatlList": "CS_GIVE_TATL_LIST", + } self.game = next_game self.enums = Z64_EnumData(self.game) @@ -549,6 +596,8 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = if self.game == "OOT": self.cs_index_start = 4 + self.cs_list_type_to_cmd["Transition"] = "CS_TRANSITION" + self.cs_list_type_to_cmd["RumbleList"] = "CS_RUMBLE_CONTROLLER_LIST" self.ootEnumNightSeq = ootEnumNightSeq self.ootEnumSkybox = ootEnumSkybox self.ootEnumCloudiness = ootEnumCloudiness @@ -557,8 +606,11 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumFloorSetting = ootEnumFloorSetting self.ootEnumFloorProperty = ootEnumFloorProperty self.ootEnumCameraSType = ootEnumCameraSType + self.ootEnumCSListType = ootEnumCSListType elif self.game == "MM": self.cs_index_start = 1 + self.cs_list_type_to_cmd["Transition"] = "CS_TRANSITION_LIST" + self.cs_list_type_to_cmd["RumbleList"] = "CS_RUMBLE_LIST" self.ootEnumNightSeq = enum_ambiance_id self.ootEnumSkybox = mm_enum_skybox self.ootEnumCloudiness = mm_enum_skybox_config @@ -567,6 +619,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumFloorSetting = mm_enum_floor_property self.ootEnumFloorProperty = mm_enum_floor_type self.ootEnumCameraSType = mm_enum_camera_setting_type + self.ootEnumCSListType = mm_enum_cs_list_type else: raise ValueError(f"ERROR: unsupported game {repr(self.game)}") @@ -583,6 +636,8 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = "csSeqPlayer": self.enums.enum_cs_fade_out_seq_player, "csMiscType": self.enums.enum_cs_misc_type, "transitionType": self.enums.enum_cs_transition_type, + "actor_cue_list_cmd_type": self.enums.enum_cs_actor_cue_list_cmd_type, + "spline_interp_type": self.enums.enum_cs_spline_interp_type, "objectKey": self.objects.ootEnumObjectKey, "actor_id": self.actors.ootEnumActorID, "chest_content": self.actors.ootEnumChestContent, @@ -596,6 +651,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = "floorSetting": self.ootEnumFloorSetting, "floorProperty": self.ootEnumFloorProperty, "camSType": self.ootEnumCameraSType, + "cs_list_type": self.ootEnumCSListType, } def get_enum(self, prop_name: str): diff --git a/fast64_internal/data/z64/enum_data.py b/fast64_internal/data/z64/enum_data.py index 2885a7c34..987688a54 100644 --- a/fast64_internal/data/z64/enum_data.py +++ b/fast64_internal/data/z64/enum_data.py @@ -8,6 +8,7 @@ class Z64_ItemElement(Z64_BaseElement): parentKey: str game: str + desc: str def __post_init__(self): # generate the name from the id @@ -90,6 +91,7 @@ def __init__(self, game: str): int(item.attrib["Index"]), enum.attrib["Key"], game, + item.attrib.get("Description", "Unset"), ) for item in enum ], @@ -128,6 +130,12 @@ def __init__(self, game: str): for key in self.enumByKey.keys(): setattr(self, f"enum_{key}", self.get_enum_data(key)) + self.enum_cs_actor_cue_list_cmd_type = [ + item for item in self.enum_cs_cmd if "actor_cue" in item[0] or "player_cue" in item[0] + ] + self.enum_cs_actor_cue_list_cmd_type.sort() + self.enum_cs_actor_cue_list_cmd_type.insert(0, ("Custom", "Custom", "Custom")) + def get_enum_data(self, enumKey: str): enum = self.enumByKey[enumKey] firstIndex = min(1, *(item.index for item in enum.items)) diff --git a/fast64_internal/data/z64/xml/mm_enum_data.xml b/fast64_internal/data/z64/xml/mm_enum_data.xml index bccb116df..e5c4782fb 100644 --- a/fast64_internal/data/z64/xml/mm_enum_data.xml +++ b/fast64_internal/data/z64/xml/mm_enum_data.xml @@ -483,23 +483,23 @@ - - - - - - - - + + + + + + + + - - - - - - + + + + + + diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index a8de3ac6d..64f680566 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -72,8 +72,10 @@ def get_prop_name(actor_key: str, param_type: str, param_subtype: str, param_ind return f"{game_data.z64.game.lower()}.{actor_key}.{suffix}{param_index}" # e.g.: `oot.en_test.props1` -def create_game_props(): +def create_game_props(game: str): """This function is used to edit the Z64_ActorProperty class""" + + game_data.z64.update(None, game, True) prop_ats = get_prop_annotations(Z64_ActorProperty) param_type_to_enum_items = { @@ -692,12 +694,10 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateS def actor_props_register(): # generate props for OoT - game_data.z64.update(None, "OOT", True) - create_game_props() + create_game_props("OOT") # generate props for MM - game_data.z64.update(None, "MM", True) - create_game_props() + create_game_props("MM") for cls in classes: register_class(cls) diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index ddd2d443d..7507080bc 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -48,36 +48,11 @@ ) -ootEnumCSListTypeListC = { - "TextList": "CS_TEXT_LIST", - "Transition": "CS_TRANSITION", - "LightSettingsList": "CS_LIGHT_SETTING_LIST", - "TimeList": "CS_TIME_LIST", - "StartSeqList": "CS_START_SEQ_LIST", - "StopSeqList": "CS_STOP_SEQ_LIST", - "FadeOutSeqList": "CS_FADE_OUT_SEQ_LIST", - "MiscList": "CS_MISC_LIST", - "RumbleList": "CS_RUMBLE_CONTROLLER_LIST", -} - ootEnumCSWriteType = [ ("Custom", "Custom", "Provide the name of a cutscene header variable", "", 0), ("Object", "Object", "Reference to Blender object representing cutscene", "", 2), ] -# order here sets order on the UI -ootEnumCSListType = [ - ("TextList", "Text List", "Textbox", "ALIGN_BOTTOM", 0), - ("MiscList", "Misc List", "Misc", "OPTIONS", 7), - ("RumbleList", "Rumble List", "Rumble Controller", "OUTLINER_OB_FORCE_FIELD", 8), - ("Transition", "Transition List", "Transition List", "COLORSET_10_VEC", 1), - ("LightSettingsList", "Light Settings List", "Lighting", "LIGHT_SUN", 2), - ("TimeList", "Time List", "Time", "TIME", 3), - ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), - ("StopSeqList", "Stop Seq List", "Stop BGM", "SNAP_FACE", 5), - ("FadeOutSeqList", "Fade-Out Seq List", "Fade BGM", "IPO_EASE_IN_OUT", 6), -] - csListTypeToIcon = { "TextList": "ALIGN_BOTTOM", "Transition": "COLORSET_10_VEC", @@ -88,6 +63,12 @@ "FadeOutSeqList": "IPO_EASE_IN_OUT", "MiscList": "OPTIONS", "RumbleList": "OUTLINER_OB_FORCE_FIELD", + "DestinationList": "EVENT_D", + "MotionBlurList": "ONIONSKIN_ON", + "ModifySeqList": "IPO_CONSTANT", + "CreditsSceneList": "WORLD", + "TransitionGeneralList": "COLORSET_06_VEC", + "GiveTatlList": "EVENT_T", } ootEnumCSTextboxType = [ @@ -96,7 +77,16 @@ ("OcarinaAction", "Ocarina Action", "Learn Song"), ] -ootEnumCSTextboxTypeIcons = ["FILE_TEXT", "HIDE_ON", "FILE_SOUND"] +ootEnumCSTextboxTypeIcons = { + "Text": "FILE_TEXT", + "None": "HIDE_ON", + "OcarinaAction": "FILE_SOUND", + "Default": "FILE_TEXT", + "Type1": "ALIGN_LEFT", + "Type3": "ALIGN_CENTER", + "BossesRemains": "GHOST_ENABLED", + "AllNormalMasks": "RECOVER_LAST", +} ootCSSubPropToName = { "startFrame": "Start Frame", @@ -135,6 +125,12 @@ "LightSettingsList": "Light Settings List", "StopSeqList": "Stop Seq List", "RumbleList": "Rumble List", + "DestinationList": "Destination List", + "MotionBlurList": "Motion Blur List", + "ModifySeqList": "Modify Seq List", + "CreditsSceneList": "Choose Credits Scene List", + "TransitionGeneralList": "Transition General List", + "GiveTatlList": "Give Tatl List", } ootEnumCSMotionCamMode = [ @@ -143,11 +139,7 @@ ("eyeOrAT", "Eye/AT Point", "Single Eye/AT point (not recommended)"), ] -ootEnumCSActorCueListCommandType = [ - item for item in game_data.z64.enums.enum_cs_cmd if "actor_cue" in item[0] or "player_cue" in item[0] -] -ootEnumCSActorCueListCommandType.sort() -ootEnumCSActorCueListCommandType.insert(0, ("Custom", "Custom", "Custom")) +# Import/Export ootCSLegacyToNewCmdNames = { "CS_CAM_POS_LIST": "CS_CAM_EYE_SPLINE", diff --git a/fast64_internal/z64/cutscene/exporter/classes.py b/fast64_internal/z64/cutscene/exporter/classes.py index c68b26ee0..d3da102fc 100644 --- a/fast64_internal/z64/cutscene/exporter/classes.py +++ b/fast64_internal/z64/cutscene/exporter/classes.py @@ -6,7 +6,6 @@ from bpy.types import Object from ....utility import PluginError, indent from ....game_data import game_data -from ..constants import ootEnumCSListTypeListC if TYPE_CHECKING: from ..properties import OOTCutsceneProperty, OOTCSTextProperty @@ -386,7 +385,7 @@ def getCutsceneData(self): enumKey = "csFadeOutSeqPlayer" if entry.listType == "FadeOutSeqList" else "seqId" propName = "csSeqPlayer" if entry.listType == "FadeOutSeqList" else "csSeqID" subData += self.getGenericSeqCmd( - ootEnumCSListTypeListC[entry.listType].removesuffix("_LIST"), + game_data.z64.cs_list_type_to_cmd[entry.listType].removesuffix("_LIST"), self.getEnumValue(enumKey, elem, propName), elem.startFrame, elem.endFrame, @@ -440,7 +439,7 @@ def getCutsceneData(self): case _: raise PluginError("ERROR: Unknown Cutscene List Type!") if entry.listType != "Transition": - listCmd = self.getGenericListCmd(ootEnumCSListTypeListC[entry.listType], entryTotal) + listCmd = self.getGenericListCmd(game_data.z64.cs_list_type_to_cmd[entry.listType], entryTotal) self.entryTotal += 1 data += listCmd + subData diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index 0dcb028e2..728d56bdf 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -1,12 +1,11 @@ import bpy -from bpy.types import Object, Operator, Context, Armature +from bpy.types import Object, Operator, Armature from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty from ....utility import PluginError from ....game_data import game_data from ..classes import CutsceneObjectFactory -from ..constants import ootEnumCSActorCueListCommandType from ..preview import initFirstFrame, setupCompositorNodes from .utility import ( setupActorCuePreview, @@ -297,7 +296,7 @@ class OOT_SearchActorCueCmdTypeEnumOperator(Operator): bl_property = "commandType" bl_options = {"REGISTER", "UNDO"} - commandType: EnumProperty(items=ootEnumCSActorCueListCommandType, default=1) + commandType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("actor_cue_list_cmd_type"), default=1) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index ea19b0a3c..10c4fe34f 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -3,10 +3,11 @@ from bpy.types import PropertyGroup, Object, UILayout, Armature, Bone, Scene, EditBone from bpy.props import IntProperty, StringProperty, PointerProperty, EnumProperty, FloatProperty from bpy.utils import register_class, unregister_class +from ....utility import prop_split from ...upgrade import upgradeCutsceneMotion from ...utility import getEnumName, prop_split from ....game_data import game_data -from ..constants import ootEnumCSMotionCamMode, ootEnumCSActorCueListCommandType +from ..constants import ootEnumCSMotionCamMode from .operators import ( CutsceneCmdAddActorCue, @@ -31,7 +32,7 @@ def getNextCuesStartFrame(self): class CutsceneCmdActorCueListProperty(PropertyGroup): - commandType: EnumProperty(items=ootEnumCSActorCueListCommandType, name="CS Actor Cue Command Type", default=1) + commandType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("actor_cue_list_cmd_type"), name="CS Actor Cue Command Type", default=1) commandTypeCustom: StringProperty(name="CS Actor Cue Command Type Custom") actorCueListToPreview: PointerProperty( type=Object, name="", poll=lambda self, object: self.isActorCueListObj(object, "CS Actor Cue List") @@ -55,7 +56,7 @@ def draw_props(self, layout: UILayout, isPreview: bool, labelPrefix: str, objNam OOT_SearchActorCueCmdTypeEnumOperator.bl_idname, icon="VIEWZOOM", text="Command Type:" ) searchOp.objName = objName - searchBox.label(text=getEnumName(ootEnumCSActorCueListCommandType, self.commandType)) + searchBox.label(text=getEnumName(game_data.z64.get_enum("actor_cue_list_cmd_type"), self.commandType)) if self.commandType == "Custom": split = box.split(factor=0.5) @@ -147,6 +148,14 @@ class CutsceneCmdCameraShotProperty(PropertyGroup): shot_spline_rel_to: EnumProperty(items=game_data.z64.enums.enum_cs_spline_rel, default=1) shot_spline_rel_to_custom: StringProperty(default="CS_CAM_REL_CUSTOM") + shot_interp_type: EnumProperty( + items=lambda self, context: game_data.z64.get_enum("spline_interp_type"), + name="Interpolation Type", + description="values 1-3 only uses a single point from the cmd, values 4-5 uses multiple points from the cmd, value 6 only uses a single point from the cmd", + default=4, + ) + shot_interp_type_custom: StringProperty(default="CS_CAM_INTERP_CUSTOM") + def getEndFrame(self, camShotObj: Object = None): if camShotObj is None: camShotObj = bpy.context.view_layer.objects.active @@ -169,9 +178,13 @@ def draw_props(self, layout: UILayout, label: str): if game_data.z64.is_oot(): box.row().prop(self, "shotCamMode", expand=True) else: - prop_split(box.row(), self, "shot_spline_rel_to", "Spline Relative To") + prop_split(box.row(), self, "shot_spline_rel_to", "Camera Relative To") if self.shot_spline_rel_to == "Custom": prop_split(box.row(), self, "shot_spline_rel_to_custom", "") + + prop_split(box.row(), self, "shot_interp_type", "Camera Interpolation Type") + if self.shot_interp_type == "Custom": + prop_split(box.row(), self, "shot_interp_type_custom", "") box.operator(CutsceneCmdAddBone.bl_idname) diff --git a/fast64_internal/z64/cutscene/operators.py b/fast64_internal/z64/cutscene/operators.py index 98858f759..a9798003d 100644 --- a/fast64_internal/z64/cutscene/operators.py +++ b/fast64_internal/z64/cutscene/operators.py @@ -10,7 +10,7 @@ from ...utility import CData, PluginError, writeCData, raisePluginError from ..utility import getCollection from ...game_data import game_data -from .constants import ootEnumCSTextboxType, ootEnumCSListType +from .constants import ootEnumCSTextboxType from .importer import importCutsceneData from .exporter import getNewCutsceneExport from ..exporter.cutscene import Cutscene @@ -129,7 +129,7 @@ class OOTCSListAdd(Operator): bl_options = {"REGISTER", "UNDO"} collectionType: StringProperty() - listType: EnumProperty(items=ootEnumCSListType) + listType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("cs_list_type")) objName: StringProperty() def execute(self, context): diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index fd7fdc15f..cd469725a 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -20,7 +20,6 @@ from .constants import ( ootEnumCSTextboxType, - ootEnumCSListType, ootEnumCSTextboxTypeIcons, ootCSSubPropToName, csListTypeToIcon, @@ -213,7 +212,7 @@ class OOTCSTransitionProperty(OOTCutsceneCommon, PropertyGroup): class OOTCSListProperty(PropertyGroup): expandTab: BoolProperty(default=True) - listType: EnumProperty(items=ootEnumCSListType) + listType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("cs_list_type")) textList: CollectionProperty(type=OOTCSTextProperty) lightSettingsList: CollectionProperty(type=OOTCSLightSettingsProperty) timeList: CollectionProperty(type=OOTCSTimeProperty) @@ -224,8 +223,8 @@ class OOTCSListProperty(PropertyGroup): def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionType: str): box = layout.box().column() - game_data.z64.update(bpy.context, None) - enumName = getEnumName(ootEnumCSListType, self.listType) + list_type_enum = game_data.z64.get_enum("cs_list_type") + enumName = getEnumName(list_type_enum, self.listType) # Draw current command tab box.prop( @@ -269,7 +268,7 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT addOp = row.operator( OOTCSTextAdd.bl_idname, text="Add " + ootEnumCSTextboxType[l][1], - icon=ootEnumCSTextboxTypeIcons[l], + icon=ootEnumCSTextboxTypeIcons[ootEnumCSTextboxType[l][0]], ) addOp.collectionType = collectionType + ".textList" @@ -278,7 +277,7 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT addOp.objName = objName else: addOp = box.operator( - OOTCollectionAdd.bl_idname, text="Add item to " + getEnumName(ootEnumCSListType, self.listType) + OOTCollectionAdd.bl_idname, text="Add item to " + getEnumName(list_type_enum, self.listType) ) addOp.option = len(data) addOp.collectionType = collectionType + "." + attrName @@ -292,7 +291,7 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT p.draw_props(box, self, listIndex, i, objName, collectionType, enumName.removesuffix(" List")) if len(data) == 0: - box.label(text="No items in " + getEnumName(ootEnumCSListType, self.listType)) + box.label(text="No items in " + getEnumName(list_type_enum, self.listType)) class OOTCutsceneCommandBase: @@ -376,7 +375,7 @@ class OOTCutsceneProperty(PropertyGroup): csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) csLists: CollectionProperty(type=OOTCSListProperty, name="Cutscene Lists") - menuTab: EnumProperty(items=ootEnumCSListType) + menuTab: EnumProperty(items=lambda self, context: game_data.z64.get_enum("cs_list_type")) preview: PointerProperty(type=OOTCutscenePreviewProperty) diff --git a/fast64_internal/z64/exporter/collision/__init__.py b/fast64_internal/z64/exporter/collision/__init__.py index d6a384297..fdb8d0ba3 100644 --- a/fast64_internal/z64/exporter/collision/__init__.py +++ b/fast64_internal/z64/exporter/collision/__init__.py @@ -156,14 +156,14 @@ def getCollisionData(dataHolder: Optional[Object], transform: Matrix, useMacros: surfaceType = SurfaceType( colProp.cameraID, colProp.exitID, - Utility.getPropValue(colProp, "floorProperty", "floorPropertyCustom"), + Utility.getPropValue(colProp, "floorProperty"), 0, # unused? Utility.getPropValue(colProp, "wallSetting"), - Utility.getPropValue(colProp, "floorSetting", "floorSettingCustom"), + Utility.getPropValue(colProp, "floorSetting"), colProp.decreaseHeight, colProp.eponaBlock, - Utility.getPropValue(colProp, "sound", "soundCustom"), - Utility.getPropValue(colProp, "terrain", "terrainCustom"), + Utility.getPropValue(colProp, "sound", enum_key="surface_material"), + Utility.getPropValue(colProp, "terrain"), colProp.lightingSetting, int(colProp.echo, base=16), colProp.hookshotable, diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index a72324e6b..d9ca0cf8a 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -195,16 +195,16 @@ def new(props: Z64_SceneHeaderProperty, sceneObj: Object): skybox_texture_id = Utility.getPropValue(props, "skybox_texture_id") return SceneInfos( - Utility.getPropValue(props, "globalObject", "globalObjectCustom"), + Utility.getPropValue(props, "globalObject", "globalObjectCustom", enum_key="global_object"), Utility.getPropValue(props, "naviCup") if game_data.z64.is_oot() else "NAVI_QUEST_HINTS_NONE", - Utility.getPropValue(props.sceneTableEntry, "drawConfig", "drawConfigCustom"), + Utility.getPropValue(props.sceneTableEntry, "drawConfig", enum_key="draw_config"), props.appendNullEntrance, sceneObj.fast64.oot.scene.write_dummy_room_list, - Utility.getPropValue(props, "skyboxID", "skyboxIDCustom"), - Utility.getPropValue(props, "skyboxCloudiness", "skyboxCloudinessCustom"), + Utility.getPropValue(props, "skyboxID"), + Utility.getPropValue(props, "skyboxCloudiness"), skybox_texture_id, - Utility.getPropValue(props, "musicSeq", "musicSeqCustom"), - Utility.getPropValue(props, "nightSeq", "nightSeqCustom"), + Utility.getPropValue(props, "musicSeq", enum_key="seq_id"), + Utility.getPropValue(props, "nightSeq"), Utility.getPropValue(props, "audioSessionPreset"), Utility.getPropValue(props, "mapLocation") if is_oot_features() else "", Utility.getPropValue(props, "cameraMode") if is_oot_features() else "", diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index d592cf85d..37964b951 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -60,15 +60,21 @@ def isCurrentHeaderValid(headerSettings: Z64_ActorHeaderProperty, headerIndex: i return False @staticmethod - def getPropValue(data, prop_name: str, custom_name: Optional[str] = None): + def getPropValue(data, prop_name: str, custom_name: Optional[str] = None, enum_key: Optional[str] = None): """Returns a property's value based on if the value is 'Custom'""" value = getattr(data, prop_name) if value != "Custom": - return value + if enum_key is not None: + return game_data.z64.enums.enumByKey[enum_key].item_by_key[value].id + else: + return value elif custom_name is not None: - return getattr(data, custom_name) + if enum_key is not None: + return game_data.z64.enums.enumByKey[enum_key].item_by_key[getattr(data, custom_name)].id + else: + return getattr(data, custom_name) return getattr(data, f"{prop_name}Custom") From da462fe6db8e8660ce6406f6d28794b6a2ebe5e6 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 9 Jan 2025 03:58:12 +0100 Subject: [PATCH 083/126] implement ui for mm cs cmds --- fast64_internal/data/z64/data.py | 16 ++-- fast64_internal/z64/cutscene/constants.py | 13 ++- .../z64/cutscene/motion/properties.py | 6 +- fast64_internal/z64/cutscene/properties.py | 82 ++++++++++++++++++- 4 files changed, 104 insertions(+), 13 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 0d4ec5cd7..4c2ea7531 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -528,12 +528,10 @@ ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), ("StopSeqList", "Stop Seq List", "Stop BGM", "SNAP_FACE", 5), ("FadeOutSeqList", "Fade-Out Seq List", "Fade BGM", "IPO_EASE_IN_OUT", 6), - ("DestinationList", "Destination List", "Destination", "EVENT_D", 9), - ("MotionBlurList", "Motion Blur List", "Motion Blur", "ONIONSKIN_ON", 10), - ("ModifySeqList", "Modify Seq List", "Modify Seq", "IPO_CONSTANT", 11), - ("CreditsSceneList", "Choose Credits Scene List", "Choose Credits Scene", "WORLD", 12), - ("TransitionGeneralList", "Transition General List", "Transition General", "COLORSET_06_VEC", 13), - ("GiveTatlList", "Give Tatl List", "Give Tatl", "EVENT_T", 14), + ("MotionBlurList", "Motion Blur List", "Motion Blur", "ONIONSKIN_ON", 9), + ("ModifySeqList", "Modify Seq List", "Modify Seq", "IPO_CONSTANT", 10), + ("CreditsSceneList", "Choose Credits Scene List", "Choose Credits Scene", "WORLD", 11), + ("TransitionGeneralList", "Transition General List", "Transition General", "COLORSET_06_VEC", 12), ] # --- @@ -572,7 +570,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = # don't update if the game is the same (or we don't want to force one) if not force and next_game == self.game: return - + self.cs_list_type_to_cmd = { "TextList": "CS_TEXT_LIST", "LightSettingsList": "CS_LIGHT_SETTING_LIST", @@ -638,6 +636,10 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = "transitionType": self.enums.enum_cs_transition_type, "actor_cue_list_cmd_type": self.enums.enum_cs_actor_cue_list_cmd_type, "spline_interp_type": self.enums.enum_cs_spline_interp_type, + "trans_general": self.enums.enum_cs_transition_general, + "blur_type": self.enums.enum_cs_motion_blur_type, + "credits_scene_type": self.enums.enum_cs_credits_scene_type, + "mod_seq_type": self.enums.enum_cs_modify_seq_type, "objectKey": self.objects.ootEnumObjectKey, "actor_id": self.actors.ootEnumActorID, "chest_content": self.actors.ootEnumChestContent, diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 7507080bc..65e137e04 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -63,12 +63,10 @@ "FadeOutSeqList": "IPO_EASE_IN_OUT", "MiscList": "OPTIONS", "RumbleList": "OUTLINER_OB_FORCE_FIELD", - "DestinationList": "EVENT_D", "MotionBlurList": "ONIONSKIN_ON", "ModifySeqList": "IPO_CONSTANT", "CreditsSceneList": "WORLD", "TransitionGeneralList": "COLORSET_06_VEC", - "GiveTatlList": "EVENT_T", } ootEnumCSTextboxType = [ @@ -115,6 +113,15 @@ "rumble_type": "Rumble Type", # Transition "transition_type": "Transition Type", + # Motion Blur + "blur_type": "Motion Blur Type", + # Transition General + "trans_general_type": "Transition Type", + "trans_color": "Transition Color", + # Choose Credits Scene + "credits_scene_type": "Credits Scene Type", + # Modify Seq + "mod_seq_type": "Modify Seq Type", # Lists "TextList": "Text List", "TimeList": "Time List", @@ -125,12 +132,10 @@ "LightSettingsList": "Light Settings List", "StopSeqList": "Stop Seq List", "RumbleList": "Rumble List", - "DestinationList": "Destination List", "MotionBlurList": "Motion Blur List", "ModifySeqList": "Modify Seq List", "CreditsSceneList": "Choose Credits Scene List", "TransitionGeneralList": "Transition General List", - "GiveTatlList": "Give Tatl List", } ootEnumCSMotionCamMode = [ diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 10c4fe34f..4c5f363d8 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -32,7 +32,11 @@ def getNextCuesStartFrame(self): class CutsceneCmdActorCueListProperty(PropertyGroup): - commandType: EnumProperty(items=lambda self, context: game_data.z64.get_enum("actor_cue_list_cmd_type"), name="CS Actor Cue Command Type", default=1) + commandType: EnumProperty( + items=lambda self, context: game_data.z64.get_enum("actor_cue_list_cmd_type"), + name="CS Actor Cue Command Type", + default=1, + ) commandTypeCustom: StringProperty(name="CS Actor Cue Command Type Custom") actorCueListToPreview: PointerProperty( type=Object, name="", poll=lambda self, object: self.isActorCueListObj(object, "CS Actor Cue List") diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index cd469725a..cf3390f35 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -1,7 +1,15 @@ import bpy from bpy.types import PropertyGroup, Object, UILayout, Scene, Context -from bpy.props import StringProperty, EnumProperty, IntProperty, BoolProperty, CollectionProperty, PointerProperty +from bpy.props import ( + StringProperty, + EnumProperty, + IntProperty, + BoolProperty, + CollectionProperty, + PointerProperty, + FloatVectorProperty, +) from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName @@ -93,6 +101,10 @@ def draw_props( "csSeqPlayer", "rumble_type", "transition_type", + "blur_type", + "trans_general_type", + "credits_scene_type", + "mod_seq_type", ] value = getattr(self, p) if name in customValues and value == "Custom": @@ -209,6 +221,51 @@ class OOTCSTransitionProperty(OOTCutsceneCommon, PropertyGroup): transition_type_custom: StringProperty("CS_TRANS_CUSTOM") +class OOTCSMotionBlurProperty(OOTCutsceneCommon, PropertyGroup): + attrName = "motion_blur_list" + subprops = ["blur_type", "startFrame", "endFrame"] + + blur_type: EnumProperty(name="", items=lambda self, context: game_data.z64.get_enum("blur_type"), default=1) + blur_type_custom: StringProperty("CS_TRANS_CUSTOM") + + +class OOTCSTransitionGeneralProperty(OOTCutsceneCommon, PropertyGroup): + attrName = "trans_general_list" + subprops = ["trans_general_type", "startFrame", "endFrame", "trans_color"] + + trans_general_type: EnumProperty( + name="", items=lambda self, context: game_data.z64.get_enum("trans_general"), default=1 + ) + trans_general_type_custom: StringProperty("CS_TRANS_GENERAL_CUSTOM") + + trans_color: FloatVectorProperty( + name="Color", + subtype="COLOR", + size=4, + min=0, + max=1, + default=(1, 1, 1, 1), + ) + + +class OOTCSChooseCreditsSceneProperty(OOTCutsceneCommon, PropertyGroup): + attrName = "credits_scene_list" + subprops = ["credits_scene_type", "startFrame"] + + credits_scene_type: EnumProperty( + name="", items=lambda self, context: game_data.z64.get_enum("credits_scene_type"), default=1 + ) + credits_scene_type_custom: StringProperty("CS_CREDITS_CUSTOM") + + +class OOTCSModifySeqProperty(OOTCutsceneCommon, PropertyGroup): + attrName = "mod_seq_list" + subprops = ["mod_seq_type", "startFrame"] + + mod_seq_type: EnumProperty(name="", items=lambda self, context: game_data.z64.get_enum("mod_seq_type"), default=1) + mod_seq_type_custom: StringProperty("CS_MOD_SEQ_CUSTOM") + + class OOTCSListProperty(PropertyGroup): expandTab: BoolProperty(default=True) @@ -220,6 +277,10 @@ class OOTCSListProperty(PropertyGroup): miscList: CollectionProperty(type=OOTCSMiscProperty) rumbleList: CollectionProperty(type=OOTCSRumbleProperty) transition_list: CollectionProperty(type=OOTCSTransitionProperty) + motion_blur_list: CollectionProperty(type=OOTCSMotionBlurProperty) + trans_general_list: CollectionProperty(type=OOTCSTransitionGeneralProperty) + credits_scene_list: CollectionProperty(type=OOTCSChooseCreditsSceneProperty) + mod_seq_list: CollectionProperty(type=OOTCSModifySeqProperty) def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionType: str): box = layout.box().column() @@ -254,6 +315,14 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT attrName = "miscList" elif self.listType == "RumbleList": attrName = "rumbleList" + elif self.listType == "MotionBlurList": + attrName = "motion_blur_list" + elif self.listType == "TransitionGeneralList": + attrName = "trans_general_list" + elif self.listType == "CreditsSceneList": + attrName = "credits_scene_list" + elif self.listType == "ModifySeqList": + attrName = "mod_seq_list" else: raise PluginError("Internal error: invalid listType " + self.listType) @@ -374,6 +443,8 @@ class OOTCutsceneProperty(PropertyGroup): ) csDestinationCustom: StringProperty(default="CS_DEST_CUSTOM") csDestinationStartFrame: IntProperty(name="Start Frame", min=0, default=99) + cs_give_tatl: BoolProperty(name="Give Tatl") + cs_give_tatl_start_frame: IntProperty(name="Start Frame", min=0, default=99) csLists: CollectionProperty(type=OOTCSListProperty, name="Cutscene Lists") menuTab: EnumProperty(items=lambda self, context: game_data.z64.get_enum("cs_list_type")) @@ -447,6 +518,11 @@ def draw_props(self, layout: UILayout, obj: Object): if self.csDestination == "Custom": prop_split(layout_custom.column(), self, "csDestinationCustom", "Cutscene Destination Custom") + b = commandsBox.box() + b.prop(self, "cs_give_tatl") + if self.cs_give_tatl: + b.prop(self, "cs_give_tatl_start_frame") + commandsBox.column_flow(columns=3, align=True).prop(self, "menuTab", expand=True) label = f"Add New {ootCSSubPropToName[self.menuTab]}" op = commandsBox.operator(OOTCSListAdd.bl_idname, text=label, icon=csListTypeToIcon[self.menuTab]) @@ -468,6 +544,10 @@ def draw_props(self, layout: UILayout, obj: Object): OOTCSMiscProperty, OOTCSRumbleProperty, OOTCSTransitionProperty, + OOTCSMotionBlurProperty, + OOTCSTransitionGeneralProperty, + OOTCSChooseCreditsSceneProperty, + OOTCSModifySeqProperty, OOTCSListProperty, OOTCutsceneTransitionProperty, OOTCutsceneMiscProperty, From bc42a1323ee3e5c82c6d965a52062b5d4ced5ddc Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 10 Jan 2025 03:23:56 +0100 Subject: [PATCH 084/126] implement cs camera export --- .gitignore | 3 + fast64_internal/data/z64/data.py | 1 + .../z64/cutscene/motion/properties.py | 28 ++-- fast64_internal/z64/cutscene/properties.py | 29 +++- .../z64/exporter/cutscene/__init__.py | 120 ++++++++++++--- .../z64/exporter/cutscene/camera.py | 133 ++++++++++++++++ fast64_internal/z64/exporter/cutscene/data.py | 142 +++++++++++++----- fast64_internal/z64/exporter/room/header.py | 3 + .../z64/exporter/scene/__init__.py | 10 +- .../z64/exporter/scene/actor_cutscene.py | 5 +- .../z64/exporter/scene/animated_mats.py | 5 +- fast64_internal/z64/exporter/scene/general.py | 3 + fast64_internal/z64/exporter/scene/header.py | 20 ++- fast64_internal/z64/scene/properties.py | 3 - 14 files changed, 412 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index 0cb2f6e73..6c84a5c69 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ __pycache__/ fast64_updater/ .python-version .idea + +# temp? just exporting my stuff in my fast64 clone because reasons +export/ diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 4c2ea7531..450d4179c 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -636,6 +636,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = "transitionType": self.enums.enum_cs_transition_type, "actor_cue_list_cmd_type": self.enums.enum_cs_actor_cue_list_cmd_type, "spline_interp_type": self.enums.enum_cs_spline_interp_type, + "spline_rel_to": self.enums.enum_cs_spline_rel, "trans_general": self.enums.enum_cs_transition_general, "blur_type": self.enums.enum_cs_motion_blur_type, "credits_scene_type": self.enums.enum_cs_credits_scene_type, diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 4c5f363d8..af30f5704 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ....utility import prop_split from ...upgrade import upgradeCutsceneMotion -from ...utility import getEnumName, prop_split +from ...utility import getEnumName, is_oot_features from ....game_data import game_data from ..constants import ootEnumCSMotionCamMode @@ -149,14 +149,15 @@ class CutsceneCmdCameraShotProperty(PropertyGroup): default="splineEyeOrAT", ) - shot_spline_rel_to: EnumProperty(items=game_data.z64.enums.enum_cs_spline_rel, default=1) + shot_duration: IntProperty(min=0, default=120) + shot_spline_rel_to: EnumProperty(items=lambda self, context: game_data.z64.get_enum("spline_rel_to"), default=1) shot_spline_rel_to_custom: StringProperty(default="CS_CAM_REL_CUSTOM") shot_interp_type: EnumProperty( items=lambda self, context: game_data.z64.get_enum("spline_interp_type"), name="Interpolation Type", description="values 1-3 only uses a single point from the cmd, values 4-5 uses multiple points from the cmd, value 6 only uses a single point from the cmd", - default=4, + default=5, ) shot_interp_type_custom: StringProperty(default="CS_CAM_INTERP_CUSTOM") @@ -176,19 +177,21 @@ def draw_props(self, layout: UILayout, label: str): box = layout.box() box.label(text=label) - split = box.split(factor=0.5) - split.prop(self, "shotStartFrame") - split.prop(self, "shotEndFrame") if game_data.z64.is_oot(): + split = box.split(factor=0.5) + split.prop(self, "shotStartFrame") + split.prop(self, "shotEndFrame") box.row().prop(self, "shotCamMode", expand=True) else: - prop_split(box.row(), self, "shot_spline_rel_to", "Camera Relative To") + layout_shot = box.column() + prop_split(layout_shot, self, "shot_duration", "Duration") + prop_split(layout_shot, self, "shot_spline_rel_to", "Camera Relative To") if self.shot_spline_rel_to == "Custom": - prop_split(box.row(), self, "shot_spline_rel_to_custom", "") + prop_split(layout_shot, self, "shot_spline_rel_to_custom", "") - prop_split(box.row(), self, "shot_interp_type", "Camera Interpolation Type") + prop_split(layout_shot, self, "shot_interp_type", "Camera Interpolation Type") if self.shot_interp_type == "Custom": - prop_split(box.row(), self, "shot_interp_type_custom", "") + prop_split(layout_shot, self, "shot_interp_type_custom", "") box.operator(CutsceneCmdAddBone.bl_idname) @@ -222,6 +225,8 @@ class CutsceneCmdCameraShotPointProperty(PropertyGroup): set=lambda self, value: self.setValue(value, "roll"), ) + shot_point_duration: IntProperty(min=0, default=30, name="Duration") + # internal usage only frame: IntProperty(default=30, min=0) viewAngle: FloatProperty(default=60.0, min=0.01, max=179.99) @@ -252,7 +257,8 @@ def draw_props(self, layout: UILayout): box = layout.box() box.label(text="Bone / Key point:") row = box.row() - for propName in ["shotPointFrame", "shotPointViewAngle", "shotPointRoll"]: + first_prop = "shotPointFrame" if is_oot_features() else "shot_point_duration" + for propName in [first_prop, "shotPointViewAngle", "shotPointRoll"]: row.prop(self, propName) diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index cf3390f35..c1abd9c4a 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -12,7 +12,7 @@ ) from bpy.utils import register_class, unregister_class from ...utility import PluginError, prop_split -from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName +from ..utility import OOTCollectionAdd, drawCollectionOps, getEnumName, is_oot_features from ...game_data import game_data from ..upgrade import upgradeCutsceneSubProps, upgradeCSListProps, upgradeCutsceneProperty from .operators import OOTCSTextAdd, OOT_SearchCSDestinationEnumOperator, OOTCSListAdd, OOT_SearchCSSeqOperator @@ -446,8 +446,21 @@ class OOTCutsceneProperty(PropertyGroup): cs_give_tatl: BoolProperty(name="Give Tatl") cs_give_tatl_start_frame: IntProperty(name="Start Frame", min=0, default=99) csLists: CollectionProperty(type=OOTCSListProperty, name="Cutscene Lists") - menuTab: EnumProperty(items=lambda self, context: game_data.z64.get_enum("cs_list_type")) + next_entrance: StringProperty(default="0xFFFF") + play_on_spawn: IntProperty(min=0, default=0) + spawn_flag_type: EnumProperty( + items=[ + ("Custom", "Custom", "Custom"), + ("CS_SPAWN_FLAG_NONE", "None", "None"), + ("CS_SPAWN_FLAG_ALWAYS", "Always", "Always"), + ("CS_SPAWN_FLAG_ONCE", "Flag", "Flag"), + ], + default=2, + ) + spawn_flag: StringProperty(default="0x00") + spawn_flags_custom: StringProperty(default="CS_SPAWN_FLAG_CUSTOM") + menuTab: EnumProperty(items=lambda self, context: game_data.z64.get_enum("cs_list_type")) preview: PointerProperty(type=OOTCutscenePreviewProperty) @staticmethod @@ -484,6 +497,7 @@ def upgrade_object(obj): del csListProp["transitionEndFrame"] def draw_props(self, layout: UILayout, obj: Object): + layout = layout.column() split = layout.split(factor=0.5) split.operator(CutsceneCmdCreateCameraShot.bl_idname, icon="VIEW_CAMERA") split.operator(CutsceneCmdPlayPreview.bl_idname, icon="RESTRICT_VIEW_OFF") @@ -496,6 +510,17 @@ def draw_props(self, layout: UILayout, obj: Object): split.label(text="Cutscene End Frame") split.prop(self, "csEndFrame") + if game_data.z64.is_mm() or not is_oot_features(): + prop_split(layout, self, "next_entrance", "Next Entrance") + prop_split(layout, self, "play_on_spawn", "Spawn") + prop_split(layout, self, "spawn_flag_type", "Spawn Flags") + + if self.spawn_flag_type == "Custom": + prop_split(layout, self, "spawn_flags_custom", "") + + if self.spawn_flag_type == "CS_SPAWN_FLAG_ONCE": + prop_split(layout, self, "spawn_flag", "") + commandsBox = layout.box() commandsBox.box().label(text="Cutscene Commands") diff --git a/fast64_internal/z64/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py index 8303e2d45..85846fa4c 100644 --- a/fast64_internal/z64/exporter/cutscene/__init__.py +++ b/fast64_internal/z64/exporter/cutscene/__init__.py @@ -1,13 +1,17 @@ import bpy from dataclasses import dataclass, field -from typing import Optional +from typing import Optional, TYPE_CHECKING from bpy.types import Object +from ....game_data import game_data from ....utility import PluginError, CData, indent -from ...utility import getCustomProperty +from ...utility import getCustomProperty, is_oot_features from ...scene.properties import Z64_SceneHeaderProperty from .data import CutsceneData +if TYPE_CHECKING: + from ...cutscene.properties import OOTCutsceneProperty + # NOTE: ``paramNumber`` is the expected number of parameters inside the parsed commands, # this account for the unused parameters. Every classes are based on the commands arguments from ``z64cutscene_commands.h`` @@ -26,6 +30,9 @@ class Cutscene: frameCount: int useMacros: bool motionOnly: bool + next_entrance: Optional[str] + spawn: Optional[int] + spawn_flags: Optional[str] paramNumber: int = field(init=False, default=2) @@ -35,8 +42,30 @@ def new(name: Optional[str], csObj: Optional[Object], useMacros: bool, motionOnl if csObj is not None: if name is None: name = csObj.name.removeprefix("Cutscene.").replace(".", "_") + + cs_prop: "OOTCutsceneProperty" = csObj.ootCutsceneProperty + if cs_prop.spawn_flag_type == "Custom": + spawn_flag: str = cs_prop.spawn_flags_custom + elif cs_prop.spawn_flag_type == "CS_SPAWN_FLAG_ONCE": + spawn_flag: str = f"CS_SPAWN_FLAG_ONCE({cs_prop.spawn_flag})" + else: + spawn_flag: str = cs_prop.spawn_flag_type + data = CutsceneData.new(csObj, useMacros, motionOnly) - return Cutscene(name, data, data.totalEntries, data.frameCount, useMacros, motionOnly) + return Cutscene( + name, + data, + data.totalEntries, + data.frameCount, + useMacros, + motionOnly, + cs_prop.next_entrance if game_data.z64.is_mm() or not is_oot_features() else None, + cs_prop.play_on_spawn if game_data.z64.is_mm() or not is_oot_features() else None, + spawn_flag if game_data.z64.is_mm() or not is_oot_features() else None, + ) + + def get_entry(self): + return "{ " + f"{self.name}, {self.next_entrance}, {self.spawn}, {self.spawn_flags}" + " }" def getC(self): """Returns the cutscene data""" @@ -49,27 +78,41 @@ def getC(self): dataListNames = [] if not self.motionOnly: - dataListNames = [ - "textList", - "miscList", - "rumbleList", - "transitionList", - "lightSettingsList", - "timeList", - "seqList", - "fadeSeqList", - ] + dataListNames.extend( + [ + "textList", + "miscList", + "rumbleList", + "transitionList", + "lightSettingsList", + "timeList", + "seqList", + "fadeSeqList", + ] + ) + + if is_oot_features(): + dataListNames.extend( + [ + "camEyeSplineList", + "camATSplineList", + "camEyeSplineRelPlayerList", + "camATSplineRelPlayerList", + "camEyeList", + "camATList", + ] + ) + else: + dataListNames.extend( + [ + "camSplineList", + ] + ) dataListNames.extend( [ "playerCueList", "actorCueList", - "camEyeSplineList", - "camATSplineList", - "camEyeSplineRelPlayerList", - "camATSplineRelPlayerList", - "camEyeList", - "camATList", ] ) @@ -80,13 +123,20 @@ def getC(self): csData.header = f"extern {declarationBase};\n" # .c + if game_data.z64.is_mm(): + cs_header = "CS_BEGIN_CUTSCENE" + cs_end = "CS_END" + else: + cs_header = "CS_HEADER" + cs_end = "CS_END_OF_SCRIPT" + csData.source = ( declarationBase + " = {\n" - + (indent + f"CS_HEADER({self.totalEntries}, {self.frameCount}),\n") + + (indent + f"{cs_header}({self.totalEntries}, {self.frameCount}),\n") + (self.data.destination.getCmd() if self.data.destination is not None else "") + "".join(entry.getCmd() for curList in dataListNames for entry in getattr(self.data, curList)) - + (indent + "CS_END_OF_SCRIPT(),\n") + + (indent + f"{cs_end}(),\n") + "};\n\n" ) @@ -99,10 +149,11 @@ def getC(self): class SceneCutscene: """This class hosts cutscene data""" + name: str entries: list[Cutscene] @staticmethod - def new(props: Z64_SceneHeaderProperty, headerIndex: int, useMacros: bool): + def new(name: str, props: Z64_SceneHeaderProperty, headerIndex: int, useMacros: bool): csObj: Object = props.csWriteObject cutsceneObjects: list[Object] = [csObj for csObj in props.extraCutscenes] entries: list[Cutscene] = [] @@ -130,12 +181,31 @@ def new(props: Z64_SceneHeaderProperty, headerIndex: int, useMacros: bool): entries.append( Cutscene.new(csWriteCustom, csObj, useMacros, bpy.context.scene.fast64.oot.exportMotionOnly) ) - return SceneCutscene(entries) + return SceneCutscene(name, entries) + + def to_c(self): + """Returns the cutscene script entry list (for MM)""" + + data = CData() + array_name = f"CutsceneScriptEntry {self.name}[]" + + # .h + data.header = f"extern {array_name};" + + # .c + data.source = ( + array_name + " = {\n" + indent + f",\n{indent}".join(cs.get_entry() for cs in self.entries) + "\n};\n\n" + ) + + return data def getCmd(self): """Returns the cutscene data scene command""" if len(self.entries) == 0: raise PluginError("ERROR: Cutscene entry list is empty!") - # entry No. 0 is always self.csObj - return indent + f"SCENE_CMD_CUTSCENE_DATA({self.entries[0].name}),\n" + if is_oot_features(): + # entry No. 0 is always self.csObj + return indent + f"SCENE_CMD_CUTSCENE_DATA({self.entries[0].name}),\n" + else: + return indent + f"SCENE_CMD_CUTSCENE_SCRIPT_LIST({len(self.entries)}, {self.name}),\n" diff --git a/fast64_internal/z64/exporter/cutscene/camera.py b/fast64_internal/z64/exporter/cutscene/camera.py index fa9ddc469..90d469d24 100644 --- a/fast64_internal/z64/exporter/cutscene/camera.py +++ b/fast64_internal/z64/exporter/cutscene/camera.py @@ -1,4 +1,5 @@ from dataclasses import dataclass, field +from typing import Optional from ....utility import PluginError, indent from ...cutscene.motion.utility import getInteger from .common import CutsceneCmdBase @@ -155,3 +156,135 @@ def from_params(params: list[str]): def getCmd(self): return self.getCamListCmd("CS_CAM_AT", self.startFrame, self.endFrame) + + +# MM's new camera commands + + +@dataclass +class CutsceneCmdNewCamPoint: + """This class contains a single Camera Point command data (the newer version)""" + + interp_type: str + weight: int + duration: int + pos: list[int] + relative_to: str + + paramNumber: int = field(init=False, default=7) + size: int = field(init=False, default=0xC) + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdNewCamPoint( + params[0], + getInteger(params[1]), + getInteger(params[2]), + [getInteger(params[3]), getInteger(params[4]), getInteger(params[5])], + params[6], + ) + + def to_c(self): + return ( + indent * 4 + + "CS_CAM_POINT(" + + f"{self.interp_type}, " + + f"{self.weight}, " + + f"{self.duration}, " + + f"{self.pos[0]}, {self.pos[1]}, {self.pos[2]}, " + + f"{self.relative_to}" + + "),\n" + ) + + +@dataclass +class CutsceneCmdCamMisc: + """This class contains the Camera Misc data""" + + camRoll: int + viewAngle: float + + paramNumber: int = field(init=False, default=4) + size: int = field(init=False, default=0x8) + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdCamMisc(getInteger(params[1]), getInteger(params[2])) + + def to_c(self): + return indent * 4 + f"CS_CAM_MISC(0, {self.camRoll}, {self.viewAngle}, 0),\n" + + +@dataclass +class CutsceneSplinePoint: + # this is not a real command but it helps as each camera point is made of one at, one eye and one misc + at: CutsceneCmdNewCamPoint + eye: CutsceneCmdNewCamPoint + misc: CutsceneCmdCamMisc + size = 0x20 + + +@dataclass +class CutsceneCmdCamSpline: + """This class contains the Camera Spline data""" + + num_entries: int + duration: int + entries: list[CutsceneSplinePoint] = field(init=False, default_factory=list) + + paramNumber: int = field(init=False, default=4) + size: int = field(init=False, default=0x8) + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdCamSpline(getInteger(params[0]), getInteger(params[3])) + + def to_c(self): + at_list: list[str] = [] + eye_list: list[str] = [] + misc_list: list[str] = [] + + for entry in self.entries: + at_list.append(entry.at.to_c()) + eye_list.append(entry.eye.to_c()) + misc_list.append(entry.misc.to_c()) + + return ( + (indent * 3 + f"CS_CAM_SPLINE({len(self.entries)}, 0, 0, {self.duration}),\n") + + "".join(at for at in at_list) + + "".join(eye for eye in eye_list) + + "".join(misc for misc in misc_list) + ) + + +@dataclass +class CutsceneCmdCamSplineList: + """This class contains the Camera Spline list data""" + + num_bytes: int + entries: list[CutsceneCmdCamSpline] = field(init=False, default_factory=list) + + paramNumber: int = 1 + listName: str = "camSplineListNew" + size: int = 0x8 + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdCamSplineList(getInteger(params[0])) + + def getCmd(self): + data = "" + num_bytes = 0 + + for entry in self.entries: + data += entry.to_c() + num_bytes += entry.size + + for item in entry.entries: + num_bytes += item.size + + return ( + (indent * 2 + f"CS_CAM_SPLINE_LIST({num_bytes}),\n") + + "".join(entry.to_c() for entry in self.entries) + + (indent * 2 + "CS_CAM_END(),\n") + ) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 560a03d01..e20d88e92 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -2,10 +2,11 @@ import math from dataclasses import dataclass, field -from typing import TYPE_CHECKING +from typing import Optional, TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError from ....game_data import game_data +from ...utility import is_oot_features from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction @@ -31,6 +32,11 @@ CutsceneCmdCamATSplineRelToPlayer, CutsceneCmdCamEye, CutsceneCmdCamAT, + CutsceneCmdNewCamPoint, + CutsceneCmdCamMisc, + CutsceneSplinePoint, + CutsceneCmdCamSpline, + CutsceneCmdCamSplineList, ) if TYPE_CHECKING: @@ -61,34 +67,44 @@ } -@dataclass class CutsceneData: """This class defines the command data inside a cutscene""" - useMacros: bool - motionOnly: bool - - totalEntries: int = field(init=False, default=0) - frameCount: int = field(init=False, default=0) - motionFrameCount: int = field(init=False, default=0) - camEndFrame: int = field(init=False, default=0) - destination: CutsceneCmdDestination = field(init=False, default=None) - actorCueList: list[CutsceneCmdActorCueList] = field(init=False, default_factory=list) - playerCueList: list[CutsceneCmdActorCueList] = field(init=False, default_factory=list) - camEyeSplineList: list[CutsceneCmdCamEyeSpline] = field(init=False, default_factory=list) - camATSplineList: list[CutsceneCmdCamATSpline] = field(init=False, default_factory=list) - camEyeSplineRelPlayerList: list[CutsceneCmdCamEyeSplineRelToPlayer] = field(init=False, default_factory=list) - camATSplineRelPlayerList: list[CutsceneCmdCamATSplineRelToPlayer] = field(init=False, default_factory=list) - camEyeList: list[CutsceneCmdCamEye] = field(init=False, default_factory=list) - camATList: list[CutsceneCmdCamAT] = field(init=False, default_factory=list) - textList: list[CutsceneCmdTextList] = field(init=False, default_factory=list) - miscList: list[CutsceneCmdMiscList] = field(init=False, default_factory=list) - rumbleList: list[CutsceneCmdRumbleControllerList] = field(init=False, default_factory=list) - transitionList: list[CutsceneCmdTransition] = field(init=False, default_factory=list) - lightSettingsList: list[CutsceneCmdLightSettingList] = field(init=False, default_factory=list) - timeList: list[CutsceneCmdTimeList] = field(init=False, default_factory=list) - seqList: list[CutsceneCmdStartStopSeqList] = field(init=False, default_factory=list) - fadeSeqList: list[CutsceneCmdFadeSeqList] = field(init=False, default_factory=list) + def __init__(self, useMacros: bool, motionOnly: bool): + self.useMacros = useMacros + self.motionOnly = motionOnly + + self.totalEntries: int = 0 + self.frameCount: int = 0 + self.motionFrameCount: int = 0 + self.camEndFrame: int = 0 + self.destination: Optional[CutsceneCmdDestination] = None + self.actorCueList: list[CutsceneCmdActorCueList] = [] + self.playerCueList: list[CutsceneCmdActorCueList] = [] + self.camEyeSplineList: list[CutsceneCmdCamEyeSpline] = [] + self.camATSplineList: list[CutsceneCmdCamATSpline] = [] + self.camEyeSplineRelPlayerList: list[CutsceneCmdCamEyeSplineRelToPlayer] = [] + self.camATSplineRelPlayerList: list[CutsceneCmdCamATSplineRelToPlayer] = [] + self.camEyeList: list[CutsceneCmdCamEye] = [] + self.camATList: list[CutsceneCmdCamAT] = [] + self.textList: list[CutsceneCmdTextList] = [] + self.miscList: list[CutsceneCmdMiscList] = [] + self.rumbleList: list[CutsceneCmdRumbleControllerList] = [] + self.transitionList: list[CutsceneCmdTransition] = [] + self.lightSettingsList: list[CutsceneCmdLightSettingList] = [] + self.timeList: list[CutsceneCmdTimeList] = [] + self.seqList: list[CutsceneCmdStartStopSeqList] = [] + self.fadeSeqList: list[CutsceneCmdFadeSeqList] = [] + + # lists from the new cutscene system + self.camSplineList: list[CutsceneCmdCamSplineList] = [] + # self.transitionListNew: list[CutsceneCmdTransitionList] = [] + # self.destinationListNew: list[CutsceneCmdDestinationList] = [] + # self.motionBlurList: list[CutsceneCmdMotionBlurList] = [] + # self.modifySeqList: list[CutsceneCmdModifySeqList] = [] + # self.creditsSceneList: list[CutsceneCmdChooseCreditsScenesList] = [] + # self.transitionGeneralList: list[CutsceneCmdTransitionGeneralList] = [] + # self.giveTatlList: list[CutsceneCmdGiveTatlList] = [] @staticmethod def new(csObj: Object, useMacros: bool, motionOnly: bool): @@ -142,9 +158,10 @@ def getOoTPosition(self, pos): return [x, y, z] - def getEnumValueFromProp(self, enumKey: str, owner, propName: str): + def getEnumValueFromProp(self, enumKey: str, owner, propName: str, custom_suffix: str = "Custom"): + game_data.z64.update(bpy.context, None) item = game_data.z64.enums.enumByKey[enumKey].item_by_key.get(getattr(owner, propName)) - return item.id if item is not None else getattr(owner, f"{propName}Custom") + return item.id if item is not None else getattr(owner, f"{propName}{custom_suffix}") def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool): """Returns the Actor Cue List commands from the corresponding objects""" @@ -289,19 +306,66 @@ def setCameraShotData(self, csObjects: dict[str, list[Object]]): shotObjects = csObjects["camShot"] if len(shotObjects) > 0: - motionFrameCount = -1 - for shotObj in shotObjects: - camMode = shotObj.data.ootCamShotProp.shotCamMode - - eyeCamList = getattr(self, self.getCamClassOrList(False, camMode, False)) - eyeCamList.append(self.getNewCamData(shotObj, False)) + if is_oot_features(): + motionFrameCount = -1 + for shotObj in shotObjects: + camMode = shotObj.data.ootCamShotProp.shotCamMode + + eyeCamList = getattr(self, self.getCamClassOrList(False, camMode, False)) + eyeCamList.append(self.getNewCamData(shotObj, False)) + + atCamList = getattr(self, self.getCamClassOrList(False, camMode, True)) + atCamList.append(self.getNewCamData(shotObj, True)) + + motionFrameCount = max(motionFrameCount, self.camEndFrame + 1) + self.motionFrameCount += motionFrameCount + self.totalEntries += len(shotObjects) * 2 + else: + new_spline_list = CutsceneCmdCamSplineList(0) # bytes are computed when getting the c data + + for shot_obj in shotObjects: + shot_prop = shot_obj.data.ootCamShotProp + new_spline = CutsceneCmdCamSpline(0, shot_prop.shot_duration) + + for i, bone in enumerate(shot_obj.data.bones): + bone_prop = bone.ootCamShotPointProp + + new_spline.entries.append( + CutsceneSplinePoint( + # At + CutsceneCmdNewCamPoint( + self.getEnumValueFromProp( + "cs_spline_interp_type", shot_prop, "shot_interp_type", "_custom" + ), + 0x64, + bone_prop.shot_point_duration, + self.getOoTPosition(bone.tail), + self.getEnumValueFromProp( + "cs_spline_rel", shot_prop, "shot_spline_rel_to", "_custom" + ), + ), + # Eye + CutsceneCmdNewCamPoint( + self.getEnumValueFromProp( + "cs_spline_interp_type", shot_prop, "shot_interp_type", "_custom" + ), + 0x64, + bone_prop.shot_point_duration, + self.getOoTPosition(bone.head), + self.getEnumValueFromProp( + "cs_spline_rel", shot_prop, "shot_spline_rel_to", "_custom" + ), + ), + # Misc + CutsceneCmdCamMisc(bone_prop.shotPointRoll, bone_prop.shotPointViewAngle), + ) + ) - atCamList = getattr(self, self.getCamClassOrList(False, camMode, True)) - atCamList.append(self.getNewCamData(shotObj, True)) + new_spline.num_entries = i + new_spline_list.entries.append(new_spline) - motionFrameCount = max(motionFrameCount, self.camEndFrame + 1) - self.motionFrameCount += motionFrameCount - self.totalEntries += len(shotObjects) * 2 + self.camSplineList.append(new_spline_list) + self.totalEntries += 1 def getNewTextCmd(self, textEntry: "OOTCSTextProperty"): match textEntry.textboxType: diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 6d4f71fe5..42a453c17 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -1,3 +1,5 @@ +import bpy + from dataclasses import dataclass, field from typing import Optional from mathutils import Matrix @@ -189,6 +191,7 @@ def new( headerIndex: int, room_index: int, ): + game_data.z64.update(bpy.context, None) actorList: list[Actor] = [] actorObjList = getObjectList(sceneObj.children, "EMPTY", "Actor", parentObj=roomObj, room_index=room_index) for obj in actorObjList: diff --git a/fast64_internal/z64/exporter/scene/__init__.py b/fast64_internal/z64/exporter/scene/__init__.py index f73dab81d..6f8ce52d3 100644 --- a/fast64_internal/z64/exporter/scene/__init__.py +++ b/fast64_internal/z64/exporter/scene/__init__.py @@ -57,7 +57,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, useMacros: bool, saveTex continue try: setattr( - altHeader, header, SceneHeader.new(f"{name}_header{i:02}", altP, sceneObj, transform, i, useMacros) + altHeader, + header, + SceneHeader.new(f"{name}_header{i:02}", altP, sceneObj, transform, i, useMacros), ) hasAlternateHeaders = True except Exception as exc: @@ -137,9 +139,9 @@ def getCmdList(self, curHeader: SceneHeader, hasAltHeaders: bool): + curHeader.entranceActors.getCmd() + (curHeader.exits.getCmd() if len(curHeader.exits.exitList) > 0 else "") + (curHeader.cutscene.getCmd() if len(curHeader.cutscene.entries) > 0 else "") - + (curHeader.map_data.get_cmds() if not is_oot_features() and curHeader.map_data is not None else "") - + (curHeader.anim_mat.get_cmd() if not is_oot_features() and curHeader.anim_mat is not None else "") - + (curHeader.actor_cs.get_cmds() if not is_oot_features() and curHeader.actor_cs is not None else "") + + (curHeader.map_data.get_cmds() if curHeader.map_data is not None and curHeader.map_data.is_used() else "") + + (curHeader.anim_mat.get_cmd() if curHeader.anim_mat is not None and curHeader.anim_mat.is_used() else "") + + (curHeader.actor_cs.get_cmds() if curHeader.actor_cs is not None and curHeader.actor_cs.is_used() else "") + Utility.getEndCmd() + "};\n\n" ) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index 2b2a6ed1e..ca7a85c16 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -3,7 +3,7 @@ from mathutils import Matrix from typing import Optional from ....utility import CData, PluginError, exportColor, scaleToU8, indent -from ...utility import getObjectList +from ...utility import getObjectList, is_oot_features from ...actor_cutscene.properties import Z64_ActorCutsceneProperty, Z64_ActorCutscene from ..utility import Utility from ..collision.camera import BgCamInformations, CameraInfo @@ -120,6 +120,9 @@ def new(name: str, scene_obj: Object, transform: Matrix, header_index: int): return SceneActorCutscene(name, f"{name}CameraInfo", f"{name}CameraData", header_index, entries) + def is_used(self): + return not is_oot_features() and len(self.entries) > 0 + def is_cs_cam_used(self): for entry in self.entries: if entry.cam_info is not None: diff --git a/fast64_internal/z64/exporter/scene/animated_mats.py b/fast64_internal/z64/exporter/scene/animated_mats.py index 1a718adde..f8839a30b 100644 --- a/fast64_internal/z64/exporter/scene/animated_mats.py +++ b/fast64_internal/z64/exporter/scene/animated_mats.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from bpy.types import Object from ....utility import CData, PluginError, exportColor, scaleToU8, indent -from ...utility import getObjectList +from ...utility import getObjectList, is_oot_features from ...animated_mats.properties import ( Z64_AnimatedMatColorParams, Z64_AnimatedMatTexScrollParams, @@ -285,6 +285,9 @@ def new(name: str, scene_obj: Object, header_index: int): return SceneAnimatedMaterial(name, header_index, entries) + def is_used(self): + return not is_oot_features() and len(self.entries) > 0 + def get_cmd(self): """Returns the sound settings, misc settings, special files and skybox settings scene commands""" diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 00f0e813c..168c6bf71 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -336,6 +336,9 @@ def new(name: str, props: Z64_SceneHeaderProperty, scene_obj: Object, transform: [MapDataChest(chest_prop, scene_obj, transform) for chest_prop in props.minimap_chest_list], ) + def is_used(self): + return not is_oot_features() and (len(self.room_list) > 0 or len(self.chest_list) > 0) + def get_cmds(self): """Returns the sound settings, misc settings, special files and skybox settings scene commands""" commands = [] diff --git a/fast64_internal/z64/exporter/scene/header.py b/fast64_internal/z64/exporter/scene/header.py index 02c4a2570..accd94302 100644 --- a/fast64_internal/z64/exporter/scene/header.py +++ b/fast64_internal/z64/exporter/scene/header.py @@ -46,7 +46,7 @@ def new( name, SceneInfos.new(props, sceneObj), SceneLighting.new(f"{name}_lightSettings", props), - SceneCutscene.new(props, headerIndex, useMacros), + SceneCutscene.new(f"{name}_cutsceneScriptEntryList", props, headerIndex, useMacros), SceneExits.new(f"{name}_exitList", props), SceneTransitionActors.new(f"{name}_transitionActors", sceneObj, transform, headerIndex), entranceActors, @@ -66,16 +66,20 @@ def getC(self): headerData = CData() + # Write the cutscene script entry list, if used + if not is_oot_features() and len(self.cutscene.entries) > 0: + headerData.append(self.cutscene.to_c()) + # Write the spawn position list data and the entrance list if len(self.entranceActors.entries) > 0: headerData.append(self.entranceActors.getC()) headerData.append(self.spawns.getC()) - # Write the transition actor list data + # Write the transition actor list data, if used if len(self.transitionActors.entries) > 0: headerData.append(self.transitionActors.getC()) - # Write the exit list + # Write the exit list, if used if len(self.exits.exitList) > 0: headerData.append(self.exits.getC()) @@ -83,18 +87,20 @@ def getC(self): if len(self.lighting.settings) > 0: headerData.append(self.lighting.getC()) - # Write the map data - if not is_oot_features() and self.map_data is not None: + # Write the map data, if used + if self.map_data is not None and self.map_data.is_used(): headerData.append(self.map_data.to_c()) # Write the path data, if used if len(self.path.pathList) > 0: headerData.append(self.path.getC()) - if not is_oot_features() and self.anim_mat is not None: + # Write the animated material list, if used + if self.anim_mat is not None and self.anim_mat.is_used(): headerData.append(self.anim_mat.to_c()) - if not is_oot_features() and self.actor_cs is not None: + # Write the actor cutscene list, if used + if self.actor_cs is not None and self.actor_cs.is_used(): headerData.append(self.actor_cs.to_c()) return headerData diff --git a/fast64_internal/z64/scene/properties.py b/fast64_internal/z64/scene/properties.py index 5a92e939c..726616ae7 100644 --- a/fast64_internal/z64/scene/properties.py +++ b/fast64_internal/z64/scene/properties.py @@ -522,9 +522,6 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj elif menuTab == "Cutscene": cutscene = layout.column() - - cutscene.enabled = is_oot_features() - r = cutscene.row() r.prop(self, "writeCutscene", text="Write Cutscene") if self.writeCutscene: From e651c0c64d8ce3fbd6f60539e52bccc9493b7226 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:03:40 +0100 Subject: [PATCH 085/126] =?UTF-8?q?progress=E2=84=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fast64_internal/data/z64/data.py | 2 + fast64_internal/z64/cutscene/properties.py | 6 +- .../z64/exporter/cutscene/camera.py | 3 + .../z64/exporter/cutscene/common.py | 4 +- fast64_internal/z64/exporter/cutscene/data.py | 71 +++++++++++++++++-- fast64_internal/z64/exporter/cutscene/misc.py | 56 ++++++++++++--- fast64_internal/z64/exporter/cutscene/text.py | 25 +++++-- .../z64/exporter/scene/actor_cutscene.py | 1 + 8 files changed, 143 insertions(+), 25 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 450d4179c..c6b508d35 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -549,9 +549,11 @@ def __init__(self, game: str): self.enum_floor_effect = enum_floor_effect def is_oot(self): + self.update(bpy.context, None) return self.game == "OOT" def is_mm(self): + self.update(bpy.context, None) return self.game == "MM" def update(self, context: Optional[Context], game: Optional[str], force: bool = False): diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index c1abd9c4a..5f239e8fc 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -110,7 +110,7 @@ def draw_props( if name in customValues and value == "Custom": prop_split(box, self, f"{name}_custom" if "_" in p else f"{name}Custom", f"{displayName} Custom") - if name == "csTextType" and value != "choice": + if is_oot_features() and name == "csTextType" and value != "choice": break @@ -136,8 +136,8 @@ class OOTCSTextProperty(OOTCutsceneCommon, PropertyGroup): default=1, ) ocarinaActionCustom: StringProperty(default="OCARINA_ACTION_CUSTOM") - topOptionTextID: StringProperty(name="", default="0x0000") - bottomOptionTextID: StringProperty(name="", default="0x0000") + topOptionTextID: StringProperty(name="", default="0xFFFF") + bottomOptionTextID: StringProperty(name="", default="0xFFFF") ocarinaMessageId: StringProperty(name="", default="0x0000") csTextType: EnumProperty( name="Text Type", items=lambda self, context: game_data.z64.get_enum("csTextType"), default=1 diff --git a/fast64_internal/z64/exporter/cutscene/camera.py b/fast64_internal/z64/exporter/cutscene/camera.py index 90d469d24..e45cc34e5 100644 --- a/fast64_internal/z64/exporter/cutscene/camera.py +++ b/fast64_internal/z64/exporter/cutscene/camera.py @@ -251,8 +251,11 @@ def to_c(self): return ( (indent * 3 + f"CS_CAM_SPLINE({len(self.entries)}, 0, 0, {self.duration}),\n") + + (indent * 4 + "// At Camera Points\n") + "".join(at for at in at_list) + + (indent * 4 + "// Eye Camera Points\n") + "".join(eye for eye in eye_list) + + (indent * 4 + "// FoV/Roll Settings\n") + "".join(misc for misc in misc_list) ) diff --git a/fast64_internal/z64/exporter/cutscene/common.py b/fast64_internal/z64/exporter/cutscene/common.py index 4811f803e..3fa7513c8 100644 --- a/fast64_internal/z64/exporter/cutscene/common.py +++ b/fast64_internal/z64/exporter/cutscene/common.py @@ -1,6 +1,7 @@ from dataclasses import dataclass from typing import Optional from ....utility import PluginError, indent +from ...utility import is_oot_features from ....game_data import game_data from ...cutscene.motion.utility import getInteger @@ -42,4 +43,5 @@ def getGenericSeqCmd(self, cmdName: str, type: str, startFrame: int, endFrame: i self.validateFrames() if type is None: raise PluginError("ERROR: Seq type is None!") - return indent * 3 + f"{cmdName}({type}, {startFrame}, {endFrame}" + ", 0" * 8 + "),\n" + pad_amount = 8 if is_oot_features() else 1 if cmdName == "CS_STOP_SEQ" else 0 + return indent * 3 + f"{cmdName}({type}, {startFrame}, {endFrame}" + ", 0" * pad_amount + "),\n" diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index e20d88e92..cb864d8f7 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -1,6 +1,7 @@ import bpy import math +from copy import copy from dataclasses import dataclass, field from typing import Optional, TYPE_CHECKING from bpy.types import Object, Bone @@ -20,6 +21,7 @@ CutsceneCmdMiscList, CutsceneCmdRumbleControllerList, CutsceneCmdTransition, + CutsceneCmdTransitionList, CutsceneCmdLightSettingList, CutsceneCmdTimeList, ) @@ -55,7 +57,7 @@ "StartSeq": CutsceneCmdStartStopSeq, "StopSeq": CutsceneCmdStartStopSeq, "FadeOutSeq": CutsceneCmdFadeSeq, - "Transition": CutsceneCmdTransition, + "Transition": CutsceneCmdTransitionList, } cmdToList = { @@ -64,6 +66,7 @@ "TimeList": "timeList", "MiscList": "miscList", "RumbleList": "rumbleList", + "Transition": "transitionList", } @@ -90,7 +93,7 @@ def __init__(self, useMacros: bool, motionOnly: bool): self.textList: list[CutsceneCmdTextList] = [] self.miscList: list[CutsceneCmdMiscList] = [] self.rumbleList: list[CutsceneCmdRumbleControllerList] = [] - self.transitionList: list[CutsceneCmdTransition] = [] + self.transitionList: list[CutsceneCmdTransitionList] = [] self.lightSettingsList: list[CutsceneCmdLightSettingList] = [] self.timeList: list[CutsceneCmdTimeList] = [] self.seqList: list[CutsceneCmdStartStopSeqList] = [] @@ -98,7 +101,6 @@ def __init__(self, useMacros: bool, motionOnly: bool): # lists from the new cutscene system self.camSplineList: list[CutsceneCmdCamSplineList] = [] - # self.transitionListNew: list[CutsceneCmdTransitionList] = [] # self.destinationListNew: list[CutsceneCmdDestinationList] = [] # self.motionBlurList: list[CutsceneCmdMotionBlurList] = [] # self.modifySeqList: list[CutsceneCmdModifySeqList] = [] @@ -322,14 +324,23 @@ def setCameraShotData(self, csObjects: dict[str, list[Object]]): self.totalEntries += len(shotObjects) * 2 else: new_spline_list = CutsceneCmdCamSplineList(0) # bytes are computed when getting the c data + i = 0 for shot_obj in shotObjects: shot_prop = shot_obj.data.ootCamShotProp new_spline = CutsceneCmdCamSpline(0, shot_prop.shot_duration) + at_total = 0 + eye_total = 0 for i, bone in enumerate(shot_obj.data.bones): bone_prop = bone.ootCamShotPointProp + if i > 0 and i < len(shot_obj.data.bones) - 1: + at_total += bone_prop.shot_point_duration + eye_total += bone_prop.shot_point_duration + + # MM TODO: move shot_interp_type and shot_spline_rel_to per bone? + # add weight property new_spline.entries.append( CutsceneSplinePoint( # At @@ -361,6 +372,43 @@ def setCameraShotData(self, csObjects: dict[str, list[Object]]): ) ) + # I don't understand how this camera system works, as far as I can tell it's + # the same as OoT? It's clear that the first and last points are ignored and by + # looking at the vanilla scenes I came to the conclusion that the last point of + # each point type (at and eye) have a duration that is the sum of all the previous + # point's durations except the very first one. By looking at the code I'm thinking + # this might work exactly like OoT where you need an extra point because of some bug + # (see the readme for explanations), idk if this is necessary ¯\_(ツ)_/¯ + # + # this block copies the last entry's informations to the extra one, + # except for the duration which is computed in the loop above + last_entry = new_spline.entries[-1] + # last_entry.at.duration = at_total + # last_entry.eye.duration = eye_total + new_spline.entries.append( + CutsceneSplinePoint( + # At + CutsceneCmdNewCamPoint( + last_entry.at.interp_type, + last_entry.at.weight, + at_total, + last_entry.at.pos, + last_entry.at.relative_to, + ), + # Eye + CutsceneCmdNewCamPoint( + last_entry.eye.interp_type, + last_entry.eye.weight, + eye_total, + last_entry.eye.pos, + last_entry.eye.relative_to, + ), + # Misc + copy(last_entry.misc), + ) + ) + i += 1 # accounting for the extra point + new_spline.num_entries = i new_spline_list.entries.append(new_spline) @@ -430,8 +478,13 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce else: self.seqList.append(cmdList) case _: - curList = getattr(entry, (entry.listType[0].lower() + entry.listType[1:])) - cmdList = cmdToClass[entry.listType](None, None) + if entry.listType == "Transition": + prop_name = "transition_list" + cmdList = cmdToClass[entry.listType](None, None, 0) + else: + prop_name = entry.listType[0].lower() + entry.listType[1:] + cmdList = cmdToClass[entry.listType](None, None) + curList = getattr(entry, prop_name) cmdList.entryTotal = len(curList) for elem in curList: match entry.listType: @@ -464,13 +517,19 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce ) ) case "RumbleList": + if not is_oot_features(): + rumble_type = self.getEnumValueFromProp("cs_rumble_type", elem, "rumble_type") + else: + rumble_type = None + cmdList.entries.append( CutsceneCmdRumbleController( elem.startFrame, - elem.endFrame, + elem.startFrame + 1, elem.rumbleSourceStrength, elem.rumbleDuration, elem.rumbleDecreaseRate, + rumble_type, ) ) case _: diff --git a/fast64_internal/z64/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py index be628616e..42a558433 100644 --- a/fast64_internal/z64/exporter/cutscene/misc.py +++ b/fast64_internal/z64/exporter/cutscene/misc.py @@ -1,6 +1,8 @@ from dataclasses import dataclass, field from typing import Optional +from ....game_data import game_data from ....utility import PluginError, indent +from ...utility import is_oot_features from ...cutscene.motion.utility import getInteger from .common import CutsceneCmdBase @@ -21,7 +23,8 @@ def from_params(params: list[str]): def getCmd(self): self.validateFrames() - return indent * 3 + (f"CS_MISC({self.type}, {self.startFrame}, {self.endFrame}" + ", 0" * 11 + "),\n") + pad_amount = 11 if is_oot_features() else 1 + return indent * 3 + (f"CS_MISC({self.type}, {self.startFrame}, {self.endFrame}" + ", 0" * pad_amount + "),\n") @dataclass @@ -42,7 +45,8 @@ def from_params(params: list[str], isLegacy: bool): def getCmd(self): self.validateFrames(False) - return indent * 3 + (f"CS_LIGHT_SETTING({self.lightSetting}, {self.startFrame}" + ", 0" * 12 + "),\n") + pad_amount = 12 if is_oot_features() else 1 + return indent * 3 + (f"CS_LIGHT_SETTING({self.lightSetting}, {self.startFrame}" + ", 0" * pad_amount + "),\n") @dataclass @@ -75,6 +79,7 @@ class CutsceneCmdRumbleController(CutsceneCmdBase): sourceStrength: int duration: int decreaseRate: int + type: Optional[str] paramNumber: int = field(init=False, default=8) @@ -86,14 +91,22 @@ def from_params(params: list[str]): getInteger(params[3]), getInteger(params[4]), getInteger(params[5]), + params[0] if not is_oot_features() else None, ) def getCmd(self): self.validateFrames(False) - return indent * 3 + ( - f"CS_RUMBLE_CONTROLLER(" - + f"0, {self.startFrame}, 0, {self.sourceStrength}, {self.duration}, {self.decreaseRate}, 0, 0),\n" - ) + if is_oot_features(): + return indent * 3 + ( + f"CS_RUMBLE_CONTROLLER(" + + f"0, {self.startFrame}, 0, {self.sourceStrength}, {self.duration}, {self.decreaseRate}, 0, 0),\n" + ) + else: + return indent * 3 + ( + f"CS_RUMBLE(" + + f"{self.type}, {self.startFrame}, {self.endFrame}, " + + f"{self.sourceStrength}, {self.duration}, {self.decreaseRate}),\n" + ) @dataclass @@ -183,7 +196,8 @@ def from_params(params: list[str]): def getCmd(self): if len(self.entries) == 0: raise PluginError("ERROR: Entry list is empty!") - return self.getGenericListCmd("CS_RUMBLE_CONTROLLER_LIST", self.entryTotal) + "".join( + suffix = "_CONTROLLER" if is_oot_features() else "" + return self.getGenericListCmd(f"CS_RUMBLE{suffix}_LIST", self.entryTotal) + "".join( entry.getCmd() for entry in self.entries ) @@ -215,7 +229,6 @@ class CutsceneCmdTransition(CutsceneCmdBase): type: str paramNumber: int = field(init=False, default=3) - listName: str = field(init=False, default="transitionList") @staticmethod def from_params(params: list[str]): @@ -223,6 +236,29 @@ def from_params(params: list[str]): getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_transition_type", params[0]) ) - def getCmd(self): + def to_c(self): self.validateFrames() - return indent * 2 + f"CS_TRANSITION({self.type}, {self.startFrame}, {self.endFrame}),\n" + return indent * 3 + f"CS_TRANSITION({self.type}, {self.startFrame}, {self.endFrame}),\n" + + +@dataclass +class CutsceneCmdTransitionList(CutsceneCmdBase): + """This class contains Transition list command data""" + + entryTotal: int + entries: list[CutsceneCmdTransition] = field(default_factory=list) + + paramNumber: int = 1 + listName: str = "transitionList" + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdTransitionList(getInteger(params[0])) + + def getCmd(self): + if game_data.z64.is_oot(): + return "".join(entry.to_c() for entry in self.entries) + else: + return (indent * 2 + f"CS_TRANSITION_LIST({len(self.entries)}),\n") + "".join( + entry.to_c() for entry in self.entries + ) diff --git a/fast64_internal/z64/exporter/cutscene/text.py b/fast64_internal/z64/exporter/cutscene/text.py index ffe532a7f..d65256ce7 100644 --- a/fast64_internal/z64/exporter/cutscene/text.py +++ b/fast64_internal/z64/exporter/cutscene/text.py @@ -1,5 +1,6 @@ from dataclasses import dataclass, field from ....utility import PluginError, indent +from ...utility import is_oot_features from ...cutscene.motion.utility import getInteger from .common import CutsceneCmdBase @@ -29,11 +30,25 @@ def from_params(params: list[str]): def getCmd(self): self.validateFrames() - return indent * 3 + ( - f"CS_TEXT(" - + f"{self.textId}, {self.startFrame}, {self.endFrame}, {self.type}, {self.altTextId1}, {self.altTextId2}" - + "),\n" - ) + if is_oot_features(): + command = ( + f"CS_TEXT(" + + f"{self.textId}, {self.startFrame}, {self.endFrame}, {self.type}, {self.altTextId1}, {self.altTextId2}" + + "),\n" + ) + else: + command = f"{self.type}(" + if self.type not in {"CS_TEXT_TYPE_1", "CS_TEXT_TYPE_3"}: + command = command.replace("_TYPE", "") + match self.type: + case "CS_TEXT_TYPE_DEFAULT" | "CS_TEXT_TYPE_1" | "CS_TEXT_TYPE_3": + command += ( + f"{self.textId}, {self.startFrame}, {self.endFrame}, {self.altTextId1}, {self.altTextId2}" + ) + case "CS_TEXT_TYPE_BOSSES_REMAINS" | "CS_TEXT_TYPE_ALL_NORMAL_MASKS": + command += f"{self.textId}, {self.startFrame}, {self.endFrame}, {self.altTextId1}" + command += "),\n" + return indent * 3 + command @dataclass diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index ca7a85c16..639080782 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -82,6 +82,7 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i entries: list[ActorCutscene] = [] obj_list = getObjectList(scene_obj.children_recursive, "EMPTY", empty_type) processed = [] + i = 0 for obj in obj_list: if empty_type == "Actor": From d2a17f76e113175fb2f63a6e64ca85d347f9384e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 15:21:09 +0100 Subject: [PATCH 086/126] more cutscene export progress --- .../z64/exporter/cutscene/__init__.py | 5 + fast64_internal/z64/exporter/cutscene/data.py | 94 ++++++++-- fast64_internal/z64/exporter/cutscene/misc.py | 172 ++++++++++++++++-- fast64_internal/z64/exporter/cutscene/seq.py | 40 +++- 4 files changed, 288 insertions(+), 23 deletions(-) diff --git a/fast64_internal/z64/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py index 85846fa4c..a711be45d 100644 --- a/fast64_internal/z64/exporter/cutscene/__init__.py +++ b/fast64_internal/z64/exporter/cutscene/__init__.py @@ -88,6 +88,10 @@ def getC(self): "timeList", "seqList", "fadeSeqList", + "motion_blur_list", + "credits_scene_list", + "transition_general_list", + "modify_seq_list", ] ) @@ -135,6 +139,7 @@ def getC(self): + " = {\n" + (indent + f"{cs_header}({self.totalEntries}, {self.frameCount}),\n") + (self.data.destination.getCmd() if self.data.destination is not None else "") + + (self.data.give_tatl.getCmd() if self.data.give_tatl is not None else "") + "".join(entry.getCmd() for curList in dataListNames for entry in getattr(self.data, curList)) + (indent + f"{cs_end}(),\n") + "};\n\n" diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index cb864d8f7..78a8165c3 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -5,13 +5,21 @@ from dataclasses import dataclass, field from typing import Optional, TYPE_CHECKING from bpy.types import Object, Bone -from ....utility import PluginError +from ....utility import PluginError, exportColor from ....game_data import game_data from ...utility import is_oot_features from .actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue -from .seq import CutsceneCmdStartStopSeqList, CutsceneCmdFadeSeqList, CutsceneCmdStartStopSeq, CutsceneCmdFadeSeq from .text import CutsceneCmdTextList, CutsceneCmdText, CutsceneCmdTextNone, CutsceneCmdTextOcarinaAction +from .seq import ( + CutsceneCmdStartStopSeqList, + CutsceneCmdFadeSeqList, + CutsceneCmdStartStopSeq, + CutsceneCmdFadeSeq, + CutsceneCmdModifySeq, + CutsceneCmdModifySeqList, +) + from .misc import ( CutsceneCmdLightSetting, CutsceneCmdTime, @@ -24,6 +32,13 @@ CutsceneCmdTransitionList, CutsceneCmdLightSettingList, CutsceneCmdTimeList, + CutsceneCmdMotionBlur, + CutsceneCmdMotionBlurList, + CutsceneCmdChooseCreditsScenes, + CutsceneCmdChooseCreditsScenesList, + CutsceneCmdTransitionGeneral, + CutsceneCmdTransitionGeneralList, + CutsceneCmdGiveTatl, ) from .camera import ( @@ -58,6 +73,10 @@ "StopSeq": CutsceneCmdStartStopSeq, "FadeOutSeq": CutsceneCmdFadeSeq, "Transition": CutsceneCmdTransitionList, + "MotionBlurList": CutsceneCmdMotionBlurList, + "CreditsSceneList": CutsceneCmdChooseCreditsScenesList, + "TransitionGeneralList": CutsceneCmdTransitionGeneralList, + "ModifySeqList": CutsceneCmdModifySeqList, } cmdToList = { @@ -67,6 +86,10 @@ "MiscList": "miscList", "RumbleList": "rumbleList", "Transition": "transitionList", + "MotionBlurList": "motion_blur_list", + "CreditsSceneList": "credits_scene_list", + "TransitionGeneralList": "transition_general_list", + "ModifySeqList": "modify_seq_list", } @@ -82,6 +105,7 @@ def __init__(self, useMacros: bool, motionOnly: bool): self.motionFrameCount: int = 0 self.camEndFrame: int = 0 self.destination: Optional[CutsceneCmdDestination] = None + self.give_tatl: Optional[CutsceneCmdGiveTatl] = None self.actorCueList: list[CutsceneCmdActorCueList] = [] self.playerCueList: list[CutsceneCmdActorCueList] = [] self.camEyeSplineList: list[CutsceneCmdCamEyeSpline] = [] @@ -101,12 +125,11 @@ def __init__(self, useMacros: bool, motionOnly: bool): # lists from the new cutscene system self.camSplineList: list[CutsceneCmdCamSplineList] = [] - # self.destinationListNew: list[CutsceneCmdDestinationList] = [] - # self.motionBlurList: list[CutsceneCmdMotionBlurList] = [] - # self.modifySeqList: list[CutsceneCmdModifySeqList] = [] - # self.creditsSceneList: list[CutsceneCmdChooseCreditsScenesList] = [] - # self.transitionGeneralList: list[CutsceneCmdTransitionGeneralList] = [] - # self.giveTatlList: list[CutsceneCmdGiveTatlList] = [] + self.motion_blur_list: list[CutsceneCmdMotionBlurList] = [] + self.modify_seq_list: list[CutsceneCmdModifySeqList] = [] + self.credits_scene_list: list[CutsceneCmdChooseCreditsScenesList] = [] + self.transition_general_list: list[CutsceneCmdTransitionGeneralList] = [] + # self.give_tatl_list: list[CutsceneCmdGiveTatlList] = [] @staticmethod def new(csObj: Object, useMacros: bool, motionOnly: bool): @@ -449,14 +472,30 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce if csProp.csUseDestination: self.destination = CutsceneCmdDestination( csProp.csDestinationStartFrame, - None, + csProp.csDestinationStartFrame + 1, self.getEnumValueFromProp("cs_destination", csProp, "csDestination"), ) self.totalEntries += 1 + if not is_oot_features() and csProp.cs_give_tatl: + self.give_tatl = CutsceneCmdGiveTatl( + csProp.cs_give_tatl_start_frame, + csProp.cs_give_tatl_start_frame + 1, + "true" if csProp.cs_give_tatl else "false", + ) + self.totalEntries += 1 + self.frameCount = csProp.csEndFrame self.totalEntries += len(csProp.csLists) + prop_map = { + "Transition": "transition_list", + "MotionBlurList": "motion_blur_list", + "CreditsSceneList": "credits_scene_list", + "TransitionGeneralList": "trans_general_list", + "ModifySeqList": "mod_seq_list", + } + for entry in csProp.csLists: match entry.listType: case "StartSeqList" | "StopSeqList" | "FadeOutSeqList": @@ -478,8 +517,8 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce else: self.seqList.append(cmdList) case _: - if entry.listType == "Transition": - prop_name = "transition_list" + if entry.listType in prop_map.keys(): + prop_name = prop_map[entry.listType] cmdList = cmdToClass[entry.listType](None, None, 0) else: prop_name = entry.listType[0].lower() + entry.listType[1:] @@ -488,6 +527,39 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce cmdList.entryTotal = len(curList) for elem in curList: match entry.listType: + case "ModifySeqList": + cmdList.entries.append( + CutsceneCmdModifySeq( + elem.startFrame, + elem.startFrame + 1, + self.getEnumValueFromProp("cs_modify_seq_type", elem, "mod_seq_type"), + ) + ) + case "CreditsSceneList": + cmdList.entries.append( + CutsceneCmdChooseCreditsScenes( + elem.startFrame, + elem.startFrame + 1, + self.getEnumValueFromProp("cs_credits_scene_type", elem, "credits_scene_type"), + ) + ) + case "TransitionGeneralList": + cmdList.entries.append( + CutsceneCmdTransitionGeneral( + elem.startFrame, + elem.endFrame, + self.getEnumValueFromProp("cs_transition_general", elem, "trans_general_type"), + exportColor(elem.trans_color[0:3]), + ) + ) + case "MotionBlurList": + cmdList.entries.append( + CutsceneCmdMotionBlur( + elem.startFrame, + elem.endFrame, + self.getEnumValueFromProp("cs_motion_blur_type", elem, "blur_type"), + ) + ) case "Transition": cmdList.entries.append( CutsceneCmdTransition( diff --git a/fast64_internal/z64/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py index 42a558433..d85695872 100644 --- a/fast64_internal/z64/exporter/cutscene/misc.py +++ b/fast64_internal/z64/exporter/cutscene/misc.py @@ -12,7 +12,6 @@ class CutsceneCmdMisc(CutsceneCmdBase): """This class contains a single misc command entry""" type: str # see ``CutsceneMiscType`` in decomp - paramNumber: int = field(init=False, default=14) @staticmethod @@ -33,7 +32,6 @@ class CutsceneCmdLightSetting(CutsceneCmdBase): isLegacy: bool lightSetting: int - paramNumber: int = field(init=False, default=11) @staticmethod @@ -55,7 +53,6 @@ class CutsceneCmdTime(CutsceneCmdBase): hour: int minute: int - paramNumber: int = field(init=False, default=5) @staticmethod @@ -80,7 +77,6 @@ class CutsceneCmdRumbleController(CutsceneCmdBase): duration: int decreaseRate: int type: Optional[str] - paramNumber: int = field(init=False, default=8) @staticmethod @@ -207,19 +203,26 @@ class CutsceneCmdDestination(CutsceneCmdBase): """This class contains Destination command data""" id: str - paramNumber: int = field(init=False, default=3) listName: str = field(init=False, default="destination") @staticmethod def from_params(params: list[str]): return CutsceneCmdDestination( - getInteger(params[1]), None, CutsceneCmdBase.getEnumValue("cs_destination", params[0]) + getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_destination", params[0]) ) def getCmd(self): self.validateFrames(False) - return indent * 2 + f"CS_DESTINATION({self.id}, {self.startFrame}, 0),\n" + if is_oot_features(): + return indent * 2 + f"CS_DESTINATION({self.id}, {self.startFrame}, {self.endFrame}),\n" + else: + return ( + indent * 2 + + f"CS_DESTINATION_LIST(1),\n" + + indent * 3 + + f"CS_DESTINATION({self.id}, {self.startFrame}, {self.endFrame}),\n" + ) @dataclass @@ -227,7 +230,6 @@ class CutsceneCmdTransition(CutsceneCmdBase): """This class contains Transition command data""" type: str - paramNumber: int = field(init=False, default=3) @staticmethod @@ -247,7 +249,6 @@ class CutsceneCmdTransitionList(CutsceneCmdBase): entryTotal: int entries: list[CutsceneCmdTransition] = field(default_factory=list) - paramNumber: int = 1 listName: str = "transitionList" @@ -259,6 +260,155 @@ def getCmd(self): if game_data.z64.is_oot(): return "".join(entry.to_c() for entry in self.entries) else: - return (indent * 2 + f"CS_TRANSITION_LIST({len(self.entries)}),\n") + "".join( - entry.to_c() for entry in self.entries + return ( + indent * 2 + + f"CS_TRANSITION_LIST({len(self.entries)}),\n" + + "".join(entry.to_c() for entry in self.entries) ) + + +@dataclass +class CutsceneCmdMotionBlur(CutsceneCmdBase): + """This class contains motion blur command data""" + + type: str + paramNumber: int = 3 + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdMotionBlur( + CutsceneCmdBase.getEnumValue("cs_motion_blur_type", params[0]), + getInteger(params[1]), + getInteger(params[2]), + ) + + def to_c(self): + return indent * 3 + f"CS_MOTION_BLUR({self.type}, {self.startFrame}, {self.endFrame}),\n" + + +@dataclass +class CutsceneCmdMotionBlurList(CutsceneCmdBase): + """This class contains motion blur list command data""" + + entryTotal: int + entries: list[CutsceneCmdMotionBlur] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "motion_blur_list" + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdMotionBlurList(getInteger(params[0])) + + def getCmd(self): + return ( + indent * 2 + + f"CS_MOTION_BLUR_LIST({len(self.entries)}),\n" + + "".join(entry.to_c() for entry in self.entries) + ) + + +@dataclass +class CutsceneCmdChooseCreditsScenes(CutsceneCmdBase): + """This class contains choose credits scenes command data""" + + type: str + paramNumber: int = 3 + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdChooseCreditsScenes( + CutsceneCmdBase.getEnumValue("cs_credits_scene_type", params[0]), + getInteger(params[1]), + getInteger(params[2]), + ) + + def to_c(self): + return indent * 3 + f"CS_CHOOSE_CREDITS_SCENES({self.type}, {self.startFrame}, {self.endFrame}),\n" + + +@dataclass +class CutsceneCmdChooseCreditsScenesList(CutsceneCmdBase): + """This class contains choose credits scenes list command data""" + + entryTotal: int + entries: list[CutsceneCmdChooseCreditsScenes] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "credits_scene_list" + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdChooseCreditsScenesList(getInteger(params[0])) + + def getCmd(self): + return ( + indent * 2 + + f"CS_CHOOSE_CREDITS_SCENES_LIST({len(self.entries)}),\n" + + "".join(entry.to_c() for entry in self.entries) + ) + + +@dataclass +class CutsceneCmdTransitionGeneral(CutsceneCmdBase): + """This class contains transition general command data""" + + type: str + rgb: list[int] + paramNumber: int = 6 + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdTransitionGeneral( + getInteger(params[1]), + getInteger(params[2]), + CutsceneCmdBase.getEnumValue("cs_transition_general", 0), + [getInteger(params[3]), getInteger(params[4]), getInteger(params[5])], + ) + + def to_c(self): + color = ", ".join(f"{c}" for c in self.rgb) + return indent * 3 + f"CS_TRANSITION_GENERAL({self.type}, {self.startFrame}, {self.endFrame}, {color}),\n" + + +@dataclass +class CutsceneCmdTransitionGeneralList(CutsceneCmdBase): + """This class contains transition general list command data""" + + entryTotal: int + entries: list[CutsceneCmdTransitionGeneral] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "transition_general_list" + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdTransitionGeneralList(getInteger(params[0])) + + def getCmd(self): + return ( + indent * 2 + + f"CS_TRANSITION_GENERAL_LIST({len(self.entries)}),\n" + + "".join(entry.to_c() for entry in self.entries) + ) + + +@dataclass +class CutsceneCmdGiveTatl(CutsceneCmdBase): + """This class contains give tatl command data""" + + giveTatl: bool + paramNumber: int = 3 + + @staticmethod + def from_params(params: list[str]): + return CutsceneCmdGiveTatl( + getInteger(params[1]), + getInteger(params[2]), + params[0] in {"true", "1"}, + ) + + def getCmd(self): + return ( + indent * 2 + + f"CS_GIVE_TATL_LIST(1),\n" + + indent * 3 + + f"CS_GIVE_TATL({self.giveTatl}, {self.startFrame}, {self.endFrame}),\n" + ) diff --git a/fast64_internal/z64/exporter/cutscene/seq.py b/fast64_internal/z64/exporter/cutscene/seq.py index bb4155c70..bebb93d97 100644 --- a/fast64_internal/z64/exporter/cutscene/seq.py +++ b/fast64_internal/z64/exporter/cutscene/seq.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field from typing import Optional -from ....utility import PluginError +from ....utility import PluginError, indent from ...cutscene.motion.utility import getInteger from .common import CutsceneCmdBase @@ -91,3 +91,41 @@ def getCmd(self): return self.getGenericListCmd("CS_FADE_OUT_SEQ_LIST", self.entryTotal) + "".join( entry.getCmd() for entry in self.entries ) + + +@dataclass +class CutsceneCmdModifySeq(CutsceneCmdBase): + """This class contains modify seq command data""" + + type: str + paramNumber: int = 3 + + @staticmethod + def from_params(params: list[str], enumKey: str): + return CutsceneCmdModifySeq( + getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_modify_seq_type", params[0]) + ) + + def to_c(self): + return indent * 3 + f"CS_MODIFY_SEQ({self.type}, {self.startFrame}, {self.endFrame}),\n" + + +@dataclass +class CutsceneCmdModifySeqList(CutsceneCmdBase): + """This class contains modify seq list command data""" + + entryTotal: int + entries: list[CutsceneCmdModifySeq] = field(default_factory=list) + paramNumber: int = 1 + listName: str = "modifySeqList" + + @staticmethod + def from_params(params: list[str]): + new = CutsceneCmdModifySeqList() + new.entryTotal = getInteger(params[0]) + return new + + def getCmd(self): + return ( + indent * 2 + f"CS_MODIFY_SEQ_LIST({len(self.entries)}),\n" + "".join(entry.to_c() for entry in self.entries) + ) From 8e2f7bc16e9c686b6142d71d0fd08bfd721f8938 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:28:41 +0100 Subject: [PATCH 087/126] missing commands --- fast64_internal/data/z64/data.py | 2 + fast64_internal/z64/cutscene/constants.py | 4 + fast64_internal/z64/cutscene/properties.py | 18 +++- .../z64/exporter/cutscene/__init__.py | 10 ++- fast64_internal/z64/exporter/cutscene/data.py | 46 ++++++++--- fast64_internal/z64/exporter/cutscene/misc.py | 40 ++++----- fast64_internal/z64/exporter/cutscene/seq.py | 82 ++++++++++++++++++- 7 files changed, 164 insertions(+), 38 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index c6b508d35..497420b83 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -532,6 +532,8 @@ ("ModifySeqList", "Modify Seq List", "Modify Seq", "IPO_CONSTANT", 10), ("CreditsSceneList", "Choose Credits Scene List", "Choose Credits Scene", "WORLD", 11), ("TransitionGeneralList", "Transition General List", "Transition General", "COLORSET_06_VEC", 12), + ("StartAmbienceList", "Start Ambience List", "Start Ambience", "SNAP_FACE", 13), + ("FadeOutAmbienceList", "Fade-Out Ambience List", "Fade-Out Ambience", "IPO_EASE_IN_OUT", 14), ] # --- diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 65e137e04..1b526764e 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -67,6 +67,8 @@ "ModifySeqList": "IPO_CONSTANT", "CreditsSceneList": "WORLD", "TransitionGeneralList": "COLORSET_06_VEC", + "StartAmbienceList": "SNAP_FACE", + "FadeOutAmbienceList": "IPO_EASE_IN_OUT", } ootEnumCSTextboxType = [ @@ -136,6 +138,8 @@ "ModifySeqList": "Modify Seq List", "CreditsSceneList": "Choose Credits Scene List", "TransitionGeneralList": "Transition General List", + "StartAmbienceList": "Start Ambience List", + "FadeOutAmbienceList": "Fade-Out Ambience List", } ootEnumCSMotionCamMode = [ diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 5f239e8fc..3ad8d8e72 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -182,8 +182,14 @@ class OOTCSSeqProperty(OOTCutsceneCommon, PropertyGroup): csSeqPlayerCustom: StringProperty(default="CS_FADE_OUT_CUSTOM") def filterProp(self, name, listProp): - types = {"FadeOutSeqList", "StopSeqList"} if game_data.z64.is_mm() else {"FadeOutSeqList"} - return name != "endFrame" or listProp.listType in types + if game_data.z64.is_mm(): + types = {"FadeOutSeqList", "StopSeqList", "StartAmbienceList", "FadeOutAmbienceList"} + else: + types = {"FadeOutSeqList"} + if "Ambience" in listProp.listType and listProp.listType in types: + return name != "csSeqID" + else: + return name != "endFrame" or listProp.listType in types def filterName(self, name, listProp): if name == "csSeqID" and listProp.listType == "FadeOutSeqList": @@ -309,7 +315,13 @@ def draw_props(self, layout: UILayout, listIndex: int, objName: str, collectionT attrName = "lightSettingsList" elif self.listType == "TimeList": attrName = "timeList" - elif self.listType in ["StartSeqList", "StopSeqList", "FadeOutSeqList"]: + elif self.listType in [ + "StartSeqList", + "StopSeqList", + "FadeOutSeqList", + "StartAmbienceList", + "FadeOutAmbienceList", + ]: attrName = "seqList" elif self.listType == "MiscList": attrName = "miscList" diff --git a/fast64_internal/z64/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py index a711be45d..01b9a51b8 100644 --- a/fast64_internal/z64/exporter/cutscene/__init__.py +++ b/fast64_internal/z64/exporter/cutscene/__init__.py @@ -92,6 +92,8 @@ def getC(self): "credits_scene_list", "transition_general_list", "modify_seq_list", + "start_ambience_list", + "fade_out_ambience_list", ] ) @@ -134,13 +136,19 @@ def getC(self): cs_header = "CS_HEADER" cs_end = "CS_END_OF_SCRIPT" + command_data = "" + for curList in dataListNames: + for entry in getattr(self.data, curList): + if len(entry.entries) > 0: + command_data += entry.getCmd() + csData.source = ( declarationBase + " = {\n" + (indent + f"{cs_header}({self.totalEntries}, {self.frameCount}),\n") + (self.data.destination.getCmd() if self.data.destination is not None else "") + (self.data.give_tatl.getCmd() if self.data.give_tatl is not None else "") - + "".join(entry.getCmd() for curList in dataListNames for entry in getattr(self.data, curList)) + + command_data + (indent + f"{cs_end}(),\n") + "};\n\n" ) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 78a8165c3..7e3a82285 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -18,6 +18,10 @@ CutsceneCmdFadeSeq, CutsceneCmdModifySeq, CutsceneCmdModifySeqList, + CutsceneCmdStartAmbience, + CutsceneCmdStartAmbienceList, + CutsceneCmdFadeOutAmbience, + CutsceneCmdFadeOutAmbienceList, ) from .misc import ( @@ -77,8 +81,13 @@ "CreditsSceneList": CutsceneCmdChooseCreditsScenesList, "TransitionGeneralList": CutsceneCmdTransitionGeneralList, "ModifySeqList": CutsceneCmdModifySeqList, + "StartAmbience": CutsceneCmdStartAmbience, + "FadeOutAmbience": CutsceneCmdFadeOutAmbience, + "StartAmbienceList": CutsceneCmdStartAmbienceList, + "FadeOutAmbienceList": CutsceneCmdFadeOutAmbienceList, } +# to CutsceneData list cmdToList = { "TextList": "textList", "LightSettingsList": "lightSettingsList", @@ -90,6 +99,8 @@ "CreditsSceneList": "credits_scene_list", "TransitionGeneralList": "transition_general_list", "ModifySeqList": "modify_seq_list", + "StartAmbienceList": "start_ambience_list", + "FadeOutAmbienceList": "fade_out_ambience_list", } @@ -129,7 +140,8 @@ def __init__(self, useMacros: bool, motionOnly: bool): self.modify_seq_list: list[CutsceneCmdModifySeqList] = [] self.credits_scene_list: list[CutsceneCmdChooseCreditsScenesList] = [] self.transition_general_list: list[CutsceneCmdTransitionGeneralList] = [] - # self.give_tatl_list: list[CutsceneCmdGiveTatlList] = [] + self.start_ambience_list: list[CutsceneCmdStartAmbienceList] = [] + self.fade_out_ambience_list: list[CutsceneCmdFadeOutAmbienceList] = [] @staticmethod def new(csObj: Object, useMacros: bool, motionOnly: bool): @@ -498,28 +510,42 @@ def setCutsceneData(self, csObjects: dict[str, list[Object]], csProp: "OOTCutsce for entry in csProp.csLists: match entry.listType: - case "StartSeqList" | "StopSeqList" | "FadeOutSeqList": + case "StartSeqList" | "StopSeqList" | "FadeOutSeqList" | "StartAmbienceList" | "FadeOutAmbienceList": isFadeOutSeq = entry.listType == "FadeOutSeqList" + is_start_ambience = entry.listType == "StartAmbienceList" + is_fade_out_ambience = entry.listType == "FadeOutAmbienceList" cmdList = cmdToClass[entry.listType](None, None) cmdList.entryTotal = len(entry.seqList) - if not isFadeOutSeq: + + if not isFadeOutSeq and not is_start_ambience and not is_fade_out_ambience: cmdList.type = "start" if entry.listType == "StartSeqList" else "stop" + for elem in entry.seqList: data = cmdToClass[entry.listType.removesuffix("List")](elem.startFrame, elem.endFrame) - if isFadeOutSeq: - data.seqPlayer = self.getEnumValueFromProp("cs_fade_out_seq_player", elem, "csSeqPlayer") - else: - data.type = cmdList.type - data.seqId = self.getEnumValueFromProp("seq_id", elem, "csSeqID") + + if not is_start_ambience and not is_fade_out_ambience: + if isFadeOutSeq: + data.seqPlayer = self.getEnumValueFromProp( + "cs_fade_out_seq_player", elem, "csSeqPlayer" + ) + else: + data.type = cmdList.type + data.seqId = self.getEnumValueFromProp("seq_id", elem, "csSeqID") + cmdList.entries.append(data) - if isFadeOutSeq: + + if is_start_ambience: + self.start_ambience_list.append(cmdList) + elif is_fade_out_ambience: + self.fade_out_ambience_list.append(cmdList) + elif isFadeOutSeq: self.fadeSeqList.append(cmdList) else: self.seqList.append(cmdList) case _: if entry.listType in prop_map.keys(): prop_name = prop_map[entry.listType] - cmdList = cmdToClass[entry.listType](None, None, 0) + cmdList = cmdToClass[entry.listType](None, None) else: prop_name = entry.listType[0].lower() + entry.listType[1:] cmdList = cmdToClass[entry.listType](None, None) diff --git a/fast64_internal/z64/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py index d85695872..a4f71d83f 100644 --- a/fast64_internal/z64/exporter/cutscene/misc.py +++ b/fast64_internal/z64/exporter/cutscene/misc.py @@ -109,7 +109,7 @@ def getCmd(self): class CutsceneCmdMiscList(CutsceneCmdBase): """This class contains Misc command data""" - entryTotal: Optional[int] = field(init=False, default=None) + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdMisc] = field(init=False, default_factory=list) paramNumber: int = field(init=False, default=1) listName: str = field(init=False, default="miscList") @@ -132,7 +132,7 @@ def getCmd(self): class CutsceneCmdLightSettingList(CutsceneCmdBase): """This class contains Light Setting List command data""" - entryTotal: Optional[int] = field(init=False, default=None) + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdLightSetting] = field(init=False, default_factory=list) paramNumber: int = field(init=False, default=1) listName: str = field(init=False, default="lightSettingsList") @@ -155,7 +155,7 @@ def getCmd(self): class CutsceneCmdTimeList(CutsceneCmdBase): """This class contains Time List command data""" - entryTotal: Optional[int] = field(init=False, default=None) + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdTime] = field(init=False, default_factory=list) paramNumber: int = field(init=False, default=1) listName: str = field(init=False, default="timeList") @@ -178,7 +178,7 @@ def getCmd(self): class CutsceneCmdRumbleControllerList(CutsceneCmdBase): """This class contains Rumble Controller List command data""" - entryTotal: Optional[int] = field(init=False, default=None) + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdRumbleController] = field(init=False, default_factory=list) paramNumber: int = field(init=False, default=1) listName: str = field(init=False, default="rumbleList") @@ -247,10 +247,10 @@ def to_c(self): class CutsceneCmdTransitionList(CutsceneCmdBase): """This class contains Transition list command data""" - entryTotal: int + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdTransition] = field(default_factory=list) - paramNumber: int = 1 - listName: str = "transitionList" + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="transitionList") @staticmethod def from_params(params: list[str]): @@ -272,7 +272,7 @@ class CutsceneCmdMotionBlur(CutsceneCmdBase): """This class contains motion blur command data""" type: str - paramNumber: int = 3 + paramNumber: int = field(init=False, default=3) @staticmethod def from_params(params: list[str]): @@ -290,10 +290,10 @@ def to_c(self): class CutsceneCmdMotionBlurList(CutsceneCmdBase): """This class contains motion blur list command data""" - entryTotal: int + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdMotionBlur] = field(default_factory=list) - paramNumber: int = 1 - listName: str = "motion_blur_list" + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="motion_blur_list") @staticmethod def from_params(params: list[str]): @@ -312,7 +312,7 @@ class CutsceneCmdChooseCreditsScenes(CutsceneCmdBase): """This class contains choose credits scenes command data""" type: str - paramNumber: int = 3 + paramNumber: int = field(init=False, default=3) @staticmethod def from_params(params: list[str]): @@ -330,10 +330,10 @@ def to_c(self): class CutsceneCmdChooseCreditsScenesList(CutsceneCmdBase): """This class contains choose credits scenes list command data""" - entryTotal: int + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdChooseCreditsScenes] = field(default_factory=list) - paramNumber: int = 1 - listName: str = "credits_scene_list" + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="credits_scene_list") @staticmethod def from_params(params: list[str]): @@ -353,7 +353,7 @@ class CutsceneCmdTransitionGeneral(CutsceneCmdBase): type: str rgb: list[int] - paramNumber: int = 6 + paramNumber: int = field(init=False, default=6) @staticmethod def from_params(params: list[str]): @@ -373,10 +373,10 @@ def to_c(self): class CutsceneCmdTransitionGeneralList(CutsceneCmdBase): """This class contains transition general list command data""" - entryTotal: int + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdTransitionGeneral] = field(default_factory=list) - paramNumber: int = 1 - listName: str = "transition_general_list" + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="transition_general_list") @staticmethod def from_params(params: list[str]): @@ -395,7 +395,7 @@ class CutsceneCmdGiveTatl(CutsceneCmdBase): """This class contains give tatl command data""" giveTatl: bool - paramNumber: int = 3 + paramNumber: int = field(init=False, default=3) @staticmethod def from_params(params: list[str]): diff --git a/fast64_internal/z64/exporter/cutscene/seq.py b/fast64_internal/z64/exporter/cutscene/seq.py index bebb93d97..b2240f7be 100644 --- a/fast64_internal/z64/exporter/cutscene/seq.py +++ b/fast64_internal/z64/exporter/cutscene/seq.py @@ -98,7 +98,7 @@ class CutsceneCmdModifySeq(CutsceneCmdBase): """This class contains modify seq command data""" type: str - paramNumber: int = 3 + paramNumber: int = field(init=False, default=3) @staticmethod def from_params(params: list[str], enumKey: str): @@ -114,10 +114,10 @@ def to_c(self): class CutsceneCmdModifySeqList(CutsceneCmdBase): """This class contains modify seq list command data""" - entryTotal: int + entryTotal: int = field(init=False, default=0) entries: list[CutsceneCmdModifySeq] = field(default_factory=list) - paramNumber: int = 1 - listName: str = "modifySeqList" + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="modify_seq_list") @staticmethod def from_params(params: list[str]): @@ -129,3 +129,77 @@ def getCmd(self): return ( indent * 2 + f"CS_MODIFY_SEQ_LIST({len(self.entries)}),\n" + "".join(entry.to_c() for entry in self.entries) ) + + +@dataclass +class CutsceneCmdStartAmbience(CutsceneCmdBase): + """This class contains modify seq command data""" + + paramNumber: int = field(init=False, default=3) + + @staticmethod + def from_params(params: list[str], enumKey: str): + return CutsceneCmdStartAmbience(getInteger(params[1]), getInteger(params[2])) + + def to_c(self): + return indent * 3 + f"CS_START_AMBIENCE(0, {self.startFrame}, {self.endFrame}),\n" + + +@dataclass +class CutsceneCmdStartAmbienceList(CutsceneCmdBase): + """This class contains modify seq list command data""" + + entryTotal: int = field(init=False, default=0) + entries: list[CutsceneCmdStartAmbience] = field(default_factory=list) + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="start_ambience_list") + + @staticmethod + def from_params(params: list[str]): + new = CutsceneCmdStartAmbienceList() + new.entryTotal = getInteger(params[0]) + return new + + def getCmd(self): + return ( + indent * 2 + + f"CS_START_AMBIENCE_LIST({len(self.entries)}),\n" + + "".join(entry.to_c() for entry in self.entries) + ) + + +@dataclass +class CutsceneCmdFadeOutAmbience(CutsceneCmdBase): + """This class contains modify seq command data""" + + paramNumber: int = field(init=False, default=3) + + @staticmethod + def from_params(params: list[str], enumKey: str): + return CutsceneCmdFadeOutAmbience(getInteger(params[1]), getInteger(params[2])) + + def to_c(self): + return indent * 3 + f"CS_FADE_OUT_AMBIENCE(0, {self.startFrame}, {self.endFrame}),\n" + + +@dataclass +class CutsceneCmdFadeOutAmbienceList(CutsceneCmdBase): + """This class contains modify seq list command data""" + + entryTotal: int = field(init=False, default=0) + entries: list[CutsceneCmdFadeOutAmbience] = field(default_factory=list) + paramNumber: int = field(init=False, default=1) + listName: str = field(init=False, default="fade_out_ambience_list") + + @staticmethod + def from_params(params: list[str]): + new = CutsceneCmdFadeOutAmbienceList() + new.entryTotal = getInteger(params[0]) + return new + + def getCmd(self): + return ( + indent * 2 + + f"CS_FADE_OUT_AMBIENCE_LIST({len(self.entries)}),\n" + + "".join(entry.to_c() for entry in self.entries) + ) From f4e52aae9476dfc60e109f008375a2c1efc45120 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:42:20 +0100 Subject: [PATCH 088/126] fixed "give tatl" showing on oot and fixed ui order --- fast64_internal/data/z64/data.py | 14 ++++++++++---- fast64_internal/z64/cutscene/properties.py | 9 +++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 497420b83..90f598efe 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -507,31 +507,37 @@ # order here sets order on the UI ootEnumCSListType = [ + # Col 1 ("TextList", "Text List", "Textbox", "ALIGN_BOTTOM", 0), ("MiscList", "Misc List", "Misc", "OPTIONS", 7), ("RumbleList", "Rumble List", "Rumble Controller", "OUTLINER_OB_FORCE_FIELD", 8), + # Col 2 ("Transition", "Transition List", "Transition List", "COLORSET_10_VEC", 1), ("LightSettingsList", "Light Settings List", "Lighting", "LIGHT_SUN", 2), ("TimeList", "Time List", "Time", "TIME", 3), + # Col 3 ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), ("StopSeqList", "Stop Seq List", "Stop BGM", "SNAP_FACE", 5), ("FadeOutSeqList", "Fade-Out Seq List", "Fade BGM", "IPO_EASE_IN_OUT", 6), ] mm_enum_cs_list_type = [ + # Col 1 ("TextList", "Text List", "Textbox", "ALIGN_BOTTOM", 0), ("MiscList", "Misc List", "Misc", "OPTIONS", 7), ("RumbleList", "Rumble List", "Rumble Controller", "OUTLINER_OB_FORCE_FIELD", 8), + ("MotionBlurList", "Motion Blur List", "Motion Blur", "ONIONSKIN_ON", 9), + ("CreditsSceneList", "Choose Credits Scene List", "Choose Credits Scene", "WORLD", 11), + # Col 2 ("Transition", "Transition", "Transition", "COLORSET_10_VEC", 1), ("LightSettingsList", "Light Settings List", "Lighting", "LIGHT_SUN", 2), ("TimeList", "Time List", "Time", "TIME", 3), + ("TransitionGeneralList", "Transition General List", "Transition General", "COLORSET_06_VEC", 12), + ("ModifySeqList", "Modify Seq List", "Modify Seq", "IPO_CONSTANT", 10), + # Col 3 ("StartSeqList", "Start Seq List", "Play BGM", "PLAY", 4), ("StopSeqList", "Stop Seq List", "Stop BGM", "SNAP_FACE", 5), ("FadeOutSeqList", "Fade-Out Seq List", "Fade BGM", "IPO_EASE_IN_OUT", 6), - ("MotionBlurList", "Motion Blur List", "Motion Blur", "ONIONSKIN_ON", 9), - ("ModifySeqList", "Modify Seq List", "Modify Seq", "IPO_CONSTANT", 10), - ("CreditsSceneList", "Choose Credits Scene List", "Choose Credits Scene", "WORLD", 11), - ("TransitionGeneralList", "Transition General List", "Transition General", "COLORSET_06_VEC", 12), ("StartAmbienceList", "Start Ambience List", "Start Ambience", "SNAP_FACE", 13), ("FadeOutAmbienceList", "Fade-Out Ambience List", "Fade-Out Ambience", "IPO_EASE_IN_OUT", 14), ] diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index 3ad8d8e72..bec715933 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -555,10 +555,11 @@ def draw_props(self, layout: UILayout, obj: Object): if self.csDestination == "Custom": prop_split(layout_custom.column(), self, "csDestinationCustom", "Cutscene Destination Custom") - b = commandsBox.box() - b.prop(self, "cs_give_tatl") - if self.cs_give_tatl: - b.prop(self, "cs_give_tatl_start_frame") + if not is_oot_features(): + b = commandsBox.box() + b.prop(self, "cs_give_tatl") + if self.cs_give_tatl: + b.prop(self, "cs_give_tatl_start_frame") commandsBox.column_flow(columns=3, align=True).prop(self, "menuTab", expand=True) label = f"Add New {ootCSSubPropToName[self.menuTab]}" From 2e48347079befe1bd4e0ff4a84bdf32e03f0efcb Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 19:10:27 +0100 Subject: [PATCH 089/126] fixed issue where first obj entry is replaced + wrong lightsetting array name --- fast64_internal/data/z64/object_data.py | 13 +++++++++---- fast64_internal/z64/exporter/scene/general.py | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/fast64_internal/data/z64/object_data.py b/fast64_internal/data/z64/object_data.py index f4dccb109..8c42f90ff 100644 --- a/fast64_internal/data/z64/object_data.py +++ b/fast64_internal/data/z64/object_data.py @@ -35,11 +35,13 @@ def __init__(self, game: str): # list of tuples used by Blender's enum properties self.deletedEntry = ("None", "(Deleted from the XML)", "None") lastIndex = max(1, *(obj.index for obj in self.objectList)) - self.ootEnumObjectKey = self.getObjectIDList(lastIndex + 1, False) + self.ootEnumObjectKey = self.getObjectIDList(lastIndex + 1, False, game) # create the legacy object list for old blends if game == "OOT": - self.ootEnumObjectIDLegacy = self.getObjectIDList(self.objects_by_key["obj_timeblock"].index + 1, True) + self.ootEnumObjectIDLegacy = self.getObjectIDList( + self.objects_by_key["obj_timeblock"].index + 1, True, game + ) # validate the legacy list, if there's any None element then something's wrong if self.deletedEntry in self.ootEnumObjectIDLegacy: @@ -47,12 +49,15 @@ def __init__(self, game: str): else: self.ootEnumObjectIDLegacy = [] - def getObjectIDList(self, max: int, isLegacy: bool): + def getObjectIDList(self, max: int, isLegacy: bool, game: str): """Generates and returns the object list in the right order""" objList = [self.deletedEntry] * max for obj in self.objectList: if obj.index < max: identifier = obj.id if isLegacy else obj.key objList[obj.index] = (identifier, obj.name, obj.id) - objList[0] = ("Custom", "Custom Object", "Custom") + if game == "OOT": + objList[0] = ("Custom", "Custom Object", "Custom") + else: + objList.insert(0, ("Custom", "Custom Object", "Custom")) return objList diff --git a/fast64_internal/z64/exporter/scene/general.py b/fast64_internal/z64/exporter/scene/general.py index 168c6bf71..a8ea016a1 100644 --- a/fast64_internal/z64/exporter/scene/general.py +++ b/fast64_internal/z64/exporter/scene/general.py @@ -108,7 +108,7 @@ def new(name: str, props: Z64_SceneHeaderProperty): else: lightList = {str(i): light for i, light in enumerate(props.lightList)} - for name, lightProp in lightList.items(): + for setting_name, lightProp in lightList.items(): try: light1 = ootGetBaseOrCustomLight(lightProp, 0, True, True) light2 = ootGetBaseOrCustomLight(lightProp, 1, True, True) @@ -127,7 +127,7 @@ def new(name: str, props: Z64_SceneHeaderProperty): ) ) except Exception as exc: - raise PluginError(f"In light settings {name}: {exc}") from exc + raise PluginError(f"In light settings {setting_name}: {exc}") from exc return SceneLighting(name, envLightMode, settings) def getCmd(self): From 51f0bb770ede76f1260b99106690231b332e5854 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 19:28:55 +0100 Subject: [PATCH 090/126] fixed wrong values in the actor cs operator --- fast64_internal/z64/tools/operators.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 1334bafae..4dbfa2d86 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -319,17 +319,17 @@ def execute(self, context: Context): entry_data_map = { # CS Cam ID: [Priority, Length, Script Index, Additional CS ID, End SFX, Custom Value, HUD visibility, End Cam, Letterbox Size] - "CS_CAM_ID_GLOBAL_ITEM_OCARINA": [550, -1, -1, 1, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_ITEM_GET": [600, -1, -1, 2, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_ITEM_BOTTLE": [700, -1, -1, 3, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_ITEM_SHOW": [700, -1, -1, 4, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_WARP_PAD_MOON": [500, -1, -1, 5, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION": [400, -1, -1, 6, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_DEATH": [100, -1, -1, 7, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_REVIVE": [200, -1, -1, 8, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_SONG_WARP": [700, -1, -1, 9, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE": [700, -1, -1, 10, 1, "255", 1, 1, 30], - "CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING": [700, -1, -1, -1, 1, "255", 1, 1, 30], + "CS_CAM_ID_GLOBAL_ITEM_OCARINA": [550, -1, -1, 1, 1, "255", 1, 1, 27], + "CS_CAM_ID_GLOBAL_ITEM_GET": [600, -1, -1, 2, 1, "255", 1, 1, 27], + "CS_CAM_ID_GLOBAL_ITEM_BOTTLE": [700, -1, -1, 3, 1, "255", 1, 2, 27], + "CS_CAM_ID_GLOBAL_ITEM_SHOW": [700, -1, -1, 4, 1, "255", 1, 1, 27], + "CS_CAM_ID_GLOBAL_WARP_PAD_MOON": [500, -1, -1, 5, 1, "255", 1, 1, 27], + "CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION": [400, -1, -1, 6, 1, "255", 1, 2, 32], + "CS_CAM_ID_GLOBAL_DEATH": [100, -1, -1, 7, 1, "255", 1, 1, 32], + "CS_CAM_ID_GLOBAL_REVIVE": [200, -1, -1, 8, 1, "255", 1, 1, 32], + "CS_CAM_ID_GLOBAL_SONG_WARP": [700, -1, -1, 9, 1, "255", 1, 1, 32], + "CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE": [700, -1, -1, 10, 1, "255", 1, 1, 32], + "CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING": [900, 135, -1, -1, 1, "1", 1, 1, 32], } for cs_cam_id, data in entry_data_map.items(): From eb6f5bc760714e51eee73f89e974f262ab68f3b9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 12 Jan 2025 19:37:11 +0100 Subject: [PATCH 091/126] workaround for actors for mm --- fast64_internal/z64/actor/properties.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 64f680566..e27a63030 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -609,7 +609,7 @@ def draw_props( paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if self.actor.actor_id != "Custom": + if is_oot_features() and self.actor.actor_id != "Custom": paramBox.prop(self.actor, "eval_params") paramBox.prop(self.actor, "params", text="") else: @@ -672,7 +672,7 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateS paramBox = box.box() paramBox.label(text="Actor Parameter") - if not self.customActor: + if is_oot_features() and not self.customActor: paramBox.prop(self.actor, "eval_params") paramBox.prop(self.actor, "params", text="") else: From cbe91a74773e54ea09fd5c334270b7832e9e63ee Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:00:56 +0100 Subject: [PATCH 092/126] motion blur and transition general preview --- fast64_internal/z64/cutscene/preview.py | 112 ++++++++++++++++++--- fast64_internal/z64/cutscene/properties.py | 21 ++++ 2 files changed, 119 insertions(+), 14 deletions(-) diff --git a/fast64_internal/z64/cutscene/preview.py b/fast64_internal/z64/cutscene/preview.py index 9d3a28830..8e50bdd62 100644 --- a/fast64_internal/z64/cutscene/preview.py +++ b/fast64_internal/z64/cutscene/preview.py @@ -4,6 +4,7 @@ from bpy.types import Scene, Object, Node from bpy.app.handlers import persistent from ...utility import gammaInverse, hexOrDecInt +from ..utility import is_oot_features from .motion.utility import getCutsceneCamera @@ -62,6 +63,7 @@ def setupCompositorNodes(): # get the existing nodes nodeTree = bpy.context.scene.node_tree nodeRenderLayer = nodeComposite = nodeRGBTrans = nodeAlphaOver = nodeRGBMisc = nodeMixRGBMisc = None + node_motion_blur = None for node in nodeTree.nodes.values(): if node.type == "R_LAYERS": nodeRenderLayer = node @@ -75,27 +77,34 @@ def setupCompositorNodes(): nodeAlphaOver = node if node.label == "CSMisc_MixRGB": nodeMixRGBMisc = node + if node.label == "CSMotionBlur": + node_motion_blur = node # create or set the data of each nodes - nodeRenderLayer = getNode(nodeRenderLayer, "CompositorNodeRLayers", "CSPreview_RenderLayer", (-500, 0)) + nodeRenderLayer = getNode(nodeRenderLayer, "CompositorNodeRLayers", "CSPreview_RenderLayer", (-300, 0)) nodeRGBMisc = getNode(nodeRGBMisc, "CompositorNodeRGB", "CSMisc_RGB", (-200, -200)) nodeRGBTrans = getNode(nodeRGBTrans, "CompositorNodeRGB", "CSTrans_RGB", (0, -200)) nodeMixRGBMisc = getNode(nodeMixRGBMisc, "CompositorNodeMixRGB", "CSMisc_MixRGB", (0, 0)) nodeAlphaOver = getNode(nodeAlphaOver, "CompositorNodeAlphaOver", "CSPreview_AlphaOver", (200, 0)) - nodeComposite = getNode(nodeComposite, "CompositorNodeComposite", "CSPreview_Composite", (400, 0)) + node_motion_blur = getNode(node_motion_blur, "CompositorNodeDBlur", "CSMotionBlur", (400, 0)) + nodeComposite = getNode(nodeComposite, "CompositorNodeComposite", "CSPreview_Composite", (600, 0)) # link the nodes together nodeTree.links.new(nodeMixRGBMisc.inputs[1], nodeRenderLayer.outputs[0]) nodeTree.links.new(nodeMixRGBMisc.inputs[2], nodeRGBMisc.outputs[0]) nodeTree.links.new(nodeAlphaOver.inputs[1], nodeMixRGBMisc.outputs[0]) nodeTree.links.new(nodeAlphaOver.inputs[2], nodeRGBTrans.outputs[0]) - nodeTree.links.new(nodeComposite.inputs[0], nodeAlphaOver.outputs[0]) + nodeTree.links.new(node_motion_blur.inputs[0], nodeAlphaOver.outputs[0]) + nodeTree.links.new(nodeComposite.inputs[0], node_motion_blur.outputs[0]) # misc settings nodeMixRGBMisc.use_alpha = True nodeMixRGBMisc.blend_type = "COLOR" bpy.context.scene.ootPreviewSettingsProperty.ootCSPreviewNodesReady = True + # blur settings + node_motion_blur.iterations = 1 + def initFirstFrame(csObj: Object, useNodeFeatures: bool, defaultCam: Object): # set default values for frame 0 @@ -103,6 +112,7 @@ def initFirstFrame(csObj: Object, useNodeFeatures: bool, defaultCam: Object): color = [0.0, 0.0, 0.0, 0.0] bpy.context.scene.node_tree.nodes["CSTrans_RGB"].outputs[0].default_value = color bpy.context.scene.node_tree.nodes["CSMisc_RGB"].outputs[0].default_value = color + bpy.context.scene.node_tree.nodes["CSMotionBlur"].zoom = 0.0 csObj.ootCutsceneProperty.preview.trigger = False csObj.ootCutsceneProperty.preview.isFixedCamSet = False if defaultCam is not None: @@ -118,7 +128,7 @@ def processCurrentFrame(csObj: Object, curFrame: float, useNodeFeatures: bool, c if useNodeFeatures: previewProp = csObj.ootCutsceneProperty.preview - for transitionCmd in csObj.ootCutsceneProperty.preview.transitionList: + for transitionCmd in previewProp.transitionList: startFrame = transitionCmd.startFrame endFrame = transitionCmd.endFrame frameCur = curFrame @@ -150,13 +160,18 @@ def processCurrentFrame(csObj: Object, curFrame: float, useNodeFeatures: bool, c else: alpha = (1.0 - lerp) * linear255 - if "half" in transitionCmd.type: + if transitionCmd.type == "gray_to_black": + color[0] = color[1] = color[2] = (1.0 - lerp) * linear160 + alpha = 1.0 + elif transitionCmd.type == "black_to_gray": + color[0] = color[1] = color[2] = lerp * linear160 + alpha = 1.0 + elif "half" in transitionCmd.type: if "_in_" in transitionCmd.type: alpha = linear255 - ((1.0 - lerp) * linear155) else: alpha = linear255 - (linear155 * lerp) - - if "gray_" in transitionCmd.type or previewProp.trigger: + elif "gray_" in transitionCmd.type or previewProp.trigger: color[0] = color[1] = color[2] = linear160 * alpha elif "red_" in transitionCmd.type: color[0] = linear255 * alpha @@ -168,7 +183,60 @@ def processCurrentFrame(csObj: Object, curFrame: float, useNodeFeatures: bool, c color[3] = alpha bpy.context.scene.node_tree.nodes["CSTrans_RGB"].outputs[0].default_value = color - for miscCmd in csObj.ootCutsceneProperty.preview.miscList: + for trans_general_cmd in previewProp.transition_general_list: + startFrame = trans_general_cmd.startFrame + endFrame = trans_general_cmd.endFrame + frameCur = curFrame + + if is_oot_features(): + bpy.context.scene.node_tree.nodes["CSTrans_RGB"].outputs[0].default_value = (0.0, 0.0, 0.0, 0.0) + break + + if blur_cmd.type == "Unknown": + print("ERROR: Unknown command!") + + if frameCur >= startFrame and endFrame >= frameCur: + color = [0.0, 0.0, 0.0, 0.0] + lerp = getLerp(endFrame, startFrame, frameCur) + linear255 = getColor(255.0) + + if trans_general_cmd.type in {"trans_general_fill_in", "trans_general_fill_out"}: + if trans_general_cmd.type == "trans_general_fill_in": + alpha = linear255 * lerp + else: + alpha = (1.0 - lerp) * linear255 + + color[0] = trans_general_cmd.color[0] * alpha + color[1] = trans_general_cmd.color[1] * alpha + color[2] = trans_general_cmd.color[2] * alpha + color[3] = alpha + bpy.context.scene.node_tree.nodes["CSTrans_RGB"].outputs[0].default_value = color + + for blur_cmd in previewProp.motion_blur_list: + startFrame = blur_cmd.startFrame + endFrame = blur_cmd.endFrame + frameCur = curFrame + + if is_oot_features(): + bpy.context.scene.node_tree.nodes["CSTrans_RGB"].outputs[0].default_value = (0.0, 0.0, 0.0, 0.0) + break + + if blur_cmd.type == "Unknown": + print("ERROR: Unknown command!") + + if frameCur >= startFrame and frameCur <= endFrame: + if blur_cmd.type == "motion_blur_enable": + bpy.context.scene.node_tree.nodes["CSMotionBlur"].zoom = 0.180 + previewProp.blur_reinit = False + elif blur_cmd.type == "motion_blur_disable": + lerp = getLerp(endFrame, startFrame, frameCur) + + if lerp >= 0.9: + bpy.context.scene.node_tree.nodes["CSMotionBlur"].zoom = 0.0 + else: + bpy.context.scene.node_tree.nodes["CSMotionBlur"].zoom = (1.0 - lerp) * 0.18 + + for miscCmd in previewProp.miscList: startFrame = miscCmd.startFrame endFrame = miscCmd.endFrame @@ -177,8 +245,8 @@ def processCurrentFrame(csObj: Object, curFrame: float, useNodeFeatures: bool, c if curFrame == startFrame: if miscCmd.type == "set_locked_viewpoint" and not None in cameraObjects: - bpy.context.scene.camera = cameraObjects[int(csObj.ootCutsceneProperty.preview.isFixedCamSet)] - csObj.ootCutsceneProperty.preview.isFixedCamSet ^= True + bpy.context.scene.camera = cameraObjects[int(previewProp.isFixedCamSet)] + previewProp.isFixedCamSet ^= True elif miscCmd.type == "stop_cutscene": # stop the playback and set the frame to 0 @@ -256,18 +324,34 @@ def cutscenePreviewFrameHandler(scene: Scene): # set preview properties previewProp.miscList.clear() previewProp.transitionList.clear() + previewProp.motion_blur_list.clear() + previewProp.transition_general_list.clear() for item in csObj.ootCutsceneProperty.csLists: if item.listType == "Transition": - newProp = previewProp.transitionList.add() - newProp.startFrame = item.transitionStartFrame - newProp.endFrame = item.transitionEndFrame - newProp.type = item.transitionType + for trans_entry in item.transition_list: + newProp = previewProp.transitionList.add() + newProp.startFrame = trans_entry.startFrame + newProp.endFrame = trans_entry.endFrame + newProp.type = trans_entry.transition_type elif item.listType == "MiscList": for miscEntry in item.miscList: newProp = previewProp.miscList.add() newProp.startFrame = miscEntry.startFrame newProp.endFrame = miscEntry.endFrame newProp.type = miscEntry.csMiscType + elif item.listType == "MotionBlurList": + for blur_entry in item.motion_blur_list: + newProp = previewProp.motion_blur_list.add() + newProp.startFrame = blur_entry.startFrame + newProp.endFrame = blur_entry.endFrame + newProp.type = blur_entry.blur_type + elif item.listType == "TransitionGeneralList": + for trans_general_entry in item.trans_general_list: + newProp = previewProp.transition_general_list.add() + newProp.startFrame = trans_general_entry.startFrame + newProp.endFrame = trans_general_entry.endFrame + newProp.type = trans_general_entry.trans_general_type + newProp.color = trans_general_entry.trans_color # execute the main preview logic curFrame = bpy.context.scene.frame_current diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index bec715933..a52537b69 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -388,14 +388,33 @@ class OOTCutsceneMiscProperty(OOTCutsceneCommandBase, PropertyGroup): type: StringProperty(default="Unknown") +class OOTCutsceneMotionBlurPreviewProperty(OOTCutsceneCommandBase, PropertyGroup): + type: StringProperty(default="Unknown") + + +class OOTCutsceneTransitionGeneralPreviewProperty(OOTCutsceneCommandBase, PropertyGroup): + type: StringProperty(default="Unknown") + color: FloatVectorProperty( + name="Color", + subtype="COLOR", + size=4, + min=0, + max=1, + default=(1, 1, 1, 1), + ) + + class OOTCutscenePreviewProperty(PropertyGroup): transitionList: CollectionProperty(type=OOTCutsceneTransitionProperty) miscList: CollectionProperty(type=OOTCutsceneMiscProperty) + motion_blur_list: CollectionProperty(type=OOTCutsceneMotionBlurPreviewProperty) + transition_general_list: CollectionProperty(type=OOTCutsceneTransitionGeneralPreviewProperty) trigger: BoolProperty(default=False) # for ``CS_TRANS_TRIGGER_INSTANCE`` isFixedCamSet: BoolProperty(default=False) prevFrame: IntProperty(default=-1) nextFrame: IntProperty(default=1) + blur_reinit: BoolProperty(default=True) class OOTCutscenePreviewSettingsProperty(PropertyGroup): @@ -589,6 +608,8 @@ def draw_props(self, layout: UILayout, obj: Object): OOTCSListProperty, OOTCutsceneTransitionProperty, OOTCutsceneMiscProperty, + OOTCutsceneMotionBlurPreviewProperty, + OOTCutsceneTransitionGeneralPreviewProperty, OOTCutscenePreviewProperty, OOTCutscenePreviewSettingsProperty, OOTCutsceneProperty, From f449cac0f395aed2ab40a2b5670e04cdd92401c6 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Mon, 13 Jan 2025 03:20:06 +0100 Subject: [PATCH 093/126] importer start (and update to the new classes) --- fast64_internal/z64/cutscene/constants.py | 56 ---- .../z64/cutscene/importer/classes.py | 261 +++++++++++++----- .../z64/cutscene/importer/functions.py | 6 +- .../z64/exporter/cutscene/__init__.py | 5 + .../z64/exporter/cutscene/actor_cue.py | 5 +- .../z64/exporter/cutscene/camera.py | 2 +- fast64_internal/z64/exporter/cutscene/data.py | 54 ++-- fast64_internal/z64/exporter/cutscene/misc.py | 30 +- fast64_internal/z64/exporter/cutscene/seq.py | 38 +-- fast64_internal/z64/exporter/cutscene/text.py | 31 ++- 10 files changed, 299 insertions(+), 189 deletions(-) diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 1b526764e..088123422 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -266,59 +266,3 @@ ootCSListAndSingleCommands = ootCSSingleCommands + ootCSListCommands ootCSListAndSingleCommands.remove("CS_HEADER") ootCutsceneCommandsC = ootCSSingleCommands + ootCSListCommands + ootCSListEntryCommands - -cmdToClass = { - "CS_CAM_POINT": CutsceneCmdCamPoint, - "CS_MISC": CutsceneCmdMisc, - "CS_LIGHT_SETTING": CutsceneCmdLightSetting, - "CS_TIME": CutsceneCmdTime, - "CS_FADE_OUT_SEQ": CutsceneCmdFadeSeq, - "CS_RUMBLE_CONTROLLER": CutsceneCmdRumbleController, - "CS_TEXT": CutsceneCmdText, - "CS_TEXT_NONE": CutsceneCmdTextNone, - "CS_TEXT_OCARINA_ACTION": CutsceneCmdTextOcarinaAction, - "CS_START_SEQ": CutsceneCmdStartStopSeq, - "CS_STOP_SEQ": CutsceneCmdStartStopSeq, - "CS_ACTOR_CUE": CutsceneCmdActorCue, - "CS_PLAYER_CUE": CutsceneCmdActorCue, - "CS_CAM_EYE_SPLINE": CutsceneCmdCamEyeSpline, - "CS_CAM_AT_SPLINE": CutsceneCmdCamATSpline, - "CS_CAM_EYE_SPLINE_REL_TO_PLAYER": CutsceneCmdCamEyeSplineRelToPlayer, - "CS_CAM_AT_SPLINE_REL_TO_PLAYER": CutsceneCmdCamATSplineRelToPlayer, - "CS_CAM_EYE": CutsceneCmdCamEye, - "CS_CAM_AT": CutsceneCmdCamAT, - "CS_MISC_LIST": CutsceneCmdMiscList, - "CS_TRANSITION": CutsceneCmdTransition, - "CS_TEXT_LIST": CutsceneCmdTextList, - "CS_LIGHT_SETTING_LIST": CutsceneCmdLightSettingList, - "CS_TIME_LIST": CutsceneCmdTimeList, - "CS_FADE_OUT_SEQ_LIST": CutsceneCmdFadeSeqList, - "CS_RUMBLE_CONTROLLER_LIST": CutsceneCmdRumbleControllerList, - "CS_START_SEQ_LIST": CutsceneCmdStartStopSeqList, - "CS_STOP_SEQ_LIST": CutsceneCmdStartStopSeqList, - "CS_ACTOR_CUE_LIST": CutsceneCmdActorCueList, - "CS_PLAYER_CUE_LIST": CutsceneCmdActorCueList, - "CS_DESTINATION": CutsceneCmdDestination, - # from new system - "CS_CAM_SPLINE_LIST": CutsceneCmdCamSplineList, - "CS_CAM_SPLINE": CutsceneCmdCamSpline, - "CS_CAM_POINT_NEW": CutsceneCmdNewCamPoint, - "CS_CAM_MISC": CutsceneCmdCamMisc, - "CS_TRANSITION_LIST": CutsceneCmdTransitionList, - "CS_DESTINATION_LIST": CutsceneCmdDestinationList, - "CS_TEXT_DEFAULT": CutsceneCmdTextGeneric, - "CS_TEXT_TYPE_1": CutsceneCmdTextGeneric, - "CS_TEXT_TYPE_3": CutsceneCmdTextGeneric, - "CS_TEXT_BOSSES_REMAINS": CutsceneCmdTextMask, - "CS_TEXT_ALL_NORMAL_MASKS": CutsceneCmdTextMask, - "CS_MOTION_BLUR_LIST": CutsceneCmdMotionBlurList, - "CS_MOTION_BLUR": CutsceneCmdMotionBlur, - "CS_MODIFY_SEQ_LIST": CutsceneCmdModifySeqList, - "CS_MODIFY_SEQ": CutsceneCmdModifySeq, - "CS_CHOOSE_CREDITS_SCENES_LIST": CutsceneCmdChooseCreditsScenesList, - "CS_CHOOSE_CREDITS_SCENES": CutsceneCmdChooseCreditsScenes, - "CS_TRANSITION_GENERAL_LIST": CutsceneCmdTransitionGeneralList, - "CS_TRANSITION_GENERAL": CutsceneCmdTransitionGeneral, - "CS_GIVE_TATL_LIST": CutsceneCmdGiveTatlList, - "CS_GIVE_TATL": CutsceneCmdGiveTatl, -} diff --git a/fast64_internal/z64/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py index a711d7554..380342cf5 100644 --- a/fast64_internal/z64/cutscene/importer/classes.py +++ b/fast64_internal/z64/cutscene/importer/classes.py @@ -5,6 +5,7 @@ from typing import Optional, TYPE_CHECKING from bpy.types import Object, Armature from ....utility import PluginError +from ...utility import is_oot_features from ..motion.utility import setupCutscene, getBlenderPosition, getInteger if TYPE_CHECKING: @@ -17,20 +18,125 @@ ootCSListEntryCommands, ootCSSingleCommands, ootCSListAndSingleCommands, - cmdToClass, ) from ..classes import ( - CutsceneCmdActorCueList, + CutsceneObjectFactory, +) + +# TODO: move these classes to a common place outside the exporter +from ...exporter.cutscene import Cutscene, CutsceneData +from ...exporter.cutscene.actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue +from ...exporter.cutscene.text import ( + CutsceneCmdTextList, + CutsceneCmdText, + CutsceneCmdTextNone, + CutsceneCmdTextOcarinaAction, +) + +from ...exporter.cutscene.seq import ( + CutsceneCmdStartStopSeqList, + CutsceneCmdFadeSeqList, + CutsceneCmdStartStopSeq, + CutsceneCmdFadeSeq, + CutsceneCmdModifySeq, + CutsceneCmdModifySeqList, + CutsceneCmdStartAmbience, + CutsceneCmdStartAmbienceList, + CutsceneCmdFadeOutAmbience, + CutsceneCmdFadeOutAmbienceList, +) + +from ...exporter.cutscene.misc import ( + CutsceneCmdLightSetting, + CutsceneCmdTime, + CutsceneCmdMisc, + CutsceneCmdRumbleController, + CutsceneCmdDestination, + CutsceneCmdMiscList, + CutsceneCmdRumbleControllerList, + CutsceneCmdTransition, + CutsceneCmdTransitionList, + CutsceneCmdLightSettingList, + CutsceneCmdTimeList, + CutsceneCmdMotionBlur, + CutsceneCmdMotionBlurList, + CutsceneCmdChooseCreditsScenes, + CutsceneCmdChooseCreditsScenesList, + CutsceneCmdTransitionGeneral, + CutsceneCmdTransitionGeneralList, + CutsceneCmdGiveTatl, +) + +from ...exporter.cutscene.camera import ( CutsceneCmdCamPoint, + CutsceneCmdCamEyeSpline, + CutsceneCmdCamATSpline, + CutsceneCmdCamEyeSplineRelToPlayer, + CutsceneCmdCamATSplineRelToPlayer, + CutsceneCmdCamEye, + CutsceneCmdCamAT, CutsceneCmdNewCamPoint, CutsceneCmdCamMisc, - CutsceneCmdCamSpline, CutsceneSplinePoint, - Cutscene, - CutsceneObjectFactory, + CutsceneCmdCamSpline, + CutsceneCmdCamSplineList, ) +cmdToClass = { + "CS_CAM_POINT": CutsceneCmdCamPoint, + "CS_MISC": CutsceneCmdMisc, + "CS_LIGHT_SETTING": CutsceneCmdLightSetting, + "CS_TIME": CutsceneCmdTime, + "CS_FADE_OUT_SEQ": CutsceneCmdFadeSeq, + "CS_RUMBLE_CONTROLLER": CutsceneCmdRumbleController, + "CS_TEXT": CutsceneCmdText, + "CS_TEXT_NONE": CutsceneCmdTextNone, + "CS_TEXT_OCARINA_ACTION": CutsceneCmdTextOcarinaAction, + "CS_START_SEQ": CutsceneCmdStartStopSeq, + "CS_STOP_SEQ": CutsceneCmdStartStopSeq, + "CS_ACTOR_CUE": CutsceneCmdActorCue, + "CS_PLAYER_CUE": CutsceneCmdActorCue, + "CS_CAM_EYE_SPLINE": CutsceneCmdCamEyeSpline, + "CS_CAM_AT_SPLINE": CutsceneCmdCamATSpline, + "CS_CAM_EYE_SPLINE_REL_TO_PLAYER": CutsceneCmdCamEyeSplineRelToPlayer, + "CS_CAM_AT_SPLINE_REL_TO_PLAYER": CutsceneCmdCamATSplineRelToPlayer, + "CS_CAM_EYE": CutsceneCmdCamEye, + "CS_CAM_AT": CutsceneCmdCamAT, + "CS_MISC_LIST": CutsceneCmdMiscList, + "CS_TRANSITION": CutsceneCmdTransition, + "CS_TEXT_LIST": CutsceneCmdTextList, + "CS_LIGHT_SETTING_LIST": CutsceneCmdLightSettingList, + "CS_TIME_LIST": CutsceneCmdTimeList, + "CS_FADE_OUT_SEQ_LIST": CutsceneCmdFadeSeqList, + "CS_RUMBLE_CONTROLLER_LIST": CutsceneCmdRumbleControllerList, + "CS_START_SEQ_LIST": CutsceneCmdStartStopSeqList, + "CS_STOP_SEQ_LIST": CutsceneCmdStartStopSeqList, + "CS_ACTOR_CUE_LIST": CutsceneCmdActorCueList, + "CS_PLAYER_CUE_LIST": CutsceneCmdActorCueList, + "CS_DESTINATION": CutsceneCmdDestination, + # from new system + "CS_CAM_SPLINE_LIST": CutsceneCmdCamSplineList, + "CS_CAM_SPLINE": CutsceneCmdCamSpline, + "CS_CAM_POINT_NEW": CutsceneCmdNewCamPoint, + "CS_CAM_MISC": CutsceneCmdCamMisc, + "CS_TRANSITION_LIST": CutsceneCmdTransitionList, + "CS_TEXT_DEFAULT": CutsceneCmdText, + "CS_TEXT_TYPE_1": CutsceneCmdText, + "CS_TEXT_TYPE_3": CutsceneCmdText, + "CS_TEXT_BOSSES_REMAINS": CutsceneCmdText, + "CS_TEXT_ALL_NORMAL_MASKS": CutsceneCmdText, + "CS_MOTION_BLUR_LIST": CutsceneCmdMotionBlurList, + "CS_MOTION_BLUR": CutsceneCmdMotionBlur, + "CS_MODIFY_SEQ_LIST": CutsceneCmdModifySeqList, + "CS_MODIFY_SEQ": CutsceneCmdModifySeq, + "CS_CHOOSE_CREDITS_SCENES_LIST": CutsceneCmdChooseCreditsScenesList, + "CS_CHOOSE_CREDITS_SCENES": CutsceneCmdChooseCreditsScenes, + "CS_TRANSITION_GENERAL_LIST": CutsceneCmdTransitionGeneralList, + "CS_TRANSITION_GENERAL": CutsceneCmdTransitionGeneral, + "CS_GIVE_TATL": CutsceneCmdGiveTatl, +} + @dataclass class ParsedCutscene: @@ -63,8 +169,10 @@ def getCmdParams(self, data: str, cmdName: str, paramNumber: int): if self.new_cs_system: if cmdName in {"CS_START_SEQ", "CS_FADE_OUT_SEQ", "CS_LIGHT_SETTING"}: paramNumber = 3 - elif cmdName in {"CS_MISC", "CS_STOP_SEQ"}: + elif cmdName in {"CS_MISC", "CS_STOP_SEQ", "CS_TEXT_ALL_NORMAL_MASKS"}: paramNumber = 4 + elif cmdName in {"CS_TEXT_DEFAULT", "CS_TEXT_TYPE_1", "CS_TEXT_TYPE_3", "CS_TEXT_BOSSES_REMAINS"}: + paramNumber = 5 elif cmdName in {"CS_RUMBLE_CONTROLLER"}: paramNumber = 6 @@ -82,9 +190,12 @@ def getCmdParams(self, data: str, cmdName: str, paramNumber: int): ) return params - def getNewCutscene(self, csData: str, name: str): + def getNewCutscene(self, csData: str, name: str, use_macros: bool, motion_only: bool): params = self.getCmdParams(csData, "CS_HEADER", Cutscene.paramNumber) - return Cutscene(name, getInteger(params[0]), getInteger(params[1])) + new_cs = Cutscene.new(name, None, use_macros, motion_only) + new_cs.totalEntries = getInteger(params[0]) + new_cs.frameCount = getInteger(params[1]) + return new_cs def correct_command_lists(self, command: str): """If using the new cs system, moves standalone commands to the proper lists""" @@ -223,7 +334,7 @@ def getParsedCutscenes(self): return parsedCutscenes - def getCutsceneList(self): + def getCutsceneList(self, use_macros: bool, motion_only: bool): """Returns the list of cutscenes with the data processed""" parsedCutscenes = self.getParsedCutscenes() @@ -239,33 +350,36 @@ def getCutsceneList(self): # that will be used later when creating Blender objects to complete the import for parsedCS in parsedCutscenes: cutscene = None + for data in parsedCS.csData: cmdData = data.removesuffix("\n").split("\n") cmdListData = cmdData.pop(0) cmdListName = cmdListData.strip().split("(")[0] - # create a new cutscene data if cmdListName == "CS_HEADER": - cutscene = self.getNewCutscene(data, parsedCS.csName) - - # if we have a cutscene, create and add the commands data in it + # create a new cutscene data + cutscene = self.getNewCutscene(data, parsedCS.csName, use_macros, motion_only) elif cutscene is not None and data.startswith(f"{cmdListName}("): + # if we have a cutscene, create and add the commands data in it isPlayer = cmdListData.startswith("CS_PLAYER_CUE_LIST(") isStartSeq = cmdListData.startswith("CS_START_SEQ_LIST(") isStopSeq = cmdListData.startswith("CS_STOP_SEQ_LIST(") - cmd = cmdToClass.get(cmdListName) - if cmd is not None: - cmdList = getattr(cutscene, "playerCueList" if isPlayer else cmd.listName) + cs_list_raw_cmd = cmdToClass.get(cmdListName) + if cs_list_raw_cmd is not None: + cmdList = getattr(cutscene.data, "playerCueList" if isPlayer else cs_list_raw_cmd.listName) - paramNumber = cmd.paramNumber - 1 if isPlayer else cmd.paramNumber + paramNumber = cs_list_raw_cmd.paramNumber - 1 if isPlayer else cs_list_raw_cmd.paramNumber params = self.getCmdParams(cmdListData, cmdListName, paramNumber) + if isStartSeq or isStopSeq: - commandData = cmd(params, type="start" if isStartSeq else "stop") + new_cs_list_data = cs_list_raw_cmd.from_params( + params, type="start" if isStartSeq else "stop" + ) elif cmdListData.startswith("CS_ACTOR_CUE_LIST(") or isPlayer: - commandData = cmd(params, isPlayer=isPlayer) + new_cs_list_data = cs_list_raw_cmd.from_params(params, isPlayer=isPlayer) else: - commandData = cmd(params) + new_cs_list_data = cs_list_raw_cmd.from_params(params) # treating camera commands separately if using the new cs commands # as it became more complex to parse since it's basically a list in a list in a list @@ -288,31 +402,33 @@ def getCutsceneList(self): entryCmd = cmdToClass[cmdEntryName] params = self.getCmdParams(d, cmdEntryName, entryCmd.paramNumber) - listEntry = entryCmd(params) + listEntry = entryCmd.from_params(params) if cmdEntryName == "CS_CAM_SPLINE": cur_spline_entry = listEntry elif cur_spline_entry is not None: - sub_list_entry = cmdToClass[cmdEntryName] - sub_params = self.getCmdParams(d, cmdEntryName, sub_list_entry.paramNumber) + cs_data_entry_base = cmdToClass[cmdEntryName] + sub_params = self.getCmdParams(d, cmdEntryName, cs_data_entry_base.paramNumber) if cur_point < cur_spline_entry.num_entries: - at_list.append(sub_list_entry(sub_params)) + at_list.append(cs_data_entry_base.from_params(sub_params)) cur_point += 1 elif cur_point < cur_spline_entry.num_entries * 2: - eye_list.append(sub_list_entry(sub_params)) + eye_list.append(cs_data_entry_base.from_params(sub_params)) cur_point += 1 elif cur_point < cur_spline_entry.num_entries * 3: - misc_list.append(sub_list_entry(sub_params)) + misc_list.append(cs_data_entry_base.from_params(sub_params)) cur_point += 1 if cur_point == cur_spline_entry.num_entries * 3: assert len(at_list) == len(eye_list) == len(misc_list) - for at, eye, misc in zip(at_list, eye_list, misc_list): - cur_spline_entry.entries.append(CutsceneSplinePoint(at, eye, misc)) + for i, (at, eye, misc) in enumerate(zip(at_list, eye_list, misc_list)): + if i < len(at_list) - 1: + # ignore the last points, see the exporter to know why + cur_spline_entry.entries.append(CutsceneSplinePoint(at, eye, misc)) - commandData.entries.append(cur_spline_entry) + new_cs_list_data.entries.append(cur_spline_entry) cur_point = 0 at_list.clear() eye_list.clear() @@ -341,15 +457,21 @@ def getCutsceneList(self): entryCmd = cmdToClass[cmdEntryName] params = self.getCmdParams(d, cmdEntryName, entryCmd.paramNumber) - if "CS_LIGHT_SETTING(" in d or isStartSeq or isStopSeq: - listEntry = entryCmd(params, isLegacy=isLegacy) + if "CS_LIGHT_SETTING(" in d: + listEntry = entryCmd.from_params(params, isLegacy) + elif isPlayer: + listEntry = entryCmd.from_params(params, True) + elif isStartSeq or isStopSeq: + listEntry = entryCmd.from_params( + params, "start" if isStartSeq else "stop", isLegacy + ) else: - listEntry = entryCmd(params) - commandData.entries.append(listEntry) + listEntry = entryCmd.from_params(params) + new_cs_list_data.entries.append(listEntry) if cmdListName == "CS_DESTINATION": - cutscene.destination = commandData + cutscene.data.destination = new_cs_list_data else: - cmdList.append(commandData) + cmdList.append(new_cs_list_data) else: print(f"WARNING: `{cmdListName}` is not implemented yet!") @@ -422,9 +544,13 @@ def validateCameraData(self, cutscene: Cutscene): """Safety checks to make sure the camera data is correct""" camLists: list[tuple[str, list, list]] = [ - ("Eye and AT Spline", cutscene.camEyeSplineList, cutscene.camATSplineList), - ("Eye and AT Spline Rel to Player", cutscene.camEyeSplineRelPlayerList, cutscene.camATSplineRelPlayerList), - ("Eye and AT", cutscene.camEyeList, cutscene.camATList), + ("Eye and AT Spline", cutscene.data.camEyeSplineList, cutscene.data.camATSplineList), + ( + "Eye and AT Spline Rel to Player", + cutscene.data.camEyeSplineRelPlayerList, + cutscene.data.camATSplineRelPlayerList, + ), + ("Eye and AT", cutscene.data.camEyeList, cutscene.data.camATList), ] for camType, eyeList, atList in camLists: @@ -527,7 +653,7 @@ def setSubPropertyData(self, subPropsData: dict[str, str], newSubElem, entry): def setPropertyData(self, csProp: "OOTCutsceneProperty", cutscene: Cutscene, propDataList: list[PropertyData]): for data in propDataList: listName = f"{data.listType[0].lower() + data.listType[1:]}List" - dataList = getattr(cutscene, (listName if data.listType != "FadeOutSeq" else "fadeSeqList")) + dataList = getattr(cutscene.data, (listName if data.listType != "FadeOutSeq" else "fadeSeqList")) for list in dataList: newElem: "OOTCSListProperty" = csProp.csLists.add() @@ -565,10 +691,10 @@ def setPropertyData(self, csProp: "OOTCutsceneProperty", cutscene: Cutscene, pro raise PluginError("ERROR: Unknown text type!") self.setSubPropertyData(data.subPropsData, newSubElem, entry) - def setCutsceneData(self, csNumber): + def setCutsceneData(self, csNumber, use_macros: bool, motion_only: bool): """Creates the cutscene empty objects from the file data""" - cutsceneList = self.getCutsceneList() + cutsceneList = self.getCutsceneList(use_macros, motion_only) if cutsceneList is None: # if it's none then there's no cutscene in the file @@ -576,39 +702,46 @@ def setCutsceneData(self, csNumber): for i, cutscene in enumerate(cutsceneList, csNumber): print(f'Found Cutscene "{cutscene.name}"! Importing...') - self.validateCameraData(cutscene) + if is_oot_features(): + self.validateCameraData(cutscene) csName = f"Cutscene.{cutscene.name}" csObj = self.getNewCutsceneObject(csName, cutscene.frameCount, None) csProp = csObj.ootCutsceneProperty csNumber = i - self.setActorCueData(csObj, cutscene.actorCueList, "Actor", i) - self.setActorCueData(csObj, cutscene.playerCueList, "Player", i) + self.setActorCueData(csObj, cutscene.data.actorCueList, "Actor", i) + self.setActorCueData(csObj, cutscene.data.playerCueList, "Player", i) - if len(cutscene.camEyeSplineList) > 0: - lastIndex = self.setCameraShotData( - csObj, cutscene.camEyeSplineList, cutscene.camATSplineList, "splineEyeOrAT", 1, i - ) + if is_oot_features(): + if len(cutscene.data.camEyeSplineList) > 0: + lastIndex = self.setCameraShotData( + csObj, cutscene.data.camEyeSplineList, cutscene.data.camATSplineList, "splineEyeOrAT", 1, i + ) - if len(cutscene.camEyeSplineRelPlayerList) > 0: - lastIndex = self.setCameraShotData( - csObj, - cutscene.camEyeSplineRelPlayerList, - cutscene.camATSplineRelPlayerList, - "splineEyeOrATRelPlayer", - lastIndex, - i, - ) + if len(cutscene.data.camEyeSplineRelPlayerList) > 0: + lastIndex = self.setCameraShotData( + csObj, + cutscene.data.camEyeSplineRelPlayerList, + cutscene.data.camATSplineRelPlayerList, + "splineEyeOrATRelPlayer", + lastIndex, + i, + ) - if len(cutscene.camEyeList) > 0: - lastIndex = self.setCameraShotData( - csObj, cutscene.camEyeList, cutscene.camATList, "eyeOrAT", lastIndex, i - ) + if len(cutscene.data.camEyeList) > 0: + lastIndex = self.setCameraShotData( + csObj, cutscene.data.camEyeList, cutscene.data.camATList, "eyeOrAT", lastIndex, i + ) + + if cutscene.data.destination is not None: + csProp.csUseDestination = True + csProp.csDestinationStartFrame = cutscene.data.destination.startFrame + self.setPropOrCustom(csProp, "csDestination", cutscene.data.destination.id) - if cutscene.destination is not None: + if not is_oot_features() and cutscene.data.give_tatl is not None: csProp.csUseDestination = True - csProp.csDestinationStartFrame = cutscene.destination.startFrame - self.setPropOrCustom(csProp, "csDestination", cutscene.destination.id) + csProp.csDestinationStartFrame = cutscene.data.destination.startFrame + self.setPropOrCustom(csProp, "cs_give_tatl", cutscene.data.give_tatl.giveTatl) propDataList = [ PropertyData("Text", {"textboxType": "id"}, True), diff --git a/fast64_internal/z64/cutscene/importer/functions.py b/fast64_internal/z64/cutscene/importer/functions.py index 6ca73d7bd..4a9ccfab4 100644 --- a/fast64_internal/z64/cutscene/importer/functions.py +++ b/fast64_internal/z64/cutscene/importer/functions.py @@ -9,4 +9,8 @@ def importCutsceneData(filePath: Optional[str], sceneData: Optional[str], csName """Initialises and imports the cutscene data from either a file or the scene data""" # NOTE: ``sceneData`` is the data read when importing a scene csMotionImport = CutsceneImport(filePath, sceneData, csName, not is_oot_features()) - return csMotionImport.setCutsceneData(bpy.context.scene.ootCSNumber) + return csMotionImport.setCutsceneData( + bpy.context.scene.ootCSNumber, + bpy.context.scene.fast64.oot.hackerFeaturesEnabled or bpy.context.scene.fast64.oot.useDecompFeatures, + bpy.context.scene.fast64.oot.exportMotionOnly, + ) diff --git a/fast64_internal/z64/exporter/cutscene/__init__.py b/fast64_internal/z64/exporter/cutscene/__init__.py index 01b9a51b8..a101e400e 100644 --- a/fast64_internal/z64/exporter/cutscene/__init__.py +++ b/fast64_internal/z64/exporter/cutscene/__init__.py @@ -63,6 +63,11 @@ def new(name: Optional[str], csObj: Optional[Object], useMacros: bool, motionOnl cs_prop.play_on_spawn if game_data.z64.is_mm() or not is_oot_features() else None, spawn_flag if game_data.z64.is_mm() or not is_oot_features() else None, ) + else: + # if importing, return a blank cutscene that we will update later + return Cutscene( + name, CutsceneData.new(None, useMacros, motionOnly), 0, 0, useMacros, motionOnly, None, None, None + ) def get_entry(self): return "{ " + f"{self.name}, {self.next_entrance}, {self.spawn}, {self.spawn_flags}" + " }" diff --git a/fast64_internal/z64/exporter/cutscene/actor_cue.py b/fast64_internal/z64/exporter/cutscene/actor_cue.py index 2208266fd..a22837fba 100644 --- a/fast64_internal/z64/exporter/cutscene/actor_cue.py +++ b/fast64_internal/z64/exporter/cutscene/actor_cue.py @@ -18,14 +18,15 @@ class CutsceneCmdActorCue(CutsceneCmdBase): paramNumber: int = field(init=False, default=15) @staticmethod - def from_params(params: list[str]): + def from_params(params: list[str], is_player: bool = False): return CutsceneCmdActorCue( getInteger(params[1]), getInteger(params[2]), - getInteger(params[0]), + CutsceneCmdBase.getEnumValue("cs_player_cue_id", params[0]) if is_player else getInteger(params[0]), [getRotation(params[3]), getRotation(params[4]), getRotation(params[5])], [getInteger(params[6]), getInteger(params[7]), getInteger(params[8])], [getInteger(params[9]), getInteger(params[10]), getInteger(params[11])], + is_player, ) def getCmd(self): diff --git a/fast64_internal/z64/exporter/cutscene/camera.py b/fast64_internal/z64/exporter/cutscene/camera.py index e45cc34e5..3d5f1e9b5 100644 --- a/fast64_internal/z64/exporter/cutscene/camera.py +++ b/fast64_internal/z64/exporter/cutscene/camera.py @@ -268,7 +268,7 @@ class CutsceneCmdCamSplineList: entries: list[CutsceneCmdCamSpline] = field(init=False, default_factory=list) paramNumber: int = 1 - listName: str = "camSplineListNew" + listName: str = "camSplineList" size: int = 0x8 @staticmethod diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 7e3a82285..2169dff85 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -2,7 +2,6 @@ import math from copy import copy -from dataclasses import dataclass, field from typing import Optional, TYPE_CHECKING from bpy.types import Object, Bone from ....utility import PluginError, exportColor @@ -144,23 +143,27 @@ def __init__(self, useMacros: bool, motionOnly: bool): self.fade_out_ambience_list: list[CutsceneCmdFadeOutAmbienceList] = [] @staticmethod - def new(csObj: Object, useMacros: bool, motionOnly: bool): - csProp: "OOTCutsceneProperty" = csObj.ootCutsceneProperty - csObjects = { - "CS Actor Cue List": [], - "CS Player Cue List": [], - "camShot": [], - } + def new(csObj: Optional[Object], useMacros: bool, motionOnly: bool): + newCutsceneData = CutsceneData(useMacros, motionOnly) - for obj in csObj.children_recursive: - if obj.type == "EMPTY" and obj.ootEmptyType in csObjects.keys(): - csObjects[obj.ootEmptyType].append(obj) - elif obj.type == "ARMATURE": - csObjects["camShot"].append(obj) - csObjects["camShot"].sort(key=lambda obj: obj.name) + if csObj is not None: + # when csObj is None it means we're in import context + csProp: "OOTCutsceneProperty" = csObj.ootCutsceneProperty + csObjects = { + "CS Actor Cue List": [], + "CS Player Cue List": [], + "camShot": [], + } + + for obj in csObj.children_recursive: + if obj.type == "EMPTY" and obj.ootEmptyType in csObjects.keys(): + csObjects[obj.ootEmptyType].append(obj) + elif obj.type == "ARMATURE": + csObjects["camShot"].append(obj) + csObjects["camShot"].sort(key=lambda obj: obj.name) + + newCutsceneData.setCutsceneData(csObjects, csProp) - newCutsceneData = CutsceneData(useMacros, motionOnly) - newCutsceneData.setCutsceneData(csObjects, csProp) return newCutsceneData def getOoTRotation(self, obj: Object): @@ -243,17 +246,16 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool if actionID is None: actionID = childObj.ootCSMotionProperty.actorCueProp.cueActionID - newActorCueList.entries.append( - CutsceneCmdActorCue( - startFrame, - endFrame, - actionID, - self.getOoTRotation(childObj), - self.getOoTPosition(childObj.location), - self.getOoTPosition(obj.children[i].location), - isPlayer, - ) + new_entry = CutsceneCmdActorCue( + startFrame, + endFrame, + actionID, + self.getOoTRotation(childObj), + self.getOoTPosition(childObj.location), + self.getOoTPosition(obj.children[i].location), ) + new_entry.isPlayer = isPlayer + newActorCueList.entries.append(new_entry) self.actorCueList.append(newActorCueList) diff --git a/fast64_internal/z64/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py index a4f71d83f..0c45cc11a 100644 --- a/fast64_internal/z64/exporter/cutscene/misc.py +++ b/fast64_internal/z64/exporter/cutscene/misc.py @@ -116,7 +116,7 @@ class CutsceneCmdMiscList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdMiscList() + new = CutsceneCmdMiscList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -139,7 +139,7 @@ class CutsceneCmdLightSettingList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdLightSettingList() + new = CutsceneCmdLightSettingList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -162,7 +162,7 @@ class CutsceneCmdTimeList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdTimeList() + new = CutsceneCmdTimeList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -185,7 +185,7 @@ class CutsceneCmdRumbleControllerList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdRumbleControllerList() + new = CutsceneCmdRumbleControllerList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -254,7 +254,9 @@ class CutsceneCmdTransitionList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - return CutsceneCmdTransitionList(getInteger(params[0])) + new = CutsceneCmdTransitionList(None, None) + new.entryTotal = getInteger(params[0]) + return new def getCmd(self): if game_data.z64.is_oot(): @@ -277,9 +279,9 @@ class CutsceneCmdMotionBlur(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): return CutsceneCmdMotionBlur( - CutsceneCmdBase.getEnumValue("cs_motion_blur_type", params[0]), getInteger(params[1]), getInteger(params[2]), + CutsceneCmdBase.getEnumValue("cs_motion_blur_type", params[0]), ) def to_c(self): @@ -297,7 +299,9 @@ class CutsceneCmdMotionBlurList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - return CutsceneCmdMotionBlurList(getInteger(params[0])) + new = CutsceneCmdMotionBlurList(None, None) + new.entryTotal = getInteger(params[0]) + return new def getCmd(self): return ( @@ -317,9 +321,9 @@ class CutsceneCmdChooseCreditsScenes(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): return CutsceneCmdChooseCreditsScenes( - CutsceneCmdBase.getEnumValue("cs_credits_scene_type", params[0]), getInteger(params[1]), getInteger(params[2]), + CutsceneCmdBase.getEnumValue("cs_credits_scene_type", params[0]), ) def to_c(self): @@ -337,7 +341,9 @@ class CutsceneCmdChooseCreditsScenesList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - return CutsceneCmdChooseCreditsScenesList(getInteger(params[0])) + new = CutsceneCmdChooseCreditsScenesList(None, None) + new.entryTotal = getInteger(params[0]) + return new def getCmd(self): return ( @@ -360,7 +366,7 @@ def from_params(params: list[str]): return CutsceneCmdTransitionGeneral( getInteger(params[1]), getInteger(params[2]), - CutsceneCmdBase.getEnumValue("cs_transition_general", 0), + CutsceneCmdBase.getEnumValue("cs_transition_general", params[0]), [getInteger(params[3]), getInteger(params[4]), getInteger(params[5])], ) @@ -380,7 +386,9 @@ class CutsceneCmdTransitionGeneralList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - return CutsceneCmdTransitionGeneralList(getInteger(params[0])) + new = CutsceneCmdTransitionGeneralList(None, None) + new.entryTotal = getInteger(params[0]) + return new def getCmd(self): return ( diff --git a/fast64_internal/z64/exporter/cutscene/seq.py b/fast64_internal/z64/exporter/cutscene/seq.py index b2240f7be..0d58d8347 100644 --- a/fast64_internal/z64/exporter/cutscene/seq.py +++ b/fast64_internal/z64/exporter/cutscene/seq.py @@ -15,10 +15,12 @@ class CutsceneCmdStartStopSeq(CutsceneCmdBase): type: Optional[str] = field(init=False, default=None) # "start" or "stop" @staticmethod - def from_params(params: list[str], isLegacy: bool): - return CutsceneCmdFadeSeq( - getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("seq_id", params[0], isLegacy) - ) + def from_params(params: list[str], type: str, is_legacy: bool): + new = CutsceneCmdStartStopSeq(getInteger(params[1]), getInteger(params[2])) + new.isLegacy = is_legacy + new.seqId = CutsceneCmdBase.getEnumValue("seq_id", params[0], new.isLegacy) + new.type = type + return new def getCmd(self): self.validateFrames() @@ -33,13 +35,12 @@ class CutsceneCmdFadeSeq(CutsceneCmdBase): seqPlayer: str = field(init=False, default=str()) paramNumber: int = field(init=False, default=11) - enumKey: str = field(init=False, default="csFadeOutSeqPlayer") @staticmethod - def from_params(params: list[str], enumKey: str): - return CutsceneCmdFadeSeq( - getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue(enumKey, params[0]) - ) + def from_params(params: list[str]): + new = CutsceneCmdFadeSeq(getInteger(params[1]), getInteger(params[2])) + new.seqPlayer = CutsceneCmdBase.getEnumValue("cs_fade_out_seq_player", params[0]) + return new def getCmd(self): self.validateFrames() @@ -57,9 +58,10 @@ class CutsceneCmdStartStopSeqList(CutsceneCmdBase): listName: str = field(init=False, default="seqList") @staticmethod - def from_params(params: list[str]): - new = CutsceneCmdStartStopSeqList() + def from_params(params: list[str], type: str): + new = CutsceneCmdStartStopSeqList(None, None) new.entryTotal = getInteger(params[0]) + new.type = type return new def getCmd(self): @@ -81,7 +83,7 @@ class CutsceneCmdFadeSeqList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdFadeSeqList() + new = CutsceneCmdFadeSeqList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -101,7 +103,7 @@ class CutsceneCmdModifySeq(CutsceneCmdBase): paramNumber: int = field(init=False, default=3) @staticmethod - def from_params(params: list[str], enumKey: str): + def from_params(params: list[str]): return CutsceneCmdModifySeq( getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_modify_seq_type", params[0]) ) @@ -121,7 +123,7 @@ class CutsceneCmdModifySeqList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdModifySeqList() + new = CutsceneCmdModifySeqList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -138,7 +140,7 @@ class CutsceneCmdStartAmbience(CutsceneCmdBase): paramNumber: int = field(init=False, default=3) @staticmethod - def from_params(params: list[str], enumKey: str): + def from_params(params: list[str]): return CutsceneCmdStartAmbience(getInteger(params[1]), getInteger(params[2])) def to_c(self): @@ -156,7 +158,7 @@ class CutsceneCmdStartAmbienceList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdStartAmbienceList() + new = CutsceneCmdStartAmbienceList(None, None) new.entryTotal = getInteger(params[0]) return new @@ -175,7 +177,7 @@ class CutsceneCmdFadeOutAmbience(CutsceneCmdBase): paramNumber: int = field(init=False, default=3) @staticmethod - def from_params(params: list[str], enumKey: str): + def from_params(params: list[str]): return CutsceneCmdFadeOutAmbience(getInteger(params[1]), getInteger(params[2])) def to_c(self): @@ -193,7 +195,7 @@ class CutsceneCmdFadeOutAmbienceList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdFadeOutAmbienceList() + new = CutsceneCmdFadeOutAmbienceList(None, None) new.entryTotal = getInteger(params[0]) return new diff --git a/fast64_internal/z64/exporter/cutscene/text.py b/fast64_internal/z64/exporter/cutscene/text.py index d65256ce7..87771892e 100644 --- a/fast64_internal/z64/exporter/cutscene/text.py +++ b/fast64_internal/z64/exporter/cutscene/text.py @@ -1,4 +1,5 @@ from dataclasses import dataclass, field +from typing import Optional from ....utility import PluginError, indent from ...utility import is_oot_features from ...cutscene.motion.utility import getInteger @@ -10,7 +11,7 @@ class CutsceneCmdText(CutsceneCmdBase): """This class contains Text command data""" textId: int - type: str + type: Optional[str] altTextId1: int altTextId2: int @@ -19,14 +20,24 @@ class CutsceneCmdText(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - return CutsceneCmdText( - getInteger(params[1]), - getInteger(params[2]), - getInteger(params[0]), - CutsceneCmdBase.getEnumValue("cs_text_type", params[3]), - getInteger(params[4]), - getInteger(params[5]), - ) + if is_oot_features(): + return CutsceneCmdText( + getInteger(params[1]), + getInteger(params[2]), + getInteger(params[0]), + CutsceneCmdBase.getEnumValue("cs_text_type", params[3]), + getInteger(params[4]), + getInteger(params[5]), + ) + else: + return CutsceneCmdText( + getInteger(params[1]), + getInteger(params[2]), + getInteger(params[0]), + None, + getInteger(params[3]), + getInteger(params[4]), + ) def getCmd(self): self.validateFrames() @@ -108,7 +119,7 @@ class CutsceneCmdTextList(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): - new = CutsceneCmdTextList() + new = CutsceneCmdTextList(None, None) new.entryTotal = getInteger(params[0]) return new From 7aac90b5b51de53320eb6c6232f0b3f53eabf686 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:44:56 +0100 Subject: [PATCH 094/126] cutscene work? idk idr it's been too long lol --- .../z64/cutscene/importer/classes.py | 49 +++++++++++++++++++ .../z64/cutscene/motion/utility.py | 13 +++-- .../z64/exporter/cutscene/camera.py | 2 +- fast64_internal/z64/exporter/utility.py | 4 ++ fast64_internal/z64/importer/scene_header.py | 9 +--- fast64_internal/z64/utility.py | 8 +++ 6 files changed, 71 insertions(+), 14 deletions(-) diff --git a/fast64_internal/z64/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py index 380342cf5..a0f008859 100644 --- a/fast64_internal/z64/cutscene/importer/classes.py +++ b/fast64_internal/z64/cutscene/importer/classes.py @@ -25,6 +25,7 @@ ) # TODO: move these classes to a common place outside the exporter +from ...exporter.utility import Utility from ...exporter.cutscene import Cutscene, CutsceneData from ...exporter.cutscene.actor_cue import CutsceneCmdActorCueList, CutsceneCmdActorCue from ...exporter.cutscene.text import ( @@ -624,6 +625,51 @@ def setCameraShotData( return endIndex + 1 + def create_camera_shots(self, cs_obj: Object, spline_list: list[CutsceneCmdCamSplineList], cs_nbr: int): + scale = bpy.context.scene.ootBlenderScale + i = 0 + + # this is required to be able to change the object mode + if bpy.context.mode != "OBJECT": + bpy.ops.object.mode_set(mode="OBJECT") + + for splines in spline_list: + start_index = i + + for i, spline in enumerate(splines.entries, start_index): + new_shot = self.getNewArmatureObject(f"CS_{cs_nbr:02}.Camera Shot {i:02}", True, cs_obj) + shot_props = new_shot.data.ootCamShotProp + armature_data: Armature = new_shot.data + + shot_props.shot_duration = spline.duration + # TODO: move this to the bones? + first_entry = spline.entries[0] + self.setPropOrCustom( + shot_props, + "shot_interp_type", + Utility.enum_id_to_key(first_entry.at.interp_type, "cs_spline_interp_type"), + ) + self.setPropOrCustom( + shot_props, + "shot_spline_rel_to", + Utility.enum_id_to_key(first_entry.at.relative_to, "cs_spline_rel"), + ) + + for j, point in enumerate(spline.entries): + bpy.ops.object.mode_set(mode="EDIT") + boneName = f"CS_{cs_nbr:02}.Camera Point {j:02}" + new_edit_bone = armature_data.edit_bones.new(boneName) + new_edit_bone.head = getBlenderPosition(point.eye.pos, scale) + new_edit_bone.tail = getBlenderPosition(point.at.pos, scale) + bpy.ops.object.mode_set(mode="OBJECT") + new_bone = armature_data.bones[boneName] + + # using the "AT" (look-at) data since this is what determines where the camera is looking + # the "Eye" only sets the location of the camera + new_bone.ootCamShotPointProp.shot_point_duration = point.at.duration + new_bone.ootCamShotPointProp.shotPointViewAngle = point.misc.viewAngle + new_bone.ootCamShotPointProp.shotPointRoll = point.misc.camRoll + def setPropOrCustom(self, prop, propName: str, value): try: setattr(prop, propName, value) @@ -732,6 +778,9 @@ def setCutsceneData(self, csNumber, use_macros: bool, motion_only: bool): lastIndex = self.setCameraShotData( csObj, cutscene.data.camEyeList, cutscene.data.camATList, "eyeOrAT", lastIndex, i ) + else: + if len(cutscene.data.camSplineList) > 0: + self.create_camera_shots(csObj, cutscene.data.camSplineList, i) if cutscene.data.destination is not None: csProp.csUseDestination = True diff --git a/fast64_internal/z64/cutscene/motion/utility.py b/fast64_internal/z64/cutscene/motion/utility.py index 4b9a5fedc..e46496675 100644 --- a/fast64_internal/z64/cutscene/motion/utility.py +++ b/fast64_internal/z64/cutscene/motion/utility.py @@ -4,7 +4,7 @@ from bpy.types import Object, Bone, Context, EditBone, Armature from mathutils import Vector from ....utility import yUpToZUp -from ...utility import ootParseRotation +from ...utility import ootParseRotation, twos_complement class BoneData: @@ -84,14 +84,17 @@ def getBlenderPosition(pos: list[int], scale: int): return [float(pos[0]) / scale, -float(pos[2]) / scale, float(pos[1]) / scale] -def getInteger(number: str): +def getInteger(number: str, is_mm: bool = False): """Returns an int number (handles properly negative hex numbers)""" if number.startswith("0x"): - number = number.removeprefix("0x") + if is_mm: + return twos_complement(number, 16) + else: + number = number.removeprefix("0x") - # ``"0" * (8 - len(number)`` adds the missing zeroes (if necessary) to have a 8 digit hex number - return unpack("!i", bytes.fromhex("0" * (8 - len(number)) + number))[0] + # ``"0" * (8 - len(number)`` adds the missing zeroes (if necessary) to have a 8 digit hex number + return unpack("!i", bytes.fromhex("0" * (8 - len(number)) + number))[0] else: return int(number) diff --git a/fast64_internal/z64/exporter/cutscene/camera.py b/fast64_internal/z64/exporter/cutscene/camera.py index 3d5f1e9b5..c26c1d78c 100644 --- a/fast64_internal/z64/exporter/cutscene/camera.py +++ b/fast64_internal/z64/exporter/cutscene/camera.py @@ -180,7 +180,7 @@ def from_params(params: list[str]): params[0], getInteger(params[1]), getInteger(params[2]), - [getInteger(params[3]), getInteger(params[4]), getInteger(params[5])], + [getInteger(params[3], True), getInteger(params[4], True), getInteger(params[5], True)], params[6], ) diff --git a/fast64_internal/z64/exporter/utility.py b/fast64_internal/z64/exporter/utility.py index 37964b951..ca9d4f9a5 100644 --- a/fast64_internal/z64/exporter/utility.py +++ b/fast64_internal/z64/exporter/utility.py @@ -78,6 +78,10 @@ def getPropValue(data, prop_name: str, custom_name: Optional[str] = None, enum_k return getattr(data, f"{prop_name}Custom") + @staticmethod + def enum_id_to_key(enum_value_id: str, enum_key: str): + return game_data.z64.enums.enumByKey[enum_key].item_by_id[enum_value_id].key + @staticmethod def getConvertedTransformWithOrientation( transform: Matrix, dataHolder: Object, obj: Object, orientation: Quaternion | Matrix diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index a854a03bb..f5a67c1c3 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -18,6 +18,7 @@ getObjectList, getEnumIndex, get_new_empty_object, + twos_complement, ) from .constants import headerNames from .utility import getDataMatch, stripName @@ -244,14 +245,6 @@ def parseAlternateSceneHeaders( ) -# from https://stackoverflow.com/a/6727975 -def twos_complement(hexstr: str, bits: int): - value = int(hexstr, 16) - if value & (1 << (bits - 1)): - value -= 1 << bits - return value - - def parse_mm_map_data(scene_header, scene_data: str, list_name: str): data_match = getDataMatch(scene_data, list_name, ["MapDataScene", "MinimapList"], "minimap scene", False) scene_map_data = data_match.strip().split(", ") diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index d9e5b6d97..6a3fd43a0 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -1254,3 +1254,11 @@ def get_actor_prop_from_obj(actor_obj: Object) -> "Z64_ActorProperty": raise PluginError(f"ERROR: Empty type not supported: {actor_obj.ootEmptyType}") return actor_prop + + +# from https://stackoverflow.com/a/6727975 +def twos_complement(hexstr: str, bits: int): + value = int(hexstr, 16) + if value & (1 << (bits - 1)): + value -= 1 << bits + return value From 2699465a7868b5de0f7decd4e857b4900f01ada9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 13 Mar 2025 22:15:56 +0100 Subject: [PATCH 095/126] fixed export issues (cs related and actor params) --- fast64_internal/z64/exporter/cutscene/data.py | 2 +- fast64_internal/z64/exporter/room/header.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fast64_internal/z64/exporter/cutscene/data.py b/fast64_internal/z64/exporter/cutscene/data.py index 2169dff85..5f5b2b0e5 100644 --- a/fast64_internal/z64/exporter/cutscene/data.py +++ b/fast64_internal/z64/exporter/cutscene/data.py @@ -253,8 +253,8 @@ def setActorCueListData(self, csObjects: dict[str, list[Object]], isPlayer: bool self.getOoTRotation(childObj), self.getOoTPosition(childObj.location), self.getOoTPosition(obj.children[i].location), + isPlayer, ) - new_entry.isPlayer = isPlayer newActorCueList.entries.append(new_entry) self.actorCueList.append(newActorCueList) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 42a453c17..469e2d3bc 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -265,7 +265,13 @@ def new( ) actor.pos = pos - actor.params = actorProp.params if actorProp.actor_id != "Custom" else actorProp.params_custom + + # force custom params for MM (temp solution until the xml is documented properly) + if is_oot_features() and actorProp.actor_id != "Custom": + actor.params = actorProp.params + else: + actor.params = actorProp.params_custom + actorList.append(actor) return RoomActors(name, actorList) From 238231189673ddc9e97855929d3ca0230ac88002 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 13 Mar 2025 22:17:16 +0100 Subject: [PATCH 096/126] specifically check for oot and not oot features --- fast64_internal/z64/exporter/room/header.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 469e2d3bc..05cfd481f 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -267,7 +267,7 @@ def new( actor.pos = pos # force custom params for MM (temp solution until the xml is documented properly) - if is_oot_features() and actorProp.actor_id != "Custom": + if game_data.z64.is_oot() and actorProp.actor_id != "Custom": actor.params = actorProp.params else: actor.params = actorProp.params_custom From c115c1cda9082e4df17c51985eaa0dcd4974f13c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 14 Mar 2025 00:41:42 +0100 Subject: [PATCH 097/126] fix entrance actors --- fast64_internal/z64/exporter/scene/actors.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index c7cc18a97..97f9b2eaf 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -175,7 +175,12 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f}), 0x00)" for r in rot ) - entranceActor.params = actorProp.params if not entranceProp.customActor else actorProp.params_custom + # force custom params for MM (temp solution until the xml is documented properly) + if game_data.z64.is_oot() and not entranceProp.customActor: + entranceActor.params = actorProp.params + else: + entranceActor.params = actorProp.params_custom + if entranceProp.tiedRoom is not None: entranceActor.roomIndex = entranceProp.tiedRoom.ootRoomHeader.roomIndex else: From b9e059c6d37598f61107372bd47f764b83bc5619 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 14 Mar 2025 01:02:31 +0100 Subject: [PATCH 098/126] I think this should fix rotations for mm --- fast64_internal/z64/exporter/room/header.py | 6 +++++- fast64_internal/z64/exporter/scene/actors.py | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index 05cfd481f..fb9342a32 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -170,7 +170,11 @@ def get_rotation_values(actorProp: Z64_ActorProperty, blender_rot_values: list[i # Figure out which rotation to export, Blender's or the override custom = "_custom" if actorProp.actor_id == "Custom" else "" rot_values = [getattr(actorProp, f"rot_{rot}{custom}") for rot in ["x", "y", "z"]] - export_rot_values = [f"DEG_TO_BINANG({(rot * (180 / 0x8000)):.3f})" for rot in blender_rot_values] + + if game_data.z64.is_oot(): + export_rot_values = [f"DEG_TO_BINANG({(rot * (180 / 0x8000)):.3f})" for rot in blender_rot_values] + else: + export_rot_values = [f"{(rot * (180 / 0x8000)):.3f}" for rot in blender_rot_values] if actorProp.actor_id == "Custom": export_rot_values = rot_values if actorProp.rot_override else export_rot_values diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 97f9b2eaf..90e159e88 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -171,8 +171,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if is_oot_features(): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: + # MM seems to use degrees directly entranceActor.rot = ", ".join( - f"SPAWN_ROT_FLAGS(DEG_TO_BINANG({(r * (180 / 0x8000)):.3f}), 0x00)" for r in rot + f"SPAWN_ROT_FLAGS({(r * (180 / 0x8000)):.3f}, 0x00)" for r in rot ) # force custom params for MM (temp solution until the xml is documented properly) From 29f35db590c34ca94213125170ec7082b39ec01e Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 14 Mar 2025 01:12:08 +0100 Subject: [PATCH 099/126] ok actually fix the thing --- fast64_internal/z64/exporter/room/header.py | 2 +- fast64_internal/z64/exporter/scene/actors.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index fb9342a32..a4b818fe6 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -174,7 +174,7 @@ def get_rotation_values(actorProp: Z64_ActorProperty, blender_rot_values: list[i if game_data.z64.is_oot(): export_rot_values = [f"DEG_TO_BINANG({(rot * (180 / 0x8000)):.3f})" for rot in blender_rot_values] else: - export_rot_values = [f"{(rot * (180 / 0x8000)):.3f}" for rot in blender_rot_values] + export_rot_values = [f"{round(rot * (180 / 0x8000))}" for rot in blender_rot_values] if actorProp.actor_id == "Custom": export_rot_values = rot_values if actorProp.rot_override else export_rot_values diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 90e159e88..8e3d05195 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -172,9 +172,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.rot = ", ".join(f"DEG_TO_BINANG({(r * (180 / 0x8000)):.3f})" for r in rot) else: # MM seems to use degrees directly - entranceActor.rot = ", ".join( - f"SPAWN_ROT_FLAGS({(r * (180 / 0x8000)):.3f}, 0x00)" for r in rot - ) + entranceActor.rot = ", ".join(f"SPAWN_ROT_FLAGS({round(r * (180 / 0x8000))}, 0x00)" for r in rot) # force custom params for MM (temp solution until the xml is documented properly) if game_data.z64.is_oot() and not entranceProp.customActor: From d0b7fdd714b6ab3d8629475da901cb44f797db55 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 00:00:28 +0200 Subject: [PATCH 100/126] fixed init issues --- fast64_internal/z64/__init__.py | 4 ++-- fast64_internal/z64/actor_cutscene/properties.py | 3 ++- fast64_internal/z64/animated_mats/properties.py | 3 ++- fast64_internal/z64/cutscene/motion/operators.py | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index a585b66c5..0dfef0112 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -214,8 +214,8 @@ def oot_register(registerPanels: bool, register_ops: bool = True): oot_operator_register() collections_register() - collision_ops_register() # register first, so panel goes above mat panel - collision_props_register() + + collision_props_register() # register first, so panel goes above mat panel cutscene_props_register() scene_props_register() room_props_register() diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py index d559df939..e7c9d4ceb 100644 --- a/fast64_internal/z64/actor_cutscene/properties.py +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -10,7 +10,8 @@ from bpy.utils import register_class, unregister_class from bpy.types import PropertyGroup, UILayout, Object from ...utility import prop_split -from ..utility import drawCollectionOps, drawAddButton, get_list_tab_text +from ..collection_utility import drawAddButton, drawCollectionOps +from ..utility import get_list_tab_text from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty diff --git a/fast64_internal/z64/animated_mats/properties.py b/fast64_internal/z64/animated_mats/properties.py index 5c4edff49..6d7b433d9 100644 --- a/fast64_internal/z64/animated_mats/properties.py +++ b/fast64_internal/z64/animated_mats/properties.py @@ -10,7 +10,8 @@ from bpy.utils import register_class, unregister_class from bpy.types import PropertyGroup, UILayout, Object from ...utility import prop_split -from ..utility import drawCollectionOps, drawAddButton, get_list_tab_text +from ..collection_utility import drawAddButton, drawCollectionOps +from ..utility import get_list_tab_text # no custom since we only need to know where to export the data diff --git a/fast64_internal/z64/cutscene/motion/operators.py b/fast64_internal/z64/cutscene/motion/operators.py index f17a98a01..ec1643e58 100644 --- a/fast64_internal/z64/cutscene/motion/operators.py +++ b/fast64_internal/z64/cutscene/motion/operators.py @@ -1,6 +1,6 @@ import bpy -from bpy.types import Object, Operator, Armature +from bpy.types import Object, Operator, Armature, Context from bpy.utils import register_class, unregister_class from bpy.props import StringProperty, EnumProperty, BoolProperty import mathutils From 64b1f6095dedd15efe7bfff61bf342d6a9ca655b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 00:11:48 +0200 Subject: [PATCH 101/126] fixed other issues --- fast64_internal/z64/__init__.py | 1 - fast64_internal/z64/cutscene/preview.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 0dfef0112..92ff7b07f 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -268,7 +268,6 @@ def oot_unregister(unregisterPanels: bool, unregister_ops: bool = True): animated_mats_unregister() oot_operator_unregister() collections_unregister() - collision_ops_unregister() # register first, so panel goes above mat panel collision_props_unregister() oot_obj_unregister() cutscene_props_unregister() diff --git a/fast64_internal/z64/cutscene/preview.py b/fast64_internal/z64/cutscene/preview.py index b8ff347de..ea9efbcd1 100644 --- a/fast64_internal/z64/cutscene/preview.py +++ b/fast64_internal/z64/cutscene/preview.py @@ -199,7 +199,7 @@ def processCurrentFrame(csObj: Object, curFrame: float, useNodeFeatures: bool, c bpy.context.scene.node_tree.nodes["CSTrans_RGB"].outputs[0].default_value = (0.0, 0.0, 0.0, 0.0) break - if blur_cmd.type == "Unknown": + if trans_general_cmd.type == "Unknown": print("ERROR: Unknown command!") if frameCur >= startFrame and endFrame >= frameCur: From 4b1cc9c220992beb23eafbc59d3f5a78d0b49df5 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 03:17:21 +0200 Subject: [PATCH 102/126] random things --- fast64_internal/z64/__init__.py | 6 ++++++ fast64_internal/z64/actor_cutscene/properties.py | 2 +- fast64_internal/z64/collision/properties.py | 2 +- fast64_internal/z64/exporter/room/header.py | 6 +++--- fast64_internal/z64/exporter/scene/actors.py | 4 ++-- fast64_internal/z64/file_settings.py | 2 +- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 92ff7b07f..256b91e21 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -135,6 +135,12 @@ def is_globalh_present(self): global_h_path = decomp_path / "include" / "global.h" return global_h_path.exists() + + def can_use_new_actor_panel(self): + if game_data.z64.is_mm(): + return False + + return self.use_new_actor_panel useDecompFeatures: bpy.props.BoolProperty( name="Use decomp for export", description="Use names and macros from decomp when exporting", default=True diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py index e7c9d4ceb..ca2733287 100644 --- a/fast64_internal/z64/actor_cutscene/properties.py +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -109,7 +109,7 @@ class Z64_ActorCutscene(PropertyGroup): def draw_props(self, layout: UILayout, owner: Object, index: int): layout = layout.column() layout.prop( - self, "show_item", text=f"Entry No. {index + 1}", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT" + self, "show_item", text=f"Entry No. {index + 1} (Array Index {index})", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT" ) if self.show_item: diff --git a/fast64_internal/z64/collision/properties.py b/fast64_internal/z64/collision/properties.py index 422c4c467..eb9ce3fcd 100644 --- a/fast64_internal/z64/collision/properties.py +++ b/fast64_internal/z64/collision/properties.py @@ -57,7 +57,7 @@ def draw_props(self, layout: UILayout, cameraObj: Object): layout.prop(self, "hasPositionData") layout.prop(self, "use_setting_default_fov") - if self.hasPositionData: + if not self.is_actor_cs_cam and self.hasPositionData: if not self.use_setting_default_fov: prop_split(layout, cameraObj.data, "angle", "Field Of View") prop_split(layout, self, "bgImageOverrideIndex", "BG Index Override") diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index d0022dfc1..df3fd99eb 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -169,7 +169,7 @@ class RoomActors: def get_rotation_values(actorProp: Z64_ActorProperty, blender_rot_values: list[int]): # Figure out which rotation to export, Blender's or the override custom = ( - "_custom" if not bpy.context.scene.fast64.oot.use_new_actor_panel or actorProp.actor_id == "Custom" else "" + "_custom" if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or actorProp.actor_id == "Custom" else "" ) rot_values = [getattr(actorProp, f"rot_{rot}{custom}") for rot in ["x", "y", "z"]] @@ -178,7 +178,7 @@ def get_rotation_values(actorProp: Z64_ActorProperty, blender_rot_values: list[i else: export_rot_values = [f"{round(rot * (180 / 0x8000))}" for rot in blender_rot_values] - if not bpy.context.scene.fast64.oot.use_new_actor_panel or actorProp.actor_id == "Custom": + if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or actorProp.actor_id == "Custom": export_rot_values = rot_values if actorProp.rot_override else export_rot_values else: for i, rot in enumerate(["X", "Y", "Z"]): @@ -273,7 +273,7 @@ def new( actor.pos = pos # force custom params for MM (temp solution until the xml is documented properly) - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.use_new_actor_panel and actorProp.actor_id != "Custom": + if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and actorProp.actor_id != "Custom": actor.params = actorProp.params else: actor.params = actorProp.params_custom diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 3810bb2a2..a1d932b13 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -99,7 +99,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.params = ( actorProp.params - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.use_new_actor_panel and actorProp.actor_id != "Custom" + if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and actorProp.actor_id != "Custom" else actorProp.params_custom ) transActor.roomFrom, transActor.cameraFront = front @@ -177,7 +177,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.rot = ", ".join(f"SPAWN_ROT_FLAGS({round(r * (180 / 0x8000))}, 0x00)" for r in rot) # force custom params for MM (temp solution until the xml is documented properly) - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.use_new_actor_panel and not entranceProp.customActor: + if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and not entranceProp.customActor: entranceActor.params = actorProp.params else: entranceActor.params = actorProp.params_custom diff --git a/fast64_internal/z64/file_settings.py b/fast64_internal/z64/file_settings.py index 5a58451de..774367a80 100644 --- a/fast64_internal/z64/file_settings.py +++ b/fast64_internal/z64/file_settings.py @@ -35,9 +35,9 @@ def draw(self, context): if not context.scene.fast64.oot.hackerFeaturesEnabled: col.prop(context.scene.fast64.oot, "useDecompFeatures") col.prop(context.scene.fast64.oot, "exportMotionOnly") - col.prop(context.scene.fast64.oot, "use_new_actor_panel") if context.scene.gameEditorMode == "OOT": + col.prop(context.scene.fast64.oot, "use_new_actor_panel") col.prop(context.scene.fast64.oot, "mm_features") From f36b6796657cafbec73cca13cad4188ec55a2379 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 03:17:39 +0200 Subject: [PATCH 103/126] fix actor cs index not exporting properly --- fast64_internal/z64/actor/properties.py | 41 ++++++++++++------- .../z64/exporter/scene/actor_cutscene.py | 9 +++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index d6085e136..f90867629 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -287,9 +287,8 @@ class Z64_ActorProperty(PropertyGroup): halfday_all_dawns: BoolProperty(default=False) halfday_all_nights: BoolProperty(default=False) halfday_bits: CollectionProperty(type=Z64_HalfdayItem) - - # internal - actor_cs_index: IntProperty(default=0x7F) + use_global_actor_cs: BoolProperty(name="Use Global Actor Cutscene", default=False) + actor_cs_index: IntProperty(min=0, max=127, default=127) @staticmethod def upgrade_object(obj: Object): @@ -510,16 +509,16 @@ def draw_props( split.label(text="Actor ID") split.label(text=getEnumName(game_data.z64.get_enum("actor_id"), self.actor_id)) - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.use_new_actor_panel and self.actor_id != "Custom": + if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor_id != "Custom": self.draw_params(actorIDBox, owner) - if game_data.z64.is_mm() or self.actor_id == "Custom": - prop_split(actorIDBox, self, "actor_id_custom", "") + if self.actor_id == "Custom": + prop_split(actorIDBox, self, "actor_id_custom", "Actor ID Custom") paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.use_new_actor_panel and self.actor_id != "Custom": + if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor_id != "Custom": paramBox.prop(self, "eval_params") paramBox.prop(self, "params", text="") else: @@ -527,7 +526,7 @@ def draw_props( rotations_used = [] - if bpy.context.scene.fast64.oot.use_new_actor_panel and self.actor_id != "Custom": + if bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor_id != "Custom": if self.is_rotation_used("XRot"): rotations_used.append("X") if self.is_rotation_used("YRot"): @@ -542,7 +541,7 @@ def draw_props( for rot in rotations_used: custom = ( - "_custom" if not bpy.context.scene.fast64.oot.use_new_actor_panel or self.actor_id == "Custom" else "" + "_custom" if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or self.actor_id == "Custom" else "" ) prop_split(paramBox, self, f"rot_{rot.lower()}{custom}", f"Rot {rot}") @@ -569,9 +568,21 @@ def draw_props( for i, item in enumerate(self.halfday_bits): item.draw_props(layout_halfday, owner, i) drawAddButton(layout_halfday, len(self.halfday_bits), "Actor Halfday", None, owner.name) - elif self.menu_tab == "Actor Cutscene": - actor_cs_props.draw_props(actorIDBox, owner, alt_scene_props, False) + actorIDBox.prop(self, "use_global_actor_cs") + + if self.use_global_actor_cs: + prop_split(actorIDBox, self, "actor_cs_index", "Actor CS Index") + label_box = actorIDBox.box() + label_box.label(text="This should match the 'CutsceneEntry' array entry of", icon="INFO") + label_box.label(text="the actor cutscene you want to use. For instance with chests, ") + label_box.label(text="it should be the index of the entry where there's") + label_box.label(text="'CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING'.") + + if self.actor_cs_index > 119: + label_box.label(text="The index can't be over 119!", icon="ERROR") + else: + actor_cs_props.draw_props(actorIDBox, owner, alt_scene_props, False) headerProp: Z64_ActorHeaderProperty = self.headerSettings headerProp.draw_props(actorIDBox, "Actor", altRoomProp, owner.name) @@ -609,7 +620,7 @@ def draw_props( split.label(text="Actor ID") split.label(text=getEnumName(game_data.z64.get_enum("actor_id"), self.actor.actor_id)) - if bpy.context.scene.fast64.oot.use_new_actor_panel and self.actor.actor_id != "Custom": + if bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor.actor_id != "Custom": self.actor.draw_params(actorIDBox, roomObj) if self.actor.actor_id == "Custom": @@ -617,7 +628,7 @@ def draw_props( paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if is_oot_features() and bpy.context.scene.fast64.oot.use_new_actor_panel and self.actor.actor_id != "Custom": + if is_oot_features() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor.actor_id != "Custom": paramBox.prop(self.actor, "eval_params") paramBox.prop(self.actor, "params", text="") else: @@ -674,12 +685,12 @@ def draw_props(self, layout: UILayout, obj: Object, altSceneProp: Z64_AlternateS prop_split(box, entranceProp, "tiedRoom", "Room") prop_split(box, entranceProp, "spawnIndex", "Spawn Index") - if bpy.context.scene.fast64.oot.use_new_actor_panel and not self.customActor: + if bpy.context.scene.fast64.oot.can_use_new_actor_panel() and not self.customActor: self.actor.draw_params(box, obj) paramBox = box.box() paramBox.label(text="Actor Parameter") - if is_oot_features() and bpy.context.scene.fast64.oot.use_new_actor_panel and not self.customActor: + if is_oot_features() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and not self.customActor: paramBox.prop(self.actor, "eval_params") paramBox.prop(self.actor, "params", text="") else: diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index 639080782..5a98e15ef 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -19,7 +19,11 @@ def __init__( self.index = index self.cam_info: Optional[CameraInfo] = None - if obj.ootEmptyType == "Actor": + if obj.ootEmptyType == "Actor" and not obj.ootActorProperty.use_global_actor_cs: + # 127 means "no cutscene", and 0-119 are all the valid array indices, any other number won't work + if index > 119 and index < 127: + raise PluginError("ERROR: the actor cutscene index must be between 0 to 119 or 127!") + obj.ootActorProperty.actor_cs_index = index if props.cs_cam_id == "Custom": @@ -92,7 +96,8 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i for i, item in enumerate(obj.z64_actor_cs_property.entries, start): if Utility.isCurrentHeaderValid(header_settings, header_index): - new_entry = ActorCutscene(scene_obj, transform, item, name, i, obj) + index = obj.ootActorProperty.actor_cs_index if obj.ootActorProperty.use_global_actor_cs else i + new_entry = ActorCutscene(scene_obj, transform, item, name, index, obj) if new_entry.cs_cam_id not in {"Custom", "Camera", "CS_CAM_ID_NONE"}: if new_entry.cs_cam_id not in processed: From 9aadef6064a6a1ac0ddc03a5277093158410f33b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 03:17:57 +0200 Subject: [PATCH 104/126] format --- fast64_internal/z64/__init__.py | 6 ++--- fast64_internal/z64/actor/properties.py | 24 +++++++++++++++---- .../z64/actor_cutscene/properties.py | 5 +++- fast64_internal/z64/exporter/room/header.py | 10 ++++++-- .../z64/exporter/scene/actor_cutscene.py | 2 +- fast64_internal/z64/exporter/scene/actors.py | 10 ++++++-- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index 256b91e21..fc9a6a9d6 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -135,11 +135,11 @@ def is_globalh_present(self): global_h_path = decomp_path / "include" / "global.h" return global_h_path.exists() - + def can_use_new_actor_panel(self): if game_data.z64.is_mm(): return False - + return self.use_new_actor_panel useDecompFeatures: bpy.props.BoolProperty( @@ -221,7 +221,7 @@ def oot_register(registerPanels: bool, register_ops: bool = True): oot_operator_register() collections_register() - collision_props_register() # register first, so panel goes above mat panel + collision_props_register() # register first, so panel goes above mat panel cutscene_props_register() scene_props_register() room_props_register() diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index f90867629..a1421af73 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -509,16 +509,24 @@ def draw_props( split.label(text="Actor ID") split.label(text=getEnumName(game_data.z64.get_enum("actor_id"), self.actor_id)) - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor_id != "Custom": + if ( + game_data.z64.is_oot() + and bpy.context.scene.fast64.oot.can_use_new_actor_panel() + and self.actor_id != "Custom" + ): self.draw_params(actorIDBox, owner) - + if self.actor_id == "Custom": prop_split(actorIDBox, self, "actor_id_custom", "Actor ID Custom") paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor_id != "Custom": + if ( + game_data.z64.is_oot() + and bpy.context.scene.fast64.oot.can_use_new_actor_panel() + and self.actor_id != "Custom" + ): paramBox.prop(self, "eval_params") paramBox.prop(self, "params", text="") else: @@ -541,7 +549,9 @@ def draw_props( for rot in rotations_used: custom = ( - "_custom" if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or self.actor_id == "Custom" else "" + "_custom" + if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or self.actor_id == "Custom" + else "" ) prop_split(paramBox, self, f"rot_{rot.lower()}{custom}", f"Rot {rot}") @@ -628,7 +638,11 @@ def draw_props( paramBox = actorIDBox.box() paramBox.label(text="Actor Parameter") - if is_oot_features() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and self.actor.actor_id != "Custom": + if ( + is_oot_features() + and bpy.context.scene.fast64.oot.can_use_new_actor_panel() + and self.actor.actor_id != "Custom" + ): paramBox.prop(self.actor, "eval_params") paramBox.prop(self.actor, "params", text="") else: diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py index ca2733287..f9cb968ac 100644 --- a/fast64_internal/z64/actor_cutscene/properties.py +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -109,7 +109,10 @@ class Z64_ActorCutscene(PropertyGroup): def draw_props(self, layout: UILayout, owner: Object, index: int): layout = layout.column() layout.prop( - self, "show_item", text=f"Entry No. {index + 1} (Array Index {index})", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT" + self, + "show_item", + text=f"Entry No. {index + 1} (Array Index {index})", + icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT", ) if self.show_item: diff --git a/fast64_internal/z64/exporter/room/header.py b/fast64_internal/z64/exporter/room/header.py index df3fd99eb..83b01387e 100644 --- a/fast64_internal/z64/exporter/room/header.py +++ b/fast64_internal/z64/exporter/room/header.py @@ -169,7 +169,9 @@ class RoomActors: def get_rotation_values(actorProp: Z64_ActorProperty, blender_rot_values: list[int]): # Figure out which rotation to export, Blender's or the override custom = ( - "_custom" if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or actorProp.actor_id == "Custom" else "" + "_custom" + if not bpy.context.scene.fast64.oot.can_use_new_actor_panel() or actorProp.actor_id == "Custom" + else "" ) rot_values = [getattr(actorProp, f"rot_{rot}{custom}") for rot in ["x", "y", "z"]] @@ -273,7 +275,11 @@ def new( actor.pos = pos # force custom params for MM (temp solution until the xml is documented properly) - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and actorProp.actor_id != "Custom": + if ( + game_data.z64.is_oot() + and bpy.context.scene.fast64.oot.can_use_new_actor_panel() + and actorProp.actor_id != "Custom" + ): actor.params = actorProp.params else: actor.params = actorProp.params_custom diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index 5a98e15ef..b2af591d8 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -96,7 +96,7 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i for i, item in enumerate(obj.z64_actor_cs_property.entries, start): if Utility.isCurrentHeaderValid(header_settings, header_index): - index = obj.ootActorProperty.actor_cs_index if obj.ootActorProperty.use_global_actor_cs else i + index = obj.ootActorProperty.actor_cs_index if obj.ootActorProperty.use_global_actor_cs else i new_entry = ActorCutscene(scene_obj, transform, item, name, index, obj) if new_entry.cs_cam_id not in {"Custom", "Camera", "CS_CAM_ID_NONE"}: diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index a1d932b13..1c1ec736f 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -99,7 +99,9 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): transActor.params = ( actorProp.params - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and actorProp.actor_id != "Custom" + if game_data.z64.is_oot() + and bpy.context.scene.fast64.oot.can_use_new_actor_panel() + and actorProp.actor_id != "Custom" else actorProp.params_custom ) transActor.roomFrom, transActor.cameraFront = front @@ -177,7 +179,11 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): entranceActor.rot = ", ".join(f"SPAWN_ROT_FLAGS({round(r * (180 / 0x8000))}, 0x00)" for r in rot) # force custom params for MM (temp solution until the xml is documented properly) - if game_data.z64.is_oot() and bpy.context.scene.fast64.oot.can_use_new_actor_panel() and not entranceProp.customActor: + if ( + game_data.z64.is_oot() + and bpy.context.scene.fast64.oot.can_use_new_actor_panel() + and not entranceProp.customActor + ): entranceActor.params = actorProp.params else: entranceActor.params = actorProp.params_custom From a57b2113178235fac2f0b4979bc2eb5d436a0878 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 03:31:17 +0200 Subject: [PATCH 105/126] don't show array index for actor cutscenes from actors empties --- fast64_internal/z64/actor_cutscene/properties.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py index f9cb968ac..07a420fb0 100644 --- a/fast64_internal/z64/actor_cutscene/properties.py +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -108,10 +108,11 @@ class Z64_ActorCutscene(PropertyGroup): def draw_props(self, layout: UILayout, owner: Object, index: int): layout = layout.column() + entry_text_suffix = f" (Array Index {index})" if owner.ootEmptyType == "Actor Cutscene" else "" layout.prop( self, "show_item", - text=f"Entry No. {index + 1} (Array Index {index})", + text=f"Entry No. {index + 1}{entry_text_suffix}", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT", ) From 89f2810db180dd8a4ea73f292e3317d1b98ee320 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 14:12:08 +0200 Subject: [PATCH 106/126] document chests and timer actors (cutscenes) --- README.md | 2 +- fast64_internal/z64/README.md | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39eaccd93..67784b9db 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ We have a Discord server for support as well as development [here](https://disco ### Links to Docs / Guides for Each Game 1. [ Super Mario 64 ](/fast64_internal/sm64/README.md) -2. [ Ocarina Of Time ](/fast64_internal/oot/README.md) +2. [ Ocarina Of Time and Majora's Mask ](/fast64_internal/z64/README.md) ### Installation Download the repository as a zip file. In Blender, go to Edit -> Preferences -> Add-Ons and click the "Install" button to install the plugin from the zip file. Find the Fast64 addon in the addon list and enable it. If it does not show up, go to Edit -> Preferences -> Save&Load and make sure 'Auto Run Python Scripts' is enabled. diff --git a/fast64_internal/z64/README.md b/fast64_internal/z64/README.md index 2c1223322..37e4fe15e 100644 --- a/fast64_internal/z64/README.md +++ b/fast64_internal/z64/README.md @@ -227,3 +227,20 @@ The informations required are the following: - `Letterbox Size`: the size of the letterbox (the two black rectangles at the top and the bottom of the screen) If you want to use your own camera, add a camera object and enable "Is Actor CS Camera". Set the index, this is NOT the same order as normal scene cameras so choose 0 for the first actor cutscene camera you add. Finally, back in the actor cutscene entry, choose "Camera Object" as the value of `CS Cam ID` and select the camera you've just created. For the camera setting simply change that from the camera object you added. + +#### Three-Day Timer Actor Cutscenes + +This actor handles the day/night transitions (and going the "Dawn of the X Day" gamestates), to setup an actor cutscene for this actor, you need to know few things: +- you need two different cameras +- the cameras you will bind to the actor cutscene entry needs to use a "fixed" setting +- you need two actor cutscene entries (one for the day, even though it's not used, and one for the night), the order doesn't really matter +- you need to bind the `Actor CS Index` to the entry you will "use" for the day and it's required to set the `Additional CS ID` to the index of the night entry +- it's also required to set the `Length` value, usually this is set to 90 frames, which corresponds to 4.5 seconds + +#### Treasure Chest Actor Cutscenes + +To achieve this you have two solutions: +- enable `Use Global Actor Cutscene` and bind the `Actor CS Index` to a global entry +- use actor-embedded actor cutscenes like the Three-Day Timer actor, but this is NOT recommended if you have several chests as it will increase the number of actor cutscene entries in the array + +For both cases the `CS Cam ID` of the actor cutscene entry need to be set to `Long Chest Opening` with a length of 135 frames (6.75 seconds) and the `Custom Value` need to be set to 1, the other parameters doesn't matter. From a29de822eb4d028ba04b26a546d1b9a6f58e7f8a Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 14:22:01 +0200 Subject: [PATCH 107/126] safety check for oob indices --- fast64_internal/z64/exporter/scene/actor_cutscene.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index b2af591d8..4fae6aff9 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -108,6 +108,14 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i start += i + # validate actor cs index + if empty_type == "Actor": + for obj in obj_list: + index = obj.ootActorProperty.actor_cs_index + + if index > i: + raise PluginError(f"ERROR: actor cutscene index out of bounds! ({index} for a total of {i + 1})") + return entries @staticmethod @@ -115,7 +123,7 @@ def new(name: str, scene_obj: Object, transform: Matrix, header_index: int): entries = SceneActorCutscene.get_entries(name, scene_obj, transform, header_index, "Actor Cutscene", 0) entries.extend(SceneActorCutscene.get_entries(name, scene_obj, transform, header_index, "Actor", len(entries))) - # validate camera indices + # validate camera indices (TODO: improve) last_cam_index = -1 for entry in entries: if entry.cam_info is not None: From 26b8c13b96a628958bc61e5ab828e9e66403252d Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 14:27:51 +0200 Subject: [PATCH 108/126] address some of the weirdness in actor cs index --- fast64_internal/z64/actor/properties.py | 8 ++++---- fast64_internal/z64/exporter/scene/actor_cutscene.py | 9 +-------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index a1421af73..8b22e0161 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -580,17 +580,17 @@ def draw_props( drawAddButton(layout_halfday, len(self.halfday_bits), "Actor Halfday", None, owner.name) elif self.menu_tab == "Actor Cutscene": actorIDBox.prop(self, "use_global_actor_cs") + prop_split(actorIDBox, self, "actor_cs_index", "Actor CS Index") + + if self.actor_cs_index > 119 and self.actor_cs_index < 127: + actorIDBox.label(text="The index can't be between 120 and 126!", icon="ERROR") if self.use_global_actor_cs: - prop_split(actorIDBox, self, "actor_cs_index", "Actor CS Index") label_box = actorIDBox.box() label_box.label(text="This should match the 'CutsceneEntry' array entry of", icon="INFO") label_box.label(text="the actor cutscene you want to use. For instance with chests, ") label_box.label(text="it should be the index of the entry where there's") label_box.label(text="'CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING'.") - - if self.actor_cs_index > 119: - label_box.label(text="The index can't be over 119!", icon="ERROR") else: actor_cs_props.draw_props(actorIDBox, owner, alt_scene_props, False) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index 4fae6aff9..df6ca6012 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -19,13 +19,6 @@ def __init__( self.index = index self.cam_info: Optional[CameraInfo] = None - if obj.ootEmptyType == "Actor" and not obj.ootActorProperty.use_global_actor_cs: - # 127 means "no cutscene", and 0-119 are all the valid array indices, any other number won't work - if index > 119 and index < 127: - raise PluginError("ERROR: the actor cutscene index must be between 0 to 119 or 127!") - - obj.ootActorProperty.actor_cs_index = index - if props.cs_cam_id == "Custom": self.cs_cam_id: str = props.cs_cam_id_custom elif props.cs_cam_id == "Camera": @@ -113,7 +106,7 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i for obj in obj_list: index = obj.ootActorProperty.actor_cs_index - if index > i: + if index > i and index < 127: raise PluginError(f"ERROR: actor cutscene index out of bounds! ({index} for a total of {i + 1})") return entries From 1a18041e509a6a8ba0b996b5723cc70b025cad5f Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 14:33:22 +0200 Subject: [PATCH 109/126] fixed bug where embedded entries would export with global check enabled --- .../z64/exporter/scene/actor_cutscene.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index df6ca6012..c50aa02e8 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -2,9 +2,10 @@ from bpy.types import Object from mathutils import Matrix from typing import Optional -from ....utility import CData, PluginError, exportColor, scaleToU8, indent +from ....utility import CData, PluginError, indent from ...utility import getObjectList, is_oot_features -from ...actor_cutscene.properties import Z64_ActorCutsceneProperty, Z64_ActorCutscene +from ...actor_cutscene.properties import Z64_ActorCutscene +from ...actor.properties import Z64_ActorProperty from ..utility import Utility from ..collision.camera import BgCamInformations, CameraInfo @@ -82,14 +83,16 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i i = 0 for obj in obj_list: + actor_prop: Z64_ActorProperty = obj.ootActorProperty + if empty_type == "Actor": - header_settings = obj.ootActorProperty.headerSettings + header_settings = actor_prop.headerSettings else: header_settings = obj.z64_actor_cs_property.header_settings for i, item in enumerate(obj.z64_actor_cs_property.entries, start): - if Utility.isCurrentHeaderValid(header_settings, header_index): - index = obj.ootActorProperty.actor_cs_index if obj.ootActorProperty.use_global_actor_cs else i + if Utility.isCurrentHeaderValid(header_settings, header_index) and not actor_prop.use_global_actor_cs: + index = actor_prop.actor_cs_index if actor_prop.use_global_actor_cs else i new_entry = ActorCutscene(scene_obj, transform, item, name, index, obj) if new_entry.cs_cam_id not in {"Custom", "Camera", "CS_CAM_ID_NONE"}: @@ -104,7 +107,7 @@ def get_entries(name: str, scene_obj: Object, transform: Matrix, header_index: i # validate actor cs index if empty_type == "Actor": for obj in obj_list: - index = obj.ootActorProperty.actor_cs_index + index = actor_prop.actor_cs_index if index > i and index < 127: raise PluginError(f"ERROR: actor cutscene index out of bounds! ({index} for a total of {i + 1})") From b485c33b1acf5942703d4493a1bfee94b94a437b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 15:28:20 +0200 Subject: [PATCH 110/126] revert updater change --- addon_updater_ops.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addon_updater_ops.py b/addon_updater_ops.py index 44575b85f..b2fd80b1c 100644 --- a/addon_updater_ops.py +++ b/addon_updater_ops.py @@ -1441,7 +1441,7 @@ def register(bl_info): # https://github.com/Fast-64/fast64 updater.engine = "Github" - updater.user = "Yanis002" + updater.user = "Fast-64" updater.repo = "fast64" # updater.addon = # define at top of module, MUST be done first @@ -1523,7 +1523,7 @@ def register(bl_info): # Note: updater.include_branch_list defaults to ['master'] branch if set to # none. Example targeting another multiple branches allowed to pull from: # updater.include_branch_list = ['master', 'dev'] - updater.include_branch_list = ["main", "mm_dev"] + updater.include_branch_list = ["main"] # Only allow manual install, thus prompting the user to open # the addon's web page to download, specifically: updater.website From 4b8680510d267d8bcac389f0e91e271a0e7a18fb Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 17:19:01 +0200 Subject: [PATCH 111/126] fix link imports part 1 --- fast64_internal/data/z64/data.py | 272 +++++++++++++++++- fast64_internal/z64/f3d_writer.py | 5 +- fast64_internal/z64/model_classes.py | 6 +- fast64_internal/z64/skeleton/constants.py | 102 ------- .../z64/skeleton/exporter/functions.py | 4 +- .../z64/skeleton/importer/functions.py | 12 +- fast64_internal/z64/skeleton/properties.py | 6 +- fast64_internal/z64/skeleton/utility.py | 6 +- 8 files changed, 298 insertions(+), 115 deletions(-) delete mode 100644 fast64_internal/z64/skeleton/constants.py diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 90f598efe..dbf4bec1f 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -1,5 +1,6 @@ import bpy +from collections import OrderedDict from dataclasses import dataclass from typing import Optional from bpy.types import Context @@ -7,7 +8,6 @@ from .object_data import Z64_ObjectData from .actor_data import Z64_ActorData - # --- # TODO: get this from XML @@ -542,6 +542,271 @@ ("FadeOutAmbienceList", "Fade-Out Ambience List", "Fade-Out Ambience", "IPO_EASE_IN_OUT", 14), ] +# Adding new rest pose entry: +# 1. Import a generic skeleton +# 2. Pose into a usable rest pose +# 3. Select skeleton, then run bpy.ops.object.oot_save_rest_pose() +# 4. Copy array data from console into an OOTSkeletonImportInfo object +# - list of tuples, first is root position, rest are euler XYZ rotations +# 5. Add object to ootSkeletonImportDict/mm_skeleton_dict + +link_skeleton_names = { + "gLinkAdultSkel", + "gLinkChildSkel", + "gLinkHumanSkel", + "gLinkDekuSkel", + "gLinkGoronSkel", + "gLinkZoraSkel", + "gLinkFierceDeitySkel", +} + +# Link overlay will be "", since Link texture array data is handled as a special case. +class OOTSkeletonImportInfo: + def __init__( + self, + skeletonName: str, + folderName: str, + actorOverlayName: str, + flipbookArrayIndex2D: int | None, + restPoseData: list[tuple[float, float, float]] | None, + ): + self.skeletonName = skeletonName + self.folderName = folderName + self.actorOverlayName = actorOverlayName # Note that overlayName = None will disable texture array reading. + self.flipbookArrayIndex2D = flipbookArrayIndex2D + self.isLink = skeletonName in link_skeleton_names + self.restPoseData = restPoseData + +oot_skeleton_dict = OrderedDict( + { + "Adult Link": OOTSkeletonImportInfo( + "gLinkAdultSkel", + "object_link_boy", + "", + 0, + [ + (0.0, 3.6050000190734863, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + "Child Link": OOTSkeletonImportInfo( + "gLinkChildSkel", + "object_link_child", + "", + 1, + [ + (0.0, 2.3559017181396484, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + } +) +oot_enum_skeleton_mode = [ + ("Generic", "Generic", "Generic"), +] +for name, info in oot_skeleton_dict.items(): + oot_enum_skeleton_mode.append((name, name, name)) + +mm_skeleton_dict = OrderedDict( + { + "Human Link": OOTSkeletonImportInfo( + "gLinkHumanSkel", + "object_link_child", + "", + 1, + [ + (0.0, 2.3559017181396484, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + "Deku Link": OOTSkeletonImportInfo( + "gLinkDekuSkel", + "object_link_nuts", + "", + 1, + [ + (0.0, 2.3559017181396484, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + "Goron Link": OOTSkeletonImportInfo( + "gLinkGoronSkel", + "object_link_goron", + "", + 1, + [ + (0.0, 2.3559017181396484, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + "Zora Link": OOTSkeletonImportInfo( + "gLinkZoraSkel", + "object_link_zora", + "", + 1, + [ + (0.0, 2.3559017181396484, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + "Fierce Deity Link": OOTSkeletonImportInfo( + "gLinkFierceDeitySkel", + "object_link_boy", + "", + 0, + [ + (0.0, 3.6050000190734863, 0.0), + (0.0, -0.0, 0.0), + (-1.5708922147750854, -0.0, -1.5707963705062866), + (0.0, -0.0, 0.0), + (0.0, 0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (0.0, -0.05235987901687622, 0.0), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (1.5707963705062866, -0.0, 1.5707963705062866), + (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), + (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), + (0.0, -0.0, 0.0), + (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), + (0.0, -0.0, 0.0), + (0.0, 0.0, -1.5707964897155762), + (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), + (0.0, -0.0, 0.0), + ], + ), + } +) +mm_enum_skeleton_mode = [ + ("Generic", "Generic", "Generic"), +] +for name, info in mm_skeleton_dict.items(): + mm_enum_skeleton_mode.append((name, name, name)) + # --- @@ -615,6 +880,8 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumFloorProperty = ootEnumFloorProperty self.ootEnumCameraSType = ootEnumCameraSType self.ootEnumCSListType = ootEnumCSListType + self.skeleton_dict = oot_skeleton_dict + self.enum_skeleton_mode = oot_enum_skeleton_mode elif self.game == "MM": self.cs_index_start = 1 self.cs_list_type_to_cmd["Transition"] = "CS_TRANSITION_LIST" @@ -628,6 +895,8 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumFloorProperty = mm_enum_floor_type self.ootEnumCameraSType = mm_enum_camera_setting_type self.ootEnumCSListType = mm_enum_cs_list_type + self.skeleton_dict = mm_skeleton_dict + self.enum_skeleton_mode = mm_enum_skeleton_mode else: raise ValueError(f"ERROR: unsupported game {repr(self.game)}") @@ -665,6 +934,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = "floorProperty": self.ootEnumFloorProperty, "camSType": self.ootEnumCameraSType, "cs_list_type": self.ootEnumCSListType, + "skeleton_mode": self.enum_skeleton_mode, } def get_enum(self, prop_name: str): diff --git a/fast64_internal/z64/f3d_writer.py b/fast64_internal/z64/f3d_writer.py index 86daf819c..15aae0547 100644 --- a/fast64_internal/z64/f3d_writer.py +++ b/fast64_internal/z64/f3d_writer.py @@ -350,7 +350,10 @@ def ootReadActorScale(basePath: str, overlayName: str, isLink: bool) -> Optional scale = actorScaleMatch.group(1).strip() if scale[-1] == "f": scale = scale[:-1] - return getOOTScale(1 / float(scale)) + try: + return getOOTScale(1 / float(scale)) + except: + print(f"WARNING: the scale value read is not a float ({repr(scale)})") print("WARNING: auto-detection failed, defaulting to this panel's actor scale property value") return None diff --git a/fast64_internal/z64/model_classes.py b/fast64_internal/z64/model_classes.py index d734cebc3..359192897 100644 --- a/fast64_internal/z64/model_classes.py +++ b/fast64_internal/z64/model_classes.py @@ -35,12 +35,14 @@ def ootGetIncludedAssetData(basePath: str, currentPaths: list[str], data: str) -> str: includeData = "" searchedPaths = currentPaths[:] + extracted_path = f"{bpy.context.scene.fast64.oot.get_extracted_path()}/" print("Included paths:") # search assets for includeMatch in re.finditer(r"\#include\s*\"(assets/objects/(.*?))\.h\"", data): - path = os.path.join(basePath, includeMatch.group(1) + ".c") + # TODO: use pathlib and check if the path exists + path = os.path.join(basePath, extracted_path + includeMatch.group(1) + ".c") if path in searchedPaths: continue searchedPaths.append(path) @@ -49,7 +51,7 @@ def ootGetIncludedAssetData(basePath: str, currentPaths: list[str], data: str) - print(path) for subIncludeMatch in re.finditer(r"\#include\s*\"(((?![/\"]).)*)\.c\"", subIncludeData): - subPath = os.path.join(os.path.dirname(path), subIncludeMatch.group(1) + ".c") + subPath = os.path.join(os.path.dirname(path), extracted_path + subIncludeMatch.group(1) + ".c") if subPath in searchedPaths: continue searchedPaths.append(subPath) diff --git a/fast64_internal/z64/skeleton/constants.py b/fast64_internal/z64/skeleton/constants.py deleted file mode 100644 index b96ebfb72..000000000 --- a/fast64_internal/z64/skeleton/constants.py +++ /dev/null @@ -1,102 +0,0 @@ -from collections import OrderedDict - - -# Adding new rest pose entry: -# 1. Import a generic skeleton -# 2. Pose into a usable rest pose -# 3. Select skeleton, then run bpy.ops.object.oot_save_rest_pose() -# 4. Copy array data from console into an OOTSkeletonImportInfo object -# - list of tuples, first is root position, rest are euler XYZ rotations -# 5. Add object to ootSkeletonImportDict - - -# Link overlay will be "", since Link texture array data is handled as a special case. -class OOTSkeletonImportInfo: - def __init__( - self, - skeletonName: str, - folderName: str, - actorOverlayName: str, - flipbookArrayIndex2D: int | None, - restPoseData: list[tuple[float, float, float]] | None, - ): - self.skeletonName = skeletonName - self.folderName = folderName - self.actorOverlayName = actorOverlayName # Note that overlayName = None will disable texture array reading. - self.flipbookArrayIndex2D = flipbookArrayIndex2D - self.isLink = skeletonName == "gLinkAdultSkel" or skeletonName == "gLinkChildSkel" - self.restPoseData = restPoseData - - -ootSkeletonImportDict = OrderedDict( - { - "Adult Link": OOTSkeletonImportInfo( - "gLinkAdultSkel", - "object_link_boy", - "", - 0, - [ - (0.0, 3.6050000190734863, 0.0), - (0.0, -0.0, 0.0), - (-1.5708922147750854, -0.0, -1.5707963705062866), - (0.0, -0.0, 0.0), - (0.0, 0.05235987901687622, 0.0), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (0.0, -0.05235987901687622, 0.0), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (1.5707963705062866, -0.0, 1.5707963705062866), - (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), - (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), - (0.0, -0.0, 0.0), - (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), - (0.0, -0.0, 0.0), - ], - ), - "Child Link": OOTSkeletonImportInfo( - "gLinkChildSkel", - "object_link_child", - "", - 1, - [ - (0.0, 2.3559017181396484, 0.0), - (0.0, -0.0, 0.0), - (-1.5708922147750854, -0.0, -1.5707963705062866), - (0.0, -0.0, 0.0), - (0.0, 0.05235987901687622, 0.0), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (0.0, -0.05235987901687622, 0.0), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (1.5707963705062866, -0.0, 1.5707963705062866), - (-4.740638548383913e-09, -5.356494803265832e-09, 1.4546878337860107), - (-4.114889869409654e-15, -1.1733899984468776e-14, 1.9080803394317627), - (0.0, -0.0, 0.0), - (1.0222795112391236e-15, -0.6981316804885864, -3.141592502593994), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (-1.0222795112391236e-15, 0.6981316804885864, -3.141592502593994), - (0.0, -0.0, 0.0), - (0.0, 0.0, -1.5707964897155762), - (-1.5707963705062866, 2.611602306365967, -0.08726644515991211), - (0.0, -0.0, 0.0), - ], - ), - # "Gerudo": OOTSkeletonImportInfo("gGerudoRedSkel", "object_geldb", "ovl_En_GeldB", None, None), - } -) - -ootEnumSkeletonImportMode = [ - ("Generic", "Generic", "Generic"), -] - -for name, info in ootSkeletonImportDict.items(): - ootEnumSkeletonImportMode.append((name, name, name)) diff --git a/fast64_internal/z64/skeleton/exporter/functions.py b/fast64_internal/z64/skeleton/exporter/functions.py index f9d10e4ea..519b66c70 100644 --- a/fast64_internal/z64/skeleton/exporter/functions.py +++ b/fast64_internal/z64/skeleton/exporter/functions.py @@ -7,7 +7,7 @@ from ....f3d.f3d_writer import getInfoDict from ...f3d_writer import ootProcessVertexGroup, writeTextureArraysNew, writeTextureArraysExisting from ...model_classes import OOTModel, OOTGfxFormatter -from ..constants import ootSkeletonImportDict +from ....game_data import game_data from ..properties import OOTSkeletonExportSettings from ..utility import ootDuplicateArmatureAndRemoveRotations, getGroupIndices, ootRemoveSkeleton from .classes import OOTLimb, OOTSkeleton @@ -220,7 +220,7 @@ def ootConvertArmatureToC( settings: OOTSkeletonExportSettings, ): if settings.mode != "Generic" and not settings.isCustom: - importInfo = ootSkeletonImportDict[settings.mode] + importInfo = game_data.z64.skeleton_dict[settings.mode] skeletonName = importInfo.skeletonName filename = skeletonName folderName = importInfo.folderName diff --git a/fast64_internal/z64/skeleton/importer/functions.py b/fast64_internal/z64/skeleton/importer/functions.py index d575883ca..da67a8468 100644 --- a/fast64_internal/z64/skeleton/importer/functions.py +++ b/fast64_internal/z64/skeleton/importer/functions.py @@ -2,13 +2,13 @@ from typing import List import mathutils, bpy, math from ....f3d.f3d_gbi import F3D, get_F3D_GBI -from ....f3d.f3d_parser import getImportData, parseF3D +from ....f3d.f3d_parser import getImportData, parseF3D, parseMatrices from ....utility import hexOrDecInt, applyRotation, PluginError from ...f3d_writer import ootReadActorScale from ...model_classes import OOTF3DContext, ootGetIncludedAssetData from ...utility import OOTEnum, ootGetObjectPath, getOOTScale, ootGetObjectHeaderPath, ootGetEnums, ootStripComments from ...texture_array import ootReadTextureArrays -from ..constants import ootSkeletonImportDict +from ....game_data import game_data from ..properties import OOTSkeletonImportSettings from ..utility import ootGetLimb, ootGetLimbs, ootGetSkeleton, applySkeletonRestPose @@ -235,12 +235,16 @@ def ootBuildSkeleton( return isLOD, armatureObj +def parse_included_objects(): + pass + + def ootImportSkeletonC(basePath: str, importSettings: OOTSkeletonImportSettings): importPath = bpy.path.abspath(importSettings.customPath) isCustomImport = importSettings.isCustom if importSettings.mode != "Generic" and not importSettings.isCustom: - importInfo = ootSkeletonImportDict[importSettings.mode] + importInfo = game_data.z64.skeleton_dict[importSettings.mode] skeletonName = importInfo.skeletonName folderName = importInfo.folderName overlayName = importInfo.actorOverlayName @@ -288,6 +292,8 @@ def ootImportSkeletonC(basePath: str, importSettings: OOTSkeletonImportSettings) if actorScale is None: actorScale = getOOTScale(importSettings.actorScale) + parseMatrices(skeletonData, f3dContext, actorScale) + # print(limbList) isLOD, armatureObj = ootBuildSkeleton( skeletonName, diff --git a/fast64_internal/z64/skeleton/properties.py b/fast64_internal/z64/skeleton/properties.py index 4f239fc7d..8b3c604d2 100644 --- a/fast64_internal/z64/skeleton/properties.py +++ b/fast64_internal/z64/skeleton/properties.py @@ -5,7 +5,7 @@ from bpy.utils import register_class, unregister_class from ...f3d.f3d_material import ootEnumDrawLayers from ...utility import prop_split -from .constants import ootEnumSkeletonImportMode +from ...game_data import game_data ootEnumBoneType = [ @@ -56,7 +56,7 @@ class OOTSkeletonExportSettings(PropertyGroup): name="Use Custom Filename", description="Override filename instead of basing it off of the Blender name" ) filename: StringProperty(name="Filename") - mode: EnumProperty(name="Mode", items=ootEnumSkeletonImportMode) + mode: EnumProperty(name="Mode", items=lambda self, context: game_data.z64.get_enum("skeleton_mode")) folder: StringProperty(name="Skeleton Folder", default="object_geldb") customPath: StringProperty(name="Custom Skeleton Path", subtype="FILE_PATH") isCustom: BoolProperty( @@ -109,7 +109,7 @@ def draw_props(self, layout: UILayout): class OOTSkeletonImportSettings(PropertyGroup): - mode: EnumProperty(name="Mode", items=ootEnumSkeletonImportMode) + mode: EnumProperty(name="Mode", items=lambda self, context: game_data.z64.get_enum("skeleton_mode")) applyRestPose: BoolProperty(name="Apply Friendly Rest Pose (If Available)", default=True) name: StringProperty(name="Skeleton Name", default="gGerudoRedSkel") folder: StringProperty(name="Skeleton Folder", default="object_geldb") diff --git a/fast64_internal/z64/skeleton/utility.py b/fast64_internal/z64/skeleton/utility.py index ce92828bf..9296a6329 100644 --- a/fast64_internal/z64/skeleton/utility.py +++ b/fast64_internal/z64/skeleton/utility.py @@ -1,4 +1,8 @@ -import mathutils, bpy, os, re +import mathutils +import bpy +import os +import re + from ...utility_anim import armatureApplyWithMesh from ..model_classes import OOTVertexGroupInfo from ..utility import checkForStartBone, getStartBone, getNextBone, ootStripComments From cb54fa2f8772d76c494cf13e10c401c84ac2f7be Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 19:56:42 +0200 Subject: [PATCH 112/126] fix the human link flipbook --- fast64_internal/data/z64/data.py | 16 +++--- fast64_internal/z64/texture_array.py | 76 +++++++++++++++++++++------- 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index dbf4bec1f..b5a4e953a 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -548,7 +548,7 @@ # 3. Select skeleton, then run bpy.ops.object.oot_save_rest_pose() # 4. Copy array data from console into an OOTSkeletonImportInfo object # - list of tuples, first is root position, rest are euler XYZ rotations -# 5. Add object to ootSkeletonImportDict/mm_skeleton_dict +# 5. Add object to oot_skeleton_dict/mm_skeleton_dict link_skeleton_names = { "gLinkAdultSkel", @@ -560,6 +560,7 @@ "gLinkFierceDeitySkel", } + # Link overlay will be "", since Link texture array data is handled as a special case. class OOTSkeletonImportInfo: def __init__( @@ -577,6 +578,7 @@ def __init__( self.isLink = skeletonName in link_skeleton_names self.restPoseData = restPoseData + oot_skeleton_dict = OrderedDict( { "Adult Link": OOTSkeletonImportInfo( @@ -653,7 +655,7 @@ def __init__( "gLinkHumanSkel", "object_link_child", "", - 1, + 0, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -683,7 +685,7 @@ def __init__( "gLinkDekuSkel", "object_link_nuts", "", - 1, + 0, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -712,8 +714,8 @@ def __init__( "Goron Link": OOTSkeletonImportInfo( "gLinkGoronSkel", "object_link_goron", - "", - 1, + None, # "", + 0, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -742,8 +744,8 @@ def __init__( "Zora Link": OOTSkeletonImportInfo( "gLinkZoraSkel", "object_link_zora", - "", - 1, + None, # "", + 0, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), diff --git a/fast64_internal/z64/texture_array.py b/fast64_internal/z64/texture_array.py index ad3f56772..41b5d10c0 100644 --- a/fast64_internal/z64/texture_array.py +++ b/fast64_internal/z64/texture_array.py @@ -1,6 +1,9 @@ -import os, re +import os +import re + from typing import Callable from ..utility import hexOrDecInt +from ..game_data import game_data from .model_classes import ( OOTF3DContext, @@ -143,29 +146,41 @@ def getTextureArrays(actorData: str, flipbookArrayIndex2D: int) -> dict[str, Tex flipbookList = {} # {array name : TextureFlipbook} if flipbookArrayIndex2D is not None: + if game_data.z64.is_oot(): + file_regex = r"void\s*\*\s*([0-9a-zA-Z\_]*)\s*\[\s*\]\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;" + array_regex = r"\{(((?!\}).)*)\}" + else: + file_regex = r"TexturePtr\s*([0-9a-zA-Z\_]*)\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;" + array_regex = r"(((?!\}).)*)" + for texArray2DMatch in re.finditer( - r"void\s*\*\s*([0-9a-zA-Z\_]*)\s*\[\s*\]\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;", + file_regex, actorData, - flags=re.DOTALL, + flags=re.DOTALL | re.MULTILINE, ): arrayMatchData = [ arrayMatch.group(1) - for arrayMatch in re.finditer(r"\{(((?!\}).)*)\}", texArray2DMatch.group(2), flags=re.DOTALL) + for arrayMatch in re.finditer(array_regex, texArray2DMatch.group(2), flags=re.DOTALL) ] if flipbookArrayIndex2D >= len(arrayMatchData): continue arrayName = texArray2DMatch.group(1).strip() - textureList = stripComments([item for item in arrayMatchData[flipbookArrayIndex2D].split(",")]) + temp = [item for item in arrayMatchData[flipbookArrayIndex2D].split(",")] + textureList = stripComments(temp) # handle trailing comma if textureList[-1] == "": textureList.pop() flipbookList[arrayName] = TextureFlipbook(arrayName, "Array", textureList) else: + array_type = "void" if game_data.z64.is_oot() else "TexturePtr" + for texArrayMatch in re.finditer( - r"void\s*\*\s*([0-9a-zA-Z\_]*)\s*\[\s*\]\s*=\s*\{(((?!\}).)*)\}", actorData, flags=re.DOTALL + array_type + r"\s*\*\s*([0-9a-zA-Z\_]*)\s*\[\s*\]\s*=\s*\{(((?!\}).)*)\}", + actorData, + flags=re.DOTALL | re.MULTILINE, ): arrayName = texArrayMatch.group(1).strip() textureList = stripComments([item for item in texArrayMatch.group(2).split(",")]) @@ -193,18 +208,43 @@ def getSPSegmentCalls(actorData: str) -> list[tuple[tuple[int, str], str, re.Mat segmentCalls = [] # find gSPSegment() calls that reference texture arrays - for spSegmentMatch in re.finditer( - r"gSPSegment\s*\(\s*POLY\_(OPA)?(XLU)?\_DISP\s*\+\+\s*,\s*([0-9a-fA-Fx]*)\s*,\s*SEGMENTED\_TO\_VIRTUAL\s*\(\s*(((?!;).)*)\)\s*\)\s*;", - actorData, - flags=re.DOTALL, - ): - # see ootEnumDrawLayers - drawLayer = "Transparent" if spSegmentMatch.group(2) else "Opaque" - segment = hexOrDecInt(spSegmentMatch.group(3)) - flipbookKey = (segment, drawLayer) - segmentParam = spSegmentMatch.group(4).strip() - - segmentCalls.append((flipbookKey, segmentParam, spSegmentMatch)) + if game_data.z64.is_oot(): + for spSegmentMatch in re.finditer( + r"gSPSegment\s*\(\s*POLY\_(OPA)?(XLU)?\_DISP\s*\+\+\s*,\s*([0-9a-fA-Fx]*)\s*,\s*SEGMENTED\_TO\_VIRTUAL\s*\(\s*(((?!;).)*)\)\s*\)\s*;", + actorData, + flags=re.DOTALL, + ): + # see ootEnumDrawLayers + drawLayer = "Transparent" if spSegmentMatch.group(2) else "Opaque" + segment = hexOrDecInt(spSegmentMatch.group(3)) + flipbookKey = (segment, drawLayer) + segmentParam = spSegmentMatch.group(4).strip() + + segmentCalls.append((flipbookKey, segmentParam, spSegmentMatch)) + else: + for spSegmentMatch in re.finditer( + r"gSPSegment\((.*),\s*([0-9a-fA-Fx]*)\s*,\s*Lib\_SegmentedToVirtual\s*\(\s*(((?!;).)*)\)\s*\)\s*;", + actorData, + flags=re.MULTILINE, + ): + # see ootEnumDrawLayers + segment = hexOrDecInt(spSegmentMatch.group(2)) + segmentParam = spSegmentMatch.group(3).strip() + + ## find the disp by looking for the next POLY_XXX_DISP before the next CLOSE_DISPS + + # get a string containing the end of the function we're reading + string_1 = actorData[actorData.index(spSegmentMatch.group(0)) :] + string_2 = string_1[: string_1.find("CLOSE_DISPS")] + + # find the next disp usage + disp = re.search( + r"POLY\_(XLU)\_DISP\s*=\s[a-zA-Z0-9_,\n&;*\s\[\]=()]*CLOSE\_DISPS", string_2, re.DOTALL | re.MULTILINE + ) + drawLayer = "Transparent" if disp is not None else "Opaque" + + flipbookKey = (segment, drawLayer) + segmentCalls.append((flipbookKey, segmentParam, spSegmentMatch)) return segmentCalls From 82a855c829c78a7fae675ebb251f8c3eb132e6d9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Wed, 28 May 2025 21:42:09 +0200 Subject: [PATCH 113/126] fixed goron and zora eyes (relies on MM PR 1777) --- fast64_internal/data/z64/data.py | 16 ++++++++-------- fast64_internal/z64/texture_array.py | 13 +++++-------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index b5a4e953a..0d33d12cd 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -655,7 +655,7 @@ def __init__( "gLinkHumanSkel", "object_link_child", "", - 0, + 4, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -684,8 +684,8 @@ def __init__( "Deku Link": OOTSkeletonImportInfo( "gLinkDekuSkel", "object_link_nuts", - "", - 0, + None, + 3, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -714,8 +714,8 @@ def __init__( "Goron Link": OOTSkeletonImportInfo( "gLinkGoronSkel", "object_link_goron", - None, # "", - 0, + "", + 1, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -744,8 +744,8 @@ def __init__( "Zora Link": OOTSkeletonImportInfo( "gLinkZoraSkel", "object_link_zora", - None, # "", - 0, + "", + 2, [ (0.0, 2.3559017181396484, 0.0), (0.0, -0.0, 0.0), @@ -774,7 +774,7 @@ def __init__( "Fierce Deity Link": OOTSkeletonImportInfo( "gLinkFierceDeitySkel", "object_link_boy", - "", + None, 0, [ (0.0, 3.6050000190734863, 0.0), diff --git a/fast64_internal/z64/texture_array.py b/fast64_internal/z64/texture_array.py index 41b5d10c0..5db73fa3f 100644 --- a/fast64_internal/z64/texture_array.py +++ b/fast64_internal/z64/texture_array.py @@ -148,10 +148,8 @@ def getTextureArrays(actorData: str, flipbookArrayIndex2D: int) -> dict[str, Tex if flipbookArrayIndex2D is not None: if game_data.z64.is_oot(): file_regex = r"void\s*\*\s*([0-9a-zA-Z\_]*)\s*\[\s*\]\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;" - array_regex = r"\{(((?!\}).)*)\}" else: - file_regex = r"TexturePtr\s*([0-9a-zA-Z\_]*)\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;" - array_regex = r"(((?!\}).)*)" + file_regex = r"TexturePtr\s*([0-9a-zA-Z\_]*)\s*\[[0-9a-zA-Z_]*\s*\]\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;" for texArray2DMatch in re.finditer( file_regex, @@ -160,7 +158,7 @@ def getTextureArrays(actorData: str, flipbookArrayIndex2D: int) -> dict[str, Tex ): arrayMatchData = [ arrayMatch.group(1) - for arrayMatch in re.finditer(array_regex, texArray2DMatch.group(2), flags=re.DOTALL) + for arrayMatch in re.finditer(r"\{(((?!\}).)*)\}", texArray2DMatch.group(2), flags=re.DOTALL) ] if flipbookArrayIndex2D >= len(arrayMatchData): @@ -168,11 +166,10 @@ def getTextureArrays(actorData: str, flipbookArrayIndex2D: int) -> dict[str, Tex arrayName = texArray2DMatch.group(1).strip() temp = [item for item in arrayMatchData[flipbookArrayIndex2D].split(",")] - textureList = stripComments(temp) - # handle trailing comma - if textureList[-1] == "": - textureList.pop() + # handle trailing comma and NULL pointers + textureList = [item for item in stripComments(temp) if item != "NULL" and item != ""] + flipbookList[arrayName] = TextureFlipbook(arrayName, "Array", textureList) else: array_type = "void" if game_data.z64.is_oot() else "TexturePtr" From 5324ff8e6106587340884260fa88cf8d515cda25 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 01:31:20 +0200 Subject: [PATCH 114/126] fix oopsie --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 141c74214..f3a5a1e77 100644 --- a/__init__.py +++ b/__init__.py @@ -386,7 +386,7 @@ def set_game_defaults(scene: bpy.types.Scene, set_ucode=True): elif scene.gameEditorMode == "MK64": f3d_type = "F3DEX" world_defaults = mk64_world_defaults - elif scene.gameEditorMode == {"OOT", "MM"}: + elif scene.gameEditorMode in {"OOT", "MM"}: f3d_type = "F3DEX2/LX2" world_defaults = oot_world_defaults elif scene.gameEditorMode == "MK64": From 7e45a2612fc5db3fa4a7991bcaeaeb966aeca146 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 02:37:30 +0200 Subject: [PATCH 115/126] fixed custom entry missing from actor list and added actorcat_door for door_shutter --- fast64_internal/data/z64/actor_data.py | 4 ++-- fast64_internal/data/z64/xml/mm_actor_list.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fast64_internal/data/z64/actor_data.py b/fast64_internal/data/z64/actor_data.py index ca6f71183..e1de70d89 100644 --- a/fast64_internal/data/z64/actor_data.py +++ b/fast64_internal/data/z64/actor_data.py @@ -129,7 +129,7 @@ def __init__(self, game: str): # list of tuples used by Blender's enum properties - lastIndex = max(1, *(actor.index for actor in self.actorList)) + lastIndex = max(1, *(actor.index for actor in self.actorList)) + 1 self.ootEnumActorID = [("None", f"{i} (Deleted from the XML)", "None") for i in range(lastIndex)] self.ootEnumActorID.insert(0, ("Custom", "Custom Actor", "Custom")) @@ -142,7 +142,7 @@ def __init__(self, game: str): i = 1 for actor in self.actorList: - self.ootEnumActorID[actor.index] = (actor.id, actor.name, actor.id) + self.ootEnumActorID[actor.index + 1] = (actor.id, actor.name, actor.id) if actor.category == "ACTORCAT_DOOR": self.ootEnumTransitionActorID[i] = (actor.id, actor.name, actor.id) i += 1 diff --git a/fast64_internal/data/z64/xml/mm_actor_list.xml b/fast64_internal/data/z64/xml/mm_actor_list.xml index 3593921e6..20f762697 100644 --- a/fast64_internal/data/z64/xml/mm_actor_list.xml +++ b/fast64_internal/data/z64/xml/mm_actor_list.xml @@ -180,7 +180,7 @@ for each sub element (of ) mentioned below: - + From 84f4f7e3c0cccb70eade5996f164c6b4535e2dfc Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 03:43:11 +0200 Subject: [PATCH 116/126] actor cutscene improvements --- fast64_internal/z64/actor/properties.py | 7 +--- .../z64/exporter/scene/actor_cutscene.py | 35 +++++++++++++------ fast64_internal/z64/exporter/scene/actors.py | 2 +- fast64_internal/z64/importer/actor.py | 10 +++--- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/fast64_internal/z64/actor/properties.py b/fast64_internal/z64/actor/properties.py index 8b22e0161..7f871738c 100644 --- a/fast64_internal/z64/actor/properties.py +++ b/fast64_internal/z64/actor/properties.py @@ -609,11 +609,6 @@ class Z64_TransitionActorProperty(PropertyGroup): actor: PointerProperty(type=Z64_ActorProperty) - # MM exclusive - cutscene_id: StringProperty( - name="Cutscene ID", default="CS_ID_GLOBAL_END", description="See the `CutsceneId` enum for more values" - ) - def isRoomEmptyObject(self, obj: Object): return obj.type == "EMPTY" and obj.ootEmptyType == "Room" @@ -649,7 +644,7 @@ def draw_props( paramBox.prop(self.actor, "params_custom", text="") if not is_oot_features(): - prop_split(actorIDBox, self, "cutscene_id", "Cutscene ID") + prop_split(actorIDBox, self.actor, "actor_cs_index", "Actor CS Index") if roomObj is None: actorIDBox.label(text="This must be part of a Room empty's hierarchy.", icon="OUTLINER") diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index c50aa02e8..37c864029 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -119,14 +119,14 @@ def new(name: str, scene_obj: Object, transform: Matrix, header_index: int): entries = SceneActorCutscene.get_entries(name, scene_obj, transform, header_index, "Actor Cutscene", 0) entries.extend(SceneActorCutscene.get_entries(name, scene_obj, transform, header_index, "Actor", len(entries))) - # validate camera indices (TODO: improve) - last_cam_index = -1 + # validate camera indices + known_camera_indices: list[int] = [] for entry in entries: if entry.cam_info is not None: - if entry.cam_info.camIndex > last_cam_index: - last_cam_index = entry.cam_info.camIndex + if entry.cam_info.camIndex not in known_camera_indices: + known_camera_indices.append(entry.cam_info.camIndex) else: - raise PluginError("ERROR: the actor cs camera indices are not consecutives!") + raise PluginError(f"ERROR: reapeated actor cutscene camera index! ({entry.cam_info.camIndex})") return SceneActorCutscene(name, f"{name}CameraInfo", f"{name}CameraData", header_index, entries) @@ -170,11 +170,18 @@ def cam_data_to_c(self): data.header = f"extern {array_name};\n" # .c - data.source = array_name + " = {\n" - for entry in self.entries: + # sort the camera list as it might not end up in the right order + camera_list: list[CameraInfo] = [] + for i, entry in enumerate(self.entries): if entry.cam_info is not None: - data.source += entry.cam_info.data.getEntryC() + "\n" + camera_list.append(entry.cam_info) + camera_list.sort(key=lambda item: item.camIndex) + + data.source = array_name + " = {\n" + + for item in camera_list: + data.source += item.data.getEntryC() + "\n" data.source = data.source[:-1] # remove extra newline data.source += "};\n\n" @@ -191,12 +198,18 @@ def cam_info_to_c(self): data.header = f"extern {array_name};\n" # .c + + # sort the camera list as it might not end up in the right order + camera_list: list[CameraInfo] = [] + for i, entry in enumerate(self.entries): + if entry.cam_info is not None: + camera_list.append(entry.cam_info) + camera_list.sort(key=lambda item: item.camIndex) + data.source = ( (array_name + " = {\n") + "".join( - entry.cam_info.getInfoEntryC(self.cam_data_array_name) - for i, entry in enumerate(self.entries) - if entry.cam_info is not None + item.getInfoEntryC(self.cam_data_array_name) for item in camera_list ) + "};\n\n" ) diff --git a/fast64_internal/z64/exporter/scene/actors.py b/fast64_internal/z64/exporter/scene/actors.py index 1c1ec736f..54d5ce968 100644 --- a/fast64_internal/z64/exporter/scene/actors.py +++ b/fast64_internal/z64/exporter/scene/actors.py @@ -95,7 +95,7 @@ def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int): if is_oot_features(): transActor.rot = f"DEG_TO_BINANG({rot_deg:.3f})" # TODO: Correct axis? else: - transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({transActorProp.cutscene_id} & 0x7F)" + transActor.rot = f"((0x{round(rot_deg):04X} & 0x1FF) << 7) | ({actorProp.actor_cs_index} & 0x7F)" transActor.params = ( actorProp.params diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 9a8269663..1496921f8 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -43,12 +43,12 @@ def parseTransActorList( position = tuple([hexOrDecInt(value) for value in params[5:8]]) rot_y = getEvalParams(params[8]) if "DEG_TO_BINANG" in params[8] else params[8] - cutscene_id = "CS_ID_GLOBAL_END" + actor_cs_index = 0x7F if game_data.z64.is_mm(): rotY_int = int(rot_y, base=0) rot_y = f"0x{(rotY_int >> 7) & 0x1FF:04X}" - cutscene_id = f"0x{rotY_int & 0x7F:02X}" + actor_cs_index = rotY_int & 0x7F rotation = tuple([0, hexOrDecInt(rot_y), 0]) @@ -68,13 +68,14 @@ def parseTransActorList( position, rotation, actorParam, - cutscene_id, + actor_cs_index, ) if not sharedSceneData.addHeaderIfItemExists(actorHash, "Transition Actor", headerIndex): actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation) actorObj.ootEmptyType = "Transition Actor" actorObj.name = "Transition " + getDisplayNameFromActorID(params[4]) transActorProp = actorObj.ootTransitionActorProperty + actorProp = transActorProp.actor sharedSceneData.transDict[actorHash] = actorObj @@ -90,12 +91,11 @@ def parseTransActorList( parentObject(toRoom, actorObj) if game_data.z64.is_mm(): - transActorProp.cutscene_id = cutscene_id + actorProp.actor_cs_index = actor_cs_index setCustomProperty(transActorProp, "cameraTransitionFront", camFront, ootEnumCamTransition) setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition) - actorProp = transActorProp.actor setCustomProperty( actorProp, "actor_id", From 24a8527848e3382c8ed775bb8db698659a9237b9 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 04:35:57 +0200 Subject: [PATCH 117/126] show array index for embedded actor cutscenes --- fast64_internal/z64/__init__.py | 3 ++ .../z64/actor_cutscene/properties.py | 28 +++++++++++++++---- fast64_internal/z64/collection_utility.py | 10 +++++++ .../z64/exporter/scene/actor_cutscene.py | 4 +-- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/fast64_internal/z64/__init__.py b/fast64_internal/z64/__init__.py index fc9a6a9d6..b99d548c5 100644 --- a/fast64_internal/z64/__init__.py +++ b/fast64_internal/z64/__init__.py @@ -119,6 +119,9 @@ class OOT_Properties(bpy.types.PropertyGroup): version_custom: bpy.props.StringProperty(name="Custom Version") mm_features: bpy.props.BoolProperty(name="Enable MM Features", default=False) + # internal + global_actor_cs_count: bpy.props.IntProperty(min=0, default=0) + def get_extracted_path(self): version = self.oot_version if game_data.z64.is_oot() else self.mm_version diff --git a/fast64_internal/z64/actor_cutscene/properties.py b/fast64_internal/z64/actor_cutscene/properties.py index 07a420fb0..7dcb63547 100644 --- a/fast64_internal/z64/actor_cutscene/properties.py +++ b/fast64_internal/z64/actor_cutscene/properties.py @@ -1,3 +1,5 @@ +import bpy + from bpy.props import ( IntProperty, PointerProperty, @@ -10,7 +12,7 @@ from bpy.utils import register_class, unregister_class from bpy.types import PropertyGroup, UILayout, Object from ...utility import prop_split -from ..collection_utility import drawAddButton, drawCollectionOps +from ..collection_utility import drawAddButton, drawCollectionOps, getCollection from ..utility import get_list_tab_text from ..actor.properties import Z64_ActorHeaderProperty from ..scene.properties import Z64_AlternateSceneHeaderProperty @@ -106,13 +108,12 @@ class Z64_ActorCutscene(PropertyGroup): # ui only props show_item: BoolProperty() - def draw_props(self, layout: UILayout, owner: Object, index: int): + def draw_props(self, layout: UILayout, owner: Object, index: int, array_index: int): layout = layout.column() - entry_text_suffix = f" (Array Index {index})" if owner.ootEmptyType == "Actor Cutscene" else "" layout.prop( self, "show_item", - text=f"Entry No. {index + 1}{entry_text_suffix}", + text=f"Entry No. {array_index + 1} (Array Index {array_index})", icon="TRIA_DOWN" if self.show_item else "TRIA_RIGHT", ) @@ -155,6 +156,17 @@ class Z64_ActorCutsceneProperty(PropertyGroup): # ui only props show_entries: BoolProperty(default=True) + def get_count(self, obj_name: str): + count = 0 + for obj in bpy.data.objects: + if obj.ootEmptyType == "Actor" and not obj.ootActorProperty.use_global_actor_cs: + if obj.name == obj_name: + break + + count += len(getCollection(obj.name, "Actor CS", 0)) + + return count + def draw_props( self, layout: UILayout, @@ -170,8 +182,14 @@ def draw_props( ) if self.show_entries: + if owner.ootEmptyType == "Actor Cutscene": + start = 0 + else: + global_actor_cs_count = bpy.context.scene.fast64.oot.global_actor_cs_count + start = global_actor_cs_count + self.get_count(owner.name) + for i, actor_cs in enumerate(self.entries): - actor_cs.draw_props(layout_entries.box(), owner, i) + actor_cs.draw_props(layout_entries.box(), owner, i, start + i) drawAddButton(layout_entries, len(self.entries), "Actor CS", None, owner.name) diff --git a/fast64_internal/z64/collection_utility.py b/fast64_internal/z64/collection_utility.py index df1a17331..e3a40939e 100644 --- a/fast64_internal/z64/collection_utility.py +++ b/fast64_internal/z64/collection_utility.py @@ -22,6 +22,11 @@ def execute(self, context): collection.add() collection.move(len(collection) - 1, self.option) + + owner = bpy.data.objects[self.objName] + if self.collectionType == "Actor CS" and owner.ootEmptyType == "Actor Cutscene": + context.scene.fast64.oot.global_actor_cs_count = len(collection) + return {"FINISHED"} @@ -39,6 +44,11 @@ class OOTCollectionRemove(Operator): def execute(self, context): collection = getCollection(self.objName, self.collectionType, self.subIndex, self.collection_index) collection.remove(self.option) + + owner = bpy.data.objects[self.objName] + if self.collectionType == "Actor CS" and owner.ootEmptyType == "Actor Cutscene": + context.scene.fast64.oot.global_actor_cs_count = len(collection) + return {"FINISHED"} diff --git a/fast64_internal/z64/exporter/scene/actor_cutscene.py b/fast64_internal/z64/exporter/scene/actor_cutscene.py index 37c864029..75f810de4 100644 --- a/fast64_internal/z64/exporter/scene/actor_cutscene.py +++ b/fast64_internal/z64/exporter/scene/actor_cutscene.py @@ -208,9 +208,7 @@ def cam_info_to_c(self): data.source = ( (array_name + " = {\n") - + "".join( - item.getInfoEntryC(self.cam_data_array_name) for item in camera_list - ) + + "".join(item.getInfoEntryC(self.cam_data_array_name) for item in camera_list) + "};\n\n" ) From a18278d238435d5659e79731284dad71927b8689 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 15:51:49 +0200 Subject: [PATCH 118/126] change time speed value --- fast64_internal/data/z64/data.py | 2 ++ fast64_internal/z64/room/properties.py | 2 +- fast64_internal/z64/tools/operators.py | 9 ++++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fast64_internal/data/z64/data.py b/fast64_internal/data/z64/data.py index 0d33d12cd..e3de403c0 100644 --- a/fast64_internal/data/z64/data.py +++ b/fast64_internal/data/z64/data.py @@ -884,6 +884,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumCSListType = ootEnumCSListType self.skeleton_dict = oot_skeleton_dict self.enum_skeleton_mode = oot_enum_skeleton_mode + self.default_time_speed = 1.0 elif self.game == "MM": self.cs_index_start = 1 self.cs_list_type_to_cmd["Transition"] = "CS_TRANSITION_LIST" @@ -899,6 +900,7 @@ def update(self, context: Optional[Context], game: Optional[str], force: bool = self.ootEnumCSListType = mm_enum_cs_list_type self.skeleton_dict = mm_skeleton_dict self.enum_skeleton_mode = mm_enum_skeleton_mode + self.default_time_speed = 0.3 else: raise ValueError(f"ERROR: unsupported game {repr(self.game)}") diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 274cf4572..cba77e832 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -125,7 +125,7 @@ class Z64_RoomHeaderProperty(PropertyGroup): leaveTimeUnchanged: BoolProperty(name="Leave Time Unchanged", default=True) timeHours: IntProperty(name="Hours", default=0, min=0, max=23) # 0xFFFE timeMinutes: IntProperty(name="Minutes", default=0, min=0, max=59) - timeSpeed: FloatProperty(name="Time Speed", default=1, min=-13, max=13) # 0xA + timeSpeed: FloatProperty(name="Time Speed", default=1.0, min=-13.0, max=13.0) # 0xA # SCENE_CMD_SKYBOX_DISABLES disableSkybox: BoolProperty(name="Disable Skybox") diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 4dbfa2d86..435694009 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -1,16 +1,17 @@ import bpy from mathutils import Vector -from bpy.ops import mesh, object, curve +from bpy.ops import mesh, object from bpy.types import Operator, Object, Context from bpy.props import FloatProperty, StringProperty, EnumProperty, BoolProperty + from ...operators import AddWaterBox, addMaterialByName from ...utility import parentObject, setOrigin +from ...game_data import game_data from ..cutscene.motion.utility import setupCutscene, createNewCameraShot from ..utility import getNewPath, get_new_empty_object, is_oot_features -from .quick_import import QuickImportAborted, quick_import_exec from ..actor_cutscene.properties import enum_end_cam, enum_end_sfx, enum_hud_visibility - +from .quick_import import QuickImportAborted, quick_import_exec class OOT_AddWaterBox(AddWaterBox): bl_idname = "object.oot_add_water_box" @@ -98,6 +99,7 @@ def execute(self, context): roomObj = context.view_layer.objects.active roomObj.ootEmptyType = "Room" roomObj.name = "Room" + roomObj.ootRoomHeader.timeSpeed = game_data.z64.default_time_speed entranceObj.ootEntranceProperty.tiedRoom = roomObj parentObject(roomObj, planeObj) @@ -129,6 +131,7 @@ def execute(self, context): roomObj = context.view_layer.objects.active roomObj.ootEmptyType = "Room" roomObj.name = "Room" + roomObj.ootRoomHeader.timeSpeed = game_data.z64.default_time_speed sceneObj = context.scene.ootSceneExportObj if sceneObj is not None: indices = [] From cb3cb1b5017548e69a1c57e3b8fd39598679b579 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 17:09:01 +0200 Subject: [PATCH 119/126] default time speed label --- fast64_internal/z64/room/properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index cba77e832..2aec6f33b 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -239,7 +239,7 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj timeRow = skyboxAndTime.row() timeRow.prop(self, "timeHours", text="Hours") timeRow.prop(self, "timeMinutes", text="Minutes") - prop_split(skyboxAndTime, self, "timeSpeed", "Time Speed") + prop_split(skyboxAndTime, self, "timeSpeed", f"Time Speed (default: {game_data.z64.default_time_speed:.2f})") # Echo prop_split(skyboxAndTime, self, "echo", "Echo") From 6b4266fbfc9e3a68108d0257ba4075c46c8669fb Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Thu, 29 May 2025 18:28:17 +0200 Subject: [PATCH 120/126] actor cs import and operator improvments --- fast64_internal/z64/importer/actor.py | 81 +++++--------------- fast64_internal/z64/importer/scene_header.py | 2 + fast64_internal/z64/tools/operators.py | 6 +- 3 files changed, 28 insertions(+), 61 deletions(-) diff --git a/fast64_internal/z64/importer/actor.py b/fast64_internal/z64/importer/actor.py index 1496921f8..3c2746034 100644 --- a/fast64_internal/z64/importer/actor.py +++ b/fast64_internal/z64/importer/actor.py @@ -5,7 +5,7 @@ from ...utility import parentObject, hexOrDecInt from ...game_data import game_data from ..scene.properties import Z64_SceneHeaderProperty -from ..utility import setCustomProperty, getEvalParams +from ..utility import setCustomProperty, getEvalParams, is_oot_features from ..constants import ( ootEnumCamTransition, halfday_bits_all_dawns, @@ -235,36 +235,6 @@ def getActorRegex(actorList: list[str]): return regex, nestedBrackets -def move_actor_cs_entry(global_cs_obj: Object, actor_obj: Object, index: int, default_entry): - index &= 0x7F - if index >= 0x78: - return default_entry - - global_cs_props = global_cs_obj.z64_actor_cs_property - actor_cs_props = actor_obj.z64_actor_cs_property - entry = global_cs_props.entries[index] - additional_cs_id = entry.additional_cs_id - - new_entry = actor_cs_props.entries.add() - new_entry.priority = entry.priority - new_entry.length = entry.length - new_entry.cs_cam_id = entry.cs_cam_id - new_entry.cs_cam_id_custom = entry.cs_cam_id_custom - new_entry.cs_cam_obj = entry.cs_cam_obj - new_entry.script_index = entry.script_index - new_entry.additional_cs_id = additional_cs_id - new_entry.end_sfx = entry.end_sfx - new_entry.end_sfx_custom = entry.end_sfx_custom - new_entry.custom_value = entry.custom_value - new_entry.hud_visibility = entry.hud_visibility - new_entry.hud_visibility_custom = entry.hud_visibility_custom - new_entry.end_cam = entry.end_cam - new_entry.end_cam_custom = entry.end_cam_custom - new_entry.letterbox_size = entry.letterbox_size - - return new_entry - - def parseActorList( roomObj: bpy.types.Object, sceneData: str, actorListName: str, sharedSceneData: SharedSceneData, headerIndex: int ): @@ -292,35 +262,26 @@ def parseActorList( handleActorWithRotAsParam(actorProp, actorID, rotation) unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex) - actor_cs_obj = None - for obj in bpy.data.objects: - if obj.type == "EMPTY" and obj.ootEmptyType == "Actor Cutscene": - actor_cs_obj = obj - break - - if sharedSceneData.includeActorCs and actor_cs_obj is not None: - # move any actor cs entry to the actor object embedded list based on the cs index of rot.y - # also move any other entries as defined by the additional cs id - new_entry = move_actor_cs_entry(actor_cs_obj, actorObj, spawn_flags[1], None) - if new_entry is not None: - while new_entry.additional_cs_id != -1: - new_entry = move_actor_cs_entry(actor_cs_obj, actorObj, new_entry.additional_cs_id, new_entry) - - # see `Actor_SpawnEntry()` - halfday_bits = ((spawn_flags[0] & 7) << 7) | (spawn_flags[2] & 0x7F) - actorProp.halfday_all = halfday_bits == halfday_bits_all_dawns | halfday_bits_all_nights - - if not actorProp.halfday_all: - actorProp.halfday_all_dawns = halfday_bits == halfday_bits_all_dawns - actorProp.halfday_all_nights = halfday_bits == halfday_bits_all_nights - - if not actorProp.halfday_all and not actorProp.halfday_all_dawns and not actorProp.halfday_all_nights: - for bits in halfday_bits_values: - value = halfday_bits & bits - - if value > 0: - new_entry = actorProp.halfday_bits.add() - new_entry.value = halfday_bits_to_enum[value] + if not is_oot_features(): + if sharedSceneData.includeActorCs: + actorProp.actor_cs_index = spawn_flags[1] + actorProp.use_global_actor_cs = actorProp.actor_cs_index < 127 + + # see `Actor_SpawnEntry()` + halfday_bits = ((spawn_flags[0] & 7) << 7) | (spawn_flags[2] & 0x7F) + actorProp.halfday_all = halfday_bits == halfday_bits_all_dawns | halfday_bits_all_nights + + if not actorProp.halfday_all: + actorProp.halfday_all_dawns = halfday_bits == halfday_bits_all_dawns + actorProp.halfday_all_nights = halfday_bits == halfday_bits_all_nights + + if not actorProp.halfday_all and not actorProp.halfday_all_dawns and not actorProp.halfday_all_nights: + for bits in halfday_bits_values: + value = halfday_bits & bits + + if value > 0: + new_entry = actorProp.halfday_bits.add() + new_entry.value = halfday_bits_to_enum[value] sharedSceneData.actorDict[actorHash] = actorObj diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index f5a67c1c3..ee4aee105 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -472,6 +472,8 @@ def parse_actor_cs(scene_obj: Object, header_index: int, scene_data: str, list_n new_entry.cs_cam_obj = obj break + bpy.context.scene.fast64.oot.global_actor_cs_count = len(props.entries) + def parseSceneCommands( sceneName: str | None, diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index 435694009..a1c8d34c3 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -6,7 +6,7 @@ from bpy.props import FloatProperty, StringProperty, EnumProperty, BoolProperty from ...operators import AddWaterBox, addMaterialByName -from ...utility import parentObject, setOrigin +from ...utility import PluginError, parentObject, setOrigin from ...game_data import game_data from ..cutscene.motion.utility import setupCutscene, createNewCameraShot from ..utility import getNewPath, get_new_empty_object, is_oot_features @@ -317,6 +317,10 @@ def draw(self, context): self.layout.label(text="Warning: This is only useful when using MM features.", icon="ERROR") def execute(self, context: Context): + for obj in bpy.data.objects: + if obj.type == "EMPTY" and obj.ootEmptyType == "Actor Cutscene": + raise PluginError(f"ERROR: an actor cutscene object already exists! ({repr(obj.name)})") + actor_cs_obj = get_new_empty_object(self.obj_name) actor_cs_obj.ootEmptyType = "Actor Cutscene" From a1eda04ee06e95b6ef598c225e45895bcc2e1780 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 8 Aug 2025 13:37:58 +0200 Subject: [PATCH 121/126] format --- fast64_internal/z64/room/properties.py | 4 +++- fast64_internal/z64/tools/operators.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/room/properties.py b/fast64_internal/z64/room/properties.py index 2aec6f33b..581c47d16 100644 --- a/fast64_internal/z64/room/properties.py +++ b/fast64_internal/z64/room/properties.py @@ -239,7 +239,9 @@ def draw_props(self, layout: UILayout, dropdownLabel: str, headerIndex: int, obj timeRow = skyboxAndTime.row() timeRow.prop(self, "timeHours", text="Hours") timeRow.prop(self, "timeMinutes", text="Minutes") - prop_split(skyboxAndTime, self, "timeSpeed", f"Time Speed (default: {game_data.z64.default_time_speed:.2f})") + prop_split( + skyboxAndTime, self, "timeSpeed", f"Time Speed (default: {game_data.z64.default_time_speed:.2f})" + ) # Echo prop_split(skyboxAndTime, self, "echo", "Echo") diff --git a/fast64_internal/z64/tools/operators.py b/fast64_internal/z64/tools/operators.py index a1c8d34c3..07c916635 100644 --- a/fast64_internal/z64/tools/operators.py +++ b/fast64_internal/z64/tools/operators.py @@ -13,6 +13,7 @@ from ..actor_cutscene.properties import enum_end_cam, enum_end_sfx, enum_hud_visibility from .quick_import import QuickImportAborted, quick_import_exec + class OOT_AddWaterBox(AddWaterBox): bl_idname = "object.oot_add_water_box" From 6f490cb8f0d8f77fe5a690cf65034145fe24c40b Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 8 Aug 2025 13:38:17 +0200 Subject: [PATCH 122/126] fix some cs import issues --- fast64_internal/z64/cutscene/constants.py | 14 ++ .../z64/cutscene/importer/classes.py | 141 ++++++++++++------ fast64_internal/z64/cutscene/properties.py | 16 +- fast64_internal/z64/exporter/cutscene/misc.py | 6 +- fast64_internal/z64/exporter/cutscene/text.py | 18 ++- fast64_internal/z64/importer/scene_header.py | 7 +- fast64_internal/z64/utility.py | 5 + 7 files changed, 134 insertions(+), 73 deletions(-) diff --git a/fast64_internal/z64/cutscene/constants.py b/fast64_internal/z64/cutscene/constants.py index 088123422..6bd7c63fe 100644 --- a/fast64_internal/z64/cutscene/constants.py +++ b/fast64_internal/z64/cutscene/constants.py @@ -266,3 +266,17 @@ ootCSListAndSingleCommands = ootCSSingleCommands + ootCSListCommands ootCSListAndSingleCommands.remove("CS_HEADER") ootCutsceneCommandsC = ootCSSingleCommands + ootCSListCommands + ootCSListEntryCommands + +custom_values = [ + "csMiscType", + "csTextType", + "ocarinaAction", + "csSeqID", + "csSeqPlayer", + "rumble_type", + "transition_type", + "blur_type", + "trans_general_type", + "credits_scene_type", + "mod_seq_type", +] diff --git a/fast64_internal/z64/cutscene/importer/classes.py b/fast64_internal/z64/cutscene/importer/classes.py index b52c4980e..7d841aee8 100644 --- a/fast64_internal/z64/cutscene/importer/classes.py +++ b/fast64_internal/z64/cutscene/importer/classes.py @@ -18,6 +18,7 @@ ootCSListEntryCommands, ootCSSingleCommands, ootCSListAndSingleCommands, + custom_values, ) from ..classes import ( @@ -138,6 +139,42 @@ "CS_GIVE_TATL": CutsceneCmdGiveTatl, } +list_type_to_list_prop_member = { + "Text": "textList", + "Misc": "miscList", + "Transition": "transition_list", + "LightSettings": "lightSettingsList", + "Time": "timeList", + "Rumble": "rumbleList", + "MotionBlur": "motion_blur_list", + "TransitionGeneral": "trans_general_list", + "CreditsScene": "credits_scene_list", + "ModifySeq": "mod_seq_list", + "StartSeq": "seqList", + "StopSeq": "seqList", + "FadeOutSeq": "seqList", + "StartAmbience": "seqList", + "FadeOutAmbience": "seqList", +} + +list_type_to_cs_data_member = { + "Text": "textList", + "Misc": "miscList", + "Transition": "transitionList", + "LightSettings": "lightSettingsList", + "Time": "timeList", + "Rumble": "rumbleList", + "MotionBlur": "motion_blur_list", + "TransitionGeneral": "transition_general_list", + "CreditsScene": "credits_scene_list", + "ModifySeq": "modify_seq_list", + "StartSeq": "seqList", + "StopSeq": "seqList", + "FadeOutSeq": "fadeSeqList", + "StartAmbience": "start_ambience_list", + "FadeOutAmbience": "fade_out_ambience_list", +} + @dataclass class ParsedCutscene: @@ -475,6 +512,8 @@ def getCutsceneList(self, use_macros: bool, motion_only: bool): listEntry = entryCmd.from_params( params, "start" if isStartSeq else "stop", isLegacy ) + elif "CS_TEXT_" in cmdEntryName: + listEntry = entryCmd.from_params(params, cmdEntryName) else: listEntry = entryCmd.from_params(params) new_cs_list_data.entries.append(listEntry) @@ -687,19 +726,9 @@ def setPropOrCustom(self, prop, propName: str, value): setattr(prop, f"{propName}_custom" if "_" in propName else f"{propName}Custom", value) def setSubPropertyData(self, subPropsData: dict[str, str], newSubElem, entry): - customNames = [ - "csMiscType", - "csTextType", - "ocarinaAction", - "transition_type", - "csSeqID", - "csSeqPlayer", - "transition", - ] - for key, value in subPropsData.items(): if value is not None: - if key in customNames: + if key in custom_values: valueToSet = getattr(entry, value) self.setPropOrCustom(newSubElem, key, valueToSet) else: @@ -707,44 +736,38 @@ def setSubPropertyData(self, subPropsData: dict[str, str], newSubElem, entry): def setPropertyData(self, csProp: "OOTCutsceneProperty", cutscene: Cutscene, propDataList: list[PropertyData]): for data in propDataList: - listName = f"{data.listType[0].lower() + data.listType[1:]}List" - dataList = getattr(cutscene.data, (listName if data.listType != "FadeOutSeq" else "fadeSeqList")) + listName = list_type_to_list_prop_member[data.listType] + dataList = getattr(cutscene.data, list_type_to_cs_data_member[data.listType]) for list in dataList: newElem: "OOTCSListProperty" = csProp.csLists.add() - - if data.listType == "Seq": - type = "StartSeqList" if list.type == "start" else "StopSeqList" - else: - type = f"{data.listType}List" if data.listType != "Transition" else data.listType - newElem.listType = type - - if data.listType == "Transition": - newElem.transitionStartFrame = list.startFrame - newElem.transitionEndFrame = list.endFrame - self.setSubPropertyData(data.subPropsData, newElem, list) - else: - list.entries.sort(key=lambda elem: elem.startFrame) - for entry in list.entries: - newSubElem = getattr(newElem, "seqList" if "fadeOut" in listName else listName).add() - newSubElem.startFrame = entry.startFrame - - if data.useEndFrame: - newSubElem.endFrame = entry.endFrame - - if data.listType == "Text": - self.setPropOrCustom(newSubElem, "textboxType", entry.id) - match entry.id: - case "Text": - newSubElem.textID = f"0x{entry.textId:04X}" - self.setPropOrCustom(newSubElem, "csTextType", entry.type) - case "None": - pass - case "OcarinaAction": - newSubElem.ocarinaMessageId = f"0x{entry.messageId:04X}" - self.setPropOrCustom(newSubElem, "ocarinaAction", entry.ocarinaActionId) - case _: - raise PluginError("ERROR: Unknown text type!") - self.setSubPropertyData(data.subPropsData, newSubElem, entry) + newElem.listType = f"{data.listType}List" if data.listType != "Transition" else data.listType + + list.entries.sort(key=lambda elem: elem.startFrame) + for entry in list.entries: + name = listName + if data.listType in {"StartSeq", "StopSeq", "StartAmbience", "FadeOutSeq"}: + name = "seqList" + + newSubElem = getattr(newElem, name).add() + newSubElem.startFrame = entry.startFrame + + if data.useEndFrame: + newSubElem.endFrame = entry.endFrame + + if data.listType == "Text": + self.setPropOrCustom(newSubElem, "textboxType", entry.id) + match entry.id: + case "Text": + newSubElem.textID = f"0x{entry.textId:04X}" + self.setPropOrCustom(newSubElem, "csTextType", entry.type) + case "None": + pass + case "OcarinaAction": + newSubElem.ocarinaMessageId = f"0x{entry.messageId:04X}" + self.setPropOrCustom(newSubElem, "ocarinaAction", entry.ocarinaActionId) + case _: + raise PluginError("ERROR: Unknown text type!") + self.setSubPropertyData(data.subPropsData, newSubElem, entry) def setCutsceneData(self, csNumber, use_macros: bool, motion_only: bool): """Creates the cutscene empty objects from the file data""" @@ -810,7 +833,9 @@ def setCutsceneData(self, csNumber, use_macros: bool, motion_only: bool): PropertyData("Transition", {"transition_type": "type"}, True), PropertyData("LightSettings", {"lightSettingsIndex": "lightSetting"}, False), PropertyData("Time", {"hour": "hour", "minute": "minute"}, False), - PropertyData("Seq", {"csSeqID": "seqId"}, False), + PropertyData("StartSeq", {"csSeqID": "seqId"}, True), + PropertyData("StopSeq", {"csSeqID": "seqId"}, True), + PropertyData("StartAmbience", {"csSeqID": "seqId"}, True), PropertyData("FadeOutSeq", {"csSeqPlayer": "seqPlayer"}, True), PropertyData( "Rumble", @@ -818,10 +843,30 @@ def setCutsceneData(self, csNumber, use_macros: bool, motion_only: bool): "rumbleSourceStrength": "sourceStrength", "rumbleDuration": "duration", "rumbleDecreaseRate": "decreaseRate", + "rumble_type": "type", }, False, ), ] + + if not is_oot_features(): + propDataList.extend( + [ + PropertyData("MotionBlur", {"blur_type": "type"}, True), + PropertyData( + "TransitionGeneral", + { + "trans_general_type": "type", + "trans_color": "rgb", + }, + True, + ), + PropertyData("CreditsScene", {"credits_scene_type": "type"}, False), + PropertyData("ModifySeq", {"mod_seq_type": "type"}, False), + PropertyData("FadeOutAmbience", {}, True), + ] + ) + self.setPropertyData(csProp, cutscene, propDataList) # Init camera + preview objects and setup the scene diff --git a/fast64_internal/z64/cutscene/properties.py b/fast64_internal/z64/cutscene/properties.py index a4ab88def..81c2fc019 100644 --- a/fast64_internal/z64/cutscene/properties.py +++ b/fast64_internal/z64/cutscene/properties.py @@ -32,6 +32,7 @@ ootEnumCSTextboxTypeIcons, ootCSSubPropToName, csListTypeToIcon, + custom_values, ) @@ -94,21 +95,8 @@ def draw_props( seqOp.itemIndex = cmdIndex seqOp.listType = listProp.listType - customValues = [ - "csMiscType", - "csTextType", - "ocarinaAction", - "csSeqID", - "csSeqPlayer", - "rumble_type", - "transition_type", - "blur_type", - "trans_general_type", - "credits_scene_type", - "mod_seq_type", - ] value = getattr(self, p) - if name in customValues and value == "Custom": + if name in custom_values and value == "Custom": prop_split(box, self, f"{name}_custom" if "_" in p else f"{name}Custom", f"{displayName} Custom") if is_oot_features() and name == "csTextType" and value != "choice": diff --git a/fast64_internal/z64/exporter/cutscene/misc.py b/fast64_internal/z64/exporter/cutscene/misc.py index 0c45cc11a..bfa0e4194 100644 --- a/fast64_internal/z64/exporter/cutscene/misc.py +++ b/fast64_internal/z64/exporter/cutscene/misc.py @@ -2,7 +2,7 @@ from typing import Optional from ....game_data import game_data from ....utility import PluginError, indent -from ...utility import is_oot_features +from ...utility import is_oot_features, parseColor from ...cutscene.motion.utility import getInteger from .common import CutsceneCmdBase @@ -363,11 +363,13 @@ class CutsceneCmdTransitionGeneral(CutsceneCmdBase): @staticmethod def from_params(params: list[str]): + rgb = list(parseColor((getInteger(params[3]), getInteger(params[4]), getInteger(params[5])))) + rgb.append(1) return CutsceneCmdTransitionGeneral( getInteger(params[1]), getInteger(params[2]), CutsceneCmdBase.getEnumValue("cs_transition_general", params[0]), - [getInteger(params[3]), getInteger(params[4]), getInteger(params[5])], + rgb, ) def to_c(self): diff --git a/fast64_internal/z64/exporter/cutscene/text.py b/fast64_internal/z64/exporter/cutscene/text.py index 87771892e..16e907594 100644 --- a/fast64_internal/z64/exporter/cutscene/text.py +++ b/fast64_internal/z64/exporter/cutscene/text.py @@ -5,6 +5,16 @@ from ...cutscene.motion.utility import getInteger from .common import CutsceneCmdBase +mm_cmd_name_to_type = { + "CS_TEXT_NONE": "CS_TEXT_TYPE_NONE", + "CS_TEXT_DEFAULT": "CS_TEXT_TYPE_DEFAULT", + "CS_TEXT_TYPE_1": "CS_TEXT_TYPE_1", + "CS_TEXT_OCARINA_ACTION": "CS_TEXT_OCARINA_ACTION", + "CS_TEXT_TYPE_3": "CS_TEXT_TYPE_3", + "CS_TEXT_BOSSES_REMAINS": "CS_TEXT_TYPE_BOSSES_REMAINS", + "CS_TEXT_ALL_NORMAL_MASKS": "CS_TEXT_TYPE_ALL_NORMAL_MASKS", +} + @dataclass class CutsceneCmdText(CutsceneCmdBase): @@ -19,7 +29,7 @@ class CutsceneCmdText(CutsceneCmdBase): id: str = field(init=False, default="Text") @staticmethod - def from_params(params: list[str]): + def from_params(params: list[str], cmd_name: str): if is_oot_features(): return CutsceneCmdText( getInteger(params[1]), @@ -34,7 +44,7 @@ def from_params(params: list[str]): getInteger(params[1]), getInteger(params[2]), getInteger(params[0]), - None, + CutsceneCmdBase.getEnumValue("cs_text_type", mm_cmd_name_to_type[cmd_name]), getInteger(params[3]), getInteger(params[4]), ) @@ -70,7 +80,7 @@ class CutsceneCmdTextNone(CutsceneCmdBase): id: str = field(init=False, default="None") @staticmethod - def from_params(params: list[str]): + def from_params(params: list[str], cmd_name: str): return CutsceneCmdTextNone(getInteger(params[0]), getInteger(params[1])) def getCmd(self): @@ -89,7 +99,7 @@ class CutsceneCmdTextOcarinaAction(CutsceneCmdBase): id: str = field(init=False, default="OcarinaAction") @staticmethod - def from_params(params: list[str]): + def from_params(params: list[str], cmd_name: str): return CutsceneCmdTextOcarinaAction( getInteger(params[1]), getInteger(params[2]), diff --git a/fast64_internal/z64/importer/scene_header.py b/fast64_internal/z64/importer/scene_header.py index ee4aee105..f8443c9cb 100644 --- a/fast64_internal/z64/importer/scene_header.py +++ b/fast64_internal/z64/importer/scene_header.py @@ -5,7 +5,7 @@ import mathutils from bpy.types import Object -from ...utility import PluginError, readFile, parentObject, hexOrDecInt, gammaInverse +from ...utility import PluginError, readFile, parentObject, hexOrDecInt from ...game_data import game_data from ...f3d.f3d_parser import parseMatrices from ..model_classes import OOTF3DContext @@ -19,6 +19,7 @@ getEnumIndex, get_new_empty_object, twos_complement, + parseColor, ) from .constants import headerNames from .utility import getDataMatch, stripName @@ -37,10 +38,6 @@ ) -def parseColor(values: tuple[str, str, str]) -> tuple[float, float, float]: - return tuple(gammaInverse([hexOrDecInt(value) / 0xFF for value in values])) - - def parseDirection(index: int, values: tuple[str, str, str]) -> tuple[float, float, float] | int: values = [hexOrDecInt(value) for value in values] diff --git a/fast64_internal/z64/utility.py b/fast64_internal/z64/utility.py index d67f6c926..a2930b9e5 100644 --- a/fast64_internal/z64/utility.py +++ b/fast64_internal/z64/utility.py @@ -24,6 +24,7 @@ applyRotation, cleanupDuplicatedObjects, hexOrDecInt, + gammaInverse, binOps, ) @@ -1058,3 +1059,7 @@ def twos_complement(hexstr: str, bits: int): if value & (1 << (bits - 1)): value -= 1 << bits return value + + +def parseColor(values: tuple[str, str, str]) -> tuple[float, float, float]: + return tuple(gammaInverse([hexOrDecInt(value) / 0xFF for value in values])) From 592b6cc42ff6f63ef1838257ee87f768748ef5c6 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 8 Aug 2025 14:25:59 +0200 Subject: [PATCH 123/126] missed some oot checks for fog preview --- fast64_internal/f3d/f3d_material.py | 8 ++++---- fast64_internal/render_settings.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fast64_internal/f3d/f3d_material.py b/fast64_internal/f3d/f3d_material.py index c613c7390..9db8a6f1b 100644 --- a/fast64_internal/f3d/f3d_material.py +++ b/fast64_internal/f3d/f3d_material.py @@ -149,8 +149,8 @@ def menu_items_enum(_self, context): ] defaultMaterialPresets = { - "Shaded Solid": {"SM64": "Shaded Solid", "OOT": "oot_shaded_solid"}, - "Shaded Texture": {"SM64": "Shaded Texture", "OOT": "oot_shaded_texture"}, + "Shaded Solid": {"SM64": "Shaded Solid", "OOT": "oot_shaded_solid", "MM": "oot_shaded_solid"}, + "Shaded Texture": {"SM64": "Shaded Texture", "OOT": "oot_shaded_texture", "MM": "oot_shaded_texture"}, } F3D_GEO_MODES = { @@ -4860,7 +4860,7 @@ def draw(self, context): prop_split(globalSettingsBox, renderSettings, "light1SpecSize", "Light 1 Specular Size") prop_split(globalSettingsBox, renderSettings, "useWorldSpaceLighting", "Use World Space Lighting") - if context.scene.gameEditorMode in ["SM64", "OOT"]: + if context.scene.gameEditorMode in ["SM64", "OOT", "MM"]: layout.separator(factor=0.5) gameSettingsBox = layout.box() gameSettingsBox.label(text="Preview Context") @@ -4872,7 +4872,7 @@ def draw(self, context): gameSettingsBox.prop(renderSettings, "sm64Area") - case "OOT": + case "OOT" | "MM": if renderSettings.ootSceneObject is not None: gameSettingsBox.prop(renderSettings, "useObjectRenderPreview", text="Use Scene for Preview") diff --git a/fast64_internal/render_settings.py b/fast64_internal/render_settings.py index 29e5a7385..40a26def6 100644 --- a/fast64_internal/render_settings.py +++ b/fast64_internal/render_settings.py @@ -252,7 +252,7 @@ def on_update_render_settings(self, context: bpy.types.Context): match context.scene.gameEditorMode: case "SM64": on_update_sm64_render_settings(self, context) - case "OOT": + case "OOT" | "MM": on_update_oot_render_settings(self, context) case _: pass @@ -396,7 +396,7 @@ class Fast64RenderSettings_Properties(bpy.types.PropertyGroup): update=on_update_sm64_render_settings, poll=poll_sm64_area, ) - # OOT + # OOT and MM ootSceneObject: bpy.props.PointerProperty( name="Scene Object", type=bpy.types.Object, From 678c22701e580fca083a775279b7c90610af47cc Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Fri, 8 Aug 2025 14:28:37 +0200 Subject: [PATCH 124/126] missed some oot checks for fog preview 2 --- fast64_internal/f3d/f3d_gbi.py | 1 + fast64_internal/f3d/flipbook.py | 2 +- fast64_internal/utility.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fast64_internal/f3d/f3d_gbi.py b/fast64_internal/f3d/f3d_gbi.py index a07dd137b..890739efb 100644 --- a/fast64_internal/f3d/f3d_gbi.py +++ b/fast64_internal/f3d/f3d_gbi.py @@ -93,6 +93,7 @@ class GfxMatWriteMethod(enum.Enum): default_draw_layers = { "SM64": sm64_default_draw_layers, "OOT": oot_default_draw_layers, + "MM": oot_default_draw_layers, } CCMUXDict = { diff --git a/fast64_internal/f3d/flipbook.py b/fast64_internal/f3d/flipbook.py index 2377dd069..39b61371b 100644 --- a/fast64_internal/f3d/flipbook.py +++ b/fast64_internal/f3d/flipbook.py @@ -284,7 +284,7 @@ class Flipbook_MaterialPanel(bpy.types.Panel): @classmethod def poll(cls, context): - return context.material is not None and context.scene.gameEditorMode in ["OOT"] + return context.material is not None and context.scene.gameEditorMode in ["OOT", "MM"] def draw(self, context): layout = self.layout diff --git a/fast64_internal/utility.py b/fast64_internal/utility.py index c3a4dd8a0..25093c5f2 100644 --- a/fast64_internal/utility.py +++ b/fast64_internal/utility.py @@ -1657,7 +1657,7 @@ def get_blender_to_game_scale(context): match context.scene.gameEditorMode: case "SM64": return context.scene.fast64.sm64.blender_to_sm64_scale - case "OOT": + case "OOT" | "MM": return context.scene.ootBlenderScale case "F3D": # TODO: (V5) create F3D game editor mode, utilize that scale From 9d2638b2cec0ae8139e00240a10715c1a0c3ecf1 Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Tue, 9 Sep 2025 15:24:07 +0200 Subject: [PATCH 125/126] show shot end frame hint for MM --- fast64_internal/z64/cutscene/motion/properties.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fast64_internal/z64/cutscene/motion/properties.py b/fast64_internal/z64/cutscene/motion/properties.py index 5b15b5cce..245658d41 100644 --- a/fast64_internal/z64/cutscene/motion/properties.py +++ b/fast64_internal/z64/cutscene/motion/properties.py @@ -167,9 +167,10 @@ def getEndFrame(self, camShotObj: Object = None): camShotObj = bpy.context.view_layer.objects.active if camShotObj.type == "ARMATURE": + shot_frame = self.shotStartFrame if game_data.z64.is_oot() else self.shot_duration boneFrameList: list[int] = [bone.ootCamShotPointProp.shotPointFrame for bone in camShotObj.data.bones] # "fake" eye end frame - return self.shotStartFrame + max(2, sum(frame for frame in boneFrameList)) + 1 + return shot_frame + max(2, sum(frame for frame in boneFrameList)) + 1 return -1 def draw_props(self, layout: UILayout, label: str): @@ -193,6 +194,7 @@ def draw_props(self, layout: UILayout, label: str): prop_split(layout_shot, self, "shot_interp_type", "Camera Interpolation Type") if self.shot_interp_type == "Custom": prop_split(layout_shot, self, "shot_interp_type_custom", "") + prop_split(layout_shot, self, "shotEndFrame", "End Frame") box.operator(CutsceneCmdAddBone.bl_idname) From e6eff43cb81e8d1aa7dd6220e2c412d6ed38c95c Mon Sep 17 00:00:00 2001 From: Yanis002 <35189056+Yanis002@users.noreply.github.com> Date: Sun, 2 Nov 2025 19:24:45 +0100 Subject: [PATCH 126/126] fixed import issues Co-authored-by: Nokaubure <15821377+Nokaubure@users.noreply.github.com> --- fast64_internal/z64/importer/scene.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/fast64_internal/z64/importer/scene.py b/fast64_internal/z64/importer/scene.py index 710420fec..2dd73efd3 100644 --- a/fast64_internal/z64/importer/scene.py +++ b/fast64_internal/z64/importer/scene.py @@ -104,8 +104,6 @@ def parseScene( subfolder = None importPath = bpy.path.abspath(bpy.context.scene.ootDecompPath) - if game_data.z64.is_oot(): - sceneName = f"{sceneName}_scene" importSubdir = "" if settings.isCustomDest is not None: @@ -121,7 +119,10 @@ def parseScene( False, True, ) - filePath = os.path.join(sceneFolderPath, f"{sceneName}.c") + if game_data.z64.is_oot(): + filePath = os.path.join(sceneFolderPath, f"{sceneName}_scene.c") + else: + filePath = os.path.join(sceneFolderPath, f"{sceneName}.c") sceneData = readFile(filePath) if bpy.context.mode != "OBJECT": @@ -145,9 +146,14 @@ def parseScene( bpy.context.space_data.overlay.show_curve_normals = True bpy.context.space_data.overlay.normals_length = 2 - sceneCommandsName = f"{sceneName}Commands" + if game_data.z64.is_oot(): + sceneCommandsName = f"{sceneName}_sceneCommands" + else: + sceneCommandsName = f"{sceneName}Commands" + if sceneCommandsName not in sceneData: - sceneCommandsName = f"{sceneName}_header00" # fast64 naming + sceneCommandsName = f"{sceneName}_scene_header00" # fast64 naming + sharedSceneData = SharedSceneData( sceneFolderPath, settings.includeMesh,