mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
PlayTheTopCard improves: added correct usage check, fixed outdated rule texts, Bolas's Citadel simplified (related to #7605);
This commit is contained in:
parent
bfe91ad32b
commit
48e9cc3e07
27 changed files with 182 additions and 182 deletions
|
|
@ -1,9 +1,5 @@
|
|||
package mage.abilities.effects;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.DependencyType;
|
||||
|
|
@ -13,6 +9,11 @@ import mage.constants.SubLayer;
|
|||
import mage.game.Game;
|
||||
import mage.target.targetpointer.TargetPointer;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
|
@ -46,8 +47,6 @@ public interface ContinuousEffect extends Effect {
|
|||
|
||||
SubLayer getSublayer();
|
||||
|
||||
void overrideRuleText(String text);
|
||||
|
||||
List<MageObjectReference> getAffectedObjects();
|
||||
|
||||
Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer);
|
||||
|
|
|
|||
|
|
@ -275,11 +275,6 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
return sublayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overrideRuleText(String text) {
|
||||
this.staticText = text;
|
||||
}
|
||||
|
||||
protected static boolean isCanKill(DynamicValue toughness) {
|
||||
if (toughness instanceof StaticValue) {
|
||||
return toughness.calculate(null, null, null) < 0;
|
||||
|
|
|
|||
|
|
@ -532,7 +532,10 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
|
||||
UUID idToCheck;
|
||||
if (objectToCheck instanceof SplitCardHalf) {
|
||||
if (!type.needPlayCardAbility() && objectToCheck instanceof SplitCardHalf) {
|
||||
// each split side uses own characteristics to check for playing, all other cases must use main card
|
||||
// rules:
|
||||
// 708.4. In every zone except the stack, the characteristics of a split card are those of its two halves combined.
|
||||
idToCheck = ((SplitCardHalf) objectToCheck).getMainCard().getId();
|
||||
} else if (!type.needPlayCardAbility() && objectToCheck instanceof AdventureCardSpell) {
|
||||
// adventure spell uses alternative characteristics for spell/stack, all other cases must use main card
|
||||
|
|
|
|||
|
|
@ -7,34 +7,44 @@ import mage.constants.AsThoughEffectType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
* @author nantuko, JayDi85
|
||||
*/
|
||||
public class PlayTheTopCardEffect extends AsThoughEffectImpl {
|
||||
|
||||
private final FilterCard filter;
|
||||
|
||||
// can play card or can play lands/cast spells, see two modes below
|
||||
private final boolean canPlayCardOnly;
|
||||
|
||||
|
||||
public PlayTheTopCardEffect() {
|
||||
this(StaticFilters.FILTER_CARD);
|
||||
staticText = "You may play lands and cast spells from the top of your library";
|
||||
this(new FilterCard("play lands and cast spells"), false);
|
||||
}
|
||||
|
||||
public PlayTheTopCardEffect(FilterCard filter) {
|
||||
public PlayTheTopCardEffect(FilterCard filter, boolean canPlayCardOnly) {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
this.filter = filter;
|
||||
staticText = "You may " + filter.getMessage() + " from the top of your library";
|
||||
this.canPlayCardOnly = canPlayCardOnly;
|
||||
this.staticText = "You may " + filter.getMessage() + " from the top of your library";
|
||||
|
||||
// verify check: if you see "card" text in the rules then use card mode
|
||||
// (there aren't any real cards after oracle update, but can be added in the future)
|
||||
if (this.canPlayCardOnly != filter.getMessage().toLowerCase(Locale.ENGLISH).contains("card")) {
|
||||
throw new IllegalArgumentException("Wrong usage of card mode settings");
|
||||
}
|
||||
}
|
||||
|
||||
public PlayTheTopCardEffect(final PlayTheTopCardEffect effect) {
|
||||
super(effect);
|
||||
this.filter = effect.filter;
|
||||
this.canPlayCardOnly = effect.canPlayCardOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -49,25 +59,45 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return applies(objectId, null, source, game, affectedControllerId);
|
||||
}
|
||||
// main card and all parts are checks in different calls.
|
||||
// two modes:
|
||||
// * can play cards (must check main card and allows any parts)
|
||||
// * can play lands/spells (must check specific part and allows specific part)
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) {
|
||||
// current card's part
|
||||
Card cardToCheck = game.getCard(objectId);
|
||||
objectId = CardUtil.getMainCardId(game, objectId); // for split cards
|
||||
|
||||
if (cardToCheck != null
|
||||
&& playerId.equals(source.getControllerId())
|
||||
&& cardToCheck.isOwnedBy(source.getControllerId())
|
||||
&& (!cardToCheck.getManaCost().isEmpty() || cardToCheck.isLand())
|
||||
&& filter.match(cardToCheck, source.getSourceId(), source.getControllerId(), game)) {
|
||||
Player player = game.getPlayer(cardToCheck.getOwnerId());
|
||||
|
||||
UUID needCardID = player.getLibrary().getFromTop(game) == null ? null : player.getLibrary().getFromTop(game).getId();
|
||||
return objectId.equals(needCardID);
|
||||
if (cardToCheck == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.canPlayCardOnly) {
|
||||
// check whole card intead part
|
||||
cardToCheck = cardToCheck.getMainCard();
|
||||
}
|
||||
|
||||
// must be you
|
||||
if (!affectedControllerId.equals(source.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must be your card
|
||||
Player player = game.getPlayer(cardToCheck.getOwnerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must be from your library
|
||||
Card topCard = player.getLibrary().getFromTop(game);
|
||||
if (topCard == null || !topCard.getId().equals(cardToCheck.getMainCard().getId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// can't cast without mana cost
|
||||
if (!cardToCheck.isLand() && cardToCheck.getManaCost().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must be correct card
|
||||
return filter.match(cardToCheck, source.getSourceId(), source.getControllerId(), game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.common.FilterLandCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -28,7 +27,7 @@ public class PlayLandsFromGraveyardControllerEffect extends AsThoughEffectImpl {
|
|||
public PlayLandsFromGraveyardControllerEffect(FilterCard filter) {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
this.filter = filter;
|
||||
staticText = "You may play " + filter.getMessage() + " from your graveyard";
|
||||
this.staticText = "You may play " + filter.getMessage() + " from your graveyard";
|
||||
}
|
||||
|
||||
public PlayLandsFromGraveyardControllerEffect(final PlayLandsFromGraveyardControllerEffect effect) {
|
||||
|
|
@ -49,30 +48,35 @@ public class PlayLandsFromGraveyardControllerEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return applies(objectId, null, source, game, affectedControllerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) {
|
||||
// current card's part
|
||||
Card cardToCheck = game.getCard(objectId);
|
||||
objectId = CardUtil.getMainCardId(game, objectId); // for split cards
|
||||
if (cardToCheck == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must be you
|
||||
if (!affectedControllerId.equals(source.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must be your card
|
||||
Player player = game.getPlayer(cardToCheck.getOwnerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UUID needCardId = objectId;
|
||||
// must be from your graveyard
|
||||
UUID needCardId = cardToCheck.getMainCard().getId();
|
||||
if (player.getGraveyard().getCards(game).stream().noneMatch(c -> c.getId().equals(needCardId))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return playerId.equals(source.getControllerId())
|
||||
&& cardToCheck.isOwnedBy(source.getControllerId())
|
||||
&& (!cardToCheck.getManaCost().isEmpty() || cardToCheck.isLand())
|
||||
&& filter.match(cardToCheck, game);
|
||||
// can't cast without mana cost
|
||||
if (!cardToCheck.isLand() && cardToCheck.getManaCost().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must be correct card
|
||||
return filter.match(cardToCheck, source.getSourceId(), source.getControllerId(), game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
|
|
@ -10,20 +8,19 @@ import mage.filter.FilterSpell;
|
|||
import mage.filter.predicate.Predicates;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ProwessAbility extends SpellCastControllerTriggeredAbility {
|
||||
|
||||
private static final FilterSpell filterNonCreatureSpell = new FilterSpell("noncreature spell");
|
||||
private static final FilterSpell filterNonCreatureSpell = new FilterSpell("noncreature spell");
|
||||
|
||||
static {
|
||||
filterNonCreatureSpell.add(Predicates.not(CardType.CREATURE.getPredicate()));
|
||||
}
|
||||
|
||||
public ProwessAbility() {
|
||||
super(new BoostSourceEffect(1,1,Duration.EndOfTurn), false);
|
||||
this.filter = filterNonCreatureSpell;
|
||||
super(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false);
|
||||
this.filter = filterNonCreatureSpell;
|
||||
}
|
||||
|
||||
public ProwessAbility(final ProwessAbility ability) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue