using cfg.CharacterCfg;
using Framework;
using Gameplay.Common;
using Gameplay.Net;
using NLDPB;
using System;
using System.Numerics;
using Gameplay;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using Button = UnityEngine.UI.Button;
using Image = UnityEngine.UI.Image;
using Vector3 = UnityEngine.Vector3;
using Vector2 = UnityEngine.Vector2;
using Cysharp.Threading.Tasks;
using UnityEngine.UI;
using PhxhSDK;
using LC.Newtonsoft.Json.Bson;
using static CriWare.CriAtomExBeatSync;
public class UILevelUpController : UIWindow
{
//UI GameObj
///Auto Gen Start///
public Image Image_BG;
public Button Button_Back;
public Button Button_Home;
public Image Image_PointBG;
public TMP_Text Text_ExpPoint;
public TMP_Text Text_UniversalExp;
public TMP_Text Text_Exp_Value;
public Image Image_LevelUPBar;
public Image Image_Poster;
public TMP_Text Text_Level_Now;
public TMP_Text Text_Level_Max;
public Image Image_Hp;
public TMP_Text Text_Hp;
public TMP_Text Text_Hp_Value;
public TMP_Text Text_Change_Hp;
public Image Image_Morale;
public TMP_Text Text_Cultivate_Morale;
public TMP_Text Text_Morale_Value;
public TMP_Text Text_Change_Morale;
public Image Image_Defense;
public TMP_Text Text_Cultivate_Defense;
public TMP_Text Text_Defense_Value;
public TMP_Text Text_Change_Defanse;
public Image Image_Armor;
public TMP_Text Text_Cultivate_Armor;
public TMP_Text Text_Armor_Value;
public TMP_Text Text_Change_Armor;
public Image Image_Attack;
public TMP_Text Text_Cultivate_Attack;
public TMP_Text Text_Attack_Value;
public TMP_Text Text_Change_Attack;
public Image Image_Speed;
public TMP_Text Text_Cultivate_Speed;
public TMP_Text Text_Speed_Value;
public TMP_Text Text_Change_Speed;
public TMP_Text Text_ExpBefore;
public TMP_Text Text_EXP;
public TMP_Text Text_Plus;
public TMP_Text Text_ExpNeed;
public TMP_Text Text_Level_Value;
public TMP_Text Text_LV;
public TMP_Text Text_LevelUpTo;
public Button Button_MAX;
public Button Button_Plus;
public Button Button_Minus;
public Image Image_LevelBar;
public Image Image_LevelArrow;
float ArrowRadius;
public TMP_Text Text_Level;
public Button Button_Cannot;
public TMP_Text Text_Cannot_Confirm;
public Button Button_Confirm;
public TMP_Text Text_Confirm;
public Button Button_Cancel;
/// Auto Gen End///
///
/// 打开角色升级界面
///
public static async UniTask Open(CharacterDataInfo characterDataInfo)
{
CommonUtils.CaptureScreenshot();
return await UIManager.Instance.CreateAndOpenWindow(UINameConst.UILevelUp, characterDataInfo);
}
///
/// 台词类
///
private class Dialogue : UIGameObjectWrapper
{
///
/// 角色名
///
private TMP_Text textName;
///
/// 角色类型
///
private TMP_Text textContent;
public Dialogue(GameObject root) : base(root)
{
textName = GetComponent("Text_Name");
textContent = GetComponent("Text_Describe");
}
public void SetInfo(string name)
{
textName.text = name;
}
public void SetDialogue(string content)
{
textContent.text = content;
}
}
///
/// 高斯模糊遮罩
///
private RawImage rawImageGaussianBlurMask;
///
/// 升级总消耗经验
///
private int expLast;
bool useAllExp = false;//达不到上限,有多少经验用多少经验
CharacterDataInfo mCharacterDataInfo;
private int mCurrentExp;
CharacterLevelExp mCharacterLevelExpCfg;
CharacterBreak mCharacterBreak;
int targetLevel ;
public DragForUI dragForUI;
private AudioInst dialogueAudio;
private Dialogue dialogue;
///
/// 是否正在播放台词语音
///
public bool IsDialoguePlaying
{
get { return dialogueAudio != null && dialogueAudio.IsPlaying; }
}
// Use this for initialization
public override void OnInit()
{
//bind UI GameObj
UILevelUpBinder.GetComponents(this);
ArrowRadius = -Image_LevelArrow.GetComponent().anchoredPosition.y;
rawImageGaussianBlurMask = GetComponent("GaussianBlurMask");
rawImageGaussianBlurMask.texture = CommonUtils.GetScreenTexture2D();
dialogue = new(FindObj("Image_ActorLineBG"));
BindButton(Button_Back, OnButton_BackClick);
BindButton(Button_Plus, OnButton_PlusClick);
BindButton(Button_Minus, OnButton_MinusClick);
BindButton(Button_MAX, OnButton_MAXClick);
BindButton(Button_Cancel, OnButton_CancelClick);
BindButton(Button_Confirm, OnButton_ConfirmClick);
BindButton(Button_Home, OnClickHome);
dragForUI = CommonUtils.GetComponent(this.gameObject,"Drag");
dragForUI.OnDragStarted += ondragStart;
dragForUI.OnDraging += ondrag;
dragForUI.OnDragCompleted += ondragend;
RegisterEvent();
}
UnityEngine.Vector2 startPos;
float interval;//滑动的间隔
float levelCursor;//将等级想象成游标进行滑动
private void ondragend(PointerEventData eventData)
{
}
private void ondrag(PointerEventData eventData)
{
//float offset = eventData.position.y - startPos.y;
float offset = eventData.delta.y;
if (offset < 0)
{
if (targetLevel <= mCharacterDataInfo.Level)//不可小于已达成等级
{
return;
}
levelCursor += interval * offset;
targetLevel = (int)levelCursor;
if (targetLevel <= mCharacterDataInfo.Level)
targetLevel = (int)mCharacterDataInfo.Level;
CalculateExp();
RefreshAfterChangeValue();
RefreshLevelUpBtn();
}
else
{
if (mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel) == null)
{
DebugUtil.LogError("没有配置Id {0} 突破等级 {1}", mCharacterDataInfo.ID, mCharacterDataInfo.BreakLevel);
return;
}
if (targetLevel >= GetExpEnoughMaxLevel(out _))
{
return;
}
levelCursor += interval * offset;
targetLevel = (int)levelCursor;
if (targetLevel > GetExpEnoughMaxLevel(out _))
{
targetLevel = GetExpEnoughMaxLevel(out uint consumeExp);
}
CalculateExp();
RefreshAfterChangeValue();
RefreshLevelUpBtn();
}
}
private void ondragStart(PointerEventData eventData)
{
startPos = eventData.position;
interval = (mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit - mCharacterDataInfo.Level) / 400f;
levelCursor = targetLevel;
}
private void OnClickHome()
{
UIManager.Instance.CloseAllNormalExcept(UINameConst.UI_MainPanel);
}
private void RegisterEvent()
{
EventManager.Instance.Register(EventManager.EventName.EN_CharacterLevelUp,(Action)OnCharacterLevelup);
}
private void OnCharacterLevelup(UpgradeType type)
{
if (type != UpgradeType.UtLevel)
{
return;
}
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.CHARACTER_LEVEL_UP);
mCharacterDataInfo = CharacterDataInfoManager.Instance.GetCharacterInfo(mCharacterDataInfo.ID);
targetLevel = (int)mCharacterDataInfo.Level;
expLast = 0;
RefreshUI();
RefreshAfterChangeValue();
RefreshLevelUpBtn();
dialogueAudio?.Stop();
dialogueAudio = DialogueManager.Instance.PlayDiaogue((int)mCharacterDataInfo.Uid,
cfg.DialogueCfg.E_DialogueType.UpLevel,
(content) => { dialogue.SetDialogue(content); });
}
private void UnregisterEvent()
{
EventManager.Instance.Unregister(EventManager.EventName.EN_CharacterLevelUp,(Action)OnCharacterLevelup);
}
private void RefreshLevelUpBtn()
{
Button_Cannot.gameObject.SetActive(expLast <= 0);//targetLevel == mCharacterDataInfo.Level
Button_Confirm.gameObject.SetActive(expLast > 0);//targetLevel != mCharacterDataInfo.Level
Button_Cancel.gameObject.SetActive(expLast > 0);
}
private void OnButton_ConfirmClick()
{
if (expLast <= 0)//targetLevel == mCharacterDataInfo.Level
{
return;
}
//if (targetLevel >= expLast)
//{
// CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_expDontFull"));
// return;
//}
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
if (Actor.Instance.Item.GetItemCount(GLConfig.Inst.data.HeroExpItem)< expLast)
{
CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_expDontFull"));
return;
}
if (targetLevel > ActorLevelTableHelper.Instance.Get((int)Actor.Instance.Base.GetProp(ActorProp.Level)).Level)
{
CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_LevelUpOutRange"));
return;
}
NetHelper.CharacterUpgrade(mCharacterDataInfo.ID, NLDPB.UpgradeType.UtLevel, (uint)targetLevel, useAllExp);
}
private void OnButton_CancelClick()
{
if (expLast <= 0)
{
return;
}
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLICK);
targetLevel = (int)mCharacterDataInfo.Level;
if (useAllExp)
useAllExp = false;
CalculateExp();
RefreshAfterChangeValue();
RefreshLevelUpBtn();
}
private void OnButton_MAXClick()
{
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLAIM);
if (targetLevel > mCharacterDataInfo.Cfg.Hp.Count)
{
DebugUtil.LogError("levelexp表和各种属性没有该突破等级的等级限制等级");
return;
}
if (targetLevel >= mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit)
{
CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_LevelUpMAX"));
return;
}
targetLevel = GetExpEnoughMaxLevel(out _);//mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit;
//expLast = (int)consumeExp;
CalculateExp();
RefreshAfterChangeValue();
RefreshLevelUpBtn();
}
///
/// 获取最大经验值填充后的等级(超出等级上限取最大等级)
///
///
///
int GetExpEnoughMaxLevel(out uint consumeExp)
{
var exp = Actor.Instance.Item.GetItemCount(GLConfig.Inst.data.HeroExpItem);
int level = (int)mCharacterDataInfo.Level;
int consume = -(int)mCharacterDataInfo.Exp;
while (level < mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit)
{
if (mCharacterLevelExpCfg.GetOrDefault((level + 1)) != null)
{
var needExp = mCharacterLevelExpCfg.GetOrDefault((level + 1)).EXP;
if (consume + needExp > exp)
{
consumeExp = exp;//达不到上限,有多少经验用多少经验
return level;
}
else
{
consume += needExp;
}
}
else
{
DebugUtil.LogError("CharacterLevelExpCfg的等级不够了!!!");
}
level++;
}
consumeExp = (uint)consume;
return level;
}
private void OnButton_MinusClick()
{
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLAIM);
if (expLast <= 0)//targetLevel <= mCharacterDataInfo.Level
{
CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_LevelUpMIN"));
return;
}
if (!useAllExp)
targetLevel--;
else
useAllExp = false;
CalculateExp();
RefreshAfterChangeValue();
RefreshLevelUpBtn();
}
private void OnButton_PlusClick()
{
AudioManager.Instance.PlayAudio(Framework.Constants.Sound.COMMON_CLAIM);
if (mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel)==null)
{
DebugUtil.LogError("没有配置Id {0} 突破等级 {1}",mCharacterDataInfo.ID, mCharacterDataInfo.BreakLevel);
return;
}
if (targetLevel >= mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit)
{
CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_LevelUpMAX"));
return;
}
if (targetLevel + 1 > GetExpEnoughMaxLevel(out uint consumeExp))
{
CommonUtils.ShowMessageTips(CommonUtils.GetLocalizeText("cultivate_expDontFull"));
expLast = (int)consumeExp;
useAllExp = true;
}
else
{
targetLevel++;
CalculateExp();
}
RefreshAfterChangeValue();
RefreshLevelUpBtn();
}
private void OnButton_BackClick()
{
CloseWindow();
}
private void LoadCfg()
{
OnLoadCfg(TableManager.Instance.Tables.CharacterLevelExp);
}
private void OnLoadCfg(CharacterLevelExp characterLevelExp)
{
mCharacterLevelExpCfg = characterLevelExp;
mCharacterBreak = TableManager.Instance.Tables.CharacterBreak;
RefreshUI();
RefreshAfterChangeValue();
}
//invoke when open window
protected override void OnShowWindow(object data = null)
{
base.OnShowWindow(data);
mCharacterDataInfo = data as CharacterDataInfo;
if (mCharacterDataInfo != null)
targetLevel = (int)mCharacterDataInfo.Level;
LoadCfg();
expLast = 0;
useAllExp = false;
dialogue.SetInfo(mCharacterDataInfo.Name);
InputManager.Instance.OnFingersMove += OnFingersHover;
}
private void OnFingersHover(float delta)
{
}
private async void RefreshUI()
{
string imgPath = CommonUtils.GetCharacterPicPath(mCharacterDataInfo.Cfg.RoleID, CommonUtils.ECharacterPicPathType.LevelUp, (int)mCharacterDataInfo.SkinID);
var sprite = await LoadAssetAsync(imgPath);
CommonUtils.RefreshCharacter2DPic(Image_Poster, sprite);
RefresLevelUpBar(mCharacterDataInfo.Level);
RefreshLevelUpBtn();
}
private void RefresLevelUpBar(uint targetRefreshLevel)
{
uint nowLevel = targetRefreshLevel;
int maxLevel = (int)mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit;
Text_Level_Now.text = nowLevel.ToString();
Text_Level_Max.text ="/" +maxLevel.ToString();
Text_Level_Value.text = targetRefreshLevel.ToString();
float fillAmount;
if (nowLevel >= maxLevel)
{
fillAmount = 1;
}
else
{
fillAmount = mCharacterDataInfo.Exp * 1.0f / (mCharacterLevelExpCfg.Get((int)mCharacterDataInfo.Level + 1).EXP == 0 ? 1 : mCharacterLevelExpCfg.Get((int)mCharacterDataInfo.Level + 1).EXP);
}
//fillAmount= mCharacterDataInfo.Exp/ //nowLevel / (float)maxLevel;
Image_LevelBar.fillAmount = fillAmount;
SetExpBarFillAmount(fillAmount);
Text_Hp_Value.text = mCharacterDataInfo.HP().ToString();
Text_Morale_Value.text = mCharacterDataInfo.Cfg.MaxMorale.ToString();
Text_Defense_Value.text = mCharacterDataInfo.Defence().ToString();
Text_Armor_Value.text= mCharacterDataInfo.Armor().ToString();
Text_Attack_Value.text=mCharacterDataInfo.Attack().ToString();
Text_Speed_Value.text=mCharacterDataInfo.MoveSpeed().ToString();
Text_Exp_Value.text = Actor.Instance.Item.GetItemCount(GLConfig.Inst.data.HeroExpItem).ToString(); ;
}
private void RefreshAfterChangeValue()
{
float changeHp = mCharacterDataInfo.HpLevelUp((int)targetLevel) - mCharacterDataInfo.HpLevelUp((int)mCharacterDataInfo.Level);
float changeMorale = 0;
float changeDefense = mCharacterDataInfo.DefenceLevelUp((int)targetLevel) - mCharacterDataInfo.DefenceLevelUp((int)mCharacterDataInfo.Level);
float changeArmor = mCharacterDataInfo.ArmorLevelUp((int)targetLevel) - mCharacterDataInfo.ArmorLevelUp((int)mCharacterDataInfo.Level);
float changeAttack = mCharacterDataInfo.AttackLevelUp((int)targetLevel) - mCharacterDataInfo.AttackLevelUp((int)mCharacterDataInfo.Level);
float changespeed = 0;
Text_Change_Hp.gameObject.SetActive(changeHp != 0);
Text_Change_Hp.text = "+" + changeHp.ToString();
Text_Change_Morale.gameObject.SetActive(changeMorale != 0);
Text_Change_Morale.text = "+" + changeMorale.ToString();
Text_Change_Defanse.gameObject.SetActive(changeDefense != 0);
Text_Change_Defanse.text = "+" + changeDefense.ToString();
Text_Change_Armor.gameObject.SetActive(changeArmor != 0);
Text_Change_Armor.text = "+" + changeArmor.ToString();
Text_Change_Attack.gameObject.SetActive(changeAttack != 0);
Text_Change_Attack.text = "+" + changeAttack.ToString();
Text_Change_Speed.gameObject.SetActive(changespeed != 0);
Text_Change_Speed.text = "+" + changespeed.ToString();
Text_ExpNeed.gameObject.SetActive(expLast > 0);
Text_ExpNeed.text = expLast.ToString();
Text_Level_Now.text = targetLevel.ToString();
Text_Level_Value.text = targetLevel.ToString();
Text_ExpBefore.text = mCharacterDataInfo.Exp.ToString();
float fillAmount;
if (targetLevel >= mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit)//= mCharacterLevelExpCfg.GetOrDefault((int)targetLevel).EXP - expLast;
{
//满级进度条
fillAmount = 1;
}
else if (expLast <= 0)
{
//无强化显示持有经验进度条
fillAmount = mCharacterDataInfo.Exp * 1.0f / (mCharacterLevelExpCfg.Get((int)mCharacterDataInfo.Level + 1).EXP == 0 ? 1 : mCharacterLevelExpCfg.Get((int)mCharacterDataInfo.Level + 1).EXP);
}
else
{
if (!useAllExp)
{
fillAmount = 0;
}
else
{
var consumeExp = expLast;
CalculateExp();
useAllExp = true;
var ExpRemainInBar = consumeExp - expLast;
expLast = consumeExp;
fillAmount = ExpRemainInBar / (float)mCharacterLevelExpCfg.GetOrDefault((int)targetLevel + 1).EXP;
}
}
//fillAmount = targetLevel / (float)mCharacterBreak.Get((int)mCharacterDataInfo.ID, (int)mCharacterDataInfo.BreakLevel).LevelLimit;
Image_LevelBar.fillAmount = fillAmount;
SetExpBarFillAmount(fillAmount);
}
///
/// 设置经验进度条及小三角位置
///
///
void SetExpBarFillAmount(float fillAmount)
{
var angle = -360 * fillAmount;
Image_LevelArrow.transform.rotation = UnityEngine.Quaternion.Euler(0, 0, angle);
float posX = Mathf.Sin(angle * Mathf.Deg2Rad) * ArrowRadius;
float posY = -Mathf.Cos(angle * Mathf.Deg2Rad) * ArrowRadius;
Image_LevelArrow.GetComponent().anchoredPosition = new Vector2(posX, posY);
}
///
/// 计算恰好升到目标等级所需经验(刚好升满经验槽的经验量)
///
void CalculateExp()
{
useAllExp = false;
expLast = 0;
for (int i = (int)mCharacterDataInfo.Level; i < targetLevel; i++)
{
if (mCharacterLevelExpCfg.GetOrDefault((i + 1)) != null)
{
expLast += mCharacterLevelExpCfg.GetOrDefault((i + 1)).EXP;
}
else
{
DebugUtil.LogError("CharacterLevelExpCfg的等级不够了!!!");
}
}
expLast -= (int)mCharacterDataInfo.Exp;
}
//invoke when reload window
protected override void OnReloadWindow(object data = null)
{
}
protected override void OnUpdate()
{
base.OnUpdate();
dialogue.IsScaleShow = IsDialoguePlaying;
}
//invoke when close window
protected override void OnHideWindow()
{
EventManager.Instance.Send(EventManager.EventName.EN_UIControllCultivateMainInput, true);
AudioManager.Instance.AudioMgrObj.StopAllSounds();
base.OnHideWindow();
}
public override void OnRelease()
{
base.OnRelease();
UnregisterEvent();
}
}