mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-02 20:26:03 +08:00
feat: consumables
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Database.Avatar;
|
||||
using EggLink.DanhengServer.Database.Lineup;
|
||||
using EggLink.DanhengServer.Enums.GridFight;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
||||
using EggLink.DanhengServer.GameServer.Game.Player;
|
||||
@@ -91,7 +90,7 @@ public class BattleGridFightOptions(GridFightGameSectionInfo curSection, GridFig
|
||||
|
||||
proto.BattleGridFightInfo = new BattleGridFightInfo
|
||||
{
|
||||
GridGameAvatarList =
|
||||
GridGameRoleList =
|
||||
{
|
||||
RoleComponent.Data.Roles.Where(x => x.Pos <= BasicComponent.GetFieldCount()).OrderBy(x => x.Pos).Select(x => x.ToBattleInfo(ItemsComponent.Data))
|
||||
},
|
||||
|
||||
@@ -18,7 +18,8 @@ public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
CurLevel = 3,
|
||||
MaxAvatarNum = 3,
|
||||
BuyLevelCost = 4,
|
||||
CurGold = 0
|
||||
CurGold = 0,
|
||||
MaxInterest = 5
|
||||
};
|
||||
|
||||
#endregion
|
||||
@@ -168,11 +169,10 @@ public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
GridFightMaxFieldCount = Data.MaxAvatarNum,
|
||||
GridFightLineupHp = Data.CurHp,
|
||||
GridFightCurGold = Data.CurGold,
|
||||
GridFightMaxInterestGold = 5,
|
||||
GridFightMaxInterestGold = Data.MaxInterest,
|
||||
GridFightComboWinNum = Data.ComboNum,
|
||||
OCMGMEHECBB = new OPIBBPCHFII
|
||||
{
|
||||
IJDIAOMINLB = new BHJALAPDBLH()
|
||||
},
|
||||
GameLockInfo = new GridFightLockInfo
|
||||
{
|
||||
@@ -181,7 +181,8 @@ public class GridFightBasicComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
},
|
||||
GridFightTargetGuideCode = Data.GuideCode,
|
||||
TrackTraitIdList = { Data.TrackingTraits },
|
||||
RoleTrackEquipmentList = { Data.TrackingEquipments.Select(x => x.ToProto(roleComp, itemsComp)) }
|
||||
RoleTrackEquipmentList = { Data.TrackingEquipments.Select(x => x.ToProto(roleComp, itemsComp)) },
|
||||
GridFightMaxLevel = 10
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
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;
|
||||
using System.Data.OscarClient;
|
||||
using System.Threading;
|
||||
using EggLink.DanhengServer.Util;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
||||
|
||||
@@ -12,6 +13,8 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
{
|
||||
public GridFightItemsInfoPb Data { get; set; } = new();
|
||||
|
||||
#region Add & Remove & Craft
|
||||
|
||||
public async ValueTask<(GridFightEquipmentItemPb?, List<BaseGridFightSyncData>)> AddEquipment(uint equipmentId, GridFightSrc src = GridFightSrc.KGridFightSrcNone, bool sendPacket = true, uint groupId = 0, params uint[] param)
|
||||
{
|
||||
if (!GameData.GridFightEquipmentData.ContainsKey(equipmentId))
|
||||
@@ -41,9 +44,11 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
var existingItem = Data.ConsumableItems.FirstOrDefault(x => x.ItemId == consumableId);
|
||||
|
||||
var isRemove = false;
|
||||
var isUpdate = false;
|
||||
|
||||
if (existingItem != null)
|
||||
{
|
||||
isUpdate = true;
|
||||
if (count < 0)
|
||||
{
|
||||
count = (int)-Math.Min(existingItem.Count, -count);
|
||||
@@ -51,10 +56,8 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
if (existingItem.Count == 0)
|
||||
{
|
||||
Data.ConsumableItems.Remove(existingItem);
|
||||
isRemove = true;
|
||||
}
|
||||
|
||||
|
||||
isRemove = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -77,7 +80,9 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
|
||||
BaseGridFightSyncData syncData = isRemove
|
||||
? new GridFightRemoveGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], 0, param)
|
||||
: new GridFightAddGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], 0, param);
|
||||
: isUpdate
|
||||
? new GridFightUpdateGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], 0, param)
|
||||
: new GridFightAddGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], 0, param);
|
||||
|
||||
if (sendPacket)
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncData));
|
||||
@@ -147,6 +152,10 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
return syncDatas;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rewards
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> TakeDrop(List<GridFightDropItemInfo> drops, bool sendPacket = false, GridFightSrc src = GridFightSrc.KGridFightSrcNone, uint groupId = 0, params uint[] param)
|
||||
{
|
||||
var syncs = new List<BaseGridFightSyncData>();
|
||||
@@ -161,52 +170,52 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
switch (item.DropType)
|
||||
{
|
||||
case GridFightDropType.Coin:
|
||||
{
|
||||
await basicComp.UpdateGoldNum((int)item.Num, false);
|
||||
syncs.Add(new GridFightGoldSyncData(src, basicComp.Data, groupId, param));
|
||||
break;
|
||||
}
|
||||
{
|
||||
await basicComp.UpdateGoldNum((int)item.Num, false);
|
||||
syncs.Add(new GridFightGoldSyncData(src, basicComp.Data, groupId, param));
|
||||
break;
|
||||
}
|
||||
case GridFightDropType.Exp:
|
||||
{
|
||||
await basicComp.AddLevelExp(item.Num, false);
|
||||
syncs.Add(new GridFightPlayerLevelSyncData(src, basicComp.Data, groupId, param));
|
||||
break;
|
||||
}
|
||||
{
|
||||
await basicComp.AddLevelExp(item.Num, false);
|
||||
syncs.Add(new GridFightPlayerLevelSyncData(src, basicComp.Data, groupId, param));
|
||||
break;
|
||||
}
|
||||
case GridFightDropType.Refresh:
|
||||
{
|
||||
shopComp.Data.FreeRefreshCount += item.Num;
|
||||
syncs.Add(new GridFightShopSyncData(src, shopComp.Data, basicComp.Data.CurLevel, groupId, param));
|
||||
break;
|
||||
}
|
||||
{
|
||||
shopComp.Data.FreeRefreshCount += item.Num;
|
||||
syncs.Add(new GridFightShopSyncData(src, shopComp.Data, basicComp.Data.CurLevel, groupId, param));
|
||||
break;
|
||||
}
|
||||
case GridFightDropType.Role:
|
||||
{
|
||||
syncs.AddRange(await roleComp.AddAvatar(item.DropItemId, item.DisplayValue.Tier, false, true,
|
||||
src, groupId, 0, param));
|
||||
break;
|
||||
}
|
||||
{
|
||||
syncs.AddRange(await roleComp.AddAvatar(item.DropItemId, item.DisplayValue.Tier, false, true,
|
||||
src, groupId, 0, param));
|
||||
break;
|
||||
}
|
||||
case GridFightDropType.Item:
|
||||
{
|
||||
// consumable or equipment
|
||||
if (GameData.GridFightConsumablesData.ContainsKey(item.DropItemId))
|
||||
{
|
||||
syncs.AddRange(await UpdateConsumable(item.DropItemId, (int)item.Num, src, false, param));
|
||||
}
|
||||
else if (GameData.GridFightEquipmentData.ContainsKey(item.DropItemId))
|
||||
{
|
||||
for (uint i = 0; i < item.Num; i++)
|
||||
// consumable or equipment
|
||||
if (GameData.GridFightConsumablesData.ContainsKey(item.DropItemId))
|
||||
{
|
||||
syncs.AddRange((await AddEquipment(item.DropItemId, src, false, groupId, param)).Item2);
|
||||
syncs.AddRange(await UpdateConsumable(item.DropItemId, (int)item.Num, src, false, param));
|
||||
}
|
||||
else if (GameData.GridFightEquipmentData.ContainsKey(item.DropItemId))
|
||||
{
|
||||
for (uint i = 0; i < item.Num; i++)
|
||||
{
|
||||
syncs.AddRange((await AddEquipment(item.DropItemId, src, false, groupId, param)).Item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GridFightDropType.Orb:
|
||||
{
|
||||
// add orbs
|
||||
syncs.AddRange(await orbComp.AddOrb(item.DropItemId, src, false, groupId, param));
|
||||
break;
|
||||
}
|
||||
{
|
||||
// add orbs
|
||||
syncs.AddRange(await orbComp.AddOrb(item.DropItemId, src, false, groupId, param));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +227,199 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
return syncs;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Consumables
|
||||
|
||||
public async ValueTask<Retcode> UseConsumable(uint itemId, GridFightConsumableTargetInfo target)
|
||||
{
|
||||
if (!GameData.GridFightConsumablesData.TryGetValue(itemId, out var consumablesExcel)) return Retcode.RetGridFightConfMiss;
|
||||
|
||||
// if owned
|
||||
var item = Data.ConsumableItems.FirstOrDefault(x => x.ItemId == itemId);
|
||||
if (item == null || item.Count == 0) return Retcode.RetGridFightItemNotEnough;
|
||||
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
if (consumablesExcel.IfConsume)
|
||||
{
|
||||
syncs.AddRange(await UpdateConsumable(itemId, -1, GridFightSrc.KGridFightSrcUseConsumable, false, item.ItemId));
|
||||
}
|
||||
|
||||
(Retcode, List<BaseGridFightSyncData>) res = consumablesExcel.ConsumableRule switch
|
||||
{
|
||||
GridFightConsumeTypeEnum.Remove => HandleRemoveConsumable(target),
|
||||
GridFightConsumeTypeEnum.Roll => await HandleRollConsumable(target),
|
||||
GridFightConsumeTypeEnum.Upgrade => await HandleUpgradeConsumable(target),
|
||||
GridFightConsumeTypeEnum.Copy => await HandleCopyConsumable(target, consumablesExcel.ConsumableParamList),
|
||||
GridFightConsumeTypeEnum.GainRecommendEquip => await HandleGainRecommendEquipConsumable(target, consumablesExcel.ConsumableParamList),
|
||||
_ => (Retcode.RetGridFightConfMiss, [])
|
||||
};
|
||||
syncs.AddRange(res.Item2);
|
||||
|
||||
if (syncs.Count > 0)
|
||||
{
|
||||
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
|
||||
}
|
||||
|
||||
return res.Item1;
|
||||
}
|
||||
|
||||
private (Retcode, List<BaseGridFightSyncData>) HandleRemoveConsumable(GridFightConsumableTargetInfo target)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
|
||||
if (target.RemoveTypeTargetInfo == null) return (Retcode.RetReqParaInvalid, syncs);
|
||||
|
||||
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
||||
var role = roleComp.Data.Roles.FirstOrDefault(x => x.UniqueId == target.RemoveTypeTargetInfo.DressRoleUniqueId);
|
||||
if (role == null) return (Retcode.RetGridFightRoleNotExist, syncs);
|
||||
|
||||
// unequip
|
||||
role.EquipmentIds.Clear();
|
||||
|
||||
// sync
|
||||
syncs.Add(new GridFightRoleUpdateSyncData(GridFightSrc.KGridFightSrcUseConsumable, role.Clone()));
|
||||
|
||||
return (Retcode.RetSucc, syncs);
|
||||
}
|
||||
|
||||
private async ValueTask<(Retcode, List<BaseGridFightSyncData>)> HandleRollConsumable(GridFightConsumableTargetInfo target)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
|
||||
if (target.RollTypeTargetInfo == null) return (Retcode.RetReqParaInvalid, syncs);
|
||||
|
||||
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
||||
var equipment = Data.EquipmentItems.FirstOrDefault(x => x.UniqueId == target.RollTypeTargetInfo.DressEquipmentUniqueId);
|
||||
var role = roleComp.Data.Roles.FirstOrDefault(x => x.UniqueId == target.RollTypeTargetInfo.DressRoleUniqueId);
|
||||
if (role == null && equipment == null) return (Retcode.RetGridFightRoleNotExist, syncs);
|
||||
|
||||
if (role != null)
|
||||
{
|
||||
// unequip old equipment
|
||||
foreach (var equipmentUid in role.EquipmentIds)
|
||||
{
|
||||
syncs.AddRange(await RemoveEquipment(equipmentUid, GridFightSrc.KGridFightSrcUseConsumable, false));
|
||||
}
|
||||
|
||||
role.EquipmentIds.Clear();
|
||||
|
||||
// sync
|
||||
syncs.Add(new GridFightRoleUpdateSyncData(GridFightSrc.KGridFightSrcUseConsumable, role.Clone()));
|
||||
}
|
||||
|
||||
if (equipment != null)
|
||||
{
|
||||
syncs.AddRange(await RollEquipment(equipment.UniqueId));
|
||||
}
|
||||
|
||||
return (Retcode.RetSucc, syncs);
|
||||
}
|
||||
|
||||
private async ValueTask<List<BaseGridFightSyncData>> RollEquipment(uint uniqueId)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
var equipment = Data.EquipmentItems.FirstOrDefault(x => x.UniqueId == uniqueId);
|
||||
if (equipment == null) return syncs;
|
||||
|
||||
// remove old equipment
|
||||
syncs.AddRange(await RemoveEquipment(equipment.UniqueId, GridFightSrc.KGridFightSrcUseConsumable, false));
|
||||
|
||||
// add new equipment
|
||||
var equipConf = GameData.GridFightEquipmentData[equipment.ItemId];
|
||||
var newEquip = GameData.GridFightEquipmentData.Values
|
||||
.Where(x => x.EquipCategory == equipConf.EquipCategory && x.ID != equipConf.ID).ToList()
|
||||
.RandomElement();
|
||||
|
||||
syncs.AddRange((await AddEquipment(newEquip.ID, GridFightSrc.KGridFightSrcUseConsumable, false))
|
||||
.Item2);
|
||||
return syncs;
|
||||
}
|
||||
|
||||
private async ValueTask<(Retcode, List<BaseGridFightSyncData>)> HandleUpgradeConsumable(GridFightConsumableTargetInfo target)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
|
||||
if (target.UpgradeTypeTargetInfo == null) return (Retcode.RetReqParaInvalid, syncs);
|
||||
|
||||
var targetEquip = Data.EquipmentItems.FirstOrDefault(x => x.UniqueId == target.UpgradeTypeTargetInfo.DressEquipmentUniqueId);
|
||||
if (targetEquip == null) return (Retcode.RetGridFightEquipNotExist, syncs);
|
||||
|
||||
var upgradeId = GameData.GridFightEquipUpgradeData.GetValueOrDefault(targetEquip.ItemId)?.UpgradeID;
|
||||
if (upgradeId == null) return (Retcode.RetGridFightConfMiss, syncs);
|
||||
|
||||
// remove old equipment
|
||||
syncs.AddRange(await RemoveEquipment(targetEquip.UniqueId, GridFightSrc.KGridFightSrcUseConsumable, false));
|
||||
|
||||
// add new equipment
|
||||
syncs.AddRange((await AddEquipment(upgradeId.Value, GridFightSrc.KGridFightSrcUseConsumable, false))
|
||||
.Item2);
|
||||
|
||||
return (Retcode.RetSucc, syncs);
|
||||
}
|
||||
|
||||
private async ValueTask<(Retcode, List<BaseGridFightSyncData>)> HandleCopyConsumable(GridFightConsumableTargetInfo target, List<uint> param)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
if (target.CopyTypeTargetInfo == null) return (Retcode.RetReqParaInvalid, syncs);
|
||||
|
||||
var maxRarity = param[0];
|
||||
var count = param[1];
|
||||
|
||||
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
||||
var targetRole = roleComp.Data.Roles.FirstOrDefault(x => x.UniqueId == target.CopyTypeTargetInfo.DressRoleUniqueId);
|
||||
|
||||
if (targetRole == null) return (Retcode.RetGridFightRoleNotExist, syncs);
|
||||
// check if can copy
|
||||
if (!GameData.GridFightRoleBasicInfoData.TryGetValue(targetRole.RoleId, out var roleConf))
|
||||
return (Retcode.RetGridFightConfMiss, syncs);
|
||||
|
||||
if (roleConf.Rarity > maxRarity) return (Retcode.RetGridFightHighRariyForCopy, syncs);
|
||||
|
||||
// check if enough space
|
||||
var canAddCount = roleComp.GetEmptyPosCount();
|
||||
if (canAddCount < count) return (Retcode.RetGridFightNoPosCanPlace, syncs);
|
||||
|
||||
// copy role
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
syncs.AddRange(await roleComp.AddAvatar(targetRole.RoleId, 1, false, true,
|
||||
GridFightSrc.KGridFightSrcUseConsumable));
|
||||
}
|
||||
|
||||
return (Retcode.RetSucc, syncs);
|
||||
}
|
||||
|
||||
private async ValueTask<(Retcode, List<BaseGridFightSyncData>)> HandleGainRecommendEquipConsumable(
|
||||
GridFightConsumableTargetInfo target, List<uint> param)
|
||||
{
|
||||
List<BaseGridFightSyncData> syncs = [];
|
||||
if (target.GainRecommendEquipTypeTargetInfo == null) return (Retcode.RetReqParaInvalid, syncs);
|
||||
|
||||
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
||||
var targetRole = roleComp.Data.Roles.FirstOrDefault(x => x.UniqueId == target.GainRecommendEquipTypeTargetInfo.DressRoleUniqueId);
|
||||
if (targetRole == null) return (Retcode.RetGridFightRoleNotExist, syncs);
|
||||
|
||||
// get recommend equipment
|
||||
if (!GameData.GridFightRoleRecommendEquipData.TryGetValue(targetRole.RoleId, out var recommendConf))
|
||||
return (Retcode.RetGridFightConfMiss, syncs);
|
||||
|
||||
var recommendList = recommendConf.FirstRecommendEquipList.Concat(recommendConf.SecondRecommendEquipList).ToList();
|
||||
|
||||
var recommendCount = Math.Min(param[0], (uint)recommendList.Count);
|
||||
var recommends = recommendList.OrderBy(_ => Guid.NewGuid()).Take((int)recommendCount).ToList();
|
||||
|
||||
syncs.AddRange(
|
||||
await Inst.CreatePendingAction<GridFightRecommendEquipmentPendingAction>(
|
||||
GridFightSrc.KGridFightSrcUseConsumable, false, recommends));
|
||||
|
||||
return (Retcode.RetSucc, syncs);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialization
|
||||
|
||||
public override GridFightGameInfo ToProto()
|
||||
{
|
||||
return new GridFightGameInfo
|
||||
@@ -229,6 +431,8 @@ public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public static class GridFightItemsComponentExtensions
|
||||
|
||||
@@ -151,6 +151,8 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> EnterNextSection(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)
|
||||
{
|
||||
@@ -170,7 +172,7 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
|
||||
List<BaseGridFightSyncData> syncs = [new GridFightLevelSyncData(src, this)];
|
||||
|
||||
syncs.AddRange(await Inst.CreatePendingAction<GridFightElitePendingAction>(sendPacket: false));
|
||||
syncs.AddRange(await Inst.CreatePendingAction<GridFightRoundBeginPendingAction>(sendPacket: false));
|
||||
if (CurrentSection.Excel.IsAugment == 1)
|
||||
{
|
||||
// create augment action
|
||||
@@ -181,14 +183,18 @@ public class GridFightLevelComponent : BaseGridFightComponent
|
||||
{
|
||||
// create supply action
|
||||
await Inst.CreatePendingAction<GridFightSupplyPendingAction>(sendPacket: false);
|
||||
await Inst.CreatePendingAction<GridFightElitePendingAction>(sendPacket: false);
|
||||
}
|
||||
else if (CurrentSection.Excel.NodeType == GridFightNodeTypeEnum.EliteBranch)
|
||||
{
|
||||
await Inst.CreatePendingAction<GridFightEliteBranchPendingAction>(sendPacket: false);
|
||||
}
|
||||
|
||||
await Inst.CreatePendingAction<GridFightEnterNodePendingAction>(sendPacket: false);
|
||||
if (CurrentSection.Excel.NodeType != GridFightNodeTypeEnum.Supply)
|
||||
await Inst.CreatePendingAction<GridFightReturnPreparationPendingAction>(sendPacket: false);
|
||||
|
||||
// refresh shop
|
||||
await shopComp.RefreshShop(true, false);
|
||||
syncs.AddRange(new GridFightShopSyncData(src, shopComp.Data, basicComp.Data.CurLevel));
|
||||
|
||||
if (sendPacket)
|
||||
{
|
||||
@@ -683,7 +689,7 @@ public static class GridFightEncounterGenerateHelper
|
||||
targets.Add(monsters.RandomElement());
|
||||
}
|
||||
|
||||
waves.Add(new GridFightGameMonsterWaveInfo(1, targets, section.MonsterCamp.ID, 3));
|
||||
waves.Add(new GridFightGameMonsterWaveInfo(1, targets, section.MonsterCamp.ID, 5));
|
||||
|
||||
return waves;
|
||||
}
|
||||
@@ -720,7 +726,7 @@ public static class GridFightEncounterGenerateHelper
|
||||
{
|
||||
List<GridFightGameMonsterWaveInfo> waves = [];
|
||||
|
||||
var waveNum = section.ChapterId == 3 ? 2 : 1;
|
||||
var waveNum = section.MonsterCamp.ID == 10 ? 2 : 1;
|
||||
|
||||
for (var i = 0; i < waveNum; i++)
|
||||
{
|
||||
@@ -734,6 +740,14 @@ public static class GridFightEncounterGenerateHelper
|
||||
if (bossMonsters.Count == 0)
|
||||
continue;
|
||||
|
||||
if (section.MonsterCamp.ID == 10)
|
||||
{
|
||||
// extra monster
|
||||
bossMonsters.Add(GameData.GridFightMonsterData[300303301]);
|
||||
bossMonsters.Add(GameData.GridFightMonsterData[300304301]);
|
||||
bossMonsters.Add(GameData.GridFightMonsterData[300305301]);
|
||||
}
|
||||
|
||||
waves.Add(new GridFightGameMonsterWaveInfo((uint)(waves.Count + 1), bossMonsters, section.MonsterCamp.ID));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -17,6 +17,11 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
return Data.Roles.Where(x => x.Pos > PrepareAreaPos).ToList().Count < 9;
|
||||
}
|
||||
|
||||
public uint GetEmptyPosCount()
|
||||
{
|
||||
return (uint)(9 - Data.Roles.Where(x => x.Pos > PrepareAreaPos).ToList().Count);
|
||||
}
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> AddAvatar(uint roleId, uint tier = 1, bool sendPacket = true,
|
||||
bool checkMerge = true, GridFightSrc src = GridFightSrc.KGridFightSrcBuyGoods, uint syncGroup = 0, uint targetPos = 0, params uint[] param)
|
||||
{
|
||||
@@ -282,9 +287,9 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
{
|
||||
return new GridFightGameInfo
|
||||
{
|
||||
GridAvatarGameInfo = new GridFightGameAvatarInfo
|
||||
GridTeamGameInfo = new GridFightGameTeamInfo
|
||||
{
|
||||
GridGameAvatarList = { Data.Roles.Select(x => x.ToProto()) }
|
||||
GridGameRoleList = { Data.Roles.Select(x => x.ToProto()) }
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -292,9 +297,9 @@ public class GridFightRoleComponent(GridFightInstance inst) : BaseGridFightCompo
|
||||
|
||||
public static class GridFightRoleInfoPbExtensions
|
||||
{
|
||||
public static GridGameAvatarInfo ToProto(this GridFightRoleInfoPb info)
|
||||
public static GridGameRoleInfo ToProto(this GridFightRoleInfoPb info)
|
||||
{
|
||||
return new GridGameAvatarInfo
|
||||
return new GridGameRoleInfo
|
||||
{
|
||||
Id = info.RoleId,
|
||||
UniqueId = info.UniqueId,
|
||||
|
||||
@@ -41,7 +41,7 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
|
||||
var expNum = 2u;
|
||||
var baseCoin = levelComp.CurrentSection.Excel.BasicGoldRewardNum;
|
||||
var interestCoin = basicComp.Data.CurGold / 10;
|
||||
var interestCoin = Math.Min(basicComp.Data.CurGold / 10, basicComp.Data.MaxInterest);
|
||||
var progress = req.Stt.GridFightBattleStt.FinishProgress;
|
||||
|
||||
if (progress == 100)
|
||||
@@ -121,8 +121,8 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
_ = GetComponent<GridFightShopComponent>().RefreshShop(true, false);
|
||||
|
||||
_ = CreatePendingAction<GridFightPortalBuffPendingAction>(sendPacket:false);
|
||||
_ = CreatePendingAction<GridFightElitePendingAction>(sendPacket: false);
|
||||
_ = CreatePendingAction<GridFightEnterNodePendingAction>(sendPacket: false);
|
||||
_ = CreatePendingAction<GridFightRoundBeginPendingAction>(sendPacket: false);
|
||||
_ = CreatePendingAction<GridFightReturnPreparationPendingAction>(sendPacket: false);
|
||||
}
|
||||
|
||||
public T GetComponent<T>() where T : BaseGridFightComponent
|
||||
@@ -189,9 +189,10 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
return pos;
|
||||
}
|
||||
|
||||
public async ValueTask<List<BaseGridFightSyncData>> CreatePendingAction<T>(GridFightSrc src = GridFightSrc.KGridFightSrcEnterNode, bool sendPacket = true) where T: BaseGridFightPendingAction
|
||||
public async ValueTask<List<BaseGridFightSyncData>> CreatePendingAction<T>(GridFightSrc src = GridFightSrc.KGridFightSrcEnterNode, bool sendPacket = true, params object[] initializeParam) where T: BaseGridFightPendingAction
|
||||
{
|
||||
var action = (T)Activator.CreateInstance(typeof(T), this)!;
|
||||
object[] paramList = [this, ..initializeParam];
|
||||
var action = (T)Activator.CreateInstance(typeof(T), paramList)!;
|
||||
var basicComp = GetComponent<GridFightBasicComponent>();
|
||||
|
||||
AddPendingAction(action);
|
||||
@@ -224,6 +225,7 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
switch (req.GridFightActionTypeCase)
|
||||
{
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.PortalBuffAction:
|
||||
{
|
||||
src = GridFightSrc.KGridFightSrcSelectPortalBuff;
|
||||
|
||||
syncs.AddRange(await levelComp.AddPortalBuff(req.PortalBuffAction.SelectPortalBuffId, false, src));
|
||||
@@ -239,10 +241,13 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
GridFightSrc.KGridFightSrcInitialSupplySelect));
|
||||
}
|
||||
|
||||
syncs.AddRange(await itemsComp.UpdateConsumable(350102, 1, GridFightSrc.KGridFightSrcInitialSupplySelect, false));
|
||||
syncs.AddRange(await itemsComp.UpdateConsumable(350102, 1,
|
||||
GridFightSrc.KGridFightSrcInitialSupplySelect, false));
|
||||
|
||||
break;
|
||||
}
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.PortalBuffRerollAction:
|
||||
{
|
||||
if (curAction is GridFightPortalBuffPendingAction portalBuffAction)
|
||||
{
|
||||
isFinish = false;
|
||||
@@ -250,13 +255,17 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.AugmentAction:
|
||||
{
|
||||
src = GridFightSrc.KGridFightSrcSelectAugment;
|
||||
|
||||
syncs.AddRange(await GetComponent<GridFightAugmentComponent>().AddAugment(req.AugmentAction.AugmentId, false, src));
|
||||
syncs.AddRange(await GetComponent<GridFightAugmentComponent>()
|
||||
.AddAugment(req.AugmentAction.AugmentId, false, src));
|
||||
break;
|
||||
|
||||
}
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.RerollAugmentAction:
|
||||
{
|
||||
if (curAction is GridFightAugmentPendingAction augmentAction)
|
||||
{
|
||||
isFinish = false;
|
||||
@@ -264,16 +273,18 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
}
|
||||
|
||||
break;
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.EliteAction:
|
||||
break;
|
||||
}
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.EliteBranchAction:
|
||||
{
|
||||
var target = req.EliteBranchAction.EliteBranchId;
|
||||
levelComp.CurrentSection.BranchId = target;
|
||||
// sync
|
||||
syncs.Add(new GridFightLevelSyncData(GridFightSrc.KGridFightSrcNone, levelComp));
|
||||
|
||||
break;
|
||||
}
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.SupplyAction:
|
||||
{
|
||||
src = GridFightSrc.KGridFightSrcSelectSupply;
|
||||
|
||||
PendingActions.Remove(curAction.QueuePosition);
|
||||
@@ -282,16 +293,34 @@ public class GridFightInstance(PlayerInstance player, uint season, uint division
|
||||
{
|
||||
foreach (var supply in req.SupplyAction.SelectSupplyIndexes)
|
||||
{
|
||||
var role = supplyAction.RoleList[(int)supply];
|
||||
var role = supplyAction.RoleList[(int)supply - 1];
|
||||
|
||||
syncs.AddRange(await GetComponent<GridFightRoleComponent>().AddAvatar(role.RoleId, 1, false, true,
|
||||
GridFightSrc.KGridFightSrcSelectSupply, 0, 0, req.SupplyAction.SelectSupplyIndexes.ToArray()));
|
||||
syncs.AddRange(await roleComp.AddAvatar(role.RoleId, 1, false,
|
||||
true,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
syncs.AddRange(await CheckCurNodeFinish(src));
|
||||
|
||||
break;
|
||||
}
|
||||
case GridFightHandlePendingActionCsReq.GridFightActionTypeOneofCase.RecommendEquipmentAction:
|
||||
{
|
||||
var target = req.RecommendEquipmentAction.SelectEquipmentId;
|
||||
|
||||
var res = await itemsComp.AddEquipment(target, GridFightSrc.KGridFightSrcNone, false, 0);
|
||||
syncs.AddRange(res.Item2);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isFinish)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightRecommendEquipmentPendingAction(GridFightInstance inst, List<uint> equipmentList) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public List<uint> EquipmentList { get; } = equipmentList;
|
||||
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
RecommendEquipmentAction = new GridFightRecommendEquipmentActionInfo
|
||||
{
|
||||
AvailableEquipmentList = { EquipmentList }
|
||||
},
|
||||
QueuePosition = QueuePosition
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,13 @@ using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightEnterNodePendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
public class GridFightReturnPreparationPendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
EnterNodeAction = new GridFightEnterNodeActionInfo(),
|
||||
ReturnPreparationAction = new GridFightReturnPreparationActionInfo(),
|
||||
QueuePosition = QueuePosition
|
||||
};
|
||||
}
|
||||
@@ -2,13 +2,13 @@ using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Game.GridFight.PendingAction;
|
||||
|
||||
public class GridFightElitePendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
public class GridFightRoundBeginPendingAction(GridFightInstance inst) : BaseGridFightPendingAction(inst)
|
||||
{
|
||||
public override GridFightPendingAction ToProto()
|
||||
{
|
||||
return new GridFightPendingAction
|
||||
{
|
||||
EliteAction = new GridFightEliteActionInfo(),
|
||||
RoundBeginAction = new GridFightRoundBeginActionInfo(),
|
||||
QueuePosition = QueuePosition
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using EggLink.DanhengServer.Data;
|
||||
using EggLink.DanhengServer.Enums.GridFight;
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Sync;
|
||||
using EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
@@ -14,7 +15,7 @@ public class GridFightSupplyPendingAction : BaseGridFightPendingAction
|
||||
|
||||
public GridFightSupplyPendingAction(GridFightInstance inst) : base(inst)
|
||||
{
|
||||
for (var i = 0; i < 3; i++)
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
RoleList.Add(new GridFightGameSupplyRoleInfo(GameData.GridFightRoleBasicInfoData.Keys.ToList().RandomElement()));
|
||||
}
|
||||
@@ -59,11 +60,15 @@ public class GridFightGameSupplyRoleInfo(uint roleId)
|
||||
{
|
||||
public uint RoleId { get; set; } = roleId;
|
||||
|
||||
public uint EquipmentId { get; set; } = GameData.GridFightEquipmentData.Values
|
||||
.Where(x => x.EquipCategory == GridFightEquipCategoryEnum.Craftable).ToList().RandomElement().ID;
|
||||
|
||||
public GridFightSupplyRoleInfo ToProto()
|
||||
{
|
||||
return new GridFightSupplyRoleInfo
|
||||
{
|
||||
RoleBasicId = RoleId
|
||||
RoleBasicId = RoleId,
|
||||
GridFightItemList = { EquipmentId }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
||||
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.GridFightUseConsumableCsReq)]
|
||||
public class HandlerGridFightUseConsumableCsReq : Handler
|
||||
{
|
||||
public override async Task OnHandle(Connection connection, byte[] header, byte[] data)
|
||||
{
|
||||
var req = GridFightUseConsumableCsReq.Parser.ParseFrom(data);
|
||||
|
||||
var gridFight = connection.Player?.GridFightManager?.GridFightInstance;
|
||||
if (gridFight == null)
|
||||
{
|
||||
await connection.SendPacket(new PacketGridFightUseConsumableScRsp(Retcode.RetGridFightNotInGameplay));
|
||||
return;
|
||||
}
|
||||
|
||||
var itemsComp = gridFight.GetComponent<GridFightItemsComponent>();
|
||||
|
||||
var code = await itemsComp.UseConsumable(req.ItemId, req.DisplayValue);
|
||||
await connection.SendPacket(new PacketGridFightUseConsumableScRsp(code));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using EggLink.DanhengServer.Kcp;
|
||||
using EggLink.DanhengServer.Proto;
|
||||
|
||||
namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.GridFight;
|
||||
|
||||
public class PacketGridFightUseConsumableScRsp : BasePacket
|
||||
{
|
||||
public PacketGridFightUseConsumableScRsp(Retcode ret) : base(CmdIds.GridFightUseConsumableScRsp)
|
||||
{
|
||||
var proto = new GridFightUseConsumableScRsp
|
||||
{
|
||||
Retcode = (uint)ret
|
||||
};
|
||||
|
||||
SetData(proto);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user