Implemented Capricopian

This commit is contained in:
Evan Kranzler 2020-04-21 17:34:18 -04:00
parent 332da23746
commit fde0873895
3 changed files with 184 additions and 76 deletions

View file

@ -0,0 +1,127 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPlayer;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.other.PlayerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Capricopian extends CardImpl {
public Capricopian(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{G}");
this.subtype.add(SubType.GOAT);
this.subtype.add(SubType.HYDRA);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Capricopian enters the battlefield with X +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(
new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance())
));
// {2}: Put a +1/+1 counter on Capricopian, then you may reselect which player Capricopian is attacking. Only the player Capricopian is attacking may activate this ability and only during the declare attackers step.
this.addAbility(new CapricopianActivatedAbility());
}
private Capricopian(final Capricopian card) {
super(card);
}
@Override
public Capricopian copy() {
return new Capricopian(this);
}
}
class CapricopianActivatedAbility extends ActivatedAbilityImpl {
CapricopianActivatedAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2));
this.addEffect(new CapricopianEffect());
this.setMayActivate(TargetController.ANY);
this.condition = new IsStepCondition(PhaseStep.DECLARE_ATTACKERS);
}
private CapricopianActivatedAbility(final CapricopianActivatedAbility ability) {
super(ability);
}
@Override
public CapricopianActivatedAbility copy() {
return new CapricopianActivatedAbility(this);
}
@Override
public String getRule() {
return "{2}: Put a +1/+1 counter on {this}, then you may reselect which player {this} is attacking. " +
"Only the player {this} is attacking may activate this ability " +
"and only during the declare attackers step. <i>(It cant attack its controller.)</i>";
}
@Override
protected boolean checkTargetController(UUID playerId, Game game) {
return super.checkTargetController(playerId, game)
&& playerId != null
&& playerId.equals(game.getCombat().getDefenderId(this.getSourceId()));
}
}
class CapricopianEffect extends OneShotEffect {
CapricopianEffect() {
super(Outcome.Benefit);
}
private CapricopianEffect(final CapricopianEffect effect) {
super(effect);
}
@Override
public CapricopianEffect copy() {
return new CapricopianEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player == null || permanent == null) {
return false;
}
if (!player.chooseUse(outcome, "Reselect attacker for " + permanent.getIdName() + "?", source, game)) {
return false;
}
FilterPlayer filterPlayer = new FilterPlayer();
filterPlayer.add(Predicates.not(new PlayerIdPredicate(permanent.getControllerId())));
filterPlayer.add(Predicates.not(new PlayerIdPredicate(game.getCombat().getDefenderId(permanent.getId()))));
TargetPlayer targetPlayer = new TargetPlayer(0, 1, true, filterPlayer);
player.choose(outcome, targetPlayer, source.getSourceId(), game);
Player newPlayer = game.getPlayer(targetPlayer.getFirstTarget());
if (newPlayer == null) {
return false;
}
return game.getCombat().addAttackingCreature(permanent.getId(), game, newPlayer.getId());
}
}

View file

@ -67,6 +67,7 @@ public final class Commander2020Edition extends ExpansionSet {
cards.add(new SetCardInfo("Cairn Wanderer", 130, Rarity.RARE, mage.cards.c.CairnWanderer.class)); cards.add(new SetCardInfo("Cairn Wanderer", 130, Rarity.RARE, mage.cards.c.CairnWanderer.class));
cards.add(new SetCardInfo("Call the Coppercoats", 23, Rarity.RARE, mage.cards.c.CallTheCoppercoats.class)); cards.add(new SetCardInfo("Call the Coppercoats", 23, Rarity.RARE, mage.cards.c.CallTheCoppercoats.class));
cards.add(new SetCardInfo("Canopy Vista", 261, Rarity.RARE, mage.cards.c.CanopyVista.class)); cards.add(new SetCardInfo("Canopy Vista", 261, Rarity.RARE, mage.cards.c.CanopyVista.class));
cards.add(new SetCardInfo("Capricopian", 58, Rarity.RARE, mage.cards.c.Capricopian.class));
cards.add(new SetCardInfo("Captivating Crew", 144, Rarity.RARE, mage.cards.c.CaptivatingCrew.class)); cards.add(new SetCardInfo("Captivating Crew", 144, Rarity.RARE, mage.cards.c.CaptivatingCrew.class));
cards.add(new SetCardInfo("Cartographer's Hawk", 24, Rarity.RARE, mage.cards.c.CartographersHawk.class)); cards.add(new SetCardInfo("Cartographer's Hawk", 24, Rarity.RARE, mage.cards.c.CartographersHawk.class));
cards.add(new SetCardInfo("Cast Out", 79, Rarity.UNCOMMON, mage.cards.c.CastOut.class)); cards.add(new SetCardInfo("Cast Out", 79, Rarity.UNCOMMON, mage.cards.c.CastOut.class));

View file

@ -1,6 +1,5 @@
package mage.abilities; package mage.abilities;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
@ -12,11 +11,7 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
import mage.abilities.mana.ManaOptions; import mage.abilities.mana.ManaOptions;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.AbilityType; import mage.constants.*;
import mage.constants.AsThoughEffectType;
import mage.constants.TargetController;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.command.Commander; import mage.game.command.Commander;
import mage.game.command.Emblem; import mage.game.command.Emblem;
@ -24,8 +19,9 @@ import mage.game.command.Plane;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public abstract class ActivatedAbilityImpl extends AbilityImpl implements ActivatedAbility { public abstract class ActivatedAbilityImpl extends AbilityImpl implements ActivatedAbility {
@ -148,6 +144,34 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
@Override @Override
public abstract ActivatedAbilityImpl copy(); public abstract ActivatedAbilityImpl copy();
protected boolean checkTargetController(UUID playerId, Game game) {
switch (mayActivate) {
case ANY:
return true;
case ACTIVE:
return game.getActivePlayerId() == playerId;
case NOT_YOU:
return !controlsAbility(playerId, game);
case TEAM:
return !game.getPlayer(controllerId).hasOpponent(playerId, game);
case OPPONENT:
return game.getPlayer(controllerId).hasOpponent(playerId, game);
case OWNER:
Permanent permanent = game.getPermanent(getSourceId());
return permanent != null && permanent.isOwnedBy(playerId);
case YOU:
return controlsAbility(playerId, game);
case CONTROLLER_ATTACHED_TO:
Permanent enchantment = game.getPermanent(getSourceId());
if (enchantment == null || enchantment.getAttachedTo() == null) {
return false;
}
Permanent enchanted = game.getPermanent(enchantment.getAttachedTo());
return enchanted != null && enchanted.isControlledBy(playerId);
}
return true;
}
@Override @Override
public ActivationStatus canActivate(UUID playerId, Game game) { public ActivationStatus canActivate(UUID playerId, Game game) {
//20091005 - 602.2 //20091005 - 602.2
@ -156,48 +180,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
|| condition.apply(game, this)))) { || condition.apply(game, this)))) {
return ActivationStatus.getFalse(); return ActivationStatus.getFalse();
} }
switch (mayActivate) { if (!this.checkTargetController(playerId, game)) {
case ANY:
break;
case ACTIVE:
if (game.getActivePlayerId() != playerId) {
return ActivationStatus.getFalse();
}
break;
case NOT_YOU:
if (controlsAbility(playerId, game)) {
return ActivationStatus.getFalse();
}
break;
case TEAM:
if (game.getPlayer(controllerId).hasOpponent(playerId, game)) {
return ActivationStatus.getFalse();
}
break;
case OPPONENT:
if (!game.getPlayer(controllerId).hasOpponent(playerId, game)) {
return ActivationStatus.getFalse();
}
break;
case OWNER:
Permanent permanent = game.getPermanent(getSourceId());
if (!permanent.isOwnedBy(playerId)) {
return ActivationStatus.getFalse();
}
break;
case YOU:
if (!controlsAbility(playerId, game)) {
return ActivationStatus.getFalse();
}
break;
case CONTROLLER_ATTACHED_TO:
Permanent enchantment = game.getPermanent(getSourceId());
if (enchantment != null && enchantment.getAttachedTo() != null) {
Permanent enchanted = game.getPermanent(enchantment.getAttachedTo());
if (enchanted != null && enchanted.isControlledBy(playerId)) {
break;
}
}
return ActivationStatus.getFalse(); return ActivationStatus.getFalse();
} }
//20091005 - 602.5d/602.5e //20091005 - 602.5d/602.5e
@ -227,7 +210,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
protected boolean controlsAbility(UUID playerId, Game game) { protected boolean controlsAbility(UUID playerId, Game game) {
if (this.controllerId != null && this.controllerId.equals(playerId)) { if (this.controllerId != null && this.controllerId.equals(playerId)) {
return true; return true;
} else { }
MageObject mageObject = game.getObject(this.sourceId); MageObject mageObject = game.getObject(this.sourceId);
if (mageObject instanceof Emblem) { if (mageObject instanceof Emblem) {
return ((Emblem) mageObject).isControlledBy(playerId); return ((Emblem) mageObject).isControlledBy(playerId);
@ -238,7 +221,6 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
} else if (game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) { } else if (game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) {
return ((Card) mageObject).isOwnedBy(playerId); return ((Card) mageObject).isOwnedBy(playerId);
} }
}
return false; return false;
} }
@ -271,8 +253,9 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
@Override @Override
public boolean activate(Game game, boolean noMana) { public boolean activate(Game game, boolean noMana) {
if (hasMoreActivationsThisTurn(game)) { if (!hasMoreActivationsThisTurn(game) || !super.activate(game, noMana)) {
if (super.activate(game, noMana)) { return false;
}
ActivationInfo activationInfo = getActivationInfo(game); ActivationInfo activationInfo = getActivationInfo(game);
if (activationInfo == null) { if (activationInfo == null) {
activationInfo = new ActivationInfo(game.getTurnNum(), 1); activationInfo = new ActivationInfo(game.getTurnNum(), 1);
@ -285,9 +268,6 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
setActivationInfo(activationInfo, game); setActivationInfo(activationInfo, game);
return true; return true;
} }
}
return false;
}
@Override @Override
public void setMaxActivationsPerTurn(int maxActivationsPerTurn) { public void setMaxActivationsPerTurn(int maxActivationsPerTurn) {