CountersAi: skip for only one against Vorinclex

This commit is contained in:
tool4EvEr
2021-10-10 18:49:29 +02:00
parent e773868f18
commit f0a3d19d38
5 changed files with 26 additions and 19 deletions

View File

@@ -22,13 +22,17 @@ import java.util.List;
import com.google.common.base.Predicate;
import forge.ai.ComputerUtilCard;
import forge.ai.SpellAbilityAi;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CounterEnumType;
import forge.game.card.CounterType;
import forge.game.keyword.Keyword;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
@@ -40,7 +44,7 @@ import forge.util.Aggregates;
* @author Forge
* @version $Id$
*/
public abstract class CountersAi {
public abstract class CountersAi extends SpellAbilityAi {
// An AbilityFactory subclass for Putting or Removing Counters on Cards.
/**
@@ -54,10 +58,16 @@ public abstract class CountersAi {
* a {@link java.lang.String} object.
* @param amount
* a int.
* @param newParam TODO
* @return a {@link forge.game.card.Card} object.
*/
public static Card chooseCursedTarget(final CardCollectionView list, final String type, final int amount) {
public static Card chooseCursedTarget(final CardCollectionView list, final String type, final int amount, final Player ai) {
Card choice;
if (amount == 1 && !CardLists.filter(ai.getOpponents().getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Vorinclex, Monstrous Raider")).isEmpty()) {
return null;
}
if (type.equals("M1M1")) {
// try to kill the best killable creature, or reduce the best one
// but try not to target a Undying Creature
@@ -87,6 +97,7 @@ public abstract class CountersAi {
*/
public static Card chooseBoonTarget(final CardCollectionView list, final String type) {
Card choice = null;
if (type.equals("P1P1")) {
choice = ComputerUtilCard.getBestCreatureAI(list);

View File

@@ -49,7 +49,6 @@ public class CountersMultiplyAi extends SpellAbilityAi {
if (!c.canReceiveCounters(counterType)) {
return false;
}
} else {
for (Map.Entry<CounterType, Integer> e : c.getCounters().entrySet()) {
// has negative counter it would double
@@ -146,7 +145,7 @@ public class CountersMultiplyAi extends SpellAbilityAi {
CardCollection aiList = CardLists.filterControlledBy(list, ai);
if (!aiList.isEmpty()) {
// counter type list to check
// first loyalty, then P1P!, then Charge Counter
// first loyalty, then P1P1, then Charge Counter
List<CounterEnumType> typeList = Lists.newArrayList(CounterEnumType.LOYALTY, CounterEnumType.P1P1, CounterEnumType.CHARGE);
for (CounterEnumType type : typeList) {
// enough targets
@@ -182,7 +181,6 @@ public class CountersMultiplyAi extends SpellAbilityAi {
private void addTargetsByCounterType(final Player ai, final SpellAbility sa, final CardCollection list,
final CounterType type) {
CardCollection newList = CardLists.filter(list, CardPredicates.hasCounter(type));
if (newList.isEmpty()) {
return;

View File

@@ -53,7 +53,7 @@ import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.MyRandom;
public class CountersPutAi extends SpellAbilityAi {
public class CountersPutAi extends CountersAi {
/*
* (non-Javadoc)
@@ -179,7 +179,7 @@ public class CountersPutAi extends SpellAbilityAi {
if (abTgt.canTgtCreature()) {
// try to kill creature with -1/-1 counters if it can
// receive counters, execpt it has undying
// receive counters, except it has undying
CardCollection oppCreat = CardLists.getTargetableCards(ai.getOpponents().getCreaturesInPlay(), sa);
CardCollection oppCreatM1 = CardLists.filter(oppCreat, CardPredicates.hasCounter(CounterEnumType.M1M1));
oppCreatM1 = CardLists.getNotKeyword(oppCreatM1, Keyword.UNDYING);
@@ -549,7 +549,7 @@ public class CountersPutAi extends SpellAbilityAi {
}
if (sa.isCurse()) {
choice = CountersAi.chooseCursedTarget(list, type, amount);
choice = chooseCursedTarget(list, type, amount, ai);
} else {
if (type.equals("P1P1") && !SpellAbilityAi.isSorcerySpeed(sa)) {
for (Card c : list) {
@@ -564,15 +564,15 @@ public class CountersPutAi extends SpellAbilityAi {
if (abCost == null
|| (ph.is(PhaseType.END_OF_TURN) && ph.getPlayerTurn().isOpponentOf(ai))) {
// only use at opponent EOT unless it is free
choice = CountersAi.chooseBoonTarget(list, type);
choice = chooseBoonTarget(list, type);
}
}
}
if (ComputerUtilAbility.getAbilitySourceName(sa).equals("Dromoka's Command")) {
choice = CountersAi.chooseBoonTarget(list, type);
choice = chooseBoonTarget(list, type);
}
} else {
choice = CountersAi.chooseBoonTarget(list, type);
choice = chooseBoonTarget(list, type);
}
}
@@ -681,7 +681,6 @@ public class CountersPutAi extends SpellAbilityAi {
sa.resetTargets();
// target loop
while (sa.canAddMoreTarget()) {
if (list.isEmpty()) {
if (!sa.isTargetNumberValid()
|| sa.getTargets().size() == 0) {
@@ -693,7 +692,7 @@ public class CountersPutAi extends SpellAbilityAi {
}
if (sa.isCurse()) {
choice = CountersAi.chooseCursedTarget(list, type, amount);
choice = chooseCursedTarget(list, type, amount, ai);
} else {
CardCollection lands = CardLists.filter(list, CardPredicates.Presets.LANDS);
SpellAbility animate = sa.findSubAbilityByType(ApiType.Animate);
@@ -702,7 +701,7 @@ public class CountersPutAi extends SpellAbilityAi {
} else if ("BoonCounterOnOppCreature".equals(logic)) {
choice = ComputerUtilCard.getWorstCreatureAI(list);
} else {
choice = CountersAi.chooseBoonTarget(list, type);
choice = chooseBoonTarget(list, type);
}
}
@@ -838,7 +837,7 @@ public class CountersPutAi extends SpellAbilityAi {
// Choose targets here:
if (sa.isCurse()) {
if (preferred) {
choice = CountersAi.chooseCursedTarget(list, type, amount);
choice = chooseCursedTarget(list, type, amount, ai);
if (choice == null && mandatory) {
choice = Aggregates.random(list);
}
@@ -852,7 +851,7 @@ public class CountersPutAi extends SpellAbilityAi {
} else {
if (preferred) {
list = ComputerUtil.getSafeTargets(ai, sa, list);
choice = CountersAi.chooseBoonTarget(list, type);
choice = chooseBoonTarget(list, type);
if (choice == null && mandatory) {
choice = Aggregates.random(list);
}

View File

@@ -104,7 +104,7 @@ public class PoisonAi extends SpellAbilityAi {
if (!betterTgts.isEmpty()) {
tgts = betterTgts;
} else if (mandatory) {
// no better choice but better than hiting himself
// no better choice but better than hitting himself
sa.getTargets().add(tgts.getFirst());
return true;
}
@@ -121,7 +121,7 @@ public class PoisonAi extends SpellAbilityAi {
// need to target something, try to target allies
PlayerCollection allies = ai.getAllies().filter(PlayerPredicates.isTargetableBy(sa));
if (!allies.isEmpty()) {
// some ally would be uneffected
// some ally would be unaffected
PlayerCollection betterAllies = allies.filter(new Predicate<Player>() {
@Override
public boolean apply(Player input) {

View File

@@ -145,7 +145,6 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
}
public boolean requirementsCheck(Game game, Map<String,String> params) {
if (this.isSuppressed()) {
return false; // Effect removed by effect
}