429 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			429 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
| 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] Renderer mRdrFloor;
 | |
|     [SerializeField] GameObject mGobMergeFx;
 | |
| 
 | |
|     private List<BlockSlot> mSlots;
 | |
| 
 | |
|     private BlockSlot mPickedSlot;
 | |
|     private BlockSlot mTouchedSlot;
 | |
| 
 | |
|     private bool mInteractable;
 | |
|     private bool mIsForbidden = false;
 | |
|     private List<int> mExcludeIndexes;
 | |
| 
 | |
|     private string mNewCardID;
 | |
| 
 | |
|     private void Awake()
 | |
|     {
 | |
|         mSlots = Utils.GetChildListFirstLayer<BlockSlot>(mCtnSlots);
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             if (mIsPlayer)
 | |
|             {
 | |
|                 mSlots[i].Init(i, OnPickUpSlot, OnMoveSlot, OnDropDownSlot);
 | |
|                 mSlots[i].ShowFloor(true);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 mSlots[i].Init(i);
 | |
|                 mSlots[i].ShowFloor(false);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         EnableInteraction(mIsPlayer);
 | |
|     }
 | |
| 
 | |
|     public List<SoldierUnit> GetAllSoldier()
 | |
|     {
 | |
|         List<SoldierUnit> tSoldierlist = new List<SoldierUnit>();
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             if (mSlots[i].HasUnit)
 | |
|             {
 | |
|                 tSoldierlist.AddRange(mSlots[i].MyUnit.GetAllSoldier());
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return tSoldierlist;
 | |
|     }
 | |
| 
 | |
|     public void CreateBaseHumanBlock()//only for player
 | |
|     {
 | |
|         CreateBlockAtRandomPos(BlockType.Human);
 | |
| 
 | |
|         AudioManager.Instance.PlaySound(AudioClipType.BuyUnit);
 | |
|     }
 | |
| 
 | |
|     public void CreateBaseMonsterBlock()//only for player
 | |
|     {
 | |
|         CreateBlockAtRandomPos(BlockType.Monster);
 | |
| 
 | |
|         AudioManager.Instance.PlaySound(AudioClipType.BuyUnit);
 | |
|     }
 | |
| 
 | |
|     public void CreateBlockAtRandomPos(BlockType pBType, int pLevel = 1)
 | |
|     {
 | |
|         List<int> tEmptyList = new List<int>();
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             if (!mSlots[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);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private string SaveBlocksAsData()
 | |
|     {
 | |
|         string tDataStr = "";
 | |
| 
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             if (mSlots[i].HasUnit)
 | |
|             {
 | |
|                 tDataStr += string.Format("{0}_{1}_{2}", i, (int)mSlots[i].MyUnit.BType, mSlots[i].MyUnit.Level) + ";";
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!string.IsNullOrEmpty(tDataStr))
 | |
|         {
 | |
|             tDataStr = tDataStr.Remove(tDataStr.LastIndexOf(';'));//remove last ';'
 | |
|         }
 | |
| 
 | |
|         return tDataStr;
 | |
|     }
 | |
| 
 | |
|     public BlockUnit CreateBlock(int pIndex, BlockType pBType, int pLevel)
 | |
|     {
 | |
|         if (pIndex < 0 || pIndex >= mSlots.Count)
 | |
|             return null;
 | |
| 
 | |
|         if (mSlots[pIndex].HasUnit)
 | |
|         {
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         BlockUnit tNewUnit = Instantiate(ResourceManager.Instance.LoadRes<BlockUnit>(Const.Path.GetBlockUnit(pBType, pLevel)));
 | |
|         mSlots[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 void ClearAll()
 | |
|     {
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             if (mSlots[i].HasUnit)
 | |
|             {
 | |
|                 Destroy(mSlots[i].MyUnit.gameObject);
 | |
|                 mSlots[i].SetUnit(null);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (mIsPlayer)
 | |
|         {
 | |
|             SavePlayerArmy();
 | |
|         }
 | |
| 
 | |
|         mBP = 0;
 | |
|         RefreshBPUI();
 | |
|     }
 | |
| 
 | |
|     public void EnableInteraction(bool pEnabled)
 | |
|     {
 | |
|         if (!pEnabled && mPickedSlot != null)
 | |
|         {
 | |
|             OnDropDownSlot(mPickedSlot.Index);
 | |
|         }
 | |
| 
 | |
|         mInteractable = pEnabled;
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             if (mInteractable)
 | |
|             {
 | |
|                 mSlots[i].SetDelegate(OnPickUpSlot, OnMoveSlot, OnDropDownSlot);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 mSlots[i].SetDelegate(null, null, null);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public void ShowFloor(bool pShow)
 | |
|     {
 | |
|         for (int i = 0; i < mSlots.Count; i++)
 | |
|         {
 | |
|             mSlots[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<int> pExcludeIndexes = null)
 | |
|     {
 | |
|         mIsForbidden = pIsForbidden;
 | |
|         mExcludeIndexes = pExcludeIndexes;
 | |
|     }
 | |
| 
 | |
|     private void OnPickUpSlot(int pIndex)
 | |
|     {
 | |
|         if (!mInteractable)
 | |
|             return;
 | |
| 
 | |
|         VibrateManager.Instance.Vibrate(VibrateType.Light);
 | |
| 
 | |
|         mPickedSlot = mSlots[pIndex];
 | |
|         mPickedSlot.SetState(IsSlotForbidden(pIndex) ? BlockState.Forbidden : BlockState.Picked);
 | |
|     }
 | |
| 
 | |
|     private void OnMoveSlot(int pIndex)
 | |
|     {
 | |
|         if (!mInteractable)
 | |
|             return;
 | |
| 
 | |
|         if (mPickedSlot == null || mPickedSlot.MyUnit == null || IsSlotForbidden(pIndex))
 | |
|             return;
 | |
| 
 | |
|         RaycastHit[] tHits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition), 100, LayerMask.GetMask("BlockSlot", "Ground"));
 | |
| 
 | |
|         BlockSlot tHitSlot = null;
 | |
|         GameObject tGround = null;
 | |
|         RaycastHit tGroundHit = new RaycastHit();
 | |
|         for (int i = 0; i < tHits.Length; i++)
 | |
|         {
 | |
|             if (tHitSlot == null && tHits[i].collider.gameObject.layer == Const.Layer.BlockSlot)
 | |
|             {
 | |
|                 tHitSlot = tHits[i].collider.gameObject.GetComponent<BlockSlot>();
 | |
|             }
 | |
| 
 | |
|             if (tHits[i].collider.gameObject.layer == Const.Layer.Ground)
 | |
|             {
 | |
|                 tGround = tHits[i].collider.gameObject;
 | |
|                 tGroundHit = tHits[i];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (mTouchedSlot != null && mTouchedSlot != tHitSlot)//reset last touched
 | |
|         {
 | |
|             mTouchedSlot.SetState(BlockState.Normal);
 | |
|             mTouchedSlot = null;
 | |
|             VibrateManager.Instance.Vibrate(VibrateType.Light);
 | |
|         }
 | |
| 
 | |
|         if (tHitSlot != null && tHitSlot != mPickedSlot)//if hit new slot,set new touched
 | |
|         {
 | |
|             mTouchedSlot = tHitSlot;
 | |
|             if (!IsSlotForbidden(mTouchedSlot.Index))
 | |
|             {
 | |
|                 if (mTouchedSlot.MyUnit != null && mPickedSlot.MyUnit != null && mTouchedSlot.MyUnit.IsMergable(mPickedSlot.MyUnit))
 | |
|                 {
 | |
|                     mTouchedSlot.SetState(BlockState.Mergable);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     mTouchedSlot.SetState(BlockState.Movable);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 mTouchedSlot.SetState(BlockState.Forbidden);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (tGround != null)
 | |
|         {
 | |
|             mPickedSlot.MyUnit.transform.position = tGroundHit.point + Vector3.up * 2;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void OnDropDownSlot(int pIndex)
 | |
|     {
 | |
|         if (!mInteractable)
 | |
|             return;
 | |
| 
 | |
|         VibrateManager.Instance.Vibrate(VibrateType.Light);
 | |
| 
 | |
|         if (mPickedSlot == null || mPickedSlot.MyUnit == null || IsSlotForbidden(pIndex))
 | |
|         {
 | |
|             mPickedSlot?.SetState(BlockState.Normal);
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         if (mTouchedSlot != null && mTouchedSlot != mPickedSlot)
 | |
|         {
 | |
|             if (!IsSlotForbidden(mTouchedSlot.Index))
 | |
|             {
 | |
|                 if (mTouchedSlot.MyUnit != null && mPickedSlot.MyUnit != null && mTouchedSlot.MyUnit.IsMergable(mPickedSlot.MyUnit))
 | |
|                 {
 | |
|                     int tOldBP = Utils.GetBpByLv(mPickedSlot.MyUnit.Level) * 2;
 | |
|                     BlockUnit tNewUnit = Instantiate(ResourceManager.Instance.LoadRes<BlockUnit>(Const.Path.GetBlockUnit(mPickedSlot.MyUnit.BType, mPickedSlot.MyUnit.Level + 1)));
 | |
|                     Destroy(mTouchedSlot.MyUnit.gameObject);
 | |
|                     Destroy(mPickedSlot.MyUnit.gameObject);
 | |
| 
 | |
|                     mTouchedSlot.SetUnit(tNewUnit);
 | |
|                     mPickedSlot.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();
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     BlockUnit tTouchUnit = mTouchedSlot.MyUnit;
 | |
|                     mTouchedSlot.SetUnit(mPickedSlot.MyUnit);
 | |
|                     mPickedSlot.SetUnit(tTouchUnit);
 | |
| 
 | |
|                     if (GuideManager.Instance.CurGuideIndex == 1)
 | |
|                     {
 | |
|                         GuideManager.Instance.FinishCurrentStep();
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 mPickedSlot.SetUnit(mPickedSlot.MyUnit);
 | |
|             }
 | |
|             
 | |
|             mTouchedSlot.SetState(BlockState.Normal);
 | |
|             mTouchedSlot = null;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             mPickedSlot.SetUnit(mPickedSlot.MyUnit);
 | |
|         }
 | |
| 
 | |
|         mPickedSlot.SetState(BlockState.Normal);
 | |
|         mPickedSlot = 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<PanelNewCard>();
 | |
|             tUINew.InitCard(mNewCardID);
 | |
| 
 | |
|             AudioManager.Instance.PlaySound(AudioClipType.NewCard);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void SavePlayerArmy()
 | |
|     {
 | |
|         if (!mIsPlayer)
 | |
|             return;
 | |
| 
 | |
|         PlayerData.Instance.ArmyStr = SaveBlocksAsData();
 | |
|     }
 | |
| 
 | |
|     private void RefreshBPUI()
 | |
|     {
 | |
|         if (mIsPlayer)
 | |
|         {
 | |
|             UIManager.Instance.GetUI<PanelTopBar>().SetPlayerBP(mBP);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             UIManager.Instance.GetUI<PanelTopBar>().SetEnemyBP(mBP);
 | |
|         }
 | |
|     }
 | |
| } |