mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-14 17:58:01 +00:00
LCI: deeproot_pilgrimage.txt and support (TapAllTrigger) (#4043)
* LCI: deeproot_pilgrimage.txt and support (TapAllTrigger) * refactor Card.tap to boolean * move tappedAll check out of CostPartWithList
This commit is contained in:
@@ -4,8 +4,12 @@ import forge.game.Game;
|
|||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.event.GameEventCardRegenerated;
|
import forge.game.event.GameEventCardRegenerated;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class RegenerationEffect extends SpellAbilityEffect {
|
public class RegenerationEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
@@ -17,6 +21,7 @@ public class RegenerationEffect extends SpellAbilityEffect {
|
|||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final Card host = sa.getHostCard();
|
final Card host = sa.getHostCard();
|
||||||
final Game game = host.getGame();
|
final Game game = host.getGame();
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (Card c : getTargetCards(sa)) {
|
for (Card c : getTargetCards(sa)) {
|
||||||
// checks already done in ReplacementEffect
|
// checks already done in ReplacementEffect
|
||||||
|
|
||||||
@@ -24,7 +29,7 @@ public class RegenerationEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
c.setDamage(0);
|
c.setDamage(0);
|
||||||
c.setHasBeenDealtDeathtouchDamage(false);
|
c.setHasBeenDealtDeathtouchDamage(false);
|
||||||
c.tap(true, cause, c.getController());
|
if (c.tap(true, cause, c.getController())) tapped.add(c);
|
||||||
c.addRegeneratedThisTurn();
|
c.addRegeneratedThisTurn();
|
||||||
|
|
||||||
if (game.getCombat() != null) {
|
if (game.getCombat() != null) {
|
||||||
@@ -40,6 +45,11 @@ public class RegenerationEffect extends SpellAbilityEffect {
|
|||||||
host.removeRemembered(c);
|
host.removeRemembered(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.AbilitySub;
|
import forge.game.spellability.AbilitySub;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class TapAllEffect extends SpellAbilityEffect {
|
public class TapAllEffect extends SpellAbilityEffect {
|
||||||
@Override
|
@Override
|
||||||
protected String getStackDescription(SpellAbility sa) {
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
@@ -41,6 +46,7 @@ public class TapAllEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
Player tapper = activator;
|
Player tapper = activator;
|
||||||
|
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card c : cards) {
|
for (final Card c : cards) {
|
||||||
if (remTapped) {
|
if (remTapped) {
|
||||||
card.addRemembered(c);
|
card.addRemembered(c);
|
||||||
@@ -48,7 +54,12 @@ public class TapAllEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("TapperController")) {
|
if (sa.hasParam("TapperController")) {
|
||||||
tapper = c.getController();
|
tapper = c.getController();
|
||||||
}
|
}
|
||||||
c.tap(true, sa, tapper);
|
if (c.tap(true, sa, tapper)) tapped.add(c);
|
||||||
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
@@ -7,10 +8,13 @@ import forge.game.card.CardCollection;
|
|||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class TapEffect extends SpellAbilityEffect {
|
public class TapEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -45,6 +49,7 @@ public class TapEffect extends SpellAbilityEffect {
|
|||||||
tapper = AbilityUtils.getDefinedPlayers(card, sa.getParam("Tapper"), sa).getFirst();
|
tapper = AbilityUtils.getDefinedPlayers(card, sa.getParam("Tapper"), sa).getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card tgtC : toTap) {
|
for (final Card tgtC : toTap) {
|
||||||
if (tgtC.isPhasedOut()) {
|
if (tgtC.isPhasedOut()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -53,13 +58,18 @@ public class TapEffect extends SpellAbilityEffect {
|
|||||||
if (tgtC.isUntapped() && remTapped || alwaysRem) {
|
if (tgtC.isUntapped() && remTapped || alwaysRem) {
|
||||||
card.addRemembered(tgtC);
|
card.addRemembered(tgtC);
|
||||||
}
|
}
|
||||||
tgtC.tap(true, sa, tapper);
|
if (tgtC.tap(true, sa, tapper)) tapped.add(tgtC);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("ETB")) {
|
if (sa.hasParam("ETB")) {
|
||||||
// do not fire Taps triggers
|
// do not fire Taps triggers
|
||||||
tgtC.setTapped(true);
|
tgtC.setTapped(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
activator.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,18 +2,23 @@ package forge.game.ability.effects;
|
|||||||
|
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerController;
|
import forge.game.player.PlayerController;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class TapOrUntapAllEffect extends SpellAbilityEffect {
|
public class TapOrUntapAllEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -60,16 +65,22 @@ public class TapOrUntapAllEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
toTap = sa.getActivatingPlayer().getController().chooseBinary(sa, sb.toString(), PlayerController.BinaryChoiceType.TapOrUntap);
|
toTap = sa.getActivatingPlayer().getController().chooseBinary(sa, sb.toString(), PlayerController.BinaryChoiceType.TapOrUntap);
|
||||||
|
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card tgtC : validCards) {
|
for (final Card tgtC : validCards) {
|
||||||
if (!tgtC.isInPlay()) {
|
if (!tgtC.isInPlay()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (toTap) {
|
if (toTap) {
|
||||||
tgtC.tap(true, sa, activator);
|
if (tgtC.tap(true, sa, activator)) tapped.add(tgtC);
|
||||||
} else {
|
} else {
|
||||||
tgtC.untap(true);
|
tgtC.untap(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.player.PlayerController;
|
import forge.game.player.PlayerController;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.util.CardTranslation;
|
import forge.util.CardTranslation;
|
||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class TapOrUntapEffect extends SpellAbilityEffect {
|
public class TapOrUntapEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -32,6 +37,7 @@ public class TapOrUntapEffect extends SpellAbilityEffect {
|
|||||||
Player activator = sa.getActivatingPlayer();
|
Player activator = sa.getActivatingPlayer();
|
||||||
PlayerController pc = activator.getController();
|
PlayerController pc = activator.getController();
|
||||||
|
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card tgtC : getTargetCards(sa)) {
|
for (final Card tgtC : getTargetCards(sa)) {
|
||||||
if (!tgtC.isInPlay()) {
|
if (!tgtC.isInPlay()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -50,11 +56,16 @@ public class TapOrUntapEffect extends SpellAbilityEffect {
|
|||||||
tapper = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Tapper"), sa).getFirst();
|
tapper = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Tapper"), sa).getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
tgtC.tap(true, sa, tapper);
|
if (tgtC.tap(true, sa, tapper)) tapped.add(tgtC);
|
||||||
} else {
|
} else {
|
||||||
tgtC.untap(true);
|
tgtC.untap(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
activator.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4439,11 +4439,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
view.updateTapped(this);
|
view.updateTapped(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void tap(boolean tapAnimation, SpellAbility cause, Player tapper) {
|
public final boolean tap(boolean tapAnimation, SpellAbility cause, Player tapper) {
|
||||||
tap(false, tapAnimation, cause, tapper);
|
return tap(false, tapAnimation, cause, tapper);
|
||||||
}
|
}
|
||||||
public final void tap(boolean attacker, boolean tapAnimation, SpellAbility cause, Player tapper) {
|
public final boolean tap(boolean attacker, boolean tapAnimation, SpellAbility cause, Player tapper) {
|
||||||
if (tapped) { return; }
|
if (tapped) { return false; }
|
||||||
|
|
||||||
// Run replacement effects
|
// Run replacement effects
|
||||||
getGame().getReplacementHandler().run(ReplacementType.Tap, AbilityKey.mapFromAffected(this));
|
getGame().getReplacementHandler().run(ReplacementType.Tap, AbilityKey.mapFromAffected(this));
|
||||||
@@ -4458,6 +4458,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
setTapped(true);
|
setTapped(true);
|
||||||
view.updateNeedsTapAnimation(tapAnimation);
|
view.updateNeedsTapAnimation(tapAnimation);
|
||||||
getGame().fireEvent(new GameEventCardTapped(this, true));
|
getGame().fireEvent(new GameEventCardTapped(this, true));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void untap(boolean untapAnimation) {
|
public final void untap(boolean untapAnimation) {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
@@ -279,26 +281,36 @@ public class CostAdjustment {
|
|||||||
// GetSpellCostChange
|
// GetSpellCostChange
|
||||||
|
|
||||||
private static void adjustCostByConvokeOrImprovise(ManaCostBeingPaid cost, final SpellAbility sa, boolean improvise, boolean test) {
|
private static void adjustCostByConvokeOrImprovise(ManaCostBeingPaid cost, final SpellAbility sa, boolean improvise, boolean test) {
|
||||||
CardCollectionView untappedCards = CardLists.filter(sa.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.UNTAPPED);
|
final Player activator = sa.getActivatingPlayer();
|
||||||
|
CardCollectionView untappedCards = CardLists.filter(activator.getCardsIn(ZoneType.Battlefield),
|
||||||
|
CardPredicates.Presets.UNTAPPED);
|
||||||
if (improvise) {
|
if (improvise) {
|
||||||
untappedCards = CardLists.filter(untappedCards, CardPredicates.Presets.ARTIFACTS);
|
untappedCards = CardLists.filter(untappedCards, CardPredicates.Presets.ARTIFACTS);
|
||||||
} else {
|
} else {
|
||||||
untappedCards = CardLists.filter(untappedCards, CardPredicates.Presets.CREATURES);
|
untappedCards = CardLists.filter(untappedCards, CardPredicates.Presets.CREATURES);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Card, ManaCostShard> convokedCards = sa.getActivatingPlayer().getController().chooseCardsForConvokeOrImprovise(sa, cost.toManaCost(), untappedCards, improvise);
|
Map<Card, ManaCostShard> convokedCards = activator.getController().chooseCardsForConvokeOrImprovise(sa,
|
||||||
|
cost.toManaCost(), untappedCards, improvise);
|
||||||
|
|
||||||
// Convoked creats are tapped here, setting up their taps triggers,
|
// Convoked creats are tapped here, setting up their taps triggers,
|
||||||
// Then again when payment is done(In InputPayManaCost.done()) with suppression of Taps triggers.
|
// Then again when payment is done(In InputPayManaCost.done()) with suppression of Taps triggers.
|
||||||
// This is to make sure that triggers go off at the right time
|
// This is to make sure that triggers go off at the right time
|
||||||
// AND that you can't use mana tapabilities of convoked creatures to pay the convoked cost.
|
// AND that you can't use mana tapabilities of convoked creatures to pay the convoked cost.
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Entry<Card, ManaCostShard> conv : convokedCards.entrySet()) {
|
for (final Entry<Card, ManaCostShard> conv : convokedCards.entrySet()) {
|
||||||
sa.addTappedForConvoke(conv.getKey());
|
Card c = conv.getKey();
|
||||||
|
sa.addTappedForConvoke(c);
|
||||||
cost.decreaseShard(conv.getValue(), 1);
|
cost.decreaseShard(conv.getValue(), 1);
|
||||||
if (!test) {
|
if (!test) {
|
||||||
conv.getKey().tap(true, sa, sa.getActivatingPlayer());
|
if (c.tap(true, sa, activator)) tapped.add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
activator.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void adjustCostByOffering(final ManaCostBeingPaid cost, final SpellAbility sa) {
|
private static void adjustCostByOffering(final ManaCostBeingPaid cost, final SpellAbility sa) {
|
||||||
|
|||||||
@@ -74,7 +74,12 @@ public class CostEnlist extends CostPartWithTrigger {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Card doPayment(Player payer, SpellAbility ability, Card targetCard, final boolean effect) {
|
protected Card doPayment(Player payer, SpellAbility ability, Card targetCard, final boolean effect) {
|
||||||
targetCard.tap(true, ability, payer);
|
if (targetCard.tap(true, ability, payer)) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, new CardCollection(targetCard));
|
||||||
|
payer.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
|
|
||||||
// need to transfer info
|
// need to transfer info
|
||||||
payTrig.addRemembered(targetCard);
|
payTrig.addRemembered(targetCard);
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,14 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostTap.
|
* The Class CostTap.
|
||||||
@@ -66,7 +71,12 @@ public class CostTap extends CostPart {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean payAsDecided(Player payer, PaymentDecision decision, SpellAbility ability, final boolean effect) {
|
public boolean payAsDecided(Player payer, PaymentDecision decision, SpellAbility ability, final boolean effect) {
|
||||||
ability.getHostCard().tap(true, ability, payer);
|
Card hostCard = ability.getHostCard();
|
||||||
|
if (hostCard.tap(true, ability, payer)) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, new CardCollection(hostCard));
|
||||||
|
payer.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,17 +18,18 @@
|
|||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.game.card.Card;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.*;
|
||||||
import forge.game.card.CardLists;
|
|
||||||
import forge.game.card.CardPredicates;
|
|
||||||
import forge.game.card.CardPredicates.Presets;
|
import forge.game.card.CardPredicates.Presets;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Lang;
|
import forge.util.Lang;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostTapType.
|
* The Class CostTapType.
|
||||||
*/
|
*/
|
||||||
@@ -200,6 +201,24 @@ public class CostTapType extends CostPartWithList {
|
|||||||
return targetCard;
|
return targetCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canPayListAtOnce() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CardCollectionView doListPayment(Player payer, SpellAbility ability, CardCollectionView targetCards, final boolean effect) {
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
|
for (Card c : targetCards) {
|
||||||
|
if (c.tap(true, ability, payer)) tapped.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
payer.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
return targetCards;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#getHashForList()
|
* @see forge.card.cost.CostPartWithList#getHashForList()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -609,12 +609,18 @@ public class PhaseHandler implements java.io.Serializable {
|
|||||||
|
|
||||||
} while (!success);
|
} while (!success);
|
||||||
|
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card attacker : combat.getAttackers()) {
|
for (final Card attacker : combat.getAttackers()) {
|
||||||
if (!attacker.attackVigilance()) {
|
if (!attacker.attackVigilance()) {
|
||||||
attacker.setTapped(false);
|
attacker.setTapped(false);
|
||||||
attacker.tap(true, true, null, null);
|
if (attacker.tap(true, true, null, null)) tapped.add(attacker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
whoDeclares.getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.isGameOver()) { // they just like to close window at any moment
|
if (game.isGameOver()) { // they just like to close window at any moment
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package forge.game.trigger;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.util.Localizer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TriggerTapAll extends Trigger {
|
||||||
|
|
||||||
|
public TriggerTapAll(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||||
|
super(params, host, intrinsic);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
||||||
|
return matchesValidParam("ValidCards", runParams.get(AbilityKey.Cards));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
|
Iterable<Card> cards = (Iterable<Card>) runParams.get(AbilityKey.Cards);
|
||||||
|
if (hasParam("ValidCards")) {
|
||||||
|
cards = Iterables.filter(cards, CardPredicates.restriction(getParam("ValidCards").split(","),
|
||||||
|
getHostCard().getController(), getHostCard(), this));
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.setTriggeringObject(AbilityKey.Cards, cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImportantStackObjects(SpellAbility sa) {
|
||||||
|
return Localizer.getInstance().getMessage("lblTapped") + ": " + sa.getTriggeringObject(AbilityKey.Cards);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -119,6 +119,7 @@ public enum TriggerType {
|
|||||||
SpellCopy(TriggerSpellAbilityCastOrCopy.class),
|
SpellCopy(TriggerSpellAbilityCastOrCopy.class),
|
||||||
Surveil(TriggerSurveil.class),
|
Surveil(TriggerSurveil.class),
|
||||||
TakesInitiative(TriggerTakesInitiative.class),
|
TakesInitiative(TriggerTakesInitiative.class),
|
||||||
|
TapAll(TriggerTapAll.class),
|
||||||
Taps(TriggerTaps.class),
|
Taps(TriggerTaps.class),
|
||||||
TapsForMana(TriggerTapsForMana.class),
|
TapsForMana(TriggerTapsForMana.class),
|
||||||
TokenCreated(TriggerTokenCreated.class),
|
TokenCreated(TriggerTokenCreated.class),
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ Types:Creature Zombie Giant
|
|||||||
PT:4/4
|
PT:4/4
|
||||||
A:AB$ ChangeZone | Cost$ tapXType<3/Cleric> | Origin$ Graveyard | Destination$ Hand | ActivationZone$ Graveyard | SpellDescription$ Return CARDNAME from your graveyard to your hand.
|
A:AB$ ChangeZone | Cost$ tapXType<3/Cleric> | Origin$ Graveyard | Destination$ Hand | ActivationZone$ Graveyard | SpellDescription$ Return CARDNAME from your graveyard to your hand.
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
|
DeckNeeds:Type$Cleric
|
||||||
Oracle:Tap three untapped Clerics you control: Return Gangrenous Goliath from your graveyard to your hand.
|
Oracle:Tap three untapped Clerics you control: Return Gangrenous Goliath from your graveyard to your hand.
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Deeproot Pilgrimage
|
||||||
|
ManaCost:1 U
|
||||||
|
Types:Enchantment
|
||||||
|
T:Mode$ TapAll | ValidCards$ Merfolk.nonToken+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever one or more nontoken Merfolk you control become tapped, create a 1/1 blue Merfolk creature token with hexproof.
|
||||||
|
SVar:TrigToken:DB$ Token | TokenScript$ u_1_1_merfolk_hexproof
|
||||||
|
DeckHas:Ability$Token & Type$Merfolk
|
||||||
|
AI:RemoveDeck:Random
|
||||||
|
DeckNeeds:Type$Merfolk
|
||||||
|
Oracle:Whenever one or more nontoken Merfolk you control become tapped, create a 1/1 blue Merfolk creature token with hexproof.
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Succumb to the Cold
|
Name:Succumb to the Cold
|
||||||
ManaCost:2 U
|
ManaCost:2 U
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Tap | ValidTgts$ Creature.OppCtrl | SubAbility$ DBCounter | TargetMin$ 1 | TargetMax$ 2 | TgtPrompt$ Select one or two target creatures an opponent controls | SpellDescription$ Tap one or two target creatures an opponent controls. Put a stun counter on each of them. (If a permanent with a stun counter would become untapped, remove one from it instead.)
|
A:SP$ Tap | ValidTgts$ Creature.OppCtrl | SubAbility$ DBCounter | TargetMin$ 1 | TargetMax$ 2 | TgtPrompt$ Select one or two target creatures an opponent controls | SpellDescription$ Tap one or two target creatures an opponent controls.
|
||||||
SVar:DBCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ Stun | CounterNum$ 1
|
SVar:DBCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ Stun | CounterNum$ 1 | StackDescription$ REP Put_{p:You} puts | SpellDescription$ Put a stun counter on each of them. (If a permanent with a stun counter would become untapped, remove one from it instead.)
|
||||||
DeckHas:Ability$Counters
|
DeckHas:Ability$Counters
|
||||||
Oracle:Tap one or two target creatures an opponent controls. Put a stun counter on each of them. (If a permanent with a stun counter would become untapped, remove one from it instead.)
|
Oracle:Tap one or two target creatures an opponent controls. Put a stun counter on each of them. (If a permanent with a stun counter would become untapped, remove one from it instead.)
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package forge.player;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.cost.*;
|
import forge.game.cost.*;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
@@ -537,13 +539,19 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
if (ability.getTappedForConvoke() != null) {
|
if (ability.getTappedForConvoke() != null) {
|
||||||
game.getTriggerHandler().suppressMode(TriggerType.Taps);
|
game.getTriggerHandler().suppressMode(TriggerType.Taps);
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card c : ability.getTappedForConvoke()) {
|
for (final Card c : ability.getTappedForConvoke()) {
|
||||||
c.setTapped(false);
|
c.setTapped(false);
|
||||||
if (!manaInputCancelled) {
|
if (!manaInputCancelled) {
|
||||||
c.tap(true, ability, ability.getActivatingPlayer());
|
if (c.tap(true, ability, ability.getActivatingPlayer())) tapped.add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
game.getTriggerHandler().clearSuppression(TriggerType.Taps);
|
game.getTriggerHandler().clearSuppression(TriggerType.Taps);
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
|
}
|
||||||
if (manaInputCancelled) {
|
if (manaInputCancelled) {
|
||||||
ability.clearTappedForConvoke();
|
ability.clearTappedForConvoke();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import java.util.Map.Entry;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
import forge.trackable.TrackableCollection;
|
import forge.trackable.TrackableCollection;
|
||||||
import forge.util.ImageUtil;
|
import forge.util.ImageUtil;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
@@ -2628,8 +2629,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
inp.setMessage(localizer.getMessage("lblChoosePermanentstoTap"));
|
inp.setMessage(localizer.getMessage("lblChoosePermanentstoTap"));
|
||||||
inp.showAndWait();
|
inp.showAndWait();
|
||||||
if (!inp.hasCancelled()) {
|
if (!inp.hasCancelled()) {
|
||||||
|
CardCollection tapped = new CardCollection();
|
||||||
for (final Card c : inp.getSelected()) {
|
for (final Card c : inp.getSelected()) {
|
||||||
c.tap(true, null, null);
|
if (c.tap(true, null, null)) tapped.add(c);
|
||||||
|
}
|
||||||
|
if (!tapped.isEmpty()) {
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Cards, tapped);
|
||||||
|
getGame().getTriggerHandler().runTrigger(TriggerType.TapAll, runParams, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user