using System; using System.Collections.Generic; using LitJson; public class GuildBossManager : GameSystemManager { public Dictionary bossActions = new Dictionary(); // 玩家伤害排行 public List playerBossHurtRank = new List(); //时间戳:讨伐数据; 用于播放每次攻击 public Dictionary taofaAtkData = new Dictionary(); //按时间顺序播放,当前播放的tick,如果找不到则从第一个开始 public int lastPlayTick { get { return LocalSave.GetInt("lastPlayTick" + PlayerDatas.Instance.baseData.PlayerID); } set { LocalSave.SetInt("lastPlayTick" + PlayerDatas.Instance.baseData.PlayerID, value); } } //玩家ID:玩家数据 (退出公会的玩家) public Dictionary taofaPlayerData = new Dictionary(); public event Action BossHurtEvent; //自己的数据 public byte m_BuZhenState; // 是否已布阵 public ushort m_AtkCount; // 已斩杀次数,用于计算剩余次数=免费次数+道具增加次数-已斩杀次数 public ushort m_ItemAddCount; // 道具增加斩杀次数 public ushort m_Anger; // 当前怒气值 public ushort m_BoxUnGetCount; // 当前未领取的宝箱数,即可领取的 public long m_BoxHurt; // 今日伤害 public long m_BoxHurtHis; // 历史伤害 //攻击数据 public HA504_tagSCFamilyTaofaAtkRet atkResult; public event Action AtkResultEvent; //配置 public int initSuperHitRate; public int[] bzAddAttrs; public int bzMaxLevel; public int freeAtkCount; public int[][] atkItemList; public int maxAngerValue; long[] bxCumulativeDamageList; public List allBXCumulativeDamageList = new List(); public int bxDailyMax; //个人每日产出上限 public long lastDmgAddValue; // 最后一档伤害增值循环用 public int addAtkCntItemID = 17; //增加讨伐次数道具ID public int bossSkinID = 7100300; void ParseConfig() { // 数值1:初始暴击率万分率,功能独立的暴击率,与角色暴击无关 // 数值3:布阵最大层级 var config = FuncConfigConfig.Get("FamilyTaofaBuzhen"); initSuperHitRate = int.Parse(config.Numerical1); bzAddAttrs = ConfigParse.GetMultipleStr(config.Numerical2); bzMaxLevel = int.Parse(config.Numerical3); // 数值1:每日免费斩杀次数 // 数值2:每次普通斩杀获得个人奖励列表 [[物品ID,个数], ...] // 数值4:常规斩杀增加怒气|暴击斩杀增加怒气|满怒气值 config = FuncConfigConfig.Get("FamilyTaofaAtk"); freeAtkCount = int.Parse(config.Numerical1); atkItemList = JsonMapper.ToObject(config.Numerical2); maxAngerValue = int.Parse(config.Numerical4.Split('|')[2]); // 数值1:产出宝箱的累计伤害列表 [宝箱1所需累计伤害, ...],最后一档伤害可以循环产出,直到当日的贡献宝箱上限 // 数值2:每日个人贡献宝箱数上限,最后一档可循环,上限控制 // 数值3:每日个人领取宝箱奖励个数上限 config = FuncConfigConfig.Get("FamilyTaofaBox"); bxCumulativeDamageList = JsonMapper.ToObject(config.Numerical1); bxDailyMax = int.Parse(config.Numerical2); lastDmgAddValue = bxCumulativeDamageList[bxCumulativeDamageList.Length - 1] - bxCumulativeDamageList[bxCumulativeDamageList.Length - 2]; //最后一档循环 for (int i = 0; i < bxDailyMax; i++) { if (i < bxCumulativeDamageList.Length) { allBXCumulativeDamageList.Add(bxCumulativeDamageList[i]); } else { allBXCumulativeDamageList.Add(allBXCumulativeDamageList[i - 1] + lastDmgAddValue); } } } public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent; ParseConfig(); } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin; GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent; } void OnBeforePlayerDataInitializeEventOnRelogin() { bossActions.Clear(); playerBossHurtRank.Clear(); m_BuZhenState = 0; m_AtkCount = 0; m_ItemAddCount = 0; m_Anger = 0; m_BoxUnGetCount = 0; m_BoxHurt = 0; m_BoxHurtHis = 0; taofaAtkData.Clear(); taofaPlayerData.Clear(); } void EnterOrQuitGuildEvent(bool isEnter) { if (!isEnter) { bossActions.Clear(); playerBossHurtRank.Clear(); taofaAtkData.Clear(); taofaPlayerData.Clear(); } UpdateRedpoint(); } //// 操作:0-斩杀攻击;1-布阵 public void TaofaBoss(int opType) { var pack = new CA613_tagCSFamilyTaofaOP(); pack.OpType = (byte)opType; GameNetSystem.Instance.SendInfo(pack); } public void UpdataMyBossData(HA503_tagSCFamilyTaofaInfo netPack) { m_BuZhenState = netPack.BuZhenState; m_AtkCount = netPack.AtkCount; m_ItemAddCount = netPack.ItemAddCount; m_Anger = netPack.Anger; m_BoxUnGetCount = netPack.BoxUnGetCount; m_BoxHurt = netPack.BoxHurt + netPack.BoxHurtEx * Constants.ExpPointValue; m_BoxHurtHis = netPack.BoxHurtHis + netPack.BoxHurtHisEx * Constants.ExpPointValue; UpdateRedpoint(); BossHurtEvent?.Invoke(); } public void UpdateAtkResult(HA504_tagSCFamilyTaofaAtkRet netPack) { atkResult = netPack; AtkResultEvent?.Invoke(); } public int GetHasAtkCnt() { return freeAtkCount + m_ItemAddCount - m_AtkCount; } // 【公会行为】 // 增加行为类型18 - 公会讨伐相关数据 // Value1 玩家ID 或 全局ID,当该值等于1时代表该条数据记录的是讨伐全局数据,以下其他值根据Value1代表不同意思 // 玩家 全局 // Time 最后讨伐时间戳 重置时间戳,前端可用于判断是否变更了不同的讨伐(变更后,前端可重置讨伐相关缓存数据,GM重置会变更) // Value2 玩家布阵时间戳 布阵层级到期时间戳 // Value3 到本公会后攻击次数 当前有效布阵层级 // Value4 到本公会后累计伤害,求余亿部分 无 // Value5 到本公会后累计伤害,整除亿部分 无 // Value6 到本公会后贡献宝箱数 无 // UseData 到本公会后记录 无 // 成员记录格式: Json格式 {"atkList":[[atkTime, 本次贡献箱子数, 本次总伤害, atkType], ...], "info":{k:v, ...}} // atkList - 讨伐记录列表,可用于表现成员头像攻击: atkTime - 攻击时间戳, atkType - 攻击类型(0-普通攻击, 1-怒气攻击) // info - 不一定有该key,仅退出的成员才有,用于更新退出成员相关基础信息,如名字、头像等,还在公会里的成员通过 // A5 20 玩家家族信息 #tagMCRoleFamilyInfo 取成员信息 // "info":{"LV":106,"Job":1,"Name":"主公3016219","FacePic":0,"FightPower":1831995,"RealmLV":12,"ServerID":86,"TitleID":0,"Face":0}, // boss讨伐的全局数据 public HA513_tagMCFamilyActionInfo.tagMCFamilyAction GetGuildBossAction() { if (bossActions.ContainsKey(1)) { return bossActions[1]; } return null; } // 获取公会中的伤害记录做排名 public bool UpdateGuildBossInfo(HA513_tagMCFamilyActionInfo vNetData) { if (vNetData.ActionType != GuildManager.GuildBossActionType) { return false; } //判断是否新的公会数据 for (int i = 0; i < vNetData.Count; i++) { var playerID = (int)vNetData.FamilyActionList[i].Value1; if (playerID != 1) { continue; } if (bossActions.ContainsKey(1) && bossActions[1].Time != vNetData.FamilyActionList[0].Time) { bossActions.Clear(); playerBossHurtRank.Clear(); } } for (int i = 0; i < vNetData.Count; i++) { bossActions[(int)vNetData.FamilyActionList[i].Value1] = vNetData.FamilyActionList[i]; } SortPlayerHurt(); RefreshAtkList(); BossHurtEvent?.Invoke(); return true; } void SortPlayerHurt() { playerBossHurtRank.Clear(); foreach (var item in bossActions) { if (item.Value.Value1 != 1) { if (item.Value.Value4 == 0 && item.Value.Value5 == 0) { continue; } playerBossHurtRank.Add(item.Value); } } playerBossHurtRank.Sort((a, b) => (b.Value4 + b.Value5 * Constants.ExpPointValue).CompareTo(a.Value4 + a.Value5 * Constants.ExpPointValue)); } //解析攻击记录 和 玩家信息(退出公会的) void RefreshAtkList() { //{"atkList":[[atkTime, 本次贡献箱子数, 本次总伤害, atkType], ...], "info":{k:v, ...}} //"info":{"LV":106,"Job":1,"Name":"主公3016219","FacePic":0,"FightPower":1831995,"RealmLV":12,"ServerID":86,"TitleID":0,"Face":0}, taofaAtkData.Clear(); taofaPlayerData.Clear(); foreach (var item in playerBossHurtRank) { JsonData jsonData = JsonMapper.ToObject(item.UseData); if (!jsonData.ContainsKey("atkList")) { continue; } var arr = JsonMapper.ToObject(jsonData["atkList"].ToJson()); for (int i = 0; i < arr.Length; i++) { taofaAtkData[(int)arr[i][0]] = new TaofaAtkData() { playerID = (int)item.Value1, atkType = (int)arr[i][3], hurt = arr[i][2], }; } if (jsonData.ContainsKey("info")) { taofaPlayerData[(int)item.Value1] = JsonMapper.ToObject(jsonData["info"].ToJson()); } } } // 获取我的排名 public int GetMyRank() { int rank = 0; for (int i = 0; i < playerBossHurtRank.Count; i++) { if (playerBossHurtRank[i].Value1 == PlayerDatas.Instance.baseData.PlayerID) { rank = i + 1; break; } } return rank; } //获取成员外观数据 头像名字等 public MemberData GetMemberData(int playerId) { var playerInfo = PlayerDatas.Instance.fairyData.GetMember(playerId); if (playerInfo == null) { return taofaPlayerData.ContainsKey(playerId) ? taofaPlayerData[playerId] : null; } return new MemberData() { LV = playerInfo.LV, Job = playerInfo.Job, Name = playerInfo.Name, FacePic = playerInfo.FacePic, FightPower = (ulong)playerInfo.FightPower, RealmLV = playerInfo.RealmLV, ServerID = playerInfo.ServerID, TitleID = playerInfo.TitleID, Face = playerInfo.Face }; } #region 红点 Redpoint redPoint = new Redpoint(MainRedDot.MainGuildRedpoint, MainRedDot.bossTaofaRedpointID); void UpdateRedpoint() { redPoint.state = RedPointState.None; if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Guild)) { return; } if (PlayerDatas.Instance.fairyData.fairy == null) { return; } if (m_BuZhenState == 0) { redPoint.state = RedPointState.Simple; return; } if (GetHasAtkCnt() > 0) { redPoint.state = RedPointState.Simple; return; } if (m_BoxUnGetCount > 0) { redPoint.state = RedPointState.Simple; return; } } #endregion } public class TaofaAtkData { public int playerID; public int atkType; public long hurt; } public class MemberData { public int LV; public int Job; public string Name; public int FacePic; public ulong FightPower; public int RealmLV; public int ServerID; public int TitleID; public int Face; }