mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Merge pull request #5553 from Zzooouhh/Zzooouhh-leg
Implemented Brine Hag, Venarian Gold, Wall of Shadows
This commit is contained in:
commit
ba5b87fae8
7 changed files with 341 additions and 3 deletions
93
Mage.Sets/src/mage/cards/b/BrineHag.java
Normal file
93
Mage.Sets/src/mage/cards/b/BrineHag.java
Normal 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;
|
||||
}
|
||||
}
|
94
Mage.Sets/src/mage/cards/v/VenarianGold.java
Normal file
94
Mage.Sets/src/mage/cards/v/VenarianGold.java
Normal 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 doesn’t untap during its controller’s 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 creature’s 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 "";
|
||||
}
|
||||
}
|
138
Mage.Sets/src/mage/cards/w/WallOfShadows.java
Normal file
138
Mage.Sets/src/mage/cards/w/WallOfShadows.java
Normal 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";
|
||||
}
|
||||
}
|
|
@ -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("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("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("Carrion Ants", 90, Rarity.RARE, mage.cards.c.CarrionAnts.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("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("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("Voodoo Doll", 298, Rarity.RARE, mage.cards.v.VoodooDoll.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 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 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 Vapor", 84, Rarity.COMMON, mage.cards.w.WallOfVapor.class));
|
||||
cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class));
|
||||
|
|
|
@ -23,7 +23,7 @@ public class AddCountersAttachedEffect extends OneShotEffect {
|
|||
private String textEnchanted;
|
||||
|
||||
public AddCountersAttachedEffect(Counter counter, String textEnchanted) {
|
||||
this(counter, new StaticValue(0), textEnchanted);
|
||||
this(counter, new StaticValue(1), textEnchanted);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,9 +56,13 @@ public class AddCountersAttachedEffect extends OneShotEffect {
|
|||
Permanent attachedTo = game.getPermanent(permanent.getAttachedTo());
|
||||
if (attachedTo != null && counter != null) {
|
||||
Counter newCounter = counter.copy();
|
||||
newCounter.add(amount.calculate(game, source, this));
|
||||
int countersToAdd = amount.calculate(game, source, this);
|
||||
if (countersToAdd > 0) {
|
||||
countersToAdd--;
|
||||
newCounter.add(countersToAdd);
|
||||
attachedTo.addCounters(newCounter, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.filter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
|
||||
|
@ -28,4 +29,5 @@ public interface Filter<E> extends Serializable {
|
|||
|
||||
Filter<E> copy();
|
||||
|
||||
List<Predicate<? super E>> getPredicates();
|
||||
}
|
||||
|
|
|
@ -75,4 +75,8 @@ public abstract class FilterImpl<E> implements Filter<E> {
|
|||
this.lockedFilter = lockedFilter;
|
||||
}
|
||||
|
||||
public List<Predicate<? super E>> getPredicates() {
|
||||
return predicates;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue