Browse Source

Add the SDL Show/Hide Modifier.

This adds a modifier for the very common PythonFileMods
xAgeSDLBoolShowHude and xAgeSDLIntShowHide. Right now, Korman doesn't
try to parse SDL files, so the variable name and type have to be
specified manually. The benefit to this, however, is the ability to
easily wire up global SDL visibility type features.
pull/414/head
Adam Johnson 3 months ago
parent
commit
0f0d6e1086
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 4
      korman/exporter/convert.py
  2. 6
      korman/operators/op_ui.py
  3. 16
      korman/plasma_api.py
  4. 86
      korman/properties/modifiers/logic.py
  5. 37
      korman/ui/modifiers/logic.py

4
korman/exporter/convert.py

@ -598,6 +598,10 @@ class Exporter:
else: else:
return bpy.context.scene.world.plasma_age.age_name return bpy.context.scene.world.plasma_age.age_name
@property
def age_sdl(self) -> bool:
return bpy.context.scene.world.plasma_age.age_sdl
@property @property
def dat_only(self): def dat_only(self):
return self._op.dat_only return self._op.dat_only

6
korman/operators/op_ui.py

@ -77,11 +77,17 @@ class CollectionRemoveOperator(UIOperator, bpy.types.Operator):
index_prop = StringProperty(name="Index Property", index_prop = StringProperty(name="Index Property",
description="Name of the active element index property", description="Name of the active element index property",
options=set()) options=set())
manual_index = IntProperty(name="Manual Index",
description="Manual integer index to remove",
options=set())
def execute(self, context): def execute(self, context):
props = getattr(context, self.context).path_resolve(self.group_path) props = getattr(context, self.context).path_resolve(self.group_path)
collection = getattr(props, self.collection_prop) collection = getattr(props, self.collection_prop)
if self.index_prop:
index = getattr(props, self.index_prop) index = getattr(props, self.index_prop)
else:
index = self.manual_index
if len(collection) > index: if len(collection) > index:
collection.remove(index) collection.remove(index)
setattr(props, self.index_prop, index - 1) setattr(props, self.index_prop, index - 1)

16
korman/plasma_api.py

@ -14,6 +14,22 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
python_files = { python_files = {
"xAgeSDLBoolShowHide.py": (
{ "id": 1, "type": "ptAttribString", "name": "sdlName" },
{ "id": 2, "type": "ptAttribBoolean", "name": "showOnTrue" },
# --- CWE Only Below ---
{ "id": 3, "type": "ptAttribBoolean", "name": "defaultValue" },
{ "id": 4, "type": "ptAttribBoolean", "name": "evalOnFirstUpdate "},
),
"xAgeSDLIntShowHide.py": (
{ "id": 1, "type": "ptAttribString", "name": "stringVarName" },
{ "id": 2, "type": "ptAttribString", "name": "stringShowStates" },
# --- CWE Only Below ---
{ "id": 3, "type": "ptAttribInt", "name": "intDefault" },
{ "id": 4, "type": "ptAttribBoolean", "name": "boolFirstUpdate "},
),
# Provided by all variants of Uru and Myst V # Provided by all variants of Uru and Myst V
"xDialogToggle.py": ( "xDialogToggle.py": (
{ "id": 1, "type": "ptAttribActivator", "name": "Activate" }, { "id": 1, "type": "ptAttribActivator", "name": "Activate" },

86
korman/properties/modifiers/logic.py

@ -15,10 +15,8 @@
from __future__ import annotations from __future__ import annotations
import bmesh
import bpy import bpy
from bpy.props import * from bpy.props import *
import mathutils
from PyHSPlasma import * from PyHSPlasma import *
from typing import * from typing import *
@ -28,6 +26,11 @@ if TYPE_CHECKING:
from ...nodes.node_messages import * from ...nodes.node_messages import *
from ...nodes.node_responder import * from ...nodes.node_responder import *
from typing import *
if TYPE_CHECKING:
from ...exporter import Exporter
from ...addon_prefs import game_versions from ...addon_prefs import game_versions
from .base import PlasmaModifierProperties, PlasmaModifierLogicWiz from .base import PlasmaModifierProperties, PlasmaModifierLogicWiz
from ...exporter import ExportError, utils from ...exporter import ExportError, utils
@ -191,6 +194,85 @@ class PlasmaMaintainersMarker(PlasmaModifierProperties):
return True return True
class PlasmaSDLIntState(bpy.types.PropertyGroup):
value: int = IntProperty(
name="State Value",
description="The object is shown when the SDL variable is set to this value",
min=0,
soft_max=255,
options=set()
)
class PlasmaSDLShowHide(PlasmaModifierProperties, PlasmaModifierLogicWiz):
pl_id = "sdl_showhide"
bl_category = "Logic"
bl_label = "SDL Show/Hide"
bl_description = "Show/Hide an object based on an SDL Variable"
bl_object_types = {"MESH", "FONT"}
bl_icon = "VISIBLE_IPO_OFF"
sdl_variable: str = StringProperty(
name="SDL Variable",
description="Name of the SDL variable that controls visibility",
options=set()
)
variable_type: str = EnumProperty(
name="Type",
description="Data type of the SDL variable",
items=[
("bool", "Boolean", "A boolean, used to represent simple on/off for a single state"),
("int", "Integer", "An integer, used to represent multiple state combinations"),
],
options=set()
)
int_states = CollectionProperty(type=PlasmaSDLIntState)
bool_state: bool = BoolProperty(
name="Show When True",
description="If checked, show this object when the SDL Variable is TRUE. If not, hide it when TRUE.",
default=True,
options=set()
)
def created(self):
# Ensure at least one SDL int state is precreated for ease of use.
# REMEMBER: Blender's "sequences" don't do truthiness correctly...
if len(self.int_states) == 0:
self.int_states.add()
def sanity_check(self, exporter: Exporter):
if not exporter.age_sdl:
raise ExportError(f"'{self.id_data.name}': Age Global SDL is required for the SDL Show/Hide modifier!")
if not self.sdl_variable.strip():
raise ExportError(f"'{self.id_data.name}': A valid SDL variable is required for the SDL Show/Hide modifier!")
def logicwiz(self, bo, tree):
if self.variable_type == "bool":
pfm_node = self._create_standard_python_file_node(tree, "xAgeSDLBoolShowHide.py")
self._create_python_attribute(pfm_node, "sdlName", value=self.sdl_variable)
self._create_python_attribute(pfm_node, "showOnTrue", value=self.bool_state)
elif self.variable_type == "int":
pfm_node = self._create_standard_python_file_node(tree, "xAgeSDLIntShowHide.py")
self._create_python_attribute(pfm_node, "stringVarName", value=self.sdl_variable)
self._create_python_attribute(pfm_node, "stringShowStates", value=",".join(self._states))
else:
raise RuntimeError()
@property
def key_name(self):
if self.variable_type == "bool":
return f"cPythBoolShowHide_{self.sdl_variable}_{self.bool_state:d}"
elif self.variable_type == "int":
return f"cPythIntShowHide_{self.sdl_variable}_{'-'.join(self._states)}"
@property
def _states(self) -> Iterable[str]:
"""Returns a sorted, deduplicated iterable of the integer (converted to strings) states we should be visible in."""
return (str(i) for i in sorted(frozenset((i.value for i in self.int_states))))
class PlasmaTelescope(PlasmaModifierProperties, PlasmaModifierLogicWiz): class PlasmaTelescope(PlasmaModifierProperties, PlasmaModifierLogicWiz):
pl_id="telescope" pl_id="telescope"

37
korman/ui/modifiers/logic.py

@ -60,6 +60,43 @@ def maintainersmarker(modifier, layout, context):
layout.label(text="Positive Y is North, positive Z is up.") layout.label(text="Positive Y is North, positive Z is up.")
layout.prop(modifier, "calibration") layout.prop(modifier, "calibration")
def sdl_showhide(modifier: PlasmaSDLShowHide, layout, context):
if not context.scene.world.plasma_age.age_sdl:
layout.label("This modifier requires Age Global SDL!", icon="ERROR")
return
valid_variable = modifier.sdl_variable.strip()
layout.alert = not valid_variable
layout.prop(modifier, "sdl_variable")
if not valid_variable:
layout.label("A valid SDL variable is required!", icon="ERROR")
layout.alert = False
layout.prop(modifier, "variable_type")
layout.separator()
def setup_collection_operator(op):
op.context = "object"
op.group_path = modifier.path_from_id()
op.collection_prop = "int_states"
op.index_prop = ""
if modifier.variable_type == "bool":
layout.prop(modifier, "bool_state")
elif modifier.variable_type == "int":
layout.label("Show when SDL variable is:")
sub = layout.column_flow()
for i, state in enumerate(modifier.int_states):
row = sub.row(align=True)
row.prop(state, "value", text="Value")
op = row.operator("ui.plasma_collection_remove", icon="ZOOMOUT", text="")
setup_collection_operator(op)
op.manual_index = i
op = layout.operator("ui.plasma_collection_add", icon="ZOOMIN", text="Add State Value")
setup_collection_operator(op)
else:
raise RuntimeError()
def telescope(modifier, layout, context): def telescope(modifier, layout, context):
layout.prop(modifier, "clickable_region") layout.prop(modifier, "clickable_region")
layout.prop(modifier, "seek_target_object", icon="EMPTY_DATA") layout.prop(modifier, "seek_target_object", icon="EMPTY_DATA")

Loading…
Cancel
Save