mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
Implement [LEG] Takklemaggot
This commit is contained in:
parent
1c19280693
commit
833d209795
5 changed files with 284 additions and 0 deletions
231
Mage.Sets/src/mage/cards/t/Takklemaggot.java
Normal file
231
Mage.Sets/src/mage/cards/t/Takklemaggot.java
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.DiesAttachedTriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersAttachedEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.CanBeEnchantedByPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author xenohedron
|
||||
*/
|
||||
public final class Takklemaggot extends CardImpl {
|
||||
|
||||
public Takklemaggot(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
|
||||
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant creature
|
||||
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||
this.getSpellAbility().addTarget(auraTarget);
|
||||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||
this.addAbility(new EnchantAbility(auraTarget));
|
||||
|
||||
// At the beginning of the upkeep of enchanted creature's controller, put a -0/-1 counter on that creature.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
|
||||
new AddCountersAttachedEffect(CounterType.M0M1.createInstance(), "that creature"),
|
||||
TargetController.CONTROLLER_ATTACHED_TO, false, false));
|
||||
|
||||
// When enchanted creature dies, that creature's controller chooses a creature that Takklemaggot could enchant.
|
||||
// If they do, return Takklemaggot to the battlefield under your control attached to that creature.
|
||||
// If they don't, return Takklemaggot to the battlefield under your control as a non-Aura enchantment.
|
||||
// It loses "enchant creature" and gains "At the beginning of that player's upkeep, Takklemaggot deals 1 damage to that player."
|
||||
this.addAbility(new DiesAttachedTriggeredAbility(new TakklemaggotEffect(), "enchanted creature",
|
||||
false, true, SetTargetPointer.ATTACHED_TO_CONTROLLER));
|
||||
}
|
||||
|
||||
private Takklemaggot(final Takklemaggot card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Takklemaggot copy() {
|
||||
return new Takklemaggot(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TakklemaggotEffect extends OneShotEffect {
|
||||
|
||||
TakklemaggotEffect() {
|
||||
super(Outcome.PutCardInPlay);
|
||||
staticText = "that creature's controller chooses a creature that {this} could enchant. " +
|
||||
"If the player does, return {this} to the battlefield under your control attached to that creature. " +
|
||||
"If they don't, return {this} to the battlefield under your control as a non-Aura enchantment. " +
|
||||
"It loses \"enchant creature\" and gains \"At the beginning of that player's upkeep, {this} deals 1 damage to that player.\"";
|
||||
}
|
||||
|
||||
private TakklemaggotEffect(final TakklemaggotEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TakklemaggotEffect copy() {
|
||||
return new TakklemaggotEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
Card auraCard = game.getCard(source.getSourceId());
|
||||
if (controller == null || player == null || auraCard == null) {
|
||||
return false;
|
||||
}
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
||||
filter.add(new CanBeEnchantedByPredicate(auraCard));
|
||||
Target target = new TargetCreaturePermanent(filter).withNotTarget(true);
|
||||
if (!game.getBattlefield().getActivePermanents(filter, player.getId(), source, game).isEmpty()
|
||||
&& player.choose(outcome, target, source, game)) {
|
||||
// return attached to that creature
|
||||
Permanent creature = game.getPermanent(target.getFirstTarget());
|
||||
if (creature == null) {
|
||||
return false;
|
||||
}
|
||||
game.getState().setValue("attachTo:" + auraCard.getId(), creature);
|
||||
controller.moveCards(auraCard, Zone.BATTLEFIELD, source, game);
|
||||
creature.addAttachment(auraCard.getId(), source, game);
|
||||
} else {
|
||||
// return as non-Aura enchantment
|
||||
game.addEffect(new TakklemaggotNonAuraEffect(player.getId()), source);
|
||||
controller.moveCards(auraCard, Zone.BATTLEFIELD, source, game);
|
||||
auraCard.addInfo("chosen player", CardUtil.addToolTipMarkTags("Chosen player: " + player.getLogName()), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TakklemaggotNonAuraEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final UUID playerId;
|
||||
|
||||
TakklemaggotNonAuraEffect(UUID playerId) {
|
||||
super(Duration.Custom, Outcome.AddAbility);
|
||||
this.playerId = playerId;
|
||||
}
|
||||
|
||||
private TakklemaggotNonAuraEffect(final TakklemaggotNonAuraEffect effect) {
|
||||
super(effect);
|
||||
this.playerId = effect.playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TakklemaggotNonAuraEffect copy() {
|
||||
return new TakklemaggotNonAuraEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
Permanent permanent;
|
||||
if (affectedObjectList.isEmpty()) { // not yet initiated, check entering permanent
|
||||
permanent = game.getPermanentEntering(source.getSourceId());
|
||||
// if an entering permanent is found, then proceed to applying continuous effects by layer
|
||||
// otherwise try to find the permanent on the battlefield
|
||||
if (permanent == null) {
|
||||
permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent == null) {
|
||||
discard(); // no permanent found, can't initiate
|
||||
return false;
|
||||
} else {
|
||||
// initiate with ZCC and check that in all future calls
|
||||
affectedObjectList.add(new MageObjectReference(source.getSourceId(), game));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
permanent = affectedObjectList.get(0).getPermanent(game);
|
||||
if (permanent == null) {
|
||||
discard(); // permanent no longer on battlefield so effect no longer applies
|
||||
return true;
|
||||
}
|
||||
}
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
permanent.removeSubType(game, SubType.AURA);
|
||||
return true;
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
List<Ability> toRemove = new ArrayList<>();
|
||||
for (Ability ability : permanent.getAbilities(game)) {
|
||||
if (ability instanceof EnchantAbility) {
|
||||
toRemove.add(ability);
|
||||
}
|
||||
}
|
||||
permanent.removeAbilities(toRemove, source.getSourceId(), game);
|
||||
permanent.addAbility(new TakklemaggotUpkeepAbility(playerId), source.getSourceId(), game);
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayer(Layer layer) {
|
||||
return Layer.AbilityAddingRemovingEffects_6 == layer || Layer.TypeChangingEffects_4 == layer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TakklemaggotUpkeepAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private final UUID playerId;
|
||||
|
||||
TakklemaggotUpkeepAbility(UUID playerId) {
|
||||
super(Zone.BATTLEFIELD, new DamageTargetEffect(1, true, "that player")
|
||||
.setTargetPointer(new FixedTarget(playerId)), false);
|
||||
this.playerId = playerId;
|
||||
setTriggerPhrase("At the beginning of that player's upkeep, ");
|
||||
}
|
||||
|
||||
private TakklemaggotUpkeepAbility(final TakklemaggotUpkeepAbility ability) {
|
||||
super(ability);
|
||||
this.playerId = ability.playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TakklemaggotUpkeepAbility copy() {
|
||||
return new TakklemaggotUpkeepAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getPlayerId().equals(this.playerId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -118,6 +118,7 @@ public final class Chronicles extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Sol'kanar the Swamp King", 85, Rarity.RARE, mage.cards.s.SolkanarTheSwampKing.class));
|
||||
cards.add(new SetCardInfo("Stangg", 86, Rarity.RARE, mage.cards.s.Stangg.class));
|
||||
cards.add(new SetCardInfo("Storm Seeker", 70, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class));
|
||||
cards.add(new SetCardInfo("Takklemaggot", 37, Rarity.UNCOMMON, mage.cards.t.Takklemaggot.class));
|
||||
cards.add(new SetCardInfo("Teleport", 26, Rarity.RARE, mage.cards.t.Teleport.class));
|
||||
cards.add(new SetCardInfo("The Fallen", 38, Rarity.UNCOMMON, mage.cards.t.TheFallen.class));
|
||||
cards.add(new SetCardInfo("The Wretched", 39, Rarity.RARE, mage.cards.t.TheWretched.class));
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ public final class Legends extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Sylvan Library", 207, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class));
|
||||
cards.add(new SetCardInfo("Sylvan Paradise", 208, Rarity.UNCOMMON, mage.cards.s.SylvanParadise.class));
|
||||
cards.add(new SetCardInfo("Syphon Soul", 118, Rarity.COMMON, mage.cards.s.SyphonSoul.class));
|
||||
cards.add(new SetCardInfo("Takklemaggot", 119, Rarity.UNCOMMON, mage.cards.t.Takklemaggot.class));
|
||||
cards.add(new SetCardInfo("Telekinesis", 79, Rarity.RARE, mage.cards.t.Telekinesis.class));
|
||||
cards.add(new SetCardInfo("Teleport", 80, Rarity.RARE, mage.cards.t.Teleport.class));
|
||||
cards.add(new SetCardInfo("Tetsuo Umezawa", 262, Rarity.RARE, mage.cards.t.TetsuoUmezawa.class));
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ public final class MastersEditionIII extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Swamp", 223, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swamp", 224, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Sword of the Ages", 202, Rarity.RARE, mage.cards.s.SwordOfTheAges.class));
|
||||
cards.add(new SetCardInfo("Takklemaggot", 76, Rarity.UNCOMMON, mage.cards.t.Takklemaggot.class));
|
||||
cards.add(new SetCardInfo("Tetsuo Umezawa", 179, Rarity.RARE, mage.cards.t.TetsuoUmezawa.class));
|
||||
cards.add(new SetCardInfo("The Abyss", 77, Rarity.RARE, mage.cards.t.TheAbyss.class));
|
||||
cards.add(new SetCardInfo("The Lady of the Mountain", 180, Rarity.COMMON, mage.cards.t.TheLadyOfTheMountain.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package org.mage.test.cards.single.leg;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class TakklemaggotTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String takklemaggot = "Takklemaggot"; // 2BB Aura
|
||||
/* Enchant creature
|
||||
At the beginning of the upkeep of enchanted creature’s controller, put a -0/-1 counter on that creature.
|
||||
When enchanted creature dies, that creature’s controller chooses a creature that Takklemaggot could enchant.
|
||||
If the player does, return Takklemaggot to the battlefield under your control attached to that creature.
|
||||
If they don’t, return Takklemaggot to the battlefield under your control as a non-Aura enchantment.
|
||||
It loses “enchant creature” and gains “At the beginning of that player’s upkeep, Takklemaggot deals 1 damage to that player.”
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testTakklemaggot() {
|
||||
addCard(Zone.HAND, playerA, takklemaggot, 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Harvest Hand", 1); // 2/2 returns as equipment "Scrounged Scythe"
|
||||
addCard(Zone.BATTLEFIELD, playerB, "White Knight", 1); // 2/2 protection from black
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mist Leopard", 1); // 3/2 shroud
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, takklemaggot, "Harvest Hand");
|
||||
|
||||
checkPT("t1", 1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Harvest Hand", 2,2);
|
||||
checkPT("t2", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Harvest Hand", 2, 1);
|
||||
checkPT("t3", 3, PhaseStep.PRECOMBAT_MAIN, playerB, "Harvest Hand", 2, 1);
|
||||
setChoice(playerB, "Mist Leopard");
|
||||
checkPermanentCount("equipment", 4, PhaseStep.POSTCOMBAT_MAIN, playerB, "Scrounged Scythe", 1);
|
||||
checkPermanentCount("takklemaggot", 4, PhaseStep.POSTCOMBAT_MAIN, playerA, takklemaggot, 1);
|
||||
checkPT("t5", 5, PhaseStep.PRECOMBAT_MAIN, playerB, "Mist Leopard", 3, 2);
|
||||
checkPT("t6", 6, PhaseStep.PRECOMBAT_MAIN, playerB, "Mist Leopard", 3, 1);
|
||||
checkPT("t7", 7, PhaseStep.PRECOMBAT_MAIN, playerB, "Mist Leopard", 3, 1);
|
||||
checkGraveyardCount("leopard", 8, PhaseStep.POSTCOMBAT_MAIN, playerB, "Mist Leopard", 1);
|
||||
checkLife("t9", 9, PhaseStep.PRECOMBAT_MAIN, playerB, 20);
|
||||
checkLife("t10", 10, PhaseStep.PRECOMBAT_MAIN, playerB, 19);
|
||||
checkLife("t11", 11, PhaseStep.PRECOMBAT_MAIN, playerB, 19);
|
||||
|
||||
setStopAt(12, PhaseStep.POSTCOMBAT_MAIN);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 18);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue