using System; using System.Collections; using System.Collections.Generic; using TableConfig; using UnityEngine; namespace Snxxz.UI { public class FairyGrabBossModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk { public List bosses { get; private set; } Dictionary> dropItemDict = new Dictionary>(); Dictionary> fairyGrabBossDict = new Dictionary>(); Dictionary bossProgressDict = new Dictionary(); public bool IsOpen { get { return dailyQuestModel.GetQuestState((int)DailyQuestType.FairyGrabBoss) == DailyQuestModel.DailyQuestState.Normal; } } public bool InActivityTime { get { DailyQuestOpenTime dailyQuestOpenTime; if (dailyQuestModel.TryGetOpenTime((int)DailyQuestType.FairyGrabBoss, out dailyQuestOpenTime)) { return dailyQuestOpenTime.InOpenTime() && dailyQuestOpenTime.IsValidServerOpenTime(); } return false; } } int m_SelectBoss = 0; public int selectBoss { get { return m_SelectBoss; } set { if (value != m_SelectBoss) { m_SelectBoss = value; if (bossSelectedEvent != null) { bossSelectedEvent(m_SelectBoss); } } } } public int surplusSeconds { get { DailyQuestOpenTime openTime; if (dailyQuestModel.TryGetOpenTime((int)DailyQuestType.FairyGrabBoss, out openTime)) { if (openTime.InOpenTime() && openTime.IsValidServerOpenTime()) { HourMinute hourMinute; if (openTime.TryGetTodayNearestOpenTime(out hourMinute)) { DateTime end = new DateTime(TimeUtility.Year, TimeUtility.Month, TimeUtility.Day, hourMinute.hourEnd, hourMinute.minuteEnd, 0); return (int)(end - TimeUtility.ServerNow).TotalSeconds; } } } return 0; } } public bool grabBossHintOpen { get; private set; } public int callMemberDuty { get; private set; } public int callMemberSeconds { get; private set; } private bool serverInited = false; //private DateTime lastQueryProgressTime = DateTime.Now; public event Action stateUpdate; public event Action bossSelectedEvent; public event Action bossHurtUpdate; public event Action bossProgressUpdate; public event Action bossAllProgressUpdate; public event Action bossGrabHintEvent; DailyQuestModel dailyQuestModel { get { return ModelCenter.Instance.GetModel(); } } DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel(); } } MapModel mapModel { get { return ModelCenter.Instance.GetModel(); } } BossHomeModel bossHomeModel { get { return ModelCenter.Instance.GetModel(); } } public override void Init() { ParseConfig(); StageManager.Instance.onStageLoadFinish += OnStageLoadFinish; DailyQuestActionTimer.Instance.RefreshDailyQuestState += RefreshDailyQuestState; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; GA_Hero.OnEnterOrExitArea += OnEnterOrExitArea; GAMgr.Instance.OnFightNpcRequest += OnFightNpcUpdate; //GAMgr.Instance.OnFightNpcRelease += OnFightNpcUpdate; PlayerDatas.Instance.PlayerDataRefreshInfoEvent += PlayerDataRefreshInfoEvent; SysNotifyMgr.Instance.sysNotifyEvent += SystemNotifyEvent; GlobalTimeEvent.Instance.secondEvent += SecondEvent; } public void OnBeforePlayerDataInitialize() { serverInited = false; bossAliveDict.Clear(); } public void OnPlayerLoginOk() { serverInited = true; } public override void UnInit() { StageManager.Instance.onStageLoadFinish -= OnStageLoadFinish; DailyQuestActionTimer.Instance.RefreshDailyQuestState -= RefreshDailyQuestState; GA_Hero.OnEnterOrExitArea -= OnEnterOrExitArea; GAMgr.Instance.OnFightNpcRequest -= OnFightNpcUpdate; //GAMgr.Instance.OnFightNpcRelease -= OnFightNpcUpdate; PlayerDatas.Instance.PlayerDataRefreshInfoEvent -= PlayerDataRefreshInfoEvent; SysNotifyMgr.Instance.sysNotifyEvent -= SystemNotifyEvent; GlobalTimeEvent.Instance.secondEvent -= SecondEvent; } private void PlayerDataRefreshInfoEvent(PlayerDataRefresh refreshType) { if (refreshType == PlayerDataRefresh.FBID) { RecheckGrabBoss(); } } private void OnEnterOrExitArea(MapArea.E_Type type, bool arg1) { if (type == MapArea.E_Type.Boss) { RecheckGrabBoss(); } } private void OnStageLoadFinish() { if (!(StageManager.Instance.CurrentStage is DungeonStage)) { grabBossHintOpen = false; fairyGrabBossHelps.Clear(); ClearGrabBossInfo(); } else { RecheckGrabBoss(); } } private void OnFightNpcUpdate(uint npcId) { if (bosses.Contains((int)npcId)) { RecheckGrabBoss(); } } void ClearGrabBossInfo() { fairyGrabBossDict.Clear(); bossProgressDict.Clear(); } public void RecheckGrabBoss() { if (!InActivityTime) { CloseGrabBossHint(); return; } if (PlayerDatas.Instance.hero == null) { CloseGrabBossHint(); return; } if (!MapArea.IsInMapArea(PlayerDatas.Instance.hero.CurMapArea, MapArea.E_Type.Boss)) { CloseGrabBossHint(); return; } var mapId = PlayerDatas.Instance.baseData.MapID; var grabBossLine = GeneralConfig.Instance.fairyGrabBossMapLines.ContainsKey(mapId) ? GeneralConfig.Instance.fairyGrabBossMapLines[mapId] : 0; if (PlayerDatas.Instance.baseData.FBID != grabBossLine) { CloseGrabBossHint(); return; } int bossId = 0; var list = GAMgr.Instance.GetTypeList(E_ActorClassType.NpcFightBoss); if (list != null) { for (int i = 0; i < list.Count; i++) { GA_NpcFightBoss bossActor = list[i] as GA_NpcFightBoss; if (bossActor != null && bosses.Contains(bossActor.NpcConfig.NPCID)) { bossId = bossActor.NpcConfig.NPCID; break; } } } if (bossId == 0) { CloseGrabBossHint(); return; } grabBossHintOpen = true; if (!WindowCenter.Instance.CheckOpen()) { WindowCenter.Instance.Open(); } if (bossGrabHintEvent != null) { bossGrabHintEvent(); } } void CloseGrabBossHint() { grabBossHintOpen = false; if (WindowCenter.Instance.CheckOpen()) { WindowCenter.Instance.CloseImmediately(); } if (bossGrabHintEvent != null) { bossGrabHintEvent(); } } private void RefreshDailyQuestState() { if (!InActivityTime) { ClearGrabBossInfo(); if (fairyGrabBossHelps.Count > 0) { fairyGrabBossHelps.Clear(); if (fairyGrabBossHelpUpdate != null) { fairyGrabBossHelpUpdate(); } } } RecheckGrabBoss(); if (stateUpdate != null) { stateUpdate(); } } private void OnFuncStateChangeEvent(int _id) { if (_id == 139) { RecheckGrabBoss(); } } void ParseConfig() { bosses = new List(); var configs = Config.Instance.GetAllValues(); for (int i = 0; i < configs.Count; i++) { bosses.Add(configs[i].NPCID); var itemArray = LitJson.JsonMapper.ToObject(configs[i].dropItems); List list = new List(); for (int k = 0; k < itemArray.Length; k++) { Item item = new Item() { id = itemArray[k][0], count = itemArray[k][1], bind = itemArray[k][2] == 1, }; list.Add(item); } dropItemDict.Add(configs[i].NPCID, list); } var config = Config.Instance.Get("FairyCallMember"); callMemberSeconds = int.Parse(config.Numerical1); callMemberDuty = int.Parse(config.Numerical2); } public bool TryGetDropItems(int bossId, out List dropItems) { return dropItemDict.TryGetValue(bossId, out dropItems); } /// /// 查询Boss伤害信息 /// /// /// 0-实时仙盟伤血 1-历史仙盟伤血 2-实时玩家伤血 3-历史玩家伤血 public void QueryGrabBossHurt(int bossId, int queryType,uint objId) { CA228_tagCMQueryFamilyBossHurt pak = new CA228_tagCMQueryFamilyBossHurt(); pak.NPCID = (uint)bossId; pak.QueryType = (byte)queryType; pak.ObjID = (uint)objId; GameNetSystem.Instance.SendInfo(pak); } public void UpdateBossHurt(HA715_tagMCFamilyBossHurtList package) { Dictionary dict = null; FairyGrabBossInfo fairyGrabBossInfo = null; if (!fairyGrabBossDict.TryGetValue((int)package.NPCID, out dict)) { dict = new Dictionary(); fairyGrabBossDict.Add((int)package.NPCID, dict); } if (!dict.TryGetValue(package.HurtType, out fairyGrabBossInfo)) { fairyGrabBossInfo = new FairyGrabBossInfo(); dict.Add(package.HurtType, fairyGrabBossInfo); } fairyGrabBossInfo.SetData(package); if (bossHurtUpdate != null) { bossHurtUpdate((int)package.NPCID, package.HurtType); } } public void QueryGrabBossProgress() { CAC04_tagCGQueryAllFamilyBossHurt pak = new CAC04_tagCGQueryAllFamilyBossHurt(); GameNetSystem.Instance.SendInfo(pak); } public void UpdateBossProgress(HAC10_tagGCAllFamilyBossHurtInfoList package) { for (int i = 0; i < package.NPCCount; i++) { var sBossProgress = package.NPCHurtInfo[i]; var bossProgress = new BossProgressInfo() { NPCID = (int)sBossProgress.NPCID, CurHP = (int)sBossProgress.CurHP, CurHPEx = (int)sBossProgress.CurHPEx, MaxHP = (int)sBossProgress.MaxHP, MaxHPEx = (int)sBossProgress.MaxHPEx, FamilyID = (int)sBossProgress.FamilyID, FamilyName = UIHelper.ServerStringTrim(sBossProgress.FamilyName), }; bossProgressDict[(int)package.NPCHurtInfo[i].NPCID] = bossProgress; if (bossProgressUpdate != null) { bossProgressUpdate(bossProgress.NPCID); } } if (bossAllProgressUpdate != null) { bossAllProgressUpdate(); } } public bool TryGetBossProgress(int bossId,out BossProgressInfo bossProgressInfo) { return bossProgressDict.TryGetValue(bossId, out bossProgressInfo); } public bool TryGetBossHurt(int bossId, int queryType, out FairyGrabBossInfo fairyGrabBossInfo) { fairyGrabBossInfo = null; if (fairyGrabBossDict.ContainsKey(bossId)) { return fairyGrabBossDict[bossId].TryGetValue(queryType, out fairyGrabBossInfo); } return false; } /// /// 只给地图界面用,谨慎使用 /// /// /// public bool TryGetFairyGrabBossLine(out int lineId) { lineId = 0; var mapId = PlayerDatas.Instance.baseData.MapID; var mapLinesDict = GeneralConfig.Instance.fairyGrabBossMapLines; if (mapLinesDict != null && mapLinesDict.ContainsKey(mapId)) { lineId = mapLinesDict[mapId]; return true; } return false; } public bool TestEnterDungeon(int bossId, out int _error) { if (!InActivityTime) { _error = 3; return false; } if (!PlayerDatas.Instance.fairyData.HasFairy) { _error = 1; return false; } if (!FuncOpen.Instance.IsFuncOpen(139)) { _error = 2; return false; } var config = Config.Instance.Get(bossId); if (config != null) { if (!mapModel.IsMapUnlocked(config.MapID)) { _error = 6; return false; } } var mapId = PlayerDatas.Instance.baseData.MapID; var mapConfig = Config.Instance.Get(mapId); if (mapConfig.MapFBType != (int)MapType.OpenCountry) { _error = 5; return false; } var dataMapId = dungeonModel.GetDataMapIdByMapId(mapId); if (dataMapId == BossHomeModel.BOSSHOME_MAPID || dataMapId == ElderGodAreaModel.ELDERGODAREA_MAPID) { _error = 4; return false; } _error = 0; return true; } public void DisplayErrorTip(int error) { switch (error) { case 1: SysNotifyMgr.Instance.ShowTip("FairyGrabBossNoFairy"); break; case 3: SysNotifyMgr.Instance.ShowTip("FairyGrabBossUnOpen"); break; case 2: FuncOpen.Instance.ProcessorFuncErrorTip(139); break; case 4: var dataMapId = dungeonModel.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID); var config = Config.Instance.Get(dataMapId); var tip = string.Empty; if (dataMapId == BossHomeModel.BOSSHOME_MAPID) { var vipLevel = PlayerDatas.Instance.baseData.VIPLv; var vipNeed = bossHomeModel.GetFloorVipRequirement(PlayerDatas.Instance.baseData.dungeonLineId + 1); if (vipLevel < vipNeed) { var moneyNeed = bossHomeModel.GetVipLackCost(PlayerDatas.Instance.baseData.dungeonLineId + 1); var dungeonId = dungeonModel.GetDungeonId(BossHomeModel.BOSSHOME_MAPID, PlayerDatas.Instance.baseData.dungeonLineId); var dungeonConfig = Config.Instance.Get(dungeonId); tip = Language.Get("QuitRemindBossHome", dungeonConfig.FBName, vipNeed, moneyNeed); } else { tip = Language.Get(config.ExitDescription); } } else { tip = Language.Get(config.ExitDescription); } ConfirmCancel.ShowPopConfirm( Language.Get("Mail101"), tip, (bool _ok) => { if (_ok) { WindowCenter.Instance.Close(); MapTransferUtility.Instance.MoveToNPC(selectBoss); } } ); break; case 5: SysNotifyMgr.Instance.ShowTip("InDungeon_CantGo"); break; case 6: SysNotifyMgr.Instance.ShowTip("Map_Delivery"); break; } } private void SecondEvent() { if (helpCoolDown && fairyGrabBossHelps.Count > 0) { var help = fairyGrabBossHelps[0]; help.seconds--; if (help.seconds <= 0) { fairyGrabBossHelps.RemoveAt(0); if (fairyGrabBossHelpUpdate != null) { fairyGrabBossHelpUpdate(); } } else { fairyGrabBossHelps[0] = help; } } } #region 召集弹窗 public bool helpCoolDown { get; set; } public List fairyGrabBossHelps = new List(); public event Action fairyGrabBossHelpUpdate; private void SystemNotifyEvent(string message, ArrayList arrayList) { if (message.Equals("FairyGrabBossHelp") && InActivityTime && PlayerDatas.Instance.baseData.Family != 0 && FuncOpen.Instance.IsFuncOpen(139)) { var npcId = 0; if (arrayList != null && arrayList.Count > 0) { int.TryParse(arrayList[0].ToString(), out npcId); } if (!bosses.Contains(npcId)) { return; } if (InAnyGrabBossArea()) { return; } if (fairyGrabBossHelps.FindIndex((x) => { return x.npcId == npcId; }) != -1) { return; } fairyGrabBossHelps.Add(new FairyGrabBossHelp() { npcId = npcId, seconds = 20, }); if (fairyGrabBossHelpUpdate != null) { fairyGrabBossHelpUpdate(); } } } public bool IsBossAlive(int npcId) { return bossAliveDict.ContainsKey(npcId) && bossAliveDict[npcId]; } Dictionary bossAliveDict = new Dictionary(); public void UpdateBossAlive(HA902_tagGCGameWorldBossInfo package) { for (int i = 0; i < package.BossCnt; i++) { var data = package.BossInfoList[i]; bossAliveDict[(int)data.BossID] = data.IsAlive == 1; } } public void RemoveHelp() { if (fairyGrabBossHelps.Count > 0) { fairyGrabBossHelps.RemoveAt(0); if (fairyGrabBossHelpUpdate != null) { fairyGrabBossHelpUpdate(); } } } public bool InAnyGrabBossArea() { if (!MapArea.IsInMapArea(PlayerDatas.Instance.hero.CurMapArea, MapArea.E_Type.Boss)) { return false; } var mapId = PlayerDatas.Instance.baseData.MapID; var grabBossLine = GeneralConfig.Instance.fairyGrabBossMapLines.ContainsKey(mapId) ? GeneralConfig.Instance.fairyGrabBossMapLines[mapId] : 0; if (PlayerDatas.Instance.baseData.FBID != grabBossLine) { return false; } int bossId = 0; var list = GAMgr.Instance.GetTypeList(E_ActorClassType.NpcFightBoss); if (list != null) { for (int i = 0; i < list.Count; i++) { GA_NpcFightBoss bossActor = list[i] as GA_NpcFightBoss; if (bossActor != null && bosses.Contains(bossActor.NpcConfig.NPCID)) { bossId = bossActor.NpcConfig.NPCID; break; } } } return bossId != 0; } public struct FairyGrabBossHelp { public int npcId; public int seconds { get; set; } } #endregion public class FairyGrabBossInfo { public int npcId { get; private set; } public int objId { get; private set; } public int hurtType { get; private set; } public int IsSort { get; private set; } public List hurtInfos = new List(); public void SetData(HA715_tagMCFamilyBossHurtList package) { npcId = (int)package.NPCID; objId = (int)package.ObjID; hurtType = package.HurtType; IsSort = package.IsSort; hurtInfos.Clear(); for (int i = 0; i < package.HurtCount; i++) { var sHurt = package.HurtList[i]; var hurtInfo = new BossHurtInfo() { FamilyID = (int)sHurt.FamilyID, HurtID = (int)sHurt.HurtID, HurtName = UIHelper.ServerStringTrim(sHurt.HurtName), HurtValue = (int)sHurt.HurtValue, HurtValueEx = (int)sHurt.HurtValueEx, InitTick = sHurt.InitTick, }; hurtInfos.Add(hurtInfo); } if (IsSort != 1) { hurtInfos.Sort(Compare); } } int Compare(BossHurtInfo x, BossHurtInfo y) { if (x.totalHurt != y.totalHurt) { return -x.totalHurt.CompareTo(y.totalHurt); } return x.InitTick.CompareTo(y.InitTick); } } public struct BossHurtInfo { public int FamilyID; public int HurtID; // 伤血的ID, 根据伤血类型表示不同的ID, 如仙盟ID或玩家ID public string HurtName; public int HurtValue; // 累计伤血,求余1亿的值 public int HurtValueEx; // 累计伤血,整除1亿的值 public uint InitTick; // 伤血初始tick,用于排序,先按伤血倒序排,再按tick正序排 public long totalHurt { get { return HurtValue + (long)HurtValueEx * Constants.ExpPointValue; } } } public struct BossProgressInfo { public int NPCID; public int CurHP; public int CurHPEx; public int MaxHP; public int MaxHPEx; public int FamilyID; public string FamilyName; public long currentHp { get { return CurHP + (long)CurHPEx * Constants.ExpPointValue; } } public long totalHp { get { return MaxHP + (long)MaxHPEx * Constants.ExpPointValue; } } } } }