Skip to content

Commit

Permalink
Merge pull request #52 from Laserlicht/def_addition
Browse files Browse the repository at this point in the history
add animations to creature table
  • Loading branch information
dydzio0614 authored Dec 7, 2024
2 parents 8e2ffef + e2ba474 commit 1ba1f86
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 211 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ json_repair==0.20.1
json5==0.9.25
pillow==10.3.0
numpy==1.26.4
homm3data==0.1.5
10 changes: 9 additions & 1 deletion src/build_mod_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,24 @@ def build_mod_page(mod_repo, mod):
def create_creature_table(md, mod, modparser):
log.info('create creature table for ' + mod["data"]["name"])
if "creatures" in mod["config"]:
header = ["Name", "Image", "Level", "Attack", "Defense", "Damage", "Speed", "HitPoints", "Growth", "AiValue"]
header = ["Name", "Image", "Anim", "Level", "Attack", "Defense", "Damage", "Speed", "HitPoints", "Growth", "AiValue"]
mdModTable = header.copy()
for k, v in mod["config"]["creatures"].items():
if not k.lower().startswith("core:") and "name" in mod["config"]["creatures"][k]:
image = ""
imageAnim = ""
if "animation" in mod["config"]["creatures"][k]["graphics"]:
animations = modparser.get_animations(mod, mod["config"]["creatures"][k]["graphics"]["animation"])
if animations is not None and 0 in animations['sequences']:
frames = animations['sequences'][0]['frames']
if len(frames) > 0:
imageAnim = Html.image(path=modparser.animation_convert_to_base64_html(frames), size='50')
if "iconLarge" in mod["config"]["creatures"][k]["graphics"]:
image = Html.image(path=modparser.get_image_base64(mod, mod["config"]["creatures"][k]["graphics"]["iconLarge"]), size='50')
mdModTable.extend([
mod["config"]["creatures"][k]["name"]["singular"],
image,
imageAnim,
get_value_if_exists(mod["config"]["creatures"][k], "level"),
get_value_if_exists(mod["config"]["creatures"][k], "attack"),
get_value_if_exists(mod["config"]["creatures"][k], "defense"),
Expand Down
203 changes: 0 additions & 203 deletions src/defextract.py

This file was deleted.

34 changes: 27 additions & 7 deletions src/parse_mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from helper import load_vcmi_json

from defextract import extract_def
from homm3data import deffile

def nested_update(d, u):
for k, v in u.items():
Expand Down Expand Up @@ -68,7 +68,7 @@ def get_mods(self):
data = load_vcmi_json(open(os.path.join(subdir, file)).read())
mods.append(
{
"pyhsicaldir": subdir,
"physicaldir": subdir,
"moddir": os.path.relpath(subdir, os.path.join(self.__tempdirname.name, os.listdir(self.__tempdirname.name)[0])),
"data": data,
"name": data["name"],
Expand All @@ -85,11 +85,11 @@ def __get_transparent_image(self, img):
return Image.fromarray(data, mode='RGBA')

def get_image(self, mod, path):
fullpaths = [os.path.join(mod["pyhsicaldir"], "content/sprites", path), os.path.join(mod["pyhsicaldir"], "content/data", path)]
fullpaths = [os.path.join(mod["physicaldir"], "content/sprites", path), os.path.join(mod["physicaldir"], "content/data", path)]
fullpaths = [x.rstrip("/") for x in fullpaths]
fullpaths = [x.rsplit('.', 1)[0] if "." in x.split("/")[-1] else x for x in fullpaths]
for fullpath in fullpaths:
for subdir, dirs, files in os.walk(mod["pyhsicaldir"]):
for subdir, dirs, files in os.walk(mod["physicaldir"]):
for file in files:
if os.path.join(subdir, file).lower().startswith(fullpath.lower()) and os.path.isfile(os.path.join(subdir, file)):
try:
Expand All @@ -108,13 +108,22 @@ def get_image_base64(self, mod, path, format="PNG"):
if img == None:
return ""
return self.image_convert_to_base64_html(img, format)

def animation_convert_to_base64_html(self, frames):
bounding_box = (min([x.convert("RGBa").getbbox()[0] for x in frames]), min([x.convert("RGBa").getbbox()[1] for x in frames]), max([x.convert("RGBa").getbbox()[2] for x in frames]), max([x.convert("RGBa").getbbox()[3] for x in frames]))
cropped_frames = [x.crop(bounding_box) for x in frames]
buffered = BytesIO()
frame_one = cropped_frames[0]
frame_one.save(buffered, format="GIF", append_images=cropped_frames, save_all=True, duration=100, loop=0, disposal=2)
img_str = "data:image/gif;base64," + base64.b64encode(buffered.getvalue()).decode()
return img_str

def get_animations(self, mod, path):
fullpaths = [os.path.join(mod["pyhsicaldir"], "content/sprites", path), os.path.join(mod["pyhsicaldir"], "content/data", path)]
fullpaths = [os.path.join(mod["physicaldir"], "content/sprites", path), os.path.join(mod["physicaldir"], "content/data", path)]
fullpaths = [x.rstrip("/") for x in fullpaths]
fullpaths = [x.rsplit('.', 1)[0] if "." in x.split("/")[-1] else x for x in fullpaths]
for fullpath in fullpaths:
for subdir, dirs, files in os.walk(mod["pyhsicaldir"]):
for subdir, dirs, files in os.walk(mod["physicaldir"]):
for file in files:
if os.path.join(subdir, file).lower().startswith(fullpath.lower()):
if file.lower().endswith(".json") or file.lower().endswith(".def"):
Expand All @@ -127,4 +136,15 @@ def get_animations(self, mod, path):
tmp["sequences"][i]["frames"][j] = self.get_image(mod, path_img)
return tmp
else:
return extract_def(os.path.join(subdir, file))
with deffile.open(os.path.join(subdir, file)) as d:
tmp = {}
tmp["sequences"] = {}
for group in d.get_groups():
tmp["sequences"][group] = {}
tmp["sequences"][group]["frames"] = []
for frame in range(d.get_frame_count(group)):
try:
tmp["sequences"][group]["frames"].append(d.read_image('combined', group, frame))
except:
pass
return tmp

0 comments on commit 1ba1f86

Please sign in to comment.