CTT/Server/Hotfix/Game/System/UI/FamilyBossComponentSystem.cs

274 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Cal.DataTable;
using ET.EventType;
using System;
using System.Collections.Generic;
namespace ET
{
public class FamilyBossComponentAwakeSystem : AwakeSystem<FamilyBossComponent>
{
public override void Awake(FamilyBossComponent self)
{
FamilyBossComponent.instance = self;
}
}
public static class FamilyBossComponentSystem
{
public class FamilyUpdatePerMinuteEvent : AEvent<EventType.UpdatePer1HourOfDay>
{
public override async ETTask Run(UpdatePer1HourOfDay args)
{
var time = DateTime.UtcNow.Hour;
if (time != 14) return;
var list = await DBComponent.Instance.QueryJson<FamilyBoss>("{}");
if (list == null || list.Count == 0)
{
return;
}
var bossList = DataTableHelper.GetAll<FamilyBossConfig>();
foreach (var familyBoss in list)
{
try
{
foreach (var config in bossList)
{
FamilyBossComponent.instance.SettleReword(familyBoss, config).Coroutine();
}
}
catch (Exception e)
{
Log.Error(e);
}
}
await ETTask.CompletedTask;
}
}
public class FamilyUpdatePerDayEvent : AEvent<EventType.UpdatePer1DayOfMonth>
{
public override async ETTask Run(UpdatePer1DayOfMonth args)
{
var list = await DBComponent.Instance.QueryJson<FamilyBoss>("{}");
if (list == null || list.Count == 0)
{
return;
}
var bossList = DataTableHelper.GetAll<FamilyBossConfig>();
foreach (var familyBoss in list)
{
try
{
foreach (FamilyBossConfig boss in bossList)
{
try
{
familyBoss.SetBossHp((int)boss.Id, boss.Hp);
}
catch (Exception e)
{
Log.Error(e);
}
}
foreach (var item in familyBoss.rankDic)
{
try
{
item.Value.Clear();
}
catch (Exception e)
{
Log.Error(e);
}
}
await DBComponent.Instance.Save(familyBoss);
}
catch (Exception e)
{
Log.Error(e);
}
}
var dic = FamilyBossComponent.instance.familyBossDic;
var _list = dic.Values;
dic.Clear();
foreach (var item in _list)
{
item.Dispose();
}
Log.Info($"更改boss血量");
await ETTask.CompletedTask;
}
}
public static async ETTask<FamilyBoss> Query(this FamilyBossComponent self, string name)
{
if (string.IsNullOrWhiteSpace(name)) return null;
if (!self.familyBossDic.TryGetValue(name, out var friend))
{
var list = await DBComponent.Instance.Query<FamilyBoss>(t => t.name == name);
if (list == null || list.Count == 0)
{
return null;
}
self.familyBossDic[name] = friend = list[0];
}
return friend;
}
public static async ETTask Save(this FamilyBossComponent self, FamilyBoss family)
{
await DBComponent.Instance.Save(family);
}
public static async ETTask Create(this FamilyBossComponent self, string name)
{
FamilyBoss familyBoss = EntityFactory.CreateWithParent<FamilyBoss>(self);
familyBoss.lockedMaxId = 1;
familyBoss.name = name;
if (familyBoss.rankDic.Count == 0)
{
var arr = DataTableHelper.GetAll<FamilyBossConfig>();
foreach (FamilyBossConfig item in arr)
{
familyBoss.rankDic.Add((int)item.Id, new LinkedList<BossDamageMap>());
familyBoss.SetBossHp((int)item.Id, item.Hp);
}
}
self.familyBossDic.Add(name, familyBoss);
await self.Save(familyBoss);
}
public static async ETTask<string> GetFamilyBossInfo(this FamilyBossComponent self, Unit unit, System.Collections.Generic.List<BossInfo> bossInfoList)
{
User user = UserComponent.Instance.Get(unit.Id);
FamilyBoss familyBoss = await self.Query(user.Family);
if (familyBoss == null)
{
return "您还没有加入家族!";
}
Family family = await FamilyComponent.Instance.Query(familyBoss.name);
if (family == null)
{
return "您还没有加入家族!";
}
foreach (var kv in familyBoss.bossHpDic)
{
FamilyBossConfig familyBossConfig = DataTableHelper.Get<FamilyBossConfig>(kv.Key);
bossInfoList.Add(new BossInfo
{
Index = kv.Key,
Hp = kv.Value,
MaxHp = familyBossConfig.Hp,
HasReward = family.HasReward(kv.Key, unit.Id)
});
}
return null;
}
public static async ETTask<string> GetRankList(this FamilyBossComponent self, Unit unit, int bossId, System.Collections.Generic.List<BossDamageMap> rankList)
{
User user = UserComponent.Instance.Get(unit.Id);
FamilyBoss familyBoss = await self.Query(user.Family);
if (familyBoss == null)
{
return "您还没有加入家族!";
}
rankList.AddRange(familyBoss.GetRankList(bossId));
return null;
}
public static async ETTask<string> SettleReword(this FamilyBossComponent self, FamilyBoss familyBoss, FamilyBossConfig config)
{
if (familyBoss == null)
{
Log.Error($"familyBoss == null");
return "系统错误!";
}
int bossId = (int)config.Id;
var rank = familyBoss.GetRankList(bossId);
var maxHp = config.Hp;
LinkedList<(long, float)> contributeList = new LinkedList<(long, float)>();
foreach (var damageInfo in rank)
{
var percent = damageInfo.TotalDamage * 1f / maxHp / damageInfo.DamageList.Count;
foreach (var memberMap in damageInfo.DamageList)
{
ModifyList(contributeList, memberMap.Id, percent);
}
}
bool isKilled = familyBoss.GetBossHp(bossId) <= 0;
Family family = await FamilyComponent.Instance.Query(familyBoss.name);
foreach (var (id, percent) in contributeList)
{
if (!family.Caintains(id))
continue;
int contribute = MathHelper.RoundToInt(config.Contribute * percent);
family.AddContribution(id, contribute);
PlayerData playerData;
int parentSetId = config.Dropasubset;
var unit = MapUnitComponent.Instance.Get(id);
if (unit == null)
{
playerData = await DBComponent.Instance.Query<PlayerData>(id);
parentSetId = playerData.UpdateDrop(config.Dropasubset);
await UnitHelper.SaveComponenet(playerData);
}
else
{
playerData = unit.GetComponent<PlayerData>();
parentSetId = playerData.UpdateDrop(config.Dropasubset);
await UnitHelper.SaveComponenet(playerData);
}
Parentset parentSet = ParentsetCategory.Instance.Get(parentSetId);
family.ClearReward(bossId, id);
foreach (var subSet in parentSet.SubsetArr)
{
SonSet sonSet = SonSetCategory.Instance.Get(subSet._Id);
(int itemId, int itemCount) = GetItemFormSet(sonSet.DropArr, percent, isKilled);
if (itemId == 0) continue;
family.AddReward(bossId, id, itemId, itemCount);
Log.Info($"【{UserComponent.Instance.Get(id)?.NickName}({id})】 掉落了【{BagHelper.GetName(itemId)}】X {itemCount}");
}
}
FamilyComponent.Instance.Save(family).Coroutine();
Log.Info($"是否击杀{bossId}阶boss {isKilled}");
int index = 0;
foreach (var (id, percent) in contributeList)
{
Log.Info($"rank [{++index}] : {id} {percent:p2}");
}
return null;
}
private static (int, int) GetItemFormSet(SonSet.Drop[] arr, float damagePercent, bool isKilled)
{
using var listComponent = ListComponent<int>.Create();
foreach (SonSet.Drop drop in arr)
{
if (drop._Id == 0)
{
float weight = isKilled ? 0.5f * drop.Weight : drop.Weight;
weight *= (2 - damagePercent * damagePercent);
listComponent.List.Add(MathHelper.RoundToInt(weight));
}
else
listComponent.List.Add(drop.Weight);
}
int index = MathHelper.GetProbabilityIndexByWeight(listComponent.List);
var item = arr[index];
return (item._Id, RandomHelper.RandomNumber(item.MinCount, item.MaxCount + 1));
}
private static void ModifyList(LinkedList<(long, float)> list, long id, float addValue)
{
var oldScord = 0f;
for (var item = list.First; item != null; item = item.Next)
{
if (item.Value.Item1 == id)
{
oldScord = item.Value.Item2;
list.Remove(item);
break;
}
}
oldScord += addValue;
LinkedListHelper.InsertToLinkedListAndSort(list, (id, oldScord), (t1, t2) => t1.Item2 > t2.Item2);
}
}
}