mirror of
https://github.com/magefree/mage.git
synced 2026-01-19 01:39:58 -08:00
more refactoring
This commit is contained in:
parent
3307eb31a5
commit
d69bc200d4
26 changed files with 335 additions and 506 deletions
|
|
@ -1,9 +1,6 @@
|
|||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||
import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility;
|
||||
|
|
@ -20,15 +17,18 @@ import mage.constants.SetTargetPointer;
|
|||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.SharesNamePredicate;
|
||||
import mage.filter.predicate.permanent.TokenPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class DualNature extends CardImpl {
|
||||
|
|
@ -129,7 +129,7 @@ class DualNatureCreatureLeavesEffect extends OneShotEffect {
|
|||
if (creature != null) {
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
filter.add(TokenPredicate.TRUE);
|
||||
filter.add(new NamePredicate(creature.getName()));
|
||||
filter.add(new SharesNamePredicate(creature));
|
||||
new ExileAllEffect(filter).apply(game, source);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateIfConditionActivatedAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
|
|
@ -16,9 +13,11 @@ import mage.constants.Zone;
|
|||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.RandomUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class EndlessAtlas extends CardImpl {
|
||||
|
|
@ -31,7 +30,7 @@ public final class EndlessAtlas extends CardImpl {
|
|||
Zone.BATTLEFIELD,
|
||||
new DrawCardSourceControllerEffect(1),
|
||||
new GenericManaCost(2),
|
||||
new EndlessAtlasCondition()
|
||||
EndlessAtlasCondition.instance
|
||||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
|
|
@ -47,21 +46,27 @@ public final class EndlessAtlas extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class EndlessAtlasCondition implements Condition {
|
||||
enum EndlessAtlasCondition implements Condition {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Map<String, Integer> landMap = new HashMap<>();
|
||||
for (Permanent land : game.getBattlefield().getActivePermanents(
|
||||
Set<Permanent> lands = new HashSet<>(game.getBattlefield().getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
|
||||
source.getControllerId(), game
|
||||
)) {
|
||||
if (land != null) {
|
||||
int landCount = landMap.getOrDefault(land.getName(), 0);
|
||||
if (landCount > 1) {
|
||||
source.getControllerId(), source, game
|
||||
));
|
||||
while (lands.size() >= 3) {
|
||||
Permanent land = RandomUtil.randomFromCollection(lands);
|
||||
lands.remove(land);
|
||||
int amount = 0;
|
||||
for (Permanent permanent : lands) {
|
||||
if (!permanent.sharesName(land, game)) {
|
||||
continue;
|
||||
}
|
||||
amount++;
|
||||
if (amount >= 3) {
|
||||
return true;
|
||||
}
|
||||
landMap.put(land.getName(), landCount + 1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -65,16 +65,16 @@ class EscapedShapeshifterEffect extends ContinuousEffectImpl {
|
|||
if (sourcePermanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
game.getBattlefield()
|
||||
.getActivePermanents(
|
||||
StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE,
|
||||
source.getControllerId(), source, game
|
||||
).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(permanent -> !permanent.getName().equals("Escaped Shapeshifter"))
|
||||
.filter(permanent -> !permanent.hasName("Escaped Shapeshifter", game))
|
||||
.map(Permanent::getAbilities)
|
||||
.flatMap(Collection::stream).filter(EscapedShapeshifterEffect::checkAbility)
|
||||
.flatMap(Collection::stream)
|
||||
.filter(EscapedShapeshifterEffect::checkAbility)
|
||||
.forEach(ability -> sourcePermanent.addAbility(ability, source.getSourceId(), game));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -97,4 +97,4 @@ class EscapedShapeshifterEffect extends ContinuousEffectImpl {
|
|||
public EscapedShapeshifterEffect copy() {
|
||||
return new EscapedShapeshifterEffect(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
|
|
@ -11,11 +9,7 @@ import mage.abilities.mana.TriggeredManaAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
|
@ -27,8 +21,9 @@ import mage.target.common.TargetLandPermanent;
|
|||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class ExtraplanarLens extends CardImpl {
|
||||
|
|
@ -123,8 +118,8 @@ class ExtraplanarLensTriggeredAbility extends TriggeredManaAbility {
|
|||
Card imprinted = game.getCard(extraplanarLens.getImprinted().get(0));
|
||||
if (imprinted != null
|
||||
&& game.getState().getZone(imprinted.getId()) == Zone.EXILED) {
|
||||
if (landTappedForMana.getName().equals(imprinted.getName())
|
||||
&& landTappedForMana.isLand(game)) {
|
||||
if (landTappedForMana.isLand(game)
|
||||
&& landTappedForMana.sharesName(imprinted, game)) {
|
||||
ManaEvent mEvent = (ManaEvent) event;
|
||||
for (Effect effect : getEffects()) {
|
||||
effect.setValue("mana", mEvent.getMana());
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
package mage.cards.e;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -10,25 +9,31 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public final class EyeOfSingularity extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("a permanent other than a basic land");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(Predicates.or(
|
||||
SuperType.BASIC.getPredicate(),
|
||||
CardType.LAND.getPredicate()
|
||||
)));
|
||||
}
|
||||
|
||||
public EyeOfSingularity(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
|
||||
|
||||
|
|
@ -38,7 +43,7 @@ public final class EyeOfSingularity extends CardImpl {
|
|||
this.addAbility(new EntersBattlefieldTriggeredAbility(new EyeOfSingularityETBEffect()));
|
||||
|
||||
// Whenever a permanent other than a basic land enters the battlefield, destroy all other permanents with that name. They can't be regenerated.
|
||||
this.addAbility(new EyeOfSingularityTriggeredAbility());
|
||||
this.addAbility(new EntersBattlefieldAllTriggeredAbility(new EyeOfSingularityTriggeredEffect(), filter));
|
||||
}
|
||||
|
||||
private EyeOfSingularity(final EyeOfSingularity card) {
|
||||
|
|
@ -56,12 +61,16 @@ class EyeOfSingularityETBEffect extends OneShotEffect {
|
|||
private static final FilterPermanent filter = new FilterPermanent();
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
|
||||
filter.add(Predicates.not(Predicates.or(
|
||||
SuperType.BASIC.getPredicate(),
|
||||
CardType.LAND.getPredicate()
|
||||
)));
|
||||
}
|
||||
|
||||
EyeOfSingularityETBEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "destroy each permanent with the same name as another permanent, except for basic lands. They can't be regenerated";
|
||||
this.staticText = "destroy each permanent with the same name as another permanent, " +
|
||||
"except for basic lands. They can't be regenerated";
|
||||
}
|
||||
|
||||
private EyeOfSingularityETBEffect(final EyeOfSingularityETBEffect effect) {
|
||||
|
|
@ -75,80 +84,23 @@ class EyeOfSingularityETBEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Map<String, UUID> cardNames = new HashMap<>();
|
||||
Map<UUID, Integer> toDestroy = new HashMap<>();
|
||||
Set<Permanent> permanents = CardUtil.streamAllPairwiseMatches(
|
||||
game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game),
|
||||
(p1, p2) -> p1.sharesName(p2, game)
|
||||
).collect(Collectors.toSet());
|
||||
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
|
||||
String cardName = permanent.getName();
|
||||
if (cardNames.get(cardName) == null) {
|
||||
cardNames.put(cardName, permanent.getId());
|
||||
} else {
|
||||
toDestroy.put(cardNames.get(cardName), 1);
|
||||
toDestroy.put(permanent.getId(), 1);
|
||||
}
|
||||
}
|
||||
for (UUID id : toDestroy.keySet()) {
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
permanent.destroy(source, game, false);
|
||||
}
|
||||
for (Permanent permanent : permanents) {
|
||||
permanent.destroy(source, game, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class EyeOfSingularityTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
EyeOfSingularityTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new EyeOfSingularityTriggeredEffect(), false);
|
||||
}
|
||||
|
||||
private EyeOfSingularityTriggeredAbility(final EyeOfSingularityTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EyeOfSingularityTriggeredAbility copy() {
|
||||
return new EyeOfSingularityTriggeredAbility(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) {
|
||||
UUID targetId = event.getTargetId();
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
|
||||
if (event.getTargetId().equals(this.getSourceId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (permanent != null && !permanent.isBasic(game)) {
|
||||
getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a permanent other than a basic land enters the battlefield, destroy all other permanents with that name. They can't be regenerated.";
|
||||
}
|
||||
}
|
||||
|
||||
class EyeOfSingularityTriggeredEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent();
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(SuperType.BASIC.getPredicate()));
|
||||
}
|
||||
|
||||
EyeOfSingularityTriggeredEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
staticText = "destroy all other permanents with that name. They can’t be regenerated";
|
||||
}
|
||||
|
||||
private EyeOfSingularityTriggeredEffect(final EyeOfSingularityTriggeredEffect effect) {
|
||||
|
|
@ -157,28 +109,20 @@ class EyeOfSingularityTriggeredEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Map<UUID, Integer> toDestroy = new HashMap<>();
|
||||
Permanent etbPermanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
|
||||
if (etbPermanent == null) {
|
||||
Permanent permanent = (Permanent) getValue("permanentEnteringBattlefield");
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
String cn = etbPermanent.getName();
|
||||
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
|
||||
String cardName = permanent.getName();
|
||||
if (cardName.equals(cn) && !Objects.equals(permanent.getId(), etbPermanent.getId())) {
|
||||
toDestroy.put(permanent.getId(), 1);
|
||||
}
|
||||
Set<Permanent> permanents = game
|
||||
.getBattlefield()
|
||||
.getActivePermanents(StaticFilters.FILTER_PERMANENT, source.getControllerId(), source, game)
|
||||
.stream()
|
||||
.filter(p -> !p.equals(permanent))
|
||||
.filter(p -> p.sharesName(permanent, game))
|
||||
.collect(Collectors.toSet());
|
||||
for (Permanent p : permanents) {
|
||||
p.destroy(source, game, true);
|
||||
}
|
||||
|
||||
for (UUID id : toDestroy.keySet()) {
|
||||
Permanent permanent = game.getPermanent(id);
|
||||
if (permanent != null) {
|
||||
permanent.destroy(source, game, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
|
|
@ -92,7 +91,6 @@ enum FrostpyreArcanistPredicate implements ObjectSourcePlayerPredicate<Card> {
|
|||
.getGraveyard()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.map(MageObject::getName)
|
||||
.anyMatch(input.getObject().getName()::equals);
|
||||
.anyMatch(card -> card.sharesName(input.getObject(), game));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class GoblinArtisansTarget extends TargetSpell {
|
|||
if (permanent != null
|
||||
&& !sourceRef.refersTo(permanent, game)
|
||||
&& permanent.isCreature(game)
|
||||
&& "Goblin Artisans".equals(permanent.getName())
|
||||
&& permanent.hasName("Goblin Artisans", game)
|
||||
&& stackObject
|
||||
.getStackAbility()
|
||||
.getTargets()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import java.util.*;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
|
|
@ -28,8 +27,9 @@ import mage.target.targetpointer.FirstTargetPointer;
|
|||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class Godsend extends CardImpl {
|
||||
|
|
@ -201,7 +201,7 @@ class GodsendRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
if ((exileZone != null)) {
|
||||
for (Card card : exileZone.getCards(game)) {
|
||||
if ((card.getName().equals(object.getName()))) {
|
||||
if ((card.sharesName(object, game))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.ControllerGainedLifeCount;
|
||||
|
|
@ -40,15 +39,11 @@ public final class GollumObsessedStalker extends CardImpl {
|
|||
this.addAbility(new SkulkAbility());
|
||||
|
||||
// At the beginning of your end step, each opponent dealt combat damage this game by a creature named Gollum, Obsessed Stalker loses life equal to the amount of life you gained this turn.
|
||||
Ability ability = new BeginningOfYourEndStepTriggeredAbility(
|
||||
new GollumObsessedStalkerEffect(),
|
||||
false
|
||||
);
|
||||
Ability ability = new BeginningOfYourEndStepTriggeredAbility(new GollumObsessedStalkerEffect(), false);
|
||||
ability.addWatcher(new PlayerGainedLifeWatcher());
|
||||
ability.addWatcher(new GollumObsessedStalkerWatcher());
|
||||
ability.addHint(ControllerGainedLifeCount.getHint());
|
||||
ability.addHint(GollumObsessedStalkerHint.instance);
|
||||
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -64,8 +59,8 @@ public final class GollumObsessedStalker extends CardImpl {
|
|||
|
||||
class GollumObsessedStalkerWatcher extends Watcher {
|
||||
|
||||
// For each creature name, the players damaged by them during combat.
|
||||
private final Map<String, Set<UUID>> playersPerName = new HashMap<>();
|
||||
// Players damaged by creatures named Gollum, Obsessed Stalker during combat.
|
||||
private final Set<UUID> players = new HashSet<>();
|
||||
|
||||
public GollumObsessedStalkerWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
|
|
@ -78,22 +73,14 @@ class GollumObsessedStalkerWatcher extends Watcher {
|
|||
return;
|
||||
}
|
||||
Permanent creature = game.getPermanent(event.getSourceId());
|
||||
if (creature == null) {
|
||||
return;
|
||||
if (creature != null && creature.isCreature(game)
|
||||
&& creature.hasName("Gollum, Obsessed Stalker", game)) {
|
||||
players.add(event.getPlayerId());
|
||||
}
|
||||
|
||||
String name = creature.getName();
|
||||
UUID playerId = event.getPlayerId();
|
||||
if (creature.getName().isEmpty() || playerId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
playersPerName.computeIfAbsent(name, k -> new HashSet<>());
|
||||
playersPerName.get(name).add(playerId);
|
||||
}
|
||||
|
||||
public Set<UUID> getPlayersDamagedByNamed(String name) {
|
||||
return playersPerName.getOrDefault(name, new HashSet<>());
|
||||
public Set<UUID> getPlayersDamagedByNamed() {
|
||||
return players;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,8 +88,8 @@ class GollumObsessedStalkerEffect extends OneShotEffect {
|
|||
|
||||
GollumObsessedStalkerEffect() {
|
||||
super(Outcome.LoseLife);
|
||||
staticText = "each opponent dealt combat damage this game by a creature named "
|
||||
+ "{this} loses life equal to the amount of life you gained this turn.";
|
||||
staticText = "each opponent dealt combat damage this game by a creature named " +
|
||||
"Gollum, Obsessed Stalker loses life equal to the amount of life you gained this turn.";
|
||||
}
|
||||
|
||||
private GollumObsessedStalkerEffect(final GollumObsessedStalkerEffect effect) {
|
||||
|
|
@ -118,14 +105,12 @@ class GollumObsessedStalkerEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
GollumObsessedStalkerWatcher damageWatcher = game.getState().getWatcher(GollumObsessedStalkerWatcher.class);
|
||||
PlayerGainedLifeWatcher lifeWatcher = game.getState().getWatcher(PlayerGainedLifeWatcher.class);
|
||||
Permanent gollum = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (damageWatcher == null || lifeWatcher == null || gollum == null) {
|
||||
if (damageWatcher == null || lifeWatcher == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = gollum.getName();
|
||||
int amount = lifeWatcher.getLifeGained(source.getControllerId());
|
||||
Set<UUID> playersDamaged = damageWatcher.getPlayersDamagedByNamed(name);
|
||||
Set<UUID> playersDamaged = damageWatcher.getPlayersDamagedByNamed();
|
||||
|
||||
if (amount == 0 || playersDamaged.isEmpty()) {
|
||||
return true;
|
||||
|
|
@ -135,12 +120,10 @@ class GollumObsessedStalkerEffect extends OneShotEffect {
|
|||
if (!playersDamaged.contains(playerId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
player.loseLife(amount, game, source, false);
|
||||
}
|
||||
|
||||
|
|
@ -153,39 +136,19 @@ enum GollumObsessedStalkerHint implements Hint {
|
|||
|
||||
@Override
|
||||
public String getText(Game game, Ability ability) {
|
||||
GollumObsessedStalkerWatcher watcher = game.getState().getWatcher(GollumObsessedStalkerWatcher.class);
|
||||
if (watcher == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String name = null;
|
||||
Permanent gollum = game.getPermanentOrLKIBattlefield(ability.getSourceId());
|
||||
if (gollum != null) {
|
||||
// Gollum is or was in play, its name is using LKI.
|
||||
name = gollum.getName();
|
||||
} else {
|
||||
// if Gollum LKI not in play (like in hand or in command zone),
|
||||
// find the object.
|
||||
MageObject gollumObj = game.getObject(ability.getSourceId());
|
||||
if (gollumObj != null) {
|
||||
name = gollumObj.getName();
|
||||
}
|
||||
}
|
||||
if (name == null || name.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Not filtering by opponent intentionally, just to provide full info everywhere.
|
||||
List<String> namesOfPlayersDealtDamage =
|
||||
watcher.getPlayersDamagedByNamed(name)
|
||||
.stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Player::getName)
|
||||
.filter(n -> !n.isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
List<String> namesOfPlayersDealtDamage = game
|
||||
.getState()
|
||||
.getWatcher(GollumObsessedStalkerWatcher.class)
|
||||
.getPlayersDamagedByNamed()
|
||||
.stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Player::getName)
|
||||
.filter(n -> !n.isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return "Players dealt combat damage by creatures named " + name + " this game: ["
|
||||
return "Players dealt combat damage by creatures named Gollum, Obsessed Stalker this game: ["
|
||||
+ String.join(", ", namesOfPlayersDealtDamage)
|
||||
+ "]";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.MageObject;
|
||||
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;
|
||||
|
|
@ -14,9 +13,7 @@ import mage.players.Player;
|
|||
import mage.target.TargetPlayer;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -62,26 +59,14 @@ class HintOfInsanityEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getFirstTarget());
|
||||
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Map<String, Integer> nameCounts = new HashMap<>();
|
||||
player.getHand()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.map(MageObject::getName)
|
||||
.forEach(s -> nameCounts.compute(s, CardUtil::setOrIncrementValue));
|
||||
Cards cards = new CardsImpl(
|
||||
player.getHand()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(card -> !card.isLand(game))
|
||||
.filter(card -> nameCounts.getOrDefault(card.getName(), 0) > 1)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
player.discard(cards, false, source, game);
|
||||
return true;
|
||||
Set<Card> cards = CardUtil.streamAllPairwiseMatches(
|
||||
player.getHand().getCards(game),
|
||||
(p1, p2) -> p1.sharesName(p2, game)
|
||||
).collect(Collectors.toSet());
|
||||
return !cards.isEmpty() && !player.discard(new CardsImpl(cards), false, source, game).isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.h;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -21,7 +19,6 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class HourOfGlory extends CardImpl {
|
||||
|
|
@ -63,28 +60,27 @@ class HourOfGloryEffect 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) {
|
||||
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (targetCreature != null) {
|
||||
controller.moveCards(targetCreature, Zone.EXILED, source, game);
|
||||
if (targetCreature.hasSubtype(SubType.GOD, game)) {
|
||||
game.processAction();
|
||||
Player targetController = game.getPlayer(targetCreature.getControllerId());
|
||||
if (targetController != null) {
|
||||
targetController.revealCards(sourceObject.getIdName(), targetController.getHand(), game);
|
||||
Set<Card> toExile = new HashSet<>();
|
||||
for (Card card : targetController.getHand().getCards(game)) {
|
||||
if (card.getName().equals(targetCreature.getName())) {
|
||||
toExile.add(card);
|
||||
}
|
||||
}
|
||||
targetController.moveCards(toExile, Zone.EXILED, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (controller == null || targetCreature == null) {
|
||||
return false;
|
||||
}
|
||||
controller.moveCards(targetCreature, Zone.EXILED, source, game);
|
||||
if (!targetCreature.hasSubtype(SubType.GOD, game)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
game.processAction();
|
||||
Player targetController = game.getPlayer(targetCreature.getControllerId());
|
||||
if (targetController == null) {
|
||||
return true;
|
||||
}
|
||||
targetController.revealCards(source, targetController.getHand(), game);
|
||||
Set<Card> toExile = new HashSet<>();
|
||||
for (Card card : targetController.getHand().getCards(game)) {
|
||||
if (card.sharesName(targetCreature, game)) {
|
||||
toExile.add(card);
|
||||
}
|
||||
}
|
||||
targetController.moveCards(toExile, Zone.EXILED, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.j;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
|
|
@ -131,12 +130,11 @@ class JourneyForTheElixirLibraryTarget extends TargetCardInLibrary {
|
|||
.anyMatch(c -> c.isLand(game))) {
|
||||
return false;
|
||||
}
|
||||
if (name.equals(card.getName())
|
||||
if (card.hasName(name, game)
|
||||
&& cards
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.map(MageObject::getName)
|
||||
.anyMatch(name::equals)) {
|
||||
.anyMatch(c -> c.hasName(name, game))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -198,13 +196,12 @@ class JourneyForTheElixirGraveyardTarget extends TargetCardInYourGraveyard {
|
|||
.getCards(game)
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(MageObject::getName)
|
||||
.anyMatch(name::equals);
|
||||
.anyMatch(card -> card.hasName(name, game));
|
||||
possibleTargets.removeIf(uuid -> {
|
||||
Card card = game.getCard(uuid);
|
||||
return card != null
|
||||
&& hasYanggu
|
||||
&& name.equals(card.getName());
|
||||
&& card.hasName(name, game);
|
||||
});
|
||||
return possibleTargets;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import mage.cards.*;
|
|||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.SharesNamePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.stack.Spell;
|
||||
|
|
@ -100,7 +100,7 @@ class KotoseTheSilentSpiderEffect extends OneShotEffect {
|
|||
controller.moveCardsToExile(card, source, game, true, exileId, exileName);
|
||||
Cards cards = new CardsImpl();
|
||||
FilterCard filter = new FilterCard("cards named " + card.getName() + " from " + opponent.getName() + "'s graveyard");
|
||||
filter.add(new NamePredicate(card.getName()));
|
||||
filter.add(new SharesNamePredicate(card));
|
||||
|
||||
TargetCardInGraveyard targetCardInGraveyard = new TargetCardInGraveyard(0, Integer.MAX_VALUE, filter);
|
||||
controller.choose(outcome, opponent.getGraveyard(), targetCardInGraveyard, source, game);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class LegionsEndEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -79,32 +79,28 @@ class LegionsEndEffect extends OneShotEffect {
|
|||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
String name = permanent.getName();
|
||||
if (name == null || name.equals("")) {
|
||||
player.revealCards(source, player.getHand(), game);
|
||||
return player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
}
|
||||
Cards cards = new CardsImpl();
|
||||
game.getBattlefield()
|
||||
.getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, player.getId(), game)
|
||||
.getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game)
|
||||
.stream()
|
||||
.filter(perm -> name.equals(perm.getName()))
|
||||
.filter(perm -> perm.sharesName(permanent, game))
|
||||
.forEach(cards::add);
|
||||
player.moveCards(cards, Zone.EXILED, source, game);
|
||||
cards.clear();
|
||||
|
||||
player.revealCards(source, player.getHand(), game);
|
||||
|
||||
player.getHand()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.filter(card -> name.equals(card.getName()))
|
||||
.filter(card -> card.sharesName(permanent, game))
|
||||
.forEach(cards::add);
|
||||
|
||||
player.getGraveyard()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.filter(card -> name.equals(card.getName()))
|
||||
.filter(card -> card.sharesName(permanent, game))
|
||||
.forEach(cards::add);
|
||||
|
||||
return player.moveCards(cards, Zone.EXILED, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,23 @@
|
|||
|
||||
package mage.cards.l;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.CostModificationType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class LocketOfYesterdays extends CardImpl {
|
||||
|
|
@ -24,7 +26,7 @@ public final class LocketOfYesterdays extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
|
||||
|
||||
// Spells you cast cost {1} less to cast for each card with the same name as that spell in your graveyard.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LocketOfYesterdaysCostReductionEffect()));
|
||||
this.addAbility(new SimpleStaticAbility(new LocketOfYesterdaysCostReductionEffect()));
|
||||
}
|
||||
|
||||
private LocketOfYesterdays(final LocketOfYesterdays card) {
|
||||
|
|
@ -50,36 +52,32 @@ class LocketOfYesterdaysCostReductionEffect extends CostModificationEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source, Ability abilityToModify) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(abilityToModify.getSourceId());
|
||||
if (sourceObject != null) {
|
||||
int amount = 0;
|
||||
for (UUID cardId : game.getPlayer(source.getControllerId()).getGraveyard()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null && card.getName().equals(sourceObject.getName())) {
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
if (amount > 0) {
|
||||
SpellAbility spellAbility = (SpellAbility) abilityToModify;
|
||||
CardUtil.adjustCost(spellAbility, amount);
|
||||
}
|
||||
return true;
|
||||
if (player == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
int amount = player
|
||||
.getGraveyard()
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.filter(card -> card.sharesName(sourceObject, game))
|
||||
.mapToInt(x -> 1)
|
||||
.sum();
|
||||
if (amount > 0) {
|
||||
CardUtil.adjustCost((SpellAbility) abilityToModify, amount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify.isControlledBy(source.getControllerId())
|
||||
&& (abilityToModify instanceof SpellAbility)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return abilityToModify.isControlledBy(source.getControllerId())
|
||||
&& abilityToModify instanceof SpellAbility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocketOfYesterdaysCostReductionEffect copy() {
|
||||
return new LocketOfYesterdaysCostReductionEffect(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mage.cards.l;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
|
||||
|
|
@ -20,11 +19,11 @@ import mage.constants.TargetController;
|
|||
import mage.filter.FilterSpell;
|
||||
import mage.filter.common.FilterInstantOrSorcerySpell;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
|
|
@ -84,14 +83,10 @@ enum LutriTheSpellchaserCompanionCondition implements CompanionCondition {
|
|||
|
||||
@Override
|
||||
public boolean isLegal(Set<Card> deck, int minimumDeckSize) {
|
||||
Map<String, Integer> cardMap = new HashMap<>();
|
||||
deck.stream()
|
||||
Set<Card> cards = deck
|
||||
.stream()
|
||||
.filter(card -> !card.hasCardTypeForDeckbuilding(CardType.LAND))
|
||||
.map(MageObject::getName)
|
||||
.forEach(s -> {
|
||||
cardMap.putIfAbsent(s, 0);
|
||||
cardMap.compute(s, (str, i) -> i + 1);
|
||||
});
|
||||
return cardMap.values().stream().noneMatch(i -> i > 1);
|
||||
.collect(Collectors.toSet());
|
||||
return cards.size() == CardUtil.differentlyNamedAmongCollection(cards, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@ package mage.cards.m;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -11,19 +15,16 @@ import mage.constants.CardType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.common.FilterArtifactPermanent;
|
||||
import mage.filter.common.FilterControlledArtifactPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.util.functions.CopyTokenFunction;
|
||||
import mage.util.RandomUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -37,14 +38,20 @@ public final class MechanizedProduction extends CardImpl {
|
|||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant artifact you control
|
||||
TargetPermanent auraTarget = new TargetControlledPermanent(new FilterControlledArtifactPermanent());
|
||||
TargetPermanent auraTarget = new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT);
|
||||
this.getSpellAbility().addTarget(auraTarget);
|
||||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Copy));
|
||||
Ability ability = new EnchantAbility(auraTarget);
|
||||
this.addAbility(ability);
|
||||
this.addAbility(new EnchantAbility(auraTarget));
|
||||
|
||||
// At the beginning of your upkeep, create a token that's a copy of enchanted artifact. Then if you control eight or more artifacts with the same name as one another, you win the game.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new MechanizedProductionEffect(), TargetController.YOU, false));
|
||||
Ability ability = new BeginningOfUpkeepTriggeredAbility(
|
||||
new MechanizedProductionEffect(), TargetController.YOU, false
|
||||
);
|
||||
ability.addEffect(new ConditionalOneShotEffect(
|
||||
new WinGameSourceControllerEffect(), MechanizedProductionCondition.instance,
|
||||
"Then if you control eight or more artifacts with the same name as one another, you win the game"
|
||||
));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private MechanizedProduction(final MechanizedProduction card) {
|
||||
|
|
@ -61,7 +68,7 @@ class MechanizedProductionEffect extends OneShotEffect {
|
|||
|
||||
MechanizedProductionEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "create a token that's a copy of enchanted artifact. Then if you control eight or more artifacts with the same name as one another, you win the game";
|
||||
this.staticText = "create a token that's a copy of enchanted artifact";
|
||||
}
|
||||
|
||||
private MechanizedProductionEffect(final MechanizedProductionEffect effect) {
|
||||
|
|
@ -75,30 +82,40 @@ class MechanizedProductionEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (sourceObject != null && sourceObject.getAttachedTo() != null) {
|
||||
Permanent enchantedArtifact = game.getPermanentOrLKIBattlefield(sourceObject.getAttachedTo());
|
||||
if (enchantedArtifact != null) {
|
||||
Token token = CopyTokenFunction.createTokenCopy(enchantedArtifact, game);
|
||||
token.putOntoBattlefield(1, game, source, source.getControllerId());
|
||||
}
|
||||
Map<String, Integer> countNames = new HashMap<>();
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), source.getControllerId(), game)) {
|
||||
int counter = countNames.getOrDefault(permanent.getName(), 0);
|
||||
countNames.put(permanent.getName(), counter + 1);
|
||||
}
|
||||
for (Entry<String, Integer> entry : countNames.entrySet()) {
|
||||
if (entry.getValue() > 7) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
game.informPlayers(controller.getLogName() + " controls eight or more artifacts with the same name as one another (" + entry.getKey() + ").");
|
||||
controller.won(game);
|
||||
return true;
|
||||
}
|
||||
Permanent enchantedArtifact = Optional
|
||||
.ofNullable(source.getSourcePermanentOrLKI(game))
|
||||
.map(Permanent::getAttachedTo)
|
||||
.map(game::getPermanentOrLKIBattlefield)
|
||||
.orElse(null);
|
||||
return enchantedArtifact != null
|
||||
&& new CreateTokenCopyTargetEffect()
|
||||
.setSavedPermanent(enchantedArtifact)
|
||||
.apply(game, source);
|
||||
}
|
||||
}
|
||||
|
||||
enum MechanizedProductionCondition implements Condition {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Set<Permanent> artifacts = new HashSet<>(game.getBattlefield().getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT,
|
||||
source.getControllerId(), source, game
|
||||
));
|
||||
while (artifacts.size() >= 8) {
|
||||
Permanent artifact = RandomUtil.randomFromCollection(artifacts);
|
||||
artifacts.remove(artifact);
|
||||
int amount = 0;
|
||||
for (Permanent permanent : artifacts) {
|
||||
if (!permanent.sharesName(artifact, game)) {
|
||||
continue;
|
||||
}
|
||||
amount++;
|
||||
if (amount >= 8) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class MedomaisProphecyDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
|||
return false;
|
||||
}
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
return spell != null && spellName.equals(spell.getName());
|
||||
return spell != null && spell.hasName(spellName, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
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.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
|
|
@ -21,8 +16,9 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward
|
||||
*/
|
||||
public final class MirrorMadPhantasm extends CardImpl {
|
||||
|
|
@ -74,7 +70,7 @@ class MirrorMadPhantasmEffect extends OneShotEffect {
|
|||
Card phantasmCard = null;
|
||||
for (Card card : owner.getLibrary().getCards(game)) {
|
||||
cards.add(card);
|
||||
if (card.getName().equals("Mirror-Mad Phantasm")) {
|
||||
if (card.hasName("Mirror-Mad Phantasm", game)) {
|
||||
phantasmCard = card;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,34 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class PatternMatcher extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCreatureCard("a creature card with the same name as another creature you control");
|
||||
|
||||
static {
|
||||
filter.add(RegularExpression.instance);
|
||||
}
|
||||
|
||||
public PatternMatcher(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
|
||||
|
||||
|
|
@ -37,7 +37,9 @@ public final class PatternMatcher extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// When Pattern Matcher enters the battlefield, you may search your library for a creature card with the same name as another creature you control, reveal it, put it into your hand, then shuffle your library.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new RegularExpression(), true));
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), true
|
||||
));
|
||||
}
|
||||
|
||||
private PatternMatcher(final PatternMatcher card) {
|
||||
|
|
@ -50,45 +52,19 @@ public final class PatternMatcher extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class RegularExpression extends OneShotEffect {
|
||||
|
||||
RegularExpression() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "search your library for a card with the same name as another creature you control, " +
|
||||
"reveal it, put it into your hand, then shuffle.";
|
||||
}
|
||||
|
||||
private RegularExpression(final RegularExpression effect) {
|
||||
super(effect);
|
||||
}
|
||||
enum RegularExpression implements ObjectSourcePlayerPredicate<Card> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public RegularExpression copy() {
|
||||
return new RegularExpression(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
List<NamePredicate> predicates = game
|
||||
public boolean apply(ObjectSourcePlayer<Card> input, Game game) {
|
||||
return game
|
||||
.getState()
|
||||
.getBattlefield()
|
||||
.getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
|
||||
source.getControllerId(), source, game
|
||||
).stream()
|
||||
.map(Permanent::getName)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(s -> !s.isEmpty())
|
||||
.map(NamePredicate::new)
|
||||
.collect(Collectors.toList());
|
||||
FilterCard filter
|
||||
= new FilterCard("a creature card with the same name as another creature you control");
|
||||
filter.add(Predicates.or(predicates));
|
||||
return new SearchLibraryPutInHandEffect(
|
||||
new TargetCardInLibrary(filter), true
|
||||
).apply(game, source);
|
||||
StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES,
|
||||
input.getPlayerId(), input.getSource(), game
|
||||
)
|
||||
.stream()
|
||||
.anyMatch(permanent -> permanent.sharesName(input.getObject(), game));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,29 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
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.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.SharesNamePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author jeffwadsworth
|
||||
|
|
@ -36,7 +39,6 @@ public final class ReapIntellect extends CardImpl {
|
|||
// same name as that card and exile them. Then that player shuffles their library.
|
||||
this.getSpellAbility().addEffect(new ReapIntellectEffect());
|
||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||
|
||||
}
|
||||
|
||||
private ReapIntellect(final ReapIntellect card) {
|
||||
|
|
@ -51,12 +53,6 @@ public final class ReapIntellect extends CardImpl {
|
|||
|
||||
class ReapIntellectEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterCard filterNonLands = new FilterCard("up to X nonland cards");
|
||||
|
||||
static {
|
||||
filterNonLands.add(Predicates.not(CardType.LAND.getPredicate()));
|
||||
}
|
||||
|
||||
public ReapIntellectEffect() {
|
||||
super(Outcome.Exile);
|
||||
staticText = "Target opponent reveals their hand. You choose up to X "
|
||||
|
|
@ -72,82 +68,51 @@ class ReapIntellectEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player targetPlayer = game.getPlayer(source.getFirstTarget());
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (targetPlayer != null && sourceObject != null && controller != null) {
|
||||
|
||||
// reveal hand of target player
|
||||
targetPlayer.revealCards(sourceObject.getName(), targetPlayer.getHand(), game);
|
||||
|
||||
// Chose cards to exile from hand
|
||||
Cards exiledCards = new CardsImpl();
|
||||
int xCost = Math.min(CardUtil.getSourceCostsTag(game, source, "X", 0), targetPlayer.getHand().size());
|
||||
TargetCard target = new TargetCard(0, xCost, Zone.HAND, filterNonLands);
|
||||
target.withNotTarget(true);
|
||||
controller.chooseTarget(Outcome.Benefit, targetPlayer.getHand(), target, source, game);
|
||||
for (UUID cardId : target.getTargets()) {
|
||||
Card chosenCard = game.getCard(cardId);
|
||||
if (chosenCard != null) {
|
||||
controller.moveCardToExileWithInfo(chosenCard, null, "", source, game, Zone.HAND, true);
|
||||
exiledCards.add(chosenCard);
|
||||
}
|
||||
}
|
||||
// Exile other cards with the same name
|
||||
// 4/15/2013 If you don't exile any cards from the player's hand, you don't search that player's library
|
||||
if (!exiledCards.isEmpty()) {
|
||||
|
||||
// Building a card filter with all names
|
||||
List<NamePredicate> names = new ArrayList<>();
|
||||
FilterCard filterNamedCards = new FilterCard();
|
||||
for (Card card : exiledCards.getCards(game)) {
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(card);
|
||||
if (exiledCards.size() == 1) {
|
||||
filterNamedCards.add(new NamePredicate(nameToSearch));
|
||||
} else {
|
||||
names.add(new NamePredicate(nameToSearch));
|
||||
}
|
||||
}
|
||||
if (exiledCards.size() > 1) {
|
||||
filterNamedCards.add(Predicates.or(names));
|
||||
}
|
||||
|
||||
// search cards in graveyard
|
||||
TargetCardInGraveyard targetCardsGraveyard = new TargetCardInGraveyard(0, Integer.MAX_VALUE, filterNamedCards);
|
||||
controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsGraveyard, source, game);
|
||||
for (UUID cardId : targetCardsGraveyard.getTargets()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, "", source, game, Zone.GRAVEYARD, true);
|
||||
}
|
||||
}
|
||||
|
||||
// search cards in hand
|
||||
TargetCard targetCardsHand = new TargetCard(0, Integer.MAX_VALUE, Zone.HAND, filterNamedCards);
|
||||
controller.chooseTarget(Outcome.Benefit, targetPlayer.getGraveyard(), targetCardsHand, source, game);
|
||||
for (UUID cardId : targetCardsHand.getTargets()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, "", source, game, Zone.HAND, true);
|
||||
}
|
||||
}
|
||||
|
||||
// search cards in Library
|
||||
TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards);
|
||||
controller.searchLibrary(targetCardsLibrary, source, game, targetPlayer.getId());
|
||||
for (UUID cardId : targetCardsLibrary.getTargets()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, null, "", source, game, Zone.LIBRARY, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
|
||||
if (controller == null || targetPlayer == null) {
|
||||
return false;
|
||||
}
|
||||
targetPlayer.revealCards(source, targetPlayer.getHand(), game);
|
||||
TargetCard target = new TargetCardInHand(
|
||||
0,
|
||||
GetXValue.instance.calculate(game, source, this),
|
||||
StaticFilters.FILTER_CARDS_NON_LAND
|
||||
);
|
||||
controller.chooseTarget(Outcome.Benefit, targetPlayer.getHand(), target, source, game);
|
||||
Cards exiledCards = new CardsImpl(target.getTargets());
|
||||
controller.moveCards(exiledCards, Zone.EXILED, source, game);
|
||||
exiledCards.retainZone(Zone.EXILED, game);
|
||||
if (exiledCards.isEmpty()) {
|
||||
targetPlayer.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
FilterCard filterCard = new FilterCard("cards with the same name");
|
||||
filterCard.add(Predicates.or(
|
||||
exiledCards
|
||||
.getCards(game)
|
||||
.stream()
|
||||
.map(SharesNamePredicate::new)
|
||||
.collect(Collectors.toSet())
|
||||
));
|
||||
exiledCards.clear();
|
||||
|
||||
TargetCardInGraveyard targetCardInGraveyard = new TargetCardInGraveyard(0, Integer.MAX_VALUE, filterCard, true);
|
||||
controller.choose(Outcome.Exile, targetPlayer.getGraveyard(), targetCardInGraveyard, source, game);
|
||||
exiledCards.addAll(targetCardInGraveyard.getTargets());
|
||||
|
||||
TargetCardInHand targetCardInHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterCard);
|
||||
controller.choose(Outcome.Exile, targetPlayer.getHand(), targetCardInHand, source, game);
|
||||
exiledCards.addAll(targetCardInHand.getTargets());
|
||||
|
||||
TargetCardInLibrary targetCardInLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterCard);
|
||||
controller.searchLibrary(targetCardInLibrary, source, game, targetPlayer.getId());
|
||||
for (UUID cardId : targetCardInLibrary.getTargets()) {
|
||||
exiledCards.add(targetPlayer.getLibrary().getCard(cardId, game));
|
||||
}
|
||||
|
||||
targetPlayer.shuffleLibrary(source, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import mage.MageInt;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.TapForManaAllTriggeredManaAbility;
|
||||
import mage.abilities.costs.common.RevealHandSourceControllerCost;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.FlipSourceEffect;
|
||||
import mage.abilities.effects.mana.ManaEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.filter.common.FilterLandCard;
|
||||
import mage.filter.common.FilterLandPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.SharesNamePredicate;
|
||||
import mage.filter.predicate.permanent.PermanentIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceColor;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
|
|
@ -143,14 +143,14 @@ class SasayasEssenceManaEffect extends ManaEffect {
|
|||
if (controller != null && producedMana != null && permanent != null) {
|
||||
FilterPermanent filter = new FilterLandPermanent();
|
||||
filter.add(Predicates.not(new PermanentIdPredicate(permanent.getId())));
|
||||
filter.add(new NamePredicate(permanent.getName()));
|
||||
filter.add(new SharesNamePredicate(permanent));
|
||||
int count = game.getBattlefield().countAll(filter, controller.getId(), game);
|
||||
if (count > 0) {
|
||||
if (producedMana.getBlack() > 0) {
|
||||
netMana.add(Mana.BlackMana(count));
|
||||
if (producedMana.getBlack() > 0) {
|
||||
netMana.add(Mana.BlackMana(count));
|
||||
}
|
||||
if (producedMana.getRed() > 0) {
|
||||
netMana.add(Mana.RedMana(count));
|
||||
netMana.add(Mana.RedMana(count));
|
||||
}
|
||||
if (producedMana.getBlue() > 0) {
|
||||
netMana.add(Mana.BlueMana(count));
|
||||
|
|
@ -163,7 +163,7 @@ class SasayasEssenceManaEffect extends ManaEffect {
|
|||
}
|
||||
if (producedMana.getColorless() > 0) {
|
||||
netMana.add(Mana.ColorlessMana(count));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return netMana;
|
||||
|
|
@ -174,12 +174,12 @@ class SasayasEssenceManaEffect extends ManaEffect {
|
|||
* RULINGS 6/1/2005 If Sasaya’s Essence’s controller has four Forests and
|
||||
* taps one of them for Green, the Essence will add GreenGreenGreen to that
|
||||
* player’s mana pool for a total of GreenGreenGreenGreen.
|
||||
*
|
||||
* <p>
|
||||
* 6/1/2005 If Sasaya’s Essence’s controller has four Mossfire Valley and
|
||||
* taps one of them for RedGreen, the Essence will add three mana (one for
|
||||
* each other Mossfire Valley) of any combination of Red and/or Green to
|
||||
* that player’s mana pool.
|
||||
*
|
||||
* <p>
|
||||
* 6/1/2005 If Sasaya’s Essence’s controller has two Brushlands and taps one
|
||||
* of them for White, Sasaya’s Essence adds another White to that player’s
|
||||
* mana pool. It won’t produce Green or Colorless unless the land was tapped
|
||||
|
|
@ -197,7 +197,7 @@ class SasayasEssenceManaEffect extends ManaEffect {
|
|||
if (controller != null && mana != null && permanent != null) {
|
||||
FilterPermanent filter = new FilterLandPermanent();
|
||||
filter.add(Predicates.not(new PermanentIdPredicate(permanent.getId())));
|
||||
filter.add(new NamePredicate(permanent.getName()));
|
||||
filter.add(new SharesNamePredicate(permanent));
|
||||
int count = game.getBattlefield().countAll(filter, controller.getId(), game);
|
||||
if (count > 0) {
|
||||
Choice choice = new ChoiceColor(true);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ import mage.util.CardUtil;
|
|||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
|
|
@ -75,13 +73,10 @@ class SphinxOfTheChimesTarget extends TargetCardInHand {
|
|||
break;
|
||||
}
|
||||
Set<UUID> set = CardUtil
|
||||
.streamPairsWithMap(
|
||||
.streamAllPairwiseMatches(
|
||||
possibleTargets,
|
||||
(u1, u2) -> game.getCard(u1).sharesName(game.getCard(u2), game)
|
||||
? Stream.of(u1, u2)
|
||||
: Stream.<UUID>empty()
|
||||
)
|
||||
.flatMap(Function.identity())
|
||||
.collect(Collectors.toSet());
|
||||
possibleTargets.clear();
|
||||
possibleTargets.addAll(set);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class YidaroWanderingMonsterWatcher extends Watcher {
|
|||
return;
|
||||
}
|
||||
Card card = game.getCard(object.getSourceId());
|
||||
if (card != null && "Yidaro, Wandering Monster".equals(card.getName())) {
|
||||
if (card != null && card.hasName("Yidaro, Wandering Monster", game)) {
|
||||
countMap.merge(object.getControllerId(), 1, Integer::sum);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.filter.predicate.mageobject.SharesNamePredicate;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.filter.predicate.permanent.LegendRuleAppliesPredicate;
|
||||
import mage.game.combat.Combat;
|
||||
|
|
@ -2869,7 +2869,7 @@ public abstract class GameImpl implements Game {
|
|||
for (Permanent legend : legendary) {
|
||||
FilterPermanent filterLegendName = new FilterPermanent();
|
||||
filterLegendName.add(SuperType.LEGENDARY.getPredicate());
|
||||
filterLegendName.add(new NamePredicate(legend.getName()));
|
||||
filterLegendName.add(new SharesNamePredicate(legend));
|
||||
filterLegendName.add(new ControllerIdPredicate(legend.getControllerId()));
|
||||
filterLegendName.add(LegendRuleAppliesPredicate.instance);
|
||||
if (!getBattlefield().contains(filterLegendName, legend.getControllerId(), null, this, 2)) {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
|
@ -2169,6 +2170,19 @@ public final class CardUtil {
|
|||
return stream.filter(clazz::isInstance).map(clazz::cast).filter(Objects::nonNull);
|
||||
}
|
||||
|
||||
public static <T> boolean checkAnyPairs(Collection<T> collection, BiPredicate<T, T> predicate) {
|
||||
return streamPairsWithMap(collection, (t1, t2) -> predicate.test(t1, t2)).anyMatch(x -> x);
|
||||
}
|
||||
|
||||
public static <T> Stream<T> streamAllPairwiseMatches(Collection<T> collection, BiPredicate<T, T> predicate) {
|
||||
return streamPairsWithMap(
|
||||
collection,
|
||||
(t1, t2) -> predicate.test(t1, t2)
|
||||
? Stream.of(t1, t2)
|
||||
: Stream.<T>empty()
|
||||
).flatMap(Function.identity()).distinct();
|
||||
}
|
||||
|
||||
private static class IntPairIterator implements Iterator<AbstractMap.SimpleImmutableEntry<Integer, Integer>> {
|
||||
private final int amount;
|
||||
private int firstCounter = 0;
|
||||
|
|
@ -2201,13 +2215,7 @@ public final class CardUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static <T> boolean checkAnyPairs(Collection<T> collection, BiPredicate<T, T> predicate) {
|
||||
return streamPairsWithMap(collection, (t1, t2) -> predicate.test(t1, t2)).anyMatch(x -> x);
|
||||
}
|
||||
|
||||
public static <T, U> Stream<U> streamPairsWithMap(
|
||||
Collection<T> collection,
|
||||
BiFunction<T, T, U> function) {
|
||||
public static <T, U> Stream<U> streamPairsWithMap(Collection<T> collection, BiFunction<T, T, U> function) {
|
||||
if (collection.size() < 2) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue