Browse Source

Implement "OneShot" logic mods

ResponderCommands can now reenable clickables by making a connection. This
will only work for the client who clicked on the clickable however. It's
still a useful feature regardless.

Also fixes some bugs when adding commands onto a command with no wait of
its own that waited on another command.
pull/10/head
Adam Johnson 9 years ago
parent
commit
17714b9d2a
  1. 39
      korman/nodes/node_conditions.py
  2. 26
      korman/nodes/node_responder.py

39
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"

26
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"):

Loading…
Cancel
Save