using ProjectBase.Event; using ShotSimulator.Event; using ShotSimulator.Target; using ShotSimulator.Train.Info; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace ShotSimulator.Train { public abstract class BaseTrainHandle { private BaseTrainCallBack m_TrainCallBack; private BaseTrainInfo m_TrainInfo; private BaseFirearmData m_FirearmData; public TrainTaskFinishType m_TrainTaskFinishType; public TimeTask m_TaskTimer; private int currentNumber; public int CurrentNumber { get { return currentNumber; } protected set { currentNumber = value; if(TrainInfo != null&& TrainInfo.finishType == TrainTaskFinishType.Number) { ExecutingTrainEventData data = new ExecutingTrainEventData() { maxNumber = TrainInfo.maxNumber, currentNumber = CurrentNumber }; EventCenter.GetInstance().RunEvent(EventKey.OnExecutingTrainDataUpdated, data); if (CurrentNumber <= 0) { CompleteTrain(); } } } } private TrainResultData m_TrainResult; public DifficultyType m_DifficultyType; private int Score; private TimeTask m_BestHitTimer; protected bool m_IsBestHit; protected int comboNums; public BaseTrainInfo TrainInfo { private set { m_TrainInfo = value; } get { return m_TrainInfo; } } public bool IsRunning { protected set; get; } public bool IsComplete { protected set; get; } public bool IsPause { protected set; get; } private bool m_IsChambered; protected float separationMagazineTime; public int m_MagazineBulletNums; public int MagazineBulletNums { protected set { m_MagazineBulletNums = value; OnBulletNumsChanged(); } get { return m_MagazineBulletNums; } } public bool IsChambered { set { m_IsChambered = value; OnChamberStateUpdated(); } get { return m_IsChambered; } } public BaseFirearmData FirearmData { protected set { m_FirearmData = value; } get { return m_FirearmData; } } private Dictionary> m_InteractiveEvents = new Dictionary>(); #region Init public BaseTrainHandle(BaseTrainCallBack callBack, BaseTrainInfo info, DifficultyType difficultyType) { this.m_TrainCallBack = callBack; this.TrainInfo = info; m_TrainTaskFinishType = info.finishType; m_DifficultyType = difficultyType; m_TrainResult = new TrainResultData(TrainInfo.metrics); } public void InitGunData(BaseFirearmData gunData) { FirearmData = gunData; } #endregion #region Train protected abstract void ResetTrain(); public virtual void PrepareTrain() { IsRunning = false; IsComplete = false; IsPause = false; CurrentNumber = TrainInfo.maxNumber; m_TrainResult.ResetMetricsDataValue(); Score = 0; TimerSystem.GetInstance().RemoveTimeTask(m_BestHitTimer); m_BestHitTimer = null; m_IsBestHit = false; comboNums = 0; TimerSystem.GetInstance().RemoveTimeTask(m_TaskTimer); ResetTrain(); TriggerTrainEvent(TrainEventType.OnPrepare); } public virtual void StartTrain() { IsRunning = true; TimerSystem.GetInstance().RemoveTimeTask(m_TaskTimer); switch (m_TrainTaskFinishType) { case TrainTaskFinishType.Time: m_TaskTimer = TimerSystem.GetInstance().AddTimeTask(CompleteTrain, TrainInfo.duration); break; default: m_TaskTimer = TimerSystem.GetInstance().AddTimeTask(null, 60 * 60 * 5); break; } if (TrainInfo.m_TrainFirearmConfig.isNeedConsumeBullet) { if (TrainInfo.m_TrainFirearmConfig.DontApplyFirearmConfig) { MagazineBulletNums = TrainInfo.m_TrainFirearmConfig.magazineCapacity; } else { MagazineBulletNums = FirearmData.magazineCapacity; } } if (FirearmData.needChambered) { IsChambered = true; } TriggerTrainEvent(TrainEventType.OnStartTrain); if (TrainInfo.bgm) { SoundManager.GetInstance().PlayBGM("Audio/音效/背景音效/bgm1"); } else { SoundManager.GetInstance().StopBGM(); } } public virtual void PauseTrain() { IsPause = true; if (m_TaskTimer != null) { m_TaskTimer.pause = true; } if (m_BestHitTimer != null) { m_BestHitTimer.pause = true; } TriggerTrainEvent(TrainEventType.OnPauseTrain); } public virtual void ContinueTrain() { IsPause = false; if (m_TaskTimer != null) { m_TaskTimer.pause = false; } if (m_BestHitTimer != null) { m_BestHitTimer.pause = false; } TriggerTrainEvent(TrainEventType.OnContinueTrain); } public virtual void CompleteTrain() { CalculateTrainResult(); IsRunning = false; IsComplete = true; m_TaskTimer = null; ResetTrain(); TriggerTrainEvent(TrainEventType.OnCompleteTrain); SoundManager.GetInstance().StopBGM(); } public virtual void ExitTrain() { IsRunning = false; IsComplete = false; TimerSystem.GetInstance().RemoveTimeTask(m_TaskTimer); m_TaskTimer = null; ResetTrain(); m_TrainResult.ResetMetricsDataValue(); TriggerTrainEvent(TrainEventType.OnExitTrain); SoundManager.GetInstance().StopBGM(); } #endregion #region ShotTarget protected void SetShotTargetInteractiveEvent(ShotTargetInteractiveType type, Action action) { if(m_InteractiveEvents.TryGetValue(type, out var value)) { value = action; } else { m_InteractiveEvents.Add(type, action); } } protected void TriggerShotTargetInteractiveEvent(ShotTargetInteractiveType type, BaseShotTarget target) { if (m_InteractiveEvents.TryGetValue(type, out var action)) { if (action != null) { action(target); } } } public void OnEnteredTarget(BaseShotTarget target) { if (!IsRunning) return; if (target != null) { target.OnEnter(); } TriggerShotTargetInteractiveEvent(ShotTargetInteractiveType.OnEnter, target); } public void OnHoveringTarget(BaseShotTarget target) { if (!IsRunning || IsPause) return; if (target != null) { target.OnHovering(); } TriggerShotTargetInteractiveEvent(ShotTargetInteractiveType.OnHovering, target); } public void OnShottedTarget(BaseShotTarget target, Vector2 ShotScreenPos) { if (!IsRunning || IsPause) return; if (TrainInfo.m_TrainFirearmConfig.isNeedConsumeBullet && MagazineBulletNums <= 0) { SoundManager.GetInstance().PlaySoundEffect("Audio/音效/手枪格洛克没子弹", false); EventCenter.GetInstance().RunEvent(EventKey.OnShootWitchEmptyBullets, null); return; } if (FirearmData.needChambered) { if (!IsChambered) { EventCenter.GetInstance().RunEvent(EventKey.OnShootWitchChamberEmpty, null); return; } } if (TrainInfo.m_TrainFirearmConfig.isNeedConsumeBullet) { MagazineBulletNums--; } SoundManager.GetInstance().PlaySoundEffect("Audio/音效/手枪格洛克射击1", false); if (target != null) { target.OnClick(); } else { GameObject emptyEffect = GameObject.Instantiate(Resources.Load("UnityTechnologies/EffectExamples/WeaponEffects/Prefabs/BulletImpactStoneEffect")); emptyEffect.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(ShotScreenPos.x, ShotScreenPos.y, 5f)); } TriggerShotTargetInteractiveEvent(ShotTargetInteractiveType.OnClick, target); //if (m_TrainTaskFinishType == TrainTaskFinishType.BulletNums) //{ // if (MagazineBulletNums <= 0) // { // CompleteTrain(); // } //} } public void OnExitedTarget(BaseShotTarget target) { if (!IsRunning || IsPause) return; if (target != null) { target.OnExit(); } TriggerShotTargetInteractiveEvent(ShotTargetInteractiveType.OnExit, target); } public void OnNotEnteringTarget(BaseShotTarget target) { if (!IsRunning || IsPause) return; TriggerShotTargetInteractiveEvent(ShotTargetInteractiveType.OnNotEntering, null); } private void TriggerTrainEvent(TrainEventType type) { if (m_TrainCallBack != null) { m_TrainCallBack.TriggerTrainEvent(type, this); } } #endregion #region Magazine public virtual void SeparationMagazine() { separationMagazineTime = m_TaskTimer.remainingTime; MagazineStateEventData data = new MagazineStateEventData() { state = MagazineState.Separation, }; EventCenter.GetInstance().RunEvent(EventKey.OnMagazineStateChanged, data); } public virtual void ReloadMagazine() { if (TrainInfo.m_TrainFirearmConfig.isNeedConsumeBullet) { if (MagazineBulletNums < FirearmData.magazineCapacity) { if (TrainInfo.m_TrainFirearmConfig.unlimitedMagazine) { if (TrainInfo.m_TrainFirearmConfig.DontApplyFirearmConfig) { MagazineBulletNums = TrainInfo.m_TrainFirearmConfig.magazineCapacity; } else { MagazineBulletNums = FirearmData.magazineCapacity; } } } SoundManager.GetInstance().PlaySoundEffect("Audio/音效/装卸弹匣", false); } MagazineStateEventData data = new MagazineStateEventData() { state = MagazineState.ReLoad, reloadedTime = separationMagazineTime - m_TaskTimer.remainingTime }; EventCenter.GetInstance().RunEvent(EventKey.OnMagazineStateChanged, data); } private void OnBulletNumsChanged() { if (MagazineBulletNums == 0) { IsChambered = false; } BulletNumsEventData data = new BulletNumsEventData() { magazineBulletNums = MagazineBulletNums, magazineCapacity = TrainInfo.m_TrainFirearmConfig.DontApplyFirearmConfig ? TrainInfo.m_TrainFirearmConfig.magazineCapacity : FirearmData.magazineCapacity }; EventCenter.GetInstance().RunEvent(EventKey.OnBulletNumsChanged, data); } #endregion #region Chamber private void OnChamberStateUpdated() { ChamberStateEventData data = new ChamberStateEventData() { IsChambered = this.IsChambered }; EventCenter.GetInstance().RunEvent(EventKey.OnChamberStateUpdated, data); if (IsChambered) { SoundManager.GetInstance().PlaySoundEffect("Audio/音效/上膛", false); } } #endregion #region TrainResult public TrainResultData GetTrainResultData() { return m_TrainResult; } public abstract void CalculateTrainResult(); protected void IncreaseScore(int value) { Score += value; if (Score < 0) { Score = 0; } SetResultMetricsDataValue(MetricsType.Score, Score); } public void SetResultMetricsDataValue(MetricsType type, double value) { if(m_TrainResult.SetMetricsDataValue(type, value)) { TrainResultEventData data = new TrainResultEventData() { type = type, value = value }; try { EventCenter.GetInstance().RunEvent(EventKey.OnTrainResultMetricsDataUpdated, data); } catch(Exception e) { Debug.LogException(e); } } } protected void StartBestHitTimer() { TimerSystem.GetInstance().RemoveTimeTask(m_BestHitTimer); m_IsBestHit = true; m_BestHitTimer = TimerSystem.GetInstance().AddTimeTask(() => { m_IsBestHit = false; }, 0.8f); } #endregion } }