mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-03 04:36:03 +08:00
679 lines
26 KiB
C#
679 lines
26 KiB
C#
using EggLink.DanhengServer.Data;
|
|
using EggLink.DanhengServer.Data.Excel;
|
|
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 EggLink.DanhengServer.Util;
|
|
|
|
namespace EggLink.DanhengServer.GameServer.Game.GridFight.Component;
|
|
|
|
public class GridFightItemsComponent(GridFightInstance inst) : BaseGridFightComponent(inst)
|
|
{
|
|
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))
|
|
return (null, []);
|
|
|
|
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
|
var info = new GridFightEquipmentItemPb
|
|
{
|
|
ItemId = equipmentId,
|
|
UniqueId = ++roleComp.Data.CurUniqueId
|
|
};
|
|
|
|
Data.EquipmentItems.Add(info);
|
|
var syncData = new GridFightAddGameItemSyncData(src, [info], [], groupId, param);
|
|
|
|
if (sendPacket)
|
|
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncData));
|
|
|
|
return (info, [syncData]);
|
|
}
|
|
|
|
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 [];
|
|
|
|
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);
|
|
existingItem.Count -= (uint)-count;
|
|
if (existingItem.Count == 0)
|
|
{
|
|
Data.ConsumableItems.Remove(existingItem);
|
|
isRemove = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
existingItem.Count += (uint)count;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (count < 0) return [];
|
|
|
|
var info = new GridFightConsumableItemPb
|
|
{
|
|
ItemId = consumableId,
|
|
Count = (uint)count // safe
|
|
};
|
|
|
|
Data.ConsumableItems.Add(info);
|
|
existingItem = info;
|
|
}
|
|
|
|
BaseGridFightSyncData syncData = isRemove
|
|
? new GridFightRemoveGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], groupId, param)
|
|
: isUpdate
|
|
? new GridFightUpdateGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], groupId, param)
|
|
: new GridFightAddGameItemSyncData(src, [], [existingItem.ToUpdateInfo(count)], groupId, param);
|
|
|
|
if (sendPacket)
|
|
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncData));
|
|
|
|
return [syncData];
|
|
}
|
|
|
|
public async ValueTask<List<BaseGridFightSyncData>> RemoveEquipment(uint uniqueId, GridFightSrc src = GridFightSrc.KGridFightSrcNone, bool sendPacket = true, params uint[] param)
|
|
{
|
|
var existingItem = Data.EquipmentItems.FirstOrDefault(x => x.UniqueId == uniqueId);
|
|
|
|
if (existingItem == null)
|
|
return [];
|
|
|
|
Data.EquipmentItems.Remove(existingItem);
|
|
|
|
List<BaseGridFightSyncData> syncDatas =
|
|
[
|
|
new GridFightRemoveGameItemSyncData(src, [existingItem], [], 0, param)
|
|
];
|
|
|
|
// if equipped
|
|
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
|
foreach (var role in roleComp.Data.Roles)
|
|
{
|
|
if (!role.EquipmentIds.Contains(existingItem.ItemId)) continue;
|
|
|
|
role.EquipmentIds.Remove(existingItem.ItemId);
|
|
syncDatas.Add(new GridFightRoleUpdateSyncData(src, role.Clone(), 0, param));
|
|
}
|
|
|
|
if (sendPacket)
|
|
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncDatas));
|
|
|
|
return syncDatas;
|
|
}
|
|
|
|
public async ValueTask<List<BaseGridFightSyncData>> CraftEquipment(uint targetEquipId, List<uint> materials)
|
|
{
|
|
List<BaseGridFightSyncData> syncDatas = [];
|
|
|
|
// remove materials
|
|
foreach (var matId in materials)
|
|
{
|
|
syncDatas.AddRange(await RemoveEquipment(matId, GridFightSrc.KGridFightSrcCraftEquip, false));
|
|
}
|
|
|
|
// add crafted equipment
|
|
var addEquipDatas = await AddEquipment(targetEquipId, GridFightSrc.KGridFightSrcCraftEquip, false);
|
|
syncDatas.AddRange(addEquipDatas.Item2);
|
|
|
|
// if auto equip to a role
|
|
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
|
var roleUnique =
|
|
(syncDatas.FirstOrDefault(x => x is GridFightRoleUpdateSyncData) as GridFightRoleUpdateSyncData)?.Role
|
|
.UniqueId ?? 0;
|
|
|
|
if (roleUnique != 0 && addEquipDatas.Item1 != null)
|
|
{
|
|
syncDatas.AddRange(await roleComp.DressRole(roleUnique, addEquipDatas.Item1.UniqueId, GridFightSrc.KGridFightSrcCraftEquip, false));
|
|
}
|
|
|
|
// sync
|
|
if (syncDatas.Count > 0)
|
|
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncDatas));
|
|
|
|
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>();
|
|
var basicComp = Inst.GetComponent<GridFightBasicComponent>();
|
|
var shopComp = Inst.GetComponent<GridFightShopComponent>();
|
|
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
|
var orbComp = Inst.GetComponent<GridFightOrbComponent>();
|
|
|
|
foreach (var item in drops)
|
|
{
|
|
// take drop
|
|
switch (item.DropType)
|
|
{
|
|
case GridFightDropType.Coin:
|
|
{
|
|
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;
|
|
}
|
|
case GridFightDropType.Refresh:
|
|
{
|
|
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;
|
|
}
|
|
case GridFightDropType.Item:
|
|
{
|
|
// consumable or equipment or forge
|
|
if (GameData.GridFightConsumablesData.ContainsKey(item.DropItemId))
|
|
{
|
|
syncs.AddRange(await UpdateConsumable(item.DropItemId, (int)item.Num, src, false, groupId,
|
|
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);
|
|
}
|
|
}
|
|
else if (GameData.GridFightForgeData.ContainsKey(item.DropItemId))
|
|
{
|
|
for (uint i = 0; i < item.Num; i++)
|
|
{
|
|
syncs.AddRange(await roleComp.AddForgeItem(item.DropItemId, false, src, groupId, 0, param));
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case GridFightDropType.Orb:
|
|
{
|
|
// add orbs
|
|
syncs.AddRange(await orbComp.AddOrb(item.DropItemId, src, false, groupId, param));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sendPacket && syncs.Count > 0)
|
|
{
|
|
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
|
|
}
|
|
|
|
return syncs;
|
|
}
|
|
|
|
public async ValueTask<(List<BaseGridFightSyncData>, List<GridFightDropItemInfo>)> TakeBasicBonusItems(
|
|
List<GridFightBasicBonusPoolV2Excel> bonuses, GridFightSrc src = GridFightSrc.KGridFightSrcNone, uint groupId = 0, bool sendPacket = true)
|
|
{
|
|
var basicComp = Inst.GetComponent<GridFightBasicComponent>();
|
|
var shopComp = Inst.GetComponent<GridFightShopComponent>();
|
|
var roleComp = Inst.GetComponent<GridFightRoleComponent>();
|
|
var orbComp = Inst.GetComponent<GridFightOrbComponent>();
|
|
|
|
List<BaseGridFightSyncData> syncs = [];
|
|
List<GridFightDropItemInfo> drops = [];
|
|
|
|
foreach (var bonus in bonuses)
|
|
{
|
|
// get drop
|
|
switch (bonus.BonusType)
|
|
{
|
|
case GridFightBonusTypeEnum.Gold:
|
|
{
|
|
// add gold
|
|
await basicComp.UpdateGoldNum((int)bonus.Value, false);
|
|
syncs.Add(new GridFightGoldSyncData(src, basicComp.Data, groupId));
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropType = GridFightDropType.Coin,
|
|
Num = bonus.Value
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.Refresh:
|
|
{
|
|
// add refresh count
|
|
shopComp.Data.FreeRefreshCount += bonus.Value;
|
|
syncs.Add(new GridFightShopSyncData(src, shopComp.Data.Clone(), basicComp.Data.CurLevel, groupId));
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropType = GridFightDropType.Refresh,
|
|
Num = bonus.Value
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.SpecificAvatar:
|
|
{
|
|
// add role
|
|
var roleId = bonus.BonusTypeParamList[0];
|
|
var tier = bonus.BonusTypeParamList[1];
|
|
|
|
syncs.AddRange(await roleComp.AddAvatar(roleId, tier, false, true, src, groupId));
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DisplayValue = new GridDropItemDisplayInfo
|
|
{
|
|
Tier = tier
|
|
},
|
|
DropItemId = roleId,
|
|
DropType = GridFightDropType.Role,
|
|
Num = 1
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.RandomAvatar:
|
|
{
|
|
// add random role
|
|
var rarity = bonus.BonusTypeParamList[0];
|
|
var tier = bonus.BonusTypeParamList[1];
|
|
|
|
var role = GameData.GridFightRoleBasicInfoData.Values.Where(x => x.Rarity == rarity && x.IsInPool)
|
|
.ToList()
|
|
.RandomElement();
|
|
|
|
syncs.AddRange(await roleComp.AddAvatar(role.ID, tier, false, true, src, groupId));
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DisplayValue = new GridDropItemDisplayInfo
|
|
{
|
|
Tier = tier
|
|
},
|
|
DropItemId = role.ID,
|
|
DropType = GridFightDropType.Role,
|
|
Num = 1
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.Item:
|
|
{
|
|
// consumable or equipment
|
|
var itemId = bonus.BonusTypeParamList[0];
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropItemId = itemId,
|
|
Num = 1,
|
|
DropType = GridFightDropType.Item
|
|
});
|
|
|
|
// check if consumable or equipment or forge
|
|
if (GameData.GridFightEquipmentData.ContainsKey(itemId))
|
|
{
|
|
syncs.AddRange((await AddEquipment(itemId, src, false, groupId)).Item2);
|
|
|
|
}
|
|
else if (GameData.GridFightConsumablesData.ContainsKey(itemId))
|
|
{
|
|
syncs.AddRange(await UpdateConsumable(itemId, 1, src, false, groupId));
|
|
}
|
|
else if (GameData.GridFightForgeData.ContainsKey(itemId))
|
|
{
|
|
syncs.AddRange(await roleComp.AddForgeItem(itemId, false, src, groupId));
|
|
}
|
|
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.Exp:
|
|
{
|
|
// add exp
|
|
await basicComp.AddLevelExp(bonus.Value, false);
|
|
syncs.Add(new GridFightPlayerLevelSyncData(src, basicComp.Data, groupId));
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropType = GridFightDropType.Exp,
|
|
Num = bonus.Value
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.Orb:
|
|
{
|
|
// add orbs
|
|
var orbId = bonus.BonusTypeParamList[0];
|
|
syncs.AddRange(await orbComp.AddOrb(orbId, src, false, groupId));
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropItemId = orbId,
|
|
DropType = GridFightDropType.Orb,
|
|
Num = bonus.Value
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.RandomEquipByCategory:
|
|
{
|
|
var category = bonus.BonusTypeParamList[0];
|
|
|
|
var equip = GameData.GridFightEquipmentData.Values.Where(x => (int)x.EquipCategory == category)
|
|
.ToList().RandomElement();
|
|
|
|
syncs.AddRange((await AddEquipment(equip.ID, src, false, groupId)).Item2);
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropItemId = equip.ID,
|
|
DropType = GridFightDropType.Item,
|
|
Num = 1
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.RandomEquipByFunc:
|
|
{
|
|
var func = bonus.BonusTypeParamList[0];
|
|
|
|
var equip = GameData.GridFightEquipmentData.Values.Where(x => (int)x.EquipFunc == func)
|
|
.ToList().RandomElement();
|
|
|
|
syncs.AddRange((await AddEquipment(equip.ID, src, false, groupId)).Item2);
|
|
|
|
drops.Add(new GridFightDropItemInfo
|
|
{
|
|
DropItemId = equip.ID,
|
|
DropType = GridFightDropType.Item,
|
|
Num = 1
|
|
});
|
|
break;
|
|
}
|
|
case GridFightBonusTypeEnum.RandomSameAvatar:
|
|
{
|
|
// TODO (not used in official server)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (syncs.Count > 0 && sendPacket)
|
|
{
|
|
await Inst.Player.SendPacket(new PacketGridFightSyncUpdateResultScNotify(syncs));
|
|
}
|
|
|
|
return (syncs, drops);
|
|
}
|
|
|
|
#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, 0, 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 RollEquipment(equipmentUid));
|
|
}
|
|
|
|
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
|
|
{
|
|
GridItemsInfo = new GridFightGameItemsInfo
|
|
{
|
|
GridFightEquipmentList = { Data.EquipmentItems.Select(x => x.ToProto()) },
|
|
GridFightConsumableList = { Data.ConsumableItems.Select(x => x.ToProto()) }
|
|
}
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public static class GridFightItemsComponentExtensions
|
|
{
|
|
public static GridFightEquipmentInfo ToProto(this GridFightEquipmentItemPb equipment)
|
|
{
|
|
return new GridFightEquipmentInfo
|
|
{
|
|
GridFightEquipmentId = equipment.ItemId,
|
|
UniqueId = equipment.UniqueId
|
|
};
|
|
}
|
|
|
|
public static GridFightConsumableInfo ToProto(this GridFightConsumableItemPb consumable)
|
|
{
|
|
return new GridFightConsumableInfo
|
|
{
|
|
ItemId = consumable.ItemId,
|
|
Num = consumable.Count
|
|
};
|
|
}
|
|
|
|
public static GridFightConsumableUpdateInfo ToUpdateInfo(this GridFightConsumableItemPb consumable, int updateCount)
|
|
{
|
|
return new GridFightConsumableUpdateInfo
|
|
{
|
|
ItemId = consumable.ItemId,
|
|
Num = consumable.Count,
|
|
ItemStackCount = updateCount
|
|
};
|
|
}
|
|
|
|
public static BattleGridFightEquipmentInfo ToBattleInfo(this GridFightEquipmentItemPb equipment)
|
|
{
|
|
return new BattleGridFightEquipmentInfo
|
|
{
|
|
GridFightEquipmentId = equipment.ItemId,
|
|
UniqueId = equipment.UniqueId
|
|
};
|
|
}
|
|
} |