package com.evacipated.cardcrawl.mod.stslib.actions.common; import com.megacrit.cardcrawl.actions.AbstractGameAction; import com.megacrit.cardcrawl.cards.AbstractCard; import com.megacrit.cardcrawl.cards.CardGroup; import com.megacrit.cardcrawl.core.Settings; import com.megacrit.cardcrawl.dungeons.AbstractDungeon; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; public class SelectCardsAction extends AbstractGameAction { private Consumer<List<AbstractCard>> callback; private String text; private boolean anyNumber; private CardGroup selectGroup; /** * @param group - ArrayList of cards to filter and select from. * Example: AbstractDungeon.player.discardPile.group * @param amount - maximum number of cards allowed for selectoin * @param textForSelect - text that will be displayed on the grid select screen at the bottom. It will show just this text with nothing else added by itself. * @param anyNumber - whether player has to select exact number of cards (amount) or any number up to, including 0. * false for exact number. * @param cardFilter - Filters the cards in the group. * Example: if you want to display only skills, it would be c -> c.type == CardType.SKILL * If you don't need the filter, set it as c -> true * @param callback - What to do with cards selected. Accepts a list with cards selected. The list would only contain one element if it's "Select one card" * Example: if you want to lose 1 hp and upgrade each card selected, it would look like * list -> { * addToBot( * new LoseHPAction(player, player, list.size()); * list.forEach(c -> c.upgrade()); * )} * * if there's no callback the action will not trigger simply because you told player to "select cards to do nothing with them" * */ public SelectCardsAction(ArrayList<AbstractCard> group, int amount, String textForSelect, boolean anyNumber, Predicate<AbstractCard> cardFilter, Consumer<List<AbstractCard>> callback) { this.amount = amount; this.duration = this.startDuration = Settings.ACTION_DUR_XFAST; text = textForSelect; this.anyNumber = anyNumber; this.callback = callback; this.selectGroup = new CardGroup(CardGroup.CardGroupType.UNSPECIFIED); this.selectGroup.group.addAll(group.stream().distinct().filter(cardFilter).collect(Collectors.toList())); // It's distinct() because if i don't it may cause the infamous "jiggle" when you see a grid of cards with a same object in different locations. } public SelectCardsAction(ArrayList<AbstractCard> group, String textForSelect, boolean anyNumber, Predicate<AbstractCard> cardFilter, Consumer<List<AbstractCard>> callback) { this(group, 1, textForSelect, anyNumber, cardFilter, callback); } public SelectCardsAction(ArrayList<AbstractCard> group, String textForSelect, Predicate<AbstractCard> cardFilter, Consumer<List<AbstractCard>> callback) { this(group, 1, textForSelect, false, cardFilter, callback); } public SelectCardsAction(ArrayList<AbstractCard> group, String textForSelect, Consumer<List<AbstractCard>> callback) { this(group, 1, textForSelect, false, c -> true, callback); } public SelectCardsAction(ArrayList<AbstractCard> group, int amount, String textForSelect, Consumer<List<AbstractCard>> callback) { this(group, amount, textForSelect, false, c -> true, callback); } @Override public void update() { if (this.duration == this.startDuration) { if ((selectGroup.size() == 0) || callback == null) { isDone = true; return; } if (selectGroup.size() <= amount && !anyNumber) { callback.accept(selectGroup.group); isDone = true; return; } AbstractDungeon.gridSelectScreen.open(selectGroup, amount, anyNumber, text); tickDuration(); } if (AbstractDungeon.gridSelectScreen.selectedCards.size() != 0) { callback.accept(AbstractDungeon.gridSelectScreen.selectedCards); AbstractDungeon.gridSelectScreen.selectedCards.clear(); AbstractDungeon.player.hand.refreshHandLayout(); isDone = true; return; } tickDuration(); } }