use of mage.filter.predicate.mageobject.NamePredicate in project mage by magefree.
the class CabalShrineEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
int count = 0;
MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) {
Spell spell = (Spell) game.getState().getValue("cabalShrine" + mageObject);
if (spell != null) {
Player controller = game.getPlayer(spell.getControllerId());
if (controller != null) {
String name = spell.getName();
FilterCard filterCardName = new FilterCard();
filterCardName.add(new NamePredicate(name));
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
count += player.getGraveyard().count(filterCardName, game);
}
}
controller.discard(count, false, false, source, game);
return true;
}
}
}
return false;
}
use of mage.filter.predicate.mageobject.NamePredicate in project mage by magefree.
the class MishraArtificerProdigyEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
FilterCard filter = new FilterCard("card named " + this.cardName);
filter.add(new NamePredicate(cardName));
Card card = null;
// Graveyard
if (controller.chooseUse(Outcome.Neutral, "Search your graveyard?", source, game)) {
// You can't fail to find the card in your graveyard because it's not hidden
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(1, 1, filter);
if (controller.choose(Outcome.PutCardInPlay, controller.getGraveyard(), target, game)) {
card = game.getCard(target.getFirstTarget());
}
}
// Hand
if (card == null && controller.chooseUse(Outcome.Neutral, "Search your hand?", source, game)) {
TargetCardInHand target = new TargetCardInHand(0, 1, filter);
if (controller.choose(Outcome.PutCardInPlay, controller.getHand(), target, game)) {
card = game.getCard(target.getFirstTarget());
}
}
// Library
if (card == null && controller.chooseUse(Outcome.Neutral, "Search your library?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter);
if (controller.searchLibrary(target, source, game)) {
card = game.getCard(target.getFirstTarget());
}
controller.shuffleLibrary(source, game);
}
// Put on battlefield
if (card != null) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
return true;
}
return false;
}
use of mage.filter.predicate.mageobject.NamePredicate in project mage by magefree.
the class RunedHaloSetProtectionEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (controller != null && cardName != null && !cardName.isEmpty()) {
FilterObject filter = new FilterObject("the card name [" + cardName + ']');
filter.add(new NamePredicate(cardName));
ContinuousEffect effect = new GainAbilityControllerEffect(new ProtectionAbility(filter), Duration.Custom);
game.addEffect(effect, source);
return true;
}
return false;
}
use of mage.filter.predicate.mageobject.NamePredicate in project mage by magefree.
the class SearchTheCityExiledCardToHandEffect method checkTrigger.
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getPlayerId().equals(this.getControllerId())) {
String cardName = "";
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null) {
cardName = spell.getName();
}
}
if (event.getType() == GameEvent.EventType.LAND_PLAYED) {
Card card = game.getCard(event.getTargetId());
if (card != null) {
cardName = card.getName();
}
}
if (!cardName.isEmpty()) {
ExileZone searchTheCityExileZone = game.getExile().getExileZone(this.getSourceId());
FilterCard filter = new FilterCard();
filter.add(new NamePredicate(cardName));
if (searchTheCityExileZone.count(filter, game) > 0) {
this.getEffects().get(0).setValue("cardName", cardName);
return true;
}
}
}
return false;
}
use of mage.filter.predicate.mageobject.NamePredicate in project mage by magefree.
the class GameImpl method checkStateBasedActions.
/**
* 116.5. Each time a player would get priority, the game first performs all
* applicable state-based actions as a single event (see rule 704,
* “State-Based Actions”), then repeats this process until no state-based
* actions are performed. Then triggered abilities are put on the stack (see
* rule 603, “Handling Triggered Abilities”). These steps repeat in order
* until no further state-based actions are performed and no abilities
* trigger. Then the player who would have received priority does so.
*
* @return
*/
protected boolean checkStateBasedActions() {
boolean somethingHappened = false;
// 20091005 - 704.5a/704.5b/704.5c
for (Player player : state.getPlayers().values()) {
if (!player.hasLost() && ((player.getLife() <= 0 && player.canLoseByZeroOrLessLife()) || player.getLibrary().isEmptyDraw() || player.getCounters().getCount(CounterType.POISON) >= 10)) {
player.lost(this);
}
}
// If a Dungeon is on its last room and is not the source of any triggered abilities, it is removed
Set<Dungeon> dungeonsToRemove = new HashSet<>();
for (CommandObject commandObject : state.getCommand()) {
if (!(commandObject instanceof Dungeon)) {
continue;
}
Dungeon dungeon = (Dungeon) commandObject;
boolean removeDungeon = !dungeon.hasNextRoom() && this.getStack().stream().filter(DungeonRoom::isRoomTrigger).map(StackObject::getSourceId).noneMatch(dungeon.getId()::equals) && this.state.getTriggered(dungeon.getControllerId()).stream().filter(DungeonRoom::isRoomTrigger).map(Ability::getSourceId).noneMatch(dungeon.getId()::equals);
if (removeDungeon) {
dungeonsToRemove.add(dungeon);
}
}
for (Dungeon dungeon : dungeonsToRemove) {
this.removeDungeon(dungeon);
somethingHappened = true;
}
// signature spells goes to command zone all the time
for (Player player : state.getPlayers().values()) {
Set<UUID> commanderIds = getCommandersIds(player, CommanderCardType.COMMANDER_OR_OATHBREAKER, false);
if (commanderIds.isEmpty()) {
continue;
}
Set<Card> commanders = new HashSet<>();
Cards toMove = new CardsImpl();
player.getGraveyard().stream().filter(commanderIds::contains).map(this::getCard).filter(Objects::nonNull).forEach(commanders::add);
commanderIds.stream().map(uuid -> getExile().getCard(uuid, this)).filter(Objects::nonNull).forEach(commanders::add);
commanders.removeIf(card -> state.checkCommanderShouldStay(card, this));
for (Card card : commanders) {
Zone currentZone = this.getState().getZone(card.getId());
String currentZoneInfo = (currentZone == null ? "(error)" : "(" + currentZone.name() + ")");
if (player.chooseUse(Outcome.Benefit, "Move " + card.getIdName() + " to the command zone or leave it in current zone " + currentZoneInfo + "?", "You can only make this choice once per object", "Move to command", "Leave in current zone " + currentZoneInfo, null, this)) {
toMove.add(card);
} else {
state.setCommanderShouldStay(card, this);
}
}
if (toMove.isEmpty()) {
continue;
}
player.moveCards(toMove, Zone.COMMAND, null, this);
somethingHappened = true;
}
// 704.5e
// If a copy of a spell is in a zone other than the stack, it ceases to exist.
// If a copy of a card is in any zone other than the stack or the battlefield, it ceases to exist.
// (Isochron Scepter) 12/1/2004: If you don't want to cast the copy, you can choose not to; the copy ceases
// to exist the next time state-based actions are checked.
//
// Copied cards can be stored in GameState.copiedCards or in game state value (until LKI rework)
// Copied cards list contains all parts of split/adventure/mdfc
Set<Card> allCopiedCards = new HashSet<>();
allCopiedCards.addAll(this.getState().getCopiedCards());
Map<String, Object> stateSavedCopiedCards = this.getState().getValues(GameState.COPIED_CARD_KEY);
allCopiedCards.addAll(stateSavedCopiedCards.values().stream().map(object -> (Card) object).filter(Objects::nonNull).collect(Collectors.toList()));
Set<Card> copiedCardsToRemove = new HashSet<>();
for (Card copiedCard : allCopiedCards) {
// 1. Zone must be checked from main card only cause mdf parts can have different zones
// (one side on battlefield, another side on outside)
// 2. Copied card creates in OUTSIDE zone and put to stack manually in the same code,
// so no SBA calls before real zone change (you will see here only unused cards like Isochron Scepter)
// (Isochron Scepter) 12/1/2004: If you don't want to cast the copy, you can choose not to; the copy ceases
// to exist the next time state-based actions are checked.
Zone zone = state.getZone(copiedCard.getMainCard().getId());
// TODO: remember LKI of copied cards here after LKI rework
switch(zone) {
case OUTSIDE:
case BATTLEFIELD:
{
// keep in outside (it's a final zone for all copied cards)
continue;
}
case STACK:
{
// copied cards aren't moves and keeps in Stack zone after resolve,
// so it must be moved manually as SBA (see Outside zone change at the end)
MageObject object = getStack().getStackObject(copiedCard.getId());
if (object != null) {
// keep in stack until resolve
continue;
}
break;
}
case GRAVEYARD:
{
for (Player player : getPlayers().values()) {
if (player.getGraveyard().contains(copiedCard.getId())) {
player.getGraveyard().remove(copiedCard);
break;
}
}
break;
}
case HAND:
{
for (Player player : getPlayers().values()) {
if (player.getHand().contains(copiedCard.getId())) {
player.getHand().remove(copiedCard);
break;
}
}
break;
}
case LIBRARY:
{
for (Player player : getPlayers().values()) {
if (player.getLibrary().getCard(copiedCard.getId(), this) != null) {
player.getLibrary().remove(copiedCard.getId(), this);
break;
}
}
break;
}
case EXILED:
{
getExile().removeCard(copiedCard, this);
break;
}
case COMMAND:
default:
{
break;
}
}
// copied card can be removed to Outside
copiedCardsToRemove.add(copiedCard);
}
// real remove
copiedCardsToRemove.forEach(card -> {
card.setZone(Zone.OUTSIDE, this);
this.getState().getCopiedCards().remove(card);
// must keep card in game state as LKI alternative until LKI rework, so don't remove from it
// TODO: change after LKI rework
// this.getState().removeValue(GameState.COPIED_CARD_KEY + copiedCard.getId().toString());
});
List<Permanent> legendary = new ArrayList<>();
List<Permanent> worldEnchantment = new ArrayList<>();
List<FilterCreaturePermanent> usePowerInsteadOfToughnessForDamageLethalityFilters = getState().getActivePowerInsteadOfToughnessForDamageLethalityFilters();
for (Permanent perm : getBattlefield().getAllActivePermanents()) {
if (perm.isCreature(this)) {
// 20091005 - 704.5f
if (perm.getToughness().getValue() <= 0) {
if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
continue;
}
} else // 20091005 - 704.5g/704.5h
{
/*
* for handling Zilortha, Strength Incarnate:
* 2020-04-17: Any time the game is checking whether damage is lethal or if a creature should be destroyed for having lethal damage marked on it, use the power of your creatures rather than their toughness to check the damage against. This includes being assigned trample damage, damage from Flame Spill, and so on.
*/
boolean usePowerInsteadOfToughnessForDamageLethality = usePowerInsteadOfToughnessForDamageLethalityFilters.stream().anyMatch(filter -> filter.match(perm, this));
int lethalDamageThreshold = usePowerInsteadOfToughnessForDamageLethality ? // Zilortha, Strength Incarnate, 2020-04-17: A creature with 0 power isn’t destroyed unless it has at least 1 damage marked on it.
Math.max(perm.getPower().getValue(), 1) : perm.getToughness().getValue();
if (lethalDamageThreshold <= perm.getDamage() || perm.isDeathtouched()) {
if (perm.destroy(null, this, false)) {
somethingHappened = true;
continue;
}
}
}
if (perm.getPairedCard() != null) {
// 702.93e.: ...another player gains control
// ...or the creature it's paired with leaves the battlefield.
Permanent paired = perm.getPairedCard().getPermanent(this);
if (paired == null || !perm.isControlledBy(paired.getControllerId()) || paired.getPairedCard() == null) {
perm.setPairedCard(null);
if (paired != null && paired.getPairedCard() != null) {
paired.setPairedCard(null);
}
somethingHappened = true;
}
}
if (perm.getBandedCards() != null && !perm.getBandedCards().isEmpty()) {
for (UUID bandedId : new ArrayList<>(perm.getBandedCards())) {
Permanent banded = getPermanent(bandedId);
if (banded == null || !perm.isControlledBy(banded.getControllerId()) || !banded.getBandedCards().contains(perm.getId())) {
perm.removeBandedCard(bandedId);
if (banded != null && banded.getBandedCards().contains(perm.getId())) {
banded.removeBandedCard(perm.getId());
}
somethingHappened = true;
}
}
}
} else if (perm.getPairedCard() != null) {
// 702.93e.: ...stops being a creature
Permanent paired = perm.getPairedCard().getPermanent(this);
perm.setPairedCard(null);
if (paired != null) {
paired.setPairedCard(null);
}
somethingHappened = true;
} else if (perm.getBandedCards() != null && !perm.getBandedCards().isEmpty()) {
perm.clearBandedCards();
for (UUID bandedId : perm.getBandedCards()) {
Permanent banded = getPermanent(bandedId);
if (banded != null) {
banded.removeBandedCard(perm.getId());
}
somethingHappened = true;
}
}
if (perm.isPlaneswalker(this)) {
// 20091005 - 704.5i
if (perm.getCounters(this).getCount(CounterType.LOYALTY) == 0) {
if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
continue;
}
}
}
if (perm.isWorld()) {
worldEnchantment.add(perm);
}
if (perm.hasSubtype(SubType.AURA, this)) {
// 20091005 - 704.5n, 702.14c
if (perm.getAttachedTo() == null) {
if (!perm.isCreature(this) && !perm.getAbilities(this).containsClass(BestowAbility.class)) {
if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
}
}
} else {
Ability spellAbility = perm.getSpellAbility();
if (spellAbility == null) {
if (!perm.getAbilities().isEmpty()) {
// Can happen for created tokens (e.g. Estrid, the Masked)
spellAbility = perm.getAbilities().get(0);
}
}
if (spellAbility.getTargets().isEmpty()) {
for (Ability ability : perm.getAbilities(this)) {
if ((ability instanceof SpellAbility) && SpellAbilityType.BASE_ALTERNATE == ((SpellAbility) ability).getSpellAbilityType() && !ability.getTargets().isEmpty()) {
spellAbility = ability;
break;
}
}
}
if (spellAbility.getTargets().isEmpty()) {
Permanent enchanted = this.getPermanent(perm.getAttachedTo());
logger.error("Aura without target: " + perm.getName() + " attached to " + (enchanted == null ? " null" : enchanted.getName()));
} else {
Target target = spellAbility.getTargets().get(0);
if (target instanceof TargetPermanent) {
Permanent attachedTo = getPermanent(perm.getAttachedTo());
if (attachedTo == null || !attachedTo.getAttachments().contains(perm.getId())) {
// handle bestow unattachment
Card card = this.getCard(perm.getId());
if (card != null && card.isCreature(this)) {
UUID wasAttachedTo = perm.getAttachedTo();
perm.attachTo(null, null, this);
fireEvent(new UnattachedEvent(wasAttachedTo, perm.getId(), perm, null));
} else if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
}
} else {
Filter auraFilter = spellAbility.getTargets().get(0).getFilter();
if (auraFilter instanceof FilterPermanent) {
if (!((FilterPermanent) auraFilter).match(attachedTo, perm.getId(), perm.getControllerId(), this) || attachedTo.cantBeAttachedBy(perm, null, this, true)) {
Card card = this.getCard(perm.getId());
if (card != null && card.isCreature(this)) {
UUID wasAttachedTo = perm.getAttachedTo();
perm.attachTo(null, null, this);
BestowAbility.becomeCreature(perm, this);
fireEvent(new UnattachedEvent(wasAttachedTo, perm.getId(), perm, null));
} else if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
}
}
} else if (!auraFilter.match(attachedTo, this) || attachedTo.cantBeAttachedBy(perm, null, this, true)) {
// handle bestow unattachment
Card card = this.getCard(perm.getId());
if (card != null && card.isCreature(this)) {
UUID wasAttachedTo = perm.getAttachedTo();
perm.attachTo(null, null, this);
BestowAbility.becomeCreature(perm, this);
fireEvent(new UnattachedEvent(wasAttachedTo, perm.getId(), perm, null));
} else if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
}
}
}
} else if (target instanceof TargetPlayer) {
Player attachedToPlayer = getPlayer(perm.getAttachedTo());
if (attachedToPlayer == null || attachedToPlayer.hasLost()) {
if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
}
} else {
Filter auraFilter = spellAbility.getTargets().get(0).getFilter();
if (!auraFilter.match(attachedToPlayer, this) || attachedToPlayer.hasProtectionFrom(perm, this)) {
if (movePermanentToGraveyardWithInfo(perm)) {
somethingHappened = true;
}
}
}
} else if (target instanceof TargetCard) {
Card attachedTo = getCard(perm.getAttachedTo());
if (attachedTo == null || !(spellAbility.getTargets().get(0)).canTarget(perm.getControllerId(), perm.getAttachedTo(), spellAbility, this)) {
if (movePermanentToGraveyardWithInfo(perm)) {
if (attachedTo != null) {
attachedTo.removeAttachment(perm.getId(), null, this);
}
somethingHappened = true;
}
}
}
}
}
}
// and it isn't the source of a chapter ability that has triggered but not yet left the stack, that Saga's controller sacrifices it.
if (perm.hasSubtype(SubType.SAGA, this)) {
int maxChapter = perm.getAbilities(this).stream().filter(SagaAbility.class::isInstance).map(SagaAbility.class::cast).map(SagaAbility::getMaxChapter).mapToInt(SagaChapter::getNumber).max().orElse(0);
boolean sacSaga = maxChapter <= perm.getCounters(this).getCount(CounterType.LORE) && this.getStack().stream().filter(SagaAbility::isChapterAbility).map(StackObject::getSourceId).noneMatch(perm.getId()::equals) && this.state.getTriggered(perm.getControllerId()).stream().filter(SagaAbility::isChapterAbility).map(Ability::getSourceId).noneMatch(perm.getId()::equals);
if (sacSaga) {
// After the last chapter ability has left the stack, you'll sacrifice the Saga
perm.sacrifice(null, this);
somethingHappened = true;
}
}
if (this.getState().isLegendaryRuleActive() && StaticFilters.FILTER_PERMANENT_LEGENDARY.match(perm, this)) {
legendary.add(perm);
}
if (StaticFilters.FILTER_PERMANENT_EQUIPMENT.match(perm, this)) {
// 20091005 - 704.5p, 702.14d
if (perm.getAttachedTo() != null) {
Permanent attachedTo = getPermanent(perm.getAttachedTo());
if (attachedTo != null) {
for (Ability ability : perm.getAbilities(this)) {
if (ability instanceof AttachableToRestrictedAbility) {
if (!((AttachableToRestrictedAbility) ability).canEquip(attachedTo, null, this)) {
attachedTo = null;
break;
}
}
}
}
if (attachedTo == null || !attachedTo.getAttachments().contains(perm.getId())) {
UUID wasAttachedTo = perm.getAttachedTo();
perm.attachTo(null, null, this);
fireEvent(new UnattachedEvent(wasAttachedTo, perm.getId(), perm, null));
} else if (!attachedTo.isCreature(this) || attachedTo.hasProtectionFrom(perm, this)) {
if (attachedTo.removeAttachment(perm.getId(), null, this)) {
somethingHappened = true;
}
}
}
}
if (StaticFilters.FILTER_PERMANENT_FORTIFICATION.match(perm, this)) {
if (perm.getAttachedTo() != null) {
Permanent land = getPermanent(perm.getAttachedTo());
if (land == null || !land.getAttachments().contains(perm.getId())) {
perm.attachTo(null, null, this);
} else if (!land.isLand(this) || land.hasProtectionFrom(perm, this)) {
if (land.removeAttachment(perm.getId(), null, this)) {
somethingHappened = true;
}
}
}
}
// it becomes unattached and remains on the battlefield.
if (!perm.getAttachments().isEmpty()) {
for (UUID attachmentId : perm.getAttachments()) {
Permanent attachment = getPermanent(attachmentId);
if (attachment != null && (attachment.isCreature(this) || !(attachment.hasSubtype(SubType.AURA, this) || attachment.hasSubtype(SubType.EQUIPMENT, this) || attachment.hasSubtype(SubType.FORTIFICATION, this)))) {
if (perm.removeAttachment(attachment.getId(), null, this)) {
somethingHappened = true;
break;
}
}
}
}
// 20110501 - 704.5r
if (perm.getCounters(this).containsKey(CounterType.P1P1) && perm.getCounters(this).containsKey(CounterType.M1M1)) {
int p1p1 = perm.getCounters(this).getCount(CounterType.P1P1);
int m1m1 = perm.getCounters(this).getCount(CounterType.M1M1);
int min = Math.min(p1p1, m1m1);
perm.getCounters(this).removeCounter(CounterType.P1P1, min);
perm.getCounters(this).removeCounter(CounterType.M1M1, min);
}
// has more than N counters of that kind on it, all but N of those counters are removed from it.
for (Ability ability : perm.getAbilities(this)) {
if (ability instanceof CantHaveMoreThanAmountCountersSourceAbility) {
CantHaveMoreThanAmountCountersSourceAbility counterAbility = (CantHaveMoreThanAmountCountersSourceAbility) ability;
int count = perm.getCounters(this).getCount(counterAbility.getCounterType());
if (count > counterAbility.getAmount()) {
perm.removeCounters(counterAbility.getCounterType().getName(), count - counterAbility.getAmount(), counterAbility, this);
somethingHappened = true;
}
}
}
}
if (legendary.size() > 1) {
// don't bother checking if less than 2 legends in play
for (Permanent legend : legendary) {
FilterPermanent filterLegendName = new FilterPermanent();
filterLegendName.add(SuperType.LEGENDARY.getPredicate());
filterLegendName.add(new NamePredicate(legend.getName()));
filterLegendName.add(new ControllerIdPredicate(legend.getControllerId()));
if (getBattlefield().contains(filterLegendName, null, legend.getControllerId(), this, 2)) {
if (!replaceEvent(GameEvent.getEvent(GameEvent.EventType.DESTROY_PERMANENT_BY_LEGENDARY_RULE, legend.getId(), legend.getControllerId()))) {
Player controller = this.getPlayer(legend.getControllerId());
if (controller != null) {
Target targetLegendaryToKeep = new TargetPermanent(filterLegendName);
targetLegendaryToKeep.setTargetName(legend.getName() + " to keep (Legendary Rule)?");
controller.chooseTarget(Outcome.Benefit, targetLegendaryToKeep, null, this);
for (Permanent dupLegend : getBattlefield().getActivePermanents(filterLegendName, legend.getControllerId(), this)) {
if (!targetLegendaryToKeep.getTargets().contains(dupLegend.getId())) {
movePermanentToGraveyardWithInfo(dupLegend);
}
}
}
return true;
}
}
}
}
// 704.5k - World Enchantments
if (worldEnchantment.size() > 1) {
int newestCard = -1;
Set<UUID> controllerIdOfNewest = new HashSet<>();
Permanent newestPermanent = null;
for (Permanent permanent : worldEnchantment) {
if (newestCard == -1) {
newestCard = permanent.getCreateOrder();
newestPermanent = permanent;
controllerIdOfNewest.clear();
controllerIdOfNewest.add(permanent.getControllerId());
} else if (newestCard < permanent.getCreateOrder()) {
newestCard = permanent.getCreateOrder();
newestPermanent = permanent;
controllerIdOfNewest.clear();
controllerIdOfNewest.add(permanent.getControllerId());
} else if (newestCard == permanent.getCreateOrder()) {
// In the event of a tie for the shortest amount of time, all are put into their owners’ graveyards. This is called the “world rule.”
newestPermanent = null;
controllerIdOfNewest.add(permanent.getControllerId());
}
}
for (UUID controllerId : controllerIdOfNewest) {
PlayerList newestPermanentControllerRange = state.getPlayersInRange(controllerId, this);
// 801.12 The "world rule" applies to a permanent only if other world permanents are within its controller's range of influence.
for (Permanent permanent : worldEnchantment) {
if (newestPermanentControllerRange.contains(permanent.getControllerId()) && !Objects.equals(newestPermanent, permanent)) {
movePermanentToGraveyardWithInfo(permanent);
somethingHappened = true;
}
}
}
}
// This is not a state-based action but it's unclear where else to put it
if (hasDayNight()) {
for (Permanent permanent : getBattlefield().getAllActivePermanents()) {
if ((permanent.getAbilities(this).containsClass(DayboundAbility.class) && !state.isDaytime()) || (permanent.getAbilities(this).containsClass(NightboundAbility.class) && state.isDaytime())) {
somethingHappened = permanent.transform(null, this, true) || somethingHappened;
}
}
}
// TODO: implement the rest
return somethingHappened;
}
Aggregations