From 90774fea0bbb567a2735f7c4682693f39ecfc0b4 Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Tue, 13 Aug 2013 14:23:49 +0200
Subject: [PATCH] * Test of Faith - Fixed that +1/+1 counters that a blocker
 got during combat already counted for damage dealt to the attacker.

---
 .../cards/prevention/TestOfFaithTest.java     | 118 ++++++++++++++++++
 Mage/src/mage/game/combat/CombatGroup.java    |  22 ++--
 Mage/src/mage/game/turn/CombatDamageStep.java |   3 +-
 3 files changed, 135 insertions(+), 8 deletions(-)
 create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/prevention/TestOfFaithTest.java

diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/prevention/TestOfFaithTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/prevention/TestOfFaithTest.java
new file mode 100644
index 0000000000..a9d9494fc5
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/prevention/TestOfFaithTest.java
@@ -0,0 +1,118 @@
+/*
+ *  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 org.mage.test.cards.prevention;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author LevelX2
+ */
+public class TestOfFaithTest extends CardTestPlayerBase {
+
+    @Test
+    public void testOneAttackerOneBlockerUsingFaith() {
+        addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+        addCard(Zone.BATTLEFIELD, playerA, "Soulmender");
+        addCard(Zone.HAND, playerA, "Test of Faith");
+
+        addCard(Zone.BATTLEFIELD, playerB, "Blur Sliver");
+
+        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Test of Faith", "Soulmender");
+
+        attack(2, playerB, "Blur Sliver");
+        block(2, playerA, "Soulmender", "Blur Sliver");
+
+        setStopAt(2, PhaseStep.END_COMBAT);
+        execute();
+
+        assertPermanentCount(playerA, "Soulmender", 1);
+        assertPowerToughness(playerA, "Soulmender", 3, 3);
+
+        assertPermanentCount(playerB, "Blur Sliver", 1);
+    }
+
+    @Test
+    public void testOneAttackerTwoBlockerOneUsingFaith() {
+        addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+        addCard(Zone.BATTLEFIELD, playerA, "Soulmender");
+        addCard(Zone.BATTLEFIELD, playerA, "Elvish Mystic");
+
+        addCard(Zone.HAND, playerA, "Test of Faith");
+
+        addCard(Zone.BATTLEFIELD, playerB, "Kalonian Tusker");
+
+        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Test of Faith", "Soulmender");
+
+        attack(2, playerB, "Kalonian Tusker");
+        block(2, playerA, "Elvish Mystic", "Kalonian Tusker");
+        block(2, playerA, "Soulmender", "Kalonian Tusker");
+
+
+        setStopAt(2, PhaseStep.END_COMBAT);
+        execute();
+
+        assertPermanentCount(playerA, "Soulmender", 1);
+        assertPowerToughness(playerA, "Soulmender", 2, 2); // one damage was prevented so Soulmender got +1/+1
+        assertPermanentCount(playerA, "Elvish Mystic", 0);
+
+        assertPermanentCount(playerB, "Kalonian Tusker", 1); // only 2 damage to Kalonian Tusker so he still lives
+    }
+
+    @Test
+    public void testOneAttackerTwoBlockerTwoUsingFaith() {
+        addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
+        addCard(Zone.BATTLEFIELD, playerA, "Soulmender");
+        addCard(Zone.BATTLEFIELD, playerA, "Elvish Mystic");
+
+        addCard(Zone.HAND, playerA, "Test of Faith", 2);
+
+        addCard(Zone.BATTLEFIELD, playerB, "Kalonian Tusker");
+
+        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Test of Faith", "Soulmender");
+        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Test of Faith", "Elvish Mystic");
+
+        attack(2, playerB, "Kalonian Tusker");
+        block(2, playerA, "Elvish Mystic", "Kalonian Tusker");
+        block(2, playerA, "Soulmender", "Kalonian Tusker");
+
+
+        setStopAt(2, PhaseStep.END_COMBAT);
+        execute();
+
+        assertPermanentCount(playerA, "Soulmender", 1);
+        assertPowerToughness(playerA, "Soulmender", 2, 2); // one damage was prevented so Soulmender got +1/+1
+        assertPermanentCount(playerA, "Elvish Mystic", 1);
+        assertPowerToughness(playerA, "Elvish Mystic", 2, 2); // two damage were prevented so Elvish Mystic got +2/+2
+
+        assertPermanentCount(playerB, "Kalonian Tusker", 1); // only 2 damage to Kalonian Tusker so he still lives
+    }
+}
diff --git a/Mage/src/mage/game/combat/CombatGroup.java b/Mage/src/mage/game/combat/CombatGroup.java
index 2255d62df8..760db26334 100644
--- a/Mage/src/mage/game/combat/CombatGroup.java
+++ b/Mage/src/mage/game/combat/CombatGroup.java
@@ -220,6 +220,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
         Permanent blocker = game.getPermanent(blockers.get(0));
         Permanent attacker = game.getPermanent(attackers.get(0));
         if (blocker != null && attacker != null) {
+            int blockerDamage = blocker.getPower().getValue(); // must be set before attacker damage marking because of effects like Test of Faith
             if (blocked && canDamage(attacker, first)) {
                 int damage = attacker.getPower().getValue();
                 if (hasTrample(attacker)) {
@@ -247,8 +248,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
                 }
             }
             if (canDamage(blocker, first)) {
-                if (blocker.getBlocking() == 1) { // blocking several creatures handled separately
-                    int blockerDamage = blocker.getPower().getValue();
+                if (blocker.getBlocking() == 1) { // blocking several creatures handled separately                    
                     attacker.markDamage(blockerDamage, blocker.getId(), game, true, true);
                 }
             }
@@ -264,6 +264,16 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
         Player player = game.getPlayer(attacker.getControllerId());
         int damage = attacker.getPower().getValue();
         if (canDamage(attacker, first)) {
+            // must be set before attacker damage marking because of effects like Test of Faith
+            Map<UUID, Integer> blockerPower = new HashMap<UUID, Integer>();
+            for (UUID blockerId: blockerOrder) {
+                Permanent blocker = game.getPermanent(blockerId);
+                if (canDamage(blocker, first)) {
+                    if (blocker.getBlocking() == 1) { // blocking several creatures handled separately
+                        blockerPower.put(blockerId, blocker.getPower().getValue());
+                    }
+                }
+            }
             Map<UUID, Integer> assigned = new HashMap<UUID, Integer>();
             if (blocked) {
                 for (UUID blockerId: blockerOrder) {
@@ -288,11 +298,9 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
                 }
             }
             for (UUID blockerId: blockerOrder) {
-                Permanent blocker = game.getPermanent(blockerId);
-                if (canDamage(blocker, first)) {
-                    if (blocker.getBlocking() == 1) { // blocking several creatures handled separately
-                        attacker.markDamage(blocker.getPower().getValue(), blocker.getId(), game, true, true);
-                    }
+                Integer power = blockerPower.get(blockerId);
+                if (power != null) {
+                    attacker.markDamage(power.intValue(), blockerId, game, true, true);
                 }
             }
             for (Map.Entry<UUID, Integer> entry : assigned.entrySet()) {
diff --git a/Mage/src/mage/game/turn/CombatDamageStep.java b/Mage/src/mage/game/turn/CombatDamageStep.java
index 8f6f27a2c5..9b1c48aa87 100644
--- a/Mage/src/mage/game/turn/CombatDamageStep.java
+++ b/Mage/src/mage/game/turn/CombatDamageStep.java
@@ -53,8 +53,9 @@ public class CombatDamageStep extends Step<CombatDamageStep> {
 
     @Override
     public boolean skipStep(Game game, UUID activePlayerId) {
-        if (game.getCombat().noAttackers())
+        if (game.getCombat().noAttackers()) {
             return true;
+        }
         return super.skipStep(game, activePlayerId);
     }