mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
[SNC] Implemented shield counter mechanic (#8830)
* [SNC] Implemented shield counter mechanic * Rework shield counter to be a global replacement effect * Add unit test for shield counter Co-authored-by: Evan Kranzler <theelk801@gmail.com>
This commit is contained in:
parent
a1c62f4495
commit
63239fe8e6
4 changed files with 134 additions and 1 deletions
|
@ -12,7 +12,7 @@ import java.util.List;
|
|||
*/
|
||||
public final class StreetsOfNewCapenna extends ExpansionSet {
|
||||
|
||||
private static final List<String> unfinished = Arrays.asList("Caldaia Strongarm", "Disciplined Duelist", "Elspeth Resplendent", "Falco Spara, Pactweaver", "Jaxis, the Troublemaker", "Mayhem Patrol", "Night Clubber", "Plasma Jockey", "Workshop Warchief", "Ziatora's Envoy");
|
||||
private static final List<String> unfinished = Arrays.asList("Elspeth Resplendent", "Falco Spara, Pactweaver", "Jaxis, the Troublemaker");
|
||||
|
||||
private static final StreetsOfNewCapenna instance = new StreetsOfNewCapenna();
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package org.mage.test.cards.replacement;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public class ShieldCounterTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testNoncombatDamage() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Disciplined Duelist");
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt");
|
||||
addTarget(playerA, "Disciplined Duelist");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
assertPermanentCount(playerA, "Disciplined Duelist", 1);
|
||||
assertCounterCount("Disciplined Duelist", CounterType.SHIELD, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombatDamage() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Disciplined Duelist");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Hill Giant");
|
||||
setStrictChooseMode(true);
|
||||
|
||||
attack(1, playerA, "Disciplined Duelist");
|
||||
block(1, playerB, "Hill Giant", "Disciplined Duelist");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
assertPermanentCount(playerA, "Disciplined Duelist", 1);
|
||||
assertCounterCount("Disciplined Duelist", CounterType.SHIELD, 0);
|
||||
assertGraveyardCount(playerB, "Hill Giant", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyEffect() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Disciplined Duelist");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.HAND, playerA, "Murder");
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Murder");
|
||||
addTarget(playerA, "Disciplined Duelist");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
assertPermanentCount(playerA, "Disciplined Duelist", 1);
|
||||
assertCounterCount("Disciplined Duelist", CounterType.SHIELD, 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package mage.abilities.effects.keyword;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public class ShieldCounterEffect extends ReplacementEffectImpl {
|
||||
|
||||
public ShieldCounterEffect() {
|
||||
super(Duration.Custom, Outcome.PreventDamage);
|
||||
this.staticText = "If it would be dealt damage or destroyed, remove a shield counter from it instead";
|
||||
}
|
||||
|
||||
private ShieldCounterEffect(final ShieldCounterEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShieldCounterEffect copy() {
|
||||
return new ShieldCounterEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null && permanent.getCounters(game).getCount(CounterType.SHIELD) > 0) {
|
||||
permanent.removeCounters(CounterType.SHIELD.getName(), 1, source, game);
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayers("Removed a shield counter from " + permanent.getLogName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
switch (event.getType()) {
|
||||
case DAMAGE_PERMANENT:
|
||||
case DESTROY_PERMANENT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
return permanent != null && permanent.getCounters(game).getCount(CounterType.SHIELD) > 0;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import mage.abilities.effects.Effect;
|
|||
import mage.abilities.effects.PreventionEffectData;
|
||||
import mage.abilities.effects.common.CopyEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.effects.keyword.ShieldCounterEffect;
|
||||
import mage.abilities.keyword.*;
|
||||
import mage.abilities.mana.DelayedTriggeredManaAbility;
|
||||
import mage.abilities.mana.TriggeredManaAbility;
|
||||
|
@ -1130,6 +1131,9 @@ public abstract class GameImpl implements Game {
|
|||
return;
|
||||
}
|
||||
|
||||
// Apply shield counter mechanic from SNC
|
||||
state.addAbility(new SimpleStaticAbility(Zone.ALL, new ShieldCounterEffect()), null);
|
||||
|
||||
// Handle companions
|
||||
Map<Player, Card> playerCompanionMap = new HashMap<>();
|
||||
for (Player player : state.getPlayers().values()) {
|
||||
|
|
Loading…
Reference in a new issue