Skip to content

Commit

Permalink
Merge branch 'magefree:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Grath authored Feb 8, 2023
2 parents 112d318 + f070f9a commit f9758a8
Show file tree
Hide file tree
Showing 18 changed files with 574 additions and 54 deletions.
27 changes: 21 additions & 6 deletions Mage.Sets/src/mage/cards/a/AminatousAugury.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.ModalDoubleFacesCard;
import mage.cards.ModalDoubleFacesCardHalf;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.AsThoughEffectType;
Expand Down Expand Up @@ -98,7 +100,7 @@ public boolean apply(Game game, Ability source) {
// put a land card from among them onto the battlefield
TargetCard target = new TargetCard(Zone.EXILED, StaticFilters.FILTER_CARD_LAND_A);

if (cardsToCast.count(StaticFilters.FILTER_CARD_LAND, game) > 0) {
if (cardsToCast.count(StaticFilters.FILTER_CARD_LAND, game) > 0) {
if (controller.chooseUse(Outcome.PutLandInPlay, "Put a land from among the exiled cards into play?", source, game)) {
if (controller.choose(Outcome.PutLandInPlay, cardsToCast, target, game)) {
Card card = cardsToCast.get(target.getFirstTarget(), game);
Expand All @@ -110,12 +112,25 @@ public boolean apply(Game game, Ability source) {
}
}

for (Card card : cardsToCast.getCards(StaticFilters.FILTER_CARD_NON_LAND, game)) {
AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
// TODO staticFilters must be configured to check the main card face (Ex: MDFC card like Sea Gate Restoration does not count as a land if face up)
for (Card card : cardsToCast.getCards(game)) {
// ex: Sea Gate Restoration bug #9956
if (card instanceof ModalDoubleFacesCard) {
ModalDoubleFacesCardHalf leftHalfCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
if (leftHalfCard != null
&& !leftHalfCard.isLand(game)) {
AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(leftHalfCard, game));
game.addEffect(effect, source);
}
continue;
}
if (!card.isLand(game)) {
AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
}
}
// TODO: I think this should be returning true
return true;
}
}
Expand Down
4 changes: 2 additions & 2 deletions Mage.Sets/src/mage/cards/a/ArdozCobblerOfWar.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public ArdozCobblerOfWar(UUID ownerId, CardSetInfo setInfo) {
this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility(
new BoostTargetEffect(2, 0)
.setText("that creature gets +2/+0 until end of turn"),
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false,
StaticFilters.FILTER_CONTROLLED_A_CREATURE, false,
SetTargetPointer.PERMANENT, true
));
).setTriggerPhrase("Whenever {this} or another creature enters the battlefield under your control, "));

// {3}{R}: Create a 1/1 red Goblin creature token with haste. Activate only as sorcery.
this.addAbility(new ActivateAsSorceryActivatedAbility(
Expand Down
2 changes: 1 addition & 1 deletion Mage.Sets/src/mage/cards/a/AtraxaGrandUnifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
Expand Down Expand Up @@ -90,6 +89,7 @@ public boolean apply(Game game, Ability source) {
TargetCard target = new AtraxaGrandUnifierTarget();
player.choose(outcome, cards, target, game);
Cards toHand = new CardsImpl(target.getTargets());
player.revealCards(source, toHand, game);
player.moveCards(toHand, Zone.HAND, source, game);
cards.retainZone(Zone.LIBRARY, game);
player.putCardsOnBottomOfLibrary(cards, game, source, false);
Expand Down
41 changes: 2 additions & 39 deletions Mage.Sets/src/mage/cards/b/BaldinCenturyHerdmaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ChooseOpponentEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.ruleModifying.CombatDamageByToughnessEffect;
import mage.cards.CardImpl;
Expand All @@ -19,13 +17,8 @@
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;

import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

/**
Expand All @@ -51,7 +44,7 @@ public BaldinCenturyHerdmaster(UUID ownerId, CardSetInfo setInfo) {

// Hundred Hand Slap—Whenever E. Honda, Sumo Champion attacks, up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand.
Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(
StaticValue.get(0), BaldinCenturyHerdmasterValue.instance, Duration.EndOfTurn
StaticValue.get(0), CardsInControllerHandCount.instance, Duration.EndOfTurn
).setText("up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand"));
ability.addTarget(new TargetCreaturePermanent(0, 100));
this.addAbility(ability.withFlavorWord("Hundred Hand Slap"));
Expand All @@ -66,33 +59,3 @@ public BaldinCenturyHerdmaster copy() {
return new BaldinCenturyHerdmaster(this);
}
}

enum BaldinCenturyHerdmasterValue implements DynamicValue {
instance;

@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return Optional.ofNullable(game.getPlayer(
(UUID) game.getState().getValue(sourceAbility.getSourceId() + ChooseOpponentEffect.VALUE_KEY)
))
.filter(Objects::nonNull)
.map(Player::getHand)
.map(Set::size)
.orElse(0);
}

@Override
public BaldinCenturyHerdmasterValue copy() {
return this;
}

@Override
public String getMessage() {
return "";
}

@Override
public String toString() {
return "1";
}
}
108 changes: 108 additions & 0 deletions Mage.Sets/src/mage/cards/b/BenevolentHydra.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package mage.cards.b;

import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.util.CardUtil;

import java.util.UUID;

/**
*
* @author Grath
*/
public final class BenevolentHydra extends CardImpl {

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

this.subtype.add(SubType.HYDRA);
this.power = new MageInt(1);
this.toughness = new MageInt(1);

// Hungering Hydra enters the battlefield with X +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(
new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance())
));

// If one or more +1/+1 counters would be put on another creature you control, that many plus one +1/+1 counters are put on it instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BenevolentHydraEffect()));

// {T}, Remove a +1/+1 counter from Benevolent Hydra: Put a +1/+1 counter on another target creature you control.
Ability ability = new SimpleActivatedAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()).setText("Put a +1/+1 counter on another target creature you control"), new TapSourceCost());
ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE));
this.addAbility(ability);
}

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

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

class BenevolentHydraEffect extends ReplacementEffectImpl {

BenevolentHydraEffect() {
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
staticText = "If one or more +1/+1 counters would be put on another creature you control, that many plus one +1/+1 counters are put on it instead";
}

BenevolentHydraEffect(final BenevolentHydraEffect effect) {
super(effect);
}

@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmountForCounters(CardUtil.overflowInc(event.getAmount(), 1), true);
return false;
}

@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ADD_COUNTERS;
}

@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getData().equals(CounterType.P1P1.getName()) && event.getAmount() > 0) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent == null) {
permanent = game.getPermanentEntering(event.getTargetId());
}
return permanent != null && permanent.isControlledBy(source.getControllerId())
&& permanent.isCreature(game) && !event.getTargetId().equals(source.getSourceId());
}
return false;
}

@Override
public boolean apply(Game game, Ability source) {
return true;
}

@Override
public BenevolentHydraEffect copy() {
return new BenevolentHydraEffect(this);
}
}
76 changes: 76 additions & 0 deletions Mage.Sets/src/mage/cards/c/CreepingBloodsucker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@

package mage.cards.c;

import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.game.Game;
import mage.players.Player;

import java.util.UUID;

/**
*
* @author Grath
*/
public final class CreepingBloodsucker extends CardImpl {

public CreepingBloodsucker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
this.subtype.add(SubType.VAMPIRE);

this.power = new MageInt(1);
this.toughness = new MageInt(2);

// At the beginning of your upkeep, Creeping Bloodsucker deals 1 damage to each opponent. You gain life equal to the damage dealt this way.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreepingBloodsuckerEffect(), TargetController.YOU, false));
}

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

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

class CreepingBloodsuckerEffect extends OneShotEffect {
public CreepingBloodsuckerEffect() {
super(Outcome.Damage);
staticText = "{this} deals 1 damage to each opponent. You gain life equal to the damage dealt this way";
}

public CreepingBloodsuckerEffect(final CreepingBloodsuckerEffect effect) {
super(effect);
}

@Override
public boolean apply(Game game, Ability source) {
int damageDealt = 0;
Player player = game.getPlayer(source.getControllerId());
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
if (player.hasOpponent(playerId, game)) {
damageDealt += game.getPlayer(playerId).damage(1, source.getSourceId(), source, game);
}
}
if (damageDealt > 0) {
game.getPlayer(source.getControllerId()).gainLife(damageDealt, game, source);
}
return true;
}

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

}
65 changes: 65 additions & 0 deletions Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package mage.cards.d;

import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetControlledCreaturePermanent;

import java.util.UUID;

/**
* @author Grath
*/
public final class DistinguishedConjurer extends CardImpl {

private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("another creature");
private static final FilterControlledCreaturePermanent filter2
= new FilterControlledCreaturePermanent("another target creature you control");

static {
filter.add(AnotherPredicate.instance);
filter2.add(AnotherPredicate.instance);
}

public DistinguishedConjurer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");

this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(2);

// Whenever another creature enters the battlefield under your control, you gain 1 life.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter));

// {4}{W}, {T}: Exile another target creature you control, then return it to the battlefield under its owner’s control.
Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{4}{W}"));
ability.addCost(new TapSourceCost());
ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then"));
ability.addTarget(new TargetControlledCreaturePermanent(filter2));
this.addAbility(ability);
}

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

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

0 comments on commit f9758a8

Please sign in to comment.