using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using URandom = UnityEngine.Random; public class BlockManager : MonoBehaviour { [SerializeField] int mBP = 0; [SerializeField] bool mIsPlayer; [SerializeField] Transform mCtnSlots; [SerializeField] SellSlot mMySellSlot; [SerializeField] Renderer mRdrFloor; [SerializeField] GameObject mGobMergeFx; private List mBlocks; private BlockSlot mPickedBlock; private BlockSlot mTouchedBlock; private SellSlot mTouchedSellSlot; private bool mInteractable; private bool mIsForbidden = false; private List mExcludeIndexes; private bool mIsAutoMerge; private Queue mAutoMergeQueue = new Queue(); private string mNewCardID; private void Awake() { mBlocks = Utils.GetChildListFirstLayer(mCtnSlots); for (int i = 0; i < mBlocks.Count; i++) { if (mIsPlayer) { mBlocks[i].Init(i, OnPickUpSlot, OnMoveSlot, OnDropDownSlot); mBlocks[i].ShowFloor(true); } else { mBlocks[i].Init(i); mBlocks[i].ShowFloor(false); } } EnableInteraction(mIsPlayer); } public List GetAllSoldier() { List tSoldierlist = new List(); for (int i = 0; i < mBlocks.Count; i++) { if (mBlocks[i].HasUnit) { tSoldierlist.AddRange(mBlocks[i].MyUnit.GetAllSoldier()); } } return tSoldierlist; } public void CreateBaseHumanBlock()//only for player { CreateBlockAtRandomPos(BlockType.Human); CheckAutoMerge(); AudioManager.Instance.PlaySound(AudioClipType.BuyUnit); } public void CreateBaseMonsterBlock()//only for player { CreateBlockAtRandomPos(BlockType.Monster); CheckAutoMerge(); AudioManager.Instance.PlaySound(AudioClipType.BuyUnit); } public void CreateBlockAtRandomPos(BlockType pBType, int pLevel = 1) { List tEmptyList = new List(); for (int i = 0; i < mBlocks.Count; i++) { if (!mBlocks[i].HasUnit) { tEmptyList.Add(i); } } if (tEmptyList.Count > 0) { CreateBlock(tEmptyList[URandom.Range(0, tEmptyList.Count)], pBType, pLevel); } } public void CreateBlocksByData(string pDataStr)//eg:0_0_1;1_1_5 { string[] tData = pDataStr.Split(';'); int tPosIndex = 0, tBType = 0, tLevel = 1; for (int i = 0; i < tData.Length; i++) { if (string.IsNullOrEmpty(tData[i])) continue; string[] tNums = tData[i].Split('_'); tPosIndex = int.Parse(tNums[0]); tBType = int.Parse(tNums[1]); tLevel = int.Parse(tNums[2]); CreateBlock(tPosIndex, (BlockType)tBType, tLevel); } } public BlockUnit CreateBlock(int pIndex, BlockType pBType, int pLevel) { if (pIndex < 0 || pIndex >= mBlocks.Count) return null; if (mBlocks[pIndex].HasUnit) { return null; } BlockUnit tNewUnit = Instantiate(ResourceManager.Instance.LoadRes(Const.Path.GetBlockUnit(pBType, pLevel))); mBlocks[pIndex].SetUnit(tNewUnit); mBP += Utils.GetBpByLv(tNewUnit.Level); RefreshBPUI(); if (mIsPlayer) { if (tNewUnit != null) { DisplayNewUnit(tNewUnit); VibrateManager.Instance.Vibrate(VibrateType.Medium); } SavePlayerArmy(); } return tNewUnit; } public string GetFormationStr() { string tDataStr = ""; for (int i = 0; i < mBlocks.Count; i++) { if (mBlocks[i].HasUnit) { tDataStr += string.Format("{0}_{1}_{2}", i, (int)mBlocks[i].MyUnit.BType, mBlocks[i].MyUnit.Level) + ";"; } } if (!string.IsNullOrEmpty(tDataStr)) { tDataStr = tDataStr.Remove(tDataStr.LastIndexOf(';'));//remove last ';' } return tDataStr; } public void ClearAll() { for (int i = 0; i < mBlocks.Count; i++) { if (mBlocks[i].HasUnit) { Destroy(mBlocks[i].MyUnit.gameObject); mBlocks[i].SetUnit(null); } } if (mIsPlayer) { SavePlayerArmy(); } mBP = 0; RefreshBPUI(); } private void MergeBlock(BlockSlot pBlockSrc, BlockSlot pBlockDst) { int tOldBP = Utils.GetBpByLv(pBlockSrc.MyUnit.Level) * 2; BlockUnit tNewUnit = Instantiate(ResourceManager.Instance.LoadRes(Const.Path.GetBlockUnit(pBlockSrc.MyUnit.BType, pBlockSrc.MyUnit.Level + 1))); Destroy(pBlockDst.MyUnit.gameObject); Destroy(pBlockSrc.MyUnit.gameObject); pBlockDst.SetUnit(tNewUnit); pBlockSrc.SetUnit(null); mBP += Utils.GetBpByLv(tNewUnit.Level) - tOldBP; RefreshBPUI(); AudioManager.Instance.PlaySound(AudioClipType.MergeUnit); if (mIsPlayer) { DisplayNewUnit(tNewUnit); string tCardID = Utils.GetCardID(tNewUnit.BType, tNewUnit.Level); if (!PlayerData.Instance.HasCard(tCardID)) { mNewCardID = tCardID; PlayerData.Instance.GetCard(mNewCardID); TimerManager.Instance.Schedule(ShowNewCard, 0.3f); } else { mNewCardID = ""; } if (GuideManager.Instance.CurGuideIndex == 2) { GuideManager.Instance.FinishCurrentStep(); } } } private void SwitchBlock(BlockSlot pBlockA, BlockSlot pBlockB) { BlockUnit tTempUnit = pBlockB.MyUnit; pBlockB.SetUnit(pBlockA.MyUnit); pBlockA.SetUnit(tTempUnit); if (GuideManager.Instance.CurGuideIndex == 1) { GuideManager.Instance.FinishCurrentStep(); } } private void RemoveBlock(BlockSlot pBlockA) { BlockUnit tUnit = pBlockA.MyUnit; pBlockA.SetUnit(null); Destroy(tUnit.gameObject); } public void EnableInteraction(bool pEnabled) { if (!pEnabled && mPickedBlock != null) { OnDropDownSlot(mPickedBlock.Index); } mInteractable = pEnabled; for (int i = 0; i < mBlocks.Count; i++) { if (mInteractable) { mBlocks[i].SetDelegate(OnPickUpSlot, OnMoveSlot, OnDropDownSlot); } else { mBlocks[i].SetDelegate(null, null, null); } } } public void ShowFloor(bool pShow) { for (int i = 0; i < mBlocks.Count; i++) { mBlocks[i].ShowFloor(pShow); } if (mIsPlayer) { if (mRdrFloor != null) { mRdrFloor.material.DOFloat(pShow ? 0 : 1, "_Dissolve", 1f); } } else { mRdrFloor.gameObject.SetActive(pShow); } } public void SetForbidden(bool pIsForbidden, List pExcludeIndexes = null) { mIsForbidden = pIsForbidden; mExcludeIndexes = pExcludeIndexes; } private void OnPickUpSlot(int pIndex) { if (!mInteractable || mIsAutoMerge) return; VibrateManager.Instance.Vibrate(VibrateType.Light); mPickedBlock = mBlocks[pIndex]; mPickedBlock.SetState(IsSlotForbidden(pIndex) ? BlockState.Forbidden : BlockState.Picked); if (PlayerData.Instance.IsAutoMergeEnabled && mPickedBlock.MyUnit != null && mMySellSlot != null) { int tSellPrice = PlayerData.Instance.CurrentSellBase * Mathf.RoundToInt(Mathf.Pow(2, mPickedBlock.MyUnit.Level - 1)); mMySellSlot.SetSellPrice(tSellPrice); mMySellSlot.Show(true); } } private void OnMoveSlot(int pIndex) { if (!mInteractable || mIsAutoMerge) return; if (mPickedBlock == null || mPickedBlock.MyUnit == null || IsSlotForbidden(pIndex)) return; RaycastHit[] tHits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition), 100, Const.Layer.OpLayer); mTouchedSellSlot = null; BlockSlot tHitBlock = null; GameObject tGround = null; RaycastHit tGroundHit = new RaycastHit(); for (int i = 0; i < tHits.Length; i++) { if (tHitBlock == null && tHits[i].collider.gameObject.layer == Const.Layer.BlockSlot) { tHitBlock = tHits[i].collider.gameObject.GetComponent(); } if (tHits[i].collider.gameObject.layer == Const.Layer.SellSlot) { mTouchedSellSlot = tHits[i].collider.gameObject.GetComponent(); } if (tHits[i].collider.gameObject.layer == Const.Layer.Ground) { tGround = tHits[i].collider.gameObject; tGroundHit = tHits[i]; } } if (mTouchedBlock != null && mTouchedBlock != tHitBlock)//reset last touched { mTouchedBlock.SetState(BlockState.Normal); mTouchedBlock = null; VibrateManager.Instance.Vibrate(VibrateType.Light); } if (tHitBlock != null && tHitBlock != mPickedBlock)//if hit new slot,set new touched { mTouchedBlock = tHitBlock; if (!IsSlotForbidden(mTouchedBlock.Index)) { if (mTouchedBlock.MyUnit != null && mPickedBlock.MyUnit != null && mTouchedBlock.MyUnit.IsMergable(mPickedBlock.MyUnit)) { mTouchedBlock.SetState(BlockState.Mergable); } else { mTouchedBlock.SetState(BlockState.Movable); } } else { mTouchedBlock.SetState(BlockState.Forbidden); } } if (mMySellSlot != null) { mMySellSlot.SetTouched(mTouchedSellSlot == mMySellSlot); } if (tGround != null) { mPickedBlock.MyUnit.transform.position = tGroundHit.point + Vector3.up * 2; } } private void OnDropDownSlot(int pIndex) { if (!mInteractable || mIsAutoMerge) return; VibrateManager.Instance.Vibrate(VibrateType.Light); if (mPickedBlock == null || mPickedBlock.MyUnit == null || IsSlotForbidden(pIndex)) { mPickedBlock?.SetState(BlockState.Normal); return; } if (mMySellSlot != null && mTouchedSellSlot == mMySellSlot) { BlockSlot tSellBlock = mPickedBlock; mPickedBlock = null; if (tSellBlock.MyUnit.Level < TKGSDKManager.Instance.GetConfigInt(TKGParamKey.SellWarningLevel)) { RemoveBlock(tSellBlock); mMySellSlot.Sell(); tSellBlock.SetState(BlockState.Normal); mMySellSlot.SetSellPrice(0); mMySellSlot.Show(false); SavePlayerArmy(); } else { PanelDialog tUIDialog = UIManager.Instance.OpenUI(); tUIDialog.Init(LanguageConfig.Instance.GetText("Caution"), string.Format(LanguageConfig.Instance.GetText("SellUnit"), UIUtils.NumForShort(mMySellSlot.CurPrice), tSellBlock.MyUnit.Level), () => { RemoveBlock(tSellBlock); mMySellSlot.Sell(); tSellBlock.SetState(BlockState.Normal); mMySellSlot.SetSellPrice(0); mMySellSlot.Show(false); SavePlayerArmy(); }, () => { tSellBlock.SetUnit(tSellBlock.MyUnit); tSellBlock.SetState(BlockState.Normal); mMySellSlot.SetSellPrice(0); mMySellSlot.Show(false); SavePlayerArmy(); }); } } else { if (mTouchedBlock != null && mTouchedBlock != mPickedBlock) { if (!IsSlotForbidden(mTouchedBlock.Index)) { if (mTouchedBlock.MyUnit != null && mPickedBlock.MyUnit != null && mTouchedBlock.MyUnit.IsMergable(mPickedBlock.MyUnit)) { MergeBlock(mPickedBlock, mTouchedBlock); } else { SwitchBlock(mPickedBlock, mTouchedBlock); } } else { mPickedBlock.SetUnit(mPickedBlock.MyUnit); } mTouchedBlock.SetState(BlockState.Normal); mTouchedBlock = null; } else { mPickedBlock.SetUnit(mPickedBlock.MyUnit); } if (PlayerData.Instance.IsAutoMergeEnabled && mMySellSlot != null) { mMySellSlot.SetSellPrice(0); mMySellSlot.Show(false); } mPickedBlock.SetState(BlockState.Normal); mPickedBlock = null; SavePlayerArmy(); } } private bool IsSlotForbidden(int pIndex) { return mIsForbidden && (mExcludeIndexes == null || !mExcludeIndexes.Contains(pIndex)); } private void DisplayNewUnit(BlockUnit pUnit) { Instantiate(mGobMergeFx, pUnit.transform.position, Quaternion.identity); pUnit.transform.localScale = Vector3.zero; pUnit.transform.DOScale(1, 0.5f).SetEase(Ease.OutBounce); } private void ShowNewCard() { if (!mIsPlayer) return; if (!string.IsNullOrEmpty(mNewCardID)) { PanelNewCard tUINew = UIManager.Instance.OpenUI(); tUINew.InitCard(mNewCardID); AudioManager.Instance.PlaySound(AudioClipType.NewCard); } } private void SavePlayerArmy() { if (!mIsPlayer) return; PlayerData.Instance.ArmyStr = GetFormationStr(); } private void RefreshBPUI() { if (mIsPlayer) { UIManager.Instance.GetUI().SetPlayerBP(mBP); } else { UIManager.Instance.GetUI().SetEnemyBP(mBP); } } public void CheckAutoMerge() { if (!PlayerData.Instance.IsAutoMergeEnabled || PlayerData.Instance.AutoMergeCount <= 0) { return; } Dictionary> tCheckDic = new Dictionary>(); for (int i = 0; i < mBlocks.Count; i++) { if (mBlocks[i].MyUnit != null && mBlocks[i].MyUnit.Level < GameConfig.Instance.BlockMaxLevel) { string tKey = mBlocks[i].MyUnit.BType.ToString() + mBlocks[i].MyUnit.Level.ToString(); if (!tCheckDic.ContainsKey(tKey)) { tCheckDic[tKey] = new List(); } tCheckDic[tKey].Add(i); if (tCheckDic[tKey].Count >= 2) { mAutoMergeQueue.Enqueue(new Vector2Int(tCheckDic[tKey][0], tCheckDic[tKey][1])); mIsAutoMerge = true; UIManager.Instance.GetUI().EnableRecruitBtns(!mIsAutoMerge); mBlocks[tCheckDic[tKey][0]].MyUnit.transform.DOMove(mBlocks[tCheckDic[tKey][1]].MyUnit.transform.position, 0.3f).SetEase(Ease.Linear).onComplete = ExcuteAutoMerge; break; } } } } private void ExcuteAutoMerge() { Vector2Int tMergePair = mAutoMergeQueue.Dequeue(); MergeBlock(mBlocks[tMergePair.x], mBlocks[tMergePair.y]); SavePlayerArmy(); PlayerData.Instance.AutoMergeCount--; UIManager.Instance.GetUI().RefreshAutoMerge(); mIsAutoMerge = false; UIManager.Instance.GetUI().EnableRecruitBtns(!mIsAutoMerge); CheckAutoMerge(); } }