Files
Loong/Assets/_Loong/Scripts/GameManager.cs
2026-01-14 19:43:37 +08:00

788 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Common;
using DragonLi.Core;
using Mirror;
using UnityEngine;
using UnityEngine.PlayerLoop;
using XPlugin.Data.JsonLiteDB;
using static XPlugin.Data.JsonLiteDB.JsonLiteDB;
using LitJson;
using Pathfinding;
using DarkTonic.MasterAudio;
using DG.Tweening;
using NaughtyAttributes;
using UnityEngine.UIElements;
/// <summary>
/// 游戏状态
/// </summary>
public enum GameState
{
None = 0,
/// <summary>
/// 教学
/// </summary>
Introduce = 1,
Playing = 2,
/// <summary>
/// 胜利
/// </summary>
Victory = 3,
/// <summary>
/// 失败
/// </summary>
Failur = 4,
}
public class GameManager : MonoBehaviour
{
public static GameManager Ins { get; private set; }
#region
public GameObject DoorPre;
public GameObject BombPre;
public GameObject ArrowPre;
public Transform doorPos;
public Transform[] bossPos;
// 怪物预制集合
public GameObject[] EnemyPres;
#endregion
// json数据库
private JsonLiteDB DB;
// 怪物信息集合
public Dictionary<EnemyType, Dictionary<int, EnemyInfo>> EnemyInfos = new Dictionary<EnemyType, Dictionary<int, EnemyInfo>>();
// 建筑信息集合
public Dictionary<BuildType, Dictionary<int, BuildInfo>> BuildInfos = new Dictionary<BuildType, Dictionary<int, BuildInfo>>();
// 枪械信息集合
public Dictionary<GunType, Dictionary<int, GunInfo>> GunInfos = new Dictionary<GunType, Dictionary<int, GunInfo>>();
// 子弹信息集合
public Dictionary<BulletType, Dictionary<int, BulletInfo>> BulletInfos = new Dictionary<BulletType, Dictionary<int, BulletInfo>>();
// 防线信息
public List<ScenesInfo> ScenesInfos = new List<ScenesInfo>();
// 剧情信息
public Dictionary<int, List<CombatUnitInfo>> CombatUnitInfos = new Dictionary<int, List<CombatUnitInfo>>();
/// <summary>
/// 敌人自增
/// </summary>
private int enemyIndex = 0;
public GameObject[] bossSouls;
public Transform[] soulsPos;
/// <summary>
/// 所有敌人
/// </summary>
public Dictionary<int, Enemy> EnemyList = new Dictionary<int, Enemy>();
/// <summary>
/// 所有敌人UI
/// </summary>
public Dictionary<int, EnemyUI> EnemyUIList = new Dictionary<int, EnemyUI>();
/// <summary>
/// 所有炮塔
/// </summary>
public Dictionary<int, Tower> TowerList = new Dictionary<int, Tower>();
public Dictionary<string, SettleInfo> SettleInfos = new Dictionary<string, SettleInfo>();
/// <summary>
/// 波次自增
/// </summary>
public int roundIndex = 0;
// 游玩结束时间
public long vistEnd = 0;
// 总游玩时长
[NonSerialized]
public int vistAllTime = (int)(60 * 10f);
public float curGameTime = 0;
public string settleData = "";
public bool isGameEnd = false;
public bool isGameStart = false;
public float curTime;
public GameState gameState = GameState.None;
[SoundGroup] public string JointIn;
[SoundGroup] public string roundSound;
[Header("咆哮")]
[SoundGroup] public string DragonRoar;
// 语音包
[SoundGroup] public string attack2IceDragon;
[SoundGroup] public string[] says;
[NonSerialized]
public int blueScore = 0;
[NonSerialized]
public int redScore = 0;
// private Arrow _nowArrow;
private int _frame = 0;
public GameObject playerPre;
public Player _player;
public int curBossId = 0;
[NonSerialized]
public Enemy CurBoss;
public Transform standPos;
void Awake()
{
Ins = this;
}
void Start()
{
AuthorPanel.Show();
LoginPanel.Show();
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
WorldUIManager.Ins.Back();
}, 1f);
foreach (var item in bossSouls)
{
item.SetActive(false);
}
#if !UNITY_EDITOR
TrueGearEffectManager.Ins.StartRequestTrueGear();
#endif
}
void Update()
{
if (gameState == GameState.Playing)
{
curGameTime+=Time.deltaTime;
}
}
public int GetNowTime()
{
return Mathf.RoundToInt(curGameTime);
}
/// <summary>
/// 创建门
/// </summary>
public void CreateDoor()
{
UpdateConf();
GameObject door = Instantiate(DoorPre);
//NetworkServer.Spawn(door);
door.transform.position = doorPos.position;
_player = Instantiate(playerPre).GetComponent<Player>();
}
public void ShowDragonSoul(Transform startPos)
{
var id = curBossId;
bossSouls[id].SetActive(true);
bossSouls[id].transform.position = startPos.position+new Vector3(0,2,0);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
bossSouls[id].transform.DOMove(soulsPos[id].position, 3).OnComplete(() =>
{
if (id == 3)
{
GameOver(GameState.Victory);
GameLocal.Ins.gameEndEffect.SetActive(true);
}
});
}, 3f);
}
/// <summary>
/// 创建下一回合
/// </summary>
public void CreateNextRound()
{
roundIndex++;
if (CreateRound(roundIndex))
{
PlaySound2DRPC(roundSound);
RpcMessageRound();
}
else
{
GameOver(GameState.Victory);
}
}
/// <summary>
/// 创建回合
/// </summary>
public bool CreateRound(int progress)
{
// 修复场上所有炮塔
foreach (Tower tower in TowerList.Values)
{
if (tower.type != TowerType.PowerCore)
{
// 只恢复被击毁的
if (tower.state == TowerState.Broken)
{
tower.RepairImm();
}
}
}
bool created = false;
CombatUnitInfos.TryGetValue(progress, out List<CombatUnitInfo> combatUnitInfos);
if (combatUnitInfos != null)
{
created = true;
foreach (CombatUnitInfo combatUnitInfo in combatUnitInfos)
{
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
if (combatUnitInfo.Special == 0)
{
CreateEnemy(
(EnemyType)combatUnitInfo.EnemyType,
combatUnitInfo.BornPos,
combatUnitInfo.BornAngleY
);
}
else
{
CreateAir(
(EnemyType)combatUnitInfo.EnemyType,
combatUnitInfo.BornPos,
combatUnitInfo.BornAngleY);
}
}, combatUnitInfo.BornTime);
}
}
return created;
}
/// <summary>
/// 教学开始
/// </summary>
public void IntroduceStart()
{
gameState = GameState.Introduce;
_frame = 0;
}
public void PlayerGetEx(int amount, Vector3 fromPos)
{
_player.GetEx(amount, fromPos);
}
/// <summary>
/// 游戏开始
/// </summary>
public void GameStart()
{
if(gameState == GameState.Playing)
return;
gameState = GameState.Playing;
isGameStart = true;
MasterAudio.PlaySound(says[1]);
// 进入教学
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
MasterAudio.PlaySound(attack2IceDragon);
MasterAudio.PlaySound(DragonRoar);
CreateEnemy(EnemyType.IceDragon, bossPos[curBossId].position, bossPos[curBossId].eulerAngles.y);
}, 8f);
ShowPlayerUI();
vistEnd = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds + vistAllTime;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
GameOver(GameState.Failur);
}, vistAllTime);
}
public void RpcShowSettle()
{
GameLocal.Ins.Settle.SetActive(true);
}
public void GivePistol()
{
Debug.Log("创建武器中...");
// GameLocal.Ins.self.PickUpGun(GunType.Pistol, -999);
}
public void SetGameState(GameState state)
{
gameState = state;
}
//1.游戏时间到
//2.所有怪物被消灭
//3.玩家被消灭
//以上都要跳出结算
public void GameOver(GameState state)
{
gameState = state;
RpcShow(gameState== GameState.Victory);
string bgmStr = "巨龙BGMWAV";
if (state == GameState.Victory)
bgmStr = "战斗胜利-长";
else if (state == GameState.Failur)
bgmStr = "战斗失败-短";
MasterAudio.StopAllOfSound("巨龙BGMWAV");
MasterAudio.PlaySound(bgmStr);
isGameEnd = true;
if (gameState == GameState.Failur)
{
LoseEndGame();
}
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
Debug.Log("游戏结束60秒后退出");
Application.Quit();
}, 60f);
}
public void LoseEndGame()
{
foreach (var item in EnemyList)
{
item.Value.CloseGuard();
Destroy(item.Value.gameObject);
}
GameLocal.Ins.self.IsAlive = false;
GameLocal.Ins.self.End();
}
public void CloseCurBoss()
{
CurBoss.Die(null,_player.transform);
}
public void RpcShow(bool isWin)
{
SettlePanel.Show(isWin);
}
public void ShowPlayerUI()
{
HUDPanel.Show();
}
/// <summary>
/// 下一波进攻开始
/// </summary>
public void RpcMessageRound()
{
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
DragonLi.Core.EventDispatcher.TriggerEvent("NewWaveStart", roundIndex);
}, 0.5f);
}
public void ChangeBgmRpc(int i)
{
GameLocal.Ins.BGMState.StateChange(i);
}
/// <summary>
/// 创建敌方单位
/// </summary>
public GameObject CreateEnemy(EnemyType type, Vector3 pos, float angleY)
{
GameObject enemy = Instantiate(EnemyPres[(int)type]);
enemy.transform.position = pos;
enemy.transform.eulerAngles = new Vector3(0, angleY, 0);
enemyIndex++;
Enemy enemyScript = enemy.GetComponent<Enemy>();
if (type <= EnemyType.BlackDragon)
CurBoss = enemyScript;
enemyScript.OnSpawn(enemyIndex, type, 1);
EnemyList.Add(enemyIndex, enemyScript);
return enemy;
}
/// <summary>
/// 删除敌方单位
/// </summary>
public void DeleteEnemy(int id)
{
GameObject enemy = EnemyList[id].gameObject;
EnemyList.Remove(id);
Destroy(enemy);
if (EnemyList.Count == 0)
{
CreateNextRound();
}
}
/// <summary>
/// 痛击场上所有敌方单位
/// </summary>
public void DamageAllEnemy()
{
foreach (Enemy enemy in EnemyList.Values)
{
enemy.ApplyDamage(999999, -1, Vector3.zero, null);
}
}
/// <summary>
/// 创建炮弹
/// </summary>
public void CreateBomb(Vector3 pos, Vector3 angle)
{
GameObject bomb = Instantiate(BombPre);
NetworkServer.Spawn(bomb);
bomb.transform.position = pos;
bomb.transform.eulerAngles = angle;
}
public void CreateAir(EnemyType type, Vector3 pos, float angleY)
{
GameObject enemy = Instantiate(EnemyPres[(int)type]);
NetworkServer.Spawn(enemy);
enemy.transform.position = pos;
enemy.transform.eulerAngles = new Vector3(0, angleY, 0);
Airdrop enemyScript = enemy.GetComponent<Airdrop>();
enemyScript.OnSpawn(type, 1);
}
/// <summary>
/// 更新配置表
/// </summary>
public void UpdateConf()
{
string text = Resources.Load<TextAsset>("Data").text;
if (text != null)
{
ParseGameJson(text);
}
}
public void ParseGameJson(string text)
{
DB = new JsonLiteDB();
DB.Load(text);
// 怪物信息
TableReader infoReader = DB["EnemysInfo"].GetReader();
while (infoReader.Read())
{
EnemyInfo info = new EnemyInfo(infoReader);
EnemyInfos.TryGetValue((EnemyType)info.Type, out Dictionary<int, EnemyInfo> infoList);
if (infoList == null)
{
Dictionary<int, EnemyInfo> list = new Dictionary<int, EnemyInfo>();
list.Add(info.Lvl, info);
EnemyInfos.Add((EnemyType)info.Type, list);
}
else
{
infoList.Add(info.Lvl, info);
}
}
// 建筑信息
infoReader = DB["BuildsInfo"].GetReader();
while (infoReader.Read())
{
BuildInfo info = new BuildInfo(infoReader);
BuildInfos.TryGetValue((BuildType)info.Type, out Dictionary<int, BuildInfo> infoList);
if (infoList == null)
{
Dictionary<int, BuildInfo> list = new Dictionary<int, BuildInfo>();
list.Add(info.Lvl, info);
BuildInfos.Add((BuildType)info.Type, list);
}
else
{
infoList.Add(info.Lvl, info);
}
}
infoReader = DB["GunsInfo"].GetReader();
while (infoReader.Read())
{
GunInfo info = new GunInfo(infoReader);
GunInfos.TryGetValue((GunType)info.Type, out Dictionary<int, GunInfo> infoList);
if (infoList == null)
{
Dictionary<int, GunInfo> list = new Dictionary<int, GunInfo>();
list.Add(info.Lvl, info);
GunInfos.Add((GunType)info.Type, list);
}
else
{
infoList.Add(info.Lvl, info);
}
}
// 子弹信息
infoReader = DB["BulletsInfo"].GetReader();
while (infoReader.Read())
{
BulletInfo info = new BulletInfo(infoReader);
BulletInfos.TryGetValue((BulletType)info.Type, out Dictionary<int, BulletInfo> infoList);
if (infoList == null)
{
Dictionary<int, BulletInfo> list = new Dictionary<int, BulletInfo>();
list.Add(info.Lvl, info);
BulletInfos.Add((BulletType)info.Type, list);
}
else
{
infoList.Add(info.Lvl, info);
}
}
// 场景信息
infoReader = DB["ScenesInfo"].GetReader();
while (infoReader.Read())
{
ScenesInfo info = new ScenesInfo(infoReader);
ScenesInfos.Add(info);
}
infoReader = DB["StoryProgressInfo"].GetReader();
while (infoReader.Read())
{
CombatUnitInfo info = new CombatUnitInfo(infoReader);
CombatUnitInfos.TryGetValue(info.Belong, out List<CombatUnitInfo> infoList);
if (infoList == null)
{
List<CombatUnitInfo> list = new List<CombatUnitInfo>();
list.Add(info);
CombatUnitInfos.Add(info.Belong, list);
}
else
{
infoList.Add(info);
}
}
Debug.Log("游戏数值更新 -> complete");
}
/// <summary>
/// 获取范围内敌人
/// </summary>
public int GetRangeEnemyId(Vector3 pos, float radius)
{
int res = -1;
foreach (Enemy enemy in EnemyList.Values)
{
float dis = Vector3.Distance(enemy.transform.position, pos);
if (dis <= radius)
{
radius = dis;
res = enemy.id;
break;
}
}
return res;
}
public void DeleteEnemyUI(int id)
{
GameObject enemyUI = EnemyUIList[id].gameObject;
EnemyUIList.Remove(id);
NetworkServer.Destroy(enemyUI);
}
public void RpcShowHUD()
{
// HUDPanel.Show();
}
#region
/// <summary>
/// 修复炮塔
/// </summary>
public void RepairTower()
{
}
/// <summary>
/// 进入联控
/// </summary>
public void JoinControlTower(int playerIndex)
{
PlayJointMusic();
// 修改所有炮塔模式
foreach (Tower tower in TowerList.Values)
{
if (tower.controllerId == -1)
{
tower.controllerId = playerIndex;
tower.mode = TowerMode.Joint;
}
}
TriggerEvent("JoinControlStart", playerIndex);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
ChangeBgmRpc(1);
foreach (Tower tower in TowerList.Values)
{
if (tower.mode == TowerMode.Joint)
{
tower.controllerId = playerIndex;
tower.mode = tower.originalMode;
}
TriggerEvent("JoinControlEnd", playerIndex);
}
}, 30f);
}
#endregion
public void TriggerEvent(string key, int param)
{
DragonLi.Core.EventDispatcher.TriggerEvent(key, param);
}
public void AddScore(string index, int damage)
{
if (SettleInfos.ContainsKey(index))
{
SettleInfos[index].Score += damage;
}
string jsonStr = JsonMapper.ToJson(SettleInfos);
settleData = jsonStr;
}
public void SetTitle(string index, string title)
{
if (SettleInfos.ContainsKey(index))
{
SettleInfos[index].Title = title;
}
Debug.Log(SettleInfos);
}
public void SetPlayerName(string index)
{
if (SettleInfos.ContainsKey(index))
{
SettleInfos[index].playerName = int.Parse(index);
}
}
public void AddData(int playerIndex)
{
SettleInfos.Add(playerIndex.ToString(), new SettleInfo());
}
public string SerializeSettleInfos()
{
return JsonUtility.ToJson(SettleInfos);
}
#region
public string GetLessTimeStr()
{
string res = "";
if (gameState == GameState.Playing)
{
res = FormatTime((int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds));
}
return res;
}
public int GetLessTimeSeconds()
{
return (int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds);
}
// 时分秒
public string FormatTime(int totalSeconds)
{
int hours = totalSeconds / 3600;
// string hh = hours < 10 ? "0" + hours : hours.ToString();
int minutes = (totalSeconds - hours * 3600) / 60;
string mm = minutes < 10f ? "0" + minutes : minutes.ToString();
int seconds = totalSeconds - hours * 3600 - minutes * 60;
string ss = seconds < 10 ? "0" + seconds : seconds.ToString();
return string.Format("{0}:{1}", mm, ss);
}
#endregion
public void PlaySound2DRPC(string sound)
{
MasterAudio.PlaySound(sound);
}
public void PlayJointMusic()
{
MasterAudio.PlaySound(JointIn);
GameLocal.Ins.BGMState.StateChange(2);
}
public void PlayNarration16()
{
MasterAudio.PlaySound(says[2]);
}
/// <summary>
/// 当心!又一只恶龙到来了,快消灭它!
/// </summary>
/// <param name="cb"></param>
public void PlayNarration17(Action cb = null)
{
StartCoroutine(MasterAudio.PlaySoundAndWaitUntilFinished(says[3], 1, null, 0, null, () =>
{
cb?.Invoke();
}));
}
/// <summary>
/// 咆哮
/// </summary>
public void PlayDragonRoar(Action cb = null)
{
// Debug.Log("咆哮开始");
StartCoroutine(MasterAudio.PlaySoundAndWaitUntilFinished(DragonRoar, 1, null, 0, null, () =>
{
// Debug.Log("咆哮结束");
cb?.Invoke();
}));
}
// /// <summary>
// /// 手上创建箭矢
// /// </summary>
// public void CreateArrowInHand()
// {
// _nowArrow = Instantiate(ArrowPre, _player.bow.bulletPoint).GetComponent<Arrow>();
// }
// /// <summary>
// /// 射出箭矢
// /// </summary>
// public void ShootArrow()
// {
// if (_nowArrow != null)
// {
// if (gameState == GameState.Introduce)
// {
// GameStart();
// }
// MasterAudio.PlaySound(arrowShoot);
// Destroy(_nowArrow.gameObject);
// }
// }
}