* Fixed a bug that effects where applied to early and often (e.g. dying creature during combat damage step raised Nighthowlers tougness, so he survived lethal damage).

This commit is contained in:
LevelX2 2014-05-24 19:19:08 +02:00
parent 71fb7bf25b
commit 7fc072f467
4 changed files with 68 additions and 21 deletions

View file

@ -0,0 +1,44 @@
/*
* 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 org.mage.test.combat;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Test that calculated p/t is applied after combat damage resolution, so a 2/2 Nighthowler
* dies if blocked from a 2/2 creature.
*
* @author LevelX2
*/
public class PowerToughnessCalculationAfterCombatDamageTest extends CardTestPlayerBase {
@Test
public void powerToughnessCalculation() {
addCard(Zone.BATTLEFIELD, playerA, "Pain Seer");
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion");
// Nighthowler and enchanted creature each get +X/+X, where X is the number of creature cards in all graveyards.
addCard(Zone.BATTLEFIELD, playerB, "Nighthowler");
addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion");
attack(2, playerB, "Nighthowler");
block(2, playerA, "Pain Seer", "Nighthowler");
setStopAt(2, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Nighthowler", 1);
assertGraveyardCount(playerA, "Pain Seer", 1);
}
}

View file

@ -28,14 +28,17 @@
package mage.abilities.effects.common;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
import mage.game.permanent.PermanentCard;
import mage.game.permanent.PermanentToken;
@ -50,6 +53,7 @@ public class CopyEffect extends ContinuousEffectImpl<CopyEffect> {
*/
private MageObject target;
private UUID sourceId;
private int zoneChangeCounter;
public CopyEffect(Permanent target, UUID sourceId) {
this(Duration.Custom, target, sourceId);
@ -65,6 +69,16 @@ public class CopyEffect extends ContinuousEffectImpl<CopyEffect> {
super(effect);
this.target = effect.target.copy();
this.sourceId = effect.sourceId;
this.zoneChangeCounter = effect.zoneChangeCounter;
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
this.zoneChangeCounter = permanent.getZoneChangeCounter();
}
}
@Override
@ -119,12 +133,9 @@ public class CopyEffect extends ContinuousEffectImpl<CopyEffect> {
@Override
public boolean isInactive(Ability source, Game game) {
// The copy effect is added, if the copy takes place. If source leaves battlefield, the copy effect must cease to exist
// The copy effect is added, if the copy takes place. If source left battlefield, the copy effect must cease to exist
Permanent permanent = game.getPermanent(this.sourceId);
if (permanent == null) {
return true;
}
return false;
return permanent == null || permanent.getZoneChangeCounter() != this.zoneChangeCounter;
}
@Override

View file

@ -461,7 +461,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
}
updateZoneChangeCounter();
game.setZone(objectId, event.getToZone());
game.fireEvent(event);
game.addSimultaneousEvent(event);
return true;
}
return false;
@ -604,7 +604,7 @@ public abstract class CardImpl<T extends CardImpl<T>> extends MageObjectImpl<T>
@Override
public void addInfo(String key, String value) {
if (info == null) {
info = new HashMap<String, String>();
info = new HashMap<>();
}
info.put(key, value);
}

View file

@ -107,7 +107,8 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
this.rarity = card.getRarity();
this.cardNumber = card.getCardNumber();
this.usesVariousArt = card.getUsesVariousArt();
this.zoneChangeCounter = card.getZoneChangeCounter();
canTransform = card.canTransform();
if (canTransform) {
secondSideCard = card.getSecondCardFace();
@ -162,11 +163,6 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
}
game.setZone(objectId, event.getToZone());
game.addSimultaneousEvent(event);
if (event.getFromZone().equals(Zone.BATTLEFIELD)) {
game.getState().handleSimultaneousEvent(game);
game.resetForSourceId(getId());
game.applyEffects(); // LevelX2: needed to execute isInactive for of custom duration copy effect if source returns directly (e.g. cloudshifted clone)
}
return game.getState().getZone(objectId) == toZone;
}
}
@ -193,11 +189,7 @@ public class PermanentCard extends PermanentImpl<PermanentCard> {
game.getExile().createZone(exileId, name).add(card);
}
game.setZone(objectId, event.getToZone());
game.fireEvent(event);
if (event.getFromZone().equals(Zone.BATTLEFIELD)) {
game.resetForSourceId(getId());
game.applyEffects();
}
game.addSimultaneousEvent(event);
return true;
}
}