Merge pull request #7 from magefree/master

Merge
This commit is contained in:
theelk801 2017-07-30 17:47:46 -04:00 committed by GitHub
commit 32226c886a
10 changed files with 107 additions and 57 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}