This commit is contained in:
BetaSteward 2010-10-06 01:51:53 +00:00
parent 2cf247d68b
commit 5eae8136e4
70 changed files with 1286 additions and 399 deletions

View file

@ -90,6 +90,7 @@ public final class Constants {
public enum Rarity {
NA ("na", "na"),
LAND ("Land", "common"),
COMMON ("Common", "common"),
UNCOMMON ("Uncommon", "uncommon"),
@ -138,6 +139,16 @@ public final class Constants {
}
}
public enum AsThoughEffectType {
BLOCK,
BE_BLOCKED,
ATTACK,
CAST,
TARGET,
PAY,
DAMAGE
}
public enum Duration {
OneUse(""),
EndOfGame("for the rest of the game"),

View file

@ -58,6 +58,8 @@ public interface Ability extends Serializable {
public void addManaCost(ManaCost cost);
public List<AlternativeCost> getAlternativeCosts();
public void addAlternativeCost(AlternativeCost cost);
public Costs<Cost> getOptionalCosts();
public void addOptionalCost(Cost cost);
public Effects getEffects();
public void addEffect(Effect effect);
public Targets getTargets();
@ -71,6 +73,7 @@ public interface Ability extends Serializable {
public boolean activate(Game game, boolean noMana);
public boolean resolve(Game game);
public void reset(Game game);
public boolean checkIfClause(Game game);
public void setControllerId(UUID controllerId);
public void setSourceId(UUID sourceID);

View file

@ -68,6 +68,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
protected ManaCosts<ManaCost> manaCosts;
protected Costs<Cost> costs;
protected ArrayList<AlternativeCost> alternativeCosts = new ArrayList<AlternativeCost>();
protected Costs<Cost> optionalCosts;
protected Targets targets;
protected Choices choices;
protected Effects effects;
@ -84,6 +85,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
this.zone = zone;
this.manaCosts = new ManaCostsImpl<ManaCost>();
this.costs = new CostsImpl<Cost>();
this.optionalCosts = new CostsImpl<Cost>();
this.effects = new Effects();
this.targets = new Targets();
this.choices = new Choices();
@ -99,6 +101,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
this.usesStack = ability.usesStack;
this.manaCosts = ability.manaCosts.copy();
this.costs = ability.costs.copy();
this.optionalCosts = ability.optionalCosts.copy();
for (AlternativeCost cost: ability.alternativeCosts) {
this.alternativeCosts.add((AlternativeCost)cost.copy());
}
@ -120,12 +123,15 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
@Override
public boolean resolve(Game game) {
boolean result = true;
for (Effect effect: getEffects()) {
if (effect instanceof OneShotEffect) {
result &= effect.apply(game, this);
}
else {
game.addEffect((ContinuousEffect) effect, this);
//20100716 - 117.12
if (checkIfClause(game)) {
for (Effect effect: getEffects()) {
if (effect instanceof OneShotEffect) {
result &= effect.apply(game, this);
}
else {
game.addEffect((ContinuousEffect) effect, this);
}
}
}
return result;
@ -168,6 +174,11 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
return false;
}
@Override
public boolean checkIfClause(Game game) {
return true;
}
@Override
public UUID getControllerId() {
return controllerId;
@ -204,6 +215,11 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
return alternativeCosts;
}
@Override
public Costs getOptionalCosts() {
return optionalCosts;
}
@Override
public Effects getEffects() {
return effects;
@ -260,11 +276,6 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
return sbRule.toString();
}
// @Override
// public String getName() {
// return "";
// }
@Override
public void addCost(Cost cost) {
if (cost != null) {
@ -286,6 +297,13 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
}
}
@Override
public void addOptionalCost(Cost cost) {
if (cost != null) {
this.optionalCosts.add(cost);
}
}
@Override
public void addEffect(Effect effect) {
if (effect != null) {

View file

@ -30,8 +30,10 @@ package mage.abilities;
import java.util.UUID;
import mage.Constants.AbilityType;
import mage.Constants.AsThoughEffectType;
import mage.Constants.CardType;
import mage.Constants.Zone;
import mage.MageObject;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.keyword.FlashAbility;
import mage.game.Game;
@ -54,8 +56,10 @@ public class SpellAbility extends ActivatedAbilityImpl<SpellAbility> {
@Override
public boolean canActivate(UUID playerId, Game game) {
if ((game.getObject(sourceId).getCardType().contains(CardType.INSTANT) ||
game.getObject(sourceId).getAbilities().containsKey(FlashAbility.getInstance().getId()) ||
MageObject object = game.getObject(sourceId);
if ((object.getCardType().contains(CardType.INSTANT) ||
object.getAbilities().containsKey(FlashAbility.getInstance().getId()) ||
game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST, game) ||
game.canPlaySorcery(playerId))) {
if (costs.canPay(sourceId, controllerId, game) && targets.canChoose(sourceId, playerId, game)) {
return true;

View file

@ -40,6 +40,6 @@ public interface TriggeredAbility extends Ability {
public void trigger(Game game, UUID controllerId);
public boolean checkTrigger(GameEvent event, Game game);
public boolean checkIfClause(Game game);
public boolean checkInterveningIfClause(Game game);
}

View file

@ -63,14 +63,14 @@ public abstract class TriggeredAbilityImpl<T extends TriggeredAbilityImpl<T>> ex
@Override
public void trigger(Game game, UUID controllerId) {
//20091005 - 603.4
if (checkIfClause(game)) {
if (checkInterveningIfClause(game)) {
this.controllerId = controllerId;
game.addTriggeredAbility(this);
}
}
@Override
public boolean checkIfClause(Game game) {
public boolean checkInterveningIfClause(Game game) {
return true;
}
@ -84,7 +84,7 @@ public abstract class TriggeredAbilityImpl<T extends TriggeredAbilityImpl<T>> ex
}
}
//20091005 - 603.4
if (checkIfClause(game))
if (checkInterveningIfClause(game))
return super.resolve(game);
return false;
}

View file

@ -31,7 +31,6 @@ package mage.abilities.costs.common;
import java.util.UUID;
import mage.Constants.Outcome;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.costs.CostImpl;
import mage.game.Game;
import mage.game.permanent.Permanent;

View file

@ -0,0 +1,45 @@
/*
* 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;
import java.util.UUID;
import mage.Constants.AsThoughEffectType;
import mage.abilities.Ability;
import mage.game.Game;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public interface AsThoughEffect<T extends AsThoughEffect<T>> extends ContinuousEffect<T> {
public boolean applies(UUID sourceId, Ability source, Game game);
public AsThoughEffectType getAsThoughEffectType();
}

View file

@ -0,0 +1,58 @@
/*
* 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;
import mage.Constants.AsThoughEffectType;
import mage.Constants.Duration;
import mage.Constants.Outcome;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public abstract class AsThoughEffectImpl<T extends AsThoughEffectImpl<T>> extends ContinuousEffectImpl<T> implements AsThoughEffect<T> {
protected AsThoughEffectType type;
public AsThoughEffectImpl(AsThoughEffectType type, Duration duration, Outcome outcome) {
super(duration, outcome);
this.type = type;
}
public AsThoughEffectImpl(final AsThoughEffectImpl effect) {
super(effect);
this.type = effect.type;
}
@Override
public AsThoughEffectType getAsThoughEffectType() {
return type;
}
}

View file

@ -41,6 +41,7 @@ import mage.game.Game;
*/
public interface ContinuousEffect<T extends ContinuousEffect<T>> extends Effect<T> {
public boolean isUsed();
public Duration getDuration();
public Date getTimestamp();
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game);

View file

@ -46,6 +46,7 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
protected Layer layer;
protected SubLayer sublayer;
protected Date timestamp;
protected boolean used = false;
public ContinuousEffectImpl(Duration duration, Outcome outcome) {
super(outcome);
@ -65,6 +66,7 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
this.layer = effect.layer;
this.sublayer = effect.sublayer;
this.timestamp = new Date(effect.timestamp.getTime());
this.used = effect.used;
}
@Override
@ -90,4 +92,9 @@ public abstract class ContinuousEffectImpl<T extends ContinuousEffectImpl<T>> ex
return this.layer == layer;
}
@Override
public boolean isUsed() {
return used;
}
}

View file

@ -37,6 +37,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import mage.Constants.AsThoughEffectType;
import mage.Constants.Duration;
import mage.Constants.Layer;
import mage.Constants.SubLayer;
@ -46,25 +48,35 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class ContinuousEffects implements Serializable {
private final Map<ContinuousEffect, Ability> effects = new HashMap<ContinuousEffect, Ability>();
private final Map<ContinuousEffect, Ability> layeredEffects = new HashMap<ContinuousEffect, Ability>();
private final Map<ReplacementEffect, Ability> replacementEffects = new HashMap<ReplacementEffect, Ability>();
private final Map<PreventionEffect, Ability> preventionEffects = new HashMap<PreventionEffect, Ability>();
private final Map<AsThoughEffect, Ability> asThoughEffects = new HashMap<AsThoughEffect, Ability>();
private final ApplyCountersEffect applyCounters;
public ContinuousEffects() {
applyCounters = new ApplyCountersEffect();
}
public ContinuousEffects(ContinuousEffects effect) {
public ContinuousEffects(final ContinuousEffects effect) {
this.applyCounters = effect.applyCounters.copy();
for (Entry<ContinuousEffect, Ability> entry: effect.effects.entrySet()) {
effects.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy());
for (Entry<ContinuousEffect, Ability> entry: effect.layeredEffects.entrySet()) {
layeredEffects.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy());
}
for (Entry<ReplacementEffect, Ability> entry: effect.replacementEffects.entrySet()) {
replacementEffects.put((ReplacementEffect)entry.getKey().copy(), entry.getValue().copy());
}
for (Entry<PreventionEffect, Ability> entry: effect.preventionEffects.entrySet()) {
preventionEffects.put((PreventionEffect)entry.getKey().copy(), entry.getValue().copy());
}
for (Entry<AsThoughEffect, Ability> entry: effect.asThoughEffects.entrySet()) {
asThoughEffects.put((AsThoughEffect)entry.getKey().copy(), entry.getValue().copy());
}
}
@ -73,7 +85,22 @@ public class ContinuousEffects implements Serializable {
}
public void removeEndOfTurnEffects() {
for (Iterator<ContinuousEffect> i = effects.keySet().iterator(); i.hasNext();) {
for (Iterator<ContinuousEffect> i = layeredEffects.keySet().iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<ReplacementEffect> i = replacementEffects.keySet().iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<PreventionEffect> i = preventionEffects.keySet().iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<AsThoughEffect> i = asThoughEffects.keySet().iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
@ -81,81 +108,92 @@ public class ContinuousEffects implements Serializable {
}
public void removeInactiveEffects(Game game) {
for (Iterator<ContinuousEffect> i = effects.keySet().iterator(); i.hasNext();) {
for (Iterator<ContinuousEffect> i = layeredEffects.keySet().iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(effects.get(entry).getSourceId());
Permanent permanent = game.getPermanent(layeredEffects.get(entry).getSourceId());
if (permanent == null || !permanent.isPhasedIn())
i.remove();
}
if (entry.getDuration() == Duration.OneUse) {
if (entry instanceof ReplacementEffect) {
if (((ReplacementEffect)entry).isUsed())
i.remove();
}
else if (entry.getDuration() == Duration.OneUse && entry.isUsed())
i.remove();
}
for (Iterator<ReplacementEffect> i = replacementEffects.keySet().iterator(); i.hasNext();) {
ReplacementEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(replacementEffects.get(entry).getSourceId());
if (permanent == null || !permanent.isPhasedIn())
i.remove();
}
else if (entry.getDuration() == Duration.OneUse && entry.isUsed())
i.remove();
}
for (Iterator<PreventionEffect> i = preventionEffects.keySet().iterator(); i.hasNext();) {
PreventionEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(preventionEffects.get(entry).getSourceId());
if (permanent == null || !permanent.isPhasedIn())
i.remove();
}
else if (entry.getDuration() == Duration.OneUse && entry.isUsed())
i.remove();
}
for (Iterator<AsThoughEffect> i = asThoughEffects.keySet().iterator(); i.hasNext();) {
AsThoughEffect entry = i.next();
if (entry.getDuration() == Duration.WhileOnBattlefield) {
Permanent permanent = game.getPermanent(asThoughEffects.get(entry).getSourceId());
if (permanent == null || !permanent.isPhasedIn())
i.remove();
}
else if (entry.getDuration() == Duration.OneUse && entry.isUsed())
i.remove();
}
}
private List<ContinuousEffect> getLayeredEffects() {
List<ContinuousEffect> layerEffects = new ArrayList<ContinuousEffect>();
for (ContinuousEffect effect: effects.keySet()) {
if (!(effect instanceof ReplacementEffect) && !(effect instanceof PreventionEffect)) {
layerEffects.add(effect);
}
}
List<ContinuousEffect> layerEffects = new ArrayList<ContinuousEffect>(layeredEffects.keySet());
Collections.sort(layerEffects, new TimestampSorter());
return layerEffects;
}
private List<ReplacementEffect> getApplicableReplacementEffects(GameEvent event, Game game) {
List<ReplacementEffect> replacementEffects = new ArrayList<ReplacementEffect>();
for (ContinuousEffect effect: effects.keySet()) {
if (effect instanceof ReplacementEffect && ((ReplacementEffect)effect).applies(event, effects.get(effect), game)) {
if (effect.getDuration() != Duration.OneUse || !((ReplacementEffect)effect).isUsed())
replacementEffects.add((ReplacementEffect)effect);
List<ReplacementEffect> replaceEffects = new ArrayList<ReplacementEffect>();
for (ReplacementEffect effect: replacementEffects.keySet()) {
if (effect.applies(event, replacementEffects.get(effect), game)) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed())
replaceEffects.add((ReplacementEffect)effect);
}
}
return replacementEffects;
return replaceEffects;
}
// private List<SelfReplacementEffect> GetApplicableSelfReplacementEffects(GameEvent event, Game game) {
// List<SelfReplacementEffect> effects = new ArrayList<SelfReplacementEffect>();
// for (IEffect effect: this) {
// if (effect instanceof SelfReplacementEffect && ((SelfReplacementEffect)effect).Applies(event, game)) {
// effects.add((SelfReplacementEffect)effect);
// }
// }
// return effects;
// }
public boolean asThough(UUID objectId, AsThoughEffectType type, Game game) {
for (Entry<AsThoughEffect, Ability> entry: asThoughEffects.entrySet()) {
AsThoughEffect effect = entry.getKey();
if (effect.getAsThoughEffectType() == type) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(objectId, entry.getValue(), game)) {
return true;
}
}
}
}
return false;
}
public boolean replaceEvent(GameEvent event, Game game) {
boolean caught = false;
// List<SelfReplacementEffect> srEffects = GetApplicableSelfReplacementEffects(event, game);
//
// if (srEffects.size() > 0) {
// if (srEffects.size() == 1) {
// caught = srEffects.get(0).ReplaceEvent(event, game);
// }
// else {
// //TODO: handle multiple
// }
// }
if (!caught) {
List<ReplacementEffect> rEffects = getApplicableReplacementEffects(event, game);
if (rEffects.size() > 0) {
int index;
if (rEffects.size() == 1) {
index = 0;
}
else {
Player player = game.getPlayer(event.getPlayerId());
index = player.chooseEffect(rEffects, game);
}
caught = rEffects.get(index).replaceEvent(event, effects.get(rEffects.get(index)), game);
List<ReplacementEffect> rEffects = getApplicableReplacementEffects(event, game);
if (rEffects.size() > 0) {
int index;
if (rEffects.size() == 1) {
index = 0;
}
else {
Player player = game.getPlayer(event.getPlayerId());
index = player.chooseEffect(rEffects, game);
}
caught = rEffects.get(index).replaceEvent(event, replacementEffects.get(rEffects.get(index)), game);
}
return caught;
@ -164,96 +202,75 @@ public class ContinuousEffects implements Serializable {
//20091005 - 613
public void apply(Game game) {
removeInactiveEffects(game);
List<ContinuousEffect> layeredEffects = getLayeredEffects();
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
List<ContinuousEffect> layerEffects = getLayeredEffects();
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, layeredEffects.get(effect), game);
}
applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game);
// for (ContinuousEffect effect: layeredEffects) {
// effect.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, game);
// }
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, layeredEffects.get(effect), game);
}
for (ContinuousEffect effect: layeredEffects) {
effect.apply(Layer.RulesEffects, SubLayer.NA, effects.get(effect), game);
for (ContinuousEffect effect: layerEffects) {
effect.apply(Layer.RulesEffects, SubLayer.NA, layeredEffects.get(effect), game);
}
}
// protected void applyCounters(Game game) {
// for (Permanent permanent: game.getBattlefield().getAllActivePermanents(CardType.CREATURE)) {
// for (BoostCounter counter: permanent.getCounters().getBoostCounters()) {
// permanent.addPower(counter.getPower() * counter.getCount());
// permanent.addToughness(counter.getToughness() * counter.getCount());
// }
// }
// }
// public String getText() {
// StringBuilder sbText = new StringBuilder();
// for (ActiveContinuousEffect effect: effects) {
// sbText.append(effect.getEffect().getText()).append(" ");
// }
// return sbText.toString();
// }
public void addEffect(ContinuousEffect effect, Ability source) {
effects.put(effect, source);
if (effect instanceof ReplacementEffect)
replacementEffects.put((ReplacementEffect)effect, source);
else if (effect instanceof PreventionEffect)
preventionEffects.put((PreventionEffect)effect, source);
else if (effect instanceof AsThoughEffect)
asThoughEffects.put((AsThoughEffect) effect,source);
else
layeredEffects.put(effect, source);
}
// public boolean effectExists(UUID abilityId) {
// for (ContinuousEffect effect: effects) {
// if (effect.getSource().getId().equals(abilityId))
// return true;
// }
// return false;
// }
}
class TimestampSorter implements Comparator<ContinuousEffect> {

View file

@ -61,5 +61,4 @@ public abstract class PreventionEffectImpl<T extends PreventionEffectImpl<T>> ex
}
}
}

View file

@ -40,6 +40,5 @@ public interface ReplacementEffect<T extends ReplacementEffect<T>> extends Conti
public boolean replaceEvent(GameEvent event, Ability source, Game game);
public boolean applies(GameEvent event, Ability source, Game game);
boolean isUsed();
}

View file

@ -37,20 +37,12 @@ import mage.Constants.Outcome;
*/
public abstract class ReplacementEffectImpl<T extends ReplacementEffectImpl<T>> extends ContinuousEffectImpl<T> implements ReplacementEffect<T> {
protected boolean used = false;
public ReplacementEffectImpl(Duration duration, Outcome outcome) {
super(duration, outcome);
}
public ReplacementEffectImpl(final ReplacementEffectImpl effect) {
super(effect);
this.used = effect.used;
}
@Override
public boolean isUsed() {
return used;
}
}

View file

@ -30,15 +30,18 @@ package mage.abilities.effects.common;
import mage.Constants.Duration;
import mage.Constants.Outcome;
import mage.Constants.TargetController;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.filter.FilterObject;
import mage.filter.FilterPermanent;
import mage.filter.FilterStackObject;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
/**
*
@ -47,9 +50,9 @@ import mage.game.permanent.Permanent;
public class CantTargetControlledEffect extends ReplacementEffectImpl<CantTargetControlledEffect> {
private FilterPermanent filterTarget;
private FilterObject filterSource;
private FilterStackObject filterSource;
public CantTargetControlledEffect(FilterPermanent filterTarget, FilterObject filterSource, Duration duration) {
public CantTargetControlledEffect(FilterPermanent filterTarget, FilterStackObject filterSource, Duration duration) {
super(duration, Outcome.Benefit);
this.filterTarget = filterTarget;
this.filterSource = filterSource;
@ -83,14 +86,15 @@ public class CantTargetControlledEffect extends ReplacementEffectImpl<CantTarget
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.TARGET) {
filterTarget.getControllerId().clear();
filterTarget.getControllerId().add(source.getControllerId());
filterTarget.setTargetController(TargetController.YOU);
// filterTarget.getControllerId().clear();
// filterTarget.getControllerId().add(source.getControllerId());
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && filterTarget.match(permanent)) {
if (permanent != null && filterTarget.match(permanent, source.getControllerId(), game)) {
if (filterSource == null)
return true;
else {
MageObject sourceObject = game.getObject(source.getSourceId());
StackObject sourceObject = game.getStack().getStackObject(source.getSourceId());
if (sourceObject != null && filterSource.match(sourceObject)) {
return true;
}

View file

@ -0,0 +1,94 @@
/*
* 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.Constants.Duration;
import mage.Constants.Outcome;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.filter.FilterObject;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CantTargetControllerEffect extends ReplacementEffectImpl<CantTargetControllerEffect> {
private FilterObject filterSource;
public CantTargetControllerEffect(FilterObject filterSource, Duration duration) {
super(duration, Outcome.Benefit);
this.filterSource = filterSource;
}
public CantTargetControllerEffect(final CantTargetControllerEffect effect) {
super(effect);
this.filterSource = effect.filterSource.copy();
}
@Override
public CantTargetControllerEffect copy() {
return new CantTargetControllerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
return true;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.TARGET && event.getTargetId().equals(source.getControllerId())) {
MageObject sourceObject = game.getObject(source.getSourceId());
if (sourceObject != null && filterSource.match(sourceObject)) {
return true;
}
}
return false;
}
@Override
public String getText(Ability source) {
StringBuilder sb = new StringBuilder();
sb.append("{this} can't be the targets of ");
sb.append(filterSource.getMessage());
sb.append(" ").append(duration.toString());
return sb.toString();
}
}

View file

@ -76,7 +76,7 @@ public class CounterUnlessPaysEffect extends OneShotEffect<CounterUnlessPaysEffe
@Override
public String getText(Ability source) {
return "Counter target " + source.getTargets().get(0).getTargetName() + " unless its controller pays ";
return "Counter target " + source.getTargets().get(0).getTargetName() + " unless its controller pays " + cost.getText();
}
}

View file

@ -67,9 +67,8 @@ public class CreateTokenEffect extends OneShotEffect<CreateTokenEffect> {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
for (int i = 0; i < amount; i++) {
controller.putOntoBattlefield(token, game);
token.putOntoBattlefield(game, source.getControllerId());
}
return true;
}

View file

@ -63,7 +63,7 @@ public class DamageAllEffect extends OneShotEffect<DamageAllEffect> {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter)) {
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
permanent.damage(amount, source.getSourceId(), game, true);
}
return true;

View file

@ -82,7 +82,6 @@ public class DamageControllerEffect extends OneShotEffect<DamageControllerEffect
public String getText(Ability source) {
StringBuilder sb = new StringBuilder();
sb.append("{source} deals ").append(Integer.toString(amount)).append(" damage to you");
sb.append(source.getTargets().get(0).getTargetName());
if (!preventable)
sb.append(". The damage can't be prevented");
return sb.toString();

View file

@ -0,0 +1,81 @@
/*
* 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 java.util.UUID;
import mage.Constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DamageEverythingEffect extends OneShotEffect<DamageEverythingEffect> {
private int amount;
public DamageEverythingEffect(int amount) {
super(Outcome.Damage);
this.amount = amount;
}
public DamageEverythingEffect(final DamageEverythingEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
public DamageEverythingEffect copy() {
return new DamageEverythingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) {
permanent.damage(amount, source.getId(), game, true);
}
for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()) {
Player player = game.getPlayer(playerId);
if (player != null)
player.damage(amount, source.getId(), game, false, true);
}
return true;
}
@Override
public String getText(Ability source) {
return "{source} deals " + Integer.toString(amount) + " damage to each creature and each player";
}
}

View file

@ -28,6 +28,7 @@
package mage.abilities.effects.common;
import java.util.UUID;
import mage.Constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@ -60,8 +61,11 @@ public class DrawCardAllEffect extends OneShotEffect<DrawCardAllEffect> {
@Override
public boolean apply(Game game, Ability source) {
for (Player player: game.getPlayers().values()) {
player.drawCards(amount, game);
Player sourcePlayer = game.getPlayer(source.getControllerId());
for (UUID playerId: sourcePlayer.getInRange()) {
Player player = game.getPlayer(playerId);
if (player != null)
player.drawCards(amount, game);
}
return true;
}

View file

@ -61,7 +61,12 @@ public class PreventAllCombatDamageEffect extends PreventionEffectImpl<PreventAl
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(0);
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
return false;
}

View file

@ -61,7 +61,12 @@ public class PreventAllDamageSourceEffect extends PreventionEffectImpl<PreventAl
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(0);
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
return false;
}

View file

@ -67,7 +67,12 @@ public class PreventAllDamageToEffect extends PreventionEffectImpl<PreventAllDam
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
event.setAmount(0);
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
return false;
}

View file

@ -64,13 +64,19 @@ public class PreventDamageTargetEffect extends PreventionEffectImpl<PreventDamag
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
if (event.getAmount() >= this.amount) {
event.setAmount(event.getAmount() - amount);
this.used = true;
} else {
int damage = event.getAmount();
event.setAmount(0);
amount -= damage;
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount());
if (!game.replaceEvent(preventEvent)) {
if (event.getAmount() >= this.amount) {
int damage = event.getAmount();
event.setAmount(event.getAmount() - amount);
this.used = true;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
} else {
int damage = event.getAmount();
event.setAmount(0);
amount -= damage;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage));
}
}
return false;
}

View file

@ -73,11 +73,12 @@ public class PutOnLibraryTargetEffect extends OneShotEffect<PutOnLibraryTargetEf
for (Player player: game.getPlayers().values()) {
if (player.getGraveyard().contains(card.getId())) {
player.getGraveyard().remove(card);
if (onTop)
player.getLibrary().putOnTop(card, game);
else
player.getLibrary().putOnBottom(card, game);
return true;
return card.moveToZone(Zone.LIBRARY, game, onTop);
// if (onTop)
// player.getLibrary().putOnTop(card, game);
// else
// player.getLibrary().putOnBottom(card, game);
// return true;
}
}
}

View file

@ -35,6 +35,7 @@ import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.game.Game;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
/**
@ -68,18 +69,7 @@ public class ReturnFromExileEffect extends OneShotEffect<ReturnFromExileEffect>
Player player;
for (UUID cardId: game.getExile().getExileZone(exileId)) {
Card card = game.getCard(cardId);
player = game.getPlayer(card.getOwnerId());
switch(zone) {
case BATTLEFIELD:
player.putOntoBattlefield(card, game);
break;
case HAND:
player.putInHand(card, game);
break;
case GRAVEYARD:
player.putInGraveyard(card, game, false);
break;
}
card.moveToZone(zone, game, false);
}
game.getExile().getExileZone(exileId).clear();
return true;

View file

@ -29,6 +29,7 @@
package mage.abilities.effects.common;
import mage.Constants.Outcome;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@ -59,8 +60,8 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect<
Player player = game.getPlayer(source.getControllerId());
Card card = player.getGraveyard().get(source.getSourceId(), game);
if (card != null) {
player.putOntoBattlefield(card, game);
player.removeFromGraveyard(card, game);
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId());
return true;
}
return false;
@ -71,5 +72,4 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect<
return "Return {this} from your graveyard to the battlefield";
}
}

View file

@ -0,0 +1,75 @@
/*
* 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.Constants.Outcome;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class ReturnSourceFromGraveyardToHandEffect extends OneShotEffect<ReturnSourceFromGraveyardToHandEffect> {
public ReturnSourceFromGraveyardToHandEffect() {
super(Outcome.PutCreatureInPlay);
}
public ReturnSourceFromGraveyardToHandEffect(final ReturnSourceFromGraveyardToHandEffect effect) {
super(effect);
}
@Override
public ReturnSourceFromGraveyardToHandEffect copy() {
return new ReturnSourceFromGraveyardToHandEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Card card = player.getGraveyard().get(source.getSourceId(), game);
if (card != null) {
player.removeFromGraveyard(card, game);
card.moveToZone(Zone.HAND, game, false);
return true;
}
return false;
}
@Override
public String getText(Ability source) {
return "Return {this} from your graveyard to your hand";
}
}

View file

@ -76,7 +76,8 @@ public class SacrificeAllEffect extends OneShotEffect<SacrificeAllEffect> {
List<UUID> perms = new ArrayList<UUID>();
for (Player player: game.getPlayers().values()) {
int numTargets = Math.min(amount, game.getBattlefield().countAll(filter, player.getId()));
TargetPermanent target = new TargetPermanent(numTargets, filter, TargetController.YOU);
filter.setTargetController(TargetController.YOU);
TargetPermanent target = new TargetPermanent(numTargets, filter);
while (!target.isChosen()) {
player.choose(Outcome.Sacrifice, target, game);
}

View file

@ -72,7 +72,8 @@ public class ScryEffect extends OneShotEffect<ScryEffect> {
while (cards.size() > 0 && player.chooseTarget(cards, target1, source, game)) {
Card card = cards.get(target1.getFirstTarget(), game);
cards.remove(card);
player.getLibrary().putOnBottom(card, game);
card.moveToZone(Zone.LIBRARY, game, false);
// player.getLibrary().putOnBottom(card, game);
target1.clearChosen();
}
if (cards.size() > 1) {
@ -82,12 +83,16 @@ public class ScryEffect extends OneShotEffect<ScryEffect> {
player.chooseTarget(cards, target2, source, game);
Card card = cards.get(target2.getFirstTarget(), game);
cards.remove(card);
player.getLibrary().putOnTop(card, game);
card.moveToZone(Zone.LIBRARY, game, true);
// player.getLibrary().putOnTop(card, game);
target2.clearChosen();
}
}
if (cards.size() == 1)
player.getLibrary().putOnTop(cards.get(cards.iterator().next(), game), game);
if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
card.moveToZone(Zone.LIBRARY, game, true);
// player.getLibrary().putOnTop(cards.get(cards.iterator().next(), game), game);
}
return true;
}

View file

@ -31,6 +31,7 @@ package mage.abilities.effects.common;
import java.util.List;
import java.util.UUID;
import mage.Constants.Outcome;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
@ -65,7 +66,7 @@ public class SearchLibraryPutInHandEffect extends SearchEffect<SearchLibraryPutI
for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null){
player.putInHand(card, game);
card.moveToZone(Zone.HAND, game, false);
}
}
player.shuffleLibrary(game);
@ -89,9 +90,4 @@ public class SearchLibraryPutInHandEffect extends SearchEffect<SearchLibraryPutI
return sb.toString();
}
// @Override
// public void setSource(Ability ability) {
// super.setSource(ability);
// target.setAbility(ability);
// }
}

View file

@ -31,6 +31,7 @@ package mage.abilities.effects.common;
import java.util.List;
import java.util.UUID;
import mage.Constants.Outcome;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
@ -78,7 +79,7 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect<SearchLibraryPutI
for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null) {
if (player.putOntoBattlefield(card, game)) {
if (card.putOntoBattlefield(game, Zone.HAND, source.getControllerId())) {
if (tapped) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null)
@ -111,10 +112,4 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect<SearchLibraryPutI
return sb.toString();
}
// @Override
// public void setSource(Ability ability) {
// super.setSource(ability);
// target.setAbility(ability);
// }
}

View file

@ -0,0 +1,84 @@
/*
* 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 java.util.List;
import java.util.UUID;
import mage.Constants.Outcome;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class SearchLibraryPutOnLibraryEffect extends SearchEffect<SearchLibraryPutOnLibraryEffect> {
public SearchLibraryPutOnLibraryEffect(TargetCardInLibrary target) {
super(target, Outcome.DrawCard);
}
public SearchLibraryPutOnLibraryEffect(final SearchLibraryPutOnLibraryEffect effect) {
super(effect);
}
@Override
public SearchLibraryPutOnLibraryEffect copy() {
return new SearchLibraryPutOnLibraryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
player.searchLibrary(target, game);
if (target.getTargets().size() > 0) {
for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null){
card.moveToZone(Zone.LIBRARY, game, true);
}
}
player.shuffleLibrary(game);
}
return true;
}
@Override
public String getText(Ability source) {
StringBuilder sb = new StringBuilder();
sb.append("Search your library for a ").append(target.getTargetName()).append(", then shuffle your library and put that card on top of it");
return sb.toString();
}
}

View file

@ -69,7 +69,7 @@ public class SearchLibraryRevealPutInHandEffect extends SearchEffect<SearchLibra
for (UUID cardId: (List<UUID>)target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
if (card != null) {
player.putInHand(card, game);
card.moveToZone(Zone.HAND, game, false);
revealed.add(card);
}
}

View file

@ -96,7 +96,8 @@ class CascadeEffect extends OneShotEffect<CascadeEffect> {
card = player.getLibrary().removeFromTop(game);
if (card == null)
break;
exile.add(card);
card.moveToExile(exile.getId(), exile.getName(), game);
// exile.add(card);
} while (card.getCardType().contains(CardType.LAND) || card.getManaCost().convertedManaCost() >= sourceCost);
if (card != null) {
@ -109,7 +110,8 @@ class CascadeEffect extends OneShotEffect<CascadeEffect> {
while (exile.size() > 0) {
card = exile.getRandom(game);
exile.remove(card.getId());
player.getLibrary().putOnBottom(card, game);
card.moveToZone(Zone.LIBRARY, game, false);
// player.getLibrary().putOnBottom(card, game);
}
return true;

View file

@ -35,6 +35,7 @@ import mage.Constants.Zone;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.Cost;
import mage.abilities.effects.common.AttachEffect;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
@ -43,9 +44,15 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class EquipAbility extends ActivatedAbilityImpl<EquipAbility> {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control");
static {
filter.setTargetController(TargetController.YOU);
}
public EquipAbility(Outcome outcome, Cost cost) {
super(Zone.BATTLEFIELD, new AttachEffect(outcome), cost);
this.addTarget(new TargetCreaturePermanent(1, TargetController.YOU));
this.addTarget(new TargetCreaturePermanent(filter));
this.timing = TimingRule.SORCERY;
}

View file

@ -34,18 +34,26 @@ import mage.Constants.Zone;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.Cost;
import mage.abilities.effects.common.AttachEffect;
import mage.filter.common.FilterLandPermanent;
import mage.target.common.TargetLandPermanent;
/**
*
* @author BetaSteward_at_googlemail.com
*/
//20091005 - 702.64
public class FortifyAbility extends ActivatedAbilityImpl<FortifyAbility> {
//20091005 - 702.64
private static FilterLandPermanent filter = new FilterLandPermanent("land you control");
static {
filter.setTargetController(TargetController.YOU);
}
public FortifyAbility(Zone zone, AttachEffect effect, Cost cost) {
super(zone, effect, cost);
this.addTarget(new TargetLandPermanent(1, TargetController.YOU));
this.addTarget(new TargetLandPermanent(filter));
timing = TimingRule.SORCERY;
}

View file

@ -0,0 +1,65 @@
/*
* 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.keyword;
import java.io.ObjectStreamException;
import mage.Constants.Zone;
import mage.abilities.StaticAbility;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class LeylineAbility extends StaticAbility<LeylineAbility>{
private static final LeylineAbility fINSTANCE = new LeylineAbility();
private Object readResolve() throws ObjectStreamException {
return fINSTANCE;
}
public static LeylineAbility getInstance() {
return fINSTANCE;
}
private LeylineAbility() {
super(Zone.HAND, null);
}
@Override
public String getRule() {
return "If {this} is in your opening hand, you may begin the game with it on the battlefield.";
}
@Override
public LeylineAbility copy() {
return fINSTANCE;
}
}

View file

@ -54,6 +54,9 @@ public interface Card extends MageObject {
public String getExpansionSetCode();
public void setExpansionSetCode(String expansionSetCode);
public boolean moveToZone(Zone zone, Game game, boolean flag);
public boolean moveToExile(UUID exileId, String name, Game game);
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId);
public void checkTriggers(Zone zone, GameEvent event, Game game);
@Override

View file

@ -41,6 +41,8 @@ import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbility;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.PermanentCard;
import mage.watchers.Watchers;
public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T> implements Card {
@ -166,4 +168,61 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
public void setExpansionSetCode(String expansionSetCode) {
this.expansionSetCode = expansionSetCode;
}
@Override
public boolean moveToZone(Zone toZone, Game game, boolean flag) {
Zone fromZone = zone;
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), ownerId, fromZone, toZone);
if (!game.replaceEvent(event)) {
switch (event.getToZone()) {
case GRAVEYARD:
game.getPlayer(ownerId).putInGraveyard(this, game, !flag);
break;
case HAND:
game.getPlayer(ownerId).getHand().add(this);
break;
case EXILED:
game.getExile().getPermanentExile().add(this);
break;
case LIBRARY:
if (flag)
game.getPlayer(ownerId).getLibrary().putOnTop(this, game);
else
game.getPlayer(ownerId).getLibrary().putOnBottom(this, game);
}
zone = event.getToZone();
game.fireEvent(new ZoneChangeEvent(this.getId(), ownerId, fromZone, event.getToZone()));
return zone == toZone;
}
return false;
}
@Override
public boolean moveToExile(UUID exileId, String name, Game game) {
Zone fromZone = zone;
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), ownerId, fromZone, Zone.EXILED);
if (!game.replaceEvent(event)) {
if (exileId == null) {
game.getExile().getPermanentExile().add(this);
}
else {
game.getExile().createZone(exileId, name).add(this);
}
game.fireEvent(new ZoneChangeEvent(this.getId(), ownerId, fromZone, Zone.EXILED));
return true;
}
return false;
}
@Override
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId) {
PermanentCard permanent = new PermanentCard(this, controllerId);
game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game);
game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent.getId(), controllerId, fromZone, Zone.BATTLEFIELD));
return true;
}
}

View file

@ -29,6 +29,7 @@
package mage.filter;
import java.io.Serializable;
import java.util.UUID;
/**
*

View file

@ -31,6 +31,8 @@ package mage.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.Constants.TargetController;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
@ -50,12 +52,13 @@ public class FilterPermanent<T extends FilterPermanent<T>> extends FilterObject<
protected boolean faceup;
protected boolean usePhased;
protected boolean phasedIn;
protected TargetController controller = TargetController.ANY;
public FilterPermanent() {
super("permanent");
}
public FilterPermanent(FilterPermanent<T> filter) {
public FilterPermanent(final FilterPermanent<T> filter) {
super(filter);
for (UUID oId: filter.ownerId) {
this.ownerId.add(oId);
@ -73,6 +76,7 @@ public class FilterPermanent<T extends FilterPermanent<T>> extends FilterObject<
this.faceup = filter.faceup;
this.usePhased = filter.usePhased;
this.phasedIn = filter.phasedIn;
this.controller = filter.controller;
}
public FilterPermanent(String name) {
@ -105,6 +109,30 @@ public class FilterPermanent<T extends FilterPermanent<T>> extends FilterObject<
return !notFilter;
}
public boolean match(Permanent permanent, UUID playerId, Game game) {
if (!this.match(permanent))
return notFilter;
if (controller != TargetController.ANY && playerId != null) {
switch(controller) {
case YOU:
if (!permanent.getControllerId().equals(playerId))
return notFilter;
break;
case OPPONENT:
if (!game.getOpponents(playerId).contains(permanent.getControllerId()))
return notFilter;
break;
case NOT_YOU:
if (permanent.getControllerId().equals(playerId))
return notFilter;
break;
}
}
return !notFilter;
}
public List<UUID> getOwnerId() {
return ownerId;
}
@ -145,6 +173,30 @@ public class FilterPermanent<T extends FilterPermanent<T>> extends FilterObject<
this.faceup = faceup;
}
public void setTargetController(TargetController controller) {
this.controller = controller;
}
// public void setController(UUID playerId, Game game) {
// controllerId.clear();
// switch (controller) {
// case ANY:
// break;
// case YOU:
// controllerId.add(playerId);
// notController = false;
// break;
// case NOT_YOU:
// controllerId.add(playerId);
// notController = true;
// break;
// case OPPONENT:
// controllerId.addAll(game.getOpponents(playerId));
// notController = false;
// break;
// }
// }
public boolean matchOwner(UUID testOwnerId) {
if (ownerId.size() > 0 && ownerId.contains(testOwnerId) == notOwner)
return false;

View file

@ -28,19 +28,15 @@
package mage.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.game.stack.Spell;
import mage.game.stack.StackObject;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterSpell extends FilterObject<Spell, FilterSpell> {
protected List<UUID> controllerId = new ArrayList<UUID>();
protected boolean notController = false;
public class FilterSpell extends FilterStackObject<FilterSpell> {
public FilterSpell() {
super("spell");
@ -56,26 +52,15 @@ public class FilterSpell extends FilterObject<Spell, FilterSpell> {
this.controllerId.add(cId);
}
this.notController = filter.notController;
this.controller = filter.controller;
}
@Override
public boolean match(Spell spell) {
if (!super.match(spell))
public boolean match(StackObject spell) {
if (!(spell instanceof Spell))
return notFilter;
if (controllerId.size() > 0 && controllerId.contains(spell.getControllerId()) == notController)
return notFilter;
return !notFilter;
}
public List<UUID> getControllerId() {
return controllerId;
}
public void setNotController(boolean notController) {
this.notController = notController;
return super.match(spell);
}
@Override

View file

@ -31,16 +31,19 @@ package mage.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.Constants.TargetController;
import mage.game.Game;
import mage.game.stack.StackObject;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterStackObject extends FilterObject<StackObject, FilterStackObject> {
public class FilterStackObject<T extends FilterStackObject<T>> extends FilterObject<StackObject, FilterStackObject<T>> {
protected List<UUID> controllerId = new ArrayList<UUID>();
protected boolean notController = false;
protected TargetController controller = TargetController.ANY;
public FilterStackObject() {
super("spell or ability");
@ -50,12 +53,13 @@ public class FilterStackObject extends FilterObject<StackObject, FilterStackObje
super(name);
}
public FilterStackObject(final FilterStackObject filter) {
public FilterStackObject(final FilterStackObject<T> filter) {
super(filter);
for (UUID cId: filter.controllerId) {
this.controllerId.add(cId);
}
this.notController = filter.notController;
this.controller = filter.controller;
}
@Override
@ -70,6 +74,30 @@ public class FilterStackObject extends FilterObject<StackObject, FilterStackObje
return !notFilter;
}
public boolean match(StackObject spell, UUID playerId, Game game) {
if (!this.match(spell))
return notFilter;
if (controller != TargetController.ANY && playerId != null) {
switch(controller) {
case YOU:
if (!spell.getControllerId().equals(playerId))
return notFilter;
break;
case OPPONENT:
if (!game.getOpponents(playerId).contains(spell.getControllerId()))
return notFilter;
break;
case NOT_YOU:
if (spell.getControllerId().equals(playerId))
return notFilter;
break;
}
}
return !notFilter;
}
public List<UUID> getControllerId() {
return controllerId;
}
@ -78,6 +106,10 @@ public class FilterStackObject extends FilterObject<StackObject, FilterStackObje
this.notController = notController;
}
public void setTargetController(TargetController controller) {
this.controller = controller;
}
@Override
public FilterStackObject copy() {
return new FilterStackObject(this);

View file

@ -0,0 +1,59 @@
/*
* 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.filter.common;
import mage.Constants.CardType;
import mage.Constants.TargetController;
import mage.filter.FilterPermanent;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterControlledCreaturePermanent extends FilterControlledPermanent<FilterControlledCreaturePermanent> {
public FilterControlledCreaturePermanent() {
this("creature you control");
}
public FilterControlledCreaturePermanent(String name) {
super(name);
cardType.add(CardType.CREATURE);
}
public FilterControlledCreaturePermanent(final FilterControlledCreaturePermanent filter) {
super(filter);
}
@Override
public FilterControlledCreaturePermanent copy() {
return new FilterControlledCreaturePermanent(this);
}
}

View file

@ -0,0 +1,58 @@
/*
* 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.filter.common;
import mage.Constants.TargetController;
import mage.filter.FilterPermanent;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterControlledPermanent<T extends FilterControlledPermanent<T>> extends FilterPermanent<FilterControlledPermanent<T>> {
public FilterControlledPermanent() {
this("permanent you control");
}
public FilterControlledPermanent(String name) {
super(name);
this.controller = TargetController.YOU;
}
public FilterControlledPermanent(final FilterControlledPermanent filter) {
super(filter);
}
@Override
public FilterControlledPermanent copy() {
return new FilterControlledPermanent(this);
}
}

View file

@ -32,6 +32,7 @@ import java.util.UUID;
import mage.filter.Filter;
import mage.filter.FilterImpl;
import mage.filter.FilterPlayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -77,6 +78,17 @@ public class FilterCreatureOrPlayer extends FilterImpl<Object, FilterCreatureOrP
return notFilter;
}
public boolean match(Object o, UUID playerId, Game game) {
if (o instanceof Player) {
return playerFilter.match((Player)o);
}
else if (o instanceof Permanent) {
return creatureFilter.match((Permanent)o, playerId, game);
}
return notFilter;
}
@Override
public FilterCreatureOrPlayer copy() {
return new FilterCreatureOrPlayer(this);

View file

@ -53,10 +53,10 @@ import mage.abilities.TriggeredAbilities;
import mage.abilities.TriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects;
import mage.abilities.keyword.LeylineAbility;
import mage.cards.Card;
import mage.cards.Cards;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.filter.Filter.ComparisonScope;
import mage.filter.common.FilterEquipment;
import mage.filter.common.FilterFortification;
@ -342,6 +342,18 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
saveState();
}
//20100716 - 103.5
for (UUID playerId: state.getPlayerList(startingPlayerId)) {
Player player = getPlayer(playerId);
for (Card card: player.getHand().getCards(this)) {
if (card.getAbilities().containsKey(LeylineAbility.getInstance().getId())) {
if (!player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this)) {
player.getHand().remove(card);
card.putOntoBattlefield(this, Zone.HAND, player.getId());
}
}
}
}
}
protected UUID findWinner() {

View file

@ -44,6 +44,10 @@ public class GameEvent {
public enum EventType {
//Game events
BEGINNING,
PREVENT_DAMAGE, PREVENTED_DAMAGE,
//Turn-based events
CHANGE_PHASE, PHASE_CHANGED,
CHANGE_STEP, STEP_CHANGED,
@ -64,7 +68,6 @@ public class GameEvent {
END_PHASE, END_PHASE_PRE, END_PHASE_POST,
END_TURN_STEP_PRE, END_TURN_STEP, END_TURN_STEP_POST,
CLEANUP_STEP_PRE, CLEANUP_STEP, CLEANUP_STEP_POST,
EMPTY_MANA_POOLS,
AT_END_OF_TURN,

View file

@ -57,4 +57,8 @@ public class ZoneChangeEvent extends GameEvent {
public Zone getToZone() {
return toZone;
}
public void setToZone(Zone toZone) {
this.toZone = toZone;
}
}

View file

@ -98,7 +98,7 @@ public class Battlefield implements Serializable {
int count = 0;
if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) {
for (Permanent permanent: field.values()) {
if (filter.match(permanent)) {
if (filter.match(permanent, sourcePlayerId, game)) {
count++;
}
}
@ -106,7 +106,7 @@ public class Battlefield implements Serializable {
else {
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
for (Permanent permanent: field.values()) {
if (range.contains(permanent.getControllerId()) && filter.match(permanent)) {
if (range.contains(permanent.getControllerId()) && filter.match(permanent, sourcePlayerId, game)) {
count++;
}
}
@ -257,7 +257,7 @@ public class Battlefield implements Serializable {
List<Permanent> active = new ArrayList<Permanent>();
Set<UUID> range = game.getPlayer(sourcePlayerId).getInRange();
for (Permanent perm: field.values()) {
if (perm.isPhasedIn() && range.contains(perm.getControllerId()) && filter.match(perm))
if (perm.isPhasedIn() && range.contains(perm.getControllerId()) && filter.match(perm, sourcePlayerId, game))
active.add(perm);
}
return active;

View file

@ -112,27 +112,11 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
@Override
public boolean moveToZone(Zone zone, Game game, boolean flag) {
if (!game.replaceEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone))) {
ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone);
if (!game.replaceEvent(event)) {
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
switch (zone) {
case GRAVEYARD:
game.getPlayer(ownerId).putInGraveyard(game.getCard(objectId), game, !flag);
break;
case HAND:
game.getPlayer(ownerId).getHand().add(game.getCard(objectId));
break;
case EXILED:
game.getExile().getPermanentExile().add(game.getCard(objectId));
break;
case LIBRARY:
if (flag)
game.getPlayer(ownerId).getLibrary().putOnTop(game.getCard(objectId), game);
else
game.getPlayer(ownerId).getLibrary().putOnBottom(game.getCard(objectId), game);
}
game.fireEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone));
return true;
Card card = game.getCard(objectId);
return card.moveToZone(event.getToZone(), game, flag);
}
}
return false;
@ -140,17 +124,8 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
@Override
public boolean moveToExile(UUID exileId, String name, Game game) {
if (!game.replaceEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED))) {
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
if (exileId == null) {
game.getExile().getPermanentExile().add(game.getCard(objectId));
}
else {
game.getExile().createZone(exileId, name).add(game.getCard(objectId));
}
game.fireEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED));
return true;
}
if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) {
return game.getCard(objectId).moveToExile(exileId, name, game);
}
return false;
}

View file

@ -43,8 +43,8 @@ public class PermanentToken extends PermanentImpl<PermanentToken> {
protected Token token;
public PermanentToken(Token token, UUID ownerId, UUID controllerId) {
super(ownerId, controllerId, token.getName());
public PermanentToken(Token token, UUID controllerId) {
super(controllerId, controllerId, token.getName());
this.token = token;
copyFromToken(token);
}
@ -104,6 +104,10 @@ public class PermanentToken extends PermanentImpl<PermanentToken> {
@Override
public void setArt(String art) { }
public Token getToken() {
return token;
}
@Override
public PermanentToken copy() {
return new PermanentToken(this);

View file

@ -29,11 +29,16 @@
package mage.game.permanent.token;
import java.util.List;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Zone;
import mage.MageObjectImpl;
import mage.ObjectColor;
import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.game.Game;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.PermanentToken;
public class Token extends MageObjectImpl<Token> {
@ -74,4 +79,14 @@ public class Token extends MageObjectImpl<Token> {
public Token copy() {
return new Token(this);
}
public boolean putOntoBattlefield(Game game, UUID controllerId) {
PermanentToken permanent = new PermanentToken(this, controllerId);
game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game);
game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent.getId(), controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD));
return true;
}
}

View file

@ -44,7 +44,6 @@ import mage.abilities.effects.common.ExileSpellEffect;
import mage.abilities.keyword.KickerAbility;
import mage.cards.Card;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.watchers.Watchers;
/**
@ -83,7 +82,8 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
if (ability.getEffects().contains(ExileSpellEffect.getInstance()))
game.getExile().getPermanentExile().add(card);
else
game.getPlayers().get(controllerId).putInGraveyard(card, game, false);
card.moveToZone(Zone.GRAVEYARD, game, false);
// game.getPlayers().get(controllerId).putInGraveyard(card, game, false);
return result;
}
//20091005 - 608.2b
@ -92,8 +92,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
}
else if (card.getCardType().contains(CardType.ENCHANTMENT) && card.getSubtype().contains("Aura")) {
if (ability.getTargets().stillLegal(ability, game)) {
Player controller = game.getPlayers().get(controllerId);
if (controller.putOntoBattlefield(card, game)) {
if (card.putOntoBattlefield(game, Zone.HAND, controllerId)) {
return ability.resolve(game);
}
return false;
@ -103,8 +102,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
return false;
}
else {
Player controller = game.getPlayers().get(controllerId);
result = controller.putOntoBattlefield(card, game);
result = card.putOntoBattlefield(game, Zone.HAND, controllerId);
resolveKicker(game);
return result;
}
@ -125,7 +123,7 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
@Override
public void counter(Game game) {
game.getPlayers().get(controllerId).putInGraveyard(card, game, false);
card.moveToZone(Zone.GRAVEYARD, game, false);
}
@Override
@ -273,4 +271,19 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
@Override
public void adjustCosts(Ability ability, Game game) {}
@Override
public boolean moveToZone(Zone zone, Game game, boolean flag) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean moveToExile(UUID exileId, String name, Game game) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId) {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View file

@ -268,4 +268,19 @@ public class StackAbility implements StackObject, Ability {
@Override
public void adjustCosts(Ability ability, Game game) {}
@Override
public Costs<Cost> getOptionalCosts() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void addOptionalCost(Cost cost) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean checkIfClause(Game game) {
return true;
}
}

View file

@ -33,6 +33,7 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.Constants.Outcome;
import mage.Constants.Zone;
import mage.MageItem;
import mage.MageObject;
import mage.abilities.Abilities;
@ -95,9 +96,6 @@ public interface Player extends MageItem, Copyable<Player> {
public boolean cast(SpellAbility ability, Game game, boolean noMana);
public boolean putInHand(Card card, Game game);
public boolean removeFromHand(Card card, Game game);
public boolean putOntoBattlefield(Card card, Game game);
// public boolean putOntoBattlefield(Card copy, Card card, Game game);
public boolean putOntoBattlefield(Token token, Game game);
public boolean removeFromBattlefield(Permanent permanent, Game game);
public boolean putInGraveyard(Card card, Game game, boolean fromBattlefield);
public boolean removeFromGraveyard(Card card, Game game);

View file

@ -259,7 +259,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, null, playerId))) {
Card card = getLibrary().removeFromTop(game);
if (card != null) {
putInHand(card, game);
card.moveToZone(Zone.HAND, game, false);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DREW_CARD, card.getId(), playerId));
return true;
}
@ -293,8 +293,6 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
public boolean putInHand(Card card, Game game) {
if (card.getOwnerId().equals(playerId)) {
this.hand.add(card);
// if (card.getSpellAbility() != null)
// card.getSpellAbility().clear();
} else {
return game.getPlayer(card.getOwnerId()).putInHand(card, game);
}
@ -330,34 +328,14 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
//20091005 - 701.1
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DISCARD_CARD, playerId, playerId))) {
removeFromHand(card, game);
putInGraveyard(card, game, false);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, playerId, playerId));
return true;
if (card.moveToZone(Zone.GRAVEYARD, game, false)) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, playerId, playerId));
return true;
}
}
return false;
}
@Override
public boolean putOntoBattlefield(Card card, Game game) {
PermanentCard permanent = new PermanentCard(card, playerId);
putOntoBattlefield(permanent, game);
return true;
}
@Override
public boolean putOntoBattlefield(Token token, Game game) {
PermanentToken permanent = new PermanentToken(token, playerId, playerId);
putOntoBattlefield(permanent, game);
return true;
}
protected void putOntoBattlefield(Permanent permanent, Game game) {
game.getBattlefield().addPermanent(permanent);
permanent.entersBattlefield(game);
game.applyEffects();
game.fireEvent(new ZoneChangeEvent(permanent.getId(), playerId, Zone.ALL, Zone.BATTLEFIELD));
}
@Override
public boolean removeFromBattlefield(Permanent permanent, Game game) {
permanent.removeFromCombat(game);
@ -414,7 +392,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), playerId))) {
game.bookmarkState();
removeFromHand(card, game);
if (putOntoBattlefield(card, game)) {
if (card.putOntoBattlefield(game, Zone.HAND, playerId)) {
landsPlayed++;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), playerId));
game.fireInformEvent(name + " plays " + card.getName());

View file

@ -33,7 +33,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.Constants.TargetController;
import mage.Constants.Zone;
import mage.MageObject;
import mage.abilities.Ability;
@ -48,38 +47,31 @@ import mage.game.permanent.Permanent;
public class TargetPermanent<T extends TargetPermanent<T>> extends TargetObject<TargetPermanent<T>> {
protected FilterPermanent filter;
protected TargetController controller;
public TargetPermanent() {
this(1, 1, new FilterPermanent(), TargetController.ANY, false);
this(1, 1, new FilterPermanent(), false);
}
public TargetPermanent(FilterPermanent filter) {
this(1, 1, filter, TargetController.ANY, false);
this(1, 1, filter, false);
}
public TargetPermanent(FilterPermanent filter, TargetController controller) {
this(1, 1, filter, controller, false);
public TargetPermanent(int numTargets, FilterPermanent filter) {
this(numTargets, numTargets, filter, false);
}
public TargetPermanent(int numTargets, FilterPermanent filter, TargetController controller) {
this(numTargets, numTargets, filter, controller, false);
}
public TargetPermanent(int minNumTargets, int maxNumTargets, FilterPermanent filter, TargetController controller, boolean notTarget) {
public TargetPermanent(int minNumTargets, int maxNumTargets, FilterPermanent filter, boolean notTarget) {
this.minNumberOfTargets = minNumTargets;
this.maxNumberOfTargets = maxNumTargets;
this.zone = Zone.BATTLEFIELD;
this.filter = filter;
this.targetName = filter.getMessage();
this.controller = controller;
this.notTarget = notTarget;
}
public TargetPermanent(final TargetPermanent<T> target) {
super(target);
this.filter = target.filter.copy();
this.controller = target.controller;
}
@Override
@ -89,42 +81,16 @@ public class TargetPermanent<T extends TargetPermanent<T>> extends TargetObject<
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
Permanent permanent = game.getPermanent(id);
if (controllerId != null)
setController(controllerId, game);
if (permanent != null) {
if (source != null)
//TODO: check for replacement effects
return permanent.canBeTargetedBy(game.getObject(source.getSourceId())) && filter.match(permanent);
return permanent.canBeTargetedBy(game.getObject(source.getSourceId())) && filter.match(permanent, controllerId, game);
else
return filter.match(permanent);
return filter.match(permanent, controllerId, game);
}
return false;
}
public void setTargetController(TargetController controller) {
this.controller = controller;
}
protected void setController(UUID controllerId, Game game) {
filter.getControllerId().clear();
switch (controller) {
case ANY:
break;
case YOU:
filter.getControllerId().add(controllerId);
filter.setNotController(false);
break;
case NOT_YOU:
filter.getControllerId().add(controllerId);
filter.setNotController(true);
break;
case OPPONENT:
filter.getControllerId().addAll(game.getOpponents(controllerId));
filter.setNotController(false);
break;
}
}
@Override
public FilterPermanent getFilter() {
return this.filter;
@ -134,8 +100,6 @@ public class TargetPermanent<T extends TargetPermanent<T>> extends TargetObject<
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
int count = 0;
MageObject targetSource = game.getObject(sourceId);
if (sourceControllerId != null)
setController(sourceControllerId, game);
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource)) {
count++;
@ -150,8 +114,6 @@ public class TargetPermanent<T extends TargetPermanent<T>> extends TargetObject<
public List<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Map<Integer, UUID> possibleTargets = new HashMap<Integer, UUID>();
MageObject targetSource = game.getObject(sourceId);
if (sourceControllerId != null)
setController(sourceControllerId, game);
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource)) {
possibleTargets.put(permanent.getValue().hashCode(), permanent.getId());

View file

@ -38,15 +38,15 @@ import mage.filter.common.FilterAttackingCreature;
public class TargetAttackingCreature extends TargetCreaturePermanent<TargetAttackingCreature> {
public TargetAttackingCreature() {
this(1, 1, new FilterAttackingCreature(), TargetController.ANY, false);
this(1, 1, new FilterAttackingCreature(), false);
}
public TargetAttackingCreature(int numTargets, TargetController controller) {
this(numTargets, numTargets, new FilterAttackingCreature(), controller, false);
public TargetAttackingCreature(int numTargets) {
this(numTargets, numTargets, new FilterAttackingCreature(), false);
}
public TargetAttackingCreature(int minNumTargets, int maxNumTargets, FilterAttackingCreature filter, TargetController controller, boolean notTarget) {
super(1, 1, filter, controller, notTarget);
public TargetAttackingCreature(int minNumTargets, int maxNumTargets, FilterAttackingCreature filter, boolean notTarget) {
super(1, 1, filter, notTarget);
this.targetName = filter.getMessage();
}

View file

@ -0,0 +1,60 @@
/*
* 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.target.common;
import mage.filter.common.FilterControlledCreaturePermanent;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class TargetControlledCreaturePermanent extends TargetControlledPermanent<TargetControlledCreaturePermanent> {
public TargetControlledCreaturePermanent() {
this(1, 1, new FilterControlledCreaturePermanent(), false);
}
public TargetControlledCreaturePermanent(int numTargets) {
this(numTargets, numTargets, new FilterControlledCreaturePermanent(), false);
}
public TargetControlledCreaturePermanent(int minNumTargets, int maxNumTargets, FilterControlledCreaturePermanent filter, boolean notTarget) {
super(1, 1, filter, notTarget);
this.targetName = filter.getMessage();
}
public TargetControlledCreaturePermanent(final TargetControlledCreaturePermanent target) {
super(target);
}
@Override
public TargetControlledCreaturePermanent copy() {
return new TargetControlledCreaturePermanent(this);
}
}

View file

@ -30,24 +30,29 @@ package mage.target.common;
import mage.Constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.target.TargetPermanent;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class TargetControlledPermanent extends TargetPermanent<TargetControlledPermanent> {
public class TargetControlledPermanent<T extends TargetControlledPermanent<T>> extends TargetPermanent<TargetControlledPermanent<T>> {
public TargetControlledPermanent() {
this(1, 1, new FilterPermanent(), false);
this(1, 1, new FilterControlledPermanent(), false);
}
public TargetControlledPermanent(int numTargets) {
this(numTargets, numTargets, new FilterPermanent(), false);
this(numTargets, numTargets, new FilterControlledPermanent(), false);
}
public TargetControlledPermanent(int minNumTargets, int maxNumTargets, FilterPermanent filter, boolean notTarget) {
super(1, 1, filter, TargetController.YOU, notTarget);
public TargetControlledPermanent(FilterControlledPermanent filter) {
this(1, 1, filter, false);
}
public TargetControlledPermanent(int minNumTargets, int maxNumTargets, FilterControlledPermanent filter, boolean notTarget) {
super(1, 1, filter, notTarget);
this.targetName = filter.getMessage();
}

View file

@ -96,7 +96,7 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
if (source != null)
return permanent.canBeTargetedBy(targetSource) && filter.match(permanent);
return permanent.canBeTargetedBy(targetSource) && filter.match(permanent, source.getControllerId(), game);
else
return filter.match(permanent);
}
@ -122,7 +122,7 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(FilterCreaturePermanent.getDefault(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent, sourceControllerId, game)) {
count++;
if (count >= this.minNumberOfTargets)
return true;
@ -142,7 +142,7 @@ public class TargetCreatureOrPlayer extends TargetImpl<TargetCreatureOrPlayer> {
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(FilterCreaturePermanent.getDefault(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent, sourceControllerId, game)) {
possibleTargets.put(permanent.getValue().hashCode(), permanent.getId());
}
}

View file

@ -87,7 +87,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount<TargetCreatureOrP
MageObject targetSource = game.getObject(source.getSourceId());
if (permanent != null) {
if (source != null)
return permanent.canBeTargetedBy(targetSource) && filter.match(permanent);
return permanent.canBeTargetedBy(targetSource) && filter.match(permanent, source.getControllerId(), game);
else
return filter.match(permanent);
}
@ -113,7 +113,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount<TargetCreatureOrP
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(FilterCreaturePermanent.getDefault(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent, sourceControllerId, game)) {
count++;
if (count >= this.minNumberOfTargets)
return true;
@ -133,7 +133,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount<TargetCreatureOrP
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(FilterCreaturePermanent.getDefault(), sourceControllerId, game)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent)) {
if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent, sourceControllerId, game)) {
possibleTargets.put(permanent.getValue().hashCode(), permanent.getId());
}
}

View file

@ -28,7 +28,6 @@
package mage.target.common;
import mage.Constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.TargetPermanent;
@ -39,19 +38,19 @@ import mage.target.TargetPermanent;
public class TargetCreaturePermanent<T extends TargetCreaturePermanent<T>> extends TargetPermanent<TargetCreaturePermanent<T>> {
public TargetCreaturePermanent() {
this(1, 1, FilterCreaturePermanent.getDefault(), TargetController.ANY, false);
this(1, 1, FilterCreaturePermanent.getDefault(), false);
}
public TargetCreaturePermanent(FilterCreaturePermanent filter) {
this(1, 1, filter, TargetController.ANY, false);
this(1, 1, filter, false);
}
public TargetCreaturePermanent(int numTargets, TargetController controller) {
this(numTargets, numTargets, FilterCreaturePermanent.getDefault(), controller, false);
public TargetCreaturePermanent(int numTargets) {
this(numTargets, numTargets, FilterCreaturePermanent.getDefault(), false);
}
public TargetCreaturePermanent(int minNumTargets, int maxNumTargets, FilterCreaturePermanent filter, TargetController controller, boolean notTarget) {
super(1, 1, filter, controller, notTarget);
public TargetCreaturePermanent(int minNumTargets, int maxNumTargets, FilterCreaturePermanent filter, boolean notTarget) {
super(1, 1, filter, notTarget);
this.targetName = filter.getMessage();
}

View file

@ -39,19 +39,19 @@ import mage.target.TargetPermanent;
public class TargetLandPermanent<T extends TargetLandPermanent<T>> extends TargetPermanent<TargetLandPermanent<T>> {
public TargetLandPermanent() {
this(1, 1, new FilterLandPermanent(), TargetController.ANY, false);
this(1, 1, new FilterLandPermanent(), false);
}
public TargetLandPermanent(FilterLandPermanent filter) {
this(1, 1, filter, TargetController.ANY, false);
this(1, 1, filter, false);
}
public TargetLandPermanent(int numTargets, TargetController controller) {
this(numTargets, numTargets, new FilterLandPermanent(), controller, false);
public TargetLandPermanent(int numTargets) {
this(numTargets, numTargets, new FilterLandPermanent(), false);
}
public TargetLandPermanent(int minNumTargets, int maxNumTargets, FilterLandPermanent filter, TargetController controller, boolean notTarget) {
super(1, 1, filter, controller, notTarget);
public TargetLandPermanent(int minNumTargets, int maxNumTargets, FilterLandPermanent filter, boolean notTarget) {
super(1, 1, filter, notTarget);
this.targetName = filter.getMessage();
}

View file

@ -28,7 +28,6 @@
package mage.target.common;
import mage.Constants.TargetController;
import mage.filter.common.FilterNonlandPermanent;
import mage.target.TargetPermanent;
@ -39,15 +38,15 @@ import mage.target.TargetPermanent;
public class TargetNonlandPermanent extends TargetPermanent<TargetNonlandPermanent> {
public TargetNonlandPermanent() {
this(1, 1, TargetController.ANY, false);
this(1, 1, false);
}
public TargetNonlandPermanent(int numTargets, TargetController controller) {
this(numTargets, numTargets, controller, false);
public TargetNonlandPermanent(int numTargets) {
this(numTargets, numTargets, false);
}
public TargetNonlandPermanent(int minNumTargets, int maxNumTargets, TargetController controller, boolean notTarget) {
super(1, 1, new FilterNonlandPermanent(), controller, notTarget);
public TargetNonlandPermanent(int minNumTargets, int maxNumTargets, boolean notTarget) {
super(1, 1, new FilterNonlandPermanent(), notTarget);
this.targetName = filter.getMessage();
}