mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Add visual chooser for two lists and use it for and/or dig
This commit is contained in:
@@ -180,6 +180,20 @@ public class PlayerControllerAi extends PlayerController {
|
||||
return selecteds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GameEntity> List<T> chooseFromTwoListsForEffect(FCollectionView<T> optionList1, FCollectionView<T> optionList2,
|
||||
boolean optional, DelayedReveal delayedReveal, SpellAbility sa, String title, Player targetedPlayer) {
|
||||
if (delayedReveal != null) {
|
||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), delayedReveal.getMessagePrefix());
|
||||
}
|
||||
T selected1 = chooseSingleEntityForEffect(optionList1, null, sa, title, optional, targetedPlayer);
|
||||
T selected2 = chooseSingleEntityForEffect(optionList2, null, sa, title, optional || selected1!=null, targetedPlayer);
|
||||
List<T> selecteds = new ArrayList<T>();
|
||||
if ( selected1 != null ) { selecteds.add(selected1); }
|
||||
if ( selected2 != null ) { selecteds.add(selected2); }
|
||||
return selecteds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAbility chooseSingleSpellForEffect(java.util.List<SpellAbility> spells, SpellAbility sa, String title,
|
||||
Map<String, Object> params) {
|
||||
|
||||
@@ -187,7 +187,7 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
if (!andOrValid.equals("")) {
|
||||
andOrCards = CardLists.getValidCards(top, andOrValid.split(","), host.getController(), host, sa);
|
||||
andOrCards.removeAll((Collection<?>)valid);
|
||||
valid.addAll(andOrCards);
|
||||
valid.addAll(andOrCards); //pfps need to add andOr cards to valid to have set of all valid cards set up
|
||||
}
|
||||
else {
|
||||
andOrCards = new CardCollection();
|
||||
@@ -241,52 +241,6 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
} else {
|
||||
String prompt;
|
||||
|
||||
if (!andOrValid.equals("")) { // pfps: old way - to be fixed soon
|
||||
|
||||
if (sa.hasParam("PrimaryPrompt")) {
|
||||
prompt = sa.getParam("PrimaryPrompt");
|
||||
} else {
|
||||
prompt = "Choose a card to put into " + destZone1.name();
|
||||
if (destZone1.equals(ZoneType.Library)) {
|
||||
if (libraryPosition == -1) {
|
||||
prompt = "Choose a card to put on the bottom of {player's} library";
|
||||
}
|
||||
else if (libraryPosition == 0) {
|
||||
prompt = "Choose a card to put on top of {player's} library";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
movedCards = new CardCollection();
|
||||
for (int i = 0; i < destZone1ChangeNum || (anyNumber && i < numToDig); i++) {
|
||||
// let user get choice
|
||||
Card chosen = null;
|
||||
if (!valid.isEmpty()) {
|
||||
// If we're choosing multiple cards, only need to show the reveal dialog the first time through.
|
||||
boolean shouldReveal = (i == 0);
|
||||
chosen = chooser.getController().chooseSingleEntityForEffect(valid, shouldReveal ? delayedReveal : null, sa, prompt, anyNumber || optional, p);
|
||||
}
|
||||
else {
|
||||
if (i == 0) {
|
||||
chooser.getController().notifyOfValue(sa, null, "No valid cards");
|
||||
}
|
||||
}
|
||||
if (chosen == null) { break; }
|
||||
movedCards.add(chosen);
|
||||
valid.remove(chosen);
|
||||
if (!andOrValid.equals("")) {
|
||||
andOrCards.remove(chosen);
|
||||
if (!chosen.isValid(andOrValid.split(","), host.getController(), host, sa)) {
|
||||
valid = new CardCollection(andOrCards);
|
||||
}
|
||||
else if (!chosen.isValid(changeValid.split(","), host.getController(), host, sa)) {
|
||||
valid.removeAll((Collection<?>)andOrCards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else { // pfps: new way
|
||||
|
||||
if (sa.hasParam("PrimaryPrompt")) {
|
||||
prompt = sa.getParam("PrimaryPrompt");
|
||||
} else {
|
||||
@@ -294,26 +248,30 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
if (destZone1.equals(ZoneType.Library)) {
|
||||
if (libraryPosition == -1) {
|
||||
prompt = "Choose card(s) to put on the bottom of {player's} library";
|
||||
}
|
||||
else if (libraryPosition == 0) {
|
||||
} else if (libraryPosition == 0) {
|
||||
prompt = "Choose card(s) to put on top of {player's} library";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
movedCards = new CardCollection();
|
||||
int min = (anyNumber || optional) ? 0 : numToDig;
|
||||
int max = Math.max(destZone1ChangeNum, anyNumber ? valid.size() : 0);
|
||||
1 if (!valid.isEmpty()) {
|
||||
if (valid.isEmpty()) {
|
||||
chooser.getController().notifyOfValue(sa, null, "No valid cards");
|
||||
} else {
|
||||
if ( p == chooser ) { // the digger can still see all the dug cards when choosing
|
||||
chooser.getController().tempShowCards(top);
|
||||
}
|
||||
List<Card> chosen = chooser.getController().chooseEntitiesForEffect(valid, min, max, delayedReveal, sa, prompt, p);
|
||||
List<Card> chosen;
|
||||
if (!andOrValid.equals("")) {
|
||||
valid.removeAll(andOrCards); //pfps remove andOr cards to get two two choices set up correctly
|
||||
chosen = chooser.getController().chooseFromTwoListsForEffect(valid, andOrCards, optional, delayedReveal, sa, prompt, p);
|
||||
} else {
|
||||
int min = (anyNumber || optional) ? 0 : numToDig;
|
||||
int max = Math.max(destZone1ChangeNum, anyNumber ? valid.size() : 0);
|
||||
chosen = chooser.getController().chooseEntitiesForEffect(valid, min, max, delayedReveal, sa, prompt, p);
|
||||
}
|
||||
chooser.getController().endTempShowCards();
|
||||
movedCards.addAll(chosen);
|
||||
} else {
|
||||
chooser.getController().notifyOfValue(sa, null, "No valid cards");
|
||||
}
|
||||
}
|
||||
|
||||
if (!changeValid.isEmpty() && !sa.hasParam("ExileFaceDown") && !sa.hasParam("NoReveal")) {
|
||||
|
||||
@@ -115,6 +115,7 @@ public abstract class PlayerController {
|
||||
Map<String, Object> params);
|
||||
|
||||
public abstract <T extends GameEntity> List<T> chooseEntitiesForEffect(FCollectionView<T> optionList, int min, int max, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer);
|
||||
public abstract <T extends GameEntity> List<T> chooseFromTwoListsForEffect(FCollectionView<T> optionList1, FCollectionView<T> optionList2, boolean optional, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer);
|
||||
|
||||
public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message);
|
||||
public abstract boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode bidlife, String string, int bid, Player winner);
|
||||
|
||||
@@ -271,18 +271,18 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
// Magenta outline for when card was chosen to pay
|
||||
if (matchUI.isUsedToPay(getCard())) {
|
||||
g2d.setColor(Color.magenta);
|
||||
final int n2 = Math.max(1, Math.round(2 * cardWidth * CardPanel.SELECTED_BORDER_SIZE));
|
||||
final int n2 = Math.max(4, Math.round(2 * cardWidth * CardPanel.SELECTED_BORDER_SIZE));
|
||||
g2d.fillRoundRect(cardXOffset - n2, (cardYOffset - n2) + offset, cardWidth + (n2 * 2), cardHeight + (n2 * 2), cornerSize + n2, cornerSize + n2);
|
||||
} else if (matchUI.isSelectable(getCard())) { // Cyan outline for selectable cards
|
||||
g2d.setColor(Color.cyan);
|
||||
final int n2 = Math.max(1, Math.round(2 * cardWidth * CardPanel.SELECTED_BORDER_SIZE));
|
||||
final int n2 = Math.max(4, Math.round(2 * cardWidth * CardPanel.SELECTED_BORDER_SIZE));
|
||||
g2d.fillRoundRect(cardXOffset - n2, (cardYOffset - n2) + offset, cardWidth + (n2 * 2), cardHeight + (n2 * 2), cornerSize + n2, cornerSize + n2);
|
||||
}
|
||||
|
||||
// Green outline for hover
|
||||
if (isSelected) {
|
||||
g2d.setColor(Color.green);
|
||||
final int n = Math.max(1, Math.round(cardWidth * CardPanel.SELECTED_BORDER_SIZE));
|
||||
final int n = Math.max(4, Math.round(cardWidth * CardPanel.SELECTED_BORDER_SIZE));
|
||||
g2d.fillRoundRect(cardXOffset - n, (cardYOffset - n) + offset, cardWidth + (n * 2), cardHeight + (n * 2), cornerSize + n , cornerSize + n);
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,12 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GameEntity> List<T> chooseFromTwoListsForEffect(FCollectionView<T> optionList1, FCollectionView<T> optionList2, boolean optional, DelayedReveal delayedReveal, SpellAbility sa, String title, Player targetedPlayer) {
|
||||
// this isn't used
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||
return true;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
vCards.add(((Card)c).getView()) ;
|
||||
}
|
||||
}
|
||||
controller.getGui().setSelectables(vCards);
|
||||
getController().getGui().setSelectables(vCards);
|
||||
final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
|
||||
for (final GameEntity c : validChoices) {
|
||||
final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null ;
|
||||
@@ -52,8 +52,8 @@ public class InputSelectEntitiesFromList<T extends GameEntity> extends InputSele
|
||||
}
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
controller.getGui().updateZones(zonesToUpdate);
|
||||
zonesShown = controller.getGui().tempShowZones(controller.getPlayer().getView(),zonesToUpdate);
|
||||
getController().getGui().updateZones(zonesToUpdate);
|
||||
zonesShown = getController().getGui().tempShowZones(controller.getPlayer().getView(),zonesToUpdate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
package forge.match.input;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
import forge.util.collect.FCollection;
|
||||
import forge.util.collect.FCollectionView;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.player.PlayerZoneUpdate;
|
||||
import forge.player.PlayerZoneUpdates;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.FThreads;
|
||||
|
||||
public class InputSelectFromTwoLists<T extends GameEntity> extends InputSelectManyBase<T> {
|
||||
private final FCollectionView<T> valid1, valid2;
|
||||
private final FCollection<T> validBoth;
|
||||
private FCollectionView<T> validChoices;
|
||||
|
||||
protected final FCollection<T> selected = new FCollection<T>();
|
||||
protected final PlayerZoneUpdates zonesToUpdate = new PlayerZoneUpdates();
|
||||
protected Iterable<PlayerZoneUpdate> zonesShown; // want to hide these zones when input done
|
||||
|
||||
public InputSelectFromTwoLists(final PlayerControllerHuman controller, final boolean optional,
|
||||
final FCollectionView<T> list1, final FCollectionView<T> list2, final SpellAbility sa0) {
|
||||
super(controller, optional?0:1, 2, sa0);
|
||||
valid1 = list1;
|
||||
valid2 = list2;
|
||||
validBoth = new FCollection<T>(valid1);
|
||||
for ( T v : valid2 ) { validBoth.add(v); }
|
||||
validChoices = validBoth;
|
||||
setSelectables();
|
||||
|
||||
for (final GameEntity c : validChoices) {
|
||||
final Zone cz = (c instanceof Card) ? ((Card) c).getZone() : null ;
|
||||
if ( cz != null ) {
|
||||
zonesToUpdate.add(new PlayerZoneUpdate(cz.getPlayer().getView(),cz.getZoneType()));
|
||||
}
|
||||
}
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
controller.getGui().updateZones(zonesToUpdate);
|
||||
zonesShown = controller.getGui().tempShowZones(controller.getPlayer().getView(),zonesToUpdate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSelectables() {
|
||||
ArrayList<CardView> vCards = new ArrayList<CardView>();
|
||||
getController().getGui().clearSelectables();
|
||||
for ( T c : validChoices ) {
|
||||
if ( c instanceof Card ) {
|
||||
vCards.add(((Card)c).getView()) ;
|
||||
}
|
||||
}
|
||||
getController().getGui().setSelectables(vCards);
|
||||
}
|
||||
|
||||
private void setValid() {
|
||||
boolean selected1 = false, selected2 = false;
|
||||
for ( T s : selected ) {
|
||||
if ( valid1.contains(s) ) { selected1 = true; }
|
||||
if ( valid2.contains(s) ) { selected2 = true; }
|
||||
}
|
||||
validChoices = selected1 ? ( selected2 ? FCollection.getEmpty() : valid2 ) : ( selected2 ? valid1 : validBoth );
|
||||
setSelectables();
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override public void run() {
|
||||
getController().getGui().updateZones(zonesToUpdate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onCardSelected(final Card c, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) {
|
||||
if (!selectEntity(c)) {
|
||||
return false;
|
||||
}
|
||||
refresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivateAction(final Card card) {
|
||||
if (validChoices.contains(card)) {
|
||||
if (selected.contains(card)) {
|
||||
return "unselect card";
|
||||
}
|
||||
return "select card";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPlayerSelected(final Player p, final ITriggerEvent triggerEvent) {
|
||||
if (!selectEntity(p)) {
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Collection<T> getSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected boolean selectEntity(final GameEntity c) {
|
||||
if (!validChoices.contains(c) && !selected.contains(c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean entityWasSelected = selected.contains(c);
|
||||
if (entityWasSelected) {
|
||||
selected.remove(c);
|
||||
}
|
||||
else {
|
||||
selected.add((T)c);
|
||||
}
|
||||
setValid();
|
||||
onSelectStateChanged(c, !entityWasSelected);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// might re-define later
|
||||
@Override
|
||||
protected boolean hasEnoughTargets() { return selected.size() >= min; }
|
||||
@Override
|
||||
protected boolean hasAllTargets() { return selected.size() >= max; }
|
||||
|
||||
@Override
|
||||
protected String getMessage() {
|
||||
return max == Integer.MAX_VALUE
|
||||
? String.format(message, selected.size())
|
||||
: String.format(message, max - selected.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
getController().getGui().hideZones(getController().getPlayer().getView(),zonesShown);
|
||||
getController().getGui().clearSelectables();
|
||||
super.onStop();
|
||||
}
|
||||
}
|
||||
@@ -407,6 +407,15 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return choices;
|
||||
}
|
||||
|
||||
// pfps there should be a better way
|
||||
private GameEntity convertToEntity(final GameEntityView view) {
|
||||
if (view instanceof CardView) {
|
||||
return game.getCard((CardView) view);
|
||||
} else if (view instanceof PlayerView) {
|
||||
return game.getPlayer((PlayerView) view);
|
||||
} else return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends GameEntity> T chooseSingleEntityForEffect(final FCollectionView<T> optionList,
|
||||
@@ -429,12 +438,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return Iterables.getFirst(optionList, null);
|
||||
}
|
||||
|
||||
if (useSelectCardsInput(optionList)) {
|
||||
if (delayedReveal != null) {
|
||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
||||
delayedReveal.getMessagePrefix());
|
||||
}
|
||||
tempShow(optionList);
|
||||
if (delayedReveal != null) {
|
||||
tempShow(delayedReveal.getCards());
|
||||
}
|
||||
if (useSelectCardsInput(optionList)) {
|
||||
final InputSelectEntitiesFromList<T> input = new InputSelectEntitiesFromList<T>(this, isOptional ? 0 : 1, 1,
|
||||
optionList, sa);
|
||||
input.setCancelAllowed(isOptional);
|
||||
@@ -444,21 +452,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return Iterables.getFirst(input.getSelected(), null);
|
||||
}
|
||||
|
||||
tempShow(optionList);
|
||||
if (delayedReveal != null) {
|
||||
tempShow(delayedReveal.getCards());
|
||||
}
|
||||
final GameEntityView result = getGui().chooseSingleEntityForEffect(title,
|
||||
GameEntityView.getEntityCollection(optionList), delayedReveal, isOptional);
|
||||
endTempShowCards();
|
||||
|
||||
if (result instanceof CardView) {
|
||||
return (T) game.getCard((CardView) result);
|
||||
}
|
||||
if (result instanceof PlayerView) {
|
||||
return (T) game.getPlayer((PlayerView) result);
|
||||
}
|
||||
return null;
|
||||
return (T) convertToEntity(result);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -470,8 +467,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
Sentry.getContext().addExtra("Card", sa.getCardView().toString());
|
||||
Sentry.getContext().addExtra("SpellAbility", sa.toString());
|
||||
|
||||
// Human is supposed to read the message and understand from it what to
|
||||
// choose
|
||||
// Human is supposed to read the message and understand from it what to // choose
|
||||
if (optionList.isEmpty()) {
|
||||
if (delayedReveal != null) {
|
||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
||||
@@ -480,15 +476,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return null;
|
||||
}
|
||||
|
||||
if (useSelectCardsInput(optionList)) {
|
||||
// if (delayedReveal != null) {
|
||||
// reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
||||
// delayedReveal.getMessagePrefix());
|
||||
//}
|
||||
tempShow(optionList);
|
||||
if (delayedReveal != null) {
|
||||
tempShow(delayedReveal.getCards());
|
||||
}
|
||||
|
||||
tempShow(optionList);
|
||||
if (useSelectCardsInput(optionList)) {
|
||||
final InputSelectEntitiesFromList<T> input = new InputSelectEntitiesFromList<T>(this, min, max,
|
||||
optionList, sa);
|
||||
input.setCancelAllowed(true);
|
||||
@@ -497,16 +490,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
endTempShowCards();
|
||||
return (List<T>) input.getSelected();
|
||||
}
|
||||
|
||||
tempShow(optionList);
|
||||
if (delayedReveal != null) {
|
||||
tempShow(delayedReveal.getCards());
|
||||
}
|
||||
final List<GameEntityView> chosen = getGui().chooseEntitiesForEffect(title,
|
||||
GameEntityView.getEntityCollection(optionList), min, max, delayedReveal);
|
||||
endTempShowCards();
|
||||
|
||||
List<T> results = new ArrayList<>();
|
||||
List<T> results = new ArrayList<>(); //pfps I'm not sure that the chosens should be modified this way
|
||||
if (chosen instanceof List && chosen.size() > 0) {
|
||||
for (GameEntityView entry: chosen) {
|
||||
if (entry instanceof CardView) {
|
||||
@@ -520,6 +508,41 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GameEntity> List<T> chooseFromTwoListsForEffect(final FCollectionView<T> optionList1, final FCollectionView<T> optionList2,
|
||||
boolean optional, final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final Player targetedPlayer) {
|
||||
// Human is supposed to read the message and understand from it what to choose
|
||||
// useful details for debugging problems with the mass select logic
|
||||
Sentry.getContext().addExtra("Card", sa.getCardView().toString());
|
||||
Sentry.getContext().addExtra("SpellAbility", sa.toString());
|
||||
|
||||
if (delayedReveal != null) {
|
||||
tempShow(delayedReveal.getCards());
|
||||
}
|
||||
|
||||
tempShow(optionList1);
|
||||
tempShow(optionList2);
|
||||
|
||||
if (useSelectCardsInput(optionList1) && useSelectCardsInput(optionList2)) {
|
||||
final InputSelectFromTwoLists<T> input = new InputSelectFromTwoLists<T>(this, optional, optionList1, optionList2, sa);
|
||||
input.setCancelAllowed(optional);
|
||||
input.setMessage(MessageUtil.formatMessage(title, player, targetedPlayer));
|
||||
input.showAndWait();
|
||||
endTempShowCards();
|
||||
return (List<T>) input.getSelected();
|
||||
}
|
||||
|
||||
final GameEntityView result1 = getGui().chooseSingleEntityForEffect(title, GameEntityView.getEntityCollection(optionList1), null, optional);
|
||||
final GameEntityView result2 = getGui().chooseSingleEntityForEffect(title, GameEntityView.getEntityCollection(optionList2), null, (result1==null)?optional:true);
|
||||
endTempShowCards();
|
||||
List<T> results = new ArrayList<>();
|
||||
GameEntity entity1 = convertToEntity(result1);
|
||||
if (entity1!=null) { results.add((T) entity1); }
|
||||
GameEntity entity2 = convertToEntity(result2);
|
||||
if (entity2!=null) { results.add((T) entity2); }
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chooseNumber(final SpellAbility sa, final String title, final int min, final int max) {
|
||||
if (min >= max) {
|
||||
|
||||
Reference in New Issue
Block a user