* Added early event type check for replacement effects to speed up game execution (not all effects already implement the new check).

This commit is contained in:
LevelX2 2014-12-26 17:28:13 +01:00
parent ba57478149
commit 9039eef0f9
40 changed files with 283 additions and 144 deletions

View file

@ -76,7 +76,7 @@ class VexingDevilEffect extends OneShotEffect {
public VexingDevilEffect() {
super(Outcome.Neutral);
staticText = "any opponent may have it deal 4 damage to him or her. If a player does, sacrifice Vexing Devil";
staticText = "any opponent may have it deal 4 damage to him or her. If a player does, sacrifice {this}";
}
VexingDevilEffect(final VexingDevilEffect effect) {
@ -85,28 +85,19 @@ class VexingDevilEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
StringBuilder sb = new StringBuilder();
sb.append("Make ").append(permanent.getName()).append(" deal 4 damage to you?");
Set<UUID> opponents = game.getOpponents(source.getControllerId());
for (UUID opponentUuid : opponents) {
if (controller != null && permanent != null) {
for (UUID opponentUuid : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentUuid);
if (opponent != null && opponent.chooseUse(Outcome.LoseLife, sb.toString(), game)) {
if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getName() + " deal 4 damage to you?", game)) {
game.informPlayers(opponent.getName() + " has chosen to receive 4 damage from " + permanent.getName());
int dealt = opponent.damage(4, permanent.getId(), game, false, true);
if (dealt == 4) {
game.informPlayers(opponent.getName() + " was dealt 4 damage so " + permanent.getName() + " will be sacrificed.");
permanent.sacrifice(source.getSourceId(), game);
return true;
} else {
game.informPlayers("4 damage wasn't dealt so " + permanent.getName() + " won't be sacrificed.");
}
opponent.damage(4, permanent.getId(), game, false, true);
permanent.sacrifice(source.getSourceId(), game);
return true;
}
}
game.informPlayers("4 damage wasn't dealt so " + permanent.getName() + " won't be sacrificed.");
return true;
}
return false;

View file

@ -142,13 +142,15 @@ class StrangleholdSkipExtraTurnsEffect extends ReplacementEffectImpl {
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.EXTRA_TURN);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (EventType.EXTRA_TURN.equals(event.getType())) {
Player controller = game.getPlayer(source.getControllerId());
return controller != null && controller.hasOpponent(event.getPlayerId(), game);
}
return false;
Player controller = game.getPlayer(source.getControllerId());
return controller != null && controller.hasOpponent(event.getPlayerId(), game);
}
}

View file

@ -37,8 +37,6 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@ -88,13 +86,14 @@ class PrimalVigorTokenEffect extends ReplacementEffectImpl {
return new PrimalVigorTokenEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CREATE_TOKEN;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
switch (event.getType()) {
case CREATE_TOKEN:
return true;
}
return false;
return true;
}
@Override
@ -112,8 +111,6 @@ class PrimalVigorTokenEffect extends ReplacementEffectImpl {
class PrimalVigorCounterEffect extends ReplacementEffectImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
PrimalVigorCounterEffect() {
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
staticText = "If one or more +1/+1 counters would be placed on a creature, twice that many +1/+1 counters are placed on that creature instead";
@ -129,14 +126,17 @@ class PrimalVigorCounterEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ADD_COUNTERS;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ADD_COUNTERS) {
Permanent target = game.getPermanent(event.getTargetId());
if (target != null && filter.match(target, game)
&& event.getData() != null && event.getData().equals("+1/+1")) {
return true;
}
Permanent target = game.getPermanent(event.getTargetId());
if (target != null && target.getCardType().contains(CardType.CREATURE)
&& event.getData() != null && event.getData().equals("+1/+1")) {
return true;
}
return false;
}

View file

@ -64,7 +64,7 @@ public class RiseFall extends SplitCard {
// Rise
// Return target creature card from a graveyard and target creature on the battlefield to their owners' hands.
getLeftHalfCard().getSpellAbility().addEffect(new RiseEffect());
getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard()));
getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard")));
getLeftHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
getLeftHalfCard().getColor().setBlue(true);
getLeftHalfCard().getColor().setBlack(true);
@ -151,7 +151,7 @@ class FallEffect extends OneShotEffect {
if (targetPlayer.getHand().size() > 1) {
do {
card = targetPlayer.getHand().getRandom(game);
} while (!cards.contains(card.getId()));
} while (cards.contains(card.getId()));
cards.add(card);
}
targetPlayer.revealCards(sourceObject.getLogName(), cards, game);

View file

@ -55,8 +55,6 @@ public class GilderBairn extends CardImpl {
this.expansionSetCode = "EVE";
this.subtype.add("Ouphe");
this.color.setBlue(true);
this.color.setGreen(true);
this.power = new MageInt(1);
this.toughness = new MageInt(3);

View file

@ -112,13 +112,16 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl {
baseEffects.add(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.ENTERS_THE_BATTLEFIELD);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) {
return true;
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) {
return true;
}
return false;
}

View file

@ -139,9 +139,14 @@ class AnafenzaTheForemostEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.ZONE_CHANGE);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD) {
if (((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD) {
Card card = game.getCard(event.getTargetId());
if (card != null && card.getCardType().contains(CardType.CREATURE) &&
game.getOpponents(source.getControllerId()).contains(card.getOwnerId())) {

View file

@ -87,14 +87,16 @@ class DoublingSeasonTokenEffect extends ReplacementEffectImpl {
return new DoublingSeasonTokenEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.CREATE_TOKEN);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
switch (event.getType()) {
case CREATE_TOKEN:
StackObject spell = game.getStack().getStackObject(event.getSourceId());
if (spell != null && spell.getControllerId().equals(source.getControllerId())) {
return true;
}
StackObject spell = game.getStack().getStackObject(event.getSourceId());
if (spell != null && spell.getControllerId().equals(source.getControllerId())) {
return true;
}
return false;
}

View file

@ -96,9 +96,14 @@ class LoxodonSmiterEffect extends ReplacementEffectImpl {
return new LoxodonSmiterEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {
if (event.getTargetId().equals(source.getSourceId())) {
ZoneChangeEvent zcEvent = (ZoneChangeEvent) event;
if (zcEvent.getFromZone() == Zone.HAND && zcEvent.getToZone() == Zone.GRAVEYARD) {
StackObject spell = game.getStack().getStackObject(event.getSourceId());

View file

@ -103,11 +103,22 @@ class PalisadeGiantReplacementEffect extends ReplacementEffectImpl {
super(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
switch(event.getType()) {
case DAMAGED_CREATURE:
case DAMAGED_PLAYER:
case DAMAGE_PLANESWALKER:
return true;
default:
return false;
}
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER && event.getPlayerId().equals(source.getControllerId()))
{
return true;
}
if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE || event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER)

View file

@ -112,9 +112,14 @@ class WiltLeafLiegeEffect extends ReplacementEffectImpl {
return new WiltLeafLiegeEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.ZONE_CHANGE);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {
if (event.getTargetId().equals(source.getSourceId())) {
ZoneChangeEvent zcEvent = (ZoneChangeEvent) event;
if (zcEvent.getFromZone() == Zone.HAND && zcEvent.getToZone() == Zone.GRAVEYARD) {
StackObject spell = game.getStack().getStackObject(event.getSourceId());

View file

@ -119,9 +119,14 @@ class MoxDiamondReplacementEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && source.getSourceId().equals(event.getTargetId())) {
if (source.getSourceId().equals(event.getTargetId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if(zEvent.getToZone().equals(Zone.BATTLEFIELD)){
return true;

View file

@ -119,12 +119,18 @@ class PutIntoGraveFromAnywhereEffect extends ReplacementEffectImpl {
baseEffects.add(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (GameEvent.EventType.ZONE_CHANGE.equals(event.getType())
&& ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(source.getSourceId())) {
if (condition == null || condition.apply(game, source)) {
if (((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(source.getSourceId()))
{
if (condition == null || condition.apply(game, source))
{
return true;
}
}

View file

@ -119,6 +119,12 @@ public class ConditionalReplacementEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return effect.checksEventType(event, game)
|| (otherwiseEffect != null && otherwiseEffect.checksEventType(event, game));
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!initDone) { // if simpleStaticAbility, init won't be called

View file

@ -61,15 +61,15 @@ public class AsTurnedFaceUpEffect extends ReplacementEffectImpl {
public void addEffect(Effect effect) {
baseEffects.add(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TURNFACEUP;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.TURNFACEUP) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
}
return false;
return event.getTargetId().equals(source.getSourceId());
}
@Override

View file

@ -163,16 +163,19 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
}
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType().equals(GameEvent.EventType.ZONE_CHANGE)) {
if (((ZoneChangeEvent) event).getToZone().equals(Zone.BATTLEFIELD)
&& !(((ZoneChangeEvent) event).getFromZone().equals(Zone.HAND)) ) {
Card card = game.getCard(event.getTargetId());
if (card != null && card.getCardType().contains(CardType.ENCHANTMENT) && card.hasSubtype("Aura")) {
return true;
}
if (((ZoneChangeEvent) event).getToZone().equals(Zone.BATTLEFIELD)
&& !(((ZoneChangeEvent) event).getFromZone().equals(Zone.HAND)) ) {
Card card = game.getCard(event.getTargetId());
if (card != null && card.getCardType().contains(CardType.ENCHANTMENT) && card.hasSubtype("Aura")) {
return true;
}
}
return false;

View file

@ -324,14 +324,17 @@ public class ContinuousEffects implements Serializable {
*/
private HashMap<ReplacementEffect, HashSet<Ability>> getApplicableReplacementEffects(GameEvent event, Game game) {
HashMap<ReplacementEffect, HashSet<Ability>> replaceEffects = new HashMap<>();
if (planeswalkerRedirectionEffect.applies(event, null, game)) {
if (planeswalkerRedirectionEffect.checksEventType(event, game) && planeswalkerRedirectionEffect.applies(event, null, game)) {
replaceEffects.put(planeswalkerRedirectionEffect, null);
}
if(auraReplacementEffect.applies(event, null, game)){
if(auraReplacementEffect.checksEventType(event, game) && auraReplacementEffect.applies(event, null, game)){
replaceEffects.put(auraReplacementEffect, null);
}
//get all applicable transient Replacement effects
for (ReplacementEffect effect: replacementEffects) {
if (!effect.checksEventType(event, game)) {
continue;
}
if (event.getAppliedEffects() != null && event.getAppliedEffects().contains(effect.getId())) {
// Effect already applied to this event, ignore it
// TODO: Handle also gained effect that are connected to different abilities.
@ -357,6 +360,9 @@ public class ContinuousEffects implements Serializable {
}
}
for (PreventionEffect effect: preventionEffects) {
if (!effect.checksEventType(event, game)) {
continue;
}
if (event.getAppliedEffects() != null && event.getAppliedEffects().contains(effect.getId())) {
// Effect already applied to this event, ignore it
// TODO: Handle also gained effect that are connected to different abilities.

View file

@ -88,6 +88,11 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl {
baseEffects.add(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return EventType.ENTERS_THE_BATTLEFIELD.equals(event.getType());
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) {

View file

@ -97,16 +97,19 @@ public abstract class PreventionEffectImpl extends ReplacementEffectImpl impleme
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
public boolean checksEventType(GameEvent event, Game game) {
switch (event.getType()) {
case DAMAGE_CREATURE:
case DAMAGE_PLAYER:
case DAMAGE_PLANESWALKER:
// return preventable flag && combatOnly check
return event.getFlag() && (!onlyCombat || ((DamageEvent)event).isCombatDamage());
default:
return false;
return true;
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getFlag() && (!onlyCombat || ((DamageEvent)event).isCombatDamage());
}
}

View file

@ -37,11 +37,21 @@ import mage.game.events.GameEvent;
* @author BetaSteward_at_googlemail.com
*/
public interface ReplacementEffect extends ContinuousEffect {
boolean replaceEvent(GameEvent event, Ability source, Game game);
/**
* This check for the relevant events is called at first to prevent further actions if
* the current event is ignored from this effect
* @param event
* @param game
* @return
*/
boolean checksEventType(GameEvent event, Game game);
boolean applies(GameEvent event, Ability source, Game game);
boolean hasSelfScope();
@Override
public ContinuousEffect copy();

View file

@ -28,9 +28,12 @@
package mage.abilities.effects;
import mage.abilities.Ability;
import mage.constants.Duration;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
@ -70,4 +73,10 @@ public abstract class ReplacementEffectImpl extends ContinuousEffectImpl impleme
public boolean hasSelfScope() {
return selfScope;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return true;
}
}

View file

@ -106,10 +106,14 @@ public class DevourEffect extends ReplacementEffectImpl {
this.devourFactor = effect.devourFactor;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD
&& event.getTargetId().equals(source.getSourceId())) {
if (event.getTargetId().equals(source.getSourceId())) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
game.getState().setValue(sourcePermanent.getId().toString() + "devoured", null);
return true;

View file

@ -94,9 +94,14 @@ public class EnterBattlefieldPayCostOrPutGraveyardEffect extends ReplacementEffe
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && source.getSourceId().equals(event.getTargetId())) {
if (source.getSourceId().equals(event.getTargetId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if(zEvent.getToZone().equals(Zone.BATTLEFIELD)){
return true;

View file

@ -83,6 +83,11 @@ public class RegenerateAttachedEffect extends ReplacementEffectImpl {
return apply(game, source);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DESTROY_PERMANENT;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
//20110204 - 701.11c - event.getAmount() is used to signal if regeneration is allowed
@ -91,7 +96,7 @@ public class RegenerateAttachedEffect extends ReplacementEffectImpl {
Permanent equipped = game.getPermanent(equipment.getAttachedTo());
if (equipped != null) {
UUID equippedID = equipped.getId();
if (event.getType() == EventType.DESTROY_PERMANENT && event.getAmount() == 0 && event.getTargetId().equals(equippedID) && !this.used) {
if (event.getAmount() == 0 && event.getTargetId().equals(equippedID) && !this.used) {
return true;
}
}

View file

@ -72,14 +72,14 @@ public class RegenerateSourceEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
return apply(game, source);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DESTROY_PERMANENT;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
//20110204 - 701.11c - event.getAmount() is used to signal if regeneration is allowed
if (event.getType() == EventType.DESTROY_PERMANENT && event.getAmount() == 0 && event.getTargetId().equals(source.getSourceId()) && !this.used) {
return true;
}
return false;
return event.getAmount() == 0 && event.getTargetId().equals(source.getSourceId()) && !this.used;
}
}

View file

@ -73,10 +73,15 @@ public class RegenerateTargetEffect extends ReplacementEffectImpl {
return apply(game, source);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return EventType.DESTROY_PERMANENT.equals(event.getType());
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
//20110204 - 701.11c - event.getAmount() is used to signal if regeneration is allowed
if (event.getType() == EventType.DESTROY_PERMANENT && event.getAmount() == 0 && event.getTargetId().equals(targetPointer.getFirst(game, source)) && !this.used) {
if (event.getAmount() == 0 && event.getTargetId().equals(targetPointer.getFirst(game, source)) && !this.used) {
return true;
}
return false;

View file

@ -68,9 +68,13 @@ public class SkipDrawStepEffect extends ReplacementEffectImpl {
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DRAW_STEP;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getType() == GameEvent.EventType.DRAW_STEP
&& (event.getPlayerId().equals(source.getControllerId()));
return event.getPlayerId().equals(source.getControllerId());
}
}

View file

@ -70,18 +70,23 @@ public class AssignNoCombatDamageSourceEffect extends ReplacementEffectImpl {
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
public boolean checksEventType(GameEvent event, Game game) {
switch (event.getType()) {
case DAMAGE_CREATURE:
case DAMAGE_PLAYER:
case DAMAGE_PLANESWALKER:
DamageEvent damageEvent = (DamageEvent) event;
return event.getSourceId().equals(source.getSourceId()) && damageEvent.isCombatDamage();
return true;
default:
return false;
}
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent) event;
return event.getSourceId().equals(source.getSourceId()) && damageEvent.isCombatDamage();
}
private String setText() {
StringBuilder sb = new StringBuilder("{this} assigns no combat damage");
switch(duration) {

View file

@ -51,8 +51,6 @@ import org.apache.log4j.Logger;
*/
public class CommanderManaReplacementEffect extends ReplacementEffectImpl {
private static final transient Logger logger = Logger.getLogger(CommanderManaReplacementEffect.class);
private final UUID playerId;
private final Mana commanderMana;
@ -115,22 +113,14 @@ public class CommanderManaReplacementEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ADD_MANA;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ADD_MANA && event.getPlayerId().equals(playerId)) {
if (logger.isDebugEnabled()) {
if (!game.getGameType().toString().startsWith("Commander")) {
logger.debug("Non Commander game has active CommanderManaReplacementEffect");
Iterator it = game.getState().getCommand().iterator();
while (it.hasNext()) {
Object object = it.next();
logger.debug("Class: " + object.getClass() + " - " + object.toString());
}
}
}
return true;
}
return false;
return event.getPlayerId().equals(playerId);
}
}

View file

@ -114,14 +114,17 @@ public class CommanderReplacementEffect extends ReplacementEffectImpl {
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && (
((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD ||
if (((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD ||
((ZoneChangeEvent)event).getToZone() == Zone.EXILED ||
(alsoLibrary && ((ZoneChangeEvent)event).getToZone() == Zone.LIBRARY))
) {
{
if (commanderId != null) {
if (((ZoneChangeEvent)event).getFromZone().equals(Zone.STACK)) {
Spell spell = game.getStack().getSpell(event.getTargetId());

View file

@ -84,15 +84,18 @@ public class DealtDamageToCreatureBySourceDies extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType().equals(EventType.ZONE_CHANGE)) {
ZoneChangeEvent zce = (ZoneChangeEvent) event;
if (zce.isDiesEvent()) {
DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId());
if (watcher != null) {
return watcher.wasDamaged(zce.getTarget());
}
ZoneChangeEvent zce = (ZoneChangeEvent) event;
if (zce.isDiesEvent()) {
DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId());
if (watcher != null) {
return watcher.wasDamaged(zce.getTarget());
}
}
return false;

View file

@ -178,9 +178,14 @@ class BuybackEffect extends ReplacementEffectImpl {
return new BuybackEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {
if (event.getTargetId().equals(source.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
if (zEvent.getFromZone() == Zone.STACK ) {
return true;

View file

@ -36,6 +36,7 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
/**
@ -109,8 +110,14 @@ class DredgeEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.DRAW_CARD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getType().equals(GameEvent.EventType.DRAW_CARD) && event.getPlayerId().equals(source.getControllerId());
return event.getPlayerId().equals(source.getControllerId());
}
}

View file

@ -98,11 +98,14 @@ class MadnessReplacementEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getType() == EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId()) &&
return event.getTargetId().equals(source.getSourceId()) &&
((ZoneChangeEvent) event).getFromZone() == Zone.HAND && ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD;
}

View file

@ -96,12 +96,18 @@ class PersistReplacementEffect extends ReplacementEffectImpl {
used = true;
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(source.getSourceId())) {
if (event.getTargetId().equals(source.getSourceId()))
{
Object fixedTarget = game.getState().getValue(new StringBuilder("persist").append(source.getSourceId()).toString());
if (fixedTarget instanceof FixedTarget && ((FixedTarget) fixedTarget).getFirst(game, source).equals(source.getSourceId())) {
if (fixedTarget instanceof FixedTarget && ((FixedTarget) fixedTarget).getFirst(game, source).equals(source.getSourceId()))
{
return true;
}
}

View file

@ -226,11 +226,14 @@ class ReboundCastFromHandReplacementEffect extends ReplacementEffectImpl {
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ZONE_CHANGE &&
((ZoneChangeEvent) event).getFromZone() == Zone.STACK &&
if (((ZoneChangeEvent) event).getFromZone() == Zone.STACK &&
((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD &&
source.getSourceId() == this.cardId) {
return true;

View file

@ -91,14 +91,16 @@ class TotemArmorEffect extends ReplacementEffectImpl {
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DESTROY_PERMANENT;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.DESTROY_PERMANENT) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null && event.getTargetId().equals(sourcePermanent.getAttachedTo())) {
return true;
}
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null && event.getTargetId().equals(sourcePermanent.getAttachedTo())) {
return true;
}
return false;
}

View file

@ -101,9 +101,14 @@ class UndyingReplacementEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(source.getSourceId())) {
if (event.getTargetId().equals(source.getSourceId())) {
Object fixedTarget = game.getState().getValue(new StringBuilder("undying").append(source.getSourceId()).toString());
if (fixedTarget instanceof FixedTarget && ((FixedTarget) fixedTarget).getFirst(game, source).equals(source.getSourceId())) {
return true;

View file

@ -135,6 +135,11 @@ class UnearthLeavesBattlefieldEffect extends ReplacementEffectImpl {
return new UnearthLeavesBattlefieldEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return EventType.ZONE_CHANGE.equals(event.getType());
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) {

View file

@ -38,6 +38,7 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -86,13 +87,16 @@ class UnleashReplacementEffect extends ReplacementEffectImpl {
public UnleashReplacementEffect(UnleashReplacementEffect effect) {
super(effect);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
if (event.getTargetId().equals(source.getSourceId())) {
return true;
}
return false;
}