diff --git a/Mage.Client/serverlist.txt b/Mage.Client/serverlist.txt index 1a756c1784..021697d81e 100644 --- a/Mage.Client/serverlist.txt +++ b/Mage.Client/serverlist.txt @@ -1,6 +1,7 @@ -woogerworks (North America):xmage.woogerworks.com:17171 -XMage.info 1 (Europe) :176.31.186.181:17171 -XMage.info 2 (Europe) :176.31.186.181:17000 -Seedds Server (Asia) :115.29.203.80:17171 -Felipejoys (Brazil) :felipejoys.no-ip.org:17171 +woogerworks (North America/USA) :xmage.woogerworks.com:17171 +XMage.info 1 (Europe/France) :176.31.186.181:17171 +XMage.info 2 (Europe/France) :176.31.186.181:17000 +IceMage (Europe/Netherlands) :ring0.cc:17171 +Seedds Server (Asia) :115.29.203.80:17171 +Felipejoys (South America/Brazil):felipejoys.no-ip.org:17171 localhost -> connect to your local server (must be started):localhost:17171 diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java index c737e45ca7..56959a416d 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java @@ -387,7 +387,7 @@ public class ComputerPlayerMCTS extends ComputerPlayer implements Player { newPlayer.getLibrary().shuffle(); for (int i = 0; i < handSize; i++) { Card card = newPlayer.getLibrary().removeFromTop(mcts); - mcts.setZone(card.getId(), Zone.HAND); + card.setZone(Zone.HAND, mcts); newPlayer.getHand().add(card); } } diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java index b3e2a16e49..bebd0914a7 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java @@ -328,7 +328,7 @@ public class MCTSNode { player.getLibrary().shuffle(); for (int i = 0; i < handSize; i++) { Card card = player.getLibrary().removeFromTop(game); - game.setZone(card.getId(), Zone.HAND); + card.setZone(Zone.HAND, game); player.getHand().add(card); } } diff --git a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java index e8bef838cf..2f89506bef 100644 --- a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java +++ b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java @@ -96,7 +96,7 @@ public class SystemUtil { } Random random = new Random(); - Set<Card> cardsToLoad = new HashSet<Card>(); + Set<Card> cardsToLoad = new HashSet<>(); for (int i = 0; i < amount; i++) { CardInfo cardInfo = cards.get(random.nextInt(cards.size())); Card card = cardInfo != null ? cardInfo.getCard() : null; @@ -128,7 +128,7 @@ public class SystemUtil { if (zone.equals(Zone.BATTLEFIELD)) { card.putOntoBattlefield(game, Zone.OUTSIDE, null, player.getId()); } else if (zone.equals(Zone.LIBRARY)) { - game.setZone(card.getId(), Zone.LIBRARY); + card.setZone(Zone.LIBRARY, game); player.getLibrary().putOnTop(card, game); } else { card.moveToZone(zone, null, game, false); diff --git a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java index fd7a757370..09411bfbfe 100644 --- a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java +++ b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java @@ -195,15 +195,15 @@ class JaceTheMindSculptorEffect3 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); - ExileZone exile = game.getExile().getPermanentExile(); if (player != null) { while (true) { if (player.getLibrary().getFromTop(game) == null) { break; } Card card = player.getLibrary().removeFromTop(game); - exile.add(card); - game.setZone(card.getId(), Zone.EXILED); + if (card != null) { + card.moveToExile(null, "", source.getSourceId(), game); + } } for (Card card : player.getHand().getCards(game)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); diff --git a/Mage/src/mage/abilities/effects/AuraReplacementEffect.java b/Mage/src/mage/abilities/effects/AuraReplacementEffect.java index 99602f9073..6d21bb6276 100644 --- a/Mage/src/mage/abilities/effects/AuraReplacementEffect.java +++ b/Mage/src/mage/abilities/effects/AuraReplacementEffect.java @@ -152,7 +152,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl { PermanentCard permanent = new PermanentCard(card, card.getOwnerId()); game.getBattlefield().addPermanent(permanent); - game.setZone(card.getId(), Zone.BATTLEFIELD); + card.setZone(Zone.BATTLEFIELD, game); game.applyEffects(); permanent.entersBattlefield(event.getSourceId(), game, fromZone, true); game.applyEffects(); diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java index e91f5ed8d1..006601129a 100644 --- a/Mage/src/mage/cards/Card.java +++ b/Mage/src/mage/cards/Card.java @@ -140,4 +140,12 @@ public interface Card extends MageObject { @Override Card copy(); + + /** + * + * @return The main card of a split half card, otherwise thae card itself is returned + */ + Card getMainCard(); + + void setZone(Zone zone, Game game); } diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index aada14c563..03c9e90684 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -419,38 +419,39 @@ public abstract class CardImpl extends MageObjectImpl implements Card { @Override public boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId) { - ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, ability.getId(), controllerId, fromZone, Zone.STACK); + Card mainCard = getMainCard(); + ZoneChangeEvent event = new ZoneChangeEvent(mainCard.getId(), ability.getId(), controllerId, fromZone, Zone.STACK); if (!game.replaceEvent(event)) { if (event.getFromZone() != null) { switch (event.getFromZone()) { case GRAVEYARD: - game.getPlayer(ownerId).removeFromGraveyard(this, game); + game.getPlayer(ownerId).removeFromGraveyard(mainCard, game); break; case HAND: - game.getPlayer(ownerId).removeFromHand(this, game); + game.getPlayer(ownerId).removeFromHand(mainCard, game); break; case LIBRARY: - game.getPlayer(ownerId).removeFromLibrary(this, game); + game.getPlayer(ownerId).removeFromLibrary(mainCard, game); break; case EXILED: - game.getExile().removeCard(this, game); + game.getExile().removeCard(mainCard, game); break; case OUTSIDE: - game.getPlayer(ownerId).getSideboard().remove(this); + game.getPlayer(ownerId).getSideboard().remove(mainCard); break; case COMMAND: - game.getState().getCommand().remove((Commander)game.getObject(objectId)); + game.getState().getCommand().remove((Commander)game.getObject(mainCard.getId())); break; default: //logger.warning("moveToZone, not fully implemented: from="+event.getFromZone() + ", to="+event.getToZone()); } - game.rememberLKI(objectId, event.getFromZone(), this); + game.rememberLKI(mainCard.getId(), event.getFromZone(), this); } game.getStack().push(new Spell(this, ability.copy(), controllerId, event.getFromZone())); - game.setZone(objectId, event.getToZone()); + setZone(event.getToZone(), game); game.fireEvent(event); - return game.getState().getZone(objectId) == Zone.STACK; + return game.getState().getZone(mainCard.getId()) == Zone.STACK; } return false; } @@ -557,7 +558,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { // make sure the controller of all continuous effects of this card are switched to the current controller game.getContinuousEffects().setController(objectId, event.getPlayerId()); game.addPermanent(permanent); - game.setZone(objectId, Zone.BATTLEFIELD); + setZone(Zone.BATTLEFIELD, game); game.setScopeRelevant(true); permanent.setTapped(tapped); permanent.entersBattlefield(sourceId, game, event.getFromZone(), true); @@ -777,4 +778,14 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } return name; } + + @Override + public Card getMainCard() { + return this; + } + + @Override + public void setZone(Zone zone, Game game) { + game.setZone(getId(), zone); + } } diff --git a/Mage/src/mage/cards/SplitCard.java b/Mage/src/mage/cards/SplitCard.java index bbff7f6e07..cce2b36ac0 100644 --- a/Mage/src/mage/cards/SplitCard.java +++ b/Mage/src/mage/cards/SplitCard.java @@ -31,15 +31,16 @@ package mage.cards; import java.util.ArrayList; import java.util.List; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.SpellAbilityType; -import mage.constants.Zone; import mage.abilities.Abilities; import mage.abilities.AbilitiesImpl; import mage.abilities.Ability; import mage.abilities.SpellAbility; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.SpellAbilityType; +import static mage.constants.SpellAbilityType.SPLIT_LEFT; +import static mage.constants.SpellAbilityType.SPLIT_RIGHT; +import mage.constants.Zone; import mage.game.Game; import mage.watchers.Watcher; @@ -90,7 +91,28 @@ public abstract class SplitCard extends CardImpl { public Card getRightHalfCard () { return rightHalfCard; } - + + @Override + public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag, ArrayList<UUID> appliedEffects) { + if (super.moveToZone(toZone, sourceId, game, flag, appliedEffects)) { + game.getState().setZone(getLeftHalfCard().getId(), toZone); + game.getState().setZone(getRightHalfCard().getId(), toZone); + return true; + } + return false; + } + + @Override + public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList<UUID> appliedEffects) { + if (super.moveToExile(exileId, name, sourceId, game, appliedEffects)) { + Zone currentZone = game.getState().getZone(getId()); + game.getState().setZone(getLeftHalfCard().getId(), currentZone); + game.getState().setZone(getRightHalfCard().getId(), currentZone); + return true; + } + return false; + } + @Override public boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId) { switch(ability.getSpellAbilityType()) { @@ -103,6 +125,14 @@ public abstract class SplitCard extends CardImpl { } } + @Override + public void setZone(Zone zone, Game game) { + super.setZone(zone, game); + game.setZone(getLeftHalfCard().getId(), zone); + game.setZone(getRightHalfCard().getId(), zone); + } + + @Override public Abilities<Ability> getAbilities(){ Abilities<Ability> allAbilites = new AbilitiesImpl<>(); @@ -198,7 +228,21 @@ class LeftHalfCard extends CardImpl { @Override public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList<UUID> appliedEffects) { return splitCardParent.moveToExile(exileId, name, sourceId, game, appliedEffects); - } + } + + @Override + public Card getMainCard() { + return splitCardParent; + } + + @Override + public void setZone(Zone zone, Game game) { + super.setZone(zone, game); + game.setZone(splitCardParent.getId(), zone); + game.setZone(splitCardParent.getRightHalfCard().getId(), zone); + } + + } /* @@ -247,4 +291,17 @@ class RightHalfCard extends CardImpl { public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList<UUID> appliedEffects) { return splitCardParent.moveToExile(exileId, name, sourceId, game, appliedEffects); } + + @Override + public Card getMainCard() { + return splitCardParent; + } + + @Override + public void setZone(Zone zone, Game game) { + super.setZone(zone, game); + game.setZone(splitCardParent.getId(), zone); + game.setZone(splitCardParent.getLeftHalfCard().getId(), zone); + } + } diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index a16426c9a2..8200578caa 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -2328,19 +2328,18 @@ public abstract class GameImpl implements Game, Serializable { loadCards(ownerId, graveyard); for (Card card : library) { - setZone(card.getId(), Zone.LIBRARY); player.getLibrary().putOnTop(card, this); } for (Card card : hand) { - setZone(card.getId(), Zone.HAND); + card.setZone(Zone.HAND, this); player.getHand().add(card); } for (Card card : graveyard) { - setZone(card.getId(), Zone.GRAVEYARD); + card.setZone(Zone.GRAVEYARD, this); player.getGraveyard().add(card); } for (PermanentCard card : battlefield) { - setZone(card.getId(), Zone.BATTLEFIELD); + card.setZone(Zone.BATTLEFIELD, this); card.setOwnerId(ownerId); PermanentCard permanent = new PermanentCard(card.getCard(), ownerId); getBattlefield().addPermanent(permanent); diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 5e9a9d7530..36788c92a6 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -210,7 +210,7 @@ public class Spell implements StackObject, Card { } } } - if (game.getState().getZone(card.getId()) == Zone.STACK) { + if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) { card.moveToZone(Zone.GRAVEYARD, ability.getSourceId(), game, false); } } @@ -999,4 +999,14 @@ public class Spell implements StackObject, Card { return card.isMorphCard(); } + @Override + public Card getMainCard() { + return card.getMainCard(); + } + + @Override + public void setZone(Zone zone, Game game) { + card.setZone(zone, game); + } + } diff --git a/Mage/src/mage/players/Library.java b/Mage/src/mage/players/Library.java index 5b878648f7..4a920c885e 100644 --- a/Mage/src/mage/players/Library.java +++ b/Mage/src/mage/players/Library.java @@ -131,7 +131,7 @@ public class Library implements Serializable { public void putOnTop(Card card, Game game) { if (card.getOwnerId().equals(playerId)) { - game.setZone(card.getId(), Zone.LIBRARY); + card.setZone(Zone.LIBRARY, game); library.addFirst(card.getId()); } else { @@ -141,7 +141,7 @@ public class Library implements Serializable { public void putOnBottom(Card card, Game game) { if (card.getOwnerId().equals(playerId)) { - game.setZone(card.getId(), Zone.LIBRARY); + card.setZone(Zone.LIBRARY, game); if (library.contains(card.getId())) { library.remove(card.getId()); } @@ -226,7 +226,7 @@ public class Library implements Serializable { public void addAll(Set<Card> cards, Game game) { for (Card card: cards) { - game.setZone(card.getId(), Zone.LIBRARY); + card.setZone(Zone.LIBRARY, game); library.add(card.getId()); } } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index f1f598202c..2da315c33f 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -650,8 +650,8 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean putInHand(Card card, Game game) { if (card.getOwnerId().equals(playerId)) { + card.setZone(Zone.HAND, game); this.hand.add(card); - game.setZone(card.getId(), Zone.HAND); } else { return game.getPlayer(card.getOwnerId()).putInHand(card, game); } @@ -924,7 +924,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (card != null) { if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability.getSourceId(), playerId))) { int bookmark = game.bookmarkState(); - Zone fromZone = game.getState().getZone(card.getId()); + Zone fromZone = game.getState().getZone(card.getMainCard().getId()); card.cast(game, fromZone, ability, playerId); Spell spell = game.getStack().getSpell(ability.getId()); // some effects set sourceId to cast without paying mana costs