Browse Source

The node tree is not a cheap whore

No need to pass it around like one. Just grab your own copy of it from
`Node.id_data`... Why is this not documented more clearly?
pull/10/head
Adam Johnson 9 years ago
parent
commit
a583540446
  1. 8
      korman/nodes/node_avatar.py
  2. 50
      korman/nodes/node_conditions.py
  3. 29
      korman/nodes/node_core.py
  4. 36
      korman/nodes/node_messages.py
  5. 26
      korman/nodes/node_responder.py
  6. 6
      korman/properties/modifiers/avatar.py
  7. 8
      korman/properties/modifiers/region.py

8
korman/nodes/node_avatar.py

@ -45,11 +45,11 @@ class PlasmaSittingBehaviorNode(PlasmaNodeBase, bpy.types.Node):
def draw_buttons_ext(self, context, layout): def draw_buttons_ext(self, context, layout):
layout.prop_menu_enum(self, "approach") layout.prop_menu_enum(self, "approach")
def get_key(self, exporter, tree, so): def get_key(self, exporter, so):
return exporter.mgr.find_create_key(plSittingModifier, name=self.create_key_name(tree), so=so) return exporter.mgr.find_create_key(plSittingModifier, name=self.key_name, so=so)
def export(self, exporter, tree, bo, so): def export(self, exporter, bo, so):
sitmod = self.get_key(exporter, tree, so).object sitmod = self.get_key(exporter, so).object
for flag in self.approach: for flag in self.approach:
sitmod.miscFlags |= getattr(plSittingModifier, flag) sitmod.miscFlags |= getattr(plSittingModifier, flag)
for key in self.find_outputs("satisfies"): for key in self.find_outputs("satisfies"):

50
korman/nodes/node_conditions.py

@ -44,12 +44,12 @@ class PlasmaClickableNode(PlasmaNodeVariableInput, bpy.types.Node):
layout.prop_search(self, "clickable", bpy.data, "objects", icon="MESH_DATA") layout.prop_search(self, "clickable", bpy.data, "objects", icon="MESH_DATA")
layout.prop(self, "bounds") layout.prop(self, "bounds")
def export(self, exporter, tree, parent_bo, parent_so): def export(self, exporter, parent_bo, parent_so):
clickable_bo, clickable_so = self._get_objects(exporter, tree, parent_so) clickable_bo, clickable_so = self._get_objects(exporter, parent_so)
if clickable_bo is None: if clickable_bo is None:
clickable_bo = parent_bo clickable_bo = parent_bo
name = self.create_key_name(tree) name = self.key_name
interface = exporter.mgr.find_create_key(plInterfaceInfoModifier, name=name, so=clickable_so).object interface = exporter.mgr.find_create_key(plInterfaceInfoModifier, name=name, so=clickable_so).object
logicmod = exporter.mgr.find_create_key(plLogicModifier, name=name, so=clickable_so) logicmod = exporter.mgr.find_create_key(plLogicModifier, name=name, so=clickable_so)
interface.addIntfKey(logicmod) interface.addIntfKey(logicmod)
@ -84,31 +84,31 @@ class PlasmaClickableNode(PlasmaNodeVariableInput, bpy.types.Node):
logicmod.addCondition(activator.key) logicmod.addCondition(activator.key)
logicmod.setLogicFlag(plLogicModifier.kLocalElement, True) logicmod.setLogicFlag(plLogicModifier.kLocalElement, True)
logicmod.cursor = plCursorChangeMsg.kCursorPoised logicmod.cursor = plCursorChangeMsg.kCursorPoised
logicmod.notify = self.generate_notify_msg(exporter, tree, parent_so, "satisfies") logicmod.notify = self.generate_notify_msg(exporter, parent_so, "satisfies")
# If we have a region attached, let it convert. # If we have a region attached, let it convert.
region = self.find_input("region", "PlasmaClickableRegionNode") region = self.find_input("region", "PlasmaClickableRegionNode")
if region is not None: if region is not None:
region.convert_subcondition(exporter, tree, clickable_bo, clickable_so, logicmod) region.convert_subcondition(exporter, clickable_bo, clickable_so, logicmod)
# Hand things off to the FaceTarget socket which does things nicely for us # Hand things off to the FaceTarget socket which does things nicely for us
face_target = self.find_input_socket("facing") face_target = self.find_input_socket("facing")
face_target.convert_subcondition(exporter, tree, clickable_bo, clickable_so, logicmod) face_target.convert_subcondition(exporter, clickable_bo, clickable_so, logicmod)
def get_key(self, exporter, tree, parent_so): def get_key(self, exporter, parent_so):
# careful... we really make lots of keys... # careful... we really make lots of keys...
clickable_bo, clickable_so = self._get_objects(exporter, tree, parent_so) clickable_bo, clickable_so = self._get_objects(exporter, parent_so)
key = exporter.mgr.find_create_key(plLogicModifier, name=self.create_key_name(tree), so=clickable_so) key = exporter.mgr.find_create_key(plLogicModifier, name=self.key_name, so=clickable_so)
return key return key
def _get_objects(self, exporter, tree, parent_so): def _get_objects(self, exporter, parent_so):
# First: look up the clickable mesh. if it is not specified, then it's this BO. # 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. # 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) # Case: sitting modifier (exports from sit position empty)
if self.clickable: if self.clickable:
clickable_bo = bpy.data.objects.get(self.clickable, None) clickable_bo = bpy.data.objects.get(self.clickable, None)
if clickable_bo is None: if clickable_bo is None:
self.raise_error("invalid Clickable object: '{}'".format(self.clickable), tree) self.raise_error("invalid Clickable object: '{}'".format(self.clickable))
clickable_so = exporter.mgr.find_create_object(plSceneObject, bl=clickable_bo) clickable_so = exporter.mgr.find_create_object(plSceneObject, bl=clickable_bo)
return (clickable_bo, clickable_so) return (clickable_bo, clickable_so)
else: else:
@ -141,11 +141,11 @@ class PlasmaClickableRegionNode(PlasmaNodeBase, bpy.types.Node):
layout.prop_search(self, "region", bpy.data, "objects", icon="MESH_DATA") layout.prop_search(self, "region", bpy.data, "objects", icon="MESH_DATA")
layout.prop(self, "bounds") layout.prop(self, "bounds")
def convert_subcondition(self, exporter, tree, parent_bo, parent_so, logicmod): def convert_subcondition(self, exporter, parent_bo, parent_so, logicmod):
# REMEMBER: parent_so doesn't have to be the actual region scene object... # REMEMBER: parent_so doesn't have to be the actual region scene object...
region_bo = bpy.data.objects.get(self.region, None) region_bo = bpy.data.objects.get(self.region, None)
if region_bo is None: if region_bo is None:
self.raise_error("invalid Region object: '{}'".format(self.region), tree) self.raise_error("invalid Region object: '{}'".format(self.region))
region_so = exporter.mgr.find_create_key(plSceneObject, bl=region_bo).object region_so = exporter.mgr.find_create_key(plSceneObject, bl=region_bo).object
# Try to figure out the appropriate bounds type for the region.... # Try to figure out the appropriate bounds type for the region....
@ -163,7 +163,7 @@ class PlasmaClickableRegionNode(PlasmaNodeBase, bpy.types.Node):
# one detector for many unrelated logic mods. However, LogicMods and Conditions appear to # one detector for many unrelated logic mods. However, LogicMods and Conditions appear to
# assume they pwn each other... so we need a unique detector. This detector must be attached # assume they pwn each other... so we need a unique detector. This detector must be attached
# as a modifier to the region's SO however. # as a modifier to the region's SO however.
name = self.create_key_name(tree) name = self.key_name
detector_key = exporter.mgr.find_create_key(plObjectInVolumeDetector, name=name, so=region_so) detector_key = exporter.mgr.find_create_key(plObjectInVolumeDetector, name=name, so=region_so)
detector = detector_key.object detector = detector_key.object
detector.addReceiver(logicmod.key) detector.addReceiver(logicmod.key)
@ -216,7 +216,7 @@ class PlasmaFacingTargetSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket):
layout.prop(self, "allow_simple", text="") layout.prop(self, "allow_simple", text="")
layout.label(text) layout.label(text)
def convert_subcondition(self, exporter, tree, bo, so, logicmod): def convert_subcondition(self, exporter, bo, so, logicmod):
assert not self.is_output assert not self.is_output
if not self.enable_condition: if not self.enable_condition:
return return
@ -225,12 +225,12 @@ class PlasmaFacingTargetSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket):
if self.simple_mode: if self.simple_mode:
directional = True directional = True
tolerance = 45 tolerance = 45
name = "{}_SimpleFacing".format(self.node.create_key_name(tree)) name = "{}_SimpleFacing".format(self.node.key_name)
elif self.is_linked: elif self.is_linked:
node = self.links[0].from_node node = self.links[0].from_node
directional = node.directional directional = node.directional
tolerance = node.tolerance tolerance = node.tolerance
name = node.create_key_name(tree) name = node.key_name
else: else:
# This is a programmer failure, so we need a traceback. # This is a programmer failure, so we need a traceback.
raise RuntimeError("Tried to export an unused PlasmaFacingTargetSocket") raise RuntimeError("Tried to export an unused PlasmaFacingTargetSocket")
@ -311,28 +311,28 @@ class PlasmaVolumeSensorNode(PlasmaNodeBase, bpy.types.Node):
layout.prop_search(self, "region", bpy.data, "objects", icon="MESH_DATA") layout.prop_search(self, "region", bpy.data, "objects", icon="MESH_DATA")
layout.prop(self, "bounds") layout.prop(self, "bounds")
def export(self, exporter, tree, bo, so): def export(self, exporter, bo, so):
interface = exporter.mgr.add_object(plInterfaceInfoModifier, name=self.create_key_name(tree), so=so) interface = exporter.mgr.add_object(plInterfaceInfoModifier, name=self.key_name, so=so)
# Region Enters # Region Enters
enter_simple = self.find_input_socket("enter").allow enter_simple = self.find_input_socket("enter").allow
enter_settings = self.find_input("enter", "PlasmaVolumeReportNode") enter_settings = self.find_input("enter", "PlasmaVolumeReportNode")
if enter_simple or enter_settings is not None: if enter_simple or enter_settings is not None:
key = self._export_volume_event(exporter, tree, bo, so, plVolumeSensorConditionalObject.kTypeEnter, enter_settings) key = self._export_volume_event(exporter, bo, so, plVolumeSensorConditionalObject.kTypeEnter, enter_settings)
interface.addIntfKey(key) interface.addIntfKey(key)
# Region Exits # Region Exits
exit_simple = self.find_input_socket("exit").allow exit_simple = self.find_input_socket("exit").allow
exit_settings = self.find_input("exit", "PlasmaVolumeReportNode") exit_settings = self.find_input("exit", "PlasmaVolumeReportNode")
if exit_simple or exit_settings is not None: if exit_simple or exit_settings is not None:
key = self._export_volume_event(exporter, tree, bo, so, plVolumeSensorConditionalObject.kTypeExit, exit_settings) key = self._export_volume_event(exporter, bo, so, plVolumeSensorConditionalObject.kTypeExit, exit_settings)
interface.addIntfKey(key) interface.addIntfKey(key)
# Don't forget to export the physical object itself! # Don't forget to export the physical object itself!
# [trollface.jpg] # [trollface.jpg]
phys_bo = bpy.data.objects.get(self.region, None) phys_bo = bpy.data.objects.get(self.region, None)
if phys_bo is None: if phys_bo is None:
self.raise_error("invalid Region object: '{}'".format(self.region), tree) 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(phys_bo, so, self.bounds, "{}_VolumeSensor".format(bo.name))
physical.memberGroup = plSimDefs.kGroupDetector physical.memberGroup = plSimDefs.kGroupDetector
@ -341,18 +341,18 @@ class PlasmaVolumeSensorNode(PlasmaNodeBase, bpy.types.Node):
if "dynamics" in self.report_on: if "dynamics" in self.report_on:
physical.reportGroup |= 1 << plSimDefs.kGroupDynamic physical.reportGroup |= 1 << plSimDefs.kGroupDynamic
def _export_volume_event(self, exporter, tree, bo, so, event, settings): def _export_volume_event(self, exporter, bo, so, event, settings):
if event == plVolumeSensorConditionalObject.kTypeEnter: if event == plVolumeSensorConditionalObject.kTypeEnter:
suffix = "Enter" suffix = "Enter"
else: else:
suffix = "Exit" suffix = "Exit"
theName = "{}_{}_{}".format(tree.name, self.name, suffix) theName = "{}_{}_{}".format(self.id_data.name, self.name, suffix)
print(" [LogicModifier '{}']".format(theName)) print(" [LogicModifier '{}']".format(theName))
logicKey = exporter.mgr.find_create_key(plLogicModifier, name=theName, so=so) logicKey = exporter.mgr.find_create_key(plLogicModifier, name=theName, so=so)
logicmod = logicKey.object logicmod = logicKey.object
logicmod.setLogicFlag(plLogicModifier.kMultiTrigger, True) logicmod.setLogicFlag(plLogicModifier.kMultiTrigger, True)
logicmod.notify = self.generate_notify_msg(exporter, tree, so, "satisfies") logicmod.notify = self.generate_notify_msg(exporter, so, "satisfies")
# Now, the detector objects # Now, the detector objects
print(" [ObjectInVolumeDetector '{}']".format(theName)) print(" [ObjectInVolumeDetector '{}']".format(theName))

29
korman/nodes/node_core.py

@ -20,24 +20,21 @@ from PyHSPlasma import plMessage, plNotifyMsg
from ..exporter import ExportError from ..exporter import ExportError
class PlasmaNodeBase: class PlasmaNodeBase:
def create_key_name(self, tree): def generate_notify_msg(self, exporter, so, socket_id, idname=None):
return "{}_{}".format(tree.name, self.name)
def generate_notify_msg(self, exporter, tree, so, socket_id, idname=None):
notify = plNotifyMsg() notify = plNotifyMsg()
notify.BCastFlags = (plMessage.kNetPropagate | plMessage.kLocalPropagate) notify.BCastFlags = (plMessage.kNetPropagate | plMessage.kLocalPropagate)
for i in self.find_outputs(socket_id, idname): for i in self.find_outputs(socket_id, idname):
key = i.get_key(exporter, tree, so) key = i.get_key(exporter, so)
if key is None: 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) 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)
else: else:
notify.addReceiver(key) notify.addReceiver(key)
return notify return notify
def get_key(self, exporter, tree, so): def get_key(self, exporter, so):
return None return None
def export(self, exporter, tree, bo, so): def export(self, exporter, bo, so):
pass pass
def find_input(self, key, idname=None): def find_input(self, key, idname=None):
@ -98,7 +95,11 @@ class PlasmaNodeBase:
def harvest_actors(self): def harvest_actors(self):
return set() return set()
def link_input(self, tree, node, out_key, in_key): @property
def key_name(self):
return "{}_{}".format(self.id_data.name, self.name)
def link_input(self, node, out_key, in_key):
"""Links a given Node's output socket to a given input socket on this Node""" """Links a given Node's output socket to a given input socket on this Node"""
if isinstance(in_key, str): if isinstance(in_key, str):
in_socket = self.find_input_socket(in_key) in_socket = self.find_input_socket(in_key)
@ -108,9 +109,9 @@ class PlasmaNodeBase:
out_socket = node.find_output_socket(out_key) out_socket = node.find_output_socket(out_key)
else: else:
out_socket = out_key out_socket = out_key
link = tree.links.new(in_socket, out_socket) link = self.id_data.links.new(in_socket, out_socket)
def link_output(self, tree, node, out_key, in_key): def link_output(self, node, out_key, in_key):
"""Links a given Node's input socket to a given output socket on this Node""" """Links a given Node's input socket to a given output socket on this Node"""
if isinstance(in_key, str): if isinstance(in_key, str):
in_socket = node.find_input_socket(in_key) in_socket = node.find_input_socket(in_key)
@ -120,14 +121,14 @@ class PlasmaNodeBase:
out_socket = self.find_output_socket(out_key) out_socket = self.find_output_socket(out_key)
else: else:
out_socket = out_key out_socket = out_key
link = tree.links.new(in_socket, out_socket) link = self.id_data.links.new(in_socket, out_socket)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return (context.bl_idname == "PlasmaNodeTree") return (context.bl_idname == "PlasmaNodeTree")
def raise_error(self, message, tree): def raise_error(self, message):
final = "Plasma Node Tree '{}' Node '{}': {}".format(tree.name, self.name, message) final = "Plasma Node Tree '{}' Node '{}': {}".format(self.id_data.name, self.name, message)
raise ExportError(final) raise ExportError(final)
@property @property
@ -167,7 +168,7 @@ class PlasmaNodeTree(bpy.types.NodeTree):
def export(self, exporter, bo, so): def export(self, exporter, bo, so):
# just pass it off to each node # just pass it off to each node
for node in self.nodes: for node in self.nodes:
node.export(exporter, self, bo, so) node.export(exporter, bo, so)
def harvest_actors(self): def harvest_actors(self):
actors = set() actors = set()

36
korman/nodes/node_messages.py

@ -150,24 +150,24 @@ class PlasmaAnimCmdMsgNode(PlasmaMessageNode, bpy.types.Node):
layout.prop(self, "event") layout.prop(self, "event")
def convert_callback_message(self, exporter, tree, so, msg, target, wait): def convert_callback_message(self, exporter, so, msg, target, wait):
cb = plEventCallbackMsg() cb = plEventCallbackMsg()
cb.addReceiver(target) cb.addReceiver(target)
cb.event = globals()[self.event] cb.event = globals()[self.event]
cb.user = wait cb.user = wait
msg.addCallback(cb) msg.addCallback(cb)
def convert_message(self, exporter, tree, so): def convert_message(self, exporter, so):
msg = plAnimCmdMsg() msg = plAnimCmdMsg()
# We're either sending this off to an AGMasterMod or a LayerAnim # We're either sending this off to an AGMasterMod or a LayerAnim
if self.anim_type == "OBJECT": if self.anim_type == "OBJECT":
obj = bpy.data.objects.get(self.object_name, None) obj = bpy.data.objects.get(self.object_name, None)
if obj is None: if obj is None:
self.raise_error("invalid object: '{}'".format(self.object_name), tree) self.raise_error("invalid object: '{}'".format(self.object_name))
anim = obj.plasma_modifiers.animation anim = obj.plasma_modifiers.animation
if not anim.enabled: if not anim.enabled:
self.raise_error("invalid animation", tree) self.raise_error("invalid animation")
group = obj.plasma_modifiers.animation_group group = obj.plasma_modifiers.animation_group
if group.enabled: if group.enabled:
# we might be controlling more than one animation. isn't that cute? # we might be controlling more than one animation. isn't that cute?
@ -181,10 +181,10 @@ class PlasmaAnimCmdMsgNode(PlasmaMessageNode, bpy.types.Node):
else: else:
material = bpy.data.materials.get(self.material_name, None) material = bpy.data.materials.get(self.material_name, None)
if material is None: if material is None:
self.raise_error("invalid material: '{}'".format(self.material_name), tree) self.raise_error("invalid material: '{}'".format(self.material_name))
tex_slot = material.texture_slots.get(self.texture_name, None) tex_slot = material.texture_slots.get(self.texture_name, None)
if tex_slot is None: if tex_slot is None:
self.raise_error("invalid texture: '{}'".format(self.texture_name), tree) self.raise_error("invalid texture: '{}'".format(self.texture_name))
name = "{}_{}_LayerAnim".format(self.material_name, self.texture_name) name = "{}_{}_LayerAnim".format(self.material_name, self.texture_name)
target = exporter.mgr.find_create_key(plLayerAnimation, name=name, so=so) target = exporter.mgr.find_create_key(plLayerAnimation, name=name, so=so)
if target is None: if target is None:
@ -240,7 +240,7 @@ class PlasmaEnableMsgNode(PlasmaMessageNode, bpy.types.Node):
options={"ENUM_FLAG"}, options={"ENUM_FLAG"},
default={"kAudible", "kDrawable", "kPhysical"}) default={"kAudible", "kDrawable", "kPhysical"})
def convert_message(self, exporter, tree, so): def convert_message(self, exporter, so):
msg = plEnableMsg() msg = plEnableMsg()
target_bo = bpy.data.objects.get(self.object_name, None) target_bo = bpy.data.objects.get(self.object_name, None)
if target_bo is None: if target_bo is None:
@ -291,12 +291,12 @@ class PlasmaOneShotMsgNode(PlasmaMessageNode, bpy.types.Node):
description="Player can reverse the OneShot", description="Player can reverse the OneShot",
default=False) default=False)
def convert_callback_message(self, exporter, tree, so, msg, target, wait): def convert_callback_message(self, exporter, so, msg, target, wait):
msg.addCallback(self.marker, target, wait) msg.addCallback(self.marker, target, wait)
def convert_message(self, exporter, tree, so): def convert_message(self, exporter, so):
msg = plOneShotMsg() msg = plOneShotMsg()
msg.addReceiver(self.get_key(exporter, tree, so)) msg.addReceiver(self.get_key(exporter, so))
return msg return msg
def draw_buttons(self, context, layout): def draw_buttons(self, context, layout):
@ -308,8 +308,8 @@ class PlasmaOneShotMsgNode(PlasmaMessageNode, bpy.types.Node):
layout.prop_search(self, "pos", bpy.data, "objects", icon="EMPTY_DATA") layout.prop_search(self, "pos", bpy.data, "objects", icon="EMPTY_DATA")
layout.prop(self, "seek") layout.prop(self, "seek")
def export(self, exporter, tree, bo, so): def export(self, exporter, bo, so):
oneshotmod = self.get_key(exporter, tree, so).object oneshotmod = self.get_key(exporter, so).object
oneshotmod.animName = self.animation oneshotmod.animName = self.animation
oneshotmod.drivable = self.drivable oneshotmod.drivable = self.drivable
oneshotmod.reversable = self.reversable oneshotmod.reversable = self.reversable
@ -317,12 +317,12 @@ class PlasmaOneShotMsgNode(PlasmaMessageNode, bpy.types.Node):
oneshotmod.noSeek = self.seek == "NONE" oneshotmod.noSeek = self.seek == "NONE"
oneshotmod.seekDuration = 1.0 oneshotmod.seekDuration = 1.0
def get_key(self, exporter, tree, so): def get_key(self, exporter, so):
name = self.create_key_name(tree) name = self.key_name
if self.pos: if self.pos:
bo = bpy.data.objects.get(self.pos, None) bo = bpy.data.objects.get(self.pos, None)
if bo is None: if bo is None:
raise ExportError("Node '{}' in '{}' specifies an invalid Position Empty".format(self.name, tree.name)) raise ExportError("Node '{}' in '{}' specifies an invalid Position Empty".format(self.name, self.id_data.name))
pos_so = exporter.mgr.find_create_object(plSceneObject, bl=bo) pos_so = exporter.mgr.find_create_object(plSceneObject, bl=bo)
return exporter.mgr.find_create_key(plOneShotMod, name=name, so=pos_so) return exporter.mgr.find_create_key(plOneShotMod, name=name, so=pos_so)
else: else:
@ -357,11 +357,11 @@ class PlasmaTimerCallbackMsgNode(PlasmaMessageNode, bpy.types.Node):
def draw_buttons(self, context, layout): def draw_buttons(self, context, layout):
layout.prop(self, "delay") layout.prop(self, "delay")
def convert_callback_message(self, exporter, tree, so, msg, target, wait): def convert_callback_message(self, exporter, so, msg, target, wait):
msg.addReceiver(target) msg.addReceiver(target)
msg.ID = wait msg.ID = wait
def convert_message(self, exporter, tree, so): def convert_message(self, exporter, so):
msg = plTimerCallbackMsg() msg = plTimerCallbackMsg()
msg.time = self.delay msg.time = self.delay
return msg return msg
@ -384,7 +384,7 @@ class PlasmaFootstepSoundMsgNode(PlasmaMessageNode, bpy.types.Node):
def draw_buttons(self, context, layout): def draw_buttons(self, context, layout):
layout.prop(self, "surface") layout.prop(self, "surface")
def convert_message(self, exporter, tree, so): def convert_message(self, exporter, so):
msg = plArmatureEffectStateMsg() msg = plArmatureEffectStateMsg()
msg.BCastFlags |= (plMessage.kPropagateToModifiers | plMessage.kNetPropagate) msg.BCastFlags |= (plMessage.kPropagateToModifiers | plMessage.kNetPropagate)
msg.surface = footstep_surface_ids[self.surface] msg.surface = footstep_surface_ids[self.surface]

26
korman/nodes/node_responder.py

@ -45,11 +45,11 @@ class PlasmaResponderNode(PlasmaNodeVariableInput, bpy.types.Node):
layout.prop(self, "detect_untrigger") layout.prop(self, "detect_untrigger")
layout.prop(self, "no_ff_sounds") layout.prop(self, "no_ff_sounds")
def get_key(self, exporter, tree, so): def get_key(self, exporter, so):
return exporter.mgr.find_create_key(plResponderModifier, name=self.create_key_name(tree), so=so) return exporter.mgr.find_create_key(plResponderModifier, name=self.key_name, so=so)
def export(self, exporter, tree, bo, so): def export(self, exporter, bo, so):
responder = self.get_key(exporter, tree, so).object responder = self.get_key(exporter, so).object
if not bo.plasma_net.manual_sdl: if not bo.plasma_net.manual_sdl:
responder.setExclude("Responder") responder.setExclude("Responder")
@ -83,7 +83,7 @@ class PlasmaResponderNode(PlasmaNodeVariableInput, bpy.types.Node):
# Convert the Responder states # Convert the Responder states
stateMgr = ResponderStateMgr(self, responder) stateMgr = ResponderStateMgr(self, responder)
for stateNode in self.find_outputs("states", "PlasmaResponderStateNode"): for stateNode in self.find_outputs("states", "PlasmaResponderStateNode"):
stateNode.convert_state(exporter, tree, so, stateMgr) stateNode.convert_state(exporter, so, stateMgr)
stateMgr.save() stateMgr.save()
def update(self): def update(self):
@ -107,7 +107,7 @@ class PlasmaResponderStateNode(PlasmaNodeVariableInput, bpy.types.Node):
def draw_buttons(self, context, layout): def draw_buttons(self, context, layout):
layout.prop(self, "default_state") layout.prop(self, "default_state")
def convert_state(self, exporter, tree, so, stateMgr): def convert_state(self, exporter, so, stateMgr):
idx, state, converted = stateMgr.get_state(self) idx, state, converted = stateMgr.get_state(self)
# No sanity checking here. Hopefully nothing crazy has happened in the UI. # No sanity checking here. Hopefully nothing crazy has happened in the UI.
@ -122,7 +122,7 @@ class PlasmaResponderStateNode(PlasmaNodeVariableInput, bpy.types.Node):
toIdx, toState, converted = stateMgr.get_state(toStateNode) toIdx, toState, converted = stateMgr.get_state(toStateNode)
state.switchToState = toIdx state.switchToState = toIdx
if not converted: if not converted:
toStateNode.convert_state(exporter, tree, so, stateMgr) toStateNode.convert_state(exporter, so, stateMgr)
class CommandMgr: class CommandMgr:
def __init__(self): def __init__(self):
@ -152,7 +152,7 @@ class PlasmaResponderStateNode(PlasmaNodeVariableInput, bpy.types.Node):
for i in self.find_outputs("cmds", "PlasmaResponderCommandNode"): for i in self.find_outputs("cmds", "PlasmaResponderCommandNode"):
# slight optimization--commands attached to states can't wait on other commands # slight optimization--commands attached to states can't wait on other commands
# namely because it's impossible to wait on a command that doesn't exist... # namely because it's impossible to wait on a command that doesn't exist...
i.convert_command(exporter, tree, so, stateMgr.responder, commands) i.convert_command(exporter, so, stateMgr.responder, commands)
commands.save(state) commands.save(state)
def update(self): def update(self):
@ -181,14 +181,14 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
self.outputs.new("PlasmaMessageSocket", "Message", "msg").link_limit = 1 self.outputs.new("PlasmaMessageSocket", "Message", "msg").link_limit = 1
self.outputs.new("PlasmaRespCommandSocket", "Trigger", "trigger") self.outputs.new("PlasmaRespCommandSocket", "Trigger", "trigger")
def convert_command(self, exporter, tree, so, responder, commandMgr, waitOn=-1): def convert_command(self, exporter, so, responder, commandMgr, waitOn=-1):
# If this command has no message, there is no need to export it... # If this command has no message, there is no need to export it...
msgNode = self.find_output("msg") msgNode = self.find_output("msg")
if msgNode is not None: if msgNode is not None:
idx, command = commandMgr.add_command(self, waitOn) idx, command = commandMgr.add_command(self, waitOn)
# Finally, convert our message... # Finally, convert our message...
msg = msgNode.convert_message(exporter, tree, so) msg = msgNode.convert_message(exporter, so)
if msg.sender is None: if msg.sender is None:
msg.sender = responder.key msg.sender = responder.key
msg.BCastFlags |= plMessage.kLocalPropagate msg.BCastFlags |= plMessage.kLocalPropagate
@ -198,7 +198,7 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
haveChildren = self.find_output("trigger", "PlasmaResponderCommandNode") is not None haveChildren = self.find_output("trigger", "PlasmaResponderCommandNode") is not None
if haveChildren and msgNode.has_callbacks: if haveChildren and msgNode.has_callbacks:
childWaitOn = commandMgr.add_wait(idx) childWaitOn = commandMgr.add_wait(idx)
msgNode.convert_callback_message(exporter, tree, so, msg, responder.key, childWaitOn) msgNode.convert_callback_message(exporter, so, msg, responder.key, childWaitOn)
else: else:
childWaitOn = waitOn childWaitOn = waitOn
command.msg = msg command.msg = msg
@ -208,7 +208,7 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
# NOTE: would be incredibly stupid to do this if we're not waiting on anything to complete # NOTE: would be incredibly stupid to do this if we're not waiting on anything to complete
if childWaitOn != -1: if childWaitOn != -1:
for child in self.find_outputs("trigger"): for child in self.find_outputs("trigger"):
key = child.get_key(exporter, tree, so) key = child.get_key(exporter, so)
if key is None: if key is None:
continue continue
logicmod = key.object logicmod = key.object
@ -229,7 +229,7 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
# Export any child commands # Export any child commands
for i in self.find_outputs("trigger", "PlasmaResponderCommandNode"): for i in self.find_outputs("trigger", "PlasmaResponderCommandNode"):
i.convert_command(exporter, tree, so, responder, commandMgr, childWaitOn) i.convert_command(exporter, so, responder, commandMgr, childWaitOn)
class PlasmaRespCommandSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket): class PlasmaRespCommandSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket):

6
korman/properties/modifiers/avatar.py

@ -83,7 +83,7 @@ class PlasmaSittingBehavior(PlasmaModifierProperties, PlasmaModifierLogicWiz):
# Clickable # Clickable
clickable = nodes.new("PlasmaClickableNode") clickable = nodes.new("PlasmaClickableNode")
clickable.link_output(tree, sittingmod, "satisfies", "condition") clickable.link_output(sittingmod, "satisfies", "condition")
clickable.clickable = self.clickable_obj clickable.clickable = self.clickable_obj
clickable.bounds = find_modifier(self.clickable_obj, "collision").bounds clickable.bounds = find_modifier(self.clickable_obj, "collision").bounds
@ -91,7 +91,7 @@ class PlasmaSittingBehavior(PlasmaModifierProperties, PlasmaModifierLogicWiz):
region_phys = find_modifier(self.region_obj, "collision") region_phys = find_modifier(self.region_obj, "collision")
if region_phys is not None: if region_phys is not None:
region = nodes.new("PlasmaClickableRegionNode") region = nodes.new("PlasmaClickableRegionNode")
region.link_output(tree, clickable, "satisfies", "region") region.link_output(clickable, "satisfies", "region")
region.name = "ClickableAvRegion" region.name = "ClickableAvRegion"
region.region = self.region_obj region.region = self.region_obj
region.bounds = region_phys.bounds region.bounds = region_phys.bounds
@ -99,7 +99,7 @@ class PlasmaSittingBehavior(PlasmaModifierProperties, PlasmaModifierLogicWiz):
# Facing Target (optional) # Facing Target (optional)
if self.facing_enabled: if self.facing_enabled:
facing = nodes.new("PlasmaFacingTargetNode") facing = nodes.new("PlasmaFacingTargetNode")
facing.link_output(tree, clickable, "satisfies", "facing") facing.link_output(clickable, "satisfies", "facing")
facing.name = "FacingClickable" facing.name = "FacingClickable"
facing.directional = True facing.directional = True
facing.tolerance = self.facing_degrees facing.tolerance = self.facing_degrees

8
korman/properties/modifiers/region.py

@ -97,16 +97,16 @@ class PlasmaFootstepRegion(PlasmaModifierProperties, PlasmaModifierLogicWiz):
# Responder # Responder
respmod = nodes.new("PlasmaResponderNode") respmod = nodes.new("PlasmaResponderNode")
respmod.name = "Resp" respmod.name = "Resp"
respmod.link_input(tree, volsens, "satisfies", "condition") respmod.link_input(volsens, "satisfies", "condition")
respstate = nodes.new("PlasmaResponderStateNode") respstate = nodes.new("PlasmaResponderStateNode")
respstate.link_input(tree, respmod, "states", "condition") respstate.link_input(respmod, "states", "condition")
respstate.default_state = True respstate.default_state = True
respcmd = nodes.new("PlasmaResponderCommandNode") respcmd = nodes.new("PlasmaResponderCommandNode")
respcmd.link_input(tree, respstate, "cmds", "whodoneit") respcmd.link_input(respstate, "cmds", "whodoneit")
# ArmatureEffectStateMsg # ArmatureEffectStateMsg
msg = nodes.new("PlasmaFootstepSoundMsgNode") msg = nodes.new("PlasmaFootstepSoundMsgNode")
msg.link_input(tree, respcmd, "msg", "sender") msg.link_input(respcmd, "msg", "sender")
msg.surface = self.surface msg.surface = self.surface

Loading…
Cancel
Save