mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 11:32:00 -08:00
* 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:
parent
71fb7bf25b
commit
7fc072f467
4 changed files with 68 additions and 21 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue