using ShotSimulator.Screen; using ShotSimulator.Target; using ShotSimulator.Tool; using ShotSimulator.Train.Info; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Random = UnityEngine.Random; namespace ShotSimulator.Train { public class GridShotTrainHandle : BaseTrainHandle { private int maxTargetNum = 3; private GridShotTrainDifficultyData m_DifficultyData; private GridShotTrainScoreData m_ScoreData; private List generateTargetTimeTasks = new List(); private double m_TotalHitNum; private double TotalHitNum { get { return m_TotalHitNum; } set { m_TotalHitNum = value; UpdatePrecision(); } } private double m_MissHitNum; private double MissHitNum { get { return m_MissHitNum; } set { m_MissHitNum = value; UpdatePrecision(); } } private double totalTargetNum; private List curTargets = new List(); public GridShotTrainHandle(BaseTrainCallBack callBack, BaseTrainInfo info, DifficultyType difficultyType) : base(callBack, info, difficultyType) { SetShotTargetInteractiveEvent(ShotTargetInteractiveType.OnClick, OnShottedTargetEvent); m_DifficultyData = info.GetDifficultyData(m_DifficultyType); m_ScoreData = info.GetScoreData(m_DifficultyType); } #region Train protected override void ResetTrain() { ResetTarget(); for(int i = 0; i < generateTargetTimeTasks.Count; i++) { TimerSystem.GetInstance().RemoveTimeTask(generateTargetTimeTasks[i]); } generateTargetTimeTasks.Clear(); m_TotalHitNum = 0; totalTargetNum = 0; m_MissHitNum = 0; } public override void StartTrain() { base.StartTrain(); ResetTrain(); InitShotTargets(); StartBestHitTimer(); } public override void PauseTrain() { base.PauseTrain(); foreach(var timer in generateTargetTimeTasks) { timer.pause = true; } } public override void ContinueTrain() { base.ContinueTrain(); foreach (var timer in generateTargetTimeTasks) { timer.pause = false; } } public override void CalculateTrainResult() { SetResultMetricsDataValue(MetricsType.TimeToKill, Math.Round(TrainInfo.duration / TotalHitNum, 2)); SetResultMetricsDataValue(MetricsType.Kill_Sec, Math.Round(TotalHitNum / TrainInfo.duration, 2)); SetResultMetricsDataValue(MetricsType.Target, totalTargetNum); SetResultMetricsDataValue(MetricsType.KillTotal, TotalHitNum); } #endregion #region TrainResult private void UpdatePrecision() { double totalShot = TotalHitNum + MissHitNum; double precision = 0; if (totalShot != 0) { precision = Math.Round(TotalHitNum / totalShot, 2); } SetResultMetricsDataValue(MetricsType.Precision, precision); } #endregion #region ShootTarget private void OnShottedTargetEvent(BaseShotTarget target) { if (target != null) { int comboS = Mathf.CeilToInt(m_ScoreData.baseScore * comboNums * m_ScoreData.comboMul); int bestS = m_IsBestHit ? Mathf.CeilToInt(m_ScoreData.baseScore * m_ScoreData.bestHitMul) : 0; IncreaseScore(m_ScoreData.baseScore + comboS + bestS); comboNums++; TotalHitNum++; DestroyShootTarget(target as SphereShotTarget); generateTargetTimeTasks.Add(TimerSystem.GetInstance().AddTimeTask(GenerateShotTarget, 0.5f)); StartBestHitTimer(); } else { MissHitNum++; comboNums = 0; int missPunitiveS = Mathf.CeilToInt(m_ScoreData.baseScore * m_ScoreData.missPunitiveMul); IncreaseScore(missPunitiveS * -1); } } #endregion private void InitShotTargets() { for (int i = 0; i < maxTargetNum; i++) { GenerateShotTarget(); } } private void GenerateShotTarget() { GameObject obj = GameObject.Instantiate(Resources.Load("Prefabs/SphereTarget")); SphereShotTarget target = obj.GetComponent(); target.IsRunning = true; target.onClickCanChangeColor = false; target.onHoveringCanChangeColor = false; target.defaultColor = ScreenEffectManager.GetInstance().GetTargetColor(); target.Init(1, ReduceHealthTriggerType.OnClick, false, ReduceHealthType.Per, MotionType.None, RandomPosition()); curTargets.Add(target); totalTargetNum++; } private Vector3 RandomPosition() { List positions = curTargets.GetGameObjectWorldPosition(); Vector2 widthLimt = Vector2.zero; Vector2 heightLimt = Vector2.zero; switch (m_DifficultyType) { case DifficultyType.Standard: widthLimt = new Vector2(-4, 4); heightLimt = new Vector2(-1.5f, 1.5f); break; case DifficultyType.Advance: widthLimt = new Vector2(-8, 8); heightLimt = new Vector2(-1.5f, 3.5f); break; case DifficultyType.Professional: widthLimt = new Vector2(-8, 8); heightLimt = new Vector2(-1.5f, 5f); break; } Vector3 min = ExtraTool.GetScreenOffsetPosition(ExtraTool.Sphere_Diameter1_ScreenLeftBottomOffset, m_DifficultyData.targetDistance, widthLimt, heightLimt); Vector3 max = ExtraTool.GetScreenOffsetPosition(ExtraTool.Sphere_Diameter1_ScreenRightTopOffset, m_DifficultyData.targetDistance, widthLimt, heightLimt); if (ExtraTool.TryGetNonOverlapRamdonPos(positions, min, max, 2, out Vector3 ramdonPos, true)) { return ramdonPos; } else { return new Vector3(0, 0, 25f); } } private void DestroyShootTarget(SphereShotTarget target) { if (target != null) { curTargets.Remove(target); target.IsRunning = false; GameObject.Destroy(target.gameObject); } } private void ResetTarget() { for (int i = 0; i < curTargets.Count; i++) { curTargets[i].IsRunning = false; GameObject.Destroy(curTargets[i].gameObject); } curTargets.Clear(); } } }