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 mSlots; private BlockSlot mPickedSlot; private BlockSlot mTouchedSlot; private bool mInteractable; private bool mIsForbidden = false; private List mExcludeIndexes; private string mNewCardID; private void Awake() { mSlots = Utils.GetChildListFirstLayer(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 GetAllSoldier() { List tSoldierlist = new List(); 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 tEmptyList = new List(); 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(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 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(); } 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(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(); 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().SetPlayerBP(mBP); } else { UIManager.Instance.GetUI().SetEnemyBP(mBP); } } }