166 lines
7.5 KiB
Python
166 lines
7.5 KiB
Python
"""
|
||
Orman düşmanları — 12 çeşit hostile NPC (2026-07-08).
|
||
|
||
NPC sayfasının yazdığı `npcs` tablosuna eklenir (stance='hostile').
|
||
Yer = forest region'larına (map_tags kind='region' category='forest', O-1..O-10)
|
||
round-robin dağıtılır. İsim'e göre idempotent (varsa günceller, yoksa ekler).
|
||
|
||
Çalıştırma:
|
||
cd /opt/stepstead && ./venv/bin/python3 db/seed_enemies_forest.py
|
||
"""
|
||
import asyncio
|
||
import sys
|
||
|
||
sys.path.insert(0, "/opt/stepstead")
|
||
|
||
import asyncpg # noqa: E402
|
||
from config import settings # noqa: E402
|
||
|
||
|
||
def desc(hp, dmg, atk, dc, weak, drops, danger, lore):
|
||
"""Özellikleri okunur bir description bloğuna paketle."""
|
||
return (
|
||
f"{lore}\n\n"
|
||
f"⚔ Saldırı türü: {atk}\n"
|
||
f"❤ Can (HP): {hp}\n"
|
||
f"🗡 Hasar: {dmg}\n"
|
||
f"🎯 Savaş zorluğu (combat DC): {dc}\n"
|
||
f"💀 Tehlike: {danger}\n"
|
||
f"🩹 Zayıflık: {weak}\n"
|
||
f"🎁 Düşürdükleri: {drops}"
|
||
)
|
||
|
||
|
||
# (name, role, stance, description)
|
||
ENEMIES = [
|
||
("Mana Solucanı", "Büyülü Yaratık", "hostile",
|
||
desc(hp=18, dmg="4-8 (mana yakımı)", atk="Büyü — mana emer",
|
||
dc=13, weak="Fiziksel darbe, demir silah",
|
||
drops="Mana özü ×1-2, parlak salgı",
|
||
danger="Orta",
|
||
lore="Yeraltı mana damarlarında beslenen, ışıldayan segmentli bir solucan. "
|
||
"Yaklaşana enerjisini emer; öldürüldüğünde içindeki saf mana damlar.")),
|
||
|
||
("Aç Kurt", "Canavar", "hostile",
|
||
desc(hp=22, dmg="6-10 (ısırık)", atk="Yakın dövüş — sürü halinde",
|
||
dc=13, weak="Ateş, yüksek zemin",
|
||
drops="Kurt eti ×1-2, kurt derisi ×1",
|
||
danger="Orta",
|
||
lore="Kışın açlıktan gözü dönmüş orman kurdu. Tek başına ürkek ama "
|
||
"sürüye katılınca korkusuzca saldırır.")),
|
||
|
||
("Yaşlı Ağaç Adam", "Bitki Devi", "hostile",
|
||
desc(hp=55, dmg="12-18 (dal savurma)", atk="Yakın dövüş — ağır ve yavaş",
|
||
dc=16, weak="Ateş, balta (woodcutting)",
|
||
drops="Kadim odun ×2-3, canlı kök, meşe palamudu",
|
||
danger="Yüksek",
|
||
lore="Yüzyıllık bir meşenin uyanmış ruhu. Toprağı sarsan adımlarla yürür; "
|
||
"yavaştır ama tek darbesi kemik kırar. Ateşten ölesiye korkar.")),
|
||
|
||
("Dev Orman Faresi", "Haşere", "hostile",
|
||
desc(hp=8, dmg="2-4 (kemirme)", atk="Yakın dövüş — kalabalık",
|
||
dc=9, weak="Hemen her şey",
|
||
drops="Fare kuyruğu, paslı çöp, bazen 1-3 gold",
|
||
danger="Düşük",
|
||
lore="İnsan boyunun yarısı kadar, hastalık taşıyan bir kemirgen. Tek başına "
|
||
"zararsız ama erzak çuvalını bir gecede boşaltır.")),
|
||
|
||
("Zehirli Orman Örümceği", "Haşere", "hostile",
|
||
desc(hp=16, dmg="5-9 (zehirli ısırık)", atk="Yakın dövüş — zehir + ağ",
|
||
dc=14, weak="Ateş, alan silahları",
|
||
drops="Örümcek zehri ×1, ipek ×1-2",
|
||
danger="Orta",
|
||
lore="Karanlık kovuklara dev ağlar geren, avını zehirle felç eden bir örümcek. "
|
||
"Ağı hareketi yavaşlatır, ısırığı damarlarda yanar.")),
|
||
|
||
("Sarmaşık Cini", "Bitki Ruhu", "hostile",
|
||
desc(hp=24, dmg="6-11 (sarma + diken)", atk="Yakın dövüş — kavrayıp sıkar",
|
||
dc=14, weak="Ateş, kesici balta",
|
||
drops="Canlı sarmaşık ×2, diken tozu, çiçek özü",
|
||
danger="Orta",
|
||
lore="Küçük ama sinsi bir bitki ruhu. Yaprakların arasına gizlenir, "
|
||
"geçeni sarmaşıklarıyla sarıp dikenlerine çeker.")),
|
||
|
||
("Mantar Spor Yaratığı", "Sporlu Canavar", "hostile",
|
||
desc(hp=20, dmg="4-7 (spor bulutu)", atk="Alan — zehirli spor patlaması",
|
||
dc=13, weak="Ateş, uzak menzil",
|
||
drops="Işıldayan mantar ×2, spor tozu, şifa mantarı",
|
||
danger="Orta",
|
||
lore="Yürüyen dev bir mantar kümesi. Vurulunca zehirli spor bulutu patlatır; "
|
||
"yakın dövüşte nefes almak tehlikelidir.")),
|
||
|
||
("Gölge Kurdu (Alfa)", "Canavar (Elit)", "hostile",
|
||
desc(hp=40, dmg="10-16 (gölge pençesi)", atk="Yakın dövüş — hızlı, görünmez sıçrar",
|
||
dc=17, weak="Işık, gümüş silah",
|
||
drops="Gölge postu ×1, alfa dişi, gümüş ore ×1",
|
||
danger="Yüksek",
|
||
lore="Karanlık ormanın en yaşlı kurt sürüsünün lideri. Gölgelerde erir, "
|
||
"arkandan belirir. Işık tuttuğunda bir an donar — tek fırsatın odur.")),
|
||
|
||
("Orman Haydutu", "Goblin", "hostile",
|
||
desc(hp=26, dmg="7-12 (paslı hançer)", atk="Yakın dövüş — pusu + hırsızlık",
|
||
dc=14, weak="Cephesel saldırı, gürültü",
|
||
drops="Çalıntı kese (5-20 gold), paslı hançer, kuru erzak",
|
||
danger="Orta",
|
||
lore="Yol kenarında pusu kuran sinsi bir goblin. Önce keseni çalmaya çalışır, "
|
||
"başaramazsa hançerine sarılır.")),
|
||
|
||
("Kanlı Yarasa", "Uçan Haşere", "hostile",
|
||
desc(hp=12, dmg="3-6 (kan emme)", atk="Havadan — dalış + kan emer",
|
||
dc=11, weak="Ateş, geniş savurma",
|
||
drops="Yarasa kanadı ×1-2, kan kesesi",
|
||
danger="Düşük",
|
||
lore="Mağara ağızlarında ve yaşlı ağaç kovuklarında asılı duran kan emici. "
|
||
"Sürü halinde daldığında kanını damla damla çeker.")),
|
||
|
||
("Bataklık Sülüğü", "Asalak", "hostile",
|
||
desc(hp=14, dmg="3-7 (yapışıp emer)", atk="Yakın dövüş — yapışır, sürekli hasar",
|
||
dc=12, weak="Tuz, ateş",
|
||
drops="Sülük özü, iyileştirici salgı ×1",
|
||
danger="Düşük-Orta",
|
||
lore="Ormanın nemli bataklık kıyısında saklanan dev sülük. Bacağına yapışır, "
|
||
"koparana dek yavaşça kan emer. Salgısı ilginç şekilde şifalıdır.")),
|
||
|
||
("Lanetli Karga Sürüsü", "Uçan Sürü", "hostile",
|
||
desc(hp=30, dmg="5-9 (gaga yağmuru)", atk="Alan — sürü halinde gözlere dalış",
|
||
dc=15, weak="Alan silahları, ateş, ses",
|
||
drops="Kara tüy ×3, lanetli boncuk, bazen gümüş ore",
|
||
danger="Orta-Yüksek",
|
||
lore="Tek bir kötü ruhu paylaşan bir karga sürüsü. Ayrı ayrı zayıf ama "
|
||
"birlikte gökten kara bir bulut gibi iner, gözleri hedef alır.")),
|
||
]
|
||
|
||
|
||
async def main():
|
||
dsn = settings.DATABASE_URL.replace("+asyncpg", "")
|
||
c = await asyncpg.connect(dsn)
|
||
|
||
forests = [r["id"] for r in await c.fetch(
|
||
"SELECT id FROM map_tags WHERE kind='region' AND category='forest' ORDER BY id"
|
||
)]
|
||
if not forests:
|
||
print("UYARI: forest region bulunamadı, map_tag_id NULL bırakılıyor.")
|
||
|
||
added = updated = 0
|
||
for i, (name, role, stance, description) in enumerate(ENEMIES):
|
||
tag = forests[i % len(forests)] if forests else None
|
||
existing = await c.fetchval("SELECT id FROM npcs WHERE name=$1", name)
|
||
if existing:
|
||
await c.execute(
|
||
"UPDATE npcs SET role=$2, stance=$3, description=$4, map_tag_id=$5, "
|
||
"updated_at=now() WHERE id=$1",
|
||
existing, role, stance, description, tag)
|
||
updated += 1
|
||
else:
|
||
await c.execute(
|
||
"INSERT INTO npcs(name,role,stance,description,map_tag_id) "
|
||
"VALUES($1,$2,$3,$4,$5)",
|
||
name, role, stance, description, tag)
|
||
added += 1
|
||
|
||
total = await c.fetchval("SELECT count(*) FROM npcs WHERE stance='hostile'")
|
||
print(f"Eklendi: {added}, güncellendi: {updated}. Toplam hostile NPC: {total}")
|
||
await c.close()
|
||
|
||
|
||
asyncio.run(main())
|