GuildTycoon/Assets/_/Features/Tests/Runtime/AutoQuestFlow.cs

246 lines
9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Adventurer.Runtime;
using Core.Runtime;
using EventSystem.Runtime;
using Player.Runtime;
using Quest.Runtime;
using Quests.Runtime;
using UnityEngine;
namespace TestFacts.Runtime
{
/// <summary>
/// Script de démonstration simple qui enchaîne automatiquement 3 actions avec Invoke:
/// 1) Recruter un héros
/// 2) Afficher une quête (ouvrir le panneau d'info)
/// 3) Valider la quête (la terminer)
///
/// Ajoutez ce composant sur un GameObject de la scène, puis assignez les références nécessaires dans l'inspecteur.
/// </summary>
public class AutoQuestFlow : BaseMonoBehaviour
{
[Header("Références (facultatives mais recommandées)")]
[Tooltip("Permet de générer un aventurier pour le recrutement.")]
[SerializeField] AdventurerFactorySO _adventurerFactory;
[Tooltip("Base de données des quêtes pour en choisir une.")]
[SerializeField] QuestFactoryDatabase _questDatabase;
[Header("Délais (en secondes)")]
[SerializeField] float _delayRecruit = 0.5f;
[SerializeField] float _delayShowQuest = 1.0f;
[SerializeField] float _delayValidate = 1.0f;
[Header("Options")]
[Tooltip("Niveau du joueur utilisé pour filtrer les quêtes disponibles si non présent dans les Facts.")]
[SerializeField] int _fallbackGuildLevel = 1;
List<AdventurerClass> _myTeam = new List<AdventurerClass>();
void Start()
{
// Enchaînement via Invoke
Invoke(nameof(Step_RecruitHero), _delayRecruit);
}
// 1) Recruter un héros
void Step_RecruitHero()
{
try
{
var player = EnsurePlayerFact();
var myAdventurers = EnsureMyAdventurersFact();
AdventurerClass recruit = null;
if (_adventurerFactory != null)
{
recruit = _adventurerFactory.CreateAdventurer();
}
else
{
// Fallback très simple si aucune factory n'est fournie
recruit = new AdventurerClass(
Guid.NewGuid(),
"Auto Recruit",
AdventurerClassEnum.Warrior,
1, 0,
10, 10, 8, 8,
new Dictionary<string, string>(),
DateTime.Now);
}
// Simule l'achat: on ajoute à la liste et on met à jour le profil
myAdventurers.Add(recruit);
player.AdventurersCount = Mathf.Max(player.AdventurersCount, myAdventurers.Count);
// Notifie les systèmes existants
AdventurerSignals.RaiseSpawnRequested(recruit);
AdventurerSignals.RaiseRefreshAdventurers();
Info($"✅ Recrutement effectué: {recruit.Name}", Color.green);
SaveFacts();
}
catch (Exception ex)
{
Debug.LogError($"[AutoQuestFlow] Erreur lors du recrutement: {ex}");
}
// Étape suivante via Invoke
Invoke(nameof(Step_ShowQuest), _delayShowQuest);
}
// 2) Afficher une quête (ouvrir le panneau d'info)
void Step_ShowQuest()
{
try
{
var player = EnsurePlayerFact();
// Récupère une quête disponible
var quest = GetAnyAvailableQuest(player.GuildLevel);
if (quest == null)
{
Warning("Aucune quête disponible trouvée.");
return;
}
// Accepter la quête et la sauvegarder
quest.State = QuestStateEnum.Accepted;
var accepted = EnsureAcceptedQuestsFact();
if (!accepted.Any(q => q.ID == quest.ID))
{
accepted.Add(quest);
}
SaveFacts();
// Sélectionne comme quête courante et ouvre le panneau d'info via les signaux existants
QuestManager.Instance.CurrentQuest = quest;
QuestSignals.RaiseRefreshQuests();
QuestSignals.RaiseInfoQuestPanel(quest);
Info($"📜 Quête affichée: {quest.Name} (état: {quest.State})", Color.cyan);
}
catch (Exception ex)
{
Debug.LogError($"[AutoQuestFlow] Erreur lors de l'affichage de la quête: {ex}");
}
// Étape suivante via Invoke
Invoke(nameof(Step_ValidateQuest), _delayValidate);
}
// 3) Valider la quête (la terminer)
void Step_ValidateQuest()
{
try
{
var quest = QuestManager.Instance.CurrentQuest;
if (quest == null)
{
Warning("Aucune quête courante à valider.");
return;
}
// S'assure d'avoir au moins un aventurier dans l'équipe
var myAdventurers = EnsureMyAdventurersFact();
if (myAdventurers.Count == 0)
{
Warning("Aucun aventurier disponible pour valider la quête.");
return;
}
// Commence la quête (nécessite Accepted -> InProgress)
// Utilise l'UI InfoQuestPanel logique: StartQuest requiert Accepted et assigne les aventuriers
if (quest.State == QuestStateEnum.Accepted)
{
// Choisit une petite équipe (1er aventurier)
_myTeam.Clear();
_myTeam.Add(myAdventurers[0]);
var gameTime = GetFact<GameTime>("game_time");
QuestManager.Instance.StartQuest(quest, _myTeam, gameTime);
}
// Force l'état InProgress si nécessaire pour pouvoir compléter
if (quest.State != QuestStateEnum.InProgress)
{
quest.State = QuestStateEnum.InProgress;
}
// Complète la quête
var teamIds = QuestClass.GetIdFromAdventurers(_myTeam);
QuestManager.Instance.CompleteQuest(quest, teamIds);
// Notifie les UIs
QuestManager.Instance.NotifyCompletedQuests();
QuestSignals.RaiseRefreshQuests();
Info($"🏁 Quête validée: {quest.Name}", Color.yellow);
SaveFacts();
}
catch (Exception ex)
{
Debug.LogError($"[AutoQuestFlow] Erreur lors de la validation de la quête: {ex}");
}
}
// --- Utils -----------------------------------------------------------
PlayerClass EnsurePlayerFact()
{
if (!FactExists<PlayerClass>(GameManager.Instance.Profile, out var player) || player == null)
{
player = new PlayerClass("Auto Guild", _fallbackGuildLevel, 9999, 10);
SetFact(GameManager.Instance.Profile, player, FactPersistence.Persistent);
}
return player;
}
List<AdventurerClass> EnsureMyAdventurersFact()
{
if (!FactExists<List<AdventurerClass>>("my_adventurers", out var list) || list == null)
{
list = new List<AdventurerClass>();
SetFact("my_adventurers", list, FactPersistence.Persistent);
}
return list;
}
List<QuestClass> EnsureAcceptedQuestsFact()
{
if (!FactExists<List<QuestClass>>("accepted_quests", out var accepted) || accepted == null)
{
accepted = new List<QuestClass>();
SetFact("accepted_quests", accepted, FactPersistence.Persistent);
}
return accepted;
}
QuestClass GetAnyAvailableQuest(int guildLevel)
{
// Si QuestManager est prêt avec sa base, utiliser son API
if (QuestManager.Instance != null)
{
var available = QuestManager.Instance.GetAvailableQuests(guildLevel);
var template = available != null && available.Count > 0 ? available[0] : null;
if (template != null)
{
return template.ToQuestClass(QuestStateEnum.Disponible);
}
}
// Fallback: utiliser la base de données si assignée
if (_questDatabase != null)
{
var factory = _questDatabase.GetFactoryForLevel(guildLevel);
var templ = factory != null ? factory.questTemplates.FirstOrDefault() : null;
if (templ != null)
{
return templ.ToQuestClass(QuestStateEnum.Disponible);
}
}
return null;
}
}
}