diff --git a/Common/Data/Config/Task/CreateSummonUnit.cs b/Common/Data/Config/Task/CreateSummonUnit.cs index b486b6ba..3573c628 100644 --- a/Common/Data/Config/Task/CreateSummonUnit.cs +++ b/Common/Data/Config/Task/CreateSummonUnit.cs @@ -3,4 +3,5 @@ public class CreateSummonUnit : TaskConfigInfo { public int SummonUnitID { get; set; } + public DynamicFloat Duration { get; set; } = new(); } \ No newline at end of file diff --git a/Common/Data/Config/Task/DestroySummonUnit.cs b/Common/Data/Config/Task/DestroySummonUnit.cs index 3153eea3..e96fd9aa 100644 --- a/Common/Data/Config/Task/DestroySummonUnit.cs +++ b/Common/Data/Config/Task/DestroySummonUnit.cs @@ -1,6 +1,11 @@ namespace EggLink.DanhengServer.Data.Config.Task; public class DestroySummonUnit : TaskConfigInfo +{ + public SummonUnitSelector SummonUnit { get; set; } = new(); +} + +public class SummonUnitSelector { public int SummonUnitID { get; set; } } \ No newline at end of file diff --git a/GameServer/Game/Scene/SceneInstance.cs b/GameServer/Game/Scene/SceneInstance.cs index d6f707b2..b21ef3c3 100644 --- a/GameServer/Game/Scene/SceneInstance.cs +++ b/GameServer/Game/Scene/SceneInstance.cs @@ -311,7 +311,33 @@ public class SceneInstance if (config.OnAfterLocalPlayerUseSkill.Count > 0) { await Player.TaskManager!.AbilityLevelTask.TriggerTasks(avatarAbility, - config.OnAfterLocalPlayerUseSkill, entity, [], req); + config.OnAfterLocalPlayerUseSkill, entity, [], req, modifier); + } + } + } + } + + public async ValueTask OnChangeLeader(int curBaseAvatarId) + { + foreach (var entity in Entities.Values.OfType()) + { + if (!GameData.AvatarConfigData.TryGetValue(entity.AvatarInfo.AvatarId, out var excel)) continue; + if (curBaseAvatarId == entity.AvatarInfo.BaseAvatarId) continue; + + // unstage modifier + GameData.AdventureAbilityConfigListData.TryGetValue(excel.AdventurePlayerID, out var avatarAbility); + if (avatarAbility == null) continue; + foreach (var modifier in entity.Modifiers.ToArray()) + { + // get modifier info + if (!GameData.AdventureModifierData.TryGetValue(modifier, out var config)) continue; + if (config.OnUnstage.Count > 0) + { + await Player.TaskManager!.AbilityLevelTask.TriggerTasks(avatarAbility, + config.OnUnstage, entity, [], new SceneCastSkillCsReq + { + CastEntityId = (uint)entity.EntityId, + }, modifier); } } } @@ -526,6 +552,7 @@ public class SceneInstance foreach (var unitValue in SummonUnit.Values) { + if (unitValue.LifeTimeMs == -1) continue; var endTime = unitValue.CreateTimeMs + unitValue.LifeTimeMs; if (endTime < Extensions.GetUnixMs()) await RemoveSummonUnitById(unitValue.SummonUnitId); @@ -581,7 +608,6 @@ public class AvatarSceneInfo : IGameEntity, IGameModifier if (oldBuff.IsExpired()) { BuffList.Remove(oldBuff); - BuffList.Add(buff); } else { @@ -641,6 +667,7 @@ public class AvatarSceneInfo : IGameEntity, IGameModifier public async ValueTask AddModifier(string modifierName) { if (Modifiers.Contains(modifierName)) return; + Modifiers.Add(modifierName); GameData.AdventureModifierData.TryGetValue(modifierName, out var modifier); GameData.AdventureAbilityConfigListData.TryGetValue(AvatarInfo.AvatarId, out var avatarAbility); @@ -655,23 +682,19 @@ public class AvatarSceneInfo : IGameEntity, IGameModifier Rot = Player.Data.Rot?.ToProto() ?? new Vector() } }); - - Modifiers.Add(modifierName); } public async ValueTask RemoveModifier(string modifierName) { if (!Modifiers.Contains(modifierName)) return; + Modifiers.Remove(modifierName); GameData.AdventureModifierData.TryGetValue(modifierName, out var modifier); GameData.AdventureAbilityConfigListData.TryGetValue(AvatarInfo.AvatarId, out var avatarAbility); if (modifier == null || avatarAbility == null) return; await Player.TaskManager!.AbilityLevelTask.TriggerTasks(avatarAbility, modifier.OnDestroy, this, [], new SceneCastSkillCsReq()); - - Modifiers.Remove(modifierName); - ; } public async ValueTask RemoveBuff(int buffId) @@ -686,4 +709,20 @@ public class AvatarSceneInfo : IGameEntity, IGameModifier await RemoveModifier(buffExcel.ModifierName); } + + public async ValueTask ClearAllBuff() + { + if (BuffList.Count == 0) return; + await Player.SendPacket(new PacketSyncEntityBuffChangeListScNotify(this, BuffList)); + + foreach (var sceneBuff in BuffList) + { + if (!GameData.MazeBuffData.TryGetValue(sceneBuff.BuffId * 10 + sceneBuff.BuffLevel, out var buffExcel)) + continue; + + await RemoveModifier(buffExcel.ModifierName); + } + + BuffList.Clear(); + } } \ No newline at end of file diff --git a/GameServer/Game/Task/AvatarTask/AbilityLevelTask.cs b/GameServer/Game/Task/AvatarTask/AbilityLevelTask.cs index 7dbffa31..74bcb68c 100644 --- a/GameServer/Game/Task/AvatarTask/AbilityLevelTask.cs +++ b/GameServer/Game/Task/AvatarTask/AbilityLevelTask.cs @@ -9,6 +9,7 @@ using EggLink.DanhengServer.GameServer.Game.RogueMagic; using EggLink.DanhengServer.GameServer.Game.Scene; using EggLink.DanhengServer.GameServer.Game.Scene.Component; using EggLink.DanhengServer.GameServer.Game.Scene.Entity; +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Scene; using EggLink.DanhengServer.Proto; using EggLink.DanhengServer.Util; @@ -41,14 +42,14 @@ public class AbilityLevelTask(PlayerInstance player) #region Manage public async ValueTask TriggerTasks(AdventureAbilityConfigListInfo abilities, - List tasks, IGameEntity casterEntity, List targetEntities, SceneCastSkillCsReq req) + List tasks, IGameEntity casterEntity, List targetEntities, SceneCastSkillCsReq req, string? modifierName = null) { BattleInstance? instance = null; List battleInfos = []; foreach (var task in tasks) try { - var res = await TriggerTask(new AbilityLevelParam(abilities, task, casterEntity, targetEntities, req)); + var res = await TriggerTask(new AbilityLevelParam(abilities, task, casterEntity, targetEntities, req, modifierName)); if (res.BattleInfos != null) battleInfos.AddRange(res.BattleInfos); if (res.Instance != null) instance = res.Instance; @@ -295,8 +296,8 @@ public class AbilityLevelTask(PlayerInstance player) CreateAvatarEntityId = param.CasterEntity.EntityId, AttachEntityId = excel.ConfigInfo?.AttachPoint == "Origin" ? param.CasterEntity.EntityId : 0, SummonUnitId = excel.ID, - CreateAvatarId = (param.CasterEntity as AvatarSceneInfo)?.AvatarInfo.AvatarId ?? 0, - LifeTimeMs = 20000, + CreateAvatarId = (param.CasterEntity as AvatarSceneInfo)?.AvatarInfo.BaseAvatarId ?? 0, + LifeTimeMs = createSummonUnit.Duration.FixedValue.Value == -1 ? -1 : 20000, TriggerList = excel.ConfigInfo?.TriggerConfig.CustomTriggers ?? [], Motion = param.Request.TargetMotion }; @@ -309,7 +310,7 @@ public class AbilityLevelTask(PlayerInstance player) public async ValueTask DestroySummonUnit(AbilityLevelParam param) { - if (param.Act is DestroySummonUnit destroySummonUnit) await Player.SceneInstance!.RemoveSummonUnitById(destroySummonUnit.SummonUnitID); // TODO + if (param.Act is DestroySummonUnit destroySummonUnit) await Player.SceneInstance!.RemoveSummonUnitById(destroySummonUnit.SummonUnit.SummonUnitID); // TODO return new AbilityLevelResult(); } @@ -340,6 +341,30 @@ public class AbilityLevelTask(PlayerInstance player) return new AbilityLevelResult(); } + public async ValueTask RemoveSelfModifier(AbilityLevelParam param) + { + if (param.ModifierName != null) + { + if (param.CasterEntity is IGameModifier mod) await mod.RemoveModifier(param.ModifierName); + } + + return new AbilityLevelResult(); + } + + public async ValueTask RefreshMazeBuffTime(AbilityLevelParam param) + { + if (param.Act is RefreshMazeBuffTime refreshMazeBuffTime) + { + // get buff + var buff = param.CasterEntity.BuffList.FirstOrDefault(x => x.BuffId == refreshMazeBuffTime.ID); + if (buff == null) return new AbilityLevelResult(); + buff.Duration = refreshMazeBuffTime.LifeTime.GetValue(); + await Player.SendPacket(new PacketSyncEntityBuffChangeListScNotify(param.CasterEntity, buff)); + } + + return new AbilityLevelResult(); + } + public async ValueTask AdventureSetAttackTargetMonsterDie(AbilityLevelParam param) { foreach (var targetEntity in param.TargetEntities) @@ -472,4 +497,4 @@ public record AbilityLevelParam( TaskConfigInfo Act, IGameEntity CasterEntity, List TargetEntities, - SceneCastSkillCsReq Request); \ No newline at end of file + SceneCastSkillCsReq Request, string? ModifierName); \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/Lineup/HandlerChangeLineupLeaderCsReq.cs b/GameServer/Server/Packet/Recv/Lineup/HandlerChangeLineupLeaderCsReq.cs index 85e7dda0..a314c5b4 100644 --- a/GameServer/Server/Packet/Recv/Lineup/HandlerChangeLineupLeaderCsReq.cs +++ b/GameServer/Server/Packet/Recv/Lineup/HandlerChangeLineupLeaderCsReq.cs @@ -28,6 +28,7 @@ public class HandlerChangeLineupLeaderCsReq : Handler var leaderAvatarId = lineup.BaseAvatars![(int)req.Slot].BaseAvatarId; lineup.LeaderAvatarId = leaderAvatarId; await player.MissionManager!.HandleFinishType(MissionFinishTypeEnum.TeamLeaderChange); + await player.SceneInstance!.OnChangeLeader(leaderAvatarId); await connection.SendPacket(new PacketChangeLineupLeaderScRsp(req.Slot)); }