diff --git a/korman/nodes/node_messages.py b/korman/nodes/node_messages.py index bed7009..4313012 100644 --- a/korman/nodes/node_messages.py +++ b/korman/nodes/node_messages.py @@ -13,16 +13,24 @@ # You should have received a copy of the GNU General Public License # along with Korman. If not, see . +from __future__ import annotations + import bpy from bpy.props import * -from collections import OrderedDict from PyHSPlasma import * +from collections import OrderedDict +from typing import * + from .node_core import * +from ..properties.modifiers.physics import subworld_types from ..properties.modifiers.region import footstep_surfaces, footstep_surface_ids from ..exporter import ExportError from .. import idprops +if TYPE_CHECKING: + from ..exporter import Exporter + class PlasmaMessageSocketBase(PlasmaNodeSocketBase): bl_color = (0.004, 0.282, 0.349, 1.0) class PlasmaMessageSocket(PlasmaMessageSocketBase, bpy.types.NodeSocket): @@ -925,6 +933,75 @@ class PlasmaSoundMsgNode(idprops.IDPropObjectMixin, PlasmaMessageWithCallbacksNo return False +class PlasmaSubworldMsgNode(PlasmaMessageNode, bpy.types.Node): + bl_category = "MSG" + bl_idname = "PlasmaSubworldMsgNode" + bl_label = "Change Subworld" + bl_width_default = 200 + + sub_type_value = EnumProperty( + items=subworld_types, + default="subworld", + options={"HIDDEN"} + ) + + def _get_sub_type(self) -> int: + if self.subworld is not None: + self.sub_type_value = self.subworld.plasma_modifiers.subworld_def.sub_type + if not self.sub_type_value: + self.sub_type_value = "subworld" + return next( + i for i, sub_type in enumerate(subworld_types) + if sub_type[0] == self.sub_type_value + ) + def _set_sub_type(self, value: int): + value_str = subworld_types[value][0] + if self.subworld is not None: + self.subworld.plasma_modifiers.subworld_def.sub_type = value_str + self.sub_type_value = value_str + + sub_type: str = EnumProperty( + name="Subworld Type", + description="Specifies the physics strategy to use for this subworld", + items=subworld_types, + get=_get_sub_type, + set=_set_sub_type, + options=set() + ) + + subworld: bpy.types.Object = PointerProperty( + name="Subworld", + description="Subworld to move the player to (leave empty for the main world)", + poll=idprops.poll_subworld_objects, + type=bpy.types.Object + ) + + def draw_buttons(self, context, layout): + need_world_type = self.subworld is None and self.sub_type == "auto" + layout.alert = need_world_type + layout.prop(self, "sub_type", text="Type") + if need_world_type: + layout.label("When leaving a subworld, the subworld type MUST be specified!", icon="ERROR") + layout.alert = False + + layout.prop(self, "subworld") + + def convert_message(self, exporter: Exporter, so: plSceneObject): + if self.subworld is None and self.sub_type == "auto": + self.raise_error("When leaving a subworld, the subworld type MUST be specified!") + + if exporter.physics.is_dedicated_subworld(self.subworld) or self.sub_type == "subworld": + msg = plSubWorldMsg() + if self.subworld: + msg.worldKey = exporter.mgr.find_key(plSceneObject, bl=self.subworld) + return msg + else: + msg = plRideAnimatedPhysMsg() + msg.BCastFlags |= plMessage.kPropagateToModifiers + msg.entering = self.subworld is not None + return msg + + class PlasmaTimerCallbackMsgNode(PlasmaMessageWithCallbacksNode, bpy.types.Node): bl_category = "MSG" bl_idname = "PlasmaTimerCallbackMsgNode" diff --git a/korman/properties/modifiers/physics.py b/korman/properties/modifiers/physics.py index 96382ef..7bed918 100644 --- a/korman/properties/modifiers/physics.py +++ b/korman/properties/modifiers/physics.py @@ -49,6 +49,12 @@ surface_types = ( ("kUser3", "User 3", ""), ) +subworld_types = ( + ("auto", "Auto", "Korman will decide which physics strategy to use"), + ("dynamicav", "Dynamic Avatar", "Allows the avatar to affected by dynamic physicals"), + ("subworld", "Separate World", "Causes all objects to be placed in a separate physics simulation"), +) + def bounds_type_index(key): return list(zip(*bounds_types))[0].index(key) @@ -136,9 +142,7 @@ class PlasmaSubworld(PlasmaModifierProperties): sub_type = EnumProperty(name="Subworld Type", description="Specifies the physics strategy to use for this subworld", - items=[("auto", "Auto", "Korman will decide which physics strategy to use"), - ("dynamicav", "Dynamic Avatar", "Allows the avatar to affected by dynamic physicals"), - ("subworld", "Separate World", "Causes all objects to be placed in a separate physics simulation")], + items=subworld_types, default="auto", options=set()) gravity = FloatVectorProperty(name="Gravity",