refactorisation du QuestSystem

This commit is contained in:
mrtoine 2025-10-10 10:46:01 +02:00
parent 2370cb670d
commit 5fa20c954c
11 changed files with 128 additions and 39 deletions

View file

@ -45,10 +45,19 @@ namespace Core.Runtime
public string GetLocalizedText(string key) public string GetLocalizedText(string key)
{ {
if (GameManager.Instance.GetLocalTexts.TryGetValue(key, out var value)) // Guard against null or empty keys
if (string.IsNullOrEmpty(key))
{
return string.Empty;
}
// Guard against missing dictionary
var dict = GameManager.Instance?.GetLocalTexts;
if (dict != null && dict.TryGetValue(key, out var value))
return value; return value;
return $"{key}"; // Fallback: return the key itself so UI shows something meaningful
return key;
} }
public void SaveLanguage(string newLanguage) public void SaveLanguage(string newLanguage)

View file

@ -29,11 +29,29 @@ namespace Decor.Runtime
void Start() void Start()
{ {
//UpdateParchmentState(); // Trigger an initial refresh
Info($"<color=yellow>Il y a actuellement {_quests} quêtes affichés sur le Panneau</color>"); QuestManager.Instance.NotifyAvailableQuestsUpdated(_player.GuildLevel);
UpdateParchmentState();
} }
void Update() void OnEnable()
{
QuestManager.OnAvailableQuestsUpdated += HandleAvailableChanged;
QuestManager.OnQuestCompleted += HandleQuestCompleted;
}
void OnDisable()
{
QuestManager.OnAvailableQuestsUpdated -= HandleAvailableChanged;
QuestManager.OnQuestCompleted -= HandleQuestCompleted;
}
void HandleAvailableChanged(System.Collections.Generic.List<QuestTemplate> _)
{
UpdateParchmentState();
}
void HandleQuestCompleted(QuestClass _)
{ {
UpdateParchmentState(); UpdateParchmentState();
} }
@ -66,8 +84,6 @@ namespace Decor.Runtime
) )
); );
_parchment.SetActive(hasTrulyAvailableQuests); _parchment.SetActive(hasTrulyAvailableQuests);
Info($"<color=green>Il y a actuellement {hasTrulyAvailableQuests} disponibles</color>");
} }
#endregion #endregion

View file

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Core.Runtime; using Core.Runtime;
using Quest.Runtime; using Quest.Runtime;
using Quests.Runtime;
using UnityEngine; using UnityEngine;
namespace Quests.Runtime._.Features.Quests namespace Quests.Runtime._.Features.Quests
@ -15,16 +16,20 @@ namespace Quests.Runtime._.Features.Quests
void Start() void Start()
{ {
if (!FactExists<List<QuestClass>>("active_quests", out var _)) if (!FactExists<List<QuestClass>>(SaveKeys.Active, out var _))
{ {
SetFact<List<QuestClass>>("active_quests", new List<QuestClass>(), FactPersistence.Persistent); SetFact<List<QuestClass>>(SaveKeys.Active, new List<QuestClass>(), FactPersistence.Persistent);
} }
QuestManager.Instance.ActiveQuests = GetFact<List<QuestClass>>("active_quests"); QuestManager.Instance.ActiveQuests = GetFact<List<QuestClass>>(SaveKeys.Active);
if (!FactExists<List<QuestClass>>("active_quests", out var _)) if (!FactExists<List<QuestClass>>(SaveKeys.Completed, out var _))
{ {
SetFact<List<QuestClass>>("completed_quests", new List<QuestClass>(), FactPersistence.Persistent); SetFact<List<QuestClass>>(SaveKeys.Completed, new List<QuestClass>(), FactPersistence.Persistent);
}
QuestManager.Instance.CompletedQuests = GetFact<List<QuestClass>>(SaveKeys.Completed);
if (!FactExists<Dictionary<System.Guid, List<QuestEventLog>>>(SaveKeys.EventLogs, out var _))
{
SetFact<Dictionary<System.Guid, List<QuestEventLog>>>(SaveKeys.EventLogs, new Dictionary<System.Guid, List<QuestEventLog>>(), FactPersistence.Persistent);
} }
QuestManager.Instance.CompletedQuests = GetFact<List<QuestClass>>("completed_quests");
Invoke(nameof(NotifyLater), 0.1f); Invoke(nameof(NotifyLater), 0.1f);
} }

View file

@ -72,6 +72,7 @@ namespace Quests.Runtime
public QuestManager() public QuestManager()
{ {
_activeEvents = new List<QuestEvent>();
GameManager.OnTimeAdvanced += CheckMissionsProgress; GameManager.OnTimeAdvanced += CheckMissionsProgress;
} }
@ -119,7 +120,7 @@ namespace Quests.Runtime
{ {
QuestClass quest = GetQuestById(questId); QuestClass quest = GetQuestById(questId);
List<QuestEventLog> events = GetFact<Dictionary<Guid, List<QuestEventLog>>>("events_quests_history")[questId]; List<QuestEventLog> events = GetFact<Dictionary<Guid, List<QuestEventLog>>>(SaveKeys.EventLogs)[questId];
return new QuestSummary(quest, events); return new QuestSummary(quest, events);
} }
@ -137,8 +138,8 @@ namespace Quests.Runtime
/// </summary> /// </summary>
public bool IsQuestCompleted(string questName) public bool IsQuestCompleted(string questName)
{ {
return ActiveQuests != null return CompletedQuests != null
&& ActiveQuests.Any(q => q.Name == questName && q.State == QuestStateEnum.Completed); && CompletedQuests.Any(q => q.Name == questName);
} }
/// <summary> /// <summary>
@ -207,7 +208,7 @@ namespace Quests.Runtime
void UpdateQuestStatus(QuestClass quest) void UpdateQuestStatus(QuestClass quest)
{ {
_activeQuests.Add(quest); _activeQuests.Add(quest);
List<QuestClass> saveQuests = GetFact<List<QuestClass>>("quests"); List<QuestClass> saveQuests = GetFact<List<QuestClass>>(SaveKeys.All);
foreach (var saveQuest in saveQuests) foreach (var saveQuest in saveQuests)
{ {
if (saveQuest.Name == quest.Name) if (saveQuest.Name == quest.Name)
@ -242,7 +243,7 @@ namespace Quests.Runtime
_activeQuests.RemoveAll(q => q.Name == quest.Name); _activeQuests.RemoveAll(q => q.Name == quest.Name);
_completedQuests.Add(quest); _completedQuests.Add(quest);
List<QuestClass> quests = GetFact<List<QuestClass>>("quests"); List<QuestClass> quests = GetFact<List<QuestClass>>(SaveKeys.All);
QuestClass questToUpdate = quests.FirstOrDefault(q => q.ID == quest.ID); QuestClass questToUpdate = quests.FirstOrDefault(q => q.ID == quest.ID);
if (questToUpdate != null) if (questToUpdate != null)
{ {
@ -319,7 +320,7 @@ namespace Quests.Runtime
var targets = questEvent.GetTargets(quest.AssignedAdventurersID); var targets = questEvent.GetTargets(quest.AssignedAdventurersID);
ApplyEffect(questEvent.Effects, targets); ApplyEffect(questEvent.Effects, targets);
Dictionary<Guid, List<QuestEventLog>> events = GetFact<Dictionary<Guid, List<QuestEventLog>>>("events_quests_history"); Dictionary<Guid, List<QuestEventLog>> events = GetFact<Dictionary<Guid, List<QuestEventLog>>>(SaveKeys.EventLogs);
if(!events.ContainsKey(quest.ID)) if(!events.ContainsKey(quest.ID))
{ {

View file

@ -3,6 +3,7 @@ namespace Quests.Runtime
public enum QuestStateEnum public enum QuestStateEnum
{ {
Disponible, Disponible,
Accepted,
Active, Active,
Completed, Completed,
} }

View file

@ -0,0 +1,10 @@
namespace Quests.Runtime
{
public static class SaveKeys
{
public const string Active = "active_quests";
public const string Completed = "completed_quests";
public const string All = "quests"; // legacy/misc list if still used elsewhere
public const string EventLogs = "events_quests_history";
}
}

View file

@ -108,6 +108,12 @@ namespace GameUI.Runtime
_panelRecap.SetActive(true); _panelRecap.SetActive(true);
_panelRecap.GetComponent<QuestLogsListUI>().ShowFor(QuestManager.Instance.CurrentQuest.ID); _panelRecap.GetComponent<QuestLogsListUI>().ShowFor(QuestManager.Instance.CurrentQuest.ID);
break; break;
case QuestStateEnum.Accepted:
_buttonActivation.SetActive(true);
_adventurersOnThisQuestPanel.SetActive(false);
_adventurersSelection.SetActive(true);
_panelRecap.SetActive(false);
break;
case QuestStateEnum.Active: case QuestStateEnum.Active:
Info("La quête est active."); Info("La quête est active.");
_buttonActivation.SetActive(false); _buttonActivation.SetActive(false);
@ -146,15 +152,16 @@ namespace GameUI.Runtime
#region Quest Operations #region Quest Operations
private QuestClass FindMatchingActiveQuest(QuestClass quest) private QuestClass FindMatchingActiveQuest(QuestClass quest)
{ {
if (!FactExists<List<QuestClass>>("active_quests", out _)) return quest; if (!FactExists<List<QuestClass>>(SaveKeys.Active, out _)) return quest;
var activeQuests = GetFact<List<QuestClass>>("active_quests"); var activeQuests = GetFact<List<QuestClass>>(SaveKeys.Active);
var matchingQuest = activeQuests.FirstOrDefault(q => q.ID == quest.ID); var matchingQuest = activeQuests.FirstOrDefault(q => q.ID == quest.ID);
return matchingQuest ?? quest; return matchingQuest ?? quest;
} }
private void UpdateQuestInfoDisplay(QuestClass quest) private void UpdateQuestInfoDisplay(QuestClass quest)
{ {
Info($"<color=green>UpdateQuestInfoDisplay : {quest.Name}</color>");
m_title.text = LocalizationSystem.Instance.GetLocalizedText(quest?.Name); m_title.text = LocalizationSystem.Instance.GetLocalizedText(quest?.Name);
string descKey = quest?.Description; string descKey = quest?.Description;
if (string.IsNullOrEmpty(descKey)) if (string.IsNullOrEmpty(descKey))
@ -171,9 +178,25 @@ namespace GameUI.Runtime
var gameTime = GetFact<GameTime>("game_time"); var gameTime = GetFact<GameTime>("game_time");
QuestManager.Instance.StartQuest(QuestManager.Instance.CurrentQuest, _adventurersSelected, gameTime); QuestManager.Instance.StartQuest(QuestManager.Instance.CurrentQuest, _adventurersSelected, gameTime);
// Ajouter la quête à la liste des quêtes actives // Mettre à jour la quête dans la liste des quêtes acceptées (Active repo)
var activeQuests = GetFact<List<QuestClass>>("active_quests"); var activeQuests = GetFact<List<QuestClass>>(SaveKeys.Active);
activeQuests.Add(QuestManager.Instance.CurrentQuest); var idx = activeQuests.FindIndex(q => q.ID == QuestManager.Instance.CurrentQuest.ID);
if (idx >= 0)
{
activeQuests[idx].State = QuestStateEnum.Active;
activeQuests[idx].StartSeconds = QuestManager.Instance.CurrentQuest.StartSeconds;
activeQuests[idx].EndSeconds = QuestManager.Instance.CurrentQuest.EndSeconds;
}
else
{
// fallback: if not found, add it once
activeQuests.Add(QuestManager.Instance.CurrentQuest);
}
SaveFacts();
// Notify panels
QuestSignals.RaiseRefreshQuests();
var player = GetFact<Player.Runtime.PlayerClass>(GameManager.Instance.Profile);
QuestManager.Instance.NotifyAvailableQuestsUpdated(player.GuildLevel);
} }
private void CleanupAfterQuestLaunch() private void CleanupAfterQuestLaunch()

View file

@ -16,6 +16,7 @@ namespace GameUI.Runtime
public void SetQuest(QuestClass quest) public void SetQuest(QuestClass quest)
{ {
Info($"<color=green>SetQuest : {quest.Name}</color>");
_quest = quest; _quest = quest;
} }

View file

@ -57,11 +57,21 @@ namespace GameUI.Runtime
public void AcceptQuest() public void AcceptQuest()
{ {
List<QuestClass> quests = GetFact<List<QuestClass>>("quests"); // Mark as accepted and add to accepted (active list used as accepted repository for now)
quests.Add(_quest); _quest.State = QuestStateEnum.Accepted;
SaveFacts(); List<QuestClass> active = GetFact<List<QuestClass>>(SaveKeys.Active);
QuestSignals.RaiseRefreshQuests(); // Idempotency: avoid duplicates
Destroy(gameObject); bool alreadyThere = active.Any(q => q.ID == _quest.ID || q.Name == _quest.Name);
if (!alreadyThere)
{
active.Add(_quest);
SaveFacts();
}
// Notify panels
QuestSignals.RaiseRefreshQuests(); // refresh QuestsPanel
var player = GetFact<Player.Runtime.PlayerClass>(GameManager.Instance.Profile);
QuestManager.Instance.NotifyAvailableQuestsUpdated(player.GuildLevel); // refresh board availability
Destroy(gameObject);
} }
#endregion #endregion

View file

@ -65,13 +65,25 @@ namespace GameUI.Runtime
void DisplayAvailableQuests(List<QuestTemplate> availableTemplates, List<QuestClass> acceptedQuests) void DisplayAvailableQuests(List<QuestTemplate> availableTemplates, List<QuestClass> acceptedQuests)
{ {
foreach (var quest in availableTemplates) // Build a set of started quest IDs (Accepted/Active + Completed)
var startedIds = new HashSet<System.Guid>();
foreach (var q in QuestManager.Instance.ActiveQuests ?? new List<QuestClass>())
{ {
if (acceptedQuests.Any(q => q.Name == quest.data.Name)) if (q.ID != System.Guid.Empty) startedIds.Add(q.ID);
}
foreach (var q in QuestManager.Instance.CompletedQuests ?? new List<QuestClass>())
{
if (q.ID != System.Guid.Empty) startedIds.Add(q.ID);
}
foreach (var template in availableTemplates)
{
// Skip if this template already started (by GUID)
if (System.Guid.TryParse(template.m_assetGuid, out var guid) && startedIds.Contains(guid))
{ {
continue; continue;
} }
DisplayCard(quest); DisplayCard(template);
} }
} }

View file

@ -44,14 +44,13 @@ namespace GameUI.Runtime
Destroy(child.gameObject); Destroy(child.gameObject);
} }
if (FactExists<List<QuestClass>>("quests", out _)) if (FactExists<List<QuestClass>>(SaveKeys.Active, out _))
{ {
List<QuestClass> questsFromSave = GetFact<List<QuestClass>>("quests"); // Show only accepted quests in this panel
List<QuestClass> accepted = GetFact<List<QuestClass>>(SaveKeys.Active);
List<QuestClass> quests = QuestManager.Instance.ResolveQuestsList(questsFromSave); foreach (var quest in accepted.Where(q => q.State == QuestStateEnum.Accepted))
foreach (var quest in quests)
{ {
DisplayQuest(quest); //=> Key : L'id de la quête, Value : Le State DisplayQuest(quest);
} }
} }
} }
@ -70,6 +69,8 @@ namespace GameUI.Runtime
questMini.m_check?.SetActive(isCompleted); questMini.m_check?.SetActive(isCompleted);
} }
Info($"<color=green>On affiche la quete : {quest.Name}</color>");
questGO.GetComponent<InteractionQuestCard>().SetQuest(quest); questGO.GetComponent<InteractionQuestCard>().SetQuest(quest);
} }