forked from External/mage
rework warp implementation (#13874)
This commit is contained in:
parent
8aafba38b9
commit
cdf23ac18a
3 changed files with 57 additions and 22 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
|
|
@ -17,7 +16,6 @@ import mage.game.permanent.Permanent;
|
|||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -63,11 +61,7 @@ class FullBoreEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent == null
|
||||
|| !game
|
||||
.getPermanentCostsTags()
|
||||
.getOrDefault(new MageObjectReference(permanent, game, -1), Collections.emptyMap())
|
||||
.containsKey(WarpAbility.WARP_ACTIVATION_VALUE_KEY)) {
|
||||
if (permanent == null || !WarpAbility.checkIfPermanentWarped(permanent, game)) {
|
||||
return false;
|
||||
}
|
||||
game.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import mage.MageIdentifier;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||
|
|
@ -10,14 +11,33 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.cards.Card;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.util.CardUtil;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 702.185. Warp
|
||||
* <p>
|
||||
* 702.185a Warp represents two static abilities that function while the card with warp is on the stack,
|
||||
* one of which may create a delayed triggered ability. “Warp [cost]” means
|
||||
* “You may cast this card from your hand by paying [cost] rather than its mana cost” and
|
||||
* “If this spell’s warp cost was paid, exile the permanent this spell becomes at the beginning of the next end step.
|
||||
* Its owner may cast this card after the current turn has ended for as long as it remains exiled.”
|
||||
* Casting a spell for its warp cost follows the rules for paying alternative costs in rules 601.2b and 601.2f–h.
|
||||
* <p>
|
||||
* 702.185b Some effects refer to “warped” cards in exile. A warped card in exile is one
|
||||
* that was exiled by the delayed triggered ability created by a warp ability.
|
||||
* <p>
|
||||
* 702.185c Some effects refer to whether “a spell was warped this turn.”
|
||||
* This means that a spell was cast for its warp cost this turn.
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class WarpAbility extends SpellAbility {
|
||||
|
|
@ -41,6 +61,7 @@ public class WarpAbility extends SpellAbility {
|
|||
this.addCost(new ManaCostsImpl<>(manaString));
|
||||
this.setAdditionalCostsRuleVisible(false);
|
||||
this.allowGraveyard = allowGraveyard;
|
||||
this.addWatcher(new WarpAbilityWatcher());
|
||||
}
|
||||
|
||||
private WarpAbility(final WarpAbility ability) {
|
||||
|
|
@ -48,15 +69,6 @@ public class WarpAbility extends SpellAbility {
|
|||
this.allowGraveyard = ability.allowGraveyard;
|
||||
}
|
||||
|
||||
// The ability sets up a delayed trigger which can't be set up using the cost tag system
|
||||
public static void addDelayedTrigger(SpellAbility spellAbility, Game game) {
|
||||
if (spellAbility instanceof WarpAbility) {
|
||||
game.addDelayedTriggeredAbility(
|
||||
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new WarpExileEffect()), spellAbility
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
switch (game.getState().getZone(getSourceId())) {
|
||||
|
|
@ -104,6 +116,13 @@ public class WarpAbility extends SpellAbility {
|
|||
public static String makeWarpString(UUID playerId) {
|
||||
return playerId + "- Warped";
|
||||
}
|
||||
|
||||
public static boolean checkIfPermanentWarped(Permanent permanent, Game game) {
|
||||
return permanent != null
|
||||
&& game.getPermanentCostsTags()
|
||||
.getOrDefault(new MageObjectReference(permanent, game, -1), Collections.emptyMap())
|
||||
.containsKey(WarpAbility.WARP_ACTIVATION_VALUE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
class WarpExileEffect extends OneShotEffect {
|
||||
|
|
@ -122,8 +141,9 @@ class WarpExileEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
|
||||
WarpExileEffect() {
|
||||
WarpExileEffect(Permanent permanent, Game game) {
|
||||
super(Outcome.Benefit);
|
||||
this.setTargetPointer(new FixedTarget(permanent, game));
|
||||
staticText = "exile this creature if it was cast for its warp cost";
|
||||
}
|
||||
|
||||
|
|
@ -138,9 +158,12 @@ class WarpExileEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent == null || permanent.getZoneChangeCounter(game) != source.getSourceObjectZoneChangeCounter() + 1) {
|
||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(permanent.getOwnerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCardsToExile(
|
||||
|
|
@ -155,3 +178,23 @@ class WarpExileEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class WarpAbilityWatcher extends Watcher {
|
||||
|
||||
WarpAbilityWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() != GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
|
||||
return;
|
||||
}
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (WarpAbility.checkIfPermanentWarped(permanent, game)) {
|
||||
game.addDelayedTriggeredAbility(
|
||||
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new WarpExileEffect(permanent, game)), permanent.getSpellAbility()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import mage.abilities.costs.mana.ManaCosts;
|
|||
import mage.abilities.keyword.BestowAbility;
|
||||
import mage.abilities.keyword.PrototypeAbility;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.abilities.keyword.WarpAbility;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.counters.Counter;
|
||||
|
|
@ -422,7 +421,6 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
} else {
|
||||
MageObjectReference mor = new MageObjectReference(getSpellAbility());
|
||||
game.storePermanentCostsTags(mor, getSpellAbility());
|
||||
WarpAbility.addDelayedTrigger(getSpellAbility(), game);
|
||||
return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue