Merge pull request #5553 from Zzooouhh/Zzooouhh-leg

Implemented Brine Hag, Venarian Gold, Wall of Shadows
This commit is contained in:
L_J 2019-01-27 09:43:30 +01:00 committed by GitHub
commit ba5b87fae8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 341 additions and 3 deletions

View file

@ -0,0 +1,93 @@
package mage.cards.b;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.PermanentInListPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author L_J
*/
public final class BrineHag extends CardImpl {
public BrineHag(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
this.subtype.add(SubType.HAG);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Brine Hag dies, change the base power and toughness of all creatures that dealt damage to it this turn to 0/2.
this.addAbility(new DiesTriggeredAbility(new BrineHagEffect()));
}
public BrineHag(final BrineHag card) {
super(card);
}
@Override
public BrineHag copy() {
return new BrineHag(this);
}
}
class BrineHagEffect extends OneShotEffect {
public BrineHagEffect() {
super(Outcome.Detriment);
this.staticText = "change the base power and toughness of all creatures that dealt damage to it this turn to 0/2";
}
public BrineHagEffect(final BrineHagEffect effect) {
super(effect);
}
@Override
public BrineHagEffect copy() {
return new BrineHagEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (sourcePermanent != null) {
List<Permanent> list = new ArrayList<>();
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
for (Permanent creature : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game)) {
if (sourcePermanent.getDealtDamageByThisTurn().contains(new MageObjectReference(creature.getId(), game))) {
list.add(creature);
}
}
}
}
if (!list.isEmpty()) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new PermanentInListPredicate(list));
game.addEffect(new SetPowerToughnessAllEffect(0, 2, Duration.Custom, filter, true), source);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,94 @@
package mage.cards.v;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.AttachedToCounterCondition;
import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
import mage.abilities.effects.common.TapEnchantedEffect;
import mage.abilities.effects.common.counter.AddCountersAttachedEffect;
import mage.abilities.effects.common.counter.RemoveCountersAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.stack.StackObject;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
* @author L_J
*/
public final class VenarianGold extends CardImpl {
public VenarianGold(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{X}{U}{U}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// When Venarian Gold enters the battlefield, tap enchanted creature and put a number of sleep counters on it equal to the value of X as you cast Venarian Gold.
Ability ability = new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect());
ability.addEffect(new AddCountersAttachedEffect(CounterType.SLEEP.createInstance(), new VenarianGoldValue(), "it equal to the value of X as you cast {this}"));
this.addAbility(ability);
// Enchanted creature doesnt untap during its controllers untap step if it has a sleep counter on it.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(),
new AttachedToCounterCondition(CounterType.SLEEP, 1)).setText("Enchanted creature doesn't untap during its controller's untap step if it has a sleep counter on it")));
// At the beginning of the upkeep of enchanted creatures controller, remove a sleep counter from that creature.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new RemoveCountersAttachedEffect(CounterType.SLEEP.createInstance(), "that creature"),
TargetController.CONTROLLER_ATTACHED_TO, false));
}
public VenarianGold(final VenarianGold card) {
super(card);
}
@Override
public VenarianGold copy() {
return new VenarianGold(this);
}
}
class VenarianGoldValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
MageObject mageObject = game.getLastKnownInformation(sourceAbility.getSourceId(), Zone.STACK);
if (mageObject != null && mageObject instanceof StackObject) {
return ((StackObject) mageObject).getStackAbility().getManaCostsToPay().getX();
}
return 0;
}
@Override
public VenarianGoldValue copy() {
return new VenarianGoldValue();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "";
}
}

View file

@ -0,0 +1,138 @@
package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.CantBeTargetedSourceEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.filter.FilterObject;
import mage.filter.FilterPermanent;
import mage.filter.FilterStackObject;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.BlockedByIdPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.DamageCreatureEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.target.Target;
/**
*
* @author L_J
*/
public final class WallOfShadows extends CardImpl {
private static final FilterObject filter = new FilterStackObject("spells that can target only Walls or of abilities that can target only Walls");
static {
filter.add(new CanTargetOnlyWallsPredicate());
}
public WallOfShadows(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.subtype.add(SubType.WALL);
this.power = new MageInt(0);
this.toughness = new MageInt(1);
// Defender
this.addAbility(DefenderAbility.getInstance());
// Prevent all damage that would be dealt to Wall of Vapor by creatures it's blocking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WallOfShadowsEffect()));
// Wall of Shadows can't be the target of spells that can target only Walls or of abilities that can target only Walls.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedSourceEffect(filter, Duration.WhileOnBattlefield)));
}
public WallOfShadows(final WallOfShadows card) {
super(card);
}
@Override
public WallOfShadows copy() {
return new WallOfShadows(this);
}
}
class WallOfShadowsEffect extends PreventionEffectImpl {
WallOfShadowsEffect() {
super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false);
staticText = "Prevent all damage that would be dealt to {this} by creatures it's blocking";
}
WallOfShadowsEffect(final WallOfShadowsEffect effect) {
super(effect);
}
@Override
public WallOfShadowsEffect copy() {
return new WallOfShadowsEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event instanceof DamageCreatureEvent && event.getAmount() > 0) {
DamageCreatureEvent damageEvent = (DamageCreatureEvent) event;
if (event.getTargetId().equals(source.getSourceId())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(damageEvent.getSourceId());
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new BlockedByIdPredicate(source.getSourceId()));
if (permanent != null && filter.match(permanent, game)) {
return true;
}
}
}
return false;
}
}
class CanTargetOnlyWallsPredicate implements Predicate<MageObject> {
@Override
public boolean apply(MageObject input, Game game) {
boolean canTargetOnlyWalls = false;
StackObject stackObject = game.getStack().getSpell(input.getId());
if (stackObject != null) {
for (Mode mode : stackObject.getStackAbility().getModes().values()) {
for (Target target : mode.getTargets()) {
Filter filter = target.getFilter();
if (filter != null && filter instanceof FilterPermanent) {
for (Object predicate : filter.getPredicates()) {
if (predicate instanceof SubtypePredicate) {
if (predicate.toString().equals("Subtype(Wall)")) {
canTargetOnlyWalls = true; // can target a Wall
} else {
return false; // can target a non-Wall permanent
}
}
// no return statement here, as different predicates might still apply (e.g. "blocking Wall")
}
} else {
return false; // can target non-permanents (i.e. not Walls)
}
}
}
}
return canTargetOnlyWalls;
}
@Override
public String toString() {
return "can target only Walls";
}
}

View file

@ -60,6 +60,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Blue Mana Battery", 275, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class)); cards.add(new SetCardInfo("Blue Mana Battery", 275, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class));
cards.add(new SetCardInfo("Boomerang", 48, Rarity.COMMON, mage.cards.b.Boomerang.class)); cards.add(new SetCardInfo("Boomerang", 48, Rarity.COMMON, mage.cards.b.Boomerang.class));
cards.add(new SetCardInfo("Boris Devilboon", 223, Rarity.RARE, mage.cards.b.BorisDevilboon.class)); cards.add(new SetCardInfo("Boris Devilboon", 223, Rarity.RARE, mage.cards.b.BorisDevilboon.class));
cards.add(new SetCardInfo("Brine Hag", 49, Rarity.UNCOMMON, mage.cards.b.BrineHag.class));
cards.add(new SetCardInfo("Bronze Horse", 276, Rarity.RARE, mage.cards.b.BronzeHorse.class)); cards.add(new SetCardInfo("Bronze Horse", 276, Rarity.RARE, mage.cards.b.BronzeHorse.class));
cards.add(new SetCardInfo("Carrion Ants", 90, Rarity.RARE, mage.cards.c.CarrionAnts.class)); cards.add(new SetCardInfo("Carrion Ants", 90, Rarity.RARE, mage.cards.c.CarrionAnts.class));
cards.add(new SetCardInfo("Cat Warriors", 177, Rarity.COMMON, mage.cards.c.CatWarriors.class)); cards.add(new SetCardInfo("Cat Warriors", 177, Rarity.COMMON, mage.cards.c.CatWarriors.class));
@ -300,6 +301,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Urborg", 310, Rarity.UNCOMMON, mage.cards.u.Urborg.class)); cards.add(new SetCardInfo("Urborg", 310, Rarity.UNCOMMON, mage.cards.u.Urborg.class));
cards.add(new SetCardInfo("Vaevictis Asmadi", 269, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class)); cards.add(new SetCardInfo("Vaevictis Asmadi", 269, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class));
cards.add(new SetCardInfo("Vampire Bats", 125, Rarity.COMMON, mage.cards.v.VampireBats.class)); cards.add(new SetCardInfo("Vampire Bats", 125, Rarity.COMMON, mage.cards.v.VampireBats.class));
cards.add(new SetCardInfo("Venarian Gold", 83, Rarity.COMMON, mage.cards.v.VenarianGold.class));
cards.add(new SetCardInfo("Visions", 41, Rarity.UNCOMMON, mage.cards.v.Visions.class)); cards.add(new SetCardInfo("Visions", 41, Rarity.UNCOMMON, mage.cards.v.Visions.class));
cards.add(new SetCardInfo("Voodoo Doll", 298, Rarity.RARE, mage.cards.v.VoodooDoll.class)); cards.add(new SetCardInfo("Voodoo Doll", 298, Rarity.RARE, mage.cards.v.VoodooDoll.class));
cards.add(new SetCardInfo("Walking Dead", 126, Rarity.COMMON, mage.cards.w.WalkingDead.class)); cards.add(new SetCardInfo("Walking Dead", 126, Rarity.COMMON, mage.cards.w.WalkingDead.class));
@ -310,6 +312,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Wall of Light", 43, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class)); cards.add(new SetCardInfo("Wall of Light", 43, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class));
cards.add(new SetCardInfo("Wall of Opposition", 171, Rarity.RARE, mage.cards.w.WallOfOpposition.class)); cards.add(new SetCardInfo("Wall of Opposition", 171, Rarity.RARE, mage.cards.w.WallOfOpposition.class));
cards.add(new SetCardInfo("Wall of Putrid Flesh", 127, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class)); cards.add(new SetCardInfo("Wall of Putrid Flesh", 127, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class));
cards.add(new SetCardInfo("Wall of Shadows", 128, Rarity.COMMON, mage.cards.w.WallOfShadows.class));
cards.add(new SetCardInfo("Wall of Tombstones", 129, Rarity.UNCOMMON, mage.cards.w.WallOfTombstones.class)); cards.add(new SetCardInfo("Wall of Tombstones", 129, Rarity.UNCOMMON, mage.cards.w.WallOfTombstones.class));
cards.add(new SetCardInfo("Wall of Vapor", 84, Rarity.COMMON, mage.cards.w.WallOfVapor.class)); cards.add(new SetCardInfo("Wall of Vapor", 84, Rarity.COMMON, mage.cards.w.WallOfVapor.class));
cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class)); cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class));

View file

@ -23,7 +23,7 @@ public class AddCountersAttachedEffect extends OneShotEffect {
private String textEnchanted; private String textEnchanted;
public AddCountersAttachedEffect(Counter counter, String textEnchanted) { public AddCountersAttachedEffect(Counter counter, String textEnchanted) {
this(counter, new StaticValue(0), textEnchanted); this(counter, new StaticValue(1), textEnchanted);
} }
/** /**
@ -56,8 +56,12 @@ public class AddCountersAttachedEffect extends OneShotEffect {
Permanent attachedTo = game.getPermanent(permanent.getAttachedTo()); Permanent attachedTo = game.getPermanent(permanent.getAttachedTo());
if (attachedTo != null && counter != null) { if (attachedTo != null && counter != null) {
Counter newCounter = counter.copy(); Counter newCounter = counter.copy();
newCounter.add(amount.calculate(game, source, this)); int countersToAdd = amount.calculate(game, source, this);
attachedTo.addCounters(newCounter, source, game); if (countersToAdd > 0) {
countersToAdd--;
newCounter.add(countersToAdd);
attachedTo.addCounters(newCounter, source, game);
}
} }
return true; return true;
} }

View file

@ -2,6 +2,7 @@
package mage.filter; package mage.filter;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
import mage.game.Game; import mage.game.Game;
@ -28,4 +29,5 @@ public interface Filter<E> extends Serializable {
Filter<E> copy(); Filter<E> copy();
List<Predicate<? super E>> getPredicates();
} }

View file

@ -75,4 +75,8 @@ public abstract class FilterImpl<E> implements Filter<E> {
this.lockedFilter = lockedFilter; this.lockedFilter = lockedFilter;
} }
public List<Predicate<? super E>> getPredicates() {
return predicates;
}
} }