mirror of
https://github.com/H-uru/korman.git
synced 2025-07-14 22:36:52 +00:00
Replace RespStateList crazy with a nicer solution
Many thanks to Deledrius for pointing out an example of this hackery in Blender's node groups!
This commit is contained in:
@ -51,14 +51,26 @@ class PlasmaNodeBase:
|
||||
|
||||
def link_input(self, tree, node, out_key, in_key):
|
||||
"""Links a given Node's output socket to a given input socket on this Node"""
|
||||
in_socket = self.find_input_socket(in_key)
|
||||
out_socket = node.find_output_socket(out_key)
|
||||
if isinstance(in_key, str):
|
||||
in_socket = self.find_input_socket(in_key)
|
||||
else:
|
||||
in_socket = in_key
|
||||
if isinstance(out_key, str):
|
||||
out_socket = node.find_output_socket(out_key)
|
||||
else:
|
||||
out_socket = out_key
|
||||
link = tree.links.new(in_socket, out_socket)
|
||||
|
||||
def link_output(self, tree, node, out_key, in_key):
|
||||
"""Links a given Node's input socket to a given output socket on this Node"""
|
||||
in_socket = node.find_input_socket(in_key)
|
||||
out_socket = self.find_output_socket(out_key)
|
||||
if isinstance(in_key, str):
|
||||
in_socket = node.find_input_socket(in_key)
|
||||
else:
|
||||
in_socket = in_key
|
||||
if isinstance(out_key, str):
|
||||
out_socket = self.find_output_socket(out_key)
|
||||
else:
|
||||
out_socket = out_key
|
||||
link = tree.links.new(in_socket, out_socket)
|
||||
|
||||
@classmethod
|
||||
@ -66,6 +78,19 @@ class PlasmaNodeBase:
|
||||
return (context.bl_idname == "PlasmaNodeTree")
|
||||
|
||||
|
||||
class PlasmaNodeVariableInput(PlasmaNodeBase):
|
||||
def ensure_sockets(self, idname, name, identifier=None):
|
||||
"""Ensures there is one (and only one) empty input socket"""
|
||||
empty = [i for i in self.inputs if i.bl_idname == idname and not i.links]
|
||||
if not empty:
|
||||
if identifier is None:
|
||||
self.inputs.new(idname, name)
|
||||
else:
|
||||
self.inputs.new(idname, name, identifier)
|
||||
while len(empty) > 1:
|
||||
self.inputs.remove(empty.pop())
|
||||
|
||||
|
||||
class PlasmaNodeSocketBase:
|
||||
def draw(self, context, layout, node, text):
|
||||
layout.label(text)
|
||||
|
@ -29,67 +29,30 @@ class PlasmaResponderNode(PlasmaNodeBase, bpy.types.Node):
|
||||
self.outputs.new("PlasmaRespStateSocket", "States", "states")
|
||||
|
||||
|
||||
class PlasmaResponderStateNode(PlasmaNodeBase, bpy.types.Node):
|
||||
class PlasmaResponderStateNode(PlasmaNodeVariableInput, bpy.types.Node):
|
||||
bl_category = "LOGIC"
|
||||
bl_idname = "PlasmaResponderStateNode"
|
||||
bl_label = "Responder State"
|
||||
|
||||
default_state = BoolProperty(name="Default State",
|
||||
description="This state is the responder's default",
|
||||
default=False)
|
||||
|
||||
def init(self, context):
|
||||
self.inputs.new("PlasmaRespStateSocket", "Condition", "whodoneit")
|
||||
self.outputs.new("PlasmaRespCommandSocket", "Commands", "cmds")
|
||||
self.outputs.new("PlasmaRespStateSocket", "Trigger", "gotostate").link_limit = 1
|
||||
|
||||
|
||||
class PlasmaRespStateSocketBase(PlasmaNodeSocketBase):
|
||||
bl_color = (0.388, 0.78, 0.388, 1.0)
|
||||
|
||||
|
||||
class PlasmaRespStateSocket(PlasmaRespStateSocketBase, bpy.types.NodeSocket):
|
||||
default_state = BoolProperty(name="Default State",
|
||||
description="This state is the Responder's default",
|
||||
default=False)
|
||||
|
||||
def draw(self, context, layout, node, text):
|
||||
# If this is a RespoderState node and the parent is a Responder, offer the user the
|
||||
# ability to make this the default state.
|
||||
if self.is_linked and not self.is_output:
|
||||
# Before we do anything, see if we need to do a delayed update...
|
||||
if node.bl_idname == "PlasmaResponderStateNode":
|
||||
parent = node.find_input("whodoneit", "PlasmaResponderNode")
|
||||
if parent is not None:
|
||||
layout.prop(self, "default_state")
|
||||
return
|
||||
|
||||
# Still here? Draw the text.
|
||||
layout.label(text)
|
||||
|
||||
|
||||
class PlasmaResponderStateListNode(PlasmaNodeBase, bpy.types.Node):
|
||||
bl_category = "LOGIC"
|
||||
bl_idname = "PlasmaResponderStateListNode"
|
||||
bl_label = "Responder State List"
|
||||
|
||||
def add_state_input(self):
|
||||
self.inputs.new("PlasmaRespStateListSocket", str(uuid.uuid4()))
|
||||
|
||||
def init(self, context):
|
||||
# Inputs will be added by the user
|
||||
self.outputs.new("PlasmaRespStateSocket", "Go To State", "gotostate")
|
||||
|
||||
def draw_buttons(self, context, layout):
|
||||
# This will allow us to add input states on the fly.
|
||||
# Caveat: We're only showing this operator in the properties because we need the node
|
||||
# to be active in the operator...
|
||||
op = layout.operator("node.plasma_add_responder_state", text="Add State", icon="ZOOMIN")
|
||||
op.node_name = self.name
|
||||
# This actually draws nothing, but it makes sure we have at least one empty input slot
|
||||
# We need this because it's possible that multiple OTHER states can call us
|
||||
self.ensure_sockets("PlasmaRespStateSocket", "Condition")
|
||||
|
||||
# Now draw a prop
|
||||
layout.prop(self, "default_state")
|
||||
|
||||
|
||||
class PlasmaRespStateListSocket(PlasmaRespStateSocketBase, bpy.types.NodeSocket):
|
||||
def draw(self, context, layout, node, text):
|
||||
# We'll allow them to delete all their inputs if they want to be stupid...
|
||||
props = layout.operator("node.plasma_remove_responder_state", text="", icon="X")
|
||||
props.node_name = node.name
|
||||
props.socket_name = self.name
|
||||
class PlasmaRespStateSocket(PlasmaNodeSocketBase, bpy.types.NodeSocket):
|
||||
bl_color = (0.388, 0.78, 0.388, 1.0)
|
||||
|
||||
|
||||
class PlasmaResponderCommandNode(PlasmaNodeBase, bpy.types.Node):
|
||||
|
@ -16,7 +16,6 @@
|
||||
from . import op_export as exporter
|
||||
from . import op_lightmap as lightmap
|
||||
from . import op_modifier as modifier
|
||||
from . import op_nodes as node
|
||||
from . import op_world as world
|
||||
|
||||
def register():
|
||||
|
@ -1,55 +0,0 @@
|
||||
# This file is part of Korman.
|
||||
#
|
||||
# Korman is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Korman is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
|
||||
class NodeOperator:
|
||||
def get_node_tree(self, context):
|
||||
space = context.space_data
|
||||
if space.type != "NODE_EDITOR":
|
||||
raise RuntimeError("Operator '{}' should only be used in the node editor".format(self.bl_idname))
|
||||
return space.node_tree
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.render.engine == "PLASMA_GAME"
|
||||
|
||||
|
||||
class ResponderStateAddOperator(NodeOperator, bpy.types.Operator):
|
||||
bl_idname = "node.plasma_add_responder_state"
|
||||
bl_label = "Add Responder State Socket"
|
||||
|
||||
node_name = StringProperty(name="Node's name", options={"HIDDEN"})
|
||||
|
||||
def execute(self, context):
|
||||
tree = self.get_node_tree(context)
|
||||
tree.nodes[self.node_name].add_state_input()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ResponderStateRemoveOperator(NodeOperator, bpy.types.Operator):
|
||||
bl_idname = "node.plasma_remove_responder_state"
|
||||
bl_label = "Remove Responder State Socket"
|
||||
|
||||
node_name = StringProperty(name="Node's name", options={"HIDDEN"})
|
||||
socket_name = StringProperty(name="Socket name to remove", options={"HIDDEN"})
|
||||
|
||||
def execute(self, context):
|
||||
tree = self.get_node_tree(context)
|
||||
node = tree.nodes[self.node_name]
|
||||
socket = node.inputs[self.socket_name]
|
||||
node.inputs.remove(socket)
|
||||
return {"FINISHED"}
|
@ -94,8 +94,8 @@ class PlasmaFootstepRegion(PlasmaModifierProperties, PlasmaModifierLogicWiz):
|
||||
respmod = nodes.new("PlasmaResponderNode")
|
||||
respmod.link_input(tree, logicmod, "trigger", "whodoneit")
|
||||
respstate = nodes.new("PlasmaResponderStateNode")
|
||||
respstate.link_input(tree, respmod, "states", "whodoneit")
|
||||
respstate.find_input_socket("whodoneit").default_state = True
|
||||
respstate.link_input(tree, respmod, "states", respstate.inputs.new("PlasmaRespStateSocket", "Responder"))
|
||||
respstate.default_state = True
|
||||
respcmd = nodes.new("PlasmaResponderCommandNode")
|
||||
respcmd.link_input(tree, respstate, "cmds", "whodoneit")
|
||||
|
||||
|
Reference in New Issue
Block a user