@@ -395,6 +395,105 @@ def simple_mode(self):
395395 return (not self .is_linked and not self .is_output )
396396
397397
398+ class PlasmaLinkEventNode (PlasmaNodeBase , bpy .types .Node ):
399+ bl_category = "CONDITIONS"
400+ bl_idname = "PlasmaLinkEventNode"
401+ bl_label = "Link Event"
402+
403+ trigger_for = EnumProperty (
404+ name = "Trigger For" ,
405+ items = [
406+ ("Me" , "Local Player" , "Trigger only for the local player" ),
407+ ("NPCs" , "NPCs" , "Trigger for NPCs (eg quabs)" ),
408+ ("Player Avatars" , "Player Avatars" , "Trigger for player controlled avatars" ),
409+ ("Everyone" , "Everyone" , "Trigger for all avatars" ),
410+ ],
411+ default = "Me" ,
412+ options = set ()
413+ )
414+ trigger_on = EnumProperty (
415+ name = "Trigger On" ,
416+ items = [
417+ ("Spawn" , "Avatar Spawns" , "Trigger when an avatar spawns" ),
418+ ("Link" , "Avatar Links" , "Trigger when an avatar links" ),
419+ ],
420+ default = "Spawn" ,
421+ options = set ()
422+ )
423+ trigger_direction = EnumProperty (
424+ name = "Trigger Direction" ,
425+ items = [
426+ ("In" , "In" , "Trigger when the avatar links/spawns into the Age" ),
427+ ("Out" , "Out" , "Trigger when the avatar links/spawns out of the Age" ),
428+ ],
429+ default = "In" ,
430+ options = set ()
431+ )
432+ trigger_at = EnumProperty (
433+ name = "Trigger At" ,
434+ items = [
435+ ("Start" , "Event Start" , "Trigger when the interesting event begins" ),
436+ ("End" , "Event End" , "Trigger when the interesting event ends" ),
437+ ],
438+ default = "Start" ,
439+ options = set ()
440+ )
441+
442+ output_sockets : dict [str , dict [str , Any ]] = {
443+ "satisfies" : {
444+ "text" : "Satisfies" ,
445+ "type" : "PlasmaConditionSocket" ,
446+ "valid_link_sockets" : {"PlasmaConditionSocket" , "PlasmaPythonFileNodeSocket" },
447+ },
448+ }
449+
450+ def draw_buttons (self , context , layout ):
451+ combo = (self .trigger_for , self .trigger_on , self .trigger_direction )
452+
453+ layout .alert = combo == ("Me" , "Spawn" , "Out" )
454+ layout .prop (self , "trigger_for" )
455+ layout .alert = False
456+
457+ layout .prop (self , "trigger_on" )
458+ layout .prop (self , "trigger_direction" )
459+ layout .prop (self , "trigger_at" )
460+
461+ def get_key (self , exporter : Exporter , so ) -> plKey [plLogicModifier ]:
462+ return self ._find_create_key (plLogicModifier , exporter , so = so )
463+
464+ def export (self , exporter : Exporter , bo , so ) -> None :
465+ combo = (self .trigger_for , self .trigger_on , self .trigger_direction )
466+ if combo == ("Me" , "Spawn" , "Out" ):
467+ self .raise_error ("Cannot trigger when the local player spawns out" )
468+
469+ # There is no class in the engine that will fire when someone links in. There are messages,
470+ # though, and they all get to Python in one way or another. So, to fire an event on link
471+ # or spawn, we're going to use a helper script xLinkEventTrigger. It will send a notification
472+ # to a kMultiTrigger LogicMod with a plActivatorActivatorConditionalObject. LMs forward
473+ # all plNotifyMsgs to their conditions, and plAACO activates on any state==1.0 plNotifyMsg,
474+ # assuming that the LogicMod is not already marked as triggered and all of the other conditions
475+ # say that they're in a valid state. Once that LogicMod fires, anything we want can be fired
476+ # off, like other PFMs or Responders. A potential optimization here is to avoid creation
477+ # of the plAACO/plLM thunk if we only have responders attached.
478+ activator = self ._find_create_object (plActivatorActivatorConditionalObject , exporter , so = so )
479+ logicmod = self ._find_create_object (plLogicModifier , exporter , so = so )
480+ logicmod .addCondition (activator .key )
481+ logicmod .notify = self .generate_notify_msg (exporter , so , "satisfies" )
482+ logicmod .setLogicFlag (plLogicModifier .kMultiTrigger , True )
483+ logicmod .setLogicFlag (plLogicModifier .kLocalElement , True )
484+
485+ pfm = self ._find_create_object (plPythonFileMod , exporter , so = so )
486+ self ._add_py_parameter (pfm , 1 , plPythonParameter .kActivator , activator .key )
487+ self ._add_py_parameter (pfm , 100 , plPythonParameter .kString , f"{ self .trigger_on } { self .trigger_direction } " )
488+ self ._add_py_parameter (pfm , 101 , plPythonParameter .kString , self .trigger_for )
489+ self ._add_py_parameter (pfm , 102 , plPythonParameter .kString , self .trigger_at )
490+ pfm .filename = "xLinkEventTrigger"
491+
492+ @property
493+ def export_once (self ):
494+ return True
495+
496+
398497class PlasmaVolumeReportNode (PlasmaNodeBase , bpy .types .Node ):
399498 bl_category = "CONDITIONS"
400499 bl_idname = "PlasmaVolumeReportNode"
0 commit comments