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 10 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):
layout.prop_menu_enum(self, "approach")
def get_key(self, exporter, tree, so):
return exporter.mgr.find_create_key(plSittingModifier, name=self.create_key_name(tree), so=so)
def get_key(self, exporter, so):
return exporter.mgr.find_create_key(plSittingModifier, name=self.key_name, so=so)
def export(self, exporter, tree, bo, so):
sitmod = self.get_key(exporter, tree, so).object
def export(self, exporter, bo, so):
sitmod = self.get_key(exporter, so).object
for flag in self.approach:
sitmod.miscFlags |= getattr(plSittingModifier, flag)
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(self, "bounds")
def export(self, exporter, tree, parent_bo, parent_so):
clickable_bo, clickable_so = self._get_objects(exporter, tree, parent_so)
def export(self, exporter, parent_bo, parent_so):
clickable_bo, clickable_so = self._get_objects(exporter, parent_so)
if clickable_bo is None:
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
logicmod = exporter.mgr.find_create_key(plLogicModifier, name=name, so=clickable_so)
interface.addIntfKey(logicmod)
@ -84,31 +84,31 @@ class PlasmaClickableNode(PlasmaNodeVariableInput, bpy.types.Node):
logicmod.addCondition(activator.key)
logicmod.setLogicFlag(plLogicModifier.kLocalElement, True)
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.
region = self.find_input("region", "PlasmaClickableRegionNode")
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
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...
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)
clickable_bo, clickable_so = self._get_objects(exporter, parent_so)
key = exporter.mgr.find_create_key(plLogicModifier, name=self.key_name, so=clickable_so)
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.
# 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)
self.raise_error("invalid Clickable object: '{}'".format(self.clickable))
clickable_so = exporter.mgr.find_create_object(plSceneObject, bl=clickable_bo)
return (clickable_bo, clickable_so)
else:
@ -141,11 +141,11 @@ class PlasmaClickableRegionNode(PlasmaNodeBase, bpy.types.Node):
layout.prop_search(self, "region", bpy.data, "objects", icon="MESH_DATA")
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...
region_bo = bpy.data.objects.get(self.region, 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
# 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
# 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.
name = self.create_key_name(tree)
name = self.key_name
detector_key = exporter.mgr.find_create_key(plObjectInVolumeDetector, name=name, so=region_so)
detector = detector_key.object
detector.addReceiver(logicmod.key)
@ -216,7 +216,7 @@ class PlasmaFacingTargetSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket):
layout.prop(self, "allow_simple", 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
if not self.enable_condition:
return
@ -225,12 +225,12 @@ class PlasmaFacingTargetSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket):
if self.simple_mode:
directional = True
tolerance = 45
name = "{}_SimpleFacing".format(self.node.create_key_name(tree))
name = "{}_SimpleFacing".format(self.node.key_name)
elif self.is_linked:
node = self.links[0].from_node
directional = node.directional
tolerance = node.tolerance
name = node.create_key_name(tree)
name = node.key_name
else:
# This is a programmer failure, so we need a traceback.
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(self, "bounds")
def export(self, exporter, tree, bo, so):
interface = exporter.mgr.add_object(plInterfaceInfoModifier, name=self.create_key_name(tree), so=so)
def export(self, exporter, bo, so):
interface = exporter.mgr.add_object(plInterfaceInfoModifier, name=self.key_name, so=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, tree, bo, so, plVolumeSensorConditionalObject.kTypeEnter, enter_settings)
key = self._export_volume_event(exporter, bo, 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, tree, bo, so, plVolumeSensorConditionalObject.kTypeExit, exit_settings)
key = self._export_volume_event(exporter, bo, 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), 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))
physical.memberGroup = plSimDefs.kGroupDetector
@ -341,18 +341,18 @@ class PlasmaVolumeSensorNode(PlasmaNodeBase, bpy.types.Node):
if "dynamics" in self.report_on:
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:
suffix = "Enter"
else:
suffix = "Exit"
theName = "{}_{}_{}".format(tree.name, self.name, suffix)
theName = "{}_{}_{}".format(self.id_data.name, self.name, suffix)
print(" [LogicModifier '{}']".format(theName))
logicKey = exporter.mgr.find_create_key(plLogicModifier, name=theName, so=so)
logicmod = logicKey.object
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
print(" [ObjectInVolumeDetector '{}']".format(theName))

29
korman/nodes/node_core.py

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

36
korman/nodes/node_messages.py

@ -150,24 +150,24 @@ class PlasmaAnimCmdMsgNode(PlasmaMessageNode, bpy.types.Node):
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.addReceiver(target)
cb.event = globals()[self.event]
cb.user = wait
msg.addCallback(cb)
def convert_message(self, exporter, tree, so):
def convert_message(self, exporter, so):
msg = plAnimCmdMsg()
# We're either sending this off to an AGMasterMod or a LayerAnim
if self.anim_type == "OBJECT":
obj = bpy.data.objects.get(self.object_name, 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
if not anim.enabled:
self.raise_error("invalid animation", tree)
self.raise_error("invalid animation")
group = obj.plasma_modifiers.animation_group
if group.enabled:
# we might be controlling more than one animation. isn't that cute?
@ -181,10 +181,10 @@ class PlasmaAnimCmdMsgNode(PlasmaMessageNode, bpy.types.Node):
else:
material = bpy.data.materials.get(self.material_name, 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)
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)
target = exporter.mgr.find_create_key(plLayerAnimation, name=name, so=so)
if target is None:
@ -240,7 +240,7 @@ class PlasmaEnableMsgNode(PlasmaMessageNode, bpy.types.Node):
options={"ENUM_FLAG"},
default={"kAudible", "kDrawable", "kPhysical"})
def convert_message(self, exporter, tree, so):
def convert_message(self, exporter, so):
msg = plEnableMsg()
target_bo = bpy.data.objects.get(self.object_name, None)
if target_bo is None:
@ -291,12 +291,12 @@ class PlasmaOneShotMsgNode(PlasmaMessageNode, bpy.types.Node):
description="Player can reverse the OneShot",
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)
def convert_message(self, exporter, tree, so):
def convert_message(self, exporter, so):
msg = plOneShotMsg()
msg.addReceiver(self.get_key(exporter, tree, so))
msg.addReceiver(self.get_key(exporter, so))
return msg
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(self, "seek")
def export(self, exporter, tree, bo, so):
oneshotmod = self.get_key(exporter, tree, so).object
def export(self, exporter, bo, so):
oneshotmod = self.get_key(exporter, so).object
oneshotmod.animName = self.animation
oneshotmod.drivable = self.drivable
oneshotmod.reversable = self.reversable
@ -317,12 +317,12 @@ class PlasmaOneShotMsgNode(PlasmaMessageNode, bpy.types.Node):
oneshotmod.noSeek = self.seek == "NONE"
oneshotmod.seekDuration = 1.0
def get_key(self, exporter, tree, so):
name = self.create_key_name(tree)
def get_key(self, exporter, so):
name = self.key_name
if self.pos:
bo = bpy.data.objects.get(self.pos, 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)
return exporter.mgr.find_create_key(plOneShotMod, name=name, so=pos_so)
else:
@ -357,11 +357,11 @@ class PlasmaTimerCallbackMsgNode(PlasmaMessageNode, bpy.types.Node):
def draw_buttons(self, context, layout):
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.ID = wait
def convert_message(self, exporter, tree, so):
def convert_message(self, exporter, so):
msg = plTimerCallbackMsg()
msg.time = self.delay
return msg
@ -384,7 +384,7 @@ class PlasmaFootstepSoundMsgNode(PlasmaMessageNode, bpy.types.Node):
def draw_buttons(self, context, layout):
layout.prop(self, "surface")
def convert_message(self, exporter, tree, so):
def convert_message(self, exporter, so):
msg = plArmatureEffectStateMsg()
msg.BCastFlags |= (plMessage.kPropagateToModifiers | plMessage.kNetPropagate)
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, "no_ff_sounds")
def get_key(self, exporter, tree, so):
return exporter.mgr.find_create_key(plResponderModifier, name=self.create_key_name(tree), so=so)
def get_key(self, exporter, so):
return exporter.mgr.find_create_key(plResponderModifier, name=self.key_name, so=so)
def export(self, exporter, tree, bo, so):
responder = self.get_key(exporter, tree, so).object
def export(self, exporter, bo, so):
responder = self.get_key(exporter, so).object
if not bo.plasma_net.manual_sdl:
responder.setExclude("Responder")
@ -83,7 +83,7 @@ class PlasmaResponderNode(PlasmaNodeVariableInput, bpy.types.Node):
# Convert the Responder states
stateMgr = ResponderStateMgr(self, responder)
for stateNode in self.find_outputs("states", "PlasmaResponderStateNode"):
stateNode.convert_state(exporter, tree, so, stateMgr)
stateNode.convert_state(exporter, so, stateMgr)
stateMgr.save()
def update(self):
@ -107,7 +107,7 @@ class PlasmaResponderStateNode(PlasmaNodeVariableInput, bpy.types.Node):
def draw_buttons(self, context, layout):
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)
# 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)
state.switchToState = toIdx
if not converted:
toStateNode.convert_state(exporter, tree, so, stateMgr)
toStateNode.convert_state(exporter, so, stateMgr)
class CommandMgr:
def __init__(self):
@ -152,7 +152,7 @@ class PlasmaResponderStateNode(PlasmaNodeVariableInput, bpy.types.Node):
for i in self.find_outputs("cmds", "PlasmaResponderCommandNode"):
# 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...
i.convert_command(exporter, tree, so, stateMgr.responder, commands)
i.convert_command(exporter, so, stateMgr.responder, commands)
commands.save(state)
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("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...
msgNode = self.find_output("msg")
if msgNode is not None:
idx, command = commandMgr.add_command(self, waitOn)
# Finally, convert our message...
msg = msgNode.convert_message(exporter, tree, so)
msg = msgNode.convert_message(exporter, so)
if msg.sender is None:
msg.sender = responder.key
msg.BCastFlags |= plMessage.kLocalPropagate
@ -198,7 +198,7 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
haveChildren = self.find_output("trigger", "PlasmaResponderCommandNode") is not None
if haveChildren and msgNode.has_callbacks:
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:
childWaitOn = waitOn
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
if childWaitOn != -1:
for child in self.find_outputs("trigger"):
key = child.get_key(exporter, tree, so)
key = child.get_key(exporter, so)
if key is None:
continue
logicmod = key.object
@ -229,7 +229,7 @@ class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
# Export any child commands
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):

6
korman/properties/modifiers/avatar.py

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

8
korman/properties/modifiers/region.py

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

Loading…
Cancel
Save