mirror of
https://github.com/magefree/mage.git
synced 2026-01-19 01:39:58 -08:00
more refactors
This commit is contained in:
parent
f4c55dfc45
commit
e0f031801d
20 changed files with 348 additions and 555 deletions
|
|
@ -1,9 +1,5 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -11,10 +7,10 @@ import mage.abilities.common.DiesSourceTriggeredAbility;
|
|||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
|
@ -22,8 +18,11 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import mage.util.CardUtil;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801 & L_J
|
||||
*/
|
||||
public final class BlazingEffigy extends CardImpl {
|
||||
|
|
@ -89,14 +88,15 @@ class BlazingEffigyWatcher extends Watcher {
|
|||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() != GameEvent.EventType.DAMAGED_PERMANENT) { return; }
|
||||
|
||||
if (event.getSourceId().equals(event.getTargetId())) { return; }
|
||||
if (event.getType() != GameEvent.EventType.DAMAGED_PERMANENT
|
||||
|| event.getSourceId().equals(event.getTargetId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Should damageSourceRef be used for anything?
|
||||
MageObjectReference damageSourceRef = new MageObjectReference(event.getSourceId(), game);
|
||||
MageObjectReference damageTargetRef = new MageObjectReference(event.getTargetId(), game);
|
||||
if (game.getPermanentOrLKIBattlefield(event.getSourceId()) != null && game.getPermanentOrLKIBattlefield(event.getSourceId()).getName().equals("Blazing Effigy")) {
|
||||
if (game.getPermanentOrLKIBattlefield(event.getSourceId()) != null && game.getPermanentOrLKIBattlefield(event.getSourceId()).hasName("Blazing Effigy", game)) {
|
||||
damagedObjects.putIfAbsent(damageTargetRef, 0);
|
||||
damagedObjects.compute(damageTargetRef, (k, damage) -> damage + event.getAmount());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
|
|
@ -11,6 +10,9 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
|
|
@ -45,6 +47,12 @@ public final class BondersOrnament extends CardImpl {
|
|||
|
||||
class BondersOrnamentEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledPermanent();
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Bonder's Ornament"));
|
||||
}
|
||||
|
||||
BondersOrnamentEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Each player who controls a permanent named Bonder's Ornament draws a card.";
|
||||
|
|
@ -63,18 +71,10 @@ class BondersOrnamentEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
if (player != null && game.getBattlefield().contains(filter, playerId, source, game, 1)) {
|
||||
player.drawCards(1, source, game);
|
||||
}
|
||||
if (game.getBattlefield()
|
||||
.getAllActivePermanents(playerId)
|
||||
.stream()
|
||||
.map(MageObject::getName)
|
||||
.noneMatch("Bonder's Ornament"::equals)) {
|
||||
continue;
|
||||
}
|
||||
player.drawCards(1, source, game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class BoobyTrapTriggeredAbility extends TriggeredAbilityImpl {
|
|||
Card drawn = game.getCard(event.getTargetId());
|
||||
if (drawn != null) {
|
||||
controller.revealCards(this, new CardsImpl(drawn), game);
|
||||
if (drawn.getName().equals(game.getState().getValue(getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) {
|
||||
if (drawn.hasName((String) game.getState().getValue(getSourceId().toString() + ChooseACardNameEffect.INFO_KEY), game)) {
|
||||
//Set target
|
||||
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
return true;
|
||||
|
|
@ -94,4 +94,4 @@ class BoobyTrapTriggeredAbility extends TriggeredAbilityImpl {
|
|||
return "The chosen player reveals each card they draw.\n" +
|
||||
"When the chosen player draws the named card, sacrifice {this}. If you do, {this} deals 10 damage to that player.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +1,28 @@
|
|||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.IsStepCondition;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalActivatedAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.watchers.Watcher;
|
||||
import mage.watchers.common.SpellsCastWatcher;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class GrimReminder extends CardImpl {
|
||||
|
|
@ -42,7 +32,7 @@ public final class GrimReminder extends CardImpl {
|
|||
|
||||
// Search your library for a nonland card and reveal it. Each opponent who cast a card this turn with the same name as that card loses 6 life. Then shuffle your library.
|
||||
this.getSpellAbility().addEffect(new GrimReminderEffect());
|
||||
this.getSpellAbility().addWatcher(new GrimReminderWatcher());
|
||||
this.getSpellAbility().addWatcher(new SpellsCastWatcher());
|
||||
|
||||
// {B}{B}: Return Grim Reminder from your graveyard to your hand. Activate this ability only during your upkeep.
|
||||
this.addAbility(new ConditionalActivatedAbility(
|
||||
|
|
@ -85,60 +75,29 @@ class GrimReminderEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller != null && sourceObject != null) {
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_NON_LAND);
|
||||
if (controller.searchLibrary(target, source, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
Cards cardsToReveal = new CardsImpl(card);
|
||||
controller.revealCards(sourceObject.getIdName(), cardsToReveal, game);
|
||||
String cardName = card.getName();
|
||||
GrimReminderWatcher watcher = game.getState().getWatcher(GrimReminderWatcher.class);
|
||||
if (watcher != null) {
|
||||
for (UUID playerId : watcher.getPlayersCastSpell(cardName)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.loseLife(6, game, source, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_NON_LAND);
|
||||
controller.searchLibrary(target, source, game);
|
||||
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
|
||||
if (card == null) {
|
||||
controller.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class GrimReminderWatcher extends Watcher {
|
||||
|
||||
private final Map<String, Set<UUID>> playersCastSpell = new HashMap<>();
|
||||
|
||||
public GrimReminderWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
|
||||
MageObject spell = game.getObject(event.getTargetId());
|
||||
UUID playerId = event.getPlayerId();
|
||||
if (playerId != null && spell != null) {
|
||||
playersCastSpell.putIfAbsent(spell.getName(), new HashSet<>());
|
||||
playersCastSpell.get(spell.getName()).add(playerId);
|
||||
controller.revealCards(source, new CardsImpl(card), game);
|
||||
String cardName = card.getName();
|
||||
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
|
||||
for (UUID playerId : game.getOpponents(source.getControllerId())) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null && watcher
|
||||
.getSpellsCastThisTurn(playerId)
|
||||
.stream()
|
||||
.anyMatch(spell -> spell.sharesName(card, game))) {
|
||||
player.loseLife(6, game, source, false);
|
||||
}
|
||||
}
|
||||
controller.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
playersCastSpell.clear();
|
||||
}
|
||||
|
||||
public Set<UUID> getPlayersCastSpell(String spellName) {
|
||||
return playersCastSpell.getOrDefault(spellName, new HashSet<>());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,40 @@
|
|||
|
||||
package mage.cards.i;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.abilities.effects.common.ExileTargetForSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetLandPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvaderParasite extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter
|
||||
= new FilterLandPermanent("a land an opponent controls with the same name as the exiled card");
|
||||
|
||||
static {
|
||||
filter.add(TargetController.OPPONENT.getControllerPredicate());
|
||||
filter.add(InvaderParasitePredicate.instance);
|
||||
}
|
||||
|
||||
public InvaderParasite(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
|
||||
this.subtype.add(SubType.PHYREXIAN);
|
||||
|
|
@ -33,12 +44,15 @@ public final class InvaderParasite extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Imprint - When Invader Parasite enters the battlefield, exile target land.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new InvaderParasiteImprintEffect(), false);
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect());
|
||||
ability.addTarget(new TargetLandPermanent());
|
||||
this.addAbility(ability);
|
||||
this.addAbility(ability.setAbilityWord(AbilityWord.IMPRINT));
|
||||
|
||||
// Whenever a land with the same name as the exiled card enters the battlefield under an opponent's control, Invader Parasite deals 2 damage to that player.
|
||||
this.addAbility(new InvaderParasiteTriggeredAbility().setAbilityWord(AbilityWord.IMPRINT));
|
||||
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
|
||||
Zone.BATTLEFIELD, new DamageTargetEffect(2, true, "that player"),
|
||||
filter, false, SetTargetPointer.PLAYER
|
||||
));
|
||||
}
|
||||
|
||||
private InvaderParasite(final InvaderParasite card) {
|
||||
|
|
@ -51,76 +65,19 @@ public final class InvaderParasite extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class InvaderParasiteImprintEffect extends OneShotEffect {
|
||||
|
||||
InvaderParasiteImprintEffect() {
|
||||
super(Outcome.Exile);
|
||||
staticText = "exile target land";
|
||||
}
|
||||
|
||||
private InvaderParasiteImprintEffect(final InvaderParasiteImprintEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
enum InvaderParasitePredicate implements ObjectSourcePlayerPredicate<Permanent> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (sourcePermanent != null && targetPermanent != null) {
|
||||
targetPermanent.moveToExile(getId(), "Invader Parasite (Imprint)", source, game);
|
||||
sourcePermanent.imprint(targetPermanent.getId(), game);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvaderParasiteImprintEffect copy() {
|
||||
return new InvaderParasiteImprintEffect(this);
|
||||
}
|
||||
}
|
||||
|
||||
class InvaderParasiteTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
InvaderParasiteTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new DamageTargetEffect(2));
|
||||
}
|
||||
|
||||
private InvaderParasiteTriggeredAbility(final InvaderParasiteTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InvaderParasiteTriggeredAbility copy() {
|
||||
return new InvaderParasiteTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (game.getOpponents(this.controllerId).contains(event.getPlayerId())) {
|
||||
Permanent targetPermanent = game.getPermanent(event.getTargetId());
|
||||
Permanent sourcePermanent = game.getPermanent(getSourceId());
|
||||
if (targetPermanent != null && sourcePermanent != null) {
|
||||
if (!sourcePermanent.getImprinted().isEmpty()) {
|
||||
Card imprintedCard = game.getCard(sourcePermanent.getImprinted().get(0));
|
||||
if (imprintedCard != null && targetPermanent.getName().equals(imprintedCard.getName())) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a land with the same name as the exiled card enters the battlefield under an opponent's control, {this} deals 2 damage to that player.";
|
||||
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
|
||||
return Optional
|
||||
.ofNullable(game)
|
||||
.map(Game::getExile)
|
||||
.map(e -> e.getExileZone(CardUtil.getExileZoneId(game, input.getSource())))
|
||||
.filter(e -> !e.isEmpty())
|
||||
.map(e -> e.getCards(game))
|
||||
.map(Collection::stream)
|
||||
.map(s -> s.anyMatch(card -> card.sharesName(input.getObject(), game)))
|
||||
.orElse(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,41 @@
|
|||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.condition.CompoundCondition;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class MineWorker extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
|
||||
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent();
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Power Plant Worker"));
|
||||
filter2.add(new NamePredicate("Tower Worker"));
|
||||
}
|
||||
|
||||
private static final Condition condition = new CompoundCondition(
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
new PermanentsOnTheBattlefieldCondition(filter2)
|
||||
);
|
||||
|
||||
public MineWorker(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
|
||||
|
||||
|
|
@ -30,7 +44,10 @@ public final class MineWorker extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
// {T}: You gain 1 life. If you control creatures named Power Plant Worker and Tower Worker, you gain 3 life instead.
|
||||
this.addAbility(new SimpleActivatedAbility(new MineWorkerEffect(), new TapSourceCost()));
|
||||
this.addAbility(new SimpleActivatedAbility(new ConditionalOneShotEffect(
|
||||
new GainLifeEffect(3), new GainLifeEffect(1), condition, "you gain 1 life. " +
|
||||
"If you control creatures named Power Plant Worker and Tower Worker, you gain 3 life instead"
|
||||
), new TapSourceCost()));
|
||||
}
|
||||
|
||||
private MineWorker(final MineWorker card) {
|
||||
|
|
@ -42,47 +59,3 @@ public final class MineWorker extends CardImpl {
|
|||
return new MineWorker(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MineWorkerEffect extends OneShotEffect {
|
||||
|
||||
MineWorkerEffect() {
|
||||
super(Outcome.GainLife);
|
||||
this.staticText = "You gain 1 life. If you control creatures named Power Plant Worker and Tower Worker, you gain 3 life instead.";
|
||||
}
|
||||
|
||||
private MineWorkerEffect(final MineWorkerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MineWorkerEffect copy() {
|
||||
return new MineWorkerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
String powerPlantName = "Power Plant Worker";
|
||||
String towerName = "Tower Worker";
|
||||
boolean powerPlant = false;
|
||||
boolean tower = false;
|
||||
int life = 1;
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, controller.getId(), game)) {
|
||||
String name = permanent.getName();
|
||||
if (!powerPlant && powerPlantName.equals(name)) {
|
||||
powerPlant = true;
|
||||
} else if (!tower && towerName.equals(name)) {
|
||||
tower = true;
|
||||
}
|
||||
if (powerPlant && tower) {
|
||||
life = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
controller.gainLife(life, game, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class NebuchadnezzarEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
opponent.revealCards(sourceObject.getIdName(), cards, game);
|
||||
cards.removeIf(uuid -> !cardName.equals(game.getCard(uuid).getName()));
|
||||
cards.removeIf(uuid -> !game.getCard(uuid).hasName(cardName, game));
|
||||
opponent.discard(cards, false, source, game);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,8 +134,8 @@ class NullChamberReplacementEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
MageObject object = game.getObject(event.getSourceId());
|
||||
if (object != null) {
|
||||
return object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NullChamberChooseEffect.INFO_KEY_CONTROLLER))
|
||||
|| object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NullChamberChooseEffect.INFO_KEY_OPPONENT));
|
||||
return object.hasName((String) game.getState().getValue(source.getSourceId().toString() + NullChamberChooseEffect.INFO_KEY_CONTROLLER), game)
|
||||
|| object.hasName((String) game.getState().getValue(source.getSourceId().toString() + NullChamberChooseEffect.INFO_KEY_OPPONENT), game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,46 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
|
||||
import mage.abilities.condition.CompoundCondition;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.AddContinuousEffectToGame;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.constants.*;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
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.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class PowerPlantWorker extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
|
||||
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent();
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Mine Worker"));
|
||||
filter2.add(new NamePredicate("Tower Worker"));
|
||||
}
|
||||
|
||||
private static final Condition condition = new CompoundCondition(
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
new PermanentsOnTheBattlefieldCondition(filter2)
|
||||
);
|
||||
|
||||
public PowerPlantWorker(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}");
|
||||
|
||||
|
|
@ -29,7 +49,15 @@ public final class PowerPlantWorker extends CardImpl {
|
|||
this.toughness = new MageInt(4);
|
||||
|
||||
// {3}: Power Plant Worker gets +2/+2 until end of turn. If you control creatures named Mine Worker and Tower Worker, put two +1/+1 counters on Power Plant Worker instead. Activate only once each turn.
|
||||
this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new PowerPlantWorkerEffect(), new GenericManaCost(3)));
|
||||
this.addAbility(new LimitedTimesPerTurnActivatedAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
new ConditionalOneShotEffect(
|
||||
new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)),
|
||||
new AddContinuousEffectToGame(new BoostSourceEffect(2, 2, Duration.EndOfTurn)),
|
||||
condition, "{this} gets +2/+2 until end of turn. If you control creatures " +
|
||||
"named Mine Worker and Tower Worker, put two +1/+1 counters on {this} instead"
|
||||
), new GenericManaCost(3)
|
||||
));
|
||||
}
|
||||
|
||||
private PowerPlantWorker(final PowerPlantWorker card) {
|
||||
|
|
@ -41,45 +69,3 @@ public final class PowerPlantWorker extends CardImpl {
|
|||
return new PowerPlantWorker(this);
|
||||
}
|
||||
}
|
||||
|
||||
class PowerPlantWorkerEffect extends OneShotEffect {
|
||||
|
||||
PowerPlantWorkerEffect() {
|
||||
super(Outcome.BoostCreature);
|
||||
this.staticText = "{this} gets +2/+2 until end of turn. If you control creatures named Mine Worker and Tower Worker, put two +1/+1 counters on {this} instead.";
|
||||
}
|
||||
|
||||
private PowerPlantWorkerEffect(final PowerPlantWorkerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PowerPlantWorkerEffect copy() {
|
||||
return new PowerPlantWorkerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
|
||||
if (sourcePermanent == null) {
|
||||
return false;
|
||||
}
|
||||
String mineName = "Mine Worker";
|
||||
String towerName = "Tower Worker";
|
||||
boolean mine = false;
|
||||
boolean tower = false;
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
|
||||
String name = permanent.getName();
|
||||
if (!mine && mineName.equals(name)) {
|
||||
mine = true;
|
||||
} else if (!tower && towerName.equals(name)) {
|
||||
tower = true;
|
||||
}
|
||||
if (mine && tower) {
|
||||
return sourcePermanent.addCounters(CounterType.P1P1.createInstance(2), source, game);
|
||||
}
|
||||
}
|
||||
game.addEffect(new BoostSourceEffect(2, 2, Duration.EndOfTurn), source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class PsychicBattleTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
|
||||
if (stackObject != null) {
|
||||
if (!stackObject.isTargetChanged() && !stackObject.getName().equals("Psychic Battle")) {
|
||||
if (!stackObject.isTargetChanged() && !stackObject.hasName("Psychic Battle", game)) {
|
||||
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||
stackObject.setTargetChanged(false); // resets the targetChanged flag
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,23 +1,21 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class RetracedImage extends CardImpl {
|
||||
|
|
@ -27,7 +25,6 @@ public final class RetracedImage extends CardImpl {
|
|||
|
||||
// Reveal a card in your hand, then put that card onto the battlefield if it has the same name as a permanent.
|
||||
this.getSpellAbility().addEffect(new RetracedImageEffect());
|
||||
|
||||
}
|
||||
|
||||
private RetracedImage(final RetracedImage card) {
|
||||
|
|
@ -59,23 +56,21 @@ class RetracedImageEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
TargetCardInHand target = new TargetCardInHand();
|
||||
if (target.canChoose(controller.getId(), source, game)
|
||||
&& controller.choose(outcome, target, source, game)) {
|
||||
Card chosenCard = game.getCard(target.getFirstTarget());
|
||||
if (chosenCard != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.add(chosenCard);
|
||||
controller.revealCards(source, cards, game);
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
|
||||
if (permanent.getName().equals(chosenCard.getName())) {
|
||||
return controller.moveCards(chosenCard, Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (controller == null || controller.getHand().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
TargetCardInHand target = new TargetCardInHand();
|
||||
controller.choose(outcome, target, source, game);
|
||||
Card chosenCard = game.getCard(target.getFirstTarget());
|
||||
return chosenCard != null
|
||||
&& game
|
||||
.getBattlefield()
|
||||
.getActivePermanents(
|
||||
StaticFilters.FILTER_PERMANENT,
|
||||
source.getControllerId(), source, game
|
||||
)
|
||||
.stream()
|
||||
.anyMatch(permanent -> permanent.sharesName(chosenCard, game))
|
||||
&& controller.moveCards(chosenCard, Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class Scalpelexis extends CardImpl {
|
||||
|
|
@ -69,26 +66,17 @@ class ScalpelexisEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (targetPlayer == null) {
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Set<String> cardNames = new HashSet<>();
|
||||
boolean doubleName;
|
||||
do {
|
||||
doubleName = false;
|
||||
Cards toExile = new CardsImpl(targetPlayer.getLibrary().getTopCards(game, 4));
|
||||
cardNames.clear();
|
||||
for (Card card : toExile.getCards(game)) {
|
||||
if (cardNames.contains(card.getName())) {
|
||||
doubleName = true;
|
||||
break;
|
||||
} else {
|
||||
cardNames.add(card.getName());
|
||||
}
|
||||
while (player.getLibrary().hasCards()) {
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
|
||||
player.moveCards(cards, Zone.EXILED, source, game);
|
||||
if (!CardUtil.checkAnyPairs(cards.getCards(game), (c1, c2) -> c1.sharesName(c2, game))) {
|
||||
break;
|
||||
}
|
||||
targetPlayer.moveCards(toExile, Zone.EXILED, source, game);
|
||||
} while (doubleName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,50 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.condition.CompoundCondition;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.target.common.TargetPlayerOrPlaneswalker;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
public final class ScepterOfEmpires extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledArtifactPermanent();
|
||||
private static final FilterPermanent filter2 = new FilterControlledArtifactPermanent();
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Crown of Empires"));
|
||||
filter2.add(new NamePredicate("Throne of Empires"));
|
||||
}
|
||||
|
||||
private static final Condition condition = new CompoundCondition(
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
new PermanentsOnTheBattlefieldCondition(filter2)
|
||||
);
|
||||
|
||||
public ScepterOfEmpires(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// {tap}: Scepter of Empires deals 1 damage to target player. It deals 3 damage to that player instead if you control artifacts named Crown of Empires and Throne of Empires.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScepterOfEmpiresEffect(), new TapSourceCost());
|
||||
Ability ability = new SimpleActivatedAbility(new ConditionalOneShotEffect(
|
||||
new DamageTargetEffect(3), new DamageTargetEffect(1), condition, "{this} deals " +
|
||||
"1 damage to target player. It deals 3 damage to that player instead if " +
|
||||
"you control artifacts named Crown of Empires and Throne of Empires"
|
||||
), new TapSourceCost());
|
||||
ability.addTarget(new TargetPlayerOrPlaneswalker());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
@ -38,38 +58,3 @@ public final class ScepterOfEmpires extends CardImpl {
|
|||
return new ScepterOfEmpires(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ScepterOfEmpiresEffect extends OneShotEffect {
|
||||
|
||||
ScepterOfEmpiresEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "Scepter of Empires deals 1 damage to target player or planeswalker. It deals 3 damage instead if you control artifacts named Crown of Empires and Throne of Empires";
|
||||
}
|
||||
|
||||
private ScepterOfEmpiresEffect(final ScepterOfEmpiresEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
boolean throne = false;
|
||||
boolean crown = false;
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) {
|
||||
if (permanent.getName().equals("Throne of Empires")) {
|
||||
throne = true;
|
||||
} else if (permanent.getName().equals("Crown of Empires")) {
|
||||
crown = true;
|
||||
}
|
||||
if (throne && crown) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int amount = throne && crown ? 3 : 1;
|
||||
return game.damagePlayerOrPermanent(source.getFirstTarget(), amount, source.getSourceId(), source, game, false, true) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScepterOfEmpiresEffect copy() {
|
||||
return new ScepterOfEmpiresEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.discard.DiscardControllerEffect;
|
||||
import mage.abilities.effects.common.DrawDiscardControllerEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -21,15 +18,15 @@ import mage.game.stack.Spell;
|
|||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class SiftThroughSands extends CardImpl {
|
||||
|
||||
private static final String rule = "<br>If you've cast a spell named Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library for a card named The Unspeakable, put it onto the battlefield, then shuffle";
|
||||
private static final FilterCreatureCard filter = new FilterCreatureCard("a card named The Unspeakable");
|
||||
|
||||
static {
|
||||
|
|
@ -37,17 +34,19 @@ public final class SiftThroughSands extends CardImpl {
|
|||
}
|
||||
|
||||
public SiftThroughSands(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{U}");
|
||||
this.subtype.add(SubType.ARCANE);
|
||||
|
||||
// Draw two cards, then discard a card.
|
||||
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
|
||||
Effect effect = new DiscardControllerEffect(1);
|
||||
effect.setText(", then discard a card");
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(2, 1));
|
||||
|
||||
// If you've cast a spell named Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library for a card named The Unspeakable, put it onto the battlefield, then shuffle your library.
|
||||
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false), new SiftThroughSandsCondition(), rule));
|
||||
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
|
||||
new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false),
|
||||
SiftThroughSandsCondition.instance, "<br>If you've cast a spell named " +
|
||||
"Peer Through Depths and a spell named Reach Through Mists this turn, you may search your library " +
|
||||
"for a card named The Unspeakable, put it onto the battlefield, then shuffle"
|
||||
));
|
||||
this.getSpellAbility().addWatcher(new SiftThroughSandsWatcher());
|
||||
}
|
||||
|
||||
|
|
@ -61,48 +60,51 @@ public final class SiftThroughSands extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class SiftThroughSandsCondition implements Condition {
|
||||
enum SiftThroughSandsCondition implements Condition {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
SiftThroughSandsWatcher watcher = game.getState().getWatcher(SiftThroughSandsWatcher.class, source.getControllerId());
|
||||
if (watcher != null) {
|
||||
return watcher.conditionMet();
|
||||
}
|
||||
return false;
|
||||
return SiftThroughSandsWatcher.checkPlayer(source.getControllerId(), game);
|
||||
}
|
||||
}
|
||||
|
||||
class SiftThroughSandsWatcher extends Watcher {
|
||||
|
||||
boolean castPeerThroughDepths = false;
|
||||
boolean castReachThroughMists = false;
|
||||
Set<UUID> castPeerThroughDepths = new HashSet<>();
|
||||
Set<UUID> castReachThroughMists = new HashSet<>();
|
||||
|
||||
public SiftThroughSandsWatcher() {
|
||||
super(WatcherScope.PLAYER);
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (condition) { //no need to check - condition has already occured
|
||||
if (event.getType() != GameEvent.EventType.SPELL_CAST) {
|
||||
return;
|
||||
}
|
||||
if (event.getType() == GameEvent.EventType.SPELL_CAST
|
||||
&& controllerId.equals(event.getPlayerId())) {
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell.getCard().getName().equals("Peer Through Depths")) {
|
||||
castPeerThroughDepths = true;
|
||||
} else if (spell.getCard().getName().equals("Reach Through Mists")) {
|
||||
castReachThroughMists = true;
|
||||
}
|
||||
condition = castPeerThroughDepths && castReachThroughMists;
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell.hasName("Peer Through Depths", game)) {
|
||||
castPeerThroughDepths.add(spell.getControllerId());
|
||||
}
|
||||
if (spell.hasName("Reach Through Mists", game)) {
|
||||
castReachThroughMists.add(spell.getControllerId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
this.castPeerThroughDepths = false;
|
||||
this.castReachThroughMists = false;
|
||||
this.castPeerThroughDepths.clear();
|
||||
this.castReachThroughMists.clear();
|
||||
}
|
||||
|
||||
static boolean checkPlayer(UUID playerId, Game game) {
|
||||
return game.getState().getWatcher(SiftThroughSandsWatcher.class).check(playerId);
|
||||
}
|
||||
|
||||
private boolean check(UUID playerId) {
|
||||
return castPeerThroughDepths.contains(playerId)
|
||||
&& castReachThroughMists.contains(playerId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class SkophosMazeWardenTriggeredAbility extends TriggeredAbilityImpl {
|
|||
if (permanent == null
|
||||
|| !permanent.isControlledBy(getControllerId())
|
||||
|| !permanent.isLand(game)
|
||||
|| !permanent.getName().equals("Labyrinth of Skophos")) {
|
||||
|| !permanent.hasName("Labyrinth of Skophos", game)) {
|
||||
return false;
|
||||
}
|
||||
Permanent creature = game.getPermanent(event.getTargetId());
|
||||
|
|
|
|||
|
|
@ -1,31 +1,25 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ChooseACardNameEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceHintType;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class SphinxAmbassador extends CardImpl {
|
||||
|
|
@ -38,8 +32,11 @@ public final class SphinxAmbassador extends CardImpl {
|
|||
this.toughness = new MageInt(5);
|
||||
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Whenever Sphinx Ambassador deals combat damage to a player, search that player's library for a card, then that player names a card. If you searched for a creature card that isn't the named card, you may put it onto the battlefield under your control. Then that player shuffles their library.
|
||||
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SphinxAmbassadorEffect(), false, true));
|
||||
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
|
||||
new SphinxAmbassadorEffect(), false, true
|
||||
));
|
||||
}
|
||||
|
||||
private SphinxAmbassador(final SphinxAmbassador card) {
|
||||
|
|
@ -56,7 +53,9 @@ class SphinxAmbassadorEffect extends OneShotEffect {
|
|||
|
||||
SphinxAmbassadorEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.staticText = "search that player's library for a card, then that player chooses a card name. If you searched for a creature card that doesn't have that name, you may put it onto the battlefield under your control. Then that player shuffles";
|
||||
this.staticText = "search that player's library for a card, then that player chooses a card name. " +
|
||||
"If you searched for a creature card that doesn't have that name, " +
|
||||
"you may put it onto the battlefield under your control. Then that player shuffles";
|
||||
}
|
||||
|
||||
private SphinxAmbassadorEffect(final SphinxAmbassadorEffect effect) {
|
||||
|
|
@ -72,40 +71,20 @@ class SphinxAmbassadorEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (controller != null && targetPlayer != null && sourcePermanent != null) {
|
||||
TargetCardInLibrary target = new TargetCardInLibrary();
|
||||
controller.searchLibrary(target, source, game, targetPlayer.getId());
|
||||
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
TreeSet<String> choices = new TreeSet<>();
|
||||
Collection<Card> cards = game.getCards();
|
||||
for (Card gameCard : cards) {
|
||||
if (gameCard.isOwnedBy(targetPlayer.getId())) {
|
||||
choices.add(gameCard.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Choice cardChoice = new ChoiceImpl(false, ChoiceHintType.CARD);
|
||||
cardChoice.setChoices(choices);
|
||||
cardChoice.clearChoice();
|
||||
if (!targetPlayer.choose(Outcome.Benefit, cardChoice, game)) {
|
||||
return false;
|
||||
}
|
||||
String cardName = cardChoice.getChoice();
|
||||
|
||||
game.informPlayers(sourcePermanent.getName() + ", named card: [" + cardName + ']');
|
||||
if (!card.getName().equals(cardName) && card.isCreature(game)) {
|
||||
if (controller.chooseUse(outcome, "Put " + card.getName() + " onto the battlefield?", source, game)) {
|
||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targetPlayer.shuffleLibrary(source, game);
|
||||
return true;
|
||||
if (controller == null || targetPlayer == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
TargetCardInLibrary target = new TargetCardInLibrary();
|
||||
controller.searchLibrary(target, source, game, targetPlayer.getId());
|
||||
Card card = targetPlayer.getLibrary().getCard(target.getFirstTarget(), game);
|
||||
String name = ChooseACardNameEffect.TypeOfName.ALL.getChoice(targetPlayer, game, source, false);
|
||||
if (card != null
|
||||
&& card.isCreature(game)
|
||||
&& !card.hasName(name, game)
|
||||
&& controller.chooseUse(outcome, "Put " + card.getName() + " onto the battlefield?", source, game)) {
|
||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
targetPlayer.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
|
|
@ -18,14 +13,15 @@ import mage.players.Player;
|
|||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author emerald000
|
||||
*/
|
||||
public final class StompingSlabs extends CardImpl {
|
||||
|
||||
public StompingSlabs(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
|
||||
|
||||
// Reveal the top seven cards of your library, then put those cards on the bottom of your library in any order. If a card named Stomping Slabs was revealed this way, Stomping Slabs deals 7 damage to any target.
|
||||
this.getSpellAbility().addEffect(new StompingSlabsEffect());
|
||||
|
|
@ -43,21 +39,21 @@ public final class StompingSlabs extends CardImpl {
|
|||
}
|
||||
|
||||
class StompingSlabsEffect extends OneShotEffect {
|
||||
|
||||
|
||||
StompingSlabsEffect() {
|
||||
super(Outcome.Damage);
|
||||
this.staticText = "Reveal the top seven cards of your library, then put those cards on the bottom of your library in any order. If a card named Stomping Slabs was revealed this way, {this} deals 7 damage to any target";
|
||||
}
|
||||
|
||||
|
||||
private StompingSlabsEffect(final StompingSlabsEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public StompingSlabsEffect copy() {
|
||||
return new StompingSlabsEffect(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
|
@ -68,7 +64,7 @@ class StompingSlabsEffect extends OneShotEffect {
|
|||
boolean stompingSlabsFound = false;
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null && card.getName().equals("Stomping Slabs")) {
|
||||
if (card != null && card.hasName("Stomping Slabs", game)) {
|
||||
stompingSlabsFound = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,17 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author cbt33, Ad Nauseum (North), Izzet Staticaster (LevelX2), Bane Alley
|
||||
* Broker (LevelX2)
|
||||
*/
|
||||
|
|
@ -56,30 +52,28 @@ class TaintedPactEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null
|
||||
|| sourceCard == null) {
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
Set<String> names = new HashSet<>();
|
||||
while (controller.canRespond()
|
||||
&& controller.getLibrary().hasCards()) {
|
||||
Cards cards = new CardsImpl();
|
||||
while (controller.canRespond() && controller.getLibrary().hasCards()) {
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
// the card move is sequential, not all at once.
|
||||
controller.moveCards(card, Zone.EXILED, source, game);
|
||||
game.processAction(); // Laelia, the Blade Reforged
|
||||
// Checks if there was already exiled a card with the same name
|
||||
if (names.contains(card.getName())) {
|
||||
break;
|
||||
}
|
||||
names.add(card.getName());
|
||||
if (controller.chooseUse(outcome, "Put " + card.getName() + " into your hand?", source, game)) {
|
||||
//Adds the current card to hand if it is chosen.
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
break;
|
||||
}
|
||||
if (card == null) {
|
||||
continue;
|
||||
}
|
||||
// the card move is sequential, not all at once.
|
||||
controller.moveCards(card, Zone.EXILED, source, game);
|
||||
game.processAction(); // Laelia, the Blade Reforged
|
||||
// Checks if there was already exiled a card with the same name
|
||||
if (cards.getCards(game).stream().anyMatch(c -> c.sharesName(card, game))) {
|
||||
break;
|
||||
}
|
||||
cards.add(card);
|
||||
if (controller.chooseUse(outcome, "Put " + card.getName() + " into your hand?", source, game)) {
|
||||
//Adds the current card to hand if it is chosen.
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,32 +1,51 @@
|
|||
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.condition.CompoundCondition;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.game.permanent.token.SoldierToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
public final class ThroneOfEmpires extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterControlledArtifactPermanent();
|
||||
private static final FilterPermanent filter2 = new FilterControlledArtifactPermanent();
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Crown of Empires"));
|
||||
filter2.add(new NamePredicate("Scepter of Empires"));
|
||||
}
|
||||
|
||||
private static final Condition condition = new CompoundCondition(
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
new PermanentsOnTheBattlefieldCondition(filter2)
|
||||
);
|
||||
|
||||
public ThroneOfEmpires(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||
|
||||
// {1}, {tap}: Create a 1/1 white Soldier creature token. Create five of those tokens instead if you control artifacts named Crown of Empires and Scepter of Empires.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ThroneOfEmpiresEffect(), new GenericManaCost(1));
|
||||
Ability ability = new SimpleActivatedAbility(new ConditionalOneShotEffect(
|
||||
new CreateTokenEffect(new SoldierToken(), 5), new CreateTokenEffect(new SoldierToken()),
|
||||
condition, "create a 1/1 white Soldier creature token. Create five of those tokens " +
|
||||
"instead if you control artifacts named Crown of Empires and Scepter of Empires"
|
||||
), new GenericManaCost(1));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
@ -40,38 +59,3 @@ public final class ThroneOfEmpires extends CardImpl {
|
|||
return new ThroneOfEmpires(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ThroneOfEmpiresEffect extends OneShotEffect {
|
||||
|
||||
ThroneOfEmpiresEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "Create a 1/1 white Soldier creature token. Create five of those tokens instead if you control artifacts named Crown of Empires and Scepter of Empires";
|
||||
}
|
||||
|
||||
private ThroneOfEmpiresEffect(final ThroneOfEmpiresEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
boolean scepter = false;
|
||||
boolean crown = false;
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) {
|
||||
if (permanent.getName().equals("Scepter of Empires")) {
|
||||
scepter = true;
|
||||
} else if (permanent.getName().equals("Crown of Empires")) {
|
||||
crown = true;
|
||||
}
|
||||
if (scepter && crown) break;
|
||||
}
|
||||
Token soldier = new SoldierToken();
|
||||
int count = scepter && crown ? 5 : 1;
|
||||
soldier.putOntoBattlefield(count, game, source, source.getControllerId());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThroneOfEmpiresEffect copy() {
|
||||
return new ThroneOfEmpiresEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.mana.DynamicManaAbility;
|
||||
import mage.constants.SubType;
|
||||
import mage.abilities.keyword.ReachAbility;
|
||||
import mage.abilities.mana.DynamicManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class TowerWorker extends CardImpl {
|
||||
|
|
@ -51,25 +52,19 @@ public final class TowerWorker extends CardImpl {
|
|||
|
||||
enum TowerWorkerValue implements DynamicValue {
|
||||
instance;
|
||||
private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
|
||||
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent();
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Mine Worker"));
|
||||
filter2.add(new NamePredicate("Power Plant Worker"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
String mineName = "Mine Worker";
|
||||
String powerPlantName = "Power Plant Worker";
|
||||
boolean mine = false;
|
||||
boolean powerPlant = false;
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, sourceAbility.getControllerId(), game)) {
|
||||
String name = permanent.getName();
|
||||
if (!mine && mineName.equals(name)) {
|
||||
mine = true;
|
||||
} else if (!powerPlant && powerPlantName.equals(name)) {
|
||||
powerPlant = true;
|
||||
}
|
||||
if (mine && powerPlant) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return game.getBattlefield().contains(filter, sourceAbility, game, 1)
|
||||
&& game.getBattlefield().contains(filter2, sourceAbility, game, 1)
|
||||
? 3 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue