using DG.Tweening; using UnityEngine; using UnityEngine.UI; namespace vnxbqy.UI { public class FairySiegeAtkWin : Window { [SerializeField] ButtonEx btnBattleReport; [SerializeField] ButtonEx btnClose; [SerializeField] ButtonEx btnReward; [SerializeField] ClickScreenOtherSpace csosReward; [SerializeField] ImageEx imgMyRelamLv; [SerializeField] RawImage rawImgMy; [SerializeField] RectTransform rectEffect; [SerializeField] RectTransform rectEnd; [SerializeField] RectTransform rectStart; [SerializeField] ScrollerController scrReward; [SerializeField] Transform tranReward; [Header("攻击按钮相关")] [SerializeField] TextEx txtEnergy; [SerializeField] ImageEx imgEnergyTime; [SerializeField] TextEx txtEnergyTime; [SerializeField] ButtonEx btnGo; [SerializeField] ButtonEx btnAdd; [Header("仙盟信息")] [SerializeField] Transform transRegularCityInfo; [SerializeField] EmblemCell emblem; [SerializeField] TextEx txtFairyName; [SerializeField] TextEx txtServerName; [SerializeField] FairySiegeStarGroup starGroup; [SerializeField] Slider slidFairy; [SerializeField] Text txtFairyHP; [SerializeField] Transform transBossCityInfo; [SerializeField] EmblemCell bossEmblem; [SerializeField] Slider slidBossCity; [SerializeField] Text txtBossCityHP; [Header("防守人员信息")] [SerializeField] Transform transHostInfo; [SerializeField] ImageEx imgHostRelamLv; [SerializeField] RawImage rawImgHost; [SerializeField] TextEx txtDamage; [SerializeField] TextEx txtHostName; [SerializeField] ImageEx imgHostName; [SerializeField] Slider slidHP; [SerializeField] Text txtHP; [SerializeField] Transform transHostAllDead; [Header("我方人物信息")] UI3DPlayerExhibitionData myData; [SerializeField] TextEx txtMyFightPonit; [SerializeField] TextEx txtMyName; [SerializeField] UIEffect uiEffAtk; [SerializeField] UIEffect uiEffStart; [SerializeField] RedpointBehaviour rpAtk; public float damageMoveDistance = 300f; Vector3 hostEulerAngles = new Vector3(0, 45, 0); Vector3 myEulerAngles = new Vector3(0, 225, 0); int atkEffectId { get { return model.atkEffectId; } } float atkEffectDelay { get { return model.atkEffectDelay; } } float atkEffectDuration { get { return model.atkEffectDuration; } } FairySiegeActModel model { get { return ModelCenter.Instance.GetModel(); } } EquipModel equipModel { get { return ModelCenter.Instance.GetModel(); } } PackModel packModel { get { return ModelCenter.Instance.GetModel(); } } RoleParticularModel roleParticularModel { get { return ModelCenter.Instance.GetModel(); } } bool isBossCityShow; FairySiegeBatSceneCity bossCityData; RoleParticularModel.ViewPlayerData viewPlayerData; #region Build-in protected override void AddListeners() { btnClose.SetListener(CloseClick); btnBattleReport.SetListener(() => model.SendQuery(6, 0, 0, model.showCityId)); btnAdd.SetListener(() => WindowCenter.Instance.Open()); btnReward.SetListener(() => model.isRewardDisplay = true); csosReward.RemoveAllListeners(); csosReward.AddListener(() => model.isRewardDisplay = false); btnGo.SetListener(() => { if (model.nowFairySiegeBatCityInfo == null) return; if (isPlaying) return; // 体力和攻城令均不足 int energy = model.energy; var hasCount = packModel.GetItemCountByID(PackType.Item, model.atkCostItemId); if (energy <= 0 && hasCount <= 0) { SysNotifyMgr.Instance.ShowTip("FairySiege13"); return; } // 不能攻击已摧毁的城池 if (!model.TryGetBatSceneCityInfo(model.showBatType, model.showBatGroup, model.showCityId, out FairySiegeBatSceneCity batSceneCity)) return; if (batSceneCity.HP <= 0 || model.nowFairySiegeBatCityInfo.GuardID == 0) { SysNotifyMgr.Instance.ShowTip("FairySiege17"); return; } //体力不足,已自动消耗一个攻城令 if (energy <= 0 && hasCount > 0) { SysNotifyMgr.Instance.ShowTip("FairySiege14"); } model.DeepCopyFairySiegeBatCityInfo(model.nowFairySiegeBatCityInfo, model.lastFairySiegeBatCityInfo); model.SendAtk(1, model.showCityId, model.nowFairySiegeBatCityInfo.GuardID); }); } protected override void BindController() { } protected override void OnPreOpen() { rpAtk.redpointId = model.GetRedpointId(FairySiegeRedPointType.Atk); ItemLogicUtility.Instance.hidePickItem = true; model.atkAwardQueue.Clear(); tranReward.SetActive(false); transHostInfo.SetActive(false); transHostAllDead.SetActive(false); scrReward.OnRefreshCell += OnRefreshCell; model.RewardDisplayAction += OnRewardDisplayAction; model.UpdateFamilyGCZBatSceneInfoEvent += OnUpdateFamilyGCZBatSceneInfoEvent; model.UpdateFamilyGCZBatReportEvent += OnUpdateFamilyGCZBatReportEvent; model.UpdateFamilyGCZPlayerInfoEvent += OnUpdateFamilyGCZPlayerInfoEvent; model.UpdateFamilyGCZBatCityInfoEvent += OnUpdateFamilyGCZBatCityInfoEvent; RoleParticularModel.OnRevPackage += OnRevPackage; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; uiEffStart.OnComplete += OnStartUIEffComplete; uiEffStart.SetActive(true); isBossCityShow = model.TryGetBossCityData(model.showBatType, model.showBatGroup, out bossCityData); btnReward.SetActive(!isBossCityShow); btnBattleReport.SetActive(!isBossCityShow); transRegularCityInfo.SetActive(!isBossCityShow); transBossCityInfo.SetActive(isBossCityShow); Reset(); Display(); } bool isPlaying = false;//自己正在攻击 private void OnUpdateFamilyGCZBatCityInfoEvent(FairySiegeBatCityInfo nowInfo) { if (nowInfo == null) return; if (isPlaying) return; //来自自己的攻击 if (nowInfo.AtkPlayerID == PlayerDatas.Instance.baseData.PlayerID) { isPlaying = true; model.DeepCopyFairySiegeBatCityInfo(nowInfo, model.myFairySiegeBatCityInfo); PlayEffectSeq(model.lastFairySiegeBatCityInfo, model.myFairySiegeBatCityInfo, nowInfo); } else { SysNotifyMgr.Instance.ShowTip(nowInfo.GuardID <= 0 ? "FairySiege15" : "FairySiege16"); model.DeepCopyFairySiegeBatCityInfo(nowInfo, model.lastFairySiegeBatCityInfo); UpdateEnemyInfo(nowInfo.GuardID, true); UpdateEnemyHP(nowInfo.HP, nowInfo.HPMax); } } public void SendModel() { if (model.nowFairySiegeBatCityInfo != null || model.nowFairySiegeBatCityInfo.GuardID != 0) { roleParticularModel.ViewCrossPlayerCacheData((int)model.nowFairySiegeBatCityInfo.GuardID); } } protected override void OnPreClose() { ItemLogicUtility.Instance.hidePickItem = false; scrReward.OnRefreshCell -= OnRefreshCell; model.RewardDisplayAction -= OnRewardDisplayAction; model.UpdateFamilyGCZBatSceneInfoEvent -= OnUpdateFamilyGCZBatSceneInfoEvent; model.UpdateFamilyGCZBatReportEvent -= OnUpdateFamilyGCZBatReportEvent; model.UpdateFamilyGCZPlayerInfoEvent -= OnUpdateFamilyGCZPlayerInfoEvent; model.UpdateFamilyGCZBatCityInfoEvent -= OnUpdateFamilyGCZBatCityInfoEvent; RoleParticularModel.OnRevPackage -= OnRevPackage; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; uiEffStart.OnComplete -= OnStartUIEffComplete; model.SendQuery(5, 0, 0, 0); } protected override void OnAfterOpen() { CreateScroller(); } protected override void OnAfterClose() { } #endregion private void OnStartUIEffComplete() { uiEffStart.SetActive(false); } private void DisplayAwardWin() { if (model.atkAwardQueue.Count <= 0) return; if (isPlaying) return; if (WindowCenter.Instance.IsOpen("FairySiegeAtkGetItemWin")) return; if (WindowCenter.Instance.IsOpen("FairySiegeAtkGetItemSuccessWin")) return; var netPack = model.atkAwardQueue.Dequeue(); model.nowAtkAwardInfo = netPack; if (model.nowAtkAwardInfo.atkAwardInfo == null) return; if (model.nowAtkAwardInfo.atkAwardInfo.killCntTotal > 0) { ItemLogicUtility.Instance.ShowGetItemEx("FairySiegeAtkGetItemSuccessWin", netPack.showItems, netPack.info, 0, eventName: netPack.eventName); } else { ItemLogicUtility.Instance.ShowGetItemEx("FairySiegeAtkGetItemWin", netPack.showItems, netPack.info, 0, eventName: netPack.eventName); } } protected override void LateUpdate() { DisplayAwardWin(); } #region 技能特效移动动画 Sequence seqEffect; private void ResetEffectSeq() { seqEffect?.Kill(); seqEffect = DOTween.Sequence(); rectEffect.anchoredPosition = rectStart.anchoredPosition; uiEffAtk.effect = atkEffectId; StopEffectAtk(); } //lastInfo 玩家发起攻击前的数据 myInfo 玩家发起攻击的返回数据 nowInfo 当前的最新数据 public void PlayEffectSeq(FairySiegeBatCityInfo lastInfo, FairySiegeBatCityInfo myInfo, FairySiegeBatCityInfo nowInfo) { ResetEffectSeq(); UI3DModelExhibition.Instance.PlayAnim(GAStaticDefine.State_Attack1Hash); seqEffect.Append( rectEffect.DOAnchorPos(rectEnd.anchoredPosition, atkEffectDuration).SetDelay(atkEffectDelay).SetEase(Ease.OutQuad) .OnStart(PlayEffectAtk) .OnComplete(() => { StopEffectAtk(); ShowDamage((long)myInfo.HurtValue); //城池被击毁 if (nowInfo.GuardID <= 0) { UpdateEnemyInfo(nowInfo.GuardID); model.DeepCopyFairySiegeBatCityInfo(nowInfo, model.lastFairySiegeBatCityInfo); isPlaying = false; return; } //打死了 if (nowInfo.GuardID != lastInfo.GuardID) { UI3DModelExhibition.InstanceClone1.PlayAnim(GAStaticDefine.State_DeadHash); UpdateEnemyHP(0, model.lastFairySiegeBatCityInfo.HPMax); model.DeepCopyFairySiegeBatCityInfo(nowInfo, model.lastFairySiegeBatCityInfo); Clock.AlarmAfter(0.4f, () => { UpdateEnemyInfo(nowInfo.GuardID, true); }); Clock.AlarmAfter(1.2f, () => { UpdateEnemyHP(nowInfo.HP, nowInfo.HPMax); isPlaying = false; }); } else { UI3DModelExhibition.InstanceClone1.PlayAnim(GAStaticDefine.State_HurtHash); model.DeepCopyFairySiegeBatCityInfo(nowInfo, model.lastFairySiegeBatCityInfo); Clock.AlarmAfter(0.4f, () => { UpdateEnemyInfo(nowInfo.GuardID, true); }); Clock.AlarmAfter(1.2f, () => { UpdateEnemyHP(nowInfo.HP, nowInfo.HPMax); isPlaying = false; }); } }) ); } private void PlayEffectAtk() { uiEffAtk.SetActive(true); uiEffAtk.Play(); } private void StopEffectAtk() { uiEffAtk.SetActive(false); uiEffAtk.Stop(); } #endregion #region 受击飘血动画 Sequence seqDamage; private void ResetDamage() { seqDamage?.Kill(); seqDamage = DOTween.Sequence(); txtDamage.SetActive(false); txtDamage.text = string.Empty; txtDamage.transform.localPosition = Vector3.zero; txtDamage.color = new Color(txtDamage.color.r, txtDamage.color.g, txtDamage.color.b, 1f); } public void ShowDamage(long HurtValue) { ResetDamage(); txtDamage.text = model.DisplayDamageNum(HurtValue); txtDamage.SetActive(true); seqDamage.Append(txtDamage.transform.DOLocalMoveY(damageMoveDistance, 0.25f).SetEase(Ease.OutQuad)); seqDamage.Append(txtDamage.DOFade(0, 0.25f).SetEase(Ease.Linear) .OnComplete(() => { txtDamage.SetActive(false); })); } #endregion //非战斗期玩家还在战斗界面时,退出相关界面 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(); } } private void OnSecondEvent() { DisplayEnergyRegenCountdown(); ExitWin(); } private void DisplayEnergy() { txtEnergy.text = Language.Get("FairySiege074", StringUtility.Contact(model.energy, "/", model.energyMax)); } private void DisplayEnergyRegenCountdown() { int time = (int)(model.energyTime + model.energyRecIntervalMin * 60 - TimeUtility.AllSeconds); imgEnergyTime.SetActive(model.energyTime != 0 && time > 0); string timeStr = TimeUtility.SecondsToDHMS(time); txtEnergyTime.text = Language.Get("FairySiege075", timeStr, 1); } private void OnRewardDisplayAction() { tranReward.SetActive(model.isRewardDisplay); } private void OnUpdateFamilyGCZBatSceneInfoEvent() { DisplayFamilyInfo(); DisplayEnergy(); } private void OnUpdateFamilyGCZPlayerInfoEvent() { DisplayEnergy(); } private void OnUpdateFamilyGCZBatReportEvent() { if (!WindowCenter.Instance.IsOpen()) { WindowCenter.Instance.Open(); } } private void CreateScroller() { scrReward.Refresh(); if (!model.killDefMemRewardDict.IsNullOrEmpty()) { var list = model.GetAllUniqueItemIDs(model.killDefMemRewardDict); for (var i = 0; i < list.Count; i++) { scrReward.AddCell(ScrollerDataType.Header, i); } } scrReward.Restart(); } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent(); _cell?.Display(cell.index); } private void DisplayFamilyInfo() { transRegularCityInfo.SetActive(!isBossCityShow); transBossCityInfo.SetActive(isBossCityShow); if (isBossCityShow) { bossEmblem.InitUI(EmblemHelper.GetOtherEmblemModel(EmblemHelper.GetDefaultFamilyEmblemId())); float fillAmount = Mathf.Round((float)bossCityData.HP / bossCityData.HPMax * 1000f) / 1000f; string info = Language.Get("FairySiege125", UIHelper.ReplaceLargeNum(bossCityData.HP), UIHelper.ReplaceLargeNum(bossCityData.HPMax)); slidBossCity.value = fillAmount; txtBossCityHP.text = info; } else { if (!model.TryGetBatSceneCityInfo(model.showBatType, model.showBatGroup, model.showCityId, out FairySiegeBatSceneCity batSceneCity)) return; if (!model.TryGetFairySiegeFamilyInfo(model.showCityId, out FairySiegeFamilyInfo familyInfo)) return; if (!FamilyGCZCampLVConfig.Has(batSceneCity.CityLV)) return; FamilyGCZCampLVConfig config = FamilyGCZCampLVConfig.Get(batSceneCity.CityLV); 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; string serverName = ServerListCenter.Instance.GetServerName((int)familyInfo.ServerID); txtServerName.text = Language.Get("Z2002", serverName); emblem.InitUI(EmblemHelper.GetOtherEmblemModel((int)familyInfo.EmblemID)); } } private void OnRevPackage(int viewType, int playerID, RoleParticularModel.ViewPlayerData data) { UpdateEnemyInfo(data); } private void DisplayEnemyDefaultModel() { var apperance = equipModel.GetAppearance(); var reikiRootEffectId = PlayerDatas.Instance.baseData.reikiRootEffectId; myData = new UI3DPlayerExhibitionData { job = PlayerDatas.Instance.baseData.Job, fashionClothesId = apperance.fashionClothes, fashionWeaponId = apperance.fashionWeapon, fashionSecondaryId = apperance.fashionSecondary, clothesId = apperance.clothes, weaponId = apperance.weapon, secondaryId = apperance.secondary, wingsId = apperance.wings, suitLevel = apperance.isSuit ? 1 : 0, reikiRootEffectId = reikiRootEffectId, isDialogue = false, equipLevel = PlayerDatas.Instance.baseData.suitLevel, scale = 1, titleID = PlayerDatas.Instance.baseData.TitleID }; UI3DModelExhibition.InstanceClone1.ShowPlayer(rawImgHost, myData); UI3DModelExhibition.InstanceClone1.ChangeModelEulerAngles(hostEulerAngles); } private void DisplayMyInfo() { int realmLevel = PlayerDatas.Instance.baseData.realmLevel; txtMyFightPonit.text = UIHelper.ReplaceLargeNum(PlayerDatas.Instance.baseData.FightPoint); txtMyName.text = PlayerDatas.Instance.baseData.PlayerName; imgMyRelamLv.SetActive(realmLevel > 0); if (realmLevel > 0) { var icon = RealmConfig.Get(realmLevel).Img; imgMyRelamLv.SetSprite(icon); imgMyRelamLv.SetNativeSize(); } var apperance = equipModel.GetAppearance(); var reikiRootEffectId = PlayerDatas.Instance.baseData.reikiRootEffectId; myData = new UI3DPlayerExhibitionData { job = PlayerDatas.Instance.baseData.Job, fashionClothesId = apperance.fashionClothes, fashionWeaponId = apperance.fashionWeapon, fashionSecondaryId = apperance.fashionSecondary, clothesId = apperance.clothes, weaponId = apperance.weapon, secondaryId = apperance.secondary, wingsId = apperance.wings, suitLevel = apperance.isSuit ? 1 : 0, reikiRootEffectId = reikiRootEffectId, isDialogue = false, equipLevel = PlayerDatas.Instance.baseData.suitLevel, scale = 1, titleID = PlayerDatas.Instance.baseData.TitleID }; UI3DModelExhibition.Instance.ShowPlayer(rawImgMy, myData); UI3DModelExhibition.Instance.ChangeModelEulerAngles(myEulerAngles); rawImgMy.raycastTarget = false; } private void UpdateEnemyHP(ulong HP, ulong HPMax) { float fillAmount = Mathf.Round((float)HP / HPMax * 1000f) / 1000f; string info = model.CalculateDamagePercentage(HP, HPMax); slidHP.value = fillAmount; txtHP.text = info; } private void DisplayModel(RoleParticularModel.ViewPlayerData viewPlayerData) { var data = new UI3DPlayerExhibitionData { job = viewPlayerData.rolePropData.Job, fashionClothesId = viewPlayerData.GetItemId(RoleEquipType.FashionClothes), fashionWeaponId = viewPlayerData.GetItemId(RoleEquipType.FashionWeapon), fashionSecondaryId = viewPlayerData.GetItemId(RoleEquipType.FashionWeapon2), clothesId = viewPlayerData.GetItemId(RoleEquipType.Clothes), suitLevel = (int)(viewPlayerData.rolePropData.EquipShowSwitch % 10), weaponId = viewPlayerData.GetItemId(RoleEquipType.Weapon), wingsId = viewPlayerData.GetItemId(RoleEquipType.Wing), secondaryId = viewPlayerData.GetItemId(RoleEquipType.Weapon2), reikiRootEffectId = (int)viewPlayerData.rolePropData.EquipShowSwitch / 1000 % 1000, isDialogue = false, equipLevel = (int)viewPlayerData.rolePropData.EquipShowSwitch / 10 % 100, titleID = viewPlayerData.rolePropData.TitleID, }; UI3DModelExhibition.InstanceClone1.ShowPlayer(rawImgHost, data); UI3DModelExhibition.InstanceClone1.ChangeModelEulerAngles(hostEulerAngles); rawImgHost.raycastTarget = false; } private void UpdateEnemyInfo(RoleParticularModel.ViewPlayerData viewPlayerData) { if (viewPlayerData == null) return; Clock.Stop(clock); transHostInfo.SetActive(true); DisplayModel(viewPlayerData); imgHostName.SetActive(true); txtHostName.text = UIHelper.ServerStringTrim(viewPlayerData.rolePropData.Name); int realmLevel = viewPlayerData.rolePropData.RealmLV; imgHostRelamLv.SetActive(realmLevel > 0); if (realmLevel > 0) { var icon = RealmConfig.Get(realmLevel).Img; imgHostRelamLv.SetSprite(icon); imgHostRelamLv.SetNativeSize(); } transHostInfo.SetActive(true); } private void DisplayEnemyDefaultInfo() { DisplayEnemyDefaultModel(); transHostInfo.SetActive(true); imgHostName.SetActive(false); imgHostRelamLv.SetActive(false); } Clock clock; private void UpdateEnemyInfo(uint GuardID, bool isShow = false) { transHostAllDead.SetActive(GuardID <= 0); transHostInfo.SetActive(isShow); //最后一个守卫被打死了放一个摧毁的城池图片 if (GuardID <= 0) { transHostInfo.SetActive(false); return; } viewPlayerData = roleParticularModel.GetViewPlayerData((int)GuardID); //防viewPlayerData为空 if (viewPlayerData == null) { SendModel(); clock = Clock.AlarmAfter(1f, DisplayEnemyDefaultInfo); return; } DisplayModel(viewPlayerData); imgHostName.SetActive(true); txtHostName.text = UIHelper.ServerStringTrim(viewPlayerData.rolePropData.Name); int realmLevel = viewPlayerData.rolePropData.RealmLV; imgHostRelamLv.SetActive(realmLevel > 0); if (realmLevel > 0) { var icon = RealmConfig.Get(realmLevel).Img; imgHostRelamLv.SetSprite(icon); imgHostRelamLv.SetNativeSize(); } transHostInfo.SetActive(true); } private void Display() { model.isRewardDisplay = false; DisplayEnergy(); DisplayEnergyRegenCountdown(); DisplayFamilyInfo(); DisplayMyInfo(); if (model.lastFairySiegeBatCityInfo != null) { UpdateEnemyInfo(model.lastFairySiegeBatCityInfo.GuardID, false); UpdateEnemyHP(model.lastFairySiegeBatCityInfo.HP, model.lastFairySiegeBatCityInfo.HPMax); } } private void Reset() { ResetEffectSeq(); ResetDamage(); } } }