Browse Source

Allow Python File nodes to activate each other.

pull/426/head
Adam Johnson 2 weeks ago
parent
commit
91453ed769
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 44
      korman/nodes/node_python.py

44
korman/nodes/node_python.py

@ -13,12 +13,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy import bpy
from bpy.props import * from bpy.props import *
from collections.abc import Iterable from collections.abc import Iterable
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from typing import *
from PyHSPlasma import * from PyHSPlasma import *
from .. import enum_props from .. import enum_props
@ -68,9 +72,12 @@ _attrib2param = {
_attrib_key_types = { _attrib_key_types = {
"ptAttribSceneobject": plFactory.ClassIndex("plSceneObject"), "ptAttribSceneobject": plFactory.ClassIndex("plSceneObject"),
"ptAttribSceneobjectList": plFactory.ClassIndex("plSceneObject"), "ptAttribSceneobjectList": plFactory.ClassIndex("plSceneObject"),
"ptAttribActivator": plFactory.ClassIndex("plLogicModifier"), "ptAttribActivator": (plFactory.ClassIndex("plLogicModifier"),
"ptAttribActivatorList": plFactory.ClassIndex("plLogicModifier"), plFactory.ClassIndex("plPythonFileMod")),
"ptAttribNamedActivator": plFactory.ClassIndex("plLogicModifier"), "ptAttribActivatorList": (plFactory.ClassIndex("plLogicModifier"),
plFactory.ClassIndex("plPythonFileMod")),
"ptAttribNamedActivator": (plFactory.ClassIndex("plLogicModifier"),
plFactory.ClassIndex("plPythonFileMod")),
"ptAttribResponder": plFactory.ClassIndex("plResponderModifier"), "ptAttribResponder": plFactory.ClassIndex("plResponderModifier"),
"ptAttribResponderList": plFactory.ClassIndex("plResponderModifier"), "ptAttribResponderList": plFactory.ClassIndex("plResponderModifier"),
"ptAttribNamedResponder": plFactory.ClassIndex("plResponderModifier"), "ptAttribNamedResponder": plFactory.ClassIndex("plResponderModifier"),
@ -187,6 +194,17 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
bl_label = "Python File" bl_label = "Python File"
bl_width_default = 290 bl_width_default = 290
# Yas, a PythonFileMod can activate another PythonFileMod
pl_attrib = {"ptAttribActivator", "ptAttribActivatorList", "ptAttribNamedActivator"}
output_sockets: dict[str, dict[str, Any]] = {
"satisfies": {
"text": "Satisfies",
"type": "PlasmaConditionSocket",
"valid_link_nodes": "PlasmaPythonFileNode",
},
}
def _poll_pytext(self, value): def _poll_pytext(self, value):
return value.name.endswith(".py") return value.name.endswith(".py")
@ -304,7 +322,7 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
param.value = i param.value = i
if not socket.is_simple_value: if not socket.is_simple_value:
self._export_key_attrib(exporter, bo, so, i, socket) self._export_key_attrib(exporter, bo, so, pfm, i, socket)
pfm.addParameter(param) pfm.addParameter(param)
def _export_ancillary_sceneobject(self, exporter, bo, so: plSceneObject) -> None: def _export_ancillary_sceneobject(self, exporter, bo, so: plSceneObject) -> None:
@ -317,7 +335,7 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
exporter.report.msg(f"Marking RT light '{so.key.name}' as animated due to usage in a Python File node", so.key.name) exporter.report.msg(f"Marking RT light '{so.key.name}' as animated due to usage in a Python File node", so.key.name)
light.setProperty(plLightInfo.kLPMovable, True) light.setProperty(plLightInfo.kLPMovable, True)
def _export_key_attrib(self, exporter, bo, so : plSceneObject, key : plKey, socket) -> None: def _export_key_attrib(self, exporter, bo, so: plSceneObject, pfm: plPythonFileMod, key: plKey, socket) -> None:
if key is None: if key is None:
exporter.report.warn("Attribute '{}' didn't return a key and therefore will be unavailable to Python", exporter.report.warn("Attribute '{}' didn't return a key and therefore will be unavailable to Python",
self.id_data.name, socket.links[0].name) self.id_data.name, socket.links[0].name)
@ -333,8 +351,11 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
self.id_data.name, socket.links[0].from_node.name, self.id_data.name, socket.links[0].from_node.name,
plFactory.ClassName(key.type)) plFactory.ClassName(key.type))
if isinstance(key.object, plSceneObject): key_object = key.object
self._export_ancillary_sceneobject(exporter, bo, key.object) if isinstance(key_object, plSceneObject):
self._export_ancillary_sceneobject(exporter, bo, key_object)
elif isinstance(key_object, plPythonFileMod):
key_object.addReceiver(pfm.key)
def _get_attrib_sockets(self, idx): def _get_attrib_sockets(self, idx):
for i in self.inputs: for i in self.inputs:
@ -342,8 +363,9 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
yield i yield i
def generate_valid_links_for(self, context, socket, is_output): def generate_valid_links_for(self, context, socket, is_output):
# Python nodes have no outputs... if is_output:
assert is_output is False yield from PlasmaNodeBase.generate_valid_links_for(self, context, socket, True)
return
attrib_type = socket.attribute_type attrib_type = socket.attribute_type
for i in bpy.types.Node.__subclasses__(): for i in bpy.types.Node.__subclasses__():
@ -493,6 +515,10 @@ class PlasmaPythonFileNode(PlasmaVersionedNode, bpy.types.Node):
while len(unconnected) > 1: while len(unconnected) > 1:
self.inputs.remove(unconnected.pop()) self.inputs.remove(unconnected.pop())
# Make sure the output sockets are present and accounted for.
self._update_extant_sockets(self.output_sockets, self.outputs)
self._update_init_sockets(self.output_sockets, self.outputs)
@property @property
def latest_version(self): def latest_version(self):
return 2 return 2

Loading…
Cancel
Save