Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix EntersBattlefieldOneOrMoreTriggeredAbility for ZONE_CHANGE_GROUP events making tokens controlled by different players #12592

Prev Previous commit
Next Next commit
Rewrite to use ZONE_CHANGE_BATCH
  • Loading branch information
jimga150 committed Jul 23, 2024
commit 537a63f73d92f9c6da7ce4545bffcb9533473616
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package mage.abilities.common;

import mage.MageItem;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeGroupEvent;
import mage.game.events.ZoneChangeBatchEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;

import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
Expand Down Expand Up @@ -41,40 +40,31 @@ private EntersBattlefieldOneOrMoreTriggeredAbility(final EntersBattlefieldOneOrM

@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE_GROUP;
return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH;
}

@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeGroupEvent zEvent = (ZoneChangeGroupEvent) event;

Player controller = game.getPlayer(this.controllerId);
if (zEvent.getToZone() != Zone.BATTLEFIELD || controller == null) {
if (controller == null) {
return false;
}

// Use Supplier for stream reuse
Supplier<Stream<Permanent>> enteringPermanentsSupplier = () -> Stream.concat(
zEvent.getTokens().stream(),
zEvent.getCards().stream()
.map(MageItem::getId)
.map(game::getPermanent)
.filter(Objects::nonNull)
);
ZoneChangeBatchEvent zEvent = (ZoneChangeBatchEvent) event;
Stream<Permanent> enteringPermanents = zEvent.getEvents().stream()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use stream fields/params due code style. Use filter with all conditions inside.

.filter(z -> z.getToZone() == Zone.BATTLEFIELD)
.map(ZoneChangeEvent::getTarget)
.filter(Objects::nonNull)
.filter(permanent -> filterPermanent.match(permanent, this.controllerId, this, game));

switch (this.targetController) {
case YOU:
if (enteringPermanentsSupplier.get().noneMatch(permanent -> permanent.getControllerId().equals(controller.getId()))) {
return false;
}
break;
return enteringPermanents.anyMatch(permanent -> permanent.getControllerId().equals(this.controllerId));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use getControllerId() and getTargetController() instead direct access due good code style.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

targetController is fine to access directly, it's internal to this class. Still need to update to getControllerId() though

case OPPONENT:
if (enteringPermanentsSupplier.get().noneMatch(permanent -> controller.hasOpponent(permanent.getControllerId(), game))) {
return false;
}
break;
return enteringPermanents.anyMatch(permanent -> controller.hasOpponent(this.controllerId, game));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line looks wrong, it should be checking permanent.getControllerId(). Looks like no ability currently uses TargetController.OPPONENT though.

also, should add a default case to the switch that throws an error (you can imagine a dev trying to use TargetController.ANY and it will silently never trigger)

}

return enteringPermanentsSupplier.get().anyMatch(permanent -> filterPermanent.match(permanent, this.controllerId, this, game));
return false;
}

@Override
Expand Down
Loading