244 lines
12 KiB
Python
244 lines
12 KiB
Python
"""
|
||
250 örnek craftable üretir: item + tarif. Idempotent (code üzerinden ON CONFLICT DO NOTHING).
|
||
Gruplar: Kerestecilik, Marangozluk, Okçuluk, Metalurji, Demircilik, Kuyumculuk,
|
||
Simya, Aşçılık, Dericilik, Balıkçılık.
|
||
Çalıştırma: cd /opt/stepstead && ./venv/bin/python3 db/seed_craftables.py
|
||
"""
|
||
import asyncio
|
||
import json
|
||
import sys
|
||
|
||
import asyncpg
|
||
|
||
sys.path.insert(0, "/opt/stepstead")
|
||
from config import settings
|
||
|
||
DSN = settings.DATABASE_URL.replace("postgresql+asyncpg://", "postgresql://")
|
||
|
||
# (kod, Türkçe ad, tier)
|
||
WOODS = [
|
||
("oak", "Meşe", 1), ("pine", "Çam", 2), ("birch", "Huş", 3), ("beech", "Kayın", 4),
|
||
("maple", "Akçaağaç", 5), ("willow", "Söğüt", 6), ("ash", "Dişbudak", 7), ("cedar", "Sedir", 8),
|
||
("walnut", "Ceviz", 9), ("cherry", "Kiraz", 10), ("yew", "Porsuk", 11),
|
||
("mahogany", "Maun", 12), ("ebony", "Abanoz", 13),
|
||
]
|
||
METALS = [
|
||
("copper", "Bakır", 1), ("bronze", "Bronz", 2), ("iron", "Demir", 3),
|
||
("steel", "Çelik", 4), ("silver", "Gümüş", 5), ("gold", "Altın", 6),
|
||
]
|
||
HERBS = [
|
||
("mint", "Nane", 1), ("sage", "Adaçayı", 2), ("thyme", "Kekik", 3), ("chamomile", "Papatya", 4),
|
||
("rosemary", "Biberiye", 5), ("basil", "Fesleğen", 6), ("nettle", "Isırgan", 7),
|
||
("lemonbalm", "Melisa", 8), ("fennel", "Rezene", 9), ("lavender", "Lavanta", 10),
|
||
("ginseng", "Ginseng", 11), ("saffron", "Safran", 12),
|
||
]
|
||
FISH = [
|
||
("carp", "Sazan", 1), ("perch", "Levrek", 2), ("anchovy", "Hamsi", 3), ("mullet", "Kefal", 4),
|
||
("mackerel", "Uskumru", 5), ("bonito", "Palamut", 6), ("bluefish", "Lüfer", 7),
|
||
("bream", "Çipura", 8), ("trout", "Alabalık", 9), ("pike", "Turna", 10),
|
||
("catfish", "Yayın", 11), ("salmon", "Somon", 12), ("turbot", "Kalkan", 13),
|
||
("tuna", "Ton Balığı", 14), ("sturgeon", "Mersin", 15),
|
||
]
|
||
ANIMALS = [
|
||
("rabbit", "Tavşan", 1), ("deer", "Geyik", 2), ("boar", "Yaban Domuzu", 3),
|
||
("wolf", "Kurt", 4), ("bear", "Ayı", 5),
|
||
]
|
||
|
||
FURNITURE = [("chair", "Sandalye", 3), ("table", "Masa", 4), ("bed", "Yatak", 6),
|
||
("cabinet", "Dolap", 5), ("door", "Kapı", 4), ("chest", "Sandık", 5)] # (kod, ad, kereste)
|
||
WEAPONS = [("axe", "Balta"), ("pickaxe", "Kazma"), ("sword", "Kılıç"),
|
||
("dagger", "Hançer"), ("shield", "Kalkan"), ("armor", "Zırh")]
|
||
JEWELRY = [("ring", "Yüzük"), ("necklace", "Kolye"), ("bracelet", "Bilezik")]
|
||
LEATHERGOODS = [("bag", "Çanta"), ("belt", "Kemer"), ("boots", "Bot"), ("gloves", "Eldiven")]
|
||
|
||
|
||
def rarity_for(tier: int, max_tier: int) -> str:
|
||
r = tier / max_tier
|
||
if r <= 0.25:
|
||
return "common"
|
||
if r <= 0.5:
|
||
return "uncommon"
|
||
if r <= 0.75:
|
||
return "rare"
|
||
if r < 1.0:
|
||
return "epic"
|
||
return "legendary"
|
||
|
||
|
||
items: list[dict] = [] # {code,name,type,rarity,stack_max,description,effect}
|
||
recipes: list[dict] = [] # {code,name,out,out_qty,skill,level,xp,steps,ings}
|
||
|
||
|
||
def add_item(code, name, typ, rarity="common", stack=99, desc=None, effect=None):
|
||
items.append({"code": code, "name": name, "type": typ, "rarity": rarity,
|
||
"stack": stack, "desc": desc, "effect": effect})
|
||
|
||
|
||
def add_recipe(code, name, out, skill, level, xp, steps, ings, out_qty=1):
|
||
recipes.append({"code": code, "name": name, "out": out, "out_qty": out_qty,
|
||
"skill": skill, "level": min(level, 50), "xp": xp, "steps": steps,
|
||
"ings": [{"item_code": c, "qty": q} for c, q in ings]})
|
||
|
||
|
||
def build():
|
||
# --- Ham maddeler ---
|
||
for w, tr, t in WOODS:
|
||
add_item(f"log_{w}", f"{tr} Odunu", "material", rarity_for(t, 13))
|
||
for m, tr, t in METALS:
|
||
if m in ("bronze", "steel"):
|
||
pass # cevheri yok, alaşım
|
||
else:
|
||
add_item(f"ore_{m}", f"{tr} Cevheri", "material", rarity_for(t, 6))
|
||
add_item(f"ingot_{m}", f"{tr} Külçe", "material", rarity_for(t, 6))
|
||
add_item("ore_tin", "Kalay Cevheri", "material", "common")
|
||
add_item("coal", "Kömür", "material", "common")
|
||
for h, tr, t in HERBS:
|
||
add_item(f"herb_{h}", f"{tr}", "material", rarity_for(t, 12))
|
||
for f, tr, t in FISH:
|
||
add_item(f"fish_{f}", f"{tr}", "material", rarity_for(t, 15))
|
||
for a, tr, t in ANIMALS:
|
||
add_item(f"leather_{a}", f"{tr} Derisi", "material", rarity_for(t, 5))
|
||
add_item(f"meat_{a}", f"{tr} Eti", "material", rarity_for(t, 5))
|
||
|
||
# --- 1) Kerestecilik: 13 kereste ---
|
||
for w, tr, t in WOODS:
|
||
add_item(f"plank_{w}", f"{tr} Kereste", "material", rarity_for(t, 13))
|
||
add_recipe(f"saw_{w}", f"{tr} Kereste", f"plank_{w}", "woodcutting",
|
||
max(1, t * 3 - 2), 4 + 2 * t, 2 + t, [(f"log_{w}", 2)], out_qty=2)
|
||
|
||
# --- 2) Marangozluk: 13 odun × 6 mobilya = 78 ---
|
||
for w, wtr, t in WOODS:
|
||
for fc, ftr, planks in FURNITURE:
|
||
add_item(f"{fc}_{w}", f"{wtr} {ftr}", "furniture", rarity_for(t, 13), stack=10)
|
||
add_recipe(f"build_{fc}_{w}", f"{wtr} {ftr}", f"{fc}_{w}", "construction",
|
||
max(1, t * 3 - 2), 8 + 3 * t, 4 + t + planks, [(f"plank_{w}", planks)])
|
||
|
||
# --- 3) Okçuluk: 13 yay + 13 ok = 26 ---
|
||
for w, wtr, t in WOODS:
|
||
add_item(f"bow_{w}", f"{wtr} Yay", "tool", rarity_for(t, 13), stack=1)
|
||
add_recipe(f"craft_bow_{w}", f"{wtr} Yay", f"bow_{w}", "combat",
|
||
max(1, t * 3 - 2), 10 + 3 * t, 6 + t, [(f"plank_{w}", 2), ("vine", 1)])
|
||
add_item(f"arrow_{w}", f"{wtr} Ok", "material", rarity_for(t, 13))
|
||
add_recipe(f"craft_arrow_{w}", f"{wtr} Ok (10)", f"arrow_{w}", "combat",
|
||
max(1, t * 3 - 2), 5 + 2 * t, 3 + t, [(f"plank_{w}", 1), ("stone_small", 1)], out_qty=10)
|
||
|
||
# --- 4) Metalurji: 4 yeni külçe (bakır+demir eritme zaten var) ---
|
||
add_recipe("smelt_bronze", "Bronz Külçe", "ingot_bronze", "smithing", 4, 12, 5,
|
||
[("ore_copper", 1), ("ore_tin", 1)])
|
||
add_recipe("smelt_steel", "Çelik Külçe", "ingot_steel", "smithing", 10, 18, 6,
|
||
[("ore_iron", 2), ("coal", 1)])
|
||
add_recipe("smelt_silver", "Gümüş Külçe", "ingot_silver", "smithing", 15, 22, 7, [("ore_silver", 2)])
|
||
add_recipe("smelt_gold", "Altın Külçe", "ingot_gold", "smithing", 20, 28, 8, [("ore_gold", 2)])
|
||
|
||
# --- 5) Demircilik: 6 metal × 6 = 36, bakır balta+kazma mevcut → 34 ---
|
||
for m, mtr, t in METALS:
|
||
for wc, wtr in WEAPONS:
|
||
if m == "copper" and wc in ("axe", "pickaxe"):
|
||
continue # craft_axe_cu / craft_pick_cu zaten var
|
||
code = f"{wc}_{m}"
|
||
typ = "tool" if wc in ("axe", "pickaxe") else "gear"
|
||
add_item(code, f"{mtr} {wtr}", typ, rarity_for(t, 6), stack=1)
|
||
n_ingot = 3 if wc in ("shield", "armor") else 2
|
||
add_recipe(f"forge_{wc}_{m}", f"{mtr} {wtr}", code, "smithing",
|
||
max(1, t * 5 - 3), 10 + 5 * t, 6 + 2 * t,
|
||
[(f"ingot_{m}", n_ingot), ("log_oak", 1)])
|
||
|
||
# --- 6) Kuyumculuk: gümüş+altın × 3 takı = 6 ---
|
||
for m, mtr, t in [("silver", "Gümüş", 5), ("gold", "Altın", 6)]:
|
||
for jc, jtr in JEWELRY:
|
||
add_item(f"{jc}_{m}", f"{mtr} {jtr}", "gear", rarity_for(t, 6), stack=1)
|
||
add_recipe(f"jewel_{jc}_{m}", f"{mtr} {jtr}", f"{jc}_{m}", "smithing",
|
||
t * 5, 15 + 4 * t, 8, [(f"ingot_{m}", 1)])
|
||
|
||
# --- 7) Simya: 12 ot × 3 = 36, nane çayı mevcut → 35 ---
|
||
for h, htr, t in HERBS:
|
||
if h != "mint": # brew_tea_mint zaten var
|
||
add_item(f"tea_{h}", f"{htr} Çayı", "consumable", rarity_for(t, 12),
|
||
desc=f"Adım bakiyesini +{40 + 5 * t} yeniler.",
|
||
effect={"type": "steps", "amount": 40 + 5 * t})
|
||
add_recipe(f"brew_tea_{h}", f"{htr} Çayı", f"tea_{h}", "alchemy",
|
||
max(1, t * 4 - 3), 6 + 2 * t, 4, [(f"herb_{h}", 2)])
|
||
add_item(f"potion_{h}", f"{htr} İksiri", "consumable", rarity_for(t, 12),
|
||
desc=f"Adım bakiyesini +{80 + 10 * t} yeniler.",
|
||
effect={"type": "steps", "amount": 80 + 10 * t})
|
||
add_recipe(f"brew_potion_{h}", f"{htr} İksiri", f"potion_{h}", "alchemy",
|
||
min(50, t * 4), 12 + 3 * t, 6, [(f"herb_{h}", 3), ("vine", 1)])
|
||
add_item(f"salve_{h}", f"{htr} Merhemi", "consumable", rarity_for(t, 12),
|
||
desc="İyileştirici merhem (gelecek özellik).")
|
||
add_recipe(f"brew_salve_{h}", f"{htr} Merhemi", f"salve_{h}", "alchemy",
|
||
min(50, t * 4 + 1), 10 + 3 * t, 5, [(f"herb_{h}", 2), ("stone_small", 1)])
|
||
|
||
# --- 8) Aşçılık: 14 balık (sazan mevcut) + 5 et × 3 = 29 ---
|
||
for f, ftr, t in FISH:
|
||
if f == "carp":
|
||
continue # cook_carp zaten var
|
||
add_item(f"cooked_{f}", f"Izgara {ftr}", "consumable", rarity_for(t, 15),
|
||
desc=f"Adım bakiyesini +{25 + 3 * t} yeniler.",
|
||
effect={"type": "steps", "amount": 25 + 3 * t})
|
||
add_recipe(f"cook_{f}", f"Izgara {ftr}", f"cooked_{f}", "cooking",
|
||
max(1, t * 3 - 2), 6 + 2 * t, 4, [(f"fish_{f}", 1)])
|
||
for a, atr, t in ANIMALS:
|
||
for mc, mtr, bonus in [("grilled", "Izgara", 30), ("stew", "Güveç", 50), ("dried", "Kurutulmuş", 40)]:
|
||
add_item(f"{mc}_{a}", f"{mtr} {atr} Eti", "consumable", rarity_for(t, 5),
|
||
desc=f"Adım bakiyesini +{bonus + 8 * t} yeniler.",
|
||
effect={"type": "steps", "amount": bonus + 8 * t})
|
||
ings = [(f"meat_{a}", 1)] if mc != "stew" else [(f"meat_{a}", 1), ("herb_mint", 1)]
|
||
add_recipe(f"cook_{mc}_{a}", f"{mtr} {atr} Eti", f"{mc}_{a}", "cooking",
|
||
min(50, t * 6), 8 + 4 * t, 5, ings)
|
||
|
||
# --- 9) Dericilik: 5 deri × 4 = 20 ---
|
||
for a, atr, t in ANIMALS:
|
||
for lc, ltr in LEATHERGOODS:
|
||
add_item(f"{lc}_{a}", f"{atr} Derisi {ltr}", "gear", rarity_for(t, 5), stack=1)
|
||
add_recipe(f"tailor_{lc}_{a}", f"{atr} Derisi {ltr}", f"{lc}_{a}", "hunting",
|
||
min(50, t * 7 - 4), 10 + 5 * t, 6 + t, [(f"leather_{a}", 2), ("vine", 1)])
|
||
|
||
# --- 10) Balıkçılık: 2 gelişmiş olta ---
|
||
add_item("fishing_rod_fine", "Usta Oltası", "tool", "rare", stack=1)
|
||
add_recipe("craft_rod_fine", "Usta Oltası", "fishing_rod_fine", "fishing", 10, 25, 8,
|
||
[("plank_willow", 2), ("vine", 2)])
|
||
add_item("fishing_rod_master", "Efsane Olta", "tool", "epic", stack=1)
|
||
add_recipe("craft_rod_master", "Efsane Olta", "fishing_rod_master", "fishing", 25, 50, 12,
|
||
[("plank_yew", 2), ("vine", 3), ("ingot_silver", 1)])
|
||
|
||
# --- 11) İnşaat ekstra: 3 ---
|
||
add_item("campfire", "Kamp Ateşi", "furniture", "common", stack=10)
|
||
add_recipe("build_campfire", "Kamp Ateşi", "campfire", "construction", 1, 8, 5,
|
||
[("stick", 3), ("stone_small", 2)])
|
||
add_item("fence", "Çit", "furniture", "common", stack=50)
|
||
add_recipe("build_fence", "Çit", "fence", "construction", 2, 6, 4, [("plank_pine", 1), ("vine", 1)])
|
||
add_item("sign", "Tabela", "furniture", "common", stack=20)
|
||
add_recipe("build_sign", "Tabela", "sign", "construction", 1, 5, 3, [("plank_oak", 1), ("stick", 1)])
|
||
|
||
|
||
async def main():
|
||
build()
|
||
print(f"Üretilen: {len(recipes)} tarif, {len(items)} item tanımı")
|
||
assert len(recipes) == 250, f"250 bekleniyor, {len(recipes)} üretildi"
|
||
|
||
conn = await asyncpg.connect(DSN)
|
||
ins_i = 0
|
||
for it in items:
|
||
r = await conn.execute("""
|
||
INSERT INTO items (code, name, type, rarity, stack_max, description, effect)
|
||
VALUES ($1,$2,$3,$4,$5,$6,$7) ON CONFLICT (code) DO NOTHING
|
||
""", it["code"], it["name"], it["type"], it["rarity"], it["stack"],
|
||
it["desc"], json.dumps(it["effect"]) if it["effect"] else None)
|
||
ins_i += int(r.endswith("1"))
|
||
ins_r = 0
|
||
for rc in recipes:
|
||
r = await conn.execute("""
|
||
INSERT INTO recipes (code, name, output_item_id, output_qty, skill, required_level,
|
||
xp_reward, step_cost, ingredients)
|
||
SELECT $1,$2,i.id,$3,$4,$5,$6,$7,$8::jsonb FROM items i WHERE i.code=$9
|
||
ON CONFLICT (code) DO NOTHING
|
||
""", rc["code"], rc["name"], rc["out_qty"], rc["skill"], rc["level"],
|
||
rc["xp"], rc["steps"], json.dumps(rc["ings"]), rc["out"])
|
||
ins_r += int(r.endswith("1"))
|
||
ti = await conn.fetchval("SELECT count(*) FROM items")
|
||
tr = await conn.fetchval("SELECT count(*) FROM recipes")
|
||
await conn.close()
|
||
print(f"DB'ye eklendi: {ins_i} item, {ins_r} tarif. Toplam: {ti} item, {tr} tarif.")
|
||
|
||
|
||
asyncio.run(main())
|