Compare commits

...

2 commits

Author SHA1 Message Date
6f87c0aae6 Ajout du plugin necessaire 2025-10-17 12:41:56 +02:00
572e49f7f7 creation d'une scene et de scripts pour le Marketing 2025-10-17 12:41:36 +02:00
15 changed files with 8078 additions and 4 deletions

BIN
Assets/.DS_Store vendored

Binary file not shown.

BIN
Assets/_/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -34,6 +34,17 @@ namespace MenuSystem.Runtime.TitleScreen
_continueButton.SetActive(false);
_loadButton.SetActive(false);
}
/*if (Input.GetKeyDown(KeyCode.R))
{
GameManager.Instance.Profile = "continue";
// Chargement du profile continue
LoadFacts();
string profileName = GetFact<string>("profile");
GameManager.Instance.Profile = profileName;
LoadFacts();
SceneLoader.Instance.LoadScene("MARKETING");
}*/
}
#endregion

View file

@ -0,0 +1,246 @@
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;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ac5369f288b040e08bf9d96369dc0568
timeCreated: 1760353594

View file

@ -0,0 +1,335 @@
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;
using UnityEngine.UI;
namespace TestFacts.Runtime
{
/// <summary>
/// Automation orientée "vidéo promo" qui ouvre et utilise les différents panels UI
/// pour illustrer un flow complet:
/// 1) Ouvrir le panel de recrutement et acheter un aventurier
/// 2) Ouvrir le panneau du tableau des quêtes et accepter une quête
/// 3) Ouvrir le panneau des quêtes acceptées, afficher la fiche (InfoQuestPanel)
/// 4) Sélectionner un aventurier via l'UI et lancer la quête
/// 5) (Option promo) Compléter immédiatement la quête pour montrer l'écran terminé
///
/// Placez ce composant sur un GameObject de la scène Marketing/Game avec les références UI assignées.
/// </summary>
public class PromoUIFlow : BaseMonoBehaviour
{
[Header("Références UI")]
[SerializeField] UIManager _uiManager;
[Tooltip("Panel boutique de recrutement (contenant RecruitementPanel)")]
[SerializeField] GameObject _recruitementPanel;
[Tooltip("Panel du tableau des quêtes disponibles (contenant QuestsBoardPanel)")]
[SerializeField] GameObject _questsBoardPanel;
[Tooltip("Panel des quêtes (liste des quêtes acceptées)")]
[SerializeField] GameObject _questsPanel;
[Tooltip("Panel Info d'une quête (contenant InfoQuestPanel)")]
[SerializeField] GameObject _infoQuestPanel;
[Header("Données (optionnelles)")]
[SerializeField] AdventurerFactorySO _adventurerFactory;
[SerializeField] QuestFactoryDatabase _questDatabase;
[Header("Délais (s)")]
[SerializeField] float _delayOpenRecruit = 0.6f;
[SerializeField] float _delayBuy = 0.8f;
[SerializeField] float _delayOpenBoard = 1.0f;
[SerializeField] float _delayAcceptQuest = 0.8f;
[SerializeField] float _delayOpenAcceptedPanel = 0.8f;
[SerializeField] float _delayOpenInfo = 0.6f;
[SerializeField] float _delaySelectAdventurer = 0.6f;
[SerializeField] float _delayLaunch = 0.6f;
[SerializeField] float _delayComplete = 0.8f;
[Header("Options")]
[SerializeField] int _fallbackGuildLevel = 1;
[SerializeField] bool _autoCompleteForPromo = true;
void Start()
{
EnsureBaselineFacts();
Invoke(nameof(Step_OpenRecruitPanel), _delayOpenRecruit);
}
// 1) Ouvrir panel recrutement
void Step_OpenRecruitPanel()
{
try
{
if (_uiManager != null && _recruitementPanel != null)
{
_uiManager.HideAllPanels();
_uiManager.ShowPanel(_recruitementPanel);
}
Info("🎬 Ouverture panel Recrutement", Color.cyan);
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] OpenRecruit error: {ex}");
}
Invoke(nameof(Step_BuyFirstAdventurer), _delayBuy);
}
// 1b) Acheter le 1er aventurier via la carte UI
void Step_BuyFirstAdventurer()
{
try
{
if (_recruitementPanel != null)
{
var card = _recruitementPanel.GetComponentsInChildren<GameUI.Runtime.AdventurerCardUI>(true)
.FirstOrDefault(c => c.m_buyButton != null);
if (card == null)
{
// Forcer une génération si rien n'est présent (le panel devrait déjà le faire à OnEnable)
var rp = _recruitementPanel.GetComponentInChildren<GameUI.Runtime.RecruitementPanel>(true);
if (rp != null && _adventurerFactory != null)
{
rp.m_adventurersSO = _adventurerFactory;
rp.GenerateAdventurer(4);
}
card = _recruitementPanel.GetComponentsInChildren<GameUI.Runtime.AdventurerCardUI>(true)
.FirstOrDefault(c => c.m_buyButton != null);
}
if (card != null && card.m_buyButton != null)
{
card.m_buyButton.onClick?.Invoke();
Info($"🧙 Aventurier acheté: {card.Adventurer?.Name}", Color.green);
}
}
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] Buy error: {ex}");
}
Invoke(nameof(Step_OpenQuestsBoard), _delayOpenBoard);
}
// 2) Ouvrir le tableau des quêtes et accepter la 1ère
void Step_OpenQuestsBoard()
{
try
{
if (_uiManager != null && _questsBoardPanel != null)
{
_uiManager.HideAllPanels();
_uiManager.ShowPanel(_questsBoardPanel);
}
Info("📋 Ouverture tableau des quêtes", Color.cyan);
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] OpenBoard error: {ex}");
}
Invoke(nameof(Step_AcceptFirstQuestOnBoard), _delayAcceptQuest);
}
void Step_AcceptFirstQuestOnBoard()
{
try
{
QuestManager.Instance.NotifyAvailableQuestsUpdated(EnsurePlayerFact().GuildLevel);
var card = _questsBoardPanel != null
? _questsBoardPanel.GetComponentsInChildren<GameUI.Runtime.QuestCardUI>(true).FirstOrDefault()
: null;
if (card == null)
{
// Fallback: générer une quête à partir de la DB si possible
var templ = _questDatabase?.GetAll()?.FirstOrDefault()?.questTemplates?.FirstOrDefault();
if (templ != null)
{
var generated = templ.ToQuestClass(QuestStateEnum.Disponible);
var go = new GameObject("GeneratedQuestCardForPromo");
var qc = go.AddComponent<GameUI.Runtime.QuestCardUI>();
qc.Setup(generated);
card = qc;
}
}
if (card != null)
{
card.AcceptQuest();
Info($"✅ Quête acceptée: {card.Quest?.Name}", Color.green);
}
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] Accept quest error: {ex}");
}
Invoke(nameof(Step_OpenAcceptedQuestsPanel), _delayOpenAcceptedPanel);
}
// 3) Ouvrir la liste des quêtes acceptées
void Step_OpenAcceptedQuestsPanel()
{
try
{
if (_uiManager != null && _questsPanel != null)
{
_uiManager.HideAllPanels();
_uiManager.ShowPanel(_questsPanel);
}
QuestSignals.RaiseRefreshQuests();
Info("📜 Ouverture panel Quêtes (acceptées)", Color.cyan);
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] OpenAccepted error: {ex}");
}
Invoke(nameof(Step_OpenInfoForFirstQuest), _delayOpenInfo);
}
// 3b) Ouvrir la fiche info d'une quête via la carte d'interaction
void Step_OpenInfoForFirstQuest()
{
try
{
var inter = _questsPanel != null
? _questsPanel.GetComponentsInChildren<GameUI.Runtime.InteractionQuestCard>(true).FirstOrDefault()
: null;
if (inter != null)
{
inter.OnClick(); // ouvre InfoQuestPanel via le signal
}
else
{
// Fallback: prendre la première quête acceptée et forcer l'ouverture
var accepted = GetFact<List<QuestClass>>("accepted_quests");
var quest = accepted?.FirstOrDefault();
if (quest != null)
{
QuestSignals.RaiseInfoQuestPanel(quest);
}
}
Info(" Ouverture InfoQuestPanel", Color.cyan);
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] OpenInfo error: {ex}");
}
Invoke(nameof(Step_SelectAdventurerInInfoPanel), _delaySelectAdventurer);
}
// 4) Sélectionner un aventurier sur l'UI et lancer la quête
void Step_SelectAdventurerInInfoPanel()
{
try
{
if (_infoQuestPanel != null)
{
// Tenter de cliquer sur une carte sélectionnable d'aventurier
var selectable = _infoQuestPanel.GetComponentsInChildren<GameUI.Runtime.AdventurerCardSelectionnable>(true)
.FirstOrDefault();
if (selectable == null)
{
// Parfois les cartes sont ailleurs (liste globale), on tente dans toute la scène
selectable = GameObject.FindObjectsOfType<GameUI.Runtime.AdventurerCardSelectionnable>(true).FirstOrDefault();
}
if (selectable != null)
{
selectable.OnClick(); // Envoie AdventurerSignals.OnAdventurerSelected
}
}
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] Select adventurer error: {ex}");
}
Invoke(nameof(Step_LaunchQuestFromInfoPanel), _delayLaunch);
}
void Step_LaunchQuestFromInfoPanel()
{
try
{
if (_infoQuestPanel != null)
{
var info = _infoQuestPanel.GetComponent<GameUI.Runtime.InfoQuestPanel>();
if (info != null)
{
info.LaunchQuest();
Info("🚀 Quête lancée", Color.yellow);
}
}
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] Launch quest error: {ex}");
}
if (_autoCompleteForPromo)
Invoke(nameof(Step_CompleteQuestNow), _delayComplete);
}
// 5) Option promo: compléter immédiatement la quête pour montrer l'état terminé
void Step_CompleteQuestNow()
{
try
{
var quest = QuestManager.Instance.CurrentQuest;
if (quest == null)
{
Warning("Aucune quête courante à compléter.");
return;
}
// Utiliser l'équipe d'un seul aventurier (le premier dispo)
var team = EnsureMyAdventurersFact();
if (team.Count == 0) return;
var ids = QuestClass.GetIdFromAdventurers(new List<AdventurerClass> { team[0] });
if (quest.State != QuestStateEnum.InProgress)
{
// S'assure que l'état est correct pour compléter
var gameTime = GetFact<GameTime>("game_time");
QuestManager.Instance.StartQuest(quest, new List<AdventurerClass> { team[0] }, gameTime);
}
QuestManager.Instance.CompleteQuest(quest, ids);
QuestManager.Instance.NotifyCompletedQuests();
QuestSignals.RaiseRefreshQuests();
Info($"🏁 Quête complétée (promo): {quest.Name}", Color.green);
}
catch (Exception ex)
{
Debug.LogError($"[PromoUIFlow] Complete quest error: {ex}");
}
}
// --- Utils -----------------------------------------------------------
void EnsureBaselineFacts()
{
var player = EnsurePlayerFact();
player.Money = Mathf.Max(player.Money, 9999);
player.AdventurersMax = Mathf.Max(player.AdventurersMax, 10);
SaveFacts();
}
PlayerClass EnsurePlayerFact()
{
if (!FactExists<PlayerClass>(GameManager.Instance.Profile, out var player) || player == null)
{
player = new PlayerClass("Promo 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;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e3a898d026f9454dbe9bb387955e1671
timeCreated: 1760354138

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 12365dde14cc143f28f571566ebddf91
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -8,6 +8,7 @@
"com.unity.inputsystem": "1.14.2",
"com.unity.multiplayer.center": "1.0.0",
"com.unity.nuget.newtonsoft-json": "3.2.1",
"com.unity.recorder": "5.1.3",
"com.unity.render-pipelines.universal": "17.2.0",
"com.unity.test-framework": "1.6.0",
"com.unity.timeline": "1.8.9",

View file

@ -15,6 +15,15 @@
},
"url": "https://packages.unity.com"
},
"com.unity.bindings.openimageio": {
"version": "1.0.0",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.collections": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.burst": {
"version": "1.8.25",
"depth": 2,
@ -34,7 +43,7 @@
},
"com.unity.collections": {
"version": "2.5.7",
"depth": 2,
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.8.19",
@ -95,7 +104,7 @@
},
"com.unity.nuget.mono-cecil": {
"version": "1.11.5",
"depth": 3,
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
@ -107,6 +116,17 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.recorder": {
"version": "5.1.3",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.timeline": "1.8.7",
"com.unity.collections": "1.2.4",
"com.unity.bindings.openimageio": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.render-pipelines.core": {
"version": "17.2.0",
"depth": 1,
@ -194,7 +214,7 @@
},
"com.unity.test-framework.performance": {
"version": "3.2.0",
"depth": 3,
"depth": 2,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.33",

View file

@ -11,6 +11,9 @@ EditorBuildSettings:
- enabled: 1
path: Assets/_/Levels/TitleScreen.unity
guid: 6743833d09976436f9d12e6a44d2dc70
- enabled: 1
path: Assets/_/Levels/MARKETING.unity
guid: 12365dde14cc143f28f571566ebddf91
m_configObjects:
com.unity.input.settings.actions: {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3}
m_UseUCBPForAssetBundles: 0

View file

@ -3,7 +3,7 @@
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
serializedVersion: 15
m_SerializationMode: 2
m_LineEndingsForNewScripts: 0
m_DefaultBehaviorMode: 0
@ -33,6 +33,7 @@ EditorSettings:
m_UseLegacyProbeSampleCount: 0
m_SerializeInlineMappingsOnOneLine: 1
m_DisableCookiesInLightmapper: 0
m_ShadowmaskStitching: 0
m_AssetPipelineMode: 1
m_RefreshImportMode: 0
m_CacheServerMode: 0
@ -46,3 +47,4 @@ EditorSettings:
m_CacheServerDownloadBatchSize: 128
m_EnableEnlightenBakedGI: 0
m_ReferencedClipsExactNaming: 1
m_ForceAssetUnloadAndGCOnSceneLoad: 1