diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 08eff876371..5766f20cc25 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1164,12 +1164,12 @@ public class AbilityUtils { } } else if (defined.startsWith("Enchanted")) { - if (card.getEntityAttachedTo() != null) { + if (card.isAttachedToEntity()) { addPlayer(Lists.newArrayList(card.getEntityAttachedTo()), defined, players); } } else if (defined.startsWith("Equipped")) { - if (card.getEquipping() != null) { + if (card.isEquipping()) { addPlayer(Lists.newArrayList(card.getEquipping()), defined, players); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java index 47788a4544e..b4290864f67 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java @@ -63,7 +63,7 @@ public class LifeExchangeVariantEffect extends SpellAbilityEffect { return; } - if (!source.isInZone(ZoneType.Battlefield)) { + if (!source.isInPlay()) { return; } diff --git a/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java b/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java index 214cf97fb1d..4e9a4fdc4b2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/MustBlockEffect.java @@ -6,6 +6,7 @@ import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import forge.GameCommand; import forge.game.Game; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; @@ -32,7 +33,7 @@ public class MustBlockEffect extends SpellAbilityEffect { cards = Lists.newArrayList(host); } - List tgtCards = Lists.newArrayList(); + final List tgtCards = Lists.newArrayList(); if (sa.hasParam("Choices")) { Player chooser = activator; if (sa.hasParam("Chooser")) { @@ -53,7 +54,7 @@ public class MustBlockEffect extends SpellAbilityEffect { } } } else { - tgtCards = getTargetCards(sa); + tgtCards.addAll(getTargetCards(sa)); } final boolean mustBlockAll = sa.hasParam("BlockAllDefined"); @@ -68,7 +69,26 @@ public class MustBlockEffect extends SpellAbilityEffect { } } } - } // mustBlockResolve() + + if (sa.hasParam("Duration")) { + final GameCommand removeBlockingRequirements = new GameCommand() { + private static final long serialVersionUID = -5861529814760561373L; + + @Override + public void run() { + for (final Card c : tgtCards) { + if (mustBlockAll) { + c.removeMustBlockCards(cards); + } else { + final Card attacker = cards.get(0); + c.removeMustBlockCard(attacker); + } + } + } + }; + addUntilCommand(sa, removeBlockingRequirements); + } + } @Override protected String getStackDescription(SpellAbility sa) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 1301eaf96d3..955aab50c61 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1321,6 +1321,12 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public final void addMustBlockCards(final Iterable attackersToBlock) { mustBlockCards = view.addCards(mustBlockCards, attackersToBlock, TrackableProperty.MustBlockCards); } + public final void removeMustBlockCard(final Card c) { + mustBlockCards = view.removeCard(mustBlockCards, c, TrackableProperty.MustBlockCards); + } + public final void removeMustBlockCards(final Iterable attackersToBlock) { + mustBlockCards = view.removeCards(mustBlockCards, attackersToBlock, TrackableProperty.MustBlockCards); + } public final void clearMustBlockCards() { mustBlockCards = view.clearCards(mustBlockCards, TrackableProperty.MustBlockCards); } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index e3bc93829a9..954bc91b226 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1590,7 +1590,7 @@ public class CardFactoryUtil { } else if (keyword.equals("Provoke")) { final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Secondary$ True" + " | TriggerDescription$ Provoke (" + inst.getReminderText() + ")"; - final String blockStr = "DB$ MustBlock | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target creature defending player controls"; + final String blockStr = "DB$ MustBlock | Duration$ UntilEndOfCombat | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target creature defending player controls"; final String untapStr = "DB$ Untap | Defined$ Targeted"; SpellAbility blockSA = AbilityFactory.getAbility(blockStr, card); diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 7f4a3ed4968..ddecade728c 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -413,7 +413,7 @@ public class CardProperty { } else if (property.startsWith("AttachedTo")) { final String restriction = property.split("AttachedTo ")[1]; - if (card.getEntityAttachedTo() == null) { + if (!card.isAttachedToEntity()) { return false; } diff --git a/forge-gui/res/cardsfolder/a/aether_storm.txt b/forge-gui/res/cardsfolder/a/aether_storm.txt index 5eb5f1e50b0..3ae4003939d 100644 --- a/forge-gui/res/cardsfolder/a/aether_storm.txt +++ b/forge-gui/res/cardsfolder/a/aether_storm.txt @@ -2,6 +2,6 @@ Name:Aether Storm ManaCost:3 U Types:Enchantment S:Mode$ CantBeCast | ValidCard$ Creature | Description$ Creature spells can't be cast. -A:AB$ Destroy | Cost$ PayLife<4> | Defined$ Self | NoReg$ True | Activator$ Player | SpellDescription$ Destroy CARDNAME. It can't be regenerated. Any player may activate this ability. +A:AB$ Destroy | Cost$ PayLife<4> | Defined$ Self | NoRegen$ True | Activator$ Player | SpellDescription$ Destroy CARDNAME. It can't be regenerated. Any player may activate this ability. AI:RemoveDeck:All Oracle:Creature spells can't be cast.\nPay 4 life: Destroy Aether Storm. It can't be regenerated. Any player may activate this ability. diff --git a/forge-gui/res/cardsfolder/a/avalanche_tusker.txt b/forge-gui/res/cardsfolder/a/avalanche_tusker.txt index 11379e6a6ef..f5dbe4b1c69 100644 --- a/forge-gui/res/cardsfolder/a/avalanche_tusker.txt +++ b/forge-gui/res/cardsfolder/a/avalanche_tusker.txt @@ -3,5 +3,5 @@ ManaCost:2 G U R Types:Creature Elephant Warrior PT:6/4 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCantBlock | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, target creature defending player controls blocks it this combat if able. -SVar:TrigCantBlock:DB$ MustBlock | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able. +SVar:TrigCantBlock:DB$ MustBlock | Duration$ UntilEndOfCombat | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able. Oracle:Whenever Avalanche Tusker attacks, target creature defending player controls blocks it this combat if able. diff --git a/forge-gui/res/cardsfolder/f/fighter_class.txt b/forge-gui/res/cardsfolder/f/fighter_class.txt index 24c08394460..4b42ac8faf0 100644 --- a/forge-gui/res/cardsfolder/f/fighter_class.txt +++ b/forge-gui/res/cardsfolder/f/fighter_class.txt @@ -7,5 +7,5 @@ K:Class:2:1 R W:AddStaticAbility$ SReduceCost SVar:SReduceCost:Mode$ ReduceCost | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 2 | Secondary$ True | Description$ Equip abilities you activate cost {2} less to activate. K:Class:3:3 R W:AddTrigger$ TriggerAttacks SVar:TriggerAttacks:Mode$ Attacks | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigMustBlock | Secondary$ True | TriggerDescription$ Whenever a creature you control attacks, up to one target creature blocks it this combat if able. -SVar:TrigMustBlock:DB$ MustBlock | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 1 | DefinedAttacker$ TriggeredAttacker | BlockAllDefined$ True +SVar:TrigMustBlock:DB$ MustBlock | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 1 | DefinedAttacker$ TriggeredAttacker | BlockAllDefined$ True | Duration$ UntilEndOfCombat Oracle:(Gain the next level as a sorcery to add its ability.)\nWhen Fighter Class enters the battlefield, search your library for an Equipment card, reveal it, put it into your hand, then shuffle.\n{1}{R}{W}: Level 2\nEquip abilities you activate cost {2} less to activate.\n{3}{R}{W}: Level 3\nWhenever a creature you control attacks, up to one target creature blocks it this combat if able. diff --git a/forge-gui/res/cardsfolder/i/impetuous_devils.txt b/forge-gui/res/cardsfolder/i/impetuous_devils.txt index e0f8673e432..372d56030c9 100644 --- a/forge-gui/res/cardsfolder/i/impetuous_devils.txt +++ b/forge-gui/res/cardsfolder/i/impetuous_devils.txt @@ -5,7 +5,7 @@ PT:6/1 K:Haste K:Trample T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigProvoke | TriggerDescription$ When CARDNAME attacks, up to one target creature defending player controls blocks it this combat if able. -SVar:TrigProvoke:DB$ MustBlock | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select up to one target creature defending player controls +SVar:TrigProvoke:DB$ MustBlock | Duration$ UntilEndOfCombat | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select up to one target creature defending player controls T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of the end step, sacrifice CARDNAME. SVar:TrigSac:DB$ Sacrifice | SacValid$ Self SVar:EndOfTurnLeavePlay:True