fix some bugs

This commit is contained in:
Somebody
2024-04-04 22:07:29 +08:00
parent 6bd777e20a
commit 3fe700a151
57 changed files with 1265 additions and 222 deletions

View File

@@ -1,4 +1,6 @@
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Util;
using Newtonsoft.Json;
namespace EggLink.DanhengServer.Data.Config
{
@@ -10,11 +12,14 @@ namespace EggLink.DanhengServer.Data.Config
public List<FloorGroupInfo> GroupList { get; set; } = [];
[JsonIgnore]
public bool Loaded = false;
[JsonIgnore]
public Dictionary<int, GroupInfo> Groups = [];
[JsonIgnore]
public Dictionary<int, PropInfo> CachedTeleports = [];
[JsonIgnore]
public List<PropInfo> UnlockedCheckpoints = [];
public AnchorInfo? GetAnchorInfo(int groupId, int anchorId)
@@ -32,18 +37,13 @@ namespace EggLink.DanhengServer.Data.Config
// Cache anchors
foreach (var group in Groups.Values)
{
if (group.PropList == null)
{
continue;
}
foreach (var prop in group.PropList)
{
// Check if prop can be teleported to
if (prop.AnchorID > 0)
{
// Put inside cached teleport list to send to client when they request map info
CachedTeleports[prop.MappingInfoID] = prop;
CachedTeleports.TryAdd(prop.MappingInfoID, prop);
UnlockedCheckpoints.Add(prop);
// Force prop to be in the unlocked state

View File

@@ -12,6 +12,7 @@ namespace EggLink.DanhengServer.Data.Config
[JsonConverter(typeof(StringEnumConverter))]
public GroupLoadSideEnum LoadSide { get; set; }
public bool LoadOnInitial { get; set; }
public string GroupName { get; set; } = "";
public LoadCondition LoadCondition { get; set; } = new();
public LoadCondition UnloadCondition { get; set; } = new();
public LoadCondition ForceUnloadCondition { get; set; } = new();
@@ -51,7 +52,10 @@ namespace EggLink.DanhengServer.Data.Config
{
if (condition.Type == ConditionTypeEnum.MainMission)
{
mission.MainMissionInfo.TryGetValue(condition.ID, out var info);
if (!mission.MainMissionInfo.TryGetValue(condition.ID, out var info))
{
info = MissionPhaseEnum.None;
}
if (info != condition.Phase)
{
if (Operation == OperationEnum.And)
@@ -75,12 +79,7 @@ namespace EggLink.DanhengServer.Data.Config
if (subMission == null) continue;
var mainMissionId = subMission.MainMissionID;
mission.MissionInfo.TryGetValue(mainMissionId, out var info);
info ??= new() { { mainMissionId, new()
{
MissionId = condition.ID,
Status = MissionPhaseEnum.None
}} };
if (info.TryGetValue(condition.ID, out var missionInfo))
if (info?.TryGetValue(condition.ID, out var missionInfo) == true)
{
if (missionInfo.Status != condition.Phase)
{
@@ -98,6 +97,24 @@ namespace EggLink.DanhengServer.Data.Config
break;
}
}
} else
{
if (condition.Phase != MissionPhaseEnum.None)
{
if (Operation == OperationEnum.And)
{
canLoad = false;
break;
}
}
else
{
if (Operation == OperationEnum.Or)
{
canLoad = true;
break;
}
}
}
}
}

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
@@ -16,6 +17,7 @@ namespace EggLink.DanhengServer.Data.Config
{
public int ID { get; set; }
public int MainMissionID { get; set; }
public string MissionJsonPath { get; set; } = "";
public List<int> TakeParamIntList { get; set; } = []; // the mission's prerequisites
[JsonConverter(typeof(StringEnumConverter))]
public MissionFinishTypeEnum FinishType { get; set; }
@@ -25,6 +27,75 @@ namespace EggLink.DanhengServer.Data.Config
public List<int> ParamIntList { get; set; } = [];
public List<FinishActionInfo> FinishActionList { get; set; } = [];
public int Progress { get; set; }
[JsonIgnore]
public SubMissionTask<EnterFloorTaskInfo> Task { get; set; } = new();
[JsonIgnore]
public SubMissionTask<PropStateTaskInfo> PropTask { get; set; } = new();
[JsonIgnore]
public int MapEntranceID { get; set; }
[JsonIgnore]
public int AnchorGroupID { get; set; }
[JsonIgnore]
public int AnchorID { get; set; }
[JsonIgnore]
public PropStateEnum SourceState { get; set; } = PropStateEnum.Closed;
public void Loaded(int type) // 1 for EnterFloor, 2 for PropState
{
if (type == 1)
{
try
{
if (Task.OnStartSequece.Count > 0)
{
MapEntranceID = Task.OnStartSequece[0].TaskList[0].EntranceID;
AnchorGroupID = Task.OnStartSequece[0].TaskList[0].GroupID;
AnchorID = Task.OnStartSequece[0].TaskList[0].AnchorID;
}
else if (Task.OnInitSequece.Count > 0)
{
MapEntranceID = Task.OnInitSequece[0].TaskList[0].EntranceID;
AnchorGroupID = Task.OnInitSequece[0].TaskList[0].GroupID;
AnchorID = Task.OnInitSequece[0].TaskList[0].AnchorID;
}
if (MapEntranceID == 0)
{
MapEntranceID = int.Parse(ParamInt2.ToString().Replace("00", "0")); // this is a hacky way to get the MapEntranceID
}
}
catch
{
MapEntranceID = int.Parse(ParamInt2.ToString().Replace("00", "0")); // this is a hacky way to get the MapEntranceID
}
} else if (type == 2)
{
foreach (var task in PropTask.OnStartSequece)
{
foreach (var prop in task.TaskList)
{
if (prop.ButtonCallBack != null)
{
SourceState = prop.ButtonCallBack[0].State;
}
}
}
foreach (var task in PropTask.OnInitSequece)
{
foreach (var prop in task.TaskList)
{
if (prop.ButtonCallBack != null)
{
SourceState = prop.ButtonCallBack[0].State;
}
}
}
}
}
}
public class FinishActionInfo
@@ -33,4 +104,31 @@ namespace EggLink.DanhengServer.Data.Config
public FinishActionTypeEnum FinishActionType { get; set; }
public List<int> FinishActionPara { get; set; } = [];
}
public class SubMissionTask<T>
{
public List<SubMissionTaskInfo<T>> OnInitSequece { get; set; } = [];
public List<SubMissionTaskInfo<T>> OnStartSequece { get; set; } = [];
}
public class SubMissionTaskInfo<T>
{
public List<T> TaskList { get; set; } = [];
}
public class EnterFloorTaskInfo
{
public int EntranceID { get; set; }
public int GroupID { get; set; }
public int AnchorID { get; set; }
}
public class PropStateTaskInfo
{
[JsonConverter(typeof(StringEnumConverter))]
public PropStateEnum State { get; set; } = PropStateEnum.Closed;
public List<PropStateTaskInfo>? ButtonCallBack { get; set; }
}
}

View File

@@ -1,6 +1,7 @@
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -68,7 +69,11 @@ namespace EggLink.DanhengServer.Data.Config
} else if (Type.Contains("AdventureSetAttackTargetMonsterDie"))
{
TaskType = TaskTypeEnum.AdventureSetAttackTargetMonsterDie;
} else if (Type.Contains("AdventureTriggerAttack"))
} else if (SuccessTaskList.Count > 0)
{
TaskType = TaskTypeEnum.SuccessTaskList;
}
else if (Type.Contains("AdventureTriggerAttack"))
{
TaskType = TaskTypeEnum.AdventureTriggerAttack;
} else if (Type.Contains("AdventureFireProjectile"))

View File

@@ -18,6 +18,9 @@ namespace EggLink.DanhengServer.Data.Excel
[JsonConverter(typeof(StringEnumConverter))]
public RarityEnum Rarity { get; set; } = 0;
[JsonConverter(typeof(StringEnumConverter))]
public DamageTypeEnum DamageType { get; set; } = 0;
[JsonIgnore()]
public List<AvatarSkillTreeConfigExcel> DefaultSkillTree = [];

View File

@@ -0,0 +1,77 @@
using EggLink.DanhengServer.Database.Inventory;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("MonsterDrop.json")]
public class MonsterDropExcel : ExcelResource
{
public int MonsterTemplateID { get; set; }
public int WorldLevel { get; set; }
public int AvatarExpReward { get; set; }
public List<MonsterDropItem> DisplayItemList { get; set; } = [];
[JsonIgnore]
public List<MonsterDropItem> DropItemList { get; set; } = [];
public override int GetId()
{
return MonsterTemplateID * 10 + WorldLevel;
}
public override void AfterAllDone()
{
foreach (var item in DisplayItemList)
{
GameData.ItemConfigData.TryGetValue(item.ItemID, out var config);
if (config == null) continue;
double mod = config.Rarity switch
{
Enums.ItemRarityEnum.NotNormal => 0.8,
Enums.ItemRarityEnum.Rare => 0.3,
Enums.ItemRarityEnum.VeryRare => 0.125,
Enums.ItemRarityEnum.SuperRare => 0,
_ => 1,
};
double count = WorldLevel + 3;
var maxCount = (int)(count * mod);
var minCount = (int)(count * mod * 0.5);
item.MinCount = minCount;
item.MaxCount = maxCount;
DropItemList.Add(item);
}
GameData.MonsterDropData.Add(GetId(), this);
}
public List<ItemData> CalculateDrop()
{
var result = new List<ItemData>();
foreach (var item in DropItemList)
{
var count = Random.Shared.Next(item.MinCount, item.MaxCount + 1);
result.Add(new ItemData()
{
ItemId = item.ItemID,
Count = count,
});
}
return result;
}
}
public class MonsterDropItem
{
public int ItemID { get; set; }
[JsonIgnore]
public int MinCount { get; set; }
[JsonIgnore]
public int MaxCount { get; set; }
}
}

View File

@@ -1,4 +1,7 @@
using System;
using EggLink.DanhengServer.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -12,6 +15,9 @@ namespace EggLink.DanhengServer.Data.Excel
public int ID { get; set; }
public HashName NPCName { get; set; } = new();
[JsonConverter(typeof(StringEnumConverter))]
public MonsterRankEnum Rank { get; set; }
public override int GetId()
{
return ID;

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("PlaneEvent.json")]
public class PlaneEventExcel : ExcelResource
{
public int EventID { get; set; }
public int WorldLevel { get; set; }
public int Reward { get; set; }
public override int GetId()
{
return EventID * 10 + WorldLevel;
}
public override void Loaded()
{
GameData.PlaneEventData.Add(GetId(), this);
}
}
}

View File

@@ -19,6 +19,7 @@ namespace EggLink.DanhengServer.Data
public static Dictionary<int, InteractConfigExcel> InteractConfigData { get; private set; } = [];
public static Dictionary<int, NPCMonsterDataExcel> NpcMonsterDataData { get; private set; } = [];
public static Dictionary<int, MonsterConfigExcel> MonsterConfigData { get; private set; } = [];
public static Dictionary<int, MonsterDropExcel> MonsterDropData { get; private set; } = [];
public static Dictionary<int, NPCDataExcel> NpcDataData { get; private set; } = [];
public static Dictionary<int, QuestDataExcel> QuestDataData { get; private set; } = [];
public static Dictionary<int, PlayerLevelConfigExcel> PlayerLevelConfigData { get; private set; } = [];
@@ -27,6 +28,7 @@ namespace EggLink.DanhengServer.Data
public static Dictionary<int, MapEntranceExcel> MapEntranceData { get; private set; } = [];
public static Dictionary<int, MazePlaneExcel> MazePlaneData { get; private set; } = [];
public static Dictionary<int, MazePropExcel> MazePropData { get; private set; } = [];
public static Dictionary<int, PlaneEventExcel> PlaneEventData { get; private set; } = [];
public static Dictionary<int, ItemConfigExcel> ItemConfigData { get; private set; } = [];
public static Dictionary<int, EquipmentConfigExcel> EquipmentConfigData { get; private set; } = [];

View File

@@ -147,7 +147,7 @@ namespace EggLink.DanhengServer.Data
}
}
foreach (var info in GameData.FloorInfoData.Values)
foreach (var info in GameData.FloorInfoData.Values)
{
foreach (var groupInfo in info.GroupList)
{
@@ -174,8 +174,8 @@ namespace EggLink.DanhengServer.Data
{
missingGroupInfos = true;
}
info.OnLoad();
}
info.OnLoad();
}
if (missingGroupInfos)
Logger.Warn($"Group infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/LevelOutput/Group. Teleports, monster battles, and natural world spawns may not work!");
@@ -207,6 +207,38 @@ namespace EggLink.DanhengServer.Data
if (missionInfo != null)
{
GameData.MainMissionData[missionExcel.Key].MissionInfo = missionInfo;
foreach (var subMission in missionInfo.SubMissionList)
{ // load mission json
var missionJsonPath = ConfigManager.Config.Path.ResourcePath + "/" + subMission.MissionJsonPath;
if (File.Exists(missionJsonPath))
{
var missionJson = File.ReadAllText(missionJsonPath).Replace("$type", "Type");
try
{
if (subMission.FinishType == Enums.MissionFinishTypeEnum.EnterFloor)
{
var mission = JsonConvert.DeserializeObject<SubMissionTask<EnterFloorTaskInfo>>(missionJson);
if (mission != null)
{
subMission.Task = mission;
subMission.Loaded(1);
}
} else if (subMission.FinishType == Enums.MissionFinishTypeEnum.PropState)
{
var mission = JsonConvert.DeserializeObject<SubMissionTask<PropStateTaskInfo>>(missionJson);
if (mission != null)
{
subMission.PropTask = mission;
subMission.Loaded(2);
}
}
} catch (Exception ex)
{
Logger.Error("Error in reading" + missionJsonPath, ex);
}
}
}
count++;
} else
{

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Enums
{
public enum DamageTypeEnum
{
Physical = 1000111,
Fire = 1000112,
Ice = 1000113,
Thunder = 1000114,
Wind = 1000115,
Quantum = 1000116,
Imaginary = 1000117
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Enums
{
public enum MonsterRankEnum
{
Unknown = 0,
Minion = 1,
MinionLv2 = 2,
Elite = 3,
LittleBoss = 4,
BigBoss = 5,
}
}

View File

@@ -15,7 +15,8 @@ namespace EggLink.DanhengServer.Enums
AdventureModifyTeamPlayerSP = 4,
CreateSummonUnit = 5,
AdventureSetAttackTargetMonsterDie = 6,
AdventureTriggerAttack = 7,
AdventureFireProjectile = 8,
SuccessTaskList = 7,
AdventureTriggerAttack = 8,
AdventureFireProjectile = 9,
}
}

View File

@@ -24,17 +24,17 @@ namespace EggLink.DanhengServer.Proto {
static BuffInfoReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Cg5CdWZmSW5mby5wcm90byL8AQoIQnVmZkluZm8SDwoHYnVmZl9pZBgIIAEo",
"DRIWCg5iYXNlX2F2YXRhcl9pZBgEIAEoDRITCgtMSVBQTExNR0lKQRgFIAEo",
"BBITCgtORUpMRUNCS0hKRxgKIAEoAhI0Cg5keW5hbWljX3ZhbHVlcxgBIAMo",
"CzIcLkJ1ZmZJbmZvLkR5bmFtaWNWYWx1ZXNFbnRyeRINCgVjb3VudBgLIAEo",
"DRITCgtLRElMS0FQTUlPSRgGIAEoDRINCgVsZXZlbBgNIAEoDRo0ChJEeW5h",
"bWljVmFsdWVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgCOgI4",
"AUIeqgIbRWdnTGluay5EYW5oZW5nU2VydmVyLlByb3RvYgZwcm90bzM="));
"Cg5CdWZmSW5mby5wcm90byL6AQoIQnVmZkluZm8SDwoHYnVmZl9pZBgIIAEo",
"DRIWCg5iYXNlX2F2YXRhcl9pZBgEIAEoDRITCgthZGRfdGltZV9tcxgFIAEo",
"BBIRCglsaWZlX3RpbWUYCiABKAISNAoOZHluYW1pY192YWx1ZXMYASADKAsy",
"HC5CdWZmSW5mby5EeW5hbWljVmFsdWVzRW50cnkSDQoFY291bnQYCyABKA0S",
"EwoLS0RJTEtBUE1JT0kYBiABKA0SDQoFbGV2ZWwYDSABKA0aNAoSRHluYW1p",
"Y1ZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoAjoCOAFC",
"HqoCG0VnZ0xpbmsuRGFuaGVuZ1NlcnZlci5Qcm90b2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.BuffInfo), global::EggLink.DanhengServer.Proto.BuffInfo.Parser, new[]{ "BuffId", "BaseAvatarId", "LIPPLLMGIJA", "NEJLECBKHJG", "DynamicValues", "Count", "KDILKAPMIOI", "Level" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.BuffInfo), global::EggLink.DanhengServer.Proto.BuffInfo.Parser, new[]{ "BuffId", "BaseAvatarId", "AddTimeMs", "LifeTime", "DynamicValues", "Count", "KDILKAPMIOI", "Level" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
}));
}
#endregion
@@ -78,8 +78,8 @@ namespace EggLink.DanhengServer.Proto {
public BuffInfo(BuffInfo other) : this() {
buffId_ = other.buffId_;
baseAvatarId_ = other.baseAvatarId_;
lIPPLLMGIJA_ = other.lIPPLLMGIJA_;
nEJLECBKHJG_ = other.nEJLECBKHJG_;
addTimeMs_ = other.addTimeMs_;
lifeTime_ = other.lifeTime_;
dynamicValues_ = other.dynamicValues_.Clone();
count_ = other.count_;
kDILKAPMIOI_ = other.kDILKAPMIOI_;
@@ -117,27 +117,27 @@ namespace EggLink.DanhengServer.Proto {
}
}
/// <summary>Field number for the "LIPPLLMGIJA" field.</summary>
public const int LIPPLLMGIJAFieldNumber = 5;
private ulong lIPPLLMGIJA_;
/// <summary>Field number for the "add_time_ms" field.</summary>
public const int AddTimeMsFieldNumber = 5;
private ulong addTimeMs_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public ulong LIPPLLMGIJA {
get { return lIPPLLMGIJA_; }
public ulong AddTimeMs {
get { return addTimeMs_; }
set {
lIPPLLMGIJA_ = value;
addTimeMs_ = value;
}
}
/// <summary>Field number for the "NEJLECBKHJG" field.</summary>
public const int NEJLECBKHJGFieldNumber = 10;
private float nEJLECBKHJG_;
/// <summary>Field number for the "life_time" field.</summary>
public const int LifeTimeFieldNumber = 10;
private float lifeTime_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public float NEJLECBKHJG {
get { return nEJLECBKHJG_; }
public float LifeTime {
get { return lifeTime_; }
set {
nEJLECBKHJG_ = value;
lifeTime_ = value;
}
}
@@ -205,8 +205,8 @@ namespace EggLink.DanhengServer.Proto {
}
if (BuffId != other.BuffId) return false;
if (BaseAvatarId != other.BaseAvatarId) return false;
if (LIPPLLMGIJA != other.LIPPLLMGIJA) return false;
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(NEJLECBKHJG, other.NEJLECBKHJG)) return false;
if (AddTimeMs != other.AddTimeMs) return false;
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(LifeTime, other.LifeTime)) return false;
if (!DynamicValues.Equals(other.DynamicValues)) return false;
if (Count != other.Count) return false;
if (KDILKAPMIOI != other.KDILKAPMIOI) return false;
@@ -220,8 +220,8 @@ namespace EggLink.DanhengServer.Proto {
int hash = 1;
if (BuffId != 0) hash ^= BuffId.GetHashCode();
if (BaseAvatarId != 0) hash ^= BaseAvatarId.GetHashCode();
if (LIPPLLMGIJA != 0UL) hash ^= LIPPLLMGIJA.GetHashCode();
if (NEJLECBKHJG != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(NEJLECBKHJG);
if (AddTimeMs != 0UL) hash ^= AddTimeMs.GetHashCode();
if (LifeTime != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(LifeTime);
hash ^= DynamicValues.GetHashCode();
if (Count != 0) hash ^= Count.GetHashCode();
if (KDILKAPMIOI != 0) hash ^= KDILKAPMIOI.GetHashCode();
@@ -249,9 +249,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(32);
output.WriteUInt32(BaseAvatarId);
}
if (LIPPLLMGIJA != 0UL) {
if (AddTimeMs != 0UL) {
output.WriteRawTag(40);
output.WriteUInt64(LIPPLLMGIJA);
output.WriteUInt64(AddTimeMs);
}
if (KDILKAPMIOI != 0) {
output.WriteRawTag(48);
@@ -261,9 +261,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(64);
output.WriteUInt32(BuffId);
}
if (NEJLECBKHJG != 0F) {
if (LifeTime != 0F) {
output.WriteRawTag(85);
output.WriteFloat(NEJLECBKHJG);
output.WriteFloat(LifeTime);
}
if (Count != 0) {
output.WriteRawTag(88);
@@ -288,9 +288,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(32);
output.WriteUInt32(BaseAvatarId);
}
if (LIPPLLMGIJA != 0UL) {
if (AddTimeMs != 0UL) {
output.WriteRawTag(40);
output.WriteUInt64(LIPPLLMGIJA);
output.WriteUInt64(AddTimeMs);
}
if (KDILKAPMIOI != 0) {
output.WriteRawTag(48);
@@ -300,9 +300,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(64);
output.WriteUInt32(BuffId);
}
if (NEJLECBKHJG != 0F) {
if (LifeTime != 0F) {
output.WriteRawTag(85);
output.WriteFloat(NEJLECBKHJG);
output.WriteFloat(LifeTime);
}
if (Count != 0) {
output.WriteRawTag(88);
@@ -328,10 +328,10 @@ namespace EggLink.DanhengServer.Proto {
if (BaseAvatarId != 0) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(BaseAvatarId);
}
if (LIPPLLMGIJA != 0UL) {
size += 1 + pb::CodedOutputStream.ComputeUInt64Size(LIPPLLMGIJA);
if (AddTimeMs != 0UL) {
size += 1 + pb::CodedOutputStream.ComputeUInt64Size(AddTimeMs);
}
if (NEJLECBKHJG != 0F) {
if (LifeTime != 0F) {
size += 1 + 4;
}
size += dynamicValues_.CalculateSize(_map_dynamicValues_codec);
@@ -362,11 +362,11 @@ namespace EggLink.DanhengServer.Proto {
if (other.BaseAvatarId != 0) {
BaseAvatarId = other.BaseAvatarId;
}
if (other.LIPPLLMGIJA != 0UL) {
LIPPLLMGIJA = other.LIPPLLMGIJA;
if (other.AddTimeMs != 0UL) {
AddTimeMs = other.AddTimeMs;
}
if (other.NEJLECBKHJG != 0F) {
NEJLECBKHJG = other.NEJLECBKHJG;
if (other.LifeTime != 0F) {
LifeTime = other.LifeTime;
}
dynamicValues_.MergeFrom(other.dynamicValues_);
if (other.Count != 0) {
@@ -402,7 +402,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 40: {
LIPPLLMGIJA = input.ReadUInt64();
AddTimeMs = input.ReadUInt64();
break;
}
case 48: {
@@ -414,7 +414,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 85: {
NEJLECBKHJG = input.ReadFloat();
LifeTime = input.ReadFloat();
break;
}
case 88: {
@@ -449,7 +449,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 40: {
LIPPLLMGIJA = input.ReadUInt64();
AddTimeMs = input.ReadUInt64();
break;
}
case 48: {
@@ -461,7 +461,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 85: {
NEJLECBKHJG = input.ReadFloat();
LifeTime = input.ReadFloat();
break;
}
case 88: {

View File

@@ -12,5 +12,7 @@
public const int INVENTORY_MAX_MATERIAL = 2000;
public static readonly List<int> UpgradeWorldLevel = [20, 30, 40, 50, 60, 65];
public const int AMBUSH_BUFF_ID = 1000102;
}
}

View File

@@ -106,10 +106,8 @@ namespace EggLink.DanhengServer.Util
{
throw new Exception("LogFile is not set");
}
using (StreamWriter sw = LogFile.AppendText())
{
sw.WriteLine(message);
}
using StreamWriter sw = LogFile.AppendText();
sw.WriteLine(message);
}
#pragma warning disable CS8602

View File

@@ -18,11 +18,23 @@
arg.SendMsg("Target not found.");
return;
}
arg.CharacterArgs.TryGetValue("x", out var str);
if (str == null) str = "1";
player.InventoryManager!.AddItem(int.Parse(arg.BasicArgs[0]), int.Parse(str));
arg.SendMsg($"Give @{player.Uid} item of {arg.BasicArgs[0]}");
if (arg.BasicArgs.Count == 0)
{
arg.SendMsg("Item not found.");
return;
}
arg.CharacterArgs.TryGetValue("x", out var str);
str ??= "1";
if (!int.TryParse(str, out var amount))
{
arg.SendMsg("Invalid amount.");
return;
}
player.InventoryManager!.AddItem(int.Parse(arg.BasicArgs[0]), amount);
arg.SendMsg($"Give @{player.Uid} {amount} items of {arg.BasicArgs[0]}");
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Command.Cmd
{
[CommandInfo("lineup", "manage the player's lineup", "/lineup")]
public class CommandLineup : ICommand
{
[CommandMethod("0 mp")]
public void SetLineupMp(CommandArg arg)
{
if (arg.Target == null)
{
arg.SendMsg("Player not found");
return;
}
var count = arg.GetInt(0);
arg.Target.Player!.LineupManager!.GainMp(count == 0 ? 2: count);
arg.SendMsg($"Player has gained {count} MP");
}
}
}

View File

@@ -1,4 +1,6 @@
namespace EggLink.DanhengServer.Command.Cmd
using System.Text;
namespace EggLink.DanhengServer.Command.Cmd
{
[CommandInfo("mission", "Manage the missions", "/mission <pass>")]
public class CommandMission : ICommand
@@ -15,5 +17,59 @@
mission.GetRunningSubMissionIdList().ForEach(mission.FinishSubMission);
arg.SendMsg("Pass all running missions.");
}
[CommandMethod("0 finish")]
public void FinishRunningMission(CommandArg arg)
{
if (arg.Target == null)
{
arg.SendMsg("Player not found.");
return;
}
if (arg.BasicArgs.Count < 1)
{
arg.SendMsg("Please specify the mission id.");
return;
}
if (!int.TryParse(arg.BasicArgs[0], out var missionId))
{
arg.SendMsg("Invalid mission id.");
return;
}
var mission = arg.Target!.Player!.MissionManager!;
//mission.AcceptSubMission(missionId);
mission.FinishSubMission(missionId);
arg.SendMsg("Finish mission.");
}
[CommandMethod("0 running")]
public void ListRunningMission(CommandArg arg)
{
if (arg.Target == null)
{
arg.SendMsg("Player not found.");
return;
}
var mission = arg.Target!.Player!.MissionManager!;
var runningMissions = mission.GetRunningSubMissionIdList();
if (runningMissions.Count == 0)
{
arg.SendMsg("No running missions.");
return;
}
var sb = new StringBuilder();
sb.AppendLine("Running missions:");
foreach (var missionId in runningMissions)
{
sb.AppendLine(missionId.ToString());
}
arg.SendMsg(sb.ToString());
}
}
}

View File

@@ -13,6 +13,11 @@ namespace EggLink.DanhengServer.Command.Cmd
[CommandMethod("0 group")]
public void GetLoadedGroup(CommandArg arg)
{
if (arg.Target == null)
{
arg.SendMsg("Player not found");
return;
}
var scene = arg.Target!.Player!.SceneInstance!;
var loadedGroup = new List<int>();
foreach (var group in scene.Entities)
@@ -28,6 +33,11 @@ namespace EggLink.DanhengServer.Command.Cmd
[CommandMethod("0 prop")]
public void GetProp(CommandArg arg)
{
if (arg.Target == null)
{
arg.SendMsg("Player not found");
return;
}
var scene = arg.Target!.Player!.SceneInstance!;
EntityProp? prop = null;
foreach (var entity in scene.GetEntitiesInGroup<EntityProp>(arg.GetInt(0)))

View File

@@ -2,6 +2,7 @@
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Database.Avatar;
using EggLink.DanhengServer.Database.Inventory;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
@@ -17,14 +18,16 @@ namespace EggLink.DanhengServer.Game.Battle
public int CocoonWave { get; set; }
public int MappingInfoId { get; set; }
public int RoundLimit { get; set; }
public int StageId { get; set; } = stages.Count > 0 ? stages[0].StageID : 0;
public int CasterIndex { get; set; }
public int StageId { get; set; } = stages.Count > 0 ? stages[0].StageID : 0; // Set to 0 when hit monster
public BattleEndStatus BattleEndStatus { get; set; }
public List<ItemData> MonsterDropItems { get; set; } = [];
public List<StageConfigExcel> Stages { get; set; } = stages;
public Database.Lineup.LineupInfo Lineup { get; set; } = lineup;
public List<EntityMonster> EntityMonsters { get; set; } = [];
public List<SceneBuff> Buffs { get; set; } = [];
public List<AvatarSceneInfo> AvatarInfo { get; set; } = [];
public List<MazeBuff> Buffs { get; set; } = [];
public BattleInstance(PlayerInstance player, Database.Lineup.LineupInfo lineup, List<EntityMonster> monsters) : this(player, lineup, new List<StageConfigExcel>())
{
@@ -43,10 +46,14 @@ namespace EggLink.DanhengServer.Game.Battle
public ItemList GetDropItemList()
{
return new()
{
var list = new ItemList();
};
foreach (var item in MonsterDropItems)
{
list.ItemList_.Add(item.ToProto());
}
return list;
}
public SceneBattleInfo ToProto()
@@ -94,7 +101,17 @@ namespace EggLink.DanhengServer.Game.Battle
proto.BattleAvatarList.Add(avatarInstance.ToBattleProto(Player.LineupManager!.GetCurLineup()!, Player.InventoryManager!.Data, avatarType));
}
proto.BuffList.AddRange(Buffs.Select(buff => buff.ToProto(CasterIndex, 1 >> Stages.Count)));
foreach (var monster in EntityMonsters)
{
monster.ApplyBuff(this);
}
foreach (var avatar in AvatarInfo)
{
avatar.ApplyBuff(this);
}
proto.BuffList.AddRange(Buffs.Select(buff => buff.ToProto(this)));
return proto;
}
}

View File

@@ -1,8 +1,10 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Database.Inventory;
using EggLink.DanhengServer.Game.Battle.Skill;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Battle;
@@ -13,16 +15,14 @@ namespace EggLink.DanhengServer.Game.Battle
{
public class BattleManager(PlayerInstance player) : BasePlayerManager(player)
{
public void StartBattle(SceneCastSkillCsReq req, MazeSkill skill, int casterAvatarId)
public void StartBattle(SceneCastSkillCsReq req, MazeSkill skill)
{
if (Player.BattleInstance != null) return;
var targetList = new List<EntityMonster>();
var avatarList = new List<AvatarSceneInfo>();
var propList = new List<EntityProp>();
if (!skill.TriggerBattle)
{
Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId));
return;
}
Player.SceneInstance!.AvatarInfo.TryGetValue((int)req.AttackedByEntityId, out var castAvatar);
if (Player.SceneInstance!.AvatarInfo.ContainsKey((int)req.AttackedByEntityId))
{
foreach (var entity in req.HitTargetEntityIdList)
@@ -72,21 +72,89 @@ namespace EggLink.DanhengServer.Game.Battle
Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId));
return;
}
foreach (var prop in propList)
{
Player.SceneInstance!.RemoveEntity(prop);
if (prop.Excel.IsMpRecover)
{
Player.LineupManager!.GainMp(2);
} else if (prop.Excel.IsHpRecover)
{
Player.LineupManager!.GetCurLineup()!.Heal(2000, false);
}
}
if (targetList.Count > 0)
{
if (castAvatar != null && req.SkillIndex > 0)
{
// cost Mp
Player!.LineupManager!.CostMp(req.AttackedByEntityId, 1);
skill.OnCast(castAvatar);
}
// Skill handle
if (!skill.TriggerBattle)
{
skill.OnHitTarget(Player.SceneInstance!.AvatarInfo[(int)req.AttackedByEntityId], targetList);
Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId));
return;
}
if (castAvatar != null)
{
skill.OnAttack(Player.SceneInstance!.AvatarInfo[(int)req.AttackedByEntityId], targetList);
}
var triggerBattle = false;
foreach (var target in targetList)
{
if (target.IsAlive)
{
triggerBattle = true;
break;
}
}
if (!triggerBattle)
{
Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId));
return;
}
BattleInstance battleInstance = new(Player, Player.LineupManager!.GetCurLineup()!, targetList)
{
WorldLevel = Player.Data.WorldLevel,
CasterIndex = (int)req.CastEntityId,
};
foreach (var item in Player.LineupManager!.GetCurLineup()!.BaseAvatars!) // get all avatars in the lineup and add them to the battle instance
{
var avatar = Player.SceneInstance!.AvatarInfo.Values.FirstOrDefault(x => x.AvatarInfo.AvatarId == item.BaseAvatarId);
if (avatar != null)
{
avatarList.Add(avatar);
}
}
MazeBuff mazeBuff;
if (castAvatar != null)
{
var index = battleInstance.Lineup.BaseAvatars!.FindIndex(x => x.BaseAvatarId == castAvatar.AvatarInfo.AvatarId);
mazeBuff = new((int?)castAvatar.AvatarInfo.Excel?.DamageType ?? 0, 1, index);
mazeBuff.DynamicValues.Add("SkillIndex", skill.IsMazeSkill ? 2 : 1);
} else
{
mazeBuff = new(GameConstants.AMBUSH_BUFF_ID, 1, -1)
{
WaveFlag = 1
};
}
if (mazeBuff.BuffID != 0) // avoid adding a buff with ID 0
{
battleInstance.Buffs.Add(mazeBuff);
}
battleInstance.AvatarInfo = avatarList;
Player.BattleInstance = battleInstance;
battleInstance.CasterIndex = Player.LineupManager!.GetCurLineup()!.BaseAvatars!.FindIndex(x => x.BaseAvatarId == casterAvatarId);
skill.OnEnterBattle(battleInstance);
Player.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId, battleInstance));
} else
{
@@ -183,15 +251,11 @@ namespace EggLink.DanhengServer.Game.Battle
switch (req.EndStatus)
{
case BattleEndStatus.BattleEndWin:
// Remove monsters from the map - Could optimize it a little better
//for (var monster in battle.NpcMonsters)
//{
// // Dont remove farmable monsters from the scene when they are defeated
// if (monster.isFarmElement()) continue;
// // Remove monster
// player.SceneInstance.RemoveEntity(monster);
//}
// Drops
foreach (var monster in battle.EntityMonsters)
{
monster.Kill();
}
// Spend stamina
if (battle.StaminaCost > 0)
{
@@ -208,7 +272,6 @@ namespace EggLink.DanhengServer.Game.Battle
updateStatus = false;
break;
}
if (updateStatus)
{
var lineup = Player.LineupManager!.GetCurLineup()!;
@@ -253,15 +316,6 @@ namespace EggLink.DanhengServer.Game.Battle
// call battle end
Player.MissionManager!.OnBattleFinish(req);
// remove monster from the scene
if (req.EndStatus == BattleEndStatus.BattleEndWin)
{
foreach (var monster in battle.EntityMonsters)
{
Player.SceneInstance!.RemoveEntity(monster);
}
}
Player.BattleInstance = null;
Player.SendPacket(new PacketPVEBattleResultScRsp(req, Player, battle));
}

View File

@@ -0,0 +1,58 @@
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Game.Battle
{
public class MazeBuff(int buffID, int buffLevel, int owner)
{
public int BuffID { get; private set; } = buffID;
public int BuffLevel { get; private set; } = buffLevel;
public int OwnerIndex { get; private set; } = owner;
public int OwnerAvatarId { get; private set; } = -1;
public int? WaveFlag { get; set; } = null;
public int Duration { get; private set; } = -1;
public Dictionary<string, float> DynamicValues { get; private set; } = [];
public MazeBuff(SceneBuff buff) : this(buff.BuffID, buff.BuffLevel, 0)
{
Duration = buff.Duration;
OwnerAvatarId = buff.OwnerAvatarId;
}
public BattleBuff ToProto(BattleInstance battle)
{
return ToProto(battle, WaveFlag ?? -1);
}
public BattleBuff ToProto(BattleInstance instance, int waveFlag)
{
var buffInfo = new BattleBuff()
{
Id = (uint)BuffID,
Level = (uint)BuffLevel,
OwnerIndex = (uint)OwnerIndex,
WaveFlag = (uint)waveFlag,
};
foreach (var item in DynamicValues)
{
buffInfo.DynamicValues.Add(item.Key, item.Value);
}
if (OwnerAvatarId != -1)
{
buffInfo.OwnerIndex = (uint)instance.Lineup.BaseAvatars!.FindIndex(x => x.BaseAvatarId == OwnerAvatarId);
OwnerIndex = (int)buffInfo.OwnerIndex;
}
if (OwnerIndex != -1)
buffInfo.TargetIndexList.Add((uint)OwnerIndex);
return buffInfo;
}
}
}

View File

@@ -1,5 +1,7 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,16 +10,29 @@ using System.Threading.Tasks;
namespace EggLink.DanhengServer.Game.Battle.Skill.Action
{
public class MazeAddMazeBuff(int buffId) : IMazeSkillAction
public class MazeAddMazeBuff(int buffId, int duration) : IMazeSkillAction
{
public void OnCast()
{
public int BuffId { get; private set; } = buffId;
public void OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
{
foreach (var entity in entities)
{
entity.TempBuff = new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration);
}
}
public void OnEnterBattle(BattleInstance instance)
public void OnCast(AvatarSceneInfo avatar)
{
instance.Buffs.Add(new SceneBuff(buffId, 1));
avatar.BuffList.Add(new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration));
}
public void OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities)
{
foreach (var entity in entities)
{
entity.BuffList.Add(new SceneBuff(BuffId, 1, avatar.AvatarInfo.AvatarId, duration));
}
}
}
}

View File

@@ -0,0 +1,33 @@
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Game.Battle.Skill.Action
{
public class MazeSetTargetMonsterDie : IMazeSkillAction
{
public void OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities)
{
foreach (var entity in entities)
{
if (entity.MonsterData.Rank < Enums.MonsterRankEnum.Elite)
{
entity.Kill();
}
}
}
public void OnCast(AvatarSceneInfo avatar)
{
}
public void OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities)
{
}
}
}

View File

@@ -1,4 +1,6 @@
using System;
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -8,8 +10,10 @@ namespace EggLink.DanhengServer.Game.Battle.Skill
{
public interface IMazeSkillAction
{
public void OnEnterBattle(BattleInstance instance);
public void OnCast(AvatarSceneInfo avatar);
public void OnCast();
public void OnHitTarget(AvatarSceneInfo avatar, List<EntityMonster> entities);
public void OnAttack(AvatarSceneInfo avatar, List<EntityMonster> entities);
}
}

View File

@@ -1,5 +1,8 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Game.Battle.Skill.Action;
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
using EggLink.DanhengServer.Util;
using System;
using System.Collections.Generic;
@@ -13,29 +16,17 @@ namespace EggLink.DanhengServer.Game.Battle.Skill
{
public List<IMazeSkillAction> Actions { get; private set; } = [];
public bool TriggerBattle { get; private set; } = true;
public MazeSkill(List<TaskInfo> taskInfos)
public bool IsMazeSkill { get; private set; } = true;
public AvatarConfigExcel? Excel { get; private set; }
public MazeSkill(List<TaskInfo> taskInfos, bool isSkill = false, AvatarConfigExcel? excel = null)
{
foreach (var task in taskInfos)
{
AddAction(task);
foreach (var t in task.SuccessTaskList)
{
AddAction(t);
}
foreach (var t in task.GetAttackInfo())
{
AddAction(t);
}
foreach (var t in task.OnProjectileHit)
{
AddAction(t);
}
foreach (var t in task.OnProjectileLifetimeFinish)
{
AddAction(t);
}
}
IsMazeSkill = isSkill;
Excel = excel;
}
public void AddAction(TaskInfo task)
@@ -45,9 +36,10 @@ namespace EggLink.DanhengServer.Game.Battle.Skill
case Enums.TaskTypeEnum.None:
break;
case Enums.TaskTypeEnum.AddMazeBuff:
Actions.Add(new MazeAddMazeBuff(task.ID));
Actions.Add(new MazeAddMazeBuff(task.ID, 20));
break;
case Enums.TaskTypeEnum.RemoveMazeBuff:
Actions.RemoveAll(a => a is MazeAddMazeBuff buff && buff.BuffId == task.ID);
break;
case Enums.TaskTypeEnum.AdventureModifyTeamPlayerHP:
break;
@@ -56,28 +48,60 @@ namespace EggLink.DanhengServer.Game.Battle.Skill
case Enums.TaskTypeEnum.CreateSummonUnit:
break;
case Enums.TaskTypeEnum.AdventureSetAttackTargetMonsterDie:
Actions.Add(new MazeSetTargetMonsterDie());
break;
case Enums.TaskTypeEnum.SuccessTaskList:
foreach (var t in task.SuccessTaskList)
{
AddAction(t);
}
break;
case Enums.TaskTypeEnum.AdventureTriggerAttack:
if (IsMazeSkill)
{
TriggerBattle = task.TriggerBattle;
}
foreach (var t in task.GetAttackInfo())
{
AddAction(t);
}
break;
case Enums.TaskTypeEnum.AdventureFireProjectile:
break;
}
foreach (var t in task.OnProjectileHit)
{
AddAction(t);
}
if (!task.TriggerBattle)
{
TriggerBattle = false;
foreach (var t in task.OnProjectileLifetimeFinish)
{
AddAction(t);
}
break;
}
}
public void OnEnterBattle(BattleInstance instance)
public void OnCast(AvatarSceneInfo info)
{
foreach (var action in Actions)
{
action.OnEnterBattle(instance);
action.OnCast(info);
}
}
public void OnAttack(AvatarSceneInfo info, List<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);
}
}
}

View File

@@ -18,12 +18,12 @@ namespace EggLink.DanhengServer.Game.Battle.Skill
if (skillIndex == 0)
{
// normal atk
mazeSkill = new(avatarConfig.MazeAtk?.OnStart.ToList() ?? []);
mazeSkill = new(avatarConfig.MazeAtk?.OnStart.ToList() ?? [], false, avatarConfig);
}
else
{
// maze skill
mazeSkill = new(avatarConfig.MazeSkill?.OnStart.ToList() ?? []);
mazeSkill = new(avatarConfig.MazeSkill?.OnStart.ToList() ?? [], true, avatarConfig);
}
return mazeSkill;
}

View File

@@ -20,7 +20,11 @@ namespace EggLink.DanhengServer.Game.Inventory
{
foreach (var item in items)
{
AddItem(item.ItemId, items.Count, true, false);
AddItem(item.ItemId, items.Count, false, false);
}
if (notify)
{
Player.SendPacket(new PacketScenePlaneEventScNotify(items));
}
DatabaseHelper.Instance?.UpdateInstance(Data);
@@ -104,7 +108,7 @@ namespace EggLink.DanhengServer.Game.Inventory
if (avatar != null && avatar.Excel != null)
{
var rankUpItem = Player.InventoryManager!.GetItem(avatar.Excel.RankUpItemId);
if (avatar.Rank + rankUpItem?.Count <= 5)
if ((avatar.Rank + rankUpItem?.Count ?? 0) <= 5)
itemData = PutItem(avatar.Excel.RankUpItemId, 1);
}
else
@@ -285,6 +289,15 @@ namespace EggLink.DanhengServer.Game.Inventory
return null;
}
public void HandlePlaneEvent(int eventId)
{
GameData.PlaneEventData.TryGetValue(eventId * 10 + Player.Data.WorldLevel, out var planeEvent);
if (planeEvent == null) return;
GameData.RewardDataData.TryGetValue(planeEvent.Reward, out var rewardData);
if (rewardData == null) return;
rewardData.GetItems().ForEach(x => AddItem(x.Item1, x.Item2));
}
#region Equip
public void EquipAvatar(int baseAvatarId, int equipmentUniqueId)

View File

@@ -210,7 +210,7 @@ namespace EggLink.DanhengServer.Game.Lineup
avatarInfo = Player.AvatarManager!.GetAvatar(avatar.BaseAvatarId);
}
if (avatarInfo == null) continue;
avatarList.Add(new AvatarSceneInfo(avatarInfo, avatarType));
avatarList.Add(new AvatarSceneInfo(avatarInfo, avatarType, Player));
}
return avatarList;
@@ -220,5 +220,19 @@ namespace EggLink.DanhengServer.Game.Lineup
{
return GetAvatarsFromTeam(LineupData.CurLineup);
}
public void CostMp(uint entityId, int count)
{
LineupData.Mp -= count;
DatabaseHelper.Instance?.UpdateInstance(LineupData);
Player.SendPacket(new PacketSceneCastSkillMpUpdateScNotify(entityId, LineupData.Mp));
}
public void GainMp(int count)
{
LineupData.Mp += count;
DatabaseHelper.Instance?.UpdateInstance(LineupData);
Player.SendPacket(new PacketSyncLineupNotify(GetCurLineup()!));
}
}
}

View File

@@ -17,6 +17,7 @@ namespace EggLink.DanhengServer.Game.Message
public class MessageManager(PlayerInstance player) : BasePlayerManager(player)
{
public MessageData Data { get; private set; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew<MessageData>(player.Uid);
public List<MessageSectionData> PendingMessagePerformSectionList { get; private set; } = [];
#region Get
@@ -166,6 +167,9 @@ namespace EggLink.DanhengServer.Game.Message
var notify = new PacketPlayerSyncScNotify(group, section);
Player.SendPacket(notify);
// broadcast to mission system
Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessagePerformSectionFinish);
Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessageSectionFinish);
}
public void FinishMessageItem(int itemId)
@@ -183,18 +187,7 @@ namespace EggLink.DanhengServer.Game.Message
{
ItemId = itemId,
});
if (itemConfig.NextItemIDList.Count == 0)
{
// finish
section.Status = MessageSectionStatus.MessageSectionFinish;
if (group.Sections.All(m => m.Status == MessageSectionStatus.MessageSectionFinish))
{
group.Status = MessageGroupStatus.MessageGroupFinish;
}
} else
{
section.ToChooseItemId.AddRange(itemConfig.NextItemIDList);
}
section.ToChooseItemId.AddRange(itemConfig.NextItemIDList);
group.RefreshTime = Extensions.GetUnixSec();
@@ -202,11 +195,6 @@ namespace EggLink.DanhengServer.Game.Message
// sync
var notify = new PacketPlayerSyncScNotify(group, section);
Player.SendPacket(notify);
// broadcast to mission system
Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessagePerformSectionFinish);
Player.MissionManager!.HandleFinishType(Enums.MissionFinishTypeEnum.MessageSectionFinish);
}
#endregion

View File

@@ -18,7 +18,7 @@ namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler
public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg)
{
player.EnterMissionScene(info.ParamInt2, info.ParamInt2, true);
player.EnterMissionScene(info.MapEntranceID, info.AnchorGroupID, info.AnchorID, true);
player.MissionManager!.FinishSubMission(info.ID);
}
}

View File

@@ -0,0 +1,36 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Player;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler
{
[MissionFinishType(MissionFinishTypeEnum.FinishMission)]
public class MissionHandlerFinishMission : MissionFinishTypeHandler
{
public override void Init(PlayerInstance player, SubMissionInfo info, object? arg)
{
}
public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg)
{
var send = true;
foreach (var mainMissionId in info.ParamIntList)
{
if (player.MissionManager!.GetMainMissionStatus(mainMissionId) != MissionPhaseEnum.Finish)
{
send = false;
break;
}
}
if (send)
{
player.MissionManager!.FinishSubMission(info.ID);
}
}
}
}

View File

@@ -0,0 +1,32 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Game.Scene.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler
{
[MissionFinishType(MissionFinishTypeEnum.KillMonster)]
public class MissionHandlerKillMonster : MissionFinishTypeHandler
{
public override void Init(PlayerInstance player, SubMissionInfo info, object? arg)
{
}
public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg)
{
if (arg is not EntityMonster monster) return;
if (monster.InstID == info.ParamInt2)
{
if (!monster.IsAlive)
{
player.MissionManager!.FinishSubMission(info.ID);
}
}
}
}
}

View File

@@ -19,8 +19,7 @@ namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler
{
if (info.ParamInt3 != 0)
{
//player.MissionManager!.FinishSubMission(subMissionId);
p.SetState(PropStateEnum.Closed);
p.SetState(info.SourceState);
}
}
}

View File

@@ -14,13 +14,13 @@ namespace EggLink.DanhengServer.Game.Mission.FinishType.Handler
public override void HandleFinishType(PlayerInstance player, SubMissionInfo info, object? arg)
{
var finish = true;
var finish = false;
foreach (var missionId in info.ParamIntList)
{
var status = player.MissionManager!.GetSubMissionStatus(missionId);
if (status != MissionPhaseEnum.Finish && status != MissionPhaseEnum.Cancel)
if (status == MissionPhaseEnum.Finish || status == MissionPhaseEnum.Cancel)
{
finish = false;
finish = true;
break;
}
}

View File

@@ -59,6 +59,13 @@ namespace EggLink.DanhengServer.Game.Mission
var list = new List<Proto.MissionSync?>();
mission.MissionInfo?.StartSubMissionList.ForEach(i => list.Add(AcceptSubMission(i, sendPacket)));
if (missionId == 4030001)
{
// skip not implemented
mission.MissionInfo?.StartSubMissionList.ForEach(FinishSubMission);
mission.MissionInfo?.FinishSubMissionList.ForEach(AcceptSubMission);
mission.MissionInfo?.FinishSubMissionList.ForEach(FinishSubMission);
}
return list;
}
@@ -93,10 +100,12 @@ namespace EggLink.DanhengServer.Game.Mission
DatabaseHelper.Instance?.UpdateInstance(Data);
if (sendPacket) Player.SendPacket(new PacketPlayerSyncScNotify(sync));
Player.SceneInstance!.SyncGroupInfo();
if (doFinishTypeAction && mission.SubMissionInfo != null)
if (mission.SubMissionInfo != null)
{
FinishTypeHandlers.TryGetValue(mission.SubMissionInfo.FinishType, out var handler);
handler?.Init(Player, mission.SubMissionInfo, null);
if (doFinishTypeAction)
handler?.HandleFinishType(Player, mission.SubMissionInfo, null);
}
return sync;
}
@@ -104,11 +113,27 @@ namespace EggLink.DanhengServer.Game.Mission
public void FinishMainMission(int missionId)
{
if (!Data.MainMissionInfo.TryGetValue(missionId, out var value)) return;
if (!GameData.MainMissionData.TryGetValue(missionId, out var mainMission)) return;
if (value != MissionPhaseEnum.Doing) return;
Data.MainMissionInfo[missionId] = MissionPhaseEnum.Finish;
var sync = new Proto.MissionSync();
sync.MainMissionIdList.Add((uint)missionId);
// get next main mission
foreach (var mission in mainMission.SubMissionIds)
{
if (GetSubMissionStatus(mission) != MissionPhaseEnum.Finish)
{
Data.MissionInfo.TryGetValue(missionId, out var info);
if (info != null)
{
info[mission] = new()
{
MissionId = mission,
Status = MissionPhaseEnum.Cancel
};
}
}
}
foreach (var nextMission in GameData.MainMissionData.Values)
{
if (!nextMission.IsEqual(Data)) continue;
@@ -125,6 +150,7 @@ namespace EggLink.DanhengServer.Game.Mission
Player.SendPacket(new PacketPlayerSyncScNotify(sync));
Player.SendPacket(new PacketStartFinishMainMissionScNotify(missionId));
HandleMissionReward(missionId);
HandleFinishType(MissionFinishTypeEnum.FinishMission);
DatabaseHelper.Instance?.UpdateInstance(Data);
}
@@ -161,7 +187,7 @@ namespace EggLink.DanhengServer.Game.Mission
}
if (canAccept)
{
var s = AcceptSubMission(nextMission.ID, false, true);
var s = AcceptSubMission(nextMission.ID, false, false);
if (s != null)
{
sync.MissionList.Add(new Proto.Mission()
@@ -343,7 +369,7 @@ namespace EggLink.DanhengServer.Game.Mission
foreach (var mission in GetRunningSubMissionIdList())
{
var subMission = GetSubMissionInfo(mission);
if (subMission != null && (subMission.FinishType == MissionFinishTypeEnum.StageWin || subMission.FinishType == MissionFinishTypeEnum.KillMonster) && req.EndStatus == Proto.BattleEndStatus.BattleEndWin) // TODO: Move to handler
if (subMission != null && (subMission.FinishType == MissionFinishTypeEnum.StageWin && req.EndStatus == Proto.BattleEndStatus.BattleEndWin)) // TODO: Move to handler
{
FinishSubMission(mission);
}

View File

@@ -174,28 +174,19 @@ namespace EggLink.DanhengServer.Game.Player
public void OnAddExp()
{
GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out var config);
if (config == null) return;
var nextExp = config.PlayerExp;
for (int i = 1; i <= Data.Level; i++)
{
GameData.PlayerLevelConfigData.TryGetValue(i, out config);
if (config == null) continue;
nextExp -= config.PlayerExp;
}
GameData.PlayerLevelConfigData.TryGetValue(Data.Level, out var config);
GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out var config2);
if (config == null || config2 == null) return;
var nextExp = config2.PlayerExp - config.PlayerExp;
while (Data.Exp >= nextExp)
{
Data.Exp -= nextExp;
Data.Level++;
GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out config);
if (config == null) break;
nextExp = config.PlayerExp;
for (int i = 1; i <= Data.Level; i++)
{
GameData.PlayerLevelConfigData.TryGetValue(i, out config);
if (config == null) continue;
nextExp -= config.PlayerExp;
}
GameData.PlayerLevelConfigData.TryGetValue(Data.Level, out config);
GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out config2);
if (config == null || config2 == null) break;
nextExp = config2.PlayerExp - config.PlayerExp;
}
OnLevelChange();
@@ -313,6 +304,9 @@ namespace EggLink.DanhengServer.Game.Player
// for mission
MissionManager!.OnPlayerInteractWithProp();
// plane event
InventoryManager!.HandlePlaneEvent(prop.PropInfo.EventID);
return prop;
}
}
@@ -348,16 +342,16 @@ namespace EggLink.DanhengServer.Game.Player
LoadScene(entrance.PlaneID, entrance.FloorID, entryId, anchor!.ToPositionProto(), anchor.ToRotationProto(), sendPacket);
}
public void EnterMissionScene(int floorId, int entryId, bool sendPacket)
public void EnterMissionScene(int entranceId, int anchorGroupId, int anchorId, bool sendPacket)
{
var entrance = GameData.GetMapEntrance(floorId, MissionManager!.Data);
GameData.MapEntranceData.TryGetValue(entranceId, out var entrance);
if (entrance == null) return;
GameData.GetFloorInfo(entrance.PlaneID, entrance.FloorID, out var floorInfo);
if (floorInfo == null) return;
int StartGroup = entrance.StartGroupID;
int StartAnchor = entrance.StartAnchorID;
int StartGroup = anchorGroupId == 0 ? entrance.StartGroupID : anchorGroupId;
int StartAnchor = anchorId == 0 ? entrance.StartAnchorID : anchorId;
if (StartAnchor == 0)
{
@@ -366,7 +360,7 @@ namespace EggLink.DanhengServer.Game.Player
}
AnchorInfo? anchor = floorInfo.GetAnchorInfo(StartGroup, StartAnchor);
LoadScene(entrance.PlaneID, entrance.FloorID, entryId, anchor!.ToPositionProto(), anchor.ToRotationProto(), sendPacket);
LoadScene(entrance.PlaneID, entrance.FloorID, entranceId, anchor!.ToPositionProto(), anchor.ToRotationProto(), sendPacket);
}
public void MoveTo(Position position)

View File

@@ -1,6 +1,11 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Database.Inventory;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Scene;
using EggLink.DanhengServer.Util;
using System;
using System.Collections.Generic;
@@ -19,12 +24,54 @@ namespace EggLink.DanhengServer.Game.Scene.Entity
public int InstID { get; set; } = InstID;
public NPCMonsterDataExcel MonsterData { get; set; } = excel;
public MonsterInfo Info { get; set; } = info;
public List<SceneBuff> BuffList { get; set; } = [];
public SceneBuff? TempBuff { get; set; }
public bool IsAlive { get; private set; } = true;
public void AddBuff(SceneBuff buff)
{
BuffList.Add(buff);
scene.Player.SendPacket(new PacketSyncEntityBuffChangeListScNotify(this, buff));
}
public void ApplyBuff(BattleInstance instance)
{
if (TempBuff != null)
{
instance.Buffs.Add(new MazeBuff(TempBuff));
TempBuff = null;
}
foreach (var buff in BuffList)
{
if (buff.IsExpired())
{
continue;
}
instance.Buffs.Add(new MazeBuff(buff));
}
}
public int GetStageId()
{
return Info.EventID * 10 + scene.Player.Data.WorldLevel;
}
public List<ItemData> Kill()
{
scene.RemoveEntity(this);
IsAlive = false;
GameData.MonsterDropData.TryGetValue(MonsterData.ID * 10 + scene.Player.Data.WorldLevel, out var dropData);
if (dropData == null) return [];
var dropItems = dropData.CalculateDrop();
scene.Player.InventoryManager!.AddItems(dropItems);
// TODO: Rogue support
// call mission handler
scene.Player.MissionManager!.HandleFinishType(MissionFinishTypeEnum.KillMonster, this);
return dropItems;
}
public SceneEntityInfo ToProto()
{
return new()
@@ -43,7 +90,6 @@ namespace EggLink.DanhengServer.Game.Scene.Entity
MonsterId = (uint)MonsterData.ID,
WorldLevel = (uint)scene.Player.Data.WorldLevel,
}
};
}
}

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Util;
using Microsoft.Extensions.Logging;
@@ -27,6 +28,14 @@ namespace EggLink.DanhengServer.Game.Scene.Entity
#endregion
public void AddBuff(SceneBuff buff)
{
}
public void ApplyBuff(BattleInstance instance)
{
}
public SceneEntityInfo ToProto()
{
SceneNpcInfo npc = new()

View File

@@ -1,6 +1,7 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Scene;
using EggLink.DanhengServer.Util;
@@ -21,6 +22,14 @@ namespace EggLink.DanhengServer.Game.Scene.Entity
public PropRogueInfo? RogueInfo { get; set; }
public void AddBuff(SceneBuff buff)
{
}
public void ApplyBuff(BattleInstance instance)
{
}
public void SetState(PropStateEnum state)
{
SetState(state, scene.IsLoaded);

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Util;
using System;
using System.Collections.Generic;
@@ -13,6 +14,10 @@ namespace EggLink.DanhengServer.Game.Scene.Entity
public int EntityID { get; set; }
public int GroupID { get; set; }
public void AddBuff(SceneBuff buff);
public void ApplyBuff(BattleInstance instance);
public SceneEntityInfo ToProto();
}
}

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Util;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -7,24 +8,34 @@ using System.Threading.Tasks;
namespace EggLink.DanhengServer.Game.Scene
{
public class SceneBuff
public class SceneBuff(int buffID, int buffLevel, int owner, int duration = -1)
{
public int BuffID { get; private set; }
public int BuffLevel { get; private set; }
public int BuffID { get; private set; } = buffID;
public int BuffLevel { get; private set; } = buffLevel;
public int OwnerAvatarId { get; private set; } = owner;
public SceneBuff(int buffID, int buffLevel)
public int Duration { get; private set; } = duration * 1000; // in milliseconds
public long CreatedTime { get; private set; } = Extensions.GetUnixMs();
public Dictionary<string, float> DynamicValues = [];
public bool IsExpired()
{
BuffID = buffID;
BuffLevel = buffLevel;
if (Duration == -1)
return true; // Permanent buff
return Extensions.GetUnixMs() - CreatedTime >= Duration;
}
public BattleBuff ToProto(int owner, int waveFlag) => new()
{
Id = (uint)BuffID,
Level = (uint)BuffLevel,
OwnerIndex = (uint)owner,
WaveFlag = (uint)waveFlag,
TargetIndexList = { (uint)owner },
};
public BuffInfo ToProto() {
var buffInfo = new BuffInfo()
{
BuffId = (uint)BuffID,
Level = (uint)BuffLevel,
BaseAvatarId = (uint)OwnerAvatarId,
AddTimeMs = (ulong)CreatedTime,
LifeTime = (ulong)Duration,
};
return buffInfo;
}
}
}

View File

@@ -3,6 +3,7 @@ using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Scene.Entity;
using EggLink.DanhengServer.Server.Packet.Send.Scene;
using EggLink.DanhengServer.Util;
namespace EggLink.DanhengServer.Game.Scene
{
@@ -18,7 +19,10 @@ namespace EggLink.DanhengServer.Game.Scene
{
continue;
}
if (group.GroupName.Contains("TrainVisitor"))
{
continue;
}
LoadGroup(group);
}
scene.IsLoaded = true;
@@ -44,6 +48,11 @@ namespace EggLink.DanhengServer.Game.Scene
continue;
}
if (group.GroupName.Contains("TrainVisitor"))
{
continue;
}
if (oldGroupId.Contains(group.Id)) // check if it should be unloaded
{
if (group.UnloadCondition.IsTrue(scene.Player.MissionManager!.Data, false) || group.ForceUnloadCondition.IsTrue(scene.Player.MissionManager!.Data, false))
@@ -194,7 +203,10 @@ namespace EggLink.DanhengServer.Game.Scene
}
else
{
prop.SetState(info.State);
if (info.State == PropStateEnum.Locked)
prop.SetState(PropStateEnum.Closed);
else
prop.SetState(info.State);
}
return prop;
}

View File

@@ -3,6 +3,7 @@ using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Database.Avatar;
using EggLink.DanhengServer.Game.Battle;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Game.Scene.Entity;
using EggLink.DanhengServer.Proto;
@@ -95,6 +96,7 @@ namespace EggLink.DanhengServer.Game.Scene
{
if (AvatarInfo.Values.ToList().FindIndex(x => x.AvatarInfo.AvatarId == avatar.AvatarInfo.AvatarId) == -1)
{
avatar.AvatarInfo.EntityId = 0;
RemoveAvatar.Add(avatar);
sendPacket = true;
}
@@ -274,7 +276,7 @@ namespace EggLink.DanhengServer.Game.Scene
#endregion
}
public class AvatarSceneInfo(AvatarInfo avatarInfo, AvatarType avatarType) : IGameEntity
public class AvatarSceneInfo(AvatarInfo avatarInfo, AvatarType avatarType, PlayerInstance Player) : IGameEntity
{
public AvatarInfo AvatarInfo = avatarInfo;
public AvatarType AvatarType = avatarType;
@@ -282,6 +284,25 @@ namespace EggLink.DanhengServer.Game.Scene
public int EntityID { get; set; } = avatarInfo.EntityId;
public int GroupID { get; set; } = 0;
public List<SceneBuff> BuffList = [];
public void AddBuff(SceneBuff buff)
{
BuffList.Add(buff);
Player.SendPacket(new PacketSyncEntityBuffChangeListScNotify(this, buff));
}
public void ApplyBuff(BattleInstance instance)
{
foreach (var buff in BuffList)
{
if (buff.IsExpired())
{
continue;
}
instance.Buffs.Add(new MazeBuff(buff));
}
}
public SceneEntityInfo ToProto()
{
return AvatarInfo.ToSceneEntityInfo(AvatarType);

View File

@@ -18,7 +18,6 @@
<ItemGroup>
<Folder Include="Server\Packet\Recv\ChessRogue\" />
<Folder Include="Server\Packet\Recv\Mail\" />
<Folder Include="Server\Packet\Recv\Friend\" />
<Folder Include="Server\Packet\Send\ChessRogue\" />
<Folder Include="Server\Packet\Send\Friend\" />
<Folder Include="Server\Packet\Send\Mail\" />

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Battle
{
[Opcode(CmdIds.QuitBattleCsReq)]
public class HandlerQuitBattleCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.Player!.BattleInstance = null;
connection.SendPacket(CmdIds.QuitBattleScRsp);
}
}
}

View File

@@ -1,5 +1,6 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Game.Battle.Skill;
using EggLink.DanhengServer.Game.Battle.Skill.Action;
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Battle;
@@ -21,17 +22,28 @@ namespace EggLink.DanhengServer.Server.Packet.Recv.Battle
{
connection.Player!.SceneInstance!.AvatarInfo.TryGetValue((int)req.AttackedByEntityId, out var info);
MazeSkill mazeSkill = new([]);
var id = 0;
if (info != null)
if (info != null) // cast by player
{
id = info.AvatarInfo.AvatarId;
mazeSkill = MazeSkillManager.GetSkill(info.AvatarInfo.AvatarId, (int)req.SkillIndex);
}
if (req.HitTargetEntityIdList.Count == 0)
{
// didnt hit any target
connection.SendPacket(new PacketSceneCastSkillScRsp(req.CastEntityId));
} else connection.Player!.BattleManager!.StartBattle(req, mazeSkill, id);
if (mazeSkill != null && req.SkillIndex > 0)
{
if (mazeSkill.Actions.FindIndex(a => a is MazeSetTargetMonsterDie) < 0)
{
connection.Player!.LineupManager!.CostMp(req.AttackedByEntityId, 1);
}
}
}
else
{
connection.Player!.BattleManager!.StartBattle(req, mazeSkill);
}
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Friend
{
[Opcode(CmdIds.GetFriendApplyListInfoCsReq)]
public class HandlerGetFriendApplyListInfoCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(CmdIds.GetFriendApplyListInfoScRsp);
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Friend
{
[Opcode(CmdIds.GetFriendListInfoCsReq)]
public class HandlerGetFriendListInfoCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(CmdIds.GetFriendListInfoScRsp);
}
}
}

View File

@@ -0,0 +1,21 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Mission;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Mission
{
[Opcode(CmdIds.GetNpcMessageGroupCsReq)]
public class HandlerGetNpcMessageGroupCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetNpcMessageGroupCsReq.Parser.ParseFrom(data);
connection.SendPacket(new PacketGetNpcMessageGroupScRsp(req.ContactIdList, connection.Player!));
}
}
}

View File

@@ -0,0 +1,21 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Scene;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Scene
{
[Opcode(CmdIds.GetUnlockTeleportCsReq)]
public class HandlerGetUnlockTeleportCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetUnlockTeleportCsReq.Parser.ParseFrom(data);
connection.SendPacket(new PacketGetUnlockTeleportScRsp(req));
}
}
}

View File

@@ -0,0 +1,23 @@
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Lineup
{
public class PacketSceneCastSkillMpUpdateScNotify : BasePacket
{
public PacketSceneCastSkillMpUpdateScNotify(uint castEntityId, int mpCount) : base(CmdIds.SceneCastSkillMpUpdateScNotify)
{
var proto = new SceneCastSkillMpUpdateScNotify()
{
CastEntityId = castEntityId,
Mp = (uint)mpCount,
};
SetData(proto);
}
}
}

View File

@@ -0,0 +1,27 @@
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Mission
{
public class PacketGetNpcMessageGroupScRsp : BasePacket
{
public PacketGetNpcMessageGroupScRsp(IEnumerable<uint> contactIdList, PlayerInstance instance) : base(CmdIds.GetNpcMessageGroupScRsp)
{
var proto = new GetNpcMessageGroupScRsp();
foreach (var contactId in contactIdList)
{
var contact = instance.MessageManager!.GetMessageGroup((int)contactId);
proto.MessageGroup.AddRange(contact);
}
SetData(proto);
}
}
}

View File

@@ -18,7 +18,7 @@ namespace EggLink.DanhengServer.Server.Packet.Send.Quest
proto.QuestList.Add(new Proto.Quest()
{
Id = (uint)quest.QuestID,
Status = QuestStatus.QuestFinish
Status = QuestStatus.QuestClose
});
}
SetData(proto);

View File

@@ -0,0 +1,34 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Scene
{
public class PacketGetUnlockTeleportScRsp : BasePacket
{
public PacketGetUnlockTeleportScRsp(GetUnlockTeleportCsReq req) : base(CmdIds.GetUnlockTeleportScRsp)
{
var rsp = new GetUnlockTeleportScRsp();
foreach (var entranceId in req.EntryIdList)
{
GameData.MapEntranceData.TryGetValue((int)entranceId, out var excel);
if (excel == null) continue;
GameData.GetFloorInfo(excel.PlaneID, excel.FloorID, out var floorInfo);
if (floorInfo == null) continue;
foreach (var teleport in floorInfo.CachedTeleports)
{
rsp.UnlockTeleportList.Add((uint)teleport.Value.MappingInfoID);
}
}
SetData(rsp);
}
}
}

View File

@@ -0,0 +1,27 @@
using EggLink.DanhengServer.Game.Scene;
using EggLink.DanhengServer.Game.Scene.Entity;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Scene
{
public class PacketSyncEntityBuffChangeListScNotify : BasePacket
{
public PacketSyncEntityBuffChangeListScNotify(IGameEntity entity, SceneBuff buff) : base(CmdIds.SyncEntityBuffChangeListScNotify)
{
var proto = new SyncEntityBuffChangeListScNotify();
var change = new EntityBuffChange()
{
EntityId = (uint)entity.EntityID,
BuffInfo = buff.ToProto(),
};
proto.EntityBuffChangeList.Add(change);
SetData(proto);
}
}
}