MissionSystem + Event system (manually re implementation)

This commit is contained in:
AlessandroCH 2025-05-18 16:46:05 +02:00
parent dab3723540
commit cb70fa6f1b
13 changed files with 413 additions and 110 deletions

View File

@ -54,7 +54,7 @@ namespace Campofinale.Game.Entities
Type = (int)5,
},
//Meta =dependencyGroupId,
BattleInfo = new()
{

View File

@ -83,6 +83,7 @@ namespace Campofinale.Game.Entities
Type =(int) ObjectTypeIndex.Enemy,
},
Attrs =
{
GetAttributes()

View File

@ -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()
{
}
}
}

View File

@ -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<GameMission> missions=new();
public List<GameQuest> 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;
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -132,7 +132,8 @@ namespace Campofinale.Packets.Cs
ScSyncAllMission m = Newtonsoft.Json.JsonConvert.DeserializeObject<ScSyncAllMission>(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()
{

View File

@ -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"));

View File

@ -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<CsSceneSetLevelScriptActive>();
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<CsSceneSetLevelScriptStart>();
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<CsSceneLevelScriptEventTrigger>();
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);

View File

@ -9,7 +9,7 @@ namespace Campofinale.Packets.Cs
public static void Handle(Player session, CsMsgId msgId, Packet packet)
{
CsTrackMission req = packet.DecodeBody<CsTrackMission>();
session.missionSystem.curMission = req.MissionId;
ScTrackMissionChange rsp = new()
{
MissionId = req.MissionId

View File

@ -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
};
}
}
}
}

View File

@ -20,6 +20,7 @@ namespace Campofinale.Resource
//TODO Move all tables to separated class
public class ResourceManager
{
public static Dictionary<string, LevelScriptEvent> levelScriptsEvents = new(); //
public static Dictionary<string, SceneAreaTable> sceneAreaTable = new();
public static StrIdNumTable strIdNumTable = new StrIdNumTable();//
public static Dictionary<string, CharacterTable> characterTable = new(); //
@ -67,7 +68,7 @@ namespace Campofinale.Resource
public static Dictionary<int, ItemTypeTable> itemTypeTable = new(); //
public static Dictionary<string, SNSChatTable> snsChatTable = new();//
public static Dictionary<string, GiftItemTable> giftItemTable = new();
public static Dictionary<string, MissionDataTable> missionDataTable = new();
public static List<MissionDataTable> missionDataTable = new();
public static InteractiveTable interactiveTable = new(); //
public static List<LevelScene> levelDatas = new();

View File

@ -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<ScriptAction> actions;
}
public class ScriptAction
{
public ScriptActionType action;
public string[] valueStr;
public ulong[] valueUlong;
}
public enum ScriptActionType
{
None = 0,
CompleteQuest = 1,
ProcessQuest = 2,
SpawnEnemy = 3
}
}

View File

@ -6,7 +6,7 @@
{
public string missionId;
public string rewardId;
public MissionType missionType;
//public MissionType missionType;
public string charId;
public string levelId;
public Dictionary<string, QuestInfo> questDic;
@ -22,7 +22,17 @@
public bool autoRestartWhenFailed;
public int objectiveConditionNum;
public string rewardId;
public List<QuestObjective> objectiveList;
public class QuestObjective
{
public ObjectiveCond condition;
public class ObjectiveCond
{
public string uniqueId;
}
}
}
public enum MissionType
{