Implemented Unstable cards & fixes

This commit is contained in:
L_J 2018-09-30 20:49:23 +02:00 committed by GitHub
parent 4e640dc8ab
commit 650986a83c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 497 additions and 6 deletions

View file

@ -0,0 +1,36 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
* @author L_J
*/
public final class BeastInShow extends CardImpl {
public BeastInShow(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(6);
this.toughness = new MageInt(4);
// Trample
this.addAbility(TrampleAbility.getInstance());
}
public BeastInShow(final BeastInShow card) {
super(card);
}
@Override
public BeastInShow copy() {
return new BeastInShow(this);
}
}

View file

@ -0,0 +1,33 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
* @author spjspj
*/
public final class DelightedKillbot extends CardImpl {
public DelightedKillbot(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
this.subtype.add(SubType.KILLBOT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
}
public DelightedKillbot(final DelightedKillbot card) {
super(card);
}
@Override
public DelightedKillbot copy() {
return new DelightedKillbot(this);
}
}

View file

@ -0,0 +1,33 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
* @author spjspj
*/
public final class DespondentKillbot extends CardImpl {
public DespondentKillbot(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
this.subtype.add(SubType.KILLBOT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
}
public DespondentKillbot(final DespondentKillbot card) {
super(card);
}
@Override
public DespondentKillbot copy() {
return new DespondentKillbot(this);
}
}

View file

@ -0,0 +1,33 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
* @author spjspj
*/
public final class EnragedKillbot extends CardImpl {
public EnragedKillbot(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
this.subtype.add(SubType.KILLBOT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
}
public EnragedKillbot(final EnragedKillbot card) {
super(card);
}
@Override
public EnragedKillbot copy() {
return new EnragedKillbot(this);
}
}

View file

@ -0,0 +1,154 @@
package mage.cards.h;
import java.util.ArrayList;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author spjspj & L_J
*/
public final class HammerJammer extends CardImpl {
public HammerJammer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// As Hammer Jammer enters the battlefield, roll a six-sided die. Hammer Jammer enters the battlefield with a number of +1/+1 counters on it equal to the result.
this.addAbility(new EntersBattlefieldAbility(new HammerJammerEntersEffect(CounterType.P1P1.createInstance())));
// Whenever you roll a die, remove all +1/+1 counters from Hammer Jammer, then put a number of +1/+1 counters on it equal to the result.
this.addAbility(new HammerJammerTriggeredAbility());
}
public HammerJammer(final HammerJammer card) {
super(card);
}
@Override
public HammerJammer copy() {
return new HammerJammer(this);
}
}
class HammerJammerEntersEffect extends EntersBattlefieldWithXCountersEffect {
public HammerJammerEntersEffect(Counter counter) {
super(counter);
}
public HammerJammerEntersEffect(EntersBattlefieldWithXCountersEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanentEntering(source.getSourceId());
if (controller != null && permanent != null) {
int amount = controller.rollDice(game, 6);
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event
permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game, appliedEffects);
return super.apply(game, source);
}
return false;
}
@Override
public EntersBattlefieldWithXCountersEffect copy() {
return new HammerJammerEntersEffect(this);
}
}
class HammerJammerTriggeredAbility extends TriggeredAbilityImpl {
public HammerJammerTriggeredAbility() {
super(Zone.BATTLEFIELD, new HammerJammerEffect(), false);
}
public HammerJammerTriggeredAbility(final HammerJammerTriggeredAbility ability) {
super(ability);
}
@Override
public HammerJammerTriggeredAbility copy() {
return new HammerJammerTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DICE_ROLLED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) {
for (Effect effect : this.getEffects()) {
effect.setValue("rolled", event.getAmount());
}
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever you roll a die, " + super.getRule();
}
}
class HammerJammerEffect extends OneShotEffect {
public HammerJammerEffect() {
super(Outcome.Benefit);
this.staticText = "remove all +1/+1 counters from {this}, then put a number of +1/+1 counters on it equal to the result";
}
public HammerJammerEffect(final HammerJammerEffect effect) {
super(effect);
}
@Override
public HammerJammerEffect copy() {
return new HammerJammerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
if (getValue("rolled") != null) {
int amount = (Integer) getValue("rolled");
permanent.removeCounters(CounterType.P1P1.createInstance(permanent.getCounters(game).getCount(CounterType.P1P1)), game);
permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game);
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.n;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
/**
*
* @author L_J
*/
public final class Novellamental extends CardImpl {
public Novellamental(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Novellamental can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public Novellamental(final Novellamental card) {
super(card);
}
@Override
public Novellamental copy() {
return new Novellamental(this);
}
}

View file

@ -0,0 +1,145 @@
package mage.cards.s;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SpellCastAllTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SetTargetPointer;
import mage.filter.FilterSpell;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.util.CardUtil;
/**
*
* @author L_J
*/
public final class StaffOfTheLetterMagus extends CardImpl {
public StaffOfTheLetterMagus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
// As Staff of the Letter Magus enters the battlefield, choose a consonant other than N, R, S, or T.
this.addAbility(new AsEntersBattlefieldAbility(new StaffOfTheLetterMagusChooseLetterEffect()));
// Whenever a player casts a spell, you gain 1 life for each time the chosen letter appears in that spells name.
this.addAbility(new SpellCastAllTriggeredAbility(new StaffOfTheLetterMagusEffect(), new FilterSpell("a spell"), false, SetTargetPointer.SPELL));
}
public StaffOfTheLetterMagus(final StaffOfTheLetterMagus card) {
super(card);
}
@Override
public StaffOfTheLetterMagus copy() {
return new StaffOfTheLetterMagus(this);
}
}
class StaffOfTheLetterMagusChooseLetterEffect extends OneShotEffect {
public StaffOfTheLetterMagusChooseLetterEffect() {
super(Outcome.Benefit);
staticText = "choose a consonant other than N, R, S, or T";
}
public StaffOfTheLetterMagusChooseLetterEffect(final StaffOfTheLetterMagusChooseLetterEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
if (mageObject == null) {
mageObject = game.getObject(source.getSourceId());
}
ChoiceImpl choice = new ChoiceImpl(true);
choice.setMessage("Choose letter");
Set<String> choices = new HashSet<>();
// Can I choose Y?
// Yes. We play by popular game show rules here. Y is a consonant.
// https://magic.wizards.com/en/articles/archive/news/unstable-faqawaslfaqpaftidawabiajtbt-2017-12-06
Character[] forbiddenChars = {'A','E','I','N','O','R','S','T','U'};
for (Character letter = 'A'; letter <= 'Z'; letter++) {
if (Arrays.binarySearch(forbiddenChars, letter) < 0) {
choices.add(letter.toString());
}
}
choice.setChoices(choices);
if (controller != null && mageObject != null && controller.choose(outcome, choice, game)) {
if (!game.isSimulation()) {
game.informPlayers(mageObject.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice());
}
game.getState().setValue(mageObject.getId() + "_letter", choice.getChoice());
if (mageObject instanceof Permanent) {
((Permanent) mageObject).addInfo("chosen letter", CardUtil.addToolTipMarkTags("Chosen letter: " + choice.getChoice()), game);
}
return true;
}
return false;
}
@Override
public StaffOfTheLetterMagusChooseLetterEffect copy() {
return new StaffOfTheLetterMagusChooseLetterEffect(this);
}
}
class StaffOfTheLetterMagusEffect extends OneShotEffect {
public StaffOfTheLetterMagusEffect() {
super(Outcome.GainLife);
staticText = "you gain 1 life for each time the chosen letter appears in that spells name";
}
public StaffOfTheLetterMagusEffect(final StaffOfTheLetterMagusEffect effect) {
super(effect);
}
@Override
public StaffOfTheLetterMagusEffect copy() {
return new StaffOfTheLetterMagusEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source));
if (controller != null && spell != null) {
MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject instanceof Permanent) {
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (permanent != null && game.getState().getValue(mageObject.getId() + "_letter") != null) {
int lifegainValue = 0;
String spellName = spell.getName();
for (int i = 0; i < spellName.length(); i++) {
Character letter = spellName.charAt(i);
String chosenLetter = (String) game.getState().getValue(mageObject.getId() + "_letter");
if (Character.isLetter(letter) && Character.toUpperCase(letter) == chosenLetter.charAt(0)) {
lifegainValue++;
}
}
controller.gainLife(lifegainValue, game, source);
return true;
}
}
}
return false;
}
}

View file

@ -21,22 +21,32 @@ public final class Unstable extends ExpansionSet {
private Unstable() {
super("Unstable", "UST", ExpansionSet.buildDate(2017, 12, 8), SetType.JOKESET);
cards.add(new SetCardInfo("Amateur Auteur", 3, Rarity.COMMON, mage.cards.a.AmateurAuteur.class));
cards.add(new SetCardInfo("Amateur Auteur", "3a", Rarity.COMMON, mage.cards.a.AmateurAuteur.class));
cards.add(new SetCardInfo("Amateur Auteur", "3b", Rarity.COMMON, mage.cards.a.AmateurAuteur.class));
cards.add(new SetCardInfo("Amateur Auteur", "3c", Rarity.COMMON, mage.cards.a.AmateurAuteur.class));
cards.add(new SetCardInfo("Amateur Auteur", "3d", Rarity.COMMON, mage.cards.a.AmateurAuteur.class));
cards.add(new SetCardInfo("As Luck Would Have It", 102, Rarity.RARE, mage.cards.a.AsLuckWouldHaveIt.class));
cards.add(new SetCardInfo("Baron Von Count", 127, Rarity.MYTHIC, mage.cards.b.BaronVonCount.class));
cards.add(new SetCardInfo("Beast in Show", "103a", Rarity.COMMON, mage.cards.b.BeastInShow.class));
cards.add(new SetCardInfo("Beast in Show", "103b", Rarity.COMMON, mage.cards.b.BeastInShow.class));
cards.add(new SetCardInfo("Beast in Show", "103c", Rarity.COMMON, mage.cards.b.BeastInShow.class));
cards.add(new SetCardInfo("Beast in Show", "103d", Rarity.COMMON, mage.cards.b.BeastInShow.class));
cards.add(new SetCardInfo("Box of Free-Range Goblins", 77, Rarity.COMMON, mage.cards.b.BoxOfFreerangeGoblins.class));
cards.add(new SetCardInfo("Buzzing Whack-a-Doodle", 141, Rarity.UNCOMMON, mage.cards.b.BuzzingWhackADoodle.class));
cards.add(new SetCardInfo("Chittering Doom", 104, Rarity.UNCOMMON, mage.cards.c.ChitteringDoom.class));
cards.add(new SetCardInfo("Crow Storm", 31, Rarity.UNCOMMON, mage.cards.c.CrowStorm.class));
cards.add(new SetCardInfo("Curious Killbot", 145, Rarity.COMMON, mage.cards.c.CuriousKillbot.class));
cards.add(new SetCardInfo("Curious Killbot", "145a", Rarity.COMMON, mage.cards.c.CuriousKillbot.class));
cards.add(new SetCardInfo("Delighted Killbot", "145b", Rarity.COMMON, mage.cards.d.DelightedKillbot.class));
cards.add(new SetCardInfo("Despondent Killbot", "145c", Rarity.COMMON, mage.cards.d.DespondentKillbot.class));
cards.add(new SetCardInfo("Dr. Julius Jumblemorph", 130, Rarity.MYTHIC, mage.cards.d.DrJuliusJumblemorph.class));
cards.add(new SetCardInfo("Enraged Killbot", "145d", Rarity.COMMON, mage.cards.e.EnragedKillbot.class));
cards.add(new SetCardInfo("Earl of Squirrel", 108, Rarity.RARE, mage.cards.e.EarlOfSquirrel.class));
cards.add(new SetCardInfo("Forest", 216, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false)));
cards.add(new SetCardInfo("GO TO JAIL", 8, Rarity.COMMON, mage.cards.g.GOTOJAIL.class));
cards.add(new SetCardInfo("Garbage Elemental", "82c", Rarity.UNCOMMON, mage.cards.g.GarbageElementalC.class));
cards.add(new SetCardInfo("Ground Pounder", 110, Rarity.COMMON, mage.cards.g.GroundPounder.class));
cards.add(new SetCardInfo("Hammer Helper", 85, Rarity.COMMON, mage.cards.h.HammerHelper.class));
cards.add(new SetCardInfo("Hammer Jammer", 86, Rarity.UNCOMMON, mage.cards.h.HammerJammer.class));
cards.add(new SetCardInfo("Hydradoodle", 112, Rarity.RARE, mage.cards.h.Hydradoodle.class));
cards.add(new SetCardInfo("Inhumaniac", 59, Rarity.UNCOMMON, mage.cards.i.Inhumaniac.class));
cards.add(new SetCardInfo("Island", 213, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false)));
@ -44,18 +54,26 @@ public final class Unstable extends ExpansionSet {
cards.add(new SetCardInfo("Lobe Lobber", 153, Rarity.UNCOMMON, mage.cards.l.LobeLobber.class));
cards.add(new SetCardInfo("Mad Science Fair Project", 154, Rarity.COMMON, mage.cards.m.MadScienceFairProject.class));
cards.add(new SetCardInfo("Mountain", 215, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false)));
cards.add(new SetCardInfo("Novellamental", "41a", Rarity.COMMON, mage.cards.n.Novellamental.class));
cards.add(new SetCardInfo("Novellamental", "41b", Rarity.COMMON, mage.cards.n.Novellamental.class));
cards.add(new SetCardInfo("Novellamental", "41c", Rarity.COMMON, mage.cards.n.Novellamental.class));
cards.add(new SetCardInfo("Novellamental", "41d", Rarity.COMMON, mage.cards.n.Novellamental.class));
cards.add(new SetCardInfo("Oddly Uneven", 15, Rarity.RARE, mage.cards.o.OddlyUneven.class));
cards.add(new SetCardInfo("Painiac", 91, Rarity.COMMON, mage.cards.p.Painiac.class));
cards.add(new SetCardInfo("Plains", 212, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false)));
cards.add(new SetCardInfo("Snickering Squirrel", 68, Rarity.COMMON, mage.cards.s.SnickeringSquirrel.class));
cards.add(new SetCardInfo("Squirrel-Powered Scheme", 70, Rarity.UNCOMMON, mage.cards.s.SquirrelPoweredScheme.class));
cards.add(new SetCardInfo("Staff of the Letter Magus", 159, Rarity.UNCOMMON, mage.cards.s.StaffOfTheLetterMagus.class));
cards.add(new SetCardInfo("Steamflogger Boss", 93, Rarity.RARE, mage.cards.s.SteamfloggerBoss.class));
cards.add(new SetCardInfo("Steel Squirrel", 162, Rarity.UNCOMMON, mage.cards.s.SteelSquirrel.class));
cards.add(new SetCardInfo("Summon the Pack", 74, Rarity.MYTHIC, mage.cards.s.SummonThePack.class));
cards.add(new SetCardInfo("Swamp", 214, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.UST_FULL_ART_BASIC, false)));
cards.add(new SetCardInfo("Sword of Dungeons & Dragons", 1, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class));
cards.add(new SetCardInfo("Target Minotaur", 98, Rarity.COMMON, mage.cards.t.TargetMinotaur.class));
cards.add(new SetCardInfo("The Big Idea", "76", Rarity.RARE, mage.cards.t.TheBigIdea.class));
cards.add(new SetCardInfo("Sword of Dungeons & Dragons", 163, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class));
cards.add(new SetCardInfo("Target Minotaur", "98a", Rarity.COMMON, mage.cards.t.TargetMinotaur.class));
cards.add(new SetCardInfo("Target Minotaur", "98b", Rarity.COMMON, mage.cards.t.TargetMinotaur.class));
cards.add(new SetCardInfo("Target Minotaur", "98c", Rarity.COMMON, mage.cards.t.TargetMinotaur.class));
cards.add(new SetCardInfo("Target Minotaur", "98d", Rarity.COMMON, mage.cards.t.TargetMinotaur.class));
cards.add(new SetCardInfo("The Big Idea", 76, Rarity.RARE, mage.cards.t.TheBigIdea.class));
cards.add(new SetCardInfo("Time Out", 48, Rarity.COMMON, mage.cards.t.TimeOut.class));
cards.add(new SetCardInfo("Very Cryptic Command", "49d", Rarity.RARE, mage.cards.v.VeryCrypticCommandD.class));
cards.add(new SetCardInfo("Willing Test Subject", 126, Rarity.COMMON, mage.cards.w.WillingTestSubject.class));