using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Common;
using DamageNumbersPro;
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 NaughtyAttributes;
using Unity.Mathematics;
using UnityEngine.UIElements;
using Random = UnityEngine.Random;
///
/// 游戏状态
///
public enum GameState
{
None = 0,
Playing = 1,
///
/// 胜利
///
Victory = 2,
///
/// 失败
///
Failur = 3,
Settle,
Waiting= 5,
}
public class GameManager : NetworkBehaviour
{
public static GameManager Ins { get; private set; }
#region 预制体
public GameObject redDoorPre;
public GameObject blueDoorPre;
public GameObject AirdropPlanePre;//空投飞机
public GameObject[] airdropItems;//空头道具
public GameObject startGameItemPre;
public GameObject damageNumberPre;
public GameObject redDamageNumberPre;
// 怪物ui预制体
public GameObject EnemyUIPre;
#endregion
#region 实例化后物体
public GameObject redDoor;
public GameObject blueDoor;
#endregion
// json数据库
private JsonLiteDB DB;
// 怪物信息集合
public Dictionary> EnemyInfos = new Dictionary>();
// 枪械信息集合
public Dictionary> GunInfos = new Dictionary>();
///
/// 所有敌人UI
///
public Dictionary EnemyUIList = new Dictionary();
public Dictionary SettleInfos = new Dictionary();
public List allPlayers = new List();
// 游玩结束时间
[NonSerialized]
[SyncVar]
public long vistEnd = 0;
// 总游玩时长
private int vistAllTime = (int)(60 * 10f);
[SyncVar]
public string settleData = "";
[SyncVar]
public GameState gameState = GameState.None;
[NonSerialized]
[SyncVar]
public int BlueScore = 0;
[NonSerialized]
[SyncVar]
public int RedScore = 0;
[NonSerialized]
[SyncVar]
public int RedRoundScore = 0;
[NonSerialized]
[SyncVar]
public int BlueRoundScore = 0;
void Awake()
{
Ins = this;
}
void Start()
{
if (isClient)
{
AuthorPanel.Show();
}
}
///
/// 创建门
///
[Server]
public void CreateDoor(Transform redPos, Transform bluePos,Transform startGamePos)
{
SetGameState(GameState.Waiting);
if(!isServer)
return;
//创建红色门
redDoor = Instantiate(redDoorPre,redPos.position,Quaternion.identity);
NetworkServer.Spawn(redDoor);
//创建蓝色门
blueDoor = Instantiate(blueDoorPre,bluePos.position,Quaternion.identity);
NetworkServer.Spawn(blueDoor);
//创建开始球
GameObject gameStartObj = Instantiate(startGameItemPre,startGamePos.position,Quaternion.identity);
NetworkServer.Spawn(gameStartObj);
//测试枪械
//GameLocal.Ins.self.GivePistol();
}
[Server]
// public void CreateDamageNumber(float damage ,Vector3 pos,bool isCritical)
// {
// if (damageNumberPre == null || redDamageNumberPre == null)
// {
// Debug.LogWarning("伤害字体预制体未设置!");
// return;
// }
//
// GameObject prefab = isCritical ? redDamageNumberPre : damageNumberPre;
// GameObject obj = Instantiate(prefab, pos, Quaternion.identity);
//
// // DamageNumbersPro 的核心组件
// var dmg = obj.GetComponent();
// if (dmg != null)
// {
// dmg.worldPos = pos;
// dmg.damageValue = isCritical? damage*2 : damage;
// dmg.OnStartClient();
// }
//
// // 网络生成(让客户端也能看到)
// NetworkServer.Spawn(obj);
// CoroutineTaskManager.Instance.WaitSecondTodo(() =>
// {
// NetworkServer.Destroy(obj);
// }, 10);
//
// }
[ClientRpc]
public void RpcShowDamageNumber(float damage, Vector3 pos, bool isCritical)
{
GameObject prefab = isCritical ? redDamageNumberPre : damageNumberPre;
if (prefab == null) return;
GameObject obj = Instantiate(prefab, pos, Quaternion.identity);
var dmg = obj.GetComponent();
if (dmg != null)
{
dmg.worldPos = pos;
dmg.damageValue = isCritical? damage*2 : damage;
dmg.OnStartClient();
}
Destroy(obj, 10f);
}
[Server]
public void GameStart()
{
AutoAssignTeams();
gameState = GameState.Playing;
vistEnd = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds + vistAllTime;
_airdropTime = 25;
_curAirdropTime = _airdropTime;
RpcShowHUD();
ChangeBgmRpc(1);
StartAirDrop();
//AstarPath.active.Scan();
NetworkServer.Destroy(redDoor);
NetworkServer.Destroy(blueDoor);
// 延迟1s后给所有人发放武器
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
foreach (var item in NetworkServer.connections.Values)
{
Player player = item.identity.GetComponent();
if (player != null)
{
player.HideInvincible();
}
}
RpcShowSettle();
}, 1f);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
GameOver();
}, vistAllTime);
}
[Server]
public void RegisterPlayer(Player p)
{
if (!allPlayers.Contains(p))
allPlayers.Add(p);
}
// ★ 玩家离开游戏时调用(在Player.OnStopServer里调用)
[Server]
public void UnRegisterPlayer(Player p)
{
if (allPlayers.Contains(p))
allPlayers.Remove(p);
}
// ★ 游戏开始时调用 → 自动分配队伍
[Server]
public void AutoAssignTeams()
{
int redCount = 0;
int blueCount = 0;
// 计算已分配队伍的人数
foreach (var p in allPlayers)
{
if (p.teamType == TeamType.Red) redCount++;
else if (p.teamType == TeamType.Blue) blueCount++;
}
// 遍历玩家 → 给没选队伍的自动分配
foreach (var p in allPlayers)
{
if (p.teamType != TeamType.None)
continue;
// 队伍数量对比
if (redCount < blueCount)
{
p.teamType = TeamType.Red;
redCount++;
}
else if (blueCount < redCount)
{
p.teamType = TeamType.Blue;
blueCount++;
}
else
{
// 一样多 → 随机
if (Random.value > 0.5f)
{
p.teamType = TeamType.Red;
redCount++;
}
else
{
p.teamType = TeamType.Blue;
blueCount++;
}
}
GivePistol(p.index);
}
}
[ClientRpc]
public void RpcShowSettle()
{
GameLocal.Ins.Settle.SetActive(true);
}
[ClientRpc]
public void GivePistol(int index)
{
Debug.Log("创建武器中...");
foreach (var item in NetworkServer.connections.Values)
{
Player player = item.identity.GetComponent();
if (player != null&&player.index == index)
{
player.GivePistol();
player.GiveArmor();
}
}
}
[Server]
public void SetGameState(GameState state)
{
gameState = state;
}
[Server]
public void GameOver()
{
gameState = GameState.Settle;
bool isBlue = GameLocal.Ins.self.teamType == TeamType.Blue;
bool isWin;
if (isBlue)
{
isWin = BlueScore > RedScore;
}
RpcShowWin(isBlue);
// if (blueScore >= redScore)
// {
// RpcShowWin(true);
// }
// else
// {
// RpcShowWin(false);
// }
}
[ClientRpc]
public void RpcShowWin(bool isBlue)
{
GameLocal.Ins.Settle.SetActive(false);
if (isBlue)
{
GameLocal.Ins.BlueWin.SetActive(true);
}
else
{
GameLocal.Ins.RedWin.SetActive(true);
}
}
[ClientRpc]
public void RpcShow()
{
SettlePanel.Show();
}
[ClientRpc]
public void ChangeBgmRpc(int i)
{
GameLocal.Ins.BGMState.StateChange(i);
}
[Server]
public void CreateAirdropPlane(Vector3 startPos, Vector3 endPos)
{
GameObject airdropPlane = Instantiate(AirdropPlanePre,startPos,quaternion.identity);
NetworkServer.Spawn(airdropPlane);
AirdropPlane airdropPlaneScript = airdropPlane.GetComponent();
airdropPlaneScript.OnSpawn(endPos);
}
[Server]
public void CreateAirDropItem(int id ,Vector3 startPos)
{
GameObject airdropItem = Instantiate(airdropItems[id],startPos,quaternion.identity);
NetworkServer.Spawn(airdropItem);
}
///
/// 痛击场上所有敌方单位
///
[Command(requiresAuthority = false)]
public void DamageAllEnemy()
{
}
///
/// 更新配置表
///
public void UpdateConf()
{
string text = Resources.Load("Data").text;
if (text != null)
{
ParseGameJson(text);
}
}
public void ParseGameJson(string text)
{
DB = new JsonLiteDB();
DB.Load(text);
TableReader infoReader = DB["GunsInfo"].GetReader();
while (infoReader.Read())
{
GunInfo info = new GunInfo(infoReader);
GunInfos.TryGetValue((GunType)info.Type, out Dictionary infoList);
if (infoList == null)
{
Dictionary list = new Dictionary();
list.Add(info.Lvl, info);
GunInfos.Add((GunType)info.Type, list);
}
else
{
infoList.Add(info.Lvl, info);
}
}
Debug.Log("游戏数值更新 -> complete");
}
[Server]
public void CreateEnemyUI(Enemy enemy)
{
GameObject enemyUI = Instantiate(EnemyUIPre);
NetworkServer.Spawn(enemyUI);
PlayerUI enemyUIScript = enemyUI.GetComponent();
enemyUIScript.Init(enemy);
EnemyUIList.Add(enemy.id, enemyUIScript);
}
[Server]
public void DeleteEnemyUI(int id)
{
GameObject enemyUI = EnemyUIList[id].gameObject;
EnemyUIList.Remove(id);
NetworkServer.Destroy(enemyUI);
}
[ClientRpc]
public void RpcShowHUD()
{
HUDPanel.Show();
}
[Server]
public void AddData(int playerIndex)
{
SettleInfos.Add(playerIndex.ToString(), new SettleInfo());
}
#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()
{
if (isServer)
{
return (int)(vistEnd - NetworkTime.time);
}
else
{
return (int)(vistEnd - NetworkClient.connection.remoteTimeStamp);
}
}
// 时分秒
public string FormatTime(int totalSeconds)
{
//确保时间不为负
totalSeconds = Mathf.Max(0, 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
[ClientRpc]
public void PlaySound2DRPC(string sound)
{
MasterAudio.PlaySound(sound);
}
[SyncVar]
private int syncRemainingTime;
private float _airdropTime;//空投时间
private float _curAirdropTime;//当前空头时间
private bool _isStartAirdrop;//是否开始倒计时空投
public void StartAirDrop()
{
_isStartAirdrop = true;
}
public void StopAirDrop()
{
_isStartAirdrop = false;
}
void Update()
{
if (isServer&& gameState==GameState.Playing&&_isStartAirdrop)
{
//服务器计算剩余时间并同步
//syncRemainingTime = GetLessTimeSeconds();
_curAirdropTime+=Time.deltaTime;
if (_curAirdropTime >= _airdropTime)
{
int airdropPosId = Random.Range(0, 4);
int endAirdropPosId =0;
if (airdropPosId == 0)
endAirdropPosId = 1;
if (airdropPosId == 1)
endAirdropPosId = 0;
if (airdropPosId == 2)
endAirdropPosId = 3;
if (airdropPosId == 3)
endAirdropPosId = 2;
CreateAirdropPlane(GameLocal.Ins.startPlanePos[airdropPosId].position,GameLocal.Ins.startPlanePos[endAirdropPosId].position);
_curAirdropTime = 0;
StopAirDrop();
}
}
}
public void StartRound()
{
gameState = GameState.Playing;
foreach (var item in allPlayers)
{
item.HideInvincible();
}
}
[Server]
public void StopRound()
{
gameState = GameState.Waiting;
foreach (var item in allPlayers)
{
item.ClearGun();
}
if (BlueRoundScore > RedRoundScore)
{
BlueScore += 1;
}
if (BlueRoundScore < RedRoundScore)
{
RedScore += 1;
}
if (BlueRoundScore == RedRoundScore)
{
RedScore += 1;
BlueScore += 1;
}
BlueRoundScore = 0;
RedRoundScore = 0;
}
public Player GetPlayerByIndex(int index)
{
return allPlayers.FirstOrDefault(p => p.index == index);
}
#region 分数系统
///
/// 红色方加分
///
///
public void AddRedScore(int playerId,int score)
{
RedRoundScore+=score;
}
///
/// 蓝色方加分
///
///
public void AddBlueScore(int playerId,int score)
{
BlueRoundScore+=score;
}
#endregion
}