Merge branch 'master' into Battlebond_Boos

This commit is contained in:
Chatziargyriou Eleftheria 2018-07-31 17:02:11 +03:00 committed by GitHub
commit 197020b162
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1466 changed files with 18523 additions and 4276 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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())));
}

View file

@ -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:

View file

@ -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();
}
}

View file

@ -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))) {

View file

@ -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;
}

View file

@ -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()));
}

View file

@ -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()));

View file

@ -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()));

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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) {

View file

@ -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()));

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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()) {

View file

@ -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) {

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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());
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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

View file

@ -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()));

View file

@ -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

View file

@ -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());
}
}

View file

@ -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;

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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();

View file

@ -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

View file

@ -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();
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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++;
}

View file

@ -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();
}

View file

@ -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)) {

View 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 thats also a creature cant equip a creature. An Equipment that loses the subtype
// Equipment cant equip a creature. An Equipment cant 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 cant equip more than one creature. If a spell or ability
// would cause an Equipment to equip more than one creature, the Equipments 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);
}
}

View file

@ -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)) {

View file

@ -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());
}
}

View file

@ -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;

View file

@ -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());

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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) {

View file

@ -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")

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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 cant legally
// be attached to an object that isnt a land. Fortifications analog to the equip keyword ability is the
// fortify keyword ability. Rules 301.5ae 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 thats
// also a creature (not a land) cant 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);
}
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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();
}

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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());
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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();

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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)) {

View file

@ -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 {

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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());

View file

@ -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;
}

View file

@ -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;

View file

@ -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