Skip to content

Commit

Permalink
Allow multiple mob versions based on blender ver
Browse files Browse the repository at this point in the history
This resolves the need here to support new assets with minimal work to make backwards compatible: #317
  • Loading branch information
TheDuckCow committed Jul 10, 2022
1 parent 3811eeb commit 86c2ca5
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 3 deletions.
17 changes: 14 additions & 3 deletions MCprep_addon/spawner/mobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,17 @@ def _add_rigs_from_blend(path, blend_name, category):
mob_names = spawn_util.filter_collections(data_from)

for name in mob_names:
description = "Spawn one {x} rig".format(x=name)
mob = context.scene.mcprep_props.mob_list_all.add()
if spawn_util.INCLUDE_COLL.lower() in name.lower():
subname = name.lower().replace(
spawn_util.INCLUDE_COLL.lower(), "")
subname = subname.strip()
else:
subname = name

description = "Spawn one {x} rig".format(x=subname)
mob.description = description # add in non all-list
mob.name = name.title()
mob.name = subname.title()
mob.category = category
mob.index = len(context.scene.mcprep_props.mob_list_all)
if category:
Expand All @@ -92,7 +99,7 @@ def _add_rigs_from_blend(path, blend_name, category):
icons = [
f for f in os.listdir(icon_folder)
if os.path.isfile(os.path.join(icon_folder, f))
and name.lower() == os.path.splitext(f.lower())[0]
and subname.lower() == os.path.splitext(f.lower())[0]
and not f.startswith(".")
and os.path.splitext(f.lower())[-1] in extensions]
if not icons:
Expand Down Expand Up @@ -135,11 +142,15 @@ def _add_rigs_from_blend(path, blend_name, category):
and not f.startswith(".")]

for blend_name in blend_files:
if not spawn_util.check_blend_eligible(blend_name, blend_files):
continue # Not eligible, use allowed blend in list instead.
blend_path = os.path.join(cat_path, blend_name)
_add_rigs_from_blend(blend_path, blend_name, category)

# Update the list with non-categorized mobs (ie root of target folder)
for blend_name in no_category_blends:
if not spawn_util.check_blend_eligible(blend_name, no_category_blends):
return # Not eligible, use allowed blend in list instead.
blend_path = os.path.join(rigpath, blend_name)
_add_rigs_from_blend(blend_path, blend_name, "")

Expand Down
61 changes: 61 additions & 0 deletions MCprep_addon/spawner/spawn_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# ##### END GPL LICENSE BLOCK #####

import os
import re

import bpy

Expand Down Expand Up @@ -89,6 +90,66 @@ def filter_collections(data_from):
return all_names


def check_blend_eligible(this_file, all_files):
"""Returns true if the path blend file is ok for this blender version.
Created to better support older blender versions without having to
compeltely remake new rig contirbutions from scratch. See for more details:
https://github.com/TheDuckCow/MCprep/issues/317
If the "pre#.#.#" suffix is found in any similar prefix named blend files,
evaluate whether the target file itself is eligible. If pre3.0.0 is found
in path, then this function returns False if the current blender version is
3.0 to force loading the non pre3.0.0 version instead, and if pre3.0.0 is
not in the path variable but pre#.#.# is found in another file, then it
returns true. If no pre#.#.# found in any files of the common base, would
always return True.
"""
basename = os.path.splitext(this_file)[0]

# Regex code to any matches of pre#.#.# at very end of name.
# (pre) for exact match,
# [0-9]+ to match any 1+ numbers
# (\.[0-9]+) for any repeat number of .#
# +$ to ensure it's an ending group.
code = r'(?i)(pre)[0-9]+(\.[0-9]+)+$'
find_suffix = re.compile(code)

def tuple_from_match(match):
prestr = match.group(0) # At most one group given +$ ending condition.
vstr = prestr[3:] # Chop off "pre".
tuple_ver = tuple([int(n) for n in vstr.split(".")])
return tuple_ver

matches = find_suffix.search(basename)
if matches:
tuple_ver = tuple_from_match(matches)
res = util.min_bv(tuple_ver)
# If the suffix = 3.0 and we are BELOW 3.0, return True (use this file)
return not res

# Remaining case: no suffix found in this target, but see if any other
# files have the same base and *do* have a suffix indicator.
for afile in all_files:
if not afile.startswith(basename):
continue
if afile == this_file:
continue # Already checked above.

base_afile = os.path.splitext(afile)[0]
matches = find_suffix.search(base_afile)
if matches:
tuple_ver = tuple_from_match(matches)
res = util.min_bv(tuple_ver)
# If the suffix = 3.0 in `afile` file, and current blender is
# below 3, then `afile` is the file that should be loaded, and the
# current file `this_file` is to be skipped.
return res

# If no matches (the most common case), then this file is eligible.
return True


def attemptScriptLoad(path):
"""Search for script that matches name of the blend file"""

Expand Down
38 changes: 38 additions & 0 deletions test_files/addon_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def __init__(self):
self.openfolder,
self.spawn_mob,
self.spawn_mob_linked,
self.check_blend_eligible,
self.change_skin,
self.import_world_split,
self.import_world_fail,
Expand Down Expand Up @@ -690,6 +691,43 @@ def spawn_mob_linked(self):
bpy.ops.mcprep.reload_mobs()
bpy.ops.mcprep.mob_spawner(toLink=True)

def check_blend_eligible(self):
from MCprep.spawner import spawn_util
fake_base = "MyMob - by Person"

suffix_new = " pre9.0.0" # Force active blender instance as older
suffix_old = " pre1.0.0" # Force active blender instance as newer.

p_none = fake_base + ".blend"
p_new = fake_base + suffix_new + ".blend"
p_old = fake_base + suffix_old + ".blend"
rando = "rando_name" + suffix_old + ".blend"

# Check where input file is the "non-versioned" one.

res = spawn_util.check_blend_eligible(p_none, [p_none, rando])
if res is not True:
return "Should have been true even if rando has suffix"

res = spawn_util.check_blend_eligible(p_none, [p_none, p_old])
if res is not True:
return "Should be true as curr blend eligible and checked latest"

res = spawn_util.check_blend_eligible(p_none, [p_none, p_new])
if res is not False:
print(p_none, p_new, res)
return "Should be false as curr blend not eligible and checked latest"

# Now check if input is a versioned file.

res = spawn_util.check_blend_eligible(p_new, [p_none, p_new])
if res is not True:
return "Should have been true since we are below min blender"

res = spawn_util.check_blend_eligible(p_old, [p_none, p_old])
if res is not False:
return "Should have been false since we are above this min blender"

def change_skin(self):
"""Test scenarios for changing skin after adding a character."""
self._clear_scene()
Expand Down

0 comments on commit 86c2ca5

Please sign in to comment.