mirror of
https://github.com/correl/mage.git
synced 2025-01-12 11:08:01 +00:00
...
This commit is contained in:
parent
2cf247d68b
commit
5eae8136e4
70 changed files with 1286 additions and 399 deletions
|
@ -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"),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
45
Mage/src/mage/abilities/effects/AsThoughEffect.java
Normal file
45
Mage/src/mage/abilities/effects/AsThoughEffect.java
Normal 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();
|
||||
|
||||
}
|
58
Mage/src/mage/abilities/effects/AsThoughEffectImpl.java
Normal file
58
Mage/src/mage/abilities/effects/AsThoughEffectImpl.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -61,5 +61,4 @@ public abstract class PreventionEffectImpl<T extends PreventionEffectImpl<T>> ex
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
65
Mage/src/mage/abilities/keyword/LeylineAbility.java
Normal file
65
Mage/src/mage/abilities/keyword/LeylineAbility.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
package mage.filter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
58
Mage/src/mage/filter/common/FilterControlledPermanent.java
Normal file
58
Mage/src/mage/filter/common/FilterControlledPermanent.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -57,4 +57,8 @@ public class ZoneChangeEvent extends GameEvent {
|
|||
public Zone getToZone() {
|
||||
return toZone;
|
||||
}
|
||||
|
||||
public void setToZone(Zone toZone) {
|
||||
this.toZone = toZone;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue