mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
commit
32226c886a
10 changed files with 107 additions and 57 deletions
|
@ -1281,7 +1281,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
hideTables();
|
||||
SessionHandler.disconnect(false);
|
||||
if (errorCall) {
|
||||
UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect to " + currentConnection.getHost() + '?');
|
||||
UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect?");
|
||||
message.setButton1("No", null);
|
||||
message.setButton2("Yes", PlayerAction.CLIENT_RECONNECT);
|
||||
showUserRequestDialog(message);
|
||||
|
|
|
@ -188,7 +188,6 @@ public class HumanPlayer extends PlayerImpl {
|
|||
synchronized (response) {
|
||||
try {
|
||||
response.wait();
|
||||
logger.info("Got response from player: " + response.toString());
|
||||
} catch (InterruptedException ex) {
|
||||
logger.error("Response error for player " + getName() + " gameId: " + game.getId(), ex);
|
||||
} finally {
|
||||
|
|
|
@ -29,6 +29,7 @@ package mage.cards.d;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
|
@ -101,13 +102,13 @@ class DuplicantExileTargetEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
|
||||
Permanent sourcePermananent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
if (sourcePermananent != null) {
|
||||
sourcePermananent.imprint(permanent.getId(), game);
|
||||
sourcePermananent.addInfo("imprint", new StringBuilder("[Imprinted card - ").append(permanent.getName()).append(']').toString(), game);
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (permanent != null && sourceObject instanceof Permanent) {
|
||||
if (permanent.moveToExile(null, null, source.getSourceId(), game)) {
|
||||
((Permanent) sourceObject).imprint(permanent.getId(), game);
|
||||
((Permanent) sourceObject).addInfo("imprint", "[Imprinted card - " + permanent.getName() + ']', game);
|
||||
}
|
||||
return permanent.moveToExile(null, null, source.getSourceId(), game);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
|
@ -43,6 +44,7 @@ import mage.constants.CardType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterInstantOrSorceryCard;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
|
@ -61,7 +63,7 @@ import mage.watchers.Watcher;
|
|||
public class JelevaNephaliasScourge extends CardImpl {
|
||||
|
||||
public JelevaNephaliasScourge(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{B}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add("Vampire");
|
||||
this.subtype.add("Wizard");
|
||||
|
@ -107,27 +109,19 @@ class JelevaNephaliasScourgeEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
if (controller != null && sourceCard != null) {
|
||||
JelevaNephaliasWatcher watcher = (JelevaNephaliasWatcher) game.getState().getWatchers().get(JelevaNephaliasWatcher.class.getSimpleName(), source.getSourceId());
|
||||
if (watcher != null) {
|
||||
int xValue = watcher.getManaSpentToCastLastTime(sourceCard.getZoneChangeCounter(game) - 1);
|
||||
if (xValue > 0) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
int cardsToExile = Math.min(player.getLibrary().size(), xValue);
|
||||
for (int i = 0; i < cardsToExile; i++) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
card.moveToExile(CardUtil.getCardExileZoneId(game, source), sourceCard.getIdName(), source.getSourceId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
JelevaNephaliasWatcher watcher = (JelevaNephaliasWatcher) game.getState().getWatchers().get(JelevaNephaliasWatcher.class.getSimpleName());
|
||||
if (controller != null && sourceObject != null && watcher != null) {
|
||||
int xValue = watcher.getManaSpentToCastLastTime(sourceObject.getId(), sourceObject.getZoneChangeCounter(game) - 1);
|
||||
if (xValue > 0) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.moveCards(player.getLibrary().getTopCards(game, xValue), Zone.EXILED, source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -173,10 +167,10 @@ class JelevaNephaliasCastEffect extends OneShotEffect {
|
|||
|
||||
class JelevaNephaliasWatcher extends Watcher {
|
||||
|
||||
private final Map<Integer, Integer> manaSpendToCast = new HashMap<>(); // cast
|
||||
private final Map<String, Integer> manaSpendToCast = new HashMap<>(); // cast
|
||||
|
||||
public JelevaNephaliasWatcher() {
|
||||
super(JelevaNephaliasWatcher.class.getSimpleName(), WatcherScope.CARD);
|
||||
super(JelevaNephaliasWatcher.class.getSimpleName(), WatcherScope.GAME);
|
||||
}
|
||||
|
||||
public JelevaNephaliasWatcher(final JelevaNephaliasWatcher watcher) {
|
||||
|
@ -190,22 +184,22 @@ class JelevaNephaliasWatcher extends Watcher {
|
|||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getSourceId().equals(sourceId)) {
|
||||
// Watcher saves all casts becaus of possible Clone cards that copy Jeleva
|
||||
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
|
||||
if (!game.getStack().isEmpty()) {
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
if (stackObject instanceof Spell && ((Spell) stackObject).getSourceId().equals(sourceId)) {
|
||||
Card card = game.getCard(sourceId);
|
||||
if (!manaSpendToCast.containsValue(card.getZoneChangeCounter(game))) {
|
||||
manaSpendToCast.put(card.getZoneChangeCounter(game), ((Spell) stackObject).getSpellAbility().getManaCostsToPay().convertedManaCost());
|
||||
}
|
||||
if (stackObject instanceof Spell) {
|
||||
Spell spell = (Spell) stackObject;
|
||||
manaSpendToCast.putIfAbsent(spell.getSourceId().toString() + spell.getCard().getZoneChangeCounter(game),
|
||||
spell.getSpellAbility().getManaCostsToPay().convertedManaCost());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getManaSpentToCastLastTime(int zoneChangeCounter) {
|
||||
return manaSpendToCast.getOrDefault(zoneChangeCounter, 0);
|
||||
public int getManaSpentToCastLastTime(UUID sourceId, int zoneChangeCounter) {
|
||||
return manaSpendToCast.getOrDefault(sourceId.toString() + zoneChangeCounter, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,8 +47,7 @@ import mage.players.Player;
|
|||
public class MindsAglow extends CardImpl {
|
||||
|
||||
public MindsAglow(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{U}");
|
||||
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}");
|
||||
|
||||
// Join forces - Starting with you, each player may pay any amount of mana. Each player draws X cards, where X is the total amount of mana paid this way.
|
||||
this.getSpellAbility().addEffect(new MindsAglowEffect());
|
||||
|
@ -87,7 +86,7 @@ class MindsAglowEffect extends OneShotEffect {
|
|||
if (controller != null) {
|
||||
int xSum = 0;
|
||||
xSum += playerPaysXGenericMana(controller, source, game);
|
||||
for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
if (!Objects.equals(playerId, controller.getId())) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
|
@ -97,7 +96,7 @@ class MindsAglowEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if (xSum > 0) {
|
||||
for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
player.drawCards(xSum, game);
|
||||
|
@ -120,6 +119,9 @@ class MindsAglowEffect extends OneShotEffect {
|
|||
if (xValue > 0) {
|
||||
Cost cost = new GenericManaCost(xValue);
|
||||
payed = cost.pay(source, game, source.getSourceId(), player.getId(), false, null);
|
||||
if (!payed) {
|
||||
game.undo(player.getId());
|
||||
}
|
||||
} else {
|
||||
payed = true;
|
||||
}
|
||||
|
|
|
@ -122,8 +122,8 @@ class OathOfNissaEffect extends OneShotEffect {
|
|||
topCards.remove(card);
|
||||
}
|
||||
}
|
||||
controller.putCardsOnBottomOfLibrary(topCards, game, source, true);
|
||||
}
|
||||
controller.putCardsOnBottomOfLibrary(topCards, game, source, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -85,4 +85,54 @@ public class FracturingGustTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithIndestructible() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
// Destroy all artifacts and enchantments. You gain 2 life for each permanent destroyed this way.
|
||||
addCard(Zone.HAND, playerA, "Fracturing Gust", 1);
|
||||
|
||||
// Flying
|
||||
// Indestructible (Damage and effects that say "destroy" don't destroy this creature.)
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Darksteel Gargoyle", 1); // Artifact Creature - Gargoyle
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fracturing Gust");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Fracturing Gust", 1);
|
||||
assertPermanentCount(playerB, "Darksteel Gargoyle", 1);
|
||||
|
||||
// No life because Darksteel Gargoyle is Indestructible
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRestInPeace() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
// Destroy all artifacts and enchantments. You gain 2 life for each permanent destroyed this way.
|
||||
addCard(Zone.HAND, playerA, "Fracturing Gust", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ornithopter", 1); // Artifact Creature 2/2
|
||||
|
||||
// When Rest in Peace enters the battlefield, exile all cards from all graveyards.
|
||||
// If a card or token would be put into a graveyard from anywhere, exile it instead.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Rest in Peace"); // Artifact
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fracturing Gust");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Fracturing Gust", 1);
|
||||
assertGraveyardCount(playerB, "Ornithopter", 0);
|
||||
assertExileCount(playerB, "Ornithopter", 1);
|
||||
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,8 @@ public class CommanderReplaceEffectTest extends CardTestCommanderDuelBase {
|
|||
addCard(Zone.HAND, playerB, "Phyrexian Rebirth", 1);
|
||||
|
||||
// Daxos of Meletis can't be blocked by creatures with power 3 or greater.
|
||||
// Whenever Daxos of Meletis deals combat damage to a player, exile the top card of that player's library. You gain life equal to that card's converted mana cost. Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it.
|
||||
// Whenever Daxos of Meletis deals combat damage to a player, exile the top card of that player's library. You gain life equal to that card's converted mana cost.
|
||||
// Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it.
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Daxos of Meletis");
|
||||
|
||||
// Destroy all creatures, then put an X/X colorless Horror artifact creature token onto the battlefield, where X is the number of creatures destroyed this way.
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.game.permanent;
|
||||
|
||||
import java.util.*;
|
||||
import mage.MageObject;
|
||||
import mage.MageObjectReference;
|
||||
import mage.ObjectColor;
|
||||
|
@ -55,8 +56,6 @@ import mage.players.Player;
|
|||
import mage.util.GameLog;
|
||||
import mage.util.ThreadLocalStringBuilder;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -972,8 +971,8 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
}
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(EventType.DESTROYED_PERMANENT, objectId, sourceId, controllerId));
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -69,8 +69,8 @@ import mage.util.SubTypeList;
|
|||
*/
|
||||
public class Spell extends StackObjImpl implements Card {
|
||||
|
||||
private final List<Card> spellCards = new ArrayList<>();
|
||||
private final List<SpellAbility> spellAbilities = new ArrayList<>();
|
||||
private final List<Card> spellCards = new ArrayList<>();
|
||||
|
||||
private final Card card;
|
||||
private final ObjectColor color;
|
||||
|
@ -108,7 +108,6 @@ public class Spell extends StackObjImpl implements Card {
|
|||
this.controllerId = controllerId;
|
||||
this.fromZone = fromZone;
|
||||
this.countered = false;
|
||||
this.doneActivatingManaAbilities = false;
|
||||
}
|
||||
|
||||
public Spell(final Spell spell) {
|
||||
|
@ -129,13 +128,18 @@ public class Spell extends StackObjImpl implements Card {
|
|||
} else {
|
||||
this.card = spell.card.copy();
|
||||
}
|
||||
this.controllerId = spell.controllerId;
|
||||
|
||||
this.fromZone = spell.fromZone;
|
||||
this.copiedSpell = spell.copiedSpell;
|
||||
this.faceDown = spell.faceDown;
|
||||
this.color = spell.color.copy();
|
||||
this.frameColor = spell.color.copy();
|
||||
this.frameStyle = spell.frameStyle;
|
||||
|
||||
this.controllerId = spell.controllerId;
|
||||
this.copiedSpell = spell.copiedSpell;
|
||||
this.faceDown = spell.faceDown;
|
||||
this.countered = spell.countered;
|
||||
this.resolving = spell.resolving;
|
||||
|
||||
this.doneActivatingManaAbilities = spell.doneActivatingManaAbilities;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue