diff --git a/Campofinale/Game/Entities/EntityInteractive.cs b/Campofinale/Game/Entities/EntityInteractive.cs index 4915960..f57fafe 100644 --- a/Campofinale/Game/Entities/EntityInteractive.cs +++ b/Campofinale/Game/Entities/EntityInteractive.cs @@ -54,7 +54,7 @@ namespace Campofinale.Game.Entities Type = (int)5, }, - + //Meta =dependencyGroupId, BattleInfo = new() { diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index 48299f3..1f79384 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -83,6 +83,7 @@ namespace Campofinale.Game.Entities Type =(int) ObjectTypeIndex.Enemy, }, + Attrs = { GetAttributes() diff --git a/Campofinale/Game/Mission/MissionSystem.cs b/Campofinale/Game/Mission/MissionSystem.cs deleted file mode 100644 index 8de3bcc..0000000 --- a/Campofinale/Game/Mission/MissionSystem.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Campofinale.Database; - -namespace Campofinale.Game.Mission -{ - public class MissionSystem - { - public Player owner; - public MissionSystem(Player o) - { - owner = o; - } - public void Save() - { - - } - public void Load() - { - } - } -} diff --git a/Campofinale/Game/MissionSys/MissionSystem.cs b/Campofinale/Game/MissionSys/MissionSystem.cs new file mode 100644 index 0000000..b7d7412 --- /dev/null +++ b/Campofinale/Game/MissionSys/MissionSystem.cs @@ -0,0 +1,246 @@ +using Campofinale.Database; +using Campofinale.Protocol; +using Campofinale.Resource; +using Campofinale.Resource.Table; +using static System.Runtime.InteropServices.JavaScript.JSType; + +namespace Campofinale.Game.MissionSys +{ + public class MissionSystem + { + public Player owner; + public List missions=new(); + public List quests=new(); + public string curMission = "e0m0"; + + public MissionSystem(Player o) + { + owner = o; + } + public ScSyncAllMission ToProto() + { + ScSyncAllMission sync = new ScSyncAllMission(); + sync.TrackMissionId = curMission; + missions.ForEach(m => + { + sync.Missions.Add(m.missionId, new Mission() + { + MissionId = m.missionId, + MissionState = (int)m.state, + + }); + }); + + quests.ForEach(q => + { + Quest quest=new Quest() + { + QuestId = q.questId, + QuestState = (int)q.state, + + }; + var data = GetQuestData(q.questId); + data.objectiveList.ForEach(o => + { + quest.QuestObjectives.Add(new QuestObjective() + { + ConditionId = o.condition.uniqueId, + Values = + { + {o.condition.uniqueId,0 } + } + }); + }); + sync.CurQuests.Add(q.questId, quest); + + }); + return sync; + } + public MissionDataTable.QuestInfo GetQuestData(string id) + { + MissionDataTable.QuestInfo quest = null; + foreach(MissionDataTable m in ResourceManager.missionDataTable) + { + if(m.questDic.TryGetValue(id, out quest)) + { + return quest; + } + }; + + return quest; + } + public void Save() + { + + } + public void Load() + { + //TODO Saving and first initialization + AddMission("e0m0",MissionState.Processing); + } + public void AddMission(string id,MissionState state = MissionState.Available, bool notify=false) + { + MissionDataTable data = ResourceManager.missionDataTable.Find(m=>m.missionId == id); + if (data != null) + { + missions.Add(new GameMission(id, state)); + if (notify) + { + ScMissionStateUpdate s = new() + { + MissionId = data.missionId, + MissionState = (int)state, + SucceedId=-1, + + }; + } + + int i = 0; + foreach (var q in data.questDic.Values) + { + AddQuest(q, false); + } + } + } + public GameQuest GetQuestById(string id) + { + return quests.Find(q => q.questId == id); + } + public void AddQuest(MissionDataTable.QuestInfo data,bool notify=false) + { + GameQuest quest = GetQuestById(data.questId); + if (quest == null) + { + quest = new GameQuest(data.questId); + quest.state = QuestState.Available; + if (notify) + { + ScQuestObjectivesUpdate upd = new() + { + QuestId = data.questId, + + }; + data.objectiveList.ForEach(o => + { + upd.QuestObjectives.Add(new QuestObjective() + { + ConditionId=o.condition.uniqueId, + Values = + { + {o.condition.uniqueId,0 } + } + }); + }); + ScQuestStateUpdate update = new() + { + QuestId = quest.questId, + QuestState = (int)quest.state, + RoleBaseInfo = owner.GetRoleBaseInfo() + }; + owner.Send(ScMsgId.ScQuestStateUpdate, update); + owner.Send(ScMsgId.ScQuestObjectivesUpdate, upd); + } + + quests.Add(quest); + } + } + public void ProcessQuest(string id) + { + GameQuest quest = GetQuestById(id); + if (quest != null) + { + + quest.state = QuestState.Processing; + var data = GetQuestData(id); + ScQuestStateUpdate update = new() + { + QuestId = quest.questId, + QuestState = (int)quest.state, + RoleBaseInfo = owner.GetRoleBaseInfo() + }; + ScQuestObjectivesUpdate upd = new() + { + QuestId = data.questId, + + }; + data.objectiveList.ForEach(o => + { + upd.QuestObjectives.Add(new QuestObjective() + { + ConditionId = o.condition.uniqueId, + Values = + { + {o.condition.uniqueId,0 } + } + }); + }); + owner.Send(ScMsgId.ScQuestObjectivesUpdate, upd); + owner.Send(ScMsgId.ScQuestStateUpdate, update); + + } + } + public void CompleteQuest(string id) + { + GameQuest quest = GetQuestById(id); + if (quest != null) + { + quest.state = QuestState.Completed; + var data = GetQuestData(id); + ScQuestStateUpdate update = new() + { + QuestId = quest.questId, + QuestState=(int)quest.state, + }; + ScQuestObjectivesUpdate upd = new() + { + QuestId = data.questId, + + }; + data.objectiveList.ForEach(o => + { + upd.QuestObjectives.Add(new QuestObjective() + { + ConditionId = o.condition.uniqueId, + IsComplete=true, + Values = + { + {o.condition.uniqueId,1 } + } + }); + }); + owner.Send(ScMsgId.ScQuestObjectivesUpdate, upd); + owner.Send(ScMsgId.ScQuestStateUpdate, update); + quests.Remove(quest); + } + } + } + public class GameQuest + { + public string questId; + public QuestState state; + public GameQuest() + { + + } + public GameQuest(string id, QuestState state = QuestState.Available) + { + questId = id; + this.state = state; + } + } + public class GameMission + { + public string missionId; + public MissionState state; + + public GameMission() + { + + } + public GameMission(string id, MissionState state = MissionState.Available) + { + missionId = id; + this.state = state; + } + } +} diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index b689077..220ac67 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -335,6 +335,7 @@ namespace Campofinale.Game lv_scene.levelData.enemies.ForEach(en => { if(GetOwner().noSpawnAnymore.Contains(en.levelLogicId) && sceneNumId != 87) return; + if (en.defaultHide) return; EntityMonster entity = new(en.entityDataIdKey,en.level,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { type=en.entityType, @@ -345,7 +346,7 @@ namespace Campofinale.Game }); lv_scene.levelData.npcs.ForEach(en => { - + if (en.defaultHide) return; if (en.npcGroupId.Contains("chr")) return; EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { @@ -426,5 +427,22 @@ namespace Campofinale.Game { return Server.clients.Find(c => c.roleId == ownerId); } + + public void SpawnEnemy(ulong v) + { + LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); + LevelEnemyData en = lv_scene.levelData.enemies.Find(e=>e.levelLogicId == v); + if(en!=null) + { + EntityMonster entity = new(en.entityDataIdKey, en.level, ownerId, en.position, en.rotation, sceneNumId, en.levelLogicId) + { + type = en.entityType, + belongLevelScriptId = en.belongLevelScriptId, + levelLogicId = en.levelLogicId + }; + entities.Add(entity); + SpawnEntity(entity); + } + } } } diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index fe8325c..8ba75f1 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -132,7 +132,8 @@ namespace Campofinale.Packets.Cs ScSyncAllMission m = Newtonsoft.Json.JsonConvert.DeserializeObject(json1); m.TrackMissionId = ""; - + //Disabled the hardcoded one and enable the missionSystem one + //session.Send(ScMsgId.ScSyncAllMission, session.missionSystem.ToProto()); session.Send(ScMsgId.ScSyncAllMission, m); /*ession.Send(ScMsgId.ScSyncAllMission, new ScSyncAllMission() { @@ -250,7 +251,7 @@ namespace Campofinale.Packets.Cs } } } });*/ - + session.Send(new PacketScGachaSync(session)); ScSettlementSyncAll settlements = new ScSettlementSyncAll() { diff --git a/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs b/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs index 2585ef6..55c7904 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneLoadFinish.cs @@ -18,11 +18,11 @@ namespace Campofinale.Packets.Cs session.sceneManager.LoadCurrentTeamEntities(); session.sceneManager.LoadCurrent(); session.LoadFinish = true; - /*session.Send(ScMessageId.ScSceneClientIdInfo, new ScSceneClientIdInfo() + session.Send(ScMsgId.ScSceneClientIdInfo, new ScSceneClientIdInfo() { RoleIdx = (uint)session.roleId, LastMaxIdx = session.random.usedGuids.Max() - });*/ + }); if (session.curSceneNumId == 98) { session.Send(new PacketScSyncGameMode(session, "spaceship")); diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index daab501..48e5f0b 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -3,6 +3,8 @@ using Campofinale.Game.Entities; using Campofinale.Network; using Campofinale.Protocol; using Campofinale.Resource; +using Campofinale.Resource.Table; +using Pastel; namespace Campofinale.Packets.Cs { @@ -12,14 +14,19 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLevelScriptActive req = packet.DecodeBody(); - - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + if (req.IsActive) { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - State = 3 - }; - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = 3 + }; + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } + } @@ -27,23 +34,63 @@ namespace Campofinale.Packets.Cs public static void HandleCsSceneSetLevelScriptStart(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLevelScriptStart req = packet.DecodeBody(); - ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + if (req.IsStart) { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, - State = 4 - }; - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = 4 + }; + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } + } - [Server.Handler(CsMsgId.CsSceneLevelScriptEventTrigger)] + public static void ExecuteEventAction(Player player, ScriptAction action) + { + switch (action.action) + { + case ScriptActionType.CompleteQuest: + player.missionSystem.CompleteQuest(action.valueStr[0]); + break; + case ScriptActionType.ProcessQuest: + player.missionSystem.ProcessQuest(action.valueStr[0]); + break; + case ScriptActionType.SpawnEnemy: + player.sceneManager.GetCurScene().SpawnEnemy(action.valueUlong[0]); + break; + default: + Logger.PrintWarn("Script Action not implemented"); + break; + } + } + [Server.Handler(CsMsgId.CsSceneLevelScriptEventTrigger)] public static void HandleCsSceneLevelScriptEventTrigger(Player session, CsMsgId cmdId, Packet packet) { CsSceneLevelScriptEventTrigger req = packet.DecodeBody(); Logger.Print(req.Properties.ToString()); - if(req.EventName== "#8777e316") + + if (ResourceManager.levelScriptsEvents.TryGetValue(req.EventName, out LevelScriptEvent levelScriptEvent)) + { + Logger.Print($"Event {req.EventName.Pastel(ConsoleColor.Yellow)} Executed."); + Logger.Print($"{levelScriptEvent.comment}"); + levelScriptEvent.actions.ForEach(a => + { + ExecuteEventAction(session, a); + }); + } + else + { + Logger.PrintWarn($"Event {req.EventName.Pastel(ConsoleColor.White)} is NOT implemented. INFO: ["); + Logger.PrintWarn($" Scene: {req.SceneNumId.ToString().Pastel(ConsoleColor.White)}, Pos: {session.position.ToProto().ToString()} "); + Logger.PrintWarn($" ScriptID: {req.ScriptId.ToString().Pastel(ConsoleColor.White)} "); + Logger.PrintWarn($"]"); + } + /*if(req.EventName== "#8777e316") { session.Send(ScMsgId.ScQuestStateUpdate, new ScQuestStateUpdate() { @@ -120,26 +167,28 @@ namespace Campofinale.Packets.Cs QuestId = "e0m0_q#7", QuestState = (int)QuestState.Processing, }); - } + }*/ ScSceneUpdateLevelScriptProperty update1 = new() { SceneNumId = req.SceneNumId, ScriptId = req.ScriptId, - + }; session.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update1); ScSceneTriggerClientLevelScriptEvent trigger = new() { EventName = req.EventName, SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId + ScriptId = req.ScriptId, + }; session.Send(ScMsgId.ScSceneTriggerClientLevelScriptEvent, trigger); ScSceneUpdateLevelScriptProperty update2 = new() { SceneNumId = req.SceneNumId, ScriptId = req.ScriptId, + }; session.Send(ScMsgId.ScSceneUpdateLevelScriptProperty, update2); diff --git a/Campofinale/Packets/Cs/HandleCsTrackMission.cs b/Campofinale/Packets/Cs/HandleCsTrackMission.cs index 28b085e..b2b07f8 100644 --- a/Campofinale/Packets/Cs/HandleCsTrackMission.cs +++ b/Campofinale/Packets/Cs/HandleCsTrackMission.cs @@ -9,7 +9,7 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId msgId, Packet packet) { CsTrackMission req = packet.DecodeBody(); - + session.missionSystem.curMission = req.MissionId; ScTrackMissionChange rsp = new() { MissionId = req.MissionId diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 14fff30..78f1ddd 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -13,7 +13,7 @@ using Campofinale.Game.Gacha; using Campofinale.Game.Spaceship; using Campofinale.Game.Dungeons; using Campofinale.Game.Factory; -using Campofinale.Game.Mission; +using Campofinale.Game.MissionSys; using Pastel; using System.Drawing; @@ -175,6 +175,7 @@ namespace Campofinale { Initialize(); //only if no account found } + missionSystem.Load(); sceneManager.Load(); factoryManager.Load(); return (data != null); @@ -267,68 +268,6 @@ namespace Campofinale } public void UnlockImportantSystems() { - /*unlockedSystems.Add((int)UnlockSystemType.Watch); - unlockedSystems.Add((int)UnlockSystemType.Weapon); - unlockedSystems.Add((int)UnlockSystemType.Equip); - unlockedSystems.Add((int)UnlockSystemType.EquipEnhance); - unlockedSystems.Add((int)UnlockSystemType.NormalAttack); - unlockedSystems.Add((int)UnlockSystemType.NormalSkill); - unlockedSystems.Add((int)UnlockSystemType.UltimateSkill); - unlockedSystems.Add((int)UnlockSystemType.TeamSkill); - unlockedSystems.Add((int)UnlockSystemType.ComboSkill); - unlockedSystems.Add((int)UnlockSystemType.TeamSwitch); - unlockedSystems.Add((int)UnlockSystemType.Dash); - unlockedSystems.Add((int)UnlockSystemType.Jump); - unlockedSystems.Add((int)UnlockSystemType.Friend); - unlockedSystems.Add((int)UnlockSystemType.SNS); - unlockedSystems.Add((int)UnlockSystemType.Settlement); - unlockedSystems.Add((int)UnlockSystemType.Map); - - unlockedSystems.Add((int)UnlockSystemType.FacTechTree); - unlockedSystems.Add((int)UnlockSystemType.FacZone); - unlockedSystems.Add((int)UnlockSystemType.FacSplitter); - unlockedSystems.Add((int)UnlockSystemType.FacConveyor); - unlockedSystems.Add((int)UnlockSystemType.FacBridge); - unlockedSystems.Add((int)UnlockSystemType.FacPipe); - unlockedSystems.Add((int)UnlockSystemType.FacBuildingPin); - unlockedSystems.Add((int)UnlockSystemType.FacBUS); - unlockedSystems.Add((int)UnlockSystemType.FacPipeConnector); - unlockedSystems.Add((int)UnlockSystemType.FacOverview); - unlockedSystems.Add((int)UnlockSystemType.FacCraftPin); - unlockedSystems.Add((int)UnlockSystemType.FacMerger); - unlockedSystems.Add((int)UnlockSystemType.FacYieldStats); - unlockedSystems.Add((int)UnlockSystemType.FacTransferPort); - unlockedSystems.Add((int)UnlockSystemType.FacHub); - unlockedSystems.Add((int)UnlockSystemType.FacMode); - unlockedSystems.Add((int)UnlockSystemType.FacSystem); - unlockedSystems.Add((int)UnlockSystemType.FacPipeSplitter); - unlockedSystems.Add((int)UnlockSystemType.FacPipeConverger); - unlockedSystems.Add((int)UnlockSystemType.AdventureBook); - unlockedSystems.Add((int)UnlockSystemType.CharUI); - unlockedSystems.Add((int)UnlockSystemType.EquipProduce); - unlockedSystems.Add((int)UnlockSystemType.EquipTech); - unlockedSystems.Add((int)UnlockSystemType.Gacha); - unlockedSystems.Add((int)UnlockSystemType.Inventory); - unlockedSystems.Add((int)UnlockSystemType.ItemQuickBar); - unlockedSystems.Add((int)UnlockSystemType.ItemSubmitRecycle); - unlockedSystems.Add((int)UnlockSystemType.ItemUse); - unlockedSystems.Add((int)UnlockSystemType.Mail); - unlockedSystems.Add((int)UnlockSystemType.ValuableDepot); - unlockedSystems.Add((int)UnlockSystemType.Wiki); - unlockedSystems.Add((int)UnlockSystemType.AIBark); - unlockedSystems.Add((int)UnlockSystemType.AdventureExpAndLv); - unlockedSystems.Add((int)UnlockSystemType.CharTeam); - - - unlockedSystems.Add((int)UnlockSystemType.SpaceshipSystem); - unlockedSystems.Add((int)UnlockSystemType.SpaceshipControlCenter); - - unlockedSystems.Add((int)UnlockSystemType.PRTS); - unlockedSystems.Add((int)UnlockSystemType.Dungeon); - unlockedSystems.Add((int)UnlockSystemType.RacingDungeon); - unlockedSystems.Add((int)UnlockSystemType.CheckIn); - unlockedSystems.Add((int)UnlockSystemType.SubmitEther);*/ - foreach(UnlockSystemType type in Enum.GetValues(typeof(UnlockSystemType))) { unlockedSystems.Add((int)type); @@ -669,5 +608,33 @@ namespace Campofinale return ""; } } + + public RoleBaseInfo GetRoleBaseInfo() + { + long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + try + { + return new RoleBaseInfo() + { + LeaderCharId = teams[teamIndex].leader, + LeaderPosition = position.ToProto(), + LeaderRotation = rotation.ToProto(), + ServerTs = (ulong)curtimestamp, + SceneName = ResourceManager.levelDatas.Find(l => l.idNum == curSceneNumId).mapIdStr + }; + } + catch (Exception e) + { + + return new RoleBaseInfo() + { + LeaderCharId = teams[teamIndex].leader, + LeaderPosition = position.ToProto(), + LeaderRotation = rotation.ToProto(), + ServerTs = (ulong)curtimestamp + }; + } + + } } } diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index c566aee..16adb7a 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -20,6 +20,7 @@ namespace Campofinale.Resource //TODO Move all tables to separated class public class ResourceManager { + public static Dictionary levelScriptsEvents = new(); // public static Dictionary sceneAreaTable = new(); public static StrIdNumTable strIdNumTable = new StrIdNumTable();// public static Dictionary characterTable = new(); // @@ -67,7 +68,7 @@ namespace Campofinale.Resource public static Dictionary itemTypeTable = new(); // public static Dictionary snsChatTable = new();// public static Dictionary giftItemTable = new(); - public static Dictionary missionDataTable = new(); + public static List missionDataTable = new(); public static InteractiveTable interactiveTable = new(); // public static List levelDatas = new(); diff --git a/Campofinale/Resource/Table/LevelScriptEvent.cs b/Campofinale/Resource/Table/LevelScriptEvent.cs new file mode 100644 index 0000000..ee6fbdc --- /dev/null +++ b/Campofinale/Resource/Table/LevelScriptEvent.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Resource.Table +{ + [TableCfgType("Json/LevelScriptEvents.json", LoadPriority.LOW)] + public class LevelScriptEvent : TableCfgResource + { + public string eventName; + public string comment; + public List actions; + } + public class ScriptAction + { + public ScriptActionType action; + public string[] valueStr; + public ulong[] valueUlong; + } + public enum ScriptActionType + { + None = 0, + CompleteQuest = 1, + ProcessQuest = 2, + SpawnEnemy = 3 + + } +} diff --git a/Campofinale/Resource/Table/MissionDataTable.cs b/Campofinale/Resource/Table/MissionDataTable.cs index 9da1ef7..b85485d 100644 --- a/Campofinale/Resource/Table/MissionDataTable.cs +++ b/Campofinale/Resource/Table/MissionDataTable.cs @@ -6,7 +6,7 @@ { public string missionId; public string rewardId; - public MissionType missionType; + //public MissionType missionType; public string charId; public string levelId; public Dictionary questDic; @@ -22,7 +22,17 @@ public bool autoRestartWhenFailed; public int objectiveConditionNum; public string rewardId; + public List objectiveList; + public class QuestObjective + { + public ObjectiveCond condition; + + public class ObjectiveCond + { + public string uniqueId; + } + } } public enum MissionType {