diff --git a/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java b/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java index 7cc93560240..1357404acfa 100644 --- a/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java +++ b/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java @@ -1,11 +1,7 @@ - package mage.cards.b; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.condition.common.IsStepCondition; import mage.abilities.costs.common.TapSourceCost; @@ -15,11 +11,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.RemoveFromCombatTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.PhaseStep; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterBlockingCreature; import mage.filter.predicate.permanent.PermanentInListPredicate; @@ -32,8 +24,9 @@ import mage.target.TargetPermanent; import mage.target.common.TargetAttackingCreature; import mage.watchers.common.BlockedByOnlyOneCreatureThisCombatWatcher; +import java.util.*; + /** - * * @author L_J */ public final class BalduvianWarlord extends CardImpl { @@ -64,7 +57,7 @@ public final class BalduvianWarlord extends CardImpl { class BalduvianWarlordUnblockEffect extends OneShotEffect { - public BalduvianWarlordUnblockEffect() { + BalduvianWarlordUnblockEffect() { super(Outcome.Benefit); this.staticText = " Remove target blocking creature from combat. Creatures it was blocking that hadn't become blocked by another creature this combat become unblocked, then it blocks an attacking creature of your choice"; } @@ -146,6 +139,15 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect { game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, bandedId, null)); } } + Set morSet = new HashSet<>(); + morSet.add(new MageObjectReference(chosenPermanent, game)); + String key = UUID.randomUUID().toString(); + game.getState().setValue("becameBlocked_" + key, morSet); + game.fireEvent(GameEvent.getEvent( + GameEvent.EventType.BATCH_BLOCK_NONCOMBAT, + source.getSourceId(), source.getSourceId(), + source.getControllerId(), key, 0) + ); } game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BLOCKER_DECLARED, chosenPermanent.getId(), permanent.getId(), permanent.getControllerId())); } diff --git a/Mage.Sets/src/mage/cards/c/ChokingVines.java b/Mage.Sets/src/mage/cards/c/ChokingVines.java index 3dce3af1475..462c2c4ecfe 100644 --- a/Mage.Sets/src/mage/cards/c/ChokingVines.java +++ b/Mage.Sets/src/mage/cards/c/ChokingVines.java @@ -1,27 +1,20 @@ package mage.cards.c; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.BecomeBlockedTargetEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.PhaseStep; import mage.game.Game; -import mage.game.combat.CombatGroup; -import mage.players.Player; -import mage.target.Target; -import mage.target.Targets; import mage.target.common.TargetCreaturePermanent; import mage.target.targetadjustment.TargetAdjuster; +import java.util.UUID; + import static mage.filter.StaticFilters.FILTER_ATTACKING_CREATURES; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; /** * @author arcox @@ -36,7 +29,8 @@ public final class ChokingVines extends CardImpl { PhaseStep.DECLARE_BLOCKERS, null, "Cast this spell only during the declare blockers step")); // X target attacking creatures become blocked. Choking Vines deals 1 damage to each of those creatures. - this.getSpellAbility().addEffect(new ChokingVinesEffect()); + this.getSpellAbility().addEffect(new BecomeBlockedTargetEffect() + .setText("X target attacking creatures become blocked.")); this.getSpellAbility().addEffect(new DamageTargetEffect(1) .setText("{this} deals 1 damage to each of those creatures")); this.getSpellAbility().setTargetAdjuster(ChokingVinesAdjuster.instance); @@ -62,44 +56,3 @@ enum ChokingVinesAdjuster implements TargetAdjuster { ability.addTarget(new TargetCreaturePermanent(x, x, FILTER_ATTACKING_CREATURES, false)); } } - -class ChokingVinesEffect extends OneShotEffect { - - public ChokingVinesEffect() { - super(Outcome.Benefit); - this.staticText = "X target attacking creatures become blocked"; - } - - public ChokingVinesEffect(final ChokingVinesEffect effect) { - super(effect); - } - - @Override - public ChokingVinesEffect copy() { - return new ChokingVinesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Targets targets = source.getTargets(); - - if (controller != null && !targets.isEmpty()) { - for (Target target : targets) { - for (UUID id : target.getTargets()) { - CombatGroup combatGroup = game.getCombat().findGroup(id); - if (combatGroup != null) { - combatGroup.setBlocked(true); // non-banded creatures - combatGroup.setBlocked(true, game); // this only works for banded creatures and needs to be checked out - Permanent attacker = game.getPermanent(id); - if (attacker != null) { - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, attacker.getId(), null)); - } - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/c/CurtainOfLight.java b/Mage.Sets/src/mage/cards/c/CurtainOfLight.java index 5f1e7056ef7..027eeae339d 100644 --- a/Mage.Sets/src/mage/cards/c/CurtainOfLight.java +++ b/Mage.Sets/src/mage/cards/c/CurtainOfLight.java @@ -1,34 +1,28 @@ - package mage.cards.c; -import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.condition.common.AfterBlockersAreDeclaredCondition; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.BecomeBlockedTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.TurnPhase; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.AttackingPredicate; import mage.filter.predicate.permanent.BlockedPredicate; -import mage.game.Game; -import mage.game.combat.CombatGroup; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class CurtainOfLight extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("unblocked attacking creature"); + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("unblocked attacking creature"); static { filter.add(AttackingPredicate.instance); @@ -39,17 +33,19 @@ public final class CurtainOfLight extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Cast Curtain of Light only during combat after blockers are declared. - this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT, AfterBlockersAreDeclaredCondition.instance)); + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility( + TurnPhase.COMBAT, AfterBlockersAreDeclaredCondition.instance + )); // Target unblocked attacking creature becomes blocked. - this.getSpellAbility().addEffect(new CurtainOfLightEffect()); + this.getSpellAbility().addEffect(new BecomeBlockedTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); // Draw a card. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); } - public CurtainOfLight(final CurtainOfLight card) { + private CurtainOfLight(final CurtainOfLight card) { super(card); } @@ -58,35 +54,3 @@ public final class CurtainOfLight extends CardImpl { return new CurtainOfLight(this); } } - -class CurtainOfLightEffect extends OneShotEffect { - - public CurtainOfLightEffect() { - super(Outcome.Benefit); - this.staticText = "Target unblocked attacking creature becomes blocked"; - } - - public CurtainOfLightEffect(final CurtainOfLightEffect effect) { - super(effect); - } - - @Override - public CurtainOfLightEffect copy() { - return new CurtainOfLightEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (controller != null && permanent != null) { - CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId()); - if (combatGroup != null) { - combatGroup.setBlocked(true, game); - game.informPlayers(permanent.getLogName() + " has become blocked"); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java b/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java index 88bb01666ea..1341174f42a 100644 --- a/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java +++ b/Mage.Sets/src/mage/cards/d/DazzlingBeauty.java @@ -1,30 +1,23 @@ - package mage.cards.d; -import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.BecomeBlockedTargetEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.PhaseStep; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.AttackingPredicate; import mage.filter.predicate.permanent.BlockedPredicate; -import mage.game.Game; -import mage.game.combat.CombatGroup; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 & L_J */ public final class DazzlingBeauty extends CardImpl { @@ -40,17 +33,20 @@ public final class DazzlingBeauty extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); // Cast Dazzling Beauty only during the declare blockers step. - this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, PhaseStep.DECLARE_BLOCKERS, null, "Cast Dazzling Beauty only during the declare blockers step")); + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility( + null, PhaseStep.DECLARE_BLOCKERS, null, + "Cast this spell only during the declare blockers step" + )); // Target unblocked attacking creature becomes blocked. - this.getSpellAbility().addEffect(new DazzlingBeautyEffect()); + this.getSpellAbility().addEffect(new BecomeBlockedTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); // Draw a card at the beginning of the next turn's upkeep. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false)); } - public DazzlingBeauty(final DazzlingBeauty card) { + private DazzlingBeauty(final DazzlingBeauty card) { super(card); } @@ -59,35 +55,3 @@ public final class DazzlingBeauty extends CardImpl { return new DazzlingBeauty(this); } } - -class DazzlingBeautyEffect extends OneShotEffect { - - public DazzlingBeautyEffect() { - super(Outcome.Benefit); - this.staticText = "Target unblocked attacking creature becomes blocked"; - } - - public DazzlingBeautyEffect(final DazzlingBeautyEffect effect) { - super(effect); - } - - @Override - public DazzlingBeautyEffect copy() { - return new DazzlingBeautyEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (controller != null && permanent != null) { - CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId()); - if (combatGroup != null) { - combatGroup.setBlocked(true, game); - game.informPlayers(permanent.getLogName() + " has become blocked"); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/f/FalseOrders.java b/Mage.Sets/src/mage/cards/f/FalseOrders.java index 28d324d5f96..45e0ae7be34 100644 --- a/Mage.Sets/src/mage/cards/f/FalseOrders.java +++ b/Mage.Sets/src/mage/cards/f/FalseOrders.java @@ -1,10 +1,6 @@ - package mage.cards.f; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.effects.Effect; @@ -30,8 +26,9 @@ import mage.target.TargetPermanent; import mage.target.common.TargetAttackingCreature; import mage.watchers.common.BlockedByOnlyOneCreatureThisCombatWatcher; +import java.util.*; + /** - * * @author L_J */ public final class FalseOrders extends CardImpl { @@ -40,7 +37,7 @@ public final class FalseOrders extends CardImpl { static { filter.add(CardType.CREATURE.getPredicate()); - filter.add(new FalseOrdersDefendingPlayerControlsPredicate()); + filter.add(FalseOrdersDefendingPlayerControlsPredicate.instance); } public FalseOrders(UUID ownerId, CardSetInfo setInfo) { @@ -55,7 +52,7 @@ public final class FalseOrders extends CardImpl { this.getSpellAbility().addWatcher(new BlockedByOnlyOneCreatureThisCombatWatcher()); } - public FalseOrders(final FalseOrders card) { + private FalseOrders(final FalseOrders card) { super(card); } @@ -66,7 +63,8 @@ public final class FalseOrders extends CardImpl { } -class FalseOrdersDefendingPlayerControlsPredicate implements ObjectPlayerPredicate> { +enum FalseOrdersDefendingPlayerControlsPredicate implements ObjectPlayerPredicate> { + instance; @Override public boolean apply(ObjectPlayer input, Game game) { @@ -76,12 +74,12 @@ class FalseOrdersDefendingPlayerControlsPredicate implements ObjectPlayerPredica class FalseOrdersUnblockEffect extends OneShotEffect { - public FalseOrdersUnblockEffect() { + FalseOrdersUnblockEffect() { super(Outcome.Benefit); this.staticText = "Remove target creature defending player controls from combat. Creatures it was blocking that had become blocked by only that creature this combat become unblocked. You may have it block an attacking creature of your choice"; } - public FalseOrdersUnblockEffect(final FalseOrdersUnblockEffect effect) { + private FalseOrdersUnblockEffect(final FalseOrdersUnblockEffect effect) { super(effect); } @@ -167,6 +165,15 @@ class FalseOrdersUnblockEffect extends OneShotEffect { game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, bandedId, null)); } } + Set morSet = new HashSet<>(); + morSet.add(new MageObjectReference(chosenPermanent, game)); + String key = UUID.randomUUID().toString(); + game.getState().setValue("becameBlocked_" + key, morSet); + game.fireEvent(GameEvent.getEvent( + GameEvent.EventType.BATCH_BLOCK_NONCOMBAT, + source.getSourceId(), source.getSourceId(), + source.getControllerId(), key, 0) + ); } game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BLOCKER_DECLARED, chosenPermanent.getId(), permanent.getId(), permanent.getControllerId())); } diff --git a/Mage.Sets/src/mage/cards/f/FogPatch.java b/Mage.Sets/src/mage/cards/f/FogPatch.java index 7e054f6c074..dc9decca0dd 100644 --- a/Mage.Sets/src/mage/cards/f/FogPatch.java +++ b/Mage.Sets/src/mage/cards/f/FogPatch.java @@ -1,22 +1,22 @@ - package mage.cards.f; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.BecomeBlockedTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.PhaseStep; +import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.combat.CombatGroup; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.target.targetpointer.FixedTargets; + +import java.util.UUID; /** - * * @author L_J */ public final class FogPatch extends CardImpl { @@ -25,13 +25,16 @@ public final class FogPatch extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // Cast Fog Patch only during the declare blockers step. - this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, PhaseStep.DECLARE_BLOCKERS, null, "Cast this spell only during the declare blockers step")); + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility( + null, PhaseStep.DECLARE_BLOCKERS, null, + "Cast this spell only during the declare blockers step" + )); // Attacking creatures become blocked. this.getSpellAbility().addEffect(new FogPatchEffect()); } - public FogPatch(final FogPatch card) { + private FogPatch(final FogPatch card) { super(card); } @@ -43,12 +46,12 @@ public final class FogPatch extends CardImpl { class FogPatchEffect extends OneShotEffect { - public FogPatchEffect() { + FogPatchEffect() { super(Outcome.Benefit); this.staticText = "Attacking creatures become blocked"; } - public FogPatchEffect(final FogPatchEffect effect) { + private FogPatchEffect(final FogPatchEffect effect) { super(effect); } @@ -59,19 +62,10 @@ class FogPatchEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID attackers : game.getCombat().getAttackers()) { - Permanent attacker = game.getPermanent(attackers); - if (attacker != null) { - CombatGroup combatGroup = game.getCombat().findGroup(attacker.getId()); - if (combatGroup != null) { - combatGroup.setBlocked(true, game); - } - } - } - return true; - } - return false; + Effect effect = new BecomeBlockedTargetEffect(); + effect.setTargetPointer(new FixedTargets(game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_ATTACKING_CREATURES, source.getSourceId(), game + ), game)); + return effect.apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/n/NeyithOfTheDireHunt.java b/Mage.Sets/src/mage/cards/n/NeyithOfTheDireHunt.java index 175f15c4ebb..65f74d18329 100644 --- a/Mage.Sets/src/mage/cards/n/NeyithOfTheDireHunt.java +++ b/Mage.Sets/src/mage/cards/n/NeyithOfTheDireHunt.java @@ -75,18 +75,33 @@ class NeyithOfTheDireHuntTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.BATCH_FIGHT - || event.getType() == GameEvent.EventType.DECLARE_BLOCKERS_STEP; + || event.getType() == GameEvent.EventType.DECLARE_BLOCKERS_STEP + || event.getType() == GameEvent.EventType.BATCH_BLOCK_NONCOMBAT; } @Override public boolean checkTrigger(GameEvent event, Game game) { + Object value; + Set permanents; switch (event.getType()) { case BATCH_FIGHT: - Object value = game.getState().getValue("batchFight_" + event.getData()); + value = game.getState().getValue("batchFight_" + event.getData()); if (!(value instanceof Set)) { return false; } - Set permanents = (Set) value; + permanents = (Set) value; + return permanents + .stream() + .map(mor -> mor.getPermanentOrLKIBattlefield(game)) + .filter(Objects::nonNull) + .map(Controllable::getControllerId) + .anyMatch(this.getControllerId()::equals); + case BATCH_BLOCK_NONCOMBAT: + value = game.getState().getValue("becameBlocked_" + event.getData()); + if (!(value instanceof Set)) { + return false; + } + permanents = (Set) value; return permanents .stream() .map(mor -> mor.getPermanentOrLKIBattlefield(game)) diff --git a/Mage.Sets/src/mage/cards/t/TrapRunner.java b/Mage.Sets/src/mage/cards/t/TrapRunner.java index 6d4b06b2f57..1b009185d0f 100644 --- a/Mage.Sets/src/mage/cards/t/TrapRunner.java +++ b/Mage.Sets/src/mage/cards/t/TrapRunner.java @@ -1,45 +1,47 @@ - package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.condition.CompoundCondition; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.AfterBlockersAreDeclaredCondition; import mage.abilities.condition.common.IsPhaseCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalActivatedAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.BecomeBlockedTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; import mage.constants.TurnPhase; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.AttackingPredicate; import mage.filter.predicate.permanent.BlockedPredicate; -import mage.game.Game; -import mage.game.combat.CombatGroup; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class TrapRunner extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("unblocked attacking creature"); + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("unblocked attacking creature"); static { filter.add(AttackingPredicate.instance); filter.add(Predicates.not(BlockedPredicate.instance)); } + private static final Condition condition = new CompoundCondition( + "during combat after blockers are declared", + new IsPhaseCondition(TurnPhase.COMBAT), + AfterBlockersAreDeclaredCondition.instance + ); + public TrapRunner(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.HUMAN); @@ -48,13 +50,14 @@ public final class TrapRunner extends CardImpl { this.toughness = new MageInt(3); // {T}: Target unblocked attacking creature becomes blocked. Activate this ability only during combat after blockers are declared. - Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new TrapRunnerEffect(), new TapSourceCost(), - new CompoundCondition("during combat after blockers are declared", new IsPhaseCondition(TurnPhase.COMBAT), AfterBlockersAreDeclaredCondition.instance)); + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, new BecomeBlockedTargetEffect(), new TapSourceCost(), condition + ); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } - public TrapRunner(final TrapRunner card) { + private TrapRunner(final TrapRunner card) { super(card); } @@ -64,35 +67,3 @@ public final class TrapRunner extends CardImpl { } } - -class TrapRunnerEffect extends OneShotEffect { - - public TrapRunnerEffect() { - super(Outcome.Benefit); - this.staticText = "Target unblocked attacking creature becomes blocked"; - } - - public TrapRunnerEffect(final TrapRunnerEffect effect) { - super(effect); - } - - @Override - public TrapRunnerEffect copy() { - return new TrapRunnerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (controller != null && permanent != null) { - CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId()); - if (combatGroup != null) { - combatGroup.setBlocked(true, game); - game.informPlayers(permanent.getLogName() + " has become blocked"); - return true; - } - } - return false; - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/common/BecomeBlockedTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/BecomeBlockedTargetEffect.java new file mode 100644 index 00000000000..4c6c465b189 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/BecomeBlockedTargetEffect.java @@ -0,0 +1,90 @@ +package mage.abilities.effects.common; + +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.util.CardUtil; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class BecomeBlockedTargetEffect extends OneShotEffect { + + public BecomeBlockedTargetEffect() { + super(Outcome.Benefit); + } + + private BecomeBlockedTargetEffect(final BecomeBlockedTargetEffect effect) { + super(effect); + } + + @Override + public BecomeBlockedTargetEffect copy() { + return new BecomeBlockedTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Set morSet = new HashSet<>(); + for (UUID targetId : targetPointer.getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent == null) { + continue; + } + CombatGroup combatGroup = game.getCombat().findGroup(permanent.getId()); + if (combatGroup == null) { + continue; + } + boolean alreadyBlocked = combatGroup.getBlocked(); + combatGroup.setBlocked(true); // non-banded creatures + combatGroup.setBlocked(true, game); // this only works for banded creatures and needs to be checked out + if (alreadyBlocked) { + continue; + } + game.fireEvent(GameEvent.getEvent( + GameEvent.EventType.CREATURE_BLOCKED, permanent.getId(), + source.getSourceId(), null + )); + morSet.add(new MageObjectReference(permanent, game)); + } + String key = UUID.randomUUID().toString(); + game.getState().setValue("becameBlocked_" + key, morSet); + game.fireEvent(GameEvent.getEvent( + GameEvent.EventType.BATCH_BLOCK_NONCOMBAT, + source.getSourceId(), source.getSourceId(), + source.getControllerId(), key, 0) + ); + return true; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(); + Target target = mode.getTargets().get(0); + if (target.getNumberOfTargets() == 1) { + String targetName = target.getTargetName(); + sb.append("target ").append(targetName).append(" becomes blocked"); + return sb.toString(); + } + if (target.getMaxNumberOfTargets() != target.getMinNumberOfTargets()) { + sb.append("up to "); + } + sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets())); + sb.append(" target ").append(target.getTargetName()).append(" become blocked"); + return sb.toString(); + } +} diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index a3712958e12..c9070f9193c 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -235,6 +235,7 @@ public class GameEvent implements Serializable { */ DECLARE_BLOCKER, BLOCKER_DECLARED, CREATURE_BLOCKED, + BATCH_BLOCK_NONCOMBAT, UNBLOCKED_ATTACKER, SEARCH_LIBRARY, LIBRARY_SEARCHED, SHUFFLE_LIBRARY, LIBRARY_SHUFFLED,