[ECL] Implement Silvergill Mentor

This commit is contained in:
theelk801 2026-01-05 21:22:50 -05:00
parent 51cfd16eb5
commit cc59f9e2e8
15 changed files with 268 additions and 148 deletions

View file

@ -2,7 +2,7 @@ package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.keyword.BeholdDragonAbility;
import mage.abilities.keyword.BeholdAbility;
import mage.game.Game;
import mage.util.CardUtil;
@ -16,7 +16,7 @@ public enum BeheldDragonCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
return CardUtil.checkSourceCostsTagExists(game, source, BeholdDragonAbility.BEHOLD_DRAGON_ACTIVATION_VALUE_KEY);
return CardUtil.checkSourceCostsTagExists(game, source, BeholdAbility.BEHOLD_ACTIVATION_VALUE_KEY);
}
@Override

View file

@ -0,0 +1,46 @@
package mage.abilities.costs.common;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.constants.BeholdType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public class BeholdCost extends CostImpl {
private final BeholdType beholdType;
public BeholdCost(BeholdType beholdType) {
super();
this.beholdType = beholdType;
this.text = "behold " + beholdType.getDescription();
}
private BeholdCost(final BeholdCost cost) {
super(cost);
this.beholdType = cost.beholdType;
}
@Override
public BeholdCost copy() {
return new BeholdCost(this);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return beholdType.canBehold(controllerId, game, source);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player player = game.getPlayer(controllerId);
paid = player != null && beholdType.doBehold(player, game, source) != null;
return paid;
}
}

View file

@ -1,109 +0,0 @@
package mage.abilities.costs.common;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.cards.Card;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public class BeholdDragonCost extends CostImpl {
private static final FilterPermanent filterPermanent = new FilterControlledPermanent(SubType.DRAGON);
private static final FilterCard filterCard = new FilterCard("a Dragon card");
static {
filterCard.add(SubType.DRAGON.getPredicate());
}
public BeholdDragonCost() {
super();
this.text = "behold a Dragon";
}
private BeholdDragonCost(final BeholdDragonCost cost) {
super(cost);
}
@Override
public BeholdDragonCost copy() {
return new BeholdDragonCost(this);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return Optional
.ofNullable(game.getPlayer(controllerId))
.map(Player::getHand)
.map(cards -> cards.count(filterCard, game) > 0)
.orElse(false)
|| game
.getBattlefield()
.contains(filterPermanent, controllerId, source, game, 1);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player player = game.getPlayer(controllerId);
if (player == null) {
paid = false;
return paid;
}
boolean hasPermanent = game
.getBattlefield()
.contains(filterPermanent, controllerId, source, game, 1);
boolean hasHand = player.getHand().count(filterCard, game) > 0;
boolean usePermanent;
if (hasPermanent && hasHand) {
usePermanent = player.chooseUse(
Outcome.Neutral, "Choose a Dragon you control or reveal one from your hand?",
null, "Choose controlled", "Reveal from hand", source, game);
} else if (hasPermanent) {
usePermanent = true;
} else if (hasHand) {
usePermanent = false;
} else {
paid = false;
return paid;
}
if (usePermanent) {
TargetPermanent target = new TargetPermanent(filterPermanent);
target.withNotTarget(true);
player.choose(Outcome.Neutral, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
paid = false;
return paid;
}
game.informPlayers(player.getLogName() + " chooses to behold " + permanent.getLogName());
paid = true;
return true;
}
TargetCard target = new TargetCardInHand(filterCard);
player.choose(Outcome.Neutral, player.getHand(), target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
paid = false;
return paid;
}
player.revealCards(source, new CardsImpl(card), game);
paid = true;
return paid;
}
}

View file

@ -4,9 +4,8 @@ import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.StaticAbility;
import mage.abilities.costs.*;
import mage.abilities.costs.common.BeholdDragonCost;
import mage.abilities.costs.common.CollectEvidenceCost;
import mage.abilities.hint.common.EvidenceHint;
import mage.abilities.costs.common.BeholdCost;
import mage.constants.BeholdType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
@ -15,38 +14,47 @@ import mage.players.Player;
/**
* @author TheElk801
*/
public class BeholdDragonAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
public class BeholdAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
private static final String promptString = "Behold a Dragon";
private static final String keywordText = "As an additional cost to cast this spell, you may behold a Dragon";
private static final String reminderText = "Choose a Dragon you control or reveal a Dragon card from your hand.";
private static final String promptString = "Behold ";
private static final String keywordText = "As an additional cost to cast this spell, you may behold ";
private static final String reminderText = "Choose % you control or reveal % card from your hand.";
private final String rule;
public static final String BEHOLD_DRAGON_ACTIVATION_VALUE_KEY = "beholdDragonActivation";
public static final String BEHOLD_ACTIVATION_VALUE_KEY = "beholdActivation";
protected OptionalAdditionalCost additionalCost;
public static OptionalAdditionalCost makeCost() {
OptionalAdditionalCost cost = new OptionalAdditionalCostImpl(keywordText , reminderText, new BeholdDragonCost());
public static OptionalAdditionalCost makeCost(BeholdType beholdType) {
OptionalAdditionalCost cost = new OptionalAdditionalCostImpl(
keywordText + beholdType.getDescription(),
String.format(reminderText, beholdType.getDescription()),
new BeholdCost(beholdType)
);
cost.setRepeatable(false);
return cost;
}
public BeholdDragonAbility( ) {
private final BeholdType beholdType;
public BeholdAbility(BeholdType beholdType) {
super(Zone.STACK, null);
this.additionalCost = makeCost();
this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText();
this.beholdType = beholdType;
this.additionalCost = makeCost(beholdType);
this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText();
this.setRuleAtTheTop(true);
}
private BeholdDragonAbility(final BeholdDragonAbility ability) {
private BeholdAbility(final BeholdAbility ability) {
super(ability);
this.beholdType = ability.beholdType;
this.rule = ability.rule;
this.additionalCost = ability.additionalCost.copy();
}
@Override
public BeholdDragonAbility copy() {
return new BeholdDragonAbility(this);
public BeholdAbility copy() {
return new BeholdAbility(this);
}
public void resetCost() {
@ -68,7 +76,7 @@ public class BeholdDragonAbility extends StaticAbility implements OptionalAdditi
this.resetCost();
boolean canPay = additionalCost.canPay(ability, this, ability.getControllerId(), game);
if (!canPay || !player.chooseUse(Outcome.Exile, promptString + '?', ability, game)) {
if (!canPay || !player.chooseUse(Outcome.Exile, promptString + beholdType.getDescription() + '?', ability, game)) {
return;
}
@ -76,7 +84,7 @@ public class BeholdDragonAbility extends StaticAbility implements OptionalAdditi
for (Cost cost : ((Costs<Cost>) additionalCost)) {
ability.getCosts().add(cost.copy());
}
ability.setCostsTag(BEHOLD_DRAGON_ACTIVATION_VALUE_KEY, null);
ability.setCostsTag(BEHOLD_ACTIVATION_VALUE_KEY, null);
}
@Override

View file

@ -0,0 +1,96 @@
package mage.constants;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.cards.CardsImpl;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public enum BeholdType {
DRAGON(SubType.DRAGON),
MERFOLK(SubType.MERFOLK);
private final FilterPermanent filterPermanent;
private final FilterCard filterCard;
private final String description;
BeholdType(SubType subType) {
this.filterPermanent = new FilterControlledPermanent(subType);
this.filterCard = new FilterCard(subType);
this.description = subType.getIndefiniteArticle() + ' ' + subType.getDescription();
}
public String getDescription() {
return description;
}
public FilterCard getFilterCard() {
return filterCard;
}
public FilterPermanent getFilterPermanent() {
return filterPermanent;
}
public boolean canBehold(UUID controllerId, Game game, Ability source) {
return Optional
.ofNullable(game.getPlayer(controllerId))
.map(Player::getHand)
.map(cards -> cards.count(this.getFilterCard(), game) > 0)
.orElse(false)
|| game
.getBattlefield()
.contains(this.getFilterPermanent(), controllerId, source, game, 1);
}
public Card doBehold(Player player, Game game, Ability source) {
boolean hasPermanent = game
.getBattlefield()
.contains(this.getFilterPermanent(), player.getId(), source, game, 1);
boolean hasHand = player.getHand().count(this.getFilterCard(), game) > 0;
boolean usePermanent;
if (hasPermanent && hasHand) {
usePermanent = player.chooseUse(
Outcome.Neutral, "Choose " + this.getDescription() + " you control or reveal one from your hand?",
null, "Choose controlled", "Reveal from hand", source, game);
} else if (hasPermanent) {
usePermanent = true;
} else if (hasHand) {
usePermanent = false;
} else {
return null;
}
if (usePermanent) {
TargetPermanent target = new TargetPermanent(this.getFilterPermanent());
target.withNotTarget(true);
player.choose(Outcome.Neutral, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
return null;
}
game.informPlayers(player.getLogName() + " chooses to behold " + permanent.getLogName());
return permanent;
}
TargetCard target = new TargetCardInHand(this.getFilterCard());
player.choose(Outcome.Neutral, player.getHand(), target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
return null;
}
player.revealCards(source, new CardsImpl(card), game);
return card;
}
}

View file

@ -0,0 +1,29 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author TheElk801
*/
public final class MerfolkWhiteBlueToken extends TokenImpl {
public MerfolkWhiteBlueToken() {
super("Merfolk Token", "1/1 white and blue Merfolk creature token");
cardType.add(CardType.CREATURE);
color.setWhite(true);
color.setBlue(true);
subtype.add(SubType.MERFOLK);
power = new MageInt(1);
toughness = new MageInt(1);
}
private MerfolkWhiteBlueToken(final MerfolkWhiteBlueToken token) {
super(token);
}
public MerfolkWhiteBlueToken copy() {
return new MerfolkWhiteBlueToken(this);
}
}