From 3fe700a151dbcb932aaf87231caaa6115524de6a Mon Sep 17 00:00:00 2001 From: Somebody Date: Thu, 4 Apr 2024 22:07:29 +0800 Subject: [PATCH] fix some bugs --- Common/Data/Config/FloorInfo.cs | 14 +-- Common/Data/Config/GroupInfo.cs | 31 +++-- Common/Data/Config/MissionInfo.cs | 98 ++++++++++++++++ Common/Data/Config/TaskInfo.cs | 7 +- Common/Data/Excel/AvatarConfigExcel.cs | 3 + Common/Data/Excel/MonsterDropExcel.cs | 77 +++++++++++++ Common/Data/Excel/NPCMonsterDataExcel.cs | 8 +- Common/Data/Excel/PlaneEventExcel.cs | 26 +++++ Common/Data/GameData.cs | 2 + Common/Data/ResourceManager.cs | 36 +++++- Common/Enums/DamageTypeEnum.cs | 19 +++ Common/Enums/MonsterRankEnum.cs | 18 +++ Common/Enums/TaskTypeEnum.cs | 5 +- Common/Proto/BuffInfo.cs | 90 +++++++-------- Common/Util/GameConstants.cs | 2 + Common/Util/Logger.cs | 6 +- GameServer/Command/Cmd/CommandGive.cs | 20 +++- GameServer/Command/Cmd/CommandLineup.cs | 25 ++++ GameServer/Command/Cmd/CommandMission.cs | 58 +++++++++- GameServer/Command/Cmd/CommandScene.cs | 10 ++ GameServer/Game/Battle/BattleInstance.cs | 31 +++-- GameServer/Game/Battle/BattleManager.cs | 108 +++++++++++++----- GameServer/Game/Battle/MazeBuff.cs | 58 ++++++++++ .../Battle/Skill/Action/MazeAddMazeBuff.cs | 25 +++- .../Skill/Action/MazeSetTargetMonsterDie.cs | 33 ++++++ .../Game/Battle/Skill/IMazeSkillAction.cs | 10 +- GameServer/Game/Battle/Skill/MazeSkill.cs | 76 +++++++----- .../Game/Battle/Skill/MazeSkillManager.cs | 4 +- GameServer/Game/Inventory/InventoryManager.cs | 17 ++- GameServer/Game/Lineup/LineupManager.cs | 16 ++- GameServer/Game/Message/MessageManager.cs | 22 +--- .../Handler/MissionHandlerEnterFloor.cs | 2 +- .../Handler/MissionHandlerFinishMission.cs | 36 ++++++ .../Handler/MissionHandlerKillMonster.cs | 32 ++++++ .../Handler/MissionHandlerPropState.cs | 3 +- .../MissionHandlerSubMissionFinishCnt.cs | 6 +- GameServer/Game/Mission/MissionManager.cs | 32 +++++- GameServer/Game/Player/PlayerInstance.cs | 40 +++---- GameServer/Game/Scene/Entity/EntityMonster.cs | 50 +++++++- GameServer/Game/Scene/Entity/EntityNpc.cs | 9 ++ GameServer/Game/Scene/Entity/EntityProp.cs | 9 ++ GameServer/Game/Scene/Entity/IGameEntity.cs | 7 +- GameServer/Game/Scene/SceneBuff.cs | 39 ++++--- GameServer/Game/Scene/SceneEntityLoader.cs | 16 ++- GameServer/Game/Scene/SceneInstance.cs | 23 +++- GameServer/GameServer.csproj | 1 - .../Recv/Battle/HandlerQuitBattleCsReq.cs | 18 +++ .../Recv/Battle/HandlerSceneCastSkillCsReq.cs | 20 +++- .../HandlerGetFriendApplyListInfoCsReq.cs | 17 +++ .../Friend/HandlerGetFriendListInfoCsReq.cs | 17 +++ .../Mission/HandlerGetNpcMessageGroupCsReq.cs | 21 ++++ .../Scene/HandlerGetUnlockTeleportCsReq.cs | 21 ++++ .../PacketSceneCastSkillMpUpdateScNotify.cs | 23 ++++ .../Mission/PacketGetNpcMessageGroupScRsp.cs | 27 +++++ .../Send/Quest/PacketGetQuestDataScRsp.cs | 2 +- .../Scene/PacketGetUnlockTeleportScRsp.cs | 34 ++++++ .../PacketSyncEntityBuffChangeListScNotify.cs | 27 +++++ 57 files changed, 1265 insertions(+), 222 deletions(-) create mode 100644 Common/Data/Excel/MonsterDropExcel.cs create mode 100644 Common/Data/Excel/PlaneEventExcel.cs create mode 100644 Common/Enums/DamageTypeEnum.cs create mode 100644 Common/Enums/MonsterRankEnum.cs create mode 100644 GameServer/Command/Cmd/CommandLineup.cs create mode 100644 GameServer/Game/Battle/MazeBuff.cs create mode 100644 GameServer/Game/Battle/Skill/Action/MazeSetTargetMonsterDie.cs create mode 100644 GameServer/Game/Mission/FinishType/Handler/MissionHandlerFinishMission.cs create mode 100644 GameServer/Game/Mission/FinishType/Handler/MissionHandlerKillMonster.cs create mode 100644 GameServer/Server/Packet/Recv/Battle/HandlerQuitBattleCsReq.cs create mode 100644 GameServer/Server/Packet/Recv/Friend/HandlerGetFriendApplyListInfoCsReq.cs create mode 100644 GameServer/Server/Packet/Recv/Friend/HandlerGetFriendListInfoCsReq.cs create mode 100644 GameServer/Server/Packet/Recv/Mission/HandlerGetNpcMessageGroupCsReq.cs create mode 100644 GameServer/Server/Packet/Recv/Scene/HandlerGetUnlockTeleportCsReq.cs create mode 100644 GameServer/Server/Packet/Send/Lineup/PacketSceneCastSkillMpUpdateScNotify.cs create mode 100644 GameServer/Server/Packet/Send/Mission/PacketGetNpcMessageGroupScRsp.cs create mode 100644 GameServer/Server/Packet/Send/Scene/PacketGetUnlockTeleportScRsp.cs create mode 100644 GameServer/Server/Packet/Send/Scene/PacketSyncEntityBuffChangeListScNotify.cs diff --git a/Common/Data/Config/FloorInfo.cs b/Common/Data/Config/FloorInfo.cs index ec24dba1..ccaf9641 100644 --- a/Common/Data/Config/FloorInfo.cs +++ b/Common/Data/Config/FloorInfo.cs @@ -1,4 +1,6 @@ using EggLink.DanhengServer.Enums; +using EggLink.DanhengServer.Util; +using Newtonsoft.Json; namespace EggLink.DanhengServer.Data.Config { @@ -10,11 +12,14 @@ namespace EggLink.DanhengServer.Data.Config public List GroupList { get; set; } = []; - + [JsonIgnore] public bool Loaded = false; + [JsonIgnore] public Dictionary Groups = []; + [JsonIgnore] public Dictionary CachedTeleports = []; + [JsonIgnore] public List UnlockedCheckpoints = []; public AnchorInfo? GetAnchorInfo(int groupId, int anchorId) @@ -32,18 +37,13 @@ namespace EggLink.DanhengServer.Data.Config // Cache anchors foreach (var group in Groups.Values) { - if (group.PropList == null) - { - continue; - } - foreach (var prop in group.PropList) { // Check if prop can be teleported to if (prop.AnchorID > 0) { // Put inside cached teleport list to send to client when they request map info - CachedTeleports[prop.MappingInfoID] = prop; + CachedTeleports.TryAdd(prop.MappingInfoID, prop); UnlockedCheckpoints.Add(prop); // Force prop to be in the unlocked state diff --git a/Common/Data/Config/GroupInfo.cs b/Common/Data/Config/GroupInfo.cs index 8358b983..4efd55ab 100644 --- a/Common/Data/Config/GroupInfo.cs +++ b/Common/Data/Config/GroupInfo.cs @@ -12,6 +12,7 @@ namespace EggLink.DanhengServer.Data.Config [JsonConverter(typeof(StringEnumConverter))] public GroupLoadSideEnum LoadSide { get; set; } public bool LoadOnInitial { get; set; } + public string GroupName { get; set; } = ""; public LoadCondition LoadCondition { get; set; } = new(); public LoadCondition UnloadCondition { get; set; } = new(); public LoadCondition ForceUnloadCondition { get; set; } = new(); @@ -51,7 +52,10 @@ namespace EggLink.DanhengServer.Data.Config { if (condition.Type == ConditionTypeEnum.MainMission) { - mission.MainMissionInfo.TryGetValue(condition.ID, out var info); + if (!mission.MainMissionInfo.TryGetValue(condition.ID, out var info)) + { + info = MissionPhaseEnum.None; + } if (info != condition.Phase) { if (Operation == OperationEnum.And) @@ -75,12 +79,7 @@ namespace EggLink.DanhengServer.Data.Config if (subMission == null) continue; var mainMissionId = subMission.MainMissionID; mission.MissionInfo.TryGetValue(mainMissionId, out var info); - info ??= new() { { mainMissionId, new() - { - MissionId = condition.ID, - Status = MissionPhaseEnum.None - }} }; - if (info.TryGetValue(condition.ID, out var missionInfo)) + if (info?.TryGetValue(condition.ID, out var missionInfo) == true) { if (missionInfo.Status != condition.Phase) { @@ -98,6 +97,24 @@ namespace EggLink.DanhengServer.Data.Config break; } } + } else + { + if (condition.Phase != MissionPhaseEnum.None) + { + if (Operation == OperationEnum.And) + { + canLoad = false; + break; + } + } + else + { + if (Operation == OperationEnum.Or) + { + canLoad = true; + break; + } + } } } } diff --git a/Common/Data/Config/MissionInfo.cs b/Common/Data/Config/MissionInfo.cs index 905cf517..4e8447dc 100644 --- a/Common/Data/Config/MissionInfo.cs +++ b/Common/Data/Config/MissionInfo.cs @@ -1,4 +1,5 @@ using EggLink.DanhengServer.Enums; +using EggLink.DanhengServer.Util; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -16,6 +17,7 @@ namespace EggLink.DanhengServer.Data.Config { public int ID { get; set; } public int MainMissionID { get; set; } + public string MissionJsonPath { get; set; } = ""; public List TakeParamIntList { get; set; } = []; // the mission's prerequisites [JsonConverter(typeof(StringEnumConverter))] public MissionFinishTypeEnum FinishType { get; set; } @@ -25,6 +27,75 @@ namespace EggLink.DanhengServer.Data.Config public List ParamIntList { get; set; } = []; public List FinishActionList { get; set; } = []; public int Progress { get; set; } + + [JsonIgnore] + public SubMissionTask Task { get; set; } = new(); + [JsonIgnore] + public SubMissionTask PropTask { get; set; } = new(); + + [JsonIgnore] + public int MapEntranceID { get; set; } + + [JsonIgnore] + public int AnchorGroupID { get; set; } + [JsonIgnore] + public int AnchorID { get; set; } + + [JsonIgnore] + public PropStateEnum SourceState { get; set; } = PropStateEnum.Closed; + + public void Loaded(int type) // 1 for EnterFloor, 2 for PropState + { + if (type == 1) + { + try + { + if (Task.OnStartSequece.Count > 0) + { + MapEntranceID = Task.OnStartSequece[0].TaskList[0].EntranceID; + AnchorGroupID = Task.OnStartSequece[0].TaskList[0].GroupID; + AnchorID = Task.OnStartSequece[0].TaskList[0].AnchorID; + } + else if (Task.OnInitSequece.Count > 0) + { + MapEntranceID = Task.OnInitSequece[0].TaskList[0].EntranceID; + AnchorGroupID = Task.OnInitSequece[0].TaskList[0].GroupID; + AnchorID = Task.OnInitSequece[0].TaskList[0].AnchorID; + } + if (MapEntranceID == 0) + { + MapEntranceID = int.Parse(ParamInt2.ToString().Replace("00", "0")); // this is a hacky way to get the MapEntranceID + } + } + catch + { + MapEntranceID = int.Parse(ParamInt2.ToString().Replace("00", "0")); // this is a hacky way to get the MapEntranceID + } + } else if (type == 2) + { + foreach (var task in PropTask.OnStartSequece) + { + foreach (var prop in task.TaskList) + { + if (prop.ButtonCallBack != null) + { + SourceState = prop.ButtonCallBack[0].State; + } + } + } + + foreach (var task in PropTask.OnInitSequece) + { + foreach (var prop in task.TaskList) + { + if (prop.ButtonCallBack != null) + { + SourceState = prop.ButtonCallBack[0].State; + } + } + } + } + } } public class FinishActionInfo @@ -33,4 +104,31 @@ namespace EggLink.DanhengServer.Data.Config public FinishActionTypeEnum FinishActionType { get; set; } public List FinishActionPara { get; set; } = []; } + + public class SubMissionTask + { + public List> OnInitSequece { get; set; } = []; + public List> OnStartSequece { get; set; } = []; + } + + public class SubMissionTaskInfo + { + public List TaskList { get; set; } = []; + } + + public class EnterFloorTaskInfo + { + public int EntranceID { get; set; } + public int GroupID { get; set; } + public int AnchorID { get; set; } + } + + public class PropStateTaskInfo + { + + [JsonConverter(typeof(StringEnumConverter))] + public PropStateEnum State { get; set; } = PropStateEnum.Closed; + + public List? ButtonCallBack { get; set; } + } } diff --git a/Common/Data/Config/TaskInfo.cs b/Common/Data/Config/TaskInfo.cs index 88ae8e3f..c5313be6 100644 --- a/Common/Data/Config/TaskInfo.cs +++ b/Common/Data/Config/TaskInfo.cs @@ -1,6 +1,7 @@ using EggLink.DanhengServer.Enums; using EggLink.DanhengServer.Util; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using System; using System.Collections.Generic; using System.Linq; @@ -68,7 +69,11 @@ namespace EggLink.DanhengServer.Data.Config } else if (Type.Contains("AdventureSetAttackTargetMonsterDie")) { TaskType = TaskTypeEnum.AdventureSetAttackTargetMonsterDie; - } else if (Type.Contains("AdventureTriggerAttack")) + } else if (SuccessTaskList.Count > 0) + { + TaskType = TaskTypeEnum.SuccessTaskList; + } + else if (Type.Contains("AdventureTriggerAttack")) { TaskType = TaskTypeEnum.AdventureTriggerAttack; } else if (Type.Contains("AdventureFireProjectile")) diff --git a/Common/Data/Excel/AvatarConfigExcel.cs b/Common/Data/Excel/AvatarConfigExcel.cs index 99964441..491e19f2 100644 --- a/Common/Data/Excel/AvatarConfigExcel.cs +++ b/Common/Data/Excel/AvatarConfigExcel.cs @@ -18,6 +18,9 @@ namespace EggLink.DanhengServer.Data.Excel [JsonConverter(typeof(StringEnumConverter))] public RarityEnum Rarity { get; set; } = 0; + [JsonConverter(typeof(StringEnumConverter))] + public DamageTypeEnum DamageType { get; set; } = 0; + [JsonIgnore()] public List DefaultSkillTree = []; diff --git a/Common/Data/Excel/MonsterDropExcel.cs b/Common/Data/Excel/MonsterDropExcel.cs new file mode 100644 index 00000000..464f9e55 --- /dev/null +++ b/Common/Data/Excel/MonsterDropExcel.cs @@ -0,0 +1,77 @@ +using EggLink.DanhengServer.Database.Inventory; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Data.Excel +{ + [ResourceEntity("MonsterDrop.json")] + public class MonsterDropExcel : ExcelResource + { + public int MonsterTemplateID { get; set; } + public int WorldLevel { get; set; } + public int AvatarExpReward { get; set; } + + public List DisplayItemList { get; set; } = []; + + [JsonIgnore] + public List DropItemList { get; set; } = []; + + public override int GetId() + { + return MonsterTemplateID * 10 + WorldLevel; + } + + public override void AfterAllDone() + { + foreach (var item in DisplayItemList) + { + GameData.ItemConfigData.TryGetValue(item.ItemID, out var config); + if (config == null) continue; + double mod = config.Rarity switch + { + Enums.ItemRarityEnum.NotNormal => 0.8, + Enums.ItemRarityEnum.Rare => 0.3, + Enums.ItemRarityEnum.VeryRare => 0.125, + Enums.ItemRarityEnum.SuperRare => 0, + _ => 1, + }; + double count = WorldLevel + 3; + var maxCount = (int)(count * mod); + var minCount = (int)(count * mod * 0.5); + item.MinCount = minCount; + item.MaxCount = maxCount; + DropItemList.Add(item); + } + GameData.MonsterDropData.Add(GetId(), this); + } + + public List CalculateDrop() + { + var result = new List(); + foreach (var item in DropItemList) + { + var count = Random.Shared.Next(item.MinCount, item.MaxCount + 1); + result.Add(new ItemData() + { + ItemId = item.ItemID, + Count = count, + }); + } + + return result; + } + } + + public class MonsterDropItem + { + public int ItemID { get; set; } + [JsonIgnore] + public int MinCount { get; set; } + [JsonIgnore] + public int MaxCount { get; set; } + } +} diff --git a/Common/Data/Excel/NPCMonsterDataExcel.cs b/Common/Data/Excel/NPCMonsterDataExcel.cs index 8b53381c..b6a3bf70 100644 --- a/Common/Data/Excel/NPCMonsterDataExcel.cs +++ b/Common/Data/Excel/NPCMonsterDataExcel.cs @@ -1,4 +1,7 @@ -using System; +using EggLink.DanhengServer.Enums; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -12,6 +15,9 @@ namespace EggLink.DanhengServer.Data.Excel public int ID { get; set; } public HashName NPCName { get; set; } = new(); + [JsonConverter(typeof(StringEnumConverter))] + public MonsterRankEnum Rank { get; set; } + public override int GetId() { return ID; diff --git a/Common/Data/Excel/PlaneEventExcel.cs b/Common/Data/Excel/PlaneEventExcel.cs new file mode 100644 index 00000000..12ae701d --- /dev/null +++ b/Common/Data/Excel/PlaneEventExcel.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Data.Excel +{ + [ResourceEntity("PlaneEvent.json")] + public class PlaneEventExcel : ExcelResource + { + public int EventID { get; set; } + public int WorldLevel { get; set; } + public int Reward { get; set; } + + public override int GetId() + { + return EventID * 10 + WorldLevel; + } + + public override void Loaded() + { + GameData.PlaneEventData.Add(GetId(), this); + } + } +} diff --git a/Common/Data/GameData.cs b/Common/Data/GameData.cs index c8c049fd..2f2d510a 100644 --- a/Common/Data/GameData.cs +++ b/Common/Data/GameData.cs @@ -19,6 +19,7 @@ namespace EggLink.DanhengServer.Data public static Dictionary InteractConfigData { get; private set; } = []; public static Dictionary NpcMonsterDataData { get; private set; } = []; public static Dictionary MonsterConfigData { get; private set; } = []; + public static Dictionary MonsterDropData { get; private set; } = []; public static Dictionary NpcDataData { get; private set; } = []; public static Dictionary QuestDataData { get; private set; } = []; public static Dictionary PlayerLevelConfigData { get; private set; } = []; @@ -27,6 +28,7 @@ namespace EggLink.DanhengServer.Data public static Dictionary MapEntranceData { get; private set; } = []; public static Dictionary MazePlaneData { get; private set; } = []; public static Dictionary MazePropData { get; private set; } = []; + public static Dictionary PlaneEventData { get; private set; } = []; public static Dictionary ItemConfigData { get; private set; } = []; public static Dictionary EquipmentConfigData { get; private set; } = []; diff --git a/Common/Data/ResourceManager.cs b/Common/Data/ResourceManager.cs index 10605713..28384c65 100644 --- a/Common/Data/ResourceManager.cs +++ b/Common/Data/ResourceManager.cs @@ -147,7 +147,7 @@ namespace EggLink.DanhengServer.Data } } - foreach (var info in GameData.FloorInfoData.Values) + foreach (var info in GameData.FloorInfoData.Values) { foreach (var groupInfo in info.GroupList) { @@ -174,8 +174,8 @@ namespace EggLink.DanhengServer.Data { missingGroupInfos = true; } - info.OnLoad(); } + info.OnLoad(); } if (missingGroupInfos) Logger.Warn($"Group infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/LevelOutput/Group. Teleports, monster battles, and natural world spawns may not work!"); @@ -207,6 +207,38 @@ namespace EggLink.DanhengServer.Data if (missionInfo != null) { GameData.MainMissionData[missionExcel.Key].MissionInfo = missionInfo; + foreach (var subMission in missionInfo.SubMissionList) + { // load mission json + var missionJsonPath = ConfigManager.Config.Path.ResourcePath + "/" + subMission.MissionJsonPath; + if (File.Exists(missionJsonPath)) + { + var missionJson = File.ReadAllText(missionJsonPath).Replace("$type", "Type"); + try + { + if (subMission.FinishType == Enums.MissionFinishTypeEnum.EnterFloor) + { + var mission = JsonConvert.DeserializeObject>(missionJson); + + if (mission != null) + { + subMission.Task = mission; + subMission.Loaded(1); + } + } else if (subMission.FinishType == Enums.MissionFinishTypeEnum.PropState) + { + var mission = JsonConvert.DeserializeObject>(missionJson); + if (mission != null) + { + subMission.PropTask = mission; + subMission.Loaded(2); + } + } + } catch (Exception ex) + { + Logger.Error("Error in reading" + missionJsonPath, ex); + } + } + } count++; } else { diff --git a/Common/Enums/DamageTypeEnum.cs b/Common/Enums/DamageTypeEnum.cs new file mode 100644 index 00000000..18fc3cec --- /dev/null +++ b/Common/Enums/DamageTypeEnum.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Enums +{ + public enum DamageTypeEnum + { + Physical = 1000111, + Fire = 1000112, + Ice = 1000113, + Thunder = 1000114, + Wind = 1000115, + Quantum = 1000116, + Imaginary = 1000117 + } +} diff --git a/Common/Enums/MonsterRankEnum.cs b/Common/Enums/MonsterRankEnum.cs new file mode 100644 index 00000000..a1aa5577 --- /dev/null +++ b/Common/Enums/MonsterRankEnum.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Enums +{ + public enum MonsterRankEnum + { + Unknown = 0, + Minion = 1, + MinionLv2 = 2, + Elite = 3, + LittleBoss = 4, + BigBoss = 5, + } +} diff --git a/Common/Enums/TaskTypeEnum.cs b/Common/Enums/TaskTypeEnum.cs index 1c3dafc1..5ad37828 100644 --- a/Common/Enums/TaskTypeEnum.cs +++ b/Common/Enums/TaskTypeEnum.cs @@ -15,7 +15,8 @@ namespace EggLink.DanhengServer.Enums AdventureModifyTeamPlayerSP = 4, CreateSummonUnit = 5, AdventureSetAttackTargetMonsterDie = 6, - AdventureTriggerAttack = 7, - AdventureFireProjectile = 8, + SuccessTaskList = 7, + AdventureTriggerAttack = 8, + AdventureFireProjectile = 9, } } diff --git a/Common/Proto/BuffInfo.cs b/Common/Proto/BuffInfo.cs index 90903acd..98898b1a 100644 --- a/Common/Proto/BuffInfo.cs +++ b/Common/Proto/BuffInfo.cs @@ -24,17 +24,17 @@ namespace EggLink.DanhengServer.Proto { static BuffInfoReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "Cg5CdWZmSW5mby5wcm90byL8AQoIQnVmZkluZm8SDwoHYnVmZl9pZBgIIAEo", - "DRIWCg5iYXNlX2F2YXRhcl9pZBgEIAEoDRITCgtMSVBQTExNR0lKQRgFIAEo", - "BBITCgtORUpMRUNCS0hKRxgKIAEoAhI0Cg5keW5hbWljX3ZhbHVlcxgBIAMo", - "CzIcLkJ1ZmZJbmZvLkR5bmFtaWNWYWx1ZXNFbnRyeRINCgVjb3VudBgLIAEo", - "DRITCgtLRElMS0FQTUlPSRgGIAEoDRINCgVsZXZlbBgNIAEoDRo0ChJEeW5h", - "bWljVmFsdWVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgCOgI4", - "AUIeqgIbRWdnTGluay5EYW5oZW5nU2VydmVyLlByb3RvYgZwcm90bzM=")); + "Cg5CdWZmSW5mby5wcm90byL6AQoIQnVmZkluZm8SDwoHYnVmZl9pZBgIIAEo", + "DRIWCg5iYXNlX2F2YXRhcl9pZBgEIAEoDRITCgthZGRfdGltZV9tcxgFIAEo", + "BBIRCglsaWZlX3RpbWUYCiABKAISNAoOZHluYW1pY192YWx1ZXMYASADKAsy", + "HC5CdWZmSW5mby5EeW5hbWljVmFsdWVzRW50cnkSDQoFY291bnQYCyABKA0S", + "EwoLS0RJTEtBUE1JT0kYBiABKA0SDQoFbGV2ZWwYDSABKA0aNAoSRHluYW1p", + "Y1ZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoAjoCOAFC", + "HqoCG0VnZ0xpbmsuRGFuaGVuZ1NlcnZlci5Qcm90b2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.BuffInfo), global::EggLink.DanhengServer.Proto.BuffInfo.Parser, new[]{ "BuffId", "BaseAvatarId", "LIPPLLMGIJA", "NEJLECBKHJG", "DynamicValues", "Count", "KDILKAPMIOI", "Level" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }) + new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.BuffInfo), global::EggLink.DanhengServer.Proto.BuffInfo.Parser, new[]{ "BuffId", "BaseAvatarId", "AddTimeMs", "LifeTime", "DynamicValues", "Count", "KDILKAPMIOI", "Level" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }) })); } #endregion @@ -78,8 +78,8 @@ namespace EggLink.DanhengServer.Proto { public BuffInfo(BuffInfo other) : this() { buffId_ = other.buffId_; baseAvatarId_ = other.baseAvatarId_; - lIPPLLMGIJA_ = other.lIPPLLMGIJA_; - nEJLECBKHJG_ = other.nEJLECBKHJG_; + addTimeMs_ = other.addTimeMs_; + lifeTime_ = other.lifeTime_; dynamicValues_ = other.dynamicValues_.Clone(); count_ = other.count_; kDILKAPMIOI_ = other.kDILKAPMIOI_; @@ -117,27 +117,27 @@ namespace EggLink.DanhengServer.Proto { } } - /// Field number for the "LIPPLLMGIJA" field. - public const int LIPPLLMGIJAFieldNumber = 5; - private ulong lIPPLLMGIJA_; + /// Field number for the "add_time_ms" field. + public const int AddTimeMsFieldNumber = 5; + private ulong addTimeMs_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] - public ulong LIPPLLMGIJA { - get { return lIPPLLMGIJA_; } + public ulong AddTimeMs { + get { return addTimeMs_; } set { - lIPPLLMGIJA_ = value; + addTimeMs_ = value; } } - /// Field number for the "NEJLECBKHJG" field. - public const int NEJLECBKHJGFieldNumber = 10; - private float nEJLECBKHJG_; + /// Field number for the "life_time" field. + public const int LifeTimeFieldNumber = 10; + private float lifeTime_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] - public float NEJLECBKHJG { - get { return nEJLECBKHJG_; } + public float LifeTime { + get { return lifeTime_; } set { - nEJLECBKHJG_ = value; + lifeTime_ = value; } } @@ -205,8 +205,8 @@ namespace EggLink.DanhengServer.Proto { } if (BuffId != other.BuffId) return false; if (BaseAvatarId != other.BaseAvatarId) return false; - if (LIPPLLMGIJA != other.LIPPLLMGIJA) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(NEJLECBKHJG, other.NEJLECBKHJG)) return false; + if (AddTimeMs != other.AddTimeMs) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(LifeTime, other.LifeTime)) return false; if (!DynamicValues.Equals(other.DynamicValues)) return false; if (Count != other.Count) return false; if (KDILKAPMIOI != other.KDILKAPMIOI) return false; @@ -220,8 +220,8 @@ namespace EggLink.DanhengServer.Proto { int hash = 1; if (BuffId != 0) hash ^= BuffId.GetHashCode(); if (BaseAvatarId != 0) hash ^= BaseAvatarId.GetHashCode(); - if (LIPPLLMGIJA != 0UL) hash ^= LIPPLLMGIJA.GetHashCode(); - if (NEJLECBKHJG != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(NEJLECBKHJG); + if (AddTimeMs != 0UL) hash ^= AddTimeMs.GetHashCode(); + if (LifeTime != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(LifeTime); hash ^= DynamicValues.GetHashCode(); if (Count != 0) hash ^= Count.GetHashCode(); if (KDILKAPMIOI != 0) hash ^= KDILKAPMIOI.GetHashCode(); @@ -249,9 +249,9 @@ namespace EggLink.DanhengServer.Proto { output.WriteRawTag(32); output.WriteUInt32(BaseAvatarId); } - if (LIPPLLMGIJA != 0UL) { + if (AddTimeMs != 0UL) { output.WriteRawTag(40); - output.WriteUInt64(LIPPLLMGIJA); + output.WriteUInt64(AddTimeMs); } if (KDILKAPMIOI != 0) { output.WriteRawTag(48); @@ -261,9 +261,9 @@ namespace EggLink.DanhengServer.Proto { output.WriteRawTag(64); output.WriteUInt32(BuffId); } - if (NEJLECBKHJG != 0F) { + if (LifeTime != 0F) { output.WriteRawTag(85); - output.WriteFloat(NEJLECBKHJG); + output.WriteFloat(LifeTime); } if (Count != 0) { output.WriteRawTag(88); @@ -288,9 +288,9 @@ namespace EggLink.DanhengServer.Proto { output.WriteRawTag(32); output.WriteUInt32(BaseAvatarId); } - if (LIPPLLMGIJA != 0UL) { + if (AddTimeMs != 0UL) { output.WriteRawTag(40); - output.WriteUInt64(LIPPLLMGIJA); + output.WriteUInt64(AddTimeMs); } if (KDILKAPMIOI != 0) { output.WriteRawTag(48); @@ -300,9 +300,9 @@ namespace EggLink.DanhengServer.Proto { output.WriteRawTag(64); output.WriteUInt32(BuffId); } - if (NEJLECBKHJG != 0F) { + if (LifeTime != 0F) { output.WriteRawTag(85); - output.WriteFloat(NEJLECBKHJG); + output.WriteFloat(LifeTime); } if (Count != 0) { output.WriteRawTag(88); @@ -328,10 +328,10 @@ namespace EggLink.DanhengServer.Proto { if (BaseAvatarId != 0) { size += 1 + pb::CodedOutputStream.ComputeUInt32Size(BaseAvatarId); } - if (LIPPLLMGIJA != 0UL) { - size += 1 + pb::CodedOutputStream.ComputeUInt64Size(LIPPLLMGIJA); + if (AddTimeMs != 0UL) { + size += 1 + pb::CodedOutputStream.ComputeUInt64Size(AddTimeMs); } - if (NEJLECBKHJG != 0F) { + if (LifeTime != 0F) { size += 1 + 4; } size += dynamicValues_.CalculateSize(_map_dynamicValues_codec); @@ -362,11 +362,11 @@ namespace EggLink.DanhengServer.Proto { if (other.BaseAvatarId != 0) { BaseAvatarId = other.BaseAvatarId; } - if (other.LIPPLLMGIJA != 0UL) { - LIPPLLMGIJA = other.LIPPLLMGIJA; + if (other.AddTimeMs != 0UL) { + AddTimeMs = other.AddTimeMs; } - if (other.NEJLECBKHJG != 0F) { - NEJLECBKHJG = other.NEJLECBKHJG; + if (other.LifeTime != 0F) { + LifeTime = other.LifeTime; } dynamicValues_.MergeFrom(other.dynamicValues_); if (other.Count != 0) { @@ -402,7 +402,7 @@ namespace EggLink.DanhengServer.Proto { break; } case 40: { - LIPPLLMGIJA = input.ReadUInt64(); + AddTimeMs = input.ReadUInt64(); break; } case 48: { @@ -414,7 +414,7 @@ namespace EggLink.DanhengServer.Proto { break; } case 85: { - NEJLECBKHJG = input.ReadFloat(); + LifeTime = input.ReadFloat(); break; } case 88: { @@ -449,7 +449,7 @@ namespace EggLink.DanhengServer.Proto { break; } case 40: { - LIPPLLMGIJA = input.ReadUInt64(); + AddTimeMs = input.ReadUInt64(); break; } case 48: { @@ -461,7 +461,7 @@ namespace EggLink.DanhengServer.Proto { break; } case 85: { - NEJLECBKHJG = input.ReadFloat(); + LifeTime = input.ReadFloat(); break; } case 88: { diff --git a/Common/Util/GameConstants.cs b/Common/Util/GameConstants.cs index 9951e391..05e337bd 100644 --- a/Common/Util/GameConstants.cs +++ b/Common/Util/GameConstants.cs @@ -12,5 +12,7 @@ public const int INVENTORY_MAX_MATERIAL = 2000; public static readonly List UpgradeWorldLevel = [20, 30, 40, 50, 60, 65]; + + public const int AMBUSH_BUFF_ID = 1000102; } } diff --git a/Common/Util/Logger.cs b/Common/Util/Logger.cs index 0dad25c9..46f0b379 100644 --- a/Common/Util/Logger.cs +++ b/Common/Util/Logger.cs @@ -106,10 +106,8 @@ namespace EggLink.DanhengServer.Util { throw new Exception("LogFile is not set"); } - using (StreamWriter sw = LogFile.AppendText()) - { - sw.WriteLine(message); - } + using StreamWriter sw = LogFile.AppendText(); + sw.WriteLine(message); } #pragma warning disable CS8602 diff --git a/GameServer/Command/Cmd/CommandGive.cs b/GameServer/Command/Cmd/CommandGive.cs index d7d2f979..d39b5477 100644 --- a/GameServer/Command/Cmd/CommandGive.cs +++ b/GameServer/Command/Cmd/CommandGive.cs @@ -18,11 +18,23 @@ arg.SendMsg("Target not found."); return; } - arg.CharacterArgs.TryGetValue("x", out var str); - if (str == null) str = "1"; - player.InventoryManager!.AddItem(int.Parse(arg.BasicArgs[0]), int.Parse(str)); - arg.SendMsg($"Give @{player.Uid} item of {arg.BasicArgs[0]}"); + if (arg.BasicArgs.Count == 0) + { + arg.SendMsg("Item not found."); + return; + } + + arg.CharacterArgs.TryGetValue("x", out var str); + str ??= "1"; + if (!int.TryParse(str, out var amount)) + { + arg.SendMsg("Invalid amount."); + return; + } + + player.InventoryManager!.AddItem(int.Parse(arg.BasicArgs[0]), amount); + arg.SendMsg($"Give @{player.Uid} {amount} items of {arg.BasicArgs[0]}"); } } } diff --git a/GameServer/Command/Cmd/CommandLineup.cs b/GameServer/Command/Cmd/CommandLineup.cs new file mode 100644 index 00000000..920edb21 --- /dev/null +++ b/GameServer/Command/Cmd/CommandLineup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Command.Cmd +{ + [CommandInfo("lineup", "manage the player's lineup", "/lineup")] + public class CommandLineup : ICommand + { + [CommandMethod("0 mp")] + public void SetLineupMp(CommandArg arg) + { + if (arg.Target == null) + { + arg.SendMsg("Player not found"); + return; + } + var count = arg.GetInt(0); + arg.Target.Player!.LineupManager!.GainMp(count == 0 ? 2: count); + arg.SendMsg($"Player has gained {count} MP"); + } + } +} diff --git a/GameServer/Command/Cmd/CommandMission.cs b/GameServer/Command/Cmd/CommandMission.cs index 89365333..3cf85b4e 100644 --- a/GameServer/Command/Cmd/CommandMission.cs +++ b/GameServer/Command/Cmd/CommandMission.cs @@ -1,4 +1,6 @@ -namespace EggLink.DanhengServer.Command.Cmd +using System.Text; + +namespace EggLink.DanhengServer.Command.Cmd { [CommandInfo("mission", "Manage the missions", "/mission ")] public class CommandMission : ICommand @@ -15,5 +17,59 @@ mission.GetRunningSubMissionIdList().ForEach(mission.FinishSubMission); arg.SendMsg("Pass all running missions."); } + + [CommandMethod("0 finish")] + public void FinishRunningMission(CommandArg arg) + { + if (arg.Target == null) + { + arg.SendMsg("Player not found."); + return; + } + + if (arg.BasicArgs.Count < 1) + { + arg.SendMsg("Please specify the mission id."); + return; + } + + if (!int.TryParse(arg.BasicArgs[0], out var missionId)) + { + arg.SendMsg("Invalid mission id."); + return; + } + + var mission = arg.Target!.Player!.MissionManager!; + //mission.AcceptSubMission(missionId); + mission.FinishSubMission(missionId); + arg.SendMsg("Finish mission."); + } + + [CommandMethod("0 running")] + public void ListRunningMission(CommandArg arg) + { + if (arg.Target == null) + { + arg.SendMsg("Player not found."); + return; + } + + var mission = arg.Target!.Player!.MissionManager!; + var runningMissions = mission.GetRunningSubMissionIdList(); + if (runningMissions.Count == 0) + { + arg.SendMsg("No running missions."); + return; + } + + var sb = new StringBuilder(); + sb.AppendLine("Running missions:"); + foreach (var missionId in runningMissions) + { + sb.AppendLine(missionId.ToString()); + } + + arg.SendMsg(sb.ToString()); + } } } diff --git a/GameServer/Command/Cmd/CommandScene.cs b/GameServer/Command/Cmd/CommandScene.cs index 4f35b5df..2e92bb97 100644 --- a/GameServer/Command/Cmd/CommandScene.cs +++ b/GameServer/Command/Cmd/CommandScene.cs @@ -13,6 +13,11 @@ namespace EggLink.DanhengServer.Command.Cmd [CommandMethod("0 group")] public void GetLoadedGroup(CommandArg arg) { + if (arg.Target == null) + { + arg.SendMsg("Player not found"); + return; + } var scene = arg.Target!.Player!.SceneInstance!; var loadedGroup = new List(); foreach (var group in scene.Entities) @@ -28,6 +33,11 @@ namespace EggLink.DanhengServer.Command.Cmd [CommandMethod("0 prop")] public void GetProp(CommandArg arg) { + if (arg.Target == null) + { + arg.SendMsg("Player not found"); + return; + } var scene = arg.Target!.Player!.SceneInstance!; EntityProp? prop = null; foreach (var entity in scene.GetEntitiesInGroup(arg.GetInt(0))) diff --git a/GameServer/Game/Battle/BattleInstance.cs b/GameServer/Game/Battle/BattleInstance.cs index 33b913f8..34f4e948 100644 --- a/GameServer/Game/Battle/BattleInstance.cs +++ b/GameServer/Game/Battle/BattleInstance.cs @@ -2,6 +2,7 @@ using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Database; using EggLink.DanhengServer.Database.Avatar; +using EggLink.DanhengServer.Database.Inventory; using EggLink.DanhengServer.Game.Player; using EggLink.DanhengServer.Game.Scene; using EggLink.DanhengServer.Game.Scene.Entity; @@ -17,14 +18,16 @@ namespace EggLink.DanhengServer.Game.Battle public int CocoonWave { get; set; } public int MappingInfoId { get; set; } public int RoundLimit { get; set; } - public int StageId { get; set; } = stages.Count > 0 ? stages[0].StageID : 0; - public int CasterIndex { get; set; } + public int StageId { get; set; } = stages.Count > 0 ? stages[0].StageID : 0; // Set to 0 when hit monster public BattleEndStatus BattleEndStatus { get; set; } + public List MonsterDropItems { get; set; } = []; + public List Stages { get; set; } = stages; public Database.Lineup.LineupInfo Lineup { get; set; } = lineup; public List EntityMonsters { get; set; } = []; - public List Buffs { get; set; } = []; + public List AvatarInfo { get; set; } = []; + public List Buffs { get; set; } = []; public BattleInstance(PlayerInstance player, Database.Lineup.LineupInfo lineup, List monsters) : this(player, lineup, new List()) { @@ -43,10 +46,14 @@ namespace EggLink.DanhengServer.Game.Battle public ItemList GetDropItemList() { - return new() - { + var list = new ItemList(); - }; + foreach (var item in MonsterDropItems) + { + list.ItemList_.Add(item.ToProto()); + } + + return list; } public SceneBattleInfo ToProto() @@ -94,7 +101,17 @@ namespace EggLink.DanhengServer.Game.Battle proto.BattleAvatarList.Add(avatarInstance.ToBattleProto(Player.LineupManager!.GetCurLineup()!, Player.InventoryManager!.Data, avatarType)); } - proto.BuffList.AddRange(Buffs.Select(buff => buff.ToProto(CasterIndex, 1 >> Stages.Count))); + foreach (var monster in EntityMonsters) + { + monster.ApplyBuff(this); + } + + foreach (var avatar in AvatarInfo) + { + avatar.ApplyBuff(this); + } + + proto.BuffList.AddRange(Buffs.Select(buff => buff.ToProto(this))); return proto; } } diff --git a/GameServer/Game/Battle/BattleManager.cs b/GameServer/Game/Battle/BattleManager.cs index 902f711c..209dfb1a 100644 --- a/GameServer/Game/Battle/BattleManager.cs +++ b/GameServer/Game/Battle/BattleManager.cs @@ -1,8 +1,10 @@ using EggLink.DanhengServer.Data; using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Database; +using EggLink.DanhengServer.Database.Inventory; using EggLink.DanhengServer.Game.Battle.Skill; using EggLink.DanhengServer.Game.Player; +using EggLink.DanhengServer.Game.Scene; using EggLink.DanhengServer.Game.Scene.Entity; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Server.Packet.Send.Battle; @@ -13,16 +15,14 @@ namespace EggLink.DanhengServer.Game.Battle { public class BattleManager(PlayerInstance player) : BasePlayerManager(player) { - public void StartBattle(SceneCastSkillCsReq req, MazeSkill skill, int casterAvatarId) + public void StartBattle(SceneCastSkillCsReq req, MazeSkill skill) { if (Player.BattleInstance != null) return; var targetList = new List(); + var avatarList = new List(); var propList = new List(); - if (!skill.TriggerBattle) - { - Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId)); - return; - } + Player.SceneInstance!.AvatarInfo.TryGetValue((int)req.AttackedByEntityId, out var castAvatar); + if (Player.SceneInstance!.AvatarInfo.ContainsKey((int)req.AttackedByEntityId)) { foreach (var entity in req.HitTargetEntityIdList) @@ -72,21 +72,89 @@ namespace EggLink.DanhengServer.Game.Battle Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId)); return; } + foreach (var prop in propList) { Player.SceneInstance!.RemoveEntity(prop); + if (prop.Excel.IsMpRecover) + { + Player.LineupManager!.GainMp(2); + } else if (prop.Excel.IsHpRecover) + { + Player.LineupManager!.GetCurLineup()!.Heal(2000, false); + } } + if (targetList.Count > 0) { + if (castAvatar != null && req.SkillIndex > 0) + { + // cost Mp + Player!.LineupManager!.CostMp(req.AttackedByEntityId, 1); + skill.OnCast(castAvatar); + } // Skill handle + if (!skill.TriggerBattle) + { + skill.OnHitTarget(Player.SceneInstance!.AvatarInfo[(int)req.AttackedByEntityId], targetList); + Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId)); + return; + } + if (castAvatar != null) + { + skill.OnAttack(Player.SceneInstance!.AvatarInfo[(int)req.AttackedByEntityId], targetList); + } + + var triggerBattle = false; + foreach (var target in targetList) + { + if (target.IsAlive) + { + triggerBattle = true; + break; + } + } + if (!triggerBattle) + { + Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId)); + return; + } + BattleInstance battleInstance = new(Player, Player.LineupManager!.GetCurLineup()!, targetList) { WorldLevel = Player.Data.WorldLevel, - CasterIndex = (int)req.CastEntityId, }; + + foreach (var item in Player.LineupManager!.GetCurLineup()!.BaseAvatars!) // get all avatars in the lineup and add them to the battle instance + { + var avatar = Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => x.AvatarInfo.AvatarId == item.BaseAvatarId); + if (avatar != null) + { + avatarList.Add(avatar); + } + } + + MazeBuff mazeBuff; + if (castAvatar != null) + { + var index = battleInstance.Lineup.BaseAvatars!.FindIndex(x => x.BaseAvatarId == castAvatar.AvatarInfo.AvatarId); + mazeBuff = new((int?)castAvatar.AvatarInfo.Excel?.DamageType ?? 0, 1, index); + mazeBuff.DynamicValues.Add("SkillIndex", skill.IsMazeSkill ? 2 : 1); + } else + { + mazeBuff = new(GameConstants.AMBUSH_BUFF_ID, 1, -1) + { + WaveFlag = 1 + }; + } + + if (mazeBuff.BuffID != 0) // avoid adding a buff with ID 0 + { + battleInstance.Buffs.Add(mazeBuff); + } + + battleInstance.AvatarInfo = avatarList; Player.BattleInstance = battleInstance; - battleInstance.CasterIndex = Player.LineupManager!.GetCurLineup()!.BaseAvatars!.FindIndex(x => x.BaseAvatarId == casterAvatarId); - skill.OnEnterBattle(battleInstance); Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, battleInstance)); } else { @@ -183,15 +251,11 @@ namespace EggLink.DanhengServer.Game.Battle switch (req.EndStatus) { case BattleEndStatus.BattleEndWin: - // Remove monsters from the map - Could optimize it a little better - //for (var monster in battle.NpcMonsters) - //{ - // // Dont remove farmable monsters from the scene when they are defeated - // if (monster.isFarmElement()) continue; - // // Remove monster - // player.SceneInstance.RemoveEntity(monster); - //} // Drops + foreach (var monster in battle.EntityMonsters) + { + monster.Kill(); + } // Spend stamina if (battle.StaminaCost > 0) { @@ -208,7 +272,6 @@ namespace EggLink.DanhengServer.Game.Battle updateStatus = false; break; } - if (updateStatus) { var lineup = Player.LineupManager!.GetCurLineup()!; @@ -253,15 +316,6 @@ namespace EggLink.DanhengServer.Game.Battle // call battle end Player.MissionManager!.OnBattleFinish(req); - // remove monster from the scene - if (req.EndStatus == BattleEndStatus.BattleEndWin) - { - foreach (var monster in battle.EntityMonsters) - { - Player.SceneInstance!.RemoveEntity(monster); - } - } - Player.BattleInstance = null; Player.SendPacket(new PacketPVEBattleResultScRsp(req, Player, battle)); } diff --git a/GameServer/Game/Battle/MazeBuff.cs b/GameServer/Game/Battle/MazeBuff.cs new file mode 100644 index 00000000..2d24eedf --- /dev/null +++ b/GameServer/Game/Battle/MazeBuff.cs @@ -0,0 +1,58 @@ +using EggLink.DanhengServer.Game.Scene; +using EggLink.DanhengServer.Proto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Game.Battle +{ + public class MazeBuff(int buffID, int buffLevel, int owner) + { + public int BuffID { get; private set; } = buffID; + public int BuffLevel { get; private set; } = buffLevel; + public int OwnerIndex { get; private set; } = owner; + public int OwnerAvatarId { get; private set; } = -1; + public int? WaveFlag { get; set; } = null; + public int Duration { get; private set; } = -1; + public Dictionary DynamicValues { get; private set; } = []; + + public MazeBuff(SceneBuff buff) : this(buff.BuffID, buff.BuffLevel, 0) + { + Duration = buff.Duration; + OwnerAvatarId = buff.OwnerAvatarId; + } + + public BattleBuff ToProto(BattleInstance battle) + { + return ToProto(battle, WaveFlag ?? -1); + } + + public BattleBuff ToProto(BattleInstance instance, int waveFlag) + { + var buffInfo = new BattleBuff() + { + Id = (uint)BuffID, + Level = (uint)BuffLevel, + OwnerIndex = (uint)OwnerIndex, + WaveFlag = (uint)waveFlag, + }; + + foreach (var item in DynamicValues) + { + buffInfo.DynamicValues.Add(item.Key, item.Value); + } + + if (OwnerAvatarId != -1) + { + buffInfo.OwnerIndex = (uint)instance.Lineup.BaseAvatars!.FindIndex(x => x.BaseAvatarId == OwnerAvatarId); + OwnerIndex = (int)buffInfo.OwnerIndex; + } + if (OwnerIndex != -1) + buffInfo.TargetIndexList.Add((uint)OwnerIndex); + + return buffInfo; + } + } +} diff --git a/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs b/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs index 37dafa11..7096bfa1 100644 --- a/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs +++ b/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs @@ -1,5 +1,7 @@ using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Game.Scene; +using EggLink.DanhengServer.Game.Scene.Entity; using System; using System.Collections.Generic; using System.Linq; @@ -8,16 +10,29 @@ using System.Threading.Tasks; namespace EggLink.DanhengServer.Game.Battle.Skill.Action { - public class MazeAddMazeBuff(int buffId) : IMazeSkillAction + public class MazeAddMazeBuff(int buffId, int duration) : IMazeSkillAction { - public void OnCast() - { + public int BuffId { get; private set; } = buffId; + public void OnAttack(AvatarSceneInfo avatar, List entities) + { + foreach (var entity in entities) + { + entity.TempBuff = new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration); + } } - public void OnEnterBattle(BattleInstance instance) + public void OnCast(AvatarSceneInfo avatar) { - instance.Buffs.Add(new SceneBuff(buffId, 1)); + avatar.BuffList.Add(new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration)); + } + + public void OnHitTarget(AvatarSceneInfo avatar, List entities) + { + foreach (var entity in entities) + { + entity.BuffList.Add(new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration)); + } } } } diff --git a/GameServer/Game/Battle/Skill/Action/MazeSetTargetMonsterDie.cs b/GameServer/Game/Battle/Skill/Action/MazeSetTargetMonsterDie.cs new file mode 100644 index 00000000..045517f7 --- /dev/null +++ b/GameServer/Game/Battle/Skill/Action/MazeSetTargetMonsterDie.cs @@ -0,0 +1,33 @@ +using EggLink.DanhengServer.Game.Scene; +using EggLink.DanhengServer.Game.Scene.Entity; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Game.Battle.Skill.Action +{ + public class MazeSetTargetMonsterDie : IMazeSkillAction + { + public void OnAttack(AvatarSceneInfo avatar, List entities) + { + foreach (var entity in entities) + { + if (entity.MonsterData.Rank < Enums.MonsterRankEnum.Elite) + { + entity.Kill(); + } + } + } + + public void OnCast(AvatarSceneInfo avatar) + { + + } + + public void OnHitTarget(AvatarSceneInfo avatar, List entities) + { + } + } +} diff --git a/GameServer/Game/Battle/Skill/IMazeSkillAction.cs b/GameServer/Game/Battle/Skill/IMazeSkillAction.cs index f9ad4d81..ef4ce1be 100644 --- a/GameServer/Game/Battle/Skill/IMazeSkillAction.cs +++ b/GameServer/Game/Battle/Skill/IMazeSkillAction.cs @@ -1,4 +1,6 @@ -using System; +using EggLink.DanhengServer.Game.Scene; +using EggLink.DanhengServer.Game.Scene.Entity; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,8 +10,10 @@ namespace EggLink.DanhengServer.Game.Battle.Skill { public interface IMazeSkillAction { - public void OnEnterBattle(BattleInstance instance); + public void OnCast(AvatarSceneInfo avatar); - public void OnCast(); + public void OnHitTarget(AvatarSceneInfo avatar, List entities); + + public void OnAttack(AvatarSceneInfo avatar, List entities); } } diff --git a/GameServer/Game/Battle/Skill/MazeSkill.cs b/GameServer/Game/Battle/Skill/MazeSkill.cs index 6e10f00c..5661329a 100644 --- a/GameServer/Game/Battle/Skill/MazeSkill.cs +++ b/GameServer/Game/Battle/Skill/MazeSkill.cs @@ -1,5 +1,8 @@ using EggLink.DanhengServer.Data.Config; +using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Game.Battle.Skill.Action; +using EggLink.DanhengServer.Game.Scene; +using EggLink.DanhengServer.Game.Scene.Entity; using EggLink.DanhengServer.Util; using System; using System.Collections.Generic; @@ -13,29 +16,17 @@ namespace EggLink.DanhengServer.Game.Battle.Skill { public List Actions { get; private set; } = []; public bool TriggerBattle { get; private set; } = true; - public MazeSkill(List taskInfos) + public bool IsMazeSkill { get; private set; } = true; + public AvatarConfigExcel? Excel { get; private set; } + + public MazeSkill(List taskInfos, bool isSkill = false, AvatarConfigExcel? excel = null) { foreach (var task in taskInfos) { AddAction(task); - foreach (var t in task.SuccessTaskList) - { - AddAction(t); - } - foreach (var t in task.GetAttackInfo()) - { - AddAction(t); - } - - foreach (var t in task.OnProjectileHit) - { - AddAction(t); - } - foreach (var t in task.OnProjectileLifetimeFinish) - { - AddAction(t); - } } + IsMazeSkill = isSkill; + Excel = excel; } public void AddAction(TaskInfo task) @@ -45,9 +36,10 @@ namespace EggLink.DanhengServer.Game.Battle.Skill case Enums.TaskTypeEnum.None: break; case Enums.TaskTypeEnum.AddMazeBuff: - Actions.Add(new MazeAddMazeBuff(task.ID)); + Actions.Add(new MazeAddMazeBuff(task.ID, 20)); break; case Enums.TaskTypeEnum.RemoveMazeBuff: + Actions.RemoveAll(a => a is MazeAddMazeBuff buff && buff.BuffId == task.ID); break; case Enums.TaskTypeEnum.AdventureModifyTeamPlayerHP: break; @@ -56,28 +48,60 @@ namespace EggLink.DanhengServer.Game.Battle.Skill case Enums.TaskTypeEnum.CreateSummonUnit: break; case Enums.TaskTypeEnum.AdventureSetAttackTargetMonsterDie: + Actions.Add(new MazeSetTargetMonsterDie()); + break; + case Enums.TaskTypeEnum.SuccessTaskList: + foreach (var t in task.SuccessTaskList) + { + AddAction(t); + } break; case Enums.TaskTypeEnum.AdventureTriggerAttack: + if (IsMazeSkill) + { + TriggerBattle = task.TriggerBattle; + } + foreach (var t in task.GetAttackInfo()) { AddAction(t); } break; case Enums.TaskTypeEnum.AdventureFireProjectile: - break; - } + foreach (var t in task.OnProjectileHit) + { + AddAction(t); + } - if (!task.TriggerBattle) - { - TriggerBattle = false; + foreach (var t in task.OnProjectileLifetimeFinish) + { + AddAction(t); + } + break; } } - public void OnEnterBattle(BattleInstance instance) + public void OnCast(AvatarSceneInfo info) { foreach (var action in Actions) { - action.OnEnterBattle(instance); + action.OnCast(info); + } + } + + public void OnAttack(AvatarSceneInfo info, List entities) + { + foreach (var action in Actions) + { + action.OnAttack(info, entities); + } + } + + public void OnHitTarget(AvatarSceneInfo info, List entities) + { + foreach (var action in Actions) + { + action.OnHitTarget(info, entities); } } } diff --git a/GameServer/Game/Battle/Skill/MazeSkillManager.cs b/GameServer/Game/Battle/Skill/MazeSkillManager.cs index 819737e7..bc884e0e 100644 --- a/GameServer/Game/Battle/Skill/MazeSkillManager.cs +++ b/GameServer/Game/Battle/Skill/MazeSkillManager.cs @@ -18,12 +18,12 @@ namespace EggLink.DanhengServer.Game.Battle.Skill if (skillIndex == 0) { // normal atk - mazeSkill = new(avatarConfig.MazeAtk?.OnStart.ToList() ?? []); + mazeSkill = new(avatarConfig.MazeAtk?.OnStart.ToList() ?? [], false, avatarConfig); } else { // maze skill - mazeSkill = new(avatarConfig.MazeSkill?.OnStart.ToList() ?? []); + mazeSkill = new(avatarConfig.MazeSkill?.OnStart.ToList() ?? [], true, avatarConfig); } return mazeSkill; } diff --git a/GameServer/Game/Inventory/InventoryManager.cs b/GameServer/Game/Inventory/InventoryManager.cs index 2b553d5a..439a8f98 100644 --- a/GameServer/Game/Inventory/InventoryManager.cs +++ b/GameServer/Game/Inventory/InventoryManager.cs @@ -20,7 +20,11 @@ namespace EggLink.DanhengServer.Game.Inventory { foreach (var item in items) { - AddItem(item.ItemId, items.Count, true, false); + AddItem(item.ItemId, items.Count, false, false); + } + if (notify) + { + Player.SendPacket(new PacketScenePlaneEventScNotify(items)); } DatabaseHelper.Instance?.UpdateInstance(Data); @@ -104,7 +108,7 @@ namespace EggLink.DanhengServer.Game.Inventory if (avatar != null && avatar.Excel != null) { var rankUpItem = Player.InventoryManager!.GetItem(avatar.Excel.RankUpItemId); - if (avatar.Rank + rankUpItem?.Count <= 5) + if ((avatar.Rank + rankUpItem?.Count ?? 0) <= 5) itemData = PutItem(avatar.Excel.RankUpItemId, 1); } else @@ -285,6 +289,15 @@ namespace EggLink.DanhengServer.Game.Inventory return null; } + public void HandlePlaneEvent(int eventId) + { + GameData.PlaneEventData.TryGetValue(eventId * 10 + Player.Data.WorldLevel, out var planeEvent); + if (planeEvent == null) return; + GameData.RewardDataData.TryGetValue(planeEvent.Reward, out var rewardData); + if (rewardData == null) return; + rewardData.GetItems().ForEach(x => AddItem(x.Item1, x.Item2)); + } + #region Equip public void EquipAvatar(int baseAvatarId, int equipmentUniqueId) diff --git a/GameServer/Game/Lineup/LineupManager.cs b/GameServer/Game/Lineup/LineupManager.cs index 2aeff393..e33affa7 100644 --- a/GameServer/Game/Lineup/LineupManager.cs +++ b/GameServer/Game/Lineup/LineupManager.cs @@ -210,7 +210,7 @@ namespace EggLink.DanhengServer.Game.Lineup avatarInfo = Player.AvatarManager!.GetAvatar(avatar.BaseAvatarId); } if (avatarInfo == null) continue; - avatarList.Add(new AvatarSceneInfo(avatarInfo, avatarType)); + avatarList.Add(new AvatarSceneInfo(avatarInfo, avatarType, Player)); } return avatarList; @@ -220,5 +220,19 @@ namespace EggLink.DanhengServer.Game.Lineup { return GetAvatarsFromTeam(LineupData.CurLineup); } + + public void CostMp(uint entityId, int count) + { + LineupData.Mp -= count; + DatabaseHelper.Instance?.UpdateInstance(LineupData); + Player.SendPacket(new PacketSceneCastSkillMpUpdateScNotify(entityId, LineupData.Mp)); + } + + public void GainMp(int count) + { + LineupData.Mp += count; + DatabaseHelper.Instance?.UpdateInstance(LineupData); + Player.SendPacket(new PacketSyncLineupNotify(GetCurLineup()!)); + } } } diff --git a/GameServer/Game/Message/MessageManager.cs b/GameServer/Game/Message/MessageManager.cs index 23d1efc1..f8353656 100644 --- a/GameServer/Game/Message/MessageManager.cs +++ b/GameServer/Game/Message/MessageManager.cs @@ -17,6 +17,7 @@ namespace EggLink.DanhengServer.Game.Message public class MessageManager(PlayerInstance player) : BasePlayerManager(player) { public MessageData Data { get; private set; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew(player.Uid); + public List PendingMessagePerformSectionList { get; private set; } = []; #region Get @@ -166,6 +167,9 @@ namespace EggLink.DanhengServer.Game.Message var notify = new PacketPlayerSyncScNotify(group, section); Player.SendPacket(notify); + // broadcast to mission system + Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessagePerformSectionFinish); + Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessageSectionFinish); } public void FinishMessageItem(int itemId) @@ -183,18 +187,7 @@ namespace EggLink.DanhengServer.Game.Message { ItemId = itemId, }); - if (itemConfig.NextItemIDList.Count == 0) - { - // finish - section.Status = MessageSectionStatus.MessageSectionFinish; - if (group.Sections.All(m => m.Status == MessageSectionStatus.MessageSectionFinish)) - { - group.Status = MessageGroupStatus.MessageGroupFinish; - } - } else - { - section.ToChooseItemId.AddRange(itemConfig.NextItemIDList); - } + section.ToChooseItemId.AddRange(itemConfig.NextItemIDList); group.RefreshTime = Extensions.GetUnixSec(); @@ -202,11 +195,6 @@ namespace EggLink.DanhengServer.Game.Message // sync var notify = new PacketPlayerSyncScNotify(group, section); Player.SendPacket(notify); - - // broadcast to mission system - Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessagePerformSectionFinish); - Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessageSectionFinish); - } #endregion diff --git a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerEnterFloor.cs b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerEnterFloor.cs index 2b6680b3..edbc7c91 100644 --- a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerEnterFloor.cs +++ b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerEnterFloor.cs @@ -18,7 +18,7 @@ namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg) { - player.EnterMissionScene(info.ParamInt2, info.ParamInt2, true); + player.EnterMissionScene(info.MapEntranceID, info.AnchorGroupID, info.AnchorID, true); player.MissionManager!.FinishSubMission(info.ID); } } diff --git a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerFinishMission.cs b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerFinishMission.cs new file mode 100644 index 00000000..0fd57e59 --- /dev/null +++ b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerFinishMission.cs @@ -0,0 +1,36 @@ +using EggLink.DanhengServer.Data.Config; +using EggLink.DanhengServer.Enums; +using EggLink.DanhengServer.Game.Player; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler +{ + [MissionFinishType(MissionFinishTypeEnum.FinishMission)] + public class MissionHandlerFinishMission : MissionFinishTypeHandler + { + public override void Init(PlayerInstance player, SubMissionInfo info, object? arg) + { + } + + public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg) + { + var send = true; + foreach (var mainMissionId in info.ParamIntList) + { + if (player.MissionManager!.GetMainMissionStatus(mainMissionId) != MissionPhaseEnum.Finish) + { + send = false; + break; + } + } + if (send) + { + player.MissionManager!.FinishSubMission(info.ID); + } + } + } +} diff --git a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerKillMonster.cs b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerKillMonster.cs new file mode 100644 index 00000000..03404b20 --- /dev/null +++ b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerKillMonster.cs @@ -0,0 +1,32 @@ +using EggLink.DanhengServer.Data.Config; +using EggLink.DanhengServer.Enums; +using EggLink.DanhengServer.Game.Player; +using EggLink.DanhengServer.Game.Scene.Entity; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler +{ + [MissionFinishType(MissionFinishTypeEnum.KillMonster)] + public class MissionHandlerKillMonster : MissionFinishTypeHandler + { + public override void Init(PlayerInstance player, SubMissionInfo info, object? arg) + { + } + + public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg) + { + if (arg is not EntityMonster monster) return; + if (monster.InstID == info.ParamInt2) + { + if (!monster.IsAlive) + { + player.MissionManager!.FinishSubMission(info.ID); + } + } + } + } +} diff --git a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerPropState.cs b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerPropState.cs index 8c691335..48d282dc 100644 --- a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerPropState.cs +++ b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerPropState.cs @@ -19,8 +19,7 @@ namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler { if (info.ParamInt3 != 0) { - //player.MissionManager!.FinishSubMission(subMissionId); - p.SetState(PropStateEnum.Closed); + p.SetState(info.SourceState); } } } diff --git a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerSubMissionFinishCnt.cs b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerSubMissionFinishCnt.cs index 03140c16..4712c759 100644 --- a/GameServer/Game/Mission/FinishType/Handler/MissionHandlerSubMissionFinishCnt.cs +++ b/GameServer/Game/Mission/FinishType/Handler/MissionHandlerSubMissionFinishCnt.cs @@ -14,13 +14,13 @@ namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg) { - var finish = true; + var finish = false; foreach (var missionId in info.ParamIntList) { var status = player.MissionManager!.GetSubMissionStatus(missionId); - if (status != MissionPhaseEnum.Finish && status != MissionPhaseEnum.Cancel) + if (status == MissionPhaseEnum.Finish || status == MissionPhaseEnum.Cancel) { - finish = false; + finish = true; break; } } diff --git a/GameServer/Game/Mission/MissionManager.cs b/GameServer/Game/Mission/MissionManager.cs index eaff22cc..5a4ce565 100644 --- a/GameServer/Game/Mission/MissionManager.cs +++ b/GameServer/Game/Mission/MissionManager.cs @@ -59,6 +59,13 @@ namespace EggLink.DanhengServer.Game.Mission var list = new List(); mission.MissionInfo?.StartSubMissionList.ForEach(i => list.Add(AcceptSubMission(i, sendPacket))); + if (missionId == 4030001) + { + // skip not implemented + mission.MissionInfo?.StartSubMissionList.ForEach(FinishSubMission); + mission.MissionInfo?.FinishSubMissionList.ForEach(AcceptSubMission); + mission.MissionInfo?.FinishSubMissionList.ForEach(FinishSubMission); + } return list; } @@ -93,10 +100,12 @@ namespace EggLink.DanhengServer.Game.Mission DatabaseHelper.Instance?.UpdateInstance(Data); if (sendPacket) Player.SendPacket(new PacketPlayerSyncScNotify(sync)); Player.SceneInstance!.SyncGroupInfo(); - if (doFinishTypeAction && mission.SubMissionInfo != null) + if (mission.SubMissionInfo != null) { FinishTypeHandlers.TryGetValue(mission.SubMissionInfo.FinishType, out var handler); handler?.Init(Player, mission.SubMissionInfo, null); + if (doFinishTypeAction) + handler?.HandleFinishType(Player, mission.SubMissionInfo, null); } return sync; } @@ -104,11 +113,27 @@ namespace EggLink.DanhengServer.Game.Mission public void FinishMainMission(int missionId) { if (!Data.MainMissionInfo.TryGetValue(missionId, out var value)) return; + if (!GameData.MainMissionData.TryGetValue(missionId, out var mainMission)) return; if (value != MissionPhaseEnum.Doing) return; Data.MainMissionInfo[missionId] = MissionPhaseEnum.Finish; var sync = new Proto.MissionSync(); sync.MainMissionIdList.Add((uint)missionId); // get next main mission + foreach (var mission in mainMission.SubMissionIds) + { + if (GetSubMissionStatus(mission) != MissionPhaseEnum.Finish) + { + Data.MissionInfo.TryGetValue(missionId, out var info); + if (info != null) + { + info[mission] = new() + { + MissionId = mission, + Status = MissionPhaseEnum.Cancel + }; + } + } + } foreach (var nextMission in GameData.MainMissionData.Values) { if (!nextMission.IsEqual(Data)) continue; @@ -125,6 +150,7 @@ namespace EggLink.DanhengServer.Game.Mission Player.SendPacket(new PacketPlayerSyncScNotify(sync)); Player.SendPacket(new PacketStartFinishMainMissionScNotify(missionId)); HandleMissionReward(missionId); + HandleFinishType(MissionFinishTypeEnum.FinishMission); DatabaseHelper.Instance?.UpdateInstance(Data); } @@ -161,7 +187,7 @@ namespace EggLink.DanhengServer.Game.Mission } if (canAccept) { - var s = AcceptSubMission(nextMission.ID, false, true); + var s = AcceptSubMission(nextMission.ID, false, false); if (s != null) { sync.MissionList.Add(new Proto.Mission() @@ -343,7 +369,7 @@ namespace EggLink.DanhengServer.Game.Mission foreach (var mission in GetRunningSubMissionIdList()) { var subMission = GetSubMissionInfo(mission); - if (subMission != null && (subMission.FinishType == MissionFinishTypeEnum.StageWin || subMission.FinishType == MissionFinishTypeEnum.KillMonster) && req.EndStatus == Proto.BattleEndStatus.BattleEndWin) // TODO: Move to handler + if (subMission != null && (subMission.FinishType == MissionFinishTypeEnum.StageWin && req.EndStatus == Proto.BattleEndStatus.BattleEndWin)) // TODO: Move to handler { FinishSubMission(mission); } diff --git a/GameServer/Game/Player/PlayerInstance.cs b/GameServer/Game/Player/PlayerInstance.cs index 61e84b12..711094e3 100644 --- a/GameServer/Game/Player/PlayerInstance.cs +++ b/GameServer/Game/Player/PlayerInstance.cs @@ -174,28 +174,19 @@ namespace EggLink.DanhengServer.Game.Player public void OnAddExp() { - GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out var config); - if (config == null) return; - var nextExp = config.PlayerExp; - for (int i = 1; i <= Data.Level; i++) - { - GameData.PlayerLevelConfigData.TryGetValue(i, out config); - if (config == null) continue; - nextExp -= config.PlayerExp; - } + GameData.PlayerLevelConfigData.TryGetValue(Data.Level, out var config); + GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out var config2); + if (config == null || config2 == null) return; + var nextExp = config2.PlayerExp - config.PlayerExp; + while (Data.Exp >= nextExp) { Data.Exp -= nextExp; Data.Level++; - GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out config); - if (config == null) break; - nextExp = config.PlayerExp; - for (int i = 1; i <= Data.Level; i++) - { - GameData.PlayerLevelConfigData.TryGetValue(i, out config); - if (config == null) continue; - nextExp -= config.PlayerExp; - } + GameData.PlayerLevelConfigData.TryGetValue(Data.Level, out config); + GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out config2); + if (config == null || config2 == null) break; + nextExp = config2.PlayerExp - config.PlayerExp; } OnLevelChange(); @@ -313,6 +304,9 @@ namespace EggLink.DanhengServer.Game.Player // for mission MissionManager!.OnPlayerInteractWithProp(); + // plane event + InventoryManager!.HandlePlaneEvent(prop.PropInfo.EventID); + return prop; } } @@ -348,16 +342,16 @@ namespace EggLink.DanhengServer.Game.Player LoadScene(entrance.PlaneID, entrance.FloorID, entryId, anchor!.ToPositionProto(), anchor.ToRotationProto(), sendPacket); } - public void EnterMissionScene(int floorId, int entryId, bool sendPacket) + public void EnterMissionScene(int entranceId, int anchorGroupId, int anchorId, bool sendPacket) { - var entrance = GameData.GetMapEntrance(floorId, MissionManager!.Data); + GameData.MapEntranceData.TryGetValue(entranceId, out var entrance); if (entrance == null) return; GameData.GetFloorInfo(entrance.PlaneID, entrance.FloorID, out var floorInfo); if (floorInfo == null) return; - int StartGroup = entrance.StartGroupID; - int StartAnchor = entrance.StartAnchorID; + int StartGroup = anchorGroupId == 0 ? entrance.StartGroupID : anchorGroupId; + int StartAnchor = anchorId == 0 ? entrance.StartAnchorID : anchorId; if (StartAnchor == 0) { @@ -366,7 +360,7 @@ namespace EggLink.DanhengServer.Game.Player } AnchorInfo? anchor = floorInfo.GetAnchorInfo(StartGroup, StartAnchor); - LoadScene(entrance.PlaneID, entrance.FloorID, entryId, anchor!.ToPositionProto(), anchor.ToRotationProto(), sendPacket); + LoadScene(entrance.PlaneID, entrance.FloorID, entranceId, anchor!.ToPositionProto(), anchor.ToRotationProto(), sendPacket); } public void MoveTo(Position position) diff --git a/GameServer/Game/Scene/Entity/EntityMonster.cs b/GameServer/Game/Scene/Entity/EntityMonster.cs index 25cdc237..e147c281 100644 --- a/GameServer/Game/Scene/Entity/EntityMonster.cs +++ b/GameServer/Game/Scene/Entity/EntityMonster.cs @@ -1,6 +1,11 @@ -using EggLink.DanhengServer.Data.Config; +using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Data.Config; using EggLink.DanhengServer.Data.Excel; +using EggLink.DanhengServer.Database.Inventory; +using EggLink.DanhengServer.Enums; +using EggLink.DanhengServer.Game.Battle; using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Server.Packet.Send.Scene; using EggLink.DanhengServer.Util; using System; using System.Collections.Generic; @@ -19,12 +24,54 @@ namespace EggLink.DanhengServer.Game.Scene.Entity public int InstID { get; set; } = InstID; public NPCMonsterDataExcel MonsterData { get; set; } = excel; public MonsterInfo Info { get; set; } = info; + public List BuffList { get; set; } = []; + public SceneBuff? TempBuff { get; set; } + public bool IsAlive { get; private set; } = true; + + public void AddBuff(SceneBuff buff) + { + BuffList.Add(buff); + scene.Player.SendPacket(new PacketSyncEntityBuffChangeListScNotify(this, buff)); + } + + public void ApplyBuff(BattleInstance instance) + { + if (TempBuff != null) + { + instance.Buffs.Add(new MazeBuff(TempBuff)); + TempBuff = null; + } + foreach (var buff in BuffList) + { + if (buff.IsExpired()) + { + continue; + } + instance.Buffs.Add(new MazeBuff(buff)); + } + } public int GetStageId() { return Info.EventID * 10 + scene.Player.Data.WorldLevel; } + public List Kill() + { + scene.RemoveEntity(this); + IsAlive = false; + + GameData.MonsterDropData.TryGetValue(MonsterData.ID * 10 + scene.Player.Data.WorldLevel, out var dropData); + if (dropData == null) return []; + var dropItems = dropData.CalculateDrop(); + scene.Player.InventoryManager!.AddItems(dropItems); + + // TODO: Rogue support + // call mission handler + scene.Player.MissionManager!.HandleFinishType(MissionFinishTypeEnum.KillMonster, this); + return dropItems; + } + public SceneEntityInfo ToProto() { return new() @@ -43,7 +90,6 @@ namespace EggLink.DanhengServer.Game.Scene.Entity MonsterId = (uint)MonsterData.ID, WorldLevel = (uint)scene.Player.Data.WorldLevel, } - }; } } diff --git a/GameServer/Game/Scene/Entity/EntityNpc.cs b/GameServer/Game/Scene/Entity/EntityNpc.cs index 23315c7d..bc47582e 100644 --- a/GameServer/Game/Scene/Entity/EntityNpc.cs +++ b/GameServer/Game/Scene/Entity/EntityNpc.cs @@ -1,4 +1,5 @@ using EggLink.DanhengServer.Data.Config; +using EggLink.DanhengServer.Game.Battle; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Util; using Microsoft.Extensions.Logging; @@ -27,6 +28,14 @@ namespace EggLink.DanhengServer.Game.Scene.Entity #endregion + public void AddBuff(SceneBuff buff) + { + } + + public void ApplyBuff(BattleInstance instance) + { + } + public SceneEntityInfo ToProto() { SceneNpcInfo npc = new() diff --git a/GameServer/Game/Scene/Entity/EntityProp.cs b/GameServer/Game/Scene/Entity/EntityProp.cs index 22cf3c37..bdcadde1 100644 --- a/GameServer/Game/Scene/Entity/EntityProp.cs +++ b/GameServer/Game/Scene/Entity/EntityProp.cs @@ -1,6 +1,7 @@ using EggLink.DanhengServer.Data.Config; using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Enums; +using EggLink.DanhengServer.Game.Battle; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Server.Packet.Send.Scene; using EggLink.DanhengServer.Util; @@ -21,6 +22,14 @@ namespace EggLink.DanhengServer.Game.Scene.Entity public PropRogueInfo? RogueInfo { get; set; } + public void AddBuff(SceneBuff buff) + { + } + + public void ApplyBuff(BattleInstance instance) + { + } + public void SetState(PropStateEnum state) { SetState(state, scene.IsLoaded); diff --git a/GameServer/Game/Scene/Entity/IGameEntity.cs b/GameServer/Game/Scene/Entity/IGameEntity.cs index ddc86742..3b9d61f9 100644 --- a/GameServer/Game/Scene/Entity/IGameEntity.cs +++ b/GameServer/Game/Scene/Entity/IGameEntity.cs @@ -1,4 +1,5 @@ -using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Game.Battle; +using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Util; using System; using System.Collections.Generic; @@ -13,6 +14,10 @@ namespace EggLink.DanhengServer.Game.Scene.Entity public int EntityID { get; set; } public int GroupID { get; set; } + public void AddBuff(SceneBuff buff); + public void ApplyBuff(BattleInstance instance); + + public SceneEntityInfo ToProto(); } } diff --git a/GameServer/Game/Scene/SceneBuff.cs b/GameServer/Game/Scene/SceneBuff.cs index 98e87fa4..4d202c06 100644 --- a/GameServer/Game/Scene/SceneBuff.cs +++ b/GameServer/Game/Scene/SceneBuff.cs @@ -1,4 +1,5 @@ using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Util; using System; using System.Collections.Generic; using System.Linq; @@ -7,24 +8,34 @@ using System.Threading.Tasks; namespace EggLink.DanhengServer.Game.Scene { - public class SceneBuff + public class SceneBuff(int buffID, int buffLevel, int owner, int duration = -1) { - public int BuffID { get; private set; } - public int BuffLevel { get; private set; } + public int BuffID { get; private set; } = buffID; + public int BuffLevel { get; private set; } = buffLevel; + public int OwnerAvatarId { get; private set; } = owner; - public SceneBuff(int buffID, int buffLevel) + public int Duration { get; private set; } = duration * 1000; // in milliseconds + public long CreatedTime { get; private set; } = Extensions.GetUnixMs(); + public Dictionary DynamicValues = []; + + public bool IsExpired() { - BuffID = buffID; - BuffLevel = buffLevel; + if (Duration == -1) + return true; // Permanent buff + return Extensions.GetUnixMs() - CreatedTime >= Duration; } - public BattleBuff ToProto(int owner, int waveFlag) => new() - { - Id = (uint)BuffID, - Level = (uint)BuffLevel, - OwnerIndex = (uint)owner, - WaveFlag = (uint)waveFlag, - TargetIndexList = { (uint)owner }, - }; + public BuffInfo ToProto() { + var buffInfo = new BuffInfo() + { + BuffId = (uint)BuffID, + Level = (uint)BuffLevel, + BaseAvatarId = (uint)OwnerAvatarId, + AddTimeMs = (ulong)CreatedTime, + LifeTime = (ulong)Duration, + }; + + return buffInfo; + } } } diff --git a/GameServer/Game/Scene/SceneEntityLoader.cs b/GameServer/Game/Scene/SceneEntityLoader.cs index aac901d5..5ee9d7b7 100644 --- a/GameServer/Game/Scene/SceneEntityLoader.cs +++ b/GameServer/Game/Scene/SceneEntityLoader.cs @@ -3,6 +3,7 @@ using EggLink.DanhengServer.Data.Config; using EggLink.DanhengServer.Enums; using EggLink.DanhengServer.Game.Scene.Entity; using EggLink.DanhengServer.Server.Packet.Send.Scene; +using EggLink.DanhengServer.Util; namespace EggLink.DanhengServer.Game.Scene { @@ -18,7 +19,10 @@ namespace EggLink.DanhengServer.Game.Scene { continue; } - + if (group.GroupName.Contains("TrainVisitor")) + { + continue; + } LoadGroup(group); } scene.IsLoaded = true; @@ -44,6 +48,11 @@ namespace EggLink.DanhengServer.Game.Scene continue; } + if (group.GroupName.Contains("TrainVisitor")) + { + continue; + } + if (oldGroupId.Contains(group.Id)) // check if it should be unloaded { if (group.UnloadCondition.IsTrue(scene.Player.MissionManager!.Data, false) || group.ForceUnloadCondition.IsTrue(scene.Player.MissionManager!.Data, false)) @@ -194,7 +203,10 @@ namespace EggLink.DanhengServer.Game.Scene } else { - prop.SetState(info.State); + if (info.State == PropStateEnum.Locked) + prop.SetState(PropStateEnum.Closed); + else + prop.SetState(info.State); } return prop; } diff --git a/GameServer/Game/Scene/SceneInstance.cs b/GameServer/Game/Scene/SceneInstance.cs index f4263c0e..b3d18fc3 100644 --- a/GameServer/Game/Scene/SceneInstance.cs +++ b/GameServer/Game/Scene/SceneInstance.cs @@ -3,6 +3,7 @@ using EggLink.DanhengServer.Data.Config; using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Database; using EggLink.DanhengServer.Database.Avatar; +using EggLink.DanhengServer.Game.Battle; using EggLink.DanhengServer.Game.Player; using EggLink.DanhengServer.Game.Scene.Entity; using EggLink.DanhengServer.Proto; @@ -95,6 +96,7 @@ namespace EggLink.DanhengServer.Game.Scene { if (AvatarInfo.Values.ToList().FindIndex(x => x.AvatarInfo.AvatarId == avatar.AvatarInfo.AvatarId) == -1) { + avatar.AvatarInfo.EntityId = 0; RemoveAvatar.Add(avatar); sendPacket = true; } @@ -274,7 +276,7 @@ namespace EggLink.DanhengServer.Game.Scene #endregion } - public class AvatarSceneInfo(AvatarInfo avatarInfo, AvatarType avatarType) : IGameEntity + public class AvatarSceneInfo(AvatarInfo avatarInfo, AvatarType avatarType, PlayerInstance Player) : IGameEntity { public AvatarInfo AvatarInfo = avatarInfo; public AvatarType AvatarType = avatarType; @@ -282,6 +284,25 @@ namespace EggLink.DanhengServer.Game.Scene public int EntityID { get; set; } = avatarInfo.EntityId; public int GroupID { get; set; } = 0; + public List BuffList = []; + public void AddBuff(SceneBuff buff) + { + BuffList.Add(buff); + Player.SendPacket(new PacketSyncEntityBuffChangeListScNotify(this, buff)); + } + + public void ApplyBuff(BattleInstance instance) + { + foreach (var buff in BuffList) + { + if (buff.IsExpired()) + { + continue; + } + instance.Buffs.Add(new MazeBuff(buff)); + } + } + public SceneEntityInfo ToProto() { return AvatarInfo.ToSceneEntityInfo(AvatarType); diff --git a/GameServer/GameServer.csproj b/GameServer/GameServer.csproj index 7c33a650..d60bc70c 100644 --- a/GameServer/GameServer.csproj +++ b/GameServer/GameServer.csproj @@ -18,7 +18,6 @@ - diff --git a/GameServer/Server/Packet/Recv/Battle/HandlerQuitBattleCsReq.cs b/GameServer/Server/Packet/Recv/Battle/HandlerQuitBattleCsReq.cs new file mode 100644 index 00000000..e8d9db96 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Battle/HandlerQuitBattleCsReq.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Recv.Battle +{ + [Opcode(CmdIds.QuitBattleCsReq)] + public class HandlerQuitBattleCsReq : Handler + { + public override void OnHandle(Connection connection, byte[] header, byte[] data) + { + connection.Player!.BattleInstance = null; + connection.SendPacket(CmdIds.QuitBattleScRsp); + } + } +} diff --git a/GameServer/Server/Packet/Recv/Battle/HandlerSceneCastSkillCsReq.cs b/GameServer/Server/Packet/Recv/Battle/HandlerSceneCastSkillCsReq.cs index f36640e4..0c121acb 100644 --- a/GameServer/Server/Packet/Recv/Battle/HandlerSceneCastSkillCsReq.cs +++ b/GameServer/Server/Packet/Recv/Battle/HandlerSceneCastSkillCsReq.cs @@ -1,5 +1,6 @@ using EggLink.DanhengServer.Data; using EggLink.DanhengServer.Game.Battle.Skill; +using EggLink.DanhengServer.Game.Battle.Skill.Action; using EggLink.DanhengServer.Game.Scene; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Server.Packet.Send.Battle; @@ -21,17 +22,28 @@ namespace EggLink.DanhengServer.Server.Packet.Recv.Battle { connection.Player!.SceneInstance!.AvatarInfo.TryGetValue((int)req.AttackedByEntityId, out var info); MazeSkill mazeSkill = new([]); - var id = 0; - if (info != null) + + if (info != null) // cast by player { - id = info.AvatarInfo.AvatarId; mazeSkill = MazeSkillManager.GetSkill(info.AvatarInfo.AvatarId, (int)req.SkillIndex); } + if (req.HitTargetEntityIdList.Count == 0) { // didnt hit any target connection.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId)); - } else connection.Player!.BattleManager!.StartBattle(req, mazeSkill, id); + if (mazeSkill != null && req.SkillIndex > 0) + { + if (mazeSkill.Actions.FindIndex(a => a is MazeSetTargetMonsterDie) < 0) + { + connection.Player!.LineupManager!.CostMp(req.AttackedByEntityId, 1); + } + } + } + else + { + connection.Player!.BattleManager!.StartBattle(req, mazeSkill); + } } } } diff --git a/GameServer/Server/Packet/Recv/Friend/HandlerGetFriendApplyListInfoCsReq.cs b/GameServer/Server/Packet/Recv/Friend/HandlerGetFriendApplyListInfoCsReq.cs new file mode 100644 index 00000000..d8e69b6e --- /dev/null +++ b/GameServer/Server/Packet/Recv/Friend/HandlerGetFriendApplyListInfoCsReq.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Recv.Friend +{ + [Opcode(CmdIds.GetFriendApplyListInfoCsReq)] + public class HandlerGetFriendApplyListInfoCsReq : Handler + { + public override void OnHandle(Connection connection, byte[] header, byte[] data) + { + connection.SendPacket(CmdIds.GetFriendApplyListInfoScRsp); + } + } +} diff --git a/GameServer/Server/Packet/Recv/Friend/HandlerGetFriendListInfoCsReq.cs b/GameServer/Server/Packet/Recv/Friend/HandlerGetFriendListInfoCsReq.cs new file mode 100644 index 00000000..1e67b29b --- /dev/null +++ b/GameServer/Server/Packet/Recv/Friend/HandlerGetFriendListInfoCsReq.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Recv.Friend +{ + [Opcode(CmdIds.GetFriendListInfoCsReq)] + public class HandlerGetFriendListInfoCsReq : Handler + { + public override void OnHandle(Connection connection, byte[] header, byte[] data) + { + connection.SendPacket(CmdIds.GetFriendListInfoScRsp); + } + } +} diff --git a/GameServer/Server/Packet/Recv/Mission/HandlerGetNpcMessageGroupCsReq.cs b/GameServer/Server/Packet/Recv/Mission/HandlerGetNpcMessageGroupCsReq.cs new file mode 100644 index 00000000..fda84a00 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Mission/HandlerGetNpcMessageGroupCsReq.cs @@ -0,0 +1,21 @@ +using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Server.Packet.Send.Mission; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Recv.Mission +{ + [Opcode(CmdIds.GetNpcMessageGroupCsReq)] + public class HandlerGetNpcMessageGroupCsReq : Handler + { + public override void OnHandle(Connection connection, byte[] header, byte[] data) + { + var req = GetNpcMessageGroupCsReq.Parser.ParseFrom(data); + + connection.SendPacket(new PacketGetNpcMessageGroupScRsp(req.ContactIdList, connection.Player!)); + } + } +} diff --git a/GameServer/Server/Packet/Recv/Scene/HandlerGetUnlockTeleportCsReq.cs b/GameServer/Server/Packet/Recv/Scene/HandlerGetUnlockTeleportCsReq.cs new file mode 100644 index 00000000..1d8b9e06 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Scene/HandlerGetUnlockTeleportCsReq.cs @@ -0,0 +1,21 @@ +using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Server.Packet.Send.Scene; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Recv.Scene +{ + [Opcode(CmdIds.GetUnlockTeleportCsReq)] + public class HandlerGetUnlockTeleportCsReq : Handler + { + public override void OnHandle(Connection connection, byte[] header, byte[] data) + { + var req = GetUnlockTeleportCsReq.Parser.ParseFrom(data); + + connection.SendPacket(new PacketGetUnlockTeleportScRsp(req)); + } + } +} diff --git a/GameServer/Server/Packet/Send/Lineup/PacketSceneCastSkillMpUpdateScNotify.cs b/GameServer/Server/Packet/Send/Lineup/PacketSceneCastSkillMpUpdateScNotify.cs new file mode 100644 index 00000000..dc3a821e --- /dev/null +++ b/GameServer/Server/Packet/Send/Lineup/PacketSceneCastSkillMpUpdateScNotify.cs @@ -0,0 +1,23 @@ +using EggLink.DanhengServer.Proto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Send.Lineup +{ + public class PacketSceneCastSkillMpUpdateScNotify : BasePacket + { + public PacketSceneCastSkillMpUpdateScNotify(uint castEntityId, int mpCount) : base(CmdIds.SceneCastSkillMpUpdateScNotify) + { + var proto = new SceneCastSkillMpUpdateScNotify() + { + CastEntityId = castEntityId, + Mp = (uint)mpCount, + }; + + SetData(proto); + } + } +} diff --git a/GameServer/Server/Packet/Send/Mission/PacketGetNpcMessageGroupScRsp.cs b/GameServer/Server/Packet/Send/Mission/PacketGetNpcMessageGroupScRsp.cs new file mode 100644 index 00000000..6a20afd4 --- /dev/null +++ b/GameServer/Server/Packet/Send/Mission/PacketGetNpcMessageGroupScRsp.cs @@ -0,0 +1,27 @@ +using EggLink.DanhengServer.Game.Player; +using EggLink.DanhengServer.Proto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Send.Mission +{ + public class PacketGetNpcMessageGroupScRsp : BasePacket + { + public PacketGetNpcMessageGroupScRsp(IEnumerable contactIdList, PlayerInstance instance) : base(CmdIds.GetNpcMessageGroupScRsp) + { + var proto = new GetNpcMessageGroupScRsp(); + + foreach (var contactId in contactIdList) + { + var contact = instance.MessageManager!.GetMessageGroup((int)contactId); + + proto.MessageGroup.AddRange(contact); + } + + SetData(proto); + } + } +} diff --git a/GameServer/Server/Packet/Send/Quest/PacketGetQuestDataScRsp.cs b/GameServer/Server/Packet/Send/Quest/PacketGetQuestDataScRsp.cs index 5dbdf83d..282791dc 100644 --- a/GameServer/Server/Packet/Send/Quest/PacketGetQuestDataScRsp.cs +++ b/GameServer/Server/Packet/Send/Quest/PacketGetQuestDataScRsp.cs @@ -18,7 +18,7 @@ namespace EggLink.DanhengServer.Server.Packet.Send.Quest proto.QuestList.Add(new Proto.Quest() { Id = (uint)quest.QuestID, - Status = QuestStatus.QuestFinish + Status = QuestStatus.QuestClose }); } SetData(proto); diff --git a/GameServer/Server/Packet/Send/Scene/PacketGetUnlockTeleportScRsp.cs b/GameServer/Server/Packet/Send/Scene/PacketGetUnlockTeleportScRsp.cs new file mode 100644 index 00000000..29846e75 --- /dev/null +++ b/GameServer/Server/Packet/Send/Scene/PacketGetUnlockTeleportScRsp.cs @@ -0,0 +1,34 @@ +using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Data.Config; +using EggLink.DanhengServer.Proto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Send.Scene +{ + public class PacketGetUnlockTeleportScRsp : BasePacket + { + public PacketGetUnlockTeleportScRsp(GetUnlockTeleportCsReq req) : base(CmdIds.GetUnlockTeleportScRsp) + { + var rsp = new GetUnlockTeleportScRsp(); + foreach (var entranceId in req.EntryIdList) + { + GameData.MapEntranceData.TryGetValue((int)entranceId, out var excel); + if (excel == null) continue; + + GameData.GetFloorInfo(excel.PlaneID, excel.FloorID, out var floorInfo); + if (floorInfo == null) continue; + + foreach (var teleport in floorInfo.CachedTeleports) + { + rsp.UnlockTeleportList.Add((uint)teleport.Value.MappingInfoID); + } + } + + SetData(rsp); + } + } +} diff --git a/GameServer/Server/Packet/Send/Scene/PacketSyncEntityBuffChangeListScNotify.cs b/GameServer/Server/Packet/Send/Scene/PacketSyncEntityBuffChangeListScNotify.cs new file mode 100644 index 00000000..9d40ad70 --- /dev/null +++ b/GameServer/Server/Packet/Send/Scene/PacketSyncEntityBuffChangeListScNotify.cs @@ -0,0 +1,27 @@ +using EggLink.DanhengServer.Game.Scene; +using EggLink.DanhengServer.Game.Scene.Entity; +using EggLink.DanhengServer.Proto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Send.Scene +{ + public class PacketSyncEntityBuffChangeListScNotify : BasePacket + { + public PacketSyncEntityBuffChangeListScNotify(IGameEntity entity, SceneBuff buff) : base(CmdIds.SyncEntityBuffChangeListScNotify) + { + var proto = new SyncEntityBuffChangeListScNotify(); + var change = new EntityBuffChange() + { + EntityId = (uint)entity.EntityID, + BuffInfo = buff.ToProto(), + }; + proto.EntityBuffChangeList.Add(change); + + SetData(proto); + } + } +}