From ddf67bc4998032cb7e206b1bd21319ad0bf03d03 Mon Sep 17 00:00:00 2001 From: StopWuyu Date: Sat, 19 Apr 2025 11:13:56 +0800 Subject: [PATCH] revert: rewrite multi path system --- Command/Command/Cmd/CommandAvatar.cs | 123 +++++--- Command/Command/Cmd/CommandGender.cs | 40 --- Command/Command/Cmd/CommandGiveall.cs | 40 +-- Command/Command/Cmd/CommandHero.cs | 68 +++++ Command/Command/Cmd/CommandUnlockAll.cs | 29 +- Common/Configuration/ConfigContainer.cs | 6 +- .../Data/Excel/AvatarSkillTreeConfigExcel.cs | 7 +- .../Excel/MultiplePathAvatarConfigExcel.cs | 13 +- Common/Data/Excel/SpecialAvatarExcel.cs | 39 +-- Common/Database/Avatar/AvatarData.cs | 265 ++++++++++++------ Common/Database/Lineup/LineupData.cs | 12 +- Common/Database/Player/PlayerData.cs | 47 ++-- .../Enums/Avatar/MultiPathAvatarTypeEnum.cs | 11 + .../Message/LanguageCHS.cs | 12 +- .../Message/LanguageCHT.cs | 12 +- .../Message/LanguageEN.cs | 12 +- GameServer/Game/Avatar/AvatarManager.cs | 66 +++-- GameServer/Game/Battle/BattleInstance.cs | 19 +- GameServer/Game/Battle/BattleManager.cs | 10 +- .../Battle/Skill/Action/MazeAddMazeBuff.cs | 6 +- .../Battle/Skill/Action/MazeSummonUnit.cs | 2 +- .../Game/Battle/Skill/MazeSkillManager.cs | 8 +- .../Game/Challenge/ChallengeInstance.cs | 20 +- GameServer/Game/Gacha/GachaManager.cs | 58 ++-- GameServer/Game/Inventory/InventoryManager.cs | 57 ++-- GameServer/Game/Lineup/LineupManager.cs | 2 +- GameServer/Game/Player/PlayerInstance.cs | 59 +++- .../Game/RogueMagic/RogueMagicManager.cs | 2 +- .../Game/RogueTourn/RogueTournManager.cs | 2 +- GameServer/Game/Scene/SceneInstance.cs | 44 +-- .../Avatar/HandlerUnlockSkilltreeCsReq.cs | 2 +- .../HandlerGetMultiPathAvatarInfoCsReq.cs | 3 + .../Recv/Player/HandlerSetAvatarPathCsReq.cs | 16 +- .../Recv/Player/HandlerSetPlayerInfoCsReq.cs | 6 +- .../HandlerSetAssistAvatarCsReq.cs | 2 +- .../HandlerSetDisplayAvatarCsReq.cs | 2 +- .../Recv/Scene/HandlerSceneCastSkillCsReq.cs | 17 +- .../Send/Avatar/PacketGetAvatarDataScRsp.cs | 4 +- .../Send/Avatar/PacketMarkAvatarScRsp.cs | 2 +- .../Lineup/PacketGetLineupAvatarDataScRsp.cs | 2 +- .../Send/Player/PacketGetBasicInfoScRsp.cs | 8 + .../PacketGetMultiPathAvatarInfoScRsp.cs | 27 +- .../Send/Player/PacketSetPlayerInfoScRsp.cs | 2 +- .../PacketGetPlayerBoardDataScRsp.cs | 3 +- .../PlayerSync/PacketPlayerSyncScNotify.cs | 6 +- WebServer/Server/MuipManager.cs | 4 +- 46 files changed, 753 insertions(+), 444 deletions(-) delete mode 100644 Command/Command/Cmd/CommandGender.cs create mode 100644 Command/Command/Cmd/CommandHero.cs create mode 100644 Common/Enums/Avatar/MultiPathAvatarTypeEnum.cs diff --git a/Command/Command/Cmd/CommandAvatar.cs b/Command/Command/Cmd/CommandAvatar.cs index 03335fc6..ae6d66cb 100644 --- a/Command/Command/Cmd/CommandAvatar.cs +++ b/Command/Command/Cmd/CommandAvatar.cs @@ -1,6 +1,9 @@ using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Enums.Avatar; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; using EggLink.DanhengServer.GameServer.Server.Packet.Send.PlayerSync; using EggLink.DanhengServer.Internationalization; +using EggLink.DanhengServer.Proto; namespace EggLink.DanhengServer.Command.Command.Cmd; @@ -22,6 +25,7 @@ public class CommandAvatar : ICommand return; } + // change basic type var avatarId = arg.GetInt(0); var level = arg.GetInt(1); if (level is < 0 or > 10) @@ -36,46 +40,48 @@ public class CommandAvatar : ICommand { player.AvatarManager!.AvatarData.Avatars.ForEach(avatar => { - avatar.PathInfo.ToList().ForEach(path => + if (avatar.PathId > 0) { - var avatarExcel = GameData.AvatarConfigData.Values.FirstOrDefault(x => - x.AvatarID == path.Key)!; - foreach (var skillConfig in avatarExcel.SkillTree) - path.Value.SkillTree[skillConfig.PointID] = Math.Min(level, skillConfig.MaxLevel); - }); + avatar.SkillTreeExtra.TryGetValue(avatar.PathId, out var hero); + hero ??= []; + var excel = GameData.AvatarConfigData[avatar.PathId]; + excel.SkillTree.ForEach(talent => { hero[talent.PointID] = Math.Min(level, talent.MaxLevel); }); + } + else + { + avatar.Excel?.SkillTree.ForEach(talent => + { + avatar.SkillTree[talent.PointID] = Math.Min(level, talent.MaxLevel); + }); + } }); await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AllAvatarsLevelSet", I18NManager.Translate("Word.Talent"), level.ToString())); // sync await player.SendPacket(new PacketPlayerSyncScNotify(player.AvatarManager.AvatarData.Avatars)); + + return; } - else + + var avatar = player.AvatarManager!.GetAvatar(avatarId); + if (avatar == null) { - var avatar = player.AvatarManager!.GetAvatar(avatarId); - if (avatar == null) - { - await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); - return; - } - var pathInfo = avatar.GetPathInfo(avatarId); - if (pathInfo == null) - { - await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); - return; - } - - var avatarExcel = GameData.AvatarConfigData.Values.FirstOrDefault(x => x.AvatarID == avatarId)!; - foreach (var skillTree in avatarExcel.SkillTree) - pathInfo.SkillTree[skillTree.PointID] = Math.Min(level, skillTree.MaxLevel); - - // sync - await player.SendPacket(new PacketPlayerSyncScNotify(avatar)); - - await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarLevelSet", - avatarExcel.Name?.Replace("{NICKNAME}", player.Data.Name) ?? avatarId.ToString(), - I18NManager.Translate("Word.Talent"), level.ToString())); + await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); + return; } + + avatar.Excel?.SkillTree.ForEach(talent => + { + avatar.SkillTree[talent.PointID] = Math.Min(level, talent.MaxLevel); + }); + + // sync + await player.SendPacket(new PacketPlayerSyncScNotify(avatar)); + + await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarLevelSet", + avatar.Excel?.Name?.Replace("{NICKNAME}", player.Data.Name) ?? avatarId.ToString(), + I18NManager.Translate("Word.Talent"), level.ToString())); } [CommandMethod("get")] @@ -124,8 +130,9 @@ public class CommandAvatar : ICommand if (id == -1) { arg.Target.Player!.AvatarManager!.AvatarData.Avatars.ForEach(avatar => - avatar.PathInfo.Values.ToList().ForEach(x => x.Rank = Math.Min(rank, 6)) - ); + { + foreach (var path in avatar.PathInfoes.Values) path.Rank = Math.Min(rank, 6); + }); await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AllAvatarsLevelSet", I18NManager.Translate("Word.Rank"), rank.ToString())); @@ -141,21 +148,14 @@ public class CommandAvatar : ICommand await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); return; } - var pathInfo = avatar.GetPathInfo(id); - if (pathInfo == null) - { - await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); - return; - } - var avatarExcel = GameData.AvatarConfigData.Values.FirstOrDefault(x => x.AvatarID == id)!; - pathInfo.Rank = Math.Min(rank, avatarExcel.MaxRank); + foreach (var path in avatar.PathInfoes.Values) path.Rank = Math.Min(rank, 6); // sync await arg.Target.SendPacket(new PacketPlayerSyncScNotify(avatar)); await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarLevelSet", - avatarExcel.Name?.Replace("{NICKNAME}", arg.Target.Player!.Data.Name) ?? id.ToString(), + avatar.Excel?.Name?.Replace("{NICKNAME}", arg.Target.Player!.Data.Name) ?? id.ToString(), I18NManager.Translate("Word.Rank"), rank.ToString())); } } @@ -207,7 +207,6 @@ public class CommandAvatar : ICommand return; } - var avatarExcel = GameData.AvatarConfigData.Values.FirstOrDefault(x => x.AvatarID == id)!; avatar.Level = Math.Min(level, 80); avatar.Promotion = GameData.GetMinPromotionForLevel(avatar.Level); @@ -215,8 +214,46 @@ public class CommandAvatar : ICommand await arg.Target.SendPacket(new PacketPlayerSyncScNotify(avatar)); await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarLevelSet", - avatarExcel.Name?.Replace("{NICKNAME}", arg.Target.Player!.Data.Name) ?? id.ToString(), + avatar.Excel?.Name?.Replace("{NICKNAME}", arg.Target.Player!.Data.Name) ?? id.ToString(), I18NManager.Translate("Word.Avatar"), level.ToString())); } } + + [CommandMethod("path")] + public async ValueTask SetPath(CommandArg arg) + { + if (arg.Target == null) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound")); + return; + } + + if (arg.BasicArgs.Count < 2) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments")); + return; + } + + var avatarId = arg.GetInt(0); + var pathId = arg.GetInt(1); + + var avatar = arg.Target.Player!.AvatarManager!.GetAvatar(avatarId); + if (avatar == null) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); + return; + } + + if (!GameData.MultiplePathAvatarConfigData.ContainsKey(pathId)) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Avatar.AvatarNotFound")); + return; + } + + await arg.Target.Player.ChangeAvatarPathType(avatarId, (MultiPathAvatarTypeEnum)pathId); + await arg.Target.SendPacket(new PacketAvatarPathChangedNotify((uint)avatarId, (MultiPathAvatarType)pathId)); + await arg.Target.SendPacket(new PacketPlayerSyncScNotify(avatar)); + + // arg.SendMsg(I18nManager.Translate("Game.Command.Avatar.AvatarLevelSet", avatar.Excel?.Name?.Replace("{NICKNAME}", arg.Target.Player!.Data.Name) ?? id.ToString(), I18nManager.Translate("Word.Avatar"), level.ToString())); + } } \ No newline at end of file diff --git a/Command/Command/Cmd/CommandGender.cs b/Command/Command/Cmd/CommandGender.cs deleted file mode 100644 index 1b5b5d4b..00000000 --- a/Command/Command/Cmd/CommandGender.cs +++ /dev/null @@ -1,40 +0,0 @@ -using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; -using EggLink.DanhengServer.Internationalization; -using EggLink.DanhengServer.Proto; - -namespace EggLink.DanhengServer.Command.Command.Cmd; - -[CommandInfo("gender", "Game.Command.Gender.Desc", "Game.Command.Gender.Usage")] -public class CommandGender : ICommand -{ - [CommandDefault] - public async ValueTask ChangeGender(CommandArg arg) - { - if (arg.Target == null) - { - await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound")); - return; - } - - if (arg.BasicArgs.Count < 1) - { - await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments")); - return; - } - - var gender = (Gender)arg.GetInt(0); - if (gender == Gender.None) - { - await arg.SendMsg(I18NManager.Translate("Game.Command.Gender.GenderNotSpecified")); - return; - } - - var player = arg.Target!.Player!; - player.Data.CurrentGender = gender; - await player.ChangeAvatarPathType(8001, gender == Gender.Man ? - MultiPathAvatarType.BoyWarriorType : MultiPathAvatarType.GirlKnightType); - await player.SendPacket(new PacketGetMultiPathAvatarInfoScRsp(player)); - - await arg.SendMsg(I18NManager.Translate("Game.Command.Gender.GenderChanged")); - } -} \ No newline at end of file diff --git a/Command/Command/Cmd/CommandGiveall.cs b/Command/Command/Cmd/CommandGiveall.cs index 80b91962..d58900b7 100644 --- a/Command/Command/Cmd/CommandGiveall.cs +++ b/Command/Command/Cmd/CommandGiveall.cs @@ -1,7 +1,6 @@ using EggLink.DanhengServer.Data; -using EggLink.DanhengServer.Database.Avatar; using EggLink.DanhengServer.Database.Inventory; -using EggLink.DanhengServer.Database.TrainParty; +using EggLink.DanhengServer.Enums.Avatar; using EggLink.DanhengServer.Enums.Item; using EggLink.DanhengServer.GameServer.Server.Packet.Send.PlayerSync; using EggLink.DanhengServer.Internationalization; @@ -34,9 +33,8 @@ public class CommandGiveall : ICommand var avatarList = GameData.AvatarConfigData.Values; foreach (var avatar in avatarList) { - // Hacky way to prevent giving random avatars - if (avatar.AvatarID > 2000 && avatar.AvatarID != 8001) continue; - + if (avatar.AvatarID > 2000 && avatar.AvatarID != 8001) + continue; // Hacky way to prevent giving random avatars if (player.AvatarManager!.GetAvatar(avatar.AvatarID) == null) { GameData.MultiplePathAvatarConfigData.TryGetValue(avatar.AvatarID, out var multiPathAvatar); @@ -46,7 +44,7 @@ public class CommandGiveall : ICommand player.AvatarManager!.GetAvatar(avatar.AvatarID)!.Level = Math.Max(Math.Min(level, 80), 0); player.AvatarManager!.GetAvatar(avatar.AvatarID)!.Promotion = GameData.GetMinPromotionForLevel(Math.Max(Math.Min(level, 80), 0)); - player.AvatarManager!.GetAvatar(avatar.AvatarID)!.GetCurAvatarInfo().Rank = + player.AvatarManager!.GetAvatar(avatar.AvatarID)!.GetCurPathInfo().Rank = Math.Max(Math.Min(rank, 6), 0); } else @@ -54,7 +52,7 @@ public class CommandGiveall : ICommand player.AvatarManager!.GetAvatar(avatar.AvatarID)!.Level = Math.Max(Math.Min(level, 80), 0); player.AvatarManager!.GetAvatar(avatar.AvatarID)!.Promotion = GameData.GetMinPromotionForLevel(Math.Max(Math.Min(level, 80), 0)); - player.AvatarManager!.GetAvatar(avatar.AvatarID)!.GetCurAvatarInfo().Rank = + player.AvatarManager!.GetAvatar(avatar.AvatarID)!.GetCurPathInfo().Rank = Math.Max(Math.Min(rank, 6), 0); } } @@ -306,23 +304,27 @@ public class CommandGiveall : ICommand foreach (var multiPathAvatar in GameData.MultiplePathAvatarConfigData.Values) { - var avatarData = player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID); - if (avatarData == null) continue; - if (avatarData.PathInfo.ContainsKey(multiPathAvatar.AvatarID)) continue; + if (player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID) == null) + { + await player.InventoryManager!.AddItem(multiPathAvatar.BaseAvatarID, 1, false, sync: false); + player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID)!.Level = Math.Max(Math.Min(1, 80), 0); + player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID)!.Promotion = + GameData.GetMinPromotionForLevel(Math.Max(Math.Min(1, 80), 0)); + player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID)!.GetCurPathInfo().Rank = + Math.Max(Math.Min(0, 6), 0); + } - var avatarExcel = GameData.AvatarConfigData.Values - .FirstOrDefault(x => x.AvatarID == multiPathAvatar.AvatarID)!; - var pathInfo = new MultiPathData(); - foreach (var skillTree in avatarExcel.DefaultSkillTree) - pathInfo.SkillTree.Add(skillTree.PointID, 1); - avatarData.PathInfo.Add(multiPathAvatar.AvatarID, pathInfo); - - await player.SendPacket(new PacketPlayerSyncScNotify(avatarData)); + var avatarData = player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID)!; + if (avatarData.PathInfoes.ContainsKey(multiPathAvatar.AvatarID)) continue; + if (multiPathAvatar.BaseAvatarID > 8000 && multiPathAvatar.AvatarID % 2 != 1) continue; + await player.ChangeAvatarPathType(multiPathAvatar.BaseAvatarID, + (MultiPathAvatarTypeEnum)multiPathAvatar.AvatarID); } await player.SendPacket(new PacketPlayerSyncScNotify(player.AvatarManager!.AvatarData.Avatars)); await arg.SendMsg(I18NManager.Translate("Game.Command.GiveAll.GiveAllItems", - I18NManager.Translate("Word.Avatar"), "1")); + I18NManager.Translate("Word.Avatar"), + "1")); } } \ No newline at end of file diff --git a/Command/Command/Cmd/CommandHero.cs b/Command/Command/Cmd/CommandHero.cs new file mode 100644 index 00000000..1d8ca8f3 --- /dev/null +++ b/Command/Command/Cmd/CommandHero.cs @@ -0,0 +1,68 @@ +using EggLink.DanhengServer.Enums.Avatar; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; +using EggLink.DanhengServer.Internationalization; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.Command.Command.Cmd; + +[CommandInfo("hero", "Game.Command.Hero.Desc", "Game.Command.Hero.Usage")] +public class CommandHero : ICommand +{ + [CommandMethod("0 gender")] + public async ValueTask ChangeGender(CommandArg arg) + { + if (arg.Target == null) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound")); + return; + } + + if (arg.BasicArgs.Count < 1) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments")); + return; + } + + var gender = (Gender)arg.GetInt(0); + if (gender == Gender.None) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Hero.GenderNotSpecified")); + return; + } + + var player = arg.Target!.Player!; + player.Data.CurrentGender = gender; + await player.ChangeAvatarPathType(8001, MultiPathAvatarTypeEnum.Warrior); + await player.SendPacket(new PacketGetMultiPathAvatarInfoScRsp(player)); + + await arg.SendMsg(I18NManager.Translate("Game.Command.Hero.GenderChanged")); + } + + [CommandMethod("0 type")] + public async ValueTask ChangeType(CommandArg arg) + { + if (arg.Target == null) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound")); + return; + } + + if (arg.BasicArgs.Count < 1) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments")); + return; + } + + var gender = (MultiPathAvatarTypeEnum)arg.GetInt(0); + if (gender == 0) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.Hero.HeroTypeNotSpecified")); + return; + } + + var player = arg.Target!.Player!; + await player.ChangeAvatarPathType(8001, gender); + + await arg.SendMsg(I18NManager.Translate("Game.Command.Hero.HeroTypeChanged")); + } +} \ No newline at end of file diff --git a/Command/Command/Cmd/CommandUnlockAll.cs b/Command/Command/Cmd/CommandUnlockAll.cs index 686021d3..2ad77d4d 100644 --- a/Command/Command/Cmd/CommandUnlockAll.cs +++ b/Command/Command/Cmd/CommandUnlockAll.cs @@ -29,21 +29,21 @@ public class CommandUnlockAll : ICommand foreach (var mission in GameData.MainMissionData.Values) missionManager.Data.SetMainMissionStatus(mission.MainMissionID, MissionPhaseEnum.Finish); - var initHero = player.Data.CurrentGender == Gender.Man ? 8001 : 8002; - player.AvatarManager!.GetAvatar(8001)!.CurAvatarId = initHero; - - // Handle scene and lineup - await player.LineupManager!.SetCurLineup(0); - await player.LineupManager!.ReplaceLineup(0, [initHero]); - player.Data.Pos = new Position(99, 62, -4800); - player.Data.Rot = new Position(); - player.Data.PlaneId = 20001; - player.Data.FloorId = 20001001; - player.Data.EntryId = 2000101; + if (player.Data.CurrentGender == Gender.Man) + { + player.Data.CurrentGender = Gender.Man; + player.Data.CurBasicType = 8001; + } + else + { + player.Data.CurrentGender = Gender.Woman; + player.Data.CurBasicType = 8002; + player.AvatarManager!.GetHero()!.PathId = 8002; + } await arg.SendMsg(I18NManager.Translate("Game.Command.UnlockAll.UnlockedAll", I18NManager.Translate("Word.Mission"))); - await arg.Target!.Player!.SendPacket(new PacketPlayerKickOutScNotify(KickType.KickLoginWhiteTimeout)); + await arg.Target!.Player!.SendPacket(new PacketPlayerKickOutScNotify()); arg.Target!.Stop(); } @@ -66,7 +66,7 @@ public class CommandUnlockAll : ICommand await arg.SendMsg(I18NManager.Translate("Game.Command.UnlockAll.UnlockedAll", I18NManager.Translate("Word.Tutorial"))); - await arg.Target!.Player!.SendPacket(new PacketPlayerKickOutScNotify(KickType.KickLoginWhiteTimeout)); + await arg.Target!.Player!.SendPacket(new PacketPlayerKickOutScNotify()); arg.Target!.Stop(); } @@ -97,8 +97,7 @@ public class CommandUnlockAll : ICommand await arg.SendMsg(I18NManager.Translate("Game.Command.UnlockAll.UnlockedAll", I18NManager.Translate("Word.TypesOfRogue"))); - - await player.SendPacket(new PacketPlayerKickOutScNotify(KickType.KickLoginWhiteTimeout)); + await arg.Target!.Player!.SendPacket(new PacketPlayerKickOutScNotify()); arg.Target!.Stop(); } } \ No newline at end of file diff --git a/Common/Configuration/ConfigContainer.cs b/Common/Configuration/ConfigContainer.cs index 00896d19..c9fc9a28 100644 --- a/Common/Configuration/ConfigContainer.cs +++ b/Common/Configuration/ConfigContainer.cs @@ -1,6 +1,4 @@ -using EggLink.DanhengServer.Proto; - -namespace EggLink.DanhengServer.Configuration; +namespace EggLink.DanhengServer.Configuration; public class ConfigContainer { @@ -78,7 +76,7 @@ public class ServerOption public int StartTrailblazerLevel { get; set; } = 1; public bool AutoUpgradeWorldLevel { get; set; } = true; public bool EnableMission { get; set; } = true; // experimental - public string DefaultGender { get; set; } = "Woman"; + public bool AutoLightSection { get; set; } = true; public string Language { get; set; } = "EN"; public string FallbackLanguage { get; set; } = "EN"; public HashSet DefaultPermissions { get; set; } = ["*"]; diff --git a/Common/Data/Excel/AvatarSkillTreeConfigExcel.cs b/Common/Data/Excel/AvatarSkillTreeConfigExcel.cs index f8cc2cda..ceea9a93 100644 --- a/Common/Data/Excel/AvatarSkillTreeConfigExcel.cs +++ b/Common/Data/Excel/AvatarSkillTreeConfigExcel.cs @@ -17,11 +17,8 @@ public class AvatarSkillTreeConfigExcel : ExcelResource public override void AfterAllDone() { GameData.AvatarConfigData.TryGetValue(AvatarID, out var excel); - if (excel != null) - { - excel.SkillTree.Add(this); - if (DefaultUnlock) excel.DefaultSkillTree.Add(this); - } + if (excel != null && DefaultUnlock) excel.DefaultSkillTree.Add(this); + if (excel != null) excel.SkillTree.Add(this); GameData.AvatarSkillTreeConfigData.Add(GetId(), this); } } \ No newline at end of file diff --git a/Common/Data/Excel/MultiplePathAvatarConfigExcel.cs b/Common/Data/Excel/MultiplePathAvatarConfigExcel.cs index 08939548..041e8971 100644 --- a/Common/Data/Excel/MultiplePathAvatarConfigExcel.cs +++ b/Common/Data/Excel/MultiplePathAvatarConfigExcel.cs @@ -1,8 +1,13 @@ -namespace EggLink.DanhengServer.Data.Excel; +using EggLink.DanhengServer.Enums.Quest; + +namespace EggLink.DanhengServer.Data.Excel; [ResourceEntity("MultiplePathAvatarConfig.json")] public class MultiplePathAvatarConfigExcel : ExcelResource { + public List? UnlockConditions = new(); + public string ChangeConfigPath { get; set; } = ""; + public string Gender { get; set; } = ""; public int AvatarID { get; set; } public int BaseAvatarID { get; set; } @@ -15,4 +20,10 @@ public class MultiplePathAvatarConfigExcel : ExcelResource { GameData.MultiplePathAvatarConfigData.Add(AvatarID, this); } +} + +public class Condition +{ + public string Param { get; set; } = ""; + public ConditionTypeEnum Type { get; set; } } \ No newline at end of file diff --git a/Common/Data/Excel/SpecialAvatarExcel.cs b/Common/Data/Excel/SpecialAvatarExcel.cs index 1b0a84e3..47ff6e81 100644 --- a/Common/Data/Excel/SpecialAvatarExcel.cs +++ b/Common/Data/Excel/SpecialAvatarExcel.cs @@ -1,5 +1,7 @@ -using EggLink.DanhengServer.Database.Avatar; +using EggLink.DanhengServer.Database; +using EggLink.DanhengServer.Database.Avatar; using EggLink.DanhengServer.Database.Inventory; +using EggLink.DanhengServer.Database.Player; using EggLink.DanhengServer.Enums.Avatar; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -55,32 +57,37 @@ public class SpecialAvatarExcel : ExcelResource GameData.AvatarConfigData.TryGetValue(PlayerID, out var avatarConfig); - var instance = new AvatarInfo(AvatarID) + var instance = new AvatarInfo { + AvatarId = AvatarID, SpecialBaseAvatarId = SpecialAvatarID, Level = Level, Promotion = Promotion, + PathInfoes = new Dictionary(), CurrentHp = hp == 0 ? 10000 : hp, CurrentSp = sp, - InternalEntityId = Id + InternalEntityId = Id, + PlayerData = DatabaseHelper.Instance!.GetInstance(uid) }; + instance.PathInfoes.Add(AvatarID, new PathInfo(AvatarID) + { + Rank = Rank, + EquipData = new ItemData + { + ItemId = EquipmentID, + Level = EquipmentLevel, + Promotion = EquipmentPromotion, + Rank = EquipmentRank + } + }); + if (avatarConfig != null) { - instance.PathInfo[avatarConfig.AvatarID] = new() - { - Rank = Rank, - EquipData = new ItemData - { - ItemId = EquipmentID, - Level = EquipmentLevel, - Promotion = EquipmentPromotion, - Rank = EquipmentRank - } - }; - foreach (var skill in avatarConfig.DefaultSkillTree) - instance.GetCurAvatarInfo().SkillTree.Add(skill.PointID, skill.Level); + instance.SkillTree.Add(skill.PointID, skill.Level); + + instance.Excel = avatarConfig; } return instance; diff --git a/Common/Database/Avatar/AvatarData.cs b/Common/Database/Avatar/AvatarData.cs index 50f9cafb..a4502914 100644 --- a/Common/Database/Avatar/AvatarData.cs +++ b/Common/Database/Avatar/AvatarData.cs @@ -1,8 +1,8 @@ using EggLink.DanhengServer.Data; using EggLink.DanhengServer.Data.Excel; using EggLink.DanhengServer.Database.Inventory; +using EggLink.DanhengServer.Database.Player; using EggLink.DanhengServer.Proto; -using EggLink.DanhengServer.Util; using Newtonsoft.Json; using SqlSugar; using LineupInfo = EggLink.DanhengServer.Database.Lineup.LineupInfo; @@ -13,13 +13,41 @@ namespace EggLink.DanhengServer.Database.Avatar; public class AvatarData : BaseDatabaseDataHelper { [SugarColumn(IsJson = true)] public List Avatars { get; set; } = []; + + [SugarColumn(IsJson = true)] public List AssistAvatars { get; set; } = []; + + [SugarColumn(IsJson = true)] public List DisplayAvatars { get; set; } = []; } public class AvatarInfo { - public int CurAvatarId { get; set; } - public int BaseAvatarId { get; set; } + [JsonIgnore] public AvatarConfigExcel? Excel; + + [JsonIgnore] public PlayerData? PlayerData; + + public AvatarInfo() + { + // only for db + } + + public AvatarInfo(AvatarConfigExcel excel) + { + Excel = excel; + SkillTree = []; + if (AvatarId == 8001) + { + } + else + { + excel.DefaultSkillTree.ForEach(skill => { SkillTree.Add(skill.PointID, skill.Level); }); + } + } + + public int AvatarId { get; set; } + [JsonIgnore] public int SpecialBaseAvatarId { get; set; } + + public int PathId { get; set; } public int Level { get; set; } public int Exp { get; set; } public int Promotion { get; set; } @@ -30,35 +58,53 @@ public class AvatarInfo public int ExtraLineupHp { get; set; } = 10000; public int ExtraLineupSp { get; set; } public bool IsMarked { get; set; } = false; - public Dictionary PathInfo { get; set; } = []; + public Dictionary SkillTree { get; set; } = []; + + public Dictionary> SkillTreeExtra { get; set; } = + []; // for hero heroId -> skillId -> level + + public Dictionary PathInfoes { get; set; } = []; + [JsonIgnore] public int InternalEntityId { get; set; } - public AvatarInfo() + [JsonIgnore] + public int EntityId { - // For db only - } - - public AvatarInfo(int baseAvatarId, int? curAvatarId = null) - { - BaseAvatarId = baseAvatarId; - CurAvatarId = curAvatarId ?? baseAvatarId; - PathInfo.Add(CurAvatarId, new()); // Security add cur pathinfo - } - - public void SetEntityId(int uid, int entityId, int worldLevel = 0) - { - if (SpecialBaseAvatarId > 0) + get => InternalEntityId; + set { - // set in SpecialAvatarExcel - GameData.SpecialAvatarData.TryGetValue(SpecialBaseAvatarId * 10 + worldLevel, - out var specialAvatar); - if (specialAvatar != null) + if (SpecialBaseAvatarId > 0 && PlayerData != null) { - specialAvatar.EntityId[uid] = entityId; + // set in SpecialAvatarExcel + GameData.SpecialAvatarData.TryGetValue(SpecialBaseAvatarId * 10 + PlayerData.WorldLevel, + out var specialAvatar); + if (specialAvatar != null) + { + specialAvatar.EntityId[PlayerData.Uid] = value; + InternalEntityId = value; + } } - } - InternalEntityId = entityId; + InternalEntityId = value; + } + } + + public void ValidateHero() + { + if (PathId == 0) return; + + var isWoman = PathId % 2 == 0; + + var shouldRemove = new List(); + foreach (var skill in SkillTreeExtra.Keys) + if (skill % 2 == 0 != isWoman) // remove + shouldRemove.Add(skill); + + foreach (var skill in shouldRemove) SkillTreeExtra.Remove(skill); + + foreach (var path in PathInfoes.Keys) + if (path % 2 == 0 != isWoman) // remove + PathInfoes.Remove(path); } public bool HasTakenReward(int promotion) @@ -81,35 +127,82 @@ public class AvatarInfo return isExtraLineup ? ExtraLineupSp : CurrentSp; } + public int GetAvatarId() + { + return PathId > 0 ? PathId : AvatarId; + } + + public int GetBaseAvatarId() + { + if (PathId > 0) + return PathId > 8000 ? 8001 : AvatarId; + return AvatarId; + } + public int GetSpecialAvatarId() { - return SpecialBaseAvatarId > 0 ? SpecialBaseAvatarId : CurAvatarId; + return SpecialBaseAvatarId > 0 ? SpecialBaseAvatarId : GetAvatarId(); } public int GetUniqueAvatarId() { - return SpecialBaseAvatarId > 0 ? SpecialBaseAvatarId : BaseAvatarId; + return SpecialBaseAvatarId > 0 ? SpecialBaseAvatarId : GetBaseAvatarId(); } - public MultiPathData GetCurAvatarInfo() + public PathInfo GetCurPathInfo() { - return GetPathInfo(CurAvatarId)!; + if (PathInfoes.ContainsKey(GetAvatarId())) return PathInfoes[GetAvatarId()]; + + PathInfoes.Add(GetAvatarId(), new PathInfo(PathId)); + return PathInfoes[GetAvatarId()]; } - public MultiPathData? GetPathInfo(int avatarId) + public PathInfo? GetPathInfo(int pathId) { - return PathInfo.TryGetValue(avatarId, out var pathInfo) ? pathInfo : null; + if (PathInfoes.TryGetValue(pathId, out var value)) return value; + return null; } - public AvatarConfigExcel GetCurAvatarConfig() + public Dictionary GetSkillTree(int pathId = 0) { - return GetAvatarConfig(CurAvatarId); + if (pathId == 0) pathId = PathId; + + if (pathId == 0 && AvatarId == 1001) + { + PathId = 1001; + pathId = 1001; // march 7th + } + + var value = SkillTree; + if (pathId > 0) + if (!SkillTreeExtra.TryGetValue(pathId, out value)) + { + value = []; + // for old data + SkillTreeExtra[pathId] = value; + var excel = GameData.AvatarConfigData[pathId]; + excel.DefaultSkillTree.ForEach(skill => { SkillTreeExtra[pathId].Add(skill.PointID, skill.Level); }); + } + + return value; } - public AvatarConfigExcel GetAvatarConfig(int avatarId) + public void VaildateSkillTree() { - return GameData.AvatarConfigData.Values.FirstOrDefault(x => - x.AvatarID == avatarId)!; + if (AvatarId < 8000) + foreach (var avatar in GameData.MultiplePathAvatarConfigData.Values) + if (avatar.AvatarID == AvatarId) + if (!SkillTreeExtra.TryGetValue(avatar.AvatarID, out var value)) + { + value = []; + // for old data + SkillTreeExtra[avatar.AvatarID] = value; + var excel = GameData.AvatarConfigData[avatar.AvatarID]; + excel.DefaultSkillTree.ForEach(skill => + { + SkillTreeExtra[avatar.AvatarID].Add(skill.PointID, skill.Level); + }); + } } public void SetCurHp(int value, bool isExtraLineup) @@ -136,22 +229,21 @@ public class AvatarInfo Level = (uint)Level, Exp = (uint)Exp, Promotion = (uint)Promotion, - Rank = (uint)GetCurAvatarInfo().Rank, - DressedSkinId = (uint)GetCurAvatarInfo().Skin, + Rank = (uint)GetCurPathInfo().Rank, FirstMetTimeStamp = (ulong)Timestamp, IsMarked = IsMarked }; - foreach (var item in GetCurAvatarInfo().Relic) + foreach (var item in GetCurPathInfo().Relic) proto.EquipRelicList.Add(new EquipRelic { RelicUniqueId = (uint)item.Value, Type = (uint)item.Key }); - if (GetCurAvatarInfo().EquipId != 0) proto.EquipmentUniqueId = (uint)GetCurAvatarInfo().EquipId; + if (GetCurPathInfo().EquipId != 0) proto.EquipmentUniqueId = (uint)GetCurPathInfo().EquipId; - foreach (var skill in GetCurAvatarInfo().SkillTree) + foreach (var skill in GetSkillTree()) proto.SkilltreeList.Add(new AvatarSkillTree { PointId = (uint)skill.Key, @@ -165,19 +257,19 @@ public class AvatarInfo return proto; } - public SceneEntityInfo ToSceneEntityInfo(Position? pos, Position? rot, AvatarType avatarType = AvatarType.AvatarFormalType) + public SceneEntityInfo ToSceneEntityInfo(AvatarType avatarType = AvatarType.AvatarFormalType) { return new SceneEntityInfo { - EntityId = (uint)InternalEntityId, + EntityId = (uint)EntityId, Motion = new MotionInfo { - Pos = pos?.ToProto() ?? new Vector(), - Rot = rot?.ToProto() ?? new Vector() + Pos = PlayerData?.Pos?.ToProto() ?? new Vector(), + Rot = PlayerData?.Rot?.ToProto() ?? new Vector() }, Actor = new SceneActorInfo { - BaseAvatarId = (uint)BaseAvatarId, + BaseAvatarId = (uint)GetBaseAvatarId(), AvatarType = avatarType } }; @@ -199,8 +291,8 @@ public class AvatarInfo }; } - public BattleAvatar ToBattleProto(int worldLevel, LineupInfo lineup, - InventoryData inventory, AvatarType avatarType = AvatarType.AvatarFormalType) + public BattleAvatar ToBattleProto(LineupInfo lineup, InventoryData inventory, + AvatarType avatarType = AvatarType.AvatarFormalType) { var proto = new BattleAvatar { @@ -208,25 +300,25 @@ public class AvatarInfo AvatarType = avatarType, Level = (uint)Level, Promotion = (uint)Promotion, - Rank = (uint)GetCurAvatarInfo().Rank, - Index = (uint)lineup.GetSlot(BaseAvatarId), + Rank = (uint)GetCurPathInfo().Rank, + Index = (uint)lineup.GetSlot(GetBaseAvatarId()), Hp = (uint)GetCurHp(lineup.LineupType != 0), SpBar = new SpBarInfo { CurSp = (uint)GetCurSp(lineup.LineupType != 0), MaxSp = 10000 }, - WorldLevel = (uint)worldLevel + WorldLevel = (uint)(PlayerData?.WorldLevel ?? 0) }; - foreach (var skill in GetCurAvatarInfo().SkillTree) + foreach (var skill in GetSkillTree()) proto.SkilltreeList.Add(new AvatarSkillTree { PointId = (uint)skill.Key, Level = (uint)skill.Value }); - foreach (var relic in GetCurAvatarInfo().Relic) + foreach (var relic in GetCurPathInfo().Relic) { var item = inventory.RelicItems?.Find(item => item.UniqueId == relic.Value); if (item != null) @@ -247,9 +339,9 @@ public class AvatarInfo } } - if (GetCurAvatarInfo().EquipId != 0) + if (GetCurPathInfo().EquipId != 0) { - var item = inventory.EquipmentItems?.Find(item => item.UniqueId == GetCurAvatarInfo().EquipId); + var item = inventory.EquipmentItems?.Find(item => item.UniqueId == GetCurPathInfo().EquipId); if (item != null) proto.EquipmentList.Add(new BattleEquipment { @@ -259,14 +351,14 @@ public class AvatarInfo Rank = (uint)item.Rank }); } - else if (GetCurAvatarInfo().EquipData != null) + else if (GetCurPathInfo().EquipData != null) { proto.EquipmentList.Add(new BattleEquipment { - Id = (uint)GetCurAvatarInfo().EquipData!.ItemId, - Level = (uint)GetCurAvatarInfo().EquipData!.Level, - Promotion = (uint)GetCurAvatarInfo().EquipData!.Promotion, - Rank = (uint)GetCurAvatarInfo().EquipData!.Rank + Id = (uint)GetCurPathInfo().EquipData!.ItemId, + Level = (uint)GetCurPathInfo().EquipData!.Level, + Promotion = (uint)GetCurPathInfo().EquipData!.Promotion, + Rank = (uint)GetCurPathInfo().EquipData!.Rank }); } @@ -277,26 +369,34 @@ public class AvatarInfo { var res = new List(); - foreach (var path in PathInfo) + GetSkillTree(); + VaildateSkillTree(); + + foreach (var path in SkillTreeExtra) { - if (path.Key > 8000 && path.Key % 2 != CurAvatarId % 2) continue; + PathInfoes.TryGetValue(path.Key, out var pathInfo); + + if (pathInfo == null) + { + PathInfoes.Add(path.Key, new PathInfo(path.Key)); + pathInfo = PathInfoes[path.Key]; + } var proto = new MultiPathAvatarInfo { AvatarId = (MultiPathAvatarType)path.Key, - Rank = (uint)path.Value.Rank, - PathEquipmentId = (uint)path.Value.EquipId, - DressedSkinId = (uint)path.Value.Skin + Rank = (uint)GetCurPathInfo().Rank, + PathEquipmentId = (uint)pathInfo.EquipId }; - foreach (var skillTree in path.Value.SkillTree) + foreach (var skill in path.Value) proto.MultiPathSkillTree.Add(new AvatarSkillTree { - PointId = (uint)skillTree.Key, - Level = (uint)skillTree.Value + PointId = (uint)skill.Key, + Level = (uint)skill.Value }); - foreach (var relic in path.Value.Relic) + foreach (var relic in pathInfo.Relic) proto.EquipRelicList.Add(new EquipRelic { Type = (uint)relic.Key, @@ -309,48 +409,47 @@ public class AvatarInfo return res; } - public DisplayAvatarDetailInfo ToDetailProto(int playerUid, int pos) + public DisplayAvatarDetailInfo ToDetailProto(int pos) { var proto = new DisplayAvatarDetailInfo { - AvatarId = (uint)CurAvatarId, + AvatarId = (uint)GetAvatarId(), Level = (uint)Level, Exp = (uint)Exp, Promotion = (uint)Promotion, - Rank = (uint)GetCurAvatarInfo().Rank, + Rank = (uint)GetCurPathInfo().Rank, Pos = (uint)pos }; - var inventory = DatabaseHelper.Instance!.GetInstance(playerUid)!; - foreach (var item in GetCurAvatarInfo().Relic) + var inventory = DatabaseHelper.Instance!.GetInstance(PlayerData!.Uid)!; + foreach (var item in GetCurPathInfo().Relic) { var relic = inventory.RelicItems.Find(x => x.UniqueId == item.Value)!; proto.RelicList.Add(relic.ToDisplayRelicProto()); } - if (GetCurAvatarInfo().EquipId != 0) + if (GetCurPathInfo().EquipId != 0) { - var equip = inventory.EquipmentItems.Find(x => x.UniqueId == GetCurAvatarInfo().EquipId)!; + var equip = inventory.EquipmentItems.Find(x => x.UniqueId == GetCurPathInfo().EquipId)!; proto.Equipment = equip.ToDisplayEquipmentProto(); } - foreach (var skillTree in GetCurAvatarInfo().SkillTree) + foreach (var skill in GetSkillTree()) proto.SkilltreeList.Add(new AvatarSkillTree { - PointId = (uint)skillTree.Key, - Level = (uint)skillTree.Value + PointId = (uint)skill.Key, + Level = (uint)skill.Value }); return proto; } } -public class MultiPathData +public class PathInfo(int pathId) { - public int Rank { get; set; } = 0; + public int PathId { get; set; } = pathId; + public int Rank { get; set; } public int EquipId { get; set; } = 0; - public int Skin { get; set; } = 0; - public Dictionary SkillTree { get; set; } = []; public Dictionary Relic { get; set; } = []; public ItemData? EquipData { get; set; } // for special avatar } \ No newline at end of file diff --git a/Common/Database/Lineup/LineupData.cs b/Common/Database/Lineup/LineupData.cs index 406db79c..5f3b96a0 100644 --- a/Common/Database/Lineup/LineupData.cs +++ b/Common/Database/Lineup/LineupData.cs @@ -44,7 +44,7 @@ public class LineupInfo if (BaseAvatars != null && AvatarData != null) foreach (var avatar in BaseAvatars) { - var avatarInfo = AvatarData?.Avatars?.Find(item => item.BaseAvatarId == avatar.BaseAvatarId); + var avatarInfo = AvatarData?.Avatars?.Find(item => item.GetBaseAvatarId() == avatar.BaseAvatarId); if (avatarInfo != null) { if (avatarInfo.GetCurHp(IsExtraLineup()) <= 0 && !allowRevive) continue; @@ -65,7 +65,7 @@ public class LineupInfo if (BaseAvatars != null && AvatarData != null) foreach (var avatar in BaseAvatars) { - var avatarInfo = AvatarData?.Avatars?.Find(item => item.CurAvatarId == avatar.BaseAvatarId); + var avatarInfo = AvatarData?.Avatars?.Find(item => item.GetAvatarId() == avatar.BaseAvatarId); if (avatarInfo != null) { if (avatarInfo.CurrentHp <= 0) continue; @@ -84,7 +84,7 @@ public class LineupInfo if (BaseAvatars != null && AvatarData != null) foreach (var avatar in BaseAvatars) { - var avatarInfo = AvatarData?.Avatars?.Find(item => item.CurAvatarId == avatar.BaseAvatarId); + var avatarInfo = AvatarData?.Avatars?.Find(item => item.GetAvatarId() == avatar.BaseAvatarId); if (avatarInfo != null) { if (avatarInfo.CurrentHp <= 0) continue; @@ -125,10 +125,10 @@ public class LineupInfo foreach (var avatar in BaseAvatars) if (avatar.AssistUid != 0) // assist avatar { - var assistPlayer = DatabaseHelper.Instance!.GetInstance(avatar.AssistUid); + var assistPlayer = DatabaseHelper.Instance?.GetInstance(avatar.AssistUid); if (assistPlayer != null) info.AvatarList.Add(assistPlayer?.Avatars - ?.Find(item => item.CurAvatarId == avatar.BaseAvatarId) + ?.Find(item => item.GetAvatarId() == avatar.BaseAvatarId) ?.ToLineupInfo(BaseAvatars.IndexOf(avatar), this, AvatarType.AvatarAssistType)); // assist avatar may not work } @@ -141,7 +141,7 @@ public class LineupInfo } else // normal avatar { - info.AvatarList.Add(AvatarData?.Avatars?.Find(item => item.BaseAvatarId == avatar.BaseAvatarId) + info.AvatarList.Add(AvatarData?.Avatars?.Find(item => item.AvatarId == avatar.BaseAvatarId) ?.ToLineupInfo(BaseAvatars.IndexOf(avatar), this)); } diff --git a/Common/Database/Player/PlayerData.cs b/Common/Database/Player/PlayerData.cs index 17b3e363..3a65e4c0 100644 --- a/Common/Database/Player/PlayerData.cs +++ b/Common/Database/Player/PlayerData.cs @@ -12,6 +12,7 @@ public class PlayerData : BaseDatabaseDataHelper public string? Name { get; set; } = ""; public string? Signature { get; set; } = ""; public int Birthday { get; set; } = 0; + public int CurBasicType { get; set; } = 8001; public int HeadIcon { get; set; } = 208001; public int PhoneTheme { get; set; } = 221000; public int ChatBubble { get; set; } = 220000; @@ -19,9 +20,8 @@ public class PlayerData : BaseDatabaseDataHelper public int PhoneCase { get; set; } = 254000; public int CurrentBgm { get; set; } = 210007; public int CurrentPamSkin { get; set; } = 252000; - public int Pet { get; set; } = 0; public bool IsGenderSet { get; set; } = false; - public Gender CurrentGender { get; set; } + public Gender CurrentGender { get; set; } = Gender.Man; public int Level { get; set; } = 1; public int Exp { get; set; } = 0; public int WorldLevel { get; set; } = 0; @@ -30,15 +30,12 @@ public class PlayerData : BaseDatabaseDataHelper public int Mcoin { get; set; } = 0; // Crystals public int TalentPoints { get; set; } = 0; // Rogue talent points + public int Pet { get; set; } = 0; [SugarColumn(IsNullable = true)] public int CurMusicLevel { get; set; } public int Stamina { get; set; } = 300; public double StaminaReserve { get; set; } = 0; public long NextStaminaRecover { get; set; } = 0; - public long MonthCard { get; set; } = 0; - - [SugarColumn(IsJson = true)] public List AssistAvatars { get; set; } = []; - [SugarColumn(IsJson = true)] public List DisplayAvatars { get; set; } = []; [SugarColumn(IsNullable = true, IsJson = true)] public Position? Pos { get; set; } @@ -58,7 +55,7 @@ public class PlayerData : BaseDatabaseDataHelper public static PlayerData? GetPlayerByUid(long uid) { - var result = DatabaseHelper.Instance!.GetInstance((int)uid); + var result = DatabaseHelper.Instance?.GetInstance((int)uid); return result; } @@ -79,6 +76,17 @@ public class PlayerData : BaseDatabaseDataHelper public PlayerSimpleInfo ToSimpleProto(FriendOnlineStatus status) { + if (!GameData.ChatBubbleConfigData.ContainsKey(ChatBubble)) // to avoid npe + ChatBubble = 220000; + + var instance = DatabaseHelper.Instance!.GetInstance(Uid)!; + + foreach (var avatar in instance.Avatars) + { + avatar.PlayerData = this; + avatar.Excel = GameData.AvatarConfigData[avatar.AvatarId]; + } + var info = new PlayerSimpleInfo { Nickname = Name, @@ -94,12 +102,11 @@ public class PlayerData : BaseDatabaseDataHelper }; var pos = 0; - var avatarData = DatabaseHelper.Instance!.GetInstance(Uid)!; - foreach (var avatar in AssistAvatars.Select( - assist => avatarData.Avatars.Find(x => x.BaseAvatarId == assist)!)) + foreach (var avatar in instance.AssistAvatars.Select( + assist => instance.Avatars.Find(x => x.AvatarId == assist)!)) info.AssistSimpleInfoList.Add(new AssistSimpleInfo { - AvatarId = (uint)avatar.BaseAvatarId, + AvatarId = (uint)avatar.AvatarId, Level = (uint)avatar.Level, Pos = (uint)pos++ }); @@ -124,17 +131,23 @@ public class PlayerData : BaseDatabaseDataHelper }; var avatarInfo = DatabaseHelper.Instance!.GetInstance(Uid); + if (avatarInfo == null) return info; + foreach (var avatar in avatarInfo.Avatars) + { + avatar.PlayerData = this; + avatar.Excel = GameData.AvatarConfigData[avatar.AvatarId]; + } var pos = 0; - foreach (var avatar in AssistAvatars.Select(assist => - avatarInfo.Avatars.Find(x => x.BaseAvatarId == assist)!)) - info.AssistAvatarList.Add(avatar.ToDetailProto(Uid, pos++)); + foreach (var avatar in avatarInfo.AssistAvatars.Select(assist => + avatarInfo.Avatars.Find(x => x.AvatarId == assist)!)) + info.AssistAvatarList.Add(avatar.ToDetailProto(pos++)); pos = 0; - foreach (var avatar in DisplayAvatars.Select(display => - avatarInfo.Avatars.Find(x => x.BaseAvatarId == display)!)) - info.DisplayAvatarList.Add(avatar.ToDetailProto(Uid, pos++)); + foreach (var avatar in avatarInfo.DisplayAvatars.Select(display => + avatarInfo.Avatars.Find(x => x.AvatarId == display)!)) + info.DisplayAvatarList.Add(avatar.ToDetailProto(pos++)); return info; } diff --git a/Common/Enums/Avatar/MultiPathAvatarTypeEnum.cs b/Common/Enums/Avatar/MultiPathAvatarTypeEnum.cs new file mode 100644 index 00000000..b869c1c0 --- /dev/null +++ b/Common/Enums/Avatar/MultiPathAvatarTypeEnum.cs @@ -0,0 +1,11 @@ +namespace EggLink.DanhengServer.Enums.Avatar; + +public enum MultiPathAvatarTypeEnum +{ + Warrior = 8001, + Knight = 8003, + Shaman = 8005, + Memory = 8007, + Mar_7thKnight = 1001, + Mar_7thRogue = 1224 +} diff --git a/Common/Internationalization/Message/LanguageCHS.cs b/Common/Internationalization/Message/LanguageCHS.cs index 00bd6e23..9ed12651 100644 --- a/Common/Internationalization/Message/LanguageCHS.cs +++ b/Common/Internationalization/Message/LanguageCHS.cs @@ -112,7 +112,7 @@ public class CommandTextCHS { public NoticeTextCHS Notice { get; } = new(); - public GenderTextCHS Gender { get; } = new(); + public HeroTextCHS Hero { get; } = new(); public AvatarTextCHS Avatar { get; } = new(); public GiveTextCHS Give { get; } = new(); public GiveAllTextCHS GiveAll { get; } = new(); @@ -201,18 +201,18 @@ public class NoticeTextCHS } /// -/// path: Game.Command.Gender +/// path: Game.Command.Hero /// -public class GenderTextCHS +public class HeroTextCHS { public string Desc => "切换主角的性别/形态\n当切换性别时,genderId为1代表男性,2代表女性\n当切换形态时,8001代表毁灭命途,8003代表存护命途,8005代表同谐命途。\n注意,切换性别时会清空所有可选命途以及行迹,为不可逆操作!"; - public string Usage => "用法:/Gender gender [genderId]\n\n用法:/Gender type [typeId]"; + public string Usage => "用法:/hero gender [genderId]\n\n用法:/hero type [typeId]"; public string GenderNotSpecified => "性别不存在!"; - public string GenderTypeNotSpecified => "主角类型不存在!"; + public string HeroTypeNotSpecified => "主角类型不存在!"; public string GenderChanged => "性别已更改!"; - public string GenderTypeChanged => "主角类型已更改!"; + public string HeroTypeChanged => "主角类型已更改!"; } /// diff --git a/Common/Internationalization/Message/LanguageCHT.cs b/Common/Internationalization/Message/LanguageCHT.cs index 7fec6836..43b684cd 100644 --- a/Common/Internationalization/Message/LanguageCHT.cs +++ b/Common/Internationalization/Message/LanguageCHT.cs @@ -112,7 +112,7 @@ public class CommandTextCHT { public NoticeTextCHT Notice { get; } = new(); - public GenderTextCHT Gender { get; } = new(); + public HeroTextCHT Hero { get; } = new(); public AvatarTextCHT Avatar { get; } = new(); public GiveTextCHT Give { get; } = new(); public GiveAllTextCHT GiveAll { get; } = new(); @@ -201,18 +201,18 @@ public class NoticeTextCHT } /// -/// path: Game.Command.Gender +/// path: Game.Command.Hero /// -public class GenderTextCHT +public class HeroTextCHT { public string Desc => "切換主角的性別/形態\n當切換性別時,genderId為1代表男性,2代表女性\n當切換形態時,8001代表毀滅命途,8003代表存護命途,8005代表同諧命途。\n註意,切換性別時會清空所有可選命途以及行跡,為不可逆操作!"; - public string Usage => "用法:/Gender gender [genderId]\n\n用法:/Gender type [typeId]"; + public string Usage => "用法:/hero gender [genderId]\n\n用法:/hero type [typeId]"; public string GenderNotSpecified => "性別不存在!"; - public string GenderTypeNotSpecified => "主角類型不存在!"; + public string HeroTypeNotSpecified => "主角類型不存在!"; public string GenderChanged => "性別已更改!"; - public string GenderTypeChanged => "主角類型已更改!"; + public string HeroTypeChanged => "主角類型已更改!"; } /// diff --git a/Common/Internationalization/Message/LanguageEN.cs b/Common/Internationalization/Message/LanguageEN.cs index 31c2f08b..ef8f203c 100644 --- a/Common/Internationalization/Message/LanguageEN.cs +++ b/Common/Internationalization/Message/LanguageEN.cs @@ -112,7 +112,7 @@ public class CommandTextEN { public NoticeTextEN Notice { get; } = new(); - public GenderTextEN Gender { get; } = new(); + public HeroTextEN Hero { get; } = new(); public AvatarTextEN Avatar { get; } = new(); public GiveTextEN Give { get; } = new(); public GiveAllTextEN GiveAll { get; } = new(); @@ -210,19 +210,19 @@ public class NoticeTextEN } /// -/// path: Game.Command.Gender +/// path: Game.Command.Hero /// -public class GenderTextEN +public class HeroTextEN { public string Desc => "Switch the gender/type of the main character\nWhen switch the gender, 1 means male, 2 means female\nWhen switch the type(path), 8001 means Destruction, 8003 means Preservation, 8005 means Harmony.\nNotice: Switch gender will clear all the paths and talents of main character, this operation is irreversible!"; - public string Usage => "Usage: /Gender gender [genderId]\n\nUsage: /Gender type [typeId]"; + public string Usage => "Usage: /hero gender [genderId]\n\nUsage: /hero type [typeId]"; public string GenderNotSpecified => "Gender does not exist!"; - public string GenderTypeNotSpecified => "Main character type does not exist!"; + public string HeroTypeNotSpecified => "Main character type does not exist!"; public string GenderChanged => "Gender has been changed!"; - public string GenderTypeChanged => "Main character type has been changed!"; + public string HeroTypeChanged => "Main character type has been changed!"; } /// diff --git a/GameServer/Game/Avatar/AvatarManager.cs b/GameServer/Game/Avatar/AvatarManager.cs index 54c8d676..22d4fda1 100644 --- a/GameServer/Game/Avatar/AvatarManager.cs +++ b/GameServer/Game/Avatar/AvatarManager.cs @@ -11,56 +11,78 @@ using EggLink.DanhengServer.Util; namespace EggLink.DanhengServer.GameServer.Game.Avatar; -public class AvatarManager(PlayerInstance player) : BasePlayerManager(player) +public class AvatarManager : BasePlayerManager { - public AvatarData AvatarData { get; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew(player.Uid); + public AvatarManager(PlayerInstance player) : base(player) + { + AvatarData = DatabaseHelper.Instance!.GetInstanceOrCreateNew(player.Uid); + foreach (var avatar in AvatarData.Avatars) + { + avatar.PlayerData = player.Data; + avatar.Excel = GameData.AvatarConfigData[avatar.AvatarId]; + } + } + + public AvatarData AvatarData { get; } public async ValueTask AddAvatar(int avatarId, bool sync = true, bool notify = true, bool isGacha = false) { - if (avatarId > 8000 && avatarId % 2 != (int)Player.Data.CurrentGender % 2) return null; GameData.AvatarConfigData.TryGetValue(avatarId, out var avatarExcel); if (avatarExcel == null) return null; GameData.MultiplePathAvatarConfigData.TryGetValue(avatarId, out var multiPathAvatar); - var baseAvatarId = multiPathAvatar?.BaseAvatarID ?? avatarId; - var avatarData = GetAvatar(baseAvatarId); - - var pathInfo = new MultiPathData(); - foreach (var skillTree in avatarExcel.DefaultSkillTree) - pathInfo.SkillTree.Add(skillTree.PointID, 1); - - // Check if base avatar exist - if (avatarData != null) + if (multiPathAvatar != null && multiPathAvatar.BaseAvatarID != avatarId) { - if (multiPathAvatar == null) return null; - if (avatarData.PathInfo.TryAdd(avatarId, pathInfo)) - return avatarExcel; + // Is path + foreach (var avatarData in AvatarData.Avatars) + if (avatarData.AvatarId == multiPathAvatar.BaseAvatarID) + { + // Add path for the character + avatarData.PathInfoes.Add(avatarId, new PathInfo(avatarId)); + break; + } + return null; } - var avatar = new AvatarInfo(baseAvatarId, avatarId) + var avatar = new AvatarInfo(avatarExcel) { + AvatarId = avatarId >= 8001 ? 8001 : avatarId, Level = 1, Timestamp = Extensions.GetUnixSec(), CurrentHp = 10000, CurrentSp = 0 }; - avatar.PathInfo[avatarId] = pathInfo; // Add curAvatarId's pathinfo + + if (avatarId >= 8001) + { + if (GetHero() != null) return null; // Only one hero + avatar.PathId = avatarId; + } + + avatar.PlayerData = Player.Data; AvatarData.Avatars.Add(avatar); - if (sync) await Player.SendPacket(new PacketPlayerSyncScNotify(avatar)); - if (notify) await Player.SendPacket(new PacketAddAvatarScNotify(avatar.BaseAvatarId, isGacha)); + if (sync) + await Player.SendPacket(new PacketPlayerSyncScNotify(avatar)); + + if (notify) await Player.SendPacket(new PacketAddAvatarScNotify(avatar.GetBaseAvatarId(), isGacha)); return avatarExcel; } public AvatarInfo? GetAvatar(int avatarId) { - if (GameData.MultiplePathAvatarConfigData.TryGetValue(avatarId, out var pathConfig)) - avatarId = pathConfig.BaseAvatarID; + if (avatarId > 8000) avatarId = 8001; + if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatarId)) + avatarId = GameData.MultiplePathAvatarConfigData[avatarId].BaseAvatarID; + return AvatarData.Avatars.Find(avatar => avatar.AvatarId == avatarId); + } - return AvatarData.Avatars.Find(avatar => avatar.BaseAvatarId == avatarId); + public AvatarInfo? GetHero() + { + return AvatarData.Avatars.Find(avatar => avatar.AvatarId == 8001); } public async ValueTask ReforgeRelic(int uniqueId) diff --git a/GameServer/Game/Battle/BattleInstance.cs b/GameServer/Game/Battle/BattleInstance.cs index 896dec47..ffe7e9c3 100644 --- a/GameServer/Game/Battle/BattleInstance.cs +++ b/GameServer/Game/Battle/BattleInstance.cs @@ -127,10 +127,16 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List 0) { List tempList = [.. list]; - foreach (var avatar in tempList.Where(avatar => - GameData.SpecialAvatarData.TryGetValue(avatar * 10 + 0, out var specialAvatarExcel) && - specialAvatarExcel.AvatarID > 8000 && specialAvatarExcel.AvatarID % 2 != (int)Player.Data.CurrentGender)) - list.Remove(avatar); + if (Player.Data.CurrentGender == Gender.Man) + foreach (var avatar in tempList.Where(avatar => + GameData.SpecialAvatarData.TryGetValue(avatar * 10 + 0, out var specialAvatarExcel) && + specialAvatarExcel.AvatarID is 8002 or 8004 or 8006)) + list.Remove(avatar); + else + foreach (var avatar in tempList.Where(avatar => + GameData.SpecialAvatarData.TryGetValue(avatar * 10 + 0, out var specialAvatarExcel) && + specialAvatarExcel.AvatarID is 8001 or 8003 or 8005)) + list.Remove(avatar); } if (list.Count > 0) // if list is not empty @@ -173,7 +179,7 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List(avatar.AssistUid); if (player != null) { - avatarInstance = player.Avatars.Find(item => item.CurAvatarId == avatar.BaseAvatarId); + avatarInstance = player.Avatars.Find(item => item.GetAvatarId() == avatar.BaseAvatarId); avatarType = AvatarType.AvatarAssistType; } } @@ -223,8 +229,7 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List diff --git a/GameServer/Game/Battle/BattleManager.cs b/GameServer/Game/Battle/BattleManager.cs index fe45ce9e..dc74f69d 100644 --- a/GameServer/Game/Battle/BattleManager.cs +++ b/GameServer/Game/Battle/BattleManager.cs @@ -157,15 +157,15 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player) avatarList.AddRange(Player.LineupManager!.GetCurLineup()!.BaseAvatars! .Select(item => Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => - x.AvatarInfo.BaseAvatarId == item.BaseAvatarId)) + x.AvatarInfo.AvatarId == item.BaseAvatarId)) .OfType()); MazeBuff? mazeBuff = null; if (castAvatar != null) { var index = battleInstance.Lineup.BaseAvatars!.FindIndex(x => - x.BaseAvatarId == castAvatar.AvatarInfo.BaseAvatarId); - GameData.AvatarConfigData.TryGetValue(castAvatar.AvatarInfo.CurAvatarId, out var avatarExcel); + x.BaseAvatarId == castAvatar.AvatarInfo.AvatarId); + GameData.AvatarConfigData.TryGetValue(castAvatar.AvatarInfo.GetAvatarId(), out var avatarExcel); if (avatarExcel != null) { mazeBuff = new MazeBuff((int)avatarExcel.DamageType, 1, index); @@ -243,7 +243,7 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player) }; var avatarList = Player.LineupManager!.GetCurLineup()!.BaseAvatars!.Select(item => - Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => x.AvatarInfo.BaseAvatarId == item.BaseAvatarId)) + Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => x.AvatarInfo.AvatarId == item.BaseAvatarId)) .OfType().ToList(); battleInstance.AvatarInfo = avatarList; @@ -312,7 +312,7 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player) } var avatarList = Player.LineupManager!.GetCurLineup()!.BaseAvatars!.Select(item => - Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => x.AvatarInfo.BaseAvatarId == item.BaseAvatarId)) + Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => x.AvatarInfo.AvatarId == item.BaseAvatarId)) .OfType().ToList(); battleInstance.AvatarInfo = avatarList; diff --git a/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs b/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs index a072094d..704d2dee 100644 --- a/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs +++ b/GameServer/Game/Battle/Skill/Action/MazeAddMazeBuff.cs @@ -11,19 +11,19 @@ public class MazeAddMazeBuff(int buffId, int duration) : IMazeSkillAction public async ValueTask OnAttack(AvatarSceneInfo avatar, List entities) { foreach (var entity in entities) - entity.TempBuff = new SceneBuff(BuffId, 1, avatar.AvatarInfo.BaseAvatarId, duration); + entity.TempBuff = new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration); await System.Threading.Tasks.Task.CompletedTask; } public async ValueTask OnCast(AvatarSceneInfo avatar, PlayerInstance player) { - await avatar.AddBuff(new SceneBuff(BuffId, 1, avatar.AvatarInfo.BaseAvatarId, duration)); + await avatar.AddBuff(new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration)); } public async ValueTask OnHitTarget(AvatarSceneInfo avatar, List entities) { foreach (var entity in entities) - await entity.AddBuff(new SceneBuff(BuffId, 1, avatar.AvatarInfo.BaseAvatarId, duration)); + await entity.AddBuff(new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration)); } } \ No newline at end of file diff --git a/GameServer/Game/Battle/Skill/Action/MazeSummonUnit.cs b/GameServer/Game/Battle/Skill/Action/MazeSummonUnit.cs index 22b2018d..d88967a9 100644 --- a/GameServer/Game/Battle/Skill/Action/MazeSummonUnit.cs +++ b/GameServer/Game/Battle/Skill/Action/MazeSummonUnit.cs @@ -16,7 +16,7 @@ public class MazeSummonUnit(SummonUnitDataExcel excel, MotionInfo motion) : IMaz CreateAvatarEntityId = avatar.EntityID, AttachEntityId = excel.ConfigInfo?.AttachPoint == "Origin" ? avatar.EntityID : 0, SummonUnitId = excel.ID, - CreateAvatarId = avatar.AvatarInfo.BaseAvatarId, + CreateAvatarId = avatar.AvatarInfo.GetAvatarId(), LifeTimeMs = 20000, TriggerList = excel.ConfigInfo?.TriggerConfig.CustomTriggers ?? [], Motion = motion diff --git a/GameServer/Game/Battle/Skill/MazeSkillManager.cs b/GameServer/Game/Battle/Skill/MazeSkillManager.cs index cf153e13..f53d5e59 100644 --- a/GameServer/Game/Battle/Skill/MazeSkillManager.cs +++ b/GameServer/Game/Battle/Skill/MazeSkillManager.cs @@ -6,9 +6,9 @@ namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill; public static class MazeSkillManager { - public static MazeSkill GetSkill(int avatarId, int skillIndex, SceneCastSkillCsReq req) + public static MazeSkill GetSkill(int baseAvatarId, int skillIndex, SceneCastSkillCsReq req) { - GameData.AvatarConfigData.TryGetValue(avatarId, out var avatarConfig); + GameData.AvatarConfigData.TryGetValue(baseAvatarId, out var avatarConfig); MazeSkill mazeSkill = new([], req); if (avatarConfig == null) return mazeSkill; @@ -21,9 +21,9 @@ public static class MazeSkillManager return mazeSkill; } - public static MazeSkill GetSkill(int avatarId, AbilityInfo ability, SceneCastSkillCsReq req) + public static MazeSkill GetSkill(int baseAvatarId, AbilityInfo ability, SceneCastSkillCsReq req) { - GameData.AvatarConfigData.TryGetValue(avatarId, out var avatarConfig); + GameData.AvatarConfigData.TryGetValue(baseAvatarId, out var avatarConfig); MazeSkill mazeSkill = new([], req); if (avatarConfig == null) return mazeSkill; diff --git a/GameServer/Game/Challenge/ChallengeInstance.cs b/GameServer/Game/Challenge/ChallengeInstance.cs index 03afcbb0..c87e614d 100644 --- a/GameServer/Game/Challenge/ChallengeInstance.cs +++ b/GameServer/Game/Challenge/ChallengeInstance.cs @@ -177,23 +177,23 @@ public class ChallengeInstance { var avatar = Player.AvatarManager?.GetAvatar(lineupAvatar.BaseAvatarId); if (avatar == null) continue; - proto.BossInfo.FirstLineup.Add((uint)avatar.CurAvatarId); - var equip = Player.InventoryManager?.GetItem(0, avatar.GetCurAvatarInfo().EquipId, + proto.BossInfo.FirstLineup.Add((uint)avatar.GetAvatarId()); + var equip = Player.InventoryManager?.GetItem(0, avatar.GetCurPathInfo().EquipId, ItemMainTypeEnum.Equipment); if (equip != null) - proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.CurAvatarId, + proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.GetAvatarId(), equip.ToChallengeEquipmentProto()); var relicProto = new ChallengeBossAvatarRelicInfo(); - foreach (var relicUniqueId in avatar.GetCurAvatarInfo().Relic) + foreach (var relicUniqueId in avatar.GetCurPathInfo().Relic) { var relic = Player.InventoryManager?.GetItem(0, relicUniqueId.Value, ItemMainTypeEnum.Relic); if (relic == null) continue; relicProto.AvatarRelicSlotMap.Add((uint)relicUniqueId.Key, relic.ToChallengeRelicProto()); } - proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.CurAvatarId, relicProto); + proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.GetAvatarId(), relicProto); } foreach (var lineupAvatar in Player.LineupManager?.GetExtraLineup(ExtraLineupType.LineupChallenge2) @@ -201,23 +201,23 @@ public class ChallengeInstance { var avatar = Player.AvatarManager?.GetAvatar(lineupAvatar.BaseAvatarId); if (avatar == null) continue; - proto.BossInfo.SecondLineup.Add((uint)avatar.CurAvatarId); - var equip = Player.InventoryManager?.GetItem(0, avatar.GetCurAvatarInfo().EquipId, + proto.BossInfo.SecondLineup.Add((uint)avatar.GetAvatarId()); + var equip = Player.InventoryManager?.GetItem(0, avatar.GetCurPathInfo().EquipId, ItemMainTypeEnum.Equipment); if (equip != null) - proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.CurAvatarId, + proto.BossInfo.ChallengeAvatarEquipmentMap.Add((uint)avatar.GetAvatarId(), equip.ToChallengeEquipmentProto()); var relicProto = new ChallengeBossAvatarRelicInfo(); - foreach (var relicUniqueId in avatar.GetCurAvatarInfo().Relic) + foreach (var relicUniqueId in avatar.GetCurPathInfo().Relic) { var relic = Player.InventoryManager?.GetItem(0, relicUniqueId.Value, ItemMainTypeEnum.Relic); if (relic == null) continue; relicProto.AvatarRelicSlotMap.Add((uint)relicUniqueId.Key, relic.ToChallengeRelicProto()); } - proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.CurAvatarId, relicProto); + proto.BossInfo.ChallengeAvatarRelicMap.Add((uint)avatar.GetAvatarId(), relicProto); } } diff --git a/GameServer/Game/Gacha/GachaManager.cs b/GameServer/Game/Gacha/GachaManager.cs index aa69a7f7..4936eb07 100644 --- a/GameServer/Game/Gacha/GachaManager.cs +++ b/GameServer/Game/Gacha/GachaManager.cs @@ -132,21 +132,24 @@ public class GachaManager(PlayerInstance player) : BasePlayerManager(player) if (avatar != null) { star += 40; - var rankUpItemId = avatar.GetCurAvatarConfig().RankUpItemId; - var rankUpItem = Player.InventoryManager!.GetItem(rankUpItemId); - if (avatar.PathInfo[item].Rank + rankUpItem?.Count >= 6) + var rankUpItemId = avatar.Excel?.RankUpItemId; + if (rankUpItemId != null) { - star += 60; - } - else - { - var dupeItem = new ItemList(); - dupeItem.ItemList_.Add(new Item + var rankUpItem = Player.InventoryManager!.GetItem(rankUpItemId.Value); + if (avatar.PathInfoes[item].Rank + rankUpItem?.Count >= 6) { - ItemId = (uint)rankUpItemId, - Num = 1 - }); - gachaItem.TransferItemList = dupeItem; + star += 60; + } + else + { + var dupeItem = new ItemList(); + dupeItem.ItemList_.Add(new Item + { + ItemId = (uint)rankUpItemId.Value, + Num = 1 + }); + gachaItem.TransferItemList = dupeItem; + } } } } @@ -164,21 +167,24 @@ public class GachaManager(PlayerInstance player) : BasePlayerManager(player) if (avatar != null) { star += 8; - var rankUpItemId = avatar.GetCurAvatarConfig().RankUpItemId; - var rankUpItem = Player.InventoryManager!.GetItem(rankUpItemId); - if (avatar.PathInfo[item].Rank + rankUpItem?.Count >= 6) + var rankUpItemId = avatar.Excel?.RankUpItemId; + if (rankUpItemId != null) { - star += 12; - } - else - { - var dupeItem = new ItemList(); - dupeItem.ItemList_.Add(new Item + var rankUpItem = Player.InventoryManager!.GetItem(rankUpItemId.Value); + if (avatar.PathInfoes[item].Rank + rankUpItem?.Count >= 6) { - ItemId = (uint)rankUpItemId, - Num = 1 - }); - gachaItem.TransferItemList = dupeItem; + star += 12; + } + else + { + var dupeItem = new ItemList(); + dupeItem.ItemList_.Add(new Item + { + ItemId = (uint)rankUpItemId.Value, + Num = 1 + }); + gachaItem.TransferItemList = dupeItem; + } } } } diff --git a/GameServer/Game/Inventory/InventoryManager.cs b/GameServer/Game/Inventory/InventoryManager.cs index 41a559ef..da0d6ec1 100644 --- a/GameServer/Game/Inventory/InventoryManager.cs +++ b/GameServer/Game/Inventory/InventoryManager.cs @@ -162,12 +162,11 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) case ItemMainTypeEnum.AvatarCard: // add avatar var avatar = Player.AvatarManager?.GetAvatar(itemId); - var pathInfo = avatar?.PathInfo[itemId]; - if (avatar != null && pathInfo != null) + if (avatar is { Excel: not null }) { - var rankUpItem = Player.InventoryManager!.GetItem(avatar.GetAvatarConfig(itemId).RankUpItemId); - if ((pathInfo.Rank + rankUpItem?.Count ?? 0) <= 5) - itemData = await PutItem(avatar.GetCurAvatarConfig().RankUpItemId, 1); + var rankUpItem = Player.InventoryManager!.GetItem(avatar.Excel.RankUpItemId); + if ((avatar.PathInfoes[itemId].Rank + rankUpItem?.Count ?? 0) <= 5) + itemData = await PutItem(avatar.Excel.RankUpItemId, 1); } else { @@ -764,13 +763,13 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) //maze buff if (useConfig.MazeBuffID > 0) foreach (var info in Player.SceneInstance?.AvatarInfo.Values.ToList() ?? []) - if (baseAvatarId == 0 || info.AvatarInfo.BaseAvatarId == baseAvatarId) - await info.AddBuff(new SceneBuff(useConfig.MazeBuffID, 1, info.AvatarInfo.BaseAvatarId)); + if (baseAvatarId == 0 || info.AvatarInfo.GetBaseAvatarId() == baseAvatarId) + await info.AddBuff(new SceneBuff(useConfig.MazeBuffID, 1, info.AvatarInfo.AvatarId)); if (useConfig.MazeBuffID2 > 0) foreach (var info in Player.SceneInstance?.AvatarInfo.Values.ToList() ?? []) - if (baseAvatarId == 0 || info.AvatarInfo.BaseAvatarId == baseAvatarId) - await info.AddBuff(new SceneBuff(useConfig.MazeBuffID2, 1, info.AvatarInfo.BaseAvatarId)); + if (baseAvatarId == 0 || info.AvatarInfo.GetBaseAvatarId() == baseAvatarId) + await info.AddBuff(new SceneBuff(useConfig.MazeBuffID2, 1, info.AvatarInfo.AvatarId)); // remove item await RemoveItem(itemId, count); @@ -785,7 +784,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) var itemData = Data.EquipmentItems.Find(x => x.UniqueId == equipmentUniqueId); var avatarData = Player.AvatarManager!.GetAvatar(avatarId); if (itemData == null || avatarData == null) return; - var oldItem = Data.EquipmentItems.Find(x => x.UniqueId == avatarData.PathInfo[avatarId].EquipId); + var oldItem = Data.EquipmentItems.Find(x => x.UniqueId == avatarData.PathInfoes[avatarId].EquipId); if (itemData.EquipAvatar > 0) // already be dressed { var equipAvatarId = itemData.EquipAvatar; @@ -793,13 +792,13 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) if (equipAvatar != null && oldItem != null) { // switch - equipAvatar.PathInfo[equipAvatarId].EquipId = oldItem.UniqueId; - oldItem.EquipAvatar = equipAvatar.CurAvatarId; + equipAvatar.PathInfoes[equipAvatarId].EquipId = oldItem.UniqueId; + oldItem.EquipAvatar = equipAvatar.GetAvatarId(); await Player.SendPacket(new PacketPlayerSyncScNotify(equipAvatar, oldItem)); } else if (equipAvatar != null && oldItem == null) { - equipAvatar.PathInfo[equipAvatarId].EquipId = 0; + equipAvatar.PathInfoes[equipAvatarId].EquipId = 0; await Player.SendPacket(new PacketPlayerSyncScNotify(equipAvatar)); } } @@ -812,8 +811,8 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) } } - itemData.EquipAvatar = avatarData.CurAvatarId; - avatarData.PathInfo[avatarId].EquipId = itemData.UniqueId; + itemData.EquipAvatar = avatarData.GetAvatarId(); + avatarData.PathInfoes[avatarId].EquipId = itemData.UniqueId; await Player.SendPacket(new PacketPlayerSyncScNotify(avatarData, itemData)); } @@ -822,7 +821,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) var itemData = Data.RelicItems.Find(x => x.UniqueId == relicUniqueId); var avatarData = Player.AvatarManager!.GetAvatar(avatarId); if (itemData == null || avatarData == null) return; - avatarData.PathInfo[avatarId].Relic.TryGetValue(slot, out var id); + avatarData.PathInfoes[avatarId].Relic.TryGetValue(slot, out var id); var oldItem = Data.RelicItems.Find(x => x.UniqueId == id); if (itemData.EquipAvatar > 0) // already be dressed @@ -832,13 +831,13 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) if (equipAvatar != null && oldItem != null) { // switch - equipAvatar.PathInfo[equipAvatarId].Relic[slot] = oldItem.UniqueId; - oldItem.EquipAvatar = equipAvatar.CurAvatarId; + equipAvatar.PathInfoes[equipAvatarId].Relic[slot] = oldItem.UniqueId; + oldItem.EquipAvatar = equipAvatar.GetAvatarId(); await Player.SendPacket(new PacketPlayerSyncScNotify(equipAvatar, oldItem)); } else if (equipAvatar != null && oldItem == null) { - equipAvatar.PathInfo[equipAvatarId].Relic[slot] = 0; + equipAvatar.PathInfoes[equipAvatarId].Relic[slot] = 0; await Player.SendPacket(new PacketPlayerSyncScNotify(equipAvatar)); } } @@ -851,8 +850,8 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) } } - itemData.EquipAvatar = avatarData.CurAvatarId; - avatarData.PathInfo[avatarId].Relic[slot] = itemData.UniqueId; + itemData.EquipAvatar = avatarData.GetAvatarId(); + avatarData.PathInfoes[avatarId].Relic[slot] = itemData.UniqueId; // save await Player.SendPacket(new PacketPlayerSyncScNotify(avatarData, itemData)); } @@ -861,7 +860,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { var avatarData = Player.AvatarManager!.GetAvatar(avatarId); if (avatarData == null) return; - var pathInfo = avatarData.PathInfo[avatarId]; + var pathInfo = avatarData.PathInfoes[avatarId]; if (pathInfo == null) return; pathInfo.Relic.TryGetValue(slot, out var uniqueId); var itemData = Data.RelicItems.Find(x => x.UniqueId == uniqueId); @@ -875,7 +874,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { var avatarData = Player.AvatarManager!.GetAvatar(avatarId); if (avatarData == null) return; - var pathInfo = avatarData.PathInfo[avatarId]; + var pathInfo = avatarData.PathInfoes[avatarId]; if (pathInfo == null) return; var itemData = Data.EquipmentItems.Find(x => x.UniqueId == pathInfo.EquipId); if (itemData == null) return; @@ -888,7 +887,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { var avatarData = Player.AvatarManager!.GetAvatar(baseAvatarId); if (avatarData == null) return []; - GameData.AvatarPromotionConfigData.TryGetValue(avatarData.BaseAvatarId * 10 + avatarData.Promotion, + GameData.AvatarPromotionConfigData.TryGetValue(avatarData.AvatarId * 10 + avatarData.Promotion, out var promotionConfig); if (promotionConfig == null) return []; var exp = 0; @@ -909,7 +908,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) var maxLevel = promotionConfig.MaxLevel; var curExp = avatarData.Exp; var curLevel = avatarData.Level; - var nextLevelExp = GameData.GetAvatarExpRequired(avatarData.GetCurAvatarConfig().ExpGroup, avatarData.Level); + var nextLevelExp = GameData.GetAvatarExpRequired(avatarData.Excel!.ExpGroup, avatarData.Level); do { int toGain; @@ -924,7 +923,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { curExp = 0; curLevel++; - nextLevelExp = GameData.GetAvatarExpRequired(avatarData.GetCurAvatarConfig().ExpGroup, curLevel); + nextLevelExp = GameData.GetAvatarExpRequired(avatarData.Excel!.ExpGroup, curLevel); } } while (exp > 0 && nextLevelExp > 0 && curLevel < maxLevel); @@ -1079,8 +1078,8 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { // Get avatar var avatarData = Player.AvatarManager!.GetAvatar(avatarId)!; - if (avatarData == null || avatarData.GetCurAvatarConfig() == null || - avatarData.Promotion >= avatarData.GetCurAvatarConfig().MaxPromotion) return false; + if (avatarData == null || avatarData.Excel == null || + avatarData.Promotion >= avatarData.Excel.MaxPromotion) return false; // Get promotion data var promotion = @@ -1255,7 +1254,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) if (avatar != null) baseAvatarId = avatar.BaseAvatarID; var avatarData = Player.AvatarManager!.GetAvatar(baseAvatarId); if (avatarData == null) return; - avatarData.GetCurAvatarInfo().Rank++; + avatarData.GetCurPathInfo().Rank++; await Player.SendPacket(new PacketPlayerSyncScNotify(avatarData)); } diff --git a/GameServer/Game/Lineup/LineupManager.cs b/GameServer/Game/Lineup/LineupManager.cs index e5c3d4aa..518c9150 100644 --- a/GameServer/Game/Lineup/LineupManager.cs +++ b/GameServer/Game/Lineup/LineupManager.cs @@ -71,7 +71,7 @@ public class LineupManager : BasePlayerManager avatarType = AvatarType.AvatarAssistType; if (avatarStorage == null) continue; foreach (var avatarData in avatarStorage.Avatars.Where(avatarData => - avatarData.BaseAvatarId == avatar.BaseAvatarId)) + avatarData.AvatarId == avatar.BaseAvatarId)) { avatarInfo = avatarData; break; diff --git a/GameServer/Game/Player/PlayerInstance.cs b/GameServer/Game/Player/PlayerInstance.cs index 5c3a4e5e..2ad0b997 100644 --- a/GameServer/Game/Player/PlayerInstance.cs +++ b/GameServer/Game/Player/PlayerInstance.cs @@ -131,7 +131,6 @@ public class PlayerInstance(PlayerData data) IsNewPlayer = true; Data.NextStaminaRecover = Extensions.GetUnixSec() + GameConstants.STAMINA_RESERVE_RECOVERY_TIME; Data.Level = ConfigManager.Config.ServerOption.StartTrailblazerLevel; - Data.CurrentGender = Enum.Parse(ConfigManager.Config.ServerOption.DefaultGender); DatabaseHelper.SaveInstance(Data); @@ -140,7 +139,7 @@ public class PlayerInstance(PlayerData data) { await InitialPlayerManager(); - await AddAvatar(8000 + (int)Data.CurrentGender); + await AddAvatar(8001); await AddAvatar(1001); if (ConfigManager.Config.ServerOption.EnableMission) { @@ -149,7 +148,8 @@ public class PlayerInstance(PlayerData data) else { await LineupManager!.AddAvatarToCurTeam(8001); - await LineupManager!.AddAvatarToCurTeam(1001); + Data.CurrentGender = Gender.Man; + Data.CurBasicType = 8001; } }); t.Wait(); @@ -240,6 +240,22 @@ public class PlayerInstance(PlayerData data) } } + foreach (var relic in InventoryManager.Data.RelicItems) + { + if (relic.MainAffix != 0) continue; // fix relic main affix + + var groupId = GameData.RelicConfigData.GetValueOrDefault(relic.ItemId)?.MainAffixGroup ?? 0; + relic.MainAffix = UtilTools.GetRandomRelicMainAffix(groupId); + } + + foreach (var avatar in AvatarManager?.AvatarData.Avatars ?? []) + foreach (var skill in avatar.GetSkillTree()) + { + GameData.AvatarSkillTreeConfigData.TryGetValue(skill.Key * 10 + 1, out var config); + if (config == null) continue; + avatar.GetSkillTree()[skill.Key] = Math.Min(skill.Value, config.MaxLevel); // limit skill level + } + await LoadScene(Data.PlaneId, Data.FloorId, Data.EntryId, Data.Pos!, Data.Rot!, false); if (SceneInstance == null) await EnterScene(2000101, 0, false); @@ -291,13 +307,33 @@ public class PlayerInstance(PlayerData data) #region Actions - public async ValueTask ChangeAvatarPathType(int baseAvatarId, MultiPathAvatarType type) + public async ValueTask ChangeAvatarPathType(int baseAvatarId, MultiPathAvatarTypeEnum type) { - var avatar = AvatarManager!.GetAvatar(baseAvatarId)!; - avatar.CurAvatarId = (int)type; - avatar.SetCurSp(0, LineupManager!.GetCurLineup()!.IsExtraLineup()); - await SendPacket(new PacketAvatarPathChangedNotify((uint)avatar.BaseAvatarId, type)); - await SendPacket(new PacketPlayerSyncScNotify(avatar)); + if (baseAvatarId == 8001) + { + var id = (int)((int)type + Data.CurrentGender - 1); + if (Data.CurBasicType == id) return; + Data.CurBasicType = id; + var avatar = AvatarManager!.GetHero()!; + // Set avatar path + avatar.PathId = id; + avatar.ValidateHero(); + avatar.SetCurSp(0, LineupManager!.GetCurLineup()!.IsExtraLineup()); + // Save new skill tree + avatar.GetSkillTree(); + await SendPacket(new PacketAvatarPathChangedNotify(8001, (MultiPathAvatarType)id)); + await SendPacket(new PacketPlayerSyncScNotify(AvatarManager!.GetHero()!)); + } + else + { + var avatar = AvatarManager!.GetAvatar(baseAvatarId)!; + avatar.PathId = (int)type; + avatar.SetCurSp(0, LineupManager!.GetCurLineup()!.IsExtraLineup()); + // Save new skill tree + avatar.GetSkillTree(); + await SendPacket(new PacketAvatarPathChangedNotify((uint)avatar.AvatarId, (MultiPathAvatarType)type)); + await SendPacket(new PacketPlayerSyncScNotify(avatar)); + } } public async ValueTask ChangeAvatarSkin(int avatarId, int skinId) @@ -893,5 +929,10 @@ public class PlayerInstance(PlayerData data) return Data.ToProto(); } + public PlayerSimpleInfo ToSimpleProto() + { + return Data.ToSimpleProto(FriendOnlineStatus.Online); + } + #endregion } \ No newline at end of file diff --git a/GameServer/Game/RogueMagic/RogueMagicManager.cs b/GameServer/Game/RogueMagic/RogueMagicManager.cs index 056f2506..0bde38b5 100644 --- a/GameServer/Game/RogueMagic/RogueMagicManager.cs +++ b/GameServer/Game/RogueMagic/RogueMagicManager.cs @@ -28,7 +28,7 @@ public class RogueMagicManager(PlayerInstance player) : BasePlayerManager(player avatar.SetCurHp(10000, true); avatar.SetCurSp(5000, true); - baseAvatarIds.Add(avatar.BaseAvatarId); + baseAvatarIds.Add(avatar.GetBaseAvatarId()); } Player.LineupManager!.SetExtraLineup(ExtraLineupType.LineupMagicRogue, baseAvatarIds); diff --git a/GameServer/Game/RogueTourn/RogueTournManager.cs b/GameServer/Game/RogueTourn/RogueTournManager.cs index 2e08c886..820b54ce 100644 --- a/GameServer/Game/RogueTourn/RogueTournManager.cs +++ b/GameServer/Game/RogueTourn/RogueTournManager.cs @@ -29,7 +29,7 @@ public class RogueTournManager(PlayerInstance player) : BasePlayerManager(player avatar.SetCurHp(10000, true); avatar.SetCurSp(5000, true); - baseAvatarIds.Add(avatar.BaseAvatarId); + baseAvatarIds.Add(avatar.GetBaseAvatarId()); } Player.LineupManager!.SetExtraLineup(ExtraLineupType.LineupTournRogue, baseAvatarIds); diff --git a/GameServer/Game/Scene/SceneInstance.cs b/GameServer/Game/Scene/SceneInstance.cs index 65515394..88618630 100644 --- a/GameServer/Game/Scene/SceneInstance.cs +++ b/GameServer/Game/Scene/SceneInstance.cs @@ -63,13 +63,12 @@ public class SceneInstance var playerGroupInfo = new SceneEntityGroupInfo(); // avatar group foreach (var avatar in AvatarInfo) - playerGroupInfo.EntityList.Add(avatar.Value.AvatarInfo - .ToSceneEntityInfo(Player.Data.Pos, Player.Data.Rot, avatar.Value.AvatarType)); + playerGroupInfo.EntityList.Add(avatar.Value.AvatarInfo.ToSceneEntityInfo(avatar.Value.AvatarType)); if (playerGroupInfo.EntityList.Count > 0) { if (LeaderEntityId == 0) { - LeaderEntityId = AvatarInfo.Values.First().AvatarInfo.InternalEntityId; + LeaderEntityId = AvatarInfo.Values.First().AvatarInfo.EntityId; sceneInfo.LeaderEntityId = (uint)LeaderEntityId; } else @@ -245,33 +244,40 @@ public class SceneInstance var removeAvatar = new List(); foreach (var avatar in Player.LineupManager?.GetAvatarsFromCurTeam() ?? []) { - if (forceSetEntityId && avatar.AvatarInfo.InternalEntityId != 0) + avatar.AvatarInfo.PlayerData = Player.Data; + if (forceSetEntityId && avatar.AvatarInfo.EntityId != 0) { - removeAvatar.Add(new AvatarSceneInfo(new AvatarInfo(), AvatarType.AvatarFormalType, Player)); - avatar.AvatarInfo.SetEntityId(Player.Uid, 0); + removeAvatar.Add(new AvatarSceneInfo(new AvatarInfo + { + EntityId = avatar.AvatarInfo.EntityId + }, AvatarType.AvatarFormalType, Player)); + avatar.AvatarInfo.EntityId = 0; sendPacket = true; } - var avatarInstance = oldAvatarInfo.Find(x => x.AvatarInfo.BaseAvatarId == avatar.AvatarInfo.BaseAvatarId); + var avatarInstance = oldAvatarInfo.Find(x => x.AvatarInfo.AvatarId == avatar.AvatarInfo.AvatarId); if (avatarInstance == null) { - if (avatar.AvatarInfo.InternalEntityId == 0) avatar.AvatarInfo.SetEntityId(Player.Uid, ++LastEntityId); + if (avatar.AvatarInfo.EntityId == 0) avatar.AvatarInfo.EntityId = ++LastEntityId; addAvatar.Add(avatar); - AvatarInfo.Add(avatar.AvatarInfo.InternalEntityId, avatar); + AvatarInfo.Add(avatar.AvatarInfo.EntityId, avatar); sendPacket = true; } else { - AvatarInfo.Add(avatarInstance.AvatarInfo.InternalEntityId, avatarInstance); + AvatarInfo.Add(avatarInstance.AvatarInfo.EntityId, avatarInstance); } } foreach (var avatar in oldAvatarInfo.Where(avatar => - AvatarInfo.Values.ToList().FindIndex(x => - x.AvatarInfo.BaseAvatarId == avatar.AvatarInfo.BaseAvatarId) == -1)) + AvatarInfo.Values.ToList().FindIndex(x => x.AvatarInfo.AvatarId == avatar.AvatarInfo.AvatarId) == + -1)) { - removeAvatar.Add(new AvatarSceneInfo(new(), AvatarType.AvatarFormalType, Player)); - avatar.AvatarInfo.SetEntityId(Player.Uid, 0); + removeAvatar.Add(new AvatarSceneInfo(new AvatarInfo + { + EntityId = avatar.AvatarInfo.EntityId + }, AvatarType.AvatarFormalType, Player)); + avatar.AvatarInfo.EntityId = 0; sendPacket = true; } @@ -281,7 +287,7 @@ public class SceneInstance if (leaderAvatarSlot == -1) leaderAvatarSlot = 0; if (AvatarInfo.Count == 0) return; var info = AvatarInfo.Values.ToList()[leaderAvatarSlot ?? 0]; - LeaderEntityId = info.AvatarInfo.InternalEntityId; + LeaderEntityId = info.AvatarInfo.EntityId; if (sendPacket && !notSendPacket) await Player.SendPacket(new PacketSceneGroupRefreshScNotify(Player, addAvatar, removeAvatar)); } @@ -473,8 +479,8 @@ public class AvatarSceneInfo(AvatarInfo avatarInfo, AvatarType avatarType, Playe public int EntityID { - get => AvatarInfo.InternalEntityId; - set => AvatarInfo.SetEntityId(player.Uid, player.Data.WorldLevel, value); + get => AvatarInfo.EntityId; + set => AvatarInfo.EntityId = value; } public int GroupID { get; set; } = 0; @@ -514,7 +520,9 @@ public class AvatarSceneInfo(AvatarInfo avatarInfo, AvatarType avatarType, Playe } public SceneEntityInfo ToProto() - => AvatarInfo.ToSceneEntityInfo(player.Data.Pos, player.Data.Rot, AvatarType); + { + return AvatarInfo.ToSceneEntityInfo(AvatarType); + } public async ValueTask RemoveBuff(int buffId) { diff --git a/GameServer/Server/Packet/Recv/Avatar/HandlerUnlockSkilltreeCsReq.cs b/GameServer/Server/Packet/Recv/Avatar/HandlerUnlockSkilltreeCsReq.cs index 2d0e1600..b5311df7 100644 --- a/GameServer/Server/Packet/Recv/Avatar/HandlerUnlockSkilltreeCsReq.cs +++ b/GameServer/Server/Packet/Recv/Avatar/HandlerUnlockSkilltreeCsReq.cs @@ -32,7 +32,7 @@ public class HandlerUnlockSkilltreeCsReq : Handler await connection.Player!.InventoryManager!.RemoveItem((int)cost.PileItem.ItemId, (int)cost.PileItem.ItemNum); - avatar.GetCurAvatarInfo().SkillTree[(int)req.PointId] = (int)req.Level; + avatar.GetSkillTree()[(int)req.PointId] = (int)req.Level; await connection.SendPacket(new PacketPlayerSyncScNotify(avatar)); diff --git a/GameServer/Server/Packet/Recv/Player/HandlerGetMultiPathAvatarInfoCsReq.cs b/GameServer/Server/Packet/Recv/Player/HandlerGetMultiPathAvatarInfoCsReq.cs index 833a4412..cb52042e 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerGetMultiPathAvatarInfoCsReq.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerGetMultiPathAvatarInfoCsReq.cs @@ -8,6 +8,9 @@ public class HandlerGetMultiPathAvatarInfoCsReq : Handler { public override async Task OnHandle(Connection connection, byte[] header, byte[] data) { + // Hacky way to prevent exploding + connection.Player!.AvatarManager!.GetHero()!.ValidateHero(); + await connection.SendPacket(new PacketGetMultiPathAvatarInfoScRsp(connection.Player!)); } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/Player/HandlerSetAvatarPathCsReq.cs b/GameServer/Server/Packet/Recv/Player/HandlerSetAvatarPathCsReq.cs index c800cfd8..0955143f 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerSetAvatarPathCsReq.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerSetAvatarPathCsReq.cs @@ -1,4 +1,5 @@ using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Enums.Avatar; using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; using EggLink.DanhengServer.Kcp; using EggLink.DanhengServer.Proto; @@ -14,12 +15,19 @@ public class HandlerSetAvatarPathCsReq : Handler GameData.MultiplePathAvatarConfigData.TryGetValue((int)req.AvatarId, out var avatar); - if (avatar == null) - await connection.SendPacket(CmdIds.SetAvatarPathScRsp); + if (avatar != null) + { + if (avatar.BaseAvatarID == 8001) + await connection.Player!.ChangeAvatarPathType(avatar.BaseAvatarID, + (MultiPathAvatarTypeEnum)(avatar.AvatarID - (connection.Player.Data.CurrentGender - 1))); + else + await connection.Player!.ChangeAvatarPathType(avatar.BaseAvatarID, + (MultiPathAvatarTypeEnum)avatar.AvatarID); + await connection.SendPacket(new PacketSetAvatarPathScRsp(avatar.AvatarID)); + } else { - await connection.Player!.ChangeAvatarPathType(avatar.BaseAvatarID, (MultiPathAvatarType)avatar.AvatarID); - await connection.SendPacket(new PacketSetAvatarPathScRsp(avatar.AvatarID)); + await connection.SendPacket(CmdIds.SetAvatarPathScRsp); } } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/Player/HandlerSetPlayerInfoCsReq.cs b/GameServer/Server/Packet/Recv/Player/HandlerSetPlayerInfoCsReq.cs index 9fc34dab..967fa2d9 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerSetPlayerInfoCsReq.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerSetPlayerInfoCsReq.cs @@ -1,4 +1,5 @@ -using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; +using EggLink.DanhengServer.Enums.Avatar; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; using EggLink.DanhengServer.GameServer.Server.Packet.Send.PlayerSync; using EggLink.DanhengServer.Kcp; using EggLink.DanhengServer.Proto; @@ -25,8 +26,7 @@ public class HandlerSetPlayerInfoCsReq : Handler else player.Data.CurrentGender = Gender.Man; player.Data.IsGenderSet = true; - await player.ChangeAvatarPathType(8001, req.Gender == Gender.Man ? - MultiPathAvatarType.BoyWarriorType : MultiPathAvatarType.GirlWarriorType); + await player.ChangeAvatarPathType(8001, MultiPathAvatarTypeEnum.Warrior); await player.LineupManager!.AddAvatarToCurTeam(8001); await player.LineupManager!.AddAvatarToCurTeam(1001); diff --git a/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetAssistAvatarCsReq.cs b/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetAssistAvatarCsReq.cs index e0b08c0e..4f6fdb4b 100644 --- a/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetAssistAvatarCsReq.cs +++ b/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetAssistAvatarCsReq.cs @@ -11,7 +11,7 @@ public class HandlerSetAssistAvatarCsReq : Handler { var req = SetAssistAvatarCsReq.Parser.ParseFrom(data); var player = connection.Player!; - var avatars = player.Data.AssistAvatars; + var avatars = player.AvatarManager!.AvatarData!.AssistAvatars; avatars.Clear(); foreach (var id in req.AvatarIdList) { diff --git a/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetDisplayAvatarCsReq.cs b/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetDisplayAvatarCsReq.cs index d10adbad..e3cce34d 100644 --- a/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetDisplayAvatarCsReq.cs +++ b/GameServer/Server/Packet/Recv/PlayerBoard/HandlerSetDisplayAvatarCsReq.cs @@ -11,7 +11,7 @@ public class HandlerSetDisplayAvatarCsReq : Handler { var req = SetDisplayAvatarCsReq.Parser.ParseFrom(data); var player = connection.Player!; - var avatars = player.Data.DisplayAvatars; + var avatars = player.AvatarManager!.AvatarData!.DisplayAvatars; avatars.Clear(); foreach (var id in req.DisplayAvatarList) { diff --git a/GameServer/Server/Packet/Recv/Scene/HandlerSceneCastSkillCsReq.cs b/GameServer/Server/Packet/Recv/Scene/HandlerSceneCastSkillCsReq.cs index 12377c2c..6f1d006c 100644 --- a/GameServer/Server/Packet/Recv/Scene/HandlerSceneCastSkillCsReq.cs +++ b/GameServer/Server/Packet/Recv/Scene/HandlerSceneCastSkillCsReq.cs @@ -25,10 +25,11 @@ public class HandlerSceneCastSkillCsReq : Handler if (req.MazeAbilityStr != "") { // overwrite - caster.AvatarInfo.GetCurAvatarConfig().MazeAbility.TryGetValue(req.MazeAbilityStr, out AbilityInfo? ability); + AbilityInfo? ability = null; + caster.AvatarInfo.Excel?.MazeAbility.TryGetValue(req.MazeAbilityStr, out ability); if (ability != null) { - mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.CurAvatarId, ability, req); + mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.GetAvatarId(), ability, req); mazeSkill.OnCast(caster, player); } } @@ -38,26 +39,26 @@ public class HandlerSceneCastSkillCsReq : Handler if (req.SkillIndex > 0) { // Cast skill effects - var excel = caster.AvatarInfo.CurAvatarId > 0 - ? GameData.AvatarConfigData[caster.AvatarInfo.CurAvatarId] - : caster.AvatarInfo.GetCurAvatarConfig(); + var excel = caster.AvatarInfo.PathId > 0 + ? GameData.AvatarConfigData[caster.AvatarInfo.PathId] + : caster.AvatarInfo.Excel; if (excel != null && excel.MazeSkill != null) { - mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.CurAvatarId, (int)req.SkillIndex, + mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.GetAvatarId(), (int)req.SkillIndex, req); mazeSkill.OnCast(caster, player); } } else { - mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.CurAvatarId, 0, req); + mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.GetAvatarId(), 0, req); } } } if (req.AssistEntityIdList.Count > 0) { - if (caster != null && caster.AvatarInfo.BaseAvatarId == 1218 && req.SkillIndex == 1) + if (caster != null && caster.AvatarInfo.AvatarId == 1218 && req.SkillIndex == 1) { // Avoid Jiqoqiu's E skill await connection.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, [])); diff --git a/GameServer/Server/Packet/Send/Avatar/PacketGetAvatarDataScRsp.cs b/GameServer/Server/Packet/Send/Avatar/PacketGetAvatarDataScRsp.cs index 3a6462d6..31813bf3 100644 --- a/GameServer/Server/Packet/Send/Avatar/PacketGetAvatarDataScRsp.cs +++ b/GameServer/Server/Packet/Send/Avatar/PacketGetAvatarDataScRsp.cs @@ -19,7 +19,7 @@ public class PacketGetAvatarDataScRsp : BasePacket player.AvatarManager?.AvatarData?.Avatars?.ForEach(avatar => { - GameData.MultiplePathAvatarConfigData.TryGetValue(avatar.BaseAvatarId, out var multiPathAvatar); + GameData.MultiplePathAvatarConfigData.TryGetValue(avatar.AvatarId, out var multiPathAvatar); if (multiPathAvatar == null) { @@ -29,7 +29,7 @@ public class PacketGetAvatarDataScRsp : BasePacket else { // Multiple path avatar - if (avatar.BaseAvatarId == multiPathAvatar.BaseAvatarID) proto.AvatarList.Add(avatar.ToProto()); + if (avatar.AvatarId == multiPathAvatar.BaseAvatarID) proto.AvatarList.Add(avatar.ToProto()); } }); diff --git a/GameServer/Server/Packet/Send/Avatar/PacketMarkAvatarScRsp.cs b/GameServer/Server/Packet/Send/Avatar/PacketMarkAvatarScRsp.cs index c37aff5f..644d64ca 100644 --- a/GameServer/Server/Packet/Send/Avatar/PacketMarkAvatarScRsp.cs +++ b/GameServer/Server/Packet/Send/Avatar/PacketMarkAvatarScRsp.cs @@ -10,7 +10,7 @@ public class PacketMarkAvatarScRsp : BasePacket { var proto = new MarkAvatarScRsp { - AvatarId = (uint)avatar.BaseAvatarId, + AvatarId = (uint)avatar.AvatarId, IsMarked = avatar.IsMarked }; diff --git a/GameServer/Server/Packet/Send/Lineup/PacketGetLineupAvatarDataScRsp.cs b/GameServer/Server/Packet/Send/Lineup/PacketGetLineupAvatarDataScRsp.cs index 160f491d..416cf646 100644 --- a/GameServer/Server/Packet/Send/Lineup/PacketGetLineupAvatarDataScRsp.cs +++ b/GameServer/Server/Packet/Send/Lineup/PacketGetLineupAvatarDataScRsp.cs @@ -14,7 +14,7 @@ public class PacketGetLineupAvatarDataScRsp : BasePacket { var data = new LineupAvatarData { - Id = (uint)avatar.BaseAvatarId, + Id = (uint)avatar.AvatarId, Hp = (uint)avatar.CurrentHp, AvatarType = AvatarType.AvatarFormalType }; diff --git a/GameServer/Server/Packet/Send/Player/PacketGetBasicInfoScRsp.cs b/GameServer/Server/Packet/Send/Player/PacketGetBasicInfoScRsp.cs index b9e91f6e..ed0c76ac 100644 --- a/GameServer/Server/Packet/Send/Player/PacketGetBasicInfoScRsp.cs +++ b/GameServer/Server/Packet/Send/Player/PacketGetBasicInfoScRsp.cs @@ -17,10 +17,18 @@ public class PacketGetBasicInfoScRsp : BasePacket PlayerSettingInfo = new PlayerSettingInfo(), Gender = (uint)player.Data.CurrentGender }; + if (ConfigManager.Config.ServerOption.EnableMission) + { + if (player.AvatarManager!.GetHero()!.PathInfoes.Count > 0) player.Data.IsGenderSet = true; + proto.Gender = (uint)player.Data.CurrentGender; proto.IsGenderSet = player.Data.IsGenderSet; + } else + { + proto.Gender = (uint)player.Data.CurrentGender; proto.IsGenderSet = true; + } SetData(proto); } diff --git a/GameServer/Server/Packet/Send/Player/PacketGetMultiPathAvatarInfoScRsp.cs b/GameServer/Server/Packet/Send/Player/PacketGetMultiPathAvatarInfoScRsp.cs index 5b22f2d5..f597d642 100644 --- a/GameServer/Server/Packet/Send/Player/PacketGetMultiPathAvatarInfoScRsp.cs +++ b/GameServer/Server/Packet/Send/Player/PacketGetMultiPathAvatarInfoScRsp.cs @@ -12,17 +12,22 @@ public class PacketGetMultiPathAvatarInfoScRsp : BasePacket var proto = new GetMultiPathAvatarInfoScRsp(); foreach (var multiPathAvatar in GameData.MultiplePathAvatarConfigData.Values) - { - if (multiPathAvatar.AvatarID != multiPathAvatar.BaseAvatarID) continue; - - var avatar = player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID); - if (avatar == null) continue; - - if (avatar.BaseAvatarId == 8001) - proto.BasicTypeIdList.Add((uint)avatar.CurAvatarId); - proto.CurAvatarPath.Add((uint)avatar.BaseAvatarId, (MultiPathAvatarType)avatar.CurAvatarId); - proto.MultiPathAvatarInfoList.Add(avatar.ToAvatarPathProto()); - } + if (!proto.CurAvatarPath.ContainsKey((uint)multiPathAvatar.BaseAvatarID)) + { + var avatar = player.AvatarManager!.GetAvatar(multiPathAvatar.BaseAvatarID); + if (avatar != null) + { + if (avatar.AvatarId == 8001) // only add main character + proto.BasicTypeIdList.Add((uint)avatar.PathId); + var pathId = avatar.PathId > 0 ? avatar.PathId : avatar.AvatarId; + if (pathId == 8001) + if (player.Data.CurrentGender != Gender.Man) + pathId++; + proto.CurAvatarPath.Add((uint)avatar.AvatarId, (MultiPathAvatarType)pathId); + if (avatar.AvatarId == multiPathAvatar.BaseAvatarID) + proto.MultiPathAvatarInfoList.Add(avatar.ToAvatarPathProto()); + } + } SetData(proto); } diff --git a/GameServer/Server/Packet/Send/Player/PacketSetPlayerInfoScRsp.cs b/GameServer/Server/Packet/Send/Player/PacketSetPlayerInfoScRsp.cs index 7f8bf97c..b028a6e8 100644 --- a/GameServer/Server/Packet/Send/Player/PacketSetPlayerInfoScRsp.cs +++ b/GameServer/Server/Packet/Send/Player/PacketSetPlayerInfoScRsp.cs @@ -10,7 +10,7 @@ public class PacketSetPlayerInfoScRsp : BasePacket { var proto = new SetPlayerInfoScRsp { - CurAvatarPath = (MultiPathAvatarType)player.AvatarManager!.GetAvatar(8001)!.CurAvatarId, + CurAvatarPath = (MultiPathAvatarType)player.Data.CurBasicType, IsModify = IsModify }; diff --git a/GameServer/Server/Packet/Send/PlayerBoard/PacketGetPlayerBoardDataScRsp.cs b/GameServer/Server/Packet/Send/PlayerBoard/PacketGetPlayerBoardDataScRsp.cs index e225b19b..52e767e3 100644 --- a/GameServer/Server/Packet/Send/PlayerBoard/PacketGetPlayerBoardDataScRsp.cs +++ b/GameServer/Server/Packet/Send/PlayerBoard/PacketGetPlayerBoardDataScRsp.cs @@ -20,7 +20,7 @@ public class PacketGetPlayerBoardDataScRsp : BasePacket }; var pos = 0; - player.Data.DisplayAvatars.ForEach(avatar => + player.AvatarManager?.AvatarData!.DisplayAvatars.ForEach(avatar => { proto.DisplayAvatarVec.DisplayAvatarList.Add(new DisplayAvatarData { @@ -28,6 +28,7 @@ public class PacketGetPlayerBoardDataScRsp : BasePacket Pos = (uint)pos++ }); }); + player.AvatarManager?.AvatarData!.AssistAvatars.ForEach(x => proto.AssistAvatarIdList.Add((uint)x)); SetData(proto); } diff --git a/GameServer/Server/Packet/Send/PlayerSync/PacketPlayerSyncScNotify.cs b/GameServer/Server/Packet/Send/PlayerSync/PacketPlayerSyncScNotify.cs index 93dad01b..cbcce98d 100644 --- a/GameServer/Server/Packet/Send/PlayerSync/PacketPlayerSyncScNotify.cs +++ b/GameServer/Server/Packet/Send/PlayerSync/PacketPlayerSyncScNotify.cs @@ -33,7 +33,7 @@ public class PacketPlayerSyncScNotify : BasePacket }; proto.AvatarSync.AvatarList.Add(avatar.ToProto()); - if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.BaseAvatarId)) + if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.AvatarId)) proto.MultiPathAvatarInfoList.Add(avatar.ToAvatarPathProto()); SetData(proto); @@ -49,7 +49,7 @@ public class PacketPlayerSyncScNotify : BasePacket foreach (var avatar in avatars) { proto.AvatarSync.AvatarList.Add(avatar.ToProto()); - if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.BaseAvatarId)) + if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.AvatarId)) proto.MultiPathAvatarInfoList.Add(avatar.ToAvatarPathProto()); } @@ -63,7 +63,7 @@ public class PacketPlayerSyncScNotify : BasePacket proto.AvatarSync = new AvatarSync(); proto.AvatarSync.AvatarList.Add(avatar.ToProto()); - if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.BaseAvatarId)) + if (GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.AvatarId)) proto.MultiPathAvatarInfoList.Add(avatar.ToAvatarPathProto()); SetData(proto); diff --git a/WebServer/Server/MuipManager.cs b/WebServer/Server/MuipManager.cs index 3dbf89ec..ee0ceaad 100644 --- a/WebServer/Server/MuipManager.cs +++ b/WebServer/Server/MuipManager.cs @@ -291,8 +291,8 @@ public static class MuipManager HeadIconId = player.HeadIcon, CurFloorId = player.FloorId, CurPlaneId = player.PlaneId, - AssistAvatarList = player.AssistAvatars, - DisplayAvatarList = player.DisplayAvatars, + AssistAvatarList = avatarData.AssistAvatars, + DisplayAvatarList = avatarData.DisplayAvatars, AcceptedMissionList = missionDict, FinishedMainMissionIdList = missionData.FinishedMainMissionIds, FinishedSubMissionIdList = missionData.FinishedSubMissionIds,