mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-02 20:26:03 +08:00
feat: grid fight pending action
This commit is contained in:
@@ -22,10 +22,11 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
|
||||
public void HandleProto(SceneBattleInfo proto, BattleInstance battle)
|
||||
{
|
||||
var avatars = AvatarComponent.GetForegroundAvatarInfos(4 + BasicComponent.GetFieldCount());
|
||||
var backAvatars = AvatarComponent.GetBackgroundAvatarInfos(4 + BasicComponent.GetFieldCount());
|
||||
|
||||
var tempLineup = new LineupInfo
|
||||
{
|
||||
BaseAvatars = avatars.Select(y => new LineupAvatarInfo
|
||||
BaseAvatars = avatars.Concat(backAvatars).Select(y => new LineupAvatarInfo
|
||||
{
|
||||
BaseAvatarId = y.BaseAvatarId
|
||||
}).ToList()
|
||||
@@ -35,6 +36,11 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
|
||||
x.ToBattleProto(
|
||||
new PlayerDataCollection(Player.Data, Player.InventoryManager!.Data, tempLineup), AvatarType.AvatarGridFightType)).ToList();
|
||||
|
||||
var backFormatted = backAvatars.Select(x =>
|
||||
x.ToBattleProto(
|
||||
new PlayerDataCollection(Player.Data, Player.InventoryManager!.Data, tempLineup),
|
||||
AvatarType.AvatarGridFightType)).ToList();
|
||||
|
||||
proto.BattleAvatarList.Add(formatted.Take(4));
|
||||
|
||||
foreach (var wave in Encounter.MonsterWaves)
|
||||
@@ -59,10 +65,22 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
|
||||
|
||||
foreach (var role in AvatarComponent.Data.Roles)
|
||||
{
|
||||
if (!GameData.GridFightRoleStarData.TryGetValue(role.RoleId << 2 | role.Tier, out var roleConf)) continue;
|
||||
if (!GameData.GridFightRoleStarData.TryGetValue(role.RoleId << 4 | role.Tier, out var roleConf)) continue;
|
||||
battle.BattleEvents.TryAdd((int)roleConf.BEID, new BattleEventInstance((int)roleConf.BEID, 5000));
|
||||
}
|
||||
|
||||
battle.Buffs.Add(new MazeBuff(35100001, 1, -1)
|
||||
{
|
||||
WaveFlag = -1
|
||||
});
|
||||
|
||||
var even = battle.Stages.First().StageConfigData.FirstOrDefault(x => x.Key == "_CreateBattleEvent");
|
||||
if (even?.Value != null)
|
||||
{
|
||||
var id = int.Parse(even.Value);
|
||||
battle.BattleEvents.TryAdd(id, new BattleEventInstance(id, 5000));
|
||||
}
|
||||
|
||||
proto.BattleGridFightInfo = new BattleGridFightInfo
|
||||
{
|
||||
GridGameAvatarList =
|
||||
@@ -72,7 +90,7 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
|
||||
BattleWaveId = 1,
|
||||
GridFightCurLevel = BasicComponent.Data.CurLevel,
|
||||
GridFightLineupHp = BasicComponent.Data.CurHp,
|
||||
GridFightAvatarList = { formatted },
|
||||
GridFightAvatarList = { formatted, backFormatted },
|
||||
GridFightStageInfo = new BattleGridFightStageInfo
|
||||
{
|
||||
ChapterId = CurSection.ChapterId,
|
||||
@@ -80,7 +98,8 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
|
||||
SectionId = CurSection.SectionId
|
||||
},
|
||||
IsOverlock = Inst.IsOverLock,
|
||||
Season = Inst.Season
|
||||
Season = Inst.Season,
|
||||
DFNBKALPGPH = 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
@@ -8,6 +9,8 @@ namespace EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
||||
|
||||
public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComponent(inst)
|
||||
{
|
||||
#region Fields & Properties
|
||||
|
||||
public const uint MaxHp = 100;
|
||||
|
||||
public GridFightBasicInfoPb Data { get; set; } = new()
|
||||
@@ -19,6 +22,10 @@ public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
CurGold = 5
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region Data Management
|
||||
|
||||
public async ValueTask<Retcode> UpdateGoldNum(int changeNum, bool sendPacket = true, GridFightSrc src = GridFightSrc.KGridFightSrcManualRefreshGoods)
|
||||
{
|
||||
if (changeNum < 0 && -changeNum > Data.CurGold)
|
||||
@@ -131,11 +138,19 @@ public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
return Retcode.RetSucc;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Information
|
||||
|
||||
public uint GetFieldCount()
|
||||
{
|
||||
return 4 + 6;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialization
|
||||
|
||||
public override GridFightGameInfo ToProto()
|
||||
{
|
||||
return new GridFightGameInfo
|
||||
@@ -162,4 +177,6 @@ public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -10,17 +10,23 @@ namespace EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
||||
|
||||
public class GridFightLevelComponent : BaseGridFightComponent
|
||||
{
|
||||
#region Properties & Fields // TODO : to proto field
|
||||
|
||||
private uint _curChapterId = 1;
|
||||
private uint _curSectionId = 1;
|
||||
public Dictionary<uint, List<GridFightGameSectionInfo>> Sections { get; } = [];
|
||||
public GridFightGameSectionInfo CurrentSection => Sections[_curChapterId][(int)(_curSectionId - 1)];
|
||||
public List<GridFightRoleDamageSttInfo> RoleDamageSttInfos { get; } = [];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public GridFightLevelComponent(GridFightInstance inst) : base(inst)
|
||||
{
|
||||
// TODO: randomly select a base route id
|
||||
List<uint> chapterIds = [1100];
|
||||
List<GridFightCampExcel> campPool = GameData.GridFightCampData.Values.ToList();
|
||||
List<GridFightCampExcel> campPool = GameData.GridFightCampData.Values.Where(x => x.BossBattleArea != 0).ToList();
|
||||
foreach (var chapterId in Enumerable.Range(1, 3))
|
||||
{
|
||||
var chapters = chapterIds.Count >= chapterId
|
||||
@@ -34,11 +40,16 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
|
||||
var camp = campPool.RandomElement(); // cannot the same
|
||||
campPool.Remove(camp);
|
||||
|
||||
// create section infos
|
||||
Sections[(uint)chapterId] = [..select.Values.Select(x => new GridFightGameSectionInfo(x, camp))];
|
||||
Sections[(uint)chapterId] = [.. select.Values.Select(x => new GridFightGameSectionInfo(x, camp))];
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stt
|
||||
|
||||
public async ValueTask<(Retcode, GridFightRoleDamageSttInfo?)> AddRoleDamageStt(uint roleId, double damage, bool sendPacket = true)
|
||||
{
|
||||
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
||||
@@ -84,6 +95,10 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
return (Retcode.RetSucc, res);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Actions
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> EnterNextSection(bool sendPacket = true)
|
||||
{
|
||||
// if last section of chapter
|
||||
@@ -104,6 +119,8 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
}
|
||||
|
||||
List<BaseGridFightSyncData> syncs = [new GridFightLevelSyncData(GridFightSrc.KGridFightSrcBattleEnd, this)];
|
||||
//await Inst.RollPortalBuff();
|
||||
|
||||
if (sendPacket)
|
||||
{
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
|
||||
@@ -112,6 +129,10 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
return syncs;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Information
|
||||
|
||||
public List<GridFightMonsterInfo> GetBossMonsters()
|
||||
{
|
||||
// get every chapter last section camp
|
||||
@@ -135,6 +156,10 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
return bosses;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialization
|
||||
|
||||
public override GridFightGameInfo ToProto()
|
||||
{
|
||||
return new GridFightGameInfo
|
||||
@@ -182,6 +207,8 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
RoleDamageSttList = { RoleDamageSttInfos.Select(x => x.ToProto()) }
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class GridFightRoleDamageSttInfo
|
||||
@@ -252,18 +279,54 @@ public class GridFightGameEncounterInfo
|
||||
EncounterDifficulty = difficulty;
|
||||
ParentSection = section;
|
||||
|
||||
if (ParentSection.Excel.NodeType != GridFightNodeTypeEnum.Monster) return;
|
||||
if (ParentSection.Excel.NodeType is not GridFightNodeTypeEnum.Monster and not GridFightNodeTypeEnum.CampMonster
|
||||
and not GridFightNodeTypeEnum.Boss and not GridFightNodeTypeEnum.EliteBranch) return;
|
||||
|
||||
var monsterPool = ParentSection.MonsterCamp.Monsters.Where(x => x.MonsterTier <= 3).OrderBy(_ => Guid.NewGuid()).ToList();
|
||||
|
||||
List<GridFightMonsterExcel> monsters = [];
|
||||
|
||||
foreach (var _ in Enumerable.Range(0, Random.Shared.Next(1, 5)))
|
||||
var waveNum = ParentSection.Excel.NodeType switch
|
||||
{
|
||||
monsters.Add(monsterPool.RandomElement());
|
||||
}
|
||||
GridFightNodeTypeEnum.Boss => 2,
|
||||
GridFightNodeTypeEnum.EliteBranch => 2,
|
||||
_ => 1
|
||||
};
|
||||
|
||||
MonsterWaves.Add(new GridFightGameMonsterWaveInfo(1, monsters, ParentSection.MonsterCamp.ID));
|
||||
List<int> monsterNum = ParentSection.Excel.NodeType switch
|
||||
{
|
||||
GridFightNodeTypeEnum.Boss => [Random.Shared.Next(3, 5), 1],
|
||||
GridFightNodeTypeEnum.EliteBranch => [Random.Shared.Next(3, 5), 3],
|
||||
GridFightNodeTypeEnum.CampMonster => [3],
|
||||
_ => [Random.Shared.Next(3, 5)]
|
||||
};
|
||||
|
||||
var monsterPool = ParentSection.MonsterCamp.Monsters.Where(x => x.MonsterTier <= 2).OrderBy(_ => Guid.NewGuid()).ToList();
|
||||
var monster4Pool = ParentSection.MonsterCamp.Monsters.Where(x => x.MonsterTier is 4 or 3).OrderBy(_ => Guid.NewGuid()).ToList();
|
||||
var monster5Pool = ParentSection.MonsterCamp.Monsters.Where(x => x.MonsterTier == 5).OrderBy(_ => Guid.NewGuid()).ToList();
|
||||
for (var i = 0; i < waveNum; i++)
|
||||
{
|
||||
if (i < waveNum - 1 || ParentSection.Excel.NodeType is GridFightNodeTypeEnum.Monster)
|
||||
{
|
||||
// no elite
|
||||
var res = monsterPool.OrderBy(_ => Guid.NewGuid()).Take(monsterNum[i]).ToList();
|
||||
MonsterWaves.Add(new GridFightGameMonsterWaveInfo((uint)(i + 1), res, ParentSection.MonsterCamp.ID));
|
||||
}
|
||||
else
|
||||
{
|
||||
var elite = ParentSection.Excel.NodeType switch
|
||||
{
|
||||
GridFightNodeTypeEnum.Boss => monster5Pool.RandomElement(),
|
||||
_ => monster4Pool.RandomElement(),
|
||||
};
|
||||
|
||||
List<GridFightMonsterExcel> monsters = [elite];
|
||||
var remain = monsterNum[i] - 1;
|
||||
|
||||
if (remain > 0)
|
||||
{
|
||||
monsters.AddRange(monsterPool.OrderBy(_ => Guid.NewGuid()).Take(remain).ToList());
|
||||
}
|
||||
|
||||
MonsterWaves.Add(new GridFightGameMonsterWaveInfo((uint)(i + 1), monsters, ParentSection.MonsterCamp.ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public uint EncounterIndex { get; set; }
|
||||
|
||||
@@ -11,7 +11,8 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
{
|
||||
public GridFightAvatarInfoPb Data { get; set; } = new();
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> AddAvatar(uint roleId, uint tier = 1, bool sendPacket = true)
|
||||
public async ValueTask<List<BaseGridFightSyncData>> AddAvatar(uint roleId, uint tier = 1, bool sendPacket = true,
|
||||
bool checkMerge = true, GridFightSrc src = GridFightSrc.KGridFightSrcBuyGoods)
|
||||
{
|
||||
var pos = 1u;
|
||||
// get first empty pos
|
||||
@@ -25,7 +26,7 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
|
||||
var info = new GridFightRoleInfoPb
|
||||
{
|
||||
RoleId = roleId,
|
||||
RoleId = roleId,
|
||||
UniqueId = ++Data.CurUniqueId,
|
||||
Tier = tier,
|
||||
Pos = pos
|
||||
@@ -33,7 +34,14 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
|
||||
Data.Roles.Add(info);
|
||||
|
||||
List<BaseGridFightSyncData> syncs = [new GridFightRoleAddSyncData(GridFightSrc.KGridFightSrcBuyGoods, info)];
|
||||
List<BaseGridFightSyncData> syncs = [new GridFightRoleAddSyncData(src, info)];
|
||||
|
||||
if (checkMerge)
|
||||
{
|
||||
var mergeSyncs = await CheckIfMergeRole();
|
||||
syncs.AddRange(mergeSyncs);
|
||||
}
|
||||
|
||||
if (sendPacket)
|
||||
{
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
|
||||
@@ -42,6 +50,58 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
return syncs;
|
||||
}
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> CheckIfMergeRole(bool sendPacket = false)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
bool hasMerged;
|
||||
|
||||
do
|
||||
{
|
||||
hasMerged = false;
|
||||
|
||||
// group roles by RoleId and Tier, then filter groups with 3 or more roles
|
||||
var mergeCandidates = Data.Roles
|
||||
.GroupBy(r => new { r.RoleId, r.Tier })
|
||||
.Where(g => g.Count() >= 3)
|
||||
.Where(g =>
|
||||
{
|
||||
// check if next tier exists
|
||||
var nextTierKey = g.Key.RoleId << 4 | (g.Key.Tier + 1);
|
||||
return GameData.GridFightRoleStarData.ContainsKey(nextTierKey);
|
||||
})
|
||||
.OrderBy(g => g.Key.RoleId)
|
||||
.ThenBy(g => g.Key.Tier)
|
||||
.FirstOrDefault(); // process one group at a time to handle continuous merging
|
||||
|
||||
if (mergeCandidates != null)
|
||||
{
|
||||
var roleId = mergeCandidates.Key.RoleId;
|
||||
var currentTier = mergeCandidates.Key.Tier;
|
||||
var toMerge = mergeCandidates.Take(3).ToList();
|
||||
|
||||
// remove merged roles
|
||||
foreach (var role in toMerge)
|
||||
{
|
||||
Data.Roles.Remove(role);
|
||||
syncs.Add(new GridFightRoleRemoveSyncData(GridFightSrc.KGridFightSrcMergeRole, role));
|
||||
}
|
||||
|
||||
// add new merged role with tier + 1
|
||||
var addSyncs = await AddAvatar(roleId, currentTier + 1, false, false, GridFightSrc.KGridFightSrcMergeRole);
|
||||
syncs.AddRange(addSyncs);
|
||||
|
||||
hasMerged = true;
|
||||
}
|
||||
} while (hasMerged); // continue until no more merges are possible
|
||||
|
||||
if (sendPacket && syncs.Count > 0)
|
||||
{
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
|
||||
}
|
||||
|
||||
return syncs;
|
||||
}
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> SellAvatar(uint uniqueId, bool sendPacket = true)
|
||||
{
|
||||
var role = Data.Roles.FirstOrDefault(x => x.UniqueId == uniqueId);
|
||||
@@ -77,7 +137,34 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
|
||||
public List<BaseAvatarInfo> GetForegroundAvatarInfos(uint maxAvatarNum)
|
||||
{
|
||||
var foreground = Data.Roles.Where(x => x.Pos <= maxAvatarNum).OrderBy(x => x.Pos).ToList();
|
||||
var foreground = Data.Roles.Where(x => x.Pos <= 4).OrderBy(x => x.Pos).ToList();
|
||||
List<BaseAvatarInfo> res = [];
|
||||
|
||||
foreach (var role in foreground)
|
||||
{
|
||||
var excel = GameData.GridFightRoleBasicInfoData[role.RoleId];
|
||||
// get formal or special
|
||||
var formal = Inst.Player.AvatarManager!.GetFormalAvatar((int)excel.AvatarID);
|
||||
if (formal != null)
|
||||
{
|
||||
res.Add(formal);
|
||||
}
|
||||
else
|
||||
{
|
||||
var special = Inst.Player.AvatarManager.GetTrialAvatar((int)excel.SpecialAvatarID);
|
||||
if (special != null)
|
||||
{
|
||||
res.Add(special);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<BaseAvatarInfo> GetBackgroundAvatarInfos(uint maxAvatarNum)
|
||||
{
|
||||
var foreground = Data.Roles.Where(x => x.Pos <= maxAvatarNum && x.Pos > 4).OrderBy(x => x.Pos).ToList();
|
||||
List<BaseAvatarInfo> res = [];
|
||||
|
||||
foreach (var role in foreground)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.Battle;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
@@ -18,7 +19,9 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
|
||||
public BattleInstance? StartBattle()
|
||||
{
|
||||
return Player.BattleManager!.StartGridFightBattle(this);
|
||||
var battle = Player.BattleManager!.StartGridFightBattle(this);
|
||||
|
||||
return battle;
|
||||
}
|
||||
|
||||
public async ValueTask EndBattle(BattleInstance battle, PVEBattleResultCsReq req)
|
||||
@@ -32,7 +35,7 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
var prevData = basicComp.Data.Clone();
|
||||
|
||||
var expNum = 5u;
|
||||
var baseCoin = 3u;
|
||||
var baseCoin = levelComp.CurrentSection.Excel.BasicGoldRewardNum;
|
||||
var interestCoin = basicComp.Data.CurGold / 10;
|
||||
|
||||
if (battle.BattleEndStatus == BattleEndStatus.BattleEndWin)
|
||||
@@ -89,8 +92,10 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
Components.Add(new GridFightLevelComponent(this));
|
||||
Components.Add(new GridFightRoleComponent(this));
|
||||
|
||||
_ = GetComponent<GridFightRoleComponent>().AddAvatar(1414, 3, false); // TODO test
|
||||
_ = GetComponent<GridFightRoleComponent>().AddAvatar(1414, 3, false);
|
||||
_ = GetComponent<GridFightShopComponent>().RefreshShop(true, false);
|
||||
|
||||
// _ = CreatePendingAction<GridFightAugmentPendingAction>(); // TODO wait for release official server
|
||||
}
|
||||
|
||||
public T GetComponent<T>() where T : BaseGridFightComponent
|
||||
@@ -106,7 +111,7 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
Season = Season,
|
||||
IsOverlock = IsOverLock,
|
||||
UniqueId = UniqueId,
|
||||
PendingAction = new GridFightPendingAction(),
|
||||
PendingAction = GetCurAction().ToProto(),
|
||||
GridFightGameData = ToGameDataInfo(),
|
||||
RogueCurrentGameInfo = { ToGameInfos() }
|
||||
};
|
||||
@@ -121,4 +126,89 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
{
|
||||
return new GridFightGameData();
|
||||
}
|
||||
|
||||
#region Pending Action
|
||||
|
||||
public SortedDictionary<uint, BaseGridFightPendingAction> PendingActions { get; set; } = new();
|
||||
private uint _curQueuePos = 1;
|
||||
|
||||
public BaseGridFightPendingAction GetCurAction()
|
||||
{
|
||||
if (PendingActions.Count > 0)
|
||||
{
|
||||
return PendingActions.First().Value;
|
||||
}
|
||||
|
||||
return new GridFightEmptyPendingAction(this);
|
||||
}
|
||||
|
||||
public uint AddPendingAction(BaseGridFightPendingAction action)
|
||||
{
|
||||
var pos = _curQueuePos++;
|
||||
|
||||
action.QueuePosition = pos;
|
||||
PendingActions[pos] = action;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
public async ValueTask CreatePendingAction<T>(GridFightSrc src = GridFightSrc.KGridFightSrcEnterNode, bool sendPacket = true) where T: BaseGridFightPendingAction
|
||||
{
|
||||
var action = (T)Activator.CreateInstance(typeof(T), this)!;
|
||||
|
||||
AddPendingAction(action);
|
||||
|
||||
if (sendPacket)
|
||||
await Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(
|
||||
new GridFightPendingActionSyncData(src, action)));
|
||||
}
|
||||
|
||||
public async ValueTask HandleResultRequest(GridFightHandlePendingActionCsReq req)
|
||||
{
|
||||
var curAction = GetCurAction();
|
||||
|
||||
switch (req.GridFightActionTypeCase)
|
||||
{
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.PortalBuffAction:
|
||||
break;
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.PortalBuffRerollAction:
|
||||
if (curAction is GridFightPortalBuffPendingAction portalBuffAction)
|
||||
{
|
||||
await portalBuffAction.RerollBuff();
|
||||
}
|
||||
|
||||
break;
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.AugmentAction:
|
||||
break;
|
||||
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.RerollAugmentAction:
|
||||
if (curAction is GridFightAugmentPendingAction augmentAction)
|
||||
{
|
||||
await augmentAction.RerollAugment(req.RerollAugmentAction.AugmentId);
|
||||
}
|
||||
|
||||
break;
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.EliteAction:
|
||||
break;
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.SupplyAction:
|
||||
break;
|
||||
}
|
||||
|
||||
// end
|
||||
PendingActions.Remove(curAction.QueuePosition);
|
||||
|
||||
await Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(
|
||||
new GridFightPendingActionSyncData(GridFightSrc.KGridFightSrcNone, GetCurAction())));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Portal Buff
|
||||
|
||||
public async ValueTask AddPortalBuff(uint portalBuffId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public abstract class BaseGridFightPendingAction(GridFightInstance inst)
|
||||
{
|
||||
public GridFightInstance Inst { get; set; } = inst;
|
||||
public uint QueuePosition { get; set; }
|
||||
public abstract GridFightPendingAction ToProto();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
using EggLink.DanhengServer.Util;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightAugmentPendingAction : BaseGridFightPendingAction
|
||||
{
|
||||
public List<GridFightAugmentSelectUnit> Augments { get; set; } = [];
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
QueuePosition = QueuePosition,
|
||||
AugmentAction = new GridFightAugmentActionInfo
|
||||
{
|
||||
PendingAugmentInfoList = { Augments.Select(x => x.ToProto()) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public GridFightAugmentPendingAction(GridFightInstance inst) : base(inst)
|
||||
{
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var augmentId = GameData.GridFightAugmentData.Keys.Where(x => Augments.All(c => c.AugmentId != x)).ToList()
|
||||
.RandomElement();
|
||||
|
||||
Augments.Add(new GridFightAugmentSelectUnit
|
||||
{
|
||||
AugmentId = augmentId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask RerollAugment(uint augmentId)
|
||||
{
|
||||
var augment = Augments.FirstOrDefault(x => x.AugmentId == augmentId);
|
||||
if (augment == null) return;
|
||||
|
||||
if (augment.CurRerollNum >= augment.MaxRerollNum)
|
||||
return;
|
||||
|
||||
var newAugmentId = GameData.GridFightAugmentData.Keys.Where(x => Augments.All(c => c.AugmentId != x)).ToList();
|
||||
augment.AugmentId = newAugmentId.RandomElement();
|
||||
|
||||
augment.CurRerollNum++;
|
||||
|
||||
// sync
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(
|
||||
new GridFightPendingActionSyncData(GridFightSrc.KGridFightSrcNone, this)));
|
||||
}
|
||||
}
|
||||
|
||||
public class GridFightAugmentSelectUnit
|
||||
{
|
||||
public uint AugmentId { get; set; }
|
||||
public uint MaxRerollNum { get; set; } = 2;
|
||||
public uint CurRerollNum { get; set; }
|
||||
|
||||
public GridFightPendingAugmentInfo ToProto()
|
||||
{
|
||||
return new GridFightPendingAugmentInfo
|
||||
{
|
||||
AugmentId = AugmentId,
|
||||
AugmentCurRerollCount = CurRerollNum,
|
||||
AugmentMaxRerollCount = MaxRerollNum
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightEliteBranchPendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
EliteBranchAction = new GridFightEliteBranchActionInfo()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightElitePendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
EliteAction = new GridFightEliteActionInfo()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightEmptyPendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightPortalBuffPendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public uint MaxRerollCount { get; set; } = 2;
|
||||
public uint CurRerollCount { get; set; }
|
||||
|
||||
public async ValueTask RerollBuff()
|
||||
{
|
||||
if (MaxRerollCount <= CurRerollCount )
|
||||
return;
|
||||
|
||||
CurRerollCount++;
|
||||
PortalBuffList = GameData.GridFightPortalBuffData.Keys.OrderBy(_ => Guid.NewGuid()).Take(3).ToList();
|
||||
|
||||
// sync
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(
|
||||
new GridFightPendingActionSyncData(GridFightSrc.KGridFightSrcNone, this)));
|
||||
}
|
||||
|
||||
public List<uint> PortalBuffList { get; set; } = GameData.GridFightPortalBuffData.Keys.OrderBy(_ => Guid.NewGuid()).Take(3).ToList();
|
||||
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
PortalBuffAction = new GridFightPortalBuffActionInfo
|
||||
{
|
||||
GridFightPortalBuffList = { PortalBuffList },
|
||||
MaxRerollCount = MaxRerollCount,
|
||||
CurRollCount = CurRerollCount
|
||||
},
|
||||
QueuePosition = QueuePosition
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
|
||||
|
||||
public class GridFightPendingActionSyncData(GridFightSrc src, BaseGridFightPendingAction action) : BaseGridFightSyncData(src)
|
||||
{
|
||||
public override GridFightSyncData ToProto()
|
||||
{
|
||||
return new GridFightSyncData
|
||||
{
|
||||
PendingAction = action.ToProto()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
using EggLink.DanhengServer.Kcp;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.GridFight;
|
||||
|
||||
[Opcode(CmdIds.GridFightHandlePendingActionCsReq)]
|
||||
public class HandlerGridFightHandlePendingActionCsReq : Handler
|
||||
{
|
||||
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
|
||||
{
|
||||
var req = GridFightHandlePendingActionCsReq.Parser.ParseFrom(data);
|
||||
|
||||
var inst = connection.Player!.GridFightManager!.GridFightInstance;
|
||||
if (inst != null)
|
||||
await inst.HandleResultRequest(req);
|
||||
|
||||
await connection.SendPacket(new PacketGridFightHandlePendingActionScRsp(req.QueuePosition));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using EggLink.DanhengServer.Kcp;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
|
||||
public class PacketGridFightHandlePendingActionScRsp : BasePacket
|
||||
{
|
||||
public PacketGridFightHandlePendingActionScRsp(uint pos) : base(CmdIds.GridFightHandlePendingActionScRsp)
|
||||
{
|
||||
var proto = new GridFightHandlePendingActionScRsp
|
||||
{
|
||||
QueuePosition = pos
|
||||
};
|
||||
|
||||
SetData(proto);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user