Files
valheim/Assets/_Valheim/Scripts/GameManager.cs

2251 lines
74 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 System.Linq;
using BehaviorDesigner.Runtime;
using BestHTTP;
using BestHTTP.JSON.LitJson;
using DarkTonic.MasterAudio;
using DG.Tweening;
using DragonLi.Core;
using DragonLi.Frame;
using JetBrains.Annotations;
using Mirror;
using NaughtyAttributes;
using Unity.Mathematics;
using Unity.XR.PXR;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.XR.Interaction.Toolkit;
using XPlugin.Data.JsonLiteDB;
using XUI;
using static XPlugin.Data.JsonLiteDB.JsonLiteDB;
using Random = System.Random;
namespace Valheim
{
public class GameManager : NetworkBehaviour
{
public static GameManager Ins { get; private set; }
#region
// 小动物预制集合
public List<GameObject> PetPres = new List<GameObject>();
// 怪物预制集合
public List<GameObject> EnemyPres = new List<GameObject>();
public List<GameObject> skillPres = new List<GameObject>();
public List<GameObject> bulletPres = new List<GameObject>();
public List<GameObject> itemPres = new List<GameObject>();
public List<GameObject> badgePres = new List<GameObject>();
public GameObject BattleArePre;
public GameObject reviePre;
public GameObject hitEffectPre;
public GameObject upgradEffectPre;
public GameObject spwanBallPointPre;
public GameObject EnergyBallPre;
public GameObject CagePre;
public GameObject EnemyUIPre;
public GameObject PetUIPre;
public GameObject AudioManagerPre;
public GameObject DoorColliderPre;
public GameObject InitDoorPre;
public GameObject aiDrPre;
public GameObject itemBoxPre;
#endregion
public int selectCardId = -1;
public Pet userPet;
public bool isGetPet = false;
public bool isPlayPetWorld;
public bool isGuide;
public SkillManager skillManager;
[NonSerialized]
public string HttpServerUrl = "";
//public string HttpServerUrl = "http://120.27.202.237:8888";
// http验证
[NonSerialized]
public readonly string Author = "";
// 验证信息
private AuthInfo authInfo = new AuthInfo();
// 游玩结束时间
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public long vistEnd = 0;
// 总游玩时长
private int vistAllTime = (int)(60 * 15F);
// 游戏是否结束
[NonSerialized]
[SyncVar]
public bool GameOver = true;
/// <summary>
/// 游戏是否通关
/// </summary>
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public bool IsWin = false;
// json数据库
private JsonLiteDB DB;
#region
// 当前关卡宠物信息集合
public Dictionary<int, EnemyData> PetDic = new Dictionary<int, EnemyData>();
// 当前关卡怪物信息集合
public Dictionary<int, EnemyData> EnemyDic = new Dictionary<int, EnemyData>();
// 关卡表2
public Dictionary<int, List<EditObjInfo>> GameLevelInfos2 = new Dictionary<int, List<EditObjInfo>>();
public List<EnemyData> EnemyDataList = new List<EnemyData>();
public Dictionary<int, SkillData> SkillDataList = new Dictionary<int, SkillData>();
public List<List<List<int>>> LevelEnemyList = new List<List<List<int>>>();
#endregion
// 宠物自增
private int petIndex = 0;
/// <summary>
/// 敌人自增
/// </summary>
private int enemyIndex = 0;
// 编队信息
public Dictionary<int, TeamInfo> Teams = new Dictionary<int, TeamInfo>();
/// <summary>
/// 跟随行为树
/// </summary>
public ExternalBehavior FollowBehavior;
// 跟随行为树
public Dictionary<int, BehaviorTree> FollowBehaviors = new Dictionary<int, BehaviorTree>();
/// <summary>
/// 所有敌人
/// </summary>
public List<Enemy> EnemyList = new List<Enemy>();
public Dictionary<int, List<Enemy>> BattleAreaEnemyDic = new Dictionary<int, List<Enemy>>();
/// <summary>
/// 巨型鱼人
/// </summary>
[NonSerialized]
public FishGiant fishGiant;
/// <summary>
/// 博士
/// </summary>
public AiDr aiDr;
/// <summary>
/// 所有动物
/// </summary>
public Dictionary<int, Pet> PetList = new Dictionary<int, Pet>();
/// <summary>
/// 所有复活点
/// </summary>
[NonSerialized]
public List<Transform> RevivePointList = new List<Transform>();
/// <summary>
/// 所有区域
/// </summary>
public Dictionary<int, BattleArea> AreaList = new Dictionary<int, BattleArea>();
/// <summary>
/// 所有笼子
/// </summary>
public Dictionary<int, List<Cage>> CageList = new Dictionary<int, List<Cage>>();
/// <summary>
/// 分配宠物给谁
/// </summary>
[NonSerialized]
[SyncVar]
public int curretAssignIndex = 0;
// [NonSerialized]
[SyncVar]
public float EnergyValue = 0;
public int curBattleAreaIndex = 0;
public int curEnemyLevel = 1;
public int curMapId;
public int curUpLevelCount;
public Vector3 lastAreaPos;
[SoundGroup] public string selectCardSound;
//添加AI相关字段
[Header("AI")]
public GameObject aiControllerPrefab;
public Transform aiSpawnPosition;
private AIController currentAI;
public Player player;
#region
void Awake()
{
Ins = this;
}
void Start()
{
if (isClient)
{
AuthorPanel.Show();
}
// MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
// {
// RpcRequestNotifyStart();
// }, 60f);
}
void Destroy()
{
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
PXR_Enterprise.UnBindEnterpriseService();
#endif
}
#endregion
#region
/// <summary>
/// 创建战斗区域
/// </summary>
[Server]
public void CreateBattleArea(int id, Vector3 pos, Vector3 scale, Vector3 angle)
{
GameObject battleArea = Instantiate(BattleArePre);
NetworkServer.Spawn(battleArea);
battleArea.transform.position = pos;
battleArea.transform.localScale = scale;
battleArea.transform.eulerAngles = angle;
BattleArea script = battleArea.GetComponent<BattleArea>();
script.Init(id);
AreaList.Add(id, script);
battleArea.SetActive(false);
}
/// <summary>
/// 创建复活点
/// </summary>
[Server]
public void CreateRevivePoint(Vector3 pos)
{
GameObject reviveArea = Instantiate(reviePre);
NetworkServer.Spawn(reviveArea);
reviveArea.transform.position = pos;
RevivePointList.Add(reviveArea.transform);
}
/// <summary>
/// 创建笼子(牢笼)
/// </summary>
[Server]
public void CreateCage(int areaId, int cageId, Vector3 pos, float angleY, float scale)
{
GameObject cage = Instantiate(CagePre);
NetworkServer.Spawn(cage);
cage.transform.position = pos;
cage.transform.eulerAngles = new Vector3(0, angleY, 0);
cage.transform.localScale = new Vector3(scale, scale, scale);
Cage script = cage.GetComponent<Cage>();
script.Init(cageId);
CageList.TryGetValue(areaId, out List<Cage> list);
if (list == null)
{
list = new List<Cage>();
CageList.Add(areaId, list);
}
list.Add(script);
}
public void CreateHitEffect(Vector3 pos)
{
GameObject hitEffect = Instantiate(hitEffectPre);
NetworkServer.Spawn(hitEffect);
hitEffect.transform.position = pos;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(hitEffect);
}, 1);
}
public void CreateUpgradEffect(Vector3 pos)
{
GameObject upgradEffect = Instantiate(upgradEffectPre);
NetworkServer.Spawn(upgradEffect);
upgradEffect.transform.position = pos;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(upgradEffect);
}, 1);
}
[Server]
public GameObject CreateSpawnBallPoint(Vector3 pos)
{
// GameObject spwanBallPoint = Instantiate(spwanBallPointPre);
// NetworkServer.Spawn(spwanBallPoint);
// spwanBallPoint.transform.position = pos;
// return spwanBallPoint;
int max = UnityEngine.Random.Range(1, 101);
if (max <= 19)
{
//CreateItemBox(pos);
}
return null;
}
public GameObject CreateEnergyBall(Vector3 pos)
{
GameObject energyBall = Instantiate(EnergyBallPre);
NetworkServer.Spawn(energyBall);
energyBall.transform.position = pos;
return energyBall;
}
public GameObject CreateDoorCoiider(Vector3 pos, Vector3 angle)
{
isShowPetWorld = false;
GameObject doorCoiider = Instantiate(DoorColliderPre);
NetworkServer.Spawn(doorCoiider);
doorCoiider.transform.position = pos;
doorCoiider.transform.localEulerAngles = angle;
return doorCoiider;
}
public bool isShowPetWorld;
public void ShowPetWorld(GameObject door = null)
{
if (isShowPetWorld)
return;
isShowPetWorld = true;
// 游戏开始
TransitionPanel.Ins.WhiteFadeOut(() =>
{
if (curUpLevelCount >= 3)
{
ClosePet();
GameInit.Ins.StartGame(() =>
{
StartCoroutine(GameManager.Ins.PlayAudio("NPC24", transform, true));
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
StartCoroutine(GameInit.Ins.PlayEndAnimation());
}, 5f);
});
}
else
{
ClosePet();
GameInit.Ins.StartGame(() =>
{
GameStart(() =>
{
GameInit.Ins.self.ShowPathGuide();
});
});
UserJoinPet();
}
if (door != null)
NetworkServer.Destroy(door);
});
}
public void CreateInitDoor()
{
GameObject door = Instantiate(InitDoorPre);
NetworkServer.Spawn(door);
door.transform.position = new Vector3(0, 0, 2);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
if (isPlayGame)
return;
CreateMap();
StartGame();
NetworkServer.Destroy(door.gameObject);
}, 5);
}
public void CreateBadge(Vector3 pos, bool isRotate)
{
isShowPetWorld = false;
GameObject obj = Instantiate(badgePres[curMapId]);
NetworkServer.Spawn(obj);
obj.transform.position = pos + new Vector3(0, 1, 0);
obj.GetComponent<Badge>().Init(isRotate);
}
public bool isPlayGame;
public void StartGame()
{
CreateAIController();
//isPlayGame = true;
//GameInit.Ins.laboratory.Init();
////MasterAudio.StopAllSoundsOfTransform(GameInit.Ins.self.transform);
//GameInit.Ins.MRBgm.StateChangeBgm(-1);
//foreach (var obj in GameInit.Ins.worldPres)
//{
// obj.SetActive(false);
//}
//vistEnd = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds + vistAllTime;
//CreateHUD();
//GameInit.Ins.Close();
//GameOver = false;
//isPlayPetWorld = false;
//TransitionPanel.Ins.WhiteFadeOut(CreateAiDr);
//GetPetList();
}
//添加创建AI角色的方法
[Server]
public void CreateAIController()
{
//检查是否已经存在AI角色
if (currentAI != null)
{
Debug.Log("AI角色已经存在不再创建新的");
return;
}
if (aiControllerPrefab != null)
{
Debug.Log("创建AI角色");
//在玩家前方创建AI角色
Vector3 spawnPosition = player.transform.position + player.transform.forward * 3f;
aiControllerPrefab = Instantiate(aiControllerPrefab, spawnPosition, Quaternion.identity);
//获取AIController并启动开场白
AIController aiController = aiControllerPrefab.GetComponent<AIController>();
GameInit.Ins.MRBgm.StateChangeBgm(-1);
if (aiController != null)
{
//注册AI介绍完成回调
aiController.OnIntroductionComplete += HandleAIIntroductionComplete;
//添加延迟,确保所有组件已经完成初始化
StartCoroutine(DelayedStartIntroduction(aiController));
}
else
{
Debug.LogError("AI预制体中的AIController组件丢失");
}
}
else
{
Debug.LogError("AI预制体没有在GameManager分配!");
}
}
private IEnumerator DelayedStartIntroduction(AIController aiController)
{
yield return new WaitForSeconds(0.1f); // 短暂延迟
aiController.StartIntroduction();
}
// 添加处理 AI 介绍完成
private void HandleAIIntroductionComplete()
{
Debug.Log("AI introduction completed!");
if (currentAI != null)
{
currentAI.OnIntroductionComplete -= HandleAIIntroductionComplete;
}
// 游戏正式开始的逻辑
StartCoroutine(StartMainGame());
}
//添加
private IEnumerator StartMainGame()
{
// 等待一下确保过渡平滑
yield return new WaitForSeconds(1f);
// 创建博士并让他开始说话
isPlayGame = true;
GameInit.Ins.laboratory.Init();
//MasterAudio.StopAllSoundsOfTransform(GameInit.Ins.self.transform);
foreach (var obj in GameInit.Ins.worldPres)
{
obj.SetActive(false);
}
vistEnd = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds + vistAllTime;
CreateHUD();
GameInit.Ins.Close();
GameOver = false;
isPlayPetWorld = false;
TransitionPanel.Ins.WhiteFadeOut(CreateAiDr);
}
public void CreateAiDr()
{
Debug.Log("创建博士");
GameObject aiDrObj = Instantiate(aiDrPre, GameInit.Ins.laboratory.transform);
NetworkServer.Spawn(aiDrObj);
aiDr = aiDrObj.GetComponent<AiDr>();
aiDr.transform.position = GameInit.Ins.aiDrPos.position;
aiDr.Init();
}
/// <summary>
/// 创建地图
/// </summary>
[Server]
public void CreateMap()
{
EditObjInfos infos = JsonMapper.ToObject<EditObjInfos>(Resources.Load<TextAsset>("Maps/" + GameInit.Ins.place).text);
GameLevelInfos2.Clear();
foreach (EditObjInfo info in infos.Data)
{
GameLevelInfos2.TryGetValue(info.ObjType, out List<EditObjInfo> infoList);
if (infoList == null)
{
List<EditObjInfo> list = new List<EditObjInfo>();
list.Add(info);
GameLevelInfos2.Add(info.ObjType, list);
}
else
{
infoList.Add(info);
}
}
// EditObjInfo doorInfo = GameLevelInfos2[(int)ObjTypes.door][0];
// CreateDoorCoiider(new Vector3(doorInfo.x, doorInfo.y, doorInfo.z), new Vector3(doorInfo.angleX, doorInfo.angleY, doorInfo.angleZ));
GameObject audioManager = Instantiate(AudioManagerPre);
NetworkServer.Spawn(audioManager);
}
public void CreateEnemyUI(Enemy enemy)
{
GameObject enemyUI = Instantiate(EnemyUIPre, enemy.uiPos.transform);
NetworkServer.Spawn(enemyUI);
enemyUI.GetComponent<EnemyUI>().Init(enemy);
}
public void CreatePetUI(Pet pet)
{
GameObject petUi = Instantiate(PetUIPre, pet.transform);
NetworkServer.Spawn(petUi);
petUi.GetComponent<PetUI>().Init(pet);
}
public IEnumerator CreateGameObjs(Action cb)
{
yield return isGuide;
Debug.Log("创建gameObjs");
AreaList.Clear();
// 生成战斗区域
List<EditObjInfo> battleAreaInfos = GameLevelInfos2[(int)ObjTypes.area];
List<EditObjInfo> curBattleAreaInfos = new List<EditObjInfo>();
foreach (EditObjInfo info in battleAreaInfos)
{
if (info.mapId == curMapId)
{
curBattleAreaInfos.Add(info);
}
}
foreach (EditObjInfo battleAreaInfo in curBattleAreaInfos)
{
CreateBattleArea(
battleAreaInfo.areaId,
new Vector3(battleAreaInfo.x, battleAreaInfo.y, battleAreaInfo.z),
new Vector3(battleAreaInfo.scaleX, battleAreaInfo.scaleY, battleAreaInfo.scaleZ),
new Vector3(battleAreaInfo.angleX, battleAreaInfo.angleY, battleAreaInfo.angleZ)
);
yield return null;
}
if (curMapId <= 0)
{
// // 生成复活点
// List<EditObjInfo> reviveInfos = GameLevelInfos2[(int)ObjTypes.revive];
// foreach (EditObjInfo reviveInfo in reviveInfos)
// {
// CreateRevivePoint(new Vector3(reviveInfo.x, reviveInfo.y, reviveInfo.z));
// yield return null;
// }
}
// // 生成怪物
// List<EditObjInfo> enemyInfos = GameLevelInfos2[(int)ObjTypes.enemy];
// foreach (EditObjInfo enemyInfo in enemyInfos)
// {
// CreateEnemy(
// (EnemyType)enemyInfo.id,
// new Vector3(enemyInfo.x, enemyInfo.y, enemyInfo.z),
// enemyInfo.angleY,
// enemyInfo.areaId,
// enemyInfo.scaleX,
// enemyInfo.lvl,
// (EnemyState)enemyInfo.state
// );
// yield return null;
// }
//
//
// // 生成宠物
// List<EditObjInfo> petInfos = GameLevelInfos2[(int)ObjTypes.pet];
// foreach (EditObjInfo petInfo in petInfos)
// {
// CreatePet(
// (PetType)petInfo.id,
// new Vector3(petInfo.x, petInfo.y, petInfo.z),
// petInfo.scaleX,
// petInfo.angleY,
// (int)petInfo.lvl,
// (PetState)petInfo.state,
// petInfo.cageId
// );
// yield return null;
// }
//
// // 生成笼子
// List<EditObjInfo> cageInfos = GameLevelInfos2[(int)ObjTypes.cage];
// foreach (EditObjInfo cageInfo in cageInfos)
// {
// CreateCage(cageInfo.areaId, cageInfo.cageId, new Vector3(cageInfo.x, cageInfo.y, cageInfo.z), cageInfo.angleY, cageInfo.scaleY);
// yield return null;
// }
//
// // 生成boss
// List<EditObjInfo> bossInfos = GameLevelInfos2[(int)ObjTypes.boss];
// foreach (EditObjInfo bossInfo in bossInfos)
// {
// CreateFishGiant(
// new Vector3(bossInfo.x, bossInfo.y, bossInfo.z),
// bossInfo.angleY,
// bossInfo.scaleX,
// bossInfo.lvl,
// (BossState)bossInfo.state,
// new Vector3(bossInfo.pos1X, 0, bossInfo.pos1Z)
// );
// yield return null;
// }
cb.Invoke();
}
public void UserJoinPet()
{
if (curMapId > 0)
return;
if (userPet != null && !isGetPet)
{
PetList.Add(petIndex, userPet);
AssignPetIndex();
PetPlace(petIndex);
isGetPet = true;
}
}
/// <summary>
/// 创建触发区域的怪物
/// </summary>
/// <returns></returns>
public IEnumerator CreateBattleAreaEnemy()
{
EnemyList.Clear();
// 生成怪物
List<EditObjInfo> enemyInfos = GameLevelInfos2[(int)ObjTypes.enemy];
List<EditObjInfo> petInfos = GameLevelInfos2[(int)ObjTypes.pet];
List<EditObjInfo> battleObjInfos = new List<EditObjInfo>();
List<EditObjInfo> battlePetInfos = new List<EditObjInfo>();
foreach (var enemyInfo in enemyInfos)
{
if (enemyInfo.areaId == curBattleAreaIndex && enemyInfo.mapId == curMapId)
battleObjInfos.Add(enemyInfo);
}
foreach (var petInfo in petInfos)
{
if (petInfo.cageId == curBattleAreaIndex && petInfo.mapId == curMapId)
battlePetInfos.Add(petInfo);
}
if (battleObjInfos.Count > 0)
{
int index = 0;
if (curEnemyLevel % 6 == 0)
{
ChangeGameBGM(Bgm.Fight);
var enemyInfo = battleObjInfos[^1];
var curId = EnemyDataList.Where(item => item.EnemyType == 2).ToList()[curMapId].EnemyId;
CreateEnemyBoss(
curId,
new Vector3(enemyInfo.x, enemyInfo.y, enemyInfo.z),
enemyInfo.angleY,
curBattleAreaIndex,
enemyInfo.scaleX,
curEnemyLevel,
EnemyState.GroundIdle
);
}
else
{
foreach (var enemyInfo in battleObjInfos)
{
if (index >= LevelEnemyList[curMapId][(curEnemyLevel - 1) % 5].Count)
break;
int curId = LevelEnemyList[curMapId][(curEnemyLevel - 1) % 5][index];
CreateEnemy(
curId,
new Vector3(enemyInfo.x, enemyInfo.y, enemyInfo.z),
enemyInfo.angleY,
curBattleAreaIndex,
enemyInfo.scaleX,
curEnemyLevel,
(EnemyState)enemyInfo.state
);
//battleObjInfos.Remove(battleObjInfos[0]);
index++;
}
}
}
//生成需要解救的宠物
if (battlePetInfos.Count > 0 && curEnemyLevel % 5 != 0)
{
var petInfo = battlePetInfos[0];
//int curId=UnityEngine.Random.Range(0, PetDic.Count-1);
int curId = UnityEngine.Random.Range(4 + curMapId * 3, 7 + curMapId * 3);
CreatePet(
curId,
new Vector3(petInfo.x, petInfo.y, petInfo.z),
petInfo.angleY,
(PetState)petInfo.state,
curEnemyLevel
);
CreateCage(
curBattleAreaIndex,
curEnemyLevel,
new Vector3(petInfo.x, petInfo.y, petInfo.z),
petInfo.angleY,
1
);
battlePetInfos.Remove(petInfo);
}
curEnemyLevel++;
yield return null;
}
#endregion
#region
/// <summary>
/// 申请创建一只宠物编队
/// </summary>
[Command(requiresAuthority = false)]
public void AddTeamCmd(int teamId)
{
Debug.Log(teamId + "玩家申请创建宠物编队");
BehaviorTree behaviorTree = gameObject.AddComponent<BehaviorTree>();
behaviorTree.ExternalBehavior = FollowBehavior;
behaviorTree.RestartWhenComplete = true;
FollowBehaviors.Add(teamId, behaviorTree);
TeamInfo teamInfo = new TeamInfo();
teamInfo.id = teamId;
Teams.Add(teamId, teamInfo);
}
/// <summary>
/// 获取编队xx所有宠物
/// </summary>
/// <param name="teamId"></param>
/// <returns></returns>
public List<GameObject> GetTeamMembers(int teamId)
{
List<GameObject> resMembers = new List<GameObject>();
TeamInfo teamInfo = Teams[teamId];
foreach (int petId in teamInfo.membersId)
{
resMembers.Add(PetList[petId].gameObject);
}
return resMembers;
}
/// <summary>
/// 重置编队行为
/// </summary>
public void ResetTeamBehavior(int teamId)
{
if (FollowBehaviors[teamId] == null) return;
FollowBehaviors[teamId].SetVariable("leader", (SharedGameObject)MRNetworkManager.Ins.roomSlots[teamId].gameObject);
FollowBehaviors[teamId].SetVariable("agents", (SharedGameObjectList)GetTeamMembers(teamId));
FollowBehaviors[teamId].SetVariable("hasInit", (SharedBool)false);
}
/// <summary>
/// 加入编队
/// </summary>
public void JoinTeam(int teamId, int petId)
{
Debug.Log(petId + "号宠物加入" + teamId + "编队");
Teams.TryGetValue(teamId, out TeamInfo info);
if (info != null)
{
Teams[teamId].membersId.Add(petId);
Teams[teamId].joinId.Add(petId);
ResetTeamBehavior(teamId);
}
}
/// <summary>
/// 暂离编队(Server)
/// </summary>
[Server]
public bool SetOutTeam(int teamId, int petId)
{
bool res = false;
Teams.TryGetValue(teamId, out TeamInfo info);
if (info != null)
{
if (info.membersId.Remove(petId))
{
info.setoutMembersId.Add(petId);
}
ResetTeamBehavior(teamId);
res = true;
Debug.Log(petId + "号宠物暂时离开" + teamId + "编队");
}
return res;
}
/// <summary>
/// 暂离归队(Server)
/// </summary>
/// <param name="teamId"></param>
/// <param name="petId"></param>
[Server]
public bool Return2Team(int teamId, int petId)
{
bool res = false;
Teams.TryGetValue(teamId, out TeamInfo info);
if (info != null)
{
if (info.setoutMembersId.Remove(petId))
{
info.membersId.Add(petId);
}
ResetTeamBehavior(teamId);
res = true;
Debug.Log(string.Format("{0}号宠物回归{1}编队", petId, teamId));
}
return res;
}
/// <summary>
/// 清空队伍中除了第一个宠物的信息
/// </summary>
public void ClearTeam()
{
foreach (var item in Teams.Values)
{
var fistId = item.joinId.First();
item.membersId = item.membersId.Contains(fistId) ? new HashSet<int> { fistId } : new HashSet<int>();
item.setoutMembersId = item.setoutMembersId.Contains(fistId) ? new HashSet<int> { fistId } : new HashSet<int>();
item.joinId = item.joinId.Contains(fistId) ? new HashSet<int> { fistId } : new HashSet<int>();
ResetTeamBehavior(item.id);
}
}
#endregion
#region
/// <summary>
/// 创建宠物
/// </summary>
/// <param name="type"></param>
/// <param name="pos"></param>
/// <returns></returns>
[Server]
public Pet CreatePet(int curId, Vector3 pos, float angleY, PetState state, int cageId)
{
GameObject pet = Instantiate(GetPetPre(curId));
NetworkServer.Spawn(pet);
pet.transform.position = pos;
pet.transform.eulerAngles = new Vector3(0, angleY, 0);
Pet script = pet.GetComponent<Pet>();
petIndex++;
script.OnSpawn(PetDic[curId], curEnemyLevel + 1, state, cageId, petIndex);
PetList.Add(petIndex, script);
return script;
}
public GameObject GetPetPre(int curId)
{
foreach (var item in PetPres)
{
if (item.GetComponent<Pet>().id == curId)
return item;
}
return null;
}
public void GetPet(int petId, Vector3 pos, Vector3 angles)
{
if (userPet != null)
NetworkServer.Destroy(userPet.gameObject);
GameObject pet = Instantiate(PetPres[petId]);
NetworkServer.Spawn(pet);
pet.transform.position = pos;
pet.transform.eulerAngles = angles;
userPet = pet.GetComponent<Pet>();
petIndex = 1;
EnemyData data = null;
foreach (var item in EnemyDataList)
{
if (item.EnemyId == petId + 1)
data = item;
}
userPet.OnSpawn(data, 1, PetState.Birth, -1, petIndex);
}
/// <summary>
/// 尝试捕捉宠物
/// </summary>
[Server]
public void Try2CapturePet(int playerId, int petId)
{
Debug.Log("尝试捕捉宠物" + petId);
Pet pet = null;
foreach (var item in PetList)
{
if (item.Value.id == petId)
pet = item.Value;
}
if (pet != null)
{
if ((pet.state == PetState.Wild) && curretAssignIndex == playerId)
{
pet.Catched(playerId);
// 宠物加入编队
JoinTeam(playerId, petId);
// 统计捕获宠物数量
// StatisticsManager.Ins.SetPlayerStatistics(playerId, "GetPetCount", Teams[playerId].membersId.Count);
}
}
}
/// <summary>
/// set all pet out line
/// </summary>
[Server]
public void SetAllPetOutLineToZero()
{
foreach (Pet pet in PetList.Values)
{
pet.SetOutLine(0);
}
}
public void PetJump()
{
foreach (Pet pet in PetList.Values)
{
pet.PlayJump();
}
}
/// <summary>
/// 分配宠物
/// </summary>
[Server]
public void PetPlace(int petId)
{
PetList.TryGetValue(petId, out Pet pet);
if (pet != null)
{
if (pet.state == PetState.NeedAssigned)
{
pet.Catched(curretAssignIndex);
JoinTeam(curretAssignIndex, petId);
}
}
}
/// <summary>
/// 打开笼子
/// </summary>
public void OpenCage(int cageId)
{
foreach (Pet pet in PetList.Values)
{
if (pet.cageId == cageId)
{
pet.Change2State(PetState.NeedAssigned);
AssignPetIndex();
PetPlace(pet.index);
break;
}
}
}
[Server]
/// <summary>
/// 回血
/// </summary>
public void RegenerationHealth(float checkRange, int count, int repliesVolume, GameObject gameObject)
{
foreach (Pet pet in PetList.Values)
{
if (Vector3.Distance(pet.transform.position, gameObject.transform.position) <= checkRange)
{
pet.AddBlood(count, repliesVolume);
}
}
}
#endregion
#region
/// <summary>
/// 创建怪物
/// </summary>
[Server]
public GameObject CreateEnemy(int curId, Vector3 Pos, float angleY, int areaId, float scale, int lvl, EnemyState enemyState)
{
GameObject enemy = Instantiate(GetEnemyPre(curId));
NetworkServer.Spawn(enemy);
enemy.transform.position = Pos;
enemy.transform.eulerAngles = new Vector3(0, angleY, 0);
Enemy enemyScript = enemy.GetComponent<Enemy>();
enemyScript.OnSpawn(EnemyDic[curId], areaId, lvl, enemyState);
EnemyList.Add(enemyScript);
enemyIndex++;
return enemy;
}
/// <summary>
/// 创建巨鱼人
/// </summary>
[Server]
public GameObject CreateFishGiant(Vector3 Pos, float angleY, float scale, int lvl, BossState state, Vector3 wakeUpPos)
{
GameObject boss = Instantiate(EnemyPres[(int)EnemyType.FishGiant]);
NetworkServer.Spawn(boss);
boss.transform.position = Pos;
boss.transform.eulerAngles = new Vector3(0, angleY, 0);
FishGiant fishGiant = boss.GetComponent<FishGiant>();
fishGiant.OnSpawn(9999, GameManager.Ins.curEnemyLevel, state, wakeUpPos);
EnemyList.Add(fishGiant);
this.fishGiant = fishGiant;
return boss;
}
[Server]
public GameObject CreateEnemyBoss(int curId, Vector3 Pos, float angleY, int areaId, float scale, int lvl, EnemyState enemyState)
{
GameObject boss = Instantiate(GetEnemyPre(curId));
NetworkServer.Spawn(boss);
boss.transform.position = Pos;
boss.transform.eulerAngles = new Vector3(0, angleY, 0);
EnemyBoss enemyBoss = boss.GetComponent<EnemyBoss>();
enemyBoss.OnSpawn(EnemyDic[curId], areaId, lvl, enemyState, Pos);
EnemyList.Add(enemyBoss);
enemyIndex++;
return boss;
}
public GameObject GetEnemyPre(int curId)
{
foreach (var item in EnemyPres)
{
if (item.GetComponent<Enemy>().id == curId)
return item;
}
return null;
}
/// <summary>
/// 获取区域可攻击怪物
/// </summary>
[Server]
public List<Enemy> GetEnemysByAreaId(int areaId)
{
List<Enemy> list = new List<Enemy>();
foreach (Enemy enemy in EnemyList)
{
if (enemy.areaId == areaId && enemy.state != EnemyState.Ghost)
{
list.Add(enemy);
}
}
return list;
}
public void SetOutLine(int wit)
{
}
/// <summary>
/// 检测区域是否清空怪物
/// </summary>
public void CheckAreaSettle(int areaId)
{
if (GetEnemysByAreaId(areaId).Count <= 0)
{
Debug.Log($"结算{areaId}区域奖励");
//打开区域内所有笼子
CageList.TryGetValue(areaId, out List<Cage> cages);
if (cages != null)
{
foreach (Cage cage in cages)
{
cage.OpenCage();
}
}
AreaList[areaId].isWin = true;
EnergyValue += 1F / AreaList.Count;
if (EnergyValue >= 1) EnergyValue = 1;
for (int i = 0; i < MRNetworkManager.Ins.roomSlots.Count; i++)
{
MRNetworkManager.Ins.roomSlots[i].GetComponent<Player>().ExitArea();
}
foreach (var item in PetList.Values)
{
if (item.state == PetState.Trained)
{
item.AddExp();
}
}
NetworkServer.Destroy(AreaList[areaId].gameObject);
AreaList.Remove(areaId);
// foreach (var pet in PetList.Values)
// {
// pet.Change2State(PetState.CurWin);
// }
//每次结算奖励时判断是否进入下一段剧情
// if (AreaList.Count == 0)
// {
// Debug.Log("进入下一段剧情");
// if (fishGiant != null) fishGiant.WakeUp();
// ChangeGameBGM(Bgm.Fight);
// }
}
}
#endregion
#region
/// <summary>
/// 命令宠物攻击
/// </summary>
[Server]
public void OrderPetAttack(int petId, int enemyId)
{
//Debug.Log(string.Format("命令宠物{0}攻击怪物{1}", petId, enemyId));
PetList.TryGetValue(petId, out Pet pet);
// 找到最近的敌人
GameObject nearestEnemy = null;
float minDistance = float.MaxValue;
Vector3 petPos = pet.transform.position;
foreach (var enemy in EnemyList)
{
if (enemy == null)
continue;
// 计算宠物和敌人之间的距离,要求敌人 GameObject 必须有有效 transform
float distance = Vector3.Distance(petPos, enemy.transform.position);
if (distance < minDistance)
{
minDistance = distance;
nearestEnemy = enemy.gameObject;
}
}
if (nearestEnemy != null)
{
// 假设每个敌人 GameObject 上都有 Enemy 组件,其中有 enemyId 属性
Enemy enemyComponent = nearestEnemy.GetComponent<Enemy>();
if (enemyComponent != null)
{
// 通知宠物攻击敌人
pet.AttackOrder(enemyComponent);
//Debug.Log($"宠物 {petId} 正在攻击离它最近的敌人 {enemyComponent.id},距离:{minDistance}");
}
else
{
//Debug.LogWarning("最近的敌人没有 Enemy 组件,无法获取 enemyId");
}
}
else
{
Debug.LogWarning("无法找到最近的敌人!");
}
}
/// <summary>
/// 命令宠物撤退
/// </summary>
public void OrderPetRetreat(int petId)
{
// Debug.Log(string.Format("命令宠物{0}撤退", petId));
PetList.TryGetValue(petId, out Pet pet);
if (pet != null)
{
pet.RetreatOrder();
}
}
/// <summary>
/// 督战宠物
/// </summary>
public void OverseerPetInArea(int teamId)
{
// if(isGuide)
// return;
// Debug.Log("区域内督战");
Teams.TryGetValue(teamId, out TeamInfo teamInfo);
Player player = MRNetworkManager.Ins.roomSlots[teamId].GetComponent<Player>();
if (teamInfo != null)
{
HashSet<int> membersId = teamInfo.membersId;
HashSet<int> setoutMembersId = teamInfo.setoutMembersId;
if (membersId.Count > 0)
{
List<Enemy> enemys = GetEnemysByAreaId(player.InAreaId);
if (enemys.Count > 0)
{
int i = 0;
foreach (int petId in membersId)
{
Enemy enemy = enemys[i % enemys.Count];
PetList.TryGetValue(petId, out Pet pet);
if (pet.state != PetState.Terminal)
{
// 给宠物分配攻击对象
OrderPetAttack(petId, enemy.id);
i++;
}
}
}
}
if (setoutMembersId.Count > 0)
{
List<Enemy> enemys2 = GetEnemysByAreaId(player.InAreaId);
if (enemys2.Count > 0)
{
int j = 0;
foreach (int petId in setoutMembersId)
{
Enemy enemy = enemys2[j % enemys2.Count];
PetList.TryGetValue(petId, out Pet pet);
if (pet.state != PetState.Terminal)
{
// 给宠物分配攻击对象
OrderPetAttack(petId, enemy.id);
j++;
}
}
}
}
}
}
/// <summary>
/// 督战宠物攻击boss
/// </summary>
public void OverseerPet2Boss(int teamId)
{
Teams.TryGetValue(teamId, out TeamInfo teamInfo);
if (teamInfo != null)
{
HashSet<int> membersId = teamInfo.membersId;
HashSet<int> setoutMembersId = teamInfo.setoutMembersId;
if (membersId.Count > 0)
{
foreach (int petId in membersId)
{
PetList.TryGetValue(petId, out Pet pet);
if (pet.state != PetState.Terminal)
{
OrderPetAttack(petId, fishGiant.id);
}
}
}
if (setoutMembersId.Count > 0)
{
foreach (int petId in membersId)
{
PetList.TryGetValue(petId, out Pet pet);
if (pet.state != PetState.Terminal)
{
OrderPetAttack(petId, fishGiant.id);
}
}
}
}
}
/// <summary>
/// 组织撤退
/// </summary>
public void OriginRetreat(int playerId)
{
Teams.TryGetValue(playerId, out TeamInfo teamInfo);
if (teamInfo != null)
{
if (Teams[playerId].joinId.Count > 0)
{
int[] membersId = Teams[playerId].joinId.ToArray();
foreach (int petId in membersId)
{
OrderPetRetreat(petId);
}
}
}
}
// 分配宠物给玩家
[Server]
public void AssignPetIndex()
{
// 使用局部变量存储roomSlots的Count属性避免多次访问。
int slotCount = MRNetworkManager.Ins.roomSlots.Count;
// 获取并返回当前分配的索引。
// int index = MRNetworkManager.Ins.roomSlots[curretAssignIndex].index;
int tempVale = curretAssignIndex + 1;
// 更新当前分配索引,使用取模运算确保索引不会超出范围。
curretAssignIndex = tempVale % slotCount;
// 输出日志,便于调试。
Debug.Log($"Current Assign Index: {curretAssignIndex}");
}
/// <summary>
/// 玩家选择卡片
/// </summary>
public void SelectCard()
{
if (selectCardId == -1 || isPlayPetWorld)
return;
LaboratoryManager.Ins.isGetPet = true;
var selectedCard = selectCardId;
MasterAudio.PlaySound3DFollowTransform(selectCardSound, GameInit.Ins.MRCamera.transform);
TransitionPanel.Ins.WhiteFadeOut(() =>
{
aiDr.ChangeState(1);
GetPet(selectedCard, GameInit.Ins.petPos.position, GameInit.Ins.petPos.rotation.eulerAngles);
});
GameInit.Ins.laboratory.CloseCards();
}
#endregion
#region
public void CreateSkill(int skillId, Vector3 pos, float time, Transform target)
{
//Debug.LogError("技能ID"+skillId);
if (GetSkill(skillId) == null)
return;
GameObject obj = Instantiate(GetSkill(skillId), pos, Quaternion.identity);
NetworkServer.Spawn(obj);
var skill = obj.GetComponent<Skill>();
skill.Init();
if (skill.isFinger && target != null)
{
obj.transform.position = target.position;
}
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(obj);
}, time);
}
public GameObject GetSkill(int skillId)
{
foreach (var obj in skillPres)
{
var skill = obj.GetComponent<Skill>();
if (skill.skillID == skillId)
return obj;
}
return null;
}
public void CreateBullet(int bulletId, Vector3 pos, Transform tran, int campId, float atk, GameObject target)
{
GameObject obj = Instantiate(GetBullet(bulletId), pos, tran.rotation);
NetworkServer.Spawn(obj);
RemoteButtlet bullet = obj.GetComponent<RemoteButtlet>();
if (bullet != null)
{
bullet.Init(campId == 2, atk, target);
}
}
public GameObject GetBullet(int bulletId)
{
foreach (var obj in bulletPres)
{
var bullet = obj.GetComponent<RemoteButtlet>();
if (bullet != null && bullet.id == bulletId)
{
return obj;
}
}
return null;
}
#endregion
#region
public void CreateItemBox(Vector3 pos)
{
GameObject obj = Instantiate(itemBoxPre, pos, Quaternion.identity);
NetworkServer.Spawn(obj);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(obj);
}, 30);
var objData = obj.GetComponent<ItemBox>();
objData.Init();
}
public PropItem CreateItem(int itemId, Vector3 pos, bool isReduce)
{
GameObject obj = Instantiate(GetItem(itemId), pos, Quaternion.identity);
NetworkServer.Spawn(obj);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(obj);
}, 30);
var itemData = obj.GetComponent<PropItem>();
itemData.Init((WeaponType)itemId);
itemData.Amplify();
if (isReduce)
itemData.Reduce();
return itemData;
}
public GameObject GetItem(int itemId)
{
foreach (var obj in itemPres)
{
var item = obj.GetComponent<PropItem>();
if (item != null && item.id == itemId)
{
return obj;
}
}
return null;
}
public void DelItem(int playerId)
{
var player = MRNetworkManager.Ins.roomSlots[playerId].GetComponent<Player>();
player.DelWeapon();
}
#endregion
#region
/// <summary>
/// 鉴权
/// </summary>
public void RequestAuth(Action<HTTPRequest, HTTPResponse> cb = null)
{
string url = "http://www.pineappletech.cn/startcount";
HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post, (req, response) =>
{
if (response != null)
{
Debug.Log("收到数据 ->" + response.DataAsText);
}
cb?.Invoke(req, response);
});
request.AddHeader("Authorization", Author);
authInfo.deviceSn = GetSn();
authInfo.startAt = ConvertTimestampToDateTime(GetTimestamp()) + "";
authInfo.shop = 23;
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
authInfo.shop = (int)GameInit.Ins.place;
if (GameInit.Ins.place == Place.Zhejiang_Jinhua_KeJiGuan)
authInfo.shop = 5;
if (GameInit.Ins.place == Place.Shandong_Jining_Shangchang_nei)
authInfo.shop = 9;
if (GameInit.Ins.place == Place.Shandong_Jinan_Huaiyin_ShengfutongShangmao_wai)
authInfo.shop = 15;
if (GameInit.Ins.place == Place.Nanjing_Qixia_Yaohuamen_Jindiguangchang_nei)
authInfo.shop = 17;
if (GameInit.Ins.place == Place.Wulanhaote_Wanda_Shangchang)
authInfo.shop = 21;
#endif
authInfo.gameId = 4;
string authJson = JsonUtility.ToJson(authInfo);
Debug.Log("发送数据 -> " + authJson);
request.RawData = System.Text.Encoding.UTF8.GetBytes(authJson);
request.AddHeader("Content-Type", "application/json");
request.Send();
}
[ClientRpc]
public void RpcRequestNotifyStart()
{
//RequestNotifyStart();
}
[ClientRpc]
public void RpcRequestNotifyEnd()
{
//RequestNotifyEnd();
}
/// <summary>
/// 通知服务器已开始游戏
/// </summary>
// public void RequestNotifyStart(Action<HTTPRequest, HTTPResponse> cb = null)
// {
// string url = HttpServerUrl + "/api/record";
// HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Put, (req, response) =>
// {
// if (response != null)
// {
// Debug.Log("收到数据 ->" + response.DataAsText);
// cb?.Invoke(req, response);
// }
// });
// request.AddHeader("Authorization", Author);
// authInfo.paid = 1;
// string authJson = JsonUtility.ToJson(authInfo);
// Debug.Log("发送数据 -> " + authJson);
// request.RawData = System.Text.Encoding.UTF8.GetBytes(authJson);
// request.AddHeader("Content-Type", "application/json");
// request.Send();
// }
//
// /// <summary>
// /// 通知服务器游戏结束
// /// </summary>
// public void RequestNotifyEnd(Action<HTTPRequest, HTTPResponse> cb = null)
// {
// string url = HttpServerUrl + "/api/record";
// HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Put, (req, response) =>
// {
// if (response != null)
// {
// Debug.Log("收到数据 ->" + response.DataAsText);
// cb?.Invoke(req, response);
// }
// });
// request.AddHeader("Authorization", Author);
// authInfo.endAt = ConvertTimestampToDateTime(GetTimestamp()) + "";
// authInfo.dur = (int)(((long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds) - (vistEnd - vistAllTime));
// string authJson = JsonUtility.ToJson(authInfo);
// Debug.Log("发送数据 -> " + authJson);
// request.RawData = System.Text.Encoding.UTF8.GetBytes(authJson);
// request.AddHeader("Content-Type", "application/json");
// request.Send();
// }
[Command(requiresAuthority = false)]
public void KillAllEnemy()
{
var enemies = new List<Enemy>(EnemyList);
foreach (var enemy in enemies)
{
if (enemy.id != 9999)
{
enemy.transform.GetComponent<IDamagable>().ApplyDamage(100000000000, true, null);
}
}
}
/// <summary>
/// 能量球飞到世界树中
/// </summary>
public IEnumerator BallFlyToTree(NetworkRoomPlayer roomPlayer, int amount, float delay, Vector3 treePos)
{
PetJump();
List<GameObject> energyBalls = new List<GameObject>();
for (int j = 0; j < amount; j++)
{
GameObject energyBall = Instantiate(EnergyBallPre);
energyBalls.Add(energyBall);
NetworkServer.Spawn(energyBall);
energyBall.transform.position = roomPlayer.transform.position;
energyBall.GetComponent<Rigidbody>().useGravity = false;
energyBall.transform.DOMove(treePos, 5F).OnComplete(() =>
{
// Math.Clamp();
EnergyValue -= 1F / (MRNetworkManager.Ins.roomSlots.Count * amount);
EnergyValue = Math.Clamp(EnergyValue, 0F, 1F);
energyBalls.Remove(energyBall);
NetworkServer.Destroy(energyBall);
if (energyBalls.Count == 0)
{
//GameEnd();
}
});
yield return new WaitForSeconds(delay);
}
}
[ClientRpc]
public void ChangeGameBGM(Bgm bgm)
{
GameInit.Ins.MRBgm.StateChangeBgm((int)bgm);
}
/// <summary>
/// 更新配置表
/// </summary>
public void UpdateConf()
{
string text = Resources.Load<TextAsset>("Data").text;
if (text != null)
{
ParseGameJson(text);
}
var str = "Data/" + GameInit.Ins.place + "Data";
string data = Resources.Load<TextAsset>(str).text;
if (data != null)
{
ParseGameDataJson(data);
}
}
#endregion
#region json
/// <summary>
/// 解析游戏使用的json
/// </summary>
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.EnemyType, 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.EnemyType, list);
// }
// else
// {
// infoList.Add(info.Lvl, info);
// }
// }
//
// infoReader = DB["PetsInfo"].GetReader();
// while (infoReader.Read())
// {
// PetInfo info = new PetInfo(infoReader);
// PetInfos.TryGetValue((PetType)info.ID, out Dictionary<int, PetInfo> infoList);
// if (infoList == null)
// {
// Dictionary<int, PetInfo> list = new Dictionary<int, PetInfo>();
// list.Add(info.Lvl, info);
// PetInfos.Add((PetType)info.ID, list);
// }
// else
// {
// infoList.Add(info.Lvl, info);
//
// }
// }
//Debug.Log("游戏数值更新 -> complete" + EnemyInfos);
}
public void ParseGameDataJson(string text)
{
DB = new JsonLiteDB();
DB.Load(text);
TableReader enemyDataReader = DB["EnemyData"].GetReader();
EnemyDataList.Clear();
while (enemyDataReader.Read())
{
EnemyData data = new EnemyData(enemyDataReader);
EnemyDataList.Add(data);
}
TableReader skillDataReader = DB["SkillData"].GetReader();
SkillDataList.Clear();
while (skillDataReader.Read())
{
SkillData data = new SkillData(skillDataReader);
SkillDataList.Add(data.SkillId, data);
}
skillManager.Init();
TableReader levelDataReader = DB["LevelData"].GetReader();
while (levelDataReader.Read())
{
LevelData data = new LevelData(levelDataReader);
LevelEnemyList.Add(data.LevelMonsters);
}
}
#endregion
public void ClosePet()
{
List<int> petIds = new List<int>();
foreach (var item in PetList)
{
if (item.Key == 1)
continue;
petIds.Add(item.Key);
NetworkServer.Destroy(item.Value.gameObject);
}
foreach (var item in petIds)
{
PetList.Remove(item);
}
foreach (var pet in PetList)
{
pet.Value.Change2State(PetState.Trained);
}
}
/// <summary>
/// 游戏开始
/// </summary>
[Server]
public void GameStart(Action cb)
{
isPlayPetWorld = true;
GetEnemyList();
GetPetList();
MasterAudio.StopAllSoundsOfTransform(aiDr.transform);
foreach (var item in AreaList)
{
item.Value.isWin = false;
}
var str = "新手教程1";
switch (curMapId)
{
case 0:
str = "新手教程2";
break;
case 1:
str = "迷雾丛林提示音";
break;
case 2:
str = "熔岩火山提示音";
break;
case 3:
str = "NPC24";
break;
}
if (curMapId == 0)
{
hud[0].Instance.GetComponent<HUD>().ShoGuide(0);
}
StartCoroutine(PlayAudio(str, GameInit.Ins.self.transform, true, () =>
{
if (curMapId == 0)
{
isGuide = true;
hud[0].Instance.GetComponent<HUD>().ShoGuide(1);
StartCoroutine(PlayAudio("新手教程1", GameInit.Ins.self.transform, true, () =>
{
isGuide = false;
}));
}
}));
StartCoroutine(CreateGameObjs(() =>
{
cb?.Invoke();
ShowBattleArea();
}));
ChangeGameBGM((Bgm)curMapId + 4);
}
public void Update()
{
if (!GameOver && GetCountDownSecond() <= 0)
{
GameEnd();
}
}
/// <summary>
/// 游戏结束
/// </summary>
[Server]
public void GameEnd()
{
GameOver = true;
//统计双方的宠物总数
// int allPetNum = 0;
// StatisticsDate date = new StatisticsDate();
// List<int> ints = new List<int>();
// Debug.Log(Teams);
// for (int i = 0; i < Teams.Count; i++)
// {
// for (int j = 0; j < Teams[i].joinId.Count; j++)
// {
// int id = Teams[i].joinId.ElementAt(j);
// allPetNum++;
// ints.Add(PetList[id].id);
// }
// }
// date.GetPetCount = allPetNum;
// date.numberIds = ints.ToArray();
// string strJson = JsonUtility.ToJson(date);
// StatisticsManager.Ins.StatisticsDate = strJson;
//所有怪物消失
foreach (Enemy Enemy in EnemyList)
{
Enemy.TrueDie();
}
if (IsWin)
{
//所有小动物原地跳舞
//世界树恢复生长
//RpcShowWorkTree();
}
else
{
ChangeGameBGM(Bgm.Fail);
}
//所有玩家展示结算页面
RpcShowResult();
RpcRequestNotifyEnd();
}
public void OpenEndScenes()
{
}
public IEnumerator PlayAudio(string audioName, Transform tran, bool isAllStop, Action cb = null)
{
if (isAllStop)
MasterAudio.StopAllSoundsOfTransform(tran);
if (audioName != "")
{
MasterAudio.PlaySound3DAtTransform(audioName, tran);
MasterAudioGroup audioGroup = MasterAudio.GrabGroup(audioName);
if (cb != null)
{
while (audioGroup.ActiveVoices > 0)
{
yield return new WaitForSeconds(1f);
}
cb?.Invoke();
}
}
}
/// <summary>
/// 通过一个区域
/// </summary>
[Server]
public void WinArea(Vector3 pos)
{
curUpLevelCount++;
// if (curUpLevelCount >= 3)
// {
// //GameEnd();
// return;
// }
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
ChangeGameBGM(Bgm.Win);
CreateBadge(pos, true);
WinAreaPanel.Show(PetList.Count - 1);
TransitionPanel.Ins.WhiteFadeOut();
curMapId++;
}, 5f);
ClearTeam();
//后续改为多个区域中随机一个
foreach (var pet in PetList)
{
pet.Value.Upgrad();
pet.Value.Change2State(PetState.AreaWin);
}
foreach (Enemy Enemy in EnemyList)
{
Enemy.TrueDie();
}
EnemyList.Clear();
CageList.Clear();
enemyIndex = 0;
}
[ClientRpc]
public void RpcShowWorkTree()
{
for (int i = 0; i < GameInit.Ins.WorkTree.Length; i++)
{
GameInit.Ins.WorkTree[0].gameObject.SetActive(false);
GameInit.Ins.WorkTree[1].gameObject.SetActive(true);
}
}
[ClientRpc]
public void RpcShowResult()
{
OverlayUIManager.Ins.Cover("UI/ResultPanel", false);
}
public UIGroup hud;
[ClientRpc]
public void CreateHUD()
{
hud = HUD.Show();
//OverlayUIManager.Ins.Cover("UI/HUD", false);
}
public bool isShowBattleArea;
/// <summary>
/// 展示战斗区域
/// </summary>
public void ShowBattleArea()
{
isShowBattleArea = false;
foreach (var area in AreaList.Values)
{
area.gameObject.SetActive(false);
}
if (curBattleAreaIndex != -1)
{
var area = AreaList[curBattleAreaIndex];
GameInit.Ins.self.InAreaId = area.AreaId;
area.gameObject.SetActive(true);
if (curMapId == 0 && curEnemyLevel == 1)
{
//触发区域怪物
GameInit.Ins.self.ClosePathGuide();
StartCoroutine(CreateBattleAreaEnemy());
area.gameObject.SetActive(false);
}
else
{
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if (isShowBattleArea || area == null)
return;
isShowBattleArea = true;
//触发区域怪物
GameInit.Ins.self.ClosePathGuide();
StartCoroutine(CreateBattleAreaEnemy());
area.gameObject.SetActive(false);
}, 10f);
}
}
else
{
foreach (var item in AreaList.Values)
{
if (item.isWin)
continue;
//item.gameObject.SetActive(true);
curBattleAreaIndex = item.AreaId;
var area = AreaList[curBattleAreaIndex];
GameInit.Ins.self.InAreaId = area.AreaId;
area.gameObject.SetActive(true);
if (curMapId == 0 && curEnemyLevel == 1)
{
//触发区域怪物
GameInit.Ins.self.ClosePathGuide();
StartCoroutine(CreateBattleAreaEnemy());
area.gameObject.SetActive(false);
}
else
{
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if (isShowBattleArea)
return;
isShowBattleArea = true;
//触发区域怪物
GameInit.Ins.self.ClosePathGuide();
StartCoroutine(CreateBattleAreaEnemy());
area.gameObject.SetActive(false);
}, 10f);
}
break;
}
}
}
/// <summary>
/// 获取当前关卡的宠物列表
/// </summary>
public void GetPetList()
{
PetDic.Clear();
int index = 0;
foreach (var data in EnemyDataList)
{
if (data.Camp == 1 && data.LevelId == curMapId)
{
PetDic.Add(data.EnemyId, data);
index++;
}
}
}
/// <summary>
/// 获取当前关卡的怪物列表
/// </summary>
public void GetEnemyList()
{
EnemyDic.Clear();
int index = 0;
foreach (var data in EnemyDataList)
{
if (data.Camp == 2 && data.LevelId == curMapId)
{
EnemyDic.Add(data.EnemyId, data);
index++;
}
}
}
#region
public List<Transform> GetRangeEnemy(Vector3 Pos, float radius, string tag)
{
Collider[] colliders;
colliders = new Collider[30];
int colliderCount = Physics.OverlapSphereNonAlloc(Pos, radius, colliders);
List<Transform> animals = new List<Transform>();
for (int i = 0; i < colliderCount; i++)
{
if (colliders[i].CompareTag(tag))
{
if (colliders[i].GetComponent<Agent>().IsAlive)
{
animals.Add(colliders[i].transform);
}
}
}
return animals;
}
/// <summary>
/// 获取范围内宠物
/// </summary>
public List<int> GetRangePetId(Vector3 pos, float radius)
{
List<int> res = new List<int>();
foreach (Pet pet in PetList.Values)
{
float dis = Vector3.Distance(pet.transform.position, pos);
if (dis <= radius)
{
res.Add(pet.id);
}
}
return res;
}
/// <summary>
/// 获取范围内敌人
/// </summary>
public List<int> GetRangeEnemyId(Vector3 pos, float radius)
{
List<int> res = new List<int>();
foreach (Enemy enemy in EnemyList)
{
float dis = Vector3.Distance(enemy.transform.position, pos);
if (dis <= radius)
{
res.Add(enemy.id);
}
}
return res;
}
/// <summary>
/// 检测一个点是否在区域内
/// </summary>
public bool CheckPointInArea(int areaId, Vector3 point)
{
AreaList.TryGetValue(areaId, out BattleArea area);
if (area == null) return false;
Bounds bounds = area.boxCollider.bounds;
point.y = 0;
if (!bounds.Contains(point)) return false;
return true;
}
#endregion
#region
/// <summary>
/// 获取sn号
/// </summary>
public string GetSn()
{
string res = "UnityEditor";
// string res = "PA8E10MGH7210380D";
#if !UNITY_EDITOR && UNITY_ANDROID && PICO
res = PXR_Enterprise.StateGetDeviceInfo(SystemInfoEnum.EQUIPMENT_SN);
#endif
return res;
}
public long GetTimestamp()
{
return (long)DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
}
public static string ConvertTimestampToDateTime(long timestamp)
{
// Unix时间戳是从1970年1月1日00:00:00开始的秒数或毫秒数
// 这里以秒为单位如果时间戳是毫秒则除以1000
DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
}
public void LogPosition(Vector3 pos)
{
Debug.Log("x:" + pos.x + " y:" + pos.y + " z:" + pos.z);
}
public string GetLessTimeStr()
{
string res = "";
if (!GameOver)
{
res = FormatTime((int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds));
}
return res;
}
public string GetLessTimeStr2()
{
string res = "";
if (!GameOver)
{
res = FormatTime2((int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds));
}
return res;
}
public string GetEndTime()
{
string res = "";
if (GameOver)
{
res = FormatTime2((int)(((long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds) - (vistEnd - vistAllTime)));
}
return res;
}
/// <summary>
/// 获取当前剩余多少秒
/// </summary>
/// <returns></returns>
public int GetCountDownSecond()
{
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);
}
public string FormatTime2(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
#region NPC引导
public void Guide1()
{
ChangeGameBGM(Bgm.Fight);
//播放第一关引导语音:这是第一关,你们只需要击败这些小家伙和大家伙就够了。不用担心,他们都是数据模拟出来的,放心大胆的动手吧!
}
public void Guide2()
{
}
#endregion
}
}