353 lines
21 KiB
Python
353 lines
21 KiB
Python
"""Build two original low-poly creature bosses as animated runtime GLBs.
|
|
|
|
Replaces weak chicken and frog visuals while keeping stable boss IDs in game data.
|
|
|
|
Run with:
|
|
/Applications/Blender.app/Contents/MacOS/Blender --background --factory-startup \
|
|
--python scripts/blender/build_replacement_creature_bosses.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import math
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import bpy
|
|
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
from build_iwt2_boss_trio import ( # noqa: E402
|
|
OUT_ROOT,
|
|
actions,
|
|
armature,
|
|
cone,
|
|
ellipsoid,
|
|
export_asset,
|
|
finish,
|
|
join_parts,
|
|
plate,
|
|
prepare_materials,
|
|
reset_scene,
|
|
)
|
|
|
|
|
|
def add_metadata(asset_id: str, concept: str) -> None:
|
|
metadata_path = OUT_ROOT / asset_id / f"{asset_id}.asset.json"
|
|
metadata = json.loads(metadata_path.read_text())
|
|
metadata["sourceConcept"] = concept
|
|
metadata["license"] = "Original project-owned asset"
|
|
metadata["runtime"]["forward"] = "-Y"
|
|
metadata["runtime"]["unit"] = "meters"
|
|
metadata_path.write_text(json.dumps(metadata, indent=2) + "\n")
|
|
|
|
|
|
def build_brassbeak_basilisk() -> None:
|
|
"""Six-legged forge basilisk replacing Cluckhorn's chicken-cow model."""
|
|
asset_id = "brassbeak-basilisk"
|
|
reset_scene()
|
|
mats = prepare_materials({
|
|
"Scale": {"color": (0.035, 0.105, 0.12, 1), "metallic": 0.14, "roughness": 0.62},
|
|
"Underbelly": {"color": (0.12, 0.19, 0.18, 1), "metallic": 0.05, "roughness": 0.72},
|
|
"Copper": {"color": (0.45, 0.16, 0.055, 1), "metallic": 0.48, "roughness": 0.33},
|
|
"Brass": {"color": (0.78, 0.48, 0.09, 1), "metallic": 0.62, "roughness": 0.25},
|
|
"Blade": {"color": (0.50, 0.58, 0.55, 1), "metallic": 0.72, "roughness": 0.2},
|
|
"Furnace": {"color": (0.02, 0.82, 0.72, 1), "roughness": 0.18, "emission": (0.01, 0.72, 0.64, 1), "strength": 5.5},
|
|
})
|
|
specs = [
|
|
("Root", (0, 0, 0), (0, 0, 0.45), None),
|
|
("Body", (0, 0.06, 1.18), (0, 0.05, 2.05), "Root"),
|
|
("Head", (0, -1.0, 1.48), (0, -1.82, 1.38), "Body"),
|
|
("Jaw", (0, -1.42, 1.28), (0, -2.05, 1.12), "Head"),
|
|
("Wing.L", (-0.62, -0.08, 1.72), (-1.55, -0.28, 1.5), "Body"),
|
|
("Wing.R", (0.62, -0.08, 1.72), (1.55, -0.28, 1.5), "Body"),
|
|
("Leg.FL", (-0.62, -0.72, 1.12), (-0.88, -0.84, 0.24), "Body"),
|
|
("Leg.FR", (0.62, -0.72, 1.12), (0.88, -0.84, 0.24), "Body"),
|
|
("Leg.ML", (-0.78, 0.03, 1.06), (-1.0, 0.02, 0.22), "Body"),
|
|
("Leg.MR", (0.78, 0.03, 1.06), (1.0, 0.02, 0.22), "Body"),
|
|
("Leg.BL", (-0.66, 0.76, 1.12), (-0.9, 0.88, 0.24), "Body"),
|
|
("Leg.BR", (0.66, 0.76, 1.12), (0.9, 0.88, 0.24), "Body"),
|
|
("Tail.1", (0, 1.0, 1.3), (0, 1.85, 1.12), "Body"),
|
|
("Tail.2", (0, 1.8, 1.12), (0, 2.7, 0.92), "Tail.1"),
|
|
]
|
|
rig = armature("BrassbeakBasilisk", specs)
|
|
|
|
# Broad armored silhouette with glowing furnace seams.
|
|
ellipsoid("BasiliskBody", (0, 0.08, 1.36), (1.08, 1.43, 0.72), mats["Scale"], "Body", 2)
|
|
ellipsoid("FurnaceBelly", (0, -0.15, 1.08), (0.78, 1.08, 0.46), mats["Underbelly"], "Body", 2)
|
|
for index, y in enumerate((-0.7, -0.22, 0.28, 0.76)):
|
|
width = 0.82 + (0.12 if index in (1, 2) else 0)
|
|
plate(
|
|
f"BackPlate{index}", (0, y, 1.92 + 0.08 * math.sin(index)),
|
|
(width, 0.55, 0.27), (math.radians(84), 0, 0),
|
|
mats["Copper"] if index % 2 == 0 else mats["Brass"], "Body",
|
|
)
|
|
cone(
|
|
f"ChimneySpine{index}", (0, y, 2.02), (0, y + 0.03, 2.52 - index * 0.04),
|
|
0.13, 0, mats["Blade"], "Body", 5,
|
|
)
|
|
for side in (-1, 1):
|
|
cone(
|
|
f"FurnaceSeam{side:+d}", (side * 0.58, -0.76, 1.34), (side * 0.72, 0.72, 1.34),
|
|
0.035, 0.022, mats["Furnace"], "Body", 5,
|
|
)
|
|
|
|
# Hammerhead, brass beak, split jaw, and crown blades.
|
|
ellipsoid("HammerHead", (0, -1.28, 1.5), (0.78, 0.74, 0.56), mats["Copper"], "Head", 2)
|
|
ellipsoid("FaceMask", (0, -1.72, 1.5), (0.58, 0.34, 0.42), mats["Brass"], "Head", 1)
|
|
cone("UpperBeak", (0, -1.68, 1.51), (0, -2.58, 1.34), 0.42, 0.035, mats["Brass"], "Head", 6)
|
|
cone("LowerBeak", (0, -1.64, 1.3), (0, -2.32, 1.18), 0.3, 0.025, mats["Blade"], "Jaw", 6)
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
ellipsoid(f"Eye{suffix}", (side * 0.43, -1.72, 1.66), (0.09, 0.055, 0.09), mats["Furnace"], "Head", 1)
|
|
cone(
|
|
f"BrowHorn{suffix}", (side * 0.42, -1.38, 1.78), (side * 0.88, -1.7, 2.03),
|
|
0.13, 0, mats["Blade"], "Head", 5,
|
|
)
|
|
for index, (x, z) in enumerate(((-0.34, 2.0), (0, 2.14), (0.34, 2.0))):
|
|
cone(f"CrownBlade{index}", (x, -1.2, 1.8), (x * 1.35, -1.15, z + 0.54), 0.12, 0, mats["Brass"], "Head", 5)
|
|
|
|
# Blade-like vestigial wings make lateral cleaves readable from camera.
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
bone = f"Wing.{suffix}"
|
|
plate(
|
|
f"WingShield{suffix}", (side * 1.05, -0.08, 1.62), (0.7, 0.56, 0.13),
|
|
(math.radians(78), math.radians(side * 18), math.radians(side * 8)), mats["Copper"], bone,
|
|
)
|
|
cone(
|
|
f"WingBlade{suffix}", (side * 0.72, -0.24, 1.7), (side * 1.95, -0.58, 1.42),
|
|
0.19, 0.015, mats["Blade"], bone, 6,
|
|
)
|
|
cone(
|
|
f"WingGlow{suffix}", (side * 0.88, -0.3, 1.69), (side * 1.7, -0.52, 1.5),
|
|
0.05, 0.008, mats["Furnace"], bone, 5,
|
|
)
|
|
|
|
# Six short piston legs: stable, strange, easy to read while scuttling.
|
|
leg_rows = (("F", -0.72), ("M", 0.03), ("B", 0.76))
|
|
for row_index, (row, y) in enumerate(leg_rows):
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
bone = f"Leg.{row}{suffix}"
|
|
hip_x = side * (0.64 if row != "M" else 0.78)
|
|
foot_x = side * (0.98 if row != "M" else 1.1)
|
|
ellipsoid(f"Hip{row}{suffix}", (hip_x, y, 1.05), (0.3, 0.34, 0.3), mats["Copper"], bone, 1)
|
|
cone(f"Shin{row}{suffix}", (hip_x, y, 1.0), (foot_x, y - 0.04, 0.28), 0.22, 0.14, mats["Scale"], bone, 6)
|
|
ellipsoid(f"Foot{row}{suffix}", (foot_x, y - 0.22, 0.2), (0.31, 0.48, 0.19), mats["Brass"], bone, 1)
|
|
for toe_index, toe_x in enumerate((-0.13, 0.13)):
|
|
cone(
|
|
f"Toe{row}{suffix}{toe_index}", (foot_x + toe_x, y - 0.42, 0.2),
|
|
(foot_x + toe_x * 1.4, y - 0.75, 0.1), 0.055, 0.004, mats["Blade"], bone, 5,
|
|
)
|
|
|
|
cone("TailCore1", (0, 0.95, 1.3), (0, 1.85, 1.1), 0.48, 0.3, mats["Scale"], "Tail.1", 7)
|
|
cone("TailCore2", (0, 1.78, 1.1), (0, 2.72, 0.88), 0.31, 0.07, mats["Copper"], "Tail.2", 7)
|
|
cone("TailBladeTop", (0, 2.45, 0.9), (0, 3.18, 1.45), 0.2, 0.015, mats["Blade"], "Tail.2", 5)
|
|
cone("TailBladeBottom", (0, 2.45, 0.9), (0, 3.15, 0.48), 0.18, 0.015, mats["Brass"], "Tail.2", 5)
|
|
ellipsoid("TailCoreGlow", (0, 2.54, 0.91), (0.14, 0.17, 0.14), mats["Furnace"], "Tail.2", 1)
|
|
|
|
body = join_parts("BrassbeakBasilisk", rig)
|
|
clips = actions(rig, brassbeak_actions())
|
|
export_asset(
|
|
asset_id, "Brassbeak Basilisk", rig, body, clips,
|
|
[
|
|
("Body", (0, 0, 1.25), (1.25, 1.55, 0.9)),
|
|
("Head", (0, -1.65, 1.42), (0.95, 1.05, 0.75)),
|
|
("Tail", (0, 2.08, 1.0), (0.55, 1.25, 0.78)),
|
|
],
|
|
(0, 0, 1.25), 8.8, "FurnaceBurst", 20,
|
|
)
|
|
add_metadata(asset_id, "Original six-legged forge basilisk designed for I Want to Heal")
|
|
|
|
|
|
def brassbeak_actions():
|
|
return [
|
|
("Idle", 60, True, [
|
|
{"frame": 1},
|
|
{"frame": 15, "locations": {"Root": (0, 0, 0.04)}, "rotations": {"Head": (3, 0, -3), "Jaw": (7, 0, 0), "Tail.2": (0, 0, 7), "Wing.L": (0, 0, -4), "Wing.R": (0, 0, 4)}},
|
|
{"frame": 30, "rotations": {"Head": (0, 0, 3), "Jaw": (0, 0, 0), "Tail.2": (0, 0, -7)}},
|
|
{"frame": 45, "locations": {"Root": (0, 0, 0.04)}, "rotations": {"Head": (3, 0, -3), "Jaw": (7, 0, 0), "Tail.2": (0, 0, 7), "Wing.L": (0, 0, -4), "Wing.R": (0, 0, 4)}},
|
|
{"frame": 60},
|
|
]),
|
|
("Scuttle", 30, True, [
|
|
{"frame": 1, "rotations": {"Leg.FL": (-18, 0, -5), "Leg.MR": (-18, 0, 4), "Leg.BL": (-18, 0, -4), "Leg.FR": (18, 0, 5), "Leg.ML": (18, 0, -4), "Leg.BR": (18, 0, 4), "Tail.2": (0, 0, -9)}},
|
|
{"frame": 8, "locations": {"Root": (0, 0, 0.08)}, "rotations": {"Body": (-3, 0, 0)}},
|
|
{"frame": 16, "rotations": {"Leg.FL": (18, 0, 5), "Leg.MR": (18, 0, -4), "Leg.BL": (18, 0, 4), "Leg.FR": (-18, 0, -5), "Leg.ML": (-18, 0, 4), "Leg.BR": (-18, 0, -4), "Tail.2": (0, 0, 9)}},
|
|
{"frame": 23, "locations": {"Root": (0, 0, 0.08)}, "rotations": {"Body": (3, 0, 0)}},
|
|
{"frame": 30, "rotations": {"Leg.FL": (-18, 0, -5), "Leg.MR": (-18, 0, 4), "Leg.BL": (-18, 0, -4), "Leg.FR": (18, 0, 5), "Leg.ML": (18, 0, -4), "Leg.BR": (18, 0, 4), "Tail.2": (0, 0, -9)}},
|
|
]),
|
|
("BeakRend", 34, False, [
|
|
{"frame": 1},
|
|
{"frame": 9, "locations": {"Root": (0, 0.12, -0.05)}, "rotations": {"Body": (-9, 0, 0), "Head": (-24, 0, 0), "Jaw": (24, 0, 0), "Wing.L": (0, -16, -10), "Wing.R": (0, 16, 10)}},
|
|
{"frame": 15, "locations": {"Root": (0, -0.2, 0.05)}, "rotations": {"Body": (15, 0, 0), "Head": (28, 0, 0), "Jaw": (-6, 0, 0)}},
|
|
{"frame": 23, "rotations": {"Head": (-8, 0, 0), "Jaw": (12, 0, 0)}},
|
|
{"frame": 34},
|
|
]),
|
|
("FurnaceBurst", 46, False, [
|
|
{"frame": 1},
|
|
{"frame": 12, "locations": {"Root": (0, 0, 0.1)}, "scales": {"Body": (0.94, 0.94, 0.94)}, "rotations": {"Wing.L": (-18, 18, -22), "Wing.R": (-18, -18, 22), "Head": (-12, 0, 0), "Jaw": (18, 0, 0), "Tail.1": (-12, 0, 0)}},
|
|
{"frame": 20, "locations": {"Root": (0, -0.08, 0.22)}, "scales": {"Body": (1.1, 1.1, 1.1)}, "rotations": {"Wing.L": (18, -62, -64), "Wing.R": (18, 62, 64), "Head": (20, 0, 0), "Jaw": (30, 0, 0), "Tail.1": (18, 0, 0), "Tail.2": (-22, 0, 0)}},
|
|
{"frame": 30, "scales": {"Body": (0.97, 0.97, 0.97)}, "rotations": {"Wing.L": (4, -18, -20), "Wing.R": (4, 18, 20), "Jaw": (4, 0, 0), "Tail.2": (8, 0, 0)}},
|
|
{"frame": 46},
|
|
]),
|
|
("Stagger", 28, False, [
|
|
{"frame": 1},
|
|
{"frame": 6, "locations": {"Root": (0.12, 0.12, -0.09)}, "rotations": {"Body": (-14, 0, 13), "Head": (22, 0, -12), "Wing.L": (24, 0, -18), "Wing.R": (-8, 0, 12)}},
|
|
{"frame": 15, "rotations": {"Body": (7, 0, -6), "Head": (-8, 0, 5)}},
|
|
{"frame": 28},
|
|
]),
|
|
("Death", 72, False, [
|
|
{"frame": 1},
|
|
{"frame": 20, "locations": {"Root": (0.15, 0.08, -0.25)}, "rotations": {"Root": (0, 25, 32), "Body": (18, 0, 12), "Head": (24, 0, -10), "Jaw": (20, 0, 0), "Wing.L": (32, 0, -26), "Wing.R": (16, 0, 20)}},
|
|
{"frame": 46, "locations": {"Root": (0.28, 0.08, -0.78)}, "rotations": {"Root": (0, 52, 82), "Body": (30, 0, 20), "Head": (42, 0, -20), "Leg.FL": (30, 0, 0), "Leg.ML": (-24, 0, 0), "Leg.BL": (20, 0, 0), "Tail.1": (-32, 0, 0), "Tail.2": (-25, 0, 0)}},
|
|
{"frame": 72, "locations": {"Root": (0.28, 0.08, -0.82)}, "rotations": {"Root": (0, 52, 82), "Body": (30, 0, 20), "Head": (44, 0, -20), "Leg.FL": (30, 0, 0), "Leg.ML": (-24, 0, 0), "Leg.BL": (20, 0, 0), "Tail.1": (-32, 0, 0), "Tail.2": (-25, 0, 0)}},
|
|
]),
|
|
]
|
|
|
|
|
|
def build_bogbell_myconid() -> None:
|
|
"""Bell-capped fungal brute replacing Mirelord's frog model."""
|
|
asset_id = "bogbell-myconid"
|
|
reset_scene()
|
|
mats = prepare_materials({
|
|
"Bark": {"color": (0.12, 0.18, 0.095, 1), "roughness": 0.88},
|
|
"Root": {"color": (0.25, 0.31, 0.16, 1), "roughness": 0.8},
|
|
"Cap": {"color": (0.29, 0.055, 0.31, 1), "roughness": 0.6},
|
|
"CapEdge": {"color": (0.52, 0.15, 0.42, 1), "roughness": 0.52},
|
|
"Gill": {"color": (0.62, 0.55, 0.31, 1), "roughness": 0.7},
|
|
"Spore": {"color": (0.48, 1.0, 0.32, 1), "roughness": 0.16, "emission": (0.22, 0.92, 0.16, 1), "strength": 4.8},
|
|
})
|
|
specs = [
|
|
("Root", (0, 0, 0), (0, 0, 0.5), None),
|
|
("Body", (0, 0, 1.15), (0, 0, 2.25), "Root"),
|
|
("Cap", (0, -0.05, 2.18), (0, -0.05, 3.18), "Body"),
|
|
("Arm.L", (-0.58, -0.15, 1.72), (-1.28, -0.62, 0.7), "Body"),
|
|
("Arm.R", (0.58, -0.15, 1.72), (1.28, -0.62, 0.7), "Body"),
|
|
("Leg.L", (-0.38, 0.08, 1.08), (-0.58, -0.1, 0.2), "Body"),
|
|
("Leg.R", (0.38, 0.08, 1.08), (0.58, -0.1, 0.2), "Body"),
|
|
("Tendril.L", (-0.42, 0.58, 1.45), (-1.05, 1.45, 0.82), "Body"),
|
|
("Tendril.R", (0.42, 0.58, 1.45), (1.05, 1.45, 0.82), "Body"),
|
|
]
|
|
rig = armature("BogbellMyconid", specs)
|
|
|
|
# Gnarled trunk and hanging bell cap.
|
|
ellipsoid("Trunk", (0, 0.05, 1.48), (0.82, 0.68, 1.05), mats["Bark"], "Body", 2)
|
|
ellipsoid("ChestKnot", (0, -0.5, 1.62), (0.58, 0.28, 0.62), mats["Root"], "Body", 1)
|
|
cone("NeckStalk", (0, -0.02, 1.95), (0, -0.04, 2.65), 0.48, 0.36, mats["Gill"], "Cap", 8)
|
|
plate("BellCap", (0, -0.04, 2.78), (1.55, 1.38, 0.55), (0, 0, 0), mats["Cap"], "Cap", 9)
|
|
ellipsoid("CapCrown", (0, 0.02, 3.04), (1.25, 1.08, 0.42), mats["CapEdge"], "Cap", 2)
|
|
plate("GillBell", (0, -0.03, 2.58), (1.28, 1.12, 0.28), (0, 0, math.radians(180)), mats["Gill"], "Cap", 9)
|
|
for index, angle in enumerate(range(0, 360, 45)):
|
|
radians = math.radians(angle)
|
|
x, y = math.cos(radians) * 1.02, math.sin(radians) * 0.87
|
|
cone(
|
|
f"CapHorn{index}", (x * 0.9, y * 0.9, 3.12), (x * 1.38, y * 1.35, 3.34 + 0.08 * (index % 2)),
|
|
0.11, 0, mats["CapEdge"], "Cap", 5,
|
|
)
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
ellipsoid(f"Eye{suffix}", (side * 0.29, -0.65, 2.18), (0.095, 0.055, 0.11), mats["Spore"], "Cap", 1)
|
|
cone(
|
|
f"FaceRoot{suffix}", (side * 0.25, -0.52, 2.03), (side * 0.42, -0.78, 1.72),
|
|
0.07, 0.015, mats["Root"], "Cap", 5,
|
|
)
|
|
ellipsoid("MouthHollow", (0, -0.68, 1.94), (0.22, 0.055, 0.13), mats["Cap"], "Cap", 1)
|
|
|
|
# Root arms end in broad knuckles for readable pummel animation.
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
bone = f"Arm.{suffix}"
|
|
cone(f"UpperArm{suffix}", (side * 0.55, -0.12, 1.78), (side * 1.04, -0.45, 1.05), 0.3, 0.22, mats["Bark"], bone, 7)
|
|
cone(f"Forearm{suffix}", (side * 1.02, -0.44, 1.06), (side * 1.34, -0.84, 0.58), 0.24, 0.18, mats["Root"], bone, 7)
|
|
ellipsoid(f"Knuckle{suffix}", (side * 1.38, -0.91, 0.48), (0.43, 0.38, 0.32), mats["Bark"], bone, 1)
|
|
for finger in (-0.16, 0, 0.16):
|
|
cone(
|
|
f"Finger{suffix}{finger}", (side * 1.36 + finger, -1.02, 0.43),
|
|
(side * 1.46 + finger, -1.35, 0.22), 0.065, 0.012, mats["Root"], bone, 5,
|
|
)
|
|
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
bone = f"Leg.{suffix}"
|
|
ellipsoid(f"Hip{suffix}", (side * 0.4, 0.08, 1.0), (0.42, 0.46, 0.5), mats["Bark"], bone, 1)
|
|
cone(f"RootLeg{suffix}", (side * 0.4, 0.06, 0.95), (side * 0.62, -0.12, 0.25), 0.34, 0.22, mats["Root"], bone, 7)
|
|
for toe_index, toe_x in enumerate((-0.22, 0, 0.22)):
|
|
cone(
|
|
f"RootToe{suffix}{toe_index}", (side * 0.62 + toe_x, -0.2, 0.25),
|
|
(side * 0.72 + toe_x * 1.25, -0.78 - abs(toe_x), 0.08), 0.095, 0.015, mats["Bark"], bone, 6,
|
|
)
|
|
|
|
# Rear tendrils drag through mire. Spore sacs pulse during eruption.
|
|
for side, suffix in ((-1, "L"), (1, "R")):
|
|
bone = f"Tendril.{suffix}"
|
|
cone(f"TendrilBase{suffix}", (side * 0.4, 0.5, 1.38), (side * 0.78, 1.22, 0.82), 0.22, 0.12, mats["Root"], bone, 7)
|
|
cone(f"TendrilTip{suffix}", (side * 0.76, 1.18, 0.84), (side * 1.28, 1.85, 0.3), 0.13, 0.018, mats["Bark"], bone, 6)
|
|
ellipsoid(f"SporeSac{suffix}", (side * 0.82, 0.72, 1.25), (0.24, 0.31, 0.3), mats["Spore"], bone, 1)
|
|
for index, (x, y, z, size) in enumerate(((-0.5, 0.45, 1.88, 0.16), (0.48, 0.5, 1.72, 0.2), (-0.28, 0.62, 1.35, 0.13))):
|
|
ellipsoid(f"BodySpore{index}", (x, y, z), (size, size * 0.82, size * 1.1), mats["Spore"], "Body", 1)
|
|
|
|
body = join_parts("BogbellMyconid", rig)
|
|
clips = actions(rig, bogbell_actions())
|
|
export_asset(
|
|
asset_id, "Bogbell Myconid", rig, body, clips,
|
|
[
|
|
("Body", (0, 0, 1.45), (1.05, 0.95, 1.35)),
|
|
("Cap", (0, 0, 2.82), (1.68, 1.48, 0.72)),
|
|
("Roots", (0, 0.38, 0.62), (1.58, 1.75, 0.72)),
|
|
],
|
|
(0, 0, 1.65), 8.5, "SporeEruption", 21,
|
|
)
|
|
add_metadata(asset_id, "Original bell-capped fungal mire creature designed for I Want to Heal")
|
|
|
|
|
|
def bogbell_actions():
|
|
return [
|
|
("Idle", 60, True, [
|
|
{"frame": 1},
|
|
{"frame": 15, "locations": {"Root": (0, 0, 0.04)}, "scales": {"Cap": (1.03, 1.03, 0.98)}, "rotations": {"Cap": (2, 0, -3), "Arm.L": (0, 0, -3), "Arm.R": (0, 0, 3), "Tendril.L": (0, 0, 7), "Tendril.R": (0, 0, -7)}},
|
|
{"frame": 30, "scales": {"Cap": (0.98, 0.98, 1.03)}, "rotations": {"Cap": (-1, 0, 3), "Tendril.L": (0, 0, -7), "Tendril.R": (0, 0, 7)}},
|
|
{"frame": 45, "locations": {"Root": (0, 0, 0.04)}, "scales": {"Cap": (1.03, 1.03, 0.98)}, "rotations": {"Cap": (2, 0, -3), "Arm.L": (0, 0, -3), "Arm.R": (0, 0, 3), "Tendril.L": (0, 0, 7), "Tendril.R": (0, 0, -7)}},
|
|
{"frame": 60},
|
|
]),
|
|
("BurrowRush", 32, True, [
|
|
{"frame": 1, "locations": {"Root": (0, 0, -0.12)}, "rotations": {"Body": (10, 0, 0), "Arm.L": (26, 0, -12), "Arm.R": (26, 0, 12), "Leg.L": (-16, 0, 0), "Leg.R": (16, 0, 0), "Tendril.L": (-18, 0, -12), "Tendril.R": (-18, 0, 12)}},
|
|
{"frame": 9, "locations": {"Root": (0, 0, -0.26)}, "rotations": {"Cap": (-9, 0, 0), "Leg.L": (16, 0, 0), "Leg.R": (-16, 0, 0), "Tendril.L": (14, 0, 10), "Tendril.R": (14, 0, -10)}},
|
|
{"frame": 17, "locations": {"Root": (0, 0, -0.12)}, "rotations": {"Body": (10, 0, 0), "Arm.L": (26, 0, -12), "Arm.R": (26, 0, 12), "Leg.L": (-16, 0, 0), "Leg.R": (16, 0, 0), "Tendril.L": (-18, 0, -12), "Tendril.R": (-18, 0, 12)}},
|
|
{"frame": 25, "locations": {"Root": (0, 0, -0.26)}, "rotations": {"Cap": (-9, 0, 0), "Leg.L": (16, 0, 0), "Leg.R": (-16, 0, 0), "Tendril.L": (14, 0, 10), "Tendril.R": (14, 0, -10)}},
|
|
{"frame": 32, "locations": {"Root": (0, 0, -0.12)}, "rotations": {"Body": (10, 0, 0), "Arm.L": (26, 0, -12), "Arm.R": (26, 0, 12), "Leg.L": (-16, 0, 0), "Leg.R": (16, 0, 0), "Tendril.L": (-18, 0, -12), "Tendril.R": (-18, 0, 12)}},
|
|
]),
|
|
("RootPummel", 36, False, [
|
|
{"frame": 1},
|
|
{"frame": 10, "locations": {"Root": (0, 0.1, 0.06)}, "rotations": {"Body": (-12, 0, 0), "Cap": (-8, 0, 0), "Arm.L": (-42, 0, -30), "Arm.R": (-42, 0, 30)}},
|
|
{"frame": 17, "locations": {"Root": (0, -0.12, -0.14)}, "rotations": {"Body": (22, 0, 0), "Cap": (18, 0, 0), "Arm.L": (58, 0, 16), "Arm.R": (58, 0, -16)}},
|
|
{"frame": 25, "rotations": {"Body": (-5, 0, 0), "Arm.L": (12, 0, -6), "Arm.R": (12, 0, 6)}},
|
|
{"frame": 36},
|
|
]),
|
|
("SporeEruption", 48, False, [
|
|
{"frame": 1},
|
|
{"frame": 13, "locations": {"Root": (0, 0, -0.12)}, "scales": {"Cap": (0.88, 0.88, 1.16)}, "rotations": {"Body": (-13, 0, 0), "Cap": (-15, 0, 0), "Arm.L": (-26, 0, -28), "Arm.R": (-26, 0, 28), "Tendril.L": (-28, 0, -24), "Tendril.R": (-28, 0, 24)}},
|
|
{"frame": 21, "locations": {"Root": (0, -0.04, 0.24)}, "scales": {"Cap": (1.18, 1.18, 0.9), "Body": (1.08, 1.08, 1.08)}, "rotations": {"Body": (18, 0, 0), "Cap": (19, 0, 0), "Arm.L": (18, 0, 62), "Arm.R": (18, 0, -62), "Tendril.L": (32, 0, 48), "Tendril.R": (32, 0, -48)}},
|
|
{"frame": 32, "scales": {"Cap": (0.97, 0.97, 1.04), "Body": (0.97, 0.97, 0.97)}, "rotations": {"Cap": (-5, 0, 0), "Arm.L": (4, 0, 12), "Arm.R": (4, 0, -12)}},
|
|
{"frame": 48},
|
|
]),
|
|
("Stagger", 28, False, [
|
|
{"frame": 1},
|
|
{"frame": 6, "locations": {"Root": (0.14, 0.1, -0.08)}, "rotations": {"Body": (-15, 0, 13), "Cap": (24, 0, -18), "Arm.L": (20, 0, -18), "Arm.R": (-8, 0, 12)}},
|
|
{"frame": 15, "rotations": {"Body": (7, 0, -6), "Cap": (-8, 0, 7)}},
|
|
{"frame": 28},
|
|
]),
|
|
("Death", 74, False, [
|
|
{"frame": 1},
|
|
{"frame": 20, "locations": {"Root": (0.14, 0.1, -0.3)}, "rotations": {"Root": (0, 24, 30), "Body": (20, 0, 12), "Cap": (28, 0, -18), "Arm.L": (30, 0, -26), "Arm.R": (16, 0, 20), "Tendril.L": (-24, 0, -14), "Tendril.R": (-16, 0, 18)}},
|
|
{"frame": 48, "locations": {"Root": (0.28, 0.1, -0.86)}, "rotations": {"Root": (0, 54, 84), "Body": (34, 0, 24), "Cap": (48, 0, -30), "Arm.L": (52, 0, -42), "Arm.R": (28, 0, 34), "Leg.L": (24, 0, 0), "Leg.R": (-18, 0, 0), "Tendril.L": (-40, 0, -24), "Tendril.R": (-34, 0, 26)}},
|
|
{"frame": 74, "locations": {"Root": (0.28, 0.1, -0.9)}, "rotations": {"Root": (0, 54, 84), "Body": (34, 0, 24), "Cap": (50, 0, -30), "Arm.L": (52, 0, -42), "Arm.R": (28, 0, 34), "Leg.L": (24, 0, 0), "Leg.R": (-18, 0, 0), "Tendril.L": (-40, 0, -24), "Tendril.R": (-34, 0, 26)}},
|
|
]),
|
|
]
|
|
|
|
|
|
def main() -> None:
|
|
bpy.context.preferences.filepaths.save_version = 0
|
|
OUT_ROOT.mkdir(parents=True, exist_ok=True)
|
|
build_brassbeak_basilisk()
|
|
build_bogbell_myconid()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|