diff --git a/korman/nodes/node_conditions.py b/korman/nodes/node_conditions.py index 221508e..6e2aaba 100644 --- a/korman/nodes/node_conditions.py +++ b/korman/nodes/node_conditions.py @@ -18,10 +18,10 @@ from bpy.props import * import math from PyHSPlasma import * -from .node_core import PlasmaNodeBase, PlasmaNodeSocketBase +from .node_core import PlasmaNodeBase, PlasmaNodeSocketBase, PlasmaNodeVariableInput from ..properties.modifiers.physics import bounds_types -class PlasmaClickableNode(PlasmaNodeBase, bpy.types.Node): +class PlasmaClickableNode(PlasmaNodeVariableInput, bpy.types.Node): bl_category = "CONDITIONS" bl_idname = "PlasmaClickableNode" bl_label = "Clickable" @@ -37,6 +37,7 @@ class PlasmaClickableNode(PlasmaNodeBase, bpy.types.Node): def init(self, context): 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("PlasmaConditionSocket", "Satisfies", "satisfies") def draw_buttons(self, context, layout): @@ -44,17 +45,9 @@ class PlasmaClickableNode(PlasmaNodeBase, bpy.types.Node): layout.prop(self, "bounds") def export(self, exporter, tree, parent_bo, parent_so): - # First: look up the clickable mesh. if it is not specified, then it's this BO. - # We do this because we might be exporting from a BO that is not actually the clickable object. - # Case: sitting modifier (exports from sit position empty) - if self.clickable: - clickable_bo = bpy.data.objects.get(self.clickable, None) - if clickable_bo is None: - self.raise_error("invalid Clickable object: '{}'".format(self.clickable), tree) - clickable_so = exporter.mgr.find_create_object(plSceneObject, bl=clickable_bo) - else: + clickable_bo, clickable_so = self._get_objects(exporter, tree, parent_so) + if clickable_bo is None: clickable_bo = parent_bo - clickable_so = parent_so name = self.create_key_name(tree) interface = exporter.mgr.find_create_key(plInterfaceInfoModifier, name=name, so=clickable_so).object @@ -102,9 +95,31 @@ class PlasmaClickableNode(PlasmaNodeBase, bpy.types.Node): face_target = self.find_input_socket("facing") face_target.convert_subcondition(exporter, tree, clickable_bo, clickable_so, logicmod) + def get_key(self, exporter, tree, parent_so): + # careful... we really make lots of keys... + clickable_bo, clickable_so = self._get_objects(exporter, tree, parent_so) + key = exporter.mgr.find_create_key(plLogicModifier, name=self.create_key_name(tree), so=clickable_so) + return key + + def _get_objects(self, exporter, tree, parent_so): + # First: look up the clickable mesh. if it is not specified, then it's this BO. + # We do this because we might be exporting from a BO that is not actually the clickable object. + # Case: sitting modifier (exports from sit position empty) + if self.clickable: + clickable_bo = bpy.data.objects.get(self.clickable, None) + if clickable_bo is None: + self.raise_error("invalid Clickable object: '{}'".format(self.clickable), tree) + clickable_so = exporter.mgr.find_create_object(plSceneObject, bl=clickable_bo) + return (clickable_bo, clickable_so) + else: + return (None, parent_so) + def harvest_actors(self): return (self.clickable,) + def update(self): + self.ensure_sockets("PlasmaRespCommandSocket", "Local Reenable", "enable_callback") + class PlasmaClickableRegionNode(PlasmaNodeBase, bpy.types.Node): bl_category = "CONDITIONS" diff --git a/korman/nodes/node_responder.py b/korman/nodes/node_responder.py index 54014d7..2b9989d 100644 --- a/korman/nodes/node_responder.py +++ b/korman/nodes/node_responder.py @@ -200,10 +200,32 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node): childWaitOn = commandMgr.add_wait(idx) msgNode.convert_callback_message(exporter, tree, so, msg, responder.key, childWaitOn) else: - childWaitOn = -1 + childWaitOn = waitOn command.msg = msg + + # If they linked us back to a condition or something that exports a LogicModifier, that + # means we need to reenable it here... NOTE: we can't filter by the node idname, sadly. + # NOTE: would be incredibly stupid to do this if we're not waiting on anything to complete + if childWaitOn != -1: + for child in self.find_outputs("trigger"): + key = child.get_key(exporter, tree, so) + if key is None: + continue + logicmod = key.object + if not isinstance(logicmod, plLogicModifier): + continue + logicmod.setLogicFlag(plLogicModifier.kOneShot, True) + + # Yep, this is an entirely new ResponderCommand that sends a plEnableMsg + enableMsg = plEnableMsg() + enableMsg.addReceiver(key) + enableMsg.sender = responder.key + enableMsg.BCastFlags |= plMessage.kLocalPropagate + enableMsg.setCmd(plEnableMsg.kEnable, True) + logicCmdIdx, logicCmd = commandMgr.add_command(self, childWaitOn) + logicCmd.msg = enableMsg else: - childWaitOn = -1 + childWaitOn = waitOn # Export any child commands for i in self.find_outputs("trigger", "PlasmaResponderCommandNode"):