using Cal.DataTable; using ET.EventType; using System; using System.Collections.Generic; namespace ET { public class FamilyBossComponentAwakeSystem : AwakeSystem { public override void Awake(FamilyBossComponent self) { FamilyBossComponent.instance = self; } } public static class FamilyBossComponentSystem { public class FamilyUpdatePerMinuteEvent : AEvent { public override async ETTask Run(UpdatePer1HourOfDay args) { int time = DateTime.UtcNow.Hour; if (time != 14) return; List list = await DBComponent.Instance.QueryJson("{}"); if (list == null || list.Count == 0) { return; } IEnumerable bossList = DataTableHelper.GetAll(); foreach (FamilyBoss familyBoss in list) { try { foreach (FamilyBossConfig config in bossList) { FamilyBossComponent.instance.SettleReword(familyBoss, config).Coroutine(); } } catch (Exception e) { Log.Error(e); } } await ETTask.CompletedTask; } } public class FamilyUpdatePerDayEvent : AEvent { public override async ETTask Run(UpdatePer1DayOfMonth args) { List list = await DBComponent.Instance.QueryJson("{}"); if (list == null || list.Count == 0) { return; } IEnumerable bossList = DataTableHelper.GetAll(); foreach (FamilyBoss familyBoss in list) { try { foreach (FamilyBossConfig boss in bossList) { try { familyBoss.SetBossHp((int)boss.Id, boss.Hp); } catch (Exception e) { Log.Error(e); } } foreach (KeyValuePair> 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); } } Dictionary dic = FamilyBossComponent.instance.familyBossDic; Dictionary.ValueCollection _list = dic.Values; dic.Clear(); foreach (FamilyBoss item in _list) { item.Dispose(); } Log.Info($"更改boss血量"); await ETTask.CompletedTask; } } public static async ETTask Query(this FamilyBossComponent self, string name) { if (string.IsNullOrWhiteSpace(name)) return null; if (!self.familyBossDic.TryGetValue(name, out FamilyBoss friend)) { List list = await DBComponent.Instance.Query(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(self); familyBoss.lockedMaxId = 1; familyBoss.name = name; if (familyBoss.rankDic.Count == 0) { IEnumerable arr = DataTableHelper.GetAll(); foreach (FamilyBossConfig item in arr) { familyBoss.rankDic.Add((int)item.Id, new LinkedList()); familyBoss.SetBossHp((int)item.Id, item.Hp); } } self.familyBossDic.Add(name, familyBoss); await self.Save(familyBoss); } public static async ETTask GetFamilyBossInfo(this FamilyBossComponent self, Unit unit, System.Collections.Generic.List 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 (KeyValuePair kv in familyBoss.bossHpDic) { FamilyBossConfig familyBossConfig = DataTableHelper.Get(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 GetRankList(this FamilyBossComponent self, Unit unit, int bossId, System.Collections.Generic.List 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 SettleReword(this FamilyBossComponent self, FamilyBoss familyBoss, FamilyBossConfig config) { if (familyBoss == null) { Log.Error($"familyBoss == null"); return "系统错误!"; } int bossId = (int)config.Id; LinkedList rank = familyBoss.GetRankList(bossId); int maxHp = config.Hp; LinkedList<(long, float)> contributeList = new LinkedList<(long, float)>(); foreach (BossDamageMap damageInfo in rank) { float percent = damageInfo.TotalDamage * 1f / maxHp / damageInfo.DamageList.Count; foreach (BossDamagePerMemberMap memberMap in damageInfo.DamageList) { ModifyList(contributeList, memberMap.Id, percent); } } bool isKilled = familyBoss.GetBossHp(bossId) <= 0; Family family = await FamilyComponent.Instance.Query(familyBoss.name); foreach ((long id, float 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; Unit unit = MapUnitComponent.Instance.Get(id); if (unit == null) { playerData = await DBComponent.Instance.Query(id); parentSetId = playerData.UpdateDrop(config.Dropasubset); await UnitHelper.SaveComponenet(playerData); } else { playerData = unit.GetComponent(); parentSetId = playerData.UpdateDrop(config.Dropasubset); await UnitHelper.SaveComponenet(playerData); } Parentset parentSet = ParentsetCategory.Instance.Get(parentSetId); family.ClearReward(bossId, id); foreach (Parentset.Subset 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 ((long id, float 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 ListComponent listComponent = ListComponent.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); SonSet.Drop 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) { float oldScord = 0f; for (LinkedListNode<(long, float)>? 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); } } }