diff --git a/Mage.Sets/src/mage/cards/g/GoroGoroAndSatoru.java b/Mage.Sets/src/mage/cards/g/GoroGoroAndSatoru.java index 28d8e4d90f6..b3e62bbeda4 100644 --- a/Mage.Sets/src/mage/cards/g/GoroGoroAndSatoru.java +++ b/Mage.Sets/src/mage/cards/g/GoroGoroAndSatoru.java @@ -1,7 +1,7 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealCombatDamageControlledTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; @@ -11,23 +11,24 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.EnteredThisTurnPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.game.permanent.token.DragonSpiritToken; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** - * @author TheElk801 + * @author Grath */ public final class GoroGoroAndSatoru extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creatures you control that entered the battlefield this turn"); + + static { + filter.add(EnteredThisTurnPredicate.instance); + } + public GoroGoroAndSatoru(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}{R}"); @@ -39,7 +40,9 @@ public final class GoroGoroAndSatoru extends CardImpl { // Whenever one or more creatures you control that entered the battlefield this turn deal combat damage to a // player, create a 5/5 red Dragon Spirit creature token with flying. - this.addAbility(new GoroGoroAndSatoruTriggeredAbility()); + this.addAbility(new DealCombatDamageControlledTriggeredAbility( + new CreateTokenEffect(new DragonSpiritToken()), filter + )); // {1}{R}: Creatures you control gain haste until end of turn. this.addAbility(new SimpleActivatedAbility(new GainAbilityControlledEffect( @@ -57,59 +60,3 @@ public final class GoroGoroAndSatoru extends CardImpl { return new GoroGoroAndSatoru(this); } } - -class GoroGoroAndSatoruTriggeredAbility extends TriggeredAbilityImpl { - - private static final FilterControlledCreaturePermanent filter - = new FilterControlledCreaturePermanent("creatures you control that entered the battlefield this turn"); - - static { - filter.add(EnteredThisTurnPredicate.instance); - } - - private final Set damagedPlayerIds = new HashSet<>(); - - public GoroGoroAndSatoruTriggeredAbility() { - super(Zone.BATTLEFIELD, new CreateTokenEffect(new DragonSpiritToken()), false); - } - - private GoroGoroAndSatoruTriggeredAbility(final GoroGoroAndSatoruTriggeredAbility ability) { - super(ability); - } - - @Override - public GoroGoroAndSatoruTriggeredAbility copy() { - return new GoroGoroAndSatoruTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER - || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRIORITY - || event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - Permanent p = game.getPermanent(event.getSourceId()); - if (damageEvent.isCombatDamage() && p != null && p.isControlledBy(this.getControllerId()) && - filter.match(p, getControllerId(), this, game) && - !damagedPlayerIds.contains(event.getPlayerId())) { - damagedPlayerIds.add(event.getPlayerId()); - return true; - } - } - if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_PRIORITY || - (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(getSourceId()))) { - damagedPlayerIds.clear(); - } - return false; - } - - @Override - public String getRule() { - return "Whenever one or more creatures you control that entered the battlefield this turn deal combat damage to a player, create a 5/5 red Dragon Spirit creature token with flying."; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java b/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java index 28a5e93d802..c8d96a93e9d 100644 --- a/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java +++ b/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java @@ -2,27 +2,33 @@ package mage.cards.q; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealCombatDamageControlledTriggeredAbility; +import mage.abilities.dynamicvalue.common.SavedDamageValue; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.game.permanent.token.DinosaurBeastToken; -import mage.target.targetpointer.FixedTarget; -import mage.watchers.Watcher; -import java.util.*; +import java.util.UUID; /** * @author TheElk801 */ public final class QuartzwoodCrasher extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control with trample"); + + static { + filter.add(new AbilityPredicate(TrampleAbility.class)); + } + public QuartzwoodCrasher(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}{G}"); @@ -35,7 +41,7 @@ public final class QuartzwoodCrasher extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever one or more creatures you control with trample deal combat damage to a player, create an X/X green Dinosaur Beast creature token with trample, where X is the amount of damage those creatures dealt to that player. - this.addAbility(new QuartzwoodCrasherTriggeredAbility()); + this.addAbility(new DealCombatDamageControlledTriggeredAbility(new QuartzwoodCrasherEffect(), filter)); } private QuartzwoodCrasher(final QuartzwoodCrasher card) { @@ -48,62 +54,12 @@ public final class QuartzwoodCrasher extends CardImpl { } } -class QuartzwoodCrasherTriggeredAbility extends TriggeredAbilityImpl { - - private final Set damagedPlayerIds = new HashSet<>(); - - QuartzwoodCrasherTriggeredAbility() { - super(Zone.BATTLEFIELD, new QuartzwoodCrasherEffect(), false); - this.addWatcher(new QuartzwoodCrasherWatcher()); - } - - private QuartzwoodCrasherTriggeredAbility(final QuartzwoodCrasherTriggeredAbility ability) { - super(ability); - } - - @Override - public QuartzwoodCrasherTriggeredAbility copy() { - return new QuartzwoodCrasherTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER - || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) { - damagedPlayerIds.clear(); - return false; - } - if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER - && ((DamagedPlayerEvent) event).isCombatDamage()) { - Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.isControlledBy(controllerId) - && creature.hasAbility(TrampleAbility.getInstance(), game) - && !damagedPlayerIds.contains(event.getTargetId())) { - damagedPlayerIds.add(event.getTargetId()); - this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever one or more creatures you control with trample deal combat damage to a player, " + - "create an X/X green Dinosaur Beast creature token with trample, " + - "where X is the amount of damage those creatures dealt to that player."; - } -} - class QuartzwoodCrasherEffect extends OneShotEffect { QuartzwoodCrasherEffect() { super(Outcome.Benefit); + this.staticText = "create an X/X green Dinosaur Beast creature token with trample, " + + "where X is the amount of damage those creatures dealt to that player."; } private QuartzwoodCrasherEffect(final QuartzwoodCrasherEffect effect) { @@ -117,45 +73,7 @@ class QuartzwoodCrasherEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - QuartzwoodCrasherWatcher watcher = game.getState().getWatcher(QuartzwoodCrasherWatcher.class); - return watcher != null && new DinosaurBeastToken( - watcher.getDamage(targetPointer.getFirst(game, source), source.getControllerId()) + return new DinosaurBeastToken(SavedDamageValue.MUCH.calculate(game, source, this) ).putOntoBattlefield(1, game, source, source.getControllerId()); } } - -class QuartzwoodCrasherWatcher extends Watcher { - - private final Map> damageMap = new HashMap<>(); - - QuartzwoodCrasherWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST - || event.getType() == GameEvent.EventType.CLEANUP_STEP_POST) { - damageMap.clear(); - return; - } - if (event.getType() != GameEvent.EventType.DAMAGED_PLAYER - || !((DamagedPlayerEvent) event).isCombatDamage()) { - return; - } - Permanent creature = game.getPermanent(event.getSourceId()); - if (creature == null || !creature.hasAbility(TrampleAbility.getInstance(), game)) { - return; - } - damageMap - .computeIfAbsent(event.getTargetId(), x -> new HashMap<>()) - .compute(creature.getControllerId(), (uuid, i) -> i == null ? event.getAmount() : event.getAmount() + i); - } - - public int getDamage(UUID damagedPlayerId, UUID controllerId) { - if (!damageMap.containsKey(damagedPlayerId)) { - return 0; - } - return damageMap.get(damagedPlayerId).getOrDefault(controllerId, 0); - } -} diff --git a/Mage/src/main/java/mage/abilities/common/DealCombatDamageControlledTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealCombatDamageControlledTriggeredAbility.java index bd16ecc6fc2..e84eec3d200 100644 --- a/Mage/src/main/java/mage/abilities/common/DealCombatDamageControlledTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealCombatDamageControlledTriggeredAbility.java @@ -39,7 +39,8 @@ public class DealCombatDamageControlledTriggeredAbility extends TriggeredAbility super(zone, effect, optional); this.setTargetPointer = setTargetPointer; this.filter = filter; - setTriggerPhrase("Whenever one or more " + filter.getMessage() + " you control deal combat damage to a player, "); + String filterMessage = (filter.getMessage().contains("you control") ? filter.getMessage() : filter.getMessage() + " you control"); + setTriggerPhrase("Whenever one or more " + filterMessage + " deal combat damage to a player, "); } protected DealCombatDamageControlledTriggeredAbility(final DealCombatDamageControlledTriggeredAbility ability) { @@ -65,8 +66,8 @@ public class DealCombatDamageControlledTriggeredAbility extends TriggeredAbility .filter(e -> { Permanent permanent = game.getPermanentOrLKIBattlefield(e.getSourceId()); return permanent != null - && filter.match(permanent, game) - && permanent.isControlledBy(this.getControllerId()); + && permanent.isControlledBy(this.getControllerId()) + && filter.match(permanent, game); }) .collect(Collectors.toList()); @@ -87,4 +88,4 @@ public class DealCombatDamageControlledTriggeredAbility extends TriggeredAbility return true; } -} \ No newline at end of file +}