fix: grid fight settle & trait effect

This commit is contained in:
Somebody
2025-11-30 12:31:30 +08:00
parent 148c2c91fe
commit 0868d17595
19 changed files with 635 additions and 100 deletions

View File

@@ -155,5 +155,32 @@ public class CommandGrid : ICommand
await arg.SendMsg(I18NManager.Translate("Game.Command.Grid.AddConsumable", consumableId.ToString()));
}
[CommandMethod("section")]
public async ValueTask SetSection(CommandArg arg)
{
if (arg.Target == null)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.PlayerNotFound"));
return;
}
var inst = arg.Target.Player!.GridFightManager?.GridFightInstance;
if (inst == null)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Grid.NotInGame"));
return;
}
if (arg.BasicArgs.Count < 2)
{
await arg.SendMsg(I18NManager.Translate("Game.Command.Notice.InvalidArguments"));
return;
}
var chapterId = (uint)arg.GetInt(0);
var sectionId = (uint)arg.GetInt(1);
await inst.GetComponent<GridFightLevelComponent>().EnterSection(chapterId, sectionId, true, GridFightSrc.KGridFightSrcNone);
await arg.SendMsg(I18NManager.Translate("Game.Command.Grid.EnterSection", chapterId.ToString(), sectionId.ToString()));
}
}

View File

@@ -0,0 +1,23 @@
using EggLink.DanhengServer.Enums.GridFight;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace EggLink.DanhengServer.Data.Excel;
[ResourceEntity("GridFightTraitEffect.json")]
public class GridFightTraitEffectExcel : ExcelResource
{
public uint ID { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public GridFightTraitEffectTypeEnum TraitEffectType { get; set; }
public override int GetId()
{
return (int)ID;
}
public override void Loaded()
{
GameData.GridFightTraitEffectData.TryAdd(ID, this);
}
}

View File

@@ -0,0 +1,22 @@
using EggLink.DanhengServer.Data.Config;
namespace EggLink.DanhengServer.Data.Excel;
[ResourceEntity("GridFightTraitEffectLayerPa.json")]
public class GridFightTraitEffectLayerPaExcel : ExcelResource
{
public uint ID { get; set; }
public uint Layer { get; set; }
public List<FixedValueInfo<double>> EffectParamList { get; set; } = [];
public override int GetId()
{
return (int)ID;
}
public override void Loaded()
{
GameData.GridFightTraitEffectLayerPaData.TryAdd(ID, []);
GameData.GridFightTraitEffectLayerPaData[ID][Layer] = this;
}
}

View File

@@ -128,6 +128,7 @@ public static class GameData
public static Dictionary<uint, GridFightDivisionInfoExcel> GridFightDivisionInfoData { get; private set; } = [];
public static Dictionary<uint, GridFightDivisionStageExcel> GridFightDivisionStageData { get; private set; } = [];
public static Dictionary<uint, GridFightEquipmentExcel> GridFightEquipmentData { get; private set; } = [];
public static Dictionary<uint, GridFightTraitEffectExcel> GridFightTraitEffectData { get; private set; } = [];
public static Dictionary<uint, GridFightEquipUpgradeExcel> GridFightEquipUpgradeData { get; private set; } = [];
public static Dictionary<uint, GridFightConsumablesExcel> GridFightConsumablesData { get; private set; } = [];
public static Dictionary<uint, GridFightCampExcel> GridFightCampData { get; private set; } = [];
@@ -143,6 +144,7 @@ public static class GameData
public static Dictionary<uint, GridFightTalentExcel> GridFightTalentData { get; private set; } = [];
public static Dictionary<uint, GridFightTraitBasicInfoExcel> GridFightTraitBasicInfoData { get; private set; } = [];
public static Dictionary<uint, Dictionary<uint, GridFightTraitLayerExcel>> GridFightTraitLayerData { get; private set; } = [];
public static Dictionary<uint, Dictionary<uint, GridFightTraitEffectLayerPaExcel>> GridFightTraitEffectLayerPaData { get; private set; } = [];
public static Dictionary<uint, GridFightSeasonTalentExcel> GridFightSeasonTalentData { get; private set; } = [];
public static Dictionary<uint, Dictionary<uint, GridFightStageRouteExcel>> GridFightStageRouteData { get; private set; } = [];
public static Dictionary<uint, GridFightNodeTemplateExcel> GridFightNodeTemplateData { get; private set; } = [];

View File

@@ -0,0 +1,17 @@
namespace EggLink.DanhengServer.Enums.GridFight;
public enum GridFightTraitEffectTypeEnum
{
None = 0,
TempEquip = 1,
TraitBonus = 2,
Bonus = 3,
MazeBuffEnhance = 4,
CoreRoleChoose = 5,
SPSlot = 6,
CoreRoleByEquipNum = 7,
TraitEffectByJson = 8,
SelectEnhance = 9,
GainFrontTrait = 10,
BackStrengthenFront = 11
}

View File

@@ -82,6 +82,13 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
battle.BattleEvents.TryAdd((int)roleConf.BEID, new BattleEventInstance((int)roleConf.BEID, 5000));
}
foreach (var traitBeId in TraitComponent.Data.Traits
.Select(x => GameData.GridFightTraitBasicInfoData.GetValueOrDefault(x.TraitId, new()))
.SelectMany(x => x.BEIDList))
{
battle.BattleEvents.TryAdd((int)traitBeId, new BattleEventInstance((int)traitBeId, 5000));
}
var ruleId = CurSection.Excel.PenaltyBonusRuleIDList.FirstOrDefault(0u);
if (ruleId == 0)
{

View File

@@ -36,7 +36,7 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
return (info, [syncData]);
}
public async ValueTask<List<BaseGridFightSyncData>> UpdateConsumable(uint consumableId, int count, GridFightSrc src = GridFightSrc.KGridFightSrcNone, bool sendPacket = true, params uint[] param)
public async ValueTask<List<BaseGridFightSyncData>> UpdateConsumable(uint consumableId, int count, GridFightSrc src = GridFightSrc.KGridFightSrcNone, bool sendPacket = true, uint groupId = 0, params uint[] param)
{
if (!GameData.GridFightConsumablesData.ContainsKey(consumableId) || count == 0)
return [];
@@ -198,7 +198,7 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
// consumable or equipment
if (GameData.GridFightConsumablesData.ContainsKey(item.DropItemId))
{
syncs.AddRange(await UpdateConsumable(item.DropItemId, (int)item.Num, src, false, param));
syncs.AddRange(await UpdateConsumable(item.DropItemId, (int)item.Num, src, false, 0, param));
}
else if (GameData.GridFightEquipmentData.ContainsKey(item.DropItemId))
{
@@ -242,7 +242,7 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
List<BaseGridFightSyncData> syncs = [];
if (consumablesExcel.IfConsume)
{
syncs.AddRange(await UpdateConsumable(itemId, -1, GridFightSrc.KGridFightSrcUseConsumable, false, item.ItemId));
syncs.AddRange(await UpdateConsumable(itemId, -1, GridFightSrc.KGridFightSrcUseConsumable, false, 0, item.ItemId));
}
(Retcode, List<BaseGridFightSyncData>) res = consumablesExcel.ConsumableRule switch

View File

@@ -32,22 +32,19 @@ public class GridFightLevelComponent : BaseGridFightComponent
// TODO: randomly select a base route id
List<uint> chapterIds = [1100];
List<GridFightCampExcel> campPool = GameData.GridFightCampData.Values.Where(x => x.BossBattleArea != 0).ToList();
var route = GameData.GridFightStageRouteData[chapterIds.RandomElement()].Values;
foreach (var chapterId in Enumerable.Range(1, 3))
{
var chapters = chapterIds.Count >= chapterId
? [GameData.GridFightStageRouteData[chapterIds[chapterId - 1]]]
: GameData.GridFightStageRouteData.Values.Where(x => x.Any(j => j.Value.ChapterID == chapterId))
.ToList();
var chapters = route.Where(x => x.ChapterID == chapterId).ToList();
if (chapters.Count == 0)
continue;
var select = chapters.RandomElement();
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] = [.. chapters.Select(x => new GridFightGameSectionInfo(x, camp))];
}
if (!GameData.GridFightDivisionStageData.TryGetValue(Inst.DivisionId, out var divisionExcel)) return;
@@ -149,26 +146,20 @@ public class GridFightLevelComponent : BaseGridFightComponent
#region Actions
public async ValueTask<List<BaseGridFightSyncData>> EnterNextSection(bool sendPacket = true, GridFightSrc src = GridFightSrc.KGridFightSrcBattleEnd)
public bool IsLastSection()
{
if (_curSectionId < Sections[_curChapterId].Count) return false;
return _curChapterId >= Sections.Count; // end of game
}
public async ValueTask<List<BaseGridFightSyncData>> EnterSection(uint chapterId, uint sectionId,
bool sendPacket = true, GridFightSrc src = GridFightSrc.KGridFightSrcBattleEnd)
{
var shopComp = Inst.GetComponent<GridFightShopComponent>();
var basicComp = Inst.GetComponent<GridFightBasicComponent>();
// if last section of chapter
if (_curSectionId >= Sections[_curChapterId].Count)
{
if (_curChapterId >= Sections.Count)
{
// end of game
return [];
}
_curChapterId++;
_curSectionId = 1;
}
else
{
_curSectionId++;
}
_curChapterId = (uint)Math.Min(Sections.Count, chapterId);
_curSectionId = (uint)Math.Min(Sections[_curChapterId].Count, sectionId);
List<BaseGridFightSyncData> syncs = [new GridFightLevelSyncData(src, this)];
@@ -204,6 +195,28 @@ public class GridFightLevelComponent : BaseGridFightComponent
return syncs;
}
public async ValueTask<List<BaseGridFightSyncData>> EnterNextSection(bool sendPacket = true, GridFightSrc src = GridFightSrc.KGridFightSrcBattleEnd)
{
// if last section of chapter
if (_curSectionId >= Sections[_curChapterId].Count)
{
if (_curChapterId >= Sections.Count)
{
// end of game
return [];
}
_curChapterId++;
_curSectionId = 1;
}
else
{
_curSectionId++;
}
return await EnterSection(_curChapterId, _curSectionId, sendPacket, src);
}
public async ValueTask<List<BaseGridFightSyncData>> AddPortalBuff(uint portalBuffId, bool sendPacket = true, GridFightSrc src = GridFightSrc.KGridFightSrcSelectPortalBuff)
{
var info = new GridFightPortalBuffInfo

View File

@@ -73,8 +73,9 @@ public class GridFightOrbComponent(GridFightInstance inst) : BaseGridFightCompon
{
case GridFightOrbTypeEnum.White:
{
// 2 coin or 3 exp
if (Random.Shared.Next(2) == 0)
// 2 coin or 3 exp or 1 consumable
var ran = Random.Shared.Next(3);
if (ran == 0)
{
await basicComp.UpdateGoldNum(2, false, GridFightSrc.KGridFightSrcUseOrb);
syncDatas.Add(new GridFightGoldSyncData(GridFightSrc.KGridFightSrcUseOrb, basicComp.Data.Clone(),
@@ -86,7 +87,7 @@ public class GridFightOrbComponent(GridFightInstance inst) : BaseGridFightCompon
Num = 2
});
}
else
else if (ran == 1)
{
await basicComp.AddLevelExp(3, false);
syncDatas.Add(new GridFightPlayerLevelSyncData(GridFightSrc.KGridFightSrcUseOrb,
@@ -98,6 +99,23 @@ public class GridFightOrbComponent(GridFightInstance inst) : BaseGridFightCompon
Num = 3
});
}
else
{
// random consumable
var consumable =
GameData.GridFightConsumablesData.Values.Where(x =>
x.ConsumableRule != GridFightConsumeTypeEnum.Remove).ToList().RandomElement();
var res = await itemsComp.UpdateConsumable(consumable.ID, 1, GridFightSrc.KGridFightSrcUseOrb, false, groupId);
syncDatas.AddRange(res);
dropItems.Add(new GridFightDropItemInfo
{
DropItemId = consumable.ID,
DropType = GridFightDropType.Item,
Num = 1
});
}
break;
}

View File

@@ -73,7 +73,7 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
}
Inst.GetComponent<GridFightTraitComponent>().CheckTrait();
await Inst.GetComponent<GridFightTraitComponent>().CheckTrait();
return syncs;
}
@@ -162,7 +162,7 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
}
Inst.GetComponent<GridFightTraitComponent>().CheckTrait();
await Inst.GetComponent<GridFightTraitComponent>().CheckTrait();
return syncs;
}
@@ -278,7 +278,7 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
}
Inst.GetComponent<GridFightTraitComponent>().CheckTrait();
await Inst.GetComponent<GridFightTraitComponent>().CheckTrait();
return Retcode.RetSucc;
}

View File

@@ -1,4 +1,8 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Enums.GridFight;
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;
using EggLink.DanhengServer.Proto.ServerSide;
@@ -8,11 +12,12 @@ public class GridFightTraitComponent(GridFightInstance inst) : BaseGridFightComp
{
public GridFightTraitInfoPb Data { get; set; } = new();
public void CheckTrait()
public async ValueTask CheckTrait()
{
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
Dictionary<uint, uint> traitCount = [];
List<BaseGridFightSyncData> syncList = [];
foreach (var traitId in GameData.GridFightTraitBasicInfoData.Keys)
{
@@ -44,26 +49,142 @@ public class GridFightTraitComponent(GridFightInstance inst) : BaseGridFightComp
if (existingTrait != null)
{
var prevLayer = existingTrait.TraitLayer;
existingTrait.TraitLayer = layer;
if (prevLayer != layer)
{
// Sync effects
foreach (var effect in existingTrait.Effects)
{
if (effect.HasCoreRoleUniqueId)
effect.CoreRoleUniqueId = 0;
syncList.Add(new GridFightTraitSyncData(GridFightSrc.KGridFightSrcTraitEffectUpdate, effect, 0,
traitId, effect.EffectId));
var effectSyncs = await HandleTraitEffect(effect, prevLayer, layer);
syncList.AddRange(effectSyncs);
}
}
}
else
{
if (layer == 0) continue; // do not add if no layer
Data.Traits.Add(new GridFightGameTraitPb
var traitInfo = new GridFightGameTraitPb
{
TraitId = traitId,
TraitLayer = layer,
Effects =
TraitLayer = layer
};
foreach (var effectId in traitExcel.TraitEffectList)
{
var effect = new GridFightGameTraitEffectPb
{
traitExcel.TraitEffectList.Select(x => new GridFightGameTraitEffectPb
{
EffectId = x
})
}
});
EffectId = effectId,
TraitId = traitId
};
traitInfo.Effects.Add(effect);
var effectSyncs = await HandleTraitEffect(effect, 0, layer);
syncList.AddRange(effectSyncs);
// sync
syncList.Add(new GridFightTraitSyncData(GridFightSrc.KGridFightSrcTraitEffectUpdate, effect, 0, traitId, effectId));
}
Data.Traits.Add(traitInfo);
}
}
// Send sync data
if (syncList.Count > 0)
{
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncList));
}
}
public async ValueTask<List<BaseGridFightSyncData>> HandleTraitEffect(GridFightGameTraitEffectPb effect, uint prevLayer, uint nextLayer)
{
var itemsComp = Inst.GetComponent<GridFightItemsComponent>();
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
List<BaseGridFightSyncData> syncList = [];
if (!GameData.GridFightTraitEffectData.TryGetValue(effect.EffectId, out var traitConf) ||
!GameData.GridFightTraitEffectLayerPaData.TryGetValue(effect.EffectId, out var effectLayerPas)) return syncList;
effectLayerPas.TryGetValue(prevLayer, out var prevEffectParam);
effectLayerPas.TryGetValue(nextLayer, out var nextEffectParam);
// Handle different effect types
switch (traitConf.TraitEffectType)
{
case GridFightTraitEffectTypeEnum.TempEquip:
{
// add equip
var prev = prevEffectParam?.EffectParamList.Select(x => (uint)x.Value).ToList() ?? [];
var cur = nextEffectParam?.EffectParamList.Select(x => (uint)x.Value).ToList() ?? [];
// remove prev - cur
var toRemove = prev.Except(cur).ToList();
var toAdd = cur.Except(prev).ToList();
// remove equips
foreach (var equipId in toRemove)
{
var item = itemsComp.Data.EquipmentItems.FirstOrDefault(x => x.ItemId == equipId);
if (item == null) continue;
syncList.AddRange(await itemsComp.RemoveEquipment(item.UniqueId,
GridFightSrc.KGridFightSrcTraitEffectUpdate, false));
}
// add equips
foreach (var equipId in toAdd)
{
var res = await itemsComp.AddEquipment(equipId, GridFightSrc.KGridFightSrcTraitEffectUpdate,
false);
syncList.AddRange(res.Item2);
}
break;
}
case GridFightTraitEffectTypeEnum.TraitBonus:
{
effect.Threshold = 0; // initialize
break;
}
case GridFightTraitEffectTypeEnum.CoreRoleChoose:
{
// create pending action
syncList.AddRange(await Inst.CreatePendingAction<GridFightTraitPendingAction>(
GridFightSrc.KGridFightSrcTraitEffectUpdate,
false, effect));
break;
}
case GridFightTraitEffectTypeEnum.CoreRoleByEquipNum:
{
// check
var traitRoles = roleComp.Data.Roles.Where(x =>
GameData.GridFightRoleBasicInfoData.GetValueOrDefault(x.RoleId)?.TraitList
.Contains(effect.TraitId) == true).ToList();
var coreRole = traitRoles.MaxBy(x => x.EquipmentIds.Count);
effect.CoreRoleUniqueId = coreRole?.UniqueId ?? 0;
break;
}
case GridFightTraitEffectTypeEnum.SelectEnhance:
{
// TODO
break;
}
}
return syncList;
}
public override GridFightGameInfo ToProto()
@@ -96,6 +217,15 @@ public static class GridFightTraitInfoPbExtensions
};
}
public static GridFightTraitSyncInfo ToSyncInfo(this GridFightGameTraitEffectPb info)
{
return new GridFightTraitSyncInfo
{
TraitId = info.TraitId,
TraitEffectInfo = info.ToProto()
};
}
public static BattleGridFightTraitInfo ToBattleInfo(this GridFightGameTraitPb info, GridFightRoleComponent roleComp)
{
var traitRoles = roleComp.Data.Roles.Where(x =>
@@ -116,7 +246,7 @@ public static class GridFightTraitInfoPbExtensions
MemberRoleUniqueId = x.UniqueId,
MemberType = GridFightTraitMemberType.KGridFightTraitMemberRole
}) },
TraitEffectList = { info.Effects.Select(x => x.ToBattleInfo())}
TraitEffectList = { info.Effects.Select(x => x.ToBattleInfo(roleComp))}
};
if (phainonRole != null && traitRoles.All(x => x.UniqueId != phainonRole.UniqueId))
@@ -138,15 +268,37 @@ public static class GridFightTraitInfoPbExtensions
return new GridFightTraitEffectInfo
{
EffectId = info.EffectId,
TraitEffectLevelExp = info.Param
TraitEffectLevelExp = info.Threshold,
TraitCoreRole = info.CoreRoleUniqueId
};
}
public static BattleGridFightTraitEffectInfo ToBattleInfo(this GridFightGameTraitEffectPb info)
public static BattleGridFightTraitEffectInfo ToBattleInfo(this GridFightGameTraitEffectPb info, GridFightRoleComponent roleComp)
{
return new BattleGridFightTraitEffectInfo
var proto = new BattleGridFightTraitEffectInfo
{
EffectId = info.EffectId
};
if (info.HasCoreRoleUniqueId)
{
var role = roleComp.Data.Roles.FirstOrDefault(x => x.UniqueId == info.CoreRoleUniqueId);
if (role != null)
proto.TraitCoreRole = new BattleGridFightTraitCoreRoleInfo
{
UniqueId = role.UniqueId,
RoleBasicId = role.RoleId
};
}
if (info.HasThreshold)
{
proto.TraitEffectLevelInfo = new GridFightTraitEffectLevelInfo
{
TraitEffectLevelExp = info.Threshold
};
}
return proto;
}
}

View File

@@ -6,7 +6,6 @@ using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
using EggLink.DanhengServer.GameServer.Game.Player;
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
using EggLink.DanhengServer.Proto;
using System.Collections.Generic;
using EggLink.DanhengServer.Util;
namespace EggLink.DanhengServer.GameServer.Game.GridFight;
@@ -56,6 +55,8 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
await basicComp.UpdateLineupHp(-5, false);
}
var end = levelComp.IsLastSection();
var comboCoin = basicComp.Data.ComboNum switch
{
>= 5 => 3u,
@@ -105,6 +106,13 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
syncs.AddRange(await curEncounter.TakeEncounterDrop(itemsComponent));
await Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
if (end)
{
// settle
await Player.SendPacket(new PacketGridFightSettleNotify(this));
Player.GridFightManager!.GridFightInstance = null;
}
}
public void InitializeComponents()
@@ -151,6 +159,38 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
};
}
public GridFightFinishInfo ToFinishInfo()
{
var roleComp = GetComponent<GridFightRoleComponent>();
var levelComp = GetComponent<GridFightLevelComponent>();
var augmentComp = GetComponent<GridFightAugmentComponent>();
var itemsComp = GetComponent<GridFightItemsComponent>();
var traitComp = GetComponent<GridFightTraitComponent>();
var basicComp = GetComponent<GridFightBasicComponent>();
return new GridFightFinishInfo
{
Reason = GridFightSettleReason.KGridFightSettleReasonFinish,
SettleRoleUniqueIdList = { roleComp.Data.Roles.Where(x => x.Pos <= GridFightRoleComponent.PrepareAreaPos).Select(x => x.UniqueId) },
GridFightEquipmentList = { itemsComp.Data.EquipmentItems.Select(x => x.ToProto()) },
GridFightAugmentInfo = { augmentComp.Data.Augments.Select(x => x.ToProto()) },
SettlePortalBuffList = { levelComp.PortalBuffs.Select(x => x.ToProto()) },
TraitDamageSttList = { levelComp.TraitDamageSttInfos.Select(x => x.ToProto(traitComp)) },
RoleDamageSttList = { levelComp.RoleDamageSttInfos.Select(x => x.ToProto()) },
GridFightTraitInfo = { traitComp.Data.Traits.Select(x => x.ToProto(roleComp)) },
GridGameRoleList = { roleComp.Data.Roles.Select(x => x.ToProto()) },
RogueTournCurAreaInfo = new GridFightFinishAreaInfo
{
ChapterId = levelComp.CurrentSection.ChapterId,
GameDivisionId = DivisionId,
GridFightCurLineupHp = basicComp.Data.CurHp,
GridFightMaxLineupHp = 100,
RouteId = levelComp.CurrentSection.Excel.ID,
SectionId = levelComp.CurrentSection.SectionId
}
};
}
public List<GridFightGameInfo> ToGameInfos()
{
return (from c in Components select c.ToProto()).ToList();
@@ -158,10 +198,7 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
public GridFightGameData ToGameDataInfo()
{
return new GridFightGameData
{
GameItemInfoList = { }
};
return new GridFightGameData();
}
#region Pending Action
@@ -300,11 +337,11 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
GridFightSrc.KGridFightSrcSelectSupply, 0, 0,
req.SupplyAction.SelectSupplyIndexes.ToArray()));
// add equipment
var res = await itemsComp.AddEquipment(role.EquipmentId,
GridFightSrc.KGridFightSrcSelectSupply, false,
0, req.SupplyAction.SelectSupplyIndexes.ToArray());
syncs.AddRange(res.Item2);
// add equipment
var res = await itemsComp.AddEquipment(role.EquipmentId,
GridFightSrc.KGridFightSrcSelectSupply, false,
0, req.SupplyAction.SelectSupplyIndexes.ToArray());
syncs.AddRange(res.Item2);
}
}
@@ -316,9 +353,22 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
{
var target = req.RecommendEquipmentAction.SelectEquipmentId;
var res = await itemsComp.AddEquipment(target, GridFightSrc.KGridFightSrcNone, false, 0);
var res = await itemsComp.AddEquipment(target, GridFightSrc.KGridFightSrcNone, false);
syncs.AddRange(res.Item2);
break;
}
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.TraitAction:
{
if (curAction is GridFightTraitPendingAction traitAction)
{
traitAction.Effect.CoreRoleUniqueId = req.TraitAction.UniqueId;
// sync
syncs.Add(new GridFightTraitSyncData(GridFightSrc.KGridFightSrcTraitEffectUpdate,
traitAction.Effect, 0, traitAction.Effect.TraitId, traitAction.Effect.EffectId));
}
break;
}
}
@@ -326,7 +376,8 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
if (isFinish)
{
PendingActions.Remove(curAction.QueuePosition);
syncs.Add(new GridFightFinishPendingActionSyncData(GridFightSrc.KGridFightSrcNone, curAction.QueuePosition));
syncs.Add(new GridFightFinishPendingActionSyncData(GridFightSrc.KGridFightSrcNone,
curAction.QueuePosition));
// unlock
basicComp.Data.LockReason = (uint)GridFightLockReason.KGridFightLockReasonUnknown;

View File

@@ -30,7 +30,6 @@ public class GridFightManager(PlayerInstance player) : BasePlayerManager(player)
#endregion
#region Serialization
public GridFightQueryInfo ToProto()

View File

@@ -0,0 +1,21 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Proto.ServerSide;
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
public class GridFightTraitPendingAction(GridFightInstance inst, GridFightGameTraitEffectPb effect) : BaseGridFightPendingAction(inst)
{
public GridFightGameTraitEffectPb Effect { get; set; } = effect;
public override GridFightPendingAction ToProto()
{
return new GridFightPendingAction
{
QueuePosition = QueuePosition,
TraitAction = new GridFightTraitActionInfo
{
EffectId = Effect.EffectId,
TraitId = Effect.TraitId
}
};
}
}

View File

@@ -0,0 +1,16 @@
using EggLink.DanhengServer.GameServer.Game.GridFight.Component;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Proto.ServerSide;
namespace EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
public class GridFightTraitSyncData(GridFightSrc src, GridFightGameTraitEffectPb trait, uint groupId = 0, params uint[] syncParams) : BaseGridFightSyncData(src, groupId, syncParams)
{
public override GridFightSyncData ToProto()
{
return new GridFightSyncData
{
TraitSyncInfo = trait.ToSyncInfo()
};
}
}

View File

@@ -0,0 +1,41 @@
using EggLink.DanhengServer.GameServer.Game.GridFight.Component;
using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
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.GridFightTraitUpdateCsReq)]
public class HandlerGridFightTraitUpdateCsReq : Handler
{
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GridFightTraitUpdateCsReq.Parser.ParseFrom(data);
var inst = connection.Player?.GridFightManager?.GridFightInstance;
if (inst == null)
{
await connection.SendPacket(CmdIds.GridFightTraitUpdateScRsp);
return;
}
var traitComp = inst.GetComponent<GridFightTraitComponent>();
var effect = traitComp.Data.Traits.FirstOrDefault(x => x.TraitId == req.TraitId)?.Effects
.FirstOrDefault(x => x.EffectId == req.EffectId);
if (effect == null)
{
await connection.SendPacket(CmdIds.GridFightTraitUpdateScRsp);
return;
}
effect.CoreRoleUniqueId = req.TraitCoreRoleInfo.UniqueId;
// sync
await connection.SendPacket(new PacketGridFightSyncUpdateResultScNotify(
new GridFightTraitSyncData(GridFightSrc.KGridFightSrcTraitEffectUpdate, effect, 0, effect.TraitId,
effect.EffectId)));
await connection.SendPacket(CmdIds.GridFightTraitUpdateScRsp);
}
}

View File

@@ -0,0 +1,24 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.GameServer.Game.GridFight;
using EggLink.DanhengServer.Kcp;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
public class PacketGridFightSettleNotify : BasePacket
{
public PacketGridFightSettleNotify(GridFightInstance inst) : base(CmdIds.GridFightSettleNotify)
{
var divisionId = GameData.GridFightDivisionInfoData.Where(x => x.Value.SeasonID == GridFightManager.CurSeasonId)
.Select(x => x.Key).Max();
var proto = new GridFightSettleNotify
{
CurDivisionId = divisionId,
PrevDivisionId = divisionId,
TournFinishInfo = inst.ToFinishInfo()
};
SetData(proto);
}
}

View File

@@ -57,27 +57,28 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
"IAMoCzIoLkdyaWRGaWdodEdhbWVBdWdtZW50UGIuU2F2ZWRWYWx1ZXNFbnRy",
"eRoyChBTYXZlZFZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgC",
"IAEoDToCOAEiQwoWR3JpZEZpZ2h0QXVnbWVudEluZm9QYhIpCghBdWdtZW50",
"cxgBIAMoCzIXLkdyaWRGaWdodEdhbWVBdWdtZW50UGIiTgoaR3JpZEZpZ2h0",
"cxgBIAMoCzIXLkdyaWRGaWdodEdhbWVBdWdtZW50UGIifwoaR3JpZEZpZ2h0",
"R2FtZVRyYWl0RWZmZWN0UGISDwoHVHJhaXRJZBgBIAEoDRIQCghFZmZlY3RJ",
"ZBgCIAEoDRINCgVQYXJhbRgDIAEoDSJpChRHcmlkRmlnaHRHYW1lVHJhaXRQ",
"YhIPCgdUcmFpdElkGAEgASgNEiwKB0VmZmVjdHMYAiADKAsyGy5HcmlkRmln",
"aHRHYW1lVHJhaXRFZmZlY3RQYhISCgpUcmFpdExheWVyGAMgASgNIj0KFEdy",
"aWRGaWdodFRyYWl0SW5mb1BiEiUKBlRyYWl0cxgBIAMoCzIVLkdyaWRGaWdo",
"dEdhbWVUcmFpdFBiIjwKGEdyaWRGaWdodEVxdWlwbWVudEl0ZW1QYhIOCgZJ",
"dGVtSWQYASABKA0SEAoIVW5pcXVlSWQYAiABKA0iOgoZR3JpZEZpZ2h0Q29u",
"c3VtYWJsZUl0ZW1QYhIOCgZJdGVtSWQYASABKA0SDQoFQ291bnQYAiABKA0i",
"fgoUR3JpZEZpZ2h0SXRlbXNJbmZvUGISMQoORXF1aXBtZW50SXRlbXMYASAD",
"KAsyGS5HcmlkRmlnaHRFcXVpcG1lbnRJdGVtUGISMwoPQ29uc3VtYWJsZUl0",
"ZW1zGAIgAygLMhouR3JpZEZpZ2h0Q29uc3VtYWJsZUl0ZW1QYiLbAgoUR3Jp",
"ZEZpZ2h0Q29tcG9uZW50UGISKAoIU2hvcEluZm8YASABKAsyFC5HcmlkRmln",
"aHRTaG9wSW5mb1BiSAASKgoJQmFzaWNJbmZvGAIgASgLMhUuR3JpZEZpZ2h0",
"QmFzaWNJbmZvUGJIABIsCgpBdmF0YXJJbmZvGAMgASgLMhYuR3JpZEZpZ2h0",
"QXZhdGFySW5mb1BiSAASJgoHT3JiSW5mbxgEIAEoCzITLkdyaWRGaWdodE9y",
"YkluZm9QYkgAEi4KC0F1Z21lbnRJbmZvGAUgASgLMhcuR3JpZEZpZ2h0QXVn",
"bWVudEluZm9QYkgAEioKCVRyYWl0SW5mbxgGIAEoCzIVLkdyaWRGaWdodFRy",
"YWl0SW5mb1BiSAASKgoJSXRlbXNJbmZvGAcgASgLMhUuR3JpZEZpZ2h0SXRl",
"bXNJbmZvUGJIAEIPCg1Db21wb25lbnRUeXBlQimqAiZFZ2dMaW5rLkRhbmhl",
"bmdTZXJ2ZXIuUHJvdG8uU2VydmVyU2lkZWIGcHJvdG8z"));
"ZBgCIAEoDRITCglUaHJlc2hvbGQYAyABKA1IABIaChBDb3JlUm9sZVVuaXF1",
"ZUlkGAQgASgNSABCDQoLRWZmZWN0UGFyYW0iaQoUR3JpZEZpZ2h0R2FtZVRy",
"YWl0UGISDwoHVHJhaXRJZBgBIAEoDRIsCgdFZmZlY3RzGAIgAygLMhsuR3Jp",
"ZEZpZ2h0R2FtZVRyYWl0RWZmZWN0UGISEgoKVHJhaXRMYXllchgDIAEoDSI9",
"ChRHcmlkRmlnaHRUcmFpdEluZm9QYhIlCgZUcmFpdHMYASADKAsyFS5Hcmlk",
"RmlnaHRHYW1lVHJhaXRQYiI8ChhHcmlkRmlnaHRFcXVpcG1lbnRJdGVtUGIS",
"DgoGSXRlbUlkGAEgASgNEhAKCFVuaXF1ZUlkGAIgASgNIjoKGUdyaWRGaWdo",
"dENvbnN1bWFibGVJdGVtUGISDgoGSXRlbUlkGAEgASgNEg0KBUNvdW50GAIg",
"ASgNIn4KFEdyaWRGaWdodEl0ZW1zSW5mb1BiEjEKDkVxdWlwbWVudEl0ZW1z",
"GAEgAygLMhkuR3JpZEZpZ2h0RXF1aXBtZW50SXRlbVBiEjMKD0NvbnN1bWFi",
"bGVJdGVtcxgCIAMoCzIaLkdyaWRGaWdodENvbnN1bWFibGVJdGVtUGIi2wIK",
"FEdyaWRGaWdodENvbXBvbmVudFBiEigKCFNob3BJbmZvGAEgASgLMhQuR3Jp",
"ZEZpZ2h0U2hvcEluZm9QYkgAEioKCUJhc2ljSW5mbxgCIAEoCzIVLkdyaWRG",
"aWdodEJhc2ljSW5mb1BiSAASLAoKQXZhdGFySW5mbxgDIAEoCzIWLkdyaWRG",
"aWdodEF2YXRhckluZm9QYkgAEiYKB09yYkluZm8YBCABKAsyEy5HcmlkRmln",
"aHRPcmJJbmZvUGJIABIuCgtBdWdtZW50SW5mbxgFIAEoCzIXLkdyaWRGaWdo",
"dEF1Z21lbnRJbmZvUGJIABIqCglUcmFpdEluZm8YBiABKAsyFS5HcmlkRmln",
"aHRUcmFpdEluZm9QYkgAEioKCUl0ZW1zSW5mbxgHIAEoCzIVLkdyaWRGaWdo",
"dEl0ZW1zSW5mb1BiSABCDwoNQ29tcG9uZW50VHlwZUIpqgImRWdnTGluay5E",
"YW5oZW5nU2VydmVyLlByb3RvLlNlcnZlclNpZGViBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
@@ -93,7 +94,7 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightOrbInfoPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightOrbInfoPb.Parser, new[]{ "Orbs" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameAugmentPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameAugmentPb.Parser, new[]{ "AugmentId", "SavedValues" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightAugmentInfoPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightAugmentInfoPb.Parser, new[]{ "Augments" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameTraitEffectPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameTraitEffectPb.Parser, new[]{ "TraitId", "EffectId", "Param" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameTraitEffectPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameTraitEffectPb.Parser, new[]{ "TraitId", "EffectId", "Threshold", "CoreRoleUniqueId" }, new[]{ "EffectParam" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameTraitPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightGameTraitPb.Parser, new[]{ "TraitId", "Effects", "TraitLayer" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightTraitInfoPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightTraitInfoPb.Parser, new[]{ "Traits" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::EggLink.DanhengServer.Proto.ServerSide.GridFightEquipmentItemPb), global::EggLink.DanhengServer.Proto.ServerSide.GridFightEquipmentItemPb.Parser, new[]{ "ItemId", "UniqueId" }, null, null, null, null),
@@ -3535,7 +3536,15 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
public GridFightGameTraitEffectPb(GridFightGameTraitEffectPb other) : this() {
traitId_ = other.traitId_;
effectId_ = other.effectId_;
param_ = other.param_;
switch (other.EffectParamCase) {
case EffectParamOneofCase.Threshold:
Threshold = other.Threshold;
break;
case EffectParamOneofCase.CoreRoleUniqueId:
CoreRoleUniqueId = other.CoreRoleUniqueId;
break;
}
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@@ -3569,17 +3578,78 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
}
}
/// <summary>Field number for the "Param" field.</summary>
public const int ParamFieldNumber = 3;
private uint param_;
/// <summary>Field number for the "Threshold" field.</summary>
public const int ThresholdFieldNumber = 3;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public uint Param {
get { return param_; }
public uint Threshold {
get { return HasThreshold ? (uint) effectParam_ : 0; }
set {
param_ = value;
effectParam_ = value;
effectParamCase_ = EffectParamOneofCase.Threshold;
}
}
/// <summary>Gets whether the "Threshold" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasThreshold {
get { return effectParamCase_ == EffectParamOneofCase.Threshold; }
}
/// <summary> Clears the value of the oneof if it's currently set to "Threshold" </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearThreshold() {
if (HasThreshold) {
ClearEffectParam();
}
}
/// <summary>Field number for the "CoreRoleUniqueId" field.</summary>
public const int CoreRoleUniqueIdFieldNumber = 4;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public uint CoreRoleUniqueId {
get { return HasCoreRoleUniqueId ? (uint) effectParam_ : 0; }
set {
effectParam_ = value;
effectParamCase_ = EffectParamOneofCase.CoreRoleUniqueId;
}
}
/// <summary>Gets whether the "CoreRoleUniqueId" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasCoreRoleUniqueId {
get { return effectParamCase_ == EffectParamOneofCase.CoreRoleUniqueId; }
}
/// <summary> Clears the value of the oneof if it's currently set to "CoreRoleUniqueId" </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearCoreRoleUniqueId() {
if (HasCoreRoleUniqueId) {
ClearEffectParam();
}
}
private object effectParam_;
/// <summary>Enum of possible cases for the "EffectParam" oneof.</summary>
public enum EffectParamOneofCase {
None = 0,
Threshold = 3,
CoreRoleUniqueId = 4,
}
private EffectParamOneofCase effectParamCase_ = EffectParamOneofCase.None;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public EffectParamOneofCase EffectParamCase {
get { return effectParamCase_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearEffectParam() {
effectParamCase_ = EffectParamOneofCase.None;
effectParam_ = null;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@@ -3598,7 +3668,9 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
}
if (TraitId != other.TraitId) return false;
if (EffectId != other.EffectId) return false;
if (Param != other.Param) return false;
if (Threshold != other.Threshold) return false;
if (CoreRoleUniqueId != other.CoreRoleUniqueId) return false;
if (EffectParamCase != other.EffectParamCase) return false;
return Equals(_unknownFields, other._unknownFields);
}
@@ -3608,7 +3680,9 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
int hash = 1;
if (TraitId != 0) hash ^= TraitId.GetHashCode();
if (EffectId != 0) hash ^= EffectId.GetHashCode();
if (Param != 0) hash ^= Param.GetHashCode();
if (HasThreshold) hash ^= Threshold.GetHashCode();
if (HasCoreRoleUniqueId) hash ^= CoreRoleUniqueId.GetHashCode();
hash ^= (int) effectParamCase_;
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@@ -3635,9 +3709,13 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
output.WriteRawTag(16);
output.WriteUInt32(EffectId);
}
if (Param != 0) {
if (HasThreshold) {
output.WriteRawTag(24);
output.WriteUInt32(Param);
output.WriteUInt32(Threshold);
}
if (HasCoreRoleUniqueId) {
output.WriteRawTag(32);
output.WriteUInt32(CoreRoleUniqueId);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
@@ -3657,9 +3735,13 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
output.WriteRawTag(16);
output.WriteUInt32(EffectId);
}
if (Param != 0) {
if (HasThreshold) {
output.WriteRawTag(24);
output.WriteUInt32(Param);
output.WriteUInt32(Threshold);
}
if (HasCoreRoleUniqueId) {
output.WriteRawTag(32);
output.WriteUInt32(CoreRoleUniqueId);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
@@ -3677,8 +3759,11 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
if (EffectId != 0) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(EffectId);
}
if (Param != 0) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Param);
if (HasThreshold) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Threshold);
}
if (HasCoreRoleUniqueId) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(CoreRoleUniqueId);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
@@ -3698,9 +3783,15 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
if (other.EffectId != 0) {
EffectId = other.EffectId;
}
if (other.Param != 0) {
Param = other.Param;
switch (other.EffectParamCase) {
case EffectParamOneofCase.Threshold:
Threshold = other.Threshold;
break;
case EffectParamOneofCase.CoreRoleUniqueId:
CoreRoleUniqueId = other.CoreRoleUniqueId;
break;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@@ -3725,7 +3816,11 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
break;
}
case 24: {
Param = input.ReadUInt32();
Threshold = input.ReadUInt32();
break;
}
case 32: {
CoreRoleUniqueId = input.ReadUInt32();
break;
}
}
@@ -3752,7 +3847,11 @@ namespace EggLink.DanhengServer.Proto.ServerSide {
break;
}
case 24: {
Param = input.ReadUInt32();
Threshold = input.ReadUInt32();
break;
}
case 32: {
CoreRoleUniqueId = input.ReadUInt32();
break;
}
}

View File

@@ -87,7 +87,10 @@ message GridFightAugmentInfoPb {
message GridFightGameTraitEffectPb {
uint32 TraitId = 1;
uint32 EffectId = 2;
uint32 Param = 3;
oneof EffectParam {
uint32 Threshold = 3;
uint32 CoreRoleUniqueId = 4;
}
}
message GridFightGameTraitPb {