mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-02 20:26:03 +08:00
refactor: maze ability
This commit is contained in:
39
Common/Data/Config/AdventureAbilityConfigInfo.cs
Normal file
39
Common/Data/Config/AdventureAbilityConfigInfo.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using EggLink.DanhengServer.Data.Config.Task;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config;
|
||||
|
||||
public class AdventureAbilityConfigInfo
|
||||
{
|
||||
public List<TaskConfigInfo> OnAbort { get; set; } = [];
|
||||
public string Name { get; set; } = "";
|
||||
public List<TaskConfigInfo> OnAdd { get; set; } = [];
|
||||
public List<TaskConfigInfo> OnRemove { get; set; } = [];
|
||||
public List<TaskConfigInfo> OnStart { get; set; } = [];
|
||||
|
||||
public static AdventureAbilityConfigInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
AdventureAbilityConfigInfo info = new();
|
||||
|
||||
if (obj.ContainsKey(nameof(OnAbort)))
|
||||
info.OnAbort = obj[nameof(OnAbort)]
|
||||
?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)).ToList() ?? [];
|
||||
|
||||
if (obj.ContainsKey(nameof(Name)))
|
||||
info.Name = obj[nameof(Name)]?.ToObject<string>() ?? "";
|
||||
|
||||
if (obj.ContainsKey(nameof(OnAdd)))
|
||||
info.OnAdd = obj[nameof(OnAdd)]
|
||||
?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)).ToList() ?? [];
|
||||
|
||||
if (obj.ContainsKey(nameof(OnRemove)))
|
||||
info.OnRemove = obj[nameof(OnRemove)]
|
||||
?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)).ToList() ?? [];
|
||||
|
||||
if (obj.ContainsKey(nameof(OnStart)))
|
||||
info.OnStart = obj[nameof(OnStart)]
|
||||
?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)).ToList() ?? [];
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
25
Common/Data/Config/AdventureAbilityConfigListInfo.cs
Normal file
25
Common/Data/Config/AdventureAbilityConfigListInfo.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using EggLink.DanhengServer.Data.Config.AdventureAbility;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config;
|
||||
|
||||
public class AdventureAbilityConfigListInfo
|
||||
{
|
||||
public List<AdventureAbilityConfigInfo> AbilityList { get; set; } = [];
|
||||
public Dictionary<string, AdventureModifierConfig> GlobalModifiers { get; set; } = [];
|
||||
|
||||
public static AdventureAbilityConfigListInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
AdventureAbilityConfigListInfo info = new();
|
||||
|
||||
if (obj.ContainsKey(nameof(AbilityList)))
|
||||
info.AbilityList = obj[nameof(AbilityList)]
|
||||
?.Select(x => AdventureAbilityConfigInfo.LoadFromJsonObject((x as JObject)!)).ToList() ?? [];
|
||||
|
||||
if (!obj.ContainsKey(nameof(GlobalModifiers))) return info;
|
||||
foreach (var jObject in obj[nameof(GlobalModifiers)]!.ToObject<Dictionary<string, JObject>>()!)
|
||||
info.GlobalModifiers.Add(jObject.Key, AdventureModifierConfig.LoadFromJObject(jObject.Value));
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using EggLink.DanhengServer.Data.Excel;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config;
|
||||
|
||||
public class SkillAbilityInfo
|
||||
{
|
||||
public List<AbilityInfo> AbilityList { get; set; } = [];
|
||||
|
||||
public void Loaded(AvatarConfigExcel excel)
|
||||
{
|
||||
foreach (var ability in AbilityList)
|
||||
{
|
||||
ability.Loaded();
|
||||
|
||||
excel.MazeAbility.Add(ability.Name, ability);
|
||||
|
||||
if (ability.Name.EndsWith("MazeSkill"))
|
||||
excel.MazeSkill = ability;
|
||||
else if (ability.Name.Contains("NormalAtk")) excel.MazeAtk = ability;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AbilityInfo
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public List<TaskInfo> OnStart { get; set; } = [];
|
||||
|
||||
public void Loaded()
|
||||
{
|
||||
foreach (var task in OnStart) task.Loaded();
|
||||
}
|
||||
}
|
||||
31
Common/Data/Config/Task/AddAdventureModifier.cs
Normal file
31
Common/Data/Config/Task/AddAdventureModifier.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class AddAdventureModifier : TaskConfigInfo
|
||||
{
|
||||
public TargetEvaluator TargetType { get; set; } = new();
|
||||
public string ModifierName { get; set; } = "";
|
||||
|
||||
public new static TaskConfigInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
var info = new AddAdventureModifier
|
||||
{
|
||||
Type = obj[nameof(Type)]!.ToObject<string>()!
|
||||
};
|
||||
|
||||
if (obj.TryGetValue(nameof(TargetType), out var value))
|
||||
{
|
||||
var targetType = value as JObject;
|
||||
var classType =
|
||||
System.Type.GetType(
|
||||
$"EggLink.DanhengServer.Data.Config.Task.{targetType?["Type"]?.ToString().Replace("RPG.GameCore.", "")}");
|
||||
classType ??= System.Type.GetType("EggLink.DanhengServer.Data.Config.Task.TargetEvaluator");
|
||||
info.TargetType = (targetType!.ToObject(classType!) as TargetEvaluator)!;
|
||||
}
|
||||
|
||||
if (obj.TryGetValue(nameof(ModifierName), out value)) info.ModifierName = value.ToObject<string>()!;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
46
Common/Data/Config/Task/AdventureFireProjectile.cs
Normal file
46
Common/Data/Config/Task/AdventureFireProjectile.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.CodeDom.Compiler;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class AdventureFireProjectile : TaskConfigInfo
|
||||
{
|
||||
public TargetEvaluator TargetType { get; set; } = new();
|
||||
//public ProjectileData Projectile { get; set; }
|
||||
public List<TaskConfigInfo> OnProjectileHit { get; set; } = [];
|
||||
public List<TaskConfigInfo> OnProjectileLifetimeFinish { get; set; } = [];
|
||||
public bool WaitProjectileFinish { get; set; }
|
||||
public string MutexName { get; set; } = "";
|
||||
|
||||
public new static TaskConfigInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
var info = new AdventureFireProjectile
|
||||
{
|
||||
Type = obj[nameof(Type)]!.ToObject<string>()!
|
||||
};
|
||||
|
||||
if (obj.TryGetValue(nameof(TargetType), out var value))
|
||||
{
|
||||
var targetType = value as JObject;
|
||||
var classType =
|
||||
System.Type.GetType(
|
||||
$"EggLink.DanhengServer.Data.Config.Task.{targetType?["Type"]?.ToString().Replace("RPG.GameCore.", "")}");
|
||||
classType ??= System.Type.GetType("EggLink.DanhengServer.Data.Config.Task.TargetEvaluator");
|
||||
info.TargetType = (targetType!.ToObject(classType!) as TargetEvaluator)!;
|
||||
}
|
||||
|
||||
foreach (var item in
|
||||
obj[nameof(OnProjectileHit)]?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)) ?? [])
|
||||
info.OnProjectileHit.Add(item);
|
||||
|
||||
foreach (var item in
|
||||
obj[nameof(OnProjectileLifetimeFinish)]?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)) ?? [])
|
||||
info.OnProjectileLifetimeFinish.Add(item);
|
||||
|
||||
if (obj.TryGetValue(nameof(WaitProjectileFinish), out value)) info.WaitProjectileFinish = value.ToObject<bool>();
|
||||
|
||||
if (obj.TryGetValue(nameof(MutexName), out value)) info.MutexName = value.ToObject<string>()!;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
76
Common/Data/Config/Task/AdventureTriggerAttack.cs
Normal file
76
Common/Data/Config/Task/AdventureTriggerAttack.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class AdventureTriggerAttack : TaskConfigInfo
|
||||
{
|
||||
public TargetEvaluator AttackTargetType { get; set; } = new();
|
||||
public TargetEvaluator AttackRootTargetType { get; set; } = new();
|
||||
public bool TriggerBattle { get; set; }
|
||||
|
||||
public float TriggerBattleDelay { get; set; }
|
||||
|
||||
// public AdventureAttackDetectSummonUnitTriggerConfig SummonUnitTriggerAttackDetectConfig { get; set; }
|
||||
// public AdventureAttackDetectShapeConfig AttackDetectConfig { get; set; }
|
||||
// public AdventureHitConfig HitConfig { get; set; }
|
||||
public List<TaskConfigInfo> OnAttack { get; set; } = [];
|
||||
public List<TaskConfigInfo> OnBattle { get; set; } = [];
|
||||
public List<TaskConfigInfo> OnHit { get; set; } = [];
|
||||
public List<TaskConfigInfo> OnKill { get; set; } = [];
|
||||
public bool IncludeProps { get; set; }
|
||||
public bool HitTargetFaceToAttacker { get; set; }
|
||||
public bool TriggerBattleByAllHitTarget { get; set; }
|
||||
public bool AttackDetectCollision { get; set; }
|
||||
|
||||
|
||||
public new static TaskConfigInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
var info = new AdventureTriggerAttack
|
||||
{
|
||||
Type = obj[nameof(Type)]!.ToObject<string>()!
|
||||
};
|
||||
if (obj.TryGetValue(nameof(AttackTargetType), out var value))
|
||||
{
|
||||
var targetType = value as JObject;
|
||||
var classType =
|
||||
System.Type.GetType(
|
||||
$"EggLink.DanhengServer.Data.Config.Task.{targetType?["Type"]?.ToString().Replace("RPG.GameCore.", "")}");
|
||||
classType ??= System.Type.GetType("EggLink.DanhengServer.Data.Config.Task.TargetEvaluator");
|
||||
info.AttackTargetType = (targetType!.ToObject(classType!) as TargetEvaluator)!;
|
||||
}
|
||||
|
||||
if (obj.TryGetValue(nameof(AttackRootTargetType), out var v))
|
||||
{
|
||||
var targetType = v as JObject;
|
||||
var classType =
|
||||
System.Type.GetType(
|
||||
$"EggLink.DanhengServer.Data.Config.Task.{targetType?["Type"]?.ToString().Replace("RPG.GameCore.", "")}");
|
||||
classType ??= System.Type.GetType("EggLink.DanhengServer.Data.Config.Task.TargetEvaluator");
|
||||
info.AttackRootTargetType = (targetType!.ToObject(classType!) as TargetEvaluator)!;
|
||||
}
|
||||
|
||||
foreach (var item in
|
||||
obj[nameof(OnAttack)]?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)) ?? [])
|
||||
info.OnAttack.Add(item);
|
||||
foreach (var item in
|
||||
obj[nameof(OnBattle)]?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)) ?? [])
|
||||
info.OnBattle.Add(item);
|
||||
foreach (var item in
|
||||
obj[nameof(OnHit)]?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)) ?? [])
|
||||
info.OnHit.Add(item);
|
||||
foreach (var item in
|
||||
obj[nameof(OnKill)]?.Select(x => TaskConfigInfo.LoadFromJsonObject((x as JObject)!)) ?? [])
|
||||
info.OnKill.Add(item);
|
||||
if (obj.TryGetValue(nameof(TriggerBattle), out value)) info.TriggerBattle = value.ToObject<bool>();
|
||||
if (obj.TryGetValue(nameof(TriggerBattleDelay), out value))
|
||||
info.TriggerBattleDelay = value.ToObject<float>();
|
||||
if (obj.TryGetValue(nameof(IncludeProps), out value)) info.IncludeProps = value.ToObject<bool>();
|
||||
if (obj.TryGetValue(nameof(HitTargetFaceToAttacker), out value))
|
||||
info.HitTargetFaceToAttacker = value.ToObject<bool>();
|
||||
if (obj.TryGetValue(nameof(TriggerBattleByAllHitTarget), out value))
|
||||
info.TriggerBattleByAllHitTarget = value.ToObject<bool>();
|
||||
if (obj.TryGetValue(nameof(AttackDetectCollision), out value))
|
||||
info.AttackDetectCollision = value.ToObject<bool>();
|
||||
return info;
|
||||
}
|
||||
}
|
||||
13
Common/Data/Config/Task/ByCharacterDamageType.cs
Normal file
13
Common/Data/Config/Task/ByCharacterDamageType.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using EggLink.DanhengServer.Enums.Avatar;
|
||||
using EggLink.DanhengServer.Enums.Task;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class ByCharacterDamageType : PredicateConfigInfo
|
||||
{
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public DamageTypeEnum DamageType { get; set; } = DamageTypeEnum.Fire;
|
||||
}
|
||||
6
Common/Data/Config/Task/CreateSummonUnit.cs
Normal file
6
Common/Data/Config/Task/CreateSummonUnit.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class DestroySummonUnit : TaskConfigInfo
|
||||
{
|
||||
public int SummonUnitID { get; set; }
|
||||
}
|
||||
6
Common/Data/Config/Task/DestroySummonUnit.cs
Normal file
6
Common/Data/Config/Task/DestroySummonUnit.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class CreateSummonUnit : TaskConfigInfo
|
||||
{
|
||||
public int SummonUnitID { get; set; }
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public class PropStateExecute : TaskConfigInfo
|
||||
{
|
||||
Type = obj[nameof(Type)]!.ToObject<string>()!
|
||||
};
|
||||
|
||||
if (obj.ContainsKey(nameof(TargetType)))
|
||||
{
|
||||
var targetType = obj[nameof(TargetType)] as JObject;
|
||||
|
||||
@@ -8,7 +8,6 @@ public class RefreshMazeBuffTime : TaskConfigInfo
|
||||
public int ID { get; set; }
|
||||
public DynamicFloat LifeTime { get; set; } = new();
|
||||
|
||||
|
||||
public new static TaskConfigInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
var info = new RefreshMazeBuffTime
|
||||
|
||||
31
Common/Data/Config/Task/RemoveAdventureModifier.cs
Normal file
31
Common/Data/Config/Task/RemoveAdventureModifier.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class RemoveAdventureModifier : TaskConfigInfo
|
||||
{
|
||||
public TargetEvaluator TargetType { get; set; } = new();
|
||||
public string ModifierName { get; set; } = "";
|
||||
|
||||
public new static TaskConfigInfo LoadFromJsonObject(JObject obj)
|
||||
{
|
||||
var info = new RemoveAdventureModifier
|
||||
{
|
||||
Type = obj[nameof(Type)]!.ToObject<string>()!
|
||||
};
|
||||
|
||||
if (obj.TryGetValue(nameof(TargetType), out var value))
|
||||
{
|
||||
var targetType = value as JObject;
|
||||
var classType =
|
||||
System.Type.GetType(
|
||||
$"EggLink.DanhengServer.Data.Config.Task.{targetType?["Type"]?.ToString().Replace("RPG.GameCore.", "")}");
|
||||
classType ??= System.Type.GetType("EggLink.DanhengServer.Data.Config.Task.TargetEvaluator");
|
||||
info.TargetType = (targetType!.ToObject(classType!) as TargetEvaluator)!;
|
||||
}
|
||||
|
||||
if (obj.TryGetValue(nameof(ModifierName), out value)) info.ModifierName = value.ToObject<string>()!;
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
6
Common/Data/Config/Task/TargetAlias.cs
Normal file
6
Common/Data/Config/Task/TargetAlias.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace EggLink.DanhengServer.Data.Config.Task;
|
||||
|
||||
public class TargetAlias : TargetEvaluator
|
||||
{
|
||||
public string Alias { get; set; } = "";
|
||||
}
|
||||
@@ -58,6 +58,34 @@ public class TaskConfigInfo
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeStr == "AdventureFireProjectile")
|
||||
{
|
||||
var res = AdventureFireProjectile.LoadFromJsonObject(json);
|
||||
res.Type = type;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeStr == "AdventureTriggerAttack")
|
||||
{
|
||||
var res = AdventureTriggerAttack.LoadFromJsonObject(json);
|
||||
res.Type = type;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeStr == "AddAdventureModifier")
|
||||
{
|
||||
var res = AddAdventureModifier.LoadFromJsonObject(json);
|
||||
res.Type = type;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeStr == "RemoveAdventureModifier")
|
||||
{
|
||||
var res = RemoveAdventureModifier.LoadFromJsonObject(json);
|
||||
res.Type = type;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeClass != null)
|
||||
{
|
||||
var res = (TaskConfigInfo)json.ToObject(typeClass)!;
|
||||
|
||||
@@ -32,13 +32,6 @@ public class AvatarConfigExcel : ExcelResource
|
||||
|
||||
[JsonIgnore] public int RankUpItemId { get; set; }
|
||||
|
||||
[JsonIgnore] public string NameKey { get; set; } = "";
|
||||
|
||||
[JsonIgnore] public AbilityInfo? MazeSkill { get; set; }
|
||||
|
||||
[JsonIgnore] public AbilityInfo? MazeAtk { get; set; }
|
||||
[JsonIgnore] public Dictionary<string, AbilityInfo> MazeAbility { get; set; } = [];
|
||||
|
||||
public override int GetId()
|
||||
{
|
||||
return AvatarID;
|
||||
@@ -48,10 +41,6 @@ public class AvatarConfigExcel : ExcelResource
|
||||
{
|
||||
if (!GameData.AvatarConfigData.ContainsKey(AvatarID)) GameData.AvatarConfigData.Add(AvatarID, this);
|
||||
RankUpItemId = AvatarID + 10000;
|
||||
|
||||
var regex = new Regex(@"(?<=Avatar_)(.*?)(?=_Config)");
|
||||
var match = regex.Match(JsonPath ?? "");
|
||||
if (match.Success) NameKey = match.Value;
|
||||
JsonPath = null;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace EggLink.DanhengServer.Data.Excel;
|
||||
|
||||
[ResourceEntity("MazeBuff.json")]
|
||||
[ResourceEntity("MazeBuff.json,AvatarMazeBuff.json", isMultifile:true)]
|
||||
public class MazeBuffExcel : ExcelResource
|
||||
{
|
||||
public int ID { get; set; }
|
||||
@@ -16,7 +16,7 @@ public class MazeBuffExcel : ExcelResource
|
||||
|
||||
public override void Loaded()
|
||||
{
|
||||
GameData.MazeBuffData.Add(GetId(), this);
|
||||
GameData.MazeBuffData.TryAdd(GetId(), this);
|
||||
}
|
||||
|
||||
public BattleBuff ToProto()
|
||||
|
||||
@@ -9,6 +9,8 @@ public class NPCMonsterDataExcel : ExcelResource
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public HashName NPCName { get; set; } = new();
|
||||
public string JsonPath { get; set; } = "";
|
||||
public string ConfigEntityPath { get; set; } = "";
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MonsterRankEnum Rank { get; set; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.Data.Config.AdventureAbility;
|
||||
using EggLink.DanhengServer.Data.Config.Scene;
|
||||
using EggLink.DanhengServer.Data.Custom;
|
||||
@@ -39,6 +40,7 @@ public static class GameData
|
||||
#region Avatar
|
||||
|
||||
public static Dictionary<int, AvatarConfigExcel> AvatarConfigData { get; private set; } = [];
|
||||
public static Dictionary<int, AdventureAbilityConfigListInfo> AdventureAbilityConfigListData { get; private set; } = [];
|
||||
public static Dictionary<int, AvatarPromotionConfigExcel> AvatarPromotionConfigData { get; private set; } = [];
|
||||
public static Dictionary<int, AvatarExpItemConfigExcel> AvatarExpItemConfigData { get; private set; } = [];
|
||||
public static Dictionary<int, AvatarSkillTreeConfigExcel> AvatarSkillTreeConfigData { get; private set; } = [];
|
||||
|
||||
@@ -416,9 +416,44 @@ public class ResourceManager
|
||||
using var reader = file.OpenRead();
|
||||
using StreamReader reader2 = new(reader);
|
||||
var text = reader2.ReadToEnd().Replace("$type", "Type");
|
||||
var skillAbilityInfo = JsonConvert.DeserializeObject<SkillAbilityInfo>(text);
|
||||
skillAbilityInfo?.Loaded(avatar);
|
||||
count += skillAbilityInfo == null ? 0 : 1;
|
||||
var obj = JObject.Parse(text);
|
||||
|
||||
var info = AdventureAbilityConfigListInfo.LoadFromJsonObject(obj);
|
||||
|
||||
GameData.AdventureAbilityConfigListData.TryAdd(avatar.AvatarID, info);
|
||||
count++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ResourceCache.IsComplete = false;
|
||||
Logger.Error(
|
||||
I18NManager.Translate("Server.ServerInfo.FailedToReadItem", adventurePath,
|
||||
I18NManager.Translate("Word.Error")), ex);
|
||||
}
|
||||
});
|
||||
|
||||
var res2 = Parallel.ForEach(GameData.NpcMonsterDataData.Values, adventure =>
|
||||
{
|
||||
var adventurePath = adventure.ConfigEntityPath.Replace("_Entity.json", "_Ability.json").Replace("_Config.json", "_Ability.json")
|
||||
.Replace("ConfigEntity", "ConfigAdventureAbility");
|
||||
|
||||
var path = ConfigManager.Config.Path.ResourcePath + "/" + adventurePath;
|
||||
var file = new FileInfo(path);
|
||||
if (!file.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using var reader = file.OpenRead();
|
||||
using StreamReader reader2 = new(reader);
|
||||
var text = reader2.ReadToEnd().Replace("$type", "Type");
|
||||
var obj = JObject.Parse(text);
|
||||
|
||||
var info = AdventureAbilityConfigListInfo.LoadFromJsonObject(obj);
|
||||
|
||||
GameData.AdventureAbilityConfigListData.TryAdd(adventure.ID, info);
|
||||
count++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -430,9 +465,9 @@ public class ResourceManager
|
||||
});
|
||||
|
||||
// wait it done
|
||||
while (!res.IsCompleted) Thread.Sleep(10);
|
||||
while (!res.IsCompleted || !res2.IsCompleted) Thread.Sleep(10);
|
||||
|
||||
if (count < GameData.AdventurePlayerData.Count)
|
||||
if (count < GameData.AdventurePlayerData.Count + GameData.NpcMonsterDataData.Count)
|
||||
Logger.Warn(I18NManager.Translate("Server.ServerInfo.ConfigMissing",
|
||||
I18NManager.Translate("Word.MazeSkillInfo"),
|
||||
$"{ConfigManager.Config.Path.ResourcePath}/Config/Level/AdventureAbility",
|
||||
|
||||
@@ -3,6 +3,7 @@ using EggLink.DanhengServer.Data.Excel;
|
||||
using EggLink.DanhengServer.Database;
|
||||
using EggLink.DanhengServer.Database.Avatar;
|
||||
using EggLink.DanhengServer.Database.Inventory;
|
||||
using EggLink.DanhengServer.Enums.Avatar;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
@@ -243,6 +244,14 @@ public class BattleInstance(PlayerInstance player, LineupInfo lineup, List<Stage
|
||||
await avatar.ApplyBuff(this);
|
||||
}).Wait();
|
||||
|
||||
foreach (var buff in Buffs.Clone())
|
||||
{
|
||||
if (Enum.IsDefined(typeof(DamageTypeEnum), buff.BuffID))
|
||||
{
|
||||
Buffs.RemoveAll(x => x.BuffID == buff.BuffID && x.DynamicValues.Count == 0);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var eventInstance in BattleEvents.Values) proto.BattleEvent.Add(eventInstance.ToProto());
|
||||
|
||||
for (var i = 1; i <= 5; i++)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Excel;
|
||||
using EggLink.DanhengServer.Database.Inventory;
|
||||
using EggLink.DanhengServer.GameServer.Game.Battle.Skill;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.RogueMagic;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
@@ -17,21 +16,21 @@ namespace EggLink.DanhengServer.GameServer.Game.Battle;
|
||||
|
||||
public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
{
|
||||
public StageConfigExcel? NextBattleStageConfig { get; set; } = null;
|
||||
public async ValueTask StartBattle(SceneCastSkillCsReq req, MazeSkill skill, List<uint> hitTargetEntityIdList)
|
||||
public StageConfigExcel? NextBattleStageConfig { get; set; }
|
||||
|
||||
public async ValueTask<BattleInstance?> StartBattle(IGameEntity attackEntity, List<IGameEntity> targetEntityList, bool isSkill)
|
||||
{
|
||||
if (Player.BattleInstance != null) return;
|
||||
if (Player.BattleInstance != null) return Player.BattleInstance;
|
||||
var targetList = new List<EntityMonster>();
|
||||
var avatarList = new List<AvatarSceneInfo>();
|
||||
var propList = new List<EntityProp>();
|
||||
Player.SceneInstance!.AvatarInfo.TryGetValue((int)req.AttackedByEntityId, out var castAvatar);
|
||||
Player.SceneInstance!.AvatarInfo.TryGetValue(attackEntity.EntityID, out var castAvatar);
|
||||
|
||||
if (Player.SceneInstance!.AvatarInfo.ContainsKey((int)req.AttackedByEntityId))
|
||||
if (castAvatar != null)
|
||||
{
|
||||
foreach (var entity in hitTargetEntityIdList)
|
||||
foreach (var entity in targetEntityList)
|
||||
{
|
||||
Player.SceneInstance!.Entities.TryGetValue((int)entity, out var entityInstance);
|
||||
switch (entityInstance)
|
||||
switch (entity)
|
||||
{
|
||||
case EntityMonster monster:
|
||||
targetList.Add(monster);
|
||||
@@ -41,35 +40,24 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var info in req.AssistMonsterEntityInfo)
|
||||
foreach (var entity in info.EntityIdList)
|
||||
{
|
||||
Player.SceneInstance!.Entities.TryGetValue((int)entity, out var entityInstance);
|
||||
if (entityInstance is not EntityMonster monster) continue;
|
||||
if (targetList.Contains(monster)) continue; // avoid adding the same monster twice
|
||||
targetList.Add(monster);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var isAmbushed =
|
||||
hitTargetEntityIdList.Any(entity => Player.SceneInstance!.AvatarInfo.ContainsKey((int)entity));
|
||||
targetEntityList.Any(entity => Player.SceneInstance!.AvatarInfo.ContainsKey(entity.EntityID));
|
||||
|
||||
if (!isAmbushed)
|
||||
{
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, []));
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var monsterEntity = Player.SceneInstance!.Entities[(int)req.AttackedByEntityId];
|
||||
var monsterEntity = Player.SceneInstance!.Entities[attackEntity.EntityID];
|
||||
if (monsterEntity is EntityMonster monster) targetList.Add(monster);
|
||||
}
|
||||
|
||||
if (targetList.Count == 0 && propList.Count == 0)
|
||||
{
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, []));
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var prop in propList)
|
||||
@@ -94,49 +82,20 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
|
||||
if (targetList.Count > 0)
|
||||
{
|
||||
// Skill handle
|
||||
if (!skill.TriggerBattle)
|
||||
{
|
||||
// Skill is not supposed to trigger a battle
|
||||
List<HitMonsterInstance> hitMonsterInstances = [];
|
||||
hitMonsterInstances.AddRange(targetList.Select(entityMonster =>
|
||||
new HitMonsterInstance(entityMonster.EntityID, MonsterBattleType.NoBattle)));
|
||||
|
||||
skill.OnHitTarget(Player.SceneInstance!.AvatarInfo[(int)req.AttackedByEntityId], targetList);
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, hitMonsterInstances));
|
||||
return;
|
||||
}
|
||||
|
||||
if (castAvatar != null)
|
||||
{
|
||||
skill.OnAttack(Player.SceneInstance!.AvatarInfo[(int)req.AttackedByEntityId], targetList);
|
||||
skill.OnCast(castAvatar, Player);
|
||||
}
|
||||
|
||||
var triggerBattle = targetList.Any(target => target.IsAlive);
|
||||
|
||||
if (!triggerBattle)
|
||||
{
|
||||
List<HitMonsterInstance> hitMonsterInstances = [];
|
||||
hitMonsterInstances.AddRange(targetList.Select(entityMonster =>
|
||||
new HitMonsterInstance(entityMonster.EntityID, MonsterBattleType.DirectDieSimulateBattle)));
|
||||
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, hitMonsterInstances));
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var inst = Player.RogueManager!.GetRogueInstance();
|
||||
if (inst is RogueMagicInstance { CurLevel.CurRoom.AdventureInstance: not null } magic)
|
||||
{
|
||||
List<HitMonsterInstance> hitMonsterInstances = [];
|
||||
hitMonsterInstances.AddRange(targetList.Select(entityMonster =>
|
||||
new HitMonsterInstance(entityMonster.EntityID, MonsterBattleType.DirectDieSkipBattle)));
|
||||
|
||||
await magic.HitMonsterInAdventure(targetList);
|
||||
|
||||
foreach (var entityMonster in targetList) await entityMonster.Kill();
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, hitMonsterInstances));
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
BattleInstance battleInstance =
|
||||
@@ -169,7 +128,7 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
if (avatarExcel != null)
|
||||
{
|
||||
mazeBuff = new MazeBuff((int)avatarExcel.DamageType, 1, index);
|
||||
mazeBuff.DynamicValues.Add("SkillIndex", skill.IsMazeSkill ? 2 : 1);
|
||||
mazeBuff.DynamicValues.Add("SkillIndex", isSkill ? 2 : 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -181,7 +140,9 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
}
|
||||
|
||||
if (mazeBuff != null && mazeBuff.BuffID != 0) // avoid adding a buff with ID 0
|
||||
{
|
||||
battleInstance.Buffs.Add(mazeBuff);
|
||||
}
|
||||
|
||||
battleInstance.AvatarInfo = avatarList;
|
||||
|
||||
@@ -192,23 +153,14 @@ public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
|
||||
Player.BattleInstance = battleInstance;
|
||||
|
||||
// Send battle start packet
|
||||
List<HitMonsterInstance> hitMonsterInstance = [];
|
||||
hitMonsterInstance.AddRange(targetList.Where(x => x.IsAlive).Select(entityMonster =>
|
||||
new HitMonsterInstance(entityMonster.EntityID, MonsterBattleType.TriggerBattle)));
|
||||
hitMonsterInstance.AddRange(targetList.Where(x => !x.IsAlive).Select(entityMonster =>
|
||||
new HitMonsterInstance(entityMonster.EntityID, MonsterBattleType.DirectDieSkipBattle)));
|
||||
|
||||
InvokeOnPlayerEnterBattle(Player, battleInstance);
|
||||
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, battleInstance,
|
||||
hitMonsterInstance));
|
||||
Player.SceneInstance?.ClearSummonUnit();
|
||||
|
||||
return battleInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
await Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, []));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async ValueTask StartStage(int eventId)
|
||||
|
||||
78
GameServer/Game/Battle/SceneSkillManager.cs
Normal file
78
GameServer/Game/Battle/SceneSkillManager.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle;
|
||||
|
||||
public class SceneSkillManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
{
|
||||
public async ValueTask<SkillResultData> OnCast(SceneCastSkillCsReq req)
|
||||
{
|
||||
// get entities
|
||||
List<IGameEntity> targetEntities = []; // enemy
|
||||
IGameEntity? attackEntity; // caster
|
||||
List<int> addEntityIds = [];
|
||||
foreach (var id in req.AssistMonsterEntityIdList)
|
||||
{
|
||||
if (Player.SceneInstance!.Entities.TryGetValue((int)id, out var v))
|
||||
{
|
||||
targetEntities.Add(v);
|
||||
addEntityIds.Add((int)id);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var info in req.AssistMonsterEntityInfo)
|
||||
{
|
||||
foreach (var id in info.EntityIdList)
|
||||
{
|
||||
if (addEntityIds.Contains((int)id)) continue;
|
||||
if (Player.SceneInstance!.Entities.TryGetValue((int)id, out var v))
|
||||
{
|
||||
targetEntities.Add(v);
|
||||
addEntityIds.Add((int)id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attackEntity = Player.SceneInstance!.Entities.GetValueOrDefault((int)req.AttackedByEntityId);
|
||||
if (attackEntity == null) return new SkillResultData(Retcode.RetSceneEntityNotExist);
|
||||
// get ability file
|
||||
var abilities = GetAbilityConfig(attackEntity);
|
||||
if (abilities == null || abilities.AbilityList.Count < 1)
|
||||
return new SkillResultData(Retcode.RetMazeNoAbility);
|
||||
|
||||
var abilityName = !string.IsNullOrEmpty(req.MazeAbilityStr) ? req.MazeAbilityStr: req.SkillIndex == 0 ? "NormalAtk01" : "MazeSkill";
|
||||
var targetAbility = abilities.AbilityList.Find(x => x.Name.Contains(abilityName));
|
||||
if (targetAbility == null)
|
||||
{
|
||||
targetAbility = abilities.AbilityList.FirstOrDefault();
|
||||
if (targetAbility == null)
|
||||
return new SkillResultData(Retcode.RetMazeNoAbility);
|
||||
}
|
||||
|
||||
// execute ability
|
||||
var res = await Player.TaskManager!.AbilityLevelTask.TriggerTasks(abilities, targetAbility.OnStart, attackEntity, targetEntities, req);
|
||||
|
||||
return new SkillResultData(Retcode.RetSucc, res.Instance, res.BattleInfos);
|
||||
}
|
||||
|
||||
private AdventureAbilityConfigListInfo? GetAbilityConfig(IGameEntity entity)
|
||||
{
|
||||
if (entity is EntityMonster monster)
|
||||
{
|
||||
return GameData.AdventureAbilityConfigListData.GetValueOrDefault(monster.MonsterData.ID);
|
||||
}
|
||||
|
||||
if (entity is AvatarSceneInfo avatar)
|
||||
{
|
||||
return GameData.AdventureAbilityConfigListData.GetValueOrDefault(avatar.AvatarInfo.GetAvatarId());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public record SkillResultData(Retcode RetCode, BattleInstance? Instance = null, List<HitMonsterInstance>? TriggerBattleInfos = null);
|
||||
@@ -1,29 +0,0 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill.Action;
|
||||
|
||||
public class MazeAddMazeBuff(int buffId, int duration) : IMazeSkillAction
|
||||
{
|
||||
public int BuffId { get; } = buffId;
|
||||
|
||||
public async ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
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.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.AvatarId, duration));
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill.Action;
|
||||
|
||||
public class MazeRemoveMazeBuff(int buffId) : IMazeSkillAction
|
||||
{
|
||||
public int BuffId { get; } = buffId;
|
||||
|
||||
public async ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async ValueTask OnCast(AvatarSceneInfo avatar, PlayerInstance player)
|
||||
{
|
||||
await avatar.RemoveBuff(BuffId);
|
||||
}
|
||||
|
||||
public async ValueTask OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
await entity.RemoveBuff(BuffId);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill.Action;
|
||||
|
||||
public class MazeRemoveSummonUnit(int unitId) : IMazeSkillAction
|
||||
{
|
||||
public int SummonUnitId = unitId;
|
||||
|
||||
public async ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async ValueTask OnCast(AvatarSceneInfo avatar, PlayerInstance player)
|
||||
{
|
||||
if (player.SceneInstance!.SummonUnit?.SummonUnitId == SummonUnitId)
|
||||
// remove
|
||||
await player.SceneInstance!.ClearSummonUnit();
|
||||
}
|
||||
|
||||
public async ValueTask OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using EggLink.DanhengServer.Enums.RogueMagic;
|
||||
using EggLink.DanhengServer.Enums.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.RogueMagic;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill.Action;
|
||||
|
||||
public class MazeSetTargetMonsterDie : IMazeSkillAction
|
||||
{
|
||||
public async ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
if (entity.MonsterData.Rank < MonsterRankEnum.Elite)
|
||||
{
|
||||
await entity.Kill();
|
||||
|
||||
await entity.Scene.Player.LineupManager!.CostMp(1, (uint)avatar.EntityID);
|
||||
var instance = entity.Scene.Player.RogueManager!.GetRogueInstance();
|
||||
switch (instance)
|
||||
{
|
||||
case null:
|
||||
continue;
|
||||
case RogueMagicInstance magic:
|
||||
await magic.RollMagicUnit(1, 1, [RogueMagicUnitCategoryEnum.Common]);
|
||||
break;
|
||||
default:
|
||||
await instance.RollBuff(1);
|
||||
break;
|
||||
}
|
||||
|
||||
await instance.GainMoney(Random.Shared.Next(20, 60));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask OnCast(AvatarSceneInfo avatar, PlayerInstance player)
|
||||
{
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async ValueTask OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
await System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using EggLink.DanhengServer.Data.Excel;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill.Action;
|
||||
|
||||
public class MazeSummonUnit(SummonUnitDataExcel excel, MotionInfo motion) : IMazeSkillAction
|
||||
{
|
||||
public async ValueTask OnCast(AvatarSceneInfo avatar, PlayerInstance player)
|
||||
{
|
||||
var unit = new EntitySummonUnit
|
||||
{
|
||||
EntityID = 0,
|
||||
CreateAvatarEntityId = avatar.EntityID,
|
||||
AttachEntityId = excel.ConfigInfo?.AttachPoint == "Origin" ? avatar.EntityID : 0,
|
||||
SummonUnitId = excel.ID,
|
||||
CreateAvatarId = avatar.AvatarInfo.GetAvatarId(),
|
||||
LifeTimeMs = 20000,
|
||||
TriggerList = excel.ConfigInfo?.TriggerConfig.CustomTriggers ?? [],
|
||||
Motion = motion
|
||||
};
|
||||
|
||||
await player.SceneInstance!.AddSummonUnitEntity(unit);
|
||||
}
|
||||
|
||||
public async ValueTask OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public async ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
|
||||
{
|
||||
await ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill;
|
||||
|
||||
public interface IMazeSkillAction
|
||||
{
|
||||
public ValueTask OnCast(AvatarSceneInfo avatar, PlayerInstance player);
|
||||
|
||||
public ValueTask OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities);
|
||||
|
||||
public ValueTask OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities);
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.Data.Excel;
|
||||
using EggLink.DanhengServer.Enums.Avatar;
|
||||
using EggLink.DanhengServer.GameServer.Game.Battle.Skill.Action;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill;
|
||||
|
||||
public class MazeSkill
|
||||
{
|
||||
public SceneCastSkillCsReq Req;
|
||||
|
||||
public MazeSkill(List<TaskInfo> taskInfos, SceneCastSkillCsReq req, bool isSkill = false,
|
||||
AvatarConfigExcel? excel = null)
|
||||
{
|
||||
Req = req;
|
||||
IsMazeSkill = isSkill;
|
||||
Excel = excel;
|
||||
foreach (var task in taskInfos) AddAction(task);
|
||||
|
||||
if (GameData.SummonUnitDataData.TryGetValue((excel?.AvatarID ?? 0) * 10 + 1, out var summonUnit) && isSkill &&
|
||||
!summonUnit.IsClient &&
|
||||
req.MazeAbilityStr == "") Actions.Add(new MazeSummonUnit(summonUnit, req.TargetMotion));
|
||||
}
|
||||
|
||||
public List<IMazeSkillAction> Actions { get; } = [];
|
||||
public bool TriggerBattle { get; private set; } = true;
|
||||
public bool IsMazeSkill { get; } = true;
|
||||
public AvatarConfigExcel? Excel { get; private set; }
|
||||
|
||||
public void AddAction(TaskInfo task)
|
||||
{
|
||||
switch (task.TaskType)
|
||||
{
|
||||
case TaskTypeEnum.None:
|
||||
break;
|
||||
case TaskTypeEnum.AddMazeBuff:
|
||||
Actions.Add(new MazeAddMazeBuff(task.ID, task.LifeTime.GetLifeTime()));
|
||||
break;
|
||||
case TaskTypeEnum.RemoveMazeBuff:
|
||||
Actions.Add(new MazeRemoveMazeBuff(task.ID));
|
||||
break;
|
||||
case TaskTypeEnum.AdventureModifyTeamPlayerHP:
|
||||
break;
|
||||
case TaskTypeEnum.AdventureModifyTeamPlayerSP:
|
||||
break;
|
||||
case TaskTypeEnum.CreateSummonUnit:
|
||||
//Actions.Add(new MazeSummonUnit(GameData.SummonUnitDataData[task.SummonUnitID], Req.TargetMotion));
|
||||
break;
|
||||
case TaskTypeEnum.DestroySummonUnit:
|
||||
Actions.Add(new MazeRemoveSummonUnit(task.SummonUnit.SummonUnitID));
|
||||
break;
|
||||
case TaskTypeEnum.AdventureSetAttackTargetMonsterDie:
|
||||
Actions.Add(new MazeSetTargetMonsterDie());
|
||||
break;
|
||||
case TaskTypeEnum.SuccessTaskList:
|
||||
foreach (var t in task.SuccessTaskList) AddAction(t);
|
||||
break;
|
||||
case TaskTypeEnum.AdventureTriggerAttack:
|
||||
if (IsMazeSkill) TriggerBattle = task.TriggerBattle;
|
||||
|
||||
foreach (var t in task.GetAttackInfo()) AddAction(t);
|
||||
break;
|
||||
case TaskTypeEnum.AdventureFireProjectile:
|
||||
foreach (var t in task.OnProjectileHit) AddAction(t);
|
||||
|
||||
foreach (var t in task.OnProjectileLifetimeFinish) AddAction(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCast(AvatarSceneInfo info, PlayerInstance player)
|
||||
{
|
||||
foreach (var action in Actions) action.OnCast(info, player);
|
||||
}
|
||||
|
||||
public void OnAttack(AvatarSceneInfo info, List<EntityMonster> entities)
|
||||
{
|
||||
foreach (var action in Actions) action.OnAttack(info, entities);
|
||||
}
|
||||
|
||||
public void OnHitTarget(AvatarSceneInfo info, List<EntityMonster> entities)
|
||||
{
|
||||
foreach (var action in Actions) action.OnHitTarget(info, entities);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Battle.Skill;
|
||||
|
||||
public static class MazeSkillManager
|
||||
{
|
||||
public static MazeSkill GetSkill(int baseAvatarId, int skillIndex, SceneCastSkillCsReq req)
|
||||
{
|
||||
GameData.AvatarConfigData.TryGetValue(baseAvatarId, out var avatarConfig);
|
||||
MazeSkill mazeSkill = new([], req);
|
||||
if (avatarConfig == null) return mazeSkill;
|
||||
|
||||
if (skillIndex == 0)
|
||||
// normal atk
|
||||
mazeSkill = new MazeSkill(avatarConfig.MazeAtk?.OnStart.ToList() ?? [], req, false, avatarConfig);
|
||||
else
|
||||
// maze skill
|
||||
mazeSkill = new MazeSkill(avatarConfig.MazeSkill?.OnStart.ToList() ?? [], req, true, avatarConfig);
|
||||
return mazeSkill;
|
||||
}
|
||||
|
||||
public static MazeSkill GetSkill(int baseAvatarId, AbilityInfo ability, SceneCastSkillCsReq req)
|
||||
{
|
||||
GameData.AvatarConfigData.TryGetValue(baseAvatarId, out var avatarConfig);
|
||||
MazeSkill mazeSkill = new([], req);
|
||||
if (avatarConfig == null) return mazeSkill;
|
||||
|
||||
mazeSkill = new MazeSkill(ability.OnStart, req, true, avatarConfig);
|
||||
return mazeSkill;
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ public class PlayerInstance(PlayerData data)
|
||||
public LineupManager? LineupManager { get; private set; }
|
||||
public InventoryManager? InventoryManager { get; private set; }
|
||||
public BattleManager? BattleManager { get; private set; }
|
||||
public SceneSkillManager? SceneSkillManager { get; private set; }
|
||||
public BattleInstance? BattleInstance { get; set; }
|
||||
|
||||
#endregion
|
||||
@@ -66,7 +67,6 @@ public class PlayerInstance(PlayerData data)
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Quest & Mission Managers
|
||||
|
||||
public MissionManager? MissionManager { get; private set; }
|
||||
@@ -166,6 +166,7 @@ public class PlayerInstance(PlayerData data)
|
||||
LineupManager = new LineupManager(this);
|
||||
InventoryManager = new InventoryManager(this);
|
||||
BattleManager = new BattleManager(this);
|
||||
SceneSkillManager = new SceneSkillManager(this);
|
||||
MissionManager = new MissionManager(this);
|
||||
GachaManager = new GachaManager(this);
|
||||
MessageManager = new MessageManager(this);
|
||||
|
||||
8
GameServer/Game/Scene/Component/IGameModifier.cs
Normal file
8
GameServer/Game/Scene/Component/IGameModifier.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Scene.Component;
|
||||
|
||||
public interface IGameModifier
|
||||
{
|
||||
public List<string> Modifiers { get; set; }
|
||||
public ValueTask AddModifier(string modifierName);
|
||||
public ValueTask RemoveModifier(string modifierName);
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Rogue.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.RogueMagic.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.RogueTourn.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;
|
||||
@@ -290,6 +291,16 @@ public class SceneInstance
|
||||
LeaderEntityId = info.AvatarInfo.EntityId;
|
||||
if (sendPacket && !notSendPacket)
|
||||
await Player.SendPacket(new PacketSceneGroupRefreshScNotify(Player, addAvatar, removeAvatar));
|
||||
|
||||
foreach (var avatar in removeAvatar)
|
||||
{
|
||||
Entities.Remove(avatar.EntityID);
|
||||
}
|
||||
|
||||
foreach (var avatar in addAvatar)
|
||||
{
|
||||
Entities.Add(avatar.EntityID, avatar);
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncGroupInfo()
|
||||
@@ -418,7 +429,7 @@ public class SceneInstance
|
||||
// enter
|
||||
var config = trigger.OnTriggerEnter;
|
||||
|
||||
Player.TaskManager!.AvatarLevelTask.TriggerTasks(config, targetEnter, SummonUnit);
|
||||
Player.TaskManager!.SummonUnitLevelTask.TriggerTasks(config, targetEnter, SummonUnit);
|
||||
}
|
||||
|
||||
if (targetExit.Count <= 0) return Retcode.RetSucc;
|
||||
@@ -426,7 +437,7 @@ public class SceneInstance
|
||||
// enter
|
||||
var config = trigger.OnTriggerExit;
|
||||
|
||||
Player.TaskManager!.AvatarLevelTask.TriggerTasks(config, targetExit, SummonUnit);
|
||||
Player.TaskManager!.SummonUnitLevelTask.TriggerTasks(config, targetExit, SummonUnit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
372
GameServer/Game/Task/AvatarTask/AbilityLevelTask.cs
Normal file
372
GameServer/Game/Task/AvatarTask/AbilityLevelTask.cs
Normal file
@@ -0,0 +1,372 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.Data.Config.Task;
|
||||
using EggLink.DanhengServer.GameServer.Game.Battle;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
using EggLink.DanhengServer.Util;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Task.AvatarTask;
|
||||
|
||||
public class AbilityLevelTask(PlayerInstance player)
|
||||
{
|
||||
public PlayerInstance Player { get; set; } = player;
|
||||
|
||||
#region Manage
|
||||
|
||||
public async ValueTask<AbilityLevelResult> TriggerTasks(AdventureAbilityConfigListInfo abilities, List<TaskConfigInfo> tasks, IGameEntity casterEntity, List<IGameEntity> targetEntities, SceneCastSkillCsReq req)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = await TriggerTask(new AbilityLevelParam(abilities, task, casterEntity, targetEntities, req));
|
||||
if (res.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(res.BattleInfos);
|
||||
}
|
||||
|
||||
if (res.Instance != null)
|
||||
{
|
||||
instance = res.Instance;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.GetByClassName().Error("An error occured, ", e);
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> TriggerTask(AbilityLevelParam param)
|
||||
{
|
||||
try
|
||||
{
|
||||
var methodName = param.Act.Type.Replace("RPG.GameCore.", "");
|
||||
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var res = method.Invoke(this, [param]);
|
||||
if (res is AbilityLevelResult result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (res is ValueTask<AbilityLevelResult> valueTask)
|
||||
{
|
||||
return await valueTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task
|
||||
|
||||
public async ValueTask<AbilityLevelResult> PredicateTaskList(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
|
||||
if (param.Act is PredicateTaskList predicateTaskList)
|
||||
{
|
||||
// handle predicateCondition
|
||||
var methodName = predicateTaskList.Predicate.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this, [predicateTaskList.Predicate, param.CasterEntity, param.TargetEntities]);
|
||||
if (resp is true)
|
||||
{
|
||||
foreach (var task in predicateTaskList.SuccessTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (result.Instance != null)
|
||||
{
|
||||
instance = result.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (result.Instance != null)
|
||||
{
|
||||
instance = result.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var task in predicateTaskList.FailedTaskList)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (result.Instance != null)
|
||||
{
|
||||
instance = result.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AdventureTriggerAttack(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
|
||||
if (param.Act is AdventureTriggerAttack adventureTriggerAttack)
|
||||
{
|
||||
var methodName = adventureTriggerAttack.AttackTargetType.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this, [adventureTriggerAttack.AttackTargetType, param.CasterEntity, param.TargetEntities]);
|
||||
if (resp is List<IGameEntity> target)
|
||||
{
|
||||
foreach (var task in adventureTriggerAttack.OnAttack)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
}
|
||||
|
||||
if (target.Count > 0 && adventureTriggerAttack.TriggerBattle)
|
||||
{
|
||||
foreach (var task in adventureTriggerAttack.OnBattle)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var entity in param.TargetEntities)
|
||||
{
|
||||
var type = MonsterBattleType.TriggerBattle;
|
||||
if (entity is EntityMonster { IsAlive: false })
|
||||
type = MonsterBattleType.DirectDieSkipBattle;
|
||||
|
||||
battleInfos.Add(new HitMonsterInstance(entity.EntityID, type));
|
||||
}
|
||||
|
||||
instance = await Player.BattleManager!.StartBattle(param.CasterEntity, param.TargetEntities, param.Request.SkillIndex == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AddMazeBuff(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
|
||||
if (param.Act is AddMazeBuff addMazeBuff)
|
||||
{
|
||||
var methodName = addMazeBuff.TargetType.Type.Replace("RPG.GameCore.", "");
|
||||
var method = GetType().GetMethod(methodName);
|
||||
if (method != null)
|
||||
{
|
||||
var resp = method.Invoke(this,
|
||||
[addMazeBuff.TargetType, param.CasterEntity, param.TargetEntities]);
|
||||
if (resp is List<IGameEntity> target)
|
||||
{
|
||||
foreach (var entity in target)
|
||||
{
|
||||
await entity.AddBuff(new SceneBuff(addMazeBuff.ID, 1, (param.CasterEntity as AvatarSceneInfo)?.AvatarInfo.GetAvatarId() ?? 0,
|
||||
addMazeBuff.LifeTime.FixedValue.Value < -1 ? 20 : -1));
|
||||
|
||||
await AddAdventureModifier(param with
|
||||
{
|
||||
Act = new AddAdventureModifier
|
||||
{
|
||||
ModifierName = GameData.MazeBuffData[addMazeBuff.ID * 10 + 1].ModifierName
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AdventureFireProjectile(AbilityLevelParam param)
|
||||
{
|
||||
BattleInstance? instance = null;
|
||||
List<HitMonsterInstance> battleInfos = [];
|
||||
|
||||
if (param.Act is AdventureFireProjectile adventureFireProjectile)
|
||||
{
|
||||
foreach (var task in adventureFireProjectile.OnProjectileHit)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (result.Instance != null)
|
||||
instance = result.Instance;
|
||||
}
|
||||
|
||||
foreach (var task in adventureFireProjectile.OnProjectileLifetimeFinish)
|
||||
{
|
||||
var result = await TriggerTask(param with { Act = task });
|
||||
if (result.BattleInfos != null)
|
||||
{
|
||||
battleInfos.AddRange(result.BattleInfos);
|
||||
}
|
||||
|
||||
if (result.Instance != null)
|
||||
instance = result.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult(instance, battleInfos);
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> CreateSummonUnit(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is CreateSummonUnit createSummonUnit)
|
||||
{
|
||||
if (!GameData.SummonUnitDataData.TryGetValue(createSummonUnit.SummonUnitID, out var excel))
|
||||
return new AbilityLevelResult();
|
||||
|
||||
var unit = new EntitySummonUnit
|
||||
{
|
||||
EntityID = 0,
|
||||
CreateAvatarEntityId = param.CasterEntity.EntityID,
|
||||
AttachEntityId = excel.ConfigInfo?.AttachPoint == "Origin" ? param.CasterEntity.EntityID : 0,
|
||||
SummonUnitId = excel.ID,
|
||||
CreateAvatarId = (param.CasterEntity as AvatarSceneInfo)?.AvatarInfo.GetAvatarId() ?? 0,
|
||||
LifeTimeMs = 20000,
|
||||
TriggerList = excel.ConfigInfo?.TriggerConfig.CustomTriggers ?? [],
|
||||
Motion = param.Request.TargetMotion
|
||||
};
|
||||
|
||||
await Player.SceneInstance!.AddSummonUnitEntity(unit);
|
||||
}
|
||||
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> DestroySummonUnit(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is CreateSummonUnit createSummonUnit)
|
||||
{
|
||||
await Player.SceneInstance!.ClearSummonUnit(); // TODO
|
||||
}
|
||||
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> AddAdventureModifier(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is AddAdventureModifier addAdventureModifier)
|
||||
{
|
||||
param.AdventureAbility.GlobalModifiers.TryGetValue(addAdventureModifier.ModifierName, out var modifier);
|
||||
if (modifier == null) return new AbilityLevelResult();
|
||||
|
||||
foreach (var task in modifier.OnCreate)
|
||||
{
|
||||
await TriggerTask(param with { Act = task });
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
public async ValueTask<AbilityLevelResult> RemoveAdventureModifier(AbilityLevelParam param)
|
||||
{
|
||||
if (param.Act is RemoveAdventureModifier removeAdventureModifier)
|
||||
{
|
||||
param.AdventureAbility.GlobalModifiers.TryGetValue(removeAdventureModifier.ModifierName, out var modifier);
|
||||
if (modifier == null) return new AbilityLevelResult();
|
||||
|
||||
foreach (var task in modifier.OnDestroy)
|
||||
{
|
||||
await TriggerTask(param with { Act = task });
|
||||
}
|
||||
}
|
||||
|
||||
return new AbilityLevelResult();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Selector
|
||||
|
||||
public List<IGameEntity> TargetAlias(TargetEvaluator selector, IGameEntity casterEntity, List<IGameEntity> targetEntities)
|
||||
{
|
||||
if (selector is TargetAlias target)
|
||||
{
|
||||
if (target.Alias == "AllEnemy")
|
||||
{
|
||||
return targetEntities;
|
||||
}
|
||||
|
||||
if (target.Alias == "Caster")
|
||||
{
|
||||
return [casterEntity];
|
||||
}
|
||||
|
||||
if (target.Alias == "AbilityTargetEntity")
|
||||
{
|
||||
return targetEntities;
|
||||
}
|
||||
|
||||
if (target.Alias == "ParamEntity")
|
||||
{
|
||||
return targetEntities;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public record AbilityLevelResult(BattleInstance? Instance = null, List<HitMonsterInstance>? BattleInfos = null);
|
||||
|
||||
public record AbilityLevelParam(AdventureAbilityConfigListInfo AdventureAbility, TaskConfigInfo Act, IGameEntity CasterEntity, List<IGameEntity> TargetEntities, SceneCastSkillCsReq Request);
|
||||
@@ -1,5 +0,0 @@
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Task.AvatarTask;
|
||||
|
||||
public class AvatarTaskTrigger
|
||||
{
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.Task.AvatarTask;
|
||||
|
||||
public class AvatarLevelTask
|
||||
public class SummonUnitLevelTask
|
||||
{
|
||||
#region Task Condition
|
||||
|
||||
@@ -7,7 +7,8 @@ public class TaskManager(PlayerInstance player) : BasePlayerManager(player)
|
||||
{
|
||||
public PerformanceTrigger PerformanceTrigger { get; } = new(player);
|
||||
public LevelTask LevelTask { get; } = new(player);
|
||||
public AvatarLevelTask AvatarLevelTask { get; } = new();
|
||||
public SummonUnitLevelTask SummonUnitLevelTask { get; } = new();
|
||||
public AbilityLevelTask AbilityLevelTask { get; } = new(player);
|
||||
public MissionTaskTrigger MissionTaskTrigger { get; } = new(player);
|
||||
public SceneTaskTrigger SceneTaskTrigger { get; } = new(player);
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Data.Config;
|
||||
using EggLink.DanhengServer.GameServer.Game.Battle.Skill;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.Scene;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.Scene;
|
||||
using EggLink.DanhengServer.Kcp;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
@@ -15,71 +12,8 @@ public class HandlerSceneCastSkillCsReq : Handler
|
||||
var req = SceneCastSkillCsReq.Parser.ParseFrom(data);
|
||||
|
||||
var player = connection.Player!;
|
||||
MazeSkill mazeSkill = new([], req);
|
||||
var res = await player.SceneSkillManager!.OnCast(req);
|
||||
|
||||
// Get casting avatar
|
||||
connection.Player!.SceneInstance!.AvatarInfo.TryGetValue((int)req.AttackedByEntityId, out var caster);
|
||||
|
||||
if (caster != null)
|
||||
{
|
||||
if (req.MazeAbilityStr != "")
|
||||
{
|
||||
// overwrite
|
||||
AbilityInfo? ability = null;
|
||||
caster.AvatarInfo.Excel?.MazeAbility.TryGetValue(req.MazeAbilityStr, out ability);
|
||||
if (ability != null)
|
||||
{
|
||||
mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.GetAvatarId(), ability, req);
|
||||
mazeSkill.OnCast(caster, player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if normal attack or technique was used
|
||||
if (req.SkillIndex > 0)
|
||||
{
|
||||
// Cast skill effects
|
||||
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.GetAvatarId(), (int)req.SkillIndex,
|
||||
req);
|
||||
mazeSkill.OnCast(caster, player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mazeSkill = MazeSkillManager.GetSkill(caster.AvatarInfo.GetAvatarId(), 0, req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (req.AssistMonsterEntityIdList.Count > 0)
|
||||
{
|
||||
if (caster != null && caster.AvatarInfo.AvatarId == 1218 && req.SkillIndex == 1)
|
||||
{
|
||||
// Avoid Jiqoqiu's E skill
|
||||
await connection.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, []));
|
||||
}
|
||||
else
|
||||
{
|
||||
var hitTargetEntityIdList = new List<uint>();
|
||||
if (req.AssistMonsterEntityIdList.Count > 0)
|
||||
foreach (var id in req.AssistMonsterEntityIdList)
|
||||
hitTargetEntityIdList.Add(id);
|
||||
else
|
||||
foreach (var id in req.HitTargetEntityIdList)
|
||||
hitTargetEntityIdList.Add(id);
|
||||
// Start battle
|
||||
await connection.Player!.BattleManager!.StartBattle(req, mazeSkill, [.. hitTargetEntityIdList]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We had no targets for some reason
|
||||
await connection.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, []));
|
||||
}
|
||||
await connection.SendPacket(new PacketSceneCastSkillScRsp(res.RetCode, req.CastEntityId, res.Instance, res.TriggerBattleInfos ?? []));
|
||||
}
|
||||
}
|
||||
@@ -32,4 +32,20 @@ public class PacketSceneCastSkillScRsp : BasePacket
|
||||
|
||||
SetData(proto);
|
||||
}
|
||||
|
||||
public PacketSceneCastSkillScRsp(Retcode retCode, uint castEntityId, BattleInstance? battle, List<HitMonsterInstance> hitMonsters) :
|
||||
base(CmdIds.SceneCastSkillScRsp)
|
||||
{
|
||||
var proto = new SceneCastSkillScRsp
|
||||
{
|
||||
Retcode = (uint)retCode,
|
||||
CastEntityId = castEntityId
|
||||
};
|
||||
|
||||
if (battle != null) proto.BattleInfo = battle.ToProto();
|
||||
|
||||
foreach (var hitMonster in hitMonsters) proto.MonsterBattleInfo.Add(hitMonster.ToProto());
|
||||
|
||||
SetData(proto);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user