forked from External/mage
Rework AsThough handling to allow choosing/affecting a specific alternate cast (#11114)
* Rework AsThoughEffect * some cleanup of MageIdentifer * refactor ActivationStatus * fix bolas's citadel * fix a couple of the Alternative Cost being applied too broadly. * fix Risen Executioneer * allow cancellation of AsThough choice. * fix One with the Multiverse * cleanup cards needing their own MageIdentifier * last couple of fixes * apply reviews for cleaner code. * some more cleanup
This commit is contained in:
parent
ba135abc78
commit
7c454fb24c
66 changed files with 1176 additions and 395 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package mage.abilities;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.MageIdentifier;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
|
|
@ -45,6 +46,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
this.spellAbilityType = spellAbilityType;
|
||||
this.spellAbilityCastMode = spellAbilityCastMode;
|
||||
this.addManaCost(cost);
|
||||
this.setIdentifier(MageIdentifier.Default);
|
||||
setSpellName();
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +99,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
}
|
||||
}
|
||||
|
||||
return null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase
|
||||
return !game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game).isEmpty() // check this first to allow Offering in main phase
|
||||
|| timing == TimingRule.INSTANT
|
||||
|| object.isInstant(game)
|
||||
|| object.hasAbility(FlashAbility.getInstance(), game)
|
||||
|
|
@ -116,13 +118,13 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
}
|
||||
|
||||
// play from not own hand
|
||||
ApprovingObject approvingObject = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this, playerId, game);
|
||||
if (approvingObject == null && getSpellAbilityType().equals(SpellAbilityType.ADVENTURE_SPELL)) {
|
||||
Set<ApprovingObject> approvingObjects = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this, playerId, game);
|
||||
if (approvingObjects.isEmpty() && getSpellAbilityType().equals(SpellAbilityType.ADVENTURE_SPELL)) {
|
||||
// allowed to cast adventures from non-hand?
|
||||
approvingObject = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.CAST_ADVENTURE_FROM_NOT_OWN_HAND_ZONE, this, playerId, game);
|
||||
approvingObjects = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.CAST_ADVENTURE_FROM_NOT_OWN_HAND_ZONE, this, playerId, game);
|
||||
}
|
||||
|
||||
if (approvingObject == null) {
|
||||
if (approvingObjects.isEmpty()) {
|
||||
Card card = game.getCard(sourceId);
|
||||
if (!(card != null && card.isOwnedBy(playerId))) {
|
||||
return ActivationStatus.getFalse();
|
||||
|
|
@ -141,12 +143,26 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: this check may not be required, but removing it require more investigation.
|
||||
// As of now it is only a way for One with the Multiverse to work.
|
||||
if (!approvingObjects.isEmpty()) {
|
||||
Card card = game.getCard(sourceId);
|
||||
Zone zone = game.getState().getZone(sourceId);
|
||||
if(card != null && card.isOwnedBy(playerId) && Zone.HAND.match(zone)) {
|
||||
// Regular casting, to be an alternative to the AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE from hand (e.g. One with the Multiverse):
|
||||
approvingObjects.add(new ApprovingObject(this, game));
|
||||
}
|
||||
}
|
||||
|
||||
// no mana restrict
|
||||
// Alternate spell abilities (Flashback, Overload) can't be cast with no mana to pay option
|
||||
if (getSpellAbilityType() == SpellAbilityType.BASE_ALTERNATE) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null
|
||||
&& player.getCastSourceIdWithAlternateMana().contains(getSourceId())) {
|
||||
&& player.getCastSourceIdWithAlternateMana()
|
||||
.getOrDefault(getSourceId(), Collections.emptySet())
|
||||
.contains(MageIdentifier.Default)
|
||||
) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
}
|
||||
|
|
@ -159,13 +175,20 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
// fused can be called from hand only, so not permitting object allows or other zones checks
|
||||
// see https://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/251926-snapcaster-mage-and-fuse
|
||||
if (game.getState().getZone(splitCard.getId()) == Zone.HAND) {
|
||||
return new ActivationStatus(splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game, playerId)
|
||||
&& splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game, playerId), null);
|
||||
return ActivationStatus.withoutApprovingObject(splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game, playerId)
|
||||
&& splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game, playerId));
|
||||
}
|
||||
}
|
||||
return ActivationStatus.getFalse();
|
||||
} else {
|
||||
return new ActivationStatus(canChooseTarget(game, playerId), approvingObject);
|
||||
if(canChooseTarget(game, playerId)) {
|
||||
if(approvingObjects == null || approvingObjects.isEmpty()) {
|
||||
return ActivationStatus.withoutApprovingObject(true);
|
||||
}
|
||||
else {
|
||||
return new ActivationStatus(approvingObjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue