using DG.Tweening;
|
using System;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using UnityEngine.UI;
|
|
namespace vnxbqy.UI
|
{
|
public class FairySiegeCityWin : Window
|
{
|
[SerializeField] ButtonEx btnBattleReport; //战报
|
[SerializeField] ButtonEx btnClose;
|
[SerializeField] ButtonEx btnSummonDragon; //神龙召唤
|
[SerializeField] RedpointBehaviour rpSummonDragon;
|
[SerializeField] ButtonEx btnSwitchGroup; //切换分组
|
[SerializeField] TextEx txtRemainTime;
|
[SerializeField] ImageEx imgEndRound; //最后一轮横幅
|
[Header("城池")]
|
[SerializeField] FairySiegeCityItem[] regularCityArr;
|
|
[Header("修罗城")]
|
[SerializeField] RectTransform rectBossCity;
|
[SerializeField] ButtonEx btnBossCity;
|
[SerializeField] FairySiegeSlider slidBossCity;
|
[SerializeField] ImageEx imgBossCity;
|
[SerializeField] ImageEx imgBossCityEffect;
|
[Header("飞龙在天技能公告框")]
|
[SerializeField] EmblemCell emblemSkill;
|
[SerializeField] ImageEx imgSkillIcon;
|
[SerializeField] ImageEx imgSkillName;
|
[SerializeField] RectTransform rectSkill;
|
[SerializeField] ScrollRect scrollRect; //滚动组件
|
|
[SerializeField] RectTransform tranMap;
|
[SerializeField] TextEx txtFairyNameSkill;
|
[SerializeField] TextEx txtPlayerNameSkill;
|
|
[Header("个人仙盟面板")]
|
[SerializeField] Transform transMyFairy;
|
[SerializeField] TextEx txtFairyName;
|
[SerializeField] EmblemCell emblem;
|
[SerializeField] ButtonEx btnRank;
|
[SerializeField] TextEx txtRank;
|
[SerializeField] FairySiegeStarGroup starGroup;
|
[SerializeField] Slider slidFairy;
|
[SerializeField] Text txtFairyHP;
|
|
[SerializeField] RectTransform rectStart;
|
[SerializeField] RectTransform rectMiddle;
|
[SerializeField] RectTransform rectEnd;
|
|
FairySiegeActModel model { get { return ModelCenter.Instance.GetModel<FairySiegeActModel>(); } }
|
|
#region Build-in
|
|
protected override void AddListeners()
|
{
|
btnBossCity.SetListener(() =>
|
{
|
if (model.isWaitC030Pack)
|
return;
|
model.isWaitC030Pack = true;
|
model.isClickCity = true;
|
model.showCityId = model.BossCityId;
|
model.SendQuery(4, model.showBatType, model.showBatGroup, model.showCityId);
|
});
|
|
btnClose.SetListener(CloseClick);
|
btnSummonDragon.SetListener(() =>
|
{
|
WindowCenter.Instance.Open<FairySiegeSummonDragonWin>();
|
});
|
btnBattleReport.SetListener(() => { model.SendQuery(6, 0, 0, 0); });
|
btnSwitchGroup.SetListener(() => WindowCenter.Instance.Open<FairySiegeSwitchGroupWin>());
|
btnRank.SetListener(() => WindowCenter.Instance.Open<FairySiegeScheduleWin>(false, 1));
|
}
|
|
protected override void BindController()
|
{
|
}
|
|
protected override void OnPreOpen()
|
{
|
rpSummonDragon.redpointId = model.GetRedpointId(FairySiegeRedPointType.SummonDragon);
|
fairySiegeBatSceneInfoQueue.Clear();
|
playSiegeBatSceneInfoQueue.Clear();
|
model.atkAwardQueue.Clear();
|
isPlayingMySkillAnim = false;
|
isPlaying = false;
|
model.isClickCity = false;
|
model.isWaitC030Pack = false;
|
scrollRect.SetActive(false);
|
rectBossCity.SetActive(false);
|
model.UpdateSwitchGroupAction += OnUpdateSwitchGroupAction;
|
model.UpdateFamilyGCZBatSceneInfoEvent += OnUpdateFamilyGCZBatSceneInfoEvent;
|
model.UpdateFamilyGCZBatReportEvent += OnUpdateFamilyGCZBatReportEvent;
|
model.JumpToCityAction += OnJumpToCityAction;
|
model.UpdateFamilyGCZBatCityInfoEvent += OnUpdateFamilyGCZBatCityInfoEvent;
|
GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
|
model.UpdateBatSceneHurtListEvent += OnUpdateBatSceneHurtListEvent;
|
}
|
|
protected override void OnPreClose()
|
{
|
model.UpdateSwitchGroupAction -= OnUpdateSwitchGroupAction;
|
model.UpdateFamilyGCZBatSceneInfoEvent -= OnUpdateFamilyGCZBatSceneInfoEvent;
|
model.UpdateFamilyGCZBatReportEvent -= OnUpdateFamilyGCZBatReportEvent;
|
model.JumpToCityAction -= OnJumpToCityAction;
|
model.UpdateFamilyGCZBatCityInfoEvent -= OnUpdateFamilyGCZBatCityInfoEvent;
|
GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
|
model.UpdateBatSceneHurtListEvent -= OnUpdateBatSceneHurtListEvent;
|
model.SendQuery(3, 0, 0, 0);
|
}
|
|
private void OnJumpToCityAction(uint tagFamilyID)
|
{
|
if (tagFamilyID == model.BossCityId)
|
{
|
JumpToCity(rectBossCity);
|
}
|
else
|
{
|
if (!TryFindCity(tagFamilyID, out RectTransform rect))
|
return;
|
JumpToCity(rect);
|
}
|
}
|
|
public Queue<FairySiegeBatSceneInfo> playSiegeBatSceneInfoQueue = new Queue<FairySiegeBatSceneInfo>();
|
|
public Queue<FairySiegeBatSceneInfo> fairySiegeBatSceneInfoQueue = new Queue<FairySiegeBatSceneInfo>();
|
|
private void OnUpdateBatSceneHurtListEvent(FairySiegeBatSceneInfo info)
|
{
|
if (info == null)
|
return;
|
if (info.AtkPlayerID == (int)PlayerDatas.Instance.baseData.PlayerID)
|
{
|
playSiegeBatSceneInfoQueue.Enqueue(model.DeepCopyFairySiegeBatSceneInfo(info));
|
}
|
else
|
{
|
fairySiegeBatSceneInfoQueue.Enqueue(model.DeepCopyFairySiegeBatSceneInfo(info));
|
}
|
}
|
|
private void OnUpdateFamilyGCZBatReportEvent()
|
{
|
if (!WindowCenter.Instance.IsOpen<FairySiegeBattleReportWin>())
|
{
|
WindowCenter.Instance.Open<FairySiegeBattleReportWin>();
|
}
|
}
|
|
private void OnUpdateSwitchGroupAction()
|
{
|
model.SendQuery(3, 0, 0, 0);
|
model.SendQuery(2, model.showBatType, model.showBatGroup, 0);
|
}
|
|
private void OnUpdateFamilyGCZBatSceneInfoEvent()
|
{
|
imgEndRound.SetActive(model.matchRound == model.matchRoundMax);
|
DisplayBatEndCountdown();
|
DisplayCity();
|
DisplayMyFamily();
|
}
|
|
protected override void OnAfterOpen()
|
{
|
Reset();
|
Display();
|
scrollRect.SetActive(true);
|
}
|
|
protected override void OnAfterClose()
|
{
|
}
|
|
#endregion
|
|
//使用飞龙在天技能,移动到指定城池
|
private void MoveToCityPos(FairySiegeBatSceneInfo info)
|
{
|
//使用飞龙在天技能,移动到指定城池
|
if (info.AtkType == 2 && !info.BatSceneHurtList.IsNullOrEmpty() && info.AtkPlayerID == PlayerDatas.Instance.baseData.PlayerID)
|
{
|
bool isBossCityShow = model.TryGetBossCityData(model.showBatType, model.showBatGroup, out FairySiegeBatSceneCity bossCityData);
|
if (isBossCityShow)
|
{
|
var normalizedPosition = CalculateNormalizedPosition(rectBossCity);
|
scrollRect.horizontalNormalizedPosition = normalizedPosition;
|
}
|
else
|
{
|
for (int i = 0; i < info.BatSceneHurtList.Count; i++)
|
{
|
if (TryFindCity(info.BatSceneHurtList[i].CityID, out var rect))
|
{
|
var normalizedPosition = CalculateNormalizedPosition(rect);
|
scrollRect.horizontalNormalizedPosition = normalizedPosition;
|
}
|
}
|
}
|
}
|
}
|
|
private void UpdateSkillFrame(FairySiegeBatSceneInfo info)
|
{
|
imgSkillIcon.SetSprite(model.GetSkillIcon((int)info.AtkType));
|
imgSkillIcon.SetNativeSize();
|
imgSkillName.SetSprite(model.GetSkillNameIcon((int)info.AtkType));
|
imgSkillName.SetNativeSize();
|
|
if (info.BatScenePlayerInfoDict.TryGetValue(info.AtkPlayerID, out var batScenePlayerInfo) &&
|
model.TryGetFairySiegeFamilyInfo(batScenePlayerInfo.FamilyID, out FairySiegeFamilyInfo fairySiegeFamilyInfo))
|
{
|
emblemSkill.SetActive(true);
|
emblemSkill.InitUI(EmblemHelper.GetOtherEmblemModel((int)fairySiegeFamilyInfo.EmblemID));
|
txtFairyNameSkill.text = fairySiegeFamilyInfo.Name;
|
txtPlayerNameSkill.text = batScenePlayerInfo.Name;
|
}
|
else
|
{
|
emblemSkill.SetActive(false);
|
txtFairyNameSkill.text = string.Empty;
|
txtPlayerNameSkill.text = string.Empty;
|
}
|
}
|
|
protected override void LateUpdate()
|
{
|
PlayAnim();
|
DisplayAwardWin();
|
}
|
|
Sequence seqFrame;
|
|
bool isPlayingMySkillAnim = false;
|
bool isPlaying = false;
|
|
private void PlayAnim()
|
{
|
FairySiegeBatSceneInfo info = null;
|
if (playSiegeBatSceneInfoQueue.Count <= 0 && fairySiegeBatSceneInfoQueue.Count <= 0)
|
return;
|
if (isPlaying)
|
return;
|
isPlaying = true;
|
if (playSiegeBatSceneInfoQueue.Count > 0)
|
{
|
info = playSiegeBatSceneInfoQueue.Dequeue();
|
}
|
else
|
{
|
if (fairySiegeBatSceneInfoQueue.Count > 0)
|
{
|
info = fairySiegeBatSceneInfoQueue.Dequeue();
|
}
|
}
|
if (info == null || info.BatSceneHurtList == null || info.AtkPlayerID <= 0)
|
{
|
isPlaying = false;
|
return;
|
}
|
if (!model.isSummonDragonWatch && info.AtkPlayerID != PlayerDatas.Instance.baseData.PlayerID)
|
{
|
isPlaying = false;
|
return;
|
}
|
isPlayingMySkillAnim = false;
|
if (info.AtkPlayerID == PlayerDatas.Instance.baseData.PlayerID)
|
{
|
isPlayingMySkillAnim = true;
|
}
|
Reset();
|
MoveToCityPos(info);
|
seqFrame = DOTween.Sequence();
|
seqFrame.Append(rectSkill.DOMove(rectMiddle.position, 0.3f)
|
.OnStart(() =>
|
{
|
UpdateSkillFrame(info);
|
})
|
.OnComplete(() =>
|
{
|
PlayThunder(info);
|
PlayDamage(info);
|
PlayShake(info);
|
}));
|
seqFrame.AppendInterval(0.7f);
|
seqFrame.AppendCallback(StopThunder);
|
seqFrame.Append(rectSkill.DOMove(rectEnd.position, 0.3f).SetDelay(0.8f).
|
OnComplete(() =>
|
{
|
isPlaying = false;
|
isPlayingMySkillAnim = false;
|
}));
|
}
|
|
//非战斗期玩家还在战斗界面时,退出相关界面
|
private void ExitWin()
|
{
|
if (!model.TryGetCurrentStateValue(out int stateValue))
|
return;
|
int state = model.GetStateByStateValue(stateValue);// 0 公示期 1 备战期 2 开战期 3 休战期 4 领奖期
|
if (state != 2)
|
{
|
WindowCenter.Instance.Close<FairySiegeCityWin>();
|
}
|
}
|
|
private void OnSecondEvent()
|
{
|
imgEndRound.SetActive(model.matchRound == model.matchRoundMax);
|
DisplayBatEndCountdown();
|
DisplayCity();
|
ExitWin();
|
}
|
|
private void DisplayBatEndCountdown()
|
{
|
if (!model.TryGetCurrentStateValue(out int stateValue))
|
return;
|
int state = model.GetStateByStateValue(stateValue);//0 公示期 1 备战期 2 开战期 3 休战期 4 领奖期
|
int roundNum = model.GetRoundNumByStateValue(stateValue);
|
bool isRemainTimeShow = state == 2;
|
txtRemainTime.SetActive(isRemainTimeShow);
|
if (isRemainTimeShow &&
|
model.TryGetEndTimeByStateValue(stateValue, out DateTime endTime) &&
|
endTime > ILTimeUtility.ServerCrossNow
|
)
|
{
|
string time = TimeUtility.SecondsToDHMS((int)(endTime - ILTimeUtility.ServerCrossNow).TotalSeconds);
|
txtRemainTime.text = Language.Get("FairySiege071", roundNum, time);
|
}
|
else
|
{
|
txtRemainTime.text = string.Empty;
|
}
|
}
|
|
private void DisplayAwardWin()
|
{
|
if (model.cityAwardQueue.Count <= 0)
|
return;
|
if (isPlayingMySkillAnim)
|
return;
|
if (WindowCenter.Instance.IsOpen("FairySiegeSummonGetItemWin"))
|
return;
|
var netPack = model.cityAwardQueue.Dequeue();
|
model.nowAtkAwardInfo = netPack;
|
if (model.nowAtkAwardInfo.atkAwardInfo == null)
|
return;
|
ItemLogicUtility.Instance.ShowGetItemEx("FairySiegeSummonGetItemWin", netPack.showItems, netPack.info, 0, eventName: netPack.eventName);
|
}
|
|
public void Reset()
|
{
|
rectSkill.localPosition = rectStart.localPosition;
|
seqFrame?.Kill();
|
StopThunder();
|
StopShake();
|
}
|
|
private void DisplayMyFamily()
|
{
|
transMyFairy.SetActive(false);
|
if (!model.TryGetNowBatTypeAndGroup(model.myFamilyID, out int battleType, out int battleGroup))
|
return;
|
if (model.showBatType != battleType || model.showBatGroup != battleGroup)
|
return;
|
if (!model.TryGetBatSceneCityInfo(battleType, battleGroup, model.myFamilyID, out FairySiegeBatSceneCity batSceneCity))
|
return;
|
if (!model.TryGetFairySiegeFamilyInfo(model.myFamilyID, out FairySiegeFamilyInfo familyInfo))
|
return;
|
|
transMyFairy.SetActive(true);
|
|
if (FamilyGCZCampLVConfig.Has(model.myCityLV))
|
{
|
FamilyGCZCampLVConfig config = FamilyGCZCampLVConfig.Get(model.myCityLV);
|
starGroup.Display(config.StarCount);
|
}
|
|
float fillAmount = Mathf.Round((float)batSceneCity.HP / batSceneCity.HPMax * 1000f) / 1000f;
|
string info = Language.Get("FairySiege125", UIHelper.ReplaceLargeNum(batSceneCity.HP), UIHelper.ReplaceLargeNum(batSceneCity.HPMax));
|
slidFairy.value = fillAmount;
|
txtFairyHP.text = info;
|
txtFairyName.text = familyInfo.Name;
|
txtRank.text = Language.Get("FairySiege072", batSceneCity.Rank);
|
emblem.InitUI(EmblemHelper.GetOtherEmblemModel((int)familyInfo.EmblemID));
|
}
|
|
public void Display()
|
{
|
imgEndRound.SetActive(model.matchRound == model.matchRoundMax);
|
DisplayBatEndCountdown();
|
DisplayCity();
|
JumpMyCity();
|
DisplayMyFamily();
|
}
|
|
private void OnUpdateFamilyGCZBatCityInfoEvent()
|
{
|
model.isWaitC030Pack = false;
|
if (model.isClickCity)
|
{
|
model.isClickCity = false;
|
if (WindowCenter.Instance.IsOpen<FairySiegeAtkWin>())
|
return;
|
WindowCenter.Instance.Open<FairySiegeAtkWin>();
|
}
|
}
|
|
#region 城池
|
|
private void JumpToCity(RectTransform rect)
|
{
|
var normalizedPosition = CalculateNormalizedPosition(rect);
|
scrollRect.horizontalNormalizedPosition = normalizedPosition;
|
}
|
|
// 尝试通过仙盟Id找到城池位置
|
public bool TryFindCity(uint cityId, out RectTransform rect)
|
{
|
rect = null;
|
if (!model.TryGetCityIndex(model.showBatType, model.showBatGroup, cityId, out var index))
|
return false;
|
if (index < 0 || index >= regularCityArr.Length)
|
return false;
|
rect = regularCityArr[index].transform as RectTransform;
|
return true;
|
}
|
|
// 跳转到我的城池
|
private void JumpMyCity()
|
{
|
//存在修罗城跳转到修罗城
|
if (model.TryGetBossCityData(model.showBatType, model.showBatGroup, out FairySiegeBatSceneCity bossCityData))
|
{
|
JumpToCity(rectBossCity);
|
}
|
else
|
{
|
var familyId = PlayerDatas.Instance.baseData.FamilyId;
|
if (!TryFindCity(familyId, out var rect))
|
{
|
return;
|
}
|
JumpToCity(rect);
|
}
|
}
|
|
private float CalculateNormalizedPosition(RectTransform rect)
|
{
|
// 获取滚动视图的宽度
|
var scrollViewWidth = scrollRect.viewport.rect.width;
|
// 获取地图的宽度
|
var mapWidth = tranMap.rect.width;
|
// 获取城池在地图中的局部位置
|
Vector2 localPos = rect.localPosition;
|
// 计算城池中心在地图中的X位置(考虑到城池的锚点是(0.5, 0.5))
|
var cityPosX = localPos.x;
|
// 计算地图内容可滚动的总距离
|
var scrollableWidth = mapWidth - scrollViewWidth;
|
if (scrollableWidth <= 0)
|
return 0;
|
// 计算目标位置,让城池尽量居中显示
|
var targetPos = cityPosX - scrollViewWidth / 2;
|
// 确保目标位置在有效范围内
|
targetPos = Mathf.Clamp(targetPos, 0, scrollableWidth);
|
// 计算归一化位置 (0 = 最左侧, 1 = 最右侧)
|
var normalizedPosition = targetPos / scrollableWidth;
|
return normalizedPosition;
|
}
|
|
public void DisplayCity()
|
{
|
rectBossCity.SetActive(false);
|
if (!model.TryGetRegularCityDataList(model.showBatType, model.showBatGroup, out List<FairySiegeBatSceneCity> regularCityDataList))
|
return;
|
for (int i = 0; i < regularCityArr.Length; i++)
|
{
|
if (i < regularCityDataList.Count)
|
{
|
regularCityArr[i].SetActive(true);
|
regularCityArr[i].Display(regularCityDataList[i]);
|
}
|
else
|
{
|
regularCityArr[i].SetActive(false);
|
}
|
}
|
|
//存在修罗城
|
if (model.TryGetBossCityData(model.showBatType, model.showBatGroup, out FairySiegeBatSceneCity bossCityData))
|
{
|
rectBossCity.SetActive(true);
|
float rate = (float)bossCityData.HP / (float)bossCityData.HPMax;
|
string rateStr = Language.Get("BlessedLand039", (rate * 100).ToString("F2"));
|
slidBossCity.Display(rate, rateStr);
|
}
|
}
|
|
#endregion
|
|
#region 飘字
|
|
private void PlayDamage(FairySiegeBatSceneInfo info)
|
{
|
bool isBossCityShow = model.TryGetBossCityData(model.showBatType, model.showBatGroup, out FairySiegeBatSceneCity bossCityData);
|
if (isBossCityShow)
|
{
|
if (TryGetBossCityDamage(info, out long damage))
|
{
|
PlayBossCityDamageSeq(damage);
|
}
|
}
|
else
|
{
|
for (int i = 0; i < info.BatSceneHurtList.Count; i++)
|
{
|
if (model.TryGetCityIndex(model.showBatType, model.showBatGroup, info.BatSceneHurtList[i].CityID, out var index))
|
{
|
regularCityArr[index].PlayDamageSeq((long)info.BatSceneHurtList[i].HurtValue);
|
}
|
}
|
}
|
}
|
|
public void PlayBossCityDamageSeq(long damage)
|
{
|
GameObject prefab = UIUtility.CreateWidget("FairySiegeCityPopUpNum", "FairySiegeCityPopUpNum");
|
prefab.transform.SetParentEx(this.transform, Vector3.zero, Quaternion.identity, Vector3.one);
|
prefab.GetComponent<FairySiegeCityPopUpNum>().Play(damage);
|
}
|
|
public bool TryGetBossCityDamage(FairySiegeBatSceneInfo info, out long damage)
|
{
|
damage = 0;
|
if (info == null || info.BatSceneHurtList == null)
|
return false;
|
foreach (var item in info.BatSceneHurtList)
|
{
|
if (item.CityID == model.BossCityId)
|
{
|
damage = (long)item.HurtValue;
|
return true;
|
}
|
}
|
return false;
|
}
|
|
#endregion
|
|
#region 抖动
|
|
private Tweener shakeTween;
|
|
public void PlayBossCityShakeTween()
|
{
|
shakeTween = imgBossCity.transform.DOShakeRotation(0.5f, 10, 10, 90).SetEase(Ease.InOutElastic).OnComplete(() =>
|
{
|
imgBossCity.transform.localRotation = Quaternion.identity;
|
});
|
}
|
|
public void StopBossCityShakeTween()
|
{
|
shakeTween?.Kill();
|
imgBossCity.transform.localRotation = Quaternion.identity;
|
}
|
|
public void StopShakeTween()
|
{
|
foreach (var item in regularCityArr)
|
{
|
item.StopShakeTween();
|
}
|
}
|
|
public void StopShake()
|
{
|
StopShakeTween();
|
StopBossCityShakeTween();
|
}
|
|
private void PlayShake(FairySiegeBatSceneInfo info)
|
{
|
bool isBossCityShow = model.TryGetBossCityData(model.showBatType, model.showBatGroup, out FairySiegeBatSceneCity bossCityData);
|
if (isBossCityShow)
|
{
|
PlayBossCityShakeTween();
|
}
|
else
|
{
|
for (int i = 0; i < info.BatSceneHurtList.Count; i++)
|
{
|
if (model.TryGetCityIndex(model.showBatType, model.showBatGroup, info.BatSceneHurtList[i].CityID, out var index))
|
{
|
regularCityArr[index].PlayShakeTween();
|
}
|
}
|
}
|
}
|
|
#endregion
|
|
#region 落雷
|
|
private void PlayThunder(FairySiegeBatSceneInfo info)
|
{
|
bool isBossCityShow = model.TryGetBossCityData(model.showBatType, model.showBatGroup, out FairySiegeBatSceneCity bossCityData);
|
if (isBossCityShow)
|
{
|
PlayBossCityThunderEffect();
|
}
|
else
|
{
|
for (int i = 0; i < info.BatSceneHurtList.Count; i++)
|
{
|
if (model.TryGetCityIndex(model.showBatType, model.showBatGroup, info.BatSceneHurtList[i].CityID, out var index))
|
{
|
regularCityArr[index].PlayThunderEffect();
|
}
|
}
|
}
|
}
|
|
private void StopThunder()
|
{
|
StopThunderEffect();
|
StopBossCityThunderEffect();
|
}
|
|
private void StopThunderEffect()
|
{
|
foreach (var city in regularCityArr)
|
{
|
city.StopThunderEffect();
|
}
|
}
|
|
public void PlayBossCityThunderEffect()
|
{
|
imgBossCityEffect.SetActive(true);
|
}
|
|
public void StopBossCityThunderEffect()
|
{
|
imgBossCityEffect.SetActive(false);
|
}
|
|
#endregion
|
}
|
}
|