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;
using KTGMGemClient;
///
/// 对战管理器,主要负责屏幕上方的敌方数据结构和相关的显示展示
/// 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 level = tower.currentLevel;
if (tower.towerFeature == EFeatureTower.Skill_Fire)
{
// 火,列攻击,直接在该兵线释放
WaveLineOpponentManager.instance.PlayWaveLineEffect(index);
AgentInsManager.instance.ExecWavelineAttack(index, tower.ElfId, 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, tower.ElfId, 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 >= ElfUpgradeData.MaxTowerLevel)
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);
}
}