import { DataSource } from 'typeorm'; import { QuestArc } from '../quest/quest-arc.entity'; import { Quest } from '../quest/quest.entity'; import { Achievement } from '../achievement/achievement.entity'; export async function seedQuests(dataSource: DataSource) { const arcRepo = dataSource.getRepository(QuestArc); const questRepo = dataSource.getRepository(Quest); const achievementRepo = dataSource.getRepository(Achievement); // --- Arc 1: Les Marais du Têtard --- let arc = await arcRepo.findOne({ where: { name: 'Les Marais du Têtard' } }); if (!arc) { arc = await arcRepo.save(arcRepo.create({ name: 'Les Marais du Têtard', description: 'Les marais grouillent de créatures hostiles. Nettoyez la zone pour prouver votre valeur.', zone: 'marais', sortOrder: 1, minLevel: 1, })); } // Get monster IDs for targeted quests const monsters = await dataSource.query('SELECT id, name FROM monsters'); const monsterMap = new Map(monsters.map((m: any) => [m.name, m.id])); const materials = await dataSource.query('SELECT id, name FROM materials'); const materialMap = new Map(materials.map((m: any) => [m.name, m.id])); const QUESTS = [ { name: 'Premiers pas', description: 'Éliminez 3 Têtards Vase pour sécuriser les abords du village.', objectiveType: 'kill_monster', objectiveTargetId: monsterMap.get('Têtard Vase') ?? null as string | null, objectiveCount: 3, rewardXp: 100, rewardGold: 30, rewardTitle: null, arcId: arc.id, arcOrder: 1, minLevel: 1, repeatable: false, }, { name: 'Chasseur de grenouilles', description: 'Les Grenouilles Boueuses menacent les récoltes. Abattez-en 5.', objectiveType: 'kill_monster', objectiveTargetId: monsterMap.get('Grenouille Boueuse') ?? null as string | null, objectiveCount: 5, rewardXp: 200, rewardGold: 60, rewardTitle: null, arcId: arc.id, arcOrder: 2, minLevel: 2, repeatable: false, }, { name: 'Apprenti combattant', description: 'Prouvez votre endurance en remportant 10 combats.', objectiveType: 'kill_any', objectiveTargetId: null, objectiveCount: 10, rewardXp: 150, rewardGold: 50, rewardTitle: null, arcId: arc.id, arcOrder: 3, minLevel: 1, repeatable: false, }, { name: 'Le gardien des marais', description: 'Le Golem de Boue terrorise les marais depuis trop longtemps. Mettez fin à son règne.', objectiveType: 'kill_monster', objectiveTargetId: monsterMap.get('Golem de Boue') ?? null as string | null, objectiveCount: 1, rewardXp: 500, rewardGold: 200, rewardTitle: 'Nettoyeur des Marais', arcId: arc.id, arcOrder: 4, minLevel: 5, repeatable: false, }, ]; // Standalone repeatable quests (daily feel) const STANDALONE = [ { name: 'Chasse du jour', description: 'Remportez 5 combats.', objectiveType: 'kill_any', objectiveTargetId: null, objectiveCount: 5, rewardXp: 80, rewardGold: 25, rewardTitle: null, arcId: null, arcOrder: 0, minLevel: 1, repeatable: true, }, { name: 'Apprenti forgeron', description: 'Améliorez un item à la forge.', objectiveType: 'forge_item', objectiveTargetId: null, objectiveCount: 1, rewardXp: 60, rewardGold: 20, rewardTitle: null, arcId: null, arcOrder: 0, minLevel: 1, repeatable: true, }, { name: 'Artisan du jour', description: 'Complétez un craft.', objectiveType: 'craft_item', objectiveTargetId: null, objectiveCount: 1, rewardXp: 50, rewardGold: 15, rewardTitle: null, arcId: null, arcOrder: 0, minLevel: 1, repeatable: true, }, ]; for (const data of [...QUESTS, ...STANDALONE]) { const existing = await questRepo.findOne({ where: { name: data.name } }); if (!existing) { await questRepo.save(questRepo.create(data)); } } // --- Quest achievements --- const QUEST_ACHIEVEMENTS = [ { key: 'quests_5', name: 'Aventurier Curieux', description: 'Compléter 5 quêtes', category: 'progression', tier: 'bronze', criteriaType: 'quests_completed', criteriaValue: 5, rewardGold: 100, rewardTitle: null }, { key: 'quests_25', name: 'Héros du Peuple', description: 'Compléter 25 quêtes', category: 'progression', tier: 'silver', criteriaType: 'quests_completed', criteriaValue: 25, rewardGold: 500, rewardTitle: 'Héros du Peuple' }, { key: 'quests_100', name: 'Légende Quêteuse', description: 'Compléter 100 quêtes', category: 'progression', tier: 'gold', criteriaType: 'quests_completed', criteriaValue: 100, rewardGold: 2000, rewardTitle: 'Légende Quêteuse' }, { key: 'arc_1', name: 'Premier Arc', description: 'Compléter un arc narratif', category: 'progression', tier: 'bronze', criteriaType: 'quest_arc_completed', criteriaValue: 1, rewardGold: 300, rewardTitle: null }, { key: 'arc_3', name: 'Conteur', description: 'Compléter 3 arcs narratifs', category: 'progression', tier: 'silver', criteriaType: 'quest_arc_completed', criteriaValue: 3, rewardGold: 1000, rewardTitle: 'Conteur' }, ]; for (const data of QUEST_ACHIEVEMENTS) { const existing = await achievementRepo.findOne({ where: { key: data.key } }); if (!existing) { await achievementRepo.save(achievementRepo.create(data)); } } console.log(`✅ 1 arc + ${QUESTS.length + STANDALONE.length} quêtes + ${QUEST_ACHIEVEMENTS.length} achievements seedés`); // --- Arc 2: Les Égouts --- let arcEgouts = await arcRepo.findOne({ where: { name: 'Les Égouts de la Cité' } }); if (!arcEgouts) { arcEgouts = await arcRepo.save(arcRepo.create({ name: 'Les Égouts de la Cité', description: 'Les égouts grouillent de créatures répugnantes. Nettoyez ces tunnels oubliés.', zone: 'egouts', sortOrder: 2, minLevel: 4, })); const ratId = monsterMap.get("Rat d'Égout") ?? null as string | null; const crocoId = monsterMap.get('Crocodile') ?? null as string | null; const roiId = monsterMap.get('Roi des Rats') ?? null as string | null; const EGOUTS_QUESTS = [ { name: 'Dératisation', description: 'Les rats pullulent. Éliminez-en 5.', objectiveType: 'kill_monster', objectiveTargetId: ratId, objectiveCount: 5, rewardXp: 200, rewardGold: 80, rewardTitle: null, arcId: arcEgouts.id, arcOrder: 1, minLevel: 4, repeatable: false }, { name: 'Chasseur des profondeurs', description: 'Remportez 15 combats dans les égouts.', objectiveType: 'kill_any', objectiveTargetId: null as string | null, objectiveCount: 15, rewardXp: 300, rewardGold: 120, rewardTitle: null, arcId: arcEgouts.id, arcOrder: 2, minLevel: 5, repeatable: false }, { name: 'Le reptile', description: 'Terrassez 3 Crocodiles qui rôdent dans les canaux.', objectiveType: 'kill_monster', objectiveTargetId: crocoId, objectiveCount: 3, rewardXp: 400, rewardGold: 150, rewardTitle: null, arcId: arcEgouts.id, arcOrder: 3, minLevel: 6, repeatable: false }, { name: 'Le Roi des Rats', description: 'Mettez fin au règne du Roi des Rats.', objectiveType: 'kill_monster', objectiveTargetId: roiId, objectiveCount: 1, rewardXp: 800, rewardGold: 400, rewardTitle: 'Nettoyeur des Égouts', arcId: arcEgouts.id, arcOrder: 4, minLevel: 7, repeatable: false }, ]; for (const q of EGOUTS_QUESTS) { await questRepo.save(questRepo.create(q)); } console.log(`✅ Arc Égouts + ${EGOUTS_QUESTS.length} quêtes seedés`); } // --- Arc 3: Le Désert --- let arcDesert = await arcRepo.findOne({ where: { name: 'Les Sables Brûlants' } }); if (!arcDesert) { arcDesert = await arcRepo.save(arcRepo.create({ name: 'Les Sables Brûlants', description: 'Le désert cache des trésors anciens et des créatures redoutables.', zone: 'desert', sortOrder: 3, minLevel: 8, })); const scorpId = monsterMap.get('Scorpion') ?? null as string | null; const sphinxId = monsterMap.get('Sphinx') ?? null as string | null; const DESERT_QUESTS = [ { name: 'Piqûres mortelles', description: 'Éliminez 5 Scorpions.', objectiveType: 'kill_monster', objectiveTargetId: scorpId, objectiveCount: 5, rewardXp: 400, rewardGold: 150, rewardTitle: null, arcId: arcDesert.id, arcOrder: 1, minLevel: 8, repeatable: false }, { name: 'Survivant du désert', description: 'Remportez 20 combats dans le désert.', objectiveType: 'kill_any', objectiveTargetId: null as string | null, objectiveCount: 20, rewardXp: 600, rewardGold: 250, rewardTitle: null, arcId: arcDesert.id, arcOrder: 2, minLevel: 9, repeatable: false }, { name: 'L\'énigme du Sphinx', description: 'Terrassez le Sphinx — gardien des sables.', objectiveType: 'kill_monster', objectiveTargetId: sphinxId, objectiveCount: 1, rewardXp: 1500, rewardGold: 800, rewardTitle: 'Conquérant du Désert', arcId: arcDesert.id, arcOrder: 3, minLevel: 12, repeatable: false }, ]; for (const q of DESERT_QUESTS) { await questRepo.save(questRepo.create(q)); } console.log(`✅ Arc Désert + ${DESERT_QUESTS.length} quêtes seedés`); } } // Update monster XP rewards (nerf for quest-driven progression) export async function nerfMonsterXp(dataSource: DataSource) { const updates = [ { name: 'Têtard Vase', xpReward: 8 }, { name: 'Grenouille Boueuse', xpReward: 15 }, { name: 'Serpent des Marais', xpReward: 25 }, { name: 'Champi Vénéneux', xpReward: 20 }, { name: 'Golem de Boue', xpReward: 50 }, ]; for (const u of updates) { await dataSource.query('UPDATE monsters SET xp_reward = ? WHERE name = ?', [u.xpReward, u.name]); } console.log('✅ XP monstres ajustée (nerf pour progression par quêtes)'); }