using Core.Utilities;
|
using System;
|
using System.Collections.Generic;
|
using TowerDefense.Level;
|
using TowerDefense.Towers;
|
using TowerDefense.UI.HUD;
|
using UnityEngine;
|
using UnityEngine.UI;
|
using TMPro;
|
using KTGMGemClient;
|
|
public class EndlessRandomTower : Singleton<EndlessRandomTower>
|
{
|
// 当前类所在的Btn.
|
public Button randomBtn;
|
|
/// <summary>
|
/// 倒计时对应的背景图片.
|
/// </summary>
|
public Image cdTimeBg;
|
|
/// <summary>
|
/// 倒计划对应的文字.
|
/// </summary>
|
public TextMeshProUGUI cdTimeText;
|
|
/// <summary>
|
/// 购买二级宝石的按钮贴图.
|
/// </summary>
|
public Sprite buyBtnLevelUp;
|
|
protected bool bSetBuyLvlUp;
|
|
protected bool bCdTimeStart;
|
|
protected float btnLvlUpCdTime;
|
|
public static bool MAX_INTERNAL = false;
|
|
// 玩家初始阵容
|
protected List<Tower> towerArray = new List<Tower>();
|
|
protected int maxTower = 0;
|
|
public static readonly int MAX_TOWERDIS = 5;
|
|
// 开始出现技能塔的时间:
|
public static float SKILL_TOWER_TIME = 30.0f;
|
|
// 购买之后直接出现2级宝石的时间.
|
public static float LEVELUP_TOWER_TIME = 10.0f;
|
|
protected System.Random mRandom;
|
|
protected int rTowerIdx = 2;
|
|
// 所有宝石随机总权重
|
private int randomTotalWeight;
|
|
// 所有宝石位置权重列表
|
private List<int> weightList;
|
|
// 是否初始化过出战数据
|
private bool isInitFightData = false;
|
|
// Start is called before the first frame update
|
void Start()
|
{
|
if (!EndlessLevelManager.instanceExists)
|
Debug.LogError("[UI] No level manager for tower list");
|
|
foreach (Tower tower in EndlessLevelManager.instance.TowerLibrary)
|
{
|
towerArray.Add(tower);
|
}
|
|
maxTower = towerArray.Count;
|
|
while (maxTower > MAX_TOWERDIS)
|
{
|
maxTower--;
|
towerArray.RemoveAt(towerArray.Count - 1);
|
}
|
|
mRandom = new System.Random();
|
|
bSetBuyLvlUp = false;
|
bCdTimeStart = false;
|
|
cdTimeBg.gameObject.SetActive(false);
|
|
cdTimeText.text = "";
|
|
randomBtn.onClick.AddListener(onClick);
|
|
}
|
|
public void ChangeBtnClickNormal()
|
{
|
randomBtn.onClick.RemoveAllListeners();
|
randomBtn.onClick.AddListener(onClick);
|
}
|
public void ChangeBtnClick()
|
{
|
randomBtn.onClick.RemoveAllListeners();
|
randomBtn.onClick.AddListener(() =>
|
{
|
AudioSourceManager.Ins.Play(AudioEnum.UIDisable);
|
});
|
}
|
|
/// <summary>
|
/// 获取TowerList.
|
/// </summary>
|
public List<Tower> towerList
|
{
|
get { return this.towerArray; }
|
}
|
|
/// <summary>
|
/// 处理按钮升级相关.
|
/// </summary>
|
private void Update()
|
{
|
float gstime = EndlessUIStart.instance.GameStartTime;
|
if (gstime <= 0) return;
|
|
if ((!bCdTimeStart) && (LEVELUP_TOWER_TIME - gstime) <= JsonDataCenter.TOWERLVLUP_CDTIME)
|
{
|
bCdTimeStart = true;
|
btnLvlUpCdTime = LEVELUP_TOWER_TIME - gstime;
|
cdTimeBg.gameObject.SetActive(true);
|
}
|
if ((!bSetBuyLvlUp) && (gstime > LEVELUP_TOWER_TIME))
|
{
|
bSetBuyLvlUp = true;
|
this.randomBtn.GetComponent<Image>().sprite = buyBtnLevelUp;
|
cdTimeBg.gameObject.SetActive(false);
|
cdTimeText.text = "";
|
}
|
|
// 更新倒计时:
|
if ((!bSetBuyLvlUp) && bCdTimeStart)
|
{
|
btnLvlUpCdTime -= Time.deltaTime;
|
string distr = ((int)Math.Ceiling(btnLvlUpCdTime)).ToString() + "s";
|
cdTimeText.text = distr;
|
}
|
}
|
|
public void actionTest()
|
{
|
multipara((str, strnew) => { Debug.Log(str + strnew); }, "Ying");
|
}
|
|
protected void actadd(string str, string strnew)
|
{
|
Debug.Log("这是新增的Action String:" + str);
|
}
|
|
/// <summary>
|
/// 用于测试Action参数的测试函数,Action多参数的用法.
|
/// </summary>
|
/// <param name="act"></param>
|
/// <param name="p1"></param>
|
protected void multipara(Action<string, string> act, string p1)
|
{
|
string finalstr = "Welcome to " + p1;
|
act += this.actadd;
|
act(finalstr, "YingYing");
|
}
|
|
/// <summary>
|
/// 获取序列化的Tower
|
/// </summary>
|
/// <returns></returns>
|
public Tower getRTower()
|
{
|
Tower t = this.towerArray[this.rTowerIdx];
|
rTowerIdx++;
|
if (rTowerIdx >= this.maxTower)
|
rTowerIdx = 2;
|
return t;
|
}
|
|
/// <summary>
|
/// 根据Tower名字获取当前的Tower指针。
|
/// </summary>
|
/// <param name="name"></param>
|
/// <returns></returns>
|
public Tower getTowerByName(string name)
|
{
|
for (int ti = 0; ti < this.maxTower; ti++)
|
if (name == this.towerArray[ti].towerName)
|
return towerArray[ti];
|
|
return GetRandomTower(false);
|
}
|
|
/// <summary>
|
/// 获取随机命中位置索引
|
/// </summary>
|
private int GetRandomIndex(List<int> list, int totalWeight)
|
{
|
int random = mRandom.Next(0, totalWeight);
|
int index = -1;
|
int total = 0;
|
|
for (int i = 0; i < list.Count; ++i)
|
{
|
total += list[i];
|
if (total >= random)
|
{
|
index = i;
|
break;
|
}
|
}
|
|
return index;
|
}
|
|
/// <summary>
|
/// 根据规则生成一个随机的塔
|
/// </summary>
|
/// <param name="onlySpawnElf">是否仅产生精灵宝石,而不产生技能宝石</param>
|
/// <returns></returns>
|
public Tower GetRandomTower(bool onlySpawnElf = true)
|
{
|
if (!isInitFightData)
|
{
|
isInitFightData = true;
|
weightList = new List<int>();
|
List<posWeight> posWeight = JsonDataCenter.GetList<posWeight>();
|
randomTotalWeight = 0;
|
|
for (int i = 0; i < posWeight.Count; ++i)
|
{
|
weightList.Add(posWeight[i].weight);
|
randomTotalWeight += posWeight[i].weight;
|
}
|
|
// 游戏开始之前先把出站组乱序
|
GameUtils.Shuffle(towerArray);
|
}
|
|
Tower ret = null;
|
|
// 还没到技能时间,忽略掉技能宝石
|
if (onlySpawnElf)
|
{
|
// 精灵宝石位置索引列表
|
List<int> elfIndexList = new List<int>();
|
|
for (int i = 0; i < towerArray.Count; ++i)
|
{
|
if (towerArray[i].towerFeature == EFeatureTower.NULL)
|
elfIndexList.Add(i);
|
}
|
|
// 没有上阵精灵宝石
|
if (elfIndexList.Count == 0)
|
{
|
Debug.LogError("--------------------- 没有上阵精灵宝石 ---------------------");
|
return null;
|
}
|
|
// 计算所有精灵宝石位置的总权重
|
int elfTotalWeight = 0;
|
// 精灵宝石位置权重列表
|
List<int> elfWeightList = new List<int>();
|
|
for (int i = 0; i < elfIndexList.Count; ++i)
|
{
|
elfTotalWeight += weightList[elfIndexList[i]];
|
elfWeightList.Add(weightList[elfIndexList[i]]);
|
}
|
|
// 所有精灵宝石位置的权重都为0,直接等概率出一个精灵宝石
|
int index = elfTotalWeight == 0 ? mRandom.Next(0, elfIndexList.Count) : GetRandomIndex(elfWeightList, elfTotalWeight);
|
ret = towerArray[elfIndexList[index]];
|
}
|
// 可以自由产生
|
else
|
{
|
int index = randomTotalWeight == 0 ? mRandom.Next(0, towerArray.Count) : GetRandomIndex(weightList, randomTotalWeight);
|
ret = towerArray[index];
|
}
|
|
// 生成宝石成功,需要调整宝石位置,把宝石放到队尾
|
towerArray.Remove(ret);
|
towerArray.Add(ret);
|
|
return ret;
|
}
|
|
/// <summary>
|
/// 随机购买Tower的入口,如果购买成功,则需要实时更新价格
|
/// </summary>
|
public void onClick()
|
{
|
if (GameConfig.IsNewbie && !GameConfig.CanBuyNewTower)
|
{
|
AudioSourceManager.Ins.Play(AudioEnum.UIDisable);
|
|
return;
|
}
|
|
AudioSourceManager.Ins.Play(AudioEnum.UI);
|
|
// 还没到技能时间,忽略掉技能宝石
|
Tower newTower = GetRandomTower(EndlessUIStart.instance.GameStartTime <= SKILL_TOWER_TIME);
|
|
if (!newTower)
|
throw new Exception("未能成功产生Tower");
|
|
RandomPlaceTower(newTower);
|
}
|
|
/// <summary>
|
/// 随机找一个空白位置放置塔防
|
/// </summary>
|
/// <param name="tower"></param>
|
public bool RandomPlaceTower(Tower tower, int level = -1, int cost = -1, int posx = -1, int posy = -1)
|
{
|
EndlessGameUI gameUI = EndlessGameUI.instance;
|
|
if (gameUI.isBuilding)
|
gameUI.CancelGhostPlacement();
|
|
if (EndlessUIStart.instance.GameStartTime >= LEVELUP_TOWER_TIME)
|
{
|
if (level == -1)
|
level = Mathf.Min(EndlessGameUI.instance.MinLevel, 1);
|
}
|
else
|
{
|
if (level == -1)
|
level = 0;
|
}
|
|
return gameUI.RandomPlaceTower(tower, posx, posy, level, cost);
|
}
|
|
/// <summary>
|
/// 在固定的位置,放置一个随机的塔防类型.
|
/// </summary>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
public void randomTower(int x, int y, int lvl, string tname = "")
|
{
|
int tidx = 0;
|
Tower targetTower = null;
|
if (tname == "")
|
{
|
tidx = mRandom.Next(0, this.maxTower);
|
// 随机升级的Tower,不能升级成为成长骰子.
|
int maxLoop = 20;
|
while (this.towerArray[tidx].towerFeature != EFeatureTower.NULL)
|
{
|
tidx = mRandom.Next(0, this.maxTower);
|
maxLoop--;
|
|
if (maxLoop <= 0)
|
{
|
tidx = this.rTowerIdx;
|
rTowerIdx++;
|
if (rTowerIdx >= maxTower)
|
rTowerIdx = 2;
|
|
Debug.LogError("超级循环发生了.");
|
break;
|
}
|
}
|
targetTower = this.towerArray[tidx];
|
}
|
else
|
targetTower = getTowerByName(tname);
|
|
// River: 随机找一个空白位置放置塔防。
|
EndlessGameUI.instance.RandomPlaceTower(targetTower, x, y, lvl, -1, true);
|
}
|
}
|