refactor: better scene entity loader

This commit is contained in:
StopWuyu
2025-06-05 19:07:06 +08:00
parent baf00261ea
commit b0a0022939
6 changed files with 145 additions and 70 deletions

View File

@@ -7,6 +7,7 @@ using EggLink.DanhengServer.Enums.Task;
using EggLink.DanhengServer.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Spectre.Console;
namespace EggLink.DanhengServer.Data.Config.Scene;
@@ -96,34 +97,24 @@ public class LoadCondition
public bool IsTrue(MissionData mission, bool defaultResult = true)
{
if (Conditions.Count == 0) return defaultResult;
var canLoad = Operation == OperationEnum.And;
// check load condition
List<Func<bool>> conditionChecks = [];
foreach (var condition in Conditions)
if (condition.Type == LevelGroupMissionTypeEnum.MainMission)
{
var info = mission.GetMainMissionStatus(condition.ID);
if (!ConfigManager.Config.ServerOption.EnableMission) info = MissionPhaseEnum.Finish;
var status = mission.GetMainMissionStatus(condition.ID);
if (!ConfigManager.Config.ServerOption.EnableMission) status = MissionPhaseEnum.Finish;
condition.Phase = condition.Phase == MissionPhaseEnum.Cancel
? MissionPhaseEnum.Finish
: condition.Phase;
if (info != condition.Phase)
{
if (Operation == OperationEnum.And)
{
canLoad = false;
break;
}
}
else
{
if (Operation == OperationEnum.Or)
{
canLoad = true;
break;
}
}
conditionChecks.Add(CheckFunc);
continue;
bool CheckFunc() => status == condition.Phase;
}
else
{
@@ -133,25 +124,23 @@ public class LoadCondition
condition.Phase = condition.Phase == MissionPhaseEnum.Cancel
? MissionPhaseEnum.Finish
: condition.Phase;
if (status != condition.Phase)
{
if (Operation == OperationEnum.And)
{
canLoad = false;
break;
}
}
else
{
if (Operation == OperationEnum.Or)
{
canLoad = true;
break;
}
}
conditionChecks.Add(CheckFunc);
continue;
bool CheckFunc() => status == condition.Phase;
}
return canLoad;
switch (Operation)
{
case OperationEnum.And when UtilTools.CheckAnd(conditionChecks, defaultResult):
case OperationEnum.Or when UtilTools.CheckOr(conditionChecks, defaultResult):
return true;
case OperationEnum.Not:
return !UtilTools.CheckOr(conditionChecks, defaultResult);
default:
return defaultResult;
}
}
}
@@ -165,43 +154,31 @@ public class SavedValueLoadCondition
public bool IsTrue(Dictionary<string, int> savedValue, bool defaultResult = true)
{
if (Conditions.Count == 0) return defaultResult;
var canLoad = Operation == OperationEnum.And;
// check load condition
List<Func<bool>> conditionChecks = [];
foreach (var condition in Conditions)
{
// saved value
var status = savedValue.GetValueOrDefault(condition.SavedValueName, 0);
var b = condition.Operation switch
{
CompareTypeEnum.Equal => status != condition.Value,
CompareTypeEnum.Greater => status <= condition.Value,
CompareTypeEnum.GreaterEqual => status > condition.Value,
CompareTypeEnum.Less => status >= condition.Value,
CompareTypeEnum.LessEqual => status < condition.Value,
CompareTypeEnum.NotEqual => status == condition.Value,
CompareTypeEnum.Unknow => true,
_ => false
};
if (condition.Operation == CompareTypeEnum.Unknow) continue;
if (b)
{
if (Operation == OperationEnum.And)
{
canLoad = false;
break;
}
}
else
{
if (Operation == OperationEnum.Or)
{
canLoad = true;
break;
}
}
conditionChecks.Add(CheckFunc);
continue;
bool CheckFunc() => UtilTools.CompareNumberByOperationEnum(status, condition.Value, condition.Operation);
}
return canLoad;
switch (Operation)
{
case OperationEnum.And when UtilTools.CheckAnd(conditionChecks, defaultResult):
case OperationEnum.Or when UtilTools.CheckOr(conditionChecks, defaultResult):
return true;
case OperationEnum.Not:
return !UtilTools.CheckOr(conditionChecks, defaultResult);
default:
return defaultResult;
}
}
}

View File

@@ -382,6 +382,15 @@ public static class GameData
FloorInfoData.TryGetValue("P" + planeId + "_F" + floorId, out outer!);
}
public static FloorInfo? GetFloorInfo(int floorId)
{
var entrance = MapEntranceData.FirstOrDefault(x => x.Value.FloorID == floorId);
if (entrance.Value == null) return null;
GetFloorInfo(entrance.Value.PlaneID, floorId, out var floorInfo);
return floorInfo;
}
public static int GetPlayerExpRequired(int level)
{
var excel = PlayerLevelConfigData[level];

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Enums.Scene;
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Enums.Scene;
using EggLink.DanhengServer.Proto;
using Google.Protobuf;
using SqlSugar;
@@ -43,6 +44,35 @@ public class SceneData : BaseDatabaseDataHelper
[SugarColumn(IsJson = true, ColumnDataType = "TEXT")]
public Dictionary<int, int> FloorTargetPuzzleGroupData { get; set; } = new();
public int GetFloorSavedValue(int floorId, string key)
{
if (FloorSavedData.TryGetValue(floorId, out var data) && data.TryGetValue(key, out var value))
{
return value;
}
// get default value if not found
var floor = GameData.GetFloorInfo(floorId);
if (floor == null) return 0;
var savedValue = floor.FloorSavedValue.FirstOrDefault(x => x.Name == key);
return savedValue?.DefaultValue ?? 0;
}
public Dictionary<string, int> GetFloorSavedValues(int floorId)
{
var floor = GameData.GetFloorInfo(floorId);
if (floor == null) return [];
var savedValues = new Dictionary<string, int>();
foreach (var value in floor.FloorSavedValue)
{
savedValues[value.Name] = GetFloorSavedValue(floorId, value.Name);
}
return savedValues;
}
}
public class ScenePropData

View File

@@ -1,4 +1,6 @@
using System.Globalization;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Enums.Task;
using System.Globalization;
namespace EggLink.DanhengServer.Util;
@@ -15,4 +17,62 @@ public static class UtilTools
_ => "EN"
};
}
public static bool CheckAnd(List<Func<bool>> actions, bool defaultValue = true)
{
if (actions.Count == 0) return defaultValue;
foreach (var action in actions)
{
try
{
var returnValue = action.Invoke();
if (!returnValue)
{
return false;
}
}
catch
{
// ignored
}
}
return true;
}
public static bool CheckOr(List<Func<bool>> actions, bool defaultValue = false)
{
if (actions.Count == 0) return defaultValue;
foreach (var action in actions)
{
try
{
var returnValue = action.Invoke();
if (returnValue)
{
return true;
}
}
catch
{
// ignored
}
}
return false;
}
public static bool CompareNumberByOperationEnum(int left, int right, CompareTypeEnum operation)
{
return operation switch
{
CompareTypeEnum.Greater => left > right,
CompareTypeEnum.GreaterEqual => left >= right,
CompareTypeEnum.NotEqual => left != right,
CompareTypeEnum.Equal => left == right,
CompareTypeEnum.LessEqual => left <= right,
CompareTypeEnum.Less => left < right,
_ => false
};
}
}

View File

@@ -324,7 +324,7 @@ public class MissionManager : BasePlayerManager
{
// Player.ChangeAvatarPathType(8001, Enums.Avatar.MultiPathAvatarTypeEnum.Knight);
var list = Player.LineupManager!.GetCurLineup()!.BaseAvatars!
.Select(x => x.SpecialAvatarId > 0 ? x.SpecialAvatarId / 10 : x.BaseAvatarId).ToList();
.Select(x => x.SpecialAvatarId > 0 ? x.SpecialAvatarId : x.BaseAvatarId).ToList();
list[list.IndexOf(8001)] = Player.Data.CurrentGender == Gender.Man ? 1008003 : 1008004;
Player.LineupManager!.SetExtraLineup(ExtraLineupType.LineupHeliobus, list);
}

View File

@@ -77,8 +77,7 @@ public class SceneEntityLoader(SceneInstance scene)
Scene.Groups.Remove(group.Id);
}
else if (!group.SavedValueCondition.IsTrue(
Scene.Player.SceneData!.FloorSavedData.GetValueOrDefault(Scene.FloorId,
[]))) // condition: Saved Value Condition
Scene.Player.SceneData!.GetFloorSavedValues(Scene.FloorId))) // condition: Saved Value Condition
{
foreach (var entity in Scene.Entities.Values.Where(entity => entity.GroupId == group.Id))
{