Fix Divergent Universe Workbench

This commit is contained in:
Somebody
2024-10-01 22:50:51 +08:00
parent c4c4e84629
commit 11e549d4d7
225 changed files with 1948 additions and 1481 deletions

View File

@@ -54,7 +54,7 @@ public class RogueProp(SceneInstance scene, MazePropExcel excel, GroupInfo group
{
RogueTournDoorInfo = new RogueTournDoorInfo
{
KPCKJNANCKA = EnterNextLayer,
EnterNextLayer = EnterNextLayer,
RogueTournRoomType = (uint)RoomType
}
};

View File

@@ -17,6 +17,8 @@ namespace EggLink.DanhengServer.GameServer.Game.RogueTourn;
public class RogueTournInstance : BaseRogueInstance
{
#region Initializer
public RogueTournInstance(PlayerInstance player, int areaId) : base(player, RogueSubModeEnum.TournRogue, 0)
{
// generate levels
@@ -35,9 +37,17 @@ public class RogueTournInstance : BaseRogueInstance
CurLayerId = 1101;
EventManager = new RogueEventManager(player, this);
var t = RollFormula(1, [RogueFormulaCategoryEnum.Common, RogueFormulaCategoryEnum.Rare]);
t.AsTask().Wait();
}
#endregion
#region Properties
public List<RogueTournFormulaExcel> RogueFormulas { get; set; } = [];
public List<int> ExpandedFormulaIdList { get; set; } = [];
public Dictionary<int, RogueTournLevelInstance> Levels { get; set; } = [];
public List<RogueTournDifficultyExcel> DifficultyExcels { get; set; } = [];
public int CurLayerId { get; set; }
@@ -46,17 +56,21 @@ public class RogueTournInstance : BaseRogueInstance
public Dictionary<RogueTournRoomTypeEnum, int> RoomTypeWeight { get; set; } = new()
{
{ RogueTournRoomTypeEnum.Battle, 7 },
{ RogueTournRoomTypeEnum.Coin, 2 },
{ RogueTournRoomTypeEnum.Shop, 2 },
{ RogueTournRoomTypeEnum.Event, 3 },
{ RogueTournRoomTypeEnum.Adventure, 3 },
{ RogueTournRoomTypeEnum.Battle, 15 },
{ RogueTournRoomTypeEnum.Coin, 4 },
{ RogueTournRoomTypeEnum.Shop, 4 },
{ RogueTournRoomTypeEnum.Event, 7 },
{ RogueTournRoomTypeEnum.Adventure, 6 },
{ RogueTournRoomTypeEnum.Reward, 5 },
{ RogueTournRoomTypeEnum.Hidden, 1 }
};
public RogueTournLevelInstance? CurLevel => Levels.GetValueOrDefault(CurLayerId);
#endregion
#region Scene
public async ValueTask EnterNextLayer(int roomIndex, RogueTournRoomTypeEnum type)
{
CurLayerId += 100;
@@ -102,11 +116,73 @@ public class RogueTournInstance : BaseRogueInstance
Player.RogueTournManager!.RogueTournInstance = null;
}
#endregion
#region Buff & Formula
public override async ValueTask RollBuff(int amount)
{
await RollBuff(amount, 2000101);
}
public async ValueTask RollFormula(int amount, List<RogueFormulaCategoryEnum> categories)
{
var formulaList = GameData.RogueTournFormulaData.Values.Where(x => !RogueFormulas.Contains(x) && categories.Contains(x.FormulaCategory)).ToList();
for (var i = 0; i < amount; i++)
{
var menu = new RogueFormulaSelectMenu(this);
menu.RollFormula(formulaList);
var action = menu.GetActionInstance();
RogueActions.Add(action.QueuePosition, action);
}
await UpdateMenu();
}
public override async ValueTask HandleBuffSelect(int buffId)
{
await base.HandleBuffSelect(buffId);
await ExpandFormula();
}
public override async ValueTask<RogueCommonActionResult?> AddBuff(int buffId, int level = 1,
RogueCommonActionResultSourceType source = RogueCommonActionResultSourceType.Dialogue,
RogueCommonActionResultDisplayType displayType = RogueCommonActionResultDisplayType.Single,
bool updateMenu = true, bool notify = true)
{
var res = await base.AddBuff(buffId, level, source, displayType, updateMenu, notify);
await ExpandFormula();
return res;
}
public async ValueTask ExpandFormula()
{
// expand formula
foreach (var formula in RogueFormulas)
{
if (formula.IsExpanded(RogueBuffs.Select(x => x.BuffId).ToList()) &&
!ExpandedFormulaIdList.Contains(formula.FormulaID))
{
ExpandedFormulaIdList.Add(formula.FormulaID);
await Player.SendPacket(new PacketSyncRogueCommonActionResultScNotify(RogueSubMode,
formula.ToResultProto(RogueCommonActionResultSourceType.Select,
RogueBuffs.Select(x => x.BuffId).ToList())));
}
else if (!formula.IsExpanded(RogueBuffs.Select(x => x.BuffId).ToList()) &&
ExpandedFormulaIdList.Contains(formula.FormulaID)) // remove expanded formula
{
ExpandedFormulaIdList.Remove(formula.FormulaID);
await Player.SendPacket(new PacketSyncRogueCommonActionResultScNotify(RogueSubMode,
formula.ToResultProto(RogueCommonActionResultSourceType.Select,
RogueBuffs.Select(x => x.BuffId).ToList())));
}
}
}
public async ValueTask HandleFormulaSelect(int formulaId)
{
if (RogueActions.Count == 0) return;
@@ -133,6 +209,10 @@ public class RogueTournInstance : BaseRogueInstance
new PacketHandleRogueCommonPendingActionScRsp(action.QueuePosition, selectFormula: true));
}
#endregion
#region Handlers
public override void OnBattleStart(BattleInstance battle)
{
base.OnBattleStart(battle);
@@ -173,19 +253,8 @@ public class RogueTournInstance : BaseRogueInstance
else
{
// trigger formula
var formulaList = GameData.RogueTournFormulaData.Values.Where(x => !RogueFormulas.Contains(x)).ToList();
for (var i = 0; i < battle.Stages.Count; i++)
{
await RollBuff(battle.Stages.Count, 2000103);
var menu = new RogueFormulaSelectMenu(this);
menu.RollFormula(formulaList);
var action = menu.GetActionInstance();
RogueActions.Add(action.QueuePosition, action);
}
await UpdateMenu();
await RollBuff(battle.Stages.Count, 2000103);
await RollFormula(battle.Stages.Count, [RogueFormulaCategoryEnum.Legendary]);
}
}
else
@@ -195,6 +264,61 @@ public class RogueTournInstance : BaseRogueInstance
}
}
#endregion
#region Workbench
public async ValueTask<Retcode> HandleFunc(RogueWorkbenchFunc func, RogueWorkbenchContentInfo content)
{
switch (func.Excel.FuncType)
{
case RogueTournWorkbenchFuncTypeEnum.BuffEnhance:
return await HandleBuffEnhance(func, content);
case RogueTournWorkbenchFuncTypeEnum.BuffReforge:
return await HandleBuffReforge(func, content);
}
return Retcode.RetSucc;
}
public async ValueTask<Retcode> HandleBuffEnhance(RogueWorkbenchFunc func, RogueWorkbenchContentInfo content)
{
var buffId = content.EnhanceBuffFunc.TargetBuffId;
var buff = RogueBuffs.Find(x => x.BuffId == buffId);
if (buff == null) return Retcode.RetRogueSelectBuffNotExist;
if (buff.BuffLevel == 2) return Retcode.RetRogueSelectBuffCertainMismatch; // already enhanced
var cost = (int)buff.BuffExcel.RogueBuffCategory;
if (func.CurNum < cost) return Retcode.RetRogueCoinNotEnough;
func.CurNum -= cost;
await EnhanceBuff(buff.BuffId, RogueCommonActionResultSourceType.Enhance);
return Retcode.RetSucc;
}
public async ValueTask<Retcode> HandleBuffReforge(RogueWorkbenchFunc func, RogueWorkbenchContentInfo content)
{
var buffId = content.ReforgeBuffFunc.HMJAFJLBPAM;
var buff = RogueBuffs.Find(x => x.BuffId == buffId);
if (buff == null) return Retcode.RetRogueSelectBuffNotExist;
var cost = func.CurCost;
if (CurMoney < cost) return Retcode.RetRogueCoinNotEnough;
func.CurCost += 30;
// TODO: remove old buff
//await ReforgeBuff(buff.BuffId, RogueCommonActionResultSourceType.Reforge);
return Retcode.RetSucc;
}
#endregion
#region Serilization
public RogueTournCurInfo ToProto()

View File

@@ -175,8 +175,14 @@ public class RogueTournEntityLoader(SceneInstance scene, PlayerInstance player)
if (room.LevelInstance.Rooms.Last().RoomIndex - 1 == room.RoomIndex) // boss only
{
if (prop.InstId != 300002) return null; // not center door
nextRoom = RogueTournRoomTypeEnum.Boss;
}
else if (room.LevelInstance.Rooms.Last().RoomIndex - 2 == room.RoomIndex && room.LevelInstance.LevelIndex == 3) // respite only
{
if (prop.InstId != 300002) return null; // not center door
nextRoom = RogueTournRoomTypeEnum.Respite;
}
else
{
if (ExistTypes.Contains(nextRoom)) continue;
@@ -206,6 +212,24 @@ public class RogueTournEntityLoader(SceneInstance scene, PlayerInstance player)
await prop.SetState(PropStateEnum.Open);
}
else if (prop.PropInfo.PropID == 1038)
{
var p = new RogueWorkbenchProp(Scene, propExcel, group, info)
{
WorkbenchId = 105
};
var workbenchExcel = GameData.RogueTournWorkbenchData.GetValueOrDefault(p.WorkbenchId);
if (workbenchExcel != null)
{
foreach (var funcExcel in workbenchExcel.Funcs)
{
p.WorkbenchFuncs.Add(new RogueWorkbenchFunc(funcExcel));
}
}
prop = p;
await prop.SetState(info.State);
}
else
{
await prop.SetState(info.State);

View File

@@ -0,0 +1,112 @@
using EggLink.DanhengServer.Data.Config.Scene;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Enums.TournRogue;
using EggLink.DanhengServer.GameServer.Game.Rogue.Scene.Entity;
using EggLink.DanhengServer.GameServer.Game.Scene;
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Game.RogueTourn.Scene;
public class RogueWorkbenchProp(SceneInstance scene, MazePropExcel excel, GroupInfo group, PropInfo prop)
: RogueProp(scene, excel, group, prop)
{
public RogueWorkbenchProp(EntityProp prop) : this(prop.Scene, prop.Excel, prop.Group, prop.PropInfo)
{
}
public int WorkbenchId { get; set; }
public List<RogueWorkbenchFunc> WorkbenchFuncs { get; set; } = [];
public override SceneEntityInfo ToProto()
{
var proto = base.ToProto();
if (WorkbenchId != 0)
proto.Prop.ExtraInfo = new PropExtraInfo
{
RogueTournWorkbenchInfo = new RogueTournWorkbenchInfo
{
WorkbenchId = (uint)WorkbenchId,
WorkbenchFuncList = { WorkbenchFuncs.Select(x => x.ToIdInfo()) }
}
};
return proto;
}
}
public class RogueWorkbenchFunc(RogueTournWorkbenchFuncExcel excel)
{
public int FuncId { get; set; } = excel.FuncID;
public RogueTournWorkbenchFuncExcel Excel { get; set; } = excel;
public int CurNum { get; set; } = 5;
public int MaxNum { get; set; } = 5;
public int CurCost { get; set; }
public WorkbenchFuncIdInfo ToIdInfo()
{
return new WorkbenchFuncIdInfo
{
WorkbenchFuncId = (uint)FuncId,
IsValid = true
};
}
public WorkbenchFuncInfo ToProto()
{
var proto = new WorkbenchFuncInfo();
switch (Excel.FuncType)
{
case RogueTournWorkbenchFuncTypeEnum.BuffEnhance:
proto.EnhanceBuffFunc = new WorkbenchEnhanceBuffFuncInfo
{
CurNum = (uint)CurNum,
MaxNum = (uint)MaxNum,
PFLOHKLIMAL = // cost
{
{1, 1},
{2, 2},
{3, 3}
}
};
break;
case RogueTournWorkbenchFuncTypeEnum.BuffReforge:
proto.ReforgeBuffFunc = new WorkbenchReforgeBuffFuncInfo
{
CostData = new ItemCostData
{
ItemList = { new ItemCost
{
PileItem = new PileItem
{
ItemId = 31,
ItemNum = (uint)CurCost
}
} }
}
};
break;
case RogueTournWorkbenchFuncTypeEnum.FormulaReforge:
proto.ReforgeFormulaFunc = new WorkbenchReforgeFormulaFuncInfo
{
CostData = new ItemCostData
{
ItemList = { new ItemCost
{
PileItem = new PileItem
{
ItemId = 31,
ItemNum = (uint)CurCost
}
} }
}
};
break;
}
return proto;
}
}

View File

@@ -33,7 +33,6 @@
<Folder Include="Server\Packet\Send\Message\" />
<Folder Include="Server\Packet\Send\Phone\" />
<Folder Include="Server\Packet\Send\PlayerBoard\" />
<Folder Include="Server\Packet\Send\RogueCommon\" />
<Folder Include="Server\Packet\Send\RollShop\" />
<Folder Include="Server\Packet\Send\StoryLine\" />
<Folder Include="Server\Packet\Send\PlayerSync\" />

View File

@@ -0,0 +1,26 @@
using EggLink.DanhengServer.GameServer.Game.RogueTourn.Scene;
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueCommon;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.RogueCommon;
[Opcode(CmdIds.RogueWorkbenchGetInfoCsReq)]
public class HandlerRogueWorkbenchGetInfoCsReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = RogueWorkbenchGetInfoCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
IGameEntity? entity = null;
player.SceneInstance?.Entities.TryGetValue((int)req.PropEntityId, out entity);
if (entity is not RogueWorkbenchProp prop)
{
await connection.SendPacket(new PacketRogueWorkbenchGetInfoScRsp(Retcode.RetSceneEntityNotExist, null));
return;
}
await connection.SendPacket(new PacketRogueWorkbenchGetInfoScRsp(Retcode.RetSucc, prop));
}
}

View File

@@ -0,0 +1,43 @@
using EggLink.DanhengServer.GameServer.Game.RogueTourn.Scene;
using EggLink.DanhengServer.GameServer.Game.Scene.Entity;
using EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueCommon;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.RogueCommon;
[Opcode(CmdIds.RogueWorkbenchHandleFuncCsReq)]
public class HandlerRogueWorkbenchHandleFuncCsReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = RogueWorkbenchHandleFuncCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
IGameEntity? entity = null;
player.SceneInstance?.Entities.TryGetValue((int)req.PropEntityId, out entity);
if (entity is not RogueWorkbenchProp prop)
{
await connection.SendPacket(new PacketRogueWorkbenchHandleFuncScRsp(Retcode.RetSceneEntityNotExist, req.WorkbenchFuncId, null));
return;
}
var func = prop.WorkbenchFuncs.Find(x => x.FuncId == req.WorkbenchFuncId);
if (func == null)
{
await connection.SendPacket(new PacketRogueWorkbenchHandleFuncScRsp(Retcode.RetFail, req.WorkbenchFuncId, null));
return;
}
var instance = player.RogueTournManager?.RogueTournInstance;
if (instance == null)
{
await connection.SendPacket(new PacketRogueWorkbenchHandleFuncScRsp(Retcode.RetTournRogueStatusMismatch, req.WorkbenchFuncId, null));
return;
}
await instance.HandleFunc(func, req.WorkbenchContent);
await connection.SendPacket(new PacketRogueWorkbenchHandleFuncScRsp(Retcode.RetSucc, req.WorkbenchFuncId, func));
}
}

View File

@@ -0,0 +1,26 @@
using EggLink.DanhengServer.GameServer.Game.RogueTourn.Scene;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueCommon;
public class PacketRogueWorkbenchGetInfoScRsp : BasePacket
{
public PacketRogueWorkbenchGetInfoScRsp(Retcode ret, RogueWorkbenchProp? prop) : base(CmdIds.RogueWorkbenchGetInfoScRsp)
{
var proto = new RogueWorkbenchGetInfoScRsp
{
Retcode = (uint)ret
};
if (prop != null)
{
foreach (var rogueWorkbenchFunc in prop.WorkbenchFuncs)
{
proto.FuncInfoMap.Add((uint)rogueWorkbenchFunc.FuncId, rogueWorkbenchFunc.ToProto());
}
}
SetData(proto);
}
}

View File

@@ -0,0 +1,24 @@
using EggLink.DanhengServer.GameServer.Game.RogueTourn.Scene;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RogueCommon;
public class PacketRogueWorkbenchHandleFuncScRsp : BasePacket
{
public PacketRogueWorkbenchHandleFuncScRsp(Retcode retcode, uint funcId, RogueWorkbenchFunc? func) : base(CmdIds.RogueWorkbenchHandleFuncScRsp)
{
var proto = new RogueWorkbenchHandleFuncScRsp
{
Retcode = (uint)retcode,
WorkbenchFuncId = funcId
};
if (func != null)
{
proto.TargetFuncInfo = func.ToProto();
}
SetData(proto);
}
}