Files
ft/Client/Assets/Scripts/EventBossFight/Data/EventBossFightManager.cs
2026-06-29 21:18:33 +08:00

961 lines
36 KiB
C#
Raw Permalink 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.Generic;
using System.Linq;
using System.Threading.Tasks;
using asap.core;
using cfg;
using game;
using GameCore;
using Newtonsoft.Json.Linq;
using UI.Wheel;
using UnityEngine;
using Random = UnityEngine.Random;
namespace EventBossFight
{
public class EventBossFightManager:AEventDataManager<EventBossFightData>
{
protected override int EventType => 4;
protected override int EventSubType => 12;
protected override void RefreshData(int eventId)
{
var fishingEvent = Tables.TbFishingEvent.GetOrDefault(eventId);
if (fishingEvent == null) return;
var cacheData = GetCacheData();
if (cacheData != null && cacheData.EventID == eventId)
{
Data.SetData(cacheData);
TryResolveBossFightStageGroupIfNeeded();
SetRedPoint();
return;
}
InitData(eventId);
SetRedPoint();
}
protected override void InitData(int eventId)
{
base.InitData(eventId);
//ClearGuidance();
ResolveBossFightStageGroupAtActivityStart();
Data.BossFightPaidReviveCount = 0;
Data.BossFightAwaitingPaidRevive = false;
InitStageData();
Data.PendingFightBootstrap = false;
var welcomeGift = GContext.container.Resolve<FishingEventData>().GetInitWelcomeGift(eventId);
AddToken(welcomeGift);
SaveData();
}
#region Rewards
public int GetFinalBossRewardsDropID()
{
var lastStage = GetLastStage();
if (lastStage != null) return lastStage.DropId;
Debug.LogError($"[EventBossFightManager]GetFinalBossRewards: lastStage is null");
return 0;
}
public List<ItemData> GetFinalBossRewards()
{
var dropId= GetFinalBossRewardsDropID();
return GContext.container.Resolve<PlayerItemData>()
.GetItemDataByDropIdAndTypeLureInflation(Data.InflationRate, dropId);
}
public List<ItemData> GetBossRewards()
{
return GContext.container.Resolve<PlayerItemData>()
.GetItemDataByDropIdAndTypeLureInflation(Data.InflationRate, Data.StageConfig.DropId);
}
public string GetSpinType(int spinPointID)
{
var spinPointConfig = Tables.TbEventBossFightSpinPoints.GetOrDefault(spinPointID);
if (spinPointConfig == null || Data == null) return string.Empty;
return spinPointConfig.SpinType;
}
public void GetDropItemInfo(int spinPointID, out string iconName, out string textNum)
{
iconName = textNum = string.Empty;
var spinPointConfig = Tables.TbEventBossFightSpinPoints.GetOrDefault(spinPointID);
if (spinPointConfig == null || Data == null) return;
iconName = spinPointConfig.Icon ?? string.Empty;
textNum =ConvertTools.GetNumberString (spinPointConfig.EffectValue * Data.Magnification);
}
/// <summary>
/// 没有禁止magnification set 所以从外面传参进来
/// </summary>
public void UseDropItem(int spinPointID,int magnification,out int convertTokenCount,out int addAmount)
{
addAmount = 0;
convertTokenCount = 0;
var spinPointConfig = Tables.TbEventBossFightSpinPoints.GetOrDefault(spinPointID);
switch (spinPointConfig.SpinType)
{
case nameof(EEventBossFightSpinType.Cure):
PlayerRevertHp(spinPointConfig,magnification,out convertTokenCount,out addAmount);
break;
case nameof(EEventBossFightSpinType.Shield):
PlayerAddShield(spinPointConfig,magnification,out convertTokenCount,out addAmount);
break;
case nameof(EEventBossFightSpinType.AttackTier1):
case nameof(EEventBossFightSpinType.AttackTier2):
PlayerAttack(spinPointConfig,magnification);
break;
}
SaveData();
}
#endregion
#region Wheel
private List<IWheelReward> _rewards = new List<IWheelReward>();
public List<IWheelReward> GetWheelRewards()
{
if (Data?.InitConfig == null) return null;
if (_rewards == null)
_rewards = new List<IWheelReward>();
else
_rewards.Clear();
foreach (var id in Data.InitConfig.SpinPointList)
{
var rewardConfig = Tables.TbEventBossFightSpinPoints.Get(id);
if (rewardConfig == null
|| _rewards.Find(x => x.Index == rewardConfig.ID) != null)
continue;
_rewards.Add(new EventBossFightWheelRewardAdapter(rewardConfig,Data.InflationRate));
}
CalculateWeights();
return _rewards;
}
// 缓存数据
private int _totalWeight = 0;
private readonly List<int> _weightRanges = new List<int>();
private void CalculateWeights()
{
_totalWeight = _rewards.Sum(r => r.Weight);
BuildWeightRanges();
}
private void BuildWeightRanges()
{
_weightRanges.Clear();
var currentWeight = 0;
foreach (var reward in _rewards)
{
currentWeight += reward.Weight;
_weightRanges.Add(currentWeight);
}
}
// 根据权重随机获取奖励
public int GetRandomRewardIndex()
{
if (_totalWeight <= 0)
{
Debug.LogError("总权重为0");
return 0;
}
var randomValue = Random.Range(0, _totalWeight);
for (int i = 0; i < _weightRanges.Count; i++)
{
if (randomValue < _weightRanges[i])
{
return i;
}
}
return _rewards.Count - 1;
}
#endregion
#region Stage
/// <summary>本周期关卡 id 列表(体力分档后取自 <see cref="EventBossFightInit.StageGroupList"/> 或回退 <see cref="EventBossFightInit.StageList"/>)。</summary>
public IReadOnlyList<int> GetResolvedStageIds() => Data.GetResolvedStageIdList();
/// <summary>
/// 根据活动开始时玩家体力与 <see cref="EventBossFightInit.TargetGroupByHook"/>(升序门槛,如 0、100、200
/// 取最大满足 <c>energy &gt;= hook[i]</c> 的下标 i无满足时返回 0。
/// </summary>
public static int ResolveStageGroupIndexByEnergy(int energy, IList<int> targetGroupByHook)
{
if (targetGroupByHook == null || targetGroupByHook.Count == 0)
return 0;
var best = -1;
for (var i = 0; i < targetGroupByHook.Count; i++)
{
if (energy >= targetGroupByHook[i])
best = i;
}
return best < 0 ? 0 : best;
}
void ResolveBossFightStageGroupAtActivityStart()
{
ApplyBossFightStageGroupResolution(saveAfter: false);
}
void TryResolveBossFightStageGroupIfNeeded()
{
if (Data.BossFightStageGroupLocked)
return;
ApplyBossFightStageGroupResolution(saveAfter: true);
}
void ApplyBossFightStageGroupResolution(bool saveAfter)
{
var init = Data.InitConfig;
if (init == null)
return;
var energy = (int)GContext.container.Resolve<PlayerData>().Energy;
if (init.StageGroupList == null || init.StageGroupList.Count == 0
|| init.TargetGroupByHook == null || init.TargetGroupByHook.Count == 0)
{
Data.BossFightStageGroupIndex = 0;
Data.BossFightHookEnergySnapshot = energy;
Data.BossFightStageGroupLocked = true;
if (saveAfter)
SaveData();
return;
}
var tier = ResolveStageGroupIndexByEnergy(energy, init.TargetGroupByHook);
tier = Mathf.Clamp(tier, 0, init.StageGroupList.Count - 1);
if (init.StageGroupList[tier] == null || init.StageGroupList[tier].Count == 0)
{
Debug.LogWarning($"[EventBossFight] StageGroupList[{tier}] 为空,尝试使用首个非空分组或回退 StageList");
tier = 0;
for (var g = 0; g < init.StageGroupList.Count; g++)
{
if (init.StageGroupList[g] != null && init.StageGroupList[g].Count > 0)
{
tier = g;
break;
}
}
}
Data.BossFightStageGroupIndex = tier;
Data.BossFightHookEnergySnapshot = energy;
Data.BossFightStageGroupLocked = true;
if (saveAfter)
SaveData();
}
private EventBossFightStage GetLastStage()
{
var ids = GetResolvedStageIds();
if (ids == null || ids.Count == 0)
{
Debug.LogError($"[EventBossFightManager]GetLastStage: resolved stage list empty");
return Tables.TbEventBossFightStage.GetOrDefault(0);
}
return Tables.TbEventBossFightStage.GetOrDefault(ids[ids.Count - 1]);
}
public EventBossFightStage GetPreviousStage()
{
var ids = GetResolvedStageIds();
if (ids == null || ids.Count == 0)
return Tables.TbEventBossFightStage.GetOrDefault(0);
var index =Data.StageCountFrom1==1?ids.Count-1: Data.StageCountFrom1 - 2;
var id=ids[index];
return Tables.TbEventBossFightStage.GetOrDefault(id);
}
/// <summary>
/// 引导关闭等需要强制把当前关血量拉回表初始值时使用(不判断 Pending 标记)。
/// </summary>
void BootstrapFightFullReset()
{
Data.PendingFightBootstrap = false;
Data.BossFightAwaitingPaidRevive = false;
Data.BossFightPaidReviveCount = 0;
InitStageData();
}
/// <summary>
/// 主界面 <see cref="EventBossFightMainPanel.CheckStageState"/>:仅当需要「回满当前关」时执行(例如无 IAP 阵亡后已回第一关再进界面)。
/// </summary>
public void ApplyPendingFightBootstrapIfNeeded()
{
if (!Data.PendingFightBootstrap)
return;
BootstrapFightFullReset();
SaveData();
}
public async void StartNewStageFight()
{
try
{
Data.IsRest = false;
Data.PendingFightBootstrap = false;
if (!TryStartNewRound())
{
InitStageData();
SaveData();
}
UITypes.EventBossFightLoadingPanel.SetType(Data.InitConfig.LoadingPanel);
await UIManager.Instance.ShowUILoad(UITypes.EventBossFightLoadingPanel);
var reviewPanel = UIManager.Instance.GetContainedUI(UITypes.EventBossFightReviewPopupPanel);
if (reviewPanel != null)
_= reviewPanel.GetComponent<EventBossFightReviewPanel>().ClosePanel();
var mainPanel= UIManager.Instance.GetContainedUI(UITypes.EventBossFightPanel);
if (mainPanel)
mainPanel.GetComponent<EventBossFightMainPanel>().OnStart();
else
await UIManager.Instance.ShowUI(UITypes.EventBossFightPanel);
GContext.Publish(new EndTransition());
}
catch (Exception e)
{
Debug.LogError($"jsd StartFight {e.Message}");
}
}
public void RestFight()
{
Data.IsRest = true;
InitStageData();
SaveData();
EventBossFightActTransition.PublishSwitchToFishing(Data?.InitConfig);
}
public bool TryStartNewRound(bool isInitData=true)
{
var stageIds = GetResolvedStageIds();
if (stageIds == null || stageIds.Count == 0 || Data.StageCountFrom1 <= stageIds.Count) return false;
Data.StageCountFrom1 = 1;
Data.RoundCountFrom1++;
Data.BossFightPaidReviveCount = 0;
Data.BossFightAwaitingPaidRevive = false;
if(isInitData)
InitStageData();
SaveData();
return true;
}
private void ResetStageProgress()
{
Data.StageCountFrom1 = 1;
Data.PendingFightBootstrap = true;
Data.BossFightAwaitingPaidRevive = false;
SaveData();
}
private void InitStageData()
{
Data.PlayerRemainHp = Data.StageConfig.PlayerHP;
Data.BossRemainHp = Data.StageConfig.BossHP;
Data.IsShowTips = true;
BossAttackTimeRefresh();
}
public void CheckStageIsMax()
{
var stageIds = GetResolvedStageIds();
if (stageIds != null && Data.StageCountFrom1 > stageIds.Count)
TryStartNewRound();
}
public bool CheckStageBossStateNoRewardPanel()
{
if (Data.BossRemainHp != 0) return false;
Data.IsRest = true;
if (!TryStartNewRound(false))
{
InitStageData();
SaveData();
}
return true;
}
public void CheckStageBossState()
{
if(CheckStageBossStateNoRewardPanel())
ShowRewardPanel();
}
public void CheckStagePlayerState()
{
if (Data.PlayerRemainHp != 0) return;
ShowEndPanel();
}
#endregion
#region boss
public bool TryBossAttack(out bool isReduceShield,out bool isReducePlayerHp,bool isRemainOnceAttack,out int lastDamage)
{
lastDamage = 0;
isReduceShield = false;
isReducePlayerHp = false;
if (IsAwaitingPaidRevive())
return false;
if(Data.IsRest)return false;
var nowSeconds = new DateTimeOffset(ZZTimeHelper.UtcNow()).ToUnixTimeSeconds();
if (nowSeconds < Data.BossAttackTime) return false;
var count=(nowSeconds-Data.BossAttackTime)/Data.StageConfig.AttackInterval+1;
//这些是离线挂机回来的逻辑
if (isRemainOnceAttack && count > 0)
{
int backupHp = Data.PlayerRemainHp;
int backupShield = Data.PlayerShieldCount;
Data.PlayerHpBeforeLastAttack = backupHp;
for (int i = 0; i < count; i++)
{
Debug.Log($"SimulateBossAttack start {i} backupHp {backupHp} backupShield {backupShield}");
if (SimulateBossAttack(backupHp, backupShield, out int newHp, out int newShield, out int damage))
{
Data.LastAttackDamage = damage;
Debug.Log($"SimulateBossAttack start {i} backupHp {backupHp} backupShield {backupShield} FatalAttackDamage {damage}");
Data.HasPendingLastAttack = true;
Data.PlayerRemainHp = 0;
Data.PlayerShieldCount=0;
SaveData();
return true;
}
backupHp = newHp;
backupShield = newShield;
Data.PlayerHpBeforeLastAttack = backupHp;
if(i == count-1)
{
Data.LastAttackDamage = damage;
if(damage==0)
Data.PlayerShieldBeforeLastAttack = backupShield+1;
Debug.Log($"SimulateBossAttack last attack start {i} backupHp {backupHp} backupShield {backupShield} FatalAttackDamage {damage}");
Data.HasPendingLastAttack = true;
Data.PlayerRemainHp = backupHp;
Data.PlayerShieldCount = backupShield;
SaveData();
return true;
}
Debug.Log($"SimulateBossAttack end {i} backupHp {backupHp} backupShield {backupShield}");
}
}
//这里是在线逻辑基本上就是1次
for (var i = 0; i < count; i++)
BossAttack(ref isReduceShield,ref isReducePlayerHp,!isRemainOnceAttack,out lastDamage);
SaveData();
return true;
}
/// <summary>
/// 执行待播放的致命攻击,返回是否减盾和是否减血
/// </summary>
public bool ExecutePendingLastAttack(out bool isReduceShield,out bool isReducePlayerHp,out int damage)
{
damage = 0;
isReduceShield = isReducePlayerHp = false;
if (!Data.HasPendingLastAttack )
return false;
// 标记已处理
if (Data.LastAttackDamage == 0)
isReduceShield = true;
else
isReducePlayerHp = true;
Data.PlayerHpBeforeLastAttack = 0;
Data.PlayerShieldBeforeLastAttack = 0;
Data.HasPendingLastAttack = false;
damage = Data.LastAttackDamage;
Data.PlayerRemainHp -= Data.LastAttackDamage;
Data.LastAttackDamage = 0;
CheckPlayIsDead();
BossAttackTimeRefresh();
SaveData();
return true;
}
/// <summary>
/// 正常情况下每次应该只执行一次
/// </summary>
/// <param name="isReduceShield"></param>
/// <param name="isReducePlayerHp"></param>
/// <param name="isRefreshTime"></param>
private void BossAttack(ref bool isReduceShield,ref bool isReducePlayerHp,bool isRefreshTime,out int damage)
{
damage=0;
if (Data.PlayerShieldCount > 0)
{
Data.PlayerShieldCount --;
if(!isReduceShield)
isReduceShield = true;
}
else
{
damage = GetBossAttackDamage(Data.StageConfig);
Data.PlayerRemainHp -= damage;
if(!isReducePlayerHp)
isReducePlayerHp = true;
}
if(isRefreshTime)
BossAttackTimeRefresh();
var isDefeat= CheckPlayIsDead();
Agg_event_bossfight_attacked(Data.StageCountFrom1,Data.RoundCountFrom1,damage,isDefeat,isReduceShield);
}
/// <summary>
/// 模拟一次boss攻击返回是否致命和伤害值
/// </summary>
private bool SimulateBossAttack(int currentHp, int currentShield, out int newHp, out int newShield, out int damage)
{
newShield = currentShield;
newHp = currentHp;
damage = 0;
bool isBlcok = false;
if (newShield > 0)
{
newShield--;
isBlcok = true;
}
else
{
damage = GetBossAttackDamage(Data.StageConfig);
newHp -= damage;
}
var isDefeat = newHp <= 0;
Agg_event_bossfight_attacked(Data.StageCountFrom1,Data.RoundCountFrom1,damage,isDefeat,isBlcok);
return isDefeat;
}
private void BossAttackTimeRefresh()
{
var now = ZZTimeHelper.UtcNow();
Data.BossAttackTime = Data.StageConfig.AttackInterval + new DateTimeOffset(now).ToUnixTimeSeconds();
}
private int GetBossAttackDamage(EventBossFightStage config)
{
var list= config.BaseDamageList.Select(x => Tables.TbEventBossFightDamage.GetOrDefault(x).Weight);
var index= FtUtils.GetRandomIdxFromWeightList(list);
var id= config.BaseDamageList[index];
return Tables.TbEventBossFightDamage.GetOrDefault(id)?.BaseAttack*config.AttackMultiplier ?? 0;
}
public (int minDamage,int maxDamage) GetBossAttackRange(EventBossFightStage config)
{
if (config == null) return default;
if(config.BaseDamageList==null || config.BaseDamageList.Count==0) return default;
int min = Int32.MaxValue;
int max = Int32.MinValue;
foreach (var baseDamage in config.BaseDamageList)
{
var damageConfig = Tables.TbEventBossFightDamage.GetOrDefault(baseDamage);
if (damageConfig == null) continue;
if(damageConfig.BaseAttack>max)
max = damageConfig.BaseAttack;
if(damageConfig.BaseAttack<min)
min = damageConfig.BaseAttack;
}
min *= config.AttackMultiplier;
max *= config.AttackMultiplier;
return (min, max);
}
private void BossReduceHp(int count)
{
Data.BossRemainHp -= count;
CheckBossIsDead();
}
private void CheckBossIsDead()
{
try
{
if (Data.BossRemainHp > 0) return;
Agg_event_bossfight_stage(Data.StageCountFrom1, Data.RoundCountFrom1);
Data.BossRemainHp = 0;
var change=new ChangeSource(Data.EventID, "Event_Minigame1", "Event_Minigame1_Bossfight", null);
GContext.container.Resolve<PlayerItemData>()
.AddItemByDropLureInflation(Data.InflationRate, Data.StageConfig.DropId,change,false);
Data.StageCountFrom1++;
}
catch (Exception e)
{
Debug.LogError(e);
}
}
#endregion
#region player
private void PlayerAddShield(EventBossFightSpinPoints spinConfig, int magnification,out int convertTokenCount,out int addAmount)
{
addAmount = 0;
convertTokenCount=0;
if(spinConfig?.SpinType!=nameof(EEventBossFightSpinType.Shield)) return;
Data.PlayerShieldCount += addAmount= spinConfig.EffectValue * magnification;
var overflowCount = Data.PlayerShieldCount - Data.InitConfig.ShieldCapacity;
if (overflowCount <= 0) return;
TryConvertToken(spinConfig, overflowCount,out convertTokenCount);
Data.PlayerShieldCount = Data.InitConfig.ShieldCapacity;
}
private void PlayerRevertHp(EventBossFightSpinPoints spinConfig, int magnification,out int convertTokenCount,out int addAmount)
{
addAmount = 0;
convertTokenCount = 0;
if(spinConfig?.SpinType!=nameof(EEventBossFightSpinType.Cure)) return;
Data.PlayerRemainHp += addAmount= spinConfig.EffectValue * magnification;
var overflowHp = Data.PlayerRemainHp - Data.StageConfig.PlayerHP;
if (overflowHp <= 0) return;
TryConvertToken(spinConfig, overflowHp,out convertTokenCount);
Data.PlayerRemainHp = Data.StageConfig.PlayerHP;
}
private void TryConvertToken(EventBossFightSpinPoints spinConfig, int overflowCount,out int convertTokenCount)
{
convertTokenCount = 0;
convertTokenCount = overflowCount / spinConfig.OverflowConvertRate;
AddToken(convertTokenCount);
}
private void PlayerAttack(EventBossFightSpinPoints spinConfig, int magnification)
{
if(spinConfig==null) return;
if(magnification<=0)return;
if(!IsAttackTypeSpin(spinConfig.SpinType)) return;
var damage = spinConfig.EffectValue * magnification;
BossReduceHp(damage);
}
public bool CheckPlayIsDead()
{
if (Data.PlayerRemainHp > 0) return false;
Data.PlayerRemainHp = 0;
Data.HasPendingLastAttack = false;
Data.LastAttackDamage=0;
Data.PlayerHpBeforeLastAttack = 0;
Data.PlayerShieldBeforeLastAttack = 0;
if (Data.BossFightAwaitingPaidRevive)
return true;
if (TryEnterPaidRevivePendingState())
{
Data.BossFightAwaitingPaidRevive = true;
SaveData();
return true;
}
ResetStageProgress();
return true;
}
/// <summary>
/// 当前付费复活应使用的 TbIAPItemList 配置 id来自 GlobalConfig.EventBossFightIapList下标封顶为最后一项
/// </summary>
public int GetPaidReviveIapTableId()
{
var list = Tables.TbGlobalConfig.EventBossFightIapList;
if (list == null || list.Count == 0)
return 0;
var idx = Math.Min(Data.BossFightPaidReviveCount, list.Count - 1);
return list[idx];
}
/// <summary>
/// 已阵亡、活动有效且配置了可用 IAP 时,等待玩家付费复活(不重置关卡进度)。
/// </summary>
public bool IsAwaitingPaidRevive()
{
if (Data == null || !Data.IsActive || Data.PlayerRemainHp > 0 || !Data.BossFightAwaitingPaidRevive)
return false;
var iapId = GetPaidReviveIapTableId();
if (iapId <= 0)
return false;
return Tables.TbIAPItemList?.GetOrDefault(iapId) != null;
}
bool TryEnterPaidRevivePendingState()
{
if (!Data.IsActive)
return false;
var iapId = GetPaidReviveIapTableId();
if (iapId <= 0)
return false;
if (Tables.TbIAPItemList?.GetOrDefault(iapId) == null)
{
Debug.LogError($"[EventBossFight] EventBossFightIapList id {iapId} not found in TbIAPItemList, fallback to fail reset.");
return false;
}
return true;
}
/// <summary>
/// 付费成功后:玩家满血(当前关 PlayerHP、Boss 剩余血量继承不变、清除等待复活标记,刷新 Boss 攻击计时。
/// </summary>
void ApplyPaidRevive()
{
Data.BossFightPaidReviveCount++;
Data.BossFightAwaitingPaidRevive = false;
Data.PendingFightBootstrap = false;
Data.PlayerRemainHp = Data.StageConfig.PlayerHP;
var maxBoss = Data.StageConfig.BossHP;
if (Data.BossRemainHp > maxBoss)
Data.BossRemainHp = maxBoss;
BossAttackTimeRefresh();
}
/// <summary>
/// 发起付费复活(无额外掉落展示)。
/// </summary>
public async Task<bool> TryPurchasePaidReviveAsync()
{
if (!IsAwaitingPaidRevive())
return false;
var iapTableId = GetPaidReviveIapTableId();
GContext.container.Resolve<PlayerItemData>().ResolveIapId(iapTableId, out var iapItem, out _);
if (iapItem == null)
return false;
var emptyGift = new List<ItemData>();
var buyType = new ShopBuyTypeData
{
type = ShopBuyType.None,
ID = Data.EventID,
IsHide = true,
NoShow = true,
extraPurcheData = new JObject
{
["event_bossfight_paid_revive"] = true,
["bossfight_paid_revive_index"] = Data.BossFightPaidReviveCount
}
};
var ok = await GContext.container.Resolve<PlayerShopData>()
.OnBuy(0, buyType, iapItem, emptyGift);
if (ok)
{
ApplyPaidRevive();
SaveData();
}
return ok;
}
#endregion
#region Pack
public async void ShowFestPack()
{
try
{
if (Data?.InitConfig == null) return;
var packData = new EventNeoNormalPackData
{
EventId = Data.EventID,
PackId = Data.InitConfig.PackId,
// Panel = Data.InitConfig.PackPanel
};
await EventNeoNormalPackPanel.TryShowAsync(packData);
}
catch (Exception e)
{
Debug.LogError(e);
}
}
#endregion
public void ShowReviewPanel()
{
UITypes.EventBossFightReviewPopupPanel.SetType(Data.InitConfig.ReviewPanel);
_= UIManager.Instance.ShowUILoad(UITypes.EventBossFightReviewPopupPanel);
}
private void ShowRewardPanel()
{
UITypes.EventBossFightRewardPopupPanel.SetType(Data.InitConfig.RewardPanel);
_= UIManager.Instance.ShowUILoad(UITypes.EventBossFightRewardPopupPanel);
}
private void ShowEndPanel()
{
UITypes.EventBossFightEndingPopupPanel.SetType(Data.InitConfig.EndingPanel);
_= UIManager.Instance.ShowUILoad(UITypes.EventBossFightEndingPopupPanel);
}
public void SetGuideState(bool isShow)
{
if(Data.IsShowGuide==isShow) return;
Data.IsShowGuide = isShow;
BootstrapFightFullReset();
SaveData();
}
public void SetShowTipsState(bool isShow)
{
if(Data.IsShowTips==isShow) return;
Data.IsShowTips = isShow;
SaveData();
}
#region Token
public string GetTokenName()
{
return Tables.TbItem.GetOrDefault(Data.InitConfig.ItemID)?.Icon??string.Empty;
}
public bool TryUseToken()
{
var currentAmount = GetTokenCount();
if (currentAmount < Data.Magnification*Data.InitConfig.SpinRequire)
{
ShowFestPack();
return false;
}
RemoveToken(Data.Magnification*Data.InitConfig.SpinRequire);
SetRedPoint();
return true;
}
public override void AddToken(int count)
{
base.AddToken(count);
SetRedPoint();
}
#endregion
private static bool IsAttackTypeSpin(string type)
{
return type.Equals(nameof(EEventBossFightSpinType.AttackTier1)) ||
type.Equals(nameof(EEventBossFightSpinType.AttackTier2));
}
#region Red
private string GetRedPointKey()
{
return "eventBossFight.red";
}
private bool GetRedPointState()
{
if (!Data.IsActive) return false;
return GetTokenCount() > 0;
}
private void SetRedPoint()
{
RedPointManager.Instance?.SetRedPointState(GetRedPointKey(), GetRedPointState(),GetTokenCount());
}
#endregion
#region guidance
// public void ClearGuidance()
// {
// GContext.container.Resolve<GuideDataCenter>().ClearGuide("BossFight01");
// }
//
// public void TryTriggerGuidance()
// {
// if (Data.PlayerRemainHp == 0)
// return;
// GContext.container.Resolve<GuideDataCenter>().TriggerGuide("BossFight01","EventBossFightUnderseaPanel",false);
// }
#endregion
#region Agg
/// <summary>
/// event_bossfight 转动一次上报
/// </summary>
/// <param name="stage_id">当前第几关</param>
/// <param name="round">当前第几轮</param>
/// <param name="multiple">倍率</param>
/// <param name="point_type">积分类型</param>
/// <param name="shield_count">玩家当前护盾</param>
/// <param name="player_hp">玩家当前生命值</param>
/// <param name="overflow_count">溢出转换</param>
/// <param name="boss_hp">boss剩余血量</param>
/// <param name="player_group">体力分档序号,<b>从 1 开始</b>(数据层 <see cref="EventBossFightData.BossFightStageGroupIndex"/> 为 0 起)</param>
public void Agg_event_bossfight(int stage_id,int round,int multiple,string point_type,int shield_count,int player_hp,int overflow_count,int boss_hp,int player_group)
{
#if AGG
using (var e = GEvent.GameEvent("event_bossfight"))
{
e.AddContent(nameof(stage_id), stage_id)
.AddContent(nameof(round), round)
.AddContent(nameof(multiple), multiple)
.AddContent(nameof(point_type), point_type)
.AddContent(nameof(shield_count), shield_count).
AddContent(nameof(player_hp), player_hp)
.AddContent(nameof(overflow_count), overflow_count)
.AddContent(nameof(boss_hp), boss_hp)
.AddContent(nameof(player_group), player_group);
}
#endif
}
/// <summary>
/// event_bossfight_stage 击败boss时上报
/// </summary>
/// <param name="stage_id">当前第几关</param>
/// <param name="round">当前第几轮</param>
public void Agg_event_bossfight_stage (int stage_id,int round)
{
#if AGG
using (var e = GEvent.GameEvent("event_bossfight_stage"))
{
e.AddContent(nameof(stage_id), stage_id)
.AddContent(nameof(round), round);
}
#endif
}
/// <summary>
/// event_bossfight_attacked 被boss攻击时上报
/// </summary>
/// <param name="stage_id">当前第几关</param>
/// <param name="round">当前第几轮</param>
/// <param name="attack">boss攻击伤害</param>
/// <param name="is_defeat">是否被击败</param>
/// <param name="is_block">是否被格挡</param>
public void Agg_event_bossfight_attacked (int stage_id,int round,int attack,bool is_defeat,bool is_block)
{
#if AGG
using (var e = GEvent.GameEvent("event_bossfight_attacked"))
{
e.AddContent(nameof(stage_id), stage_id)
.AddContent(nameof(round), round)
.AddContent(nameof(attack), attack)
.AddContent(nameof(is_defeat), is_defeat)
.AddContent(nameof(is_block), is_block);
}
#endif
}
#endregion
#if UNITY_EDITOR
#region DebugFuc
public void Debug_StartTargetStageFight(int stageIndex)
{
Data.StageCountFrom1 = stageIndex;
InitStageData();
SaveData();
}
public void Debug_UseDropItem(int spinPointID,int magnification,out int convertTokenCount,out int addAmount)
{
addAmount = 0;
convertTokenCount = 0;
var spinPointConfig = Tables.TbEventBossFightSpinPoints.GetOrDefault(spinPointID);
switch (spinPointConfig.SpinType)
{
case nameof(EEventBossFightSpinType.Cure):
PlayerRevertHp(spinPointConfig,magnification,out convertTokenCount,out addAmount);
break;
case nameof(EEventBossFightSpinType.Shield):
PlayerAddShield(spinPointConfig,magnification,out convertTokenCount,out addAmount);
break;
case nameof(EEventBossFightSpinType.AttackTier1):
case nameof(EEventBossFightSpinType.AttackTier2):
PlayerAttack(spinPointConfig,magnification);
break;
}
SaveData();
}
#endregion
#endif
}
}