424 lines
30 KiB
Python
424 lines
30 KiB
Python
"""
|
|
Part library and per-type weights for generate_sprite.py.
|
|
|
|
How picking works
|
|
-----------------
|
|
1. A body plan is picked using PLAN_WEIGHTS[type].
|
|
2. Each slot in PICK_ORDER (generate_sprite.py) is filled with one part. A part is a
|
|
candidate only if:
|
|
- the chosen body plan is in its `plans`
|
|
- if it has `requires`, at least one of those tags was added by an earlier pick
|
|
- none of its `tags` were excluded by an earlier pick, and none of its
|
|
`excludes` match an earlier pick's tags
|
|
3. Candidate weight = types.get(type, other). Higher = more likely. 0 = never.
|
|
"none" entries are real choices, so their weight controls how often a slot is empty.
|
|
|
|
Bodies are complete base creatures (body, head and face drawn together); the other slots
|
|
vary them. Tags ending in "_head" (head family, gates head_top parts) and tags starting
|
|
with "_" (used only so a base can exclude one specific part shape) are internal plumbing.
|
|
All other tags show up as the sprite's "attributes" (beaked, finned, fluffy, tailed...).
|
|
|
|
Editing this file changes which parts existing businesses get, since every pick
|
|
draws from the same seeded random sequence.
|
|
"""
|
|
|
|
TYPES = [
|
|
"normal", "fire", "water", "grass", "electric", "ice", "fighting", "poison",
|
|
"ground", "flying", "psychic", "bug", "rock", "ghost", "dragon",
|
|
]
|
|
|
|
# Signature color per type. Used for the "type" palette (flames, leaves, sparks...)
|
|
# and as a fallback when a logo has no usable second color.
|
|
TYPE_COLORS = {
|
|
"normal": "#A8A878", "fire": "#F08030", "water": "#6890F0", "grass": "#78C850",
|
|
"electric": "#F8D030", "ice": "#98D8D8", "fighting": "#C03028", "poison": "#A040A0",
|
|
"ground": "#E0C068", "flying": "#A890F0", "psychic": "#F85888", "bug": "#A8B820",
|
|
"rock": "#B8A038", "ghost": "#705898", "dragon": "#7038F8",
|
|
}
|
|
|
|
PLANS = ["quadruped", "biped", "serpentine", "avian", "aquatic", "blob", "insectoid"]
|
|
ALL = PLANS
|
|
LEGGED = ["quadruped", "biped"]
|
|
|
|
PLAN_WEIGHTS = {
|
|
"normal": {"quadruped": 5, "biped": 4, "avian": 2, "blob": 1, "serpentine": 0.5},
|
|
"fire": {"quadruped": 5, "biped": 3, "serpentine": 1.5, "avian": 1.5, "blob": 1},
|
|
"water": {"aquatic": 5, "serpentine": 2.5, "quadruped": 2, "biped": 1.5, "blob": 1},
|
|
"grass": {"quadruped": 4, "biped": 3, "blob": 2, "serpentine": 1, "insectoid": 1},
|
|
"electric": {"quadruped": 4, "biped": 3, "blob": 2, "avian": 1, "insectoid": 1},
|
|
"ice": {"quadruped": 3, "biped": 2, "aquatic": 2, "avian": 1.5, "blob": 1.5, "serpentine": 1},
|
|
"fighting": {"biped": 7, "quadruped": 2, "insectoid": 0.5},
|
|
"poison": {"blob": 4, "serpentine": 3, "quadruped": 2, "biped": 2, "insectoid": 2},
|
|
"ground": {"quadruped": 5, "biped": 3, "serpentine": 2, "insectoid": 0.5},
|
|
"flying": {"avian": 7, "quadruped": 1, "serpentine": 1, "insectoid": 1},
|
|
"psychic": {"biped": 4, "quadruped": 3, "blob": 2, "avian": 1.5},
|
|
"bug": {"insectoid": 7, "serpentine": 1, "avian": 0.5},
|
|
"rock": {"biped": 3, "quadruped": 3, "serpentine": 2, "blob": 2},
|
|
"ghost": {"blob": 6, "serpentine": 2, "biped": 1, "avian": 0.5},
|
|
"dragon": {"serpentine": 4, "quadruped": 3, "biped": 3, "avian": 0.5},
|
|
}
|
|
|
|
# Procedural markings: painted onto the body's main-color pixels in the accent color.
|
|
# No sprites needed. "_other" is the weight for types not listed. The belly patch is
|
|
# centred on the body's aura anchor (its visual centre), so it lands on the tummy
|
|
# rather than across a big baked-in head.
|
|
MARKINGS = {
|
|
"none": {"_other": 4},
|
|
"spots": {"grass": 3, "poison": 3, "bug": 2, "water": 2, "electric": 2, "normal": 1.5, "_other": 0.5},
|
|
"speckles": {"ground": 3, "rock": 3, "ice": 1.5, "normal": 1, "_other": 0.3},
|
|
"belly": {"normal": 3, "water": 2, "fire": 2, "dragon": 2, "ice": 2, "fighting": 2, "ground": 2, "_other": 1},
|
|
}
|
|
|
|
# Combination rules for the variation slots.
|
|
# - At most MAX_FEATURES of head_top/back/tail are filled (picked in that order), so a creature
|
|
# gets one or two signature features instead of a pile of unrelated parts.
|
|
# - Each feature part has a visual motif. Once a motif is on the creature, more parts of the
|
|
# same motif are boosted (x MOTIF_SAME) and parts of an unrelated motif are damped
|
|
# (x MOTIF_CLASH), unless the pair is listed in MOTIF_PAIRS. Parts without a motif (plain fur
|
|
# ears and tails) go with anything.
|
|
# Slots skipped during generation (their art stays in the library). Remove "aura" to bring
|
|
# the floating aura effects back.
|
|
DISABLED_SLOTS = {"aura"}
|
|
FEATURE_SLOTS = ("head_top", "back", "tail")
|
|
MAX_FEATURES = 2
|
|
MOTIF_SAME, MOTIF_CLASH = 2.5, 0.08
|
|
MOTIFS = {
|
|
# feathers
|
|
"crest_feather": "feather", "wings_feather": "feather", "wings_feather_small": "feather",
|
|
"tail_feather_fan": "feather",
|
|
# plants
|
|
"leaf_sprout": "plant", "flower_bloom": "plant", "mushroom_cap": "plant", "plant_bulb": "plant",
|
|
"leaf_cape": "plant", "flower_back": "plant", "mushroom_back": "plant", "tail_leaf": "plant",
|
|
# fire
|
|
"crest_flame": "fire", "flame_mane": "fire", "tail_flame_tip": "fire",
|
|
# spooky
|
|
"wisp_flame": "spooky", "wings_bat": "spooky", "ghost_tatters": "spooky", "tail_wispy": "spooky",
|
|
# crystal / ice
|
|
"ice_crown": "crystal", "crystal_spikes": "crystal", "gem_forehead": "crystal", "crystal_cluster": "crystal",
|
|
"icicle_spikes": "crystal", "tail_ice_shard": "crystal", "tail_crystal": "crystal",
|
|
# water
|
|
"ears_fin": "water", "water_spout": "water", "dorsal_fin": "water", "tail_fish_fin": "water",
|
|
# electric
|
|
"ears_bolt": "electric", "coil_spikes": "electric", "tail_lightning": "electric",
|
|
# armour / rock
|
|
"horn_single": "armor", "horns_ram": "armor", "shell_round": "armor", "shell_spiked": "armor",
|
|
"spikes_back": "armor", "rock_plates": "armor", "tail_club": "armor", "tail_spiked": "armor",
|
|
# dragon
|
|
"horns_dragon": "dragon", "wings_dragon": "dragon", "sail_fin": "dragon", "tail_dragon": "dragon",
|
|
# bug
|
|
"antennae": "bug", "wings_bug": "bug", "tail_stinger": "bug",
|
|
# sky
|
|
"cloud_tuft": "sky", "cloud_puffs": "sky",
|
|
}
|
|
MOTIF_PAIRS = {frozenset(p) for p in [
|
|
("dragon", "armor"), ("dragon", "fire"), ("crystal", "armor"), ("crystal", "water"), ("plant", "bug"),
|
|
("feather", "sky"), ("fire", "armor"), ("water", "armor"), ("spooky", "crystal"), ("electric", "armor"),
|
|
("sky", "electric"), ("sky", "crystal"), ("feather", "fire"), ("dragon", "water"),
|
|
]}
|
|
|
|
|
|
def part(name, plans=ALL, types=None, other=0.25, tags=(), requires=(), excludes=(), deny=(),
|
|
palette="main", size=None, z=None, desc=""):
|
|
return {
|
|
"name": name, "plans": list(plans), "types": dict(types or {}), "other": other,
|
|
"tags": list(tags), "requires": list(requires), "excludes": list(excludes), "deny": list(deny),
|
|
"palette": palette, "size": size, "z": z, "desc": desc,
|
|
}
|
|
|
|
|
|
def none(types=None, other=1.0, plans=ALL, requires=()):
|
|
return part("none", plans, types, other, requires=requires, desc="(empty slot, no sprite)")
|
|
|
|
|
|
# Head-family tags carried by each base body. head_top parts use them in `requires`.
|
|
MAMMAL = ["mammal_head"]
|
|
ANY_FACE = ["mammal_head", "reptile_head", "integrated_head"]
|
|
NOT_BEAK = ["mammal_head", "reptile_head", "rock_head", "insect_head", "integrated_head", "ghost_head"]
|
|
INTEGRATED = ["integrated_head"]
|
|
|
|
|
|
def base(name, plan, types, head, size, desc, tags=(), excludes=(), deny=()):
|
|
"""A complete designed creature (body + head + face in one sprite).
|
|
|
|
head: head-family tag(s) gating head_top parts. excludes: tags of variation parts that
|
|
clash with features already drawn into the base (e.g. "eared" when it has ears).
|
|
deny: specific variation part names that don't sit well on this base."""
|
|
heads = [head] if isinstance(head, str) else list(head)
|
|
return part(name, [plan], types, 0.3, tags=heads + list(tags), excludes=excludes, deny=deny,
|
|
size=size, desc=desc)
|
|
|
|
|
|
# --------------------------------------------------------------------------- body (base creatures)
|
|
BODY = [
|
|
# quadruped
|
|
base("base_fox", "quadruped", {"fire": 3, "electric": 3, "psychic": 3, "normal": 2, "ice": 2}, "mammal_head",
|
|
(42, 36), "Chibi fox/cat critter with cheek tufts, big pointed ears and a fluffy bib", excludes=["eared"],
|
|
deny=["ears_fin", "horns_ram", "horns_dragon", "crystal_spikes", "tail_fish_fin"]),
|
|
base("base_cub", "quadruped", {"ground": 4, "rock": 3, "fighting": 3, "normal": 2, "grass": 2}, "mammal_head",
|
|
(40, 34), "Chunky bear-cub on all fours, round ears, sturdy paws", excludes=["eared", "_side_horns"],
|
|
deny=["ears_fin", "horns_dragon", "crystal_spikes", "mane_fluffy", "tail_fish_fin"]),
|
|
base("base_pup", "quadruped", {"normal": 4, "fire": 3, "fighting": 2, "water": 1.5}, "mammal_head",
|
|
(42, 34), "Bouncy puppy with floppy ears and a happy open mouth", excludes=["eared", "_side_horns"],
|
|
deny=["ears_fin", "horns_dragon", "tail_fish_fin"]),
|
|
base("base_salamander", "quadruped", {"fire": 3, "water": 3, "poison": 3, "dragon": 2, "grass": 1}, "reptile_head",
|
|
(47, 27), "Low chibi salamander/newt with a wide smile and frilly cheeks", excludes=["_head_fins"],
|
|
deny=["horns_ram", "tail_fluffy", "mane_fluffy"]),
|
|
base("base_drake", "quadruped", {"dragon": 5, "fire": 3, "rock": 2, "ground": 1}, "reptile_head",
|
|
(42, 38), "Cool baby dragon on four legs, nub horns, confident grin", excludes=["horned", "_headband"],
|
|
deny=["ears_fin", "crest_feather", "crystal_spikes", "tail_fluffy"]),
|
|
base("base_fawn", "quadruped", {"grass": 4, "psychic": 3, "ice": 3, "normal": 1}, "mammal_head",
|
|
(42, 35), "Dainty chibi fawn in 3/4 view: big leaf ears, gentle eyes, spotted back",
|
|
excludes=["eared", "_side_horns"],
|
|
deny=["ears_fin", "crystal_spikes", "mane_fluffy", "tail_fish_fin", "horns_dragon", "wings_bat",
|
|
"wings_dragon", "mushroom_back"]),
|
|
# biped
|
|
base("base_imp", "biped", {"electric": 4, "normal": 3, "psychic": 2, "ghost": 1}, "mammal_head",
|
|
(40, 40), "Upright mouse-imp with big round ears and a cheeky fanged grin", excludes=["eared"],
|
|
deny=["ears_fin", "crystal_spikes", "shell_round", "shell_spiked", "rock_plates", "tail_fish_fin"]),
|
|
base("base_brawler", "biped", {"fighting": 5, "rock": 3, "ground": 3, "normal": 1}, "mammal_head",
|
|
(42, 43), "Stout little fighter with big fists and a determined face", excludes=["eared"],
|
|
deny=["ears_fin", "spiky_hair", "crystal_spikes", "flame_mane", "tail_stub", "tail_fish_fin", "tail_feather_fan"]),
|
|
base("base_bunny", "biped", {"normal": 4, "grass": 3, "ice": 2, "psychic": 2}, "mammal_head",
|
|
(36, 45), "Upright chibi bunny with long ears and a fluffy chest", excludes=["eared"],
|
|
deny=["ears_fin", "horn_single", "horns_dragon", "antennae", "crest_flame", "crystal_spikes", "spiky_hair", "water_spout", "wings_dragon", "flame_mane", "tail_fish_fin", "tail_feather_fan"]),
|
|
base("base_dino", "biped", {"dragon": 4, "fire": 3, "ground": 2, "water": 1}, "reptile_head",
|
|
(36, 44), "Little upright dino with a big head, tiny arms and a toothy grin", excludes=["_headband"],
|
|
deny=["flame_mane"]),
|
|
base("base_pixie", "biped", {"psychic": 4, "ghost": 3, "grass": 2, "poison": 2}, "mammal_head",
|
|
(42, 39), "Leaf-elf pixie with sweeping pointed ears, round torso, stubby legs and a mischievous grin",
|
|
excludes=["eared"],
|
|
deny=["ears_fin", "wings_dragon", "shell_spiked", "rock_plates", "tail_feather_fan"]),
|
|
# avian
|
|
base("base_chick", "avian", {"normal": 4, "ice": 3, "electric": 2, "water": 2, "flying": 2}, "beak_head",
|
|
(36, 35), "Egg-round chick with a feather tuft, wing nubs and a tiny beak",
|
|
deny=["crest_feather", "wings_bat"]),
|
|
base("base_owl", "avian", {"psychic": 4, "flying": 3, "ghost": 3, "normal": 1}, "beak_head",
|
|
(36, 36), "Round owlet with huge eyes and ear tufts", excludes=["eared"],
|
|
deny=["crest_feather", "crest_flame", "crystal_spikes", "ice_crown", "wisp_flame", "wings_feather", "wings_bat"]),
|
|
base("base_hawk", "avian", {"flying": 5, "fire": 3, "fighting": 3, "dragon": 1}, "beak_head",
|
|
(38, 37), "Cool young hawk, puffed chest, sharp brow and hooked beak",
|
|
deny=["crest_feather", "wisp_flame", "wings_feather", "wings_bat"]),
|
|
base("base_penguin", "avian", {"ice": 5, "water": 4, "normal": 1}, "beak_head",
|
|
(36, 38), "Chubby penguin chick with flipper wings and a bib",
|
|
deny=["wings_feather", "wings_feather_small", "wings_bat", "tail_wispy", "ghost_tatters"]),
|
|
# aquatic
|
|
base("base_guppy", "aquatic", {"water": 5, "poison": 2, "ice": 2, "dragon": 1}, "integrated_head",
|
|
(46, 33), "Round bubbly fish with big eyes and frilly fins",
|
|
deny=["ears_round", "ears_long", "ears_floppy", "shell_round"]),
|
|
base("base_otter", "aquatic", {"ice": 4, "water": 4, "normal": 2}, "mammal_head",
|
|
(49, 30), "Chubby seal/otter pup lying on its flippers", excludes=["eared"],
|
|
deny=["shell_round", "tail_fish_fin"]),
|
|
base("base_axolotl", "aquatic", {"water": 4, "poison": 3, "dragon": 2, "grass": 1}, "reptile_head",
|
|
(51, 30), "Smiling axolotl with feathery gill fronds", excludes=["_head_fins"],
|
|
deny=["horns_ram", "shell_round"]),
|
|
# serpentine
|
|
base("base_noodle", "serpentine", {"poison": 4, "ground": 3, "normal": 2, "grass": 2}, "reptile_head",
|
|
(44, 40), "Cute coiled snake with a big round head and a sly smile",
|
|
deny=["dorsal_fin"]),
|
|
base("base_eel", "serpentine", {"water": 4, "ice": 3, "electric": 2, "dragon": 2}, "reptile_head",
|
|
(45, 46), "Rising sea-serpent with fin frills and big eyes", excludes=["finned"],
|
|
deny=["horns_ram", "wings_bat", "wings_dragon", "spikes_back", "leaf_cape", "crystal_cluster", "rock_plates", "cloud_puffs", "ghost_tatters", "icicle_spikes"]),
|
|
base("base_wyrm", "serpentine", {"dragon": 4, "ghost": 3, "psychic": 1, "ice": 1}, "reptile_head",
|
|
(43, 44), "Cool coiled young wyrm with whisker barbels and a proud look", excludes=["horned", "feathered"],
|
|
deny=["ears_fin", "crystal_spikes", "spiky_hair", "dorsal_fin"]),
|
|
# blob
|
|
base("base_blob", "blob", {"normal": 4, "grass": 3, "ice": 3, "electric": 2}, "integrated_head",
|
|
(40, 33), "Squishy mochi blob with a curl on top and a big smile",
|
|
deny=["horn_single", "horns_ram", "ears_bolt", "ears_fin", "flower_back"]),
|
|
base("base_slime", "blob", {"poison": 5, "water": 3, "ghost": 1}, "integrated_head",
|
|
(40, 34), "Drippy goo blob with a cheeky tongue-out face",
|
|
deny=["ears_floppy", "mushroom_back"]),
|
|
base("base_wisp", "blob", {"ghost": 5, "psychic": 3, "fire": 1, "flying": 1}, ["integrated_head", "ghost_head"],
|
|
(36, 40), "Floating ghost wisp with a curly tail-end and a spooky-cute grin", excludes=["tailed"],
|
|
deny=["ears_floppy", "flower_back"]),
|
|
base("base_pebble", "blob", {"rock": 5, "ground": 3, "fighting": 1}, "integrated_head",
|
|
(38, 32), "Round rock lump creature with a sturdy little face and stubby feet",
|
|
deny=["ears_floppy", "mushroom_back"]),
|
|
# insectoid
|
|
base("base_beetle", "insectoid", {"bug": 4, "rock": 2, "ground": 2, "poison": 1}, "insect_head",
|
|
(42, 30), "Round shiny beetle bug with a horn and stubby legs", excludes=["horned"],
|
|
deny=["crystal_spikes", "shell_spiked"]),
|
|
base("base_grub", "insectoid", {"bug": 4, "grass": 3, "poison": 3}, "insect_head",
|
|
(44, 27), "Plump caterpillar with a big happy face and tufted segments",
|
|
deny=["shell_spiked", "coil_spikes"]),
|
|
base("base_bee", "insectoid", {"bug": 4, "flying": 2, "fighting": 2, "electric": 1}, "insect_head",
|
|
(38, 35), "Fuzzy round bee/bug with tiny wings and antennae", excludes=["winged", "antennae"],
|
|
deny=["horns_ram", "horns_dragon", "shell_spiked", "tail_leaf", "tail_stinger", "coil_spikes"]),
|
|
]
|
|
|
|
# --------------------------------------------------------------------------- head_top
|
|
HEAD_TOP = [
|
|
none({"normal": 4, "poison": 2.5, "fighting": 2.5, "water": 2.5, "ghost": 2.5}, 2),
|
|
part("ears_pointed", types={"electric": 4, "normal": 3, "fire": 3, "psychic": 3, "grass": 1.5}, other=0.5,
|
|
requires=MAMMAL + INTEGRATED, tags=["eared"], desc="Pair of tall pointed ears"),
|
|
part("ears_round", types={"normal": 4, "electric": 2, "ground": 2, "ice": 2, "water": 1.5}, other=0.5,
|
|
requires=MAMMAL + INTEGRATED, tags=["eared"], desc="Pair of round mouse/bear ears"),
|
|
part("ears_long", types={"normal": 3, "psychic": 3, "grass": 2, "flying": 1.5, "ice": 1}, other=0.3,
|
|
requires=MAMMAL + INTEGRATED, tags=["eared"], size=(18, 20), z=25, desc="Long rabbit ears (drawn behind the creature)"),
|
|
part("ears_floppy", types={"normal": 4, "water": 2, "ground": 1.5, "grass": 1}, other=0.3,
|
|
requires=MAMMAL + INTEGRATED, tags=["eared"], size=(26, 12), z=25, desc="Droopy hanging ears (drawn behind the creature)"),
|
|
part("ears_bolt", types={"electric": 7}, other=0.05, requires=MAMMAL + INTEGRATED, tags=["eared"],
|
|
desc="Zigzag lightning-bolt ears, type-colored tips"),
|
|
part("ears_fin", types={"water": 5, "ice": 2, "dragon": 1.5}, other=0.1, requires=ANY_FACE,
|
|
tags=["finned", "eared", "_head_fins"], palette="accent", desc="Fin-shaped ear frills"),
|
|
part("horn_single", types={"rock": 3, "ground": 3, "bug": 3, "dragon": 2, "fighting": 2, "poison": 2}, other=0.3,
|
|
requires=NOT_BEAK, tags=["horned"], palette="accent", size=(10, 14), desc="One forehead horn (rhino/beetle)"),
|
|
part("horns_ram", types={"rock": 4, "ground": 4, "fighting": 3, "normal": 1.5}, other=0.2,
|
|
requires=NOT_BEAK, tags=["horned", "_side_horns"], palette="accent", size=(26, 14), desc="Curled ram horns"),
|
|
part("horns_dragon", types={"dragon": 7, "fire": 2, "ghost": 1}, other=0.1,
|
|
requires=NOT_BEAK, tags=["horned"], palette="accent", size=(22, 16), desc="Swept-back dragon horns"),
|
|
part("antennae", types={"bug": 7, "electric": 2, "psychic": 1.5, "poison": 1}, other=0.1,
|
|
requires=["insect_head", "mammal_head", "integrated_head"], tags=["antennae"], size=(16, 16),
|
|
desc="Two thin antennae with tips"),
|
|
part("crest_feather", types={"flying": 6, "fire": 2, "fighting": 1.5, "psychic": 1}, other=0.2,
|
|
requires=["beak_head", "reptile_head"], tags=["feathered"], palette="accent", desc="Swept feather crest"),
|
|
part("crest_flame", types={"fire": 8}, other=0.05, palette="type", desc="Flickering flame on top of head"),
|
|
part("leaf_sprout", types={"grass": 8}, other=0.05, palette="type", size=(14, 14), desc="Leaf/sprout growing from head"),
|
|
part("flower_bloom", types={"grass": 5, "poison": 2, "psychic": 1.5}, other=0.1, palette="accent",
|
|
tags=["floral"], desc="Small flower on head"),
|
|
part("mushroom_cap", types={"poison": 4, "grass": 3, "bug": 2, "ghost": 1}, other=0.05, palette="accent",
|
|
size=(20, 12), desc="Mushroom cap worn like a hat"),
|
|
part("ice_crown", types={"ice": 8}, other=0.05, palette="type", size=(18, 12), desc="Ring of small icicles"),
|
|
part("crystal_spikes", types={"rock": 5, "ice": 3, "psychic": 2}, other=0.05, palette="accent",
|
|
tags=["crystal"], desc="Cluster of crystal shards"),
|
|
part("gem_forehead", types={"psychic": 6, "dragon": 2, "rock": 1.5, "ghost": 1}, other=0.05, palette="accent",
|
|
tags=["gem"], size=(8, 8), desc="Gem set in forehead"),
|
|
part("spiky_hair", types={"fighting": 3, "electric": 3, "poison": 2, "normal": 1, "fire": 1}, other=0.2,
|
|
requires=ANY_FACE, tags=["spiky"], size=(20, 12), desc="Spiky tuft of fur/hair"),
|
|
part("headband", types={"fighting": 6, "normal": 0.5}, other=0.02,
|
|
requires=["mammal_head", "reptile_head", "rock_head", "ghost_head"], tags=["_headband"], palette="accent",
|
|
size=(24, 10),
|
|
desc="Tied headband with trailing ends"),
|
|
part("wisp_flame", types={"ghost": 6, "fire": 1.5, "psychic": 1}, other=0.02, palette="type",
|
|
desc="Ghostly floating flame wisp"),
|
|
part("water_spout", types={"water": 5, "ice": 1}, other=0.02, palette="type", desc="Water droplet/fountain crest"),
|
|
part("cloud_tuft", types={"flying": 3, "electric": 2, "ice": 1.5}, other=0.05, palette="type",
|
|
tags=["fluffy"], size=(20, 12), desc="Puffy cloud tuft"),
|
|
]
|
|
|
|
# (Faces are baked into the base creatures; there are no head, snout or eyes slots.)
|
|
|
|
# --------------------------------------------------------------------------- back
|
|
BACK = [
|
|
none({"normal": 5, "fighting": 4, "water": 3, "electric": 3, "psychic": 3, "poison": 3, "ground": 3,
|
|
"fire": 3, "ghost": 3, "ice": 2.5, "rock": 2, "grass": 2, "dragon": 1.5, "bug": 1, "flying": 0.5}, 2),
|
|
part("wings_feather", ["avian", "biped", "quadruped"],
|
|
{"flying": 8, "fire": 2, "normal": 1.5, "psychic": 1.5, "ice": 1}, 0.3,
|
|
tags=["winged", "feathered"], palette="accent", size=(44, 30), desc="Full feathered wings, spread"),
|
|
part("wings_feather_small", ["avian", "biped", "quadruped", "blob"],
|
|
{"flying": 4, "normal": 2, "ice": 2, "psychic": 1, "water": 1}, 0.3,
|
|
tags=["winged", "feathered"], palette="accent", size=(30, 14), desc="Tiny stubby wings"),
|
|
part("wings_bat", ["biped", "quadruped", "avian", "blob", "serpentine"],
|
|
{"ghost": 4, "poison": 4, "dragon": 2, "flying": 2, "psychic": 1}, 0.1,
|
|
tags=["winged"], palette="accent", size=(44, 26), desc="Membrane bat wings"),
|
|
part("wings_bug", ["insectoid", "biped", "blob"],
|
|
{"bug": 6, "grass": 2, "poison": 2, "psychic": 1.5, "electric": 1}, 0.1,
|
|
tags=["winged"], palette="accent", size=(40, 28), desc="Translucent veined insect wings"),
|
|
part("wings_dragon", ["quadruped", "biped", "serpentine"], {"dragon": 6, "fire": 3, "flying": 2, "rock": 1}, 0.1,
|
|
tags=["winged"], palette="accent", size=(48, 32), desc="Large clawed dragon wings"),
|
|
part("shell_round", ["quadruped", "biped", "aquatic"], {"water": 5, "ground": 3, "rock": 2, "grass": 1}, 0.2,
|
|
tags=["shelled"], palette="accent", size=(40, 26), desc="Domed turtle shell"),
|
|
part("shell_spiked", ["quadruped", "biped", "insectoid"],
|
|
{"rock": 4, "ground": 3, "poison": 2, "water": 2, "fighting": 1}, 0.1,
|
|
tags=["shelled", "spiky"], palette="accent", size=(40, 28), desc="Armored shell with spikes"),
|
|
part("spikes_back", ["quadruped", "biped", "serpentine", "aquatic", "blob"],
|
|
{"ground": 4, "poison": 3, "rock": 3, "dragon": 2, "ice": 2, "fire": 1.5}, 0.2,
|
|
tags=["spiky"], palette="accent", size=(36, 14), desc="Row of spikes along the spine"),
|
|
part("sail_fin", ["quadruped", "biped", "serpentine"], {"fire": 4, "dragon": 3, "water": 2, "electric": 1.5}, 0.1,
|
|
tags=["finned"], palette="accent", size=(34, 20), desc="Tall dimetrodon-style back sail"),
|
|
part("dorsal_fin", ["aquatic", "serpentine", "quadruped"], {"water": 7, "ice": 2, "dragon": 1.5}, 0.05,
|
|
tags=["finned"], palette="accent", size=(20, 16), desc="Shark-style dorsal fin"),
|
|
part("plant_bulb", ["quadruped", "biped", "blob"], {"grass": 6, "poison": 2}, 0.02,
|
|
tags=["leafy"], palette="type", size=(30, 26), desc="Large seed pod/bulb with leaves"),
|
|
part("leaf_cape", ["quadruped", "biped", "serpentine", "insectoid"], {"grass": 6, "bug": 2, "flying": 1}, 0.02,
|
|
tags=["leafy"], palette="type", size=(38, 20), desc="Overlapping leaves along the back"),
|
|
part("flower_back", ["quadruped", "biped", "blob"], {"grass": 5, "poison": 2, "psychic": 1.5}, 0.02,
|
|
tags=["floral"], palette="accent", size=(32, 26), desc="Big blooming flower"),
|
|
part("mushroom_back", ["quadruped", "insectoid", "blob"], {"grass": 3, "poison": 3, "bug": 3, "ghost": 1}, 0.02,
|
|
palette="accent", size=(30, 22), desc="Cluster of mushrooms growing on back"),
|
|
part("flame_mane", LEGGED, {"fire": 8, "dragon": 1}, 0.02,
|
|
tags=["fiery"], palette="type", size=(36, 28), desc="Mane/collar of fire"),
|
|
part("crystal_cluster", ["quadruped", "biped", "blob", "serpentine"], {"rock": 5, "ice": 3, "psychic": 3}, 0.02,
|
|
tags=["crystal"], palette="accent", size=(30, 24), desc="Crystals jutting from back"),
|
|
part("rock_plates", ["quadruped", "biped", "serpentine"], {"rock": 6, "ground": 3, "fighting": 1}, 0.02,
|
|
tags=["armored"], palette="accent", size=(38, 20), desc="Boulder armor plates"),
|
|
part("icicle_spikes", ["quadruped", "biped", "aquatic", "avian", "blob"], {"ice": 8, "water": 1}, 0.02,
|
|
tags=["spiky"], palette="type", size=(29, 24), desc="Tight fan of icicles rising from the back"),
|
|
part("mane_fluffy", LEGGED, {"normal": 4, "fighting": 3, "electric": 2, "fire": 1.5, "ice": 1.5}, 0.2,
|
|
tags=["fluffy"], size=(34, 26), desc="Big fluffy fur collar/mane"),
|
|
part("coil_spikes", ["quadruped", "biped", "blob", "insectoid"], {"electric": 7, "normal": 0.3}, 0.02,
|
|
tags=["electric"], palette="type", size=(26, 24), desc="Chunky coil/battery prongs with a spark"),
|
|
part("cloud_puffs", ["blob", "avian", "quadruped", "serpentine"],
|
|
{"flying": 4, "ice": 2, "psychic": 2, "electric": 1.5, "normal": 1}, 0.05,
|
|
tags=["fluffy"], palette="type", size=(30, 20), desc="Fluffy cloud hugging the back"),
|
|
part("ghost_tatters", ["biped", "blob", "serpentine", "avian"], {"ghost": 6, "psychic": 1, "poison": 1}, 0.02,
|
|
palette="accent", size=(26, 24), desc="Short ghostly shroud draped from the shoulders"),
|
|
]
|
|
|
|
# --------------------------------------------------------------------------- tail
|
|
TAIL = [
|
|
none({"fighting": 3, "bug": 3, "ghost": 3, "psychic": 2, "normal": 2}, 1.5, plans=ALL),
|
|
part("tail_stub", ["quadruped", "biped", "avian"], {"normal": 4, "ground": 2, "ice": 2, "rock": 1.5, "fighting": 1.5}, 0.5,
|
|
tags=["tailed"], size=(10, 10), desc="Short round stub tail"),
|
|
part("tail_fluffy", LEGGED, {"normal": 4, "ice": 3, "electric": 2, "psychic": 2, "fire": 1.5}, 0.4,
|
|
tags=["tailed", "fluffy"], size=(26, 20), desc="Big fluffy fox/squirrel tail"),
|
|
part("tail_long_thin", LEGGED, {"psychic": 3, "normal": 2, "poison": 2, "electric": 2, "ghost": 1}, 0.4,
|
|
tags=["tailed"], size=(30, 12), desc="Long thin tail with tuft"),
|
|
part("tail_curly", LEGGED, {"normal": 3, "psychic": 3, "grass": 1.5, "poison": 1}, 0.3,
|
|
tags=["tailed"], size=(16, 16), desc="Spiral curly tail"),
|
|
part("tail_flame_tip", ["quadruped", "biped", "serpentine"], {"fire": 8}, 0.05,
|
|
tags=["tailed", "fiery"], palette="type", size=(28, 20), desc="Tail ending in a flame"),
|
|
part("tail_lightning", LEGGED, {"electric": 8}, 0.05,
|
|
tags=["tailed"], palette="type", size=(26, 22), desc="Zigzag lightning-bolt tail"),
|
|
part("tail_leaf", ["quadruped", "biped", "insectoid", "serpentine"], {"grass": 7, "bug": 1.5}, 0.05,
|
|
tags=["tailed", "leafy"], palette="type", size=(24, 16), desc="Tail ending in a big leaf"),
|
|
part("tail_fish_fin", ["aquatic", "serpentine", "quadruped", "biped"], {"water": 7, "ice": 2, "dragon": 1.5}, 0.05,
|
|
tags=["tailed", "finned"], palette="accent", size=(22, 22), desc="Forked fish/mermaid tail fin"),
|
|
part("tail_club", LEGGED, {"rock": 5, "ground": 4, "fighting": 1.5}, 0.05,
|
|
tags=["tailed"], size=(28, 16), desc="Heavy club-ended tail"),
|
|
part("tail_spiked", ["quadruped", "biped", "serpentine"],
|
|
{"ground": 3, "rock": 3, "dragon": 3, "poison": 2, "ice": 1.5}, 0.1,
|
|
tags=["tailed", "spiky"], size=(28, 14), desc="Tail with spikes"),
|
|
part("tail_stinger", ["insectoid", "serpentine", "quadruped", "biped"], {"bug": 5, "poison": 5}, 0.05,
|
|
tags=["tailed", "stinger"], palette="accent", size=(22, 18), desc="Curved stinger tail"),
|
|
part("tail_feather_fan", ["avian", "biped"], {"flying": 7, "fire": 2, "psychic": 1.5, "normal": 1}, 0.1,
|
|
tags=["tailed", "feathered"], palette="accent", size=(22, 22), desc="Fanned tail feathers"),
|
|
part("tail_wispy", ["blob", "serpentine", "biped", "avian"], {"ghost": 7, "psychic": 1.5, "fire": 1}, 0.05,
|
|
tags=["tailed"], size=(24, 16), desc="Fading smoky wisp tail"),
|
|
part("tail_ice_shard", ["quadruped", "biped", "aquatic", "serpentine"], {"ice": 8}, 0.05,
|
|
tags=["tailed", "crystal"], palette="type", size=(24, 16), desc="Tail ending in an ice shard"),
|
|
part("tail_dragon", ["quadruped", "biped", "serpentine"], {"dragon": 6, "fire": 2, "ground": 1.5, "water": 1}, 0.1,
|
|
tags=["tailed"], size=(30, 16), desc="Thick tapered tail with small fin"),
|
|
part("tail_rattle", ["serpentine"], {"poison": 4, "ground": 4, "normal": 1}, 0.2,
|
|
tags=["tailed"], palette="accent", size=(14, 12), desc="Rattlesnake rattle tip"),
|
|
part("tail_crystal", ["quadruped", "biped", "serpentine"], {"psychic": 4, "rock": 3, "ice": 2}, 0.05,
|
|
tags=["tailed", "crystal"], palette="accent", size=(24, 16), desc="Tail tipped with a crystal"),
|
|
]
|
|
|
|
# --------------------------------------------------------------------------- aura
|
|
_AURA_SIZE = (84, 84)
|
|
AURA = [
|
|
none(other=8),
|
|
part("aura_embers", types={"fire": 3}, other=0, palette="type", size=_AURA_SIZE, desc="Floating embers"),
|
|
part("aura_sparks", types={"electric": 3}, other=0, palette="type", size=_AURA_SIZE, desc="Crackling sparks"),
|
|
part("aura_bubbles", types={"water": 3, "poison": 0.5}, other=0, palette="type", size=_AURA_SIZE, desc="Rising bubbles"),
|
|
part("aura_leaves", types={"grass": 3, "flying": 0.5, "bug": 0.5}, other=0, palette="type", size=_AURA_SIZE,
|
|
desc="Drifting leaves"),
|
|
part("aura_snowflakes", types={"ice": 3}, other=0, palette="type", size=_AURA_SIZE, desc="Snowflakes"),
|
|
part("aura_wisps", types={"ghost": 3, "psychic": 0.5}, other=0, palette="type", size=_AURA_SIZE, desc="Ghost wisps"),
|
|
part("aura_rings", types={"psychic": 3}, other=0, palette="type", size=_AURA_SIZE, desc="Psychic rings/ripples"),
|
|
part("aura_dust", types={"ground": 3, "rock": 1.5, "fighting": 1}, other=0, palette="type", size=_AURA_SIZE,
|
|
desc="Dust cloud at the feet"),
|
|
part("aura_toxic", types={"poison": 3}, other=0, palette="type", size=_AURA_SIZE, desc="Toxic bubbles and drips"),
|
|
part("aura_sparkle", types={"dragon": 2, "normal": 1, "psychic": 1, "flying": 0.5}, other=0, palette="type",
|
|
size=_AURA_SIZE, desc="Twinkling sparkles"),
|
|
part("aura_gusts", types={"flying": 3, "dragon": 0.5}, other=0, palette="type", size=_AURA_SIZE, desc="Wind swirls"),
|
|
part("aura_pebbles", types={"rock": 3, "ground": 1, "psychic": 0.5}, other=0, palette="type", size=_AURA_SIZE,
|
|
desc="Floating pebbles"),
|
|
part("aura_power", types={"fighting": 3}, other=0, palette="type", size=_AURA_SIZE, desc="Power-up energy lines"),
|
|
part("aura_spores", types={"bug": 2, "grass": 1.5, "poison": 1.5}, other=0, palette="type", size=_AURA_SIZE,
|
|
desc="Floating spores"),
|
|
]
|
|
|
|
SLOTS = {"body": BODY, "back": BACK, "tail": TAIL, "head_top": HEAD_TOP, "aura": AURA}
|