mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Clean up
This commit is contained in:
@@ -29,7 +29,6 @@ public class BecomesBlockedAi extends SpellAbilityAi {
|
||||
if (tgt != null) {
|
||||
sa.resetTargets();
|
||||
CardCollection list = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), aiPlayer.getOpponents());
|
||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
list = CardLists.getNotKeyword(list, Keyword.TRAMPLE);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ public class BidLifeAi extends SpellAbilityAi {
|
||||
sa.resetTargets();
|
||||
if (tgt.canTgtCreature()) {
|
||||
List<Card> list = CardLists.getTargetableCards(AiAttackController.choosePreferredDefenderPlayer(aiPlayer).getCardsIn(ZoneType.Battlefield), sa);
|
||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
|
||||
if (list.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -471,8 +471,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
}
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
hPlay.remove(c);
|
||||
hPlay.remove(o);
|
||||
}
|
||||
}
|
||||
hPlay = CardLists.getTargetableCards(hPlay, sa);
|
||||
|
||||
@@ -91,8 +91,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
||||
}
|
||||
final List<Card> threatenedTargets = new ArrayList<>();
|
||||
// filter AIs battlefield by what I can target
|
||||
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard, sa);
|
||||
targetables = CardLists.getTargetableCards(targetables, sa);
|
||||
List<Card> targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
for (final Card c : targetables) {
|
||||
if (objects.contains(c)) {
|
||||
|
||||
@@ -104,7 +104,6 @@ public class EffectAi extends SpellAbilityAi {
|
||||
}
|
||||
} else {
|
||||
List<Card> list = game.getCombat().getAttackers();
|
||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
Card target = ComputerUtilCard.getBestCreatureAI(list);
|
||||
if (target == null) {
|
||||
|
||||
@@ -111,10 +111,8 @@ public class PhasesAi extends SpellAbilityAi {
|
||||
|
||||
private boolean phasesUnpreferredTargeting(final Game game, final SpellAbility sa, final boolean mandatory) {
|
||||
final Card source = sa.getHostCard();
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
|
||||
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa), sa);
|
||||
CardCollectionView list = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
// in general, if it's our own creature, choose the weakest one, if it's the opponent's creature,
|
||||
// choose the strongest one
|
||||
|
||||
@@ -87,9 +87,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
} else {
|
||||
sa.resetTargets();
|
||||
// filter AIs battlefield by what I can target
|
||||
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(),
|
||||
ai, hostCard, sa);
|
||||
targetables = CardLists.getTargetableCards(targetables, sa);
|
||||
List<Card> targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
if (targetables.size() == 0) {
|
||||
return false;
|
||||
@@ -149,14 +147,10 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
private static boolean regenMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
|
||||
final Card hostCard = sa.getHostCard();
|
||||
final Game game = ai.getGame();
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
sa.resetTargets();
|
||||
// filter AIs battlefield by what I can target
|
||||
CardCollectionView targetables = game.getCardsIn(ZoneType.Battlefield);
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard, sa);
|
||||
targetables = CardLists.getTargetableCards(targetables, sa);
|
||||
CardCollectionView targetables = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
||||
final List<Card> compTargetables = CardLists.filterControlledBy(targetables, ai);
|
||||
|
||||
if (targetables.size() == 0) {
|
||||
|
||||
@@ -145,7 +145,6 @@ public class TokenAi extends SpellAbilityAi {
|
||||
/*
|
||||
* readParameters() is called in checkPhaseRestrictions
|
||||
*/
|
||||
final Card source = sa.getHostCard();
|
||||
final Game game = ai.getGame();
|
||||
final Player opp = ai.getWeakestOpponent();
|
||||
|
||||
@@ -174,9 +173,7 @@ public class TokenAi extends SpellAbilityAi {
|
||||
sa.getTargets().add(ai);
|
||||
} else {
|
||||
// Flash Foliage
|
||||
CardCollection list = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
CardCollection list = CardLists.getTargetableCards(ai.getOpponents().getCardsIn(ZoneType.Battlefield), sa);
|
||||
CardCollection betterList = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card c) {
|
||||
|
||||
@@ -241,9 +241,7 @@ public class UntapAi extends SpellAbilityAi {
|
||||
final Card source = sa.getHostCard();
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
|
||||
CardCollection list = CardLists.getValidCards(source.getGame().getCardsIn(ZoneType.Battlefield),
|
||||
tgt.getValidTgts(), source.getController(), source, sa);
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
CardCollection list = CardLists.getTargetableCards(source.getGame().getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
// filter by enchantments and planeswalkers, their tapped state doesn't matter.
|
||||
final String[] tappablePermanents = { "Enchantment", "Planeswalker" };
|
||||
|
||||
@@ -231,15 +231,15 @@ public class CardLists {
|
||||
}
|
||||
|
||||
public static CardCollection getTargetableCards(Iterable<Card> cardList, SpellAbility source) {
|
||||
CardCollection result = CardLists.filter(cardList, CardPredicates.isTargetableBy(source));
|
||||
final CardCollection result = CardLists.filter(cardList, CardPredicates.isTargetableBy(source));
|
||||
// Filter more cards that can only be detected along with other candidates
|
||||
if (source.getTargets().isEmpty() && source.usesTargeting() && source.getMinTargets() >= 2) {
|
||||
CardCollection removeList = new CardCollection();
|
||||
TargetRestrictions tr = source.getTargetRestrictions();
|
||||
for (final Card card : cardList) {
|
||||
for (final Card card : result) {
|
||||
if (tr.isSameController()) {
|
||||
boolean found = false;
|
||||
for (final Card card2 : cardList) {
|
||||
for (final Card card2 : result) {
|
||||
if (card != card2 && card.getController() == card2.getController()) {
|
||||
found = true;
|
||||
break;
|
||||
@@ -252,7 +252,7 @@ public class CardLists {
|
||||
|
||||
if (tr.isWithoutSameCreatureType()) {
|
||||
boolean found = false;
|
||||
for (final Card card2 : cardList) {
|
||||
for (final Card card2 : result) {
|
||||
if (card != card2 && !card.sharesCreatureTypeWith(card2)) {
|
||||
found = true;
|
||||
break;
|
||||
@@ -265,7 +265,7 @@ public class CardLists {
|
||||
|
||||
if (tr.isWithSameCreatureType()) {
|
||||
boolean found = false;
|
||||
for (final Card card2 : cardList) {
|
||||
for (final Card card2 : result) {
|
||||
if (card != card2 && card.sharesCreatureTypeWith(card2)) {
|
||||
found = true;
|
||||
break;
|
||||
@@ -278,7 +278,7 @@ public class CardLists {
|
||||
|
||||
if (tr.isWithSameCardType()) {
|
||||
boolean found = false;
|
||||
for (final Card card2 : cardList) {
|
||||
for (final Card card2 : result) {
|
||||
if (card != card2 && card.sharesCardTypeWith(card2)) {
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@@ -35,7 +35,6 @@ import forge.card.MagicColor;
|
||||
import forge.game.CardTraitBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
@@ -550,9 +549,9 @@ public final class CardUtil {
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
final List<ZoneType> zone = tgt.getZone();
|
||||
|
||||
final boolean canTgtStack = zone.contains(ZoneType.Stack);
|
||||
List<Card> validCards = CardLists.getValidCards(game.getCardsIn(zone), tgt.getValidTgts(), ability.getActivatingPlayer(), activatingCard, ability);
|
||||
List<Card> choices = CardLists.getTargetableCards(validCards, ability);
|
||||
final boolean canTgtStack = zone.contains(ZoneType.Stack);
|
||||
if (canTgtStack) {
|
||||
// Since getTargetableCards doesn't have additional checks if one of the Zones is stack
|
||||
// Remove the activating card from targeting itself if its on the Stack
|
||||
@@ -560,56 +559,11 @@ public final class CardUtil {
|
||||
choices.remove(activatingCard);
|
||||
}
|
||||
}
|
||||
List<GameObject> targetedObjects = ability.getUniqueTargets();
|
||||
|
||||
// Remove cards already targeted
|
||||
final List<Card> targeted = Lists.newArrayList(ability.getTargets().getTargetCards());
|
||||
choices.removeAll(targeted);
|
||||
|
||||
// Remove cards exceeding total CMC
|
||||
if (ability.hasParam("MaxTotalTargetCMC")) {
|
||||
int totalCMCTargeted = 0;
|
||||
for (final Card c : targeted) {
|
||||
totalCMCTargeted += c.getCMC();
|
||||
}
|
||||
|
||||
final List<Card> choicesCopy = Lists.newArrayList(choices);
|
||||
for (final Card c : choicesCopy) {
|
||||
if (c.getCMC() > tgt.getMaxTotalCMC(activatingCard, ability) - totalCMCTargeted) {
|
||||
choices.remove(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove cards exceeding total power
|
||||
if (ability.hasParam("MaxTotalTargetPower")) {
|
||||
int totalPowerTargeted = 0;
|
||||
for (final Card c : targeted) {
|
||||
totalPowerTargeted += c.getNetPower();
|
||||
}
|
||||
|
||||
final List<Card> choicesCopy = Lists.newArrayList(choices);
|
||||
for (final Card c : choicesCopy) {
|
||||
if (c.getNetPower() > tgt.getMaxTotalPower(activatingCard, ability) - totalPowerTargeted) {
|
||||
choices.remove(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all cards (including subability targets) must have the same controller
|
||||
if (tgt.isSameController() && !targetedObjects.isEmpty()) {
|
||||
final List<Card> list = Lists.newArrayList();
|
||||
for (final Object o : targetedObjects) {
|
||||
if (o instanceof Card) {
|
||||
list.add((Card) o);
|
||||
}
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
final Card card = list.get(0);
|
||||
choices = CardLists.filter(choices, CardPredicates.sharesControllerWith(card));
|
||||
}
|
||||
}
|
||||
|
||||
return choices;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.Map;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ForwardingList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
@@ -100,8 +99,8 @@ public class TargetChoices extends ForwardingList<GameObject> implements Cloneab
|
||||
return Iterables.filter(targets, SpellAbility.class);
|
||||
}
|
||||
|
||||
public final List<GameEntity> getTargetEntities() {
|
||||
return Lists.newArrayList(Iterables.filter(targets, GameEntity.class));
|
||||
public final Iterable<GameEntity> getTargetEntities() {
|
||||
return Iterables.filter(targets, GameEntity.class);
|
||||
}
|
||||
|
||||
public final boolean isTargetingAnyCard() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
Name:Barrin's Spite
|
||||
ManaCost:2 U B
|
||||
Types:Sorcery
|
||||
A:SP$ Pump | Cost$ 2 U B | ValidTgts$ Creature | TgtPrompt$ Choose two target creatures controlled by the same player | TargetMin$ 2 | TargetMax$ 2 | TargetUnique$ True | TargetsWithSameController$ True | RememberTargets$ True | IsCurse$ True | SubAbility$ DBChooseSac | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures controlled by the same player. Their controller chooses and sacrifices one of them. Return the other to its owner's hand.
|
||||
SVar:DBChooseSac:DB$ ChooseCard | Choices$ Card.IsRemembered | Defined$ TargetedController | ChoiceTitle$ Choose one to sacrifice | ForgetChosen$ True | SubAbility$ DBSac | StackDescription$ None | AILogic$ WorstCard
|
||||
A:SP$ Pump | Cost$ 2 U B | ValidTgts$ Creature | TgtPrompt$ Choose two target creatures controlled by the same player | TargetMin$ 2 | TargetMax$ 2 | TargetUnique$ True | TargetsWithSameController$ True | IsCurse$ True | SubAbility$ DBChooseSac | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures controlled by the same player. Their controller chooses and sacrifices one of them. Return the other to its owner's hand.
|
||||
SVar:DBChooseSac:DB$ ChooseCard | DefinedCards$ Targeted | Defined$ TargetedController | ChoiceTitle$ Choose one to sacrifice | SubAbility$ DBSac | StackDescription$ None | AILogic$ WorstCard
|
||||
SVar:DBSac:DB$ Destroy | Defined$ ChosenCard | Sacrifice$ True | SubAbility$ DBBounce | StackDescription$ None
|
||||
SVar:DBBounce:DB$ ChangeZone | Defined$ Remembered | Origin$ Battlefield | Destination$ Hand | SubAbility$ DBCleanup | StackDescription$ None
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:DBBounce:DB$ ChangeZone | Defined$ Targeted | Origin$ Battlefield | Destination$ Hand | StackDescription$ None
|
||||
Oracle:Choose two target creatures controlled by the same player. Their controller chooses and sacrifices one of them. Return the other to its owner's hand.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
Name:Incriminate
|
||||
ManaCost:1 B
|
||||
Types:Sorcery
|
||||
A:SP$ Pump | Cost$ 1 B | ValidTgts$ Creature | TgtPrompt$ Choose two target creatures controlled by the same player | TargetMin$ 2 | TargetMax$ 2 | TargetUnique$ True | TargetsWithSameController$ True | RememberTargets$ True | IsCurse$ True | SubAbility$ DBChooseSac | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures controlled by the same player. That player sacrifices one of them.
|
||||
SVar:DBChooseSac:DB$ ChooseCard | Choices$ Card.IsRemembered | Defined$ TargetedController | ChoiceTitle$ Choose one to sacrifice | SubAbility$ DBSac | StackDescription$ None | AILogic$ WorstCard
|
||||
SVar:DBSac:DB$ Destroy | Defined$ ChosenCard | Sacrifice$ True | SubAbility$ DBCleanup | StackDescription$ None
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
A:SP$ Pump | Cost$ 1 B | ValidTgts$ Creature | TgtPrompt$ Choose two target creatures controlled by the same player | TargetMin$ 2 | TargetMax$ 2 | TargetUnique$ True | TargetsWithSameController$ True | IsCurse$ True | SubAbility$ DBChooseSac | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures controlled by the same player. That player sacrifices one of them.
|
||||
SVar:DBChooseSac:DB$ ChooseCard | DefinedCards$ Targeted | Defined$ TargetedController | ChoiceTitle$ Choose one to sacrifice | SubAbility$ DBSac | StackDescription$ None | AILogic$ WorstCard
|
||||
SVar:DBSac:DB$ Destroy | Defined$ ChosenCard | Sacrifice$ True | StackDescription$ None
|
||||
Oracle:Choose two target creatures controlled by the same player. That player sacrifices one of them.
|
||||
|
||||
@@ -2,6 +2,6 @@ Name:Mutiny
|
||||
ManaCost:R
|
||||
Types:Sorcery
|
||||
A:SP$ Pump | Cost$ R | ValidTgts$ Creature.OppCtrl | AILogic$ PowerDmg | TgtPrompt$ Select target creature an opponent controls | SubAbility$ MutinyDamage | StackDescription$ None | SpellDescription$ Target creature an opponent controls deals damage equal to its power to another target creature that player controls.
|
||||
SVar:MutinyDamage:DB$ DealDamage | ValidTgts$ Creature.OppCtrl | TargetUnique$ True | TargetsWithSameController$ True | AILogic$ PowerDmg | NumDmg$ X | DamageSource$ ParentTarget
|
||||
SVar:MutinyDamage:DB$ DealDamage | ValidTgts$ Creature | TargetUnique$ True | TargetsWithDefinedController$ ParentTargetedController | AILogic$ PowerDmg | NumDmg$ X | DamageSource$ ParentTarget
|
||||
SVar:X:ParentTargeted$CardPower
|
||||
Oracle:Target creature an opponent controls deals damage equal to its power to another target creature that player controls.
|
||||
|
||||
@@ -213,6 +213,20 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("MaxTotalTargetPower")) {
|
||||
int maxTotalPower = tgt.getMaxTotalPower(sa.getHostCard(), sa);
|
||||
if (maxTotalPower > 0) {
|
||||
int soFar = Aggregates.sum(sa.getTargets().getTargetCards(), CardPredicates.Accessors.fnGetNetPower);
|
||||
if (!sa.isTargeting(card)) {
|
||||
soFar += card.getNetPower();
|
||||
}
|
||||
if (soFar > maxTotalPower) {
|
||||
showMessage(sa.getHostCard() + " - Cannot target this card (power limit exceeded)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all cards must have same controllers
|
||||
if (tgt.isSameController()) {
|
||||
final List<Player> targetedControllers = new ArrayList<>();
|
||||
@@ -228,20 +242,6 @@ public final class InputSelectTargets extends InputSyncronizedBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("MaxTotalTargetPower")) {
|
||||
int maxTotalPower = tgt.getMaxTotalPower(sa.getHostCard(), sa);
|
||||
if (maxTotalPower > 0) {
|
||||
int soFar = Aggregates.sum(sa.getTargets().getTargetCards(), CardPredicates.Accessors.fnGetNetPower);
|
||||
if (!sa.isTargeting(card)) {
|
||||
soFar += card.getNetPower();
|
||||
}
|
||||
if (soFar > maxTotalPower) {
|
||||
showMessage(sa.getHostCard() + " - Cannot target this card (power limit exceeded)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all cards must have different controllers
|
||||
if (tgt.isDifferentControllers()) {
|
||||
final List<Player> targetedControllers = new ArrayList<>();
|
||||
|
||||
@@ -2012,17 +2012,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
boolean result = select.chooseTargets(null, null, null, false, canFilterMustTarget);
|
||||
|
||||
final List<GameEntity> targets = currentAbility.getTargets().getTargetEntities();
|
||||
final Iterable<GameEntity> targets = currentAbility.getTargets().getTargetEntities();
|
||||
final int size = Iterables.size(targets);
|
||||
int amount = currentAbility.getStillToDivide();
|
||||
|
||||
// assign divided as you choose values
|
||||
if (result && targets.size() > 0 && amount > 0) {
|
||||
if (result && size > 0 && amount > 0) {
|
||||
if (currentAbility.hasParam("DividedUpTo")) {
|
||||
amount = chooseNumber(currentAbility, localizer.getMessage("lblHowMany"), targets.size(), amount);
|
||||
amount = chooseNumber(currentAbility, localizer.getMessage("lblHowMany"), size, amount);
|
||||
}
|
||||
if (targets.size() == 1) {
|
||||
currentAbility.addDividedAllocation(targets.get(0), amount);
|
||||
} else if (targets.size() == amount) {
|
||||
if (size == 1) {
|
||||
currentAbility.addDividedAllocation(Iterables.get(targets, 0), amount);
|
||||
} else if (size == amount) {
|
||||
for (GameEntity e : targets) {
|
||||
currentAbility.addDividedAllocation(e, 1);
|
||||
}
|
||||
@@ -2030,7 +2031,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
for (GameEntity e : targets) {
|
||||
currentAbility.addDividedAllocation(e, 0);
|
||||
}
|
||||
} else if (targets.size() > amount) {
|
||||
} else if (size > amount) {
|
||||
return false;
|
||||
} else {
|
||||
String label = "lblDamage";
|
||||
@@ -2041,7 +2042,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
label = localizer.getMessage(label).toLowerCase();
|
||||
final CardView vSource = CardView.get(currentAbility.getHostCard());
|
||||
final Map<Object, Integer> vTargets = new HashMap<>(targets.size());
|
||||
final Map<Object, Integer> vTargets = new HashMap<>(size);
|
||||
for (GameEntity e : targets) {
|
||||
vTargets.put(GameEntityView.get(e), amount);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public class TargetSelection {
|
||||
// Cancel ability if there aren't any valid Candidates
|
||||
return false;
|
||||
}
|
||||
if (isMandatory() && candidates.size() == 0 && hasEnoughTargets) {
|
||||
if (isMandatory() && candidates.isEmpty() && hasEnoughTargets) {
|
||||
// Mandatory target selection, that has no candidates but enough targets (Min == 0, but no choices)
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user