mirror of
https://github.com/magefree/mage.git
synced 2025-12-27 22:12:03 -08:00
Merge branch 'master' into Battlebond_Boos
This commit is contained in:
commit
197020b162
1466 changed files with 18523 additions and 4276 deletions
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -24,6 +23,11 @@ public class MageObjectReference implements Comparable<MageObjectReference>, Ser
|
|||
private final int zoneChangeCounter;
|
||||
|
||||
public MageObjectReference(MageObject mageObject, Game game) {
|
||||
if (mageObject == null) {
|
||||
this.sourceId = null;
|
||||
this.zoneChangeCounter = -1;
|
||||
return;
|
||||
}
|
||||
this.sourceId = mageObject.getId();
|
||||
this.zoneChangeCounter = mageObject.getZoneChangeCounter(game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1051,7 +1051,8 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
|
||||
/**
|
||||
* Returns if this {@link Mana} object has more than or equal values of mana
|
||||
* as the passed in {@link Mana} object.
|
||||
* as the passed in {@link Mana} object. Ignores {Any} mana to prevent
|
||||
* endless iterations.
|
||||
*
|
||||
* @param mana the mana to compare with
|
||||
* @return if this object has more than or equal mana to the passed in
|
||||
|
|
@ -1090,13 +1091,44 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
moreMana = mana1;
|
||||
lessMana = mana2;
|
||||
}
|
||||
if (lessMana.getWhite() > moreMana.getWhite()
|
||||
|| lessMana.getRed() > moreMana.getRed()
|
||||
|| lessMana.getGreen() > moreMana.getGreen()
|
||||
|| lessMana.getBlue() > moreMana.getBlue()
|
||||
|| lessMana.getBlack() > moreMana.getBlack()
|
||||
|| lessMana.getColorless() > moreMana.getColorless()
|
||||
|| lessMana.getAny() > moreMana.getAny()) {
|
||||
int anyDiff = mana2.getAny() - mana1.getAny();
|
||||
if (lessMana.getWhite() > moreMana.getWhite()) {
|
||||
anyDiff -= lessMana.getWhite() - moreMana.getWhite();
|
||||
if (anyDiff < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (lessMana.getRed() > moreMana.getRed()) {
|
||||
anyDiff -= lessMana.getRed() - moreMana.getRed();
|
||||
if (anyDiff < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (lessMana.getGreen() > moreMana.getGreen()) {
|
||||
anyDiff -= lessMana.getGreen() - moreMana.getGreen();
|
||||
if (anyDiff < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (lessMana.getBlue() > moreMana.getBlue()) {
|
||||
anyDiff -= lessMana.getBlue() - moreMana.getBlue();
|
||||
if (anyDiff < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (lessMana.getBlack() > moreMana.getBlack()) {
|
||||
anyDiff -= lessMana.getBlack() - moreMana.getBlack();
|
||||
if (anyDiff < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (lessMana.getColorless() > moreMana.getColorless()) {
|
||||
anyDiff -= lessMana.getColorless() - moreMana.getColorless();
|
||||
if (anyDiff < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (lessMana.getAny() > moreMana.getAny()) {
|
||||
return null;
|
||||
}
|
||||
return moreMana;
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
}
|
||||
MageObject object = game.getObject(this.getSourceId());
|
||||
// emblem/planes are always actual
|
||||
if (object != null && (object instanceof Emblem || object instanceof Plane)) {
|
||||
if (object instanceof Emblem || object instanceof Plane) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
|
|||
break;
|
||||
case OWNER:
|
||||
Permanent permanent = game.getPermanent(getSourceId());
|
||||
if (!permanent.getOwnerId().equals(playerId)) {
|
||||
if (!permanent.isOwnedBy(playerId)) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
break;
|
||||
|
|
@ -191,7 +191,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
|
|||
Permanent enchantment = game.getPermanent(getSourceId());
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null) {
|
||||
Permanent enchanted = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (enchanted != null && enchanted.getControllerId().equals(playerId)) {
|
||||
if (enchanted != null && enchanted.isControlledBy(playerId)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa
|
|||
} else if (mageObject instanceof Plane) {
|
||||
return ((Plane) mageObject).getControllerId().equals(playerId);
|
||||
} else if (game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) {
|
||||
return ((Card) mageObject).getOwnerId().equals(playerId);
|
||||
return ((Card) mageObject).isOwnedBy(playerId);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class PlayLandAbility extends ActivatedAbilityImpl {
|
|||
return ActivationStatus.getFalse();
|
||||
}
|
||||
//20091005 - 114.2a
|
||||
return new ActivationStatus(game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject);
|
||||
return new ActivationStatus(game.isActivePlayer(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class SpecialActions extends AbilitiesImpl<SpecialAction> {
|
|||
public LinkedHashMap<UUID, SpecialAction> getControlledBy(UUID controllerId, boolean manaAction) {
|
||||
LinkedHashMap<UUID, SpecialAction> controlledBy = new LinkedHashMap<>();
|
||||
for (SpecialAction action: this) {
|
||||
if (action.getControllerId().equals(controllerId) && action.isManaAction() == manaAction) {
|
||||
if (action.isControlledBy(controllerId) && action.isManaAction() == manaAction) {
|
||||
controlledBy.put(action.id, action);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class SpellAbility extends ActivatedAbilityImpl {
|
|||
MageObjectReference permittingSource = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, playerId, game);
|
||||
if (permittingSource == null) {
|
||||
Card card = game.getCard(sourceId);
|
||||
if (!(card != null && card.getOwnerId().equals(playerId))) {
|
||||
if (!(card != null && card.isOwnedBy(playerId))) {
|
||||
return ActivationStatus.getFalse();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class AllyEntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl
|
|||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
EntersTheBattlefieldEvent ebe = (EntersTheBattlefieldEvent) event;
|
||||
return ebe.getTarget().getControllerId().equals(this.controllerId)
|
||||
return ebe.getTarget().isControlledBy(this.controllerId)
|
||||
&& (event.getTargetId().equals(this.getSourceId())
|
||||
|| (ebe.getTarget().hasSubtype(SubType.ALLY, game) && !event.getTargetId().equals(this.getSourceId())));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public class AttackedByCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
|||
UUID defendingPlayer = game.getCombat().getDefendingPlayerId(event.getSourceId(), game);
|
||||
Permanent attackingCreature = game.getPermanent(event.getSourceId());
|
||||
if (filter.match(attackingCreature, game)
|
||||
&& getControllerId().equals(defendingPlayer)
|
||||
&& isControlledBy(defendingPlayer)
|
||||
&& attackingCreature != null) {
|
||||
switch (setTargetPointer) {
|
||||
case PERMANENT:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.common;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -67,7 +66,7 @@ public class AttacksAllTriggeredAbility extends TriggeredAbilityImpl {
|
|||
check = true;
|
||||
} else {
|
||||
Permanent planeswalker = game.getPermanent(event.getTargetId());
|
||||
if (planeswalker != null && planeswalker.isPlaneswalker() && planeswalker.getControllerId().equals(getControllerId())) {
|
||||
if (planeswalker != null && planeswalker.isPlaneswalker() && planeswalker.isControlledBy(getControllerId())) {
|
||||
check = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +101,10 @@ public class AttacksAllTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a " + filter.getMessage() + " attacks" + (attacksYouOrYourPlaneswalker ? " you or a planeswalker you control" : "") + ", " + super.getRule();
|
||||
return "Whenever " + (filter.getMessage().startsWith("an") ? "" : "a ")
|
||||
+ filter.getMessage() + " attacks"
|
||||
+ (attacksYouOrYourPlaneswalker ? " you or a planeswalker you control" : "")
|
||||
+ ", " + super.getRule();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class AttacksAloneTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if(game.getActivePlayerId().equals(this.controllerId) ) {
|
||||
if(game.isActivePlayer(this.controllerId) ) {
|
||||
UUID creatureId = this.getSourceId();
|
||||
if(creatureId != null) {
|
||||
if(game.getCombat().attacksAlone() && Objects.equals(creatureId, game.getCombat().getAttackers().get(0))) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class BecomesMonstrousTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null && permanent.isCreature()
|
||||
&& (permanent.getControllerId().equals(getControllerId()))) {
|
||||
&& (permanent.isControlledBy(getControllerId()))) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl {
|
|||
Permanent attachment = game.getPermanent(sourceId);
|
||||
if (attachment != null && attachment.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||
if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) {
|
||||
if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) {
|
||||
if (getTargets().isEmpty()) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public class BeginningOfEndStepTriggeredAbility extends TriggeredAbilityImpl {
|
|||
Permanent attachment = game.getPermanent(sourceId);
|
||||
if (attachment != null && attachment.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||
if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) {
|
||||
if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) {
|
||||
if (getTargets().isEmpty()) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public class BeginningOfUpkeepTriggeredAbility extends TriggeredAbilityImpl {
|
|||
Permanent attachment = game.getPermanent(sourceId);
|
||||
if (attachment != null && attachment.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||
if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) {
|
||||
if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) {
|
||||
if (setTargetPointer && getTargets().isEmpty()) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North, Loki
|
||||
*/
|
||||
public class BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
protected FilterPermanent filter;
|
||||
protected String rule;
|
||||
|
||||
public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(Effect effect, boolean optional) {
|
||||
this(effect, StaticFilters.FILTER_PERMANENT_CREATURE, optional, null);
|
||||
}
|
||||
|
||||
public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) {
|
||||
this(effect, filter, optional, null);
|
||||
}
|
||||
|
||||
public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional, String rule) {
|
||||
super(Zone.BATTLEFIELD, effect, optional);
|
||||
this.filter = filter;
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(final BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.filter = ability.filter;
|
||||
this.rule = ability.rule;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DECLARED_BLOCKERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
for (CombatGroup group : game.getCombat().getGroups()) {
|
||||
if (group.getAttackers().contains(sourceId)){
|
||||
if (filter == null){
|
||||
return group.getBlocked();
|
||||
}
|
||||
for (UUID uuid : group.getBlockers()){
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(uuid);
|
||||
if (permanent != null && filter.match(permanent, game)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (group.getBlockers().contains(sourceId)){
|
||||
if (filter == null){
|
||||
return true;
|
||||
}
|
||||
for (UUID uuid : group.getAttackers()){
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(uuid);
|
||||
if (permanent != null && filter.match(permanent, game)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
if (rule != null) {
|
||||
return rule;
|
||||
}
|
||||
return "Whenever {this} blocks or becomes blocked by one or more " + (filter != null ? filter.getMessage() : "creatures") + ", " + super.getRule();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility copy() {
|
||||
return new BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ package mage.abilities.common;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -11,8 +12,8 @@ import mage.game.Game;
|
|||
import mage.game.events.DamagedPlayerEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -20,22 +21,25 @@ import mage.game.permanent.Permanent;
|
|||
*/
|
||||
public class ControlledCreaturesDealCombatDamagePlayerTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private boolean madeDamage = false;
|
||||
private Set<UUID> damagedPlayerIds = new HashSet<>();
|
||||
private boolean setTargetPointer;
|
||||
|
||||
public ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(Effect effect) {
|
||||
this(Zone.BATTLEFIELD, effect);
|
||||
}
|
||||
|
||||
public ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(Zone zone, Effect effect) {
|
||||
this(zone, effect, false);
|
||||
}
|
||||
|
||||
public ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(Zone zone, Effect effect, boolean setTargetPointer) {
|
||||
super(zone, effect, false);
|
||||
this.setTargetPointer = setTargetPointer;
|
||||
}
|
||||
|
||||
public ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(final ControlledCreaturesDealCombatDamagePlayerTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.madeDamage = ability.madeDamage;
|
||||
this.damagedPlayerIds = new HashSet<>();
|
||||
this.damagedPlayerIds.addAll(ability.damagedPlayerIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -55,28 +59,19 @@ public class ControlledCreaturesDealCombatDamagePlayerTriggeredAbility extends T
|
|||
if (event.getType() == EventType.DAMAGED_PLAYER) {
|
||||
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
|
||||
Permanent p = game.getPermanent(event.getSourceId());
|
||||
if (damageEvent.isCombatDamage() && p != null && p.getControllerId().equals(this.getControllerId())) {
|
||||
madeDamage = true;
|
||||
if (damageEvent.isCombatDamage() && p != null && p.isControlledBy(this.getControllerId()) && !damagedPlayerIds.contains(event.getPlayerId())) {
|
||||
damagedPlayerIds.add(event.getPlayerId());
|
||||
}
|
||||
}
|
||||
if (event.getType() == EventType.COMBAT_DAMAGE_STEP_PRIORITY) {
|
||||
if (madeDamage) {
|
||||
Set<UUID> damagedPlayersCopy = new HashSet<>();
|
||||
damagedPlayersCopy.addAll(damagedPlayerIds);
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setValue("damagedPlayers", damagedPlayersCopy);
|
||||
if (setTargetPointer) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
}
|
||||
}
|
||||
damagedPlayerIds.clear();
|
||||
madeDamage = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event.getType() == EventType.ZONE_CHANGE && event.getTargetId().equals(getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.GRAVEYARD) {
|
||||
damagedPlayerIds.clear();
|
||||
}
|
||||
if (event.getType() == EventType.COMBAT_DAMAGE_STEP_PRIORITY ||
|
||||
(event.getType() == EventType.ZONE_CHANGE && event.getTargetId().equals(getSourceId()))) {
|
||||
damagedPlayerIds.clear();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||
if (filter.match(permanent, sourceId, controllerId, game)
|
||||
&& (permanent.getControllerId().equals(this.controllerId) ^ opponentController)) {
|
||||
&& (permanent.isControlledBy(this.controllerId) ^ opponentController)) {
|
||||
if (!this.getTargets().isEmpty()) {
|
||||
Target target = this.getTargets().get(0);
|
||||
if (target instanceof TargetPlayer) {
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ public class DealsDamageToACreatureAttachedTriggeredAbility extends TriggeredAbi
|
|||
if (!combatOnly || ((DamagedCreatureEvent) event).isCombatDamage()) {
|
||||
Permanent attachment = game.getPermanent(this.getSourceId());
|
||||
if (attachment != null
|
||||
&& attachment.getAttachedTo() != null
|
||||
&& event.getSourceId().equals(attachment.getAttachedTo())) {
|
||||
&& attachment.isAttachedTo(event.getSourceId())) {
|
||||
if (setTargetPointer) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class DealsDamageToAPlayerAttachedTriggeredAbility extends TriggeredAbili
|
|||
}
|
||||
}
|
||||
if (targetController == TargetController.YOU) {
|
||||
if (!this.getControllerId().equals(event.getPlayerId())) {
|
||||
if (!this.isControlledBy(event.getPlayerId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class EntersBattlefieldControlledTriggeredAbility extends EntersBattlefie
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (super.checkTrigger(event, game)) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
return permanent != null && permanent.getControllerId().equals(this.getControllerId());
|
||||
return permanent != null && permanent.isControlledBy(this.getControllerId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class ExertCreatureControllerTriggeredAbility extends TriggeredAbilityImp
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
boolean weAreExerting = getControllerId().equals(event.getPlayerId());
|
||||
boolean weAreExerting = isControlledBy(event.getPlayerId());
|
||||
Permanent exerted = game.getPermanent(event.getTargetId());
|
||||
boolean exertedIsCreature = (exerted != null) && exerted.isCreature();
|
||||
return weAreExerting && exertedIsCreature;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class LandfallAbility extends TriggeredAbilityImpl {
|
|||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null
|
||||
&& permanent.isLand()
|
||||
&& permanent.getControllerId().equals(this.controllerId)) {
|
||||
&& permanent.isControlledBy(this.controllerId)) {
|
||||
triggeringLand = permanent;
|
||||
if (setTargetPointer == SetTargetPointer.PERMANENT) {
|
||||
for (Effect effect : getAllEffects()) {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi
|
|||
if (zEvent.getFromZone() == Zone.BATTLEFIELD
|
||||
&& zEvent.getToZone() == Zone.GRAVEYARD) {
|
||||
if (filter.match(zEvent.getTarget(), this.getSourceId(), this.getControllerId(), game)) {
|
||||
if (onlyToControllerGraveyard && !this.getControllerId().equals(game.getOwnerId(zEvent.getTargetId()))) {
|
||||
if (onlyToControllerGraveyard && !this.isControlledBy(game.getOwnerId(zEvent.getTargetId()))) {
|
||||
return false;
|
||||
}
|
||||
if (setTargetPointer) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class SacrificeIfCastAtInstantTimeTriggeredAbility extends TriggeredAbili
|
|||
// CHECK
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell != null && spell.getSourceId().equals(getSourceId())) {
|
||||
return !(game.isMainPhase() && game.getActivePlayerId().equals(event.getPlayerId()) && game.getStack().size() == 1);
|
||||
return !(game.isMainPhase() && game.isActivePlayer(event.getPlayerId()) && game.getStack().size() == 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import mage.abilities.condition.Condition;
|
|||
import mage.abilities.condition.InvertCondition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
|
|
@ -19,7 +19,7 @@ import mage.filter.predicate.mageobject.ColorPredicate;
|
|||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class SanctuaryTriggeredAbility extends ConditionalTriggeredAbility {
|
||||
public class SanctuaryInterveningIfTriggeredAbility extends ConditionalInterveningIfTriggeredAbility {
|
||||
|
||||
private static Condition makeOrCondition(ObjectColor color1, ObjectColor color2) {
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
|
|
@ -48,7 +48,7 @@ public class SanctuaryTriggeredAbility extends ConditionalTriggeredAbility {
|
|||
return ability;
|
||||
}
|
||||
|
||||
public SanctuaryTriggeredAbility(OneShotEffect effect1, OneShotEffect effect2, ObjectColor color1, ObjectColor color2, String text) {
|
||||
public SanctuaryInterveningIfTriggeredAbility(OneShotEffect effect1, OneShotEffect effect2, ObjectColor color1, ObjectColor color2, String text) {
|
||||
super(makeTrigger(effect1, effect2, color1, color2), makeOrCondition(color1, color2), text);
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ public class SpellCounteredControllerTriggeredAbility extends TriggeredAbilityIm
|
|||
if (stackObjectThatCountered == null) {
|
||||
stackObjectThatCountered = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK);
|
||||
}
|
||||
if (stackObjectThatCountered != null && stackObjectThatCountered.getControllerId().equals(getControllerId())) {
|
||||
if (stackObjectThatCountered != null && stackObjectThatCountered.isControlledBy(getControllerId())) {
|
||||
StackObject counteredStackObject = (StackObject) game.getLastKnownInformation(event.getTargetId(), Zone.STACK);
|
||||
return counteredStackObject != null && (counteredStackObject instanceof Spell);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
|
|||
Permanent attachment = game.getPermanent(sourceId);
|
||||
if (attachment != null && attachment.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||
if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) {
|
||||
if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTrigg
|
|||
Permanent attachment = game.getPermanent(sourceId);
|
||||
if (attachment != null && attachment.getAttachedTo() != null) {
|
||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||
if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) {
|
||||
if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) {
|
||||
correctEndPhase = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.abilities.common.delayed;
|
||||
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Duration;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public class AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(Effect effect) {
|
||||
this(effect, Duration.Custom, true);
|
||||
}
|
||||
|
||||
public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(Effect effect, Duration duration, boolean triggerOnlyOnce) {
|
||||
super(effect, duration, triggerOnlyOnce);
|
||||
}
|
||||
|
||||
public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility copy() {
|
||||
return new AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DRAW_STEP_PRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getPlayerId().equals(this.controllerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ public class PactDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return game.getActivePlayerId().equals(this.getControllerId());
|
||||
return game.isActivePlayer(this.getControllerId());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public enum CommanderInPlayCondition implements Condition {
|
|||
if (controller != null) {
|
||||
for (UUID commanderId : controller.getCommandersIds()) {
|
||||
Permanent commander = game.getPermanent(commanderId);
|
||||
if (commander != null && commander.getControllerId().equals(source.getControllerId())) {
|
||||
if (commander != null && commander.isControlledBy(source.getControllerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ public enum ControllerAttackedThisTurnCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
|
||||
return source.getControllerId().equals(game.getActivePlayerId()) && watcher != null && !watcher.getAttackedThisTurnCreatures().isEmpty();
|
||||
return source.isControlledBy(game.getActivePlayerId()) && watcher != null && !watcher.getAttackedThisTurnCreatures().isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class IsStepCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return phaseStep == game.getStep().getType() && (!onlyDuringYourSteps || game.getActivePlayerId().equals(source.getControllerId()));
|
||||
return phaseStep == game.getStep().getType() && (!onlyDuringYourSteps || game.isActivePlayer(source.getControllerId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ public class MeldCondition implements Condition {
|
|||
MageObject sourceMageObject = source.getSourceObjectIfItStillExists(game);
|
||||
if (sourceMageObject != null && sourceMageObject instanceof Permanent) {
|
||||
Permanent sourcePermanent = (Permanent) sourceMageObject;
|
||||
if (sourcePermanent.getControllerId().equals(source.getControllerId())
|
||||
&& sourcePermanent.getOwnerId().equals(source.getControllerId())) {
|
||||
if (sourcePermanent.isControlledBy(source.getControllerId())
|
||||
&& sourcePermanent.isOwnedBy(source.getControllerId())) {
|
||||
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
|
||||
filter.add(new NamePredicate(this.meldWithName));
|
||||
filter.add(new OwnerIdPredicate(source.getControllerId()));
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public enum MonarchIsSourceControllerCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return source.getControllerId().equals(game.getMonarchId());
|
||||
return source.isControlledBy(game.getMonarchId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public enum MyMainPhaseCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getActivePlayerId().equals(source.getControllerId()) &&
|
||||
return game.isActivePlayer(source.getControllerId()) &&
|
||||
turnPhases.contains(game.getTurn().getPhase().getType());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public enum MyTurnBeforeAttackersDeclaredCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
if (game.getActivePlayerId().equals(source.getControllerId())) {
|
||||
if (game.isActivePlayer(source.getControllerId())) {
|
||||
TurnPhase turnPhase = game.getTurn().getPhase().getType();
|
||||
if (turnPhase == TurnPhase.BEGINNING || turnPhase == TurnPhase.PRECOMBAT_MAIN) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public enum MyTurnCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return game.getActivePlayerId().equals(source.getControllerId());
|
||||
return game.isActivePlayer(source.getControllerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter
|
|||
if (condition == null || alternateCosts.size() == 1) {
|
||||
sb.append(" rather than pay this spell's mana cost");
|
||||
} else if (alternateCosts.isEmpty()) {
|
||||
sb.append("cast {this} without paying its mana cost");
|
||||
sb.append("cast this spell without paying its mana cost");
|
||||
}
|
||||
sb.append('.');
|
||||
if (numberCosts == 1 && remarkText != null) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class ExileSourceCost extends CostImpl {
|
|||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
MageObject sourceObject = ability.getSourceObject(game);
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null && sourceObject != null && (sourceObject instanceof Card)) {
|
||||
if (controller != null && sourceObject instanceof Card) {
|
||||
UUID exileZoneId = null;
|
||||
String exileZoneName = "";
|
||||
if (toUniqueExileZone) {
|
||||
|
|
|
|||
|
|
@ -207,7 +207,9 @@ public abstract class ManaCostImpl extends CostImpl implements ManaCost {
|
|||
return true;
|
||||
}
|
||||
Player player = game.getPlayer(controllerId);
|
||||
assignPayment(game, ability, player.getManaPool(), costToPay);
|
||||
if (!player.getManaPool().isForcedToPay()) {
|
||||
assignPayment(game, ability, player.getManaPool(), costToPay);
|
||||
}
|
||||
game.getState().getSpecialActions().removeManaActions();
|
||||
while (!isPaid()) {
|
||||
ManaCost unpaid = this.getUnpaid();
|
||||
|
|
|
|||
|
|
@ -117,7 +117,9 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
|||
}
|
||||
|
||||
Player player = game.getPlayer(controllerId);
|
||||
assignPayment(game, ability, player.getManaPool(), this);
|
||||
if (!player.getManaPool().isForcedToPay()) {
|
||||
assignPayment(game, ability, player.getManaPool(), this);
|
||||
}
|
||||
game.getState().getSpecialActions().removeManaActions();
|
||||
while (!isPaid()) {
|
||||
ManaCost unpaid = this.getUnpaid();
|
||||
|
|
@ -235,10 +237,15 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
|||
|
||||
@Override
|
||||
public void assignPayment(Game game, Ability ability, ManaPool pool, Cost costToPay) {
|
||||
if (!pool.isAutoPayment() && pool.getUnlockedManaType() == null) {
|
||||
boolean wasUnlockedManaType = (pool.getUnlockedManaType() != null);
|
||||
if (!pool.isAutoPayment() && !wasUnlockedManaType) {
|
||||
// if auto payment is inactive and no mana type was clicked manually - do nothing
|
||||
return;
|
||||
}
|
||||
ManaCosts referenceCosts = null;
|
||||
if (pool.isForcedToPay()) {
|
||||
referenceCosts = this.copy();
|
||||
}
|
||||
// attempt to pay colorless costs (not generic) mana costs first
|
||||
for (ManaCost cost : this) {
|
||||
if (!cost.isPaid() && cost instanceof ColorlessManaCost) {
|
||||
|
|
@ -318,6 +325,31 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
|||
}
|
||||
// stop using mana of the clicked mana type
|
||||
pool.lockManaType();
|
||||
if (!wasUnlockedManaType) {
|
||||
handleForcedToPayOnlyForCurrentPayment(game, pool, referenceCosts);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleForcedToPayOnlyForCurrentPayment(Game game, ManaPool pool, ManaCosts referenceCosts) {
|
||||
// for Word of Command
|
||||
if (pool.isForcedToPay()) {
|
||||
if (referenceCosts != null && this.getText().equals(referenceCosts.getText())) {
|
||||
UUID playerId = pool.getPlayerId();
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
game.undo(playerId);
|
||||
this.clearPaid();
|
||||
this.setX(referenceCosts.getX());
|
||||
player.getManaPool().restoreMana(pool.getPoolBookmark());
|
||||
game.bookmarkState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void forceManaRollback(Game game, ManaPool pool) {
|
||||
// for Word of Command
|
||||
handleForcedToPayOnlyForCurrentPayment(game, pool, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
package mage.abilities.decorator;
|
||||
|
||||
import mage.abilities.Modes;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.constants.EffectType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
* Adds condition to {@link mage.abilities.effects.ContinuousEffect}. Acts as
|
||||
* decorator.
|
||||
*
|
||||
* @author nantuko
|
||||
*/
|
||||
public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
protected TriggeredAbility ability;
|
||||
protected Condition condition;
|
||||
protected String abilityText;
|
||||
|
||||
/**
|
||||
* Triggered ability with a condition. Set the optionality for the trigger
|
||||
* ability itself.
|
||||
*
|
||||
* @param ability
|
||||
* @param condition
|
||||
* @param text explicit rule text for the ability, if null or empty, the
|
||||
* rule text generated by the triggered ability itself is used.
|
||||
*/
|
||||
public ConditionalInterveningIfTriggeredAbility(TriggeredAbility ability, Condition condition, String text) {
|
||||
super(ability.getZone(), null);
|
||||
this.ability = ability;
|
||||
this.modes = ability.getModes();
|
||||
this.condition = condition;
|
||||
this.abilityText = text;
|
||||
}
|
||||
|
||||
public ConditionalInterveningIfTriggeredAbility(final ConditionalInterveningIfTriggeredAbility triggered) {
|
||||
super(triggered);
|
||||
this.ability = triggered.ability.copy();
|
||||
this.condition = triggered.condition;
|
||||
this.abilityText = triggered.abilityText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkInterveningIfClause(Game game) {
|
||||
return condition.apply(game, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionalInterveningIfTriggeredAbility copy() {
|
||||
return new ConditionalInterveningIfTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return ability.checkEventType(event, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ability.setSourceId(this.getSourceId());
|
||||
ability.setControllerId(this.getControllerId());
|
||||
return ability.checkTrigger(event, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
if (abilityText == null || abilityText.isEmpty()) {
|
||||
return ability.getRule();
|
||||
}
|
||||
return abilityText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effects getEffects() {
|
||||
return ability.getEffects();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEffect(Effect effect) {
|
||||
ability.addEffect(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modes getModes() {
|
||||
return ability.getModes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effects getEffects(Game game, EffectType effectType) {
|
||||
return ability.getEffects(game, effectType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOptional() {
|
||||
return ability.isOptional();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ import mage.game.events.GameEvent;
|
|||
* Adds condition to {@link mage.abilities.effects.ContinuousEffect}. Acts as
|
||||
* decorator.
|
||||
*
|
||||
* @author nantuko
|
||||
* @author noahg
|
||||
*/
|
||||
public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
|
|
@ -46,11 +46,6 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
|||
this.abilityText = triggered.abilityText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkInterveningIfClause(Game game) {
|
||||
return condition.apply(game, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionalTriggeredAbility copy() {
|
||||
return new ConditionalTriggeredAbility(this);
|
||||
|
|
@ -65,7 +60,7 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ability.setSourceId(this.getSourceId());
|
||||
ability.setControllerId(this.getControllerId());
|
||||
return ability.checkTrigger(event, game);
|
||||
return ability.checkTrigger(event, game) && condition.apply(game, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class HighestConvertedManaCostValue implements DynamicValue {
|
|||
return 0;
|
||||
}
|
||||
int highCMC = 0;
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, controller.getId(), game)) {
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
|
||||
int cmc = permanent.getConvertedManaCost();
|
||||
highCMC = Math.max(highCMC, cmc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public class ManaSpentToCastCount implements DynamicValue {
|
|||
}
|
||||
if (spell != null) {
|
||||
// NOT the cmc of the spell on the stack
|
||||
return spell.getSpellAbility().getManaCostsToPay().convertedManaCost() + spell.getSpellAbility().getManaCostsToPay().getX();
|
||||
return spell.getSpellAbility().getManaCostsToPay().convertedManaCost();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public class PermanentsYouOwnThatOpponentsControlCount implements DynamicValue {
|
|||
int count = 0;
|
||||
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(sourceAbility.getControllerId(), game)) {
|
||||
if (!permanent.getOwnerId().equals(permanent.getControllerId()) && permanent.getOwnerId().equals(sourceAbility.getControllerId())) {
|
||||
if (!permanent.isOwnedBy(permanent.getControllerId()) && permanent.isOwnedBy(sourceAbility.getControllerId())) {
|
||||
if (opponentIds.contains(permanent.getControllerId())) {
|
||||
count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
|
|||
Player player = game.getPlayer(startingControllerId);
|
||||
if (player != null) {
|
||||
if (player.isInGame()) {
|
||||
return game.getActivePlayerId().equals(startingControllerId) && game.getTurnNum() != startingTurn;
|
||||
return game.isActivePlayer(startingControllerId) && game.getTurnNum() != startingTurn;
|
||||
}
|
||||
return player.hasReachedNextTurnAfterLeaving();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ public class ContinuousEffects implements Serializable {
|
|||
for (SpliceCardEffect effect : spliceCardEffects) {
|
||||
Set<Ability> abilities = spliceCardEffects.getAbility(effect.getId());
|
||||
for (Ability ability : abilities) {
|
||||
if (ability.getControllerId().equals(playerId) && (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null))) {
|
||||
if (ability.isControlledBy(playerId) && (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null))) {
|
||||
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
|
||||
spliceEffects.add(effect);
|
||||
break;
|
||||
|
|
@ -543,7 +543,7 @@ public class ContinuousEffects implements Serializable {
|
|||
* @param game
|
||||
* @return
|
||||
*/
|
||||
private List<AsThoughEffect> getApplicableAsThoughEffects(AsThoughEffectType type, Game game) {
|
||||
public List<AsThoughEffect> getApplicableAsThoughEffects(AsThoughEffectType type, Game game) {
|
||||
List<AsThoughEffect> asThoughEffectsList = new ArrayList<>();
|
||||
if (asThoughEffectsMap.containsKey(type)) {
|
||||
for (AsThoughEffect effect : asThoughEffectsMap.get(type)) {
|
||||
|
|
|
|||
39
Mage/src/main/java/mage/abilities/effects/EquipEffect.java
Normal file
39
Mage/src/main/java/mage/abilities/effects/EquipEffect.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package mage.abilities.effects;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
public class EquipEffect extends AttachEffect {
|
||||
|
||||
public EquipEffect(Outcome outcome) {
|
||||
super(outcome, "Equip");
|
||||
}
|
||||
|
||||
public EquipEffect(EquipEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
//301.5c An Equipment that’s also a creature can’t equip a creature. An Equipment that loses the subtype
|
||||
// “Equipment” can’t equip a creature. An Equipment can’t equip itself. An Equipment that equips an illegal or
|
||||
// nonexistent permanent becomes unattached from that permanent but remains on the battlefield. (This is a
|
||||
// state-based action. See rule 704.) An Equipment can’t equip more than one creature. If a spell or ability
|
||||
// would cause an Equipment to equip more than one creature, the Equipment’s controller chooses which creature
|
||||
// it equips.
|
||||
if (sourcePermanent != null && sourcePermanent.hasSubtype(SubType.EQUIPMENT, game) && !sourcePermanent.isCreature()) {
|
||||
return super.apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EquipEffect copy(){
|
||||
return new EquipEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ public class GainAbilitySpellsEffect extends ContinuousEffectImpl {
|
|||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (player != null && permanent != null) {
|
||||
for (Card card : game.getExile().getAllCards(game)) {
|
||||
if (card.getOwnerId().equals(source.getControllerId()) && filter.match(card, game)) {
|
||||
if (card.isOwnedBy(source.getControllerId()) && filter.match(card, game)) {
|
||||
game.getState().addOtherAbility(card, ability);
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ public class GainAbilitySpellsEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
}
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
if (stackObject.getControllerId().equals(source.getControllerId())) {
|
||||
if (stackObject.isControlledBy(source.getControllerId())) {
|
||||
Card card = game.getCard(stackObject.getSourceId());
|
||||
if (card != null && filter.match(card, game)) {
|
||||
if (!card.getAbilities().contains(ability)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CanBlockAsThoughtItHadShadowEffect extends AsThoughEffectImpl {
|
||||
|
||||
public CanBlockAsThoughtItHadShadowEffect(Duration duration) {
|
||||
super(AsThoughEffectType.BLOCK_SHADOW, duration, Outcome.Benefit);
|
||||
staticText = "{this} can block creatures with shadow as though {this} had shadow";
|
||||
}
|
||||
|
||||
public CanBlockAsThoughtItHadShadowEffect(final CanBlockAsThoughtItHadShadowEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CanBlockAsThoughtItHadShadowEffect copy() {
|
||||
return new CanBlockAsThoughtItHadShadowEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return sourceId.equals(source.getSourceId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ public class CantBeCounteredControlledEffect extends ContinuousRuleModifyingEffe
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell != null && spell.getControllerId().equals(source.getControllerId())
|
||||
if (spell != null && spell.isControlledBy(source.getControllerId())
|
||||
&& filterTarget.match(spell, source.getSourceId(), source.getControllerId(), game)) {
|
||||
if (filterSource == null) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import mage.abilities.effects.ContinuousEffectImpl;
|
|||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
|
||||
public class CopyTokenEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected Token token;
|
||||
|
||||
public CopyTokenEffect(Token token) {
|
||||
|
|
@ -28,19 +28,19 @@ public class CopyTokenEffect extends ContinuousEffectImpl {
|
|||
permanent.setName(token.getName());
|
||||
permanent.getColor(game).setColor(token.getColor(game));
|
||||
permanent.getCardType().clear();
|
||||
for (CardType type: token.getCardType()) {
|
||||
for (CardType type : token.getCardType()) {
|
||||
permanent.addCardType(type);
|
||||
}
|
||||
permanent.getSubtype(game).clear();
|
||||
for (SubType type: token.getSubtype(game)) {
|
||||
for (SubType type : token.getSubtype(game)) {
|
||||
permanent.getSubtype(game).add(type);
|
||||
}
|
||||
permanent.getSuperType().clear();
|
||||
for (SuperType type: token.getSuperType()) {
|
||||
for (SuperType type : token.getSuperType()) {
|
||||
permanent.addSuperType(type);
|
||||
}
|
||||
permanent.getAbilities().clear();
|
||||
for (Ability ability: token.getAbilities()) {
|
||||
for (Ability ability : token.getAbilities()) {
|
||||
permanent.addAbility(ability, game);
|
||||
}
|
||||
permanent.getPower().setValue(token.getPower().getValue());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -8,6 +7,8 @@ import mage.MageObject;
|
|||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
|
|
@ -17,6 +18,7 @@ import mage.constants.CardType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.EmptyToken;
|
||||
|
|
@ -33,7 +35,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
|
||||
private final UUID playerId;
|
||||
private final CardType additionalCardType;
|
||||
private boolean gainsHaste;
|
||||
private boolean hasHaste;
|
||||
private final int number;
|
||||
private List<Permanent> addedTokenPermanents;
|
||||
private SubType additionalSubType;
|
||||
|
|
@ -62,12 +64,12 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
this(playerId, null, false);
|
||||
}
|
||||
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste) {
|
||||
this(playerId, additionalCardType, gainsHaste, 1);
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean hasHaste) {
|
||||
this(playerId, additionalCardType, hasHaste, 1);
|
||||
}
|
||||
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number) {
|
||||
this(playerId, additionalCardType, gainsHaste, number, false, false);
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean hasHaste, int number) {
|
||||
this(playerId, additionalCardType, hasHaste, number, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,24 +77,24 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
* @param playerId null the token is controlled/owned by the controller of
|
||||
* the source ability
|
||||
* @param additionalCardType the token gains this card type in addition
|
||||
* @param gainsHaste the token gains haste
|
||||
* @param hasHaste the token gains haste
|
||||
* @param number number of tokens to put into play
|
||||
* @param tapped
|
||||
* @param attacking
|
||||
*/
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking) {
|
||||
this(playerId, additionalCardType, gainsHaste, number, tapped, attacking, null);
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean hasHaste, int number, boolean tapped, boolean attacking) {
|
||||
this(playerId, additionalCardType, hasHaste, number, tapped, attacking, null);
|
||||
}
|
||||
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer) {
|
||||
this(playerId, additionalCardType, gainsHaste, number, tapped, attacking, attackedPlayer, Integer.MIN_VALUE, Integer.MIN_VALUE, false);
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean hasHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer) {
|
||||
this(playerId, additionalCardType, hasHaste, number, tapped, attacking, attackedPlayer, Integer.MIN_VALUE, Integer.MIN_VALUE, false);
|
||||
}
|
||||
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer, int power, int toughness, boolean gainsFlying) {
|
||||
public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean hasHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer, int power, int toughness, boolean gainsFlying) {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.playerId = playerId;
|
||||
this.additionalCardType = additionalCardType;
|
||||
this.gainsHaste = gainsHaste;
|
||||
this.hasHaste = hasHaste;
|
||||
this.addedTokenPermanents = new ArrayList<>();
|
||||
this.number = number;
|
||||
this.tapped = tapped;
|
||||
|
|
@ -107,7 +109,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
super(effect);
|
||||
this.playerId = effect.playerId;
|
||||
this.additionalCardType = effect.additionalCardType;
|
||||
this.gainsHaste = effect.gainsHaste;
|
||||
this.hasHaste = effect.hasHaste;
|
||||
this.addedTokenPermanents = new ArrayList<>(effect.addedTokenPermanents);
|
||||
this.number = effect.number;
|
||||
this.additionalSubType = effect.additionalSubType;
|
||||
|
|
@ -124,14 +126,6 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
this.isntLegendary = effect.isntLegendary;
|
||||
}
|
||||
|
||||
public void setBecomesArtifact(boolean becomesArtifact) {
|
||||
this.becomesArtifact = becomesArtifact;
|
||||
}
|
||||
|
||||
public void setIsntLegendary(boolean isntLegendary) {
|
||||
this.isntLegendary = isntLegendary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID targetId;
|
||||
|
|
@ -187,7 +181,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
if (additionalCardType != null && !token.getCardType().contains(additionalCardType)) {
|
||||
token.addCardType(additionalCardType);
|
||||
}
|
||||
if (gainsHaste) {
|
||||
if (hasHaste) {
|
||||
token.addAbility(HasteAbility.getInstance());
|
||||
}
|
||||
if (gainsFlying) {
|
||||
|
|
@ -282,4 +276,33 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
|||
public void setUseLKI(boolean useLKI) {
|
||||
this.useLKI = useLKI;
|
||||
}
|
||||
|
||||
public void setBecomesArtifact(boolean becomesArtifact) {
|
||||
this.becomesArtifact = becomesArtifact;
|
||||
}
|
||||
|
||||
public void setIsntLegendary(boolean isntLegendary) {
|
||||
this.isntLegendary = isntLegendary;
|
||||
}
|
||||
|
||||
public void setHasHaste(boolean hasHaste) {
|
||||
this.hasHaste = hasHaste;
|
||||
}
|
||||
|
||||
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
||||
for (Permanent tokenPermanent : addedTokenPermanents) {
|
||||
ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD);
|
||||
exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game));
|
||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect), source);
|
||||
}
|
||||
}
|
||||
|
||||
public void exileTokensCreatedAtEndOfCombat(Game game, Ability source) {
|
||||
for (Permanent tokenPermanent : addedTokenPermanents) {
|
||||
|
||||
ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD);
|
||||
exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game));
|
||||
game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class CreatureExploresTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId());
|
||||
if (creature != null) {
|
||||
return creature.getControllerId().equals(getControllerId());
|
||||
return creature.isControlledBy(getControllerId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class DetainAllRestrictionEffect extends RestrictionEffect {
|
|||
for (FixedTarget fixedTarget : this.detainedObjects) {
|
||||
Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
permanent.addInfo(new StringBuilder("detain").append(getId()).toString(), "[Detained]", game);
|
||||
permanent.addInfo("detain" + getId(), "[Detained]", game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,11 +85,11 @@ class DetainAllRestrictionEffect extends RestrictionEffect {
|
|||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) {
|
||||
if (game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
|
||||
if (game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
|
||||
for (FixedTarget fixedTarget : this.detainedObjects) {
|
||||
Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
permanent.addInfo(new StringBuilder("detain").append(getId()).toString(), "", game);
|
||||
permanent.addInfo("detain" + getId(), "", game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class DetainRestrictionEffect extends RestrictionEffect {
|
|||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) {
|
||||
if (game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
|
||||
if (game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
|
||||
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
String costText = cost.getText();
|
||||
if (costText != null
|
||||
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("put")
|
||||
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("return")
|
||||
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("exile")
|
||||
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("discard")
|
||||
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("sacrifice")
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public class DontUntapInControllersNextUntapStepSourceEffect extends ContinuousR
|
|||
}
|
||||
// remember the turn of the untap step the effect has to be applied
|
||||
if (event.getType() == GameEvent.EventType.UNTAP_STEP
|
||||
&& game.getActivePlayerId().equals(source.getControllerId())) {
|
||||
&& game.isActivePlayer(source.getControllerId())) {
|
||||
if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step
|
||||
discard();
|
||||
return false;
|
||||
|
|
@ -70,7 +70,7 @@ public class DontUntapInControllersNextUntapStepSourceEffect extends ContinuousR
|
|||
// skip untap action
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP
|
||||
&& event.getType() == GameEvent.EventType.UNTAP
|
||||
&& game.getActivePlayerId().equals(source.getControllerId())
|
||||
&& game.isActivePlayer(source.getControllerId())
|
||||
&& event.getTargetId().equals(source.getSourceId())) {
|
||||
discard();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -101,8 +101,8 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
|
|||
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
if (game.getActivePlayerId().equals(permanent.getControllerId())
|
||||
&& ((onlyIfControlledByPlayer == null) || (game.getActivePlayerId().equals(onlyIfControlledByPlayer)))) { // if effect works only for specific player, all permanents have to be set to handled in that players untap step
|
||||
if (game.isActivePlayer(permanent.getControllerId())
|
||||
&& ((onlyIfControlledByPlayer == null) || (game.isActivePlayer(onlyIfControlledByPlayer)))) { // if effect works only for specific player, all permanents have to be set to handled in that players untap step
|
||||
if (!handledTargetsDuringTurn.containsKey(targetId)) {
|
||||
// it's the untep step of the current controller and the effect was not handled for this target yet, so do it now
|
||||
handledTargetsDuringTurn.put(targetId, false);
|
||||
|
|
@ -127,8 +127,8 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
|
|||
&& !handledTargetsDuringTurn.get(event.getTargetId())
|
||||
&& getTargetPointer().getTargets(game, source).contains(event.getTargetId())) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) {
|
||||
if ((onlyIfControlledByPlayer == null) || game.getActivePlayerId().equals(onlyIfControlledByPlayer)) { // If onlyIfControlledByPlayer is set, then don't apply unless we're currently controlled by the specified player.
|
||||
if (permanent != null && game.isActivePlayer(permanent.getControllerId())) {
|
||||
if ((onlyIfControlledByPlayer == null) || game.isActivePlayer(onlyIfControlledByPlayer)) { // If onlyIfControlledByPlayer is set, then don't apply unless we're currently controlled by the specified player.
|
||||
handledTargetsDuringTurn.put(event.getTargetId(), !twoSteps);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class DontUntapInControllersUntapStepAllEffect extends ContinuousRuleModi
|
|||
if (permanent != null) {
|
||||
switch(targetController) {
|
||||
case YOU:
|
||||
if (!permanent.getControllerId().equals(source.getControllerId())) {
|
||||
if (!permanent.isControlledBy(source.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -76,7 +76,7 @@ public class DontUntapInControllersUntapStepAllEffect extends ContinuousRuleModi
|
|||
default:
|
||||
throw new RuntimeException("Type of TargetController not supported!");
|
||||
}
|
||||
if (game.getActivePlayerId().equals(permanent.getControllerId()) && // controller's untap step
|
||||
if (game.isActivePlayer(permanent.getControllerId()) && // controller's untap step
|
||||
filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public class DontUntapInControllersUntapStepEnchantedEffect extends ContinuousRu
|
|||
Permanent enchantment = game.getPermanent(source.getSourceId());
|
||||
if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) {
|
||||
Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (permanent != null && permanent.getControllerId().equals(game.getActivePlayerId())) {
|
||||
if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class DontUntapInControllersUntapStepSourceEffect extends ContinuousRuleM
|
|||
if (game.getTurn().getStepType() == PhaseStep.UNTAP
|
||||
&& event.getTargetId().equals(source.getSourceId())) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null && permanent.getControllerId().equals(game.getActivePlayerId())) {
|
||||
if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM
|
|||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
||||
if (event.getTargetId().equals(targetId)) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) {
|
||||
if (permanent != null && game.isActivePlayer(permanent.getControllerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public class DontUntapInPlayersNextUntapStepAllEffect extends ContinuousRuleModi
|
|||
}
|
||||
// remember the turn of the untap step the effect has to be applied
|
||||
if (event.getType() == EventType.UNTAP_STEP) {
|
||||
if (game.getActivePlayerId().equals(getTargetPointer().getFirst(game, source))) {
|
||||
if (game.isActivePlayer(getTargetPointer().getFirst(game, source))) {
|
||||
if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step
|
||||
discard();
|
||||
return false;
|
||||
|
|
@ -94,13 +94,13 @@ public class DontUntapInPlayersNextUntapStepAllEffect extends ContinuousRuleModi
|
|||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (!permanent.getControllerId().equals(getTargetPointer().getFirst(game, source))) {
|
||||
if (!permanent.isControlledBy(getTargetPointer().getFirst(game, source))) {
|
||||
return false;
|
||||
}
|
||||
if (controller != null && !game.isOpponent(controller, permanent.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
if (game.getActivePlayerId().equals(permanent.getControllerId())
|
||||
if (game.isActivePlayer(permanent.getControllerId())
|
||||
&& // controller's untap step
|
||||
filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
public class FortifyEffect extends AttachEffect{
|
||||
|
||||
public FortifyEffect(Outcome outcome) {
|
||||
super(outcome, "Fortify");
|
||||
}
|
||||
|
||||
public FortifyEffect(FortifyEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
|
||||
//Some artifacts have the subtype “Fortification.” A Fortification can be attached to a land. It can’t legally
|
||||
// be attached to an object that isn’t a land. Fortification’s analog to the equip keyword ability is the
|
||||
// fortify keyword ability. Rules 301.5a–e apply to Fortifications in relation to lands just as they apply to
|
||||
// Equipment in relation to creatures, with one clarification relating to rule 301.5c: a Fortification that’s
|
||||
// also a creature (not a land) can’t fortify a land. (See rule 702.66, “Fortify.”)
|
||||
if (sourcePermanent != null && sourcePermanent.hasSubtype(SubType.FORTIFICATION, game) && !sourcePermanent.isCreature()
|
||||
&& !sourcePermanent.isLand()) {
|
||||
return super.apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FortifyEffect copy(){
|
||||
return new FortifyEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ public class HideawayPlayEffect extends OneShotEffect {
|
|||
*/
|
||||
if (card.isLand()) {
|
||||
UUID playerId = controller.getId();
|
||||
if (!game.getActivePlayerId().equals(playerId) || !game.getPlayer(playerId).canPlayLand()) {
|
||||
if (!game.isActivePlayer(playerId) || !game.getPlayer(playerId).canPlayLand()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff
|
|||
private boolean putOnTopSelected;
|
||||
private boolean anyOrder;
|
||||
|
||||
//TODO: These constructors are a mess
|
||||
public LookLibraryAndPickControllerEffect(DynamicValue numberOfCards,
|
||||
boolean mayShuffleAfter, DynamicValue numberToPick,
|
||||
FilterCard pickFilter, boolean putOnTop) {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if (mayShuffleAfter) {
|
||||
if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle his or her library?"), source, game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle their library?"), source, game)) {
|
||||
targetPlayer.shuffleLibrary(source, game);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class PopulateEffect extends OneShotEffect {
|
|||
|
||||
public PopulateEffect(String prefixText) {
|
||||
super(Outcome.Copy);
|
||||
this.staticText = (!prefixText.isEmpty() ? prefixText + " p" : "P") + "opulate <i>(Put a token onto the battlefield that's a copy of a creature token you control.)</i>";
|
||||
this.staticText = (!prefixText.isEmpty() ? prefixText + " p" : "P") + "opulate <i>(Create a token that's a copy of a creature token you control.)</i>";
|
||||
}
|
||||
|
||||
public PopulateEffect(final PopulateEffect effect) {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public class PutOnLibraryTargetEffect extends OneShotEffect {
|
|||
Cards cardsPlayer = new CardsImpl();
|
||||
for (Iterator<Card> iterator = cards.iterator(); iterator.hasNext();) {
|
||||
Card next = iterator.next();
|
||||
if (next.getOwnerId().equals(owner.getId())) {
|
||||
if (next.isOwnedBy(owner.getId())) {
|
||||
cardsPlayer.add(next);
|
||||
iterator.remove();
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ public class PutOnLibraryTargetEffect extends OneShotEffect {
|
|||
Cards cardsPlayer = new CardsImpl();
|
||||
for (Iterator<Permanent> iterator = permanents.iterator(); iterator.hasNext();) {
|
||||
Permanent next = iterator.next();
|
||||
if (next.getOwnerId().equals(owner.getId())) {
|
||||
if (next.isOwnedBy(owner.getId())) {
|
||||
cardsPlayer.add(next);
|
||||
iterator.remove();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect {
|
|||
for (Target target : source.getTargets()) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
MageObject mageObject = game.getObject(targetId);
|
||||
if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) {
|
||||
if (mageObject instanceof Spell && mageObject.isCopy()) {
|
||||
copyIds.add(targetId);
|
||||
} else if (mageObject instanceof Card) {
|
||||
cards.add((Card) mageObject);
|
||||
|
|
@ -68,7 +68,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect {
|
|||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
||||
MageObject mageObject = game.getObject(targetId);
|
||||
if (mageObject != null) {
|
||||
if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) {
|
||||
if (mageObject instanceof Spell && mageObject.isCopy()) {
|
||||
copyIds.add(targetId);
|
||||
} else {
|
||||
cards.add((Card) mageObject);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author noahg
|
||||
*/
|
||||
public class RevealHandSourceControllerEffect extends OneShotEffect {
|
||||
|
||||
public RevealHandSourceControllerEffect() {
|
||||
super(Outcome.Discard);
|
||||
this.staticText = "reveal your hand";
|
||||
}
|
||||
|
||||
public RevealHandSourceControllerEffect(final RevealHandSourceControllerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (player != null && sourceObject != null) {
|
||||
player.revealCards(sourceObject.getIdName(), player.getHand(), game);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RevealHandSourceControllerEffect copy() {
|
||||
return new RevealHandSourceControllerEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,9 @@ import mage.abilities.dynamicvalue.DynamicValue;
|
|||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
|
@ -36,7 +38,8 @@ public class SacrificeOpponentsEffect extends OneShotEffect {
|
|||
public SacrificeOpponentsEffect(DynamicValue amount, FilterPermanent filter) {
|
||||
super(Outcome.Sacrifice);
|
||||
this.amount = amount;
|
||||
this.filter = filter;
|
||||
this.filter = filter.copy();
|
||||
this.filter.add(new ControllerPredicate(TargetController.YOU));
|
||||
setText();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class SacrificeSourceEffect extends OneShotEffect {
|
|||
if (sourceObject instanceof Permanent) {
|
||||
Permanent permanent = (Permanent) sourceObject;
|
||||
// you can only sacrifice a permanent you control
|
||||
if (source.getControllerId().equals(permanent.getControllerId())) {
|
||||
if (source.isControlledBy(permanent.getControllerId())) {
|
||||
return permanent.sacrifice(source.getSourceId(), game);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*
|
||||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.turn.TurnMod;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author noahg
|
||||
*/
|
||||
public class SkipNextDrawStepControllerEffect extends OneShotEffect {
|
||||
|
||||
public SkipNextDrawStepControllerEffect() {
|
||||
this("you skip your next draw step");
|
||||
}
|
||||
|
||||
public SkipNextDrawStepControllerEffect(String text) {
|
||||
super(Outcome.Detriment);
|
||||
this.staticText = text;
|
||||
}
|
||||
|
||||
public SkipNextDrawStepControllerEffect(SkipNextDrawStepControllerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
game.getState().getTurnMods().add(new TurnMod(player.getId(), PhaseStep.DRAW));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkipNextDrawStepControllerEffect copy() {
|
||||
return new SkipNextDrawStepControllerEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ public class SkipUntapOptionalSourceEffect extends RestrictionEffect {
|
|||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
return permanent.getId().equals(source.getSourceId())
|
||||
&& permanent.getControllerId().equals(game.getActivePlayerId()) && // your untap step
|
||||
&& permanent.isControlledBy(game.getActivePlayerId()) && // your untap step
|
||||
permanent.isTapped();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public class WishEffect extends OneShotEffect {
|
|||
}
|
||||
if (alsoFromExile) {
|
||||
for (Card exileCard : exile) {
|
||||
if (exileCard.getOwnerId().equals(source.getControllerId()) && filter.match(exileCard, game)) {
|
||||
if (exileCard.isOwnedBy(source.getControllerId()) && filter.match(exileCard, game)) {
|
||||
filteredCards.add(exileCard);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class CantAttackControllerAttachedEffect extends RestrictionEffect {
|
|||
return false;
|
||||
}
|
||||
Permanent planeswalker = game.getPermanent(defenderId);
|
||||
return planeswalker == null || !planeswalker.getControllerId().equals(source.getControllerId());
|
||||
return planeswalker == null || !planeswalker.isControlledBy(source.getControllerId());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class CantAttackYouOrPlaneswalkerAllEffect extends RestrictionEffect {
|
|||
return false;
|
||||
}
|
||||
Permanent planeswalker = game.getPermanent(defenderId);
|
||||
return planeswalker == null || !planeswalker.getControllerId().equals(source.getControllerId());
|
||||
return planeswalker == null || !planeswalker.isControlledBy(source.getControllerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class CantAttackYouUnlessPayManaAllEffect extends PayCostToAttackBlockEff
|
|||
}
|
||||
}
|
||||
// attack target is controlling player
|
||||
if (source.getControllerId().equals(event.getTargetId())) {
|
||||
if (source.isControlledBy(event.getTargetId())) {
|
||||
return true;
|
||||
}
|
||||
// or attack target is a planeswalker of the controlling player
|
||||
|
|
@ -64,7 +64,7 @@ public class CantAttackYouUnlessPayManaAllEffect extends PayCostToAttackBlockEff
|
|||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null
|
||||
&& permanent.isPlaneswalker()
|
||||
&& permanent.getControllerId().equals(source.getControllerId())) {
|
||||
&& permanent.isControlledBy(source.getControllerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class CantBeBlockedAttachedEffect extends RestrictionEffect {
|
|||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
Permanent attachment = game.getPermanent(source.getSourceId());
|
||||
return attachment != null && attachment.getAttachedTo() != null
|
||||
&& attachment.getAttachedTo().equals(permanent.getId());
|
||||
return attachment != null
|
||||
&& attachment.isAttachedTo(permanent.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class GoadAllEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
|
||||
if (!creature.getControllerId().equals(source.getControllerId())) {
|
||||
if (!creature.isControlledBy(source.getControllerId())) {
|
||||
Effect effect = new GoadTargetEffect();
|
||||
effect.setTargetPointer(new FixedTarget(creature, game));
|
||||
effect.apply(game, source);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class ActivateAbilitiesAnyTimeYouCouldCastInstantEffect extends AsThoughE
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game) {
|
||||
return affectedAbility.getControllerId().equals(source.getControllerId())
|
||||
return affectedAbility.isControlledBy(source.getControllerId())
|
||||
&& activatedAbility.isInstance(affectedAbility);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class AddCardTypeTargetEffect extends ContinuousEffectImpl {
|
|||
sb.append(cardType.toString().toLowerCase(Locale.ENGLISH)).append(" ");
|
||||
}
|
||||
sb.append("in addition to its other types");
|
||||
if (getDuration().equals(Duration.EndOfTurn)) {
|
||||
if (getDuration() == Duration.EndOfTurn) {
|
||||
sb.append(" until end of turn");
|
||||
}
|
||||
return sb.toString();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package mage.abilities.effects.common.continuous;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
public class AddChosenSubtypeEffect extends ContinuousEffectImpl {
|
||||
|
||||
public AddChosenSubtypeEffect() {
|
||||
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
|
||||
staticText = "{this} is the chosen type in addition to its other types";
|
||||
}
|
||||
|
||||
public AddChosenSubtypeEffect(final AddChosenSubtypeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(permanent.getId(), game);
|
||||
if (subType != null && !permanent.hasSubtype(subType, game)) {
|
||||
permanent.getSubtype(game).add(subType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddChosenSubtypeEffect copy() {
|
||||
return new AddChosenSubtypeEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*
|
||||
*/
|
||||
package mage.abilities.effects.common.continuous;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.choices.ChoiceColor;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX
|
||||
*/
|
||||
public class BecomesColorAllEffect extends ContinuousEffectImpl {
|
||||
|
||||
private ObjectColor setColor;
|
||||
protected boolean loseOther;
|
||||
protected FilterPermanent filter;
|
||||
|
||||
/**
|
||||
* Set the color of a spell or permanent
|
||||
*
|
||||
* @param duration
|
||||
*/
|
||||
public BecomesColorAllEffect(Duration duration) {
|
||||
this(null, duration);
|
||||
}
|
||||
|
||||
public BecomesColorAllEffect(ObjectColor setColor, Duration duration) {
|
||||
this(setColor, duration, new FilterPermanent("All permanents"), true, null);
|
||||
}
|
||||
|
||||
public BecomesColorAllEffect(ObjectColor setColor, Duration duration, FilterPermanent filter, boolean loseOther, String text) {
|
||||
super(duration, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Neutral);
|
||||
this.setColor = setColor;
|
||||
this.filter = filter;
|
||||
this.loseOther = loseOther;
|
||||
staticText = text;
|
||||
}
|
||||
|
||||
public BecomesColorAllEffect(final BecomesColorAllEffect effect) {
|
||||
super(effect);
|
||||
this.setColor = effect.setColor;
|
||||
this.filter = effect.filter;
|
||||
this.loseOther = effect.loseOther;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
if (setColor == null) {
|
||||
ChoiceColor choice = new ChoiceColor();
|
||||
if (!controller.choose(Outcome.PutManaInPool, choice, game)) {
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
setColor = choice.getColor();
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers(controller.getLogName() + " has chosen the color: " + setColor.toString());
|
||||
}
|
||||
}
|
||||
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
if (setColor != null) {
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
|
||||
if (permanent != null) {
|
||||
switch (layer) {
|
||||
case ColorChangingEffects_5:
|
||||
if (loseOther) {
|
||||
permanent.getColor(game).setColor(new ObjectColor());
|
||||
}
|
||||
permanent.getColor(game).addColor(setColor);
|
||||
break;
|
||||
}
|
||||
} else if (duration == Duration.Custom) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BecomesColorAllEffect copy() {
|
||||
return new BecomesColorAllEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
if (staticText != null && !staticText.isEmpty()) {
|
||||
return staticText;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(filter.getMessage());
|
||||
sb.append(" become ");
|
||||
if (setColor == null) {
|
||||
sb.append("the color of your choice");
|
||||
} else {
|
||||
sb.append(setColor.getDescription());
|
||||
}
|
||||
if (!duration.toString().equals("")) {
|
||||
sb.append(' ').append(duration.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ public class CantCastMoreThanOneSpellEffect extends ContinuousRuleModifyingEffec
|
|||
break;
|
||||
case CONTROLLER_ATTACHED_TO:
|
||||
Permanent attachment = game.getPermanent(source.getSourceId());
|
||||
if (attachment == null || !attachment.getAttachedTo().equals(event.getPlayerId())) {
|
||||
if (attachment == null || !attachment.isAttachedTo(event.getPlayerId())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class CastAsThoughItHadFlashAllEffect extends AsThoughEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(UUID affectedSpellId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (anyPlayer || source.getControllerId().equals(affectedControllerId)) {
|
||||
if (anyPlayer || source.isControlledBy(affectedControllerId)) {
|
||||
Card card = game.getCard(affectedSpellId);
|
||||
return card != null && filter.match(card, game);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
|
|||
}
|
||||
if (permanent1 != null && permanent2 != null) {
|
||||
// exchange works only for two different controllers
|
||||
if (permanent1.getControllerId().equals(permanent2.getControllerId())) {
|
||||
if (permanent1.isControlledBy(permanent2.getControllerId())) {
|
||||
// discard effect if controller of both permanents is the same
|
||||
discard();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl {
|
|||
if (player != null && permanent != null) {
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
// only spells cast, so no copies of spells
|
||||
if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) {
|
||||
if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId())) {
|
||||
Spell spell = (Spell) stackObject;
|
||||
if (filter.match(spell, game)) {
|
||||
if (!spell.getAbilities().contains(ability)) {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
return true;
|
||||
}
|
||||
if (durationPhaseStep != null && durationPhaseStep == game.getPhase().getStep().getType()) {
|
||||
if (!sameStep && game.getActivePlayerId().equals(durationPlayerId) || game.getPlayer(durationPlayerId).hasReachedNextTurnAfterLeaving()) {
|
||||
if (!sameStep && game.isActivePlayer(durationPlayerId) || game.getPlayer(durationPlayerId).hasReachedNextTurnAfterLeaving()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class GainControlTargetEffect extends ContinuousEffectImpl {
|
|||
Permanent permanent = game.getPermanent(permanentId);
|
||||
if (permanent != null) {
|
||||
targetStillExists = true;
|
||||
if (!permanent.getControllerId().equals(controllingPlayerId)) {
|
||||
if (!permanent.isControlledBy(controllingPlayerId)) {
|
||||
GameEvent loseControlEvent = GameEvent.getEvent(GameEvent.EventType.LOSE_CONTROL, permanentId, source.getId(), permanent.getControllerId());
|
||||
if (game.replaceEvent(loseControlEvent)) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
package mage.abilities.effects.common.continuous;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author noahg
|
||||
*/
|
||||
public class LoseArtifactTypeTargetEffect extends ContinuousEffectImpl{
|
||||
|
||||
public LoseArtifactTypeTargetEffect(Duration duration) {
|
||||
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
|
||||
dependencyTypes.add(DependencyType.ArtifactAddingRemoving);
|
||||
setText("isn't an artifact");
|
||||
}
|
||||
|
||||
public LoseArtifactTypeTargetEffect(final LoseArtifactTypeTargetEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoseArtifactTypeTargetEffect copy() {
|
||||
return new LoseArtifactTypeTargetEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game); //To change body of generated methods, choose Tools | Templates.
|
||||
if (duration.isOnlyValidIfNoZoneChange()) {
|
||||
// If source permanent is no longer onto battlefield discard the effect
|
||||
if (source.getSourcePermanentIfItStillExists(game) == null) {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||
for (UUID targetId : targetPointer.getTargets(game, source)) {
|
||||
if (targetId != null) {
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent != null) {
|
||||
switch (layer) {
|
||||
case TypeChangingEffects_4:
|
||||
if (sublayer == SubLayer.NA) {
|
||||
permanent.getCardType().remove(CardType.ARTIFACT);
|
||||
permanent.getSubtype(game).removeAll(SubType.getArtifactTypes(false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayer(Layer layer) {
|
||||
return layer == Layer.TypeChangingEffects_4;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
|
|||
Card cardOnTop = game.getCard(objectId);
|
||||
if (cardOnTop != null
|
||||
&& affectedControllerId.equals(source.getControllerId())
|
||||
&& cardOnTop.getOwnerId().equals(source.getControllerId())
|
||||
&& cardOnTop.isOwnedBy(source.getControllerId())
|
||||
&& (!cardOnTop.getManaCost().isEmpty() || cardOnTop.isLand())
|
||||
&& filter.match(cardOnTop, game)) {
|
||||
Player player = game.getPlayer(cardOnTop.getOwnerId());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.effects.common.continuous;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
|
|
@ -16,13 +15,24 @@ import mage.game.permanent.Permanent;
|
|||
*/
|
||||
public class SetPowerToughnessEnchantedEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final int power;
|
||||
private final int toughness;
|
||||
|
||||
public SetPowerToughnessEnchantedEffect() {
|
||||
this(0, 2);
|
||||
}
|
||||
|
||||
public SetPowerToughnessEnchantedEffect(int power, int toughness) {
|
||||
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.SetPT_7b, Outcome.BoostCreature);
|
||||
staticText = "Enchanted creature has base power and toughness 0/2";
|
||||
staticText = "Enchanted creature has base power and toughness " + power + "/" + toughness;
|
||||
this.power = power;
|
||||
this.toughness = toughness;
|
||||
}
|
||||
|
||||
public SetPowerToughnessEnchantedEffect(final SetPowerToughnessEnchantedEffect effect) {
|
||||
super(effect);
|
||||
this.power = effect.power;
|
||||
this.toughness = effect.toughness;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -36,8 +46,8 @@ public class SetPowerToughnessEnchantedEffect extends ContinuousEffectImpl {
|
|||
if (enchantment != null && enchantment.getAttachedTo() != null) {
|
||||
Permanent enchanted = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (enchanted != null) {
|
||||
enchanted.getPower().setValue(0);
|
||||
enchanted.getToughness().setValue(2);
|
||||
enchanted.getPower().setValue(power);
|
||||
enchanted.getToughness().setValue(toughness);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class UntapAllDuringEachOtherPlayersUntapStepEffect extends ContinuousEff
|
|||
applied = Boolean.FALSE;
|
||||
}
|
||||
if (!applied && layer == Layer.RulesEffects) {
|
||||
if (!source.getControllerId().equals(game.getActivePlayerId()) && game.getStep().getType() == PhaseStep.UNTAP) {
|
||||
if (!source.isControlledBy(game.getActivePlayerId()) && game.getStep().getType() == PhaseStep.UNTAP) {
|
||||
game.getState().setValue(source.getSourceId() + "applied", true);
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
|
||||
boolean untap = true;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class UntapSourceDuringEachOtherPlayersUntapStepEffect extends Continuous
|
|||
applied = Boolean.FALSE;
|
||||
}
|
||||
if (!applied && layer == Layer.RulesEffects) {
|
||||
if (!source.getControllerId().equals(game.getActivePlayerId())
|
||||
if (!source.isControlledBy(game.getActivePlayerId())
|
||||
&& game.getStep() != null
|
||||
&& game.getStep().getType() == PhaseStep.UNTAP) {
|
||||
game.getState().setValue(source.getSourceId() + "applied", true);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue