implement [MH3] Nethergoyf, refactor targets usages by game param (#12267)

This commit is contained in:
Susucre 2024-05-21 13:34:38 +02:00 committed by GitHub
parent 88b6f4036f
commit 754b382e78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
62 changed files with 592 additions and 285 deletions

View file

@ -34,7 +34,6 @@ import mage.target.Targets;
import mage.util.RandomUtil;
import org.apache.log4j.Logger;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@ -392,7 +391,7 @@ public class ComputerPlayer6 extends ComputerPlayer {
if (effect != null
&& stackObject.getControllerId().equals(playerId)) {
Target target = effect.getTarget();
if (!target.doneChoosing()) {
if (!target.doneChoosing(game)) {
for (UUID targetId : target.possibleTargets(stackObject.getControllerId(), stackObject.getStackAbility(), game)) {
Game sim = game.createSimulationForAI();
StackAbility newAbility = (StackAbility) stackObject.copy();
@ -740,10 +739,10 @@ public class ComputerPlayer6 extends ComputerPlayer {
if (targets.isEmpty()) {
return super.chooseTarget(outcome, cards, target, source, game);
}
if (!target.doneChoosing()) {
if (!target.doneChoosing(game)) {
for (UUID targetId : targets) {
target.addTarget(targetId, source, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
targets.clear();
return true;
}
@ -758,10 +757,10 @@ public class ComputerPlayer6 extends ComputerPlayer {
if (targets.isEmpty()) {
return super.choose(outcome, cards, target, source, game);
}
if (!target.doneChoosing()) {
if (!target.doneChoosing(game)) {
for (UUID targetId : targets) {
target.add(targetId, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
targets.clear();
return true;
}

View file

@ -10,7 +10,6 @@ import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.Effect;
import mage.cards.Card;
import mage.game.Game;
import mage.game.combat.Combat;
import mage.game.events.GameEvent;
@ -149,7 +148,7 @@ public final class SimulatedPlayer2 extends ComputerPlayer {
}
newAbility.adjustTargets(game);
// add the different possible target option for the specific X value
if (!newAbility.getTargets().getUnchosen().isEmpty()) {
if (!newAbility.getTargets().getUnchosen(game).isEmpty()) {
addTargetOptions(options, newAbility, targetNum, game);
}
}

View file

@ -174,7 +174,7 @@ public class ComputerPlayer extends PlayerImpl {
for (int i = unplayable.size() - 1; i >= 0; i--) {
if (target.canTarget(abilityControllerId, unplayable.values().toArray(new Card[0])[i].getId(), null, game)) {
target.add(unplayable.values().toArray(new Card[0])[i].getId(), game);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -184,7 +184,7 @@ public class ComputerPlayer extends PlayerImpl {
for (int i = 0; i < hand.size(); i++) {
if (target.canTarget(abilityControllerId, hand.toArray(new UUID[0])[i], null, game)) {
target.add(hand.toArray(new UUID[0])[i], game);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -252,12 +252,12 @@ public class ComputerPlayer extends PlayerImpl {
}
// add the target
target.add(permanent.getId(), game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCardInHand
@ -269,7 +269,7 @@ public class ComputerPlayer extends PlayerImpl {
cards.add(card);
}
}
while ((outcome.isGood() ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen())
while ((outcome.isGood() ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen(game))
&& !cards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, cards, outcome, target, null, game);
if (pick != null) {
@ -277,7 +277,7 @@ public class ComputerPlayer extends PlayerImpl {
cards.remove(pick);
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetAnyTarget) {
@ -410,7 +410,7 @@ public class ComputerPlayer extends PlayerImpl {
// exile cost workaround: exile is bad, but exile from graveyard in most cases is good (more exiled -- more good things you get, e.g. delve's pay)
boolean isRealGood = outcome.isGood() || outcome == Outcome.Exile;
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen())
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen(game))
&& !cards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, cards, outcome, target, null, game);
if (pick != null) {
@ -421,7 +421,7 @@ public class ComputerPlayer extends PlayerImpl {
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCardInGraveyard
@ -437,7 +437,7 @@ public class ComputerPlayer extends PlayerImpl {
// exile cost workaround: exile is bad, but exile from graveyard in most cases is good (more exiled -- more good things you get, e.g. delve's pay)
boolean isRealGood = outcome.isGood() || outcome == Outcome.Exile;
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen())
while ((isRealGood ? target.getTargets().size() < target.getMaxNumberOfTargets() : !target.isChosen(game))
&& !cards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, cards, outcome, target, null, game);
if (pick != null) {
@ -448,7 +448,7 @@ public class ComputerPlayer extends PlayerImpl {
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard
@ -460,7 +460,7 @@ public class ComputerPlayer extends PlayerImpl {
Card card = pickTarget(abilityControllerId, cards, outcome, target, null, game);
if (card != null && alreadyTargeted != null && !alreadyTargeted.contains(card.getId())) {
target.add(card.getId(), game);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -485,7 +485,7 @@ public class ComputerPlayer extends PlayerImpl {
Card card = pickTarget(abilityControllerId, cards, outcome, target, null, game);
if (card != null && alreadyTargeted != null && !alreadyTargeted.contains(card.getId())) {
target.add(card.getId(), game);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -517,14 +517,14 @@ public class ComputerPlayer extends PlayerImpl {
if (target.getOriginalTarget() instanceof TargetPermanentOrSuspendedCard) {
Cards cards = new CardsImpl(possibleTargets);
List<Card> possibleCards = new ArrayList<>(cards.getCards(game));
while (!target.isChosen() && !possibleCards.isEmpty()) {
while (!target.isChosen(game) && !possibleCards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, possibleCards, outcome, target, null, game);
if (pick != null) {
target.addTarget(pick.getId(), null, game);
possibleCards.remove(pick);
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCard
@ -537,14 +537,14 @@ public class ComputerPlayer extends PlayerImpl {
}
}
}
while (!target.isChosen() && !cardsInCommandZone.isEmpty()) {
while (!target.isChosen(game) && !cardsInCommandZone.isEmpty()) {
Card pick = pickTarget(abilityControllerId, cardsInCommandZone, outcome, target, null, game);
if (pick != null) {
target.addTarget(pick.getId(), null, game);
cardsInCommandZone.remove(pick);
}
}
return target.isChosen();
return target.isChosen(game);
}
throw new IllegalStateException("Target wasn't handled in computer's choose method: " + target.getClass().getCanonicalName());
@ -641,7 +641,7 @@ public class ComputerPlayer extends PlayerImpl {
}
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetDiscard
@ -650,7 +650,7 @@ public class ComputerPlayer extends PlayerImpl {
// good
Cards cards = new CardsImpl(possibleTargets);
List<Card> cardsInHand = new ArrayList<>(cards.getCards(game));
while (!target.isChosen()
while (!target.isChosen(game)
&& !cardsInHand.isEmpty()
&& target.getMaxNumberOfTargets() > target.getTargets().size()) {
Card card = pickBestCard(cardsInHand, null, target, source, game);
@ -658,7 +658,7 @@ public class ComputerPlayer extends PlayerImpl {
if (target.canTarget(abilityControllerId, card.getId(), source, game)) {
target.addTarget(card.getId(), source, game);
cardsInHand.remove(card);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -671,7 +671,7 @@ public class ComputerPlayer extends PlayerImpl {
if (possibleTargets.contains(card.getId())
&& target.canTarget(abilityControllerId, card.getId(), source, game)) {
target.addTarget(card.getId(), source, game);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -681,7 +681,7 @@ public class ComputerPlayer extends PlayerImpl {
if (possibleTargets.contains(card.getId())
&& target.canTarget(abilityControllerId, card.getId(), source, game)) {
target.addTarget(card.getId(), source, game);
if (target.isChosen()) {
if (target.isChosen(game)) {
return true;
}
}
@ -707,7 +707,7 @@ public class ComputerPlayer extends PlayerImpl {
}
}
}
return target.isChosen();
return target.isChosen(game);
}
@ -749,7 +749,7 @@ public class ComputerPlayer extends PlayerImpl {
target.addTarget(permanent.getId(), source, game);
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCreatureOrPlayer) {
@ -956,14 +956,14 @@ public class ComputerPlayer extends PlayerImpl {
if (target.getOriginalTarget() instanceof TargetCardInYourGraveyard) {
List<Card> cards = new ArrayList<>(game.getPlayer(abilityControllerId).getGraveyard().getCards((FilterCard) target.getFilter(), game));
while (!target.isChosen() && !cards.isEmpty()) {
while (!target.isChosen(game) && !cards.isEmpty()) {
Card card = pickTarget(abilityControllerId, cards, outcome, target, source, game);
if (card != null) {
target.addTarget(card.getId(), source, game);
cards.remove(card); // pickTarget don't remove cards (only on second+ tries)
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetSpell
@ -1034,7 +1034,7 @@ public class ComputerPlayer extends PlayerImpl {
if (target.getOriginalTarget() instanceof TargetDefender) {
UUID randomDefender = RandomUtil.randomFromCollection(possibleTargets);
target.addTarget(randomDefender, source, game);
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCardInASingleGraveyard) {
@ -1042,14 +1042,14 @@ public class ComputerPlayer extends PlayerImpl {
for (Player player : game.getPlayers().values()) {
cards.addAll(player.getGraveyard().getCards(game));
}
while (!target.isChosen() && !cards.isEmpty()) {
while (!target.isChosen(game) && !cards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, cards, outcome, target, source, game);
if (pick != null) {
target.addTarget(pick.getId(), source, game);
cards.remove(pick); // pickTarget don't remove cards (only on second+ tries)
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCardInExile) {
@ -1070,14 +1070,14 @@ public class ComputerPlayer extends PlayerImpl {
cards.add(card);
}
}
while (!target.isChosen() && !cards.isEmpty()) {
while (!target.isChosen(game) && !cards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, cards, outcome, target, source, game);
if (pick != null) {
target.addTarget(pick.getId(), source, game);
cards.remove(pick); // pickTarget don't remove cards (only on second+ tries)
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
@ -1088,22 +1088,22 @@ public class ComputerPlayer extends PlayerImpl {
stackObjects.add(stackObject);
}
}
while (!target.isChosen() && !stackObjects.isEmpty()) {
while (!target.isChosen(game) && !stackObjects.isEmpty()) {
StackObject pick = stackObjects.get(0);
if (pick != null) {
target.addTarget(pick.getId(), source, game);
stackObjects.remove(0);
}
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetActivatedOrTriggeredAbility) {
Iterator<UUID> iterator = target.possibleTargets(source.getControllerId(), source, game).iterator();
while (!target.isChosen() && iterator.hasNext()) {
while (!target.isChosen(game) && iterator.hasNext()) {
target.addTarget(iterator.next(), source, game);
}
return target.isChosen();
return target.isChosen(game);
}
if (target.getOriginalTarget() instanceof TargetCardInGraveyardBattlefieldOrStack) {
@ -1121,14 +1121,14 @@ public class ComputerPlayer extends PlayerImpl {
if (target.getOriginalTarget() instanceof TargetPermanentOrSuspendedCard) {
Cards cards = new CardsImpl(possibleTargets);
List<Card> possibleCards = new ArrayList<>(cards.getCards(game));
while (!target.isChosen() && !possibleCards.isEmpty()) {
while (!target.isChosen(game) && !possibleCards.isEmpty()) {
Card pick = pickTarget(abilityControllerId, possibleCards, outcome, target, source, game);
if (pick != null) {
target.addTarget(pick.getId(), source, game);
possibleCards.remove(pick);
}
}
return target.isChosen();
return target.isChosen(game);
}
throw new IllegalStateException("Target wasn't handled in computer's chooseTarget method: " + target.getClass().getCanonicalName());
@ -2063,7 +2063,7 @@ public class ComputerPlayer extends PlayerImpl {
// we still use playerId when getting cards even if they don't control the search
List<Card> cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), playerId, source, game));
while (!target.doneChoosing()) {
while (!target.doneChoosing(game)) {
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
if (card != null) {
target.addTarget(card.getId(), source, game);
@ -2094,7 +2094,7 @@ public class ComputerPlayer extends PlayerImpl {
}
List<Card> cardChoices = new ArrayList<>(cards.getCards(target.getFilter(), abilityControllerId, source, game));
while (!target.doneChoosing()) {
while (!target.doneChoosing(game)) {
Card card = pickTarget(abilityControllerId, cardChoices, outcome, target, source, game);
if (card != null) {
target.add(card.getId(), game);

View file

@ -674,7 +674,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), possibleTargetIds, required, getOptions(target, options));
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(game), getRelatedObjectName(source, game)), possibleTargetIds, required, getOptions(target, options));
}
waitForResponse(game);
responseId = getFixedResponseUUID(game);
@ -696,7 +696,7 @@ public class HumanPlayer extends PlayerImpl {
if (target instanceof TargetPermanent) {
if (((TargetPermanent) target).canTarget(abilityControllerId, responseId, source, game, false)) {
target.add(responseId, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
@ -708,7 +708,7 @@ public class HumanPlayer extends PlayerImpl {
target.remove(responseId);
} else {
target.addTarget(responseId, (Ability) object, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
@ -718,7 +718,7 @@ public class HumanPlayer extends PlayerImpl {
target.remove(responseId);
} else {
target.addTarget(responseId, null, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
@ -775,7 +775,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)),
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(game), getRelatedObjectName(source, game)),
possibleTargetIds, required, getOptions(target, options));
}
waitForResponse(game);
@ -792,7 +792,7 @@ public class HumanPlayer extends PlayerImpl {
if (possibleTargetIds.contains(responseId)) {
if (target.canTarget(abilityControllerId, responseId, source, game)) {
target.addTarget(responseId, source, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
@ -873,7 +873,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage()), cards, required, options);
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(game)), cards, required, options);
}
waitForResponse(game);
@ -886,7 +886,7 @@ public class HumanPlayer extends PlayerImpl {
} else {
if (target.canTarget(abilityControllerId, responseId, source, cards, game)) {
target.add(responseId, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
@ -956,7 +956,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), cards, required, options);
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(game), getRelatedObjectName(source, game)), cards, required, options);
}
waitForResponse(game);
@ -968,7 +968,7 @@ public class HumanPlayer extends PlayerImpl {
target.remove(responseId);
} else if (target.canTarget(abilityControllerId, responseId, source, cards, game)) {
target.addTarget(responseId, source, game);
if (target.doneChoosing()) {
if (target.doneChoosing(game)) {
return true;
}
}
@ -1051,7 +1051,7 @@ public class HumanPlayer extends PlayerImpl {
prepareForResponse(game);
if (!isExecutingMacro()) {
String multiType = multiAmountType == MultiAmountType.DAMAGE ? " to divide %d damage" : " to distribute %d counters";
String message = target.getMessage() + String.format(multiType, amountTotal);
String message = target.getMessage(game) + String.format(multiType, amountTotal);
game.fireSelectTargetEvent(playerId, new MessageToClient(message, getRelatedObjectName(source, game)), possibleTargetIds, required, options);
}
waitForResponse(game);