From e6e2184b62413e4e44162fa54745457799d1389c Mon Sep 17 00:00:00 2001 From: Patrick Dulebohn Date: Sat, 15 Oct 2022 16:07:42 -0400 Subject: [PATCH] Add Imager Modifier First commit of a potential Imager modifier for Korman --- korman/properties/modifiers/logic.py | 182 ++++++++++++++++++++++++++- korman/ui/modifiers/logic.py | 38 ++++++ 2 files changed, 219 insertions(+), 1 deletion(-) diff --git a/korman/properties/modifiers/logic.py b/korman/properties/modifiers/logic.py index 2fcec98..7924709 100644 --- a/korman/properties/modifiers/logic.py +++ b/korman/properties/modifiers/logic.py @@ -18,7 +18,7 @@ from bpy.props import * from PyHSPlasma import * from ...addon_prefs import game_versions -from .base import PlasmaModifierProperties +from .base import PlasmaModifierProperties, PlasmaModifierLogicWiz from ...exporter import ExportError from ... import idprops @@ -117,3 +117,183 @@ class PlasmaMaintainersMarker(PlasmaModifierProperties): @property def requires_actor(self): return True + + +# Let's set up the xSimpleImager.py scripting +imager_pfms = { + "filename": "xSimpleImager.py", + "attribs": ( + { 'id': 1, 'type': "ptAttribString", 'name': "ImagerName" }, + { 'id': 2, 'type': "ptAttribDynamicMap", 'name': "ImagerMap" }, + { 'id': 3, 'type': "ptAttribActivator", 'name': "ImagerRegion" }, + { 'id': 4, 'type': "ptAttribInt", 'name': "ImagerTime" }, + { 'id': 5, 'type': "ptAttribBoolean", 'name': "ImagerMembersOnly" }, + { 'id': 6, 'type': "ptAttribSceneobject", 'name': "ImagerObject" }, + { 'id': 7, 'type': "ptAttribInt", 'name': "ImagerMax" }, + { 'id': 8, 'type': "ptAttribResponder", 'name': "ImagerButtonResp" }, + { 'id': 9, 'type': "ptAttribString", 'name': "ImagerInboxVariable" }, + { 'id': 10, 'type': "ptAttribBoolean", 'name': "ImagerPelletUpload" }, + { 'id': 11, 'type': "ptAttribSceneobject", 'name': "ImagerClueObject" }, + { 'id': 12, 'type': "ptAttribInt", 'name': "ImagerClueTime" }, + { 'id': 13, 'type': "ptAttribInt", 'name': "ImagerRandomTime" }, + ) +} + + +pl_attrib = ("ptAttribMaterial", "ptAttribMaterialList", + "ptAttribDynamicMap", "ptAttribMaterialAnimation") + + +class PlasmaImager(PlasmaModifierProperties, PlasmaModifierLogicWiz): + pl_id = "imager" + + bl_category = "Logic" + bl_label = "Imager" + bl_description = "Set up an imager for posting or visitor list." + bl_icon = "IMAGE_DATA" + + # Shameless copy paste ahead. + def _poll_material(self, value: bpy.types.Material) -> bool: + # Don't filter materials by texture - this would (potentially) result in surprising UX + # in that you would have to clear the texture selection before being able to select + # certain materials. + if self.imager_object is not None: + object_materials = (slot.material for slot in self.imager_object.material_slots if slot and slot.material) + return value in object_materials + return True + + def _poll_texture(self, value: bpy.types.Texture) -> bool: + if self.imager_material is not None: + return value.name in self.imager_material.texture_slots + elif self.imager_object is not None: + for i in (slot.material for slot in self.imager_object.material_slots if slot and slot.material): + if value in (slot.texture for slot in i.texture_slots if slot and slot.texture): + return True + return False + else: + return True + + imager_name = StringProperty(name="Imager Name", + description="Name of the imager referenced by KI and scripts (case sensitive for the latter).", + options=set()) + imager_object = PointerProperty(name="Imager Object", + description="Imager mesh object.", + options=set(), + type=bpy.types.Object, + poll=idprops.poll_drawable_objects) + imager_material = PointerProperty(name="Material", + description="Material containing the imager texture.", + type=bpy.types.Material, + poll=_poll_material) + imager_texture = PointerProperty(name="Texture", + description="Texture slot used for the imager.", + type=bpy.types.Texture, + poll=_poll_texture) + imager_region = PointerProperty(name="Imager Region (optional)", + description="Activation region for postable imager.", + options=set(), + type=bpy.types.Object, + poll=idprops.poll_mesh_objects) + imager_time = IntProperty(name="Image View Time", + description="Number of seconds each image or text is viewed", + min=1, soft_max=10, default=10, + options=set()) + imager_membersonly = BoolProperty(name="Only Members Can Post?", + description="Sets if the imager is only postable by members (false is recommended)", + default=False, + options=set()) + imager_maximum = IntProperty(name="Image Limit", + description="Sets the maximum number of images and texts the imager can hold.", + min=1, soft_max=10, default=10, + options=set()) + imager_pellets = BoolProperty(name="Pellet Imager?", + description="Enable if you'd like the imager to post and keep pellet scores.", + default=False, + options=set()) + imager_clueobject = PointerProperty(name="Clue Imager Object", + description="Mesh Object that will pop up intermittently.", + options=set(), + type=bpy.types.Object, + poll=idprops.poll_drawable_objects) + imager_cluetime = IntProperty(name="Clue Time", + description="Time the clue will appear in seconds.", + min=1, soft_max=870, default=870, + options=set()) + imager_randomtime = IntProperty(name="Randomizer Time", + description="Time in seconds that will randomize the clue appearance.", + min=0, soft_max=870, default=0, + options=set()) + + def logicwiz(self, bo, tree): + nodes = tree.nodes + + imager_pfm = imager_pfms + imagernode = self._create_python_file_node(tree, imager_pfm["filename"], imager_pfm["attribs"]) + self._create_imager_nodes(bo, tree.nodes, imagernode) + + + def _create_imager_nodes(self, imager_object, nodes, imagernode): + #Imager Name + imagername = nodes.new("PlasmaAttribStringNode") + imagername.value = self.imager_name + imagername.link_output(imagernode, "pfm", "ImagerName") + + # Texture + imagertext = nodes.new("PlasmaAttribTextureNode") + imagertext.target_object = self.imager_object + imagertext.material = self.imager_material + imagertext.texture = self.imager_texture + imagertext.link_output(imagernode, "pfm", "ImagerMap") + + # Region Object if we want one + if self.imager_region: + imagerregion = nodes.new("PlasmaVolumeSensorNode") + imagerregion.region_object = self.imager_region + for i in imagerregion.inputs: + i.allow = True + imagerregion.link_output(imagernode, "satisfies", "ImagerRegion") + + # Seconds between posts + imagersec = nodes.new("PlasmaAttribIntNode") + imagersec.value_int = self.imager_time + imagersec.link_output(imagernode, "pfm", "ImagerTime") + + # Members only? + imagermember = nodes.new("PlasmaAttribBoolNode") + imagermember.value = self.imager_membersonly + imagermember.link_output(imagernode, "pfm", "ImagerMembersOnly") + + # Imager Mesh Object + imagerobject = nodes.new("PlasmaAttribObjectNode") + imagerobject.target_object = self.imager_object + imagerobject.link_output(imagernode, "pfm", "ImagerObject") + + # Maximum Images + imagermax = nodes.new("PlasmaAttribIntNode") + imagermax.value_int = self.imager_maximum + imagermax.link_output(imagernode, "pfm", "ImagerMax") + + # Optional SDL placeholder (needed?) + imagersdl = nodes.new("PlasmaAttribStringNode") + imagersdl.link_output(imagernode, "pfm", "ImagerInboxVariable") + + # Pellet Imager? + imagerpellet = nodes.new("PlasmaAttribBoolNode") + imagerpellet.value = self.imager_pellets + imagerpellet.link_output(imagernode, "pfm", "ImagerPelletUpload") + + # Puzzle Imager Object if we have one + if self.imager_clueobject: + imagerclueobj = nodes.new("PlasmaAttribObjectNode") + imagerclueobj.target_object = self.imager_clueobject + imagerclueobj.link_output(imagernode, "pfm", "ImagerClueObject") + + # Clue Time + imagercluetime = nodes.new("PlasmaAttribIntNode") + imagercluetime.value_int = self.imager_cluetime + imagercluetime.link_output(imagernode, "pfm", "ImagerClueTime") + + # Random Clue Time + imagerrandomtime = nodes.new("PlasmaAttribIntNode") + imagerrandomtime.value_int = self.imager_randomtime + imagerrandomtime.link_output(imagernode, "pfm", "ImagerRandomTime") diff --git a/korman/ui/modifiers/logic.py b/korman/ui/modifiers/logic.py index d657b5f..0fe520f 100644 --- a/korman/ui/modifiers/logic.py +++ b/korman/ui/modifiers/logic.py @@ -42,3 +42,41 @@ def spawnpoint(modifier, layout, context): def maintainersmarker(modifier, layout, context): layout.label(text="Positive Y is North, positive Z is up.") layout.prop(modifier, "calibration") + +def imager(modifier, layout, context): + layout.prop(modifier, "imager_object") + if modifier.imager_object: + layout.prop(modifier, "imager_material") + if modifier.imager_material is not None: + layout.prop(modifier, "imager_texture") + else: + layout.label(text="Choose a Material Slot") + if modifier.imager_material and modifier.imager_texture: + layout.prop(modifier, "imager_name") + layout.separator() + layout.label(text="For Postable Imagers:") + layout.prop(modifier, "imager_region") + split = layout.split() + col = split.column() + col.prop(modifier, "imager_time") + col.prop(modifier, "imager_maximum") + + col = split.column() + col.prop(modifier, "imager_membersonly") + col.prop(modifier, "imager_pellets") + + layout.separator() + layout.label(text="For Clue Imager:") + layout.prop(modifier, "imager_clueobject") + if modifier.imager_clueobject: + split = layout.split() + col = split.column() + col.prop(modifier, "imager_cluetime") + + col = split.column() + col.prop(modifier, "imager_randomtime") + else: + layout.label(text="Choose a Texture Slot") + else: + layout.label(text="Choose an imager mesh object!", icon="ERROR") +