Implemented Allosaurus Shepherd and Blessed Sanctuary (#6711)

* added allosaurus shepherd and blessed sanctuary

* fixed nonascii apostrophes

* added continuous effect dependency
This commit is contained in:
18ths 2020-06-24 17:17:32 +02:00 committed by GitHub
parent 785be83484
commit 40036271da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 264 additions and 24 deletions

View file

@ -1401,4 +1401,7 @@
|Generate|TOK:C20|Soldier|||SoldierToken| |Generate|TOK:C20|Soldier|||SoldierToken|
|Generate|TOK:C20|Spirit|||SpiritWhiteToken| |Generate|TOK:C20|Spirit|||SpiritWhiteToken|
|Generate|TOK:C20|Treasure|||TreasureToken| |Generate|TOK:C20|Treasure|||TreasureToken|
|Generate|TOK:C20|Zombie|||ZombieToken| |Generate|TOK:C20|Zombie|||ZombieToken|
# JMP
|Generate|TOK:JMP|Unicorn|||UnicornToken|

View file

@ -0,0 +1,68 @@
package mage.cards.a;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.CantBeCounteredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CantBeCounteredControlledEffect;
import mage.abilities.effects.common.continuous.CreaturesBecomeOtherTypeEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.FilterSpell;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
import java.util.UUID;
public class AllosaurusShepherd extends CardImpl {
private static final FilterSpell greenSpellsFilter = new FilterSpell("green spells");
private static final FilterPermanent elvesFilter = new FilterControlledCreaturePermanent("each Elf creature you control");
static {
greenSpellsFilter.add(new ColorPredicate(ObjectColor.GREEN));
elvesFilter.add(SubType.ELF.getPredicate());
}
public AllosaurusShepherd(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
//Allosaurus Shepherd can't be countered.
this.addAbility(new CantBeCounteredAbility());
//Green spells you control can't be countered.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new CantBeCounteredControlledEffect(greenSpellsFilter, null, Duration.WhileOnBattlefield)));
//4GG: Until end of turn, each Elf creature you control has base power and toughness 5/5 and becomes a Dinosaur in addition to its other creature types.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new SetPowerToughnessAllEffect(5, 5, Duration.EndOfTurn, elvesFilter, true)
.setText("Until end of turn, each Elf creature you control has base power and toughness 5/5"),
new ManaCostsImpl("{4}{G}{G}"));
ability.addEffect(new CreaturesBecomeOtherTypeEffect(elvesFilter, SubType.DINOSAUR, Duration.EndOfTurn)
.setText("and becomes a Dinosaur in addition to its other creature types"));
this.addAbility(ability);
}
public AllosaurusShepherd(final AllosaurusShepherd card) {
super(card);
}
@Override
public AllosaurusShepherd copy() {
return new AllosaurusShepherd(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.b;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.PreventAllNonCombatDamageToAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.permanent.token.UnicornToken;
import java.util.UUID;
public class BlessedSanctuary extends CardImpl {
private static final FilterPermanent filterYourCreatures = new FilterControlledCreaturePermanent("creatures you control");
private static final FilterControlledCreaturePermanent filterNontoken = new FilterControlledCreaturePermanent("nontoken creature");
static {
filterNontoken.add(Predicates.not(TokenPredicate.instance));
}
public BlessedSanctuary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{W}");
//Prevent all noncombat damage that would be dealt to you and creatures you control.
this.addAbility(new SimpleStaticAbility(new PreventAllNonCombatDamageToAllEffect(
Duration.WhileOnBattlefield, filterYourCreatures, true)));
//Whenever a nontoken creature enters the battlefield under your control, create a 2/2 white Unicorn creature token.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD,
new CreateTokenEffect(new UnicornToken()), filterNontoken, false));
}
public BlessedSanctuary(final BlessedSanctuary card) {
super(card);
}
@Override
public BlessedSanctuary copy() {
return new BlessedSanctuary(this);
}
}

View file

@ -3,13 +3,15 @@ package mage.cards.d;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.BecomesTargetTriggeredAbility; import mage.abilities.common.BecomesTargetTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.effects.common.continuous.CreaturesBecomeOtherTypeEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -20,13 +22,18 @@ import mage.game.permanent.Permanent;
*/ */
public final class DismissIntoDream extends CardImpl { public final class DismissIntoDream extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Each creature your opponents control");
static {
filter.add(TargetController.OPPONENT.getControllerPredicate());
}
public DismissIntoDream(UUID ownerId, CardSetInfo setInfo) { public DismissIntoDream(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{6}{U}"); super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{6}{U}");
// Each creature your opponents control is an Illusion in addition to its other types // Each creature your opponents control is an Illusion in addition to its other types
// and has "When this creature becomes the target of a spell or ability, sacrifice it." // and has "When this creature becomes the target of a spell or ability, sacrifice it."
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DismissIntoDreamEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DismissIntoDreamEffect(filter)));
} }
public DismissIntoDream(final DismissIntoDream card) { public DismissIntoDream(final DismissIntoDream card) {
@ -39,16 +46,11 @@ public final class DismissIntoDream extends CardImpl {
} }
} }
class DismissIntoDreamEffect extends ContinuousEffectImpl { class DismissIntoDreamEffect extends CreaturesBecomeOtherTypeEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); DismissIntoDreamEffect(FilterPermanent filter) {
static { super(filter, SubType.ILLUSION, Duration.WhileOnBattlefield);
filter.add(TargetController.OPPONENT.getControllerPredicate()); this.outcome = Outcome.Detriment;
}
DismissIntoDreamEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Each creature your opponents control is an Illusion in addition to its other types and has \"When this creature becomes the target of a spell or ability, sacrifice it.\"";
} }
DismissIntoDreamEffect(final DismissIntoDreamEffect effect) { DismissIntoDreamEffect(final DismissIntoDreamEffect effect) {
@ -67,23 +69,24 @@ class DismissIntoDreamEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Permanent object: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { super.apply(layer, sublayer, source, game);
switch (layer) {
case AbilityAddingRemovingEffects_6: if (layer == Layer.AbilityAddingRemovingEffects_6) {
object.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), source.getSourceId(), game); for (Permanent object: game.getBattlefield().getActivePermanents(this.filter, source.getControllerId(), game)) {
break; object.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), source.getSourceId(), game);
case TypeChangingEffects_4:
if (!object.hasSubtype(SubType.ILLUSION, game)) {
object.getSubtype(game).add(SubType.ILLUSION);
}
break;
} }
} }
return true; return true;
} }
@Override @Override
public boolean hasLayer(Layer layer) { public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; return super.hasLayer(layer) || layer == Layer.AbilityAddingRemovingEffects_6;
}
@Override
public String getText(Mode mode) {
return super.getText(mode) + " and has \"When this creature becomes the target of a spell or ability, sacrifice it.\"";
} }
} }

View file

@ -31,6 +31,7 @@ public final class Jumpstart extends ExpansionSet {
cards.add(new SetCardInfo("Agonizing Syphon", 199, Rarity.COMMON, mage.cards.a.AgonizingSyphon.class)); cards.add(new SetCardInfo("Agonizing Syphon", 199, Rarity.COMMON, mage.cards.a.AgonizingSyphon.class));
cards.add(new SetCardInfo("Ajani's Chosen", 82, Rarity.RARE, mage.cards.a.AjanisChosen.class)); cards.add(new SetCardInfo("Ajani's Chosen", 82, Rarity.RARE, mage.cards.a.AjanisChosen.class));
cards.add(new SetCardInfo("Alabaster Mage", 83, Rarity.UNCOMMON, mage.cards.a.AlabasterMage.class)); cards.add(new SetCardInfo("Alabaster Mage", 83, Rarity.UNCOMMON, mage.cards.a.AlabasterMage.class));
cards.add(new SetCardInfo("Allosaurus Shepherd", 28, Rarity.MYTHIC, mage.cards.a.AllosaurusShepherd.class));
cards.add(new SetCardInfo("Alloy Myr", 457, Rarity.COMMON, mage.cards.a.AlloyMyr.class)); cards.add(new SetCardInfo("Alloy Myr", 457, Rarity.COMMON, mage.cards.a.AlloyMyr.class));
cards.add(new SetCardInfo("Ambassador Oak", 375, Rarity.COMMON, mage.cards.a.AmbassadorOak.class)); cards.add(new SetCardInfo("Ambassador Oak", 375, Rarity.COMMON, mage.cards.a.AmbassadorOak.class));
cards.add(new SetCardInfo("Ancestral Statue", 458, Rarity.COMMON, mage.cards.a.AncestralStatue.class)); cards.add(new SetCardInfo("Ancestral Statue", 458, Rarity.COMMON, mage.cards.a.AncestralStatue.class));
@ -63,6 +64,7 @@ public final class Jumpstart extends ExpansionSet {
cards.add(new SetCardInfo("Black Cat", 203, Rarity.COMMON, mage.cards.b.BlackCat.class)); cards.add(new SetCardInfo("Black Cat", 203, Rarity.COMMON, mage.cards.b.BlackCat.class));
cards.add(new SetCardInfo("Black Market", 204, Rarity.RARE, mage.cards.b.BlackMarket.class)); cards.add(new SetCardInfo("Black Market", 204, Rarity.RARE, mage.cards.b.BlackMarket.class));
cards.add(new SetCardInfo("Blessed Spirits", 92, Rarity.UNCOMMON, mage.cards.b.BlessedSpirits.class)); cards.add(new SetCardInfo("Blessed Spirits", 92, Rarity.UNCOMMON, mage.cards.b.BlessedSpirits.class));
cards.add(new SetCardInfo("Blessed Sanctuary", 1, Rarity.RARE, mage.cards.b.BlessedSanctuary.class));
cards.add(new SetCardInfo("Blighted Bat", 205, Rarity.COMMON, mage.cards.b.BlightedBat.class)); cards.add(new SetCardInfo("Blighted Bat", 205, Rarity.COMMON, mage.cards.b.BlightedBat.class));
cards.add(new SetCardInfo("Blindblast", 295, Rarity.COMMON, mage.cards.b.Blindblast.class)); cards.add(new SetCardInfo("Blindblast", 295, Rarity.COMMON, mage.cards.b.Blindblast.class));
cards.add(new SetCardInfo("Blood Artist", 206, Rarity.UNCOMMON, mage.cards.b.BloodArtist.class)); cards.add(new SetCardInfo("Blood Artist", 206, Rarity.UNCOMMON, mage.cards.b.BloodArtist.class));

View file

@ -27,7 +27,11 @@ public class PreventAllNonCombatDamageToAllEffect extends PreventionEffectImpl {
super(duration, Integer.MAX_VALUE, false); super(duration, Integer.MAX_VALUE, false);
this.filter = filter; this.filter = filter;
this.andToYou = andToYou; this.andToYou = andToYou;
staticText = "Prevent all non combat damage that would be dealt to " + (andToYou ? "you and " : "") + filter.getMessage() + ' ' + duration.toString(); staticText = "Prevent all non combat damage that would be dealt to " + (andToYou ? "you and " : "") + filter.getMessage();
if (duration != Duration.WhileOnBattlefield) {
staticText += ' ' + duration.toString();
}
} }
private PreventAllNonCombatDamageToAllEffect(final PreventAllNonCombatDamageToAllEffect effect) { private PreventAllNonCombatDamageToAllEffect(final PreventAllNonCombatDamageToAllEffect effect) {

View file

@ -0,0 +1,67 @@
package mage.abilities.effects.common.continuous;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
public class CreaturesBecomeOtherTypeEffect extends ContinuousEffectImpl {
protected final FilterPermanent filter;
private final SubType subType;
public CreaturesBecomeOtherTypeEffect(FilterPermanent filter, SubType subType, Duration duration) {
super(duration, Outcome.Neutral);
this.filter = filter;
this.subType = subType;
this.dependendToTypes.add(DependencyType.BecomeCreature); // Opalescence and Starfield of Nyx
}
protected CreaturesBecomeOtherTypeEffect(final CreaturesBecomeOtherTypeEffect effect) {
super(effect);
this.filter = effect.filter;
this.subType = effect.subType;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public CreaturesBecomeOtherTypeEffect copy() {
return new CreaturesBecomeOtherTypeEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
if (layer == Layer.TypeChangingEffects_4) {
for (Permanent object: game.getBattlefield().getActivePermanents(this.filter, source.getControllerId(), game)) {
if (!object.hasSubtype(this.subType, game)) {
object.getSubtype(game).add(this.subType);
}
}
}
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
return this.filter.getMessage() + " is " + this.subType.getIndefiniteArticle()
+ " " + this.subType.toString() + " in addition to its other types";
}
}

View file

@ -98,6 +98,10 @@ public class SetPowerToughnessAllEffect extends ContinuousEffectImpl {
@Override @Override
public String getText(Mode mode) { public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(filter.getMessage()); sb.append(filter.getMessage());
if (filter.getMessage().toLowerCase(Locale.ENGLISH).startsWith("Each ")) { if (filter.getMessage().toLowerCase(Locale.ENGLISH).startsWith("Each ")) {

View file

@ -496,6 +496,19 @@ public enum SubType {
return predicate; return predicate;
} }
public String getIndefiniteArticle() {
if (isVowel(description.charAt(0))) {
return "an";
} else {
return "a";
}
}
private boolean isVowel(char c) {
return "AEIOUaeiou".indexOf(c) != -1;
}
public static SubType fromString(String value) { public static SubType fromString(String value) {
for (SubType st : SubType.values()) { for (SubType st : SubType.values()) {
if (st.toString().equals(value)) { if (st.toString().equals(value)) {

View file

@ -0,0 +1,27 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
public final class UnicornToken extends TokenImpl {
public UnicornToken() {
super("Unicorn", "2/2 white Unicorn creature token");
setExpansionSetCodeForImage("JMP");
cardType.add(CardType.CREATURE);
subtype.add(SubType.UNICORN);
color.setWhite(true);
power = new MageInt(2);
toughness = new MageInt(2);
}
private UnicornToken(final UnicornToken token) {
super(token);
}
@Override
public UnicornToken copy() {
return new UnicornToken(this);
}
}