package com.evacipated.cardcrawl.mod.stslib.actions.common; import com.megacrit.cardcrawl.actions.AbstractGameAction; import com.megacrit.cardcrawl.cards.AbstractCard; 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 SelectCardsInHandAction extends AbstractGameAction { private Predicate<AbstractCard> predicate; private Consumer<List<AbstractCard>> callback; private String text; private boolean anyNumber, canPickZero; private ArrayList<AbstractCard> hand; private ArrayList<AbstractCard> tempHand; /** * @param amount - max number of cards player can select * @param textForSelect - text that will be displayed at the top of the screen. It will be automatically attached to base game "Select X card/s to " text * @param anyNumber - whether player has to select exact number of cards or any number up to. * false for exact number * @param canPickZero - whether player can skip selection by picking zero cards. * @param cardFilter - filter that will be applied to cards in hand. * 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. * 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 SelectCardsInHandAction(int amount, String textForSelect, boolean anyNumber, boolean canPickZero, Predicate<AbstractCard> cardFilter, Consumer<List<AbstractCard>> callback) { this.amount = amount; this.duration = this.startDuration = Settings.ACTION_DUR_XFAST; text = textForSelect; this.anyNumber = anyNumber; this.canPickZero = canPickZero; this.predicate = cardFilter; this.callback = callback; this.hand = AbstractDungeon.player.hand.group; tempHand = new ArrayList<>(); tempHand.addAll(hand); } public SelectCardsInHandAction(int amount, String textForSelect, Predicate<AbstractCard> cardFilter, Consumer<List<AbstractCard>> callback) { this(amount, textForSelect, false, false, cardFilter, callback); } public SelectCardsInHandAction(int amount, String textForSelect, Consumer<List<AbstractCard>> callback) { this(amount, textForSelect, false, false, (c -> true), callback); } public SelectCardsInHandAction(String textForSelect, Predicate<AbstractCard> cardFilter, Consumer<List<AbstractCard>> callback) { this(1, textForSelect, false, false, cardFilter, callback); } public SelectCardsInHandAction(String textForSelect, Consumer<List<AbstractCard>> callback) { this(1, textForSelect, false, false, (c -> true), callback); } @Override public void update() { if (this.duration == this.startDuration) { if ((hand.size() == 0) || (hand.stream().noneMatch(predicate)) || callback == null) { isDone = true; return; } if (hand.stream().filter(predicate).count() <= amount && !anyNumber && !canPickZero) { callback.accept(hand.stream().filter(predicate).collect(Collectors.toList())); AbstractDungeon.player.hand.refreshHandLayout(); AbstractDungeon.player.hand.applyPowers(); isDone = true; return; } tempHand.removeIf(predicate); if (tempHand.size() > 0) hand.removeIf(c -> tempHand.contains(c)); AbstractDungeon.handCardSelectScreen.open(text, amount, anyNumber, canPickZero); tickDuration(); return; } if (!AbstractDungeon.handCardSelectScreen.wereCardsRetrieved) { callback.accept(AbstractDungeon.handCardSelectScreen.selectedCards.group); hand.addAll(AbstractDungeon.handCardSelectScreen.selectedCards.group); AbstractDungeon.handCardSelectScreen.wereCardsRetrieved = true; AbstractDungeon.handCardSelectScreen.selectedCards.group.clear(); if (tempHand.size() > 0) hand.addAll(tempHand); AbstractDungeon.player.hand.refreshHandLayout(); AbstractDungeon.player.hand.applyPowers(); isDone = true; return; } tickDuration(); } }