revert: rewrite multi path system

This commit is contained in:
StopWuyu
2025-04-19 11:13:56 +08:00
parent 78a1573965
commit ddf67bc499
46 changed files with 753 additions and 444 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<string> DefaultPermissions { get; set; } = ["*"];

View File

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

View File

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

View File

@@ -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<int, PathInfo>(),
CurrentHp = hp == 0 ? 10000 : hp,
CurrentSp = sp,
InternalEntityId = Id
InternalEntityId = Id,
PlayerData = DatabaseHelper.Instance!.GetInstance<PlayerData>(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;

View File

@@ -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<AvatarInfo> Avatars { get; set; } = [];
[SugarColumn(IsJson = true)] public List<int> AssistAvatars { get; set; } = [];
[SugarColumn(IsJson = true)] public List<int> 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<int, MultiPathData> PathInfo { get; set; } = [];
public Dictionary<int, int> SkillTree { get; set; } = [];
public Dictionary<int, Dictionary<int, int>> SkillTreeExtra { get; set; } =
[]; // for hero heroId -> skillId -> level
public Dictionary<int, PathInfo> 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<int>();
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<int, int> 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<MultiPathAvatarInfo>();
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<InventoryData>(playerUid)!;
foreach (var item in GetCurAvatarInfo().Relic)
var inventory = DatabaseHelper.Instance!.GetInstance<InventoryData>(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<int, int> SkillTree { get; set; } = [];
public Dictionary<int, int> Relic { get; set; } = [];
public ItemData? EquipData { get; set; } // for special avatar
}

View File

@@ -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<AvatarData>(avatar.AssistUid);
var assistPlayer = DatabaseHelper.Instance?.GetInstance<AvatarData>(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));
}

View File

@@ -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<int> AssistAvatars { get; set; } = [];
[SugarColumn(IsJson = true)] public List<int> 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<PlayerData>((int)uid);
var result = DatabaseHelper.Instance?.GetInstance<PlayerData>((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<AvatarData>(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<AvatarData>(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<AvatarData>(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;
}

View File

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

View File

@@ -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
}
/// <summary>
/// path: Game.Command.Gender
/// path: Game.Command.Hero
/// </summary>
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 => "主角类型已更改!";
}
/// <summary>

View File

@@ -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
}
/// <summary>
/// path: Game.Command.Gender
/// path: Game.Command.Hero
/// </summary>
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 => "主角類型已更改!";
}
/// <summary>

View File

@@ -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
}
/// <summary>
/// path: Game.Command.Gender
/// path: Game.Command.Hero
/// </summary>
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!";
}
/// <summary>

View File

@@ -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<AvatarData>(player.Uid);
public AvatarManager(PlayerInstance player) : base(player)
{
AvatarData = DatabaseHelper.Instance!.GetInstanceOrCreateNew<AvatarData>(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<AvatarConfigExcel?> 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)

View File

@@ -127,10 +127,16 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List<Stage
if (list.Count > 0)
{
List<int> 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<Stage
var player = DatabaseHelper.Instance!.GetInstance<AvatarData>(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<Stage
var avatars = GetBattleAvatars();
foreach (var avatar in avatars)
proto.BattleAvatarList.Add(avatar.Key.ToBattleProto(
Player.Data.WorldLevel, Player.LineupManager!.GetCurLineup()!,
proto.BattleAvatarList.Add(avatar.Key.ToBattleProto(Player.LineupManager!.GetCurLineup()!,
Player.InventoryManager!.Data, avatar.Value));
System.Threading.Tasks.Task.Run(async () =>

View File

@@ -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<AvatarSceneInfo>());
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<AvatarSceneInfo>().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<AvatarSceneInfo>().ToList();
battleInstance.AvatarInfo = avatarList;

View File

@@ -11,19 +11,19 @@ public class MazeAddMazeBuff(int buffId, int duration) : IMazeSkillAction
public async ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> 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<EntityMonster> 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));
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<Gender>(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
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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, []));

View File

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

View File

@@ -10,7 +10,7 @@ public class PacketMarkAvatarScRsp : BasePacket
{
var proto = new MarkAvatarScRsp
{
AvatarId = (uint)avatar.BaseAvatarId,
AvatarId = (uint)avatar.AvatarId,
IsMarked = avatar.IsMarked
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,