🇸🇮 Kompletna reorganizacija v slovensko strukturo
✅ NAREJENO: - Scan 1,112 PNG datotek - Najdenih 109 duplikatov (preskočenih) - Premaknjenih 635 aktivnih assetov v slovensko strukturo - Izbrisanih 14 starih angleških map - Updatanih 11 scriptov za nove poti 📁 NOVA STRUKTURA: assets/slike/ ├── liki/ (karakterji: Kai, Gronk, Ana, NPCs) ├── sovrazniki/ (zombiji, mutanti, bossi) ├── biomi/ (18 zon) ├── zgradbe/ (vse stavbe in props) ├── predmeti/ (orodja, semena, hrana) ├── orozje/ (hladno, strelno) ├── rastline/ (posevki, drevesa) ├── ui/ (interface elementi) ├── efekti/ (voda, dim) └── cutscene/ (flashbacki) 💡 ADHD-FRIENDLY: - Slovensko poimenovanje - Max 2 nivoja podmap - Logična kategorizacija - Enostavno iskanje
This commit is contained in:
@@ -94,7 +94,7 @@ def main():
|
||||
print("=" * 70)
|
||||
|
||||
# Process demo directory
|
||||
demo_dir = Path('assets/images/demo')
|
||||
demo_dir = Path('assets/slike')
|
||||
total = 0
|
||||
|
||||
if demo_dir.exists():
|
||||
|
||||
@@ -156,7 +156,7 @@ def main():
|
||||
print("=" * 70)
|
||||
|
||||
# Process demo directory
|
||||
demo_dir = Path('assets/images/demo')
|
||||
demo_dir = Path('assets/slike')
|
||||
|
||||
categories = [
|
||||
'terrain', 'crops', 'buildings', 'items',
|
||||
|
||||
393
scripts/complete_reorganization.py
Normal file
393
scripts/complete_reorganization.py
Normal file
@@ -0,0 +1,393 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🇸🇮 KOMPLEKNA REORGANIZACIJA ASSETOV - SLOVENSKO
|
||||
|
||||
1. Scan za duplikate (iste slike)
|
||||
2. Scan za neuporabljene slike
|
||||
3. Premakni vse v slovenske mape
|
||||
4. Izbriši stare angleške mape
|
||||
5. Update vse skripte
|
||||
|
||||
NOVA STRUKTURA (SLOVENSKO):
|
||||
assets/slike/
|
||||
├── liki/ (protagonisti)
|
||||
├── sovrazniki/ (zombiji, mutanti, bossi)
|
||||
├── biomi/ (18 zon)
|
||||
├── zgradbe/ (stavbe)
|
||||
├── predmeti/ (tools, seeds, food)
|
||||
├── orozje/ (weapons)
|
||||
├── rastline/ (crops, trees, plants)
|
||||
├── ui/ (interface)
|
||||
├── efekti/ (effects)
|
||||
└── cutscene/ (flashbacks)
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import shutil
|
||||
import re
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
from typing import Dict, List, Set
|
||||
|
||||
# Paths
|
||||
REPO = Path("/Users/davidkotnik/repos/novafarma")
|
||||
OLD_ASSETS = REPO / "assets/images"
|
||||
NEW_ASSETS = REPO / "assets/slike"
|
||||
SRC_DIR = REPO / "src"
|
||||
|
||||
# Mapping: OLD → NEW
|
||||
MAPPING = {
|
||||
"characters": "liki",
|
||||
"enemies": "sovrazniki",
|
||||
"biomes": "biomi",
|
||||
"buildings": "zgradbe",
|
||||
"items": "predmeti",
|
||||
"weapons": "orozje",
|
||||
"plants": "rastline",
|
||||
"crops": "rastline", # merge crops into rastline
|
||||
"ui": "ui",
|
||||
"effects": "efekti",
|
||||
"cutscenes": "cutscene",
|
||||
"environment": "rastline", # trees, rocks → rastline
|
||||
"props": "zgradbe", # props → zgradbe (campfire, etc)
|
||||
"bosses": "sovrazniki", # bosses → sovrazniki
|
||||
"mutanti": "sovrazniki", # mutanti → sovrazniki
|
||||
"zivali": "rastline", # animals → rastline
|
||||
"npcs": "liki", # npcs → liki
|
||||
"workstations": "zgradbe",
|
||||
}
|
||||
|
||||
class AssetReorganizer:
|
||||
def __init__(self):
|
||||
self.duplicates: Dict[str, List[Path]] = defaultdict(list)
|
||||
self.file_hashes: Dict[str, Path] = {}
|
||||
self.all_pngs: List[Path] = []
|
||||
self.used_assets: Set[str] = set()
|
||||
self.stats = {
|
||||
"total_files": 0,
|
||||
"duplicates": 0,
|
||||
"unused": 0,
|
||||
"migrated": 0,
|
||||
"deleted": 0,
|
||||
}
|
||||
|
||||
def calculate_hash(self, filepath: Path) -> str:
|
||||
"""Calculate MD5 hash of file."""
|
||||
hash_md5 = hashlib.md5()
|
||||
with open(filepath, "rb") as f:
|
||||
for chunk in iter(lambda: f.read(4096), b""):
|
||||
hash_md5.update(chunk)
|
||||
return hash_md5.hexdigest()
|
||||
|
||||
def scan_duplicates(self):
|
||||
"""Find duplicate images by content hash."""
|
||||
print("🔍 Scanning for duplicate images...")
|
||||
|
||||
self.all_pngs = list(OLD_ASSETS.rglob("*.png"))
|
||||
self.stats["total_files"] = len(self.all_pngs)
|
||||
|
||||
print(f" Found {len(self.all_pngs)} PNG files")
|
||||
|
||||
for filepath in self.all_pngs:
|
||||
file_hash = self.calculate_hash(filepath)
|
||||
|
||||
if file_hash in self.file_hashes:
|
||||
# Duplicate found!
|
||||
original = self.file_hashes[file_hash]
|
||||
self.duplicates[file_hash].append(filepath)
|
||||
print(f" 🔴 DUPLICATE: {filepath.name}")
|
||||
print(f" → Same as: {original.name}")
|
||||
else:
|
||||
self.file_hashes[file_hash] = filepath
|
||||
|
||||
print(f"\n ✅ Found {len(self.duplicates)} duplicate groups\n")
|
||||
self.stats["duplicates"] = sum(len(files) for files in self.duplicates.values())
|
||||
|
||||
def scan_code_references(self):
|
||||
"""Scan source code for asset references."""
|
||||
print("🔍 Scanning code for asset usage...")
|
||||
|
||||
# Patterns to match asset references
|
||||
patterns = [
|
||||
r'["\']([^"\']*\.png)["\']', # "filename.png"
|
||||
r'load\.image\(["\']([^"\']+)["\']', # Phaser load.image
|
||||
r'assets/images/([^"\']+\.png)', # Direct path references
|
||||
]
|
||||
|
||||
code_files = list(SRC_DIR.rglob("*.js")) + list(REPO.glob("*.js"))
|
||||
|
||||
for code_file in code_files:
|
||||
try:
|
||||
content = code_file.read_text(encoding='utf-8')
|
||||
for pattern in patterns:
|
||||
matches = re.findall(pattern, content)
|
||||
for match in matches:
|
||||
# Extract just the filename
|
||||
filename = Path(match).name
|
||||
self.used_assets.add(filename)
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Could not read {code_file.name}: {e}")
|
||||
|
||||
print(f" ✅ Found {len(self.used_assets)} referenced assets\n")
|
||||
|
||||
def find_unused(self):
|
||||
"""Find PNG files not referenced in code."""
|
||||
print("🔍 Finding unused assets...")
|
||||
|
||||
unused = []
|
||||
for filepath in self.all_pngs:
|
||||
if filepath.name not in self.used_assets:
|
||||
# Also check without timestamps/suffixes
|
||||
base_name = re.sub(r'_\d{13,}\.png$', '.png', filepath.name)
|
||||
base_name = re.sub(r'_(styleA|styleB|original|sprite|preview)_.*\.png$', '.png', base_name)
|
||||
|
||||
if base_name not in self.used_assets and filepath.name not in self.used_assets:
|
||||
unused.append(filepath)
|
||||
|
||||
self.stats["unused"] = len(unused)
|
||||
print(f" ⚠️ Found {len(unused)} potentially unused files\n")
|
||||
|
||||
return unused
|
||||
|
||||
def create_slovenian_structure(self):
|
||||
"""Create new Slovenian folder structure."""
|
||||
print("📁 Creating Slovenian folder structure...")
|
||||
|
||||
folders = [
|
||||
"liki/kai",
|
||||
"liki/gronk",
|
||||
"liki/ana",
|
||||
"liki/grok",
|
||||
"liki/npcs",
|
||||
"sovrazniki/zombiji",
|
||||
"sovrazniki/mutanti",
|
||||
"sovrazniki/bossi",
|
||||
"biomi/01_dolina_farm",
|
||||
"biomi/02_temni_gozd",
|
||||
"biomi/03_zapusceno_mesto",
|
||||
"zgradbe",
|
||||
"predmeti/orodja",
|
||||
"predmeti/semena",
|
||||
"predmeti/hrana",
|
||||
"orozje/hladno", # melee
|
||||
"orozje/strelno", # ranged
|
||||
"rastline/posevki",
|
||||
"rastline/drevesa",
|
||||
"ui",
|
||||
"efekti/voda",
|
||||
"efekti/dim",
|
||||
"cutscene",
|
||||
]
|
||||
|
||||
for folder in folders:
|
||||
path = NEW_ASSETS / folder
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
print(f" ✅ {folder}/")
|
||||
|
||||
print()
|
||||
|
||||
def migrate_assets(self, delete_duplicates=False, delete_unused=False):
|
||||
"""Migrate all assets to new structure."""
|
||||
print("🚚 Migrating assets to Slovenian structure...")
|
||||
|
||||
# Get list of files to skip (duplicates + unused)
|
||||
skip_files = set()
|
||||
|
||||
if delete_duplicates:
|
||||
for dup_list in self.duplicates.values():
|
||||
# Keep first, delete rest
|
||||
skip_files.update(dup_list)
|
||||
|
||||
if delete_unused:
|
||||
unused = self.find_unused()
|
||||
skip_files.update(unused)
|
||||
|
||||
# Migrate each category
|
||||
for old_name, new_name in MAPPING.items():
|
||||
old_path = OLD_ASSETS / old_name
|
||||
|
||||
if not old_path.exists():
|
||||
continue
|
||||
|
||||
print(f"\n📦 {old_name}/ → {new_name}/")
|
||||
|
||||
# Find all PNGs in this category
|
||||
png_files = list(old_path.rglob("*.png"))
|
||||
|
||||
for src_file in png_files:
|
||||
if src_file in skip_files:
|
||||
print(f" ⏭️ SKIP: {src_file.name} (duplicate/unused)")
|
||||
continue
|
||||
|
||||
# Determine target based on filename
|
||||
target_dir = NEW_ASSETS / new_name
|
||||
|
||||
# Sub-categorization
|
||||
if new_name == "liki":
|
||||
if "kai_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "liki/kai"
|
||||
elif "gronk_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "liki/gronk"
|
||||
elif "ana_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "liki/ana"
|
||||
elif "npc_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "liki/npcs"
|
||||
|
||||
elif new_name == "sovrazniki":
|
||||
if "zombie_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "sovrazniki/zombiji"
|
||||
elif "mutant_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "sovrazniki/mutanti"
|
||||
elif "boss_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "sovrazniki/bossi"
|
||||
|
||||
elif new_name == "rastline":
|
||||
if "wheat_" in src_file.name.lower() or "crop_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "rastline/posevki"
|
||||
elif "tree_" in src_file.name.lower() or "oak_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "rastline/drevesa"
|
||||
|
||||
elif new_name == "predmeti":
|
||||
if "hoe_" in src_file.name.lower() or "axe_" in src_file.name.lower() or "watering" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "predmeti/orodja"
|
||||
elif "seed" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "predmeti/semena"
|
||||
|
||||
elif new_name == "efekti":
|
||||
if "water_" in src_file.name.lower():
|
||||
target_dir = NEW_ASSETS / "efekti/voda"
|
||||
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
dest_file = target_dir / src_file.name
|
||||
|
||||
try:
|
||||
shutil.copy2(src_file, dest_file)
|
||||
print(f" ✅ {src_file.name}")
|
||||
self.stats["migrated"] += 1
|
||||
except Exception as e:
|
||||
print(f" ❌ {src_file.name}: {e}")
|
||||
|
||||
# Also migrate demo/ folder
|
||||
demo_path = OLD_ASSETS / "demo"
|
||||
if demo_path.exists():
|
||||
print(f"\n📦 demo/ → (various Slovenian folders)")
|
||||
self._migrate_demo_folder(demo_path, skip_files)
|
||||
|
||||
def _migrate_demo_folder(self, demo_path: Path, skip_files: Set[Path]):
|
||||
"""Migrate demo folder to appropriate Slovenian locations."""
|
||||
for src_file in demo_path.rglob("*.png"):
|
||||
if src_file in skip_files:
|
||||
continue
|
||||
|
||||
# Classify by filename
|
||||
filename_lower = src_file.name.lower()
|
||||
|
||||
if "kai_" in filename_lower:
|
||||
target = NEW_ASSETS / "liki/kai" / src_file.name
|
||||
elif "zombie_" in filename_lower:
|
||||
target = NEW_ASSETS / "sovrazniki/zombiji" / src_file.name
|
||||
elif "wheat_" in filename_lower:
|
||||
target = NEW_ASSETS / "rastline/posevki" / src_file.name
|
||||
elif "tree_" in filename_lower or "oak_" in filename_lower:
|
||||
target = NEW_ASSETS / "rastline/drevesa" / src_file.name
|
||||
elif "grass_" in filename_lower or "dirt_" in filename_lower or "stone_path" in filename_lower:
|
||||
target = NEW_ASSETS / "biomi/01_dolina_farm" / src_file.name
|
||||
elif "shack" in filename_lower or "barn" in filename_lower or "tent" in filename_lower:
|
||||
target = NEW_ASSETS / "zgradbe" / src_file.name
|
||||
elif "water_anim" in filename_lower:
|
||||
target = NEW_ASSETS / "efekti/voda" / src_file.name
|
||||
elif "ui_" in filename_lower:
|
||||
target = NEW_ASSETS / "ui" / src_file.name
|
||||
else:
|
||||
target = NEW_ASSETS / "ostalo" / src_file.name
|
||||
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
shutil.copy2(src_file, target)
|
||||
print(f" ✅ {src_file.name}")
|
||||
self.stats["migrated"] += 1
|
||||
except Exception as e:
|
||||
print(f" ❌ {src_file.name}: {e}")
|
||||
|
||||
def cleanup_old_folders(self):
|
||||
"""Remove old English folders (after migration)."""
|
||||
print("\n🗑️ Removing old English folders...")
|
||||
|
||||
old_folders = [
|
||||
"characters", "enemies", "buildings", "items", "weapons",
|
||||
"plants", "crops", "environment", "props", "bosses",
|
||||
"mutanti", "zivali", "npcs", "workstations", "demo",
|
||||
"demo_originals_with_white_bg"
|
||||
]
|
||||
|
||||
for folder_name in old_folders:
|
||||
folder_path = OLD_ASSETS / folder_name
|
||||
if folder_path.exists() and folder_path.is_dir():
|
||||
try:
|
||||
shutil.rmtree(folder_path)
|
||||
print(f" 🗑️ Deleted: {folder_name}/")
|
||||
except Exception as e:
|
||||
print(f" ❌ Could not delete {folder_name}/: {e}")
|
||||
|
||||
def generate_report(self):
|
||||
"""Generate final report."""
|
||||
print("\n" + "="*70)
|
||||
print("📊 REORGANIZATION COMPLETE!")
|
||||
print("="*70)
|
||||
print(f" Total files scanned: {self.stats['total_files']:4d}")
|
||||
print(f" Duplicates found: {self.stats['duplicates']:4d}")
|
||||
print(f" Unused files: {self.stats['unused']:4d}")
|
||||
print(f" Files migrated: {self.stats['migrated']:4d}")
|
||||
print("="*70)
|
||||
print("\n✅ Nova struktura: assets/slike/")
|
||||
print(" 📂 liki/")
|
||||
print(" 📂 sovrazniki/")
|
||||
print(" 📂 biomi/")
|
||||
print(" 📂 zgradbe/")
|
||||
print(" 📂 predmeti/")
|
||||
print(" 📂 orozje/")
|
||||
print(" 📂 rastline/")
|
||||
print(" 📂 ui/")
|
||||
print(" 📂 efekti/")
|
||||
print(" 📂 cutscene/")
|
||||
print("="*70)
|
||||
|
||||
def main():
|
||||
print("="*70)
|
||||
print("🇸🇮 KOMPLEKNA REORGANIZACIJA - SLOVENSKO")
|
||||
print("="*70)
|
||||
|
||||
reorganizer = AssetReorganizer()
|
||||
|
||||
# Step 1: Scan duplicates
|
||||
reorganizer.scan_duplicates()
|
||||
|
||||
# Step 2: Scan code
|
||||
reorganizer.scan_code_references()
|
||||
|
||||
# Step 3: Find unused
|
||||
reorganizer.find_unused()
|
||||
|
||||
# Step 4: Create new structure
|
||||
reorganizer.create_slovenian_structure()
|
||||
|
||||
# Step 5: Migrate (with cleanup)
|
||||
reorganizer.migrate_assets(
|
||||
delete_duplicates=True, # Skip duplicates
|
||||
delete_unused=False # Keep unused for now (manual review)
|
||||
)
|
||||
|
||||
# Step 6: Cleanup old folders
|
||||
reorganizer.cleanup_old_folders()
|
||||
|
||||
# Step 7: Report
|
||||
reorganizer.generate_report()
|
||||
|
||||
print("\n📝 NASLEDNJI KORAKI:")
|
||||
print(" 1. git status # Preglej spremembe")
|
||||
print(" 2. Preveri da vse deluje")
|
||||
print(" 3. git add -A && git commit -m '🇸🇮 Reorganizacija v slovensko strukturo'")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
61
scripts/copy_generated_assets.py
Normal file
61
scripts/copy_generated_assets.py
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Copy generated assets from brain folder to proper directories
|
||||
"""
|
||||
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
BRAIN = Path("/Users/davidkotnik/.gemini/antigravity/brain/0170fb0d-72f7-4963-a613-14216b9eae14")
|
||||
BASE = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
||||
|
||||
# Create directories
|
||||
(BASE / "npcs").mkdir(parents=True, exist_ok=True)
|
||||
(BASE / "biomes" / "01_lush_forest").mkdir(parents=True, exist_ok=True)
|
||||
(BASE / "vehicles").mkdir(parents=True, exist_ok=True)
|
||||
(BASE / "bosses").mkdir(parents=True, exist_ok=True)
|
||||
(BASE / "tools").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
stats = {}
|
||||
|
||||
# Copy NPCs
|
||||
npc_files = list(BRAIN.glob("npc_*.png"))
|
||||
for f in npc_files:
|
||||
shutil.copy2(f, BASE / "npcs" / f.name)
|
||||
stats['npcs'] = len(npc_files)
|
||||
|
||||
# Copy Biome #01
|
||||
biome_files = list(BRAIN.glob("biome01_*.png"))
|
||||
for f in biome_files:
|
||||
shutil.copy2(f, BASE / "biomes" / "01_lush_forest" / f.name)
|
||||
stats['biome01'] = len(biome_files)
|
||||
|
||||
# Copy Vehicles
|
||||
vehicle_files = list(BRAIN.glob("vehicle_*.png"))
|
||||
for f in vehicle_files:
|
||||
shutil.copy2(f, BASE / "vehicles" / f.name)
|
||||
stats['vehicles'] = len(vehicle_files)
|
||||
|
||||
# Copy Bosses
|
||||
boss_files = list(BRAIN.glob("boss_*.png"))
|
||||
for f in boss_files:
|
||||
shutil.copy2(f, BASE / "bosses" / f.name)
|
||||
stats['bosses'] = len(boss_files)
|
||||
|
||||
# Copy Tools
|
||||
tool_patterns = ["hoe_*.png", "watering_*.png", "axe_*.png"]
|
||||
tool_count = 0
|
||||
for pattern in tool_patterns:
|
||||
for f in BRAIN.glob(pattern):
|
||||
shutil.copy2(f, BASE / "tools" / f.name)
|
||||
tool_count += 1
|
||||
stats['tools'] = tool_count
|
||||
|
||||
# Print summary
|
||||
print("✅ ASSETS COPIED!")
|
||||
print(f" NPCs: {stats['npcs']} files")
|
||||
print(f" Biome #01: {stats['biome01']} files")
|
||||
print(f" Vehicles: {stats['vehicles']} files")
|
||||
print(f" Bosses: {stats['bosses']} files")
|
||||
print(f" Tools: {stats['tools']} files")
|
||||
print(f"\n📊 TOTAL: {sum(stats.values())} files copied")
|
||||
@@ -168,7 +168,7 @@ def main():
|
||||
print(f" → Ask Antigravity to run:")
|
||||
print(f" generate_image('{building}', '{prompt}')")
|
||||
print(f"\n Then continue with:")
|
||||
print(f" 1. Copy artifact to assets/images/buildings/")
|
||||
print(f" 1. Copy artifact to assets/slike/zgradbe/")
|
||||
print(f" 2. Run background removal")
|
||||
|
||||
# Placeholder - in real usage, Antigravity will generate here
|
||||
|
||||
201
scripts/migrate_demo_to_production.py
Normal file
201
scripts/migrate_demo_to_production.py
Normal file
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🔄 MIGRATE DEMO ASSETS TO PRODUCTION STRUCTURE
|
||||
|
||||
This script moves all assets from:
|
||||
assets/slike/
|
||||
|
||||
To the proper production structure:
|
||||
assets/slike/liki/kai/
|
||||
assets/slike/biomi/01_dolina_farm/
|
||||
assets/slike/sovrazniki/zombies/
|
||||
etc.
|
||||
|
||||
Usage:
|
||||
python3 scripts/migrate_demo_to_production.py [--dry-run]
|
||||
"""
|
||||
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
|
||||
# Base paths
|
||||
REPO_ROOT = Path("/Users/davidkotnik/repos/novafarma")
|
||||
DEMO_DIR = REPO_ROOT / "assets/slike"
|
||||
ASSETS_DIR = REPO_ROOT / "assets/images"
|
||||
|
||||
# Target directories
|
||||
TARGETS = {
|
||||
"characters/kai": ASSETS_DIR / "characters/kai",
|
||||
"biomes/01_dolina_farm/terrain": ASSETS_DIR / "biomes/01_dolina_farm/terrain",
|
||||
"biomes/01_dolina_farm/buildings": ASSETS_DIR / "biomes/01_dolina_farm/buildings",
|
||||
"biomes/01_dolina_farm/props": ASSETS_DIR / "biomes/01_dolina_farm/props",
|
||||
"enemies/zombies": ASSETS_DIR / "enemies/zombies",
|
||||
"effects/water": ASSETS_DIR / "effects/water",
|
||||
"items/tools": ASSETS_DIR / "items/tools",
|
||||
"items/seeds": ASSETS_DIR / "items/seeds",
|
||||
"ui": ASSETS_DIR / "ui",
|
||||
}
|
||||
|
||||
# Asset classification rules
|
||||
RULES = {
|
||||
# Kai (protagonist)
|
||||
"kai_": "characters/kai",
|
||||
|
||||
# Zombies
|
||||
"zombie_": "enemies/zombies",
|
||||
|
||||
# Terrain
|
||||
"grass_": "biomes/01_dolina_farm/terrain",
|
||||
"dirt_": "biomes/01_dolina_farm/terrain",
|
||||
"tilled_": "biomes/01_dolina_farm/terrain",
|
||||
"stone_path": "biomes/01_dolina_farm/terrain",
|
||||
"mud_": "biomes/01_dolina_farm/terrain",
|
||||
|
||||
# Buildings
|
||||
"shack": "biomes/01_dolina_farm/buildings",
|
||||
"barn": "biomes/01_dolina_farm/buildings",
|
||||
"tent": "biomes/01_dolina_farm/buildings",
|
||||
"campfire": "biomes/01_dolina_farm/props",
|
||||
"water_well": "biomes/01_dolina_farm/buildings",
|
||||
"storage_chest": "biomes/01_dolina_farm/props",
|
||||
|
||||
# Props/Environment
|
||||
"tree_": "biomes/01_dolina_farm/props",
|
||||
"oak_tree": "biomes/01_dolina_farm/props",
|
||||
"rock_": "biomes/01_dolina_farm/props",
|
||||
"bush_": "biomes/01_dolina_farm/props",
|
||||
"fence_": "biomes/01_dolina_farm/props",
|
||||
"sign_": "biomes/01_dolina_farm/props",
|
||||
|
||||
# Effects
|
||||
"water_anim": "effects/water",
|
||||
"smoke_": "effects/particles",
|
||||
|
||||
# Items
|
||||
"hoe_": "items/tools",
|
||||
"axe_": "items/tools",
|
||||
"pickaxe_": "items/tools",
|
||||
"watering_can": "items/tools",
|
||||
"wheat_seed": "items/seeds",
|
||||
"potato_seed": "items/seeds",
|
||||
"corn_seed": "items/seeds",
|
||||
|
||||
# UI
|
||||
"ui_": "ui",
|
||||
}
|
||||
|
||||
def classify_asset(filename: str) -> str:
|
||||
"""Determine where an asset should go based on its name."""
|
||||
for pattern, target in RULES.items():
|
||||
if pattern in filename.lower():
|
||||
return target
|
||||
|
||||
# Default: keep in current subfolder structure
|
||||
return None
|
||||
|
||||
def scan_demo_folder():
|
||||
"""Scan demo folder and classify all assets."""
|
||||
migrations = defaultdict(list)
|
||||
|
||||
for filepath in DEMO_DIR.rglob("*.png"):
|
||||
# Skip if it's in a nested preview/original folder
|
||||
if "preview" in filepath.parts or "original" in filepath.parts:
|
||||
continue
|
||||
|
||||
relative_to_demo = filepath.relative_to(DEMO_DIR)
|
||||
target_category = classify_asset(filepath.name)
|
||||
|
||||
if target_category:
|
||||
migrations[target_category].append(filepath)
|
||||
else:
|
||||
# Keep the subfolder structure (characters/, buildings/, etc.)
|
||||
subfolder = relative_to_demo.parts[0] if len(relative_to_demo.parts) > 1 else "misc"
|
||||
migrations[subfolder].append(filepath)
|
||||
|
||||
return migrations
|
||||
|
||||
def create_target_directories():
|
||||
"""Ensure all target directories exist."""
|
||||
for target_path in TARGETS.values():
|
||||
target_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Additional specific directories
|
||||
(ASSETS_DIR / "effects/particles").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def migrate_assets(migrations, dry_run=False):
|
||||
"""Move assets to their target locations."""
|
||||
stats = defaultdict(int)
|
||||
|
||||
for category, files in migrations.items():
|
||||
target_dir = TARGETS.get(category)
|
||||
|
||||
if not target_dir:
|
||||
# Use direct category as subdirectory
|
||||
target_dir = ASSETS_DIR / category
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"\n📁 {category}/ ({len(files)} files)")
|
||||
|
||||
for src_file in files:
|
||||
dest_file = target_dir / src_file.name
|
||||
|
||||
if dry_run:
|
||||
print(f" [DRY RUN] {src_file.name} → {target_dir.name}/")
|
||||
else:
|
||||
try:
|
||||
shutil.move(str(src_file), str(dest_file))
|
||||
print(f" ✅ {src_file.name}")
|
||||
stats[category] += 1
|
||||
except Exception as e:
|
||||
print(f" ❌ {src_file.name}: {e}")
|
||||
|
||||
return stats
|
||||
|
||||
def main():
|
||||
dry_run = "--dry-run" in sys.argv
|
||||
|
||||
print("═" * 70)
|
||||
print("🔄 DEMO → PRODUCTION ASSET MIGRATION")
|
||||
print("═" * 70)
|
||||
|
||||
if dry_run:
|
||||
print("⚠️ DRY RUN MODE - No files will be moved\n")
|
||||
|
||||
# Step 1: Scan
|
||||
print("📊 Scanning demo folder...")
|
||||
migrations = scan_demo_folder()
|
||||
|
||||
# Step 2: Create directories
|
||||
print("\n📁 Creating target directories...")
|
||||
create_target_directories()
|
||||
|
||||
# Step 3: Migrate
|
||||
print("\n🚚 Migrating assets...")
|
||||
stats = migrate_assets(migrations, dry_run=dry_run)
|
||||
|
||||
# Summary
|
||||
print("\n" + "═" * 70)
|
||||
print("📊 MIGRATION SUMMARY")
|
||||
print("═" * 70)
|
||||
|
||||
total = sum(stats.values())
|
||||
for category, count in sorted(stats.items()):
|
||||
print(f" {category:40s} {count:3d} files")
|
||||
|
||||
print("─" * 70)
|
||||
print(f" {'TOTAL':40s} {total:3d} files")
|
||||
print("═" * 70)
|
||||
|
||||
if dry_run:
|
||||
print("\n💡 Run without --dry-run to perform the migration")
|
||||
else:
|
||||
print("\n✅ Migration complete!")
|
||||
print("\n📝 Next steps:")
|
||||
print(" 1. Review the changes: git status")
|
||||
print(" 2. Test the game to ensure assets load correctly")
|
||||
print(" 3. Commit the reorganization: git add -A && git commit -m '🗂️ Migrate demo assets to production structure'")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -11,7 +11,7 @@ import shutil
|
||||
def rename_and_organize_demo():
|
||||
"""Organize demo assets into subfolders with clean names"""
|
||||
|
||||
demo_base = Path("assets/images/demo")
|
||||
demo_base = Path("assets/slike")
|
||||
|
||||
categories = {
|
||||
'characters': demo_base / 'characters',
|
||||
|
||||
@@ -66,7 +66,7 @@ if __name__ == "__main__":
|
||||
print("Usage: python3 remove_background.py <image_or_directory>")
|
||||
print("\nExamples:")
|
||||
print(" python3 remove_background.py image.png")
|
||||
print(" python3 remove_background.py assets/images/buildings/")
|
||||
print(" python3 remove_background.py assets/slike/zgradbe/")
|
||||
print(" python3 remove_background.py assets/images/ --recursive")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ def main():
|
||||
print("🗂️ ASSET REORGANIZATION: SUBFOLDERS WITH ORIGINALS + RESIZED")
|
||||
print("=" * 70)
|
||||
|
||||
demo_dir = Path('assets/images/demo')
|
||||
demo_dir = Path('assets/slike')
|
||||
print(f"\n📦 Processing: {demo_dir}")
|
||||
|
||||
total = 0
|
||||
|
||||
@@ -98,7 +98,7 @@ def main():
|
||||
print("=" * 60)
|
||||
|
||||
# Resize transparent assets
|
||||
demo_dir = Path('assets/images/demo')
|
||||
demo_dir = Path('assets/slike')
|
||||
print(f"\n📦 TRANSPARENT ASSETS: {demo_dir}")
|
||||
|
||||
total = 0
|
||||
@@ -110,7 +110,7 @@ def main():
|
||||
total += resize_category(demo_dir, 'environment')
|
||||
|
||||
# Resize white background originals
|
||||
orig_dir = Path('assets/images/demo_originals_with_white_bg')
|
||||
orig_dir = Path('assets/slike_originals_with_white_bg')
|
||||
if orig_dir.exists():
|
||||
print(f"\n📦 WHITE BG ORIGINALS: {orig_dir}")
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ def main():
|
||||
print("🎮 RESIZING TO PROPER INDIE GAME SIZES (32×32 STANDARD)")
|
||||
print("=" * 60)
|
||||
|
||||
demo_dir = Path('assets/images/demo')
|
||||
demo_dir = Path('assets/slike')
|
||||
print(f"\n📦 Transparent assets: {demo_dir}")
|
||||
|
||||
total = 0
|
||||
@@ -100,7 +100,7 @@ def main():
|
||||
|
||||
total += resize_category(demo_dir, 'environment')
|
||||
|
||||
orig_dir = Path('assets/images/demo_originals_with_white_bg')
|
||||
orig_dir = Path('assets/slike_originals_with_white_bg')
|
||||
if orig_dir.exists():
|
||||
print(f"\n📦 White BG originals: {orig_dir}")
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ def main():
|
||||
print("📏 TILE-ALIGNED RESIZE & RENAME (Multiples of 32px)")
|
||||
print("=" * 70)
|
||||
|
||||
demo_dir = Path('assets/images/demo')
|
||||
demo_dir = Path('assets/slike')
|
||||
print(f"\n📦 Processing: {demo_dir}")
|
||||
|
||||
total = 0
|
||||
@@ -142,7 +142,7 @@ def main():
|
||||
total += process_category(demo_dir, 'environment')
|
||||
|
||||
# White BG originals
|
||||
orig_dir = Path('assets/images/demo_originals_with_white_bg')
|
||||
orig_dir = Path('assets/slike_originals_with_white_bg')
|
||||
if orig_dir.exists():
|
||||
print(f"\n📦 Processing: {orig_dir}")
|
||||
|
||||
|
||||
80
scripts/update_paths_to_slovenian.py
Normal file
80
scripts/update_paths_to_slovenian.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Update all scripts to use new Slovenian paths
|
||||
|
||||
Old: assets/slike/liki/kai/
|
||||
New: assets/slike/liki/kai/
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path("/Users/davidkotnik/repos/novafarma")
|
||||
|
||||
# Path mappings
|
||||
REPLACEMENTS = {
|
||||
r'assets/slike/liki': 'assets/slike/liki',
|
||||
r'assets/slike/sovrazniki': 'assets/slike/sovrazniki',
|
||||
r'assets/slike/zgradbe': 'assets/slike/zgradbe',
|
||||
r'assets/slike/predmeti': 'assets/slike/predmeti',
|
||||
r'assets/slike/orozje': 'assets/slike/orozje',
|
||||
r'assets/slike/rastline/posevki': 'assets/slike/rastline/posevki',
|
||||
r'assets/slike/rastline': 'assets/slike/rastline',
|
||||
r'assets/slike/rastline': 'assets/slike/rastline',
|
||||
r'assets/slike/zgradbe': 'assets/slike/zgradbe',
|
||||
r'assets/slike/biomi': 'assets/slike/biomi',
|
||||
r'assets/slike/ui': 'assets/slike/ui',
|
||||
r'assets/slike/efekti': 'assets/slike/efekti',
|
||||
r'assets/slike/cutscene': 'assets/slike/cutscene',
|
||||
r'assets/slike': 'assets/slike',
|
||||
r'assets/slike/sovrazniki/bossi': 'assets/slike/sovrazniki/bossi',
|
||||
r'assets/slike/sovrazniki/mutanti': 'assets/slike/sovrazniki/mutanti',
|
||||
r'assets/slike/rastline': 'assets/slike/rastline',
|
||||
r'assets/slike/liki/npcs': 'assets/slike/liki/npcs',
|
||||
}
|
||||
|
||||
def update_file(filepath: Path):
|
||||
"""Update a single file with new paths."""
|
||||
try:
|
||||
content = filepath.read_text(encoding='utf-8')
|
||||
original = content
|
||||
|
||||
for old_path, new_path in REPLACEMENTS.items():
|
||||
content = re.sub(old_path, new_path, content)
|
||||
|
||||
if content != original:
|
||||
filepath.write_text(content, encoding='utf-8')
|
||||
print(f"✅ Updated: {filepath.name}")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"❌ Error updating {filepath.name}: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
print("🔧 Updating all scripts to use Slovenian paths...\n")
|
||||
|
||||
# Update JavaScript files
|
||||
js_files = list(REPO.glob("src/**/*.js")) + list(REPO.glob("*.js"))
|
||||
|
||||
updated_count = 0
|
||||
for js_file in js_files:
|
||||
if update_file(js_file):
|
||||
updated_count += 1
|
||||
|
||||
# Update Python scripts
|
||||
py_files = list(REPO.glob("scripts/**/*.py"))
|
||||
for py_file in py_files:
|
||||
if update_file(py_file):
|
||||
updated_count += 1
|
||||
|
||||
# Update Tiled maps
|
||||
tmx_files = list(REPO.glob("maps/**/*.tmx"))
|
||||
for tmx_file in tmx_files:
|
||||
if update_file(tmx_file):
|
||||
updated_count += 1
|
||||
|
||||
print(f"\n✅ Updated {updated_count} files to use Slovenian structure!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user