[CLU] Implement Apothecary White & Emissary Green (#12642)

This commit is contained in:
Sidorovich77 2024-08-15 04:10:07 +03:00 committed by GitHub
parent 37bf7a68cd
commit 1e414442b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 202 additions and 0 deletions

View file

@ -0,0 +1,106 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.TapVariableTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.game.permanent.token.FoodToken;
import mage.game.permanent.token.HumanToken;
import java.util.Objects;
import java.util.UUID;
/**
* @author Sidorovich77
*/
public final class ApothecaryWhite extends CardImpl {
static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "untapped Foods you control");
static {
filter.add(TappedPredicate.UNTAPPED);
}
public ApothecaryWhite(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Whenever you attack, you create a Food token for each player being attacked.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(
new CreateTokenEffect(new FoodToken(), ApothecaryWhiteValue.instance)
.setText("you create a Food token for each player being attacked."), 1));
// {W}, {T}, Tap X untapped Foods you control: Create X 1/1 white Human creature tokens.
Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new HumanToken(), GetXValue.instance), new ManaCostsImpl<>("{W}"));
ability.addCost(new TapSourceCost());
ability.addCost(new TapVariableTargetCost(filter));
this.addAbility(ability);
}
private ApothecaryWhite(final ApothecaryWhite card) {
super(card);
}
@Override
public ApothecaryWhite copy() {
return new ApothecaryWhite(this);
}
}
enum ApothecaryWhiteValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return game
.getCombat()
.getGroups()
.stream()
.filter(combatGroup -> combatGroup
.getAttackers()
.stream()
.map(game::getControllerId)
.anyMatch(sourceAbility::isControlledBy))
.map(CombatGroup::getDefenderId)
.filter(Objects::nonNull)
.distinct()
.map(game::getPlayer)
.filter(Objects::nonNull)
.mapToInt(x -> 1)
.sum();
}
@Override
public ApothecaryWhiteValue copy() {
return this;
}
@Override
public String getMessage() {
return "player being attacked.";
}
}

View file

@ -0,0 +1,94 @@
package mage.cards.e;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.TwoChoiceVote;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.TreasureToken;
import java.util.UUID;
/**
* @author Sidorovich77
*/
public final class EmissaryGreen extends CardImpl {
public EmissaryGreen(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
//Whenever Emissary Green attacks, starting with you, each player votes for profit or security.
// You create a number of Treasure tokens equal to twice the number of profit votes.
// Put a number of +1/+1 counters on each creature you control equal to the number of security votes.
this.addAbility(new AttacksTriggeredAbility(new EmissaryGreenEffect()));
}
private EmissaryGreen(final EmissaryGreen card) {
super(card);
}
@Override
public EmissaryGreen copy() {
return new EmissaryGreen(this);
}
}
class EmissaryGreenEffect extends OneShotEffect {
EmissaryGreenEffect() {
super(Outcome.Benefit);
staticText = "starting with you, each player votes for profit or security. " +
"You create a number of Treasure tokens equal to twice the number of profit votes. " +
"Put a number of +1/+1 counters on each creature you control equal to the number of security votes.";
}
private EmissaryGreenEffect(final EmissaryGreenEffect effect) {
super(effect);
}
@Override
public EmissaryGreenEffect copy() {
return new EmissaryGreenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
TwoChoiceVote vote = new TwoChoiceVote(
"Profit (treasure)", "Security (+1/+1 counters)", Outcome.Detriment
);
vote.doVotes(source, game);
int profitCounter = vote.getVoteCount(true);
int securityCounter = vote.getVoteCount(false);
if (profitCounter > 0) {
new TreasureToken().putOntoBattlefield(2 * profitCounter, game, source);
}
if (securityCounter > 0) {
AddCountersAllEffect countersAllEffect = new AddCountersAllEffect(
CounterType.P1P1.createInstance(),
StaticValue.get(securityCounter),
StaticFilters.FILTER_CONTROLLED_CREATURE
);
countersAllEffect.setText("put a number of +1/+1 counters on each creature you control equal to the number of security votes.");
countersAllEffect.apply(game, source);
}
return profitCounter + securityCounter > 0;
}
}

View file

@ -25,6 +25,7 @@ public final class RavnicaClueEdition extends ExpansionSet {
cards.add(new SetCardInfo("Afterlife Insurance", 23, Rarity.UNCOMMON, mage.cards.a.AfterlifeInsurance.class));
cards.add(new SetCardInfo("Ajani's Pridemate", 52, Rarity.UNCOMMON, mage.cards.a.AjanisPridemate.class));
cards.add(new SetCardInfo("Angel of Vitality", 53, Rarity.UNCOMMON, mage.cards.a.AngelOfVitality.class));
cards.add(new SetCardInfo("Apothecary White", 1, Rarity.RARE, mage.cards.a.ApothecaryWhite.class));
cards.add(new SetCardInfo("Azorius Arrester", 54, Rarity.COMMON, mage.cards.a.AzoriusArrester.class));
cards.add(new SetCardInfo("Azorius Chancery", 229, Rarity.COMMON, mage.cards.a.AzoriusChancery.class));
cards.add(new SetCardInfo("Azorius Guildgate", 230, Rarity.COMMON, mage.cards.a.AzoriusGuildgate.class));
@ -81,6 +82,7 @@ public final class RavnicaClueEdition extends ExpansionSet {
cards.add(new SetCardInfo("Duskmantle Seer", 188, Rarity.MYTHIC, mage.cards.d.DuskmantleSeer.class));
cards.add(new SetCardInfo("Duskshell Crawler", 161, Rarity.COMMON, mage.cards.d.DuskshellCrawler.class));
cards.add(new SetCardInfo("Ecstatic Electromancer", 31, Rarity.UNCOMMON, mage.cards.e.EcstaticElectromancer.class));
cards.add(new SetCardInfo("Emissary Green", 5, Rarity.RARE, mage.cards.e.EmissaryGreen.class));
cards.add(new SetCardInfo("Enforcer Griffin", 60, Rarity.COMMON, mage.cards.e.EnforcerGriffin.class));
cards.add(new SetCardInfo("Enraged Ceratok", 162, Rarity.UNCOMMON, mage.cards.e.EnragedCeratok.class));
cards.add(new SetCardInfo("Erratic Visionary", 85, Rarity.COMMON, mage.cards.e.ErraticVisionary.class));