1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-03-29 11:43:34 -09:00

Fixed the "can only block flying creatures effect" (e.g. Varporkin). It was implemented as replacement effect instead of restriction effect which leads to dead locks in combat if it was forced to block a non flyer.

This commit is contained in:
LevelX2 2014-03-16 10:05:20 +01:00
parent 694e1f2bf2
commit 4232a3b7f1
12 changed files with 89 additions and 135 deletions

View file

@ -28,14 +28,12 @@
package mage.sets.avacynrestored;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
@ -54,7 +52,7 @@ public class Gloomwidow extends CardImpl<Gloomwidow> {
this.addAbility(ReachAbility.getInstance());
// Gloomwidow can block only creatures with flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public Gloomwidow(final Gloomwidow card) {

View file

@ -27,16 +27,13 @@
*/
package mage.sets.avacynrestored;
import mage.constants.CardType;
import mage.constants.Rarity;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.Zone;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
@ -58,7 +55,7 @@ public class ScrapskinDrake extends CardImpl<ScrapskinDrake> {
this.addAbility(FlyingAbility.getInstance());
// Scrapskin Drake can block only creatures with flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public ScrapskinDrake(final ScrapskinDrake card) {

View file

@ -28,16 +28,13 @@
package mage.sets.darkascension;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.UndyingAbility;
import mage.cards.CardImpl;
import mage.constants.Zone;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
* @author Loki
@ -55,7 +52,7 @@ public class StormboundGeist extends CardImpl<StormboundGeist> {
this.addAbility(FlyingAbility.getInstance());
// Stormbound Geist can block only creatures with flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
this.addAbility(new CanBlockOnlyFlyingAbility());
// Undying
this.addAbility(new UndyingAbility());
}

View file

@ -1,4 +1,4 @@
/*
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
@ -28,14 +28,12 @@
package mage.sets.magic2012;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
@ -53,7 +51,8 @@ public class SkywinderDrake extends CardImpl<SkywinderDrake> {
this.toughness = new MageInt(1);
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
// Skywinder Drake can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public SkywinderDrake(final SkywinderDrake card) {

View file

@ -28,14 +28,12 @@
package mage.sets.tenth;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
@ -53,7 +51,8 @@ public class CloudElemental extends CardImpl<CloudElemental> {
this.toughness = new MageInt(3);
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
// Cloud Elemental can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public CloudElemental(final CloudElemental card) {

View file

@ -28,15 +28,12 @@
package mage.sets.tenth;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.Zone;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
@ -52,7 +49,9 @@ public class CloudSprite extends CardImpl<CloudSprite> {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
// Cloud Sprite can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public CloudSprite(final CloudSprite card) {

View file

@ -29,13 +29,11 @@ package mage.sets.theros;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
/**
*
@ -55,7 +53,7 @@ public class Vaporkin extends CardImpl<Vaporkin> {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Vaporkin can block only creatures with flying.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public Vaporkin(final Vaporkin card) {

View file

@ -29,14 +29,12 @@
package mage.sets.zendikar;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockOnlyFlyingEffect;
import mage.abilities.common.CanBlockOnlyFlyingAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
@ -54,7 +52,8 @@ public class WelkinTern extends CardImpl<WelkinTern> {
this.toughness = new MageInt( 1);
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockOnlyFlyingEffect()));
// Welkin Tern can block only creatures with flying.
this.addAbility(new CanBlockOnlyFlyingAbility());
}
public WelkinTern (final WelkinTern card) {

View file

@ -0,0 +1,46 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.common;
import mage.abilities.effects.common.combat.CantBlockAllEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
/**
*
* @author LevelX2
*/
public class CanBlockOnlyFlyingAbility extends SimpleStaticAbility {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with flying");
static {
filter.add(new AbilityPredicate(FlyingAbility.class));
}
public CanBlockOnlyFlyingAbility() {
super(Zone.BATTLEFIELD, new CantBlockAllEffect(filter, Duration.WhileOnBattlefield));
}
private CanBlockOnlyFlyingAbility(CanBlockOnlyFlyingAbility ability) {
super(ability);
}
@Override
public String getRule() {
return "{this} can block only creatures with flying.";
}
@Override
public CanBlockOnlyFlyingAbility copy() {
return new CanBlockOnlyFlyingAbility(this);
}
}

View file

@ -1,82 +0,0 @@
/*
* 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.combat;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.MageSingleton;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
/**
*
* @author North
*/
public class CanBlockOnlyFlyingEffect extends ReplacementEffectImpl<CanBlockOnlyFlyingEffect> implements MageSingleton {
public CanBlockOnlyFlyingEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "{this} can block only creatures with flying";
}
public CanBlockOnlyFlyingEffect(final CanBlockOnlyFlyingEffect effect) {
super(effect);
}
@Override
public CanBlockOnlyFlyingEffect copy() {
return new CanBlockOnlyFlyingEffect(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.DECLARE_BLOCKER && source.getSourceId().equals(event.getSourceId())) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && !permanent.getAbilities().containsKey(FlyingAbility.getInstance().getId())) {
return true;
}
}
return false;
}
}

View file

@ -27,10 +27,10 @@
*/
package mage.abilities.effects.common.combat;
import mage.constants.Duration;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.RestrictionEffect;
import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -41,7 +41,7 @@ import mage.game.permanent.Permanent;
*/
public class CantBlockAllEffect extends RestrictionEffect<CantBlockAllEffect> {
private FilterCreaturePermanent filter;
private final FilterCreaturePermanent filter;
public CantBlockAllEffect(FilterCreaturePermanent filter, Duration duration) {
super(duration);

View file

@ -1585,6 +1585,10 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
if (blocker != null && group != null && group.canBlock(blocker, game)) {
group.addBlocker(blockerId, playerId, game);
game.getCombat().addBlockingGroup(blockerId, attackerId, playerId, game);
} else {
if (this.isHuman()) {
game.informPlayer(this, "You can't block this creature.");
}
}
}