using ActionGameFramework.Health;
|
using Core.Health;
|
using Core.Utilities;
|
using DG.Tweening;
|
using KTGMGemClient;
|
using System;
|
using System.Collections.Generic;
|
using TowerDefense.Agents;
|
using TowerDefense.Targetting;
|
using TowerDefense.UI.HUD;
|
using UnityEngine;
|
using UnityEngine.AI;
|
using TowerDefense.Level;
|
using TowerDefense.Towers;
|
|
/// <summary>
|
/// 基于兵线的Agent Instance管理器
|
/// </summary>
|
public class WaveLineAgentInsMgr
|
{
|
/// <summary>
|
/// 当前WaveID对应到的所有Agent实例
|
/// </summary>
|
protected List<Agent> agentInsList;
|
protected Vector3 targetPosition;
|
|
/// <summary>
|
/// 对应的WaveLineID.
|
/// </summary>
|
public int waveLineID
|
{
|
get; set;
|
}
|
|
public WaveLineAgentInsMgr(int waveID)
|
{
|
waveLineID = waveID;
|
agentInsList = new List<Agent>();
|
}
|
|
/// <summary>
|
/// 添加一个AgentIns.
|
/// </summary>
|
/// <param name="ag"></param>
|
public void addAgentIns(Agent ag)
|
{
|
agentInsList.Add(ag);
|
}
|
|
/// <summary>
|
/// 删除一个AgentIns.
|
/// </summary>
|
/// <param name="ag"></param>
|
public void delAgentIns(Agent ag)
|
{
|
agentInsList.Remove(ag);
|
}
|
|
/// <summary>
|
/// 当前列对应的怪物数目
|
/// </summary>
|
/// <returns></returns>
|
public int getAgentInsNum()
|
{
|
int ret = 0;
|
|
for (int i = 0; i < agentInsList.Count; ++i)
|
{
|
if (agentInsList[i].AgentType == SpawnAgentType.Normal)
|
++ret;
|
}
|
|
return ret;
|
}
|
|
/// <summary>
|
/// 获取当前管理对应的listAgent.
|
/// </summary>
|
public List<Agent> listAgent { get { return this.agentInsList; } }
|
|
// /// <summary>
|
// /// 获取距目标结点最近的Agent.
|
// /// </summary>
|
// /// <returns></returns>
|
// public Agent getMinDisAgent(bool _noPoison = false)
|
// {
|
// if (agentInsList.Count == 0) return null;
|
|
// // 排序,然后返回对应的数据
|
// // 直接使用闭包函数来进行排序:
|
// agentInsList.Sort((left, right) =>
|
// {
|
// if (left.distanceToDest > right.distanceToDest)
|
// {
|
// return 1;
|
// }
|
// else if (left.distanceToDest == right.distanceToDest)
|
// {
|
// return 0;
|
// }
|
// else
|
// {
|
// return -1;
|
// }
|
// });
|
|
// if (_noPoison)
|
// {
|
// for (int ti = 0; ti < agentInsList.Count; ti++)
|
// {
|
// if (!agentInsList[ti].bInPoison)
|
// return agentInsList[ti];
|
// }
|
|
// return null;
|
// }
|
// else
|
// return agentInsList[0];
|
// }
|
|
public Agent GetMinDistanceAgent()
|
{
|
Agent ret = null;
|
float minDistance = -1f;
|
|
WaveLineAgentInsMgr[] waveLineAgentIns = AgentInsManager.instance.GetWaveLineList();
|
WaveLineAgentInsMgr waveLineAgentInsMgr = waveLineAgentIns[waveLineID];
|
List<Agent> agents = waveLineAgentInsMgr.listAgent;
|
Vector3 endPos = EndlessLevelManager.instance.GetHomeBasePosition(waveLineID + 1);
|
|
for (int i = 0; i < agents.Count; ++i)
|
{
|
float distance = Mathf.Abs(agents[i].transform.position.z - endPos.z);
|
|
if (minDistance < 0 || distance < minDistance)
|
{
|
minDistance = distance;
|
ret = agents[i];
|
}
|
}
|
|
return ret;
|
}
|
|
}
|
|
/// <summary>
|
/// Wave刷新出来的每一个AgentInstance加进来,统一管理。Targetter不再管理每一个细节。
|
/// 每一个关卡统一管理在场景内出现的AgentInstance.
|
/// </summary>
|
public class AgentInsManager : Singleton<AgentInsManager>
|
{
|
protected readonly int MAX_ATTCNT = 5;
|
|
public static bool bBossCreateState = false;
|
/// <summary>
|
/// Agent位置重设的特效.
|
/// </summary>
|
public GameObject posResetFx;
|
|
/// <summary>
|
/// Agent之间的电弧特效,两个Agent之间发生
|
/// </summary>
|
public GameObject lightBoltFx;
|
|
/// <summary>
|
/// 被电弧击中的效果.
|
/// </summary>
|
public GameObject lightHitFx;
|
|
/// <summary>
|
/// 所有Agent往中间移动的时候,播放的粒子特效
|
/// </summary>
|
public ParticleSystem centMovEffect;
|
|
/// <summary>
|
/// 战场上所有存活的Agent的列表,遍历这个列表,提取出所有的数据
|
/// </summary>
|
protected List<Agent> agentInsList;
|
|
protected Agent agentMinDis = null;
|
|
|
protected List<Targetable> agentInRange = null;
|
/// <summary>
|
/// 存储Agent已方的最高血量数据
|
/// </summary>
|
protected List<Targetable> agentListMaxHp = null;
|
protected Agent agentMaxHp = null;
|
|
/// <summary>
|
/// 对手方要处理的Agent列表
|
/// </summary>
|
protected List<Agent> oppoAgentInsList;
|
protected Agent oppoAgentMinDis = null;
|
protected List<Targetable> oppoAgentInRange = null;
|
/// <summary>
|
/// 存储Agent最高血量数据.
|
/// </summary>
|
protected List<Targetable> oppoAgentListMaxHp = null;
|
protected Agent oppoAgentMaxHp = null;
|
|
/// <summary>
|
/// 随机种子.
|
/// </summary>
|
protected System.Random mRand;
|
|
/// <summary>
|
/// 正方兵线Agent管理数组
|
/// </summary>
|
protected WaveLineAgentInsMgr[] agentWaveLineArray;
|
|
/// <summary>
|
/// 反方兵线Agent管理数组
|
/// </summary>
|
protected WaveLineAgentInsMgr[] oppoAgentWaveLineArray;
|
|
|
/// <summary>
|
/// 用于排序的Buf.
|
/// </summary>
|
protected Agent[] agentTmpArr = new Agent[3];
|
|
|
|
// Start is called before the first frame update
|
void Start()
|
{
|
agentInsList = new List<Agent>();
|
agentInRange = new List<Targetable>();
|
agentListMaxHp = new List<Targetable>();
|
|
oppoAgentInsList = new List<Agent>();
|
oppoAgentInRange = new List<Targetable>();
|
oppoAgentListMaxHp = new List<Targetable>();
|
|
agentWaveLineArray = new WaveLineAgentInsMgr[5];
|
for (int ti = 0; ti < agentWaveLineArray.Length; ti++)
|
agentWaveLineArray[ti] = new WaveLineAgentInsMgr(ti);
|
|
oppoAgentWaveLineArray = new WaveLineAgentInsMgr[5];
|
for (int ti = 0; ti < oppoAgentWaveLineArray.Length; ti++)
|
oppoAgentWaveLineArray[ti] = new WaveLineAgentInsMgr(ti);
|
|
|
mRand = new System.Random();
|
}
|
|
|
public WaveLineAgentInsMgr[] getOppoWaveLineList()
|
{
|
return this.oppoAgentWaveLineArray;
|
}
|
|
public WaveLineAgentInsMgr[] GetWaveLineList()
|
{
|
return agentWaveLineArray;
|
}
|
|
/// <summary>
|
/// 设置某条兵线的所有小兵的移动状态
|
/// </summary>
|
/// <param name="waveLineId">兵线id 1~5, 如果是-1则设置所有兵线的状态</param>
|
/// <param name="canMove">是否可以移动</param>
|
/// <param name="isOppo">是否是敌方</param>
|
public void SetWaveLineCanMove(int waveLineId, bool canMove, bool isOppo)
|
{
|
WaveLineAgentInsMgr[] waveLineAgents = isOppo ? getOppoWaveLineList() : GetWaveLineList();
|
|
for (int i = 0; i < waveLineAgents.Length; ++i)
|
{
|
if (i == waveLineId - 1 || waveLineId == -1)
|
{
|
List<Agent> list = waveLineAgents[i].listAgent;
|
|
for (int j = 0; j < list.Count; ++j)
|
{
|
list[j].CanMove = canMove;
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 根据赛道获得该赛道的所有敌人
|
/// </summary>
|
/// <param name="tunel">赛道id (1~5)</param>
|
/// <param name="isOppo">是否是对手的赛道</param>
|
/// <returns></returns>
|
public List<Agent> GetAgentsByTunel(int tunel, bool isOppo = false)
|
{
|
WaveLineAgentInsMgr[] waveLineAgents = isOppo ? getOppoWaveLineList() : GetWaveLineList();
|
List<Agent> ret = new List<Agent>();
|
|
for (int i = 0; i < waveLineAgents.Length; ++i)
|
{
|
if (i == tunel - 1)
|
{
|
for (int j = 0; j < waveLineAgents[i].listAgent.Count; ++j)
|
{
|
if (waveLineAgents[i].listAgent[j].AgentType == SpawnAgentType.Normal)
|
ret.Add(waveLineAgents[i].listAgent[j]);
|
}
|
|
return ret;
|
}
|
}
|
|
return null;
|
}
|
|
public List<Agent> agentList
|
{
|
get { return this.agentInsList; }
|
}
|
public List<Agent> oppoAgentList
|
{
|
get { return this.oppoAgentInsList; }
|
}
|
|
/// <summary>
|
/// 获取距离最短的Agent.
|
/// </summary>
|
public Agent MinDisAgent
|
{
|
get { return this.agentMinDis; }
|
}
|
|
/// <summary>
|
/// 获取距离最近的Agents
|
/// </summary>
|
/// <param name="lineid"></param>
|
/// <returns></returns>
|
public Agent GetMinDisAgent(int lineid, bool oppo, bool forceGet = false, bool noPoison = false)
|
{
|
if (lineid >= agentWaveLineArray.Length) return null;
|
if (lineid < 0) return null;
|
|
Agent ag;
|
if (oppo)
|
// ag = oppoAgentWaveLineArray[lineid].getMinDisAgent(noPoison);
|
ag = oppoAgentWaveLineArray[lineid].GetMinDistanceAgent();
|
else
|
// ag = agentWaveLineArray[lineid].getMinDisAgent(noPoison);
|
ag = agentWaveLineArray[lineid].GetMinDistanceAgent();
|
|
// 这一行防止无限的循环下去。
|
if (forceGet) return ag;
|
|
agentTmpArr[0] = ag;
|
|
if (!EndlessLevelManager.instanceExists)
|
{
|
Agent agLeft = GetMinDisAgent(lineid - 1, oppo, true, noPoison);
|
Agent agRight = GetMinDisAgent(lineid + 1, oppo, true, noPoison);
|
|
agentTmpArr[1] = agLeft;
|
agentTmpArr[2] = agRight;
|
}
|
else
|
{
|
agentTmpArr[1] = null;
|
agentTmpArr[2] = null;
|
}
|
|
float minDis = 100000000f;
|
int idx = -1;
|
for (int ti = 0; ti < agentTmpArr.Length; ti++)
|
{
|
if ((agentTmpArr[ti] != null) && (agentTmpArr[ti].distanceToDest < minDis))
|
{
|
idx = ti;
|
minDis = agentTmpArr[ti].distanceToDest;
|
}
|
}
|
|
//
|
// 返回最近的Agent数据指针.
|
if (idx < 0)
|
{
|
// 如果是查找无中毒状态的Agent,再查一次:
|
if (noPoison)
|
return GetMinDisAgent(lineid, oppo, forceGet);
|
|
return null;
|
}
|
else
|
return agentTmpArr[idx];
|
}
|
|
|
public List<Targetable> AgentInRange
|
{
|
get { return this.agentInRange; }
|
}
|
|
public Agent oppoMinDisAgent
|
{
|
get { return this.oppoAgentMinDis; }
|
}
|
|
/// <summary>
|
/// 获取血量最大的数据
|
/// </summary>
|
/// <param name="opponent"></param>
|
/// <returns></returns>
|
public Agent getMaxHpAgent(bool opponent)
|
{
|
if (opponent) return this.oppoAgentMaxHp;
|
else return this.agentMaxHp;
|
}
|
|
public List<Targetable> getAgentListMaxHp(bool opponent)
|
{
|
if (opponent) return oppoAgentListMaxHp;
|
else return agentListMaxHp;
|
}
|
|
/// <summary>
|
/// 获取随机的AgentList.
|
/// </summary>
|
/// <param name="opponent"></param>
|
/// <returns></returns>
|
public List<Targetable> getAgentListRandom(bool opponent)
|
{
|
List<Agent> tlist;
|
List<Targetable> resList = new List<Targetable>();
|
if (opponent)
|
tlist = oppoAgentInsList;
|
else tlist = agentInsList;
|
|
int maxCnt = MAX_ATTCNT;
|
if (tlist.Count < maxCnt)
|
maxCnt = tlist.Count;
|
for (int ti = 0; ti < maxCnt; ti++)
|
{
|
int idx = mRand.Next(0, tlist.Count);
|
if (tlist[idx].opponentAgent != opponent) continue;
|
resList.Add(tlist[idx]);
|
}
|
|
return resList;
|
}
|
|
|
/// <summary>
|
/// 返回一个随机的Agent.
|
/// </summary>
|
/// <param name="opponent"></param>
|
/// <returns></returns>
|
public Agent getRandomAgent(bool opponent)
|
{
|
List<Agent> tlist;
|
if (opponent)
|
tlist = oppoAgentInsList;
|
else tlist = agentInsList;
|
|
if (tlist.Count == 0) return null;
|
|
int idx = mRand.Next(0, tlist.Count);
|
|
return tlist[idx];
|
}
|
|
public List<Targetable> OppoAgentInRange
|
{
|
get { return this.oppoAgentInRange; }
|
}
|
protected void updateAgent()
|
{
|
this.agentInRange.Clear();
|
this.agentListMaxHp.Clear();
|
this.agentMinDis = null;
|
this.agentMaxHp = null;
|
if (agentInsList.Count == 0) return;
|
|
|
// 用闭包函数先对血量进行排序.
|
agentInsList.Sort((left, right) =>
|
{
|
if (left.healthVal < right.healthVal)
|
return 1;
|
else if (left.healthVal == right.healthVal)
|
return 0;
|
else return -1;
|
});
|
agentMaxHp = agentInsList[0];
|
int maxCnt = MAX_ATTCNT;
|
if (agentInsList.Count < maxCnt)
|
maxCnt = agentInsList.Count;
|
for (int ti = 0; ti < maxCnt; ti++)
|
{
|
if (agentInsList[ti].opponentAgent) continue;
|
this.agentListMaxHp.Add(agentInsList[ti]);
|
}
|
|
|
|
// 直接使用闭包函数来进行排序:
|
agentInsList.Sort((left, right) =>
|
{
|
if (left.distanceToDest > right.distanceToDest)
|
{
|
return 1;
|
}
|
else if (left.distanceToDest == right.distanceToDest)
|
{
|
return 0;
|
}
|
else
|
{
|
return -1;
|
}
|
});
|
|
agentMinDis = agentInsList[0];
|
|
//maxCnt = MAX_ATTCNT;
|
//if (agentInsList.Count < maxCnt)
|
// maxCnt = agentInsList.Count;
|
for (int ti = 0; ti < maxCnt; ti++)
|
{
|
if (agentInsList[ti].opponentAgent) continue;
|
|
this.agentInRange.Add(agentInsList[ti]);
|
}
|
|
|
return;
|
}
|
|
/// <summary>
|
/// 场景内所有的Agent移动到中心坐标。
|
/// </summary>
|
public void moveAllAgentToCenter()
|
{
|
float moveTime = 0.9f;
|
Targetter.bSearchTarget = false;
|
bBossCreateState = true;
|
|
|
int cnt = this.agentInsList.Count;
|
Vector3 cpos = this.GetCenterPos(false);
|
for (int ti = 0; ti < cnt; ti++)
|
{
|
agentInsList[ti].SetNode(null, -1);
|
NavMeshAgent ag = agentInsList[ti].navMeshAgent;
|
ag.transform.DOMoveX(cpos.x, moveTime);
|
ag.transform.DOMoveZ(cpos.z, moveTime);
|
}
|
// 播放特效
|
ParticleSystem tpar = Instantiate<ParticleSystem>(centMovEffect);
|
tpar.transform.position = cpos;
|
tpar.Simulate(0.0f);
|
tpar.Play();
|
|
cnt = this.oppoAgentInsList.Count;
|
cpos = this.GetCenterPos(true);
|
for (int ti = 0; ti < cnt; ti++)
|
{
|
oppoAgentInsList[ti].SetNode(null, -1);
|
NavMeshAgent ag = oppoAgentInsList[ti].navMeshAgent;
|
ag.transform.DOMoveX(cpos.x, moveTime);
|
ag.transform.DOMoveZ(cpos.z, moveTime);
|
}
|
// 播放特效:
|
tpar = Instantiate<ParticleSystem>(centMovEffect);
|
tpar.transform.position = cpos;
|
tpar.Simulate(0.0f);
|
tpar.Play();
|
//
|
// 1.25秒之后消失掉所有的小怪:
|
Invoke("releaseAllCenterAgent", moveTime + 0.1f);
|
}
|
|
public void restartLevel()
|
{
|
bBossCreateState = false;
|
return;
|
}
|
|
/// <summary>
|
/// 获取WaveManager相关的中心点
|
/// </summary>
|
/// <returns></returns>
|
public Vector3 GetCenterPos(bool oppo)
|
{
|
Vector3 cpos = Vector3.zero;
|
return cpos;
|
}
|
|
protected void updateOpponentAgent()
|
{
|
this.oppoAgentInRange.Clear();
|
this.oppoAgentListMaxHp.Clear();
|
this.oppoAgentMinDis = null;
|
this.oppoAgentMaxHp = null;
|
if ((oppoAgentInsList.Count == 0))
|
return;
|
|
// 根据血量进行排序:
|
oppoAgentInsList.Sort((left, right) =>
|
{
|
if (left.healthVal < right.healthVal)
|
return 1;
|
else if (left.healthVal == right.healthVal)
|
return 0;
|
else return -1;
|
});
|
this.oppoAgentMaxHp = oppoAgentInsList[0];
|
int maxCnt = MAX_ATTCNT;
|
if (oppoAgentInsList.Count < MAX_ATTCNT)
|
maxCnt = oppoAgentInsList.Count;
|
for (int ti = 0; ti < maxCnt; ti++)
|
{
|
if (!oppoAgentInsList[ti].opponentAgent) continue;
|
oppoAgentListMaxHp.Add(oppoAgentInsList[ti]);
|
}
|
|
// 离目标的距离进行排序:
|
oppoAgentInsList.Sort((left, right) =>
|
{
|
if (left.distanceToDest > right.distanceToDest)
|
{
|
return 1;
|
}
|
else if (left.distanceToDest == right.distanceToDest)
|
{
|
return 0;
|
}
|
else
|
{
|
return -1;
|
}
|
});
|
|
oppoAgentMinDis = oppoAgentInsList[0];
|
|
for (int ti = 0; ti < maxCnt; ti++)
|
{
|
if (!oppoAgentInsList[ti].opponentAgent) continue;
|
|
oppoAgentInRange.Add(oppoAgentInsList[ti]);
|
}
|
|
|
}
|
|
/// <summary>
|
/// 再次更新opponentManager
|
/// </summary>
|
/// <param name="opponent"></param>
|
public void updateInsMgrPos(bool opponent)
|
{
|
if (opponent)
|
this.updateOpponentAgent();
|
else
|
this.updateAgent();
|
|
}
|
|
/// <summary>
|
/// 处理战场上的Bomb伤害.以Bomb中心的为单位对战场上的怪物进行伤害。
|
/// </summary>
|
/// <param name="pos"></param>
|
/// <param name="sid"></param>
|
/// <param name="slevel"></param>
|
/// <param name="opponent"></param>
|
public void ExecBombAttack(Vector3 pos, int sid, int slevel, bool opponent)
|
{
|
skilllevelinfo slinfo = JsonDataCenter.GetSkillLevelInfo(sid, slevel + 1);
|
if (slinfo == null) return;
|
|
WaveLineAgentInsMgr[] mgrList;
|
if (opponent)
|
mgrList = oppoAgentWaveLineArray;
|
else
|
mgrList = agentWaveLineArray;
|
|
pos.y = 0;
|
if (slinfo.atcmod.Count < 2) return;
|
|
float radius = slinfo.atcmod[1];
|
int deathCount = 0;
|
|
for (int ti = 0; ti < mgrList.Length; ti++)
|
{
|
WaveLineAgentInsMgr mgr = mgrList[ti];
|
for (int idx = 0; idx < mgr.listAgent.Count; idx++)
|
{
|
Agent eag = mgr.listAgent[idx];
|
Vector3 fpos = eag.transform.position;
|
fpos.y = 0;
|
float dist = Vector3.Distance(fpos, pos);
|
|
if (radius < dist)
|
continue;
|
|
bool isDeath = eag.isDead;
|
|
if (eag.AgentType == SpawnAgentType.BubbleBomb)
|
{
|
buffinfo bufdata = JsonDataCenter.GetBuffFromId(3);
|
if (bufdata != null)
|
{
|
if (bufdata.buff_func[0] == 3)
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBubbleBombBeDizzinessed, (eag as BubbleBombAgent).Id, bufdata.last);
|
}
|
}
|
else
|
{
|
float damage = slinfo.skilleffect[2];
|
damage += (slinfo.skilleffect[1] / 100.0f * eag.configuration.maxHealth);
|
damage = (float)Math.Floor(damage);
|
|
eag.TakeDamage(damage, fpos, null);
|
if (!eag.opponentAgent)
|
{
|
// if (GameUI.instanceExists)
|
// GameUI.instance.generateBloodText(fpos, damage);
|
// else if (EndlessGameUI.instanceExists)
|
// EndlessGameUI.instance.generateBloodText(fpos, damage);
|
}
|
|
if (!isDeath && eag.isDead)
|
++deathCount;
|
|
if (eag.isDead)
|
continue;
|
else
|
eag.SetAgentBuffEffect(3);
|
}
|
}
|
}
|
|
if (deathCount > 1)
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessOneTimeKillCount, deathCount);
|
|
return;
|
}
|
|
|
|
/// <summary>
|
/// 处理战场上的兵线伤害,以兵线为单位对怪物进行伤害
|
/// </summary>
|
/// <param name="waveline"></param>
|
/// <param name="sid"></param>
|
/// <param name="slevel"></param>
|
/// <param name="opponent"></param>
|
public void ExecWavelineAttack(int waveline, int sid, int slevel, bool opponent)
|
{
|
skilllevelinfo slinfo = JsonDataCenter.GetSkillLevelInfo(sid, slevel + 1);
|
if (slinfo == null) return;
|
|
WaveLineAgentInsMgr wavelineIns;
|
if (opponent)
|
wavelineIns = oppoAgentWaveLineArray[waveline];
|
else
|
wavelineIns = agentWaveLineArray[waveline];
|
|
if (wavelineIns == null) return;
|
|
List<Agent> listAg = wavelineIns.listAgent;
|
// 统计被火技能直接烧死的数量
|
int deathCount = 0;
|
|
for (int ti = listAg.Count - 1; ti >= 0; ti--)
|
{
|
Agent eag = listAg[ti];
|
|
if (eag.isDead) continue;
|
|
if (eag.AgentType == SpawnAgentType.BubbleBomb)
|
{
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessFireSkillKillBubbleBomb, (eag as BubbleBombAgent).Id);
|
// 泡泡炸弹是直接就被火技能秒杀的
|
++deathCount;
|
}
|
else
|
{
|
Vector3 fpos = eag.transform.position;
|
float damage = slinfo.skilleffect[2];
|
damage += (slinfo.skilleffect[1] / 100.0f * eag.configuration.maxHealth);
|
damage = (float)Math.Floor(damage);
|
|
eag.TakeDamage(damage, fpos, null);
|
if (!eag.opponentAgent)
|
{
|
// if (GameUI.instanceExists)
|
// GameUI.instance.generateBloodText(fpos, damage);
|
// else if (EndlessGameUI.instanceExists)
|
// EndlessGameUI.instance.generateBloodText(fpos, damage);
|
}
|
|
eag.PlayFireSkillHit();
|
|
if (eag.isDead)
|
++deathCount;
|
}
|
|
}
|
if (deathCount > 1)
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessOneTimeKillCount, deathCount);
|
}
|
|
|
/// <summary>
|
/// 处理战场上的兵线伤害,以兵线为单位对怪物进行伤害---所有兵线
|
/// </summary>
|
/// <param name="waveline"></param>
|
/// <param name="sid"></param>
|
/// <param name="slevel"></param>
|
/// <param name="opponent"></param>
|
public void ExecAllWavelineAttack(int sid, int slevel, bool opponent)
|
{
|
skilllevelinfo slinfo = JsonDataCenter.GetSkillLevelInfo(sid, slevel + 1);
|
if (slinfo == null) return;
|
|
WaveLineAgentInsMgr wavelineIns;
|
if (opponent)
|
{
|
for (int i = 0; i < oppoAgentWaveLineArray.Length; i++)
|
{
|
wavelineIns = oppoAgentWaveLineArray[i];
|
CalculateWavelineAttack(slinfo, wavelineIns, sid, slevel);
|
}
|
}
|
else
|
{
|
for (int i = 0; i < agentWaveLineArray.Length; i++)
|
{
|
wavelineIns = agentWaveLineArray[i];
|
CalculateWavelineAttack(slinfo, wavelineIns, sid, slevel);
|
}
|
}
|
|
}
|
|
private void CalculateWavelineAttack(skilllevelinfo slinfo, WaveLineAgentInsMgr wavelineIns, int sid, int slevel)
|
{
|
if (wavelineIns == null) return;
|
|
List<Agent> listAg = wavelineIns.listAgent;
|
// 统计被火技能直接烧死的数量
|
int deathCount = 0;
|
|
for (int ti = listAg.Count - 1; ti >= 0; ti--)
|
{
|
Agent eag = listAg[ti];
|
|
if (eag.isDead) continue;
|
|
if (eag.AgentType == SpawnAgentType.BubbleBomb)
|
{
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessFireSkillKillBubbleBomb, (eag as BubbleBombAgent).Id);
|
// 泡泡炸弹是直接就被火技能秒杀的
|
++deathCount;
|
}
|
else
|
{
|
Vector3 fpos = eag.transform.position;
|
float damage = slinfo.skilleffect[2];
|
damage += (slinfo.skilleffect[1] / 100.0f * eag.configuration.maxHealth);
|
damage = (float)Math.Floor(damage);
|
|
eag.TakeDamage(damage, fpos, null);
|
if (!eag.opponentAgent)
|
{
|
// if (GameUI.instanceExists)
|
// GameUI.instance.generateBloodText(fpos, damage);
|
// else if (EndlessGameUI.instanceExists)
|
// EndlessGameUI.instance.generateBloodText(fpos, damage);
|
}
|
|
eag.PlayFireSkillHit();
|
|
if (eag.isDead)
|
++deathCount;
|
}
|
|
}
|
if (deathCount > 1)
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessOneTimeKillCount, deathCount);
|
}
|
|
/// <summary>
|
/// 每一帧更新,更新之后获取几个刚性数据:
|
/// 1:血量最多的AgentInstance.
|
/// 2:最前面的AgentInstance.
|
/// </summary>
|
void Update()
|
{
|
this.updateAgent();
|
this.updateOpponentAgent();
|
UpdateWoodAim();
|
}
|
|
/// <summary>
|
/// 更新木属性精灵瞄准
|
/// </summary>
|
private void UpdateWoodAim()
|
{
|
if (!EndlessLevelManager.instanceExists) return;
|
|
WaveLineAgentInsMgr[] mgrs = GetWaveLineList();
|
|
for (int i = 0; i < 5; ++i)
|
{
|
List<Agent> agents = mgrs[i].listAgent;
|
// 是否发现有正在蓄力的木属性精灵
|
bool findCharge = false;
|
Tower tower = null;
|
|
if (agents.Count == 0) continue;
|
|
for (int j = 2; j <= 3; ++j)
|
{
|
tower = EndlessGameUI.instance.FindTowerWithGridIdx(i, j);
|
|
if (!tower || !tower.gameObject.activeInHierarchy || tower.ElfId != 301) continue;
|
|
if (tower.IsWoodCharge)
|
{
|
findCharge = true;
|
break;
|
}
|
}
|
|
if (!findCharge)
|
{
|
for (int j = 0; j < agents.Count; ++j)
|
{
|
agents[j].StopWoodAimEffect();
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 对当前Agent同一列内一定区域内的怪物进行攻击:
|
/// </summary>
|
/// <param name="ag"></param>
|
public int StartExplodeAttack(Agent ag, float damage)
|
{
|
WaveLineAgentInsMgr tmgr;
|
if (!ag.opponentAgent)
|
tmgr = this.agentWaveLineArray[ag.waveLineID];
|
else
|
tmgr = this.oppoAgentWaveLineArray[ag.waveLineID];
|
|
if (tmgr.getAgentInsNum() <= 1) return 0;
|
|
List<Agent> listAg = tmgr.listAgent;
|
|
Vector3 tpos = ag.transform.position;
|
int deathCount = 0;
|
|
for (int ti = listAg.Count - 1; ti >= 0; ti--)
|
{
|
Agent eag = listAg[ti];
|
if (eag == ag) continue;
|
|
Vector3 fpos = eag.transform.position;
|
tpos.y = 0;
|
fpos.y = 0;
|
// 8 打4个木, 12 打 6个木
|
if (Vector3.Distance(tpos, fpos) > 8) continue;
|
|
if (eag.AgentType == SpawnAgentType.BubbleBomb)
|
{
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, (eag as BubbleBombAgent).Id);
|
}
|
else
|
{
|
eag.TakeDamage(damage, fpos, null);
|
if (!eag.opponentAgent)
|
{
|
// if (GameUI.instanceExists)
|
// GameUI.instance.generateBloodText(fpos, damage);
|
// else if (EndlessGameUI.instanceExists)
|
// EndlessGameUI.instance.generateBloodText(fpos, damage);
|
}
|
if (eag.isDead)
|
++deathCount;
|
}
|
}
|
|
return deathCount;
|
|
/* foreach (Agent eag in listAg)
|
{
|
if (eag == ag) continue;
|
Vector3 fpos = eag.transform.position;
|
tpos.y = 0;
|
fpos.y = 0;
|
if (Vector3.Distance(tpos, fpos) < 8)
|
{
|
eag.TakeDamage(damage, fpos, null);
|
GameUI.instance.generateBloodText(fpos, damage, false, false);
|
}
|
}*/
|
}
|
|
/// <summary>
|
/// 开启链式攻击.
|
/// </summary>
|
/// <param name="chainStart"></param>
|
public void StartChainAttack(Agent chainStart, IAlignmentProvider alignment, float chainAttackHurt)
|
{
|
List<Agent> opList = null;
|
if (chainStart.opponentAgent)
|
opList = oppoAgentInsList;
|
else
|
opList = agentInsList;
|
|
int maxCnt = opList.Count;
|
List<Agent> listBlood = new List<Agent>();
|
for (int ti = 0; ti < maxCnt - 1; ti++)
|
{
|
if (opList[ti] != chainStart) continue;
|
int chainAttackNum = 0;
|
for (int tj = ti + 1; tj < maxCnt; tj++)
|
{
|
var lightBolt = opList[tj].GetComponent<LightBoltEffect>();
|
if (lightBolt == null)
|
{
|
|
lightBolt = opList[tj].gameObject.AddComponent<LightBoltEffect>();
|
lightBolt.Initialize(2, lightBoltFx, lightHitFx, opList[tj], opList[tj - 1]);
|
|
listBlood.Add(opList[tj]);
|
}
|
|
// 最多两个受到影响:
|
chainAttackNum++;
|
if (chainAttackNum >= 3)
|
break;
|
}
|
}
|
|
// TEST CODE: 最终应该是由服务器说了算的伤害.
|
// 每一个被链式攻击的怪物,飘血.
|
foreach (Agent ag in listBlood)
|
{
|
if (ag.AgentType != SpawnAgentType.Normal) continue;
|
int tid = ag.liveID;
|
Damager damager = ag.GetComponent<Damager>();
|
ag.TakeDamage(chainAttackHurt, ag.position, alignment);
|
// 处理飘字效果:
|
// if ((ag.liveID == tid) && (!ag.opponentAgent))
|
// {
|
// if (GameUI.instanceExists)
|
// GameUI.instance.generateBloodText(ag.position, chainAttackHurt);
|
// else if (EndlessGameUI.instanceExists)
|
// EndlessGameUI.instance.generateBloodText(ag.position, chainAttackHurt);
|
// }
|
}
|
listBlood.Clear();
|
|
}
|
|
|
protected void addWaveLineAgent(Agent ag)
|
{
|
if (ag.opponentAgent)
|
oppoAgentWaveLineArray[ag.waveLineID].addAgentIns(ag);
|
else
|
agentWaveLineArray[ag.waveLineID].addAgentIns(ag);
|
}
|
|
protected void delWaveLineAgent(Agent ag)
|
{
|
if (ag.opponentAgent)
|
oppoAgentWaveLineArray[ag.waveLineID].delAgentIns(ag);
|
else
|
agentWaveLineArray[ag.waveLineID].delAgentIns(ag);
|
}
|
|
/// <summary>
|
/// 管理器增加Agent.
|
/// </summary>
|
/// <param name="ag"></param>
|
public void addAgent(Agent ag)
|
{
|
addWaveLineAgent(ag);
|
if (!ag.opponentAgent)
|
{
|
this.agentInsList.Add(ag);
|
}
|
else
|
{
|
this.oppoAgentInsList.Add(ag);
|
}
|
|
}
|
|
/// <summary>
|
/// 更新当前管理器内所有怪物的移动速度
|
/// </summary>
|
/// <param name="fscale"></param>
|
public void ScaleAgentSpeed(float fscale)
|
{
|
for (int ti = 0; ti < agentInsList.Count; ti++)
|
agentInsList[ti].SetMoveSpeedScale(fscale);
|
for (int ti = 0; ti < oppoAgentInsList.Count; ti++)
|
oppoAgentInsList[ti].SetMoveSpeedScale(fscale);
|
}
|
|
/// <summary>
|
/// 管理器减少一个Agent,临时缓存队列也需要更新数据
|
/// </summary>
|
/// <param name="ag"></param>
|
public void removeAgent(Agent ag)
|
{
|
delWaveLineAgent(ag);
|
if (!ag.opponentAgent)
|
{
|
this.agentInsList.Remove(ag);
|
this.agentListMaxHp.Remove(ag);
|
if (agentMaxHp == ag)
|
agentMaxHp = null;
|
}
|
else
|
{
|
this.oppoAgentInsList.Remove(ag);
|
this.oppoAgentListMaxHp.Remove(ag);
|
if (oppoAgentMaxHp)
|
oppoAgentMaxHp = null;
|
}
|
|
|
}
|
|
/// <summary>
|
/// 获取最前面的Agent.
|
/// </summary>
|
/// <returns></returns>
|
public Agent getMostFrontAgent()
|
{
|
return null;
|
}
|
|
/// <summary>
|
/// 获取血量最多的Agent.
|
/// </summary>
|
/// <returns></returns>
|
public Agent getMostHealthAgent()
|
{
|
return null;
|
}
|
|
}
|