using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Linq;
|
using Jace.Operations;
|
using LitJson;
|
|
using UnityEngine;
|
|
//武将相关界面的操作数据管理
|
public partial class HeroUIManager : GameSystemManager<HeroUIManager>
|
{
|
#region 武将列表界面
|
public List<string> heroSortList { get; private set; } = new List<string>(); //上阵为主线的 GUID列表
|
public List<int> selectHeroList = new List<int>(); //武将列表界面 筛选职业
|
public string selectHeroGuid; //选中的武将id
|
public int[] heroRedpointItemList; //有影响红点的道具
|
#endregion
|
|
public WaitHeroFuncResponse waitResponse; //请求武将功能,与服务端交互
|
|
//用于非上阵武将战力变化时 武将ID:上次战力
|
//使用方法:其他功能界面设置该值即可
|
public KeyValuePair<string, long> lastFightPower = new KeyValuePair<string, long>();
|
|
public bool isCustonHeroFormation = false;
|
public List<TeamHero> custonTeamHeroes = new List<TeamHero>();
|
|
public Dictionary<int, int> heroStarGuideDic = new Dictionary<int, int>();
|
|
public int firstHeroIDBookUpdate = 0; //图鉴中第一个可以升级或者升星的武将,引导用
|
|
public List<int> heroSpecialAttrsForSelect = new List<int>(); //筛选用的特殊属性汇总
|
|
public bool isOpenHeroTip = false;
|
|
public override void Init()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
|
DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnLoginLoadOK;
|
HeroManager.Instance.onHeroChangeEvent += OnHeroChangeEvent;
|
GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
|
PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
|
TeamManager.Instance.OnTeamChange += OnTeamChangeEvent;
|
QuickSetting.Instance.onQuickSettingUpdate += OnQuickSettingUpdate;
|
ParseConfig();
|
InitHeroOnTeamRedpointList();
|
InitHerosData();
|
}
|
|
public override void Release()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
|
DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnLoginLoadOK;
|
HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent;
|
GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
|
PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
|
TeamManager.Instance.OnTeamChange -= OnTeamChangeEvent;
|
QuickSetting.Instance.onQuickSettingUpdate -= OnQuickSettingUpdate;
|
}
|
|
void ParseConfig()
|
{
|
var config = FuncConfigConfig.Get("HeroRebirth");
|
payBackMoneyType = int.Parse(config.Numerical1);
|
rebornAwakeHeroMaxCount = int.Parse(config.Numerical2);
|
rebornFormula = config.Numerical3;
|
rebornPayBackPer = int.Parse(config.Numerical4);
|
deletePayBackPer = int.Parse(config.Numerical5);
|
|
ParseGiftConfig();
|
|
config = FuncConfigConfig.Get("HeroRedpoint");
|
heroRedpointItemList = JsonMapper.ToObject<int[]>(config.Numerical1);
|
|
config = FuncConfigConfig.Get("HeroOnTeam");
|
lockHeroCountLimit = JsonMapper.ToObject<int[][]>(config.Numerical1);
|
teamSortByJob = JsonMapper.ToObject<int[]>(config.Numerical2);
|
onekeyGuideID = int.Parse(config.Numerical3);
|
onekeyGuidePosList = JsonMapper.ToObject<int[]>(config.Numerical4);
|
|
config = FuncConfigConfig.Get("Guide");
|
heroStarGuideDic = ConfigParse.ParseIntDict(config.Numerical1);
|
|
config = FuncConfigConfig.Get("HeroDelete");
|
jumpDeleteHeroQuality = int.Parse(config.Numerical1);
|
isJumpDeleteHero = int.Parse(config.Numerical2) == 1;
|
}
|
|
public void OnBeforePlayerDataInitialize()
|
{
|
heroSortList.Clear();
|
heroOnTeamSortList.Clear();
|
awakeRebirthCnt = 0;
|
waitResponse = default;
|
heroCollectInfoDic.Clear();
|
newHeroIDList.Clear();
|
firstHeroIDBookUpdate = 0;
|
isOpenHeroTip = false;
|
}
|
|
|
void OnLoginLoadOK()
|
{
|
UpdateHeroCardRedpoint();
|
}
|
|
private void OnHeroChangeEvent(HeroInfo hero)
|
{
|
if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
|
return;
|
|
WaitServerResponse(hero);
|
|
refreshRedPoint = true;
|
}
|
|
private void WaitServerResponse(HeroInfo hero)
|
{
|
if (waitResponse.Equals(default(WaitHeroFuncResponse)))
|
{
|
return;
|
}
|
// 等待超过5秒 不处理
|
var nowTime = Time.time;
|
if (waitResponse.time > 0f && waitResponse.time + 5 < nowTime)
|
{
|
waitResponse = default;
|
return;
|
}
|
|
if (hero.itemHero.guid != waitResponse.guid)
|
{
|
return;
|
}
|
|
if (waitResponse.type == HeroFuncType.Break)
|
{
|
UIManager.Instance.OpenWindow<HeroLVBreakSuccessWin>();
|
}
|
else if (waitResponse.type == HeroFuncType.Gift)
|
{
|
UIManager.Instance.OpenWindow<HeroGiftEatSuccessWin>();
|
}
|
else if (waitResponse.type == HeroFuncType.Awake)
|
{
|
var config = HeroAwakeConfig.GetHeroAwakeConfig(hero.heroId, hero.awakeLevel);
|
if (hero.talentAwakeRandomIDList.Count > 0)
|
{
|
UIManager.Instance.OpenWindow<HeroAwakeSelectGiftWin>();
|
}
|
else if (config.SkillID != 0 || config.UnlockTalentSlot != 0)
|
{
|
UIManager.Instance.OpenWindow<HeroAwakeSuccessWin>();
|
}
|
}
|
waitResponse = default;
|
|
}
|
|
#region 武将UI常用接口
|
public string GetCountryName(int index)
|
{
|
return RichTextMsgReplaceConfig.GetRichReplace("Country", index);
|
}
|
|
public string GetJobName(int index)
|
{
|
return RichTextMsgReplaceConfig.GetRichReplace("Class", index);
|
}
|
|
public string GetCountryIconName(int index)
|
{
|
return StringUtility.Concat("herocountry", index.ToString());
|
}
|
|
public string GetJobIconName(int index)
|
{
|
return StringUtility.Concat("herojob", index.ToString());
|
}
|
|
public int GetMaxLV(int quality)
|
{
|
return HeroQualityLVConfig.maxlvDic[quality];
|
}
|
|
//是否达到最高级
|
public bool IsLVMax(HeroInfo hero)
|
{
|
return hero.heroLevel >= GetMaxLV(hero.Quality);
|
|
}
|
//突破所需等级
|
public int GetNeedLVByBreakLV(int quality, int breakLevel)
|
{
|
return HeroQualityBreakConfig.GetQualityBreakConfig(quality, breakLevel).UPLVNeed;
|
}
|
|
//是否达到可突破的条件
|
public bool IsCanBreak(HeroInfo hero, int showTip = 0)
|
{
|
if (hero.heroLevel < GetNeedLVByBreakLV(hero.Quality, hero.breakLevel))
|
{
|
//等级未达标
|
if (showTip != 0)
|
{
|
SysNotifyMgr.Instance.ShowTip("HeroLVNotEnough");
|
}
|
return false;
|
}
|
if (hero.breakLevel >= HeroBreakConfig.GetMaxBreakLv(hero.heroId))
|
{
|
//突破等级已达最高级
|
return false;
|
}
|
|
//材料是否足够
|
|
var breakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(hero.Quality, hero.breakLevel);
|
for (int i = 0; i < breakConfig.UPCostItemList.Length; i++)
|
{
|
if (!ItemLogicUtility.CheckItemCount(PackType.Item, breakConfig.UPCostItemList[i][0], breakConfig.UPCostItemList[i][1], showTip))
|
{
|
return false;
|
}
|
}
|
return true;
|
}
|
|
public int GetAllHeroPer()
|
{
|
var list = HeroManager.Instance.GetHeroList();
|
int per = 0;
|
foreach (var hero in list)
|
{
|
if (hero.isAttrActive)
|
{
|
per += hero.GetAddPer();
|
}
|
}
|
return per;
|
}
|
|
#endregion
|
|
|
public void QueryUnLockHeroPack()
|
{
|
//解锁更多的武将背包
|
int canBuyCnt = PackManager.Instance.GetCanBuyPackGirdCount(PackType.Hero);
|
if (canBuyCnt <= 0)
|
{
|
return;
|
}
|
|
var buyInfo = PackManager.Instance.BuyPackGirdNeedData(PackType.Hero);
|
ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"),
|
Language.Get("HeroPack1", UIHelper.GetIconNameWithMoneyType(buyInfo[0]), buyInfo[1], buyInfo[2]),
|
(bool isOK) =>
|
{
|
if (isOK)
|
{
|
if (UIHelper.GetMoneyCnt(buyInfo[0]) < buyInfo[1])
|
{
|
SysNotifyMgr.Instance.ShowTip("LackMoney", buyInfo[0]);
|
return;
|
}
|
PackManager.Instance.BuyPackGird(PackType.Hero);
|
}
|
});
|
}
|
|
//刷新时机, 打开武将界面 或者 关闭功能界面
|
public void SortHeroList()
|
{
|
heroSortList = HeroManager.Instance.GetHeroGuidList(selectHeroList);
|
heroSortList.Sort(CmpHero);
|
}
|
|
|
int CmpHero(string guidA, string guidB)
|
{
|
HeroInfo heroA = HeroManager.Instance.GetHero(guidA);
|
HeroInfo heroB = HeroManager.Instance.GetHero(guidB);
|
if (heroA == null || heroB == null)
|
{
|
return 0;
|
}
|
|
bool isActiveA = heroA.isAttrActive;
|
bool isActiveB = heroB.isAttrActive;
|
if (isActiveA != isActiveB)
|
{
|
return isActiveA ? -1 : 1;
|
}
|
|
// 排序规则:上阵>武将等级>突破等级>武将觉醒阶级>武将品质>武将吞噬星级>武将ID
|
bool isInTeamA = heroA.IsInTeamByTeamType(TeamType.Story);
|
bool isInTeamB = heroB.IsInTeamByTeamType(TeamType.Story);
|
if (isInTeamA != isInTeamB)
|
{
|
return isInTeamA ? -1 : 1;
|
}
|
if (heroA.heroLevel != heroB.heroLevel)
|
{
|
return heroA.heroLevel > heroB.heroLevel ? -1 : 1;
|
}
|
if (heroA.breakLevel != heroB.breakLevel)
|
{
|
return heroA.breakLevel > heroB.breakLevel ? -1 : 1;
|
}
|
if (heroA.awakeLevel != heroB.awakeLevel)
|
{
|
return heroA.awakeLevel > heroB.awakeLevel ? -1 : 1;
|
}
|
if (heroA.Quality != heroB.Quality)
|
{
|
return heroA.Quality > heroB.Quality ? -1 : 1;
|
}
|
if (heroA.heroStar != heroB.heroStar)
|
{
|
return heroA.heroStar > heroB.heroStar ? -1 : 1;
|
}
|
|
return heroA.heroId.CompareTo(heroB.heroId);
|
}
|
|
|
#region 招募
|
|
public HappXBTitle selectCallType; //寻宝枚举类型
|
public int selectCallIndex;//0:1抽 1:10抽 对应配置顺序
|
public const string skipKey = "SkipHeroCall";
|
|
//积分招募预览
|
public List<int> heroCallSortList { get; private set; } = new List<int>(); //积分招募列表
|
public List<int> selectHeroCallList = new List<int>(); //筛选
|
|
public List<int> newHeroIDList = new List<int>(); //新武将列表
|
public bool IsNewHero(int heroID)
|
{
|
HB122_tagSCHeroInfo.tagSCHero bookInfo;
|
if (TryGetHeroBookInfo(heroID, out bookInfo))
|
{
|
if (bookInfo.BookInitState < 2)
|
{
|
//更精准的 需要比较本次抽的同武将个数 和 背包里有的个数再比较
|
if (HappyXBModel.Instance.GetCountInResult(heroID) >= HeroManager.Instance.GetHeroCountByID(heroID))
|
{
|
AddNewHero(heroID);
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
|
AddNewHero(heroID);
|
return true;
|
}
|
|
public void AddNewHero(int heroID)
|
{
|
if (newHeroIDList.Contains(heroID))
|
{
|
return;
|
}
|
newHeroIDList.Add(heroID);
|
|
PhantasmPavilionManager.Instance.AddNewHero(heroID);
|
}
|
|
public void RemoveNewHero(int heroID)
|
{
|
if (!newHeroIDList.Contains(heroID))
|
{
|
return;
|
}
|
newHeroIDList.Remove(heroID);
|
refreshRedPoint = true;
|
}
|
|
List<int> allHeroCallScoreList = new List<int>(); //积分招募列表
|
public void SortHeroCallList()
|
{
|
if (allHeroCallScoreList.IsNullOrEmpty())
|
{
|
allHeroCallScoreList = HappyXBModel.Instance.GetAllGridLibItemIDByType((int)HappXBTitle.HeroCallScore);
|
}
|
heroCallSortList = new List<int>();
|
if (selectHeroCallList.IsNullOrEmpty())
|
{
|
heroCallSortList = allHeroCallScoreList;
|
}
|
else
|
{
|
|
int job = 0;
|
int country = 0;
|
int hurtType = 0;
|
int fightAttrType = 0;
|
int specialAttrType = 0;
|
if (!selectHeroCallList.IsNullOrEmpty())
|
{
|
job = selectHeroCallList[0];
|
country = selectHeroCallList[1];
|
hurtType = selectHeroCallList[2];
|
fightAttrType = selectHeroCallList[3];
|
specialAttrType = selectHeroCallList[4];
|
}
|
|
|
foreach (var item in allHeroCallScoreList)
|
{
|
HeroConfig heroConfig = HeroConfig.Get(item);
|
if (heroConfig == null)
|
{
|
continue;
|
}
|
|
//0代表全部, 同级别是可复选,不同级别为且的关系
|
bool isMatch = true;
|
if (job != 0)
|
{
|
isMatch = isMatch && (job & (1 << heroConfig.Class)) > 0;
|
}
|
if (country != 0)
|
{
|
isMatch = isMatch && (country & (1 << heroConfig.Country)) > 0;
|
}
|
if (hurtType != 0)
|
{
|
isMatch = isMatch && (hurtType & (1 << heroConfig.HurtType)) > 0;
|
}
|
if (fightAttrType != 0)
|
{
|
isMatch = isMatch && (fightAttrType & (1 << heroConfig.Specialty)) > 0;
|
}
|
if (specialAttrType != 0)
|
{
|
bool isMatch2 = false;
|
for (int i = 0; i < heroConfig.Specialty2.Length; i++)
|
{
|
isMatch2 = (specialAttrType & (1 << heroConfig.Specialty2[i])) > 0;
|
if (isMatch2)
|
break;
|
}
|
isMatch = isMatch && isMatch2;
|
}
|
if (!isMatch)
|
{
|
continue;
|
}
|
|
heroCallSortList.Add(item);
|
}
|
}
|
|
heroCallSortList.Sort(CmpHeroID);
|
}
|
|
int CmpHeroID(int idA, int idB)
|
{
|
HeroConfig heroA = HeroConfig.Get(idA);
|
HeroConfig heroB = HeroConfig.Get(idB);
|
|
// 排序规则:武将品质>武将ID
|
if (heroA.Quality != heroB.Quality)
|
{
|
return heroA.Quality > heroB.Quality ? -1 : 1;
|
}
|
|
return heroA.HeroID.CompareTo(heroB.HeroID);
|
}
|
|
#endregion
|
|
|
// 优先功能提醒类型:1觉醒 2升星 3突破 4升级
|
// 主线上阵武将才需要提醒 觉醒>升星>突破>升级
|
public int GetFuncState(HeroInfo hero)
|
{
|
if (!hero.isAttrActive)
|
return 0;
|
|
var heroCnt = PackManager.Instance.GetItemCountByID(PackType.Hero, hero.heroId);
|
if (!hero.IsInTeamByTeamType(TeamType.Story))
|
{
|
if (hero.heroStar < hero.GetCurMaxStar() && heroCnt > 1)
|
{
|
return 2;
|
}
|
return 0;
|
}
|
|
var itemPack = PackManager.Instance.GetSinglePack(PackType.Item);
|
//5星后才能觉醒
|
if (hero.heroStar < starLevelCanAwake)
|
{
|
if (heroCnt > 1) return 2;
|
}
|
else
|
{
|
if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HeroAwake))
|
{
|
//判断觉醒材料是否足够
|
var maxAwakeLV = HeroAwakeConfig.GetMaxAwakeLV(hero.heroId);
|
if (hero.awakeLevel < maxAwakeLV)
|
{
|
var config = HeroQualityAwakeConfig.GetQualityAwakeConfig(hero.Quality, hero.awakeLevel);
|
if (itemPack.GetCountById(config.UPCostItem[0]) >= config.UPCostItem[1])
|
{
|
return 1;
|
}
|
}
|
}
|
}
|
|
if (hero.heroStar < hero.GetCurMaxStar() && heroCnt > 1)
|
{
|
return 2;
|
}
|
|
if (IsCanBreak(hero))
|
{
|
return 3;
|
}
|
|
if (!IsLVMax(hero))
|
{
|
var lvupConfig = HeroQualityLVConfig.GetQualityLVConfig(hero.Quality, hero.heroLevel);
|
if (itemPack.GetCountById(lvupConfig.UPCostItem[0]) >= lvupConfig.UPCostItem[1])
|
{
|
return 4;
|
}
|
}
|
return 0;
|
}
|
|
|
#region 红点
|
|
public bool refreshRedPoint = false;
|
List<Redpoint> heroOnTeamRedpointList = new List<Redpoint>(); //上阵的武将红点
|
List<Redpoint> heroBookRedpointList = new List<Redpoint>(); //图鉴所有武将红点
|
|
//生效未上阵的 可吞噬的共用一个红点
|
Redpoint heroEatRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 8);
|
//新标识的红点 所有武将统一个
|
Redpoint newMarkRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 9);
|
void InitHeroOnTeamRedpointList()
|
{
|
heroOnTeamRedpointList.Clear();
|
for (int i = 0; i < TeamConst.MaxTeamHeroCount; i++)
|
{
|
heroOnTeamRedpointList.Add(new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + i));
|
}
|
}
|
|
|
//武将卡的红点:只给上阵武将刷红点(含新标识),非上阵武将的新图标按图片处理不归类为红点
|
void UpdateHeroCardRedpoint()
|
{
|
if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Hero))
|
return;
|
|
var team = TeamManager.Instance.GetTeam(TeamType.Story);
|
for (int i = 0; i < heroOnTeamRedpointList.Count; i++)
|
{
|
var redpoint = heroOnTeamRedpointList[i];
|
var teamHero = team.GetServerHeroByIndex(i);
|
if (teamHero != null)
|
{
|
var hero = HeroManager.Instance.GetHero(teamHero.guid);
|
if (hero != null)
|
{
|
if (GetFuncState(hero) > 0)
|
{
|
redpoint.state = RedPointState.Simple;
|
continue;
|
}
|
}
|
}
|
|
redpoint.state = RedPointState.None;
|
}
|
|
newMarkRedPoint.state = newHeroIDList.Count > 0 ? RedPointState.New : RedPointState.None;
|
|
heroEatRedPoint.state = RedPointState.None;
|
var _list = HeroManager.Instance.GetHeroList();
|
foreach (var hero in _list)
|
{
|
if (!hero.isAttrActive)
|
{
|
continue;
|
}
|
if (hero.heroStar >= hero.GetCurMaxStar())
|
{
|
continue;
|
}
|
|
if (HeroManager.Instance.GetHeroCountByID(hero.heroId) > 1)
|
{
|
heroEatRedPoint.state = RedPointState.GetReward;
|
break;
|
}
|
}
|
|
}
|
|
|
void InitHerosData()
|
{
|
heroBookRedpointList.Clear();
|
foreach (var key in HeroConfig.GetKeys())
|
{
|
var config = HeroConfig.Get(key);
|
|
//汇总特殊属性
|
if (!config.Specialty2.IsNullOrEmpty())
|
{
|
foreach (var num in config.Specialty2)
|
{
|
if (!heroSpecialAttrsForSelect.Contains(num))
|
{
|
heroSpecialAttrsForSelect.Add(num);
|
}
|
}
|
}
|
|
if (config.PlayerCanUse == 0)
|
continue;
|
|
//图鉴红点
|
heroBookRedpointList.Add(new Redpoint(MainRedDot.HeroCardCollectRedpoint, MainRedDot.HeroCardCollectRedpoint * 10000000 + key));
|
}
|
|
heroSpecialAttrsForSelect.Sort();
|
}
|
|
|
//某个武将图鉴中是否显示红点
|
public bool IsBookShowRedPoint(int heroID)
|
{
|
var state = GetHeroBookState(heroID, HeroConfig.Get(heroID).Quality);
|
if (state == 1 || state == 3 || state == 4)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
void UpdateHeroBookRedpoint()
|
{
|
if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Hero))
|
return;
|
|
foreach (var redpoint in heroBookRedpointList)
|
{
|
var heroID = redpoint.id % 10000000;
|
var state = GetHeroBookState(heroID, HeroConfig.Get(heroID).Quality);
|
if (state == 1 || state == 3 || state == 4)
|
{
|
redpoint.state = RedPointState.Simple;
|
continue;
|
}
|
redpoint.state = RedPointState.None;
|
}
|
}
|
|
|
void OnSecondEvent()
|
{
|
if (refreshRedPoint)
|
{
|
UpdateHeroCardRedpoint();
|
refreshRedPoint = false;
|
}
|
}
|
|
void RefreshItemEvent(PackType packType, int index, int itemID)
|
{
|
if (packType != PackType.Item)
|
return;
|
|
if (heroRedpointItemList.Contains(itemID))
|
{
|
refreshRedPoint = true;
|
}
|
}
|
|
void OnTeamChangeEvent(TeamType teamType)
|
{
|
if (teamType == TeamType.Story)
|
{
|
refreshRedPoint = true;
|
}
|
}
|
#endregion
|
}
|
|
#region 等待服务端响应
|
public struct WaitHeroFuncResponse
|
{
|
public HeroFuncType type;
|
public string guid;
|
public float time;
|
}
|
|
//武将功能类型
|
public enum HeroFuncType
|
{
|
None = 0, //无功能
|
Break = 1, //突破
|
Gift = 2, //天赋吞噬
|
Awake = 3, //觉醒
|
}
|
#endregion
|