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();
}
}
}
}