feat: Prop Timeline

This commit is contained in:
StopWuyu
2024-12-14 19:40:50 +08:00
parent 8458474952
commit 3b23e4af46
8 changed files with 177 additions and 2 deletions

View File

@@ -1,4 +1,6 @@
using EggLink.DanhengServer.Enums.Scene;
using EggLink.DanhengServer.Proto;
using Google.Protobuf;
using SqlSugar;
namespace EggLink.DanhengServer.Database.Scene;
@@ -20,10 +22,31 @@ public class SceneData : BaseDatabaseDataHelper
[SugarColumn(IsJson = true)]
public Dictionary<int, Dictionary<string, int>> FloorSavedData { get; set; } =
[]; // Dictionary<FloorId, Dictionary<SaveDataKey, SaveDataValue>>
[SugarColumn(IsJson = true)]
public Dictionary<int, Dictionary<int, Dictionary<int, ScenePropTimelineData>>> PropTimelineData { get; set; } =
[]; // Dictionary<FloorId, Dictionary<GroupId, Dictionary<PropId, ScenePropTimelineData>>
}
public class ScenePropData
{
public int PropId;
public PropStateEnum State;
public int PropId { get; set; }
public PropStateEnum State { get; set; }
}
public class ScenePropTimelineData
{
public uint UintValue { get; set; }
public bool BoolValue { get; set; }
public string ByteValue { get; set; } = ""; // Base64
public PropTimelineInfo ToProto()
{
return new PropTimelineInfo
{
TimelineIntValue = UintValue,
TimelineBoolValue = BoolValue,
TimelineByteValue = ByteString.FromBase64(ByteValue)
};
}
}

View File

@@ -0,0 +1,43 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Enums.Mission;
using EggLink.DanhengServer.GameServer.Game.Player;
using System.Text;
namespace EggLink.DanhengServer.GameServer.Game.Mission.FinishType.Handler;
[MissionFinishType(MissionFinishTypeEnum.TimeLineSetState)]
public class MissionHandlerTimeLineSetState : MissionFinishTypeHandler
{
public override async ValueTask HandleMissionFinishType(PlayerInstance player, SubMissionInfo info, object? arg)
{
var floorId = info.LevelFloorID;
var groupId = info.ParamInt1;
var propId = info.ParamInt2;
var value = info.ParamStr1;
var data = player.GetScenePropTimelineData(floorId, groupId, propId); // get data
if (data == null) return;
// compare
if (Encoding.UTF8.GetString(Convert.FromBase64String(data.ByteValue)) != value) return;
await player.MissionManager!.FinishSubMission(info.ID);
}
public override async ValueTask HandleQuestFinishType(PlayerInstance player, QuestDataExcel quest, FinishWayExcel excel, object? arg)
{
var floorId = excel.MazeFloorID;
var groupId = excel.ParamInt1;
var propId = excel.ParamInt2;
var value = excel.ParamStr1;
var data = player.GetScenePropTimelineData(floorId, groupId, propId); // get data
if (data == null) return;
// compare
if (Encoding.UTF8.GetString(Convert.FromBase64String(data.ByteValue)) != value) return;
await player.MissionManager!.FinishSubMission(excel.ID);
}
}

View File

@@ -0,0 +1,22 @@
using EggLink.DanhengServer.Data.Config;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Enums.Mission;
using EggLink.DanhengServer.GameServer.Game.Player;
namespace EggLink.DanhengServer.GameServer.Game.Mission.FinishType.Handler;
[MissionFinishType(MissionFinishTypeEnum.TimeLineSetStateCnt)]
public class MissionHandlerTimeLineSetStateCnt : MissionFinishTypeHandler
{
public override async ValueTask HandleMissionFinishType(PlayerInstance player, SubMissionInfo info, object? arg)
{
// TODO
await ValueTask.CompletedTask;
}
public override async ValueTask HandleQuestFinishType(PlayerInstance player, QuestDataExcel quest, FinishWayExcel excel, object? arg)
{
// TODO
await ValueTask.CompletedTask;
}
}

View File

@@ -550,6 +550,49 @@ public class PlayerInstance(PlayerData data)
return prop;
}
public async ValueTask SetPropTimeline(int propEntityId, PropTimelineInfo info)
{
if (SceneInstance == null) return;
SceneInstance.Entities.TryGetValue(propEntityId, out var entity);
if (entity is not EntityProp prop) return;
var data = new ScenePropTimelineData
{
BoolValue = info.TimelineBoolValue,
ByteValue = info.TimelineByteValue.ToBase64(),
UintValue = info.TimelineIntValue
};
// save to db
SceneData!.PropTimelineData.TryGetValue(Data.FloorId, out var floorData);
if (floorData == null)
{
floorData = new Dictionary<int, Dictionary<int, ScenePropTimelineData>>();
SceneData.PropTimelineData[Data.FloorId] = floorData;
}
if (!floorData.ContainsKey(prop.GroupID))
floorData[prop.GroupID] = new Dictionary<int, ScenePropTimelineData>();
floorData[prop.GroupID][prop.PropInfo.ID] = data;
prop.PropTimelineData = data;
// handle mission / quest
await MissionManager!.HandleFinishType(MissionFinishTypeEnum.TimeLineSetState);
await MissionManager!.HandleFinishType(MissionFinishTypeEnum.TimeLineSetStateCnt);
}
public ScenePropTimelineData? GetScenePropTimelineData(int floorId, int groupId, int propId)
{
SceneData!.PropTimelineData.TryGetValue(floorId, out var floorData);
if (floorData == null) return null;
floorData.TryGetValue(groupId, out var groupData);
if (groupData == null) return null;
groupData.TryGetValue(propId, out var data);
return data;
}
public async ValueTask<bool> EnterScene(int entryId, int teleportId, bool sendPacket, int storyLineId = 0,
bool mapTp = false)
{

View File

@@ -1,5 +1,6 @@
using EggLink.DanhengServer.Data.Config.Scene;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Database.Scene;
using EggLink.DanhengServer.Enums.Scene;
using EggLink.DanhengServer.GameServer.Game.Battle;
using EggLink.DanhengServer.GameServer.Server.Packet.Send.Scene;
@@ -20,6 +21,7 @@ public class EntityProp(SceneInstance scene, MazePropExcel excel, GroupInfo grou
public GroupInfo Group { get; set; } = group;
public int EntityID { get; set; }
public int GroupID { get; set; } = group.Id;
public ScenePropTimelineData? PropTimelineData { get; set; }
public async ValueTask AddBuff(SceneBuff buff)
{
@@ -39,6 +41,11 @@ public class EntityProp(SceneInstance scene, MazePropExcel excel, GroupInfo grou
PropState = (uint)State
};
if (PropTimelineData != null)
{
prop.TimelineInfo = PropTimelineData.ToProto();
}
return new SceneEntityInfo
{
EntityId = (uint)EntityID,

View File

@@ -276,6 +276,9 @@ public class SceneEntityLoader(SceneInstance scene)
prop.State = prop.Excel.PropType == PropTypeEnum.PROP_ELEVATOR ? PropStateEnum.Elevator1 : info.State;
}
var timelineData = Scene.Player.GetScenePropTimelineData(Scene.FloorId, group.Id, info.ID);
prop.PropTimelineData = timelineData;
if (group.GroupName.Contains("Machine"))
{
await prop.SetState(PropStateEnum.Open);

View File

@@ -0,0 +1,17 @@
using EggLink.DanhengServer.GameServer.Server.Packet.Send.Scene;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.Scene;
[Opcode(CmdIds.ChangePropTimelineInfoCsReq)]
public class HandlerChangePropTimelineInfoCsReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = ChangePropTimelineInfoCsReq.Parser.ParseFrom(data);
await connection.Player!.SetPropTimeline((int)req.PropEntityId, req.TimelineInfo);
await connection.SendPacket(new PacketChangePropTimelineInfoScRsp(req.PropEntityId));
}
}

View File

@@ -0,0 +1,17 @@
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Scene;
public class PacketChangePropTimelineInfoScRsp : BasePacket
{
public PacketChangePropTimelineInfoScRsp(uint entityId) : base(CmdIds.ChangePropTimelineInfoScRsp)
{
var proto = new ChangePropTimelineInfoScRsp
{
PropEntityId = entityId
};
SetData(proto);
}
}