using System.Collections; using System.Collections.Generic; using UnityEngine; using Core.Utilities; using TowerDefense.Towers.Placement; using TowerDefense.Nodes; using TowerDefense.Level; using Core.Economy; using TowerDefense.Towers; using TowerDefense.UI.HUD; using TowerDefense.Agents; /// /// 对战管理器,主要负责屏幕上方的敌方数据结构和相关的显示展示 /// 1: 放置塔防的区域。 /// 2: OppomentNodeList 对方Agent的刷新和行进路线。 /// 3: CurrencyMgr 对方的现金管理 /// 4: OpponentAI 对方的AI管理器,用于管理AI相关的内容,是升级,还是购买,还是其它相关。 /// 先做一个简单的功能,在开始之后,Opponent先后购买相关的Tower,然后OpponentAgent开始从对方 /// Node行进,直到最后死亡。 /// /// 先能刷新出来OpponentAgent再说下一步 /// public class OpponentMgr : Singleton { protected static readonly int MAX_TOWER = 5; /// /// 用于对手刷新出来Agent相对应的数据 /// public WaveManager m_WaveManager; /// /// 思考决策的时间间隔. /// public float thinkInternal = 0.5f; // 改的时间很长是为了调试 /// /// 放置塔防的IPlacementArea. Placement area ghost tower is currently on /// public IPlacementArea m_CurrentArea; /// /// 处理TowerList相关的数据.AI相关的内容也要 /// protected List m_listTower = new List(); protected List m_waitBuyTowerPos = new List(); /// /// 对方Agent刷新的StartNode区域. /// protected Node m_StartNode; /// /// 对手的现金管理器 /// protected Currency m_Currency; /// /// 是否已经开始刷怪 /// protected bool bWaveStart = false; /// /// 用于内部判断是否触发智能的时间变量. /// protected float thinkTimeEle = 0; /// /// 当前空闲的塔位数目 /// protected int freeTowerPos = 0; /// /// 每一个Tower对应的AttributeID. /// protected int[] towerAttributeID = new int[5]; protected int[] towerLevel = new int[5]; // 是否第一次,测试代码: protected static bool bFirst = true; public int startingCurrency { get; set; } public Currency currency { get { return this.m_Currency; } } // 待释放技能宝石队列 private Queue canReleaseSkillsQueue = new Queue(); // 可释放技能的怪物数量限制 >= 4 可释放 private int agentQuantityLimit = 4; /// /// 设置每一条兵线对应的AttID /// /// /// public void SetTowerAttID(int waveline, int id, int lvl) { towerAttributeID[waveline] = id; towerLevel[waveline] = lvl; //if( lvl >=1 ) this.UpdateWaveSpawn(waveline, id); } public int GetTowerAttID(int waveline) { return towerAttributeID[waveline]; } public int GetTowerLevel(int waveline) { return towerLevel[waveline]; } /// /// 增加一个Tower. /// /// public void addTower(Tower tw) { this.m_listTower.Add(tw); } /// /// 根据坐标获取对应的Tower指针. /// /// /// public Tower getTower(int x, int y) { foreach (Tower t in m_listTower) { if ((t.gridPosition.x == x) && (t.gridPosition.y == y)) return t; } return null; } /// /// 删除一个Tower. /// /// public void removeTower(Tower tw) { m_listTower.Remove(tw); } /// /// 更新刷怪时间. /// /// /// protected void UpdateWaveSpawn(int gridx, int attid) { LevelManager.instance.waveManager.UpdateWaveSpawnTime(gridx, attid); } // // Start is called before the first frame update void Start() { bFirst = true; bWaveStart = false; for (int ti = 0; ti < MAX_TOWER; ti++) towerAttributeID[ti] = 0; // 获取IPlaceArea.获取相应的放置区域。 GameObject placeObj = GameObject.FindGameObjectWithTag("PlaceTowerOpponent"); if (placeObj == null) return; m_CurrentArea = placeObj.GetComponent(); // 初始化全局的Starting Currency. startingCurrency = LevelManager.instance.startingCurrency; m_Currency = new Currency(startingCurrency); m_Currency.currencyChanged += M_Currency_currencyChanged; if (RandomTower.MAX_INTERNAL) this.thinkInternal = 1000; } public void ResetCurrency(int currency) { int curChg = currency - m_Currency.currentCurrency; m_Currency.AddCurrency(curChg); } private void M_Currency_currencyChanged() { //int cnum = m_Currency.currentCurrency; //Debug.Log("当前反方的现金数目是:" + cnum); } /* float updateTime = 6.2f; protected void updateTest() { updateTime -= Time.deltaTime; if( updateTime <= 0 ) { updateTime = 100; this.upgradeAttackTower(2); } }*/ // Update is called once per frame void Update() { //if (!this.bWaveStart) return; if (!UIStart.bGameStart) return; // TEST CODE: // this.updateTest(); this.thinkTimeEle += Time.deltaTime; if (thinkInternal > thinkTimeEle) return; thinkTimeEle -= thinkInternal; // 触发思考操作:加入一个随机的Tower. if (bFirst) { bFirst = false; RandomTower.instance.randomOpponentTower(false); this.currency.TryPurchase(TowerPrice.instance.opponentTowerPrice); TowerPrice.instance.onTowerBuySuccess(); } // 更新开格子相关 this.updateTowerPosBuy(); // 触发升级Tower的操作. this.UpdateAttackTower(); PurchaseTower(); ReleaseSkills(); } /// /// 购买产生塔 /// private void PurchaseTower() { // 首先需要钱够 if (currency.currentCurrency >= TowerPrice.instance.opponentTowerPrice) { // 如果还不能产生精灵宝石 if (UIStart.instance.gameStartTime <= RandomTower.SKILL_TOWER_TIME) { if (freeTowerPos > 0 && m_CurrentArea.hasFreeAttackPos()) { --freeTowerPos; RandomTower.instance.randomOpponentTower(false); } } else { // 先获取一个随机的宝石 Tower newTower = RandomTower.instance.GetRandomTower(true, false); if (newTower.towerFeature == EFeatureTower.NULL && m_CurrentArea.hasFreeAttackPos()) { --freeTowerPos; RandomTower.instance.RandomPlaceTower(newTower, true); } else { // 技能宝石的话,直接购买,购买成功放入队列 int cost = TowerPrice.instance.opponentTowerPrice; bool purchaseSuccess = OpponentMgr.instance.currency.TryPurchase(cost); if (purchaseSuccess) canReleaseSkillsQueue.Enqueue(newTower); } } } } /// /// AI 如果 有技能宝石 并且 某一条路线的怪物数量 >= 4 释放技能 /// private void ReleaseSkills() { if (canReleaseSkillsQueue.Count == 0) return; WaveLineAgentInsMgr[] waveLineList = AgentInsManager.instance.getOppoWaveLineList(); int index = -1; // 找某一条兵线怪物数量 >= 4 的 for (int i = 0; i < waveLineList.Length; ++i) { int num = waveLineList[i].getAgentInsNum(); if (num >= agentQuantityLimit) { index = i; break; } } if (index == -1) return; Tower tower = canReleaseSkillsQueue.Dequeue(); int attributeId = tower.attributeId; int level = tower.currentLevel; if (tower.towerFeature == EFeatureTower.Skill_Fire) { // 火,列攻击,直接在该兵线释放 WaveLineOpponentManager.instance.PlayWaveLineEffect(index); AgentInsManager.instance.ExecWavelineAttack(index, attributeId, level, true); } else if (tower.towerFeature == EFeatureTower.Skill_Bomb) { // 控制,技能中心为离塔最近的小怪的中心点 Agent agent = AgentInsManager.instance.GetMinDisAgent(index, true); WaveLineOpponentManager.instance.PlayBattleAreaBombEffect(agent.transform.position); AgentInsManager.instance.ExecBombAttack(agent.transform.position, attributeId, level, true); } } /// /// 更新火属性Tower对左右塔的攻击增加. /// protected void updateFireTowerAttRise() { for (int ti = 0; ti < MAX_TOWER; ti++) { Tower tw = this.getTower(ti, 0); if (tw) tw.attackRise = 0.0f; } for (int ti = 0; ti < MAX_TOWER; ti++) { Tower tw = this.getTower(ti, 0); if (tw.towerFeature == EFeatureTower.LightTower) { int nidx = ti - 1; if (nidx >= 0) { tw = getTower(nidx, 0); if (tw) tw.attackRise = 0.1f; } nidx = ti + 1; if (nidx < MAX_TOWER) { tw = getTower(nidx, 0); if (tw) tw.attackRise = 0.1f; } } } } /// /// 更新AI开格子逻辑. /// protected void updateTowerPosBuy() { if (m_waitBuyTowerPos.Count > 0) { if (currency.currentCurrency >= TowerPlacementGrid.GRID_OPENCASH_OPPO) { m_CurrentArea.buyWaitBuyGrid(m_waitBuyTowerPos[0], 0); m_waitBuyTowerPos.RemoveAt(0); } } else { if (currency.currentCurrency >= TowerPlacementGrid.GRID_OPENCASH_OPPO) { if (m_CurrentArea.isWaitBuyGrid(1, 0)) { m_CurrentArea.buyWaitBuyGrid(1, 0); freeTowerPos++; } else if (m_CurrentArea.isWaitBuyGrid(3, 0)) { m_CurrentArea.buyWaitBuyGrid(3, 0); freeTowerPos++; } else if (m_CurrentArea.isWaitBuyGrid(0, 0)) { m_CurrentArea.buyWaitBuyGrid(0, 0); freeTowerPos++; } else if (m_CurrentArea.isWaitBuyGrid(4, 0)) { m_CurrentArea.buyWaitBuyGrid(4, 0); freeTowerPos++; } } } return; } /// /// 反方攻击塔位的升级逻辑更新,暂时根据场内小怪数目使用简单的逻辑。 /// protected void UpdateAttackTower() { WaveLineAgentInsMgr[] waveLineList = AgentInsManager.instance.getOppoWaveLineList(); for (int ti = 0; ti < waveLineList.Length; ti++) { int agentNum = waveLineList[ti].getAgentInsNum(); Tower tower = this.getTower(ti, 0); if (!tower) continue; int lvl = tower.currentLevel; if (lvl >= Tower.MAX_LEVEL) continue; if ((agentNum - 1) <= lvl) continue; // 塔位升级相关的数据: if (tower.towerFeature != EFeatureTower.GrowUp) { if ((lvl == 0) && (currency.TryPurchase(80))) { this.upgradeAttackTower(ti); } else if ((lvl == 1) && (currency.TryPurchase(240))) { this.upgradeAttackTower(ti); } else if ((lvl == 2) && (currency.TryPurchase(440))) { this.upgradeAttackTower(ti); } } } } /// /// 升级某一个攻击位的Tower. /// /// protected void upgradeAttackTower(int xpos) { Tower newTower = RandomTower.instance.GetRandomTower(true, true); Tower oldTower = this.getTower(xpos, 0); if (oldTower == null) return; GameUI.instance.DisplaceTower(newTower, oldTower); } /// /// 开启某一个等待购买的塔位。 /// /// /// public bool openWaitBuyGrid(int x) { if (null == this.m_CurrentArea) return false; if (m_CurrentArea.isWaitBuyGrid(x, 0)) { if (currency.currentCurrency < TowerPlacementGrid.GRID_OPENCASH_OPPO) { m_waitBuyTowerPos.Add(x); return true; } return m_CurrentArea.buyWaitBuyGrid(x, 0); } else return true; } /// /// 开始Wave移动 /// public void StartWaves() { this.bWaveStart = true; m_WaveManager.StartWaves(); } /// /// 开启一条兵线. /// /// public void startWaveLine(int x, int attid) { m_WaveManager.startWaveLine(x, attid); if (m_CurrentArea.isWaitBuyGrid(x, 0)) { openWaitBuyGrid(x); freeTowerPos++; } } public void prepareWaveline(int x) { m_WaveManager.prepareWaveline(x); } /// /// 停止某一条兵线的出兵。 /// /// public void stopWaveLine(int x) { m_WaveManager.stopWaveLine(x); } }