From 8e71703e3c85517adbd1451329f999b28803b4b2 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 14 Jul 2015 21:32:46 -0400 Subject: [PATCH] Fix linking activators to PFMs ... And finally relent on exposing the keys of region sensors. Oh boy, the fallout from this change will be fun to contain :/ --- korman/nodes/node_conditions.py | 59 ++++++++++++++++++++++++++++----- korman/nodes/node_core.py | 3 ++ korman/nodes/node_python.py | 49 ++++++++++++++------------- 3 files changed, 79 insertions(+), 32 deletions(-) diff --git a/korman/nodes/node_conditions.py b/korman/nodes/node_conditions.py index ea9af0b..ce2333c 100644 --- a/korman/nodes/node_conditions.py +++ b/korman/nodes/node_conditions.py @@ -38,6 +38,7 @@ class PlasmaClickableNode(PlasmaNodeVariableInput, bpy.types.Node): self.inputs.new("PlasmaClickableRegionSocket", "Avatar Inside Region", "region") self.inputs.new("PlasmaFacingTargetSocket", "Avatar Facing Target", "facing") self.inputs.new("PlasmaRespCommandSocket", "Local Reenable", "enable_callback") + self.outputs.new("PlasmaPythonReferenceNodeSocket", "References", "keyref") self.outputs.new("PlasmaConditionSocket", "Satisfies", "satisfies") def draw_buttons(self, context, layout): @@ -135,7 +136,6 @@ class PlasmaClickableRegionNode(PlasmaNodeBase, bpy.types.Node): default="hull") def init(self, context): - self.outputs.new("PlasmaPythonReferenceNodeSocket", "References", "keyref") self.outputs.new("PlasmaClickableRegionSocket", "Satisfies", "satisfies") def draw_buttons(self, context, layout): @@ -303,6 +303,7 @@ class PlasmaVolumeSensorNode(PlasmaNodeBase, bpy.types.Node): def init(self, context): self.inputs.new("PlasmaVolumeSettingsSocketIn", "Trigger on Enter", "enter") self.inputs.new("PlasmaVolumeSettingsSocketIn", "Trigger on Exit", "exit") + self.outputs.new("PlasmaPythonReferenceNodeSocket", "References", "keyref") self.outputs.new("PlasmaConditionSocket", "Satisfies", "satisfies") def draw_buttons(self, context, layout): @@ -312,29 +313,52 @@ class PlasmaVolumeSensorNode(PlasmaNodeBase, bpy.types.Node): layout.prop_search(self, "region", bpy.data, "objects", icon="MESH_DATA") layout.prop(self, "bounds") - def export(self, exporter, bo, so): - interface = exporter.mgr.add_object(plInterfaceInfoModifier, name=self.key_name, so=so) + def get_key(self, exporter, parent_so): + bo = self.region_object + so = exporter.find_create_object(plSceneObject, bl=bo) + rgn_enter, rgn_exit = None, None + + if self.report_enters: + theName = "{}_{}_Enter".format(self.id_data.name, self.name) + rgn_enter = exporter.mgr.find_create_key(plLogicModifier, name=theName, so=so) + if self.report_exits: + theName = "{}_{}_Exit".format(self.id_data.name, self.name) + rgn_exit = exporter.mgr.find_create_key(plLogicModifier, name=theName, so=so) + + if rgn_enter is None: + return rgn_exit + elif rgn_exit is None: + return rgn_enter + else: + # !!! ... !!! + # Sorry + # -- Hoikas + # !!! ... !!! + return (rgn_enter, rgn_exit) + + def export(self, exporter, bo, parent_so): + # We need to ensure we export to the correct SO + region_bo = self.region_object + region_so = exporter.mgr.find_create_object(plSceneObject, bl=region_bo) + interface = exporter.mgr.find_create_object(plInterfaceInfoModifier, name=self.key_name, so=region_so) # Region Enters enter_simple = self.find_input_socket("enter").allow enter_settings = self.find_input("enter", "PlasmaVolumeReportNode") if enter_simple or enter_settings is not None: - key = self._export_volume_event(exporter, bo, so, plVolumeSensorConditionalObject.kTypeEnter, enter_settings) + key = self._export_volume_event(exporter, region_bo, region_so, plVolumeSensorConditionalObject.kTypeEnter, enter_settings) interface.addIntfKey(key) # Region Exits exit_simple = self.find_input_socket("exit").allow exit_settings = self.find_input("exit", "PlasmaVolumeReportNode") if exit_simple or exit_settings is not None: - key = self._export_volume_event(exporter, bo, so, plVolumeSensorConditionalObject.kTypeExit, exit_settings) + key = self._export_volume_event(exporter, region_bo, region_so, plVolumeSensorConditionalObject.kTypeExit, exit_settings) interface.addIntfKey(key) # Don't forget to export the physical object itself! # [trollface.jpg] - phys_bo = bpy.data.objects.get(self.region, None) - if phys_bo is None: - self.raise_error("invalid Region object: '{}'".format(self.region)) - simIface, physical = exporter.physics.generate_physical(phys_bo, so, self.bounds, "{}_VolumeSensor".format(bo.name)) + simIface, physical = exporter.physics.generate_physical(region_bo, region_so, self.bounds, "{}_VolumeSensor".format(region_bo.name)) physical.memberGroup = plSimDefs.kGroupDetector if "avatar" in self.report_on: @@ -379,6 +403,23 @@ class PlasmaVolumeSensorNode(PlasmaNodeBase, bpy.types.Node): logicmod.addCondition(volKey) return logicKey + @property + def region_object(self): + phys_bo = bpy.data.objects.get(self.region, None) + if phys_bo is None: + self.raise_error("invalid Region object: '{}'".format(self.region)) + return phys_bo + + @property + def report_enters(self): + return (self.find_input_socket("enter").allow or + self.find_input("enter", "PlasmaVolumeReportNode") is not None) + + @property + def report_exits(self): + return (self.find_input_socket("exit").allow or + self.find_input("exit", "PlasmaVolumeReportNode") is not None) + class PlasmaVolumeSettingsSocket(PlasmaNodeSocketBase): bl_color = (43.1, 24.7, 0.0, 1.0) diff --git a/korman/nodes/node_core.py b/korman/nodes/node_core.py index 127f5d6..cdc30d5 100644 --- a/korman/nodes/node_core.py +++ b/korman/nodes/node_core.py @@ -27,6 +27,9 @@ class PlasmaNodeBase: key = i.get_key(exporter, so) if key is None: exporter.report.warn(" '{}' Node '{}' doesn't expose a key. It won't be triggered by '{}'!".format(i.bl_idname, i.name, self.name), indent=3) + elif isinstance(key, tuple): + for i in key: + notify.addReceiver(key) else: notify.addReceiver(key) return notify diff --git a/korman/nodes/node_python.py b/korman/nodes/node_python.py index 9918604..9845b68 100644 --- a/korman/nodes/node_python.py +++ b/korman/nodes/node_python.py @@ -171,29 +171,32 @@ class PlasmaPythonFileNode(PlasmaNodeBase, bpy.types.Node): attrib = socket.attribute_type from_node = socket.links[0].from_node - param = plPythonParameter() - param.id = socket.attribute_id - param.valueType = _attrib2param[attrib] - if socket.is_simple_value: - param.value = from_node.value - else: - key = from_node.get_key(exporter, so) - if key is None: - msg = "'{}' Node '{}' didn't return a key and therefore will be unavailable to Python".format( - self.id_data.name, from_node.name) - exporter.report.warn(msg, indent=3) - else: - key_type = _attrib_key_types[attrib] - if isinstance(key_type, tuple): - good_key = key.type in key_type - else: - good_key = key.type == key.type - if not good_key: - msg = "'{}' Node '{}' returned an unexpected key type '{}'".format( - self.id_data.name, from_node.name, plFactory.ClassName(key.type)) + value = from_node.value if socket.is_simple_value else from_node.get_key(exporter, so) + if not isinstance(value, tuple): + value = (value,) + for i in value: + param = plPythonParameter() + param.id = socket.attribute_id + param.valueType = _attrib2param[attrib] + param.value = i + + # Key type sanity checking... Because I trust no user. + if not socket.is_simple_value: + if i is None: + msg = "'{}' Node '{}' didn't return a key and therefore will be unavailable to Python".format( + self.id_data.name, from_node.name) exporter.report.warn(msg, indent=3) - param.value = key - pfm.addParameter(param) + else: + key_type = _attrib_key_types[attrib] + if isinstance(key_type, tuple): + good_key = i.type in key_type + else: + good_key = i.type == key_type + if not good_key: + msg = "'{}' Node '{}' returned an unexpected key type '{}'".format( + self.id_data.name, from_node.name, plFactory.ClassName(i.type)) + exporter.report.warn(msg, indent=3) + pfm.addParameter(param) def _get_attrib_sockets(self, idx): for i in self.inputs: @@ -424,7 +427,7 @@ class PlasmaAttribObjectNode(PlasmaAttribNodeBase, bpy.types.Node): self.raise_error("must be connected to a Python File node!") attrib = attrib.attribute_type - bo = bpy.objects.data.get(self.object_name, None) + bo = bpy.data.objects.get(self.object_name, None) if bo is None: self.raise_error("invalid object specified: '{}'".format(self.object_name)) ref_so_key = exporter.mgr.find_create_key(plSceneObject, bl=bo)