311 lines
12 KiB
C#
Executable File
311 lines
12 KiB
C#
Executable File
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)
|
||
{
|
||
int time = DateTime.UtcNow.Hour;
|
||
Log.Info($"{DateTime.UtcNow}");
|
||
if (time != 14) return;
|
||
List<FamilyBoss> list = await DBComponent.Instance.QueryJson<FamilyBoss>("{}");
|
||
if (list == null || list.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
IEnumerable<FamilyBossConfig> bossList = DataTableHelper.GetAll<FamilyBossConfig>();
|
||
foreach (FamilyBoss familyBoss in list)
|
||
{
|
||
try
|
||
{
|
||
foreach (FamilyBossConfig config in bossList)
|
||
{
|
||
await FamilyBossComponent.instance.SettleReword(familyBoss, config);
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
}
|
||
}
|
||
|
||
await ETTask.CompletedTask;
|
||
}
|
||
}
|
||
|
||
public class FamilyUpdatePerDayEvent: AEvent<EventType.UpdatePer1DayOfMonth>
|
||
{
|
||
public override async ETTask Run(UpdatePer1DayOfMonth args)
|
||
{
|
||
List<FamilyBoss> list = await DBComponent.Instance.QueryJson<FamilyBoss>("{}");
|
||
if (list == null || list.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
IEnumerable<FamilyBossConfig> bossList = DataTableHelper.GetAll<FamilyBossConfig>();
|
||
foreach (FamilyBoss familyBoss in list)
|
||
{
|
||
try
|
||
{
|
||
foreach (FamilyBossConfig boss in bossList)
|
||
{
|
||
try
|
||
{
|
||
MonsterBase monsterBase = MonsterBaseCategory.Instance.Get(boss.MonsterId);
|
||
familyBoss.SetBossHp((int) boss.Id, monsterBase.Hp);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Log.Error(e);
|
||
}
|
||
}
|
||
|
||
foreach (KeyValuePair<int, LinkedList<BossDamageMap>> 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<string, FamilyBoss> dic = FamilyBossComponent.instance.familyBossDic;
|
||
Dictionary<string, FamilyBoss>.ValueCollection _list = dic.Values;
|
||
dic.Clear();
|
||
foreach (FamilyBoss 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 FamilyBoss friend))
|
||
{
|
||
List<FamilyBoss> 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)
|
||
{
|
||
IEnumerable<FamilyBossConfig> arr = DataTableHelper.GetAll<FamilyBossConfig>();
|
||
foreach (FamilyBossConfig item in arr)
|
||
{
|
||
familyBoss.rankDic.Add((int) item.Id, new LinkedList<BossDamageMap>());
|
||
MonsterBase monsterBase = MonsterBaseCategory.Instance.Get(item.MonsterId);
|
||
familyBoss.SetBossHp((int) item.Id, monsterBase.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 (KeyValuePair<int, int> kv in familyBoss.bossHpDic)
|
||
{
|
||
FamilyBossConfig familyBossConfig = DataTableHelper.Get<FamilyBossConfig>(kv.Key);
|
||
MonsterBase monsterBase = MonsterBaseCategory.Instance.Get(familyBossConfig.MonsterId);
|
||
bossInfoList.Add(
|
||
new BossInfo { Index = kv.Key, Hp = kv.Value, MaxHp = monsterBase.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 "系统错误!";
|
||
}
|
||
Log.Info($"开始结算 {familyBoss.name}");
|
||
|
||
int bossId = (int) config.Id;
|
||
|
||
bool isKilled = familyBoss.GetBossHp(bossId) <= 0;
|
||
Family family = await FamilyComponent.Instance.Query(familyBoss.name);
|
||
if (family==null)
|
||
{
|
||
Log.Error($"family == null where {familyBoss.name}");
|
||
return "系统错误!";
|
||
}
|
||
family.ClearReward(bossId);
|
||
|
||
|
||
LinkedList<BossDamageMap> rank = familyBoss.GetRankList(bossId);
|
||
MonsterBase monsterBase = MonsterBaseCategory.Instance.Get(config.MonsterId);
|
||
int maxHp = monsterBase.Hp;
|
||
LinkedList<(long, float)> contributeList = new LinkedList<(long, float)>();
|
||
foreach (BossDamageMap damageInfo in rank)
|
||
{
|
||
float totalPercent = damageInfo.TotalDamage * 1f / maxHp;
|
||
if(totalPercent<0.025f)
|
||
continue;
|
||
float percent = totalPercent / damageInfo.DamageList.Count;
|
||
foreach (BossDamagePerMemberMap memberMap in damageInfo.DamageList)
|
||
{
|
||
ModifyList(contributeList, memberMap.Id, percent);
|
||
|
||
int personalContribute = MathHelper.RoundToInt(config.PersonalContribute * totalPercent);
|
||
family.AddReward(bossId, memberMap.Id, BagHelper.FamilyCoinId, personalContribute);
|
||
}
|
||
}
|
||
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<PlayerData>(id);
|
||
parentSetId = playerData.UpdateDrop(config.Dropasubset);
|
||
UnitHelper.SaveComponenet(self.DomainZone(), playerData);
|
||
}
|
||
else
|
||
{
|
||
playerData = unit.GetComponent<PlayerData>();
|
||
parentSetId = playerData.UpdateDrop(config.Dropasubset);
|
||
UnitHelper.SaveComponenet(self.DomainZone(), playerData);
|
||
}
|
||
|
||
Parentset parentSet = ParentsetCategory.Instance.Get(parentSetId);
|
||
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}");
|
||
|
||
return null;
|
||
}
|
||
|
||
private static (int, int) GetItemFormSet(SonSet.Drop[] arr, float damagePercent, bool isKilled)
|
||
{
|
||
using ListComponent<int> 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);
|
||
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);
|
||
}
|
||
}
|
||
} |