Read manifest + stub load set button
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
if "bpy" in locals():
|
||||
import importlib
|
||||
importlib.reload(globals)
|
||||
importlib.reload(properties)
|
||||
importlib.reload(operators)
|
||||
importlib.reload(panels)
|
||||
importlib.reload(preferences)
|
||||
else:
|
||||
from . import globals
|
||||
from . import properties
|
||||
from . import operators
|
||||
from . import panels
|
||||
from . import preferences
|
||||
@@ -13,6 +15,7 @@ else:
|
||||
import bpy
|
||||
|
||||
classes = (
|
||||
*properties.classes,
|
||||
*operators.classes,
|
||||
*panels.classes,
|
||||
preferences.D2ToolboxPreferences,
|
||||
@@ -22,6 +25,8 @@ def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
bpy.types.Scene.d2toolbox = bpy.props.PointerProperty(type=properties.D2ToolboxProperties)
|
||||
|
||||
if globals.getManifest() is None and bpy.app.online_access:
|
||||
try:
|
||||
globals.fetchAndSaveManifest()
|
||||
@@ -29,6 +34,8 @@ def register():
|
||||
print(f"D2Toolbox: failed to fetch manifest on load: {e}")
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Scene.d2toolbox
|
||||
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
|
||||
@@ -23,7 +23,19 @@ class D2TOOLBOX_OT_refetch_manifest(bpy.types.Operator):
|
||||
self.report({"INFO"}, "Manifest refreshed")
|
||||
return {"FINISHED"}
|
||||
|
||||
class D2TOOLBOX_OT_load_set(bpy.types.Operator):
|
||||
"""Load the selected armor set (stub)."""
|
||||
bl_idname = "d2toolbox.load_set"
|
||||
bl_label = "Load Set"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
# Stub for now
|
||||
self.report({"INFO"}, "Load Set (stub)")
|
||||
return {"FINISHED"}
|
||||
|
||||
classes = (
|
||||
D2TOOLBOX_OT_hello,
|
||||
D2TOOLBOX_OT_refetch_manifest
|
||||
D2TOOLBOX_OT_refetch_manifest,
|
||||
D2TOOLBOX_OT_load_set
|
||||
)
|
||||
|
||||
@@ -17,6 +17,40 @@ class D2TOOLBOX_PT_main(bpy.types.Panel):
|
||||
return
|
||||
|
||||
layout = self.layout
|
||||
|
||||
props = context.scene.d2toolbox
|
||||
|
||||
layout.label(text="Armor Set Loader")
|
||||
|
||||
layout.label(text="Class")
|
||||
row = layout.row(align=True)
|
||||
row.prop_enum(props, "d2_class", "hunter")
|
||||
row.prop_enum(props, "d2_class", "warlock")
|
||||
row.prop_enum(props, "d2_class", "titan")
|
||||
|
||||
layout.label(text="Sex")
|
||||
row = layout.row(align=True)
|
||||
row.prop_enum(props, "d2_sex", "male")
|
||||
row.prop_enum(props, "d2_sex", "female")
|
||||
|
||||
ready = props.d2_class != "NONE" and props.d2_sex != "NONE"
|
||||
col = layout.column()
|
||||
col.enabled = ready # greyed out until Class + Sex chosen
|
||||
col.prop(props, "slot_head")
|
||||
col.prop(props, "slot_arms")
|
||||
col.prop(props, "slot_chest")
|
||||
col.prop(props, "slot_legs")
|
||||
col.prop(props, "slot_class_item")
|
||||
|
||||
all_selected = ready and all(
|
||||
getattr(props, a) != "NONE"
|
||||
for a in ("slot_head", "slot_arms", "slot_chest", "slot_legs", "slot_class_item")
|
||||
)
|
||||
sub = layout.column()
|
||||
sub.enabled = all_selected # greyed out until all 5 slots chosen
|
||||
sub.operator("d2toolbox.load_set")
|
||||
|
||||
layout.separator()
|
||||
layout.label(text="Miscellaneous")
|
||||
layout.operator("d2toolbox.refetch_manifest")
|
||||
|
||||
|
||||
53
d2toolbox/properties.py
Normal file
53
d2toolbox/properties.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import bpy
|
||||
from . import globals
|
||||
|
||||
# Blender garbage-collects strings returned by dynamic EnumProperty `items`
|
||||
# callbacks unless a Python reference is kept. Cache each built list here,
|
||||
# keyed by (class, sex), to keep them alive.
|
||||
_armor_items_cache = {}
|
||||
|
||||
CLASS_ITEMS = [
|
||||
("NONE", "", ""),
|
||||
("hunter", "Hunter", ""),
|
||||
("warlock", "Warlock", ""),
|
||||
("titan", "Titan", ""),
|
||||
]
|
||||
|
||||
SEX_ITEMS = [
|
||||
("NONE", "", ""),
|
||||
("male", "Male", ""),
|
||||
("female", "Female", ""),
|
||||
]
|
||||
|
||||
_SLOT_ATTRS = ("slot_head", "slot_arms", "slot_chest", "slot_legs", "slot_class_item")
|
||||
|
||||
def _armor_items(self, context):
|
||||
key = (self.d2_class, self.d2_sex)
|
||||
items = [("NONE", "— None —", "")]
|
||||
if self.d2_class != "NONE" and self.d2_sex != "NONE":
|
||||
manifest = globals.getManifest()
|
||||
entries = (manifest.get(self.d2_class, {}).get(self.d2_sex, []) if manifest else []) or []
|
||||
for i, entry in enumerate(entries):
|
||||
name = entry.get("name", "Unknown")
|
||||
season = entry.get("season", "")
|
||||
label = f"{name} - {season}" if season else name
|
||||
items.append((str(i), label, ""))
|
||||
_armor_items_cache[key] = items
|
||||
return items
|
||||
|
||||
def _reset_slots(self, context):
|
||||
for attr in _SLOT_ATTRS:
|
||||
self[attr] = 0 # index 0 == 'NONE'
|
||||
|
||||
class D2ToolboxProperties(bpy.types.PropertyGroup):
|
||||
d2_class: bpy.props.EnumProperty(name="Class", items=CLASS_ITEMS, default="NONE", update=_reset_slots)
|
||||
d2_sex: bpy.props.EnumProperty(name="Sex", items=SEX_ITEMS, default="NONE", update=_reset_slots)
|
||||
slot_head: bpy.props.EnumProperty(name="Head", items=_armor_items)
|
||||
slot_arms: bpy.props.EnumProperty(name="Arms", items=_armor_items)
|
||||
slot_chest: bpy.props.EnumProperty(name="Chest", items=_armor_items)
|
||||
slot_legs: bpy.props.EnumProperty(name="Legs", items=_armor_items)
|
||||
slot_class_item: bpy.props.EnumProperty(name="Class Item", items=_armor_items)
|
||||
|
||||
classes = (
|
||||
D2ToolboxProperties,
|
||||
)
|
||||
Reference in New Issue
Block a user