🚀 Blueprint System, Dark Chibi Animals & Massive Reference Organization
FEATURES: ✅ Blueprint System: Auto-generated ghost/hologram items for building mode ✅ ItemManager: Logic for Item/Blueprint switching ✅ New Animals: Cow, Pig, Bear, Wolf (Dark Noir Chibi Style) ORGANIZATION: ✅ Flattened Reference Library: All 6k+ images in 'glavna_referenca' for easy review ✅ Cleanup: Empty 'ZA_PREGLED' and '_NESORTIRANO' sorted ✅ Unlocked: 'glavna_referenca' ready for manual editing STATUS: Ready for DEMO assembly!
This commit is contained in:
76
scripts/flatten_references.py
Normal file
76
scripts/flatten_references.py
Normal file
@@ -0,0 +1,76 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
ROOT_DIR = os.path.abspath("assets/slike/glavna_referenca")
|
||||
|
||||
def flatten_folder():
|
||||
if not os.path.exists(ROOT_DIR):
|
||||
print("❌ Folder not found!")
|
||||
return
|
||||
|
||||
print(f"🚜 Flattening {ROOT_DIR}...")
|
||||
|
||||
moved_count = 0
|
||||
|
||||
# Walk bottom-up to handle subdirs
|
||||
for root, dirs, files in os.walk(ROOT_DIR, topdown=False):
|
||||
if root == ROOT_DIR:
|
||||
continue # Skip root folder itself
|
||||
|
||||
for file in files:
|
||||
if file.startswith("."): continue
|
||||
|
||||
src_path = os.path.join(root, file)
|
||||
dest_path = os.path.join(ROOT_DIR, file)
|
||||
|
||||
# Handle duplicate names
|
||||
if os.path.exists(dest_path):
|
||||
base, ext = os.path.splitext(file)
|
||||
counter = 1
|
||||
while os.path.exists(os.path.join(ROOT_DIR, f"{base}_{counter}{ext}")):
|
||||
counter += 1
|
||||
dest_path = os.path.join(ROOT_DIR, f"{base}_{counter}{ext}")
|
||||
|
||||
try:
|
||||
shutil.move(src_path, dest_path)
|
||||
moved_count += 1
|
||||
except Exception as e:
|
||||
print(f"❌ Error moving {file}: {e}")
|
||||
|
||||
# Remove empty dir
|
||||
try:
|
||||
if not os.listdir(root):
|
||||
os.rmdir(root)
|
||||
# print(f"🗑️ Removed empty dir: {root}")
|
||||
except:
|
||||
pass
|
||||
|
||||
print(f"✨ DONE! Moved {moved_count} images to root.")
|
||||
|
||||
# 2. Add New Animals (Steampunk + Dark Chibi)
|
||||
print("🎨 Importing generated animals...")
|
||||
EXT_SRCS = [
|
||||
"assets/slike/animals/generated_steampunk",
|
||||
"assets/slike/animals/generated_dark_chibi" # If exists
|
||||
]
|
||||
|
||||
imported = 0
|
||||
for ext_src in EXT_SRCS:
|
||||
if os.path.exists(ext_src):
|
||||
for file in os.listdir(ext_src):
|
||||
if file.startswith("."): continue
|
||||
|
||||
src = os.path.join(ext_src, file)
|
||||
dest = os.path.join(ROOT_DIR, file)
|
||||
|
||||
if os.path.exists(dest):
|
||||
base, ext = os.path.splitext(file)
|
||||
dest = os.path.join(ROOT_DIR, f"{base}_NEW{ext}")
|
||||
|
||||
shutil.copy(src, dest)
|
||||
imported += 1
|
||||
|
||||
print(f"✅ Imported {imported} new animals.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
flatten_folder()
|
||||
83
scripts/generate_blueprints.py
Normal file
83
scripts/generate_blueprints.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import os
|
||||
from PIL import Image, ImageEnhance
|
||||
|
||||
# Konfiguracija
|
||||
SOURCE_DIR = os.path.abspath("assets/slike/items")
|
||||
DEST_DIR = os.path.abspath("assets/slike/items/blueprints")
|
||||
|
||||
# Prezri te mape in datoteke
|
||||
IGNORE_DIRS = {'blueprints', '.DS_Store'}
|
||||
EXTENSIONS = {'.png', '.jpg', '.jpeg'}
|
||||
|
||||
def create_blueprint_effect(image_path, save_path):
|
||||
try:
|
||||
img = Image.open(image_path).convert("RGBA")
|
||||
|
||||
# 1. Naredi sliko prosojno (Ghost effect)
|
||||
# Split channels
|
||||
r, g, b, a = img.split()
|
||||
|
||||
# Zmanjšaj alpha kanal (prosojnost na 60%)
|
||||
# Opcija: Lahko bi uporabil constante, ampak point() je hiter
|
||||
a = a.point(lambda p: p * 0.6)
|
||||
|
||||
# 2. Dodaj modrikast tint (Hologram effect)
|
||||
# Povečaj Blue kanal, zmanjšaj Red in Green
|
||||
r = r.point(lambda p: p * 0.5) # Temnejši
|
||||
g = g.point(lambda p: p * 0.7) # Srednji
|
||||
b = b.point(lambda p: min(p * 1.5, 255)) # Svetlejši modri
|
||||
|
||||
# Združi nazaj
|
||||
ghost_img = Image.merge("RGBA", (r, g, b, a))
|
||||
|
||||
# Shrani
|
||||
ghost_img.save(save_path, "PNG")
|
||||
print(f"👻 Created blueprint: {os.path.basename(save_path)}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ Error processing {image_path}: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
if not os.path.exists(DEST_DIR):
|
||||
os.makedirs(DEST_DIR)
|
||||
|
||||
print(f"🔍 Scanning {SOURCE_DIR} for items...")
|
||||
|
||||
count = 0
|
||||
|
||||
for root, dirs, files in os.walk(SOURCE_DIR):
|
||||
# Preskoči samo mapo blueprints da ne delamo blueprintov iz blueprintov
|
||||
if 'blueprints' in root:
|
||||
continue
|
||||
|
||||
for file in files:
|
||||
if any(file.lower().endswith(ext) for ext in EXTENSIONS):
|
||||
# Izračunaj relativno pot (npr. tools/axe.png)
|
||||
rel_path = os.path.relpath(root, SOURCE_DIR)
|
||||
|
||||
# Ciljna mapa (ohrani strukturo, npr. blueprints/tools/)
|
||||
if rel_path == ".":
|
||||
target_subdir = DEST_DIR
|
||||
else:
|
||||
target_subdir = os.path.join(DEST_DIR, rel_path)
|
||||
|
||||
if not os.path.exists(target_subdir):
|
||||
os.makedirs(target_subdir)
|
||||
|
||||
source_file = os.path.join(root, file)
|
||||
dest_file = os.path.join(target_subdir, file)
|
||||
|
||||
# Ustvari blueprint če še ne obstaja
|
||||
if not os.path.exists(dest_file):
|
||||
create_blueprint_effect(source_file, dest_file)
|
||||
count += 1
|
||||
else:
|
||||
# Opcija: Preveri timestamp če je original novejši?
|
||||
# Zaenkrat samo preskočimo obstoječe.
|
||||
pass
|
||||
|
||||
print(f"✨ DONE! Created {count} new blueprints.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
82
scripts/organize_nesortirano_final.py
Normal file
82
scripts/organize_nesortirano_final.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
SOURCE_DIR = os.path.abspath("assets/slike/glavna_referenca/_NESORTIRANO")
|
||||
DEST_BASE = os.path.abspath("assets/slike/glavna_referenca")
|
||||
|
||||
RULES = {
|
||||
# DINOSAURS -> Dino Valley
|
||||
"dinosaurs": "biomes/10_dino_valley/enemies",
|
||||
"trex": "biomes/10_dino_valley/boss",
|
||||
"raptor": "biomes/10_dino_valley/enemies",
|
||||
"triceratops": "biomes/10_dino_valley/enemies",
|
||||
|
||||
# CHERNOBYL
|
||||
"Chernobyl": "biomes/20_chernobyl", # Script will check for 'props', 'building' keywords
|
||||
"radioactive": "biomes/09_radioactive/terrain",
|
||||
|
||||
# ARCTIC
|
||||
"Arctic": "biomes/06_snow",
|
||||
|
||||
# Other Biomes based on keywords
|
||||
"desert": "biomes/04_desert",
|
||||
"swamp": "biomes/03_swamp",
|
||||
"forest": "biomes/02_forest",
|
||||
"jungle": "biomes/16_amazon_rainforest",
|
||||
"amazon": "biomes/16_amazon_rainforest",
|
||||
"egypt": "biomes/15_egyptian_desert",
|
||||
"mexic": "biomes/18_mexican_cenotes",
|
||||
"witch": "biomes/19_witch_forest",
|
||||
"atlantis": "biomes/17_atlantis",
|
||||
|
||||
# Common Items
|
||||
"potion": "items/consumables",
|
||||
"tool": "items/tools",
|
||||
"weapon": "items/weapons",
|
||||
|
||||
# Susi (Just in case some are left)
|
||||
"susi": "characters/susi",
|
||||
}
|
||||
|
||||
def organize():
|
||||
if not os.path.exists(SOURCE_DIR):
|
||||
print("❌ NESORTIRANO map not found")
|
||||
return
|
||||
|
||||
print("📦 Organizing NESORTIRANO...")
|
||||
count = 0
|
||||
|
||||
for filename in os.listdir(SOURCE_DIR):
|
||||
if filename.startswith("."): continue
|
||||
|
||||
src_path = os.path.join(SOURCE_DIR, filename)
|
||||
lower_name = filename.lower()
|
||||
dest_subdir = None
|
||||
|
||||
# 1. SPECIAL LOGIC FOR CHERNOBYL PROPS
|
||||
if "chernobyl" in lower_name and "props" in lower_name:
|
||||
dest_subdir = "biomes/20_chernobyl/items"
|
||||
elif "chernobyl" in lower_name:
|
||||
dest_subdir = "biomes/20_chernobyl/buildings"
|
||||
|
||||
# 2. General Rules
|
||||
if not dest_subdir:
|
||||
for keyword, path in RULES.items():
|
||||
if keyword.lower() in lower_name:
|
||||
dest_subdir = path
|
||||
break
|
||||
|
||||
# 3. Move it
|
||||
if dest_subdir:
|
||||
full_dest_dir = os.path.join(DEST_BASE, dest_subdir)
|
||||
if not os.path.exists(full_dest_dir):
|
||||
os.makedirs(full_dest_dir)
|
||||
|
||||
shutil.move(src_path, os.path.join(full_dest_dir, filename))
|
||||
count += 1
|
||||
if count % 50 == 0: print(f"Moved {count} files...")
|
||||
|
||||
print(f"✅ Finished! Organized {count} files from NESORTIRANO.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
organize()
|
||||
145
scripts/organize_za_pregled.py
Normal file
145
scripts/organize_za_pregled.py
Normal file
@@ -0,0 +1,145 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
SOURCE_DIR = os.path.abspath("assets/slike/ZA_PREGLED")
|
||||
DEST_BASE = os.path.abspath("assets/slike/glavna_referenca")
|
||||
|
||||
# Mapping rules: Keyword -> Destination Subfolder
|
||||
RULES = {
|
||||
# Characters
|
||||
"kai": "characters/kai",
|
||||
"ana": "characters/ana",
|
||||
"gronk": "characters/gronk",
|
||||
"susi": "characters/susi",
|
||||
"zombie": "characters/enemies",
|
||||
"boss": "biomes/bosses", # General boss folder or specifics
|
||||
"druid": "characters/npc/magical",
|
||||
"priest": "characters/npc/magical",
|
||||
"witch": "characters/npc/magical",
|
||||
"baker": "characters/npc/town",
|
||||
"blacksmith": "characters/npc/town",
|
||||
"trader": "characters/npc/town",
|
||||
"merchant": "characters/npc/town",
|
||||
"fisherman": "characters/npc/town",
|
||||
"scientist": "characters/npc/special",
|
||||
"guide": "characters/npc/special",
|
||||
"hunter": "characters/npc/special",
|
||||
"chief": "characters/npc/special",
|
||||
"pharaoh": "characters/npc/special",
|
||||
"stalker": "characters/npc/special",
|
||||
|
||||
# Animals
|
||||
"cow": "animals/farm",
|
||||
"pig": "animals/farm",
|
||||
"chicken": "animals/farm",
|
||||
"sheep": "animals/farm",
|
||||
"goat": "animals/farm",
|
||||
"horse": "animals/farm",
|
||||
"wolf": "animals/wild",
|
||||
"bear": "animals/wild",
|
||||
"fox": "animals/wild",
|
||||
"deer": "animals/wild",
|
||||
"rabbit": "animals/wild",
|
||||
"bird": "animals/wild",
|
||||
|
||||
# Biomes/Environment
|
||||
"tree": "biomes/02_forest/vegetation", # Default placement, user can refine
|
||||
"grass": "biomes/01_grassland/terrain",
|
||||
"rock": "environment/narava",
|
||||
"stone": "environment/narava",
|
||||
"water": "environment/narava",
|
||||
"desert": "biomes/04_desert",
|
||||
"swamp": "biomes/03_swamp",
|
||||
"snow": "biomes/06_snow",
|
||||
"volcan": "biomes/05_mountain", # Or volcanic biome
|
||||
|
||||
# Items
|
||||
"tool": "items/tools",
|
||||
"weapon": "items/weapons",
|
||||
"food": "items/food",
|
||||
"seed": "items/farming/seeds",
|
||||
"crop": "items/farming/crops",
|
||||
"potion": "items/consumables",
|
||||
"book": "items/special",
|
||||
"key": "items/special",
|
||||
|
||||
# Buildings
|
||||
"house": "buildings/town",
|
||||
"shop": "buildings/town",
|
||||
"hut": "buildings/wild",
|
||||
"tent": "buildings/camping",
|
||||
"ruin": "buildings/ruins",
|
||||
"wall": "buildings/structures",
|
||||
|
||||
# UI
|
||||
"icon": "ui/icons",
|
||||
"button": "ui/buttons",
|
||||
"panel": "ui/panels",
|
||||
"menu": "ui/menus",
|
||||
}
|
||||
|
||||
def organize_za_pregled():
|
||||
if not os.path.exists(SOURCE_DIR):
|
||||
print("❌ Source directory not found!")
|
||||
return
|
||||
|
||||
print("🔓 Unlocking destination folder just in case...")
|
||||
os.system(f"chmod -R u+w {DEST_BASE}")
|
||||
|
||||
print(f"📦 Organizing {SOURCE_DIR}...")
|
||||
|
||||
moved_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
files = [f for f in os.listdir(SOURCE_DIR) if os.path.isfile(os.path.join(SOURCE_DIR, f))]
|
||||
|
||||
for filename in files:
|
||||
if filename.startswith("."): continue # Skip hidden files
|
||||
|
||||
src_path = os.path.join(SOURCE_DIR, filename)
|
||||
lower_name = filename.lower()
|
||||
|
||||
destination = None
|
||||
|
||||
# Check rules
|
||||
for keyword, relative_dest in RULES.items():
|
||||
if keyword in lower_name:
|
||||
destination = os.path.join(DEST_BASE, relative_dest)
|
||||
break
|
||||
|
||||
# Default fallback if no rule matches but looks like something
|
||||
if not destination:
|
||||
if "anim" in lower_name:
|
||||
destination = os.path.join(DEST_BASE, "_NESORTIRANO/animations")
|
||||
elif ".png" in lower_name or ".jpg" in lower_name:
|
||||
destination = os.path.join(DEST_BASE, "_NESORTIRANO/images")
|
||||
else:
|
||||
destination = os.path.join(DEST_BASE, "_NESORTIRANO/other")
|
||||
|
||||
# Move file
|
||||
if destination:
|
||||
if not os.path.exists(destination):
|
||||
os.makedirs(destination)
|
||||
|
||||
try:
|
||||
dest_path = os.path.join(destination, filename)
|
||||
# Handle duplicates
|
||||
if os.path.exists(dest_path):
|
||||
base, ext = os.path.splitext(filename)
|
||||
dest_path = os.path.join(destination, f"{base}_COPY{ext}")
|
||||
|
||||
shutil.move(src_path, dest_path)
|
||||
moved_count += 1
|
||||
if moved_count % 100 == 0:
|
||||
print(f" Moved {moved_count} files...")
|
||||
except Exception as e:
|
||||
print(f"❌ Error moving {filename}: {e}")
|
||||
skipped_count += 1
|
||||
else:
|
||||
skipped_count += 1
|
||||
|
||||
print(f"✨ DONE! Moved {moved_count} files. Skipped {skipped_count}.")
|
||||
print("🔒 Don't forget to lock the folder again if needed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
organize_za_pregled()
|
||||
Reference in New Issue
Block a user