mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
- Fixed #5619
This commit is contained in:
parent
e08fe53672
commit
697706748a
1 changed files with 32 additions and 130 deletions
|
@ -1,15 +1,11 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.costs.Cost;
|
|
||||||
import mage.abilities.costs.CostImpl;
|
|
||||||
import mage.abilities.costs.Costs;
|
|
||||||
import mage.abilities.effects.AsThoughEffectImpl;
|
import mage.abilities.effects.AsThoughEffectImpl;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.choices.Choice;
|
|
||||||
import mage.choices.ChoiceImpl;
|
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.game.ExileZone;
|
import mage.game.ExileZone;
|
||||||
|
@ -18,11 +14,9 @@ import mage.players.Player;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.choices.Choice;
|
||||||
|
import mage.choices.ChoiceImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -50,20 +44,19 @@ public class AminatousAugury extends CardImpl {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AminatousAuguryEffect extends OneShotEffect{
|
class AminatousAuguryEffect extends OneShotEffect {
|
||||||
|
|
||||||
public AminatousAuguryEffect() {
|
public AminatousAuguryEffect() {
|
||||||
super(Outcome.PlayForFree);
|
super(Outcome.PlayForFree);
|
||||||
staticText = "Exile the top eight cards of your library. You may put a land card from among them onto the" +
|
staticText = "Exile the top eight cards of your library. You may put a land card from among them onto the"
|
||||||
" battlefield. Until end of turn, for each nonland card type, you may cast a card of that type from" +
|
+ " battlefield. Until end of turn, for each nonland card type, you may cast a card of that type from"
|
||||||
" among the exiled cards without paying its mana cost.";
|
+ " among the exiled cards without paying its mana cost.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public AminatousAuguryEffect(final AminatousAuguryEffect effect) {
|
public AminatousAuguryEffect(final AminatousAuguryEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AminatousAuguryEffect copy() {
|
public AminatousAuguryEffect copy() {
|
||||||
return new AminatousAuguryEffect(this);
|
return new AminatousAuguryEffect(this);
|
||||||
|
@ -97,9 +90,8 @@ class AminatousAuguryEffect extends OneShotEffect{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AminatousAuguryExileHandler exileHandler = new AminatousAuguryExileHandler(cardsToCast, source, game);
|
for (Card card : cardsToCast.getCards(StaticFilters.FILTER_CARD_NON_LAND, game)) {
|
||||||
for (Card card:cardsToCast.getCards(StaticFilters.FILTER_CARD_NON_LAND,game)) {
|
AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect();
|
||||||
AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect(card.getCardType(), exileHandler);
|
|
||||||
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
|
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
|
||||||
game.addEffect(effect, source);
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
|
@ -109,20 +101,14 @@ class AminatousAuguryEffect extends OneShotEffect{
|
||||||
}
|
}
|
||||||
|
|
||||||
class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
|
class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
|
||||||
private final AminatousAuguryExileHandler cardTypeHandler;
|
|
||||||
private final EnumSet<CardType> cardType;
|
|
||||||
|
|
||||||
public AminatousAuguryCastFromExileEffect(EnumSet<CardType> cardType, AminatousAuguryExileHandler cardTypeTracker) {
|
public AminatousAuguryCastFromExileEffect() {
|
||||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.PlayForFree);
|
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.PlayForFree);
|
||||||
this.cardTypeHandler = cardTypeTracker;
|
|
||||||
this.cardType = cardType;
|
|
||||||
staticText = "Cast this card without paying its mana cost";
|
staticText = "Cast this card without paying its mana cost";
|
||||||
}
|
}
|
||||||
|
|
||||||
public AminatousAuguryCastFromExileEffect(final AminatousAuguryCastFromExileEffect effect) {
|
public AminatousAuguryCastFromExileEffect(final AminatousAuguryCastFromExileEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
this.cardTypeHandler = effect.cardTypeHandler;
|
|
||||||
this.cardType = effect.cardType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -137,117 +123,33 @@ class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||||
if (!cardTypeHandler.atLeastOneAvailable(cardType)){
|
Player player = game.getPlayer(affectedControllerId);
|
||||||
return false;
|
EnumSet<CardType> cardTypes = EnumSet.noneOf(CardType.class);
|
||||||
|
Boolean checkType = false;
|
||||||
|
if (game.getState().getValue(source.getSourceId().toString() + "cardTypes") != null) {
|
||||||
|
cardTypes = (EnumSet<CardType>) game.getState().getValue(source.getSourceId().toString() + "cardTypes");
|
||||||
}
|
}
|
||||||
if (sourceId != null && sourceId.equals(getTargetPointer().getFirst(game, source))
|
//TODO add code for choosing from multiple card types and adding additional costs to the card
|
||||||
|
if (player != null
|
||||||
|
&& sourceId != null
|
||||||
|
&& sourceId.equals(getTargetPointer().getFirst(game, source))
|
||||||
&& affectedControllerId.equals(source.getControllerId())) {
|
&& affectedControllerId.equals(source.getControllerId())) {
|
||||||
Card card = game.getCard(sourceId);
|
Card card = game.getCard(sourceId);
|
||||||
if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) {
|
if (card != null
|
||||||
Player player = game.getPlayer(affectedControllerId);
|
&& game.getState().getZone(sourceId) == Zone.EXILED) {
|
||||||
Costs costs = card.getSpellAbility().getCosts().copy();
|
for (CardType cardT : cardTypes) {
|
||||||
costs.add(new ConsumeCardTypeCost(cardType, cardTypeHandler));
|
if (card.getCardType().contains(cardT)) {
|
||||||
player.setCastSourceIdWithAlternateMana(sourceId, null, costs);
|
checkType = true;
|
||||||
return true;
|
}
|
||||||
|
}
|
||||||
|
if (!checkType) {
|
||||||
|
player.setCastSourceIdWithAlternateMana(sourceId, null, null);
|
||||||
|
cardTypes.addAll(card.getCardType());
|
||||||
|
game.getState().setValue(source.getSourceId().toString() + "cardTypes", cardTypes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tracks which card types have already been cast, and provides utility functions for confirming used types.
|
|
||||||
* (one ExileHandler is shared between all cards from a single cast of Animatou's Augury)
|
|
||||||
*/
|
|
||||||
class AminatousAuguryExileHandler {
|
|
||||||
private final EnumSet<CardType> usedCardTypes;
|
|
||||||
|
|
||||||
public AminatousAuguryExileHandler(Cards cards, Ability source, Game game){
|
|
||||||
usedCardTypes = EnumSet.noneOf(CardType.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnumSet<CardType> availableTypes(EnumSet<CardType> types){
|
|
||||||
EnumSet<CardType> available = EnumSet.copyOf(types);
|
|
||||||
available.removeAll(usedCardTypes);
|
|
||||||
return available;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean atLeastOneAvailable(EnumSet<CardType> types){
|
|
||||||
EnumSet<CardType> available = availableTypes(types);
|
|
||||||
return !available.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean useCardType(CardType type){
|
|
||||||
if (usedCardTypes.contains(type)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
usedCardTypes.add(type);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the user to choose one of the given card types
|
|
||||||
*/
|
|
||||||
class CardTypeChoice extends ChoiceImpl{
|
|
||||||
|
|
||||||
public CardTypeChoice (EnumSet<CardType> types){
|
|
||||||
super(false);
|
|
||||||
for (CardType type:types){
|
|
||||||
this.choices.add(type+"");
|
|
||||||
}
|
|
||||||
this.message = "Choose card type to cast as";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConsumeCardTypeCost extends CostImpl{
|
|
||||||
|
|
||||||
final private AminatousAuguryExileHandler exileHandler;
|
|
||||||
final private EnumSet<CardType> types;
|
|
||||||
|
|
||||||
public ConsumeCardTypeCost (EnumSet<CardType> types, AminatousAuguryExileHandler exileHandler){
|
|
||||||
this.exileHandler = exileHandler;
|
|
||||||
this.types = types;
|
|
||||||
this.text = "Cast as "+types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
|
|
||||||
return exileHandler.atLeastOneAvailable(types);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
|
|
||||||
if (isPaid()){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
CardType choiceType;
|
|
||||||
EnumSet<CardType> availableChoices = exileHandler.availableTypes(types);
|
|
||||||
if (availableChoices.size()==1){
|
|
||||||
// if there is only one possibility, don't need to prompt for a choice
|
|
||||||
choiceType = availableChoices.iterator().next();
|
|
||||||
}else {
|
|
||||||
Choice choice = new CardTypeChoice(availableChoices);
|
|
||||||
if (!game.getPlayer(controllerId).choose(Outcome.Neutral, choice, game)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Optional<CardType> optionalChoice = Arrays.stream(CardType.values()).filter(type -> type.toString().equals(choice.getChoice())).findAny();
|
|
||||||
if (optionalChoice.isPresent()){
|
|
||||||
choiceType = optionalChoice.get();
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
paid = exileHandler.useCardType(choiceType);
|
|
||||||
return paid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cost copy() {
|
|
||||||
return new ConsumeCardTypeCost(types, exileHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue