948 lines
31 KiB
C#
948 lines
31 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace TcgEngine.UI
|
||
{
|
||
/// <summary>
|
||
/// CollectionPanel 玩家可以看到他们拥有的所有卡片的面板
|
||
/// 还有他们可以使用甲板建造者的面板
|
||
/// </summary>
|
||
|
||
public class CollectionPanel : UIPanel
|
||
{
|
||
[Header("Cards")]
|
||
public ScrollRect scroll_rect;
|
||
public RectTransform scroll_content;
|
||
public CardGrid grid_content;
|
||
public GameObject card_prefab;
|
||
|
||
[Header("Left Side")]
|
||
public IconButton[] team_filters;
|
||
public Toggle toggle_owned;
|
||
public Toggle toggle_not_owned;
|
||
|
||
public Toggle toggle_character;
|
||
public Toggle toggle_spell;
|
||
public Toggle toggle_artifact;
|
||
public Toggle toggle_equipment;
|
||
public Toggle toggle_secret;
|
||
|
||
public Toggle toggle_common;
|
||
public Toggle toggle_uncommon;
|
||
public Toggle toggle_rare;
|
||
public Toggle toggle_mythic;
|
||
|
||
public Toggle toggle_foil;
|
||
|
||
public Dropdown sort_dropdown;
|
||
public InputField search;
|
||
|
||
[Header("Right Side")]
|
||
public UIPanel deck_list_panel;
|
||
public UIPanel card_list_panel;
|
||
public DeckLine[] deck_lines;
|
||
|
||
[Header("Deckbuilding")]
|
||
public InputField deck_title;
|
||
public Text deck_quantity;
|
||
public GameObject deck_cards_prefab;
|
||
public RectTransform deck_content;
|
||
public GridLayoutGroup deck_grid;
|
||
public IconButton[] hero_powers;
|
||
|
||
[Header("切换卡组面板")]
|
||
public UIPanel changeCover;
|
||
|
||
private TeamData filter_team = null;
|
||
public int filter_dropdown = 0;
|
||
private string filter_search = "";
|
||
|
||
private List<CollectionCard> card_list = new List<CollectionCard>();
|
||
private List<CollectionCard> all_list = new List<CollectionCard>();
|
||
private List<DeckLine> deck_card_lines = new List<DeckLine>();
|
||
|
||
private string current_deck_tid;
|
||
private Image current_deck_image;
|
||
private bool editing_deck = false;
|
||
private bool saving = false;
|
||
private bool spawned = false;
|
||
|
||
private bool update_grid = false;
|
||
private float update_grid_timer = 0f;
|
||
|
||
// 分帧加载
|
||
private Coroutine spawnRoutine;
|
||
|
||
private List<UserCardData> deck_cards = new List<UserCardData>();
|
||
|
||
private static CollectionPanel instance;
|
||
|
||
protected override void Awake()
|
||
{
|
||
base.Awake();
|
||
instance = this;
|
||
|
||
//Delete grid content
|
||
for (int i = 0; i < grid_content.transform.childCount; i++)
|
||
Destroy(grid_content.transform.GetChild(i).gameObject);
|
||
for (int i = 0; i < deck_grid.transform.childCount; i++)
|
||
Destroy(deck_grid.transform.GetChild(i).gameObject);
|
||
|
||
foreach (DeckLine line in deck_lines)
|
||
line.onClick += OnClickDeckLine;
|
||
foreach (DeckLine line in deck_lines)
|
||
line.onClickDelete += OnClickDeckDelete;
|
||
foreach (DeckLine line in deck_lines)
|
||
line.onChangeCover += OnChangeCover;
|
||
|
||
foreach (IconButton button in team_filters)
|
||
button.onClick += OnClickTeam;
|
||
}
|
||
|
||
protected override void Start()
|
||
{
|
||
base.Start();
|
||
|
||
// 设置点击能力悬停文本
|
||
foreach (IconButton btn in hero_powers)
|
||
{
|
||
CardData icard = CardData.Get(btn.GetValue());
|
||
HoverTargetUI hover = btn.GetComponent<HoverTargetUI>();
|
||
AbilityData iability = icard?.GetAbility(AbilityTrigger.Activate);
|
||
if (icard != null && hover != null && iability != null)
|
||
{
|
||
string color = ColorUtility.ToHtmlStringRGBA(icard.team.color);
|
||
hover.text = "<b><color=#" + color + ">Hero Power: </color>";
|
||
hover.text += icard.title + "</b>\n " + iability.GetDesc(icard);
|
||
if (iability.mana_cost > 0)
|
||
hover.text += " <size=16>Mana: " + iability.mana_cost + "</size>";
|
||
}
|
||
}
|
||
}
|
||
|
||
protected override void Update()
|
||
{
|
||
base.Update();
|
||
}
|
||
|
||
private void LateUpdate()
|
||
{
|
||
//Resize grid
|
||
update_grid_timer += Time.deltaTime;
|
||
if (update_grid && update_grid_timer > 0.2f)
|
||
{
|
||
grid_content.GetColumnAndRow(out int rows, out int cols);
|
||
if (cols > 0)
|
||
{
|
||
float row_height = grid_content.GetGrid().cellSize.y + grid_content.GetGrid().spacing.y;
|
||
float height = rows * row_height;
|
||
scroll_content.sizeDelta = new Vector2(scroll_content.sizeDelta.x, height + 100);
|
||
update_grid = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void SpawnCards()
|
||
{
|
||
spawned = true;
|
||
|
||
all_list = CardUILoading.Get().CardList();
|
||
foreach (CollectionCard dCard in all_list)
|
||
{
|
||
dCard.onClick += OnClickCard;
|
||
dCard.onClickRight += OnClickCardRight;
|
||
}
|
||
|
||
|
||
// if (spawnRoutine != null)
|
||
// StopCoroutine(spawnRoutine);
|
||
// spawnRoutine = StartCoroutine(SpawnCardsCoroutine());
|
||
}
|
||
|
||
private IEnumerator SpawnCardsCoroutine()
|
||
{
|
||
spawned = true;
|
||
foreach (CollectionCard card in all_list)
|
||
Destroy(card.gameObject);
|
||
all_list.Clear();
|
||
|
||
int batchSize = 2; // 每帧生成2张卡
|
||
int counter = 0;
|
||
|
||
List<VariantData> variants = VariantData.GetAll();
|
||
List<CardData> cards = CardData.GetAll();
|
||
|
||
foreach (VariantData variant in variants)
|
||
{
|
||
foreach (CardData card in cards)
|
||
{
|
||
GameObject nCard = Instantiate(card_prefab, grid_content.transform);
|
||
CollectionCard dCard = nCard.GetComponent<CollectionCard>();
|
||
dCard.SetCard(card, variant, 0);
|
||
dCard.onClick += OnClickCard;
|
||
dCard.onClickRight += OnClickCardRight;
|
||
|
||
all_list.Add(dCard);
|
||
nCard.SetActive(false);
|
||
|
||
counter++;
|
||
if (counter % batchSize == 0)
|
||
yield return null; // 每 batchSize 张卡让出一帧
|
||
}
|
||
}
|
||
}
|
||
|
||
// private IEnumerator SpawnCardsCoroutine()
|
||
// {
|
||
// spawned = true;
|
||
// foreach (CollectionCard card in all_list)
|
||
// Destroy(card.gameObject);
|
||
// all_list.Clear();
|
||
//
|
||
// int batchSize = 2; // 每帧生成2张卡
|
||
// int counter = 0;
|
||
//
|
||
// List<VariantData> variants = VariantData.GetAll();
|
||
// List<CardData> cards = CardData.GetAll();
|
||
//
|
||
// foreach (VariantData variant in variants)
|
||
// {
|
||
// foreach (CardData card in cards)
|
||
// {
|
||
// GameObject nCard = Instantiate(card_prefab, grid_content.transform);
|
||
// CollectionCard dCard = nCard.GetComponent<CollectionCard>();
|
||
// dCard.SetCard(card, variant, 0);
|
||
// dCard.onClick += OnClickCard;
|
||
// dCard.onClickRight += OnClickCardRight;
|
||
//
|
||
// all_list.Add(dCard);
|
||
// nCard.SetActive(false);
|
||
//
|
||
// counter++;
|
||
// if (counter % batchSize == 0)
|
||
// yield return null; // 每 batchSize 张卡让出一帧
|
||
// }
|
||
// }
|
||
//
|
||
// isLoaded = true;
|
||
// Hide();
|
||
// }
|
||
|
||
//----- Reload User Data ---------------
|
||
|
||
public async void ReloadUser()
|
||
{
|
||
await Authenticator.Get().LoadUserData();
|
||
MainMenu.Get().RefreshDeckList();
|
||
RefreshCardsQuantities();
|
||
|
||
if (!editing_deck)
|
||
RefreshDeckList();
|
||
}
|
||
|
||
public async void ReloadUserCards()
|
||
{
|
||
await Authenticator.Get().LoadUserData();
|
||
RefreshCardsQuantities();
|
||
}
|
||
|
||
public void RefreshCover(Image cover)
|
||
{
|
||
current_deck_image.sprite = cover.sprite;
|
||
}
|
||
|
||
public async void ReloadUserDecks()
|
||
{
|
||
await Authenticator.Get().LoadUserData();
|
||
MainMenu.Get().RefreshDeckList();
|
||
RefreshDeckList();
|
||
}
|
||
|
||
//----- Refresh UI --------
|
||
|
||
public void RefreshAll()
|
||
{
|
||
RefreshFilters();
|
||
RefreshCards();
|
||
RefreshDeckList();
|
||
RefreshStarterDeck();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 筛选刷新
|
||
/// </summary>
|
||
private void RefreshFilters()
|
||
{
|
||
search.text = "";
|
||
sort_dropdown.value = 0;
|
||
foreach (IconButton button in team_filters)
|
||
button.Deactivate();
|
||
|
||
filter_team = null;
|
||
filter_dropdown = 0;
|
||
filter_search = "";
|
||
}
|
||
|
||
private void ShowDeckList()
|
||
{
|
||
deck_list_panel.Show();
|
||
changeCover.Hide();
|
||
card_list_panel.Hide();
|
||
editing_deck = false;
|
||
}
|
||
|
||
private void ShowDeckCards()
|
||
{
|
||
deck_list_panel.Hide();
|
||
changeCover.Hide();
|
||
card_list_panel.Show();
|
||
}
|
||
|
||
public void RefreshCards()
|
||
{
|
||
if (!spawned)
|
||
SpawnCards();
|
||
|
||
card_list.Clear();
|
||
|
||
UserData udata = Authenticator.Get().UserData;
|
||
if (udata == null)
|
||
return;
|
||
|
||
VariantData variant = VariantData.GetDefault();
|
||
VariantData special = VariantData.GetSpecial();
|
||
if (toggle_foil.isOn && special != null)
|
||
variant = special;
|
||
|
||
List<CardDataQ> all_cards = new List<CardDataQ>();
|
||
List<CardDataQ> shown_cards = new List<CardDataQ>();
|
||
|
||
foreach (CardData icard in CardData.GetAll())
|
||
{
|
||
CardDataQ card = new CardDataQ();
|
||
card.card = icard;
|
||
card.variant = variant;
|
||
card.quantity = udata.GetCardQuantity(icard, variant);
|
||
all_cards.Add(card);
|
||
}
|
||
|
||
// 统一的基础排序逻辑
|
||
all_cards.Sort((CardDataQ a, CardDataQ b) =>
|
||
{
|
||
// 第一级排序:isOnline(false 的永远在最下面)
|
||
bool aOnline = a.card.isOnline;
|
||
bool bOnline = b.card.isOnline;
|
||
if (aOnline != bOnline)
|
||
return bOnline.CompareTo(aOnline); // true在前 false在后
|
||
|
||
// 第二级排序:根据 dropdown 决定方式
|
||
switch (filter_dropdown)
|
||
{
|
||
case 0: // Name
|
||
return a.card.title.CompareTo(b.card.title);
|
||
case 1: // Attack
|
||
return b.card.attack == a.card.attack ? b.card.hp.CompareTo(a.card.hp) : b.card.attack.CompareTo(a.card.attack);
|
||
case 2: // HP
|
||
return b.card.hp == a.card.hp ? b.card.attack.CompareTo(a.card.attack) : b.card.hp.CompareTo(a.card.hp);
|
||
case 3: // Mana Cost
|
||
return b.card.mana == a.card.mana ? a.card.title.CompareTo(b.card.title) : a.card.mana.CompareTo(b.card.mana);
|
||
default:
|
||
return a.card.title.CompareTo(b.card.title);
|
||
}
|
||
});
|
||
|
||
foreach (CardDataQ card in all_cards)
|
||
{
|
||
if (card.card.deckbuilding)
|
||
{
|
||
CardData icard = card.card;
|
||
if (filter_team == null || filter_team == icard.team)
|
||
{
|
||
bool owned = card.quantity > 0;
|
||
RarityData rarity = icard.rarity;
|
||
CardType type = icard.type;
|
||
|
||
bool owned_check = (owned && toggle_owned.isOn)
|
||
|| (!owned && toggle_not_owned.isOn)
|
||
|| toggle_owned.isOn == toggle_not_owned.isOn;
|
||
|
||
bool type_check = (type == CardType.Character && toggle_character.isOn)
|
||
|| (type == CardType.Spell && toggle_spell.isOn)
|
||
|| (type == CardType.Artifact && toggle_artifact.isOn)
|
||
|| (type == CardType.Equipment && toggle_equipment.isOn)
|
||
|| (type == CardType.Secret && toggle_secret.isOn)
|
||
|| (!toggle_character.isOn && !toggle_spell.isOn && !toggle_artifact.isOn && !toggle_equipment.isOn && !toggle_secret.isOn);
|
||
|
||
bool rarity_check = (rarity.rank == 1 && toggle_common.isOn)
|
||
|| (rarity.rank == 2 && toggle_uncommon.isOn)
|
||
|| (rarity.rank == 3 && toggle_rare.isOn)
|
||
|| (rarity.rank == 4 && toggle_mythic.isOn)
|
||
|| (!toggle_common.isOn && !toggle_uncommon.isOn && !toggle_rare.isOn && !toggle_mythic.isOn);
|
||
|
||
string search = filter_search.ToLower();
|
||
bool search_check = string.IsNullOrWhiteSpace(search)
|
||
|| icard.id.Contains(search)
|
||
|| icard.title.ToLower().Contains(search)
|
||
|| icard.GetText().ToLower().Contains(search);
|
||
|
||
if (owned_check && type_check && rarity_check && search_check)
|
||
{
|
||
shown_cards.Add(card);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int index = 0;
|
||
foreach (CardDataQ qcard in shown_cards)
|
||
{
|
||
if (index < all_list.Count)
|
||
{
|
||
CollectionCard dcard = all_list[index];
|
||
dcard.SetCard(qcard.card, qcard.variant, 0);
|
||
card_list.Add(dcard);
|
||
if (!dcard.gameObject.activeSelf)
|
||
dcard.gameObject.SetActive(true);
|
||
index++;
|
||
}
|
||
}
|
||
|
||
for (int i = index; i < all_list.Count; i++)
|
||
all_list[i].gameObject.SetActive(false);
|
||
|
||
update_grid = true;
|
||
update_grid_timer = 0f;
|
||
scroll_rect.verticalNormalizedPosition = 1f;
|
||
RefreshCardsQuantities();
|
||
}
|
||
|
||
private void RefreshCardsQuantities()
|
||
{
|
||
UserData udata = Authenticator.Get().UserData;
|
||
foreach (CollectionCard card in card_list)
|
||
{
|
||
CardData icard = card.GetCard();
|
||
VariantData ivariant = card.GetVariant();
|
||
bool owned = IsCardOwned(udata, icard, ivariant, 1);
|
||
int quantity = udata.GetCardQuantity(icard, ivariant);
|
||
card.SetQuantity(quantity);
|
||
card.SetGrayscale(!owned);
|
||
}
|
||
}
|
||
|
||
private void RefreshDeckList()
|
||
{
|
||
foreach (DeckLine line in deck_lines)
|
||
line.Hide();
|
||
deck_cards.Clear();
|
||
editing_deck = false;
|
||
saving = false;
|
||
|
||
UserData udata = Authenticator.Get().UserData;
|
||
if (udata == null)
|
||
return;
|
||
|
||
int index = 0;
|
||
foreach (UserDeckData deck in udata.decks)
|
||
{
|
||
if (index < deck_lines.Length)
|
||
{
|
||
DeckLine line = deck_lines[index];
|
||
line.SetLine(udata, deck);
|
||
}
|
||
index++;
|
||
}
|
||
|
||
if (index < deck_lines.Length)
|
||
{
|
||
DeckLine line = deck_lines[index];
|
||
line.SetLine("+");
|
||
}
|
||
RefreshCardsQuantities();
|
||
}
|
||
|
||
public void RefreshDeck(UserDeckData deck)
|
||
{
|
||
deck_title.text = "Deck Name";
|
||
current_deck_tid = GameTool.GenerateRandomID(7);
|
||
deck_cards.Clear();
|
||
saving = false;
|
||
editing_deck = true;
|
||
|
||
foreach (IconButton btn in hero_powers)
|
||
btn.Deactivate();
|
||
|
||
if (deck != null)
|
||
{
|
||
deck_title.text = deck.title;
|
||
current_deck_tid = deck.tid;
|
||
|
||
foreach (IconButton btn in hero_powers)
|
||
{
|
||
if (deck.hero != null && btn.GetValue() == deck.hero.tid)
|
||
btn.Activate();
|
||
}
|
||
|
||
for (int i = 0; i < deck.cards.Length; i++)
|
||
{
|
||
CardData card = CardData.Get(deck.cards[i].tid);
|
||
VariantData variant = VariantData.Get(deck.cards[i].variant);
|
||
if (card != null && variant != null)
|
||
{
|
||
AddDeckCard(card, variant, deck.cards[i].quantity);
|
||
}
|
||
}
|
||
}
|
||
|
||
RefreshDeckCards();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 刷新牌组卡片
|
||
/// </summary>
|
||
private void RefreshDeckCards()
|
||
{
|
||
foreach (DeckLine line in deck_card_lines)
|
||
line.Hide();
|
||
|
||
List<CardDataQ> list = new List<CardDataQ>();
|
||
foreach (UserCardData card in deck_cards)
|
||
{
|
||
CardDataQ acard = new CardDataQ();
|
||
acard.card = CardData.Get(card.tid);
|
||
acard.variant = VariantData.Get(card.variant);
|
||
acard.quantity = card.quantity;
|
||
list.Add(acard);
|
||
}
|
||
list.Sort((CardDataQ a, CardDataQ b) => { return a.card.title.CompareTo(b.card.title); });
|
||
|
||
UserData udata = Authenticator.Get().UserData;
|
||
int index = 0;
|
||
int count = 0;
|
||
foreach (CardDataQ card in list)
|
||
{
|
||
if (index >= deck_card_lines.Count)
|
||
CreateDeckCard();
|
||
|
||
if (index < deck_card_lines.Count)
|
||
{
|
||
DeckLine line = deck_card_lines[index];
|
||
if (line != null)
|
||
{
|
||
line.SetLine(card.card, card.variant, card.quantity, !IsCardOwned(udata, card.card, card.variant, card.quantity));
|
||
count += card.quantity;
|
||
}
|
||
}
|
||
index++;
|
||
}
|
||
|
||
deck_quantity.text = count + "/" + GameplayData.Get().deck_size;
|
||
deck_quantity.color = count >= GameplayData.Get().deck_size ? Color.white : Color.red;
|
||
|
||
RefreshCardsQuantities();
|
||
}
|
||
|
||
// 刷新新手卡组
|
||
private void RefreshStarterDeck()
|
||
{
|
||
UserData udata = Authenticator.Get().UserData;
|
||
if (udata != null && (udata.cards.Length == 0 || udata.rewards.Length == 0))
|
||
{
|
||
if (GameplayData.Get().starter_decks.Length > 0)
|
||
{
|
||
StarterDeckPanel.Get().Show();
|
||
}
|
||
}
|
||
}
|
||
|
||
//-------- Deck editing actions
|
||
|
||
private void CreateDeckCard()
|
||
{
|
||
GameObject deck_line = Instantiate(deck_cards_prefab, deck_grid.transform);
|
||
DeckLine line = deck_line.GetComponent<DeckLine>();
|
||
deck_card_lines.Add(line);
|
||
float height = deck_card_lines.Count * 70f + 20f;
|
||
deck_content.sizeDelta = new Vector2(deck_content.sizeDelta.x, height);
|
||
line.onClick += OnClickCardLine;
|
||
line.onClickRight += OnRightClickCardLine;
|
||
}
|
||
|
||
private void AddDeckCard(CardData card, VariantData variant, int quantity = 1)
|
||
{
|
||
AddDeckCard(card.id, variant.id, quantity);
|
||
}
|
||
|
||
private void RemoveDeckCard(CardData card, VariantData variant)
|
||
{
|
||
RemoveDeckCard(card.id, variant.id);
|
||
}
|
||
|
||
private void AddDeckCard(string tid, string variant, int quantity = 1)
|
||
{
|
||
UserCardData ucard = GetDeckCard(tid, variant);
|
||
if (ucard != null)
|
||
{
|
||
ucard.quantity += quantity;
|
||
}
|
||
else
|
||
{
|
||
ucard = new UserCardData(tid, variant);
|
||
ucard.quantity = quantity;
|
||
deck_cards.Add(ucard);
|
||
}
|
||
}
|
||
|
||
private void RemoveDeckCard(string tid, string variant)
|
||
{
|
||
for (int i = deck_cards.Count - 1; i >= 0; i--)
|
||
{
|
||
UserCardData ucard = deck_cards[i];
|
||
if (ucard.tid == tid && ucard.variant == variant)
|
||
{
|
||
ucard.quantity--;
|
||
|
||
if(ucard.quantity <= 0)
|
||
deck_cards.RemoveAt(i);
|
||
}
|
||
}
|
||
}
|
||
|
||
private UserCardData GetDeckCard(string tid, string variant)
|
||
{
|
||
foreach (UserCardData ucard in deck_cards)
|
||
{
|
||
if (ucard.tid == tid && ucard.variant == variant)
|
||
return ucard;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
// 保存卡组
|
||
private void SaveDeck()
|
||
{
|
||
int totalCardCount = 0;
|
||
foreach (UserCardData card in deck_cards)
|
||
{
|
||
totalCardCount += card.quantity;
|
||
}
|
||
|
||
if (totalCardCount == 0)
|
||
{
|
||
ShowNotification("卡组为空,无法保存");
|
||
return;
|
||
}
|
||
|
||
if (totalCardCount != GameplayData.Get().deck_size)
|
||
{
|
||
ShowNotification("卡组数量错误,无法保存。当前总数: " + totalCardCount + ", 需要: " + GameplayData.Get().deck_size);
|
||
return;
|
||
}
|
||
|
||
UserData udata = Authenticator.Get().UserData;
|
||
UserDeckData udeck = new UserDeckData();
|
||
udeck.tid = current_deck_tid;
|
||
udeck.title = deck_title.text;
|
||
udeck.hero = new UserCardData();
|
||
udeck.hero.tid = GetSelectedHeroId();
|
||
udeck.hero.variant = VariantData.GetDefault().id;
|
||
udeck.cards = deck_cards.ToArray();
|
||
if (string.IsNullOrEmpty(udeck.cover))
|
||
{
|
||
udeck.cover = "wind";
|
||
}
|
||
saving = true;
|
||
|
||
if (Authenticator.Get().IsTest())
|
||
SaveDeckTest(udata, udeck);
|
||
|
||
if (Authenticator.Get().IsApi())
|
||
SaveDeckAPI(udata, udeck);
|
||
|
||
ShowDeckList();
|
||
}
|
||
|
||
private async void SaveDeckTest(UserData udata, UserDeckData udeck)
|
||
{
|
||
udata.SetDeck(udeck);
|
||
await Authenticator.Get().SaveUserData();
|
||
ReloadUserDecks();
|
||
}
|
||
|
||
public async void SaveDeckAPI(UserData udata, UserDeckData udeck)
|
||
{
|
||
string url = ApiClient.ServerURL + "/users/deck/" + udeck.tid;
|
||
string jdata = ApiTool.ToJson(udeck);
|
||
WebResponse res = await ApiClient.Get().SendPostRequest(url, jdata);
|
||
UserDeckData[] decks = ApiTool.JsonToArray<UserDeckData>(res.data);
|
||
saving = res.success;
|
||
|
||
if (res.success && decks != null)
|
||
{
|
||
udata.decks = decks;
|
||
await Authenticator.Get().SaveUserData();
|
||
ReloadUserDecks();
|
||
}
|
||
}
|
||
|
||
public async void DeleteDeck(string deck_tid)
|
||
{
|
||
UserData udata = Authenticator.Get().UserData;
|
||
UserDeckData udeck = udata.GetDeck(deck_tid);
|
||
List<UserDeckData> decks = new List<UserDeckData>(udata.decks);
|
||
decks.Remove(udeck);
|
||
udata.decks = decks.ToArray();
|
||
|
||
if (Authenticator.Get().IsApi())
|
||
{
|
||
string url = ApiClient.ServerURL + "/users/deck/" + deck_tid;
|
||
await ApiClient.Get().SendRequest(url, "DELETE", "");
|
||
}
|
||
|
||
await Authenticator.Get().SaveUserData();
|
||
ReloadUserDecks();
|
||
}
|
||
|
||
//---- Left Panel Filters Clicks -----------
|
||
|
||
public void OnClickTeam(IconButton button)
|
||
{
|
||
filter_team = null;
|
||
if (button.IsActive())
|
||
{
|
||
foreach (TeamData team in TeamData.GetAll())
|
||
{
|
||
if (button.GetValue() == TeamTitleData.Team(team.id))
|
||
filter_team = team;
|
||
}
|
||
}
|
||
RefreshCards();
|
||
}
|
||
|
||
public void OnChangeToggle()
|
||
{
|
||
RefreshCards();
|
||
}
|
||
|
||
public void OnChangeDropdown()
|
||
{
|
||
filter_dropdown = sort_dropdown.value;
|
||
RefreshCards();
|
||
}
|
||
|
||
public void OnChangeSearch()
|
||
{
|
||
filter_search = search.text;
|
||
RefreshCards();
|
||
}
|
||
|
||
//---- Card grid clicks ----------
|
||
|
||
public void OnClickCard(CardUI card)
|
||
{
|
||
if (!editing_deck)
|
||
{
|
||
CardZoomPanel.Get().ShowCard(card.GetCard(), card.GetVariant());
|
||
return;
|
||
}
|
||
|
||
CardData icard = card.GetCard();
|
||
VariantData variant = card.GetVariant();
|
||
if (icard != null)
|
||
{
|
||
int in_deck = CountDeckCards(icard, variant);
|
||
int in_deck_same = CountDeckCards(icard);
|
||
UserData udata = Authenticator.Get().UserData;
|
||
|
||
bool owner = IsCardOwned(udata, card.GetCard(), card.GetVariant(), in_deck + 1);
|
||
bool deck_limit = in_deck_same < GameplayData.Get().deck_duplicate_max;
|
||
bool ssr_limit = CheckSSRLimit(icard);
|
||
|
||
if (owner && deck_limit && ssr_limit)
|
||
{
|
||
AddDeckCard(icard, variant);
|
||
RefreshDeckCards();
|
||
}
|
||
else
|
||
{
|
||
if (!owner)
|
||
ShowNotification("卡牌数量不足");
|
||
else if (!deck_limit)
|
||
ShowNotification("相同卡牌最多只能添加 " + GameplayData.Get().deck_duplicate_max + " 张");
|
||
else if (!ssr_limit)
|
||
ShowNotification("SSR以上卡牌最多只能添加 " + GameplayData.Get().deck_ssr_max + " 张");
|
||
}
|
||
}
|
||
}
|
||
|
||
public void OnClickCardRight(CardUI card)
|
||
{
|
||
CardZoomPanel.Get().ShowCard(card.GetCard(), card.GetVariant());
|
||
}
|
||
|
||
//---- Right Panel Click -------
|
||
|
||
public void OnClickDeckLine(DeckLine line)
|
||
{
|
||
if (line.IsHidden() || saving)
|
||
return;
|
||
UserDeckData deck = line.GetUserDeck();
|
||
RefreshDeck(deck);
|
||
ShowDeckCards();
|
||
}
|
||
|
||
private void OnClickCardLine(DeckLine line)
|
||
{
|
||
CardData card = line.GetCard();
|
||
VariantData variant = line.GetVariant();
|
||
if (card != null)
|
||
{
|
||
RemoveDeckCard(card, variant);
|
||
}
|
||
|
||
RefreshDeckCards();
|
||
}
|
||
|
||
private void OnRightClickCardLine(DeckLine line)
|
||
{
|
||
CardData icard = line.GetCard();
|
||
if (icard != null)
|
||
CardZoomPanel.Get().ShowCard(icard, line.GetVariant());
|
||
}
|
||
|
||
// ---- Deck editing Click -----
|
||
|
||
public void OnClickSaveDeck()
|
||
{
|
||
if (!saving)
|
||
{
|
||
SaveDeck();
|
||
}
|
||
}
|
||
|
||
public void OnClickDeckBack()
|
||
{
|
||
ShowDeckList();
|
||
}
|
||
|
||
public void OnClickDeleteDeck()
|
||
{
|
||
if (editing_deck && !string.IsNullOrEmpty(current_deck_tid))
|
||
{
|
||
DeleteDeck(current_deck_tid);
|
||
}
|
||
}
|
||
|
||
public void OnClickDeckDelete(DeckLine line)
|
||
{
|
||
if (line.IsHidden())
|
||
return;
|
||
UserDeckData deck = line.GetUserDeck();
|
||
if (deck != null)
|
||
{
|
||
DeleteDeck(deck.tid);
|
||
}
|
||
}
|
||
|
||
public void OnChangeCover(DeckLine line)
|
||
{
|
||
current_deck_image = line.image;
|
||
ChangeCoverPanel.Get().OpenPanel(line);
|
||
}
|
||
|
||
// ---- Getters -----
|
||
|
||
public int CountDeckCards(CardData card, VariantData cvariant)
|
||
{
|
||
int count = 0;
|
||
foreach (UserCardData ucard in deck_cards)
|
||
{
|
||
if (ucard.tid == card.id && ucard.variant == cvariant.id)
|
||
count += ucard.quantity;
|
||
}
|
||
return count;
|
||
}
|
||
|
||
public int CountDeckCards(CardData card)
|
||
{
|
||
int count = 0;
|
||
foreach (UserCardData ucard in deck_cards)
|
||
{
|
||
if (ucard.tid == card.id)
|
||
count += ucard.quantity;
|
||
}
|
||
return count;
|
||
}
|
||
|
||
private bool IsCardOwned(UserData udata, CardData card, VariantData variant, int quantity)
|
||
{
|
||
return udata.GetCardQuantity(card, variant) >= quantity;
|
||
}
|
||
|
||
private bool CheckSSRLimit(CardData card)
|
||
{
|
||
// 检查卡牌稀有度是否 >= 4 (SSR级别)
|
||
if (card.rarity.rank >= 4)
|
||
{
|
||
int ssr_count = CountSSRCards();
|
||
return ssr_count < GameplayData.Get().deck_ssr_max;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private int CountSSRCards()
|
||
{
|
||
int count = 0;
|
||
foreach (UserCardData ucard in deck_cards)
|
||
{
|
||
CardData card = CardData.Get(ucard.tid);
|
||
if (card != null && card.rarity.rank >= 4)
|
||
{
|
||
count += ucard.quantity;
|
||
}
|
||
}
|
||
return count;
|
||
}
|
||
|
||
private string GetSelectedHeroId()
|
||
{
|
||
foreach (IconButton btn in hero_powers)
|
||
{
|
||
if (btn.IsActive())
|
||
return btn.GetValue();
|
||
}
|
||
return "";
|
||
}
|
||
|
||
private void ShowNotification(string message)
|
||
{
|
||
WarningText.ShowText(message);
|
||
}
|
||
|
||
public override void Show(bool instant = false)
|
||
{
|
||
base.Show(instant);
|
||
RefreshAll();
|
||
ShowDeckList();
|
||
}
|
||
|
||
public override void Hide(bool instant = false)
|
||
{
|
||
base.Hide(instant);
|
||
}
|
||
|
||
public static CollectionPanel Get()
|
||
{
|
||
return instance;
|
||
}
|
||
}
|
||
|
||
public struct CardDataQ
|
||
{
|
||
public CardData card;
|
||
public VariantData variant;
|
||
public int quantity;
|
||
}
|
||
} |