using AX.InputSystem;
using AX.NetworkSystem;
using System.Collections.Generic;
using UnityEngine;
//[RequireComponent(typeof(Rigidbody))]
///
/// 油罐爆炸
///
public class OilTanksExplode : MonoBehaviour
{
// 是否发生爆炸
public bool IsExplode = false;
// 罐体是否受热,冷却强度是否足够
public bool IsHeating = false;
//// 热负荷,需要的冷却强度-千焦/小时 /3600千焦/秒
//public float HeatLoad = 3600f;
// 爆炸音效-音效
public AudioClip ExplodeAudio;
// 正常罐模型
public GameObject NomalModel;
// 爆炸罐模型
public GameObject ExplodeModel;
// 受到的爆炸力
private float power = 2000f;
private Vector3 explosionPos;
private float radius = 20f;
public GameObject particle;
// 冷却组件
public List Coolings;
// 罐体信息
public OilTankMessage OilData;
private void Awake()
{
OilTanksExplodeManager.AddOilTanksExplode(gameObject.name, this);
}
private void OnDestroy()
{
OilTanksExplodeManager.RemoveOilTanksExplode(gameObject.name);
}
public void Explode(Vector3 point)
{
NomalModel.SetActive(false);
ExplodeModel.SetActive(true);
//Vector3 point = transform.position + new Vector3(Random.Range(-6, 6), 6, Random.Range(-6, 6));
//得到碰撞点的坐标
//实例化出这个物体
Instantiate(particle, point, Quaternion.Euler(new Vector3(-90, 0, 0)));
//Physics.OverlapSphere():球体投射,给定一个球心和半径,返回球体投射到的物体的碰撞器
Collider[] colliders = Physics.OverlapSphere(point, radius);
foreach (Collider hits in colliders) //遍历碰撞器数组
{
//如果这个物体有刚体组件
if (hits.GetComponent())
{
//给定爆炸力大小,爆炸点,爆炸半径
//利用刚体组件添加爆炸力AddExplosionForce
hits.GetComponent().AddExplosionForce(power, point, radius);
}
}
// 如果是导调组,创建
if (CurrentUserInfo.role == Role.导调组)
{
// 如果没有生成全页面火
if (!CheckHaveLiquidLevel())
{
CloneLiquidLevelFire(NomalModel.transform.position + new Vector3(0, 10, 0));
}
// 对伤员造成伤害
HurtOnMan();
}
}
private void HurtOnMan()
{
// 获取所有重伤员
BaseHaemalController[] wounded = GameObject.Find("P_AllParent/P_Disasters/P_Wounded").GetComponentsInChildren();
// 获取所有轻伤员
BaseHaemalController[] trappedPerson = GameObject.Find("P_AllParent/P_Disasters/P_TrappedPerson").GetComponentsInChildren();
// 获取所有伤员
List allPerson = new List();
allPerson.AddRange(wounded);
allPerson.AddRange(trappedPerson);
// 检测伤员与爆炸的距离
foreach (var item in allPerson)
{
float distance = Vector3.Distance(transform.position, item.transform.position);
if (distance <= OilData.ExplodeDeadRange)
{
item.Haemal = 0;
}
else if (distance <= OilData.ExplodeHurtRange)
{
if (item.Haemal > 50)
{
item.Haemal = 50;
}
}
}
}
public void CloneLiquidLevelFire(Vector3 pos)
{
var arg = new CloneCmdArgs();
if (NomalModel.transform.GetComponent())
{
arg.gameObjID = NomalModel.transform.GetComponent().GameObjID;
}
arg.cloneObjType = CloneObjType.LiquidLevel;
arg.hitPos = pos;
CloneCommand.Instance.Execute(EntitiesManager.Instance.CreateObjID(CurrentUserInfo.mySelf.Id), arg);
}
private float time = 0;
void Update()
{
// 导调组,非灾情库模式,未爆炸
if (GameSettings.othersSettings.mode != Mode.DisasterManagement
&& CurrentUserInfo.role == Role.导调组
&& !IsExplode
&& GameSettings.othersSettings.isStartDrill
)
{
// 检查周围是否有火源
SearchNearUnits();
// 检查罐体是否正在受热
CheckIsHeating();
if (IsHeating)
{
time += Time.deltaTime;
}
if (time >= OilData.ExplodeTime * 60)
{
// 罐体可以发生爆炸
if (OilData.IsCanExplode)
{
IsExplode = true;
foreach (var item in Coolings)
{
item.IsOver = true;
}
Vector3 point = transform.position + new Vector3(Random.Range(-6, 6), 6, Random.Range(-6, 6));
ExplodeData data = new ExplodeData() { Name = gameObject.name, Point = point };
NetworkManager.Default.SendAsync("OLITANKS_EXPLODE_SYNC", data);
}
}
}
}
private void CheckIsHeating()
{
IsHeating = false;
foreach (var item in Coolings)
{
if (item.IsHeating)
{
if (item.IsCooling == false)
{
IsHeating = true;
}
}
}
}
// 查询附近火源
public void SearchNearUnits()
{
Collider[] colliders = Physics.OverlapSphere(transform.position, 20f, 1 << LayerMask.NameToLayer("Thermal"));
if (colliders.Length > 0)
{
//IsHeating = true;
foreach (var item in Coolings)
{
item.IsHeating = true;
item.SetCoolingObject();
}
}
else
{
foreach (var item in Coolings)
{
item.IsHeating = false;
}
//IsHeating = false;
}
}
// 检测是否存在全液面火
public bool CheckHaveLiquidLevel()
{
Vector3 position = transform.position + new Vector3(0, 10, 0);
Collider[] colliders = Physics.OverlapSphere(position, 5f, 1 << LayerMask.NameToLayer("Thermal"));
if (colliders.Length > 0)
{
// 远近由索引限定
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].GetComponent().gameObjType == CloneObjType.LiquidLevel)
{
return true;
}
}
}
return false;
}
}
public class OilTanksExplodeManager
{
static Dictionary OilTanksExplodes = new Dictionary();
public static void AddOilTanksExplode(string name, OilTanksExplode oilTanksExplode)
{
if (!OilTanksExplodes.ContainsKey(name))
{
OilTanksExplodes.Add(name, oilTanksExplode);
}
}
public static void RemoveOilTanksExplode(string name)
{
if (OilTanksExplodes.ContainsKey(name))
{
OilTanksExplodes.Remove(name);
}
}
public static void OilTanksExplodeByName(string name, Vector3 point)
{
if (OilTanksExplodes.ContainsKey(name))
{
OilTanksExplodes[name].Explode(point);
}
}
}
public class ExplodeData
{
public string Name;
public Vector3 Point;
}