Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[STX] Implement Ecological Appreciation #7732

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions Mage.Sets/src/mage/cards/e/EcologicalAppreciation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package mage.cards.e;

import com.google.common.collect.Sets;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetOpponent;
import mage.util.CardUtil;

import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
*
* @author htrajan
*/
public final class EcologicalAppreciation extends CardImpl {

public EcologicalAppreciation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{2}{G}");

// Search your library and graveyard for up to four creature cards with different names that each have mana value X or less and reveal them. An opponent chooses two of those cards. Shuffle the chosen cards into your library and put the rest onto the battlefield. Exile Ecological Appreciation.
this.getSpellAbility().addEffect(new EcologicalAppreciationEffect());
this.getSpellAbility().addEffect(ExileSpellEffect.getInstance());
}

private EcologicalAppreciation(final EcologicalAppreciation card) {
super(card);
}

@Override
public EcologicalAppreciation copy() {
return new EcologicalAppreciation(this);
}
}

class EcologicalAppreciationEffect extends OneShotEffect {

EcologicalAppreciationEffect() {
super(Outcome.Benefit);
staticText = "search your library and graveyard for up to four creature cards with different names that each have mana value X or less and reveal them. An opponent chooses two of those cards. Shuffle the chosen cards into your library and put the rest onto the battlefield";
}

private EcologicalAppreciationEffect(final EcologicalAppreciationEffect effect) {
super(effect);
}

@Override
public EcologicalAppreciationEffect copy() {
return new EcologicalAppreciationEffect(this);
}

@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
int xValue = source.getManaCostsToPay().getX();
FilterCard filter = new FilterCreatureCard();
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1));
TargetCard targetCardsInLibrary = new TargetCardInLibrary(0, 4, filter) {
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Card card = game.getCard(id);
Set<Card> disallowedCards = this.getTargets().stream()
.map(game::getCard)
.collect(Collectors.toSet());
return isValidTarget(card, disallowedCards);
}
};
targetCardsInLibrary.setNotTarget(true);
Copy link
Member

@JayDi85 JayDi85 Apr 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use target.withChooseHint to inform user in choose dialog about current step or additional info. Example: "step 1 of 2, from library".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

targetCardsInLibrary.withChooseHint("Step 1 of 2: Search library");
player.choose(Outcome.PutCreatureInPlay, new CardsImpl(player.getLibrary().getCards(game)), targetCardsInLibrary, game);
Cards cards = new CardsImpl(targetCardsInLibrary.getTargets());

boolean status = !cards.isEmpty();

if (status) {
int remainingCards = 4 - cards.size();
if (remainingCards > 0) {
TargetCard targetCardsInGY = new TargetCardInYourGraveyard(0, remainingCards, filter) {
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Card card = game.getCard(id);
Set<Card> disallowedCards = this.getTargets().stream()
.map(game::getCard)
.collect(Collectors.toSet());
return isValidTarget(card, Sets.union(disallowedCards, cards.getCards(game)));
}
};
targetCardsInGY.setNotTarget(true);
targetCardsInGY.withChooseHint("Step 2 of 2: Search graveyard");
player.choose(Outcome.PutCreatureInPlay, new CardsImpl(player.getGraveyard().getCards(game)), targetCardsInGY, game);
cards.addAll(targetCardsInGY.getTargets());
}

TargetOpponent targetOpponent = new TargetOpponent();
targetOpponent.setNotTarget(true);
player.choose(outcome, targetOpponent, source.getSourceId(), game);
Player opponent = game.getPlayer(targetOpponent.getFirstTarget());

if (opponent == null) {
status = false;
}

if (status) {
TargetCard chosenCards = new TargetCard(2, Zone.ALL, StaticFilters.FILTER_CARD);
chosenCards.setNotTarget(true);
opponent.choose(outcome, cards, chosenCards, game);
Cards toShuffle = new CardsImpl(chosenCards.getTargets().stream()
.map(game::getCard)
.collect(Collectors.toList()));

player.putCardsOnTopOfLibrary(toShuffle, game, source, false);
cards.removeAll(toShuffle);

player.moveCards(cards, Zone.BATTLEFIELD, source, game);
}
}

player.shuffleLibrary(source, game);

return status;
}

private boolean isValidTarget(Card target, Set<Card> disallowedCards) {
return target != null &&
disallowedCards.stream()
.filter(Objects::nonNull)
.map(MageObject::getName)
.noneMatch(name -> CardUtil.haveSameNames(name, target.getName()));
}
}
4 changes: 3 additions & 1 deletion Mage.Sets/src/mage/cards/e/EmergentUltimatum.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public boolean apply(Game game, Ability source) {
return false;
}
TargetCardInLibrary targetCardInLibrary = new EmergentUltimatumTarget();
targetCardInLibrary.setNotTarget(true);
boolean searched = player.searchLibrary(targetCardInLibrary, source, game);
Cards cards = new CardsImpl(targetCardInLibrary.getTargets());
player.moveCards(cards, Zone.EXILED, source, game);
Expand All @@ -85,9 +86,10 @@ public boolean apply(Game game, Ability source) {
if (searched) {
player.shuffleLibrary(source, game);
}
return true;
return false;
}
TargetCardInExile targetCardInExile = new TargetCardInExile(StaticFilters.FILTER_CARD);
targetCardInExile.setNotTarget(true);
opponent.choose(outcome, cards, targetCardInExile, game);
Card toShuffle = game.getCard(targetCardInExile.getFirstTarget());
if (toShuffle != null) {
Expand Down
1 change: 1 addition & 0 deletions Mage.Sets/src/mage/sets/StrixhavenSchoolOfMages.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ private StrixhavenSchoolOfMages() {
cards.add(new SetCardInfo("Dream Strix", 42, Rarity.RARE, mage.cards.d.DreamStrix.class));
cards.add(new SetCardInfo("Dueling Coach", 15, Rarity.UNCOMMON, mage.cards.d.DuelingCoach.class));
cards.add(new SetCardInfo("Eager First-Year", 16, Rarity.COMMON, mage.cards.e.EagerFirstYear.class));
cards.add(new SetCardInfo("Ecological Appreciation", 128, Rarity.MYTHIC, mage.cards.e.EcologicalAppreciation.class));
cards.add(new SetCardInfo("Elemental Expressionist", 181, Rarity.RARE, mage.cards.e.ElementalExpressionist.class));
cards.add(new SetCardInfo("Elemental Masterpiece", 182, Rarity.COMMON, mage.cards.e.ElementalMasterpiece.class));
cards.add(new SetCardInfo("Elemental Summoning", 183, Rarity.COMMON, mage.cards.e.ElementalSummoning.class));
Expand Down