Read manifest + stub load set button
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
if "bpy" in locals():
|
if "bpy" in locals():
|
||||||
import importlib
|
import importlib
|
||||||
importlib.reload(globals)
|
importlib.reload(globals)
|
||||||
|
importlib.reload(properties)
|
||||||
importlib.reload(operators)
|
importlib.reload(operators)
|
||||||
importlib.reload(panels)
|
importlib.reload(panels)
|
||||||
importlib.reload(preferences)
|
importlib.reload(preferences)
|
||||||
else:
|
else:
|
||||||
from . import globals
|
from . import globals
|
||||||
|
from . import properties
|
||||||
from . import operators
|
from . import operators
|
||||||
from . import panels
|
from . import panels
|
||||||
from . import preferences
|
from . import preferences
|
||||||
@@ -13,6 +15,7 @@ else:
|
|||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
|
*properties.classes,
|
||||||
*operators.classes,
|
*operators.classes,
|
||||||
*panels.classes,
|
*panels.classes,
|
||||||
preferences.D2ToolboxPreferences,
|
preferences.D2ToolboxPreferences,
|
||||||
@@ -22,6 +25,8 @@ def register():
|
|||||||
for cls in classes:
|
for cls in classes:
|
||||||
bpy.utils.register_class(cls)
|
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:
|
if globals.getManifest() is None and bpy.app.online_access:
|
||||||
try:
|
try:
|
||||||
globals.fetchAndSaveManifest()
|
globals.fetchAndSaveManifest()
|
||||||
@@ -29,6 +34,8 @@ def register():
|
|||||||
print(f"D2Toolbox: failed to fetch manifest on load: {e}")
|
print(f"D2Toolbox: failed to fetch manifest on load: {e}")
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
del bpy.types.Scene.d2toolbox
|
||||||
|
|
||||||
for cls in reversed(classes):
|
for cls in reversed(classes):
|
||||||
bpy.utils.unregister_class(cls)
|
bpy.utils.unregister_class(cls)
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,19 @@ class D2TOOLBOX_OT_refetch_manifest(bpy.types.Operator):
|
|||||||
self.report({"INFO"}, "Manifest refreshed")
|
self.report({"INFO"}, "Manifest refreshed")
|
||||||
return {"FINISHED"}
|
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 = (
|
classes = (
|
||||||
D2TOOLBOX_OT_hello,
|
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
|
return
|
||||||
|
|
||||||
layout = self.layout
|
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.label(text="Miscellaneous")
|
||||||
layout.operator("d2toolbox.refetch_manifest")
|
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