mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
Improved canActivate support:
* added support of non controller activates in ActivatedManaAbility (mayActivate); * removed custom code from ActivatedManaAbility; * removed custom code from Mana Cache; * added additional comments;
This commit is contained in:
parent
bdeb0dde66
commit
33380f09c2
8 changed files with 33 additions and 29 deletions
|
@ -53,6 +53,7 @@ public class GlimpseTheCosmos extends CardImpl {
|
|||
|
||||
}
|
||||
|
||||
// TODO: card can't use custom SpellAbility, must be reworked to PLAY_FROM_NOT_OWN_HAND_ZONE (example: Worldheart Phoenix)
|
||||
class GlimpseTheCosmosAbility extends SpellAbility {
|
||||
|
||||
private String abilityName;
|
||||
|
@ -74,6 +75,7 @@ class GlimpseTheCosmosAbility extends SpellAbility {
|
|||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
// TODO: miss super.canActivate?
|
||||
Card card = game.getCard(getSourceId());
|
||||
if (card != null) {
|
||||
// Card must be in the graveyard zone
|
||||
|
|
|
@ -11,10 +11,7 @@ import mage.abilities.effects.mana.BasicManaEffect;
|
|||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
|
@ -94,6 +91,7 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
|
|||
super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.ColorlessMana(1), new CountersSourceCount(CounterType.CHARGE)),
|
||||
new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1)));
|
||||
this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 0, 1));
|
||||
this.setMayActivate(TargetController.ANY);
|
||||
}
|
||||
|
||||
public ManaCacheManaAbility(final ManaCacheManaAbility ability) {
|
||||
|
@ -102,17 +100,15 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl {
|
|||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) {
|
||||
// any player, but only during their turn before the end step
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null
|
||||
|| !playerId.equals(game.getActivePlayerId())
|
||||
|| !game.getStep().getType().isBefore(PhaseStep.END_TURN)) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null && playerId.equals(game.getActivePlayerId()) && game.getStep().getType().isBefore(PhaseStep.END_TURN)) {
|
||||
if (costs.canPay(this, this, playerId, game)) {
|
||||
this.setControllerId(playerId);
|
||||
return ActivationStatus.getTrue(this, game);
|
||||
}
|
||||
}
|
||||
return ActivationStatus.getFalse();
|
||||
|
||||
return super.canActivate(playerId, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,6 +53,11 @@ public interface ActivatedAbility extends Ability {
|
|||
*/
|
||||
ActivationStatus canActivate(UUID playerId, Game game); // has to return a reference to the permitting ability/source
|
||||
|
||||
/**
|
||||
* Who can activate an ability. By default, only you (the controller/owner).
|
||||
*
|
||||
* @param mayActivate
|
||||
*/
|
||||
void setMayActivate(TargetController mayActivate);
|
||||
|
||||
/**
|
||||
|
|
|
@ -173,7 +173,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
|
|||
}
|
||||
|
||||
/**
|
||||
* Basic activation check. It contains costs and targets legality too.
|
||||
* Activated ability check, not spells. It contains costs and targets legality too.
|
||||
* <p>
|
||||
* WARNING, don't forget to call super.canActivate on override in card's code in most cases.
|
||||
*
|
||||
|
|
|
@ -25,6 +25,14 @@ public class PlayLandAbility extends ActivatedAbilityImpl {
|
|||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
// 20210723 - 116.2a
|
||||
// Playing a land is a special action. To play a land, a player puts that land onto the battlefield
|
||||
// from the zone it was in (usually that player’s hand). By default, a player can take this action
|
||||
// only once during each of their turns. A player can take this action any time they have priority
|
||||
// and the stack is empty during a main phase of their turn. See rule 305, “Lands.”
|
||||
|
||||
// no super.canActivate() call
|
||||
|
||||
ApprovingObject approvingObject = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this, playerId, game);
|
||||
if (!controlsAbility(playerId, game) && null == approvingObject) {
|
||||
return ActivationStatus.getFalse();
|
||||
|
|
|
@ -87,6 +87,9 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
// spells can be cast from non hand zones, so must use custom check
|
||||
// no super.canActivate() call
|
||||
|
||||
if (this.spellCanBeActivatedRegularlyNow(playerId, game)) {
|
||||
if (spellAbilityType == SpellAbilityType.SPLIT
|
||||
|| spellAbilityType == SpellAbilityType.SPLIT_AFTERMATH) {
|
||||
|
@ -121,7 +124,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
}
|
||||
}
|
||||
|
||||
// can pay all costs
|
||||
// can pay all costs and choose targets
|
||||
if (costs.canPay(this, this, playerId, game)) {
|
||||
if (getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
|
||||
SplitCard splitCard = (SplitCard) game.getCard(getSourceId());
|
||||
|
|
|
@ -42,18 +42,6 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
|
|||
|
||||
@Override
|
||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
if (!controlsAbility(playerId, game)) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
if (timing == TimingRule.SORCERY
|
||||
&& !game.canPlaySorcery(playerId)
|
||||
&& null == game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game)) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
|
||||
// check if player is in the process of playing spell costs and they are no longer allowed to use
|
||||
// activated mana abilities (e.g. because they started to use improvise or convoke)
|
||||
if (!game.getStack().isEmpty()) {
|
||||
|
@ -69,8 +57,7 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
|
|||
}
|
||||
}
|
||||
|
||||
//20091005 - 605.3a
|
||||
return new ActivationStatus(costs.canPay(this, this, controllerId, game), null);
|
||||
return super.canActivate(playerId, game);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3706,6 +3706,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
|
||||
// check the hand zone (Sen Triplets)
|
||||
// TODO: remove direct hand check (reveal fix in Sen Triplets)?
|
||||
// human games: cards from opponent's hand must be revealed before play
|
||||
// AI games: computer can see and play cards from opponent's hand without reveal
|
||||
if (fromAll || fromZone == Zone.HAND) {
|
||||
for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) {
|
||||
Player player = game.getPlayer(playerInRangeId);
|
||||
|
|
Loading…
Reference in a new issue