using System; using System.Collections.Generic; using System.Dynamic; using Core.Extensions; using KTGMGemClient; using TowerDefense.Nodes; using UnityEngine; using UnityEngine.Analytics; namespace TowerDefense.Level { /// /// 用于在路径上生成Boss的数据 /// public struct BossSpawnData { public float time; public float speed; public float hp; public int gold; public int waveline; } /// /// WaveManager - handles wave initialisation and completion /// 需要修改这个类,把编辑生成的Wave修改成有规律的配置Wave,更加自动化,减少配置的工作量。 /// public class WaveManager : MonoBehaviour { protected static int BOSS_AGGEN_IDX = 6; // BOSS数据的索引. // 刷怪的速度缩放和怪物的移动速度数据缩放 public static float SPAWNMONSTER_TIMESCALE = 1.0f; public static float MONSTERMOVE_TIMESCALE = 1.0f; /// /// 多个开始Node,每一个对应一个EndNode,根据当前位置是否放置塔防而确定是否出兵。 /// public List startNodeList; /// /// 游戏开始时各兵线是否开启. /// public List waveInitStart; /// /// WaveMgr内Boss刷新的数据列表. /// protected List bossSpawnList; /// /// 刷怪管理器内普通怪物的血量逻辑。暂时每10秒 + 100. /// public float initAgentHealth = 100; /// /// Current wave being used /// protected int m_CurrentIndex; /// /// Whether the WaveManager starts waves on Awake - defaulted to null since the LevelManager should call function /// public bool startWavesOnAwake; /// /// 初始化所有的Wave,使用不同的StartNode. /// [Tooltip("Specify list in order")] public List waves = new List(); /// /// 当前WaveManager是否开始Wave. /// protected bool bWaveStarted = false; /// /// 正方OR反方. /// protected bool bOpponent = false; /// /// 是否怪物已加速. /// protected bool[] bArrMSpeedUp; /// /// The total number of waves /// public int totalWaves { get { return waves.Count; } } /// /// Called when all waves are finished /// public event Action spawningCompleted; /// /// 开始更新后的时间和刷怪管理器对应的普通怪血量。 /// protected float eTimeUpdate = 0; protected float commonAgentHealth = 0; /// /// Starts the waves /// public virtual void StartWaves() { if (waves.Count > 0) { InitCurrentWave(); bWaveStarted = true; eTimeUpdate = 0; commonAgentHealth = initAgentHealth; initBossSpawnData(); } else { Debug.LogWarning("[LEVEL] No Waves on wave manager. Calling spawningCompleted"); SafelyCallSpawningCompleted(); } } /// /// 从配置文件初始化Boss发布的数据。 /// protected void initBossSpawnData() { List listBoss = JsonDataCenter.GetList(); bossSpawnList = new List(); for (int ti = 0; ti < listBoss.Count; ti++) { BossSpawnData tbsd = new BossSpawnData(); boss tboss = listBoss[ti]; tbsd.time = tboss.time / 1000; tbsd.hp = tboss.hp; tbsd.speed = tboss.speed; tbsd.waveline = tboss.way - 1; tbsd.gold = tboss.gold; bossSpawnList.Add(tbsd); } bOpponent = startNodeList[0].bOpponentSide; // 处理MonsterSpeedUp数据 SPAWNMONSTER_TIMESCALE = 1.0f; MONSTERMOVE_TIMESCALE = 1.0f; List listms = JsonDataCenter.monSpeedUp; bArrMSpeedUp = new bool[listms.Count]; for (int ti = 0; ti < bArrMSpeedUp.Length; ti++) bArrMSpeedUp[ti] = false; } /// /// 处理怪物的SpeedUp数据 /// protected void UpdateMonsterSpeedUp() { float gstartTime = UIStart.instance.gameStartTime; List listms = JsonDataCenter.monSpeedUp; float mbSpeed = MONSTERMOVE_TIMESCALE; for (int ti = 0; ti < bArrMSpeedUp.Length; ti++) { if (bArrMSpeedUp[ti]) continue; bool bset = false; /*if (ti == 0) bset = (gstartTime >= 10); else if( ti == 1 ) bset = (gstartTime >= 20); else */ bset = gstartTime >= listms[ti].speedTime; if (bset) { SPAWNMONSTER_TIMESCALE = listms[ti].spawnTimeScale; MONSTERMOVE_TIMESCALE = listms[ti].moveSpeedScale; bArrMSpeedUp[ti] = true; if (ti == 0) UIStart.instance.SetFirstSpeedUp(); else if (ti == 1) UIStart.instance.SetSecondSpeedUp(); float fscale = MONSTERMOVE_TIMESCALE / mbSpeed; AgentInsManager.instance.ScaleAgentSpeed(fscale); break; } } } /// /// 处理WaveMgr内Boss的生成效果 /// protected void UpdateBossSpawn() { // 没有Boss可发布了 if (bossSpawnList.Count <= 0) return; float gstartTime = UIStart.instance.gameStartTime; for (int ti = bossSpawnList.Count - 1; ti >= 0; ti--) { BossSpawnData bd = bossSpawnList[ti]; if (!bOpponent) { if ((bd.time - gstartTime) <= 30) WaveLineSelMgr.instance.StartCountDownBossWarning(30, bd.waveline); if ((bd.time - gstartTime) < 5) WaveLineSelMgr.instance.waveLineBossWarning(bd.waveline, true); } if (gstartTime < bd.time) continue; // 生成当前的Boss怪: waves[bd.waveline].SpawnCommonAgent(BOSS_AGGEN_IDX, bd.hp, bd.speed, bd.gold); if (!bOpponent) { WaveLineSelMgr.instance.waveLineBossWarning(bd.waveline, false); WaveLineSelMgr.instance.StopCountDownBossWarning(bd.waveline); } bossSpawnList.RemoveAt(ti); } } /// /// 当前刷怪管理器的更新逻辑。 /// 1:每10秒刷新的普通怪会增加100的血量 /// public void Update() { if (!bWaveStarted) return; UpdateBossSpawn(); // 有一个管理器更新就可以了 if (!bOpponent) UpdateMonsterSpeedUp(); eTimeUpdate += Time.deltaTime; while (eTimeUpdate > 9.99f) { eTimeUpdate -= 9.99f; commonAgentHealth += 100f; // 设置对应的数据: waves[m_CurrentIndex].commonAgentHealth = commonAgentHealth; } // 原来的代码,暂不处理,先搞多条兵线的代码操作: // 判断是否时间归零,如果时间归零,则对AgentInsManager做出相应的处理. /* if( AgentInsManager.bBossCreateState ) { // 当前Manager内的Wave创建Boss.如果已经创建Boss,则不处理。 if( !waves[m_CurrentIndex].bBossCreated) { bool opponent = false; if (startingNode.transform.position.z > 0) opponent = true; waves[m_CurrentIndex].CreateBossAgent(AgentInsManager.instance.GetCenterPos( opponent )); } else { AgentInsManager.bBossCreateState = false; } }*/ } /// /// 从Tower的AttributeId获取到怪物的数据 /// /// /// protected List GetMonsterDataFromAttributeId(int id) { geminfo tgem = new geminfo(); if (JsonDataCenter.gemInfoDic.TryGetValue(id, out tgem)) return tgem.summon; else { Debug.Log("找不到对应ID的Gem:" + id); return null; } } /// /// 获取当前Wave的开始位置 /// /// /// public Vector3 GetWaveEndPos(int waveline) { return startNodeList[waveline].GetNextNode().transform.position; } /// /// 在当前的WaveManager内插入一个Agent. /// /// 参数暂时由内部管理的血量数据接手。\ /// WORK START: 从这里开始调试出发: /*public void SpawnAgent( int waveline,float hp,float speed, int attributeId ) { if (waveline == 1) waveline = 1; if( bWaveStarted) { Wave wave = waves[waveline]; List summon = GetMonsterDataFromAttributeId(attributeId); if (summon == null) return; // 按属性需不在场景内生成小怪. monster tm = JsonDataCenter.monsterDic[summon[0]]; int fid = (int)Math.Floor((attributeId - 101) / 4.0f) + 1; hp = tm.hp * hp; speed = tm.speed * speed; *//*if( summon[1] == 1 ) wave.SpawnCommonAgent( fid,hp,speed ); else { // 更多的处理 for( int ti = 0;ti /// Inits the first wave /// protected virtual void Awake() { if (startWavesOnAwake) { StartWaves(); } } /// /// Initialize the current wave /// protected virtual void InitCurrentWave() { for (int idx = 0; idx < waves.Count; idx++) { Wave wave = waves[idx]; wave.commonAgentHealth = initAgentHealth; if (waveInitStart[idx]) wave.Init(startNodeList[idx], idx); else wave.InitNode(startNodeList[idx], idx); } } /// /// 开启战场中某一条兵线 /// /// public bool startWaveLine(int x, int attid) { if (x >= waveInitStart.Count) return false; //if (waveInitStart[x]) return false; waveInitStart[x] = true; waves[x].Init(startNodeList[x], x); waves[x].UpdateSpawnInstruction(Wave.GetFidFromAttribute(attid)); return true; } public void prepareWaveline(int x) { if (x >= waveInitStart.Count) return; waves[x].PrepareToSpawnAgent(startNodeList[x], x); } public void UpdateWaveSpawnTime(int x, int attributeId) { waves[x].UpdateSpawnInstruction(Wave.GetFidFromAttribute(attributeId)); } /// /// 停止某一条兵线的推进。 /// /// /// public bool stopWaveLine(int x) { if (x >= waveInitStart.Count) return false; if (!waveInitStart[x]) return false; waves[x].stopWave(); return true; } /// /// Calls spawningCompleted event /// protected virtual void SafelyCallSpawningCompleted() { if (spawningCompleted != null) { spawningCompleted(); } } } }