This commit is contained in:
tool4EvEr
2023-03-29 16:02:58 +02:00
parent 65964ad586
commit 99f8cca233
18 changed files with 47 additions and 113 deletions

View File

@@ -29,7 +29,6 @@ public class BecomesBlockedAi extends SpellAbilityAi {
if (tgt != null) { if (tgt != null) {
sa.resetTargets(); sa.resetTargets();
CardCollection list = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), aiPlayer.getOpponents()); 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.getTargetableCards(list, sa);
list = CardLists.getNotKeyword(list, Keyword.TRAMPLE); list = CardLists.getNotKeyword(list, Keyword.TRAMPLE);

View File

@@ -26,7 +26,6 @@ public class BidLifeAi extends SpellAbilityAi {
sa.resetTargets(); sa.resetTargets();
if (tgt.canTgtCreature()) { if (tgt.canTgtCreature()) {
List<Card> list = CardLists.getTargetableCards(AiAttackController.choosePreferredDefenderPlayer(aiPlayer).getCardsIn(ZoneType.Battlefield), sa); 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()) { if (list.isEmpty()) {
return false; return false;
} }

View File

@@ -471,8 +471,7 @@ public class DamageDealAi extends DamageAiBase {
} }
for (final Object o : objects) { for (final Object o : objects) {
if (o instanceof Card) { if (o instanceof Card) {
final Card c = (Card) o; hPlay.remove(o);
hPlay.remove(c);
} }
} }
hPlay = CardLists.getTargetableCards(hPlay, sa); hPlay = CardLists.getTargetableCards(hPlay, sa);

View File

@@ -91,8 +91,7 @@ public class DamagePreventAi extends SpellAbilityAi {
} }
final List<Card> threatenedTargets = new ArrayList<>(); final List<Card> threatenedTargets = new ArrayList<>();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard, sa); List<Card> targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
targetables = CardLists.getTargetableCards(targetables, sa);
for (final Card c : targetables) { for (final Card c : targetables) {
if (objects.contains(c)) { if (objects.contains(c)) {

View File

@@ -104,7 +104,6 @@ public class EffectAi extends SpellAbilityAi {
} }
} else { } else {
List<Card> list = game.getCombat().getAttackers(); List<Card> list = game.getCombat().getAttackers();
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
list = CardLists.getTargetableCards(list, sa); list = CardLists.getTargetableCards(list, sa);
Card target = ComputerUtilCard.getBestCreatureAI(list); Card target = ComputerUtilCard.getBestCreatureAI(list);
if (target == null) { if (target == null) {

View File

@@ -111,10 +111,8 @@ public class PhasesAi extends SpellAbilityAi {
private boolean phasesUnpreferredTargeting(final Game game, final SpellAbility sa, final boolean mandatory) { private boolean phasesUnpreferredTargeting(final Game game, final SpellAbility sa, final boolean mandatory) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); CardCollectionView list = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa), sa);
// in general, if it's our own creature, choose the weakest one, if it's the opponent's creature, // in general, if it's our own creature, choose the weakest one, if it's the opponent's creature,
// choose the strongest one // choose the strongest one

View File

@@ -87,9 +87,7 @@ public class RegenerateAi extends SpellAbilityAi {
} else { } else {
sa.resetTargets(); sa.resetTargets();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), List<Card> targetables = CardLists.getTargetableCards(ai.getCardsIn(ZoneType.Battlefield), sa);
ai, hostCard, sa);
targetables = CardLists.getTargetableCards(targetables, sa);
if (targetables.size() == 0) { if (targetables.size() == 0) {
return false; return false;
@@ -149,14 +147,10 @@ public class RegenerateAi extends SpellAbilityAi {
} }
private static boolean regenMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { private static boolean regenMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
final Card hostCard = sa.getHostCard();
final Game game = ai.getGame(); final Game game = ai.getGame();
final TargetRestrictions tgt = sa.getTargetRestrictions();
sa.resetTargets(); sa.resetTargets();
// filter AIs battlefield by what I can target // filter AIs battlefield by what I can target
CardCollectionView targetables = game.getCardsIn(ZoneType.Battlefield); CardCollectionView targetables = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard, sa);
targetables = CardLists.getTargetableCards(targetables, sa);
final List<Card> compTargetables = CardLists.filterControlledBy(targetables, ai); final List<Card> compTargetables = CardLists.filterControlledBy(targetables, ai);
if (targetables.size() == 0) { if (targetables.size() == 0) {

View File

@@ -145,7 +145,6 @@ public class TokenAi extends SpellAbilityAi {
/* /*
* readParameters() is called in checkPhaseRestrictions * readParameters() is called in checkPhaseRestrictions
*/ */
final Card source = sa.getHostCard();
final Game game = ai.getGame(); final Game game = ai.getGame();
final Player opp = ai.getWeakestOpponent(); final Player opp = ai.getWeakestOpponent();
@@ -174,9 +173,7 @@ public class TokenAi extends SpellAbilityAi {
sa.getTargets().add(ai); sa.getTargets().add(ai);
} else { } else {
// Flash Foliage // Flash Foliage
CardCollection list = ai.getOpponents().getCardsIn(ZoneType.Battlefield); CardCollection list = CardLists.getTargetableCards(ai.getOpponents().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
CardCollection betterList = CardLists.filter(list, new Predicate<Card>() { CardCollection betterList = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
public boolean apply(Card c) { public boolean apply(Card c) {

View File

@@ -241,9 +241,7 @@ public class UntapAi extends SpellAbilityAi {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollection list = CardLists.getValidCards(source.getGame().getCardsIn(ZoneType.Battlefield), CardCollection list = CardLists.getTargetableCards(source.getGame().getCardsIn(ZoneType.Battlefield), sa);
tgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
// filter by enchantments and planeswalkers, their tapped state doesn't matter. // filter by enchantments and planeswalkers, their tapped state doesn't matter.
final String[] tappablePermanents = { "Enchantment", "Planeswalker" }; final String[] tappablePermanents = { "Enchantment", "Planeswalker" };

View File

@@ -231,15 +231,15 @@ public class CardLists {
} }
public static CardCollection getTargetableCards(Iterable<Card> cardList, SpellAbility source) { 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 // Filter more cards that can only be detected along with other candidates
if (source.getTargets().isEmpty() && source.usesTargeting() && source.getMinTargets() >= 2) { if (source.getTargets().isEmpty() && source.usesTargeting() && source.getMinTargets() >= 2) {
CardCollection removeList = new CardCollection(); CardCollection removeList = new CardCollection();
TargetRestrictions tr = source.getTargetRestrictions(); TargetRestrictions tr = source.getTargetRestrictions();
for (final Card card : cardList) { for (final Card card : result) {
if (tr.isSameController()) { if (tr.isSameController()) {
boolean found = false; boolean found = false;
for (final Card card2 : cardList) { for (final Card card2 : result) {
if (card != card2 && card.getController() == card2.getController()) { if (card != card2 && card.getController() == card2.getController()) {
found = true; found = true;
break; break;
@@ -252,7 +252,7 @@ public class CardLists {
if (tr.isWithoutSameCreatureType()) { if (tr.isWithoutSameCreatureType()) {
boolean found = false; boolean found = false;
for (final Card card2 : cardList) { for (final Card card2 : result) {
if (card != card2 && !card.sharesCreatureTypeWith(card2)) { if (card != card2 && !card.sharesCreatureTypeWith(card2)) {
found = true; found = true;
break; break;
@@ -265,7 +265,7 @@ public class CardLists {
if (tr.isWithSameCreatureType()) { if (tr.isWithSameCreatureType()) {
boolean found = false; boolean found = false;
for (final Card card2 : cardList) { for (final Card card2 : result) {
if (card != card2 && card.sharesCreatureTypeWith(card2)) { if (card != card2 && card.sharesCreatureTypeWith(card2)) {
found = true; found = true;
break; break;
@@ -278,7 +278,7 @@ public class CardLists {
if (tr.isWithSameCardType()) { if (tr.isWithSameCardType()) {
boolean found = false; boolean found = false;
for (final Card card2 : cardList) { for (final Card card2 : result) {
if (card != card2 && card.sharesCardTypeWith(card2)) { if (card != card2 && card.sharesCardTypeWith(card2)) {
found = true; found = true;
break; break;

View File

@@ -35,7 +35,6 @@ import forge.card.MagicColor;
import forge.game.CardTraitBase; import forge.game.CardTraitBase;
import forge.game.Game; import forge.game.Game;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.GameObject;
import forge.game.ability.AbilityKey; import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
@@ -550,9 +549,9 @@ public final class CardUtil {
final Game game = ability.getActivatingPlayer().getGame(); final Game game = ability.getActivatingPlayer().getGame();
final List<ZoneType> zone = tgt.getZone(); 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> validCards = CardLists.getValidCards(game.getCardsIn(zone), tgt.getValidTgts(), ability.getActivatingPlayer(), activatingCard, ability);
List<Card> choices = CardLists.getTargetableCards(validCards, ability); List<Card> choices = CardLists.getTargetableCards(validCards, ability);
final boolean canTgtStack = zone.contains(ZoneType.Stack);
if (canTgtStack) { if (canTgtStack) {
// Since getTargetableCards doesn't have additional checks if one of the Zones is stack // 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 // Remove the activating card from targeting itself if its on the Stack
@@ -560,56 +559,11 @@ public final class CardUtil {
choices.remove(activatingCard); choices.remove(activatingCard);
} }
} }
List<GameObject> targetedObjects = ability.getUniqueTargets();
// Remove cards already targeted // Remove cards already targeted
final List<Card> targeted = Lists.newArrayList(ability.getTargets().getTargetCards()); final List<Card> targeted = Lists.newArrayList(ability.getTargets().getTargetCards());
choices.removeAll(targeted); 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; return choices;
} }
} }

View File

@@ -24,7 +24,6 @@ import java.util.Map;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.ForwardingList; import com.google.common.collect.ForwardingList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import forge.game.GameEntity; import forge.game.GameEntity;
@@ -100,8 +99,8 @@ public class TargetChoices extends ForwardingList<GameObject> implements Cloneab
return Iterables.filter(targets, SpellAbility.class); return Iterables.filter(targets, SpellAbility.class);
} }
public final List<GameEntity> getTargetEntities() { public final Iterable<GameEntity> getTargetEntities() {
return Lists.newArrayList(Iterables.filter(targets, GameEntity.class)); return Iterables.filter(targets, GameEntity.class);
} }
public final boolean isTargetingAnyCard() { public final boolean isTargetingAnyCard() {

View File

@@ -1,9 +1,8 @@
Name:Barrin's Spite Name:Barrin's Spite
ManaCost:2 U B ManaCost:2 U B
Types:Sorcery 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. 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 | Choices$ Card.IsRemembered | Defined$ TargetedController | ChoiceTitle$ Choose one to sacrifice | ForgetChosen$ True | SubAbility$ DBSac | StackDescription$ None | AILogic$ WorstCard 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: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:DBBounce:DB$ ChangeZone | Defined$ Targeted | Origin$ Battlefield | Destination$ Hand | StackDescription$ None
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
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. 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.

View File

@@ -1,8 +1,7 @@
Name:Incriminate Name:Incriminate
ManaCost:1 B ManaCost:1 B
Types:Sorcery 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. 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 | Choices$ Card.IsRemembered | Defined$ TargetedController | ChoiceTitle$ Choose one to sacrifice | SubAbility$ DBSac | StackDescription$ None | AILogic$ WorstCard 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$ DBCleanup | StackDescription$ None SVar:DBSac:DB$ Destroy | Defined$ ChosenCard | Sacrifice$ True | StackDescription$ None
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
Oracle:Choose two target creatures controlled by the same player. That player sacrifices one of them. Oracle:Choose two target creatures controlled by the same player. That player sacrifices one of them.

View File

@@ -2,6 +2,6 @@ Name:Mutiny
ManaCost:R ManaCost:R
Types:Sorcery 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. 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 SVar:X:ParentTargeted$CardPower
Oracle:Target creature an opponent controls deals damage equal to its power to another target creature that player controls. Oracle:Target creature an opponent controls deals damage equal to its power to another target creature that player controls.

View File

@@ -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 all cards must have same controllers
if (tgt.isSameController()) { if (tgt.isSameController()) {
final List<Player> targetedControllers = new ArrayList<>(); 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 all cards must have different controllers
if (tgt.isDifferentControllers()) { if (tgt.isDifferentControllers()) {
final List<Player> targetedControllers = new ArrayList<>(); final List<Player> targetedControllers = new ArrayList<>();

View File

@@ -2012,17 +2012,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
boolean result = select.chooseTargets(null, null, null, false, canFilterMustTarget); 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(); int amount = currentAbility.getStillToDivide();
// assign divided as you choose values // assign divided as you choose values
if (result && targets.size() > 0 && amount > 0) { if (result && size > 0 && amount > 0) {
if (currentAbility.hasParam("DividedUpTo")) { 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) { if (size == 1) {
currentAbility.addDividedAllocation(targets.get(0), amount); currentAbility.addDividedAllocation(Iterables.get(targets, 0), amount);
} else if (targets.size() == amount) { } else if (size == amount) {
for (GameEntity e : targets) { for (GameEntity e : targets) {
currentAbility.addDividedAllocation(e, 1); currentAbility.addDividedAllocation(e, 1);
} }
@@ -2030,7 +2031,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
for (GameEntity e : targets) { for (GameEntity e : targets) {
currentAbility.addDividedAllocation(e, 0); currentAbility.addDividedAllocation(e, 0);
} }
} else if (targets.size() > amount) { } else if (size > amount) {
return false; return false;
} else { } else {
String label = "lblDamage"; String label = "lblDamage";
@@ -2041,7 +2042,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
} }
label = localizer.getMessage(label).toLowerCase(); label = localizer.getMessage(label).toLowerCase();
final CardView vSource = CardView.get(currentAbility.getHostCard()); 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) { for (GameEntity e : targets) {
vTargets.put(GameEntityView.get(e), amount); vTargets.put(GameEntityView.get(e), amount);
} }

View File

@@ -118,7 +118,7 @@ public class TargetSelection {
// Cancel ability if there aren't any valid Candidates // Cancel ability if there aren't any valid Candidates
return false; 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) // Mandatory target selection, that has no candidates but enough targets (Min == 0, but no choices)
return true; return true;
} }