wangguan
2020-12-10 a9bf69ea82070c8e9723e610cb7cea430f2daa11
Assets/Scripts/TowerDefense/Level/AgentInsManager.cs
@@ -10,6 +10,8 @@
using TowerDefense.UI.HUD;
using UnityEngine;
using UnityEngine.AI;
using TowerDefense.Level;
using TowerDefense.Towers;
/// <summary>
/// 基于兵线的Agent Instance管理器
@@ -60,7 +62,15 @@
    /// <returns></returns>
    public int getAgentInsNum()
    {
        return this.agentInsList.Count;
        int ret = 0;
        for (int i = 0; i < agentInsList.Count; ++i)
        {
            if (agentInsList[i].AgentType == SpawnAgentType.Normal)
                ++ret;
        }
        return ret;
    }
    /// <summary>
@@ -68,44 +78,68 @@
    /// </summary>
    public List<Agent> listAgent { get { return this.agentInsList; } }
    /// <summary>
    /// 获取距目标结点最近的Agent.
    /// </summary>
    /// <returns></returns>
    public Agent getMinDisAgent(bool _noPoison = false)
    // /// <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()
    {
        if (agentInsList.Count == 0) return null;
        Agent ret = null;
        float minDistance = -1f;
        // 排序,然后返回对应的数据
        // 直接使用闭包函数来进行排序:
        agentInsList.Sort((left, right) =>
        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)
        {
            if (left.distanceToDest > right.distanceToDest)
            {
                return 1;
            }
            else if (left.distanceToDest == right.distanceToDest)
            {
                return 0;
            }
            else
            {
                return -1;
            }
        });
            float distance = Mathf.Abs(agents[i].transform.position.z - endPos.z);
        if (_noPoison)
        {
            for (int ti = 0; ti < agentInsList.Count; ti++)
            if (minDistance < 0 || distance < minDistance)
            {
                if (!agentInsList[ti].bInPoison)
                    return agentInsList[ti];
                minDistance = distance;
                ret = agents[i];
            }
            return null;
        }
        else
            return agentInsList[0];
        return ret;
    }
}
@@ -223,6 +257,58 @@
        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; }
@@ -252,19 +338,30 @@
        Agent ag;
        if (oppo)
            ag = oppoAgentWaveLineArray[lineid].getMinDisAgent(noPoison);
            // ag = oppoAgentWaveLineArray[lineid].getMinDisAgent(noPoison);
            ag = oppoAgentWaveLineArray[lineid].GetMinDistanceAgent();
        else
            ag = agentWaveLineArray[lineid].getMinDisAgent(noPoison);
            // ag = agentWaveLineArray[lineid].getMinDisAgent(noPoison);
            ag = agentWaveLineArray[lineid].GetMinDistanceAgent();
        // 这一行防止无限的循环下去。
        if (forceGet) return ag;
        Agent agLeft = GetMinDisAgent(lineid - 1, oppo, true, noPoison);
        Agent agRight = GetMinDisAgent(lineid + 1, oppo, true, noPoison);
        agentTmpArr[0] = ag;
        agentTmpArr[1] = agLeft;
        agentTmpArr[2] = agRight;
        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;
@@ -482,27 +579,6 @@
        return;
    }
    protected void releaseAllCenterAgent()
    {
        int cnt = this.agentInsList.Count;
        for (int ti = cnt - 1; ti >= 0; ti--)
        {
            if (agentInsList[ti].bBoss)
                continue;
            agentInsList[ti].Remove();
        }
        cnt = this.oppoAgentInsList.Count;
        for (int ti = cnt - 1; ti >= 0; ti--)
        {
            if (oppoAgentInsList[ti].bBoss)
                continue;
            oppoAgentInsList[ti].Remove();
        }
    }
    /// <summary>
    /// 获取WaveManager相关的中心点
    /// </summary>
@@ -512,7 +588,6 @@
        Vector3 cpos = Vector3.zero;
        return cpos;
    }
    protected void updateOpponentAgent()
    {
@@ -606,6 +681,8 @@
        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];
@@ -615,29 +692,49 @@
                Vector3 fpos = eag.transform.position;
                fpos.y = 0;
                float dist = Vector3.Distance(fpos, pos);
                if (radius < dist)
                    continue;
                float damage = slinfo.skilleffect[2];
                damage += (slinfo.skilleffect[1] / 100.0f * eag.configuration.maxHealth);
                damage = (float)Math.Floor(damage);
                bool isDeath = eag.isDead;
                eag.TakeDamage(damage, fpos, null);
                if (!eag.opponentAgent)
                if (eag.AgentType == SpawnAgentType.BubbleBomb)
                {
                    if (GameUI.instanceExists)
                        GameUI.instance.generateBloodText(fpos, damage, false, false);
                    else if (EndlessGameUI.instanceExists)
                        EndlessGameUI.instance.generateBloodText(fpos, damage, false, false);
                    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);
                    }
                }
                if (eag.isDead)
                    continue;
                else
                    eag.SetAgentBuffEffect(3);
                {
                    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;
    }
@@ -663,76 +760,188 @@
            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];
            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 (eag.isDead) continue;
            if (eag.AgentType == SpawnAgentType.BubbleBomb)
            {
                if (GameUI.instanceExists)
                    GameUI.instance.generateBloodText(fpos, damage, false, false);
                else if (EndlessGameUI.instanceExists)
                    EndlessGameUI.instance.generateBloodText(fpos, damage, false, false);
                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.
    /// 3:
    /// </summary>
    void Update()
    {
        this.updateAgent();
        this.updateOpponentAgent();
        UpdateWoodAim();
    }
        // 测试重设最前面的Agent到初始化位置:
        if (Input.GetKeyDown(KeyCode.A))
    /// <summary>
    /// 更新木属性精灵瞄准
    /// </summary>
    private void UpdateWoodAim()
    {
        if (!EndlessLevelManager.instanceExists) return;
        WaveLineAgentInsMgr[] mgrs = GetWaveLineList();
        for (int i = 0; i < 5; ++i)
        {
            // 测试数据,重设Agent到开始位置
            if (agentInsList.Count >= 2)
            List<Agent> agents = mgrs[i].listAgent;
            // 是否发现有正在蓄力的木属性精灵
            bool findCharge = false;
            Tower tower = null;
            if (agents.Count == 0) continue;
            for (int j = 2; j <= 3; ++j)
            {
                /*   var posResetEff = MinDisAgent.GetComponent<AgentResetPosEffect>();
                   if (posResetEff == null)
                   {
                       posResetEff = MinDisAgent.gameObject.AddComponent<AgentResetPosEffect>();
                   }
                   posResetEff.Initialize(4, posResetFx );*/
                var lightBolt = agentInsList[1].GetComponent<LightBoltEffect>();
                if (lightBolt == null)
                tower = EndlessGameUI.instance.FindTowerWithGridIdx(i, j);
                if (!tower || !tower.gameObject.activeInHierarchy || tower.ElfId != 301) continue;
                if (tower.IsWoodCharge)
                {
                    lightBolt = agentInsList[1].gameObject.AddComponent<LightBoltEffect>();
                    findCharge = true;
                    break;
                }
                lightBolt.Initialize(2, lightBoltFx, lightHitFx, agentInsList[1], agentInsList[0]);
            }
            if (!findCharge)
            {
                for (int j = 0; j < agents.Count; ++j)
                {
                    agents[j].StopWoodAimEffect();
                }
            }
        }
        /*
        // TEST CODE TO DELETE:
        if( Input.GetKeyDown( KeyCode.S ))
        {
            this.moveAllAgentToCenter();
        }
        if( Input.GetKeyDown( KeyCode.D))
        {
            Targetter.bSearchTarget = !Targetter.bSearchTarget;
        }*/
    }
    /// <summary>
    /// 对当前Agent同一列内一定区域内的怪物进行攻击:
    /// </summary>
    /// <param name="ag"></param>
    public void StartExplodeAttack(Agent ag, float damage)
    public int StartExplodeAttack(Agent ag, float damage)
    {
        WaveLineAgentInsMgr tmgr;
        if (!ag.opponentAgent)
@@ -740,30 +949,45 @@
        else
            tmgr = this.oppoAgentWaveLineArray[ag.waveLineID];
        if (tmgr.getAgentInsNum() <= 1) return;
        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;
            if (Vector3.Distance(tpos, fpos) < 8)
            if (eag.AgentType == SpawnAgentType.BubbleBomb)
            {
                eag.TakeDamage(damage, fpos, null);
                if (!eag.opponentAgent)
                EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, (eag as BubbleBombAgent).Id);
            }
            else
            {
                Vector3 fpos = eag.transform.position;
                tpos.y = 0;
                fpos.y = 0;
                if (Vector3.Distance(tpos, fpos) < 12)
                {
                    if (GameUI.instanceExists)
                        GameUI.instance.generateBloodText(fpos, damage, false, false);
                    else if (EndlessGameUI.instanceExists)
                        EndlessGameUI.instance.generateBloodText(fpos, damage, false, false);
                    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;
@@ -819,17 +1043,18 @@
        // 每一个被链式攻击的怪物,飘血.
        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, false, false);
                else if (EndlessGameUI.instanceExists)
                    EndlessGameUI.instance.generateBloodText(ag.position, chainAttackHurt, false, false);
            }
            // 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();