备份CatanBuilding瘦身独立工程
This commit is contained in:
329
Assets/Scripts/UI/ShootingRange/ShootingRangeAct.cs
Normal file
329
Assets/Scripts/UI/ShootingRange/ShootingRangeAct.cs
Normal file
@@ -0,0 +1,329 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
public class ShootingRangeAct : AGameAct
|
||||
{
|
||||
private EventShootingRangeData _data;
|
||||
public const int AmmoCost = 1;
|
||||
private WinterShootingRangePanel _mainPanel;
|
||||
private int _clickableCounter;
|
||||
[SerializeField] private List<ShootingRound> stageList;
|
||||
public static IEventAggregator EventAggregator = new EventAggregator();
|
||||
private readonly CompositeDisposable _disposables = new CompositeDisposable();
|
||||
|
||||
/// <summary>
|
||||
/// This method is used in a weird way that Assertion Error can not be caught.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override async System.Threading.Tasks.Task<bool> StartAsync()
|
||||
{
|
||||
// await Awaiters.NextFrame;
|
||||
_clickableCounter = 0;
|
||||
BlockClick();
|
||||
_data = GContext.container.Resolve<EventShootingRangeData>();
|
||||
_data.HasBeenOpened = true;
|
||||
_mainPanel = (await UIManager.Instance.ShowUILoad(UITypes.EventWinterShootingPanel)).GetComponent<WinterShootingRangePanel>();
|
||||
// _mainPanel.Init();
|
||||
GContext.container.Resolve<IDeferredRewardStashService>().Reset();
|
||||
EventAggregator.GetEvent<EventPanelClose>().Subscribe(_ => UnblockClick()).AddTo(_disposables);
|
||||
EventAggregator.GetEvent<EventPanelOpen>().Subscribe(_ => BlockClick()).AddTo(_disposables);
|
||||
EventAggregator.GetEvent<EventRewardPanelClose>().Subscribe(OnRewardPanelClose).AddTo(_disposables);
|
||||
GContext.OnEvent<DeferredRewardStashPanel.EventStashPanelClose>().Subscribe(_ => UnblockClick()).AddTo(_disposables);
|
||||
GContext.OnEvent<DeferredRewardStashPanel.EventStashPanelOpen>().Subscribe(_ => BlockClick()).AddTo(_disposables);
|
||||
ClearStages();
|
||||
GContext.Publish(new EndTransition());
|
||||
// await LoadStageAsync();
|
||||
LoadStage();
|
||||
UnblockClick();
|
||||
GContext.OnEvent<EventShootingRangeDebug>().Subscribe(DebugShootingRange).AddTo(this);
|
||||
return await base.StartAsync();
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_clickableCounter == 0 && Input.GetMouseButtonDown(0))
|
||||
{
|
||||
if (_data.RemainingTime.TotalSeconds <= -5)
|
||||
_mainPanel.OnClickClose();
|
||||
BlockClick();
|
||||
var target = SelectTarget()?.GetComponent<ShootingTarget>();
|
||||
if (!target || _data.IsTargetHit(target.targetIdx))
|
||||
{
|
||||
UnblockClick();
|
||||
return;
|
||||
}
|
||||
|
||||
ShootWithoutDisplay(target.targetIdx, out var rewardIndex, out var rewards);
|
||||
if (rewardIndex == -1)
|
||||
{
|
||||
UnblockClick();
|
||||
return;
|
||||
}
|
||||
|
||||
int eventTrackingHook = rewards.Where(reward => reward.id == 1001).Sum(reward => (int)reward.count);
|
||||
/*
|
||||
Debug.Log($"<color=#fe231b>Event tracking:</color>");
|
||||
Debug.Log($"<color=#fe231b> round: {_data.RoundCount + 1}</color>");
|
||||
Debug.Log($"<color=#fe231b> stage: {_data.CurrentStageIdx + 1}</color>");
|
||||
Debug.Log($"<color=#fe231b> target: {_data.GetHitTargetCount()}</color>");
|
||||
Debug.Log($"<color=#fe231b> is_over: {(rewardIndex == 0 ? 1 : 0)}</color>");
|
||||
Debug.Log($"<color=#fe231b> drop_list: {_data.CurrentStage.DropId[rewardIndex]}</color>");
|
||||
Debug.Log($"<color=#fe231b> reward_hook: {eventTrackingHook}</color>");
|
||||
Debug.Log($"<color=#fe231b> combine_id: {(_data.RoundCount + 1) * 10000 + (_data.CurrentStageIdx + 1) * 100 + _data.GetHitTargetCount()}</color>");
|
||||
*/
|
||||
#if AGG
|
||||
using (var e = GEvent.GameEvent("event_shooting"))
|
||||
{
|
||||
e.AddContent("round", _data.RoundCount + 1)
|
||||
.AddContent("stage", _data.CurrentStageIdx + 1)
|
||||
.AddContent("target", _data.GetHitTargetCount())
|
||||
.AddContent("is_over", rewardIndex == 0 ? 1 : 0)
|
||||
.AddContent("drop_list", _data.CurrentStage.DropId[rewardIndex])
|
||||
.AddContent("reward_hook", eventTrackingHook)
|
||||
.AddContent("combine_id",
|
||||
(_data.RoundCount + 1) * 10000 + (_data.CurrentStageIdx + 1) * 100 + _data.GetHitTargetCount());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (Input.GetKeyDown(KeyCode.R))
|
||||
{
|
||||
_data.ResetData();
|
||||
}
|
||||
#endif
|
||||
bool isFinal = _data.IsFinalStage;
|
||||
if (rewardIndex == 0)
|
||||
_data.SwitchToNextStage();
|
||||
_data.UploadData();
|
||||
Display(target, rewardIndex == 0, isFinal, rewards);
|
||||
}
|
||||
}
|
||||
|
||||
/*public static void SubscribeEvent<T>(T e, Action<T> a)
|
||||
{
|
||||
EventAggregator.GetEvent<T>().Subscribe(a).AddTo(Disposables);
|
||||
}*/
|
||||
|
||||
private void ClearStages()
|
||||
{
|
||||
Assert.IsTrue(_data.CurrentStageIdx >= 0 && _data.CurrentStageIdx < stageList.Count,
|
||||
$"Stage index {_data.CurrentStageIdx} is out of range {stageList.Count}");
|
||||
Debug.Log("Load Stage start.");
|
||||
foreach (var stage in stageList)
|
||||
{
|
||||
stage.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task LoadStageAsync()
|
||||
{
|
||||
await stageList[_data.CurrentStageIdx].ShowAsync();
|
||||
}
|
||||
|
||||
private void LoadStage()
|
||||
{
|
||||
stageList[_data.CurrentStageIdx].Show();
|
||||
}
|
||||
|
||||
private GameObject SelectTarget()
|
||||
{
|
||||
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
if (Physics.Raycast(ray, out var hit) && hit.collider.CompareTag("ShootingTarget"))
|
||||
return hit.collider.gameObject;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ShootWithoutDisplay(int targetIdx, out int rewardIdx, out List<ItemData> rewards)
|
||||
{
|
||||
rewardIdx = -1;
|
||||
rewards = null;
|
||||
/*if (_data.IsGameDepleted)
|
||||
{
|
||||
Debug.Log("Game depleted.");
|
||||
return;
|
||||
}*/
|
||||
if (_data.AmmoCount < AmmoCost)
|
||||
{
|
||||
Debug.Log("Not enough ammo.");
|
||||
// _mainPanel.ShowAmmoTip();
|
||||
_mainPanel.OnClickSupply();
|
||||
return;
|
||||
}
|
||||
_data.AddAmmo(-AmmoCost);
|
||||
var processedWeightList = _data.CurrentStage.Weight.Select((w, i) => _data.IsRewardCollected(i) ? 0 : w).ToList();
|
||||
processedWeightList[0] = _data.IsGrandPrizeAllowed ? processedWeightList[0] : 0;
|
||||
rewardIdx = _data.PickRandomIndex(processedWeightList);
|
||||
// Debug.Log($"Got reward No.{rewardIdx}, dropId {_data.CurrentStage.DropId[rewardIdx]}.");
|
||||
rewards = GContext.container.Resolve<PlayerItemData>()
|
||||
.GetItemDataByDropId(_data.CurrentStage.DropId[rewardIdx]);
|
||||
foreach (var reward in rewards)
|
||||
{
|
||||
if (reward.id != _data.CycleItem.ItemId)
|
||||
GContext.Publish(new DeferredRewardStashService.EventStashItem { Item = reward });
|
||||
else
|
||||
GContext.container.Resolve<PlayerItemData>().AddItem(reward);
|
||||
}
|
||||
_data.SetRewardCollected(rewardIdx);
|
||||
_data.SetTargetHit(targetIdx);
|
||||
}
|
||||
|
||||
[Tooltip("开镜动画出现延迟")][SerializeField] private float jiandaAimDelay;
|
||||
[Tooltip("靶子碎裂延迟")][SerializeField] private float jiandaTargetBreakDelay;
|
||||
[Tooltip("过关面板出现延迟")][SerializeField] private float jiandaRewardPanelPopupDelay;
|
||||
[Tooltip("切换关卡延迟")][SerializeField] private float jiandaSwitchStageDelay;
|
||||
|
||||
[Tooltip("奖励出现并飞入延迟")]
|
||||
[SerializeField]
|
||||
private float jiandaRewardFlyDelay;
|
||||
|
||||
[Tooltip("雪人出现延迟")][SerializeField] private float jiandaSnowManPopupDelay;
|
||||
|
||||
[Tooltip("允许面板操作的延迟,从点击开始")]
|
||||
[SerializeField]
|
||||
private float jiandaUnblockDelay = 2.1f;
|
||||
|
||||
[Tooltip("奖励出现时,相对于靶子的,奖励位置偏移")]
|
||||
[SerializeField]
|
||||
private Vector2 jiandaRewardPositionOffset = new Vector2(0, 0);
|
||||
|
||||
private void Display(ShootingTarget target, bool needSwitchStage, bool isFinalStage,
|
||||
List<ItemData> rewards)
|
||||
{
|
||||
if (needSwitchStage && rewards is null)
|
||||
{
|
||||
Debug.LogWarning($"Empty grand prize.");
|
||||
return;
|
||||
}
|
||||
|
||||
_mainPanel.UpdateAmmoCount(AmmoCost);
|
||||
// var localHitPosition = _mainPanel.GetUiHitPosition(target.gameObject);
|
||||
var localHitPosition = UIManager.Instance.WorldToScreen(target.transform.position);
|
||||
_ = _mainPanel.ShowCrosshairAfterDelay(localHitPosition, jiandaAimDelay);
|
||||
_ = target.PlayBreakAnimationWithDelay(jiandaTargetBreakDelay);
|
||||
if (needSwitchStage)
|
||||
{
|
||||
_ = _mainPanel.ShowSnowmanAfterDelay(localHitPosition + jiandaRewardPositionOffset, jiandaSnowManPopupDelay);
|
||||
_ = ShowRewardPopupWithDelay(rewards, isFinalStage, jiandaRewardPanelPopupDelay);
|
||||
// Will unblock when panel is closed!
|
||||
// Will receive event when panel is closed.
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaUnblockDelay))
|
||||
.ContinueWith(_ => UnblockClick());
|
||||
_ = _mainPanel.PlayRewardFlyWithDelay(rewards[0], localHitPosition + jiandaRewardPositionOffset, jiandaRewardFlyDelay);
|
||||
// UnblockClick();
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task ShowRewardPopupWithDelay(List<ItemData> rewards, bool doesShowFinal,
|
||||
float delay)
|
||||
{
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(delay));
|
||||
var finalRewardPopup = (await UIManager.Instance.ShowUI(UITypes.ShootingRangeFinalRewardPopup))
|
||||
.GetComponent<ShootingRangeFinalRewardPopupPanel>();
|
||||
finalRewardPopup.Init(rewards, doesShowFinal);
|
||||
}
|
||||
|
||||
private void OnRewardPanelClose(EventRewardPanelClose e)
|
||||
{
|
||||
BlockClick();
|
||||
|
||||
if (e.IsFinalStage)
|
||||
{
|
||||
_mainPanel.OnClickClose();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = _mainPanel.MoveSnowmanAfterDelayAndUpdateTarget(0f);
|
||||
for (int i = 0; i < e.Rewards.Length; i++)
|
||||
{
|
||||
_ = _mainPanel.PlayRewardFlyWithDelay(e.Rewards[i], e.RewardPositionList[i], 0f);
|
||||
}
|
||||
_ = SwitchStageWithDelay(jiandaSwitchStageDelay);
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task SwitchStageWithDelay(float delay)
|
||||
{
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(delay));
|
||||
ClearStages();
|
||||
var panel = await UIManager.Instance.ShowUI(UITypes.ShootingRangeTransitionPanel);
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(0.8f));
|
||||
_mainPanel.UpdateAmmoCount();
|
||||
_mainPanel.SetRewards();
|
||||
panel.GetComponent<CloudTransitionPanel>().EndTransition(new EndTransition());
|
||||
// await LoadStageAsync();
|
||||
LoadStage();
|
||||
UnblockClick();
|
||||
}
|
||||
|
||||
private void LogRewardState()
|
||||
{
|
||||
Debug.Log("Checking reward status.");
|
||||
for (int i = 0; i < _data.CurrentStage.DropId.Count; i++)
|
||||
{
|
||||
Debug.Log($" Reward {i}: {_data.IsRewardCollected(i)}");
|
||||
}
|
||||
// Debug.Log();
|
||||
}
|
||||
|
||||
private void BlockClick()
|
||||
{
|
||||
_clickableCounter++;
|
||||
// Debug.Log($"<color=#a6a6a6>Block to: {_clickableCounter}.</color>");
|
||||
}
|
||||
|
||||
private void UnblockClick()
|
||||
{
|
||||
_clickableCounter--;
|
||||
// Debug.Log($"<color=#a6a6a6>Unblock to: {_clickableCounter}.</color>");
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
RedPointManager.Instance.SetRedPointState(EventShootingRangeData.EntranceRedPointId,
|
||||
_data.DoNeedEntranceRedPoint);
|
||||
_disposables?.Dispose();
|
||||
Debug.Log("Exit ShootingRangeAct.");
|
||||
// GContext.container.Resolve<IDeferredRewardStashService>().Flush();
|
||||
}
|
||||
|
||||
public class EventPanelClose
|
||||
{
|
||||
}
|
||||
|
||||
public class EventPanelOpen
|
||||
{
|
||||
}
|
||||
|
||||
public class EventRewardPanelClose
|
||||
{
|
||||
public bool IsFinalStage;
|
||||
public ItemData[] Rewards;
|
||||
public Vector2[] RewardPositionList;
|
||||
}
|
||||
|
||||
public class EventAmmoBought
|
||||
{
|
||||
}
|
||||
|
||||
private void DebugShootingRange(EventShootingRangeDebug e)
|
||||
{
|
||||
_data.SwitchToStage(e.StageIdx);
|
||||
ClearStages();
|
||||
_ = LoadStageAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public class EventShootingRangeDebug
|
||||
{
|
||||
public int StageIdx;
|
||||
}
|
||||
Reference in New Issue
Block a user