forked from External/mage
Bestow rework/fixes (#13973)
* New Bestow test, minor improvements * Partially rework Bestow to not rely on perpetual card modifications * Add Bestow subtype tests, improve PrototypeTest * Fix Subtype existing without required card type * Improve docs, improve aura spell copy target copying check, improve subtype handling * Add additional test * Review improvements * Remove subtype/type check * Consolidate temporary becomeAura into function * Add Enchant Creature ability
This commit is contained in:
parent
95f53fc671
commit
8cd1bec19d
8 changed files with 248 additions and 166 deletions
|
|
@ -20,7 +20,6 @@ import mage.game.MageObjectAttribute;
|
|||
import mage.game.events.CopiedStackObjectEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
|
@ -335,45 +334,39 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
counter(null, /*this.getSpellAbility()*/ game);
|
||||
return false;
|
||||
} else if (this.isEnchantment(game) && this.hasSubtype(SubType.AURA, game)) {
|
||||
boolean bestow = SpellAbilityCastMode.BESTOW.equals(ability.getSpellAbilityCastMode());
|
||||
if (ability.getTargets().stillLegal(ability, game)) {
|
||||
boolean bestow = SpellAbilityCastMode.BESTOW.equals(ability.getSpellAbilityCastMode());
|
||||
if (bestow) {
|
||||
// before put to play:
|
||||
// Must be removed first time, after that will be removed by continous effect
|
||||
// Otherwise effects like evolve trigger from creature comes into play event
|
||||
card.removeCardType(CardType.CREATURE);
|
||||
card.addSubType(game, SubType.AURA);
|
||||
BestowAbility.becomeAura(game, card);
|
||||
}
|
||||
UUID permId;
|
||||
boolean flag;
|
||||
boolean permanentCreated;
|
||||
if (isCopy()) {
|
||||
Token token = CopyTokenFunction.createTokenCopy(card, game, this);
|
||||
// The token that a resolving copy of a spell becomes isn’t said to have been “created.” (2020-09-25)
|
||||
if (token.putOntoBattlefield(1, game, ability, getControllerId(), false, false, null, null, false)) {
|
||||
permId = token.getLastAddedTokenIds().stream().findFirst().orElse(null);
|
||||
flag = true;
|
||||
permanentCreated = true;
|
||||
} else {
|
||||
permId = null;
|
||||
flag = false;
|
||||
permanentCreated = false;
|
||||
}
|
||||
} else {
|
||||
permId = card.getId();
|
||||
MageObjectReference mor = new MageObjectReference(getSpellAbility());
|
||||
game.storePermanentCostsTags(mor, getSpellAbility());
|
||||
flag = controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null);
|
||||
permanentCreated = controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null);
|
||||
}
|
||||
if (flag) {
|
||||
if (permanentCreated) {
|
||||
if (bestow) {
|
||||
// card will be copied during putOntoBattlefield, so the card of CardPermanent has to be changed
|
||||
// TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities
|
||||
Permanent permanent = game.getPermanent(permId);
|
||||
if (permanent instanceof PermanentCard) {
|
||||
// after put to play:
|
||||
// restore removed stats (see "before put to play" above)
|
||||
permanent.setSpellAbility(ability); // otherwise spell ability without bestow will be set
|
||||
card.addCardType(CardType.CREATURE);
|
||||
card.getSubtype().remove(SubType.AURA);
|
||||
}
|
||||
permanent.setSpellAbility(ability); // otherwise spell ability without bestow will be set
|
||||
// The continuous effect that makes the permanent an aura doesn't apply until after the permanent has already entered,
|
||||
// so it must be modified manually here first. Same root cause as the Blood Moon problem https://github.com/magefree/mage/issues/4202
|
||||
BestowAbility.becomeAura(game, permanent);
|
||||
}
|
||||
if (isCopy()) {
|
||||
Permanent token = game.getPermanent(permId);
|
||||
|
|
@ -381,7 +374,8 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
return false;
|
||||
}
|
||||
for (Ability ability2 : token.getAbilities()) {
|
||||
if (!bestow || ability2 instanceof BestowAbility) {
|
||||
if (ability2 instanceof SpellAbility && ability2.getTargets().size() == 1) {
|
||||
// Copy aura SpellAbility's targets into the new token's SpellAbility
|
||||
ability2.getTargets().get(0).add(ability.getFirstTarget(), game);
|
||||
ability2.getEffects().get(0).apply(game, ability2);
|
||||
return ability2.resolve(game);
|
||||
|
|
@ -391,24 +385,13 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
}
|
||||
return ability.resolve(game);
|
||||
}
|
||||
if (bestow) {
|
||||
card.addCardType(game, CardType.CREATURE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Aura has no legal target and its a bestow enchantment -> Add it to battlefield as creature
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) {
|
||||
if (bestow) {
|
||||
MageObjectReference mor = new MageObjectReference(getSpellAbility());
|
||||
game.storePermanentCostsTags(mor, getSpellAbility());
|
||||
if (controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null)) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent instanceof PermanentCard) {
|
||||
((PermanentCard) permanent).getCard().addCardType(game, CardType.CREATURE);
|
||||
((PermanentCard) permanent).getCard().removeSubType(game, SubType.AURA);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null);
|
||||
} else {
|
||||
//20091005 - 608.2b
|
||||
if (!game.isSimulation()) {
|
||||
|
|
@ -585,10 +568,8 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
return cardTypes;
|
||||
}
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) {
|
||||
List<CardType> cardTypes = new ArrayList<>();
|
||||
cardTypes.addAll(card.getCardType(game));
|
||||
cardTypes.remove(CardType.CREATURE);
|
||||
return cardTypes;
|
||||
Card modifiedCard = this.getSpellAbility().getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(card, this.getSpellAbility(), game);
|
||||
return modifiedCard.getCardType(game);
|
||||
}
|
||||
return card.getCardType(game);
|
||||
}
|
||||
|
|
@ -600,26 +581,19 @@ public class Spell extends StackObjectImpl implements Card {
|
|||
|
||||
@Override
|
||||
public SubTypes getSubtype(Game game) {
|
||||
// Bestow's changes are non-copiable, and must be reapplied
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) {
|
||||
SubTypes subtypes = card.getSubtype(game);
|
||||
if (!subtypes.contains(SubType.AURA)) { // do it only once
|
||||
subtypes.add(SubType.AURA);
|
||||
}
|
||||
return subtypes;
|
||||
Card modifiedCard = this.getSpellAbility().getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(card, this.getSpellAbility(), game);
|
||||
return modifiedCard.getSubtype();
|
||||
}
|
||||
return card.getSubtype(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSubtype(SubType subtype, Game game) {
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) { // workaround for Bestow (don't like it)
|
||||
SubTypes subtypes = card.getSubtype(game);
|
||||
if (!subtypes.contains(SubType.AURA)) { // do it only once
|
||||
subtypes.add(SubType.AURA);
|
||||
}
|
||||
if (subtypes.contains(subtype)) {
|
||||
return true;
|
||||
}
|
||||
if (SpellAbilityCastMode.BESTOW.equals(this.getSpellAbility().getSpellAbilityCastMode())) {
|
||||
Card modifiedCard = this.getSpellAbility().getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(card, this.getSpellAbility(), game);
|
||||
return modifiedCard.hasSubtype(subtype, game);
|
||||
}
|
||||
return card.hasSubtype(subtype, game);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue