This commit is contained in:
BetaSteward 2010-11-26 05:06:25 +00:00
parent a99ef071c8
commit 3b1696d8f0
14 changed files with 102 additions and 31 deletions

View file

@ -32,6 +32,7 @@ import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Duration;
import mage.Constants.Rarity;
import mage.Constants.TargetController;
import mage.abilities.effects.common.PreventAllDamageToEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreatureOrPlayer;
@ -42,11 +43,18 @@ import mage.filter.common.FilterCreatureOrPlayer;
*/
public class SafePassage extends CardImpl<SafePassage> {
private static FilterCreatureOrPlayer filter = new FilterCreatureOrPlayer("you and creatures you control");
static {
filter.getCreatureFilter().setTargetController(TargetController.YOU);
filter.getPlayerFilter().setPlayerTarget(TargetController.YOU);
}
public SafePassage(UUID ownerId) {
super(ownerId, 28, "Safe Passage", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.expansionSetCode = "M10";
this.color.setWhite(true);
this.getSpellAbility().addEffect(new PreventAllDamageToEffect(Duration.EndOfTurn, new FilterCreatureOrPlayer("you and creatures you control", ownerId)));
this.getSpellAbility().addEffect(new PreventAllDamageToEffect(Duration.EndOfTurn, filter));
}
public SafePassage(final SafePassage card) {

View file

@ -62,7 +62,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
private final static transient Logger logger = Logging.getLogger(AbilityImpl.class.getName());
protected final UUID id;
protected UUID id;
protected AbilityType abilityType;
protected UUID controllerId;
protected UUID sourceId;

View file

@ -90,4 +90,10 @@ public class SpellAbility extends ActivatedAbilityImpl<SpellAbility> {
return new SpellAbility(this);
}
public SpellAbility copySpell() {
SpellAbility spell = new SpellAbility(this);
spell.id = UUID.randomUUID();
return spell;
}
}

View file

@ -40,7 +40,7 @@ import mage.game.events.GameEvent;
*
* @author BetaSteward_at_googlemail.com
*/
public abstract class PreventionEffectImpl<T extends PreventionEffectImpl<T>> extends ReplacementEffectImpl<T> {
public abstract class PreventionEffectImpl<T extends PreventionEffectImpl<T>> extends ReplacementEffectImpl<T> implements PreventionEffect<T> {
public PreventionEffectImpl(Duration duration) {
super(duration, Outcome.PreventDamage);

View file

@ -75,7 +75,7 @@ public class CantTargetSourceEffect extends ReplacementEffectImpl<CantTargetSour
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.TARGET && event.getTargetId().equals(source.getSourceId())) {
StackObject sourceObject = game.getStack().getStackObject(event.getSourceId());
if (sourceObject != null && filterSource.match(sourceObject)) {
if (sourceObject != null && filterSource.match(sourceObject, source.getControllerId(), game)) {
return true;
}
}

View file

@ -53,7 +53,7 @@ public class CopyTargetSpellEffect extends OneShotEffect<CopyTargetSpellEffect>
public boolean apply(Game game, Ability source) {
Spell spell = game.getStack().getSpell(source.getFirstTarget());
if (spell != null) {
Spell copy = spell.copy();
Spell copy = spell.copySpell();
copy.setControllerId(source.getControllerId());
game.getStack().push(copy);
copy.chooseNewTargets(game);

View file

@ -32,6 +32,7 @@ import mage.Constants.Duration;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.filter.Filter;
import mage.filter.FilterInPlay;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@ -43,9 +44,9 @@ import mage.players.Player;
*/
public class PreventAllDamageToEffect extends PreventionEffectImpl<PreventAllDamageToEffect> {
protected Filter filter;
protected FilterInPlay filter;
public PreventAllDamageToEffect(Duration duration, Filter filter) {
public PreventAllDamageToEffect(Duration duration, FilterInPlay filter) {
super(duration);
this.filter = filter;
}
@ -81,12 +82,12 @@ public class PreventAllDamageToEffect extends PreventionEffectImpl<PreventAllDam
if (super.applies(event, source, game)) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
if (filter.match(permanent))
if (filter.match(permanent, source.getControllerId(), game))
return true;
}
else {
Player player = game.getPlayer(event.getTargetId());
if (player != null && filter.match(player))
if (player != null && filter.match(player, source.getControllerId(), game))
return true;
}
}

View file

@ -34,7 +34,7 @@ import java.io.Serializable;
*
* @author BetaSteward_at_googlemail.com
*/
public interface Filter<T> extends Serializable {
public interface Filter<E> extends Serializable {
public enum ComparisonType {
GreaterThan, Equal, LessThan
@ -44,11 +44,11 @@ public interface Filter<T> extends Serializable {
Any, All
}
public boolean match(T o);
public boolean match(E o);
public String getMessage();
public void setMessage(String message);
public void setNotFilter(boolean notFilter);
public Filter<T> copy();
public Filter<E> copy();
}

View file

@ -31,6 +31,8 @@ package mage.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.Constants.TargetController;
import mage.game.Game;
import mage.players.Player;
/**
@ -41,6 +43,7 @@ public class FilterPlayer extends FilterImpl<Player, FilterPlayer> implements Fi
protected List<UUID> playerId = new ArrayList<UUID>();
protected boolean notPlayer;
protected TargetController playerTarget = TargetController.ANY;
public FilterPlayer() {
super("player");
@ -52,6 +55,7 @@ public class FilterPlayer extends FilterImpl<Player, FilterPlayer> implements Fi
this.playerId.add(pId);
}
this.notPlayer = filter.notPlayer;
this.playerTarget = filter.playerTarget;
}
@Override
@ -63,6 +67,30 @@ public class FilterPlayer extends FilterImpl<Player, FilterPlayer> implements Fi
return !notFilter;
}
public boolean match(Player player, UUID playerId, Game game) {
if (!this.match(player))
return notFilter;
if (playerTarget != TargetController.ANY && playerId != null) {
switch(playerTarget) {
case YOU:
if (!player.getId().equals(playerId))
return notFilter;
break;
case OPPONENT:
if (!game.getOpponents(playerId).contains(player.getId()))
return notFilter;
break;
case NOT_YOU:
if (player.getId().equals(playerId))
return notFilter;
break;
}
}
return !notFilter;
}
public List<UUID> getPlayerId() {
return playerId;
}
@ -71,6 +99,10 @@ public class FilterPlayer extends FilterImpl<Player, FilterPlayer> implements Fi
this.notPlayer = notPlayer;
}
public void setPlayerTarget(TargetController playerTarget) {
this.playerTarget = playerTarget;
}
@Override
public FilterPlayer copy() {
return new FilterPlayer(this);

View file

@ -31,6 +31,7 @@ package mage.filter.common;
import java.util.UUID;
import mage.filter.Filter;
import mage.filter.FilterImpl;
import mage.filter.FilterInPlay;
import mage.filter.FilterPlayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -40,7 +41,7 @@ import mage.players.Player;
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterCreatureOrPlayer extends FilterImpl<Object, FilterCreatureOrPlayer> implements Filter<Object> {
public class FilterCreatureOrPlayer extends FilterImpl<Object, FilterCreatureOrPlayer> implements FilterInPlay<Object> {
protected FilterCreaturePermanent creatureFilter;
protected FilterPlayer playerFilter;
@ -80,9 +81,10 @@ public class FilterCreatureOrPlayer extends FilterImpl<Object, FilterCreatureOrP
return notFilter;
}
@Override
public boolean match(Object o, UUID playerId, Game game) {
if (o instanceof Player) {
return playerFilter.match((Player)o);
return playerFilter.match((Player)o, playerId, game);
}
else if (o instanceof Permanent) {
return creatureFilter.match((Permanent)o, playerId, game);
@ -90,6 +92,13 @@ public class FilterCreatureOrPlayer extends FilterImpl<Object, FilterCreatureOrP
return notFilter;
}
public FilterCreaturePermanent getCreatureFilter() {
return this.creatureFilter;
}
public FilterPlayer getPlayerFilter() {
return this.playerFilter;
}
@Override
public FilterCreatureOrPlayer copy() {

View file

@ -48,6 +48,7 @@ import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Battlefield;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.game.stack.StackObject;
import mage.game.turn.Turn;
import mage.game.turn.TurnMods;
@ -307,13 +308,19 @@ public class GameState implements Serializable, Copyable<GameState> {
public void handleEvent(GameEvent event, Game game) {
watchers.watch(event, game);
if (!replaceEvent(event, game)) {
//TODO: this is awkward - improve
if (event.getType() == EventType.ZONE_CHANGE) {
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
if (zEvent.getTarget() instanceof PermanentCard) {
((PermanentCard)zEvent.getTarget()).checkPermanentOnlyTriggers(zEvent, game);
}
else {
zEvent.getTarget().checkTriggers(zEvent.getFromZone(), event, game);
zEvent.getTarget().checkTriggers(zEvent.getToZone(), event, game);
}
}
}
for (Player player: players.values()) {
player.checkTriggers(event, game);
}

View file

@ -35,10 +35,12 @@ import mage.Constants.CardType;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.keyword.LevelAbility;
import mage.cards.Card;
import mage.cards.LevelerCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
@ -112,6 +114,21 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
this.cardNumber = card.getCardNumber();
}
public void checkPermanentOnlyTriggers(ZoneChangeEvent event, Game game) {
// we only want to trigger abilities that are not on the underlying card ie. have been added by another effect
// card abilities will get triggered later when the card hits the new zone
Card card = game.getCard(objectId).copy();
for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getFromZone())) {
if (!card.getAbilities().containsKey(ability.getId()))
ability.checkTrigger(event, game);
}
for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getToZone())) {
if (!card.getAbilities().containsKey(ability.getId()))
ability.checkTrigger(event, game);
}
}
@Override
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) {
Zone fromZone = game.getZone(objectId);

View file

@ -496,19 +496,6 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
return (!hasProtectionFrom(source));
}
// protected void addEffects(Game game) {
// for (Ability ability: abilities.getStaticAbilities(Zone.BATTLEFIELD)) {
// if (ability instanceof EntersBattlefieldStaticAbility) {
// for (Effect effect: ability.getEffects()) {
// if (effect instanceof OneShotEffect) {
// //20100423 - 603.6e
// effect.apply(game, ability);
// }
// }
// }
// }
// }
@Override
public boolean destroy(UUID sourceId, Game game, boolean noRegen) {
//20091005 - 701.6

View file

@ -283,8 +283,12 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
public void setExpansionSetCode(String expansionSetCode) {}
@Override
public Spell<T> copy() {
return new Spell<T>(this);
public Spell copy() {
return new Spell(this);
}
public Spell copySpell() {
return new Spell(this.card.copy(), this.ability.copySpell(), this.controllerId);
}
@Override