备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ab4ee44dc11796442b378076ad25900f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class EventLuckyBubbleTask : MonoBehaviour
{
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54a218ae649cd6045b56e79b600ce46c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using System;
using UnityEngine.UI;
using UniRx;
using asap.core;
using game;
using GameCore;
public class EventLuckyCardButton : EventButtonResource
{
[SerializeField] private TMP_Text textTimer;
[SerializeField] private Button button;
[SerializeField] private Image icon;
private ILoadResourceService _loadResourceService;
EventLuckyGameModel model;
IDisposable disposable;
private void Awake()
{
_loadResourceService = GContext.container.Resolve<ILoadResourceService>();
}
private void OnEnable()
{
model = GContext.container.Resolve<EventLuckyGameModel>();
if (model == null || !model.IsActive)
{
gameObject.SetActive(false);
if (model != null)
{
model.Dispose();
}
GContext.container.Unregister<EventLuckyGameModel>();
return;
}
var fishingEvent = model.fishingEvent;
UpdateTimer();
disposable = Observable.Interval(TimeSpan.FromSeconds(1f)).Subscribe(UpdateTimer);
CheckResource(new List<string>(){
model.eventInfo.MainPrefab,
model.eventInfo.ActName ,
model.eventInfo.IconName});
}
private void Start()
{
button.onClick.AddListener(EnterActAsync);
}
private void UpdateTimer(long _ = 0L)
{
textTimer.text = ConvertTools.ConvertTime2(model.RemainingTime);
if (!model.IsActive)
gameObject.SetActive(false);
}
private async void EnterActAsync()
{
try
{
bool isReady = await _loadResourceService.Loads(
new List<string>(){
model.eventInfo.MainPrefab,
model.eventInfo.ActName });
if (isReady)
{
GContext.Publish(new UnloadActToNextAct { actId = model.eventInfo.ActName });
}
else
{
var panel = await UIManager.Instance.ShowUI(UITypes.CloudTransitionPanel);
panel.GetComponent<CloudTransitionPanel>()
.SetBtn(true, () => GContext.Publish(new UnloadActToNextAct(model.eventInfo.ActName)));
}
}
catch (Exception e)
{
Debug.Log($"<color=#22a6f2>[EventLuckyCardButton] EnterActError: {e.Message}\n{e.StackTrace}</color>");
throw;
}
}
private void OnDisable()
{
disposable?.Dispose();
disposable = null;
}
protected override void OnLoadEventResource()
{
if (model.IsActive)
{
GContext.container.Resolve<IUIService>().SetImageSprite(icon, model.eventInfo.IconName);
gameObject.SetActive(true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f0b553daea94e34fa1ac8c4574fb5fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public partial class EventLuckyCardItem : EventLuckyCardItemBase, IEventLuckyCardItem
{
public GameObject bgNormal;
public GameObject bgWishprize;
public GameObject card_back;
public GameObject reward_multiplier;
public TMP_Text reward_multiplier_num;
public RewardItemNew reward;
public GameObject claimed;
public GameObject multiplier;
public TMP_Text multiplier_num;
public Animation anim;
public Button btn;
private void Reset()
{
bgNormal = transform.Find("card_reward/bg_normal").gameObject;
bgWishprize = transform.Find("card_reward/bg_wishprize").gameObject;
card_back = transform.Find("card_back").gameObject;
reward_multiplier = transform.Find("card_reward/reward_multiplier").gameObject;
reward_multiplier_num = transform.Find("card_reward/reward_multiplier/text_num").GetComponent<TMP_Text>();
reward = transform.Find("card_reward/reward").GetComponent<RewardItemNew>();
claimed = transform.Find("card_reward/claimed").gameObject;
multiplier = transform.Find("card_reward/multiplier").gameObject;
multiplier_num = transform.Find("card_reward/multiplier/text_num").GetComponent<TMP_Text>();
anim = GetComponent<Animation>();
btn = GetComponent<Button>();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: abbd64e464f8b754c83f7ebae5c967e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class EventLuckyCardItemBase : MonoBehaviour, IEventLuckyCardItem
{
public int index { get; set; }
public Action<int> OnClickCard { get; set; }
public virtual void ViewReward(CardRewardShowData showData)
{
// Implement view reward logic
}
public virtual void OpenReward(CardRewardShowData showData)
{
// Implement open reward logic
}
public virtual void PlayWishprize(bool value)
{
// Implement play wish prize logic
}
public virtual void PlayReward()
{
// Implement play reward logic
}
public virtual void PlayBack()
{
// Implement play back logic
}
public Vector3 GetPosition()
{
return transform.position;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a2f537c1ed4150b4184ddece8245b956
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
using GameCore;
public partial class EventLuckyCardItem : EventLuckyCardItemBase, IEventLuckyCardItem
{
private void Start()
{
btn.onClick.AddListener(() =>
{
OnClickCard?.Invoke(index);
});
}
public override void ViewReward(CardRewardShowData showData)
{
claimed.SetActive(showData.isHas);
multiplier.SetActive(showData.isHas && showData.multiplier > 0);
multiplier_num.text = $"x{showData.multiplier}";
bgNormal.SetActive(!showData.isWishPrize);
bgWishprize.SetActive(showData.isWishPrize);
if (showData.id == LuckyCardsSystem.ItemID)
{
reward.gameObject.SetActive(false);
reward_multiplier.SetActive(true);
reward_multiplier_num.text = $"x{showData.num}";
}
else
{
reward_multiplier.SetActive(false);
reward.SetData(new ItemData(showData.id, showData.num));
}
}
public override void OpenReward(CardRewardShowData showData)
{
claimed.SetActive(false);
multiplier.SetActive(showData.isHas && showData.multiplier > 0);
multiplier_num.text = $"x{showData.multiplier}";
bgNormal.SetActive(!showData.isWishPrize);
bgWishprize.SetActive(showData.isWishPrize);
if (showData.id == LuckyCardsSystem.ItemID)
{
reward.gameObject.SetActive(false);
reward_multiplier.SetActive(true);
reward_multiplier_num.text = $"x{showData.num}";
}
else
{
reward_multiplier.SetActive(false);
if (showData.id == 0 || showData.num == 0)
{
reward.gameObject.SetActive(false);
return;
}
reward.SetData(new ItemData(showData.id, showData.num));
if (showData.isWishPrize)
{
int num = ConvertTools.KeepThreeSignificantDigits(showData.num);
string text = $"x{ConvertTools.GetNumberString(num)}";
reward.text_num.text = $"<color=#FFF823>{text}</color>";
}
}
}
public override void PlayWishprize(bool v)
{
if (v)
{
anim.Play("card_fanmian_wishprize");
}
else
{
anim.Play("card_fanmian_normal");
}
}
public override void PlayReward()
{
anim.Play("card_reward");
}
public override void PlayBack()
{
anim.Play("car_fanmian_back");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b313ceafde302bd4d900d8d675549331
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using asap.core;
using GameCore;
using System.Threading.Tasks;
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine;
public class EventLuckyCardsAct : AGameAct
{
EventLuckyGameModel model;
LuckyCardsSystem luckyCardsSystem;
private CanvasScaler _canvasScaler;
private readonly float normalScale = 0.75f, actScale = 1.0f, duration = 0.75f;
private readonly Vector2 targetResolution = new Vector2(1080, 2340);
private Vector2 originalResolution;
public override async Task<bool> StartAsync()
{
GContext.container.Unregister<LuckyCardsSystem>();
luckyCardsSystem = new LuckyCardsSystem();
GContext.container.RegisterInstance(luckyCardsSystem);
model = GContext.container.Resolve<EventLuckyGameModel>();
UIType uIType = new UIType(model.eventInfo.MainPrefab);
_canvasScaler = UIManager.Instance.GetComponent<CanvasScaler>();
// DOTween.To(() => _canvasScaler.matchWidthOrHeight, v => _canvasScaler.matchWidthOrHeight = v, actScale, duration).SetEase(Ease.OutQuad);
originalResolution = _canvasScaler.referenceResolution;
DOTween.To(() => _canvasScaler.referenceResolution, v => _canvasScaler.referenceResolution = v, targetResolution, duration).SetEase(Ease.OutQuad);
var panel = await UIManager.Instance.ShowUINotLoading(uIType);
GContext.container.Resolve<IDeferredRewardStashService>().Reset();
return await base.StartAsync();
}
public override Task StopAsync()
{
GContext.container.Unregister<LuckyCardsSystem>();
UIManager.Instance.DestroyUI(model.eventInfo.MainPrefab);
return base.StopAsync();
}
protected override void OnDestroy()
{
DOTween.To(() => _canvasScaler.referenceResolution, v => _canvasScaler.referenceResolution = v, originalResolution, duration).SetEase(Ease.OutQuad);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e9f8a2934c1f9dc49bce17d419a2d134
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using Spine;
using Spine.Unity;
public class EventLuckyCardsNPC : EventLuckyNPCBase
{
public SkeletonGraphic skeletonGraphic;
private void Start()
{
skeletonGraphic.AnimationState.Complete += HandleAnimationComplete;
}
void HandleAnimationComplete(TrackEntry trackEntry)
{
skeletonGraphic.AnimationState.SetAnimation(0, "luckycards_npc_idle", true);
}
override public void PlayIdle()
{
skeletonGraphic.AnimationState.SetAnimation(0, "luckycards_npc_idle", true);
}
override public void PlayStart()
{
skeletonGraphic.AnimationState.SetAnimation(0, "luckycards_npc_start", false);
}
override public void PlayCelebrate01()
{
skeletonGraphic.AnimationState.SetAnimation(0, "luckycards_npc_celebrate01", false);
}
override public void PlayCelebrate02()
{
skeletonGraphic.AnimationState.SetAnimation(0, "luckycards_npc_celebrate02", false);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 556a56c0d84d80648a9484e332e7851b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public partial class EventLuckyCardsPanel : MonoBehaviour
{
[SerializeField] private Animation ani, cardAni, mask;
[SerializeField] private Button btnClose, btn_reward, btnTicket, btnInfo, btnView, btn_select, btn_nextround, btn_start;
[SerializeField] private TMP_Text textTicketCount, text_progress, textTimer, costNum, multiplierNum;
[SerializeField] private RewardFly rewardFlyPrefab;
[SerializeField] private Image bar;
[SerializeField] private RewardItemNew wishprizeReward;
[SerializeField] private RewardItemNew rewardItem;
[SerializeField] List<EventLuckyCardItemBase> luckyCardsItems = new List<EventLuckyCardItemBase>();
[SerializeField] private LuckyCardsPrizetSelecte selectePanel;
[SerializeField] private GameObject wishprize, finger, multiplier, text_start, clickMask, RewradPopup;
[SerializeField] private DeferredRewardStashButton rewardStashButton;
[SerializeField] private EventLuckyNPCBase npc;
//特效
[SerializeField] private GameObject multiplier_fly, multiplier_light, wishprize_fly, wishprize_light, wishprize_show_1, wishprize_show_2;
[SerializeField] private float multiplier_fly_time = 0.5f, wishprize_fly_time = 0.5f, wishprize_show = 0.5f;
LuckyTaskBtn luckyTaskBtn;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 75b6a26290c78d0479b9064339cc3cc7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,594 @@
using asap.core;
using DG.Tweening;
using game;
using Game;
using GameCore;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
public partial class EventLuckyCardsPanel : MonoBehaviour
{
const string ViewPanel = "Event{0}PrizetViewPopupPanel";
string EventPanelName = "LuckyCards";
LuckyCardsSystem luckyCardsSystem;
int currentMultiplier = 0;
bool isCanClick = false;
int ticketCount;
private void Awake()
{
luckyTaskBtn = transform.Find("root/btn_task").GetComponent<LuckyTaskBtn>();
}
private void Start()
{
GContext.OnEvent<ResAddEvent>().Where(x => x.Type == 8).Subscribe(x =>
{
TicketAddAnim();
}).AddTo(this);
luckyCardsSystem = GContext.container.Resolve<LuckyCardsSystem>();
luckyCardsSystem.Init();
luckyTaskBtn.Init(luckyCardsSystem.model, luckyCardsSystem.model.LuckyTaskRedPointKey);
btnClose.onClick.AddListener(OnCloseButtonClick);
btnTicket.onClick.AddListener(OnClickPack);
btnInfo.onClick.AddListener(OnClickInfo);
btnView.onClick.AddListener(OnClickView);
btn_start.onClick.AddListener(ClickRestartGame);
btn_reward.onClick.AddListener(OnClickReward);
InitProgress();
InitCardsItems();
InitLuckyCardsPrizetSelecte();
UpdateTimer();
Observable.Interval(TimeSpan.FromSeconds(1f)).Subscribe(UpdateTimer).AddTo(this);
CardRewardShowData show = luckyCardsSystem.GetWishPrizeShow();
if (show.id == 0)
{
btn_select.gameObject.SetActive(true);
wishprize.SetActive(false);
StartGame();
btn_start.gameObject.SetActive(true);
multiplier.SetActive(false);
}
else
{
btn_select.gameObject.SetActive(false);
wishprize.SetActive(true);
Init();
}
RefreshCost();
if (currentMultiplier > 0)
{
multiplierNum.text = currentMultiplier.ToString();
}
else
{
multiplierNum.text = "1";
}
npc.PlayIdle();
GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide("EventLuckyCardsPanel");
}
void RefreshCost()
{
ticketCount = luckyCardsSystem.TicketCount;
int itemCost = luckyCardsSystem.config.ItemCost;
costNum.text = ticketCount < itemCost ? $"<color=red>{itemCost}</color>" : $"<color=#13FF00>{itemCost}</color>";
textTicketCount.text = ticketCount == 0 ? "<color=red>0</color>" : $"{ticketCount} ";
}
void TicketAddAnim()
{
//播放跳字
int old = ticketCount;
ticketCount = luckyCardsSystem.TicketCount;
int itemCost = luckyCardsSystem.config.ItemCost;
costNum.text = ticketCount < itemCost ? $"<color=red>{itemCost}</color>" : $"<color=#13FF00>{itemCost}</color>";
DOTween.Kill("text_ticket");
DOTween.To(() => old, x => old = x, ticketCount, 1f).OnUpdate(() =>
{
textTicketCount.text = $"{old} ";
}).SetId("text_ticket");
}
void InitProgress()
{
var cardsMain = luckyCardsSystem.CardsMain;
List<int> milestoneList = cardsMain.MilestoneList;
List<int> milestoneRewardList = cardsMain.MilestoneRewardList;
int milestoneCount = milestoneList.Count;
ProgressMilestone progressMilestone = luckyCardsSystem.progressMilestone;
//计算奖励
int newProgress = progressMilestone.progress;
float fill = 1;
int index = 0;
for (int i = 0; i < milestoneCount; i++)
{
if (newProgress >= milestoneList[i])
{
index = i + 1;
}
else
{
int dropId = milestoneRewardList[i];
var rewardData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
rewardItem.SetData(rewardData);
break;
}
}
if (index < milestoneCount)
{
int startCount = 0;
if (index > 0)
{
startCount = milestoneList[index - 1];
}
fill = (newProgress - startCount) * 1f / (milestoneList[index] - startCount);
text_progress.text = $"{newProgress - startCount}/{milestoneList[index] - startCount}";
}
else
{
int dropId = milestoneRewardList[milestoneCount - 1];
var rewardData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
rewardItem.SetData(rewardData);
text_progress.text = LocalizationMgr.GetText("UI_EventRankPopupPanel_15");
}
bar.fillAmount = fill;
}
void InitCardsItems()
{
for (int i = 0; i < luckyCardsItems.Count; i++)
{
luckyCardsItems[i].index = i;
luckyCardsItems[i].OnClickCard = OnClickCard;
}
}
void InitLuckyCardsPrizetSelecte()
{
btn_select.onClick.AddListener(OpenSelect);
btn_nextround.onClick.AddListener(OpenSelect);
selectePanel.btn_close.onClick.AddListener(CloseSelect);
selectePanel.btn_confrim.onClick.AddListener(OnConfirmWishPrize);
}
void OpenSelect()
{
finger.SetActive(false);
var itemDatas = luckyCardsSystem.GetWishPrizeReward();
var rewardItemNews = selectePanel.rewardItemNews;
for (int i = 0; i < rewardItemNews.Count; i++)
{
if (i < itemDatas.Count)
{
rewardItemNews[i].SetData(itemDatas[i]);
}
}
selectePanel.OpenSelect();
}
void OnConfirmWishPrize()
{
RestartGame();
}
void RestartGame()
{
GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide("EventLuckyCardsPanel");
int index = selectePanel.GetSelectedIndex();
if (index < 0)
{
Debug.LogWarning("[EventLucky] Selected index is out of range.");
return;
}
if (luckyCardsSystem.LuckyCardsData.rewardData.Count == 0)
{
ani.Play("EventLuckyCards_change_2");
luckyCardsSystem.RefreshReward();
}
luckyCardsSystem.OnConfirmWishPrize(index);
RefreshCost();
Restart();
CloseSelect();
}
void CloseSelect()
{
selectePanel.gameObject.SetActive(false);
}
void OnClickCard(int index)
{
if (!isCanClick)
{
if (btn_start.gameObject.activeSelf)
{
ClickRestartGame();
}
return;
}
ItemData itemData = luckyCardsSystem.OnClickCard(index);
if (itemData == null)
{
return;
}
List<int> previewPos = luckyCardsSystem.LuckyCardsData.pos;
var cardRewardShowData = luckyCardsSystem.cardRewardShowDatas;
IEventLuckyCardItem luckyCardItem = luckyCardsItems[index];
CardRewardShowData rewardShowData = cardRewardShowData[previewPos.Count - 1];
rewardShowData.isHas = true;
luckyCardItem.OpenReward(rewardShowData);
if (rewardShowData.id == LuckyCardsSystem.ItemID)
{
GContext.container.Resolve<GuideDataCenter>().TriggerGuide(GroupName.LuckyCard02.ToString(), "EventLuckyCardsPanel", false);
}
if (rewardShowData.isWishPrize)
{
npc.PlayCelebrate02();
luckyCardItem.PlayWishprize(true);
}
else
{
luckyCardItem.PlayWishprize(false);
}
RefreshCost();
Fly(rewardShowData, index);
}
async void Fly(CardRewardShowData rewardShowData, int index)
{
clickMask.SetActive(true);
Vector3 srcPosition = luckyCardsItems[index].GetPosition();
ItemData itemData = new ItemData(rewardShowData.id, rewardShowData.num);
await Awaiters.Seconds(0.5f);
if (rewardShowData.isWishPrize)
{
//先飞上面,再飞下面
if (currentMultiplier > 0)
{
if (rewardShowData.multiplier != currentMultiplier)
{
Debug.Log($"[EventLuckyCards] Multiplier mismatch: {rewardShowData.multiplier} != {currentMultiplier}.");
}
itemData.count *= currentMultiplier;
}
currentMultiplier = 0;
multiplierNum.text = "1";
await FlyMultiplierFx(srcPosition, wishprize_fly, wishprize_light, multiplier_fly_time);
wishprizeReward.text_num.text = $"x{ConvertTools.GetNumberString(itemData.count)}";
ani.Play("EventLuckyCards_change_1");
await Awaiters.Seconds(1);
Vector3 destPosition = wishprizeReward.transform.position;
await FlyToPack(destPosition, itemData);
wishprize_light.gameObject.SetActive(false);
}
else if (rewardShowData.id == LuckyCardsSystem.ItemID)
{
//倍率
currentMultiplier += rewardShowData.num;
//动画
await FlyMultiplierFx(srcPosition, multiplier_fly, multiplier_light, multiplier_fly_time);
multiplierNum.text = currentMultiplier.ToString();
}
else
{
//飞到背包
if (currentMultiplier > 0)
{
if (rewardShowData.multiplier != currentMultiplier)
{
Debug.Log($"[EventLuckyCards] Multiplier mismatch: {rewardShowData.multiplier} != {currentMultiplier}.");
}
itemData.count *= currentMultiplier;
currentMultiplier = 0;
multiplierNum.text = "1";
await Awaiters.Seconds(1f);
}
await FlyToPack(srcPosition, itemData);
}
//进度奖励动画
await PlayProgress();
multiplier_light.SetActive(false);
clickMask.SetActive(false);
}
async Task FlyMultiplierFx(Vector3 srcPosition, GameObject fly, GameObject light, float duration)
{
fly.transform.position = srcPosition;
fly.SetActive(true);
fly.transform.DOMove(light.transform.position, duration)
.OnComplete(() =>
{
fly.SetActive(false);
light.SetActive(true);
});
await Awaiters.Seconds(duration + 0.2f);
}
async Task PlayProgress()
{
ProgressMilestone progressMilestone = luckyCardsSystem.progressMilestone;
if (progressMilestone.oldProgress == progressMilestone.progress)
{
return;
}
luckyCardsSystem.progressMilestone.oldProgress = progressMilestone.progress;
var cardsMain = luckyCardsSystem.CardsMain;
List<int> milestoneList = cardsMain.MilestoneList;
List<int> milestoneRewardList = cardsMain.MilestoneRewardList;
int milestoneCount = milestoneList.Count;
//计算奖励
int newProgress = progressMilestone.progress;
int index = 0;
if (progressMilestone.rewardIndex != null && progressMilestone.rewardIndex.Count > 0)
{
for (int i = 0; i < progressMilestone.rewardIndex.Count; i++)
{
index = progressMilestone.rewardIndex[i];
if (index >= 0)
{
//==========飞奖励===========
int dropId = milestoneRewardList[index];
var rewardData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
rewardItem.SetData(rewardData);
int startCount = 0;
if (index > 0)
startCount = milestoneList[index - 1];
int maxPro = milestoneList[index] - startCount;
bar.DOFillAmount(1, 0.5f)
.OnUpdate(() =>
{
text_progress.text = $"{(int)(maxPro * bar.fillAmount)}/{maxPro}";
})
.OnComplete(() =>
{
text_progress.text = $"{maxPro}/{maxPro}";
})
;
await Awaiters.Seconds(0.5f);
await FlyToPack(rewardItem.transform.position, rewardData);
//===========飞奖励==========
bar.fillAmount = 0f;
}
}
}
index = 0;
for (int i = 0; i < milestoneCount; i++)
{
if (newProgress >= milestoneList[i])
{
index = i + 1;
}
else
{
int dropId = milestoneRewardList[i];
var rewardData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
rewardItem.SetData(rewardData);
break;
}
}
if (index < milestoneCount)
{
int startCount = 0;
if (index > 0)
startCount = milestoneList[index - 1];
int curProgress = newProgress - startCount;
int maxPro = milestoneList[index] - startCount;
float fill = curProgress * 1f / maxPro;
bar.DOFillAmount(fill, 0.3f).OnUpdate(() =>
{
text_progress.text = $"{(int)(maxPro * bar.fillAmount)}/{maxPro}";
})
.OnComplete(() =>
{
text_progress.text = $"{curProgress}/{maxPro}";
});
}
else
{
bar.fillAmount = 1f;
text_progress.text = LocalizationMgr.GetText("UI_EventRankPopupPanel_15");
}
}
async Task FlyToPack(Vector3 srcPosition, ItemData itemData)
{
//var targetImg = stampRewardView.GetFirstEmptyImage();
Vector3 destPosition = rewardStashButton.transform.position;
float iconSize = rewardStashButton.Icon.rect.width;
CollectionItemFly collectionItemFly = new CollectionItemFly()
{
itemID = itemData.id,
numStr = itemData.count.ToString(),
sourcePos = srcPosition,
destPos = destPosition,
isPlayOpen = true,
isPlayClose = true,
isDestinationRewardStash = true,
targetIconSize = iconSize
};
var rewardFly = Instantiate(rewardFlyPrefab, rewardFlyPrefab.transform.parent).GetComponent<RewardFly>();
rewardFly.gameObject.SetActive(true);
await rewardFly.ShowAsync(collectionItemFly);
Destroy(rewardFly.gameObject);
//mask.gameObject.SetActive(false);
rewardStashButton.PlayReceiveAnimationWithDelay(0);
}
private void OnClickPack()
{
luckyCardsSystem.OnClickPack();
}
private void UpdateTimer(long _ = 0L)
{
textTimer.text = LocalizationMgr.GetFormatTextValue("UI_COMMON_end", ConvertTools.ConvertTime2(luckyCardsSystem.RemainingTime));
if (luckyCardsSystem.RemainingTime.TotalSeconds <= 0)
OnCloseButtonClick();
}
void OnClickReward()
{
RewradPopup.SetActive(true);
}
private async void OnClickInfo()
{
var cardsMain = luckyCardsSystem.CardsMain;
await UIManager.Instance.ShowUINotLoading(new UIType(cardsMain.InfoPanel));
}
async void OnClickView()
{
try
{
GameObject popup = await UIManager.Instance.ShowUINotLoading(new UIType(string.Format(ViewPanel, EventPanelName)));
if (popup != null)
{
var popupPanel = popup.GetComponent<EventLuckyCardsPrizetViewPopupPanel>();
if (popupPanel != null)
{
popupPanel.btnClose.onClick.AddListener(() => UIManager.Instance.DestroyUI(string.Format(ViewPanel, EventPanelName)));
popupPanel.btn_confrim.onClick.AddListener(() => UIManager.Instance.DestroyUI(string.Format(ViewPanel, EventPanelName)));
var popupItems = popupPanel.luckyCardsItems;
List<int> previewPos = luckyCardsSystem.previewPos;
var cardRewardShowData = luckyCardsSystem.cardRewardShowDatas;
for (int i = 0; i < popupItems.Count; i++)
{
popupItems[i].ViewReward(cardRewardShowData[previewPos[i]]);
}
}
}
}
catch (Exception e)
{
Debug.LogWarning($"[EventLuckyCards] Error in OnclickView: {e.Message}");
}
}
void ShowWishPrize()
{
CardRewardShowData show = luckyCardsSystem.GetWishPrizeShow();
wishprizeReward.SetData(new ItemData(show.id, show.num));
}
async void Restart()
{
isCanClick = false;
clickMask.SetActive(true);
wishprize_show_1.SetActive(true);
ShowWishPrize();
wishprize_show_2.SetActive(false);
wishprize.SetActive(true);
btn_select.gameObject.SetActive(false);
var popupItems = luckyCardsItems;
List<int> previewPos = luckyCardsSystem.previewPos;
var cardRewardShowData = luckyCardsSystem.cardRewardShowDatas;
for (int i = 0; i < popupItems.Count; i++)
{
popupItems[i].OpenReward(cardRewardShowData[previewPos[i]]);
popupItems[i].PlayReward();
}
CardRewardShowData WishPrizeShow = luckyCardsSystem.GetWishPrizeShow();
CardRewardShowData showData = new CardRewardShowData();
showData.isHas = false;
showData.isWishPrize = true;
popupItems[0].OpenReward(showData);
await Awaiters.Seconds(wishprize_show);
popupItems[0].OpenReward(WishPrizeShow);
wishprize_show_2.SetActive(true);
await PlayProgress();
clickMask.SetActive(false);
btn_start.gameObject.SetActive(true);
ShowStartText(true);
wishprize_show_1.SetActive(false);
}
async void ClickRestartGame()
{
CardRewardShowData show = luckyCardsSystem.GetWishPrizeShow();
if (show.id == 0)
{
finger.SetActive(true);
return;
}
isCanClick = true;
btn_start.gameObject.SetActive(false);
ShowStartText(false);
clickMask.SetActive(true);
var popupItems = luckyCardsItems;
for (int i = 0; i < popupItems.Count; i++)
{
popupItems[i].PlayBack();
}
await Awaiters.Seconds(0.5f);
cardAni.Play();
mask.Play();
await Awaiters.Seconds(3f);
npc.PlayStart();
clickMask.SetActive(false);
}
void ShowStartText(bool value)
{
multiplier.SetActive(!value);
text_start.SetActive(value);
}
void StartGame()
{
ShowWishPrize();
var popupItems = luckyCardsItems;
List<int> previewPos = luckyCardsSystem.previewPos;
var cardRewardShowData = luckyCardsSystem.cardRewardShowDatas;
for (int i = 0; i < popupItems.Count; i++)
{
popupItems[i].OpenReward(cardRewardShowData[previewPos[i]]);
popupItems[i].PlayReward();
}
isCanClick = false;
}
private void Init()
{
ShowWishPrize();
var popupItems = luckyCardsItems;
List<int> clickPos = luckyCardsSystem.LuckyCardsData.pos;
List<CardRewardShowData> cardRewardShowData = luckyCardsSystem.cardRewardShowDatas;
IEventLuckyCardItem luckyCardItem = null;
for (int i = 0; i < clickPos.Count; i++)
{
CardRewardShowData cardRewardShow = cardRewardShowData[i];
luckyCardItem = popupItems[clickPos[i]];
luckyCardItem.OpenReward(cardRewardShow);
if (cardRewardShow.id == LuckyCardsSystem.ItemID)
{
currentMultiplier += cardRewardShow.num;
}
else
{
currentMultiplier = 0;
}
luckyCardItem.PlayReward();
}
isCanClick = true;
}
private void OnCloseButtonClick()
{
GContext.Publish(new UnloadActToNextAct());
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ba15bcbb9a90a4a49b79c75d4c92ac21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EventLuckyCardsPrizetViewPopupPanel : MonoBehaviour
{
public List<EventLuckyCardItemBase> luckyCardsItems = new List<EventLuckyCardItemBase>();
public Button btn_confrim, btnClose;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 622d0dc6796acd846ab2c941f80f27d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class EventLuckyCardsProgressRewardItem : MonoBehaviour
{
public RewardItemNew rewardItem;
public TMP_Text text_task;
private void Reset()
{
rewardItem = transform.Find("reward").GetComponent<RewardItemNew>();
text_task = transform.Find("text_progress").GetComponent<TMP_Text>();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d253910f3abc8494985bbacba55c5679
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public partial class EventLuckyCardsProgressRewradPopupPanel : MonoBehaviour
{
public float[] progressBar = new float[] { 0.149f, 0.363f, 0.576f, 0.788f, 1f };
public List<EventLuckyCardsProgressRewardItem> rewardItems = new List<EventLuckyCardsProgressRewardItem>();
public Image bar;
public Button btnClose;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d7c88cf3f49e0f42ac1be072d145904
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using asap.core;
using cfg;
using GameCore;
using System.Collections.Generic;
using UnityEngine;
public partial class EventLuckyCardsProgressRewradPopupPanel : MonoBehaviour
{
LuckyCardsSystem luckyCardsSystem;
void Awake()
{
luckyCardsSystem = GContext.container.Resolve<LuckyCardsSystem>();
btnClose.onClick.AddListener(() =>
{
gameObject.SetActive(false);
});
}
private void OnEnable()
{
SetItem();
}
void SetItem()
{
var cardsMain = luckyCardsSystem.CardsMain;
int itemID = cardsMain.Item;
Item item = GContext.container.Resolve<Tables>().GetItemData(itemID);
List<int> milestoneList = cardsMain.MilestoneList;
List<int> milestoneRewardList = cardsMain.MilestoneRewardList;
int milestoneCount = milestoneList.Count;
ProgressMilestone progressMilestone = luckyCardsSystem.progressMilestone;
//计算奖励
int newProgress = progressMilestone.progress;
int curIndex = 0;
for (int i = 0; i < milestoneCount; i++)
{
if (i < rewardItems.Count)
{
EventLuckyCardsProgressRewardItem rewardItem = rewardItems[i];
int dropId = milestoneRewardList[i];
var rewardData = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
rewardItem.rewardItem.SetData(rewardData);
bool isClaim = newProgress >= milestoneList[i];
rewardItem.text_task.text = milestoneList[i].ToString();
if (isClaim)
{
rewardItem.rewardItem.SetReceived(true);
curIndex = i + 1;
}
}
}
if (curIndex == milestoneCount)
{
bar.fillAmount = 1f;
}
else
{
float startProgress = curIndex > 0 ? milestoneList[curIndex - 1] : 0f;
float endProgress = milestoneList[curIndex];
float startFillAmount = curIndex > 0 ? progressBar[curIndex - 1] : 0f;
float endFillAmount = progressBar[curIndex];
bar.fillAmount = (float)(newProgress - startProgress) / (endProgress - startProgress) * (endFillAmount - startFillAmount) + startFillAmount;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 333f152a66fca0543b72afd82da82d56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using System.Collections;
using UnityEngine;
public class EventLuckyNPCBase : MonoBehaviour
{
public virtual void PlayIdle()
{
}
public virtual void PlayStart()
{
}
public virtual void PlayCelebrate01()
{
}
public virtual void PlayCelebrate02()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f5e2c361e8ed00c45914e7051f2c9895
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using System;
using UnityEngine;
public interface IEventLuckyCardItem
{
int index { get; set; }
Action<int> OnClickCard { get; set; }
public void ViewReward(CardRewardShowData showData);
public void OpenReward(CardRewardShowData showData);
public void PlayWishprize(bool value);
public void PlayReward();
public void PlayBack();
public Vector3 GetPosition();
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 465a80edd744ace49837fa5d5e8f5588
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class LuckyCardsPrizetSelecte : MonoBehaviour
{
public List<Toggle> toggles;
public List<GameObject> selecteds;
public List<RewardItemNew> rewardItemNews;
public Button btn_confrim, btn_confrim_gray, btn_close;
public TMP_Text resetNum, resetNum_gray;
public GameObject text_info_nocost, text_info_cost;
private void OnEnable()
{
for (int i = 0; i < toggles.Count; i++)
{
toggles[i].isOn = false;
toggles[i].onValueChanged.RemoveAllListeners();
toggles[i].onValueChanged.AddListener((isOn) =>
{
OnSelect();
});
}
}
public int GetSelectedIndex()
{
for (int i = 0; i < toggles.Count; i++)
{
if (toggles[i].isOn)
{
return i;
}
}
return -1;
}
public void OnSelect()
{
int isSelected = -1;
for (int i = 0; i < toggles.Count; i++)
{
if (toggles[i].isOn)
{
isSelected = i;
break;
}
}
for (int i = 0; i < selecteds.Count; i++)
{
selecteds[i].SetActive(i == isSelected);
}
btn_confrim.gameObject.SetActive(isSelected >= 0);
btn_confrim_gray.gameObject.SetActive(isSelected < 0);
}
public void OpenSelect()
{
btn_confrim.gameObject.SetActive(false);
btn_confrim_gray.gameObject.SetActive(true);
text_info_nocost.SetActive(true);
text_info_cost.SetActive(false);
gameObject.SetActive(true);
btn_close.gameObject.SetActive(false);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85d2e3d72e6d277468f4b4b822d15ca6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,502 @@
using asap.core;
using cfg;
using game;
using GameCore;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class LuckyCardsSystem
{
public const int ItemID = -1; // -1表示倍率卡,其他为奖励ID
public EventLuckyGameModel model { get; private set; }
EventLuckyCardsMain cardsMain;
public EventLuckyCardsMain CardsMain => cardsMain;
public TimeSpan RemainingTime => model.RemainingTime;
public int TicketCount => model.TicketCount;
LuckyCardsData luckyCardsData;
public LuckyCardsData LuckyCardsData => luckyCardsData;
Tables tables;
int wishPrizeIndex;
//预览位置
public List<int> previewPos = new List<int>();
public List<CardRewardShowData> cardRewardShowDatas = new List<CardRewardShowData>();
public EventLuckyCardsConfig config;
public ProgressMilestone progressMilestone;
public void Init()
{
tables = GContext.container.Resolve<Tables>();
model = GContext.container.Resolve<EventLuckyGameModel>();
cardsMain = tables.TbEventLuckyCardsMain.GetOrDefault(model.cycle.RedirectID);
string json = model.EventGameData;
progressMilestone = new ProgressMilestone();
progressMilestone.oldProgress = progressMilestone.progress = model.Progress;
progressMilestone.rewardIndex = new List<int>(); // 初始化奖励索引为-1表示未触发奖励
try
{
luckyCardsData = Newtonsoft.Json.JsonConvert.DeserializeObject<LuckyCardsData>(json);
}
catch (System.Exception e)
{
UnityEngine.Debug.LogWarning($"Error parsing LuckyCardsSystem JSON: {e.Message}");
}
if (luckyCardsData == null || luckyCardsData.rewardData == null || luckyCardsData.rewardData.Count == 0)
{
RefreshReward(); // 如果没有数据,开始新游戏
}
else
{
wishPrizeIndex = GetWishPrizeIndex();
SetPreviewPos();
SetCardRewardShowData();
}
SetConfig();
}
public async void OnClickPack()
{
EventPackManager eventPack = GContext.container.Resolve<Tables>().TbEventPackManager.GetOrDefault(cardsMain.PackId);
GameObject go = await UIManager.Instance.ShowUINotLoading(new UIType(eventPack.Panel));
if (go == null)
{
return;
}
EventLuckyTriplePackPanel triple = go.GetComponent<EventLuckyTriplePackPanel>();
triple.Init(EventLuckyTriplePackData.Create(model.EventId, cardsMain.PackId));
}
public ItemData OnClickCard(int index)
{
if (luckyCardsData == null || luckyCardsData.rewardData.Count == 0)
{
return null;
}
if (model.TicketCount < config.ItemCost)
{
OnClickPack();
return null;
}
luckyCardsData.pos.Add(index);
int rewardIndex = luckyCardsData.pos.Count - 1;
int dropId = Cost(config.ItemCost);
CardRewardShowData cardRewardData = cardRewardShowDatas[rewardIndex];
ItemData itemData = new ItemData(cardRewardData.id, cardRewardData.num);
int wishprize_multiple = 1;
if (cardRewardData.multiplier > 0)
{
wishprize_multiple = cardRewardData.multiplier;
itemData.count *= cardRewardData.multiplier;
}
if (cardRewardData.id != ItemID)
{
var e = new DeferredRewardStashService.EventStashItem { Item = itemData };
GContext.Publish(e);
}
#if AGG
using (var e = GEvent.GameEvent("event_luckycards"))
{
e.AddContent("is_wishprize", rewardIndex == wishPrizeIndex)
.AddContent("item_cost", config.ItemCost)
.AddContent("reward", $"{itemData.id},{itemData.count}")
.AddContent("round", luckyCardsData.count)
.AddContent("milestone_reward", dropId)
;
}
#endif
//如果抽取大奖位置,直接结束
if (rewardIndex == wishPrizeIndex)
{
int multiple_cards_number = 0;
for (int i = 0; i < rewardIndex; i++)
{
if (luckyCardsData.rewardData[i].id == ItemID)
{
multiple_cards_number++;
}
}
luckyCardsData.rewardData.Clear();
#if AGG
using (var e = GEvent.GameEvent("event_luckycards_wishprize"))
{
e.AddContent("number", wishPrizeIndex + 1)
.AddContent("round", luckyCardsData.count)
.AddContent("wishprize_multiple", wishprize_multiple)
.AddContent("multiple_cards_number", multiple_cards_number);
}
#endif
luckyCardsData.count++;
model.InitDicTasks();
}
SaveData();
SetConfig();
return itemData;
}
void SetConfig()
{
if (luckyCardsData == null || luckyCardsData.pos == null || luckyCardsData.pos.Count == 0)
{
config = tables.TbEventLuckyCardsConfig.GetOrDefault(1);
return;
}
config = tables.TbEventLuckyCardsConfig.GetOrDefault(luckyCardsData.pos.Count + 1);
if (config == null)
config = tables.TbEventLuckyCardsConfig.GetOrDefault(1); // 默认配置
}
public List<ItemData> GetWishPrizeReward()
{
int index = luckyCardsData.count - 1;
if (index < 0 || index >= cardsMain.WishPrize.Count)
{
index = cardsMain.WishPrize.Count - 1; // 确保索引在有效范围内
}
int wishPrizeId = cardsMain.WishPrize[index];
return GContext.container.Resolve<PlayerItemData>().GetItemDataByDropId(wishPrizeId);
}
public CardRewardShowData GetWishPrizeShow()
{
if (wishPrizeIndex < 0 || wishPrizeIndex >= cardRewardShowDatas.Count)
{
Debug.LogError($"[LuckyCardsSystem]: Invalid wish prize index: {wishPrizeIndex}");
return null;
}
return cardRewardShowDatas[wishPrizeIndex];
}
public void OnConfirmWishPrize(int selectedWishPrizeIndex)
{
if (selectedWishPrizeIndex < 0)
{
return;
}
List<ItemData> reward = GetWishPrizeReward();
if (reward == null || selectedWishPrizeIndex >= luckyCardsData.rewardData.Count)
{
Debug.LogError($"[LuckyCardsSystem]: Invalid wish prize index: {selectedWishPrizeIndex}");
return;
}
CardRewardShowData cardRewardShowData = cardRewardShowDatas[wishPrizeIndex];
CardRewardData wishRewardData = luckyCardsData.rewardData[wishPrizeIndex];
ItemData itemData = reward[selectedWishPrizeIndex];
cardRewardShowData.id = wishRewardData.id = itemData.id;
cardRewardShowData.num = wishRewardData.num = itemData.count;
SaveData();
#if AGG
using (var e = GEvent.GameEvent("event_luckycards_select_wishprize"))
{
e.AddContent("reward", itemData.id)
.AddContent("round", luckyCardsData.count)
.AddContent("reward_count", itemData.count);
}
#endif
}
public void RefreshReward()
{
if (luckyCardsData == null)
{
luckyCardsData = new LuckyCardsData();
luckyCardsData.count++;
}
else
{
luckyCardsData.rewardData.Clear();
luckyCardsData.pos.Clear();
}
if (luckyCardsData.count < cardsMain.WishPrize.Count)
{
luckyCardsData.seed = cardsMain.RandomSeedRound1[UnityEngine.Random.Range(0, cardsMain.RandomSeedRound1.Count)];
}
else
{
luckyCardsData.seed = (int)DateTime.UtcNow.Ticks; // 使用当前时间的Ticks作为随机种子
}
Debug.Log($"[LuckyCardsSystem]: Refreshing rewards with seed: {luckyCardsData.seed}, count: {luckyCardsData.count}");
//先随大奖位置
wishPrizeIndex = GetWishPrizeIndex();
SetRewardData();
SetPreviewPos();
//保存
SaveData();
SetCardRewardShowData();
SetConfig();
}
void SetRewardData()
{
System.Random random = new System.Random(luckyCardsData.seed);
List<EventLuckyCardsPrizePool> pools = tables.TbEventLuckyCardsPrizePool.DataList;
Dictionary<int, int> poolWeight = new Dictionary<int, int>();
foreach (var pool in pools)
{
poolWeight[pool.ID] = pool.Weight;
}
int multiplierCount = 0;
for (int i = 0; i < 9; i++)
{
//出现在心愿大奖之后权重变为X且不受权重下降的影响
if (i == wishPrizeIndex)
{
poolWeight = WishPrizeNewDic(poolWeight);
}
int selectedPoolId = GetSelectedPoolId(poolWeight, random);
EventLuckyCardsPrizePool selectedPool = tables.TbEventLuckyCardsPrizePool.GetOrDefault(selectedPoolId);
if (selectedPool == null)
{
UnityEngine.Debug.LogError($"[LuckyCardsSystem]: Selected pool not found for ID: {selectedPoolId}");
}
CardRewardData cardRewardData = new CardRewardData();
cardRewardData.id = selectedPool.Item;
cardRewardData.num = selectedPool.Count;
if (selectedPool.Item == 1002)
{
cardRewardData.num = GContext.container.Resolve<PlayerItemData>().GetExtraCoinMag(selectedPool.Count);
}
luckyCardsData.rewardData.Add(cardRewardData);
if (i < wishPrizeIndex || selectedPool.AdjustWeight2 == 0)
{
poolWeight[selectedPoolId] = selectedPool.AdjustWeight;
}
if (selectedPool.Item == ItemID)
{
multiplierCount++;
if (multiplierCount >= cardsMain.MaxMultipleCardsCount)
{
poolWeight = MaxMultipleNewDic(poolWeight);
}
}
}
CardRewardData wishRewardData = new CardRewardData();
luckyCardsData.rewardData.Insert(wishPrizeIndex, wishRewardData);
}
int GetSelectedPoolId(Dictionary<int, int> poolWeight, System.Random random)
{
int weightSum = poolWeight.Values.Sum();
int randomValue = random.Next(0, weightSum);
int cumulativeWeight = 0;
int selectedPoolId = 0;
foreach (var kvp in poolWeight)
{
if (kvp.Value == 0)
{
continue;
}
cumulativeWeight += kvp.Value;
if (randomValue < cumulativeWeight)
{
selectedPoolId = kvp.Key;
break;
}
}
return selectedPoolId;
}
Dictionary<int, int> WishPrizeNewDic(Dictionary<int, int> poolWeight)
{
var oldPoolWeight = poolWeight;
poolWeight = new Dictionary<int, int>();
EventLuckyCardsPrizePool selectedPool;
foreach (var kvp in oldPoolWeight)
{
if (kvp.Value == 0)
{
continue;
}
selectedPool = tables.TbEventLuckyCardsPrizePool.GetOrDefault(kvp.Key);
if (selectedPool.AdjustWeight2 > 0)
{
poolWeight[kvp.Key] = selectedPool.AdjustWeight2;
}
else
{
poolWeight[kvp.Key] = kvp.Value;
}
}
return poolWeight;
}
Dictionary<int, int> MaxMultipleNewDic(Dictionary<int, int> poolWeight)
{
var oldPoolWeight = poolWeight;
poolWeight = new Dictionary<int, int>();
EventLuckyCardsPrizePool selectedPool;
foreach (var kvp in oldPoolWeight)
{
if (kvp.Value == 0)
{
continue;
}
selectedPool = tables.TbEventLuckyCardsPrizePool.GetOrDefault(kvp.Key);
if (selectedPool.Item != ItemID)
{
poolWeight[kvp.Key] = kvp.Value;
}
}
return poolWeight;
}
/// <summary>
/// 使用随机种子
/// </summary>
/// <param name="random"></param>
/// <returns></returns>
int GetWishPrizeIndex()
{
System.Random random = new System.Random(luckyCardsData.seed);
List<EventLuckyCardsConfig> configs = GContext.container.Resolve<Tables>().TbEventLuckyCardsConfig.DataList;
//权重随机
int weightSum = configs.Select(c => c.WishPrizeWeight).Sum();
int randomValue = random.Next(0, weightSum);
int cumulativeWeight = 0;
int wishPrizeIndex = 0;
for (int i = 0; i < configs.Count; i++)
{
cumulativeWeight += configs[i].WishPrizeWeight;
if (randomValue < cumulativeWeight)
{
wishPrizeIndex = i;
break;
}
}
//Debug.Log($"[LuckyCardsSystem]:Wish Prize Index: {wishPrizeIndex}, Seed: {luckyCardsData.seed}");
return wishPrizeIndex;
}
void SetPreviewPos()
{
previewPos.Clear();
System.Random random = new System.Random(luckyCardsData.seed);
List<int> availablePositions = Enumerable.Range(0, 10).ToList();
for (int i = 0; i < 10; i++)
{
int index = random.Next(availablePositions.Count);
previewPos.Add(availablePositions[index]);
availablePositions.RemoveAt(index);
}
previewPos.Remove(wishPrizeIndex);
// 将大奖位置放在最前面
previewPos.Insert(0, wishPrizeIndex);
//Debug.Log($"[LuckyCardsSystem]:Preview Positions: {string.Join(", ", previewPos)}");
}
void SaveData()
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(luckyCardsData);
//Debug.Log($"[LuckyCardsSystem]:Saving LuckyCardsData: {json}");
model.SetEventGameData(json);
}
int Cost(int count)
{
model.AddTicket(-count);
//增加进度
int oldProgress = model.Progress;
progressMilestone.oldProgress = oldProgress;
List<int> milestoneList = cardsMain.MilestoneList;
if (oldProgress >= milestoneList[^1])
{
return 0;
}
List<int> milestoneRewardList = cardsMain.MilestoneRewardList;
model.AddProgress(count);
//计算奖励
int newProgress = model.Progress;
progressMilestone.rewardIndex.Clear();
int dropId = 0;
for (int i = 0; i < milestoneList.Count; i++)
{
if (oldProgress < milestoneList[i] && newProgress >= milestoneList[i])
{
// 触发奖励
dropId = milestoneRewardList[i];
var rewardItem = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
if (rewardItem != null)
{
var e = new DeferredRewardStashService.EventStashItem { Item = rewardItem };
GContext.Publish(e);
}
progressMilestone.rewardIndex.Add(i); // 添加奖励索引
}
}
progressMilestone.progress = newProgress;
return dropId;
}
/// <summary>
/// 显示用的数据
/// </summary>
void SetCardRewardShowData()
{
cardRewardShowDatas.Clear();
int multiplier = 0;
for (int i = 0; i < luckyCardsData.rewardData.Count; i++)
{
CardRewardData rewardData = luckyCardsData.rewardData[i];
CardRewardShowData showData = new CardRewardShowData
{
id = rewardData.id,
num = rewardData.num,
isHas = i < luckyCardsData.pos.Count,
isWishPrize = i == wishPrizeIndex, // 判断是否为大奖位置
};
if (rewardData.id == ItemID)
{
multiplier += rewardData.num;
}
else
{
showData.multiplier = multiplier;
multiplier = 0; // 重置倍率
}
cardRewardShowDatas.Add(showData);
}
}
}
public class LuckyCardsData
{
// 奖励抽奖顺序
public List<CardRewardData> rewardData = new List<CardRewardData>();
// 玩家抽取顺序随机种子,计算展示顺序
public int seed;
// 玩家抽取的位置顺序,可以计算倍率
public List<int> pos = new List<int>();
public int count = 0; // 玩家抽取的次数
}
public class CardRewardData
{
public int id;
public int num;
}
public class CardRewardShowData
{
public int id; // 奖励ID
public int num; // 奖励数量
public int multiplier;
public bool isHas;
public bool isWishPrize;
}
public struct ProgressMilestone
{
public int oldProgress; // 旧的进度
public int progress;
public List<int> rewardIndex;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40fbaa48e12176b48a2d92ee35308d7c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,298 @@
using asap.core;
using cfg;
using GameCore;
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 同一系列的活动使用同一个Model
/// 礼包、代币、进度奖励等数据结构都相同
/// 后续活动只用关系自己的玩法数据即可
/// </summary>
public class EventLuckyGameModel : ILuckyTaskGetData, ILuckyTaskUIGetData
{
public static EventLuckyGameModel Get()
{
var model = GContext.container.Resolve<EventLuckyGameModel>();
if (model == null)
{
GContext.container.Register<EventLuckyGameModel>().AsSingleton();
model = GContext.container.Resolve<EventLuckyGameModel>();
}
return model;
}
public const string Key = "EventLuckGameRecord";
public const string PackRedPointKey = "luckgame.pack";
public const string RedPointKey = "luckgame";
EventLuckGameRecord eventLuckGameRecord = new EventLuckGameRecord();
FishingEventData fishingEventData;
Tables tables;
public FishingEvent fishingEvent { get; private set; }
public EventLuckGameInfo eventInfo { get; private set; } = new EventLuckGameInfo();
public FishingEventCycleItem3 cycle { get; private set; }
public int EventId => eventLuckGameRecord.EventId;
public int Progress => eventLuckGameRecord.Progress;
public string EventGameData => eventLuckGameRecord.EventGameData;
public TimeSpan RemainingTime
{
get
{
if (fishingEvent == null || fishingEvent.TimeDefinition is not LimitedTime limitedTime)
{
return TimeSpan.Zero;
}
return System.DateTime.Parse(limitedTime.EndTime) - ZZTimeHelper.UtcNow();
}
}
public EventLuckyGameModel(FishingEventData fishingEventData, Tables tables)
{
this.fishingEventData = fishingEventData ?? GContext.container.Resolve<FishingEventData>();
this.tables = tables ?? GContext.container.Resolve<Tables>();
luckyTaskData = new LuckyTaskData(this);
}
public void Save()
{
string s = Newtonsoft.Json.JsonConvert.SerializeObject(eventLuckGameRecord);
//Debug.Log($"[EventLuckGameModel] Save EventLuckGameRecord: {s}");
PlayFabMgr.Instance.UpdateUserDataValue(Key, s);
}
//=========================以下是活动数据=========================
public int TicketCount
{
get
{
if (!IsActive)
{
return 0;
}
//_ticketCount = fishingEventData.GetTransitionDataCount(EventId);
return eventLuckGameRecord.TicketCount;
}
private set
{
if (!IsActive)
{
return;
}
eventLuckGameRecord.TicketCount = value;
if (eventLuckGameRecord.TicketCount < 0)
{
eventLuckGameRecord.TicketCount = 0;
}
fishingEventData.SaveTransitionData(EventId, eventLuckGameRecord.TicketCount);
Save();
RedPointManager.Instance.SetRedPointState(RedPointKey, eventLuckGameRecord.TicketCount >= cycle.RedDot);
}
}
public bool IsActive
{
get
{
if (fishingEvent == null)
{
return false;
}
if (fishingEvent.TimeDefinition is LimitedTime limitedTime)
{
return ZZTimeHelper.UtcNow() < System.DateTime.Parse(limitedTime.EndTime) && ZZTimeHelper.UtcNow() > System.DateTime.Parse(limitedTime.StartTime);
}
return false;
}
}
public void AddTicket(int count)
{
if (fishingEvent == null || cycle == null || !IsActive)
{
Debug.LogError("[EventLuckGameModel] _tableEvent is null, cannot add ticket.");
return;
}
TicketCount += count;
}
#region
public void AddProgress(int progress)
{
if (fishingEvent == null)
{
Debug.LogError("[EventLuckGameModel] _tableEvent is null, cannot add progress.");
return;
}
eventLuckGameRecord.Progress += progress;
if (eventLuckGameRecord.Progress < 0)
{
eventLuckGameRecord.Progress = 0;
}
Save();
}
#endregion
public void OnEvent(FishingEvent t)
{
fishingEvent = t;
if (t == null)
{
return;
}
string s = PlayFabMgr.Instance.GetLocalData(Key);
if (string.IsNullOrEmpty(s))
{
eventLuckGameRecord = new EventLuckGameRecord();
}
else
{
try
{
eventLuckGameRecord = Newtonsoft.Json.JsonConvert.DeserializeObject<EventLuckGameRecord>(s);
}
catch (Exception e)
{
Debug.LogError($"[EventLuckGameModel] Deserialize Error: {e.Message}");
eventLuckGameRecord = new EventLuckGameRecord();
}
}
DicTasks = eventLuckGameRecord.DicTasks;
cycle = tables.TbFishingEventCycleItem3.GetOrDefault(t.RedirectID);
if (cycle == null)
{
Debug.LogError($"[EventLuckGameModel] CycleItem3 not found for RedirectID: {t.RedirectID}");
return;
}
if (eventLuckGameRecord.EventId != t.ID)
{
eventLuckGameRecord.EventId = t.ID;
eventLuckGameRecord.ChainProgress = 0;
eventLuckGameRecord.Progress = 0;
eventLuckGameRecord.EventGameData = string.Empty;
TicketCount = cycle.WelcomeGift;
DicTasks.Clear();
}
SetEventInfo();
}
//=========================以上是活动数据=========================
//=========================以下是玩法数据=========================
public void SetEventGameData(string data)
{
if (fishingEvent == null)
{
Debug.LogError("[EventLuckyGameModel] fishingEvent is null, cannot set event game data.");
return;
}
eventLuckGameRecord.EventGameData = data;
Save();
}
void SetEventInfo()
{
if (fishingEvent == null)
{
Debug.LogError("[EventLuckyGameModel] fishingEvent is null, cannot set event info.");
return;
}
eventInfo = GetEventLuckGameInfo();
if (DicTasks.Count == 0 && eventInfo.TaskRound1 != null && eventInfo.TaskRound1.Count > 0)
{
luckyTaskData.InitDicTasks(eventInfo.TaskRound1);
}
else
{
luckyTaskData.SetRedPoint();
}
RedPointManager.Instance.SetRedPointState(RedPointKey, eventLuckGameRecord.TicketCount >= cycle.RedDot);
}
EventLuckGameInfo GetEventLuckGameInfo()
{
var eventInfo = new EventLuckGameInfo();
if (fishingEvent.SubType == 4)
{
EventLuckyCardsMain _tableMain = tables.TbEventLuckyCardsMain.GetOrDefault(cycle.RedirectID);
if (_tableMain == null)
{
Debug.LogError($"[EventLuckyCardsMain] EventLuckyCardsMain is Null RedirectID {cycle.RedirectID}");
fishingEvent = null;
return null;
}
eventInfo.IconName = _tableMain.Icon;
eventInfo.MainPrefab = _tableMain.Prefab;
eventInfo.TaskPanelName = _tableMain.TaskPrefab;
eventInfo.ItemID = _tableMain.Item;
eventInfo.PackId = _tableMain.PackId;
eventInfo.TaskRound1 = _tableMain.TaskRound1;
eventInfo.TaskRound2 = _tableMain.TaskRound2;
}
return eventInfo;
}
#region
//这是一个工具类,只有一个监听任务触发的状态,处理任务数据
private LuckyTaskData luckyTaskData;
/// 获取任务面板名称,配表
public string TaskPanelName => eventInfo.TaskPanelName;
public string LuckyTaskRedPointKey => "luckgame.luckytask";
//任务数据存储
public Dictionary<int, int> DicTasks { get; set; } = new Dictionary<int, int>();
public void InitDicTasks()
{
luckyTaskData.InitDicTasks(eventInfo.TaskRound2);
}
public void SaveTaskData()
{
eventLuckGameRecord.DicTasks = DicTasks;
Save();
}
public bool OnGetTaskReward(int id)
{
return luckyTaskData.OnGetTaskReward(id, eventInfo.TaskRound2);
}
public int GetLuckyPackID()
{
if (fishingEvent == null || cycle == null || eventInfo == null)
{
Debug.LogError("[EventLuckyGameModel] fishingEvent or cycle is null, cannot get lucky gift info.");
return 0;
}
return eventInfo.PackId;
}
#endregion
//=========================以上是玩法数据=========================
public void Dispose()
{
luckyTaskData.Dispose();
}
}
public class EventLuckGameRecord
{
public int EventId { get; set; }
public int ChainProgress { get; set; }
public int Progress { get; set; }
public int TicketCount { get; set; } = 0;
public string EventGameData { get; set; } = "";
public Dictionary<int, int> DicTasks { get; set; } = new Dictionary<int, int>();
}
public class EventLuckGameInfo
{
public string ActName = "EventLuckyCardsAct";
public string IconName;
public string MainPrefab;
public string TaskPanelName;
public int ItemID;
public int PackId;
public List<int> TaskRound1;
public List<int> TaskRound2;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 03ebe0c81d318f0458a26c6c4f3f6119
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: